riscv: Implement large addend for global address
This commit is contained in:
parent
2656f8edcc
commit
7bc0cb5ba0
1 changed files with 9 additions and 3 deletions
|
@ -166,7 +166,7 @@ ST_FUNC void gsym_addr(int t_, int a_)
|
||||||
|
|
||||||
static int load_symofs(int r, SValue *sv, int forstore)
|
static int load_symofs(int r, SValue *sv, int forstore)
|
||||||
{
|
{
|
||||||
int rr, doload = 0;
|
int rr, doload = 0, large_addend = 0;
|
||||||
int fc = sv->c.i, v = sv->r & VT_VALMASK;
|
int fc = sv->c.i, v = sv->r & VT_VALMASK;
|
||||||
if (sv->r & VT_SYM) {
|
if (sv->r & VT_SYM) {
|
||||||
Sym label = {0};
|
Sym label = {0};
|
||||||
|
@ -176,8 +176,9 @@ static int load_symofs(int r, SValue *sv, int forstore)
|
||||||
R_RISCV_PCREL_HI20, sv->c.i);
|
R_RISCV_PCREL_HI20, sv->c.i);
|
||||||
sv->c.i = 0;
|
sv->c.i = 0;
|
||||||
} else {
|
} else {
|
||||||
if (((unsigned)fc + (1 << 11)) >> 12)
|
if (((unsigned)fc + (1 << 11)) >> 12){
|
||||||
tcc_error("unimp: large addend for global address (0x%lx)", (long)sv->c.i);
|
large_addend = 1;
|
||||||
|
}
|
||||||
greloca(cur_text_section, sv->sym, ind,
|
greloca(cur_text_section, sv->sym, ind,
|
||||||
R_RISCV_GOT_HI20, 0);
|
R_RISCV_GOT_HI20, 0);
|
||||||
doload = 1;
|
doload = 1;
|
||||||
|
@ -192,6 +193,11 @@ static int load_symofs(int r, SValue *sv, int forstore)
|
||||||
? R_RISCV_PCREL_LO12_I : R_RISCV_PCREL_LO12_S, 0);
|
? R_RISCV_PCREL_LO12_I : R_RISCV_PCREL_LO12_S, 0);
|
||||||
if (doload) {
|
if (doload) {
|
||||||
EI(0x03, 3, rr, rr, 0); // ld RR, 0(RR)
|
EI(0x03, 3, rr, rr, 0); // ld RR, 0(RR)
|
||||||
|
if (large_addend) {
|
||||||
|
o(0x37 | (5 << 7) | ((0x800 + fc) & 0xfffff000)); //lui t0, high(fc)
|
||||||
|
ER(0x33, 0, rr, rr, 5, 0); // add RR, RR, t0
|
||||||
|
sv->c.i = fc << 20 >> 20;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (v == VT_LOCAL || v == VT_LLOCAL) {
|
} else if (v == VT_LOCAL || v == VT_LLOCAL) {
|
||||||
rr = 8; // s0
|
rr = 8; // s0
|
||||||
|
|
Loading…
Add table
Reference in a new issue