fixes 95_bitfields. loading 64bit constants is suboptimal right now. int32_t shifts really need to use the W form, otherwise 'x << 24 >> 24' doesn't extract the low 8 bits.
Unified · Split
| @@ -215,17 +215,32 @@ ST_FUNC void load(int r, SValue *sv) · 214 unmodified lines | |||
| 215 | int64_t si = sv->c.i; | 215 | int64_t si = sv->c.i; |
| 216 | uint32_t pi; | 216 | uint32_t pi; |
| 217 | si >>= 32; | 217 | si >>= 32; |
| 218 | if (si != 0) | 218 | if (si != 0) { |
| 219 | tcc_error("unimp: load(very large const)"); | 219 | pi = si; |
| 220 | /* A 32bit unsigned constant. lui always sign extends, so we need | 220 | if (fc < 0) |
| 221 | tricks. */ | 221 | pi++; |
| 222 | pi = (uint32_t)sv->c.i; | 222 | o(0x37 | (rr << 7) | (((pi + 0x800) & 0xfffff000))); // lui RR, up(up(fc)) |
| 223 | o(0x37 | (rr << 7) | (((pi + 0x80000) & 0xfff00000) >> 8)); // lui RR, up(fc)>>8 | 223 | EI(0x13, 0, rr, rr, (int)pi << 20 >> 20); // addi RR, RR, lo(up(fc)) |
| 224 | EI(0x13, 0, rr, rr, (((pi + 0x200) & 0x000ffc00) >> 8) | (-((int)(pi + 0x200) & 0x80000) >> 8)); // addi RR, RR, mid(fc) | 224 | EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12 |
| 225 | EI(0x13, 1, rr, rr, 8); // slli RR, RR, 8 | 225 | EI(0x13, 0, rr, rr, (fc + (1 << 19)) >> 20); // addi RR, RR, up(lo(fc)) |
| 226 | fc = (pi & 0x3ff) | (-((int)(pi & 0x200))); | 226 | EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12 |
| 227 | rb = rr; | 227 | fc = fc << 12 >> 12; |
| 228 | do32bit = 0; | 228 | EI(0x13, 0, rr, rr, fc >> 8); // addi RR, RR, lo1(lo(fc)) |
| 229 | EI(0x13, 1, rr, rr, 8); // slli RR, RR, 8 | ||
| 230 | fc &= 0xff; | ||
| 231 | rb = rr; | ||
| 232 | do32bit = 0; | ||
| 233 | } else { | ||
| 234 | /* A 32bit unsigned constant. lui always sign extends, so we need | ||
| 235 | tricks. */ | ||
| 236 | pi = (uint32_t)sv->c.i; | ||
| 237 | o(0x37 | (rr << 7) | (((pi + 0x80000) & 0xfff00000) >> 8)); // lui RR, up(fc)>>8 | ||
| 238 | EI(0x13, 0, rr, rr, (((pi + 0x200) & 0x000ffc00) >> 8) | (-((int)(pi + 0x200) & 0x80000) >> 8)); // addi RR, RR, mid(fc) | ||
| 239 | EI(0x13, 1, rr, rr, 8); // slli RR, RR, 8 | ||
| 240 | fc = (pi & 0x3ff) | (-((int)(pi & 0x200))); | ||
| 241 | rb = rr; | ||
| 242 | do32bit = 0; | ||
| 243 | } | ||
| 229 | } | 244 | } |
| 230 | if (((unsigned)fc + (1 << 11)) >> 12) | 245 | if (((unsigned)fc + (1 << 11)) >> 12) |
| 231 | o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)), rb = rr; //lui RR, upper(fc) | 246 | o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)), rb = rr; //lui RR, upper(fc) |
| @@ -619,6 +634,7 @@ static void gen_opil(int op, int ll) · 387 unmodified lines | |||
| 619 | vtop++; | 634 | vtop++; |
| 620 | vtop[0].r = d; | 635 | vtop[0].r = d; |
| 621 | d = ireg(d); | 636 | d = ireg(d); |
| 637 | ll = ll ? 0 : 8; | ||
| 622 | switch (op) { | 638 | switch (op) { |
| 623 | case '%': | 639 | case '%': |
| 624 | case TOK_PDIV: | 640 | case TOK_PDIV: |
| @@ -632,10 +648,10 @@ static void gen_opil(int op, int ll) · 7 unmodified lines | |||
| 632 | o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x20 << 25)); //sub d, a, b | 648 | o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x20 << 25)); //sub d, a, b |
| 633 | break; | 649 | break; |
| 634 | case TOK_SAR: | 650 | case TOK_SAR: |
| 635 | o(0x33 | (d << 7) | (a << 15) | (b << 20) | (5 << 12) | (1 << 30)); //sra d, a, b | 651 | o(0x33 | ll | (d << 7) | (a << 15) | (b << 20) | (5 << 12) | (1 << 30)); //sra d, a, b |
| 636 | break; | 652 | break; |
| 637 | case TOK_SHR: | 653 | case TOK_SHR: |
| 638 | o(0x33 | (d << 7) | (a << 15) | (b << 20) | (5 << 12)); //srl d, a, b | 654 | o(0x33 | ll | (d << 7) | (a << 15) | (b << 20) | (5 << 12)); //srl d, a, b |
| 639 | break; | 655 | break; |
| 640 | case TOK_SHL: | 656 | case TOK_SHL: |
| 641 | o(0x33 | (d << 7) | (a << 15) | (b << 20) | (1 << 12)); //sll d, a, b | 657 | o(0x33 | (d << 7) | (a << 15) | (b << 20) | (1 << 12)); //sll d, a, b |