decoder.isa (12119:e9ef3ee3171d) decoder.isa (12120:133620bfc43b)
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

--- 16 unchanged lines hidden (view full) ---

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

--- 16 unchanged lines hidden (view full) ---

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}