mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
AArch64 does not have LEA, fake it (#21064)
This commit is contained in:
parent
0ae065db22
commit
c4d45a1a49
3 changed files with 24 additions and 6 deletions
|
@ -58,6 +58,7 @@ nothrow:
|
|||
void loadFromEA(ref code cs, reg_t reg, uint szw, uint szr)
|
||||
{
|
||||
//debug printf("loadFromEA() reg: %d, szw: %d, szr: %d\n", reg, szw, szr);
|
||||
//debug printf("EV1.Voffset: %d\n", cast(int)cs.IEV1.Voffset);
|
||||
assert(szr <= szw);
|
||||
cs.Iop = INSTR.nop;
|
||||
assert(reg != NOREG);
|
||||
|
@ -496,6 +497,7 @@ void loadea(ref CodeBuilder cdb,elem* e,ref code cs,uint op,reg_t reg,targ_size_
|
|||
getlvalue(cdb, cs, e, keepmsk, rmx);
|
||||
cs.IEV1.Voffset += offset;
|
||||
|
||||
assert(op != LEA); // AArch64 does not have LEA
|
||||
loadFromEA(cs,reg,sz == 8 ? 8 : 4,sz);
|
||||
|
||||
getregs(cdb, desmsk); // save any regs we destroy
|
||||
|
|
|
@ -1371,9 +1371,16 @@ static if (0)
|
|||
}
|
||||
else
|
||||
{
|
||||
loadea(cdb,e,cs,LEA,reg,0,0,0); // LEA reg,EA
|
||||
if (I64)
|
||||
code_orrex(cdb.last(), REX_W);
|
||||
uint sh = 0;
|
||||
uint base = 0;
|
||||
cs.Iop = INSTR.addsub_imm(1,0,0,sh,base,cgstate.BP,reg); // ADD reg,BP,base
|
||||
cs.IFL1 = fl;
|
||||
cs.IEV1.Vsym = e.Vsym;
|
||||
cs.IEV1.Voffset = 0;
|
||||
cdb.gen(&cs);
|
||||
cdb.gen1(INSTR.addsub_imm(1,0,0,sh,cast(uint)e.Voffset,reg,reg)); // ADD reg,reg,Voffset
|
||||
// TODO AArch64 common subexpressions?
|
||||
//loadea(cdb,e,cs,LEA,reg,0,0,0); // LEA reg,EA
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -1295,7 +1295,7 @@ void assignaddrc(code* c)
|
|||
s = c.IEV1.Vsym;
|
||||
uint sz = 8;
|
||||
uint ins = c.Iop;
|
||||
if (0 && c.IFL1 != FL.unde)
|
||||
if (c.IFL1 != FL.unde)
|
||||
{
|
||||
printf("FL: %-8s ", fl_str(c.IFL1));
|
||||
disassemble(ins);
|
||||
|
@ -1428,7 +1428,6 @@ void assignaddrc(code* c)
|
|||
L2:
|
||||
offset = cast(int)offset; // sign extend
|
||||
// Load/store register (unsigned immediate) https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#ldst_pos
|
||||
assert(field(ins,29,27) == 7);
|
||||
uint opc = field(ins,23,22);
|
||||
uint shift = field(ins,31,30); // 0:1 1:2 2:4 3:8 shift for imm12
|
||||
uint op24 = field(ins,25,24);
|
||||
|
@ -1436,9 +1435,18 @@ void assignaddrc(code* c)
|
|||
if (cgstate.hasframe)
|
||||
offset += REGSIZE * 2;
|
||||
offset += localsize;
|
||||
if (op24 == 1)
|
||||
if (field(ins,28,23) == 0x22) // Add/subtract (immediate)
|
||||
{
|
||||
uint imm12 = field(ins,21,10); // unsigned 12 bits
|
||||
//printf("imm12: %d offset: %llx\n", imm12, offset);
|
||||
imm12 += offset;
|
||||
assert(imm12 < 0x1000);
|
||||
ins = setField(ins,21,10,imm12);
|
||||
}
|
||||
else if (op24 == 1)
|
||||
{
|
||||
assert(field(ins,29,27) == 7);
|
||||
uint imm12 = field(ins,21,10); // unsigned 12 bits
|
||||
offset += imm12 << shift; // add in imm
|
||||
//printf("shift: %d offset: %llx imm12: %x\n", shift, offset, imm12);
|
||||
assert((offset & ((1 << shift) - 1)) == 0); // no misaligned access
|
||||
|
@ -1448,6 +1456,7 @@ void assignaddrc(code* c)
|
|||
}
|
||||
else if (op24 == 0)
|
||||
{
|
||||
assert(field(ins,29,27) == 7);
|
||||
if (opc == 2 && shift == 0)
|
||||
shift = 4;
|
||||
uint imm9 = field(ins,20,12); // signed 9 bits
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue