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