mirror of
https://github.com/dlang/dmd.git
synced 2025-04-27 21:51:03 +03:00
AArch64 doesn't have LEA instruction, so use pointers instead of Effective Address (#21072)
This commit is contained in:
parent
2036516c17
commit
63152e453c
6 changed files with 27 additions and 10 deletions
|
@ -1067,7 +1067,7 @@ void cdind(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
|
||||||
|
|
||||||
uint decode(uint to, uint from, bool uns) { return to * 4 * 2 + from * 2 + uns; }
|
uint decode(uint to, uint from, bool uns) { return to * 4 * 2 + from * 2 + uns; }
|
||||||
|
|
||||||
switch (decode(4, sz, uns))
|
switch (decode(sz == 8 ? 8 : 4, sz, uns))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
int = *byte ldrsb w0,[x1] 39C00020
|
int = *byte ldrsb w0,[x1] 39C00020
|
||||||
|
|
|
@ -140,6 +140,7 @@ enum
|
||||||
SCSCT = 4, // storage class is valid for use in static ctor
|
SCSCT = 4, // storage class is valid for use in static ctor
|
||||||
SCSS = 8, // storage class is on the stack
|
SCSS = 8, // storage class is on the stack
|
||||||
SCRD = 0x10, // we can do reaching definitions on these
|
SCRD = 0x10, // we can do reaching definitions on these
|
||||||
|
SCDATA = 0x20, // goes in data segment
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine if Symbol has a Ssymnum associated with it.
|
// Determine if Symbol has a Ssymnum associated with it.
|
||||||
|
|
|
@ -3286,6 +3286,8 @@ private elem* elind(elem* e, Goal goal)
|
||||||
switch (e1.Eoper)
|
switch (e1.Eoper)
|
||||||
{
|
{
|
||||||
case OPrelconst:
|
case OPrelconst:
|
||||||
|
if (sytab[e1.Vsym.Sclass] & SCDATA && e1.Vsym.Sfl != FL.func && cgstate.AArch64)
|
||||||
|
break;
|
||||||
e.E1.ET = e.ET;
|
e.E1.ET = e.ET;
|
||||||
e = el_selecte1(e);
|
e = el_selecte1(e);
|
||||||
e.Eoper = OPvar;
|
e.Eoper = OPvar;
|
||||||
|
|
|
@ -2762,8 +2762,11 @@ size_t ElfObj_writerel(int targseg, size_t offset, reltype_t reltype,
|
||||||
{
|
{
|
||||||
// Elf64_Rela stores addend in Rela.r_addend field
|
// Elf64_Rela stores addend in Rela.r_addend field
|
||||||
sz = relsize64(reltype);
|
sz = relsize64(reltype);
|
||||||
if (!elfobj.AArch64)
|
if (!elfobj.AArch64 || reltype == R_AARCH64_ABS64) // TODO AArch64: extend to all fixups?
|
||||||
|
{
|
||||||
|
//printf("writeaddrval() targseg: %d offset: %lld sz: %lld\n", targseg, offset, sz);
|
||||||
writeaddrval(targseg, offset, 0, sz);
|
writeaddrval(targseg, offset, 0, sz);
|
||||||
|
}
|
||||||
ElfObj_addrel(targseg, offset, reltype, symidx, val);
|
ElfObj_addrel(targseg, offset, reltype, symidx, val);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -113,17 +113,17 @@ tym_t pointertype = TYnptr; /* default data pointer type */
|
||||||
* SCxxxx types.
|
* SCxxxx types.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char[SCMAX] sytab =
|
ubyte[SCMAX] sytab =
|
||||||
[
|
[
|
||||||
/* unde */ SCEXP|SCKEP|SCSCT, /* undefined */
|
/* unde */ SCEXP|SCKEP|SCSCT, /* undefined */
|
||||||
/* auto */ SCEXP|SCSS|SCRD , /* automatic (stack) */
|
/* auto */ SCEXP|SCSS|SCRD , /* automatic (stack) */
|
||||||
/* static */ SCEXP|SCKEP|SCSCT, /* statically allocated */
|
/* static */ SCEXP|SCKEP|SCSCT|SCDATA, /* statically allocated */
|
||||||
/* thread */ SCEXP|SCKEP , /* thread local */
|
/* thread */ SCEXP|SCKEP , /* thread local */
|
||||||
/* extern */ SCEXP|SCKEP|SCSCT, /* external */
|
/* extern */ SCEXP|SCKEP|SCSCT|SCDATA, /* external */
|
||||||
/* register */ SCEXP|SCSS|SCRD , /* registered variable */
|
/* register */ SCEXP|SCSS|SCRD , /* registered variable */
|
||||||
/* pseudo */ SCEXP , /* pseudo register variable */
|
/* pseudo */ SCEXP , /* pseudo register variable */
|
||||||
/* global */ SCEXP|SCKEP|SCSCT, /* top level global definition */
|
/* global */ SCEXP|SCKEP|SCSCT|SCDATA, /* top level global definition */
|
||||||
/* comdat */ SCEXP|SCKEP|SCSCT, /* initialized common block */
|
/* comdat */ SCEXP|SCKEP|SCSCT|SCDATA, /* initialized common block */
|
||||||
/* parameter */SCEXP|SCSS , /* function parameter */
|
/* parameter */SCEXP|SCSS , /* function parameter */
|
||||||
/* regpar */ SCEXP|SCSS , /* function register parameter */
|
/* regpar */ SCEXP|SCSS , /* function register parameter */
|
||||||
/* fastpar */ SCEXP|SCSS , /* function parameter passed in register */
|
/* fastpar */ SCEXP|SCSS , /* function parameter passed in register */
|
||||||
|
@ -144,13 +144,13 @@ char[SCMAX] sytab =
|
||||||
/* overload */ SCEXP , /* for overloaded function names */
|
/* overload */ SCEXP , /* for overloaded function names */
|
||||||
/* friend */ 0 , /* friend of a class */
|
/* friend */ 0 , /* friend of a class */
|
||||||
/* virtual */ 0 , /* virtual function */
|
/* virtual */ 0 , /* virtual function */
|
||||||
/* locstat */ SCEXP|SCSCT , /* static, but local to a function */
|
/* locstat */ SCEXP|SCSCT|SCDATA, /* static, but local to a function */
|
||||||
/* template */ 0 , /* class template */
|
/* template */ 0 , /* class template */
|
||||||
/* functempl */0 , /* function template */
|
/* functempl */0 , /* function template */
|
||||||
/* ftexpspec */0 , /* function template explicit specialization */
|
/* ftexpspec */0 , /* function template explicit specialization */
|
||||||
/* linkage */ 0 , /* function linkage symbol */
|
/* linkage */ 0 , /* function linkage symbol */
|
||||||
/* public */ SCEXP|SCKEP|SCSCT, /* generate a pubdef for this */
|
/* public */ SCEXP|SCKEP|SCSCT, /* generate a pubdef for this */
|
||||||
/* comdef */ SCEXP|SCKEP|SCSCT, /* uninitialized common block */
|
/* comdef */ SCEXP|SCKEP|SCSCT|SCDATA, /* uninitialized common block */
|
||||||
/* bprel */ SCEXP|SCSS , /* variable at fixed offset from frame pointer */
|
/* bprel */ SCEXP|SCSS , /* variable at fixed offset from frame pointer */
|
||||||
/* namespace */0 , /* namespace */
|
/* namespace */0 , /* namespace */
|
||||||
/* alias */ 0 , /* alias to another symbol */
|
/* alias */ 0 , /* alias to another symbol */
|
||||||
|
|
|
@ -769,7 +769,18 @@ elem* toElem(Expression e, ref IRState irs)
|
||||||
e = el_bin(OPadd, TYnptr, e, el_long(TYsize_t, offset));
|
e = el_bin(OPadd, TYnptr, e, el_long(TYsize_t, offset));
|
||||||
}
|
}
|
||||||
else if (se.op == EXP.variable)
|
else if (se.op == EXP.variable)
|
||||||
e = el_var(s);
|
{
|
||||||
|
if (sytab[s.Sclass] & SCDATA && s.Sfl != FL.func && target.isAArch64)
|
||||||
|
{
|
||||||
|
/* AArch64 does not have an LEA instruction,
|
||||||
|
* so access data segment data via a pointer
|
||||||
|
*/
|
||||||
|
e = el_ptr(s);
|
||||||
|
e = el_una(OPind,s.Stype.Tty,e); // e = * & s
|
||||||
|
}
|
||||||
|
else
|
||||||
|
e = el_var(s);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
e = nrvo ? el_var(s) : el_ptr(s);
|
e = nrvo ? el_var(s) : el_ptr(s);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue