Skip to content

Commit

Permalink
Correct LDR/STR instructions for SIMD&FP
Browse files Browse the repository at this point in the history
Saving all FP registers in BaseTramp
Remove #if for DYNINST_snippetBreakpoint
  • Loading branch information
Sasha @leela committed Nov 8, 2018
1 parent e603a1d commit 2ceafc6
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 33 deletions.
12 changes: 9 additions & 3 deletions common/src/arch-aarch64.h
Expand Up @@ -73,12 +73,18 @@ namespace NS_aarch64 {
#define ANDShiftOp 0x0A
#define EORShiftOp 0x4A

#define STRImmOp 0x1C0
#define LDRImmOp 0x1C2
#define STRFPImmOp 0x1E0
#define STRImmOp 0x1C0

#define LDRFPImmOp 0x1E2
#define STRImmUIOp 0xE4
#define STRFPImmOp 0x1E0

#define LDRFPImmUOp 0xF5
#define STRFPImmUOp 0xF4

#define LDRImmUIOp 0xE5
#define STRImmUIOp 0xE4

#define LDRSWImmUIOp 0xE6

#define MSROp 0xD51
Expand Down
46 changes: 30 additions & 16 deletions dyninstAPI/src/codegen-aarch64.C
Expand Up @@ -502,7 +502,7 @@ void insnCodeGen::loadImmIntoReg(codeGen &gen, Register rt, T value)
}


// This is for generating STR/LDR (imediate) for indexing modes of Post, Pre and Offset
// This is for generating STR/LDR (immediate) for indexing modes of Post, Pre and Offset
void insnCodeGen::generateMemAccess32or64(codeGen &gen, LoadStore accType,
Register r1, Register r2, int immd, bool is64bit, IndexMode im)
{
Expand All @@ -521,15 +521,15 @@ void insnCodeGen::generateMemAccess32or64(codeGen &gen, LoadStore accType,
if(immd >= -256 && immd <= 255) {
INSN_SET(insn, 21, 29, (accType == Load) ? LDRImmOp : STRImmOp);
INSN_SET(insn, 10, 11, im==Post?0x1:0x3);
INSN_SET(insn, 12, 20, immd);
INSN_SET(insn, 12, 20, immd); // can be negative so no enconding
} else {
assert(!"Cannot perform a post/pre-indexed memory access for offsets not in range [-256, 255]!");
}
break;
case Offset:
INSN_SET(insn, 22, 29, (accType == Load) ? LDRImmUIOp : STRImmUIOp);
assert(immd>=0); // this offset is supposed to unsigned, i.e. positive
INSN_SET(insn, 10, 21, immd>>3);
assert(immd>=0); // this offset is supposed to be unsigned, i.e. positive
INSN_SET(insn, 10, 21, immd>>(is64bit?3:2)); // always positive so encode
break;
}

Expand All @@ -540,26 +540,40 @@ void insnCodeGen::generateMemAccess32or64(codeGen &gen, LoadStore accType,
insnCodeGen::generate(gen, insn);
}

// This is for generating STR/LDR (SIMD&FP) (immediate) for indexing modes of Post, Pre and Offset
void insnCodeGen::generateMemAccessFP(codeGen &gen, LoadStore accType,
Register rt, Register rn, int immd, int size, bool is128bit)
Register rt, Register rn, int immd, int size, bool is128bit, IndexMode im)
{
instruction insn;
insn.clear();

if(size < 0 || size > 3)
assert(!"Size field for STR (immediate, SIMD&FP) variant has to be in the range [0-3]!");
switch(im){
case Post:
case Pre:
//Set opcode, index and offset bits
if(immd >= -256 && immd <= 255) {
INSN_SET(insn, 21, 29, (accType == Load) ? LDRFPImmOp : STRFPImmOp);
INSN_SET(insn, 10, 11, im==Post?0x1:0x3);
INSN_SET(insn, 12, 20, immd); // can be negative so no enconding
} else {
assert(!"Cannot perform a post/pre-indexed memory access for offsets not in range [-256, 255]!");
}
break;
case Offset:
INSN_SET(insn, 22, 29, (accType == Load) ? LDRFPImmUOp : STRFPImmUOp);
assert(immd>=0); // this offset is supposed to be unsigned, i.e. positive
INSN_SET(insn, 10, 21, immd>>4); //#sasha change encoding to appropriate
break;
}

//Set size, opcode, index and offset bits
INSN_SET(insn, 30, 31, size & 0x3);
INSN_SET(insn, 21, 29, (accType == Load) ? LDRFPImmOp : STRFPImmOp);
// STR/LDR can be 8, 16, 32, 64, and 128, this might need to change
// it's more complicated than just the bit 23. 31 and 30 also decides
if(is128bit)
INSN_SET(insn, 23, 23, 1);
INSN_SET(insn, 10, 11, 0x1);
if(immd >= -256 && immd <= 255) {
INSN_SET(insn, 12, 20, immd);
} else {
assert(!"Cannot perform a post-indexed memory access for offsets not in range [-256, 255]!");
}

if(size < 0 || size > 3)
assert(!"Size field for STR (immediate, SIMD&FP) variant has to be in the range [0-3]!");
INSN_SET(insn, 30, 31, size & 0x3);

//Set memory access register and register for address calculation.
INSN_SET(insn, 0, 4, rt);
Expand Down
2 changes: 1 addition & 1 deletion dyninstAPI/src/codegen-aarch64.h
Expand Up @@ -105,7 +105,7 @@ class insnCodeGen {
Register r2, int immd, bool is64bit, IndexMode im=Post);

static void generateMemAccessFP(codeGen &gen, LoadStore accType, Register rt,
Register rn, int immd, int size, bool is128bit);
Register rn, int immd, int size, bool is128bit, IndexMode im=Offset);

