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