decoder.isa (11725:eb58f1bbeac8) decoder.isa (11726:11950d45640b)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2015 RISC-V Foundation
4// Copyright (c) 2016 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 OPCODE default Unknown::unknown() {
38 0x03: decode FUNCT3 {
39 format Load {
40 0x0: lb({{
41 Rd_sd = Mem_sb;
42 }});
43 0x1: lh({{
44 Rd_sd = Mem_sh;
45 }});
46 0x2: lw({{
47 Rd_sd = Mem_sw;
48 }});
49 0x3: ld({{
50 Rd_sd = Mem_sd;
51 }});
52 0x4: lbu({{
53 Rd = Mem_ub;
54 }});
55 0x5: lhu({{
56 Rd = Mem_uh;
57 }});
58 0x6: lwu({{
59 Rd = Mem_uw;
60 }});
61 }
62 }
63
64 0x07: decode FUNCT3 {
65 format Load {
66 0x2: flw({{
67 Fd_bits = (uint64_t)Mem_uw;
68 }});
69 0x3: fld({{
70 Fd_bits = Mem;
71 }});
72 }
73 }
74
75 0x0f: decode FUNCT3 {
76 format IOp {
77 0x0: fence({{
78 }}, IsNonSpeculative, IsMemBarrier, No_OpClass);
79 0x1: fence_i({{
80 }}, IsNonSpeculative, IsSerializeAfter, No_OpClass);
81 }
82 }
83
84 0x13: decode FUNCT3 {
85 format IOp {
86 0x0: addi({{
87 Rd_sd = Rs1_sd + imm;
88 }});
89 0x1: slli({{
90 Rd = Rs1 << SHAMT6;
91 }});
92 0x2: slti({{
93 Rd = (Rs1_sd < imm) ? 1 : 0;
94 }});
95 0x3: sltiu({{
96 Rd = (Rs1 < (uint64_t)imm) ? 1 : 0;
97 }});
98 0x4: xori({{
99 Rd = Rs1 ^ (uint64_t)imm;
100 }});
101 0x5: decode SRTYPE {
102 0x0: srli({{
103 Rd = Rs1 >> SHAMT6;
104 }});
105 0x1: srai({{
106 Rd_sd = Rs1_sd >> SHAMT6;
107 }});
108 }
109 0x6: ori({{
110 Rd = Rs1 | (uint64_t)imm;
111 }});
112 0x7: andi({{
113 Rd = Rs1 & (uint64_t)imm;
114 }});
115 }
116 }
117
118 0x17: UOp::auipc({{
119 Rd = PC + imm;
120 }});
121
122 0x1b: decode FUNCT3 {
123 format IOp {
124 0x0: addiw({{
125 Rd_sd = (int32_t)Rs1 + (int32_t)imm;
126 }});
127 0x1: slliw({{
128 Rd_sd = Rs1_sw << SHAMT5;
129 }});
130 0x5: decode SRTYPE {
131 0x0: srliw({{
132 Rd = Rs1_uw >> SHAMT5;
133 }});
134 0x1: sraiw({{
135 Rd_sd = Rs1_sw >> SHAMT5;
136 }});
137 }
138 }
139 }
140
141 0x23: decode FUNCT3 {
142 format Store {
143 0x0: sb({{
144 Mem_ub = Rs2_ub;
145 }});
146 0x1: sh({{
147 Mem_uh = Rs2_uh;
148 }});
149 0x2: sw({{
150 Mem_uw = Rs2_uw;
151 }});
152 0x3: sd({{
153 Mem_ud = Rs2_ud;
154 }});
155 }
156 }
157
158 0x27: decode FUNCT3 {
159 format Store {
160 0x2: fsw({{
161 Mem_uw = (uint32_t)Fs2_bits;
162 }});
163 0x3: fsd({{
164 Mem_ud = Fs2_bits;
165 }});
166 }
167 }
168
1// -*- mode:c++ -*-
2
3// Copyright (c) 2015 RISC-V Foundation
4// Copyright (c) 2016 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 OPCODE default Unknown::unknown() {
38 0x03: decode FUNCT3 {
39 format Load {
40 0x0: lb({{
41 Rd_sd = Mem_sb;
42 }});
43 0x1: lh({{
44 Rd_sd = Mem_sh;
45 }});
46 0x2: lw({{
47 Rd_sd = Mem_sw;
48 }});
49 0x3: ld({{
50 Rd_sd = Mem_sd;
51 }});
52 0x4: lbu({{
53 Rd = Mem_ub;
54 }});
55 0x5: lhu({{
56 Rd = Mem_uh;
57 }});
58 0x6: lwu({{
59 Rd = Mem_uw;
60 }});
61 }
62 }
63
64 0x07: decode FUNCT3 {
65 format Load {
66 0x2: flw({{
67 Fd_bits = (uint64_t)Mem_uw;
68 }});
69 0x3: fld({{
70 Fd_bits = Mem;
71 }});
72 }
73 }
74
75 0x0f: decode FUNCT3 {
76 format IOp {
77 0x0: fence({{
78 }}, IsNonSpeculative, IsMemBarrier, No_OpClass);
79 0x1: fence_i({{
80 }}, IsNonSpeculative, IsSerializeAfter, No_OpClass);
81 }
82 }
83
84 0x13: decode FUNCT3 {
85 format IOp {
86 0x0: addi({{
87 Rd_sd = Rs1_sd + imm;
88 }});
89 0x1: slli({{
90 Rd = Rs1 << SHAMT6;
91 }});
92 0x2: slti({{
93 Rd = (Rs1_sd < imm) ? 1 : 0;
94 }});
95 0x3: sltiu({{
96 Rd = (Rs1 < (uint64_t)imm) ? 1 : 0;
97 }});
98 0x4: xori({{
99 Rd = Rs1 ^ (uint64_t)imm;
100 }});
101 0x5: decode SRTYPE {
102 0x0: srli({{
103 Rd = Rs1 >> SHAMT6;
104 }});
105 0x1: srai({{
106 Rd_sd = Rs1_sd >> SHAMT6;
107 }});
108 }
109 0x6: ori({{
110 Rd = Rs1 | (uint64_t)imm;
111 }});
112 0x7: andi({{
113 Rd = Rs1 & (uint64_t)imm;
114 }});
115 }
116 }
117
118 0x17: UOp::auipc({{
119 Rd = PC + imm;
120 }});
121
122 0x1b: decode FUNCT3 {
123 format IOp {
124 0x0: addiw({{
125 Rd_sd = (int32_t)Rs1 + (int32_t)imm;
126 }});
127 0x1: slliw({{
128 Rd_sd = Rs1_sw << SHAMT5;
129 }});
130 0x5: decode SRTYPE {
131 0x0: srliw({{
132 Rd = Rs1_uw >> SHAMT5;
133 }});
134 0x1: sraiw({{
135 Rd_sd = Rs1_sw >> SHAMT5;
136 }});
137 }
138 }
139 }
140
141 0x23: decode FUNCT3 {
142 format Store {
143 0x0: sb({{
144 Mem_ub = Rs2_ub;
145 }});
146 0x1: sh({{
147 Mem_uh = Rs2_uh;
148 }});
149 0x2: sw({{
150 Mem_uw = Rs2_uw;
151 }});
152 0x3: sd({{
153 Mem_ud = Rs2_ud;
154 }});
155 }
156 }
157
158 0x27: decode FUNCT3 {
159 format Store {
160 0x2: fsw({{
161 Mem_uw = (uint32_t)Fs2_bits;
162 }});
163 0x3: fsd({{
164 Mem_ud = Fs2_bits;
165 }});
166 }
167 }
168
169 0x2f: decode FUNCT3 {
170 0x2: decode AMOFUNCT {
171 0x2: LoadReserved::lr_w({{
172 Rd_sd = Mem_sw;
173 }}, mem_flags=LLSC, aq=AQ, rl=RL);
174 0x3: StoreCond::sc_w({{
175 Mem_uw = Rs2_uw;
176 }}, {{
177 Rd = result;
178 }}, inst_flags=IsStoreConditional, mem_flags=LLSC, aq=AQ, rl=RL);
179 format AtomicMemOp {
180 0x0: amoadd_w({{Rt_sd = Mem_sw;}}, {{
181 Mem_sw = Rs2_sw + Rt_sd;
182 Rd_sd = Rt_sd;
183 }}, {{EA = Rs1;}});
184 0x1: amoswap_w({{Rt_sd = Mem_sw;}}, {{
185 Mem_sw = Rs2_uw;
186 Rd_sd = Rt_sd;
187 }}, {{EA = Rs1;}});
188 0x4: amoxor_w({{Rt_sd = Mem_sw;}}, {{
189 Mem_sw = Rs2_uw^Rt_sd;
190 Rd_sd = Rt_sd;
191 }}, {{EA = Rs1;}});
192 0x8: amoor_w({{Rt_sd = Mem_sw;}}, {{
193 Mem_sw = Rs2_uw | Rt_sd;
194 Rd_sd = Rt_sd;
195 }}, {{EA = Rs1;}});
196 0xc: amoand_w({{Rt_sd = Mem_sw;}}, {{
197 Mem_sw = Rs2_uw&Rt_sd;
198 Rd_sd = Rt_sd;
199 }}, {{EA = Rs1;}});
200 0x10: amomin_w({{Rt_sd = Mem_sw;}}, {{
201 Mem_sw = std::min<int32_t>(Rs2_sw, Rt_sd);
202 Rd_sd = Rt_sd;
203 }}, {{EA = Rs1;}});
204 0x14: amomax_w({{Rt_sd = Mem_sw;}}, {{
205 Mem_sw = std::max<int32_t>(Rs2_sw, Rt_sd);
206 Rd_sd = Rt_sd;
207 }}, {{EA = Rs1;}});
208 0x18: amominu_w({{Rt_sd = Mem_sw;}}, {{
209 Mem_sw = std::min<uint32_t>(Rs2_uw, Rt_sd);
210 Rd_sd = Rt_sd;
211 }}, {{EA = Rs1;}});
212 0x1c: amomaxu_w({{Rt_sd = Mem_sw;}}, {{
213 Mem_sw = std::max<uint32_t>(Rs2_uw, Rt_sd);
214 Rd_sd = Rt_sd;
215 }}, {{EA = Rs1;}});
216 }
217 }
218 0x3: decode AMOFUNCT {
219 0x2: LoadReserved::lr_d({{
220 Rd_sd = Mem_sd;
221 }}, aq=AQ, rl=RL);
222 0x3: StoreCond::sc_d({{
223 Mem = Rs2;
224 }}, {{
225 Rd = result;
226 }}, aq=AQ, rl=RL);
227 format AtomicMemOp {
228 0x0: amoadd_d({{Rt_sd = Mem_sd;}}, {{
229 Mem_sd = Rs2_sd + Rt_sd;
230 Rd_sd = Rt_sd;
231 }}, {{EA = Rs1;}});
232 0x1: amoswap_d({{Rt = Mem;}}, {{
233 Mem = Rs2;
234 Rd = Rt;
235 }}, {{EA = Rs1;}});
236 0x4: amoxor_d({{Rt = Mem;}}, {{
237 Mem = Rs2^Rt;
238 Rd = Rt;
239 }}, {{EA = Rs1;}});
240 0x8: amoor_d({{Rt = Mem;}}, {{
241 Mem = Rs2 | Rt;
242 Rd = Rt;
243 }}, {{EA = Rs1;}});
244 0xc: amoand_d({{Rt = Mem;}}, {{
245 Mem = Rs2&Rt;
246 Rd = Rt;
247 }}, {{EA = Rs1;}});
248 0x10: amomin_d({{Rt_sd = Mem_sd;}}, {{
249 Mem_sd = std::min(Rs2_sd, Rt_sd);
250 Rd_sd = Rt_sd;
251 }}, {{EA = Rs1;}});
252 0x14: amomax_d({{Rt_sd = Mem_sd;}}, {{
253 Mem_sd = std::max(Rs2_sd, Rt_sd);
254 Rd_sd = Rt_sd;
255 }}, {{EA = Rs1;}});
256 0x18: amominu_d({{Rt = Mem;}}, {{
257 Mem = std::min(Rs2, Rt);
258 Rd = Rt;
259 }}, {{EA = Rs1;}});
260 0x1c: amomaxu_d({{Rt = Mem;}}, {{
261 Mem = std::max(Rs2, Rt);
262 Rd = Rt;
263 }}, {{EA = Rs1;}});
264 }
265 }
266 }
169 0x33: decode FUNCT3 {
170 format ROp {
171 0x0: decode FUNCT7 {
172 0x0: add({{
173 Rd = Rs1_sd + Rs2_sd;
174 }});
175 0x1: mul({{
176 Rd = Rs1_sd*Rs2_sd;
177 }}, IntMultOp);
178 0x20: sub({{
179 Rd = Rs1_sd - Rs2_sd;
180 }});
181 }
182 0x1: decode FUNCT7 {
183 0x0: sll({{
184 Rd = Rs1 << Rs2<5:0>;
185 }});
186 0x1: mulh({{
187 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
188
189 uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd);
190 uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32;
191 uint64_t Rs2_lo = (uint32_t)std::abs(Rs2_sd);
192 uint64_t Rs2_hi = (uint64_t)std::abs(Rs2_sd) >> 32;
193
194 uint64_t hi = Rs1_hi*Rs2_hi;
195 uint64_t mid1 = Rs1_hi*Rs2_lo;
196 uint64_t mid2 = Rs1_lo*Rs2_hi;
197 uint64_t lo = Rs2_lo*Rs1_lo;
198 uint64_t carry = ((uint64_t)(uint32_t)mid1
199 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
200
201 uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
202 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0) : res;
203 }}, IntMultOp);
204 }
205 0x2: decode FUNCT7 {
206 0x0: slt({{
207 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
208 }});
209 0x1: mulhsu({{
210 bool negate = Rs1_sd < 0;
211 uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd);
212 uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32;
213 uint64_t Rs2_lo = (uint32_t)Rs2;
214 uint64_t Rs2_hi = Rs2 >> 32;
215
216 uint64_t hi = Rs1_hi*Rs2_hi;
217 uint64_t mid1 = Rs1_hi*Rs2_lo;
218 uint64_t mid2 = Rs1_lo*Rs2_hi;
219 uint64_t lo = Rs1_lo*Rs2_lo;
220 uint64_t carry = ((uint64_t)(uint32_t)mid1
221 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
222
223 uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
224 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
225 }}, IntMultOp);
226 }
227 0x3: decode FUNCT7 {
228 0x0: sltu({{
229 Rd = (Rs1 < Rs2) ? 1 : 0;
230 }});
231 0x1: mulhu({{
232 uint64_t Rs1_lo = (uint32_t)Rs1;
233 uint64_t Rs1_hi = Rs1 >> 32;
234 uint64_t Rs2_lo = (uint32_t)Rs2;
235 uint64_t Rs2_hi = Rs2 >> 32;
236
237 uint64_t hi = Rs1_hi*Rs2_hi;
238 uint64_t mid1 = Rs1_hi*Rs2_lo;
239 uint64_t mid2 = Rs1_lo*Rs2_hi;
240 uint64_t lo = Rs1_lo*Rs2_lo;
241 uint64_t carry = ((uint64_t)(uint32_t)mid1
242 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
243
244 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
245 }}, IntMultOp);
246 }
247 0x4: decode FUNCT7 {
248 0x0: xor({{
249 Rd = Rs1 ^ Rs2;
250 }});
251 0x1: div({{
252 if (Rs2_sd == 0) {
253 Rd_sd = -1;
254 } else if (Rs1_sd == std::numeric_limits<int64_t>::min()
255 && Rs2_sd == -1) {
256 Rd_sd = std::numeric_limits<int64_t>::min();
257 } else {
258 Rd_sd = Rs1_sd/Rs2_sd;
259 }
260 }}, IntDivOp);
261 }
262 0x5: decode FUNCT7 {
263 0x0: srl({{
264 Rd = Rs1 >> Rs2<5:0>;
265 }});
266 0x1: divu({{
267 if (Rs2 == 0) {
268 Rd = std::numeric_limits<uint64_t>::max();
269 } else {
270 Rd = Rs1/Rs2;
271 }
272 }}, IntDivOp);
273 0x20: sra({{
274 Rd_sd = Rs1_sd >> Rs2<5:0>;
275 }});
276 }
277 0x6: decode FUNCT7 {
278 0x0: or({{
279 Rd = Rs1 | Rs2;
280 }});
281 0x1: rem({{
282 if (Rs2_sd == 0) {
283 Rd = Rs1_sd;
284 } else if (Rs1_sd == std::numeric_limits<int64_t>::min()
285 && Rs2_sd == -1) {
286 Rd = 0;
287 } else {
288 Rd = Rs1_sd%Rs2_sd;
289 }
290 }}, IntDivOp);
291 }
292 0x7: decode FUNCT7 {
293 0x0: and({{
294 Rd = Rs1 & Rs2;
295 }});
296 0x1: remu({{
297 if (Rs2 == 0) {
298 Rd = Rs1;
299 } else {
300 Rd = Rs1%Rs2;
301 }
302 }}, IntDivOp);
303 }
304 }
305 }
306
307 0x37: UOp::lui({{
308 Rd = (uint64_t)imm;
309 }});
310
311 0x3b: decode FUNCT3 {
312 format ROp {
313 0x0: decode FUNCT7 {
314 0x0: addw({{
315 Rd_sd = Rs1_sw + Rs2_sw;
316 }});
317 0x1: mulw({{
318 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
319 }}, IntMultOp);
320 0x20: subw({{
321 Rd_sd = Rs1_sw - Rs2_sw;
322 }});
323 }
324 0x1: sllw({{
325 Rd_sd = Rs1_sw << Rs2<4:0>;
326 }});
327 0x4: divw({{
328 if (Rs2_sw == 0) {
329 Rd_sd = -1;
330 } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
331 && Rs2_sw == -1) {
332 Rd_sd = std::numeric_limits<int32_t>::min();
333 } else {
334 Rd_sd = Rs1_sw/Rs2_sw;
335 }
336 }}, IntDivOp);
337 0x5: decode FUNCT7 {
338 0x0: srlw({{
339 Rd_uw = Rs1_uw >> Rs2<4:0>;
340 }});
341 0x1: divuw({{
342 if (Rs2_uw == 0) {
343 Rd_sd = std::numeric_limits<IntReg>::max();
344 } else {
345 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
346 }
347 }}, IntDivOp);
348 0x20: sraw({{
349 Rd_sd = Rs1_sw >> Rs2<4:0>;
350 }});
351 }
352 0x6: remw({{
353 if (Rs2_sw == 0) {
354 Rd_sd = Rs1_sw;
355 } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
356 && Rs2_sw == -1) {
357 Rd_sd = 0;
358 } else {
359 Rd_sd = Rs1_sw%Rs2_sw;
360 }
361 }}, IntDivOp);
362 0x7: remuw({{
363 if (Rs2_uw == 0) {
364 Rd_sd = (int32_t)Rs1_uw;
365 } else {
366 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
367 }
368 }}, IntDivOp);
369 }
370 }
371
372 format FPR4Op {
373 0x43: decode FUNCT2 {
374 0x0: fmadd_s({{
375 uint32_t temp;
376 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
377 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
378 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
379 float fd;
380
381 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
382 if (issignalingnan(fs1) || issignalingnan(fs2)
383 || issignalingnan(fs3)) {
384 FFLAGS |= FloatInvalid;
385 }
386 fd = std::numeric_limits<float>::quiet_NaN();
387 } else if (std::isinf(fs1) || std::isinf(fs2) ||
388 std::isinf(fs3)) {
389 if (std::signbit(fs1) == std::signbit(fs2)
390 && !std::isinf(fs3)) {
391 fd = std::numeric_limits<float>::infinity();
392 } else if (std::signbit(fs1) != std::signbit(fs2)
393 && !std::isinf(fs3)) {
394 fd = -std::numeric_limits<float>::infinity();
395 } else { // Fs3_sf is infinity
396 fd = fs3;
397 }
398 } else {
399 fd = fs1*fs2 + fs3;
400 }
401 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
402 }}, FloatMultOp);
403 0x1: fmadd_d({{
404 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
405 if (issignalingnan(Fs1) || issignalingnan(Fs2)
406 || issignalingnan(Fs3)) {
407 FFLAGS |= FloatInvalid;
408 }
409 Fd = std::numeric_limits<double>::quiet_NaN();
410 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
411 std::isinf(Fs3)) {
412 if (std::signbit(Fs1) == std::signbit(Fs2)
413 && !std::isinf(Fs3)) {
414 Fd = std::numeric_limits<double>::infinity();
415 } else if (std::signbit(Fs1) != std::signbit(Fs2)
416 && !std::isinf(Fs3)) {
417 Fd = -std::numeric_limits<double>::infinity();
418 } else {
419 Fd = Fs3;
420 }
421 } else {
422 Fd = Fs1*Fs2 + Fs3;
423 }
424 }}, FloatMultOp);
425 }
426 0x47: decode FUNCT2 {
427 0x0: fmsub_s({{
428 uint32_t temp;
429 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
430 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
431 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
432 float fd;
433
434 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
435 if (issignalingnan(fs1) || issignalingnan(fs2)
436 || issignalingnan(fs3)) {
437 FFLAGS |= FloatInvalid;
438 }
439 fd = std::numeric_limits<float>::quiet_NaN();
440 } else if (std::isinf(fs1) || std::isinf(fs2) ||
441 std::isinf(fs3)) {
442 if (std::signbit(fs1) == std::signbit(fs2)
443 && !std::isinf(fs3)) {
444 fd = std::numeric_limits<float>::infinity();
445 } else if (std::signbit(fs1) != std::signbit(fs2)
446 && !std::isinf(fs3)) {
447 fd = -std::numeric_limits<float>::infinity();
448 } else { // Fs3_sf is infinity
449 fd = -fs3;
450 }
451 } else {
452 fd = fs1*fs2 - fs3;
453 }
454 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
455 }}, FloatMultOp);
456 0x1: fmsub_d({{
457 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
458 if (issignalingnan(Fs1) || issignalingnan(Fs2)
459 || issignalingnan(Fs3)) {
460 FFLAGS |= FloatInvalid;
461 }
462 Fd = std::numeric_limits<double>::quiet_NaN();
463 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
464 std::isinf(Fs3)) {
465 if (std::signbit(Fs1) == std::signbit(Fs2)
466 && !std::isinf(Fs3)) {
467 Fd = std::numeric_limits<double>::infinity();
468 } else if (std::signbit(Fs1) != std::signbit(Fs2)
469 && !std::isinf(Fs3)) {
470 Fd = -std::numeric_limits<double>::infinity();
471 } else {
472 Fd = -Fs3;
473 }
474 } else {
475 Fd = Fs1*Fs2 - Fs3;
476 }
477 }}, FloatMultOp);
478 }
479 0x4b: decode FUNCT2 {
480 0x0: fnmsub_s({{
481 uint32_t temp;
482 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
483 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
484 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
485 float fd;
486
487 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
488 if (issignalingnan(fs1) || issignalingnan(fs2)
489 || issignalingnan(fs3)) {
490 FFLAGS |= FloatInvalid;
491 }
492 fd = std::numeric_limits<float>::quiet_NaN();
493 } else if (std::isinf(fs1) || std::isinf(fs2) ||
494 std::isinf(fs3)) {
495 if (std::signbit(fs1) == std::signbit(fs2)
496 && !std::isinf(fs3)) {
497 fd = -std::numeric_limits<float>::infinity();
498 } else if (std::signbit(fs1) != std::signbit(fs2)
499 && !std::isinf(fs3)) {
500 fd = std::numeric_limits<float>::infinity();
501 } else { // Fs3_sf is infinity
502 fd = fs3;
503 }
504 } else {
505 fd = -(fs1*fs2 - fs3);
506 }
507 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
508 }}, FloatMultOp);
509 0x1: fnmsub_d({{
510 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
511 if (issignalingnan(Fs1) || issignalingnan(Fs2)
512 || issignalingnan(Fs3)) {
513 FFLAGS |= FloatInvalid;
514 }
515 Fd = std::numeric_limits<double>::quiet_NaN();
516 } else if (std::isinf(Fs1) || std::isinf(Fs2)
517 || std::isinf(Fs3)) {
518 if (std::signbit(Fs1) == std::signbit(Fs2)
519 && !std::isinf(Fs3)) {
520 Fd = -std::numeric_limits<double>::infinity();
521 } else if (std::signbit(Fs1) != std::signbit(Fs2)
522 && !std::isinf(Fs3)) {
523 Fd = std::numeric_limits<double>::infinity();
524 } else {
525 Fd = Fs3;
526 }
527 } else {
528 Fd = -(Fs1*Fs2 - Fs3);
529 }
530 }}, FloatMultOp);
531 }
532 0x4f: decode FUNCT2 {
533 0x0: fnmadd_s({{
534 uint32_t temp;
535 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
536 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
537 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
538 float fd;
539
540 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
541 if (issignalingnan(fs1) || issignalingnan(fs2)
542 || issignalingnan(fs3)) {
543 FFLAGS |= FloatInvalid;
544 }
545 fd = std::numeric_limits<float>::quiet_NaN();
546 } else if (std::isinf(fs1) || std::isinf(fs2) ||
547 std::isinf(fs3)) {
548 if (std::signbit(fs1) == std::signbit(fs2)
549 && !std::isinf(fs3)) {
550 fd = -std::numeric_limits<float>::infinity();
551 } else if (std::signbit(fs1) != std::signbit(fs2)
552 && !std::isinf(fs3)) {
553 fd = std::numeric_limits<float>::infinity();
554 } else { // Fs3_sf is infinity
555 fd = -fs3;
556 }
557 } else {
558 fd = -(fs1*fs2 + fs3);
559 }
560 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
561 }}, FloatMultOp);
562 0x1: fnmadd_d({{
563 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
564 if (issignalingnan(Fs1) || issignalingnan(Fs2)
565 || issignalingnan(Fs3)) {
566 FFLAGS |= FloatInvalid;
567 }
568 Fd = std::numeric_limits<double>::quiet_NaN();
569 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
570 std::isinf(Fs3)) {
571 if (std::signbit(Fs1) == std::signbit(Fs2)
572 && !std::isinf(Fs3)) {
573 Fd = -std::numeric_limits<double>::infinity();
574 } else if (std::signbit(Fs1) != std::signbit(Fs2)
575 && !std::isinf(Fs3)) {
576 Fd = std::numeric_limits<double>::infinity();
577 } else {
578 Fd = -Fs3;
579 }
580 } else {
581 Fd = -(Fs1*Fs2 + Fs3);
582 }
583 }}, FloatMultOp);
584 }
585 }
586
587 0x53: decode FUNCT7 {
588 format FPROp {
589 0x0: fadd_s({{
590 uint32_t temp;
591 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
592 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
593 float fd;
594
595 if (std::isnan(fs1) || std::isnan(fs2)) {
596 if (issignalingnan(fs1) || issignalingnan(fs2)) {
597 FFLAGS |= FloatInvalid;
598 }
599 fd = std::numeric_limits<float>::quiet_NaN();
600 } else {
601 fd = fs1 + fs2;
602 }
603 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
604 }}, FloatAddOp);
605 0x1: fadd_d({{
606 if (std::isnan(Fs1) || std::isnan(Fs2)) {
607 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
608 FFLAGS |= FloatInvalid;
609 }
610 Fd = std::numeric_limits<double>::quiet_NaN();
611 } else {
612 Fd = Fs1 + Fs2;
613 }
614 }}, FloatAddOp);
615 0x4: fsub_s({{
616 uint32_t temp;
617 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
618 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
619 float fd;
620
621 if (std::isnan(fs1) || std::isnan(fs2)) {
622 if (issignalingnan(fs1) || issignalingnan(fs2)) {
623 FFLAGS |= FloatInvalid;
624 }
625 fd = std::numeric_limits<float>::quiet_NaN();
626 } else {
627 fd = fs1 - fs2;
628 }
629 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
630 }}, FloatAddOp);
631 0x5: fsub_d({{
632 if (std::isnan(Fs1) || std::isnan(Fs2)) {
633 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
634 FFLAGS |= FloatInvalid;
635 }
636 Fd = std::numeric_limits<double>::quiet_NaN();
637 } else {
638 Fd = Fs1 - Fs2;
639 }
640 }}, FloatAddOp);
641 0x8: fmul_s({{
642 uint32_t temp;
643 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
644 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
645 float fd;
646
647 if (std::isnan(fs1) || std::isnan(fs2)) {
648 if (issignalingnan(fs1) || issignalingnan(fs2)) {
649 FFLAGS |= FloatInvalid;
650 }
651 fd = std::numeric_limits<float>::quiet_NaN();
652 } else {
653 fd = fs1*fs2;
654 }
655 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
656 }}, FloatMultOp);
657 0x9: fmul_d({{
658 if (std::isnan(Fs1) || std::isnan(Fs2)) {
659 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
660 FFLAGS |= FloatInvalid;
661 }
662 Fd = std::numeric_limits<double>::quiet_NaN();
663 } else {
664 Fd = Fs1*Fs2;
665 }
666 }}, FloatMultOp);
667 0xc: fdiv_s({{
668 uint32_t temp;
669 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
670 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
671 float fd;
672
673 if (std::isnan(fs1) || std::isnan(fs2)) {
674 if (issignalingnan(fs1) || issignalingnan(fs2)) {
675 FFLAGS |= FloatInvalid;
676 }
677 fd = std::numeric_limits<float>::quiet_NaN();
678 } else {
679 fd = fs1/fs2;
680 }
681 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
682 }}, FloatDivOp);
683 0xd: fdiv_d({{
684 if (std::isnan(Fs1) || std::isnan(Fs2)) {
685 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
686 FFLAGS |= FloatInvalid;
687 }
688 Fd = std::numeric_limits<double>::quiet_NaN();
689 } else {
690 Fd = Fs1/Fs2;
691 }
692 }}, FloatDivOp);
693 0x10: decode ROUND_MODE {
694 0x0: fsgnj_s({{
695 uint32_t temp;
696 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
697 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
698 float fd;
699
700 if (issignalingnan(fs1)) {
701 fd = std::numeric_limits<float>::signaling_NaN();
702 std::feclearexcept(FE_INVALID);
703 } else {
704 fd = std::copysign(fs1, fs2);
705 }
706 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
707 }});
708 0x1: fsgnjn_s({{
709 uint32_t temp;
710 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
711 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
712 float fd;
713
714 if (issignalingnan(fs1)) {
715 fd = std::numeric_limits<float>::signaling_NaN();
716 std::feclearexcept(FE_INVALID);
717 } else {
718 fd = std::copysign(fs1, -fs2);
719 }
720 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
721 }});
722 0x2: fsgnjx_s({{
723 uint32_t temp;
724 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
725 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
726 float fd;
727
728 if (issignalingnan(fs1)) {
729 fd = std::numeric_limits<float>::signaling_NaN();
730 std::feclearexcept(FE_INVALID);
731 } else {
732 fd = fs1*(std::signbit(fs2) ? -1.0 : 1.0);
733 }
734 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
735 }});
736 }
737 0x11: decode ROUND_MODE {
738 0x0: fsgnj_d({{
739 if (issignalingnan(Fs1)) {
740 Fd = std::numeric_limits<double>::signaling_NaN();
741 std::feclearexcept(FE_INVALID);
742 } else {
743 Fd = std::copysign(Fs1, Fs2);
744 }
745 }});
746 0x1: fsgnjn_d({{
747 if (issignalingnan(Fs1)) {
748 Fd = std::numeric_limits<double>::signaling_NaN();
749 std::feclearexcept(FE_INVALID);
750 } else {
751 Fd = std::copysign(Fs1, -Fs2);
752 }
753 }});
754 0x2: fsgnjx_d({{
755 if (issignalingnan(Fs1)) {
756 Fd = std::numeric_limits<double>::signaling_NaN();
757 std::feclearexcept(FE_INVALID);
758 } else {
759 Fd = Fs1*(std::signbit(Fs2) ? -1.0 : 1.0);
760 }
761 }});
762 }
763 0x14: decode ROUND_MODE {
764 0x0: fmin_s({{
765 uint32_t temp;
766 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
767 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
768 float fd;
769
770 if (issignalingnan(fs2)) {
771 fd = fs1;
772 FFLAGS |= FloatInvalid;
773 } else if (issignalingnan(fs1)) {
774 fd = fs2;
775 FFLAGS |= FloatInvalid;
776 } else {
777 fd = std::fmin(fs1, fs2);
778 }
779 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
780 }}, FloatCmpOp);
781 0x1: fmax_s({{
782 uint32_t temp;
783 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
784 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
785 float fd;
786
787 if (issignalingnan(fs2)) {
788 fd = fs1;
789 FFLAGS |= FloatInvalid;
790 } else if (issignalingnan(fs1)) {
791 fd = fs2;
792 FFLAGS |= FloatInvalid;
793 } else {
794 fd = std::fmax(fs1, fs2);
795 }
796 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
797 }}, FloatCmpOp);
798 }
799 0x15: decode ROUND_MODE {
800 0x0: fmin_d({{
801 if (issignalingnan(Fs2)) {
802 Fd = Fs1;
803 FFLAGS |= FloatInvalid;
804 } else if (issignalingnan(Fs1)) {
805 Fd = Fs2;
806 FFLAGS |= FloatInvalid;
807 } else {
808 Fd = std::fmin(Fs1, Fs2);
809 }
810 }}, FloatCmpOp);
811 0x1: fmax_d({{
812 if (issignalingnan(Fs2)) {
813 Fd = Fs1;
814 FFLAGS |= FloatInvalid;
815 } else if (issignalingnan(Fs1)) {
816 Fd = Fs2;
817 FFLAGS |= FloatInvalid;
818 } else {
819 Fd = std::fmax(Fs1, Fs2);
820 }
821 }}, FloatCmpOp);
822 }
823 0x20: fcvt_s_d({{
824 assert(CONV_SGN == 1);
825 float fd;
826 if (issignalingnan(Fs1)) {
827 fd = std::numeric_limits<float>::quiet_NaN();
828 FFLAGS |= FloatInvalid;
829 } else {
830 fd = (float)Fs1;
831 }
832 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
833 }}, FloatCvtOp);
834 0x21: fcvt_d_s({{
835 assert(CONV_SGN == 0);
836 uint32_t temp;
837 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
838
839 if (issignalingnan(fs1)) {
840 Fd = std::numeric_limits<double>::quiet_NaN();
841 FFLAGS |= FloatInvalid;
842 } else {
843 Fd = (double)fs1;
844 }
845 }}, FloatCvtOp);
846 0x2c: fsqrt_s({{
847 assert(RS2 == 0);
848 uint32_t temp;
849 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
850 float fd;
851
852 if (issignalingnan(Fs1_sf)) {
853 FFLAGS |= FloatInvalid;
854 }
855 fd = std::sqrt(fs1);
856 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
857 }}, FloatSqrtOp);
858 0x2d: fsqrt_d({{
859 assert(RS2 == 0);
860 Fd = std::sqrt(Fs1);
861 }}, FloatSqrtOp);
862 0x50: decode ROUND_MODE {
863 0x0: fle_s({{
864 uint32_t temp;
865 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
866 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
867
868 if (std::isnan(fs1) || std::isnan(fs2)) {
869 FFLAGS |= FloatInvalid;
870 Rd = 0;
871 } else {
872 Rd = fs1 <= fs2 ? 1 : 0;
873 }
874 }}, FloatCmpOp);
875 0x1: flt_s({{
876 uint32_t temp;
877 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
878 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
879
880 if (std::isnan(fs1) || std::isnan(fs2)) {
881 FFLAGS |= FloatInvalid;
882 Rd = 0;
883 } else {
884 Rd = fs1 < fs2 ? 1 : 0;
885 }
886 }}, FloatCmpOp);
887 0x2: feq_s({{
888 uint32_t temp;
889 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
890 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
891
892 if (issignalingnan(fs1) || issignalingnan(fs2)) {
893 FFLAGS |= FloatInvalid;
894 }
895 Rd = fs1 == fs2 ? 1 : 0;
896 }}, FloatCmpOp);
897 }
898 0x51: decode ROUND_MODE {
899 0x0: fle_d({{
900 if (std::isnan(Fs1) || std::isnan(Fs2)) {
901 FFLAGS |= FloatInvalid;
902 Rd = 0;
903 } else {
904 Rd = Fs1 <= Fs2 ? 1 : 0;
905 }
906 }}, FloatCmpOp);
907 0x1: flt_d({{
908 if (std::isnan(Fs1) || std::isnan(Fs2)) {
909 FFLAGS |= FloatInvalid;
910 Rd = 0;
911 } else {
912 Rd = Fs1 < Fs2 ? 1 : 0;
913 }
914 }}, FloatCmpOp);
915 0x2: feq_d({{
916 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
917 FFLAGS |= FloatInvalid;
918 }
919 Rd = Fs1 == Fs2 ? 1 : 0;
920 }}, FloatCmpOp);
921 }
922 0x60: decode CONV_SGN {
923 0x0: fcvt_w_s({{
924 uint32_t temp;
925 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
926
927 if (std::isnan(fs1)) {
928 Rd_sd = std::numeric_limits<int32_t>::max();
929 FFLAGS |= FloatInvalid;
930 } else {
931 Rd_sd = (int32_t)fs1;
932 if (std::fetestexcept(FE_INVALID)) {
933 if (std::signbit(fs1)) {
934 Rd_sd = std::numeric_limits<int32_t>::min();
935 } else {
936 Rd_sd = std::numeric_limits<int32_t>::max();
937 }
938 std::feclearexcept(FE_INEXACT);
939 }
940 }
941 }}, FloatCvtOp);
942 0x1: fcvt_wu_s({{
943 uint32_t temp;
944 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
945
946 if (fs1 < 0.0) {
947 Rd = 0;
948 FFLAGS |= FloatInvalid;
949 } else {
950 Rd = (uint32_t)fs1;
951 if (std::fetestexcept(FE_INVALID)) {
952 Rd = std::numeric_limits<uint64_t>::max();
953 std::feclearexcept(FE_INEXACT);
954 }
955 }
956 }}, FloatCvtOp);
957 0x2: fcvt_l_s({{
958 uint32_t temp;
959 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
960
961 if (std::isnan(fs1)) {
962 Rd_sd = std::numeric_limits<int64_t>::max();
963 FFLAGS |= FloatInvalid;
964 } else {
965 Rd_sd = (int64_t)fs1;
966 if (std::fetestexcept(FE_INVALID)) {
967 if (std::signbit(fs1)) {
968 Rd_sd = std::numeric_limits<int64_t>::min();
969 } else {
970 Rd_sd = std::numeric_limits<int64_t>::max();
971 }
972 std::feclearexcept(FE_INEXACT);
973 }
974 }
975 }}, FloatCvtOp);
976 0x3: fcvt_lu_s({{
977 uint32_t temp;
978 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
979
980 if (fs1 < 0.0) {
981 Rd = 0;
982 FFLAGS |= FloatInvalid;
983 } else {
984 Rd = (uint64_t)fs1;
985 if (std::fetestexcept(FE_INVALID)) {
986 Rd = std::numeric_limits<uint64_t>::max();
987 std::feclearexcept(FE_INEXACT);
988 }
989 }
990 }}, FloatCvtOp);
991 }
992 0x61: decode CONV_SGN {
993 0x0: fcvt_w_d({{
994 Rd_sd = (int32_t)Fs1;
995 if (std::fetestexcept(FE_INVALID)) {
996 if (Fs1 < 0.0) {
997 Rd_sd = std::numeric_limits<int32_t>::min();
998 } else {
999 Rd_sd = std::numeric_limits<int32_t>::max();
1000 }
1001 std::feclearexcept(FE_INEXACT);
1002 }
1003 }}, FloatCvtOp);
1004 0x1: fcvt_wu_d({{
1005 if (Fs1 < 0.0) {
1006 Rd = 0;
1007 FFLAGS |= FloatInvalid;
1008 } else {
1009 Rd = (uint32_t)Fs1;
1010 if (std::fetestexcept(FE_INVALID)) {
1011 Rd = std::numeric_limits<uint64_t>::max();
1012 std::feclearexcept(FE_INEXACT);
1013 }
1014 }
1015 }}, FloatCvtOp);
1016 0x2: fcvt_l_d({{
1017 Rd_sd = Fs1;
1018 if (std::fetestexcept(FE_INVALID)) {
1019 if (Fs1 < 0.0) {
1020 Rd_sd = std::numeric_limits<int64_t>::min();
1021 } else {
1022 Rd_sd = std::numeric_limits<int64_t>::max();
1023 }
1024 std::feclearexcept(FE_INEXACT);
1025 }
1026 }}, FloatCvtOp);
1027 0x3: fcvt_lu_d({{
1028 if (Fs1 < 0.0) {
1029 Rd = 0;
1030 FFLAGS |= FloatInvalid;
1031 } else {
1032 Rd = (uint64_t)Fs1;
1033 if (std::fetestexcept(FE_INVALID)) {
1034 Rd = std::numeric_limits<uint64_t>::max();
1035 std::feclearexcept(FE_INEXACT);
1036 }
1037 }
1038 }}, FloatCvtOp);
1039 }
1040 0x68: decode CONV_SGN {
1041 0x0: fcvt_s_w({{
1042 float temp = (float)Rs1_sw;
1043 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1044 }}, FloatCvtOp);
1045 0x1: fcvt_s_wu({{
1046 float temp = (float)Rs1_uw;
1047 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1048 }}, FloatCvtOp);
1049 0x2: fcvt_s_l({{
1050 float temp = (float)Rs1_sd;
1051 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1052 }}, FloatCvtOp);
1053 0x3: fcvt_s_lu({{
1054 float temp = (float)Rs1;
1055 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1056 }}, FloatCvtOp);
1057 }
1058 0x69: decode CONV_SGN {
1059 0x0: fcvt_d_w({{
1060 Fd = (double)Rs1_sw;
1061 }}, FloatCvtOp);
1062 0x1: fcvt_d_wu({{
1063 Fd = (double)Rs1_uw;
1064 }}, FloatCvtOp);
1065 0x2: fcvt_d_l({{
1066 Fd = (double)Rs1_sd;
1067 }}, FloatCvtOp);
1068 0x3: fcvt_d_lu({{
1069 Fd = (double)Rs1;
1070 }}, FloatCvtOp);
1071 }
1072 0x70: decode ROUND_MODE {
1073 0x0: fmv_x_s({{
1074 Rd = (uint32_t)Fs1_bits;
1075 if ((Rd&0x80000000) != 0) {
1076 Rd |= (0xFFFFFFFFULL << 32);
1077 }
1078 }}, FloatCvtOp);
1079 0x1: fclass_s({{
1080 uint32_t temp;
1081 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1082 switch (std::fpclassify(fs1)) {
1083 case FP_INFINITE:
1084 if (std::signbit(fs1)) {
1085 Rd = 1 << 0;
1086 } else {
1087 Rd = 1 << 7;
1088 }
1089 break;
1090 case FP_NAN:
1091 if (issignalingnan(fs1)) {
1092 Rd = 1 << 8;
1093 } else {
1094 Rd = 1 << 9;
1095 }
1096 break;
1097 case FP_ZERO:
1098 if (std::signbit(fs1)) {
1099 Rd = 1 << 3;
1100 } else {
1101 Rd = 1 << 4;
1102 }
1103 break;
1104 case FP_SUBNORMAL:
1105 if (std::signbit(fs1)) {
1106 Rd = 1 << 2;
1107 } else {
1108 Rd = 1 << 5;
1109 }
1110 break;
1111 case FP_NORMAL:
1112 if (std::signbit(fs1)) {
1113 Rd = 1 << 1;
1114 } else {
1115 Rd = 1 << 6;
1116 }
1117 break;
1118 default:
1119 panic("Unknown classification for operand.");
1120 break;
1121 }
1122 }});
1123 }
1124 0x71: decode ROUND_MODE {
1125 0x0: fmv_x_d({{
1126 Rd = Fs1_bits;
1127 }}, FloatCvtOp);
1128 0x1: fclass_d({{
1129 switch (std::fpclassify(Fs1)) {
1130 case FP_INFINITE:
1131 if (std::signbit(Fs1)) {
1132 Rd = 1 << 0;
1133 } else {
1134 Rd = 1 << 7;
1135 }
1136 break;
1137 case FP_NAN:
1138 if (issignalingnan(Fs1)) {
1139 Rd = 1 << 8;
1140 } else {
1141 Rd = 1 << 9;
1142 }
1143 break;
1144 case FP_ZERO:
1145 if (std::signbit(Fs1)) {
1146 Rd = 1 << 3;
1147 } else {
1148 Rd = 1 << 4;
1149 }
1150 break;
1151 case FP_SUBNORMAL:
1152 if (std::signbit(Fs1)) {
1153 Rd = 1 << 2;
1154 } else {
1155 Rd = 1 << 5;
1156 }
1157 break;
1158 case FP_NORMAL:
1159 if (std::signbit(Fs1)) {
1160 Rd = 1 << 1;
1161 } else {
1162 Rd = 1 << 6;
1163 }
1164 break;
1165 default:
1166 panic("Unknown classification for operand.");
1167 break;
1168 }
1169 }});
1170 }
1171 0x78: fmv_s_x({{
1172 Fd_bits = (uint64_t)Rs1_uw;
1173 }}, FloatCvtOp);
1174 0x79: fmv_d_x({{
1175 Fd_bits = Rs1;
1176 }}, FloatCvtOp);
1177 }
1178 }
1179 0x63: decode FUNCT3 {
1180 format SBOp {
1181 0x0: beq({{
1182 if (Rs1 == Rs2) {
1183 NPC = PC + imm;
1184 } else {
1185 NPC = NPC;
1186 }
1187 }}, IsDirectControl, IsCondControl);
1188 0x1: bne({{
1189 if (Rs1 != Rs2) {
1190 NPC = PC + imm;
1191 } else {
1192 NPC = NPC;
1193 }
1194 }}, IsDirectControl, IsCondControl);
1195 0x4: blt({{
1196 if (Rs1_sd < Rs2_sd) {
1197 NPC = PC + imm;
1198 } else {
1199 NPC = NPC;
1200 }
1201 }}, IsDirectControl, IsCondControl);
1202 0x5: bge({{
1203 if (Rs1_sd >= Rs2_sd) {
1204 NPC = PC + imm;
1205 } else {
1206 NPC = NPC;
1207 }
1208 }}, IsDirectControl, IsCondControl);
1209 0x6: bltu({{
1210 if (Rs1 < Rs2) {
1211 NPC = PC + imm;
1212 } else {
1213 NPC = NPC;
1214 }
1215 }}, IsDirectControl, IsCondControl);
1216 0x7: bgeu({{
1217 if (Rs1 >= Rs2) {
1218 NPC = PC + imm;
1219 } else {
1220 NPC = NPC;
1221 }
1222 }}, IsDirectControl, IsCondControl);
1223 }
1224 }
1225
1226 0x67: decode FUNCT3 {
1227 0x0: Jump::jalr({{
1228 Rd = NPC;
1229 NPC = (imm + Rs1) & (~0x1);
1230 }}, IsIndirectControl, IsUncondControl, IsCall);
1231 }
1232
1233 0x6f: UJOp::jal({{
1234 Rd = NPC;
1235 NPC = PC + imm;
1236 }}, IsDirectControl, IsUncondControl, IsCall);
1237
1238 0x73: decode FUNCT3 {
1239 format IOp {
1240 0x0: decode FUNCT12 {
1241 0x0: ecall({{
1242 fault = std::make_shared<SyscallFault>();
1243 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall, No_OpClass);
1244 0x1: ebreak({{
1245 fault = std::make_shared<BreakpointFault>();
1246 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1247 0x100: eret({{
1248 fault = std::make_shared<UnimplementedFault>("eret");
1249 }}, No_OpClass);
1250 }
1251 0x1: csrrw({{
1252 Rd = xc->readMiscReg(FUNCT12);
1253 xc->setMiscReg(FUNCT12, Rs1);
1254 }}, IsNonSpeculative, No_OpClass);
1255 0x2: csrrs({{
1256 Rd = xc->readMiscReg(FUNCT12);
1257 if (Rs1 != 0) {
1258 xc->setMiscReg(FUNCT12, Rd | Rs1);
1259 }
1260 }}, IsNonSpeculative, No_OpClass);
1261 0x3: csrrc({{
1262 Rd = xc->readMiscReg(FUNCT12);
1263 if (Rs1 != 0) {
1264 xc->setMiscReg(FUNCT12, Rd & ~Rs1);
1265 }
1266 }}, IsNonSpeculative, No_OpClass);
1267 0x5: csrrwi({{
1268 Rd = xc->readMiscReg(FUNCT12);
1269 xc->setMiscReg(FUNCT12, ZIMM);
1270 }}, IsNonSpeculative, No_OpClass);
1271 0x6: csrrsi({{
1272 Rd = xc->readMiscReg(FUNCT12);
1273 if (ZIMM != 0) {
1274 xc->setMiscReg(FUNCT12, Rd | ZIMM);
1275 }
1276 }}, IsNonSpeculative, No_OpClass);
1277 0x7: csrrci({{
1278 Rd = xc->readMiscReg(FUNCT12);
1279 if (ZIMM != 0) {
1280 xc->setMiscReg(FUNCT12, Rd & ~ZIMM);
1281 }
1282 }}, IsNonSpeculative, No_OpClass);
1283 }
1284 }
1285}
267 0x33: decode FUNCT3 {
268 format ROp {
269 0x0: decode FUNCT7 {
270 0x0: add({{
271 Rd = Rs1_sd + Rs2_sd;
272 }});
273 0x1: mul({{
274 Rd = Rs1_sd*Rs2_sd;
275 }}, IntMultOp);
276 0x20: sub({{
277 Rd = Rs1_sd - Rs2_sd;
278 }});
279 }
280 0x1: decode FUNCT7 {
281 0x0: sll({{
282 Rd = Rs1 << Rs2<5:0>;
283 }});
284 0x1: mulh({{
285 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
286
287 uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd);
288 uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32;
289 uint64_t Rs2_lo = (uint32_t)std::abs(Rs2_sd);
290 uint64_t Rs2_hi = (uint64_t)std::abs(Rs2_sd) >> 32;
291
292 uint64_t hi = Rs1_hi*Rs2_hi;
293 uint64_t mid1 = Rs1_hi*Rs2_lo;
294 uint64_t mid2 = Rs1_lo*Rs2_hi;
295 uint64_t lo = Rs2_lo*Rs1_lo;
296 uint64_t carry = ((uint64_t)(uint32_t)mid1
297 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
298
299 uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
300 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0) : res;
301 }}, IntMultOp);
302 }
303 0x2: decode FUNCT7 {
304 0x0: slt({{
305 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
306 }});
307 0x1: mulhsu({{
308 bool negate = Rs1_sd < 0;
309 uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd);
310 uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32;
311 uint64_t Rs2_lo = (uint32_t)Rs2;
312 uint64_t Rs2_hi = Rs2 >> 32;
313
314 uint64_t hi = Rs1_hi*Rs2_hi;
315 uint64_t mid1 = Rs1_hi*Rs2_lo;
316 uint64_t mid2 = Rs1_lo*Rs2_hi;
317 uint64_t lo = Rs1_lo*Rs2_lo;
318 uint64_t carry = ((uint64_t)(uint32_t)mid1
319 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
320
321 uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
322 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
323 }}, IntMultOp);
324 }
325 0x3: decode FUNCT7 {
326 0x0: sltu({{
327 Rd = (Rs1 < Rs2) ? 1 : 0;
328 }});
329 0x1: mulhu({{
330 uint64_t Rs1_lo = (uint32_t)Rs1;
331 uint64_t Rs1_hi = Rs1 >> 32;
332 uint64_t Rs2_lo = (uint32_t)Rs2;
333 uint64_t Rs2_hi = Rs2 >> 32;
334
335 uint64_t hi = Rs1_hi*Rs2_hi;
336 uint64_t mid1 = Rs1_hi*Rs2_lo;
337 uint64_t mid2 = Rs1_lo*Rs2_hi;
338 uint64_t lo = Rs1_lo*Rs2_lo;
339 uint64_t carry = ((uint64_t)(uint32_t)mid1
340 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
341
342 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
343 }}, IntMultOp);
344 }
345 0x4: decode FUNCT7 {
346 0x0: xor({{
347 Rd = Rs1 ^ Rs2;
348 }});
349 0x1: div({{
350 if (Rs2_sd == 0) {
351 Rd_sd = -1;
352 } else if (Rs1_sd == std::numeric_limits<int64_t>::min()
353 && Rs2_sd == -1) {
354 Rd_sd = std::numeric_limits<int64_t>::min();
355 } else {
356 Rd_sd = Rs1_sd/Rs2_sd;
357 }
358 }}, IntDivOp);
359 }
360 0x5: decode FUNCT7 {
361 0x0: srl({{
362 Rd = Rs1 >> Rs2<5:0>;
363 }});
364 0x1: divu({{
365 if (Rs2 == 0) {
366 Rd = std::numeric_limits<uint64_t>::max();
367 } else {
368 Rd = Rs1/Rs2;
369 }
370 }}, IntDivOp);
371 0x20: sra({{
372 Rd_sd = Rs1_sd >> Rs2<5:0>;
373 }});
374 }
375 0x6: decode FUNCT7 {
376 0x0: or({{
377 Rd = Rs1 | Rs2;
378 }});
379 0x1: rem({{
380 if (Rs2_sd == 0) {
381 Rd = Rs1_sd;
382 } else if (Rs1_sd == std::numeric_limits<int64_t>::min()
383 && Rs2_sd == -1) {
384 Rd = 0;
385 } else {
386 Rd = Rs1_sd%Rs2_sd;
387 }
388 }}, IntDivOp);
389 }
390 0x7: decode FUNCT7 {
391 0x0: and({{
392 Rd = Rs1 & Rs2;
393 }});
394 0x1: remu({{
395 if (Rs2 == 0) {
396 Rd = Rs1;
397 } else {
398 Rd = Rs1%Rs2;
399 }
400 }}, IntDivOp);
401 }
402 }
403 }
404
405 0x37: UOp::lui({{
406 Rd = (uint64_t)imm;
407 }});
408
409 0x3b: decode FUNCT3 {
410 format ROp {
411 0x0: decode FUNCT7 {
412 0x0: addw({{
413 Rd_sd = Rs1_sw + Rs2_sw;
414 }});
415 0x1: mulw({{
416 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
417 }}, IntMultOp);
418 0x20: subw({{
419 Rd_sd = Rs1_sw - Rs2_sw;
420 }});
421 }
422 0x1: sllw({{
423 Rd_sd = Rs1_sw << Rs2<4:0>;
424 }});
425 0x4: divw({{
426 if (Rs2_sw == 0) {
427 Rd_sd = -1;
428 } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
429 && Rs2_sw == -1) {
430 Rd_sd = std::numeric_limits<int32_t>::min();
431 } else {
432 Rd_sd = Rs1_sw/Rs2_sw;
433 }
434 }}, IntDivOp);
435 0x5: decode FUNCT7 {
436 0x0: srlw({{
437 Rd_uw = Rs1_uw >> Rs2<4:0>;
438 }});
439 0x1: divuw({{
440 if (Rs2_uw == 0) {
441 Rd_sd = std::numeric_limits<IntReg>::max();
442 } else {
443 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
444 }
445 }}, IntDivOp);
446 0x20: sraw({{
447 Rd_sd = Rs1_sw >> Rs2<4:0>;
448 }});
449 }
450 0x6: remw({{
451 if (Rs2_sw == 0) {
452 Rd_sd = Rs1_sw;
453 } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
454 && Rs2_sw == -1) {
455 Rd_sd = 0;
456 } else {
457 Rd_sd = Rs1_sw%Rs2_sw;
458 }
459 }}, IntDivOp);
460 0x7: remuw({{
461 if (Rs2_uw == 0) {
462 Rd_sd = (int32_t)Rs1_uw;
463 } else {
464 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
465 }
466 }}, IntDivOp);
467 }
468 }
469
470 format FPR4Op {
471 0x43: decode FUNCT2 {
472 0x0: fmadd_s({{
473 uint32_t temp;
474 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
475 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
476 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
477 float fd;
478
479 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
480 if (issignalingnan(fs1) || issignalingnan(fs2)
481 || issignalingnan(fs3)) {
482 FFLAGS |= FloatInvalid;
483 }
484 fd = std::numeric_limits<float>::quiet_NaN();
485 } else if (std::isinf(fs1) || std::isinf(fs2) ||
486 std::isinf(fs3)) {
487 if (std::signbit(fs1) == std::signbit(fs2)
488 && !std::isinf(fs3)) {
489 fd = std::numeric_limits<float>::infinity();
490 } else if (std::signbit(fs1) != std::signbit(fs2)
491 && !std::isinf(fs3)) {
492 fd = -std::numeric_limits<float>::infinity();
493 } else { // Fs3_sf is infinity
494 fd = fs3;
495 }
496 } else {
497 fd = fs1*fs2 + fs3;
498 }
499 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
500 }}, FloatMultOp);
501 0x1: fmadd_d({{
502 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
503 if (issignalingnan(Fs1) || issignalingnan(Fs2)
504 || issignalingnan(Fs3)) {
505 FFLAGS |= FloatInvalid;
506 }
507 Fd = std::numeric_limits<double>::quiet_NaN();
508 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
509 std::isinf(Fs3)) {
510 if (std::signbit(Fs1) == std::signbit(Fs2)
511 && !std::isinf(Fs3)) {
512 Fd = std::numeric_limits<double>::infinity();
513 } else if (std::signbit(Fs1) != std::signbit(Fs2)
514 && !std::isinf(Fs3)) {
515 Fd = -std::numeric_limits<double>::infinity();
516 } else {
517 Fd = Fs3;
518 }
519 } else {
520 Fd = Fs1*Fs2 + Fs3;
521 }
522 }}, FloatMultOp);
523 }
524 0x47: decode FUNCT2 {
525 0x0: fmsub_s({{
526 uint32_t temp;
527 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
528 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
529 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
530 float fd;
531
532 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
533 if (issignalingnan(fs1) || issignalingnan(fs2)
534 || issignalingnan(fs3)) {
535 FFLAGS |= FloatInvalid;
536 }
537 fd = std::numeric_limits<float>::quiet_NaN();
538 } else if (std::isinf(fs1) || std::isinf(fs2) ||
539 std::isinf(fs3)) {
540 if (std::signbit(fs1) == std::signbit(fs2)
541 && !std::isinf(fs3)) {
542 fd = std::numeric_limits<float>::infinity();
543 } else if (std::signbit(fs1) != std::signbit(fs2)
544 && !std::isinf(fs3)) {
545 fd = -std::numeric_limits<float>::infinity();
546 } else { // Fs3_sf is infinity
547 fd = -fs3;
548 }
549 } else {
550 fd = fs1*fs2 - fs3;
551 }
552 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
553 }}, FloatMultOp);
554 0x1: fmsub_d({{
555 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
556 if (issignalingnan(Fs1) || issignalingnan(Fs2)
557 || issignalingnan(Fs3)) {
558 FFLAGS |= FloatInvalid;
559 }
560 Fd = std::numeric_limits<double>::quiet_NaN();
561 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
562 std::isinf(Fs3)) {
563 if (std::signbit(Fs1) == std::signbit(Fs2)
564 && !std::isinf(Fs3)) {
565 Fd = std::numeric_limits<double>::infinity();
566 } else if (std::signbit(Fs1) != std::signbit(Fs2)
567 && !std::isinf(Fs3)) {
568 Fd = -std::numeric_limits<double>::infinity();
569 } else {
570 Fd = -Fs3;
571 }
572 } else {
573 Fd = Fs1*Fs2 - Fs3;
574 }
575 }}, FloatMultOp);
576 }
577 0x4b: decode FUNCT2 {
578 0x0: fnmsub_s({{
579 uint32_t temp;
580 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
581 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
582 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
583 float fd;
584
585 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
586 if (issignalingnan(fs1) || issignalingnan(fs2)
587 || issignalingnan(fs3)) {
588 FFLAGS |= FloatInvalid;
589 }
590 fd = std::numeric_limits<float>::quiet_NaN();
591 } else if (std::isinf(fs1) || std::isinf(fs2) ||
592 std::isinf(fs3)) {
593 if (std::signbit(fs1) == std::signbit(fs2)
594 && !std::isinf(fs3)) {
595 fd = -std::numeric_limits<float>::infinity();
596 } else if (std::signbit(fs1) != std::signbit(fs2)
597 && !std::isinf(fs3)) {
598 fd = std::numeric_limits<float>::infinity();
599 } else { // Fs3_sf is infinity
600 fd = fs3;
601 }
602 } else {
603 fd = -(fs1*fs2 - fs3);
604 }
605 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
606 }}, FloatMultOp);
607 0x1: fnmsub_d({{
608 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
609 if (issignalingnan(Fs1) || issignalingnan(Fs2)
610 || issignalingnan(Fs3)) {
611 FFLAGS |= FloatInvalid;
612 }
613 Fd = std::numeric_limits<double>::quiet_NaN();
614 } else if (std::isinf(Fs1) || std::isinf(Fs2)
615 || std::isinf(Fs3)) {
616 if (std::signbit(Fs1) == std::signbit(Fs2)
617 && !std::isinf(Fs3)) {
618 Fd = -std::numeric_limits<double>::infinity();
619 } else if (std::signbit(Fs1) != std::signbit(Fs2)
620 && !std::isinf(Fs3)) {
621 Fd = std::numeric_limits<double>::infinity();
622 } else {
623 Fd = Fs3;
624 }
625 } else {
626 Fd = -(Fs1*Fs2 - Fs3);
627 }
628 }}, FloatMultOp);
629 }
630 0x4f: decode FUNCT2 {
631 0x0: fnmadd_s({{
632 uint32_t temp;
633 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
634 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
635 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
636 float fd;
637
638 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
639 if (issignalingnan(fs1) || issignalingnan(fs2)
640 || issignalingnan(fs3)) {
641 FFLAGS |= FloatInvalid;
642 }
643 fd = std::numeric_limits<float>::quiet_NaN();
644 } else if (std::isinf(fs1) || std::isinf(fs2) ||
645 std::isinf(fs3)) {
646 if (std::signbit(fs1) == std::signbit(fs2)
647 && !std::isinf(fs3)) {
648 fd = -std::numeric_limits<float>::infinity();
649 } else if (std::signbit(fs1) != std::signbit(fs2)
650 && !std::isinf(fs3)) {
651 fd = std::numeric_limits<float>::infinity();
652 } else { // Fs3_sf is infinity
653 fd = -fs3;
654 }
655 } else {
656 fd = -(fs1*fs2 + fs3);
657 }
658 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
659 }}, FloatMultOp);
660 0x1: fnmadd_d({{
661 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
662 if (issignalingnan(Fs1) || issignalingnan(Fs2)
663 || issignalingnan(Fs3)) {
664 FFLAGS |= FloatInvalid;
665 }
666 Fd = std::numeric_limits<double>::quiet_NaN();
667 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
668 std::isinf(Fs3)) {
669 if (std::signbit(Fs1) == std::signbit(Fs2)
670 && !std::isinf(Fs3)) {
671 Fd = -std::numeric_limits<double>::infinity();
672 } else if (std::signbit(Fs1) != std::signbit(Fs2)
673 && !std::isinf(Fs3)) {
674 Fd = std::numeric_limits<double>::infinity();
675 } else {
676 Fd = -Fs3;
677 }
678 } else {
679 Fd = -(Fs1*Fs2 + Fs3);
680 }
681 }}, FloatMultOp);
682 }
683 }
684
685 0x53: decode FUNCT7 {
686 format FPROp {
687 0x0: fadd_s({{
688 uint32_t temp;
689 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
690 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
691 float fd;
692
693 if (std::isnan(fs1) || std::isnan(fs2)) {
694 if (issignalingnan(fs1) || issignalingnan(fs2)) {
695 FFLAGS |= FloatInvalid;
696 }
697 fd = std::numeric_limits<float>::quiet_NaN();
698 } else {
699 fd = fs1 + fs2;
700 }
701 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
702 }}, FloatAddOp);
703 0x1: fadd_d({{
704 if (std::isnan(Fs1) || std::isnan(Fs2)) {
705 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
706 FFLAGS |= FloatInvalid;
707 }
708 Fd = std::numeric_limits<double>::quiet_NaN();
709 } else {
710 Fd = Fs1 + Fs2;
711 }
712 }}, FloatAddOp);
713 0x4: fsub_s({{
714 uint32_t temp;
715 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
716 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
717 float fd;
718
719 if (std::isnan(fs1) || std::isnan(fs2)) {
720 if (issignalingnan(fs1) || issignalingnan(fs2)) {
721 FFLAGS |= FloatInvalid;
722 }
723 fd = std::numeric_limits<float>::quiet_NaN();
724 } else {
725 fd = fs1 - fs2;
726 }
727 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
728 }}, FloatAddOp);
729 0x5: fsub_d({{
730 if (std::isnan(Fs1) || std::isnan(Fs2)) {
731 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
732 FFLAGS |= FloatInvalid;
733 }
734 Fd = std::numeric_limits<double>::quiet_NaN();
735 } else {
736 Fd = Fs1 - Fs2;
737 }
738 }}, FloatAddOp);
739 0x8: fmul_s({{
740 uint32_t temp;
741 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
742 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
743 float fd;
744
745 if (std::isnan(fs1) || std::isnan(fs2)) {
746 if (issignalingnan(fs1) || issignalingnan(fs2)) {
747 FFLAGS |= FloatInvalid;
748 }
749 fd = std::numeric_limits<float>::quiet_NaN();
750 } else {
751 fd = fs1*fs2;
752 }
753 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
754 }}, FloatMultOp);
755 0x9: fmul_d({{
756 if (std::isnan(Fs1) || std::isnan(Fs2)) {
757 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
758 FFLAGS |= FloatInvalid;
759 }
760 Fd = std::numeric_limits<double>::quiet_NaN();
761 } else {
762 Fd = Fs1*Fs2;
763 }
764 }}, FloatMultOp);
765 0xc: fdiv_s({{
766 uint32_t temp;
767 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
768 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
769 float fd;
770
771 if (std::isnan(fs1) || std::isnan(fs2)) {
772 if (issignalingnan(fs1) || issignalingnan(fs2)) {
773 FFLAGS |= FloatInvalid;
774 }
775 fd = std::numeric_limits<float>::quiet_NaN();
776 } else {
777 fd = fs1/fs2;
778 }
779 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
780 }}, FloatDivOp);
781 0xd: fdiv_d({{
782 if (std::isnan(Fs1) || std::isnan(Fs2)) {
783 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
784 FFLAGS |= FloatInvalid;
785 }
786 Fd = std::numeric_limits<double>::quiet_NaN();
787 } else {
788 Fd = Fs1/Fs2;
789 }
790 }}, FloatDivOp);
791 0x10: decode ROUND_MODE {
792 0x0: fsgnj_s({{
793 uint32_t temp;
794 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
795 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
796 float fd;
797
798 if (issignalingnan(fs1)) {
799 fd = std::numeric_limits<float>::signaling_NaN();
800 std::feclearexcept(FE_INVALID);
801 } else {
802 fd = std::copysign(fs1, fs2);
803 }
804 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
805 }});
806 0x1: fsgnjn_s({{
807 uint32_t temp;
808 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
809 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
810 float fd;
811
812 if (issignalingnan(fs1)) {
813 fd = std::numeric_limits<float>::signaling_NaN();
814 std::feclearexcept(FE_INVALID);
815 } else {
816 fd = std::copysign(fs1, -fs2);
817 }
818 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
819 }});
820 0x2: fsgnjx_s({{
821 uint32_t temp;
822 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
823 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
824 float fd;
825
826 if (issignalingnan(fs1)) {
827 fd = std::numeric_limits<float>::signaling_NaN();
828 std::feclearexcept(FE_INVALID);
829 } else {
830 fd = fs1*(std::signbit(fs2) ? -1.0 : 1.0);
831 }
832 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
833 }});
834 }
835 0x11: decode ROUND_MODE {
836 0x0: fsgnj_d({{
837 if (issignalingnan(Fs1)) {
838 Fd = std::numeric_limits<double>::signaling_NaN();
839 std::feclearexcept(FE_INVALID);
840 } else {
841 Fd = std::copysign(Fs1, Fs2);
842 }
843 }});
844 0x1: fsgnjn_d({{
845 if (issignalingnan(Fs1)) {
846 Fd = std::numeric_limits<double>::signaling_NaN();
847 std::feclearexcept(FE_INVALID);
848 } else {
849 Fd = std::copysign(Fs1, -Fs2);
850 }
851 }});
852 0x2: fsgnjx_d({{
853 if (issignalingnan(Fs1)) {
854 Fd = std::numeric_limits<double>::signaling_NaN();
855 std::feclearexcept(FE_INVALID);
856 } else {
857 Fd = Fs1*(std::signbit(Fs2) ? -1.0 : 1.0);
858 }
859 }});
860 }
861 0x14: decode ROUND_MODE {
862 0x0: fmin_s({{
863 uint32_t temp;
864 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
865 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
866 float fd;
867
868 if (issignalingnan(fs2)) {
869 fd = fs1;
870 FFLAGS |= FloatInvalid;
871 } else if (issignalingnan(fs1)) {
872 fd = fs2;
873 FFLAGS |= FloatInvalid;
874 } else {
875 fd = std::fmin(fs1, fs2);
876 }
877 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
878 }}, FloatCmpOp);
879 0x1: fmax_s({{
880 uint32_t temp;
881 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
882 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
883 float fd;
884
885 if (issignalingnan(fs2)) {
886 fd = fs1;
887 FFLAGS |= FloatInvalid;
888 } else if (issignalingnan(fs1)) {
889 fd = fs2;
890 FFLAGS |= FloatInvalid;
891 } else {
892 fd = std::fmax(fs1, fs2);
893 }
894 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
895 }}, FloatCmpOp);
896 }
897 0x15: decode ROUND_MODE {
898 0x0: fmin_d({{
899 if (issignalingnan(Fs2)) {
900 Fd = Fs1;
901 FFLAGS |= FloatInvalid;
902 } else if (issignalingnan(Fs1)) {
903 Fd = Fs2;
904 FFLAGS |= FloatInvalid;
905 } else {
906 Fd = std::fmin(Fs1, Fs2);
907 }
908 }}, FloatCmpOp);
909 0x1: fmax_d({{
910 if (issignalingnan(Fs2)) {
911 Fd = Fs1;
912 FFLAGS |= FloatInvalid;
913 } else if (issignalingnan(Fs1)) {
914 Fd = Fs2;
915 FFLAGS |= FloatInvalid;
916 } else {
917 Fd = std::fmax(Fs1, Fs2);
918 }
919 }}, FloatCmpOp);
920 }
921 0x20: fcvt_s_d({{
922 assert(CONV_SGN == 1);
923 float fd;
924 if (issignalingnan(Fs1)) {
925 fd = std::numeric_limits<float>::quiet_NaN();
926 FFLAGS |= FloatInvalid;
927 } else {
928 fd = (float)Fs1;
929 }
930 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
931 }}, FloatCvtOp);
932 0x21: fcvt_d_s({{
933 assert(CONV_SGN == 0);
934 uint32_t temp;
935 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
936
937 if (issignalingnan(fs1)) {
938 Fd = std::numeric_limits<double>::quiet_NaN();
939 FFLAGS |= FloatInvalid;
940 } else {
941 Fd = (double)fs1;
942 }
943 }}, FloatCvtOp);
944 0x2c: fsqrt_s({{
945 assert(RS2 == 0);
946 uint32_t temp;
947 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
948 float fd;
949
950 if (issignalingnan(Fs1_sf)) {
951 FFLAGS |= FloatInvalid;
952 }
953 fd = std::sqrt(fs1);
954 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
955 }}, FloatSqrtOp);
956 0x2d: fsqrt_d({{
957 assert(RS2 == 0);
958 Fd = std::sqrt(Fs1);
959 }}, FloatSqrtOp);
960 0x50: decode ROUND_MODE {
961 0x0: fle_s({{
962 uint32_t temp;
963 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
964 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
965
966 if (std::isnan(fs1) || std::isnan(fs2)) {
967 FFLAGS |= FloatInvalid;
968 Rd = 0;
969 } else {
970 Rd = fs1 <= fs2 ? 1 : 0;
971 }
972 }}, FloatCmpOp);
973 0x1: flt_s({{
974 uint32_t temp;
975 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
976 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
977
978 if (std::isnan(fs1) || std::isnan(fs2)) {
979 FFLAGS |= FloatInvalid;
980 Rd = 0;
981 } else {
982 Rd = fs1 < fs2 ? 1 : 0;
983 }
984 }}, FloatCmpOp);
985 0x2: feq_s({{
986 uint32_t temp;
987 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
988 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
989
990 if (issignalingnan(fs1) || issignalingnan(fs2)) {
991 FFLAGS |= FloatInvalid;
992 }
993 Rd = fs1 == fs2 ? 1 : 0;
994 }}, FloatCmpOp);
995 }
996 0x51: decode ROUND_MODE {
997 0x0: fle_d({{
998 if (std::isnan(Fs1) || std::isnan(Fs2)) {
999 FFLAGS |= FloatInvalid;
1000 Rd = 0;
1001 } else {
1002 Rd = Fs1 <= Fs2 ? 1 : 0;
1003 }
1004 }}, FloatCmpOp);
1005 0x1: flt_d({{
1006 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1007 FFLAGS |= FloatInvalid;
1008 Rd = 0;
1009 } else {
1010 Rd = Fs1 < Fs2 ? 1 : 0;
1011 }
1012 }}, FloatCmpOp);
1013 0x2: feq_d({{
1014 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1015 FFLAGS |= FloatInvalid;
1016 }
1017 Rd = Fs1 == Fs2 ? 1 : 0;
1018 }}, FloatCmpOp);
1019 }
1020 0x60: decode CONV_SGN {
1021 0x0: fcvt_w_s({{
1022 uint32_t temp;
1023 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1024
1025 if (std::isnan(fs1)) {
1026 Rd_sd = std::numeric_limits<int32_t>::max();
1027 FFLAGS |= FloatInvalid;
1028 } else {
1029 Rd_sd = (int32_t)fs1;
1030 if (std::fetestexcept(FE_INVALID)) {
1031 if (std::signbit(fs1)) {
1032 Rd_sd = std::numeric_limits<int32_t>::min();
1033 } else {
1034 Rd_sd = std::numeric_limits<int32_t>::max();
1035 }
1036 std::feclearexcept(FE_INEXACT);
1037 }
1038 }
1039 }}, FloatCvtOp);
1040 0x1: fcvt_wu_s({{
1041 uint32_t temp;
1042 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1043
1044 if (fs1 < 0.0) {
1045 Rd = 0;
1046 FFLAGS |= FloatInvalid;
1047 } else {
1048 Rd = (uint32_t)fs1;
1049 if (std::fetestexcept(FE_INVALID)) {
1050 Rd = std::numeric_limits<uint64_t>::max();
1051 std::feclearexcept(FE_INEXACT);
1052 }
1053 }
1054 }}, FloatCvtOp);
1055 0x2: fcvt_l_s({{
1056 uint32_t temp;
1057 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1058
1059 if (std::isnan(fs1)) {
1060 Rd_sd = std::numeric_limits<int64_t>::max();
1061 FFLAGS |= FloatInvalid;
1062 } else {
1063 Rd_sd = (int64_t)fs1;
1064 if (std::fetestexcept(FE_INVALID)) {
1065 if (std::signbit(fs1)) {
1066 Rd_sd = std::numeric_limits<int64_t>::min();
1067 } else {
1068 Rd_sd = std::numeric_limits<int64_t>::max();
1069 }
1070 std::feclearexcept(FE_INEXACT);
1071 }
1072 }
1073 }}, FloatCvtOp);
1074 0x3: fcvt_lu_s({{
1075 uint32_t temp;
1076 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1077
1078 if (fs1 < 0.0) {
1079 Rd = 0;
1080 FFLAGS |= FloatInvalid;
1081 } else {
1082 Rd = (uint64_t)fs1;
1083 if (std::fetestexcept(FE_INVALID)) {
1084 Rd = std::numeric_limits<uint64_t>::max();
1085 std::feclearexcept(FE_INEXACT);
1086 }
1087 }
1088 }}, FloatCvtOp);
1089 }
1090 0x61: decode CONV_SGN {
1091 0x0: fcvt_w_d({{
1092 Rd_sd = (int32_t)Fs1;
1093 if (std::fetestexcept(FE_INVALID)) {
1094 if (Fs1 < 0.0) {
1095 Rd_sd = std::numeric_limits<int32_t>::min();
1096 } else {
1097 Rd_sd = std::numeric_limits<int32_t>::max();
1098 }
1099 std::feclearexcept(FE_INEXACT);
1100 }
1101 }}, FloatCvtOp);
1102 0x1: fcvt_wu_d({{
1103 if (Fs1 < 0.0) {
1104 Rd = 0;
1105 FFLAGS |= FloatInvalid;
1106 } else {
1107 Rd = (uint32_t)Fs1;
1108 if (std::fetestexcept(FE_INVALID)) {
1109 Rd = std::numeric_limits<uint64_t>::max();
1110 std::feclearexcept(FE_INEXACT);
1111 }
1112 }
1113 }}, FloatCvtOp);
1114 0x2: fcvt_l_d({{
1115 Rd_sd = Fs1;
1116 if (std::fetestexcept(FE_INVALID)) {
1117 if (Fs1 < 0.0) {
1118 Rd_sd = std::numeric_limits<int64_t>::min();
1119 } else {
1120 Rd_sd = std::numeric_limits<int64_t>::max();
1121 }
1122 std::feclearexcept(FE_INEXACT);
1123 }
1124 }}, FloatCvtOp);
1125 0x3: fcvt_lu_d({{
1126 if (Fs1 < 0.0) {
1127 Rd = 0;
1128 FFLAGS |= FloatInvalid;
1129 } else {
1130 Rd = (uint64_t)Fs1;
1131 if (std::fetestexcept(FE_INVALID)) {
1132 Rd = std::numeric_limits<uint64_t>::max();
1133 std::feclearexcept(FE_INEXACT);
1134 }
1135 }
1136 }}, FloatCvtOp);
1137 }
1138 0x68: decode CONV_SGN {
1139 0x0: fcvt_s_w({{
1140 float temp = (float)Rs1_sw;
1141 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1142 }}, FloatCvtOp);
1143 0x1: fcvt_s_wu({{
1144 float temp = (float)Rs1_uw;
1145 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1146 }}, FloatCvtOp);
1147 0x2: fcvt_s_l({{
1148 float temp = (float)Rs1_sd;
1149 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1150 }}, FloatCvtOp);
1151 0x3: fcvt_s_lu({{
1152 float temp = (float)Rs1;
1153 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1154 }}, FloatCvtOp);
1155 }
1156 0x69: decode CONV_SGN {
1157 0x0: fcvt_d_w({{
1158 Fd = (double)Rs1_sw;
1159 }}, FloatCvtOp);
1160 0x1: fcvt_d_wu({{
1161 Fd = (double)Rs1_uw;
1162 }}, FloatCvtOp);
1163 0x2: fcvt_d_l({{
1164 Fd = (double)Rs1_sd;
1165 }}, FloatCvtOp);
1166 0x3: fcvt_d_lu({{
1167 Fd = (double)Rs1;
1168 }}, FloatCvtOp);
1169 }
1170 0x70: decode ROUND_MODE {
1171 0x0: fmv_x_s({{
1172 Rd = (uint32_t)Fs1_bits;
1173 if ((Rd&0x80000000) != 0) {
1174 Rd |= (0xFFFFFFFFULL << 32);
1175 }
1176 }}, FloatCvtOp);
1177 0x1: fclass_s({{
1178 uint32_t temp;
1179 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1180 switch (std::fpclassify(fs1)) {
1181 case FP_INFINITE:
1182 if (std::signbit(fs1)) {
1183 Rd = 1 << 0;
1184 } else {
1185 Rd = 1 << 7;
1186 }
1187 break;
1188 case FP_NAN:
1189 if (issignalingnan(fs1)) {
1190 Rd = 1 << 8;
1191 } else {
1192 Rd = 1 << 9;
1193 }
1194 break;
1195 case FP_ZERO:
1196 if (std::signbit(fs1)) {
1197 Rd = 1 << 3;
1198 } else {
1199 Rd = 1 << 4;
1200 }
1201 break;
1202 case FP_SUBNORMAL:
1203 if (std::signbit(fs1)) {
1204 Rd = 1 << 2;
1205 } else {
1206 Rd = 1 << 5;
1207 }
1208 break;
1209 case FP_NORMAL:
1210 if (std::signbit(fs1)) {
1211 Rd = 1 << 1;
1212 } else {
1213 Rd = 1 << 6;
1214 }
1215 break;
1216 default:
1217 panic("Unknown classification for operand.");
1218 break;
1219 }
1220 }});
1221 }
1222 0x71: decode ROUND_MODE {
1223 0x0: fmv_x_d({{
1224 Rd = Fs1_bits;
1225 }}, FloatCvtOp);
1226 0x1: fclass_d({{
1227 switch (std::fpclassify(Fs1)) {
1228 case FP_INFINITE:
1229 if (std::signbit(Fs1)) {
1230 Rd = 1 << 0;
1231 } else {
1232 Rd = 1 << 7;
1233 }
1234 break;
1235 case FP_NAN:
1236 if (issignalingnan(Fs1)) {
1237 Rd = 1 << 8;
1238 } else {
1239 Rd = 1 << 9;
1240 }
1241 break;
1242 case FP_ZERO:
1243 if (std::signbit(Fs1)) {
1244 Rd = 1 << 3;
1245 } else {
1246 Rd = 1 << 4;
1247 }
1248 break;
1249 case FP_SUBNORMAL:
1250 if (std::signbit(Fs1)) {
1251 Rd = 1 << 2;
1252 } else {
1253 Rd = 1 << 5;
1254 }
1255 break;
1256 case FP_NORMAL:
1257 if (std::signbit(Fs1)) {
1258 Rd = 1 << 1;
1259 } else {
1260 Rd = 1 << 6;
1261 }
1262 break;
1263 default:
1264 panic("Unknown classification for operand.");
1265 break;
1266 }
1267 }});
1268 }
1269 0x78: fmv_s_x({{
1270 Fd_bits = (uint64_t)Rs1_uw;
1271 }}, FloatCvtOp);
1272 0x79: fmv_d_x({{
1273 Fd_bits = Rs1;
1274 }}, FloatCvtOp);
1275 }
1276 }
1277 0x63: decode FUNCT3 {
1278 format SBOp {
1279 0x0: beq({{
1280 if (Rs1 == Rs2) {
1281 NPC = PC + imm;
1282 } else {
1283 NPC = NPC;
1284 }
1285 }}, IsDirectControl, IsCondControl);
1286 0x1: bne({{
1287 if (Rs1 != Rs2) {
1288 NPC = PC + imm;
1289 } else {
1290 NPC = NPC;
1291 }
1292 }}, IsDirectControl, IsCondControl);
1293 0x4: blt({{
1294 if (Rs1_sd < Rs2_sd) {
1295 NPC = PC + imm;
1296 } else {
1297 NPC = NPC;
1298 }
1299 }}, IsDirectControl, IsCondControl);
1300 0x5: bge({{
1301 if (Rs1_sd >= Rs2_sd) {
1302 NPC = PC + imm;
1303 } else {
1304 NPC = NPC;
1305 }
1306 }}, IsDirectControl, IsCondControl);
1307 0x6: bltu({{
1308 if (Rs1 < Rs2) {
1309 NPC = PC + imm;
1310 } else {
1311 NPC = NPC;
1312 }
1313 }}, IsDirectControl, IsCondControl);
1314 0x7: bgeu({{
1315 if (Rs1 >= Rs2) {
1316 NPC = PC + imm;
1317 } else {
1318 NPC = NPC;
1319 }
1320 }}, IsDirectControl, IsCondControl);
1321 }
1322 }
1323
1324 0x67: decode FUNCT3 {
1325 0x0: Jump::jalr({{
1326 Rd = NPC;
1327 NPC = (imm + Rs1) & (~0x1);
1328 }}, IsIndirectControl, IsUncondControl, IsCall);
1329 }
1330
1331 0x6f: UJOp::jal({{
1332 Rd = NPC;
1333 NPC = PC + imm;
1334 }}, IsDirectControl, IsUncondControl, IsCall);
1335
1336 0x73: decode FUNCT3 {
1337 format IOp {
1338 0x0: decode FUNCT12 {
1339 0x0: ecall({{
1340 fault = std::make_shared<SyscallFault>();
1341 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall, No_OpClass);
1342 0x1: ebreak({{
1343 fault = std::make_shared<BreakpointFault>();
1344 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1345 0x100: eret({{
1346 fault = std::make_shared<UnimplementedFault>("eret");
1347 }}, No_OpClass);
1348 }
1349 0x1: csrrw({{
1350 Rd = xc->readMiscReg(FUNCT12);
1351 xc->setMiscReg(FUNCT12, Rs1);
1352 }}, IsNonSpeculative, No_OpClass);
1353 0x2: csrrs({{
1354 Rd = xc->readMiscReg(FUNCT12);
1355 if (Rs1 != 0) {
1356 xc->setMiscReg(FUNCT12, Rd | Rs1);
1357 }
1358 }}, IsNonSpeculative, No_OpClass);
1359 0x3: csrrc({{
1360 Rd = xc->readMiscReg(FUNCT12);
1361 if (Rs1 != 0) {
1362 xc->setMiscReg(FUNCT12, Rd & ~Rs1);
1363 }
1364 }}, IsNonSpeculative, No_OpClass);
1365 0x5: csrrwi({{
1366 Rd = xc->readMiscReg(FUNCT12);
1367 xc->setMiscReg(FUNCT12, ZIMM);
1368 }}, IsNonSpeculative, No_OpClass);
1369 0x6: csrrsi({{
1370 Rd = xc->readMiscReg(FUNCT12);
1371 if (ZIMM != 0) {
1372 xc->setMiscReg(FUNCT12, Rd | ZIMM);
1373 }
1374 }}, IsNonSpeculative, No_OpClass);
1375 0x7: csrrci({{
1376 Rd = xc->readMiscReg(FUNCT12);
1377 if (ZIMM != 0) {
1378 xc->setMiscReg(FUNCT12, Rd & ~ZIMM);
1379 }
1380 }}, IsNonSpeculative, No_OpClass);
1381 }
1382 }
1383}