Skip to content

Commit

Permalink
Implemented stack frame creation and tear down functions.
Browse files Browse the repository at this point in the history
This commit implements EmitterAARCH64SaveRegs::createFrame and
EmitterAARCH64RestoreRegs::tearFrame, mimicking the stack frame creation
and tear down functionality followed by ARM64 binaries. The check for
the link register in saveSPR/restoreSPR is also removed since the link
register will no longer be handled as a SPR.
  • Loading branch information
ssunny7 committed Mar 9, 2017
1 parent ed027c4 commit cd6c19f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 43 deletions.
4 changes: 2 additions & 2 deletions dyninstAPI/src/emit-aarch64.h
Expand Up @@ -233,7 +233,7 @@ class EmitterAARCH64SaveRegs {

unsigned saveSPRegisters(codeGen &gen, registerSpace *, int force_save);

void createFrame(codeGen &gen);
void createFrame(codeGen &gen, EmitterAARCH64SaveRegs saveRegs);

private:
void saveSPR(codeGen &gen, Register scratchReg, int sprnum, int stkOffset);
Expand All @@ -255,7 +255,7 @@ class EmitterAARCH64RestoreRegs {

unsigned restoreSPRegisters(codeGen &gen, registerSpace *, int force_save);

void tearFrame(codeGen &gen);
void tearFrame(codeGen &gen, EmitterAARCH64RestoreRegs restoreRegs);

private:
void restoreSPR(codeGen &gen, Register scratchReg, int sprnum, int stkOffset);
Expand Down
90 changes: 49 additions & 41 deletions dyninstAPI/src/inst-aarch64.C
Expand Up @@ -119,7 +119,7 @@ void registerSpace::initialize64() {
char name[32];
sprintf(name, "fpr%d", idx - fpr0);
registers.push_back(new registerSlot(idx,
name,
name,//TODO mov SP to FP
false,
registerSlot::liveAlways,
registerSlot::FPR));
Expand Down Expand Up @@ -149,22 +149,18 @@ void EmitterAARCH64SaveRegs::saveSPR(codeGen &gen, Register scratchReg, int sprn
if(!sysRegCodeMap.count(sprnum))
assert(!"Invalid/unknown system register passed to saveSPR()!");

if(sprnum != SPR_LR) {
instruction insn;
insn.clear();

//Set opcode for MRS instruction
INSN_SET(insn, 20, 31, MRSOp);
//Set destination register
INSN_SET(insn, 0, 4, scratchReg & 0x1F);
//Set bits representing source system register
INSN_SET(insn, 5, 19, sysRegCodeMap[sprnum]);
insnCodeGen::generate(gen, insn);
} else {
scratchReg = gen.rs()->getRegByName("r30");
}
instruction insn;
insn.clear();

//Set opcode for MRS instruction
INSN_SET(insn, 20, 31, MRSOp);
//Set destination register
INSN_SET(insn, 0, 4, scratchReg & 0x1F);
//Set bits representing source system register
INSN_SET(insn, 5, 19, sysRegCodeMap[sprnum]);
insnCodeGen::generate(gen, insn);

insnCodeGen::generateMemAccess32or64(gen, insnCodeGen::Store, scratchReg, REG_SP, stkOffset, sprnum == SPR_LR);
insnCodeGen::generateMemAccess32or64(gen, insnCodeGen::Store, scratchReg, REG_SP, stkOffset, false);
}

// Dest != reg : optimizate away a load/move pair
Expand Down Expand Up @@ -200,8 +196,18 @@ unsigned EmitterAARCH64SaveRegs::saveSPRegisters(codeGen &gen, registerSpace *,
return num_saved;
}

void EmitterAARCH64SaveRegs::createFrame(codeGen &gen) {
assert(0); //Not implemented
void EmitterAARCH64SaveRegs::createFrame(codeGen &gen, EmitterAARCH64SaveRegs saveRegs) {
//Save link register
Register linkRegister = gen.rs()->getRegByName("r30");
saveRegs.saveRegister(gen, linkRegister, GPRSIZE_64);

//Save frame pointer
Register framePointer = gen.rs()->getRegByName("r29");
saveRegs.saveRegister(gen, framePointer, GPRSIZE_64);

//Move stack pointer to frame pointer
Register stackPointer = gen.rs()->getRegByName("sp");
insnCodeGen::generateMoveSP(gen, stackPointer, framePointer, true);
}

/***********************************************************************************************/
Expand Down Expand Up @@ -236,34 +242,36 @@ unsigned EmitterAARCH64RestoreRegs::restoreSPRegisters(codeGen &gen, registerSpa
return num_restored;
}

void EmitterAARCH64RestoreRegs::tearFrame(codeGen &gen) {
assert(0); //Not implemented
void EmitterAARCH64RestoreRegs::tearFrame(codeGen &gen, EmitterAARCH64RestoreRegs restoreRegs) {
//Restore frame pointer
Register framePointer = gen.rs()->getRegByName("r29");
restoreRegs.restoreRegister(gen, framePointer, GPRSIZE_64);

//Restore link register
Register linkRegister = gen.rs()->getRegByName("r30");
restoreRegs.restoreRegister(gen, linkRegister, GPRSIZE_64);
}

/********************************* Private methods *********************************************/

void EmitterAARCH64RestoreRegs::restoreSPR(codeGen &gen, Register scratchReg, int sprnum, int stkOffset) {
if(sprnum == SPR_LR)
scratchReg = gen.rs()->getRegByName("r30");
insnCodeGen::generateMemAccess32or64(gen, insnCodeGen::Load, scratchReg, REG_SP, stkOffset, sprnum == SPR_LR);
insnCodeGen::generateMemAccess32or64(gen, insnCodeGen::Load, scratchReg, REG_SP, stkOffset, false);

//TODO move map to common location
if(sprnum != SPR_LR) {
map<int, int> sysRegCodeMap = map_list_of(SPR_NZCV, 0x5A10)(SPR_FPCR, 0x5A20)(SPR_FPSR, 0x5A21);
if (!sysRegCodeMap.count(sprnum))
assert(!"Invalid/unknown system register passed to restoreSPR()!");

instruction insn;
insn.clear();

//Set opcode for MSR (register) instruction
INSN_SET(insn, 20, 31, MSROp);
//Set source register
INSN_SET(insn, 0, 4, scratchReg & 0x1F);
//Set bits representing destination system register
INSN_SET(insn, 5, 19, sysRegCodeMap[sprnum]);
insnCodeGen::generate(gen, insn);
}
map<int, int> sysRegCodeMap = map_list_of(SPR_NZCV, 0x5A10)(SPR_FPCR, 0x5A20)(SPR_FPSR, 0x5A21);
if (!sysRegCodeMap.count(sprnum))
assert(!"Invalid/unknown system register passed to restoreSPR()!");

instruction insn;
insn.clear();

//Set opcode for MSR (register) instruction
INSN_SET(insn, 20, 31, MSROp);
//Set source register
INSN_SET(insn, 0, 4, scratchReg & 0x1F);
//Set bits representing destination system register
INSN_SET(insn, 5, 19, sysRegCodeMap[sprnum]);
insnCodeGen::generate(gen, insn);
}

// Dest != reg : optimizate away a load/move pair
Expand Down Expand Up @@ -295,7 +303,7 @@ bool baseTramp::generateSaves(codeGen &gen,
baseTramp *bt = this;
bool saveFrame = !bt || bt->needsFrame();
if(saveFrame)
saveRegs.createFrame(gen);
saveRegs.createFrame(gen, saveRegs);
bt->createdFrame = saveFrame;

saveRegs.saveGPRegisters(gen, gen.rs());
Expand Down Expand Up @@ -327,7 +335,7 @@ bool baseTramp::generateRestores(codeGen &gen,
restoreRegs.restoreGPRegisters(gen, gen.rs());

if(bt->createdFrame)
restoreRegs.tearFrame(gen);
restoreRegs.tearFrame(gen, restoreRegs);

return true;
}
Expand Down

0 comments on commit cd6c19f

Please sign in to comment.