| @@ -189,12 +189,22 @@ ST_FUNC void load(int r, SValue *sv) · 188 unmodified lines |
| 189 | tcc_error("unimp: load(non-local lval)"); | 189 | tcc_error("unimp: load(non-local lval)"); |
| 190 | } | 190 | } |
| 191 | } else if (v == VT_CONST) { | 191 | } else if (v == VT_CONST) { |
| 192 | int rb = 0, do32bit = 8; | 192 | int rb = 0, do32bit = 8, doload = 0; |
| 193 | assert(!is_float(sv->type.t) && is_ireg(r)); | 193 | assert(!is_float(sv->type.t) && is_ireg(r)); |
| 194 | if (fr & VT_SYM) { | 194 | if (fr & VT_SYM) { |
| 195 | static Sym label; | 195 | static Sym label; |
| 196 | greloca(cur_text_section, sv->sym, ind, | 196 | if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax |
| 197 | R_RISCV_PCREL_HI20, sv->c.i); | 197 | greloca(cur_text_section, sv->sym, ind, |
| | 198 | R_RISCV_PCREL_HI20, sv->c.i); |
| | 199 | fc = 0; |
| | 200 | sv->c.i = 0; |
| | 201 | } else { |
| | 202 | if (((unsigned)fc + (1 << 11)) >> 12) |
| | 203 | tcc_error("unimp: large addend for global address"); |
| | 204 | greloca(cur_text_section, sv->sym, ind, |
| | 205 | R_RISCV_GOT_HI20, 0); |
| | 206 | doload = 1; |
| | 207 | } |
| 198 | if (!label.v) { | 208 | if (!label.v) { |
| 199 | label.v = tok_alloc(".L0 ", 4)->tok; | 209 | label.v = tok_alloc(".L0 ", 4)->tok; |
| 200 | label.type.t = VT_VOID | VT_STATIC; | 210 | label.type.t = VT_VOID | VT_STATIC; |
| @@ -205,8 +215,6 @@ ST_FUNC void load(int r, SValue *sv) · 4 unmodified lines |
| 205 | greloca(cur_text_section, &label, ind, | 215 | greloca(cur_text_section, &label, ind, |
| 206 | R_RISCV_PCREL_LO12_I, 0); | 216 | R_RISCV_PCREL_LO12_I, 0); |
| 207 | rb = rr; | 217 | rb = rr; |
| 208 | fc = 0; | | |
| 209 | sv->c.i = 0; | | |
| 210 | do32bit = 0; | 218 | do32bit = 0; |
| 211 | } | 219 | } |
| 212 | if (is_float(sv->type.t)) | 220 | if (is_float(sv->type.t)) |
| @@ -244,7 +252,12 @@ ST_FUNC void load(int r, SValue *sv) · 31 unmodified lines |
| 244 | } | 252 | } |
| 245 | if (((unsigned)fc + (1 << 11)) >> 12) | 253 | if (((unsigned)fc + (1 << 11)) >> 12) |
| 246 | o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)), rb = rr; //lui RR, upper(fc) | 254 | o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)), rb = rr; //lui RR, upper(fc) |
| 247 | EI(0x13 | do32bit, 0, rr, rb, fc << 20 >> 20); // addi[w] R, x0|R, FC | 255 | if (doload) { |
| | 256 | EI(0x03, 3, rr, rr, 0); // ld RR, 0(RR) |
| | 257 | if (fc) |
| | 258 | EI(0x13 | do32bit, 0, rr, rr, fc << 20 >> 20); // addi[w] R, x0|R, FC |
| | 259 | } else |
| | 260 | EI(0x13 | do32bit, 0, rr, rb, fc << 20 >> 20); // addi[w] R, x0|R, FC |
| 248 | } else if (v == VT_LOCAL) { | 261 | } else if (v == VT_LOCAL) { |
| 249 | assert(is_ireg(r)); | 262 | assert(is_ireg(r)); |
| 250 | if (((unsigned)fc + (1 << 11)) >> 12) | 263 | if (((unsigned)fc + (1 << 11)) >> 12) |
| @@ -636,7 +649,6 @@ static void gen_opil(int op, int ll) · 385 unmodified lines |
| 636 | d = ireg(d); | 649 | d = ireg(d); |
| 637 | ll = ll ? 0 : 8; | 650 | ll = ll ? 0 : 8; |
| 638 | switch (op) { | 651 | switch (op) { |
| 639 | case '%': | | |
| 640 | case TOK_PDIV: | 652 | case TOK_PDIV: |
| 641 | default: | 653 | default: |
| 642 | tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL)); | 654 | tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL)); |
| @@ -671,6 +683,9 @@ static void gen_opil(int op, int ll) · 28 unmodified lines |
| 671 | case '|': | 683 | case '|': |
| 672 | o(0x33 | (d << 7) | (a << 15) | (b << 20) | (6 << 12)); // or d, a, b | 684 | o(0x33 | (d << 7) | (a << 15) | (b << 20) | (6 << 12)); // or d, a, b |
| 673 | break; | 685 | break; |
| | 686 | case '%': |
| | 687 | o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x01 << 25) | (6 << 12)); //rem d, a, b |
| | 688 | break; |
| 674 | case TOK_UMOD: | 689 | case TOK_UMOD: |
| 675 | o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x01 << 25) | (7 << 12)); //remu d, a, b | 690 | o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x01 << 25) | (7 << 12)); //remu d, a, b |
| 676 | break; | 691 | break; |