1/* 2 * Copyright (c) 2017 The University of Virginia 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Alec Roelke 29 */ 30 31#include <limits> 32 33#include "insttest.h" 34#include "rv64c.h" 35#include "rv64d.h" 36 37int main() 38{ 39 using namespace insttest; 40 using namespace std; 41 42 // C.LWSP 43 expect<bool>(true, []{ 44 uint64_t lw = 0, lwsp = -1; 45 int64_t i = 16; 46 asm volatile("lw %0,%2(sp);" 47 "c.lwsp %1,%2(sp);" 48 : "=r" (lw), "=r" (lwsp) 49 : "i" (i)); 50 return lw == lwsp; 51 }, "c.lwsp"); 52 53 // C.LDSP 54 expect<bool>(true, []{ 55 uint64_t ld = 0, ldsp = -1; 56 int64_t i = 8; 57 asm volatile("ld %0,%2(sp);" 58 "c.ldsp %1,%2(sp);" 59 : "=r" (ld), "=r" (ldsp) 60 : "i" (i)); 61 return ld == ldsp; 62 }, "c.ldsp"); 63 64 // C.FLDSP 65 expect<bool>(true, []{ 66 double fld = 0.0, fldsp = -1.0; 67 int64_t i = 32; 68 asm volatile("fld %0,%2(sp);" 69 "c.fldsp %1,%2(sp);" 70 : "=f" (fld), "=f" (fldsp) 71 : "i" (i)); 72 return D::bits(fld) == D::bits(fldsp); 73 }, "c.fldsp"); 74 75 // C.SWSP 76 expect<bool>(true, []{ 77 int64_t value = -1, result = 0; 78 asm volatile("addi sp,sp,-8;" 79 "c.swsp %1,8(sp);" 80 "lw %0,8(sp);" 81 "addi sp,sp,8;" 82 : "=r" (result) 83 : "r" (value) 84 : "memory"); 85 return value == result; 86 }, "c.swsp"); 87 88 // C.SDSP 89 expect<bool>(true, []{ 90 int64_t value = -1, result = 0; 91 asm volatile("addi sp,sp,-8;" 92 "c.sdsp %1,8(sp);" 93 "ld %0,8(sp);" 94 "addi sp,sp,8;" 95 : "=r" (result) 96 : "r" (value) 97 : "memory"); 98 return value == result; 99 }, "c.sdsp"); 100 101 // C.FSDSP 102 expect<bool>(true, []{ 103 double value = 0.1, result = numeric_limits<double>::signaling_NaN(); 104 asm volatile("addi sp,sp,-8;" 105 "c.fsdsp %1,8(sp);" 106 "fld %0,8(sp);" 107 "addi sp,sp,8;" 108 : "=f" (result) 109 : "f" (value) 110 : "memory"); 111 return value == result; 112 }, "c.fsdsp"); 113 114 // C.LW, C.LD, C.FLD 115 expect<int64_t>(458752, 116 []{return C::c_load<int32_t, int64_t>(0x00070000);}, 117 "c.lw, positive"); 118 expect<int64_t>(numeric_limits<int32_t>::min(), 119 []{return C::c_load<int32_t, int64_t>(0x80000000);}, 120 "c.lw, negative"); 121 expect<int64_t>(30064771072, 122 []{return C::c_load<int64_t, int64_t>(30064771072);}, "c.ld"); 123 expect<double>(3.1415926, []{return C::c_load<double, double>(3.1415926);}, 124 "c.fld"); 125 126 // C.SW, C.SD, C.FSD 127 expect<uint32_t>(0xFFFFFFFF, []{return C::c_store<int32_t>(-1);}, "c.sw"); 128 expect<uint64_t>(-1, []{return C::c_store<int64_t>(-1);}, "c.sd"); 129 expect<double>(1.61803398875, 130 []{return C::c_store<double>(1.61803398875);}, "c.fsd"); 131 132 // C.J, C.JR, C.JALR 133 expect<bool>(true, []{return C::c_j();}, "c.j"); 134 expect<bool>(true, []{return C::c_jr();}, "c.jr"); 135 expect<bool>(true, []{return C::c_jalr();}, "c.jalr"); 136 137 // C.BEQZ 138 expect<bool>(true, []{return C::c_beqz(0);}, "c.beqz, zero"); 139 expect<bool>(false, []{return C::c_beqz(7);}, "c.beqz, not zero"); 140 141 // C.BNEZ 142 expect<bool>(true, []{return C::c_bnez(15);}, "c.bnez, not zero"); 143 expect<bool>(false, []{return C::c_bnez(0);}, "c.bnez, zero"); 144 145 // C.LI 146 expect<int64_t>(1, []{return C::c_li(1);}, "c.li"); 147 expect<int64_t>(-1, []{return C::c_li(-1);}, "c.li, sign extend"); 148 149 // C.LUI 150 expect<int64_t>(4096, []{return C::c_lui(1);}, "c.lui"); 151 // Note that sign extension can't be tested here because apparently the 152 // compiler doesn't allow the 6th (sign) bit of the immediate to be 1 153 154 // C.ADDI 155 expect<int64_t>(15, []{return C::c_addi(7, 8);}, "c.addi"); 156 157 // C.ADDIW 158 expect<int64_t>(15, []{return C::c_addiw(8, 7);}, "c.addiw"); 159 expect<int64_t>(1, []{return C::c_addiw(0xFFFFFFFF, 2);}, 160 "c.addiw, overflow"); 161 expect<int64_t>(1, []{return C::c_addiw(0x100000001, 0);}, 162 "c.addiw, truncate"); 163 164 // C.ADDI16SP 165 expect<bool>(true, []{ 166 uint64_t sp = 0, rd = 0; 167 const int16_t i = 4; 168 asm volatile("mv %0,sp;" 169 "c.addi16sp sp,%2;" 170 "mv %1,sp;" 171 "mv sp,%0;" 172 : "+r" (sp), "=r" (rd) 173 : "i" (i*16)); 174 return rd == sp + i*16; 175 }, "c.addi16sp"); 176 177 // C.ADDI4SPN 178 expect<bool>(true, []{ 179 uint64_t sp = 0, rd = 0; 180 const int16_t i = 3; 181 asm volatile("mv %0,sp;" 182 "c.addi4spn %1,sp,%2;" 183 : "=r" (sp), "=r" (rd) 184 : "i" (i*4)); 185 return rd == sp + i*4; 186 }, "c.addi4spn"); 187 188 // C.SLLI 189 expect<uint64_t>(16, []{return C::c_slli(1, 4);}, "c.slli"); 190 expect<uint64_t>(0, []{return C::c_slli(8, 61);}, "c.slli, overflow"); 191 192 // C.SRLI 193 expect<uint64_t>(4, []{return C::c_srli(128, 5);}, "c.srli"); 194 expect<uint64_t>(0, []{return C::c_srli(128, 8);}, "c.srli, overflow"); 195 expect<uint64_t>(1, []{return C::c_srli(-1, 63);}, "c.srli, -1"); 196 197 // C.SRAI 198 expect<uint64_t>(4, []{return C::c_srai(128, 5);}, "c.srai"); 199 expect<uint64_t>(0, []{return C::c_srai(128, 8);}, "c.srai, overflow"); 200 expect<uint64_t>(-1, []{return C::c_srai(-2, 63);}, "c.srai, -1"); 201 202 // C.ANDI 203 expect<uint64_t>(0, []{return C::c_andi(-1, 0);}, "c.andi (0)"); 204 expect<uint64_t>(0x1234567812345678ULL, 205 []{return C::c_andi(0x1234567812345678ULL, -1);}, "c.andi (1)"); 206 207 // C.MV 208 expect<int64_t>(1024, []{return C::c_mv(1024);}, "c.mv"); 209 210 // C.ADD 211 expect<int64_t>(15, []{return C::c_add(10, 5);}, "c.add"); 212 213 // C.AND 214 expect<uint64_t>(0, []{return C::c_and(-1, 0);}, "c.and (0)"); 215 expect<uint64_t>(0x1234567812345678ULL, 216 []{return C::c_and(0x1234567812345678ULL, -1);}, "c.and (-1)"); 217 218 // C.OR 219 expect<uint64_t>(-1, 220 []{return C::c_or(0xAAAAAAAAAAAAAAAAULL, 221 0x5555555555555555ULL);}, 222 "c.or (1)"); 223 expect<uint64_t>(0xAAAAAAAAAAAAAAAAULL, 224 []{return C::c_or(0xAAAAAAAAAAAAAAAAULL, 225 0xAAAAAAAAAAAAAAAAULL);}, 226 "c.or (A)"); 227 228 // C.XOR 229 expect<uint64_t>(-1, 230 []{return C::c_xor(0xAAAAAAAAAAAAAAAAULL, 231 0x5555555555555555ULL);}, 232 "c.xor (1)"); 233 expect<uint64_t>(0, 234 []{return C::c_xor(0xAAAAAAAAAAAAAAAAULL, 235 0xAAAAAAAAAAAAAAAAULL);}, 236 "c.xor (0)"); 237 238 // C.SUB 239 expect<int64_t>(65535, []{return C::c_sub(65536, 1);}, "c.sub"); 240 241 // C.ADDW 242 expect<int64_t>(1073742078, []{return C::c_addw(0x3FFFFFFF, 255);}, 243 "c.addw"); 244 expect<int64_t>(-1, []{return C::c_addw(0x7FFFFFFF, 0x80000000);}, 245 "c.addw, overflow"); 246 expect<int64_t>(65536, []{return C::c_addw(0xFFFFFFFF0000FFFFLL, 1);}, 247 "c.addw, truncate"); 248 249 // C.SUBW 250 expect<int64_t>(65535, []{return C::c_subw(65536, 1);}, "c.subw"); 251 expect<int64_t>(-1, []{return C::c_subw(0x7FFFFFFF, 0x80000000);}, 252 "c.subw, \"overflow\""); 253 expect<int64_t>(0, 254 []{return C::c_subw(0xAAAAAAAAFFFFFFFFULL,0x55555555FFFFFFFFULL);}, 255 "c.subw, truncate"); 256}