History

riscv64: implement float/double constant loading

Meng Zhuo committed 5 months ago

Commit 724b24e1 parent d8aee9b1 file · +19 −3Browse files

Unified · Split

riscv64-gen.c+19−3
@@ -294,13 +294,29 @@ ST_FUNC void load(int r, SValue *sv) · 293 unmodified lines
294294 EI(opcode, func3, rr, br, fc); // l[bhwd][u] / fl[wd] RR, fc(BR)
295295 } else if (v == VT_CONST) {
296296 int rb = 0, do32bit = 8, zext = 0;
297− assert((!is_float(sv->type.t) && is_ireg(r)) || bt == VT_LDOUBLE);
297+ if (is_float(sv->type.t) && bt != VT_LDOUBLE) {
298+ /* load float/double constant: move bit pattern from int reg */
299+ uint64_t val = sv->c.i;
300+ int is_dbl = bt == VT_DOUBLE;
301+ if (val == 0) {
302+ o(0x53 | (rr << 7) | ((unsigned)(0x78 | is_dbl) << 25));
303+ return;
304+ }
305+ if (is_dbl) {
306+ load_large_constant(6, (int)val, (int)(val >> 32));
307+ } else {
308+ if (LOW_OVERFLOW(fc))
309+ o(0x37 | (6 << 7) | UPPER(fc)); // lui t1, upper
310+ EI(0x13 | 8, 0, 6, LOW_OVERFLOW(fc) ? 6 : 0, SIGN11(fc)); // addiw t1,...
311+ }
312+ o(0x53 | (rr << 7) | (6 << 15) | ((unsigned)(0x78 | is_dbl) << 25));
313+ return;
314+ }
315+ assert(is_ireg(r) || bt == VT_LDOUBLE);
298316 if (fr & VT_SYM) {
299317 rb = load_symofs(r, sv, 0, &fc);
300318 do32bit = 0;
301319 }
302− if (is_float(sv->type.t) && bt != VT_LDOUBLE)
303− tcc_error("unimp: load(float)");
304320 if (do32bit && fc != sv->c.i) {
305321 int64_t si = sv->c.i;
306322 si >>= 32;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t