mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-26 08:00:09 +08:00
64bit: Fix addends > 32 bits
If a symbolic reference is offsetted by a constant > 32bit the backends can't deal with that, so don't construct such values.
This commit is contained in:
parent
a2a596e767
commit
235711f3d3
7
tccgen.c
7
tccgen.c
@ -1775,8 +1775,13 @@ static void gen_opic(int op)
|
|||||||
/* symbol + constant case */
|
/* symbol + constant case */
|
||||||
if (op == '-')
|
if (op == '-')
|
||||||
l2 = -l2;
|
l2 = -l2;
|
||||||
|
l2 += vtop[-1].c.i;
|
||||||
|
/* The backends can't always deal with addends to symbols
|
||||||
|
larger than +-1<<31. Don't construct such. */
|
||||||
|
if ((int)l2 != l2)
|
||||||
|
goto general_case;
|
||||||
vtop--;
|
vtop--;
|
||||||
vtop->c.i += l2;
|
vtop->c.i = l2;
|
||||||
} else {
|
} else {
|
||||||
general_case:
|
general_case:
|
||||||
if (!nocode_wanted) {
|
if (!nocode_wanted) {
|
||||||
|
@ -2429,6 +2429,19 @@ void getmyaddress(void)
|
|||||||
{
|
{
|
||||||
printf("in getmyaddress\n");
|
printf("in getmyaddress\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __LP64__
|
||||||
|
long __pa_symbol(void)
|
||||||
|
{
|
||||||
|
/* This 64bit constant was handled incorrectly, it was used as addend
|
||||||
|
(which can hold 64bit just fine) in connection with a symbol,
|
||||||
|
and TCC generates wrong code for that (displacements are 32bit only).
|
||||||
|
This effectively is "+ 0x80000000", and if addresses of globals
|
||||||
|
are below 2GB the result should be a number without high 32 bits set. */
|
||||||
|
return ((long)(((unsigned long)(&rel1))) - (0xffffffff80000000UL));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned long theaddress = (unsigned long)getmyaddress;
|
unsigned long theaddress = (unsigned long)getmyaddress;
|
||||||
void relocation_test(void)
|
void relocation_test(void)
|
||||||
{
|
{
|
||||||
@ -2436,6 +2449,9 @@ void relocation_test(void)
|
|||||||
printf("*rel1=%d\n", *rel1);
|
printf("*rel1=%d\n", *rel1);
|
||||||
printf("*rel2=%d\n", *rel2);
|
printf("*rel2=%d\n", *rel2);
|
||||||
fptr();
|
fptr();
|
||||||
|
#ifdef __LP64__
|
||||||
|
printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void old_style_f(a,b,c)
|
void old_style_f(a,b,c)
|
||||||
|
@ -349,6 +349,8 @@ void load(int r, SValue *sv)
|
|||||||
fr = sv->r;
|
fr = sv->r;
|
||||||
ft = sv->type.t & ~VT_DEFSIGN;
|
ft = sv->type.t & ~VT_DEFSIGN;
|
||||||
fc = sv->c.i;
|
fc = sv->c.i;
|
||||||
|
if (fc != sv->c.i && (fr & VT_SYM))
|
||||||
|
tcc_error("64 bit addend in load");
|
||||||
|
|
||||||
ft &= ~(VT_VOLATILE | VT_CONSTANT);
|
ft &= ~(VT_VOLATILE | VT_CONSTANT);
|
||||||
|
|
||||||
@ -528,9 +530,11 @@ void store(int r, SValue *v)
|
|||||||
v = pe_getimport(v, &v2);
|
v = pe_getimport(v, &v2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
fr = v->r & VT_VALMASK;
|
||||||
ft = v->type.t;
|
ft = v->type.t;
|
||||||
fc = v->c.i;
|
fc = v->c.i;
|
||||||
fr = v->r & VT_VALMASK;
|
if (fc != v->c.i && (fr & VT_SYM))
|
||||||
|
tcc_error("64 bit addend in store");
|
||||||
ft &= ~(VT_VOLATILE | VT_CONSTANT);
|
ft &= ~(VT_VOLATILE | VT_CONSTANT);
|
||||||
bt = ft & VT_BTYPE;
|
bt = ft & VT_BTYPE;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user