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