Skip to content

Commit

Permalink
Implemented 32/64 bit memory access (store) instruction generation.
Browse files Browse the repository at this point in the history
insnCodeGen::generateMemAccess32or64() for ARM generates a STR
instruction for storing/loading a single 32- or 64-bit value.

This function will also eventually generate the equivalent load (LDR)
    instruction.
  • Loading branch information
ssunny7 committed Feb 24, 2017
1 parent fb9bc66 commit 44396a6
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 22 deletions.
2 changes: 2 additions & 0 deletions common/src/arch-aarch64.h
Expand Up @@ -62,6 +62,8 @@ namespace NS_aarch64 {
#define BCondOp 0x2A
#define BRegOp 0xD61F
#define NOOP 0xD503201F
#define STRImmOp 0x1C0
#define STRImmUIOp 0xE4

#define MIN_IMM8 (-32768)
#define MAX_IMM8 (32767)
Expand Down
30 changes: 27 additions & 3 deletions dyninstAPI/src/codegen-aarch64.C
Expand Up @@ -245,10 +245,34 @@ void insnCodeGen::generateMove(codeGen &gen, int imm16, int shift, Register rd,
insnCodeGen::generate(gen, insn);
}

void insnCodeGen::generateMemAccess64(codeGen &gen, int op, int xop, Register r1, Register r2, int immd)
/* Currently, I'm only considering generation of only STR/LDR and their register/immediate variants.*/
void insnCodeGen::generateMemAccess32or64(codeGen &gen, int op, int index, Register r1, Register r2, int immd, bool is64bit)
{
assert(0);
//#warning "This function is not implemented yet!"
instruction insn;
insn.clear();

//Bit 31 is always 1. Bit 30 is 1 if we're using the 64-bit variant.
INSN_SET(insn, 31, 31, 1);
if(is64bit)
INSN_SET(insn, 30, 30, 1);

//Set opcode, index and offset bits
/*At the moment, I only need the STR instructions, hence the check below only compares to the opcode for the STR immediate-unsigned offset variant.
However, once the LDR variant is also required to be generated, this check will have to be updated. TODO */
if(op != STRImmUIOp) {
INSN_SET(insn, 21, 29, op);
INSN_SET(insn, 10, 11, index);
INSN_SET(insn, 12, 20, immd);
} else {
INSN_SET(insn, 22, 29, op);
INSN_SET(insn, 10, 21, is64bit ? (immd >> 3) : (immd >> 2));
}

//Set memory access register and register for address calculation.
INSN_SET(insn, 0, 4, r1 & 0x1F);
INSN_SET(insn, 5, 9, r2 & 0x1F);

insnCodeGen::generate(gen, insn);
}

// rlwinm ra,rs,n,0,31-n
Expand Down
21 changes: 10 additions & 11 deletions dyninstAPI/src/codegen-aarch64.h
Expand Up @@ -69,6 +69,9 @@ class insnCodeGen {
Address to,
bool isCall);

static void generateMemAccess32or64(codeGen &gen, int op, int index,
Register r1, Register r2, int immd, bool is64bit);

/** TODO **/
static void generateLoadReg(codeGen &gen, Register rt,
Register ra, Register rb);
Expand All @@ -85,9 +88,6 @@ class insnCodeGen {
static void generateAddReg(codeGen &gen, int op,
Register rt, Register ra, Register rb);

static void generateMemAccess64(codeGen &gen, int op, int xop,
Register r1, Register r2, int immd);

static void generateLShift(codeGen &gen, Register rs,
int shift, Register ra);

Expand Down Expand Up @@ -119,6 +119,13 @@ class insnCodeGen {
static void generateMoveToLR(codeGen &gen, Register rs);

static void generateMoveToCR(codeGen &gen, Register rs);

static bool generateMem(codeGen &gen,
instruction &insn,
Address origAddr,
Address newAddr,
Register newLoadReg,
Register newStoreReg);

/** *** **/

Expand All @@ -136,14 +143,6 @@ class insnCodeGen {
patchTarget *fallthroughOverride = NULL,
patchTarget *targetOverride = NULL);

//TODO
static bool generateMem(codeGen &gen,
instruction &insn,
Address origAddr,
Address newAddr,
Register newLoadReg,
Register newStoreReg);

//TODO
// Routines to create/remove a new stack frame for getting scratch registers
static int
Expand Down
2 changes: 1 addition & 1 deletion dyninstAPI/src/inst-aarch64.C
Expand Up @@ -108,7 +108,7 @@ void registerSpace::initialize64() {
//SPRs
registers.push_back(new registerSlot(lr, "lr", true, registerSlot::liveAlways, registerSlot::SPR));
registers.push_back(new registerSlot(sp, "sp", true, registerSlot::liveAlways, registerSlot::SPR));
registers.push_back(new registerSlot(pstate, "pstate", true, registerSlot::liveAlways, registerSlot::SPR));
registers.push_back(new registerSlot(pstate, "nzcv", true, registerSlot::liveAlways, registerSlot::SPR));
registers.push_back(new registerSlot(fpcr, "fpcr", true, registerSlot::liveAlways, registerSlot::SPR));
registers.push_back(new registerSlot(fpsr, "fpsr", true, registerSlot::liveAlways, registerSlot::SPR));

Expand Down
13 changes: 6 additions & 7 deletions dyninstAPI/src/inst-aarch64.h
Expand Up @@ -103,17 +103,16 @@
+ FUNCSAVE_64 + FUNCARGS_64 + LINKAREA_64)
#define PDYN_RESERVED_64 (LINKAREA_64 + FUNCARGS_64 + FUNCSAVE_64)

//TODO ??/Fix for ARM
#define TRAMP_SPR_OFFSET_64 (PDYN_RESERVED_64)
#define STK_CR_64 (STK_LR + 8)
#define STK_CTR_64 (STK_CR_64 + 8)
#define STK_XER_64 (STK_CTR_64 + 8)
#define STK_FP_CR_64 (STK_XER_64 + 8)
#define STK_SPR0_64 (STK_FP_CR_64+ 8)
#define STK_LR ( 0)
#define STK_SP_EL0 (STK_LR + 8)
#define STK_NZCV (STK_SP_EL0 + 8)
#define STK_FPCR (STK_NZCV + 4)
#define STK_FPSR (STK_FPCR + 4)

#define TRAMP_FPR_OFFSET_64 (TRAMP_SPR_OFFSET_64 + SPRSAVE_64)
#define TRAMP_GPR_OFFSET_64 (TRAMP_FPR_OFFSET_64 + FPRSAVE)
#define FUNC_CALL_SAVE_64 (LINKAREA_64 + FUNCARGS_64)
#define FUNC_CALL_SAVE_64 (LINKAREA_64 + FUNCARGS_64)

///////////////////////////// Multi-instruction sequences
class codeGen;
Expand Down

0 comments on commit 44396a6

Please sign in to comment.