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