1// -*- mode:c++ -*- 2 3// Copyright (c) 2015 RISC-V Foundation
| 1// -*- mode:c++ -*- 2 3// Copyright (c) 2015 RISC-V Foundation
|
4// Copyright (c) 2016 The University of Virginia
| 4// Copyright (c) 2017 The University of Virginia
|
5// All rights reserved. 6// 7// Redistribution and use in source and binary forms, with or without 8// modification, are permitted provided that the following conditions are 9// met: redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer; 11// redistributions in binary form must reproduce the above copyright 12// notice, this list of conditions and the following disclaimer in the 13// documentation and/or other materials provided with the distribution; 14// neither the name of the copyright holders nor the names of its 15// contributors may be used to endorse or promote products derived from 16// this software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29// 30// Authors: Alec Roelke 31 32//////////////////////////////////////////////////////////////////// 33// 34// The RISC-V ISA decoder 35// 36
| 5// All rights reserved. 6// 7// Redistribution and use in source and binary forms, with or without 8// modification, are permitted provided that the following conditions are 9// met: redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer; 11// redistributions in binary form must reproduce the above copyright 12// notice, this list of conditions and the following disclaimer in the 13// documentation and/or other materials provided with the distribution; 14// neither the name of the copyright holders nor the names of its 15// contributors may be used to endorse or promote products derived from 16// this software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29// 30// Authors: Alec Roelke 31 32//////////////////////////////////////////////////////////////////// 33// 34// The RISC-V ISA decoder 35// 36
|
37decode OPCODE default Unknown::unknown() { 38 0x03: decode FUNCT3 { 39 format Load { 40 0x0: lb({{ 41 Rd_sd = Mem_sb;
| 37decode QUADRANT default Unknown::unknown() { 38 0x0: decode COPCODE { 39 0x0: CUIOp::c_addi4spn({{ 40 imm = CIMM8<1:1> << 2 | 41 CIMM8<0:0> << 3 | 42 CIMM8<7:6> << 4 | 43 CIMM8<5:2> << 6; 44 }}, {{ 45 assert(imm != 0); 46 Rp2 = sp + imm; 47 }}); 48 format CompressedLoad { 49 0x1: c_fld({{ 50 ldisp = CIMM3 << 3 | CIMM2 << 6; 51 }}, {{ 52 Fp2_bits = Mem; 53 }}, {{ 54 EA = Rp1 + ldisp;
|
42 }});
| 55 }});
|
43 0x1: lh({{ 44 Rd_sd = Mem_sh;
| 56 0x2: c_lw({{ 57 ldisp = CIMM2<1:1> << 2 | 58 CIMM3 << 3 | 59 CIMM2<0:0> << 6; 60 }}, {{ 61 Rp2_sd = Mem_sw; 62 }}, {{ 63 EA = Rp1 + ldisp;
|
45 }});
| 64 }});
|
46 0x2: lw({{ 47 Rd_sd = Mem_sw;
| 65 0x3: c_ld({{ 66 ldisp = CIMM3 << 3 | CIMM2 << 6; 67 }}, {{ 68 Rp2_sd = Mem_sd; 69 }}, {{ 70 EA = Rp1 + ldisp;
|
48 }});
| 71 }});
|
49 0x3: ld({{ 50 Rd_sd = Mem_sd;
| 72 } 73 format CompressedStore { 74 0x5: c_fsd({{ 75 sdisp = CIMM3 << 3 | CIMM2 << 6; 76 }}, {{ 77 Mem = Fp2_bits; 78 }}, {{ 79 EA = Rp1 + sdisp;
|
51 }});
| 80 }});
|
52 0x4: lbu({{ 53 Rd = Mem_ub;
| 81 0x6: c_sw({{ 82 sdisp = CIMM2<1:1> << 2 | 83 CIMM3 << 3 | 84 CIMM2<0:0> << 6; 85 }}, {{ 86 Mem_uw = Rp2_uw; 87 }}, ea_code={{ 88 EA = Rp1 + sdisp;
|
54 }});
| 89 }});
|
55 0x5: lhu({{ 56 Rd = Mem_uh;
| 90 0x7: c_sd({{ 91 sdisp = CIMM3 << 3 | CIMM2 << 6; 92 }}, {{ 93 Mem_ud = Rp2_ud; 94 }}, {{ 95 EA = Rp1 + sdisp;
|
57 }});
| 96 }});
|
58 0x6: lwu({{ 59 Rd = Mem_uw; 60 }});
| |
61 } 62 }
| 97 } 98 }
|
63 64 0x07: decode FUNCT3 { 65 format Load { 66 0x2: flw({{ 67 Fd_bits = (uint64_t)Mem_uw;
| 99 0x1: decode COPCODE { 100 format CIOp { 101 0x0: c_addi({{ 102 imm = CIMM5; 103 if (CIMM1 > 0) 104 imm |= ~((uint64_t)0x1F); 105 }}, {{ 106 assert((RC1 == 0) == (imm == 0)); 107 Rc1_sd = Rc1_sd + imm;
|
68 }});
| 108 }});
|
69 0x3: fld({{ 70 Fd_bits = Mem;
| 109 0x1: c_addiw({{ 110 imm = CIMM5; 111 if (CIMM1 > 0) 112 imm |= ~((uint64_t)0x1F); 113 }}, {{ 114 assert(RC1 != 0); 115 Rc1_sd = (int32_t)Rc1_sd + imm;
|
71 }});
| 116 }});
|
72 } 73 } 74 75 0x0f: decode FUNCT3 { 76 format IOp { 77 0x0: fence({{ 78 }}, IsNonSpeculative, IsMemBarrier, No_OpClass); 79 0x1: fence_i({{ 80 }}, IsNonSpeculative, IsSerializeAfter, No_OpClass); 81 } 82 } 83 84 0x13: decode FUNCT3 { 85 format IOp { 86 0x0: addi({{ 87 Rd_sd = Rs1_sd + imm;
| 117 0x2: c_li({{ 118 imm = CIMM5; 119 if (CIMM1 > 0) 120 imm |= ~((uint64_t)0x1F); 121 }}, {{ 122 assert(RC1 != 0); 123 Rc1_sd = imm;
|
88 }});
| 124 }});
|
89 0x1: slli({{ 90 Rd = Rs1 << SHAMT6; 91 }}); 92 0x2: slti({{ 93 Rd = (Rs1_sd < imm) ? 1 : 0; 94 }}); 95 0x3: sltiu({{ 96 Rd = (Rs1 < (uint64_t)imm) ? 1 : 0; 97 }}); 98 0x4: xori({{ 99 Rd = Rs1 ^ (uint64_t)imm; 100 }}); 101 0x5: decode SRTYPE { 102 0x0: srli({{ 103 Rd = Rs1 >> SHAMT6;
| 125 0x3: decode RC1 { 126 0x2: c_addi16sp({{ 127 imm = CIMM5<4:4> << 4 | 128 CIMM5<0:0> << 5 | 129 CIMM5<3:3> << 6 | 130 CIMM5<2:1> << 7; 131 if (CIMM1 > 0) 132 imm |= ~((int64_t)0x1FF); 133 }}, {{ 134 assert(imm != 0); 135 sp_sd = sp_sd + imm;
|
104 }});
| 136 }});
|
105 0x1: srai({{ 106 Rd_sd = Rs1_sd >> SHAMT6;
| 137 default: c_lui({{ 138 imm = CIMM5 << 12; 139 if (CIMM1 > 0) 140 imm |= ~((uint64_t)0x1FFFF); 141 }}, {{ 142 assert(RC1 != 0 && RC1 != 2); 143 assert(imm != 0); 144 Rc1_sd = imm;
|
107 }}); 108 }
| 145 }}); 146 }
|
109 0x6: ori({{ 110 Rd = Rs1 | (uint64_t)imm; 111 }}); 112 0x7: andi({{ 113 Rd = Rs1 & (uint64_t)imm; 114 }});
| |
115 }
| 147 }
|
116 } 117 118 0x17: UOp::auipc({{ 119 Rd = PC + imm; 120 }}); 121 122 0x1b: decode FUNCT3 { 123 format IOp { 124 0x0: addiw({{ 125 Rd_sd = (int32_t)Rs1 + (int32_t)imm; 126 }}); 127 0x1: slliw({{ 128 Rd_sd = Rs1_sw << SHAMT5; 129 }}); 130 0x5: decode SRTYPE { 131 0x0: srliw({{ 132 Rd = Rs1_uw >> SHAMT5;
| 148 0x4: decode CFUNCT2HIGH { 149 format CUIOp { 150 0x0: c_srli({{ 151 imm = CIMM5 | (CIMM1 << 5); 152 assert(imm != 0); 153 }}, {{ 154 Rp1 = Rp1 >> imm;
|
133 }});
| 155 }});
|
134 0x1: sraiw({{ 135 Rd_sd = Rs1_sw >> SHAMT5;
| 156 0x1: c_srai({{ 157 imm = CIMM5 | (CIMM1 << 5); 158 assert(imm != 0); 159 }}, {{ 160 Rp1_sd = Rp1_sd >> imm;
|
136 }});
| 161 }});
|
| 162 0x2: c_andi({{ 163 imm = CIMM5; 164 if (CIMM1 > 0) 165 imm |= ~((uint64_t)0x1F); 166 }}, {{ 167 Rp1 = Rp1 & imm; 168 }});
|
137 }
| 169 }
|
| 170 format ROp { 171 0x3: decode CFUNCT1 { 172 0x0: decode CFUNCT2LOW { 173 0x0: c_sub({{ 174 Rp1 = Rp1 - Rp2; 175 }}); 176 0x1: c_xor({{ 177 Rp1 = Rp1 ^ Rp2; 178 }}); 179 0x2: c_or({{ 180 Rp1 = Rp1 | Rp2; 181 }}); 182 0x3: c_and({{ 183 Rp1 = Rp1 & Rp2; 184 }}); 185 } 186 0x1: decode CFUNCT2LOW { 187 0x0: c_subw({{ 188 Rp1_sd = (int32_t)Rp1_sd - Rp2_sw; 189 }}); 190 0x1: c_addw({{ 191 Rp1_sd = (int32_t)Rp1_sd + Rp2_sw; 192 }}); 193 } 194 } 195 }
|
138 }
| 196 }
|
139 }
| 197 0x5: JOp::c_j({{ 198 int64_t offset = CJUMPIMM<3:1> << 1 | 199 CJUMPIMM<9:9> << 4 | 200 CJUMPIMM<0:0> << 5 | 201 CJUMPIMM<5:5> << 6 | 202 CJUMPIMM<4:4> << 7 | 203 CJUMPIMM<8:7> << 8 | 204 CJUMPIMM<6:6> << 10; 205 if (CJUMPIMM<10:10> > 0) 206 offset |= ~((int64_t)0x7FF); 207 NPC = PC + offset; 208 }}, IsIndirectControl, IsUncondControl, IsCall); 209 format BOp { 210 0x6: c_beqz({{ 211 int64_t offset = CIMM5<2:1> << 1 | 212 CIMM3<1:0> << 3 | 213 CIMM5<0:0> << 5 | 214 CIMM5<4:3> << 6; 215 if (CIMM3<2:2> > 0) 216 offset |= ~((int64_t)0xFF);
|
140
| 217
|
141 0x23: decode FUNCT3 { 142 format Store { 143 0x0: sb({{ 144 Mem_ub = Rs2_ub; 145 }}); 146 0x1: sh({{ 147 Mem_uh = Rs2_uh; 148 }}); 149 0x2: sw({{ 150 Mem_uw = Rs2_uw; 151 }}); 152 0x3: sd({{ 153 Mem_ud = Rs2_ud; 154 }});
| 218 if (Rp1 == 0) 219 NPC = PC + offset; 220 else 221 NPC = NPC; 222 }}, IsDirectControl, IsCondControl); 223 0x7: c_bnez({{ 224 int64_t offset = CIMM5<2:1> << 1 | 225 CIMM3<1:0> << 3 | 226 CIMM5<0:0> << 5 | 227 CIMM5<4:3> << 6; 228 if (CIMM3<2:2> > 0) 229 offset |= ~((int64_t)0xFF); 230 231 if (Rp1 != 0) 232 NPC = PC + offset; 233 else 234 NPC = NPC; 235 }}, IsDirectControl, IsCondControl);
|
155 } 156 }
| 236 } 237 }
|
157 158 0x27: decode FUNCT3 { 159 format Store { 160 0x2: fsw({{ 161 Mem_uw = (uint32_t)Fs2_bits;
| 238 0x2: decode COPCODE { 239 0x0: CUIOp::c_slli({{ 240 imm = CIMM5 | (CIMM1 << 5); 241 assert(imm != 0); 242 }}, {{ 243 assert(RC1 != 0); 244 Rc1 = Rc1 << imm; 245 }}); 246 format CompressedLoad { 247 0x1: c_fldsp({{ 248 ldisp = CIMM5<4:3> << 3 | 249 CIMM1 << 5 | 250 CIMM5<2:0> << 6; 251 }}, {{ 252 Fc1_bits = Mem; 253 }}, {{ 254 EA = sp + ldisp;
|
162 }});
| 255 }});
|
163 0x3: fsd({{ 164 Mem_ud = Fs2_bits;
| 256 0x2: c_lwsp({{ 257 ldisp = CIMM5<4:2> << 2 | 258 CIMM1 << 5 | 259 CIMM5<1:0> << 6; 260 }}, {{ 261 assert(RC1 != 0); 262 Rc1_sd = Mem_sw; 263 }}, {{ 264 EA = sp + ldisp;
|
165 }});
| 265 }});
|
166 } 167 } 168 169 0x2f: decode FUNCT3 { 170 0x2: decode AMOFUNCT { 171 0x2: LoadReserved::lr_w({{ 172 Rd_sd = Mem_sw; 173 }}, mem_flags=LLSC); 174 0x3: StoreCond::sc_w({{ 175 Mem_uw = Rs2_uw;
| 266 0x3: c_ldsp({{ 267 ldisp = CIMM5<4:3> << 3 | 268 CIMM1 << 5 | 269 CIMM5<2:0> << 6;
|
176 }}, {{
| 270 }}, {{
|
177 Rd = result; 178 }}, inst_flags=IsStoreConditional, mem_flags=LLSC); 179 format AtomicMemOp { 180 0x0: amoadd_w({{Rt_sd = Mem_sw;}}, {{ 181 Mem_sw = Rs2_sw + Rt_sd; 182 Rd_sd = Rt_sd; 183 }}, {{EA = Rs1;}}); 184 0x1: amoswap_w({{Rt_sd = Mem_sw;}}, {{ 185 Mem_sw = Rs2_uw; 186 Rd_sd = Rt_sd; 187 }}, {{EA = Rs1;}}); 188 0x4: amoxor_w({{Rt_sd = Mem_sw;}}, {{ 189 Mem_sw = Rs2_uw^Rt_sd; 190 Rd_sd = Rt_sd; 191 }}, {{EA = Rs1;}}); 192 0x8: amoor_w({{Rt_sd = Mem_sw;}}, {{ 193 Mem_sw = Rs2_uw | Rt_sd; 194 Rd_sd = Rt_sd; 195 }}, {{EA = Rs1;}}); 196 0xc: amoand_w({{Rt_sd = Mem_sw;}}, {{ 197 Mem_sw = Rs2_uw&Rt_sd; 198 Rd_sd = Rt_sd; 199 }}, {{EA = Rs1;}}); 200 0x10: amomin_w({{Rt_sd = Mem_sw;}}, {{ 201 Mem_sw = std::min<int32_t>(Rs2_sw, Rt_sd); 202 Rd_sd = Rt_sd; 203 }}, {{EA = Rs1;}}); 204 0x14: amomax_w({{Rt_sd = Mem_sw;}}, {{ 205 Mem_sw = std::max<int32_t>(Rs2_sw, Rt_sd); 206 Rd_sd = Rt_sd; 207 }}, {{EA = Rs1;}}); 208 0x18: amominu_w({{Rt_sd = Mem_sw;}}, {{ 209 Mem_sw = std::min<uint32_t>(Rs2_uw, Rt_sd); 210 Rd_sd = Rt_sd; 211 }}, {{EA = Rs1;}}); 212 0x1c: amomaxu_w({{Rt_sd = Mem_sw;}}, {{ 213 Mem_sw = std::max<uint32_t>(Rs2_uw, Rt_sd); 214 Rd_sd = Rt_sd; 215 }}, {{EA = Rs1;}});
| 271 assert(RC1 != 0); 272 Rc1_sd = Mem_sd; 273 }}, {{ 274 EA = sp + ldisp; 275 }}); 276 } 277 0x4: decode CFUNCT1 { 278 0x0: decode RC2 { 279 0x0: Jump::c_jr({{ 280 assert(RC1 != 0); 281 NPC = Rc1; 282 }}, IsIndirectControl, IsUncondControl, IsCall); 283 default: CROp::c_mv({{ 284 assert(RC1 != 0); 285 Rc1 = Rc2; 286 }});
|
216 }
| 287 }
|
| 288 0x1: decode RC1 { 289 0x0: SystemOp::c_ebreak({{ 290 assert(RC2 == 0); 291 fault = make_shared<BreakpointFault>(); 292 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); 293 default: decode RC2 { 294 0x0: Jump::c_jalr({{ 295 assert(RC1 != 0); 296 ra = NPC; 297 NPC = Rc1; 298 }}, IsIndirectControl, IsUncondControl, IsCall); 299 default: ROp::c_add({{ 300 Rc1_sd = Rc1_sd + Rc2_sd; 301 }}); 302 } 303 }
|
217 }
| 304 }
|
218 0x3: decode AMOFUNCT { 219 0x2: LoadReserved::lr_d({{ 220 Rd_sd = Mem_sd; 221 }}, mem_flags=LLSC); 222 0x3: StoreCond::sc_d({{ 223 Mem = Rs2;
| 305 format CompressedStore { 306 0x5: c_fsdsp({{ 307 sdisp = CIMM6<5:3> << 3 | 308 CIMM6<2:0> << 6;
|
224 }}, {{
| 309 }}, {{
|
225 Rd = result; 226 }}, mem_flags=LLSC, inst_flags=IsStoreConditional); 227 format AtomicMemOp { 228 0x0: amoadd_d({{Rt_sd = Mem_sd;}}, {{ 229 Mem_sd = Rs2_sd + Rt_sd; 230 Rd_sd = Rt_sd; 231 }}, {{EA = Rs1;}}); 232 0x1: amoswap_d({{Rt = Mem;}}, {{ 233 Mem = Rs2; 234 Rd = Rt; 235 }}, {{EA = Rs1;}}); 236 0x4: amoxor_d({{Rt = Mem;}}, {{ 237 Mem = Rs2^Rt; 238 Rd = Rt; 239 }}, {{EA = Rs1;}}); 240 0x8: amoor_d({{Rt = Mem;}}, {{ 241 Mem = Rs2 | Rt; 242 Rd = Rt; 243 }}, {{EA = Rs1;}}); 244 0xc: amoand_d({{Rt = Mem;}}, {{ 245 Mem = Rs2&Rt; 246 Rd = Rt; 247 }}, {{EA = Rs1;}}); 248 0x10: amomin_d({{Rt_sd = Mem_sd;}}, {{ 249 Mem_sd = std::min(Rs2_sd, Rt_sd); 250 Rd_sd = Rt_sd; 251 }}, {{EA = Rs1;}}); 252 0x14: amomax_d({{Rt_sd = Mem_sd;}}, {{ 253 Mem_sd = std::max(Rs2_sd, Rt_sd); 254 Rd_sd = Rt_sd; 255 }}, {{EA = Rs1;}}); 256 0x18: amominu_d({{Rt = Mem;}}, {{ 257 Mem = std::min(Rs2, Rt); 258 Rd = Rt; 259 }}, {{EA = Rs1;}}); 260 0x1c: amomaxu_d({{Rt = Mem;}}, {{ 261 Mem = std::max(Rs2, Rt); 262 Rd = Rt; 263 }}, {{EA = Rs1;}}); 264 }
| 310 Mem_ud = Fc2_bits; 311 }}, {{ 312 EA = sp + sdisp; 313 }}); 314 0x6: c_swsp({{ 315 sdisp = CIMM6<5:2> << 2 | 316 CIMM6<1:0> << 6; 317 }}, {{ 318 Mem_uw = Rc2_uw; 319 }}, {{ 320 EA = sp + sdisp; 321 }}); 322 0x7: c_sdsp({{ 323 sdisp = CIMM6<5:3> << 3 | 324 CIMM6<2:0> << 6; 325 }}, {{ 326 Mem = Rc2; 327 }}, {{ 328 EA = sp + sdisp; 329 }});
|
265 } 266 }
| 330 } 331 }
|
267 0x33: decode FUNCT3 { 268 format ROp { 269 0x0: decode FUNCT7 { 270 0x0: add({{ 271 Rd = Rs1_sd + Rs2_sd;
| 332 0x3: decode OPCODE { 333 0x00: decode FUNCT3 { 334 format Load { 335 0x0: lb({{ 336 Rd_sd = Mem_sb;
|
272 }});
| 337 }});
|
273 0x1: mul({{ 274 Rd = Rs1_sd*Rs2_sd; 275 }}, IntMultOp); 276 0x20: sub({{ 277 Rd = Rs1_sd - Rs2_sd;
| 338 0x1: lh({{ 339 Rd_sd = Mem_sh;
|
278 }});
| 340 }});
|
279 } 280 0x1: decode FUNCT7 { 281 0x0: sll({{ 282 Rd = Rs1 << Rs2<5:0>;
| 341 0x2: lw({{ 342 Rd_sd = Mem_sw;
|
283 }});
| 343 }});
|
284 0x1: mulh({{ 285 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0); 286 287 uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd); 288 uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32; 289 uint64_t Rs2_lo = (uint32_t)std::abs(Rs2_sd); 290 uint64_t Rs2_hi = (uint64_t)std::abs(Rs2_sd) >> 32; 291 292 uint64_t hi = Rs1_hi*Rs2_hi; 293 uint64_t mid1 = Rs1_hi*Rs2_lo; 294 uint64_t mid2 = Rs1_lo*Rs2_hi; 295 uint64_t lo = Rs2_lo*Rs1_lo; 296 uint64_t carry = ((uint64_t)(uint32_t)mid1 297 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32; 298 299 uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry; 300 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0) : res; 301 }}, IntMultOp); 302 } 303 0x2: decode FUNCT7 { 304 0x0: slt({{ 305 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
| 344 0x3: ld({{ 345 Rd_sd = Mem_sd;
|
306 }});
| 346 }});
|
307 0x1: mulhsu({{ 308 bool negate = Rs1_sd < 0; 309 uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd); 310 uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32; 311 uint64_t Rs2_lo = (uint32_t)Rs2; 312 uint64_t Rs2_hi = Rs2 >> 32; 313 314 uint64_t hi = Rs1_hi*Rs2_hi; 315 uint64_t mid1 = Rs1_hi*Rs2_lo; 316 uint64_t mid2 = Rs1_lo*Rs2_hi; 317 uint64_t lo = Rs1_lo*Rs2_lo; 318 uint64_t carry = ((uint64_t)(uint32_t)mid1 319 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32; 320 321 uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry; 322 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res; 323 }}, IntMultOp); 324 } 325 0x3: decode FUNCT7 { 326 0x0: sltu({{ 327 Rd = (Rs1 < Rs2) ? 1 : 0;
| 347 0x4: lbu({{ 348 Rd = Mem_ub;
|
328 }});
| 349 }});
|
329 0x1: mulhu({{ 330 uint64_t Rs1_lo = (uint32_t)Rs1; 331 uint64_t Rs1_hi = Rs1 >> 32; 332 uint64_t Rs2_lo = (uint32_t)Rs2; 333 uint64_t Rs2_hi = Rs2 >> 32; 334 335 uint64_t hi = Rs1_hi*Rs2_hi; 336 uint64_t mid1 = Rs1_hi*Rs2_lo; 337 uint64_t mid2 = Rs1_lo*Rs2_hi; 338 uint64_t lo = Rs1_lo*Rs2_lo; 339 uint64_t carry = ((uint64_t)(uint32_t)mid1 340 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32; 341 342 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry; 343 }}, IntMultOp); 344 } 345 0x4: decode FUNCT7 { 346 0x0: xor({{ 347 Rd = Rs1 ^ Rs2;
| 350 0x5: lhu({{ 351 Rd = Mem_uh;
|
348 }});
| 352 }});
|
349 0x1: div({{ 350 if (Rs2_sd == 0) { 351 Rd_sd = -1; 352 } else if (Rs1_sd == std::numeric_limits<int64_t>::min() 353 && Rs2_sd == -1) { 354 Rd_sd = std::numeric_limits<int64_t>::min(); 355 } else { 356 Rd_sd = Rs1_sd/Rs2_sd; 357 } 358 }}, IntDivOp); 359 } 360 0x5: decode FUNCT7 { 361 0x0: srl({{ 362 Rd = Rs1 >> Rs2<5:0>;
| 353 0x6: lwu({{ 354 Rd = Mem_uw;
|
363 }});
| 355 }});
|
364 0x1: divu({{ 365 if (Rs2 == 0) { 366 Rd = std::numeric_limits<uint64_t>::max(); 367 } else { 368 Rd = Rs1/Rs2; 369 } 370 }}, IntDivOp); 371 0x20: sra({{ 372 Rd_sd = Rs1_sd >> Rs2<5:0>; 373 }});
| |
374 }
| 356 }
|
375 0x6: decode FUNCT7 { 376 0x0: or({{ 377 Rd = Rs1 | Rs2;
| 357 } 358 359 0x01: decode FUNCT3 { 360 format Load { 361 0x2: flw({{ 362 Fd_bits = (uint64_t)Mem_uw;
|
378 }});
| 363 }});
|
379 0x1: rem({{ 380 if (Rs2_sd == 0) { 381 Rd = Rs1_sd; 382 } else if (Rs1_sd == std::numeric_limits<int64_t>::min() 383 && Rs2_sd == -1) { 384 Rd = 0; 385 } else { 386 Rd = Rs1_sd%Rs2_sd; 387 } 388 }}, IntDivOp); 389 } 390 0x7: decode FUNCT7 { 391 0x0: and({{ 392 Rd = Rs1 & Rs2;
| 364 0x3: fld({{ 365 Fd_bits = Mem;
|
393 }});
| 366 }});
|
394 0x1: remu({{ 395 if (Rs2 == 0) { 396 Rd = Rs1; 397 } else { 398 Rd = Rs1%Rs2; 399 } 400 }}, IntDivOp);
| |
401 } 402 }
| 367 } 368 }
|
403 }
| |
404
| 369
|
405 0x37: UOp::lui({{ 406 Rd = (uint64_t)imm; 407 }});
| 370 0x03: decode FUNCT3 { 371 format IOp { 372 0x0: fence({{ 373 }}, IsNonSpeculative, IsMemBarrier, No_OpClass); 374 0x1: fence_i({{ 375 }}, IsNonSpeculative, IsSerializeAfter, No_OpClass); 376 } 377 }
|
408
| 378
|
409 0x3b: decode FUNCT3 { 410 format ROp { 411 0x0: decode FUNCT7 { 412 0x0: addw({{ 413 Rd_sd = Rs1_sw + Rs2_sw;
| 379 0x04: decode FUNCT3 { 380 format IOp { 381 0x0: addi({{ 382 Rd_sd = Rs1_sd + imm;
|
414 }});
| 383 }});
|
415 0x1: mulw({{ 416 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw); 417 }}, IntMultOp); 418 0x20: subw({{ 419 Rd_sd = Rs1_sw - Rs2_sw;
| 384 0x1: slli({{ 385 Rd = Rs1 << SHAMT6;
|
420 }});
| 386 }});
|
421 } 422 0x1: sllw({{ 423 Rd_sd = Rs1_sw << Rs2<4:0>; 424 }}); 425 0x4: divw({{ 426 if (Rs2_sw == 0) { 427 Rd_sd = -1; 428 } else if (Rs1_sw == std::numeric_limits<int32_t>::min() 429 && Rs2_sw == -1) { 430 Rd_sd = std::numeric_limits<int32_t>::min(); 431 } else { 432 Rd_sd = Rs1_sw/Rs2_sw;
| 387 0x2: slti({{ 388 Rd = (Rs1_sd < imm) ? 1 : 0; 389 }}); 390 0x3: sltiu({{ 391 Rd = (Rs1 < (uint64_t)imm) ? 1 : 0; 392 }}); 393 0x4: xori({{ 394 Rd = Rs1 ^ (uint64_t)imm; 395 }}); 396 0x5: decode SRTYPE { 397 0x0: srli({{ 398 Rd = Rs1 >> SHAMT6; 399 }}); 400 0x1: srai({{ 401 Rd_sd = Rs1_sd >> SHAMT6; 402 }});
|
433 }
| 403 }
|
434 }}, IntDivOp); 435 0x5: decode FUNCT7 { 436 0x0: srlw({{ 437 Rd_uw = Rs1_uw >> Rs2<4:0>;
| 404 0x6: ori({{ 405 Rd = Rs1 | (uint64_t)imm;
|
438 }});
| 406 }});
|
439 0x1: divuw({{ 440 if (Rs2_uw == 0) { 441 Rd_sd = std::numeric_limits<IntReg>::max(); 442 } else { 443 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw); 444 } 445 }}, IntDivOp); 446 0x20: sraw({{ 447 Rd_sd = Rs1_sw >> Rs2<4:0>;
| 407 0x7: andi({{ 408 Rd = Rs1 & (uint64_t)imm;
|
448 }}); 449 }
| 409 }}); 410 }
|
450 0x6: remw({{ 451 if (Rs2_sw == 0) { 452 Rd_sd = Rs1_sw; 453 } else if (Rs1_sw == std::numeric_limits<int32_t>::min() 454 && Rs2_sw == -1) { 455 Rd_sd = 0; 456 } else { 457 Rd_sd = Rs1_sw%Rs2_sw; 458 } 459 }}, IntDivOp); 460 0x7: remuw({{ 461 if (Rs2_uw == 0) { 462 Rd_sd = (int32_t)Rs1_uw; 463 } else { 464 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw); 465 } 466 }}, IntDivOp);
| |
467 }
| 411 }
|
468 }
| |
469
| 412
|
470 format FPROp { 471 0x43: decode FUNCT2 { 472 0x0: fmadd_s({{ 473 uint32_t temp; 474 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 475 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 476 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits); 477 float fd;
| 413 0x05: UOp::auipc({{ 414 Rd = PC + imm; 415 }});
|
478
| 416
|
479 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) { 480 if (issignalingnan(fs1) || issignalingnan(fs2) 481 || issignalingnan(fs3)) { 482 FFLAGS |= FloatInvalid; 483 } 484 fd = std::numeric_limits<float>::quiet_NaN(); 485 } else if (std::isinf(fs1) || std::isinf(fs2) || 486 std::isinf(fs3)) { 487 if (std::signbit(fs1) == std::signbit(fs2) 488 && !std::isinf(fs3)) { 489 fd = std::numeric_limits<float>::infinity(); 490 } else if (std::signbit(fs1) != std::signbit(fs2) 491 && !std::isinf(fs3)) { 492 fd = -std::numeric_limits<float>::infinity(); 493 } else { // Fs3_sf is infinity 494 fd = fs3; 495 } 496 } else { 497 fd = fs1*fs2 + fs3;
| 417 0x06: decode FUNCT3 { 418 format IOp { 419 0x0: addiw({{ 420 Rd_sd = (int32_t)Rs1 + (int32_t)imm; 421 }}); 422 0x1: slliw({{ 423 Rd_sd = Rs1_sw << SHAMT5; 424 }}); 425 0x5: decode SRTYPE { 426 0x0: srliw({{ 427 Rd = Rs1_uw >> SHAMT5; 428 }}); 429 0x1: sraiw({{ 430 Rd_sd = Rs1_sw >> SHAMT5; 431 }});
|
498 }
| 432 }
|
499 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 500 }}, FloatMultOp); 501 0x1: fmadd_d({{ 502 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) { 503 if (issignalingnan(Fs1) || issignalingnan(Fs2) 504 || issignalingnan(Fs3)) { 505 FFLAGS |= FloatInvalid; 506 } 507 Fd = std::numeric_limits<double>::quiet_NaN(); 508 } else if (std::isinf(Fs1) || std::isinf(Fs2) || 509 std::isinf(Fs3)) { 510 if (std::signbit(Fs1) == std::signbit(Fs2) 511 && !std::isinf(Fs3)) { 512 Fd = std::numeric_limits<double>::infinity(); 513 } else if (std::signbit(Fs1) != std::signbit(Fs2) 514 && !std::isinf(Fs3)) { 515 Fd = -std::numeric_limits<double>::infinity(); 516 } else { 517 Fd = Fs3; 518 } 519 } else { 520 Fd = Fs1*Fs2 + Fs3; 521 } 522 }}, FloatMultOp);
| 433 }
|
523 }
| 434 }
|
524 0x47: decode FUNCT2 { 525 0x0: fmsub_s({{ 526 uint32_t temp; 527 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 528 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 529 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits); 530 float fd;
| |
531
| 435
|
532 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) { 533 if (issignalingnan(fs1) || issignalingnan(fs2) 534 || issignalingnan(fs3)) { 535 FFLAGS |= FloatInvalid; 536 } 537 fd = std::numeric_limits<float>::quiet_NaN(); 538 } else if (std::isinf(fs1) || std::isinf(fs2) || 539 std::isinf(fs3)) { 540 if (std::signbit(fs1) == std::signbit(fs2) 541 && !std::isinf(fs3)) { 542 fd = std::numeric_limits<float>::infinity(); 543 } else if (std::signbit(fs1) != std::signbit(fs2) 544 && !std::isinf(fs3)) { 545 fd = -std::numeric_limits<float>::infinity(); 546 } else { // Fs3_sf is infinity 547 fd = -fs3; 548 } 549 } else { 550 fd = fs1*fs2 - fs3; 551 } 552 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 553 }}, FloatMultOp); 554 0x1: fmsub_d({{ 555 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) { 556 if (issignalingnan(Fs1) || issignalingnan(Fs2) 557 || issignalingnan(Fs3)) { 558 FFLAGS |= FloatInvalid; 559 } 560 Fd = std::numeric_limits<double>::quiet_NaN(); 561 } else if (std::isinf(Fs1) || std::isinf(Fs2) || 562 std::isinf(Fs3)) { 563 if (std::signbit(Fs1) == std::signbit(Fs2) 564 && !std::isinf(Fs3)) { 565 Fd = std::numeric_limits<double>::infinity(); 566 } else if (std::signbit(Fs1) != std::signbit(Fs2) 567 && !std::isinf(Fs3)) { 568 Fd = -std::numeric_limits<double>::infinity(); 569 } else { 570 Fd = -Fs3; 571 } 572 } else { 573 Fd = Fs1*Fs2 - Fs3; 574 } 575 }}, FloatMultOp);
| 436 0x08: decode FUNCT3 { 437 format Store { 438 0x0: sb({{ 439 Mem_ub = Rs2_ub; 440 }}); 441 0x1: sh({{ 442 Mem_uh = Rs2_uh; 443 }}); 444 0x2: sw({{ 445 Mem_uw = Rs2_uw; 446 }}); 447 0x3: sd({{ 448 Mem_ud = Rs2_ud; 449 }}); 450 }
|
576 }
| 451 }
|
577 0x4b: decode FUNCT2 { 578 0x0: fnmsub_s({{ 579 uint32_t temp; 580 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 581 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 582 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits); 583 float fd;
| |
584
| 452
|
585 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) { 586 if (issignalingnan(fs1) || issignalingnan(fs2) 587 || issignalingnan(fs3)) { 588 FFLAGS |= FloatInvalid; 589 } 590 fd = std::numeric_limits<float>::quiet_NaN(); 591 } else if (std::isinf(fs1) || std::isinf(fs2) || 592 std::isinf(fs3)) { 593 if (std::signbit(fs1) == std::signbit(fs2) 594 && !std::isinf(fs3)) { 595 fd = -std::numeric_limits<float>::infinity(); 596 } else if (std::signbit(fs1) != std::signbit(fs2) 597 && !std::isinf(fs3)) { 598 fd = std::numeric_limits<float>::infinity(); 599 } else { // Fs3_sf is infinity 600 fd = fs3; 601 } 602 } else { 603 fd = -(fs1*fs2 - fs3); 604 } 605 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 606 }}, FloatMultOp); 607 0x1: fnmsub_d({{ 608 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) { 609 if (issignalingnan(Fs1) || issignalingnan(Fs2) 610 || issignalingnan(Fs3)) { 611 FFLAGS |= FloatInvalid; 612 } 613 Fd = std::numeric_limits<double>::quiet_NaN(); 614 } else if (std::isinf(Fs1) || std::isinf(Fs2) 615 || std::isinf(Fs3)) { 616 if (std::signbit(Fs1) == std::signbit(Fs2) 617 && !std::isinf(Fs3)) { 618 Fd = -std::numeric_limits<double>::infinity(); 619 } else if (std::signbit(Fs1) != std::signbit(Fs2) 620 && !std::isinf(Fs3)) { 621 Fd = std::numeric_limits<double>::infinity(); 622 } else { 623 Fd = Fs3; 624 } 625 } else { 626 Fd = -(Fs1*Fs2 - Fs3); 627 } 628 }}, FloatMultOp);
| 453 0x09: decode FUNCT3 { 454 format Store { 455 0x2: fsw({{ 456 Mem_uw = (uint32_t)Fs2_bits; 457 }}); 458 0x3: fsd({{ 459 Mem_ud = Fs2_bits; 460 }}); 461 }
|
629 }
| 462 }
|
630 0x4f: decode FUNCT2 { 631 0x0: fnmadd_s({{ 632 uint32_t temp; 633 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 634 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 635 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits); 636 float fd;
| |
637
| 463
|
638 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) { 639 if (issignalingnan(fs1) || issignalingnan(fs2) 640 || issignalingnan(fs3)) { 641 FFLAGS |= FloatInvalid; 642 } 643 fd = std::numeric_limits<float>::quiet_NaN(); 644 } else if (std::isinf(fs1) || std::isinf(fs2) || 645 std::isinf(fs3)) { 646 if (std::signbit(fs1) == std::signbit(fs2) 647 && !std::isinf(fs3)) { 648 fd = -std::numeric_limits<float>::infinity(); 649 } else if (std::signbit(fs1) != std::signbit(fs2) 650 && !std::isinf(fs3)) { 651 fd = std::numeric_limits<float>::infinity(); 652 } else { // Fs3_sf is infinity 653 fd = -fs3; 654 } 655 } else { 656 fd = -(fs1*fs2 + fs3);
| 464 0x0b: decode FUNCT3 { 465 0x2: decode AMOFUNCT { 466 0x2: LoadReserved::lr_w({{ 467 Rd_sd = Mem_sw; 468 }}, mem_flags=LLSC); 469 0x3: StoreCond::sc_w({{ 470 Mem_uw = Rs2_uw; 471 }}, {{ 472 Rd = result; 473 }}, inst_flags=IsStoreConditional, mem_flags=LLSC); 474 format AtomicMemOp { 475 0x0: amoadd_w({{Rt_sd = Mem_sw;}}, {{ 476 Mem_sw = Rs2_sw + Rt_sd; 477 Rd_sd = Rt_sd; 478 }}, {{EA = Rs1;}}); 479 0x1: amoswap_w({{Rt_sd = Mem_sw;}}, {{ 480 Mem_sw = Rs2_uw; 481 Rd_sd = Rt_sd; 482 }}, {{EA = Rs1;}}); 483 0x4: amoxor_w({{Rt_sd = Mem_sw;}}, {{ 484 Mem_sw = Rs2_uw^Rt_sd; 485 Rd_sd = Rt_sd; 486 }}, {{EA = Rs1;}}); 487 0x8: amoor_w({{Rt_sd = Mem_sw;}}, {{ 488 Mem_sw = Rs2_uw | Rt_sd; 489 Rd_sd = Rt_sd; 490 }}, {{EA = Rs1;}}); 491 0xc: amoand_w({{Rt_sd = Mem_sw;}}, {{ 492 Mem_sw = Rs2_uw&Rt_sd; 493 Rd_sd = Rt_sd; 494 }}, {{EA = Rs1;}}); 495 0x10: amomin_w({{Rt_sd = Mem_sw;}}, {{ 496 Mem_sw = min<int32_t>(Rs2_sw, Rt_sd); 497 Rd_sd = Rt_sd; 498 }}, {{EA = Rs1;}}); 499 0x14: amomax_w({{Rt_sd = Mem_sw;}}, {{ 500 Mem_sw = max<int32_t>(Rs2_sw, Rt_sd); 501 Rd_sd = Rt_sd; 502 }}, {{EA = Rs1;}}); 503 0x18: amominu_w({{Rt_sd = Mem_sw;}}, {{ 504 Mem_sw = min<uint32_t>(Rs2_uw, Rt_sd); 505 Rd_sd = Rt_sd; 506 }}, {{EA = Rs1;}}); 507 0x1c: amomaxu_w({{Rt_sd = Mem_sw;}}, {{ 508 Mem_sw = max<uint32_t>(Rs2_uw, Rt_sd); 509 Rd_sd = Rt_sd; 510 }}, {{EA = Rs1;}});
|
657 }
| 511 }
|
658 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 659 }}, FloatMultOp); 660 0x1: fnmadd_d({{ 661 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) { 662 if (issignalingnan(Fs1) || issignalingnan(Fs2) 663 || issignalingnan(Fs3)) { 664 FFLAGS |= FloatInvalid; 665 } 666 Fd = std::numeric_limits<double>::quiet_NaN(); 667 } else if (std::isinf(Fs1) || std::isinf(Fs2) || 668 std::isinf(Fs3)) { 669 if (std::signbit(Fs1) == std::signbit(Fs2) 670 && !std::isinf(Fs3)) { 671 Fd = -std::numeric_limits<double>::infinity(); 672 } else if (std::signbit(Fs1) != std::signbit(Fs2) 673 && !std::isinf(Fs3)) { 674 Fd = std::numeric_limits<double>::infinity(); 675 } else { 676 Fd = -Fs3; 677 } 678 } else { 679 Fd = -(Fs1*Fs2 + Fs3);
| 512 } 513 0x3: decode AMOFUNCT { 514 0x2: LoadReserved::lr_d({{ 515 Rd_sd = Mem_sd; 516 }}, mem_flags=LLSC); 517 0x3: StoreCond::sc_d({{ 518 Mem = Rs2; 519 }}, {{ 520 Rd = result; 521 }}, mem_flags=LLSC, inst_flags=IsStoreConditional); 522 format AtomicMemOp { 523 0x0: amoadd_d({{Rt_sd = Mem_sd;}}, {{ 524 Mem_sd = Rs2_sd + Rt_sd; 525 Rd_sd = Rt_sd; 526 }}, {{EA = Rs1;}}); 527 0x1: amoswap_d({{Rt = Mem;}}, {{ 528 Mem = Rs2; 529 Rd = Rt; 530 }}, {{EA = Rs1;}}); 531 0x4: amoxor_d({{Rt = Mem;}}, {{ 532 Mem = Rs2^Rt; 533 Rd = Rt; 534 }}, {{EA = Rs1;}}); 535 0x8: amoor_d({{Rt = Mem;}}, {{ 536 Mem = Rs2 | Rt; 537 Rd = Rt; 538 }}, {{EA = Rs1;}}); 539 0xc: amoand_d({{Rt = Mem;}}, {{ 540 Mem = Rs2&Rt; 541 Rd = Rt; 542 }}, {{EA = Rs1;}}); 543 0x10: amomin_d({{Rt_sd = Mem_sd;}}, {{ 544 Mem_sd = min(Rs2_sd, Rt_sd); 545 Rd_sd = Rt_sd; 546 }}, {{EA = Rs1;}}); 547 0x14: amomax_d({{Rt_sd = Mem_sd;}}, {{ 548 Mem_sd = max(Rs2_sd, Rt_sd); 549 Rd_sd = Rt_sd; 550 }}, {{EA = Rs1;}}); 551 0x18: amominu_d({{Rt = Mem;}}, {{ 552 Mem = min(Rs2, Rt); 553 Rd = Rt; 554 }}, {{EA = Rs1;}}); 555 0x1c: amomaxu_d({{Rt = Mem;}}, {{ 556 Mem = max(Rs2, Rt); 557 Rd = Rt; 558 }}, {{EA = Rs1;}});
|
680 }
| 559 }
|
681 }}, FloatMultOp);
| 560 }
|
682 }
| 561 }
|
| 562 0x0c: decode FUNCT3 { 563 format ROp { 564 0x0: decode FUNCT7 { 565 0x0: add({{ 566 Rd = Rs1_sd + Rs2_sd; 567 }}); 568 0x1: mul({{ 569 Rd = Rs1_sd*Rs2_sd; 570 }}, IntMultOp); 571 0x20: sub({{ 572 Rd = Rs1_sd - Rs2_sd; 573 }}); 574 } 575 0x1: decode FUNCT7 { 576 0x0: sll({{ 577 Rd = Rs1 << Rs2<5:0>; 578 }}); 579 0x1: mulh({{ 580 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
|
683
| 581
|
684 0x53: decode FUNCT7 { 685 0x0: fadd_s({{ 686 uint32_t temp; 687 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 688 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 689 float fd;
| 582 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd); 583 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32; 584 uint64_t Rs2_lo = (uint32_t)abs(Rs2_sd); 585 uint64_t Rs2_hi = (uint64_t)abs(Rs2_sd) >> 32;
|
690
| 586
|
691 if (std::isnan(fs1) || std::isnan(fs2)) { 692 if (issignalingnan(fs1) || issignalingnan(fs2)) { 693 FFLAGS |= FloatInvalid; 694 } 695 fd = std::numeric_limits<float>::quiet_NaN(); 696 } else { 697 fd = fs1 + fs2;
| 587 uint64_t hi = Rs1_hi*Rs2_hi; 588 uint64_t mid1 = Rs1_hi*Rs2_lo; 589 uint64_t mid2 = Rs1_lo*Rs2_hi; 590 uint64_t lo = Rs2_lo*Rs1_lo; 591 uint64_t carry = ((uint64_t)(uint32_t)mid1 592 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32; 593 594 uint64_t res = hi + 595 (mid1 >> 32) + 596 (mid2 >> 32) + 597 carry; 598 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0) 599 : res; 600 }}, IntMultOp);
|
698 }
| 601 }
|
699 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 700 }}, FloatAddOp); 701 0x1: fadd_d({{ 702 if (std::isnan(Fs1) || std::isnan(Fs2)) { 703 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 704 FFLAGS |= FloatInvalid; 705 } 706 Fd = std::numeric_limits<double>::quiet_NaN(); 707 } else { 708 Fd = Fs1 + Fs2;
| 602 0x2: decode FUNCT7 { 603 0x0: slt({{ 604 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0; 605 }}); 606 0x1: mulhsu({{ 607 bool negate = Rs1_sd < 0; 608 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd); 609 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32; 610 uint64_t Rs2_lo = (uint32_t)Rs2; 611 uint64_t Rs2_hi = Rs2 >> 32; 612 613 uint64_t hi = Rs1_hi*Rs2_hi; 614 uint64_t mid1 = Rs1_hi*Rs2_lo; 615 uint64_t mid2 = Rs1_lo*Rs2_hi; 616 uint64_t lo = Rs1_lo*Rs2_lo; 617 uint64_t carry = ((uint64_t)(uint32_t)mid1 618 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32; 619 620 uint64_t res = hi + 621 (mid1 >> 32) + 622 (mid2 >> 32) + 623 carry; 624 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res; 625 }}, IntMultOp);
|
709 }
| 626 }
|
710 }}, FloatAddOp); 711 0x4: fsub_s({{ 712 uint32_t temp; 713 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 714 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 715 float fd;
| 627 0x3: decode FUNCT7 { 628 0x0: sltu({{ 629 Rd = (Rs1 < Rs2) ? 1 : 0; 630 }}); 631 0x1: mulhu({{ 632 uint64_t Rs1_lo = (uint32_t)Rs1; 633 uint64_t Rs1_hi = Rs1 >> 32; 634 uint64_t Rs2_lo = (uint32_t)Rs2; 635 uint64_t Rs2_hi = Rs2 >> 32;
|
716
| 636
|
717 if (std::isnan(fs1) || std::isnan(fs2)) { 718 if (issignalingnan(fs1) || issignalingnan(fs2)) { 719 FFLAGS |= FloatInvalid; 720 } 721 fd = std::numeric_limits<float>::quiet_NaN(); 722 } else { 723 fd = fs1 - fs2;
| 637 uint64_t hi = Rs1_hi*Rs2_hi; 638 uint64_t mid1 = Rs1_hi*Rs2_lo; 639 uint64_t mid2 = Rs1_lo*Rs2_hi; 640 uint64_t lo = Rs1_lo*Rs2_lo; 641 uint64_t carry = ((uint64_t)(uint32_t)mid1 642 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32; 643 644 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry; 645 }}, IntMultOp);
|
724 }
| 646 }
|
725 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 726 }}, FloatAddOp); 727 0x5: fsub_d({{ 728 if (std::isnan(Fs1) || std::isnan(Fs2)) { 729 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 730 FFLAGS |= FloatInvalid; 731 } 732 Fd = std::numeric_limits<double>::quiet_NaN(); 733 } else { 734 Fd = Fs1 - Fs2;
| 647 0x4: decode FUNCT7 { 648 0x0: xor({{ 649 Rd = Rs1 ^ Rs2; 650 }}); 651 0x1: div({{ 652 if (Rs2_sd == 0) { 653 Rd_sd = -1; 654 } else if (Rs1_sd == numeric_limits<int64_t>::min() 655 && Rs2_sd == -1) { 656 Rd_sd = numeric_limits<int64_t>::min(); 657 } else { 658 Rd_sd = Rs1_sd/Rs2_sd; 659 } 660 }}, IntDivOp);
|
735 }
| 661 }
|
736 }}, FloatAddOp); 737 0x8: fmul_s({{ 738 uint32_t temp; 739 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 740 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 741 float fd; 742 743 if (std::isnan(fs1) || std::isnan(fs2)) { 744 if (issignalingnan(fs1) || issignalingnan(fs2)) { 745 FFLAGS |= FloatInvalid; 746 } 747 fd = std::numeric_limits<float>::quiet_NaN(); 748 } else { 749 fd = fs1*fs2;
| 662 0x5: decode FUNCT7 { 663 0x0: srl({{ 664 Rd = Rs1 >> Rs2<5:0>; 665 }}); 666 0x1: divu({{ 667 if (Rs2 == 0) { 668 Rd = numeric_limits<uint64_t>::max(); 669 } else { 670 Rd = Rs1/Rs2; 671 } 672 }}, IntDivOp); 673 0x20: sra({{ 674 Rd_sd = Rs1_sd >> Rs2<5:0>; 675 }});
|
750 }
| 676 }
|
751 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 752 }}, FloatMultOp); 753 0x9: fmul_d({{ 754 if (std::isnan(Fs1) || std::isnan(Fs2)) { 755 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 756 FFLAGS |= FloatInvalid; 757 } 758 Fd = std::numeric_limits<double>::quiet_NaN(); 759 } else { 760 Fd = Fs1*Fs2;
| 677 0x6: decode FUNCT7 { 678 0x0: or({{ 679 Rd = Rs1 | Rs2; 680 }}); 681 0x1: rem({{ 682 if (Rs2_sd == 0) { 683 Rd = Rs1_sd; 684 } else if (Rs1_sd == numeric_limits<int64_t>::min() 685 && Rs2_sd == -1) { 686 Rd = 0; 687 } else { 688 Rd = Rs1_sd%Rs2_sd; 689 } 690 }}, IntDivOp);
|
761 }
| 691 }
|
762 }}, FloatMultOp); 763 0xc: fdiv_s({{ 764 uint32_t temp; 765 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 766 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 767 float fd;
| 692 0x7: decode FUNCT7 { 693 0x0: and({{ 694 Rd = Rs1 & Rs2; 695 }}); 696 0x1: remu({{ 697 if (Rs2 == 0) { 698 Rd = Rs1; 699 } else { 700 Rd = Rs1%Rs2; 701 } 702 }}, IntDivOp); 703 } 704 } 705 }
|
768
| 706
|
769 if (std::isnan(fs1) || std::isnan(fs2)) { 770 if (issignalingnan(fs1) || issignalingnan(fs2)) { 771 FFLAGS |= FloatInvalid; 772 } 773 fd = std::numeric_limits<float>::quiet_NaN(); 774 } else { 775 fd = fs1/fs2;
| 707 0x0d: UOp::lui({{ 708 Rd = (uint64_t)imm; 709 }}); 710 711 0x0e: decode FUNCT3 { 712 format ROp { 713 0x0: decode FUNCT7 { 714 0x0: addw({{ 715 Rd_sd = Rs1_sw + Rs2_sw; 716 }}); 717 0x1: mulw({{ 718 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw); 719 }}, IntMultOp); 720 0x20: subw({{ 721 Rd_sd = Rs1_sw - Rs2_sw; 722 }});
|
776 }
| 723 }
|
777 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 778 }}, FloatDivOp); 779 0xd: fdiv_d({{ 780 if (std::isnan(Fs1) || std::isnan(Fs2)) { 781 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 782 FFLAGS |= FloatInvalid;
| 724 0x1: sllw({{ 725 Rd_sd = Rs1_sw << Rs2<4:0>; 726 }}); 727 0x4: divw({{ 728 if (Rs2_sw == 0) { 729 Rd_sd = -1; 730 } else if (Rs1_sw == numeric_limits<int32_t>::min() 731 && Rs2_sw == -1) { 732 Rd_sd = numeric_limits<int32_t>::min(); 733 } else { 734 Rd_sd = Rs1_sw/Rs2_sw;
|
783 }
| 735 }
|
784 Fd = std::numeric_limits<double>::quiet_NaN(); 785 } else { 786 Fd = Fs1/Fs2;
| 736 }}, IntDivOp); 737 0x5: decode FUNCT7 { 738 0x0: srlw({{ 739 Rd_uw = Rs1_uw >> Rs2<4:0>; 740 }}); 741 0x1: divuw({{ 742 if (Rs2_uw == 0) { 743 Rd_sd = numeric_limits<IntReg>::max(); 744 } else { 745 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw); 746 } 747 }}, IntDivOp); 748 0x20: sraw({{ 749 Rd_sd = Rs1_sw >> Rs2<4:0>; 750 }});
|
787 }
| 751 }
|
788 }}, FloatDivOp); 789 0x10: decode ROUND_MODE { 790 0x0: fsgnj_s({{
| 752 0x6: remw({{ 753 if (Rs2_sw == 0) { 754 Rd_sd = Rs1_sw; 755 } else if (Rs1_sw == numeric_limits<int32_t>::min() 756 && Rs2_sw == -1) { 757 Rd_sd = 0; 758 } else { 759 Rd_sd = Rs1_sw%Rs2_sw; 760 } 761 }}, IntDivOp); 762 0x7: remuw({{ 763 if (Rs2_uw == 0) { 764 Rd_sd = (int32_t)Rs1_uw; 765 } else { 766 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw); 767 } 768 }}, IntDivOp); 769 } 770 } 771 772 format FPROp { 773 0x10: decode FUNCT2 { 774 0x0: fmadd_s({{
|
791 uint32_t temp; 792 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 793 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
| 775 uint32_t temp; 776 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 777 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
|
| 778 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
|
794 float fd; 795
| 779 float fd; 780
|
796 if (issignalingnan(fs1)) { 797 fd = std::numeric_limits<float>::signaling_NaN(); 798 std::feclearexcept(FE_INVALID);
| 781 if (isnan(fs1) || isnan(fs2) || isnan(fs3)) { 782 if (issignalingnan(fs1) || issignalingnan(fs2) 783 || issignalingnan(fs3)) { 784 FFLAGS |= FloatInvalid; 785 } 786 fd = numeric_limits<float>::quiet_NaN(); 787 } else if (isinf(fs1) || isinf(fs2) || 788 isinf(fs3)) { 789 if (signbit(fs1) == signbit(fs2) 790 && !isinf(fs3)) { 791 fd = numeric_limits<float>::infinity(); 792 } else if (signbit(fs1) != signbit(fs2) 793 && !isinf(fs3)) { 794 fd = -numeric_limits<float>::infinity(); 795 } else { // Fs3_sf is infinity 796 fd = fs3; 797 }
|
799 } else {
| 798 } else {
|
800 fd = std::copysign(fs1, fs2);
| 799 fd = fs1*fs2 + fs3;
|
801 } 802 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
| 800 } 801 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
|
803 }}); 804 0x1: fsgnjn_s({{
| 802 }}, FloatMultOp); 803 0x1: fmadd_d({{ 804 if (isnan(Fs1) || isnan(Fs2) || isnan(Fs3)) { 805 if (issignalingnan(Fs1) || issignalingnan(Fs2) 806 || issignalingnan(Fs3)) { 807 FFLAGS |= FloatInvalid; 808 } 809 Fd = numeric_limits<double>::quiet_NaN(); 810 } else if (isinf(Fs1) || isinf(Fs2) || 811 isinf(Fs3)) { 812 if (signbit(Fs1) == signbit(Fs2) 813 && !isinf(Fs3)) { 814 Fd = numeric_limits<double>::infinity(); 815 } else if (signbit(Fs1) != signbit(Fs2) 816 && !isinf(Fs3)) { 817 Fd = -numeric_limits<double>::infinity(); 818 } else { 819 Fd = Fs3; 820 } 821 } else { 822 Fd = Fs1*Fs2 + Fs3; 823 } 824 }}, FloatMultOp); 825 } 826 0x11: decode FUNCT2 { 827 0x0: fmsub_s({{
|
805 uint32_t temp; 806 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 807 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
| 828 uint32_t temp; 829 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 830 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
|
| 831 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
|
808 float fd; 809
| 832 float fd; 833
|
810 if (issignalingnan(fs1)) { 811 fd = std::numeric_limits<float>::signaling_NaN(); 812 std::feclearexcept(FE_INVALID);
| 834 if (isnan(fs1) || isnan(fs2) || isnan(fs3)) { 835 if (issignalingnan(fs1) || issignalingnan(fs2) 836 || issignalingnan(fs3)) { 837 FFLAGS |= FloatInvalid; 838 } 839 fd = numeric_limits<float>::quiet_NaN(); 840 } else if (isinf(fs1) || isinf(fs2) || 841 isinf(fs3)) { 842 if (signbit(fs1) == signbit(fs2) 843 && !isinf(fs3)) { 844 fd = numeric_limits<float>::infinity(); 845 } else if (signbit(fs1) != signbit(fs2) 846 && !isinf(fs3)) { 847 fd = -numeric_limits<float>::infinity(); 848 } else { // Fs3_sf is infinity 849 fd = -fs3; 850 }
|
813 } else {
| 851 } else {
|
814 fd = std::copysign(fs1, -fs2);
| 852 fd = fs1*fs2 - fs3;
|
815 } 816 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
| 853 } 854 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
|
817 }}); 818 0x2: fsgnjx_s({{
| 855 }}, FloatMultOp); 856 0x1: fmsub_d({{ 857 if (isnan(Fs1) || isnan(Fs2) || isnan(Fs3)) { 858 if (issignalingnan(Fs1) || issignalingnan(Fs2) 859 || issignalingnan(Fs3)) { 860 FFLAGS |= FloatInvalid; 861 } 862 Fd = numeric_limits<double>::quiet_NaN(); 863 } else if (isinf(Fs1) || isinf(Fs2) || 864 isinf(Fs3)) { 865 if (signbit(Fs1) == signbit(Fs2) 866 && !isinf(Fs3)) { 867 Fd = numeric_limits<double>::infinity(); 868 } else if (signbit(Fs1) != signbit(Fs2) 869 && !isinf(Fs3)) { 870 Fd = -numeric_limits<double>::infinity(); 871 } else { 872 Fd = -Fs3; 873 } 874 } else { 875 Fd = Fs1*Fs2 - Fs3; 876 } 877 }}, FloatMultOp); 878 } 879 0x12: decode FUNCT2 { 880 0x0: fnmsub_s({{
|
819 uint32_t temp; 820 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 821 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
| 881 uint32_t temp; 882 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 883 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
|
| 884 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
|
822 float fd; 823
| 885 float fd; 886
|
824 if (issignalingnan(fs1)) { 825 fd = std::numeric_limits<float>::signaling_NaN(); 826 std::feclearexcept(FE_INVALID);
| 887 if (isnan(fs1) || isnan(fs2) || isnan(fs3)) { 888 if (issignalingnan(fs1) || issignalingnan(fs2) 889 || issignalingnan(fs3)) { 890 FFLAGS |= FloatInvalid; 891 } 892 fd = numeric_limits<float>::quiet_NaN(); 893 } else if (isinf(fs1) || isinf(fs2) || 894 isinf(fs3)) { 895 if (signbit(fs1) == signbit(fs2) 896 && !isinf(fs3)) { 897 fd = -numeric_limits<float>::infinity(); 898 } else if (signbit(fs1) != signbit(fs2) 899 && !isinf(fs3)) { 900 fd = numeric_limits<float>::infinity(); 901 } else { // Fs3_sf is infinity 902 fd = fs3; 903 }
|
827 } else {
| 904 } else {
|
828 fd = fs1*(std::signbit(fs2) ? -1.0 : 1.0);
| 905 fd = -(fs1*fs2 - fs3);
|
829 } 830 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
| 906 } 907 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
|
831 }}); 832 } 833 0x11: decode ROUND_MODE { 834 0x0: fsgnj_d({{ 835 if (issignalingnan(Fs1)) { 836 Fd = std::numeric_limits<double>::signaling_NaN(); 837 std::feclearexcept(FE_INVALID);
| 908 }}, FloatMultOp); 909 0x1: fnmsub_d({{ 910 if (isnan(Fs1) || isnan(Fs2) || isnan(Fs3)) { 911 if (issignalingnan(Fs1) || issignalingnan(Fs2) 912 || issignalingnan(Fs3)) { 913 FFLAGS |= FloatInvalid; 914 } 915 Fd = numeric_limits<double>::quiet_NaN(); 916 } else if (isinf(Fs1) || isinf(Fs2) 917 || isinf(Fs3)) { 918 if (signbit(Fs1) == signbit(Fs2) 919 && !isinf(Fs3)) { 920 Fd = -numeric_limits<double>::infinity(); 921 } else if (signbit(Fs1) != signbit(Fs2) 922 && !isinf(Fs3)) { 923 Fd = numeric_limits<double>::infinity(); 924 } else { 925 Fd = Fs3; 926 }
|
838 } else {
| 927 } else {
|
839 Fd = std::copysign(Fs1, Fs2);
| 928 Fd = -(Fs1*Fs2 - Fs3);
|
840 }
| 929 }
|
841 }}); 842 0x1: fsgnjn_d({{ 843 if (issignalingnan(Fs1)) { 844 Fd = std::numeric_limits<double>::signaling_NaN(); 845 std::feclearexcept(FE_INVALID); 846 } else { 847 Fd = std::copysign(Fs1, -Fs2); 848 } 849 }}); 850 0x2: fsgnjx_d({{ 851 if (issignalingnan(Fs1)) { 852 Fd = std::numeric_limits<double>::signaling_NaN(); 853 std::feclearexcept(FE_INVALID); 854 } else { 855 Fd = Fs1*(std::signbit(Fs2) ? -1.0 : 1.0); 856 } 857 }});
| 930 }}, FloatMultOp);
|
858 }
| 931 }
|
859 0x14: decode ROUND_MODE { 860 0x0: fmin_s({{
| 932 0x13: decode FUNCT2 { 933 0x0: fnmadd_s({{
|
861 uint32_t temp; 862 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 863 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
| 934 uint32_t temp; 935 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 936 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
|
| 937 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
|
864 float fd; 865
| 938 float fd; 939
|
866 if (issignalingnan(fs2)) { 867 fd = fs1; 868 FFLAGS |= FloatInvalid; 869 } else if (issignalingnan(fs1)) { 870 fd = fs2; 871 FFLAGS |= FloatInvalid;
| 940 if (isnan(fs1) || isnan(fs2) || isnan(fs3)) { 941 if (issignalingnan(fs1) || issignalingnan(fs2) 942 || issignalingnan(fs3)) { 943 FFLAGS |= FloatInvalid; 944 } 945 fd = numeric_limits<float>::quiet_NaN(); 946 } else if (isinf(fs1) || isinf(fs2) || 947 isinf(fs3)) { 948 if (signbit(fs1) == signbit(fs2) 949 && !isinf(fs3)) { 950 fd = -numeric_limits<float>::infinity(); 951 } else if (signbit(fs1) != signbit(fs2) 952 && !isinf(fs3)) { 953 fd = numeric_limits<float>::infinity(); 954 } else { // Fs3_sf is infinity 955 fd = -fs3; 956 }
|
872 } else {
| 957 } else {
|
873 fd = std::fmin(fs1, fs2);
| 958 fd = -(fs1*fs2 + fs3);
|
874 } 875 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
| 959 } 960 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
|
876 }}, FloatCmpOp); 877 0x1: fmax_s({{
| 961 }}, FloatMultOp); 962 0x1: fnmadd_d({{ 963 if (isnan(Fs1) || isnan(Fs2) || isnan(Fs3)) { 964 if (issignalingnan(Fs1) || issignalingnan(Fs2) 965 || issignalingnan(Fs3)) { 966 FFLAGS |= FloatInvalid; 967 } 968 Fd = numeric_limits<double>::quiet_NaN(); 969 } else if (isinf(Fs1) || isinf(Fs2) || 970 isinf(Fs3)) { 971 if (signbit(Fs1) == signbit(Fs2) 972 && !isinf(Fs3)) { 973 Fd = -numeric_limits<double>::infinity(); 974 } else if (signbit(Fs1) != signbit(Fs2) 975 && !isinf(Fs3)) { 976 Fd = numeric_limits<double>::infinity(); 977 } else { 978 Fd = -Fs3; 979 } 980 } else { 981 Fd = -(Fs1*Fs2 + Fs3); 982 } 983 }}, FloatMultOp); 984 } 985 0x14: decode FUNCT7 { 986 0x0: fadd_s({{
|
878 uint32_t temp; 879 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 880 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 881 float fd; 882
| 987 uint32_t temp; 988 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 989 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 990 float fd; 991
|
883 if (issignalingnan(fs2)) { 884 fd = fs1; 885 FFLAGS |= FloatInvalid; 886 } else if (issignalingnan(fs1)) { 887 fd = fs2; 888 FFLAGS |= FloatInvalid;
| 992 if (isnan(fs1) || isnan(fs2)) { 993 if (issignalingnan(fs1) || issignalingnan(fs2)) { 994 FFLAGS |= FloatInvalid; 995 } 996 fd = numeric_limits<float>::quiet_NaN();
|
889 } else {
| 997 } else {
|
890 fd = std::fmax(fs1, fs2);
| 998 fd = fs1 + fs2;
|
891 } 892 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
| 999 } 1000 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
|
893 }}, FloatCmpOp); 894 } 895 0x15: decode ROUND_MODE { 896 0x0: fmin_d({{ 897 if (issignalingnan(Fs2)) { 898 Fd = Fs1; 899 FFLAGS |= FloatInvalid; 900 } else if (issignalingnan(Fs1)) { 901 Fd = Fs2; 902 FFLAGS |= FloatInvalid;
| 1001 }}, FloatAddOp); 1002 0x1: fadd_d({{ 1003 if (isnan(Fs1) || isnan(Fs2)) { 1004 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 1005 FFLAGS |= FloatInvalid; 1006 } 1007 Fd = numeric_limits<double>::quiet_NaN();
|
903 } else {
| 1008 } else {
|
904 Fd = std::fmin(Fs1, Fs2);
| 1009 Fd = Fs1 + Fs2;
|
905 }
| 1010 }
|
906 }}, FloatCmpOp); 907 0x1: fmax_d({{ 908 if (issignalingnan(Fs2)) { 909 Fd = Fs1; 910 FFLAGS |= FloatInvalid; 911 } else if (issignalingnan(Fs1)) { 912 Fd = Fs2; 913 FFLAGS |= FloatInvalid; 914 } else { 915 Fd = std::fmax(Fs1, Fs2); 916 } 917 }}, FloatCmpOp); 918 } 919 0x20: fcvt_s_d({{ 920 assert(CONV_SGN == 1); 921 float fd; 922 if (issignalingnan(Fs1)) { 923 fd = std::numeric_limits<float>::quiet_NaN(); 924 FFLAGS |= FloatInvalid; 925 } else { 926 fd = (float)Fs1; 927 } 928 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 929 }}, FloatCvtOp); 930 0x21: fcvt_d_s({{ 931 assert(CONV_SGN == 0); 932 uint32_t temp; 933 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 934 935 if (issignalingnan(fs1)) { 936 Fd = std::numeric_limits<double>::quiet_NaN(); 937 FFLAGS |= FloatInvalid; 938 } else { 939 Fd = (double)fs1; 940 } 941 }}, FloatCvtOp); 942 0x2c: fsqrt_s({{ 943 assert(RS2 == 0); 944 uint32_t temp; 945 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 946 float fd; 947 948 if (issignalingnan(Fs1_sf)) { 949 FFLAGS |= FloatInvalid; 950 } 951 fd = std::sqrt(fs1); 952 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 953 }}, FloatSqrtOp); 954 0x2d: fsqrt_d({{ 955 assert(RS2 == 0); 956 Fd = std::sqrt(Fs1); 957 }}, FloatSqrtOp); 958 0x50: decode ROUND_MODE { 959 0x0: fle_s({{
| 1011 }}, FloatAddOp); 1012 0x4: fsub_s({{
|
960 uint32_t temp; 961 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 962 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
| 1013 uint32_t temp; 1014 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1015 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
|
| 1016 float fd;
|
963
| 1017
|
964 if (std::isnan(fs1) || std::isnan(fs2)) { 965 FFLAGS |= FloatInvalid; 966 Rd = 0;
| 1018 if (isnan(fs1) || isnan(fs2)) { 1019 if (issignalingnan(fs1) || issignalingnan(fs2)) { 1020 FFLAGS |= FloatInvalid; 1021 } 1022 fd = numeric_limits<float>::quiet_NaN();
|
967 } else {
| 1023 } else {
|
968 Rd = fs1 <= fs2 ? 1 : 0;
| 1024 fd = fs1 - fs2;
|
969 }
| 1025 }
|
970 }}, FloatCmpOp); 971 0x1: flt_s({{ 972 uint32_t temp; 973 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 974 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 975 976 if (std::isnan(fs1) || std::isnan(fs2)) { 977 FFLAGS |= FloatInvalid; 978 Rd = 0;
| 1026 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 1027 }}, FloatAddOp); 1028 0x5: fsub_d({{ 1029 if (isnan(Fs1) || isnan(Fs2)) { 1030 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 1031 FFLAGS |= FloatInvalid; 1032 } 1033 Fd = numeric_limits<double>::quiet_NaN();
|
979 } else {
| 1034 } else {
|
980 Rd = fs1 < fs2 ? 1 : 0;
| 1035 Fd = Fs1 - Fs2;
|
981 }
| 1036 }
|
982 }}, FloatCmpOp); 983 0x2: feq_s({{
| 1037 }}, FloatAddOp); 1038 0x8: fmul_s({{
|
984 uint32_t temp; 985 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 986 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
| 1039 uint32_t temp; 1040 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1041 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
|
| 1042 float fd;
|
987
| 1043
|
988 if (issignalingnan(fs1) || issignalingnan(fs2)) { 989 FFLAGS |= FloatInvalid; 990 } 991 Rd = fs1 == fs2 ? 1 : 0; 992 }}, FloatCmpOp); 993 } 994 0x51: decode ROUND_MODE { 995 0x0: fle_d({{ 996 if (std::isnan(Fs1) || std::isnan(Fs2)) { 997 FFLAGS |= FloatInvalid; 998 Rd = 0;
| 1044 if (isnan(fs1) || isnan(fs2)) { 1045 if (issignalingnan(fs1) || issignalingnan(fs2)) { 1046 FFLAGS |= FloatInvalid; 1047 } 1048 fd = numeric_limits<float>::quiet_NaN();
|
999 } else {
| 1049 } else {
|
1000 Rd = Fs1 <= Fs2 ? 1 : 0;
| 1050 fd = fs1*fs2;
|
1001 }
| 1051 }
|
1002 }}, FloatCmpOp); 1003 0x1: flt_d({{ 1004 if (std::isnan(Fs1) || std::isnan(Fs2)) { 1005 FFLAGS |= FloatInvalid; 1006 Rd = 0;
| 1052 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 1053 }}, FloatMultOp); 1054 0x9: fmul_d({{ 1055 if (isnan(Fs1) || isnan(Fs2)) { 1056 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 1057 FFLAGS |= FloatInvalid; 1058 } 1059 Fd = numeric_limits<double>::quiet_NaN();
|
1007 } else {
| 1060 } else {
|
1008 Rd = Fs1 < Fs2 ? 1 : 0;
| 1061 Fd = Fs1*Fs2;
|
1009 }
| 1062 }
|
1010 }}, FloatCmpOp); 1011 0x2: feq_d({{ 1012 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 1013 FFLAGS |= FloatInvalid; 1014 } 1015 Rd = Fs1 == Fs2 ? 1 : 0; 1016 }}, FloatCmpOp); 1017 } 1018 0x60: decode CONV_SGN { 1019 0x0: fcvt_w_s({{
| 1063 }}, FloatMultOp); 1064 0xc: fdiv_s({{
|
1020 uint32_t temp; 1021 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
| 1065 uint32_t temp; 1066 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
|
| 1067 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 1068 float fd;
|
1022
| 1069
|
1023 if (std::isnan(fs1)) { 1024 Rd_sd = std::numeric_limits<int32_t>::max(); 1025 FFLAGS |= FloatInvalid;
| 1070 if (isnan(fs1) || isnan(fs2)) { 1071 if (issignalingnan(fs1) || issignalingnan(fs2)) { 1072 FFLAGS |= FloatInvalid; 1073 } 1074 fd = numeric_limits<float>::quiet_NaN();
|
1026 } else {
| 1075 } else {
|
1027 Rd_sd = (int32_t)fs1; 1028 if (std::fetestexcept(FE_INVALID)) { 1029 if (std::signbit(fs1)) { 1030 Rd_sd = std::numeric_limits<int32_t>::min(); 1031 } else { 1032 Rd_sd = std::numeric_limits<int32_t>::max(); 1033 } 1034 std::feclearexcept(FE_INEXACT);
| 1076 fd = fs1/fs2; 1077 } 1078 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 1079 }}, FloatDivOp); 1080 0xd: fdiv_d({{ 1081 if (isnan(Fs1) || isnan(Fs2)) { 1082 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 1083 FFLAGS |= FloatInvalid;
|
1035 }
| 1084 }
|
| 1085 Fd = numeric_limits<double>::quiet_NaN(); 1086 } else { 1087 Fd = Fs1/Fs2;
|
1036 }
| 1088 }
|
1037 }}, FloatCvtOp); 1038 0x1: fcvt_wu_s({{ 1039 uint32_t temp; 1040 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
| 1089 }}, FloatDivOp); 1090 0x10: decode ROUND_MODE { 1091 0x0: fsgnj_s({{ 1092 uint32_t temp; 1093 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1094 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 1095 float fd;
|
1041
| 1096
|
1042 if (fs1 < 0.0) { 1043 Rd = 0;
| 1097 if (issignalingnan(fs1)) { 1098 fd = numeric_limits<float>::signaling_NaN(); 1099 feclearexcept(FE_INVALID); 1100 } else { 1101 fd = copysign(fs1, fs2); 1102 } 1103 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 1104 }}); 1105 0x1: fsgnjn_s({{ 1106 uint32_t temp; 1107 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1108 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 1109 float fd; 1110 1111 if (issignalingnan(fs1)) { 1112 fd = numeric_limits<float>::signaling_NaN(); 1113 feclearexcept(FE_INVALID); 1114 } else { 1115 fd = copysign(fs1, -fs2); 1116 } 1117 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 1118 }}); 1119 0x2: fsgnjx_s({{ 1120 uint32_t temp; 1121 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1122 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 1123 float fd; 1124 1125 if (issignalingnan(fs1)) { 1126 fd = numeric_limits<float>::signaling_NaN(); 1127 feclearexcept(FE_INVALID); 1128 } else { 1129 fd = fs1*(signbit(fs2) ? -1.0 : 1.0); 1130 } 1131 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 1132 }}); 1133 } 1134 0x11: decode ROUND_MODE { 1135 0x0: fsgnj_d({{ 1136 if (issignalingnan(Fs1)) { 1137 Fd = numeric_limits<double>::signaling_NaN(); 1138 feclearexcept(FE_INVALID); 1139 } else { 1140 Fd = copysign(Fs1, Fs2); 1141 } 1142 }}); 1143 0x1: fsgnjn_d({{ 1144 if (issignalingnan(Fs1)) { 1145 Fd = numeric_limits<double>::signaling_NaN(); 1146 feclearexcept(FE_INVALID); 1147 } else { 1148 Fd = copysign(Fs1, -Fs2); 1149 } 1150 }}); 1151 0x2: fsgnjx_d({{ 1152 if (issignalingnan(Fs1)) { 1153 Fd = numeric_limits<double>::signaling_NaN(); 1154 feclearexcept(FE_INVALID); 1155 } else { 1156 Fd = Fs1*(signbit(Fs2) ? -1.0 : 1.0); 1157 } 1158 }}); 1159 } 1160 0x14: decode ROUND_MODE { 1161 0x0: fmin_s({{ 1162 uint32_t temp; 1163 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1164 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 1165 float fd; 1166 1167 if (issignalingnan(fs2)) { 1168 fd = fs1; 1169 FFLAGS |= FloatInvalid; 1170 } else if (issignalingnan(fs1)) { 1171 fd = fs2; 1172 FFLAGS |= FloatInvalid; 1173 } else { 1174 fd = fmin(fs1, fs2); 1175 } 1176 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 1177 }}, FloatCmpOp); 1178 0x1: fmax_s({{ 1179 uint32_t temp; 1180 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1181 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 1182 float fd; 1183 1184 if (issignalingnan(fs2)) { 1185 fd = fs1; 1186 FFLAGS |= FloatInvalid; 1187 } else if (issignalingnan(fs1)) { 1188 fd = fs2; 1189 FFLAGS |= FloatInvalid; 1190 } else { 1191 fd = fmax(fs1, fs2); 1192 } 1193 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 1194 }}, FloatCmpOp); 1195 } 1196 0x15: decode ROUND_MODE { 1197 0x0: fmin_d({{ 1198 if (issignalingnan(Fs2)) { 1199 Fd = Fs1; 1200 FFLAGS |= FloatInvalid; 1201 } else if (issignalingnan(Fs1)) { 1202 Fd = Fs2; 1203 FFLAGS |= FloatInvalid; 1204 } else { 1205 Fd = fmin(Fs1, Fs2); 1206 } 1207 }}, FloatCmpOp); 1208 0x1: fmax_d({{ 1209 if (issignalingnan(Fs2)) { 1210 Fd = Fs1; 1211 FFLAGS |= FloatInvalid; 1212 } else if (issignalingnan(Fs1)) { 1213 Fd = Fs2; 1214 FFLAGS |= FloatInvalid; 1215 } else { 1216 Fd = fmax(Fs1, Fs2); 1217 } 1218 }}, FloatCmpOp); 1219 } 1220 0x20: fcvt_s_d({{ 1221 assert(CONV_SGN == 1); 1222 float fd; 1223 if (issignalingnan(Fs1)) { 1224 fd = numeric_limits<float>::quiet_NaN();
|
1044 FFLAGS |= FloatInvalid; 1045 } else {
| 1225 FFLAGS |= FloatInvalid; 1226 } else {
|
1046 Rd = (uint32_t)fs1; 1047 if (std::fetestexcept(FE_INVALID)) { 1048 Rd = std::numeric_limits<uint64_t>::max(); 1049 std::feclearexcept(FE_INEXACT); 1050 }
| 1227 fd = (float)Fs1;
|
1051 }
| 1228 }
|
| 1229 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
|
1052 }}, FloatCvtOp);
| 1230 }}, FloatCvtOp);
|
1053 0x2: fcvt_l_s({{
| 1231 0x21: fcvt_d_s({{ 1232 assert(CONV_SGN == 0);
|
1054 uint32_t temp; 1055 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1056
| 1233 uint32_t temp; 1234 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1235
|
1057 if (std::isnan(fs1)) { 1058 Rd_sd = std::numeric_limits<int64_t>::max();
| 1236 if (issignalingnan(fs1)) { 1237 Fd = numeric_limits<double>::quiet_NaN();
|
1059 FFLAGS |= FloatInvalid; 1060 } else {
| 1238 FFLAGS |= FloatInvalid; 1239 } else {
|
1061 Rd_sd = (int64_t)fs1; 1062 if (std::fetestexcept(FE_INVALID)) { 1063 if (std::signbit(fs1)) { 1064 Rd_sd = std::numeric_limits<int64_t>::min(); 1065 } else { 1066 Rd_sd = std::numeric_limits<int64_t>::max(); 1067 } 1068 std::feclearexcept(FE_INEXACT); 1069 }
| 1240 Fd = (double)fs1;
|
1070 } 1071 }}, FloatCvtOp);
| 1241 } 1242 }}, FloatCvtOp);
|
1072 0x3: fcvt_lu_s({{
| 1243 0x2c: fsqrt_s({{ 1244 assert(RS2 == 0);
|
1073 uint32_t temp; 1074 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
| 1245 uint32_t temp; 1246 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
|
| 1247 float fd;
|
1075
| 1248
|
1076 if (fs1 < 0.0) { 1077 Rd = 0;
| 1249 if (issignalingnan(Fs1_sf)) {
|
1078 FFLAGS |= FloatInvalid;
| 1250 FFLAGS |= FloatInvalid;
|
1079 } else { 1080 Rd = (uint64_t)fs1; 1081 if (std::fetestexcept(FE_INVALID)) { 1082 Rd = std::numeric_limits<uint64_t>::max(); 1083 std::feclearexcept(FE_INEXACT); 1084 }
| |
1085 }
| 1251 }
|
1086 }}, FloatCvtOp); 1087 } 1088 0x61: decode CONV_SGN { 1089 0x0: fcvt_w_d({{ 1090 Rd_sd = (int32_t)Fs1; 1091 if (std::fetestexcept(FE_INVALID)) { 1092 if (Fs1 < 0.0) { 1093 Rd_sd = std::numeric_limits<int32_t>::min();
| 1252 fd = sqrt(fs1); 1253 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 1254 }}, FloatSqrtOp); 1255 0x2d: fsqrt_d({{ 1256 assert(RS2 == 0); 1257 Fd = sqrt(Fs1); 1258 }}, FloatSqrtOp); 1259 0x50: decode ROUND_MODE { 1260 0x0: fle_s({{ 1261 uint32_t temp; 1262 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1263 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 1264 1265 if (isnan(fs1) || isnan(fs2)) { 1266 FFLAGS |= FloatInvalid; 1267 Rd = 0;
|
1094 } else {
| 1268 } else {
|
1095 Rd_sd = std::numeric_limits<int32_t>::max();
| 1269 Rd = fs1 <= fs2 ? 1 : 0;
|
1096 }
| 1270 }
|
1097 std::feclearexcept(FE_INEXACT); 1098 } 1099 }}, FloatCvtOp); 1100 0x1: fcvt_wu_d({{ 1101 if (Fs1 < 0.0) { 1102 Rd = 0; 1103 FFLAGS |= FloatInvalid; 1104 } else { 1105 Rd = (uint32_t)Fs1; 1106 if (std::fetestexcept(FE_INVALID)) { 1107 Rd = std::numeric_limits<uint64_t>::max(); 1108 std::feclearexcept(FE_INEXACT); 1109 } 1110 } 1111 }}, FloatCvtOp); 1112 0x2: fcvt_l_d({{ 1113 Rd_sd = Fs1; 1114 if (std::fetestexcept(FE_INVALID)) { 1115 if (Fs1 < 0.0) { 1116 Rd_sd = std::numeric_limits<int64_t>::min();
| 1271 }}, FloatCmpOp); 1272 0x1: flt_s({{ 1273 uint32_t temp; 1274 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1275 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 1276 1277 if (isnan(fs1) || isnan(fs2)) { 1278 FFLAGS |= FloatInvalid; 1279 Rd = 0;
|
1117 } else {
| 1280 } else {
|
1118 Rd_sd = std::numeric_limits<int64_t>::max();
| 1281 Rd = fs1 < fs2 ? 1 : 0;
|
1119 }
| 1282 }
|
1120 std::feclearexcept(FE_INEXACT); 1121 } 1122 }}, FloatCvtOp); 1123 0x3: fcvt_lu_d({{ 1124 if (Fs1 < 0.0) { 1125 Rd = 0; 1126 FFLAGS |= FloatInvalid; 1127 } else { 1128 Rd = (uint64_t)Fs1; 1129 if (std::fetestexcept(FE_INVALID)) { 1130 Rd = std::numeric_limits<uint64_t>::max(); 1131 std::feclearexcept(FE_INEXACT);
| 1283 }}, FloatCmpOp); 1284 0x2: feq_s({{ 1285 uint32_t temp; 1286 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1287 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 1288 1289 if (issignalingnan(fs1) || issignalingnan(fs2)) { 1290 FFLAGS |= FloatInvalid;
|
1132 }
| 1291 }
|
1133 } 1134 }}, FloatCvtOp); 1135 } 1136 0x68: decode CONV_SGN { 1137 0x0: fcvt_s_w({{ 1138 float temp = (float)Rs1_sw; 1139 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1140 }}, FloatCvtOp); 1141 0x1: fcvt_s_wu({{ 1142 float temp = (float)Rs1_uw; 1143 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1144 }}, FloatCvtOp); 1145 0x2: fcvt_s_l({{ 1146 float temp = (float)Rs1_sd; 1147 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1148 }}, FloatCvtOp); 1149 0x3: fcvt_s_lu({{ 1150 float temp = (float)Rs1; 1151 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1152 }}, FloatCvtOp); 1153 } 1154 0x69: decode CONV_SGN { 1155 0x0: fcvt_d_w({{ 1156 Fd = (double)Rs1_sw; 1157 }}, FloatCvtOp); 1158 0x1: fcvt_d_wu({{ 1159 Fd = (double)Rs1_uw; 1160 }}, FloatCvtOp); 1161 0x2: fcvt_d_l({{ 1162 Fd = (double)Rs1_sd; 1163 }}, FloatCvtOp); 1164 0x3: fcvt_d_lu({{ 1165 Fd = (double)Rs1; 1166 }}, FloatCvtOp); 1167 } 1168 0x70: decode ROUND_MODE { 1169 0x0: fmv_x_s({{ 1170 Rd = (uint32_t)Fs1_bits; 1171 if ((Rd&0x80000000) != 0) { 1172 Rd |= (0xFFFFFFFFULL << 32); 1173 } 1174 }}, FloatCvtOp); 1175 0x1: fclass_s({{ 1176 uint32_t temp; 1177 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1178 switch (std::fpclassify(fs1)) { 1179 case FP_INFINITE: 1180 if (std::signbit(fs1)) { 1181 Rd = 1 << 0;
| 1292 Rd = fs1 == fs2 ? 1 : 0; 1293 }}, FloatCmpOp); 1294 } 1295 0x51: decode ROUND_MODE { 1296 0x0: fle_d({{ 1297 if (isnan(Fs1) || isnan(Fs2)) { 1298 FFLAGS |= FloatInvalid; 1299 Rd = 0;
|
1182 } else {
| 1300 } else {
|
1183 Rd = 1 << 7;
| 1301 Rd = Fs1 <= Fs2 ? 1 : 0;
|
1184 }
| 1302 }
|
1185 break; 1186 case FP_NAN: 1187 if (issignalingnan(fs1)) { 1188 Rd = 1 << 8;
| 1303 }}, FloatCmpOp); 1304 0x1: flt_d({{ 1305 if (isnan(Fs1) || isnan(Fs2)) { 1306 FFLAGS |= FloatInvalid; 1307 Rd = 0;
|
1189 } else {
| 1308 } else {
|
1190 Rd = 1 << 9;
| 1309 Rd = Fs1 < Fs2 ? 1 : 0;
|
1191 }
| 1310 }
|
1192 break; 1193 case FP_ZERO: 1194 if (std::signbit(fs1)) { 1195 Rd = 1 << 3; 1196 } else { 1197 Rd = 1 << 4;
| 1311 }}, FloatCmpOp); 1312 0x2: feq_d({{ 1313 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 1314 FFLAGS |= FloatInvalid;
|
1198 }
| 1315 }
|
1199 break; 1200 case FP_SUBNORMAL: 1201 if (std::signbit(fs1)) { 1202 Rd = 1 << 2;
| 1316 Rd = Fs1 == Fs2 ? 1 : 0; 1317 }}, FloatCmpOp); 1318 } 1319 0x60: decode CONV_SGN { 1320 0x0: fcvt_w_s({{ 1321 uint32_t temp; 1322 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1323 1324 if (isnan(fs1)) { 1325 Rd_sd = numeric_limits<int32_t>::max(); 1326 FFLAGS |= FloatInvalid;
|
1203 } else {
| 1327 } else {
|
1204 Rd = 1 << 5;
| 1328 Rd_sd = (int32_t)fs1; 1329 if (fetestexcept(FE_INVALID)) { 1330 if (signbit(fs1)) { 1331 Rd_sd = numeric_limits<int32_t>::min(); 1332 } else { 1333 Rd_sd = numeric_limits<int32_t>::max(); 1334 } 1335 feclearexcept(FE_INEXACT); 1336 }
|
1205 }
| 1337 }
|
1206 break; 1207 case FP_NORMAL: 1208 if (std::signbit(fs1)) { 1209 Rd = 1 << 1;
| 1338 }}, FloatCvtOp); 1339 0x1: fcvt_wu_s({{ 1340 uint32_t temp; 1341 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1342 1343 if (fs1 < 0.0) { 1344 Rd = 0; 1345 FFLAGS |= FloatInvalid;
|
1210 } else {
| 1346 } else {
|
1211 Rd = 1 << 6;
| 1347 Rd = (uint32_t)fs1; 1348 if (fetestexcept(FE_INVALID)) { 1349 Rd = numeric_limits<uint64_t>::max(); 1350 feclearexcept(FE_INEXACT); 1351 }
|
1212 }
| 1352 }
|
1213 break; 1214 default: 1215 panic("Unknown classification for operand."); 1216 break; 1217 } 1218 }}); 1219 } 1220 0x71: decode ROUND_MODE { 1221 0x0: fmv_x_d({{ 1222 Rd = Fs1_bits; 1223 }}, FloatCvtOp); 1224 0x1: fclass_d({{ 1225 switch (std::fpclassify(Fs1)) { 1226 case FP_INFINITE: 1227 if (std::signbit(Fs1)) { 1228 Rd = 1 << 0;
| 1353 }}, FloatCvtOp); 1354 0x2: fcvt_l_s({{ 1355 uint32_t temp; 1356 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1357 1358 if (isnan(fs1)) { 1359 Rd_sd = numeric_limits<int64_t>::max(); 1360 FFLAGS |= FloatInvalid;
|
1229 } else {
| 1361 } else {
|
1230 Rd = 1 << 7;
| 1362 Rd_sd = (int64_t)fs1; 1363 if (fetestexcept(FE_INVALID)) { 1364 if (signbit(fs1)) { 1365 Rd_sd = numeric_limits<int64_t>::min(); 1366 } else { 1367 Rd_sd = numeric_limits<int64_t>::max(); 1368 } 1369 feclearexcept(FE_INEXACT); 1370 }
|
1231 }
| 1371 }
|
1232 break; 1233 case FP_NAN: 1234 if (issignalingnan(Fs1)) { 1235 Rd = 1 << 8;
| 1372 }}, FloatCvtOp); 1373 0x3: fcvt_lu_s({{ 1374 uint32_t temp; 1375 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1376 1377 if (fs1 < 0.0) { 1378 Rd = 0; 1379 FFLAGS |= FloatInvalid;
|
1236 } else {
| 1380 } else {
|
1237 Rd = 1 << 9;
| 1381 Rd = (uint64_t)fs1; 1382 if (fetestexcept(FE_INVALID)) { 1383 Rd = numeric_limits<uint64_t>::max(); 1384 feclearexcept(FE_INEXACT); 1385 }
|
1238 }
| 1386 }
|
1239 break; 1240 case FP_ZERO: 1241 if (std::signbit(Fs1)) { 1242 Rd = 1 << 3; 1243 } else { 1244 Rd = 1 << 4;
| 1387 }}, FloatCvtOp); 1388 } 1389 0x61: decode CONV_SGN { 1390 0x0: fcvt_w_d({{ 1391 Rd_sd = (int32_t)Fs1; 1392 if (fetestexcept(FE_INVALID)) { 1393 if (Fs1 < 0.0) { 1394 Rd_sd = numeric_limits<int32_t>::min(); 1395 } else { 1396 Rd_sd = numeric_limits<int32_t>::max(); 1397 } 1398 feclearexcept(FE_INEXACT);
|
1245 }
| 1399 }
|
1246 break; 1247 case FP_SUBNORMAL: 1248 if (std::signbit(Fs1)) { 1249 Rd = 1 << 2;
| 1400 }}, FloatCvtOp); 1401 0x1: fcvt_wu_d({{ 1402 if (Fs1 < 0.0) { 1403 Rd = 0; 1404 FFLAGS |= FloatInvalid;
|
1250 } else {
| 1405 } else {
|
1251 Rd = 1 << 5;
| 1406 Rd = (uint32_t)Fs1; 1407 if (fetestexcept(FE_INVALID)) { 1408 Rd = numeric_limits<uint64_t>::max(); 1409 feclearexcept(FE_INEXACT); 1410 }
|
1252 }
| 1411 }
|
1253 break; 1254 case FP_NORMAL: 1255 if (std::signbit(Fs1)) { 1256 Rd = 1 << 1;
| 1412 }}, FloatCvtOp); 1413 0x2: fcvt_l_d({{ 1414 Rd_sd = Fs1; 1415 if (fetestexcept(FE_INVALID)) { 1416 if (Fs1 < 0.0) { 1417 Rd_sd = numeric_limits<int64_t>::min(); 1418 } else { 1419 Rd_sd = numeric_limits<int64_t>::max(); 1420 } 1421 feclearexcept(FE_INEXACT); 1422 } 1423 }}, FloatCvtOp); 1424 0x3: fcvt_lu_d({{ 1425 if (Fs1 < 0.0) { 1426 Rd = 0; 1427 FFLAGS |= FloatInvalid;
|
1257 } else {
| 1428 } else {
|
1258 Rd = 1 << 6;
| 1429 Rd = (uint64_t)Fs1; 1430 if (fetestexcept(FE_INVALID)) { 1431 Rd = numeric_limits<uint64_t>::max(); 1432 feclearexcept(FE_INEXACT); 1433 }
|
1259 }
| 1434 }
|
1260 break; 1261 default: 1262 panic("Unknown classification for operand."); 1263 break; 1264 } 1265 }}); 1266 } 1267 0x78: fmv_s_x({{ 1268 Fd_bits = (uint64_t)Rs1_uw; 1269 }}, FloatCvtOp); 1270 0x79: fmv_d_x({{ 1271 Fd_bits = Rs1; 1272 }}, FloatCvtOp); 1273 } 1274 } 1275 1276 0x63: decode FUNCT3 { 1277 format BOp { 1278 0x0: beq({{ 1279 if (Rs1 == Rs2) { 1280 NPC = PC + imm; 1281 } else { 1282 NPC = NPC;
| 1435 }}, FloatCvtOp);
|
1283 }
| 1436 }
|
1284 }}, IsDirectControl, IsCondControl); 1285 0x1: bne({{ 1286 if (Rs1 != Rs2) { 1287 NPC = PC + imm; 1288 } else { 1289 NPC = NPC;
| 1437 0x68: decode CONV_SGN { 1438 0x0: fcvt_s_w({{ 1439 float temp = (float)Rs1_sw; 1440 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1441 }}, FloatCvtOp); 1442 0x1: fcvt_s_wu({{ 1443 float temp = (float)Rs1_uw; 1444 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1445 }}, FloatCvtOp); 1446 0x2: fcvt_s_l({{ 1447 float temp = (float)Rs1_sd; 1448 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1449 }}, FloatCvtOp); 1450 0x3: fcvt_s_lu({{ 1451 float temp = (float)Rs1; 1452 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1453 }}, FloatCvtOp);
|
1290 }
| 1454 }
|
1291 }}, IsDirectControl, IsCondControl); 1292 0x4: blt({{ 1293 if (Rs1_sd < Rs2_sd) { 1294 NPC = PC + imm; 1295 } else { 1296 NPC = NPC;
| 1455 0x69: decode CONV_SGN { 1456 0x0: fcvt_d_w({{ 1457 Fd = (double)Rs1_sw; 1458 }}, FloatCvtOp); 1459 0x1: fcvt_d_wu({{ 1460 Fd = (double)Rs1_uw; 1461 }}, FloatCvtOp); 1462 0x2: fcvt_d_l({{ 1463 Fd = (double)Rs1_sd; 1464 }}, FloatCvtOp); 1465 0x3: fcvt_d_lu({{ 1466 Fd = (double)Rs1; 1467 }}, FloatCvtOp);
|
1297 }
| 1468 }
|
1298 }}, IsDirectControl, IsCondControl); 1299 0x5: bge({{ 1300 if (Rs1_sd >= Rs2_sd) { 1301 NPC = PC + imm; 1302 } else { 1303 NPC = NPC;
| 1469 0x70: decode ROUND_MODE { 1470 0x0: fmv_x_s({{ 1471 Rd = (uint32_t)Fs1_bits; 1472 if ((Rd&0x80000000) != 0) { 1473 Rd |= (0xFFFFFFFFULL << 32); 1474 } 1475 }}, FloatCvtOp); 1476 0x1: fclass_s({{ 1477 uint32_t temp; 1478 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1479 switch (fpclassify(fs1)) { 1480 case FP_INFINITE: 1481 if (signbit(fs1)) { 1482 Rd = 1 << 0; 1483 } else { 1484 Rd = 1 << 7; 1485 } 1486 break; 1487 case FP_NAN: 1488 if (issignalingnan(fs1)) { 1489 Rd = 1 << 8; 1490 } else { 1491 Rd = 1 << 9; 1492 } 1493 break; 1494 case FP_ZERO: 1495 if (signbit(fs1)) { 1496 Rd = 1 << 3; 1497 } else { 1498 Rd = 1 << 4; 1499 } 1500 break; 1501 case FP_SUBNORMAL: 1502 if (signbit(fs1)) { 1503 Rd = 1 << 2; 1504 } else { 1505 Rd = 1 << 5; 1506 } 1507 break; 1508 case FP_NORMAL: 1509 if (signbit(fs1)) { 1510 Rd = 1 << 1; 1511 } else { 1512 Rd = 1 << 6; 1513 } 1514 break; 1515 default: 1516 panic("Unknown classification for operand."); 1517 break; 1518 } 1519 }});
|
1304 }
| 1520 }
|
1305 }}, IsDirectControl, IsCondControl); 1306 0x6: bltu({{ 1307 if (Rs1 < Rs2) { 1308 NPC = PC + imm; 1309 } else { 1310 NPC = NPC;
| 1521 0x71: decode ROUND_MODE { 1522 0x0: fmv_x_d({{ 1523 Rd = Fs1_bits; 1524 }}, FloatCvtOp); 1525 0x1: fclass_d({{ 1526 switch (fpclassify(Fs1)) { 1527 case FP_INFINITE: 1528 if (signbit(Fs1)) { 1529 Rd = 1 << 0; 1530 } else { 1531 Rd = 1 << 7; 1532 } 1533 break; 1534 case FP_NAN: 1535 if (issignalingnan(Fs1)) { 1536 Rd = 1 << 8; 1537 } else { 1538 Rd = 1 << 9; 1539 } 1540 break; 1541 case FP_ZERO: 1542 if (signbit(Fs1)) { 1543 Rd = 1 << 3; 1544 } else { 1545 Rd = 1 << 4; 1546 } 1547 break; 1548 case FP_SUBNORMAL: 1549 if (signbit(Fs1)) { 1550 Rd = 1 << 2; 1551 } else { 1552 Rd = 1 << 5; 1553 } 1554 break; 1555 case FP_NORMAL: 1556 if (signbit(Fs1)) { 1557 Rd = 1 << 1; 1558 } else { 1559 Rd = 1 << 6; 1560 } 1561 break; 1562 default: 1563 panic("Unknown classification for operand."); 1564 break; 1565 } 1566 }});
|
1311 }
| 1567 }
|
1312 }}, IsDirectControl, IsCondControl); 1313 0x7: bgeu({{ 1314 if (Rs1 >= Rs2) { 1315 NPC = PC + imm; 1316 } else { 1317 NPC = NPC; 1318 } 1319 }}, IsDirectControl, IsCondControl);
| 1568 0x78: fmv_s_x({{ 1569 Fd_bits = (uint64_t)Rs1_uw; 1570 }}, FloatCvtOp); 1571 0x79: fmv_d_x({{ 1572 Fd_bits = Rs1; 1573 }}, FloatCvtOp); 1574 }
|
1320 }
| 1575 }
|
1321 }
| |
1322
| 1576
|
1323 0x67: decode FUNCT3 { 1324 0x0: Jump::jalr({{ 1325 Rd = NPC; 1326 NPC = (imm + Rs1) & (~0x1); 1327 }}, IsIndirectControl, IsUncondControl, IsCall); 1328 }
| 1577 0x18: decode FUNCT3 { 1578 format BOp { 1579 0x0: beq({{ 1580 if (Rs1 == Rs2) { 1581 NPC = PC + imm; 1582 } else { 1583 NPC = NPC; 1584 } 1585 }}, IsDirectControl, IsCondControl); 1586 0x1: bne({{ 1587 if (Rs1 != Rs2) { 1588 NPC = PC + imm; 1589 } else { 1590 NPC = NPC; 1591 } 1592 }}, IsDirectControl, IsCondControl); 1593 0x4: blt({{ 1594 if (Rs1_sd < Rs2_sd) { 1595 NPC = PC + imm; 1596 } else { 1597 NPC = NPC; 1598 } 1599 }}, IsDirectControl, IsCondControl); 1600 0x5: bge({{ 1601 if (Rs1_sd >= Rs2_sd) { 1602 NPC = PC + imm; 1603 } else { 1604 NPC = NPC; 1605 } 1606 }}, IsDirectControl, IsCondControl); 1607 0x6: bltu({{ 1608 if (Rs1 < Rs2) { 1609 NPC = PC + imm; 1610 } else { 1611 NPC = NPC; 1612 } 1613 }}, IsDirectControl, IsCondControl); 1614 0x7: bgeu({{ 1615 if (Rs1 >= Rs2) { 1616 NPC = PC + imm; 1617 } else { 1618 NPC = NPC; 1619 } 1620 }}, IsDirectControl, IsCondControl); 1621 } 1622 }
|
1329
| 1623
|
1330 0x6f: JOp::jal({{ 1331 Rd = NPC; 1332 NPC = PC + imm; 1333 }}, IsDirectControl, IsUncondControl, IsCall);
| 1624 0x19: decode FUNCT3 { 1625 0x0: Jump::jalr({{ 1626 Rd = NPC; 1627 NPC = (imm + Rs1) & (~0x1); 1628 }}, IsIndirectControl, IsUncondControl, IsCall); 1629 }
|
1334
| 1630
|
1335 0x73: decode FUNCT3 { 1336 format SystemOp { 1337 0x0: decode FUNCT12 { 1338 0x0: ecall({{ 1339 fault = std::make_shared<SyscallFault>(); 1340 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall, No_OpClass); 1341 0x1: ebreak({{ 1342 fault = std::make_shared<BreakpointFault>(); 1343 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); 1344 0x100: eret({{ 1345 fault = std::make_shared<UnimplementedFault>("eret"); 1346 }}, No_OpClass);
| 1631 0x1b: JOp::jal({{ 1632 Rd = NPC; 1633 NPC = PC + imm; 1634 }}, IsDirectControl, IsUncondControl, IsCall); 1635 1636 0x1c: decode FUNCT3 { 1637 format SystemOp { 1638 0x0: decode FUNCT12 { 1639 0x0: ecall({{ 1640 fault = make_shared<SyscallFault>(); 1641 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall, 1642 No_OpClass); 1643 0x1: ebreak({{ 1644 fault = make_shared<BreakpointFault>(); 1645 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); 1646 0x100: eret({{ 1647 fault = make_shared<UnimplementedFault>("eret"); 1648 }}, No_OpClass); 1649 }
|
1347 }
| 1650 }
|
| 1651 format CSROp { 1652 0x1: csrrw({{ 1653 Rd = xc->readMiscReg(csr); 1654 xc->setMiscReg(csr, Rs1); 1655 }}, IsNonSpeculative, No_OpClass); 1656 0x2: csrrs({{ 1657 Rd = xc->readMiscReg(csr); 1658 if (Rs1 != 0) { 1659 xc->setMiscReg(csr, Rd | Rs1); 1660 } 1661 }}, IsNonSpeculative, No_OpClass); 1662 0x3: csrrc({{ 1663 Rd = xc->readMiscReg(csr); 1664 if (Rs1 != 0) { 1665 xc->setMiscReg(csr, Rd & ~Rs1); 1666 } 1667 }}, IsNonSpeculative, No_OpClass); 1668 0x5: csrrwi({{ 1669 Rd = xc->readMiscReg(csr); 1670 xc->setMiscReg(csr, uimm); 1671 }}, IsNonSpeculative, No_OpClass); 1672 0x6: csrrsi({{ 1673 Rd = xc->readMiscReg(csr); 1674 if (uimm != 0) { 1675 xc->setMiscReg(csr, Rd | uimm); 1676 } 1677 }}, IsNonSpeculative, No_OpClass); 1678 0x7: csrrci({{ 1679 Rd = xc->readMiscReg(csr); 1680 if (uimm != 0) { 1681 xc->setMiscReg(csr, Rd & ~uimm); 1682 } 1683 }}, IsNonSpeculative, No_OpClass); 1684 }
|
1348 }
| 1685 }
|
1349 format CSROp { 1350 0x1: csrrw({{ 1351 Rd = xc->readMiscReg(csr); 1352 xc->setMiscReg(csr, Rs1); 1353 }}, IsNonSpeculative, No_OpClass); 1354 0x2: csrrs({{ 1355 Rd = xc->readMiscReg(csr); 1356 if (Rs1 != 0) { 1357 xc->setMiscReg(csr, Rd | Rs1); 1358 } 1359 }}, IsNonSpeculative, No_OpClass); 1360 0x3: csrrc({{ 1361 Rd = xc->readMiscReg(csr); 1362 if (Rs1 != 0) { 1363 xc->setMiscReg(csr, Rd & ~Rs1); 1364 } 1365 }}, IsNonSpeculative, No_OpClass); 1366 0x5: csrrwi({{ 1367 Rd = xc->readMiscReg(csr); 1368 xc->setMiscReg(csr, uimm); 1369 }}, IsNonSpeculative, No_OpClass); 1370 0x6: csrrsi({{ 1371 Rd = xc->readMiscReg(csr); 1372 if (uimm != 0) { 1373 xc->setMiscReg(csr, Rd | uimm); 1374 } 1375 }}, IsNonSpeculative, No_OpClass); 1376 0x7: csrrci({{ 1377 Rd = xc->readMiscReg(csr); 1378 if (uimm != 0) { 1379 xc->setMiscReg(csr, Rd & ~uimm); 1380 } 1381 }}, IsNonSpeculative, No_OpClass); 1382 }
| |
1383 } 1384}
| 1686 } 1687}
|