mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
fix offsets in prolog_saveregs/restoreregs (#21251)
This commit is contained in:
parent
d6602a6b0f
commit
93d2e53e94
2 changed files with 32 additions and 13 deletions
|
@ -341,7 +341,8 @@ void genBranch(ref CodeBuilder cdb, COND cond, FL fltarg, block* targ)
|
||||||
@trusted
|
@trusted
|
||||||
void prolog_saveregs(ref CGstate cg, ref CodeBuilder cdb, regm_t topush, int cfa_offset)
|
void prolog_saveregs(ref CGstate cg, ref CodeBuilder cdb, regm_t topush, int cfa_offset)
|
||||||
{
|
{
|
||||||
printf("prolog_saveregs() topush: %s pushoffuse: %d\n", regm_str(topush), cg.pushoffuse);
|
//printf("prolog_saveregs() topush: %s pushoffuse: %d\n", regm_str(topush), cg.pushoffuse);
|
||||||
|
//printf("function: %s\n", funcsym_p.Sident.ptr);
|
||||||
assert(!(topush & ~fregsaved));
|
assert(!(topush & ~fregsaved));
|
||||||
assert(cg.pushoffuse || !topush);
|
assert(cg.pushoffuse || !topush);
|
||||||
|
|
||||||
|
@ -349,6 +350,7 @@ void prolog_saveregs(ref CGstate cg, ref CodeBuilder cdb, regm_t topush, int cfa
|
||||||
int xmmtopush = 0;
|
int xmmtopush = 0;
|
||||||
int gptopush = popcnt(topush); // general purpose registers to save
|
int gptopush = popcnt(topush); // general purpose registers to save
|
||||||
targ_size_t gpoffset = cg.pushoff + cg.BPoff;
|
targ_size_t gpoffset = cg.pushoff + cg.BPoff;
|
||||||
|
gpoffset += localsize;
|
||||||
reg_t fp; // frame pointer
|
reg_t fp; // frame pointer
|
||||||
if (!cg.hasframe || cg.enforcealign)
|
if (!cg.hasframe || cg.enforcealign)
|
||||||
{
|
{
|
||||||
|
@ -391,6 +393,7 @@ void prolog_saveregs(ref CGstate cg, ref CodeBuilder cdb, regm_t topush, int cfa
|
||||||
@trusted
|
@trusted
|
||||||
private void epilog_restoreregs(ref CGstate cg, ref CodeBuilder cdb, regm_t topop)
|
private void epilog_restoreregs(ref CGstate cg, ref CodeBuilder cdb, regm_t topop)
|
||||||
{
|
{
|
||||||
|
//printf("prolog_restoreregs() topop: %s\n", regm_str(topop));
|
||||||
assert(cg.AArch64);
|
assert(cg.AArch64);
|
||||||
|
|
||||||
assert(cg.pushoffuse || !topop);
|
assert(cg.pushoffuse || !topop);
|
||||||
|
@ -399,6 +402,7 @@ private void epilog_restoreregs(ref CGstate cg, ref CodeBuilder cdb, regm_t topo
|
||||||
int xmmtopop = popcnt(topop & XMMREGS); // XMM regs take 16 bytes
|
int xmmtopop = popcnt(topop & XMMREGS); // XMM regs take 16 bytes
|
||||||
int gptopop = popcnt(topop); // general purpose registers to save
|
int gptopop = popcnt(topop); // general purpose registers to save
|
||||||
targ_size_t gpoffset = cg.pushoff + cg.BPoff;
|
targ_size_t gpoffset = cg.pushoff + cg.BPoff;
|
||||||
|
gpoffset += localsize;
|
||||||
|
|
||||||
reg_t fp;
|
reg_t fp;
|
||||||
if (!cg.hasframe || cg.enforcealign)
|
if (!cg.hasframe || cg.enforcealign)
|
||||||
|
@ -416,7 +420,7 @@ private void epilog_restoreregs(ref CGstate cg, ref CodeBuilder cdb, regm_t topo
|
||||||
|
|
||||||
const ins = (mask(reg) & INSTR.FLOATREGS)
|
const ins = (mask(reg) & INSTR.FLOATREGS)
|
||||||
// https://www.scs.stanford.edu/~zyedidia/arm64/ldr_imm_fpsimd.html
|
// https://www.scs.stanford.edu/~zyedidia/arm64/ldr_imm_fpsimd.html
|
||||||
? INSTR.ldr_imm_fpsimd(3,0,cast(uint)gpoffset >> 3,fp,reg) // LDR reg,[fp,#offset]
|
? INSTR.ldr_imm_fpsimd(3,1,cast(uint)gpoffset >> 3,fp,reg) // LDR reg,[fp,#offset]
|
||||||
: INSTR.ldr_imm_gen(1, reg, fp, gpoffset); // LDR reg,[fp,#offset]
|
: INSTR.ldr_imm_gen(1, reg, fp, gpoffset); // LDR reg,[fp,#offset]
|
||||||
cdb.gen1(ins);
|
cdb.gen1(ins);
|
||||||
gpoffset += REGSIZE;
|
gpoffset += REGSIZE;
|
||||||
|
@ -705,7 +709,7 @@ void epilog(block* b)
|
||||||
* order they were pushed.
|
* order they were pushed.
|
||||||
*/
|
*/
|
||||||
topop = fregsaved & ~cgstate.mfuncreg;
|
topop = fregsaved & ~cgstate.mfuncreg;
|
||||||
// epilog_restoreregs(cdbx, topop); // implement
|
epilog_restoreregs(cgstate, cdbx, topop);
|
||||||
|
|
||||||
if (cgstate.usednteh & NTEHjmonitor)
|
if (cgstate.usednteh & NTEHjmonitor)
|
||||||
{
|
{
|
||||||
|
|
|
@ -795,13 +795,27 @@ else
|
||||||
/* Instead of pushing the registers onto the stack one by one,
|
/* Instead of pushing the registers onto the stack one by one,
|
||||||
* allocate space in the stack frame and copy/restore them there.
|
* allocate space in the stack frame and copy/restore them there.
|
||||||
*/
|
*/
|
||||||
int xmmtopush = popcnt(topush & XMMREGS); // XMM regs take 16 bytes
|
if (cg.AArch64)
|
||||||
int gptopush = popcnt(topush) - xmmtopush; // general purpose registers to save
|
|
||||||
if (cg.NDPoff || xmmtopush || cg.funcarg.size)
|
|
||||||
{
|
{
|
||||||
cg.pushoff = alignsection(cg.pushoff - (gptopush * REGSIZE + xmmtopush * 16),
|
//printf("topush: %s\n", regm_str(topush));
|
||||||
xmmtopush ? STACKALIGN : REGSIZE, bias);
|
int numtopush = popcnt(topush);
|
||||||
cg.pushoffuse = true; // tell others we're using this strategy
|
if (numtopush || cg.funcarg.size)
|
||||||
|
{
|
||||||
|
cg.pushoff = alignsection(cg.pushoff - numtopush * REGSIZE,
|
||||||
|
REGSIZE, bias);
|
||||||
|
cg.pushoffuse = true; // tell others we're using this strategy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int xmmtopush = popcnt(topush & XMMREGS); // XMM regs take 16 bytes
|
||||||
|
int gptopush = popcnt(topush) - xmmtopush; // general purpose registers to save
|
||||||
|
if (cg.NDPoff || xmmtopush || cg.funcarg.size)
|
||||||
|
{
|
||||||
|
cg.pushoff = alignsection(cg.pushoff - (gptopush * REGSIZE + xmmtopush * 16),
|
||||||
|
xmmtopush ? STACKALIGN : REGSIZE, bias);
|
||||||
|
cg.pushoffuse = true; // tell others we're using this strategy
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -823,8 +837,8 @@ else
|
||||||
localsize = -cg.funcarg.offset;
|
localsize = -cg.funcarg.offset;
|
||||||
|
|
||||||
static if (0)
|
static if (0)
|
||||||
printf("Alloca.offset = x%llx, cstop = x%llx, CSoff = x%llx, NDPoff = x%llx, localsize = x%llx\n",
|
printf("Alloca.offset: x%llx cstop: x%llx CSoff: x%llx NDPoff: x%llx pushoff: x%llx localsize: x%llx\n",
|
||||||
cast(long)cg.Alloca.offset, cast(long)CSE.size(), cast(long)cg.CSoff, cast(long)cg.NDPoff, cast(long)localsize);
|
cast(long)cg.Alloca.offset, cast(long)CSE.size(), cast(long)cg.CSoff, cast(long)cg.NDPoff, cast(long)cg.pushoff, cast(long)localsize);
|
||||||
assert(cast(targ_ptrdiff_t)localsize >= 0);
|
assert(cast(targ_ptrdiff_t)localsize >= 0);
|
||||||
|
|
||||||
// Keep the stack aligned by 8 for any subsequent function calls
|
// Keep the stack aligned by 8 for any subsequent function calls
|
||||||
|
@ -855,8 +869,8 @@ else
|
||||||
cg.funcarg.offset = -localsize;
|
cg.funcarg.offset = -localsize;
|
||||||
|
|
||||||
static if (0)
|
static if (0)
|
||||||
printf("Foff x%02x Auto.size x%02x NDPoff x%02x CSoff x%02x Para.size x%02x localsize x%02x\n",
|
printf("Foff x%02x Auto.size x%02x NDPoff x%02x CSoff x%02x Para.size x%02x pushoff x%02x localsize x%02x\n",
|
||||||
cast(int)cg.Foff,cast(int)cg.Auto.size,cast(int)cg.NDPoff,cast(int)cg.CSoff,cast(int)cg.Para.size,cast(int)localsize);
|
cast(int)cg.Foff,cast(int)cg.Auto.size,cast(int)cg.NDPoff,cast(int)cg.CSoff,cast(int)cg.Para.size,cast(int)cg.pushoff,cast(int)localsize);
|
||||||
|
|
||||||
uint xlocalsize = cast(uint)localsize; // amount to subtract from ESP to make room for locals
|
uint xlocalsize = cast(uint)localsize; // amount to subtract from ESP to make room for locals
|
||||||
|
|
||||||
|
@ -924,6 +938,7 @@ else
|
||||||
}
|
}
|
||||||
else if (cg.needframe) // if variables or parameters
|
else if (cg.needframe) // if variables or parameters
|
||||||
{
|
{
|
||||||
|
// xlocalsize can be adjusted for NTEXCEPTIONS==2
|
||||||
prolog_frame(cg, cdbx, farfunc, xlocalsize, enter, cfa_offset);
|
prolog_frame(cg, cdbx, farfunc, xlocalsize, enter, cfa_offset);
|
||||||
cg.hasframe = true;
|
cg.hasframe = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue