x86-64: fix load() for const pointers: (void*)-2

tcc-xref
grischka 2009-07-18 22:07:03 +02:00
parent fc977d56c9
commit bb5e0df79a
1 changed files with 22 additions and 21 deletions

View File

@ -191,6 +191,7 @@ static int oad(int c, int s)
return s; return s;
} }
#if 0
/* output constant with relocation if 'r & VT_SYM' is true */ /* output constant with relocation if 'r & VT_SYM' is true */
static void gen_addr64(int r, Sym *sym, int64_t c) static void gen_addr64(int r, Sym *sym, int64_t c)
{ {
@ -198,6 +199,7 @@ static void gen_addr64(int r, Sym *sym, int64_t c)
greloc(cur_text_section, sym, ind, R_X86_64_64); greloc(cur_text_section, sym, ind, R_X86_64_64);
gen_le64(c); gen_le64(c);
} }
#endif
/* output constant with relocation if 'r & VT_SYM' is true */ /* output constant with relocation if 'r & VT_SYM' is true */
static void gen_addrpc32(int r, Sym *sym, int c) static void gen_addrpc32(int r, Sym *sym, int c)
@ -354,30 +356,29 @@ void load(int r, SValue *sv)
gen_modrm(r, fr, sv->sym, fc); gen_modrm(r, fr, sv->sym, fc);
} else { } else {
if (v == VT_CONST) { if (v == VT_CONST) {
if ((ft & VT_BTYPE) == VT_LLONG) { if (fr & VT_SYM) {
assert(!(fr & VT_SYM)); #ifdef TCC_TARGET_PE
o(0x8d48);
o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */
gen_addrpc32(fr, sv->sym, fc);
#else
if (sv->sym->type.t & VT_STATIC) {
o(0x8d48);
o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */
gen_addrpc32(fr, sv->sym, fc);
} else {
o(0x8b48);
o(0x05 + REG_VALUE(r) * 8); /* mov xx(%rip), r */
gen_gotpcrel(r, sv->sym, fc);
}
#endif
} else if (is64_type(ft)) {
o(0x48); o(0x48);
o(0xb8 + REG_VALUE(r)); /* mov $xx, r */ o(0xb8 + REG_VALUE(r)); /* mov $xx, r */
gen_addr64(fr, sv->sym, sv->c.ull); gen_le64(sv->c.ull);
} else { } else {
if (fr & VT_SYM) { o(0xb8 + REG_VALUE(r)); /* mov $xx, r */
#ifndef TCC_TARGET_PE gen_le32(fc);
if (sv->sym->type.t & VT_STATIC) {
#endif
o(0x8d48);
o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */
gen_addrpc32(fr, sv->sym, fc);
#ifndef TCC_TARGET_PE
} else {
o(0x8b48);
o(0x05 + REG_VALUE(r) * 8); /* mov xx(%rip), r */
gen_gotpcrel(r, sv->sym, fc);
}
#endif
} else {
o(0xb8 + REG_VALUE(r)); /* mov $xx, r */
gen_le32(fc);
}
} }
} else if (v == VT_LOCAL) { } else if (v == VT_LOCAL) {
o(0x48 | REX_BASE(r)); o(0x48 | REX_BASE(r));