| @@ -36,6 +36,7 @@ · 35 unmodified lines |
| 36 | #include <assert.h> | 36 | #include <assert.h> |
| 37 | | 37 | |
| 38 | #define UPPER(x) (((unsigned)(x) + 0x800u) & 0xfffff000) | 38 | #define UPPER(x) (((unsigned)(x) + 0x800u) & 0xfffff000) |
| | 39 | #define LOW_OVERFLOW(x) UPPER(x) |
| 39 | #define SIGN7(x) ((((x) & 0xff) ^ 0x80) - 0x80) | 40 | #define SIGN7(x) ((((x) & 0xff) ^ 0x80) - 0x80) |
| 40 | #define SIGN11(x) ((((x) & 0xfff) ^ 0x800) - 0x800) | 41 | #define SIGN11(x) ((((x) & 0xfff) ^ 0x800) - 0x800) |
| 41 | | 42 | |
| @@ -135,14 +136,14 @@ static void ER(uint32_t opcode, uint32_t func3, · 93 unmodified lines |
| 135 | static void EI(uint32_t opcode, uint32_t func3, | 136 | static void EI(uint32_t opcode, uint32_t func3, |
| 136 | uint32_t rd, uint32_t rs1, uint32_t imm) | 137 | uint32_t rd, uint32_t rs1, uint32_t imm) |
| 137 | { | 138 | { |
| 138 | assert(! ((imm + (1 << 11)) >> 12)); | 139 | assert(! LOW_OVERFLOW(imm)); |
| 139 | EIu(opcode, func3, rd, rs1, imm); | 140 | EIu(opcode, func3, rd, rs1, imm); |
| 140 | } | 141 | } |
| 141 | | 142 | |
| 142 | static void ES(uint32_t opcode, uint32_t func3, | 143 | static void ES(uint32_t opcode, uint32_t func3, |
| 143 | uint32_t rs1, uint32_t rs2, uint32_t imm) | 144 | uint32_t rs1, uint32_t rs2, uint32_t imm) |
| 144 | { | 145 | { |
| 145 | assert(! ((imm + (1 << 11)) >> 12)); | 146 | assert(! LOW_OVERFLOW(imm)); |
| 146 | o(opcode | (func3 << 12) | ((imm & 0x1f) << 7) | (rs1 << 15) | 147 | o(opcode | (func3 << 12) | ((imm & 0x1f) << 7) | (rs1 << 15) |
| 147 | | (rs2 << 20) | ((imm >> 5) << 25)); | 148 | | (rs2 << 20) | ((imm >> 5) << 25)); |
| 148 | } | 149 | } |
| @@ -158,7 +159,7 @@ ST_FUNC void gsym_addr(int t_, int a_) · 9 unmodified lines |
| 158 | uint32_t r = a - t, imm; | 159 | uint32_t r = a - t, imm; |
| 159 | if ((r + (1 << 21)) & ~((1U << 22) - 2)) | 160 | if ((r + (1 << 21)) & ~((1U << 22) - 2)) |
| 160 | tcc_error("out-of-range branch chain"); | 161 | tcc_error("out-of-range branch chain"); |
| 161 | imm = (((r >> 12) & 0xff) << 12) | 162 | imm = (((r >> 12) & 0xff) << 12) |
| 162 | | (((r >> 11) & 1) << 20) | 163 | | (((r >> 11) & 1) << 20) |
| 163 | | (((r >> 1) & 0x3ff) << 21) | 164 | | (((r >> 1) & 0x3ff) << 21) |
| 164 | | (((r >> 20) & 1) << 31); | 165 | | (((r >> 20) & 1) << 31); |
| @@ -179,7 +180,7 @@ static int load_symofs(int r, SValue *sv, int forstore, int *new_fc) · 14 unmodified lines |
| 179 | R_RISCV_PCREL_HI20, sv->c.i); | 180 | R_RISCV_PCREL_HI20, sv->c.i); |
| 180 | *new_fc = 0; | 181 | *new_fc = 0; |
| 181 | } else { | 182 | } else { |
| 182 | if (((unsigned)fc + (1 << 11)) >> 12){ | 183 | if (LOW_OVERFLOW(fc)){ |
| 183 | large_addend = 1; | 184 | large_addend = 1; |
| 184 | } | 185 | } |
| 185 | greloca(cur_text_section, sv->sym, ind, | 186 | greloca(cur_text_section, sv->sym, ind, |
| @@ -206,7 +207,7 @@ static int load_symofs(int r, SValue *sv, int forstore, int *new_fc) · 20 unmodified lines |
| 206 | rr = 8; // s0 | 207 | rr = 8; // s0 |
| 207 | if (fc != sv->c.i) | 208 | if (fc != sv->c.i) |
| 208 | tcc_error("unimp: store(giant local off) (0x%lx)", (long)sv->c.i); | 209 | tcc_error("unimp: store(giant local off) (0x%lx)", (long)sv->c.i); |
| 209 | if (((unsigned)fc + (1 << 11)) >> 12) { | 210 | if (LOW_OVERFLOW(fc)) { |
| 210 | rr = is_ireg(r) ? ireg(r) : 5; // t0 | 211 | rr = is_ireg(r) ? ireg(r) : 5; // t0 |
| 211 | o(0x37 | (rr << 7) | UPPER(fc)); //lui RR, upper(fc) | 212 | o(0x37 | (rr << 7) | UPPER(fc)); //lui RR, upper(fc) |
| 212 | ER(0x33, 0, rr, rr, 8, 0); // add RR, RR, s0 | 213 | ER(0x33, 0, rr, rr, 8, 0); // add RR, RR, s0 |
| @@ -251,7 +252,7 @@ ST_FUNC void load(int r, SValue *sv) · 38 unmodified lines |
| 251 | br = load_symofs(r, sv, 0, &fc); | 252 | br = load_symofs(r, sv, 0, &fc); |
| 252 | } else if (v < VT_CONST) { | 253 | } else if (v < VT_CONST) { |
| 253 | br = ireg(v); | 254 | br = ireg(v); |
| 254 | /*if (((unsigned)fc + (1 << 11)) >> 12) | 255 | /*if (LOW_OVERFLOW(fc)) |
| 255 | tcc_error("unimp: load(large addend) (0x%x)", fc);*/ | 256 | tcc_error("unimp: load(large addend) (0x%x)", fc);*/ |
| 256 | fc = 0; // XXX store ofs in LVAL(reg) | 257 | fc = 0; // XXX store ofs in LVAL(reg) |
| 257 | } else if (v == VT_LLOCAL) { | 258 | } else if (v == VT_LLOCAL) { |
| @@ -297,7 +298,7 @@ ST_FUNC void load(int r, SValue *sv) · 39 unmodified lines |
| 297 | zext = 1; | 298 | zext = 1; |
| 298 | } | 299 | } |
| 299 | } | 300 | } |
| 300 | if (((unsigned)fc + (1 << 11)) >> 12) | 301 | if (LOW_OVERFLOW(fc)) |
| 301 | o(0x37 | (rr << 7) | UPPER(fc)), rb = rr; //lui RR, upper(fc) | 302 | o(0x37 | (rr << 7) | UPPER(fc)), rb = rr; //lui RR, upper(fc) |
| 302 | if (fc || (rr != rb) || do32bit || (fr & VT_SYM)) | 303 | if (fc || (rr != rb) || do32bit || (fr & VT_SYM)) |
| 303 | EI(0x13 | do32bit, 0, rr, rb, SIGN11(fc)); // addi[w] R, x0|R, FC | 304 | EI(0x13 | do32bit, 0, rr, rb, SIGN11(fc)); // addi[w] R, x0|R, FC |
| @@ -392,7 +393,7 @@ ST_FUNC void store(int r, SValue *sv) · 88 unmodified lines |
| 392 | ptrreg = load_symofs(-1, sv, 1, &fc); | 393 | ptrreg = load_symofs(-1, sv, 1, &fc); |
| 393 | } else if (fr < VT_CONST) { | 394 | } else if (fr < VT_CONST) { |
| 394 | ptrreg = ireg(fr); | 395 | ptrreg = ireg(fr); |
| 395 | /*if (((unsigned)fc + (1 << 11)) >> 12) | 396 | /*if (LOW_OVERFLOW(fc)) |
| 396 | tcc_error("unimp: store(large addend) (0x%x)", fc);*/ | 397 | tcc_error("unimp: store(large addend) (0x%x)", fc);*/ |
| 397 | fc = 0; // XXX support offsets regs | 398 | fc = 0; // XXX support offsets regs |
| 398 | } else if (fr == VT_CONST) { | 399 | } else if (fr == VT_CONST) { |
| @@ -1014,7 +1015,7 @@ static void gen_opil(int op, int ll) · 615 unmodified lines |
| 1014 | ll = ll ? 0 : 8; | 1015 | ll = ll ? 0 : 8; |
| 1015 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | 1016 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { |
| 1016 | int fc = vtop->c.i; | 1017 | int fc = vtop->c.i; |
| 1017 | if (fc == vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) { | 1018 | if (fc == vtop->c.i && !LOW_OVERFLOW(fc)) { |
| 1018 | int cll = 0; | 1019 | int cll = 0; |
| 1019 | int m = ll ? 31 : 63; | 1020 | int m = ll ? 31 : 63; |
| 1020 | vswap(); | 1021 | vswap(); |
| @@ -1381,7 +1382,7 @@ ST_FUNC void ggoto(void) · 360 unmodified lines |
| 1381 | | 1382 | |
| 1382 | ST_FUNC void gen_vla_sp_save(int addr) | 1383 | ST_FUNC void gen_vla_sp_save(int addr) |
| 1383 | { | 1384 | { |
| 1384 | if (((unsigned)addr + (1 << 11)) >> 12) { | 1385 | if (LOW_OVERFLOW(addr)) { |
| 1385 | o(0x37 | (5 << 7) | UPPER(addr)); //lui t0,upper(addr) | 1386 | o(0x37 | (5 << 7) | UPPER(addr)); //lui t0,upper(addr) |
| 1386 | ER(0x33, 0, 5, 5, 8, 0); // add t0, t0, s0 | 1387 | ER(0x33, 0, 5, 5, 8, 0); // add t0, t0, s0 |
| 1387 | ES(0x23, 3, 5, 2, SIGN11(addr)); // sd sp, fc(t0) | 1388 | ES(0x23, 3, 5, 2, SIGN11(addr)); // sd sp, fc(t0) |
| @@ -1392,7 +1393,7 @@ ST_FUNC void gen_vla_sp_save(int addr) · 4 unmodified lines |
| 1392 | | 1393 | |
| 1393 | ST_FUNC void gen_vla_sp_restore(int addr) | 1394 | ST_FUNC void gen_vla_sp_restore(int addr) |
| 1394 | { | 1395 | { |
| 1395 | if (((unsigned)addr + (1 << 11)) >> 12) { | 1396 | if (LOW_OVERFLOW(addr)) { |
| 1396 | o(0x37 | (5 << 7) | UPPER(addr)); //lui t0,upper(addr) | 1397 | o(0x37 | (5 << 7) | UPPER(addr)); //lui t0,upper(addr) |
| 1397 | ER(0x33, 0, 5, 5, 8, 0); // add t0, t0, s0 | 1398 | ER(0x33, 0, 5, 5, 8, 0); // add t0, t0, s0 |
| 1398 | EI(0x03, 3, 2, 5, SIGN11(addr)); // ld sp, fc(t0) | 1399 | EI(0x03, 3, 2, 5, SIGN11(addr)); // ld sp, fc(t0) |