template<typename T>
static void loadImmIntoReg(codeGen &gen, Register rt, T value);
Expand Down
23 changes: 15 additions & 8 deletions dyninstAPI/src/inst-aarch64.C
Expand Up @@ -183,6 +183,7 @@ unsigned EmitterAARCH64SaveRegs::saveGPRegisters(

for(unsigned int idx = 0; idx < numReqGPRs; idx++) {
registerSlot *reg = theRegSpace->GPRs()[idx];

if (reg->liveState == registerSlot::live) {
int offset_from_sp = offset + (reg->encoding() * gen.width());
insnCodeGen::saveRegister(gen, reg->number, offset_from_sp);
Expand All @@ -194,17 +195,21 @@ unsigned EmitterAARCH64SaveRegs::saveGPRegisters(
return ret;
}

unsigned EmitterAARCH64SaveRegs::saveFPRegisters(codeGen &gen, registerSpace *theRegSpace, int offset) {
unsigned EmitterAARCH64SaveRegs::saveFPRegisters(
codeGen &gen, registerSpace *theRegSpace, int offset)
{
unsigned ret = 0;

for(int idx = 0; idx < theRegSpace->numFPRs(); idx++) {
registerSlot *reg = theRegSpace->FPRs()[idx];

if(reg->liveState == registerSlot::live) {
saveFPRegister(gen, reg->number, -8*FPRSIZE_64);
reg->liveState = registerSlot::spilled;
//if(reg->liveState == registerSlot::live) {
int offset_from_sp = offset + (reg->encoding() * FPRSIZE_64);
saveFPRegister(gen, reg->number, offset_from_sp);
//reg->liveState = registerSlot::spilled;
theRegSpace->markSavedRegister(reg->number, offset_from_sp);
ret++;
}
//}
}

return ret;
Expand Down Expand Up @@ -278,6 +283,7 @@ unsigned EmitterAARCH64RestoreRegs::restoreGPRegisters(
registerSlot *reg = theRegSpace->GPRs()[idx];

if(reg->liveState == registerSlot::spilled) {
//#sasha this should be GPRSIZE_64 and not gen.width
int offset_from_sp = offset + (reg->encoding() * gen.width());
insnCodeGen::restoreRegister(gen, reg->number, offset_from_sp);
ret++;
Expand All @@ -295,10 +301,11 @@ unsigned EmitterAARCH64RestoreRegs::restoreFPRegisters(
for(int idx = theRegSpace->numFPRs() - 1; idx >= 0; idx--) {
registerSlot *reg = theRegSpace->FPRs()[idx];

if(reg->liveState == registerSlot::spilled) {
restoreFPRegister(gen, reg->number, 8*FPRSIZE_64);
//if(reg->liveState == registerSlot::spilled) {
int offset_from_sp = offset + (reg->encoding() * FPRSIZE_64);
restoreFPRegister(gen, reg->number, offset_from_sp);
ret++;
}
//}
}

return ret;
Expand Down
5 changes: 0 additions & 5 deletions dyninstAPI_RT/src/RTcommon.c
Expand Up @@ -223,8 +223,6 @@ int DYNINSTreturnZero()

/* Used to by dyninst breakpoint snippet */
void DYNINST_snippetBreakpoint() {
//#warning "This function is not implemented for AARCH64 yet!"
#if !defined(arch_aarch64)
tc_lock_lock(&DYNINST_trace_lock);

/* Set the state so the mutator knows what's up */
Expand All @@ -236,9 +234,6 @@ void DYNINST_snippetBreakpoint() {
DYNINST_synch_event_id = DSE_undefined;

tc_lock_unlock(&DYNINST_trace_lock);
#else
assert(0);
#endif
}

/* Used to instrument (and report) the entry of fork */
Expand Down

0 comments on commit 2ceafc6

Please sign in to comment.