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 | 215 | int64_t si = sv->c.i; |
| 216 | 216 | uint32_t pi; |
| 217 | 217 | si >>= 32; |
| 218 | − if (si != 0) | |
| 219 | − tcc_error("unimp: load(very large const)"); | |
| 220 | − /* A 32bit unsigned constant. lui always sign extends, so we need | |
| 221 | − tricks. */ | |
| 222 | − pi = (uint32_t)sv->c.i; | |
| 223 | − o(0x37 | (rr << 7) | (((pi + 0x80000) & 0xfff00000) >> 8)); // lui RR, up(fc)>>8 | |
| 224 | − EI(0x13, 0, rr, rr, (((pi + 0x200) & 0x000ffc00) >> 8) | (-((int)(pi + 0x200) & 0x80000) >> 8)); // addi RR, RR, mid(fc) | |
| 225 | − EI(0x13, 1, rr, rr, 8); // slli RR, RR, 8 | |
| 226 | − fc = (pi & 0x3ff) | (-((int)(pi & 0x200))); | |
| 227 | − rb = rr; | |
| 228 | − do32bit = 0; | |
| 218 | + if (si != 0) { | |
| 219 | + pi = si; | |
| 220 | + if (fc < 0) | |
| 221 | + pi++; | |
| 222 | + o(0x37 | (rr << 7) | (((pi + 0x800) & 0xfffff000))); // lui RR, up(up(fc)) | |
| 223 | + EI(0x13, 0, rr, rr, (int)pi << 20 >> 20); // addi RR, RR, lo(up(fc)) | |
| 224 | + EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12 | |
| 225 | + EI(0x13, 0, rr, rr, (fc + (1 << 19)) >> 20); // addi RR, RR, up(lo(fc)) | |
| 226 | + EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12 | |
| 227 | + fc = fc << 12 >> 12; | |
| 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 | 245 | if (((unsigned)fc + (1 << 11)) >> 12) |
| 231 | 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 | 634 | vtop++; |
| 620 | 635 | vtop[0].r = d; |
| 621 | 636 | d = ireg(d); |
| 637 | + ll = ll ? 0 : 8; | |
| 622 | 638 | switch (op) { |
| 623 | 639 | case '%': |
| 624 | 640 | case TOK_PDIV: |
| @@ -632,10 +648,10 @@ static void gen_opil(int op, int ll) · 7 unmodified lines | ||
| 632 | 648 | o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x20 << 25)); //sub d, a, b |
| 633 | 649 | break; |
| 634 | 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 | 652 | break; |
| 637 | 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 | 655 | break; |
| 640 | 656 | case TOK_SHL: |
| 641 | 657 | o(0x33 | (d << 7) | (a << 15) | (b << 20) | (1 << 12)); //sll d, a, b |