Unified · Split
| @@ -294,13 +294,29 @@ ST_FUNC void load(int r, SValue *sv) · 293 unmodified lines | ||
| 294 | 294 | EI(opcode, func3, rr, br, fc); // l[bhwd][u] / fl[wd] RR, fc(BR) |
| 295 | 295 | } else if (v == VT_CONST) { |
| 296 | 296 | 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); | |
| 298 | 316 | if (fr & VT_SYM) { |
| 299 | 317 | rb = load_symofs(r, sv, 0, &fc); |
| 300 | 318 | do32bit = 0; |
| 301 | 319 | } |
| 302 | − if (is_float(sv->type.t) && bt != VT_LDOUBLE) | |
| 303 | − tcc_error("unimp: load(float)"); | |
| 304 | 320 | if (do32bit && fc != sv->c.i) { |
| 305 | 321 | int64_t si = sv->c.i; |
| 306 | 322 | si >>= 32; |