Skip to content

Commit

Permalink
Implementing more instruction generators for div and sub.
Browse files Browse the repository at this point in the history
Adding emit-aarch64.C to put aarch64 Emitters implementations.
  • Loading branch information
Sasha Nicolas (arm1) committed Apr 14, 2018
1 parent 28f89a9 commit 92115c5
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 44 deletions.
1 change: 1 addition & 0 deletions common/src/arch-aarch64.h
Expand Up @@ -67,6 +67,7 @@ namespace NS_aarch64 {
#define SUBShiftOp 0x4B
#define SUBImmOp 0x51
#define MULOp 0xD8
#define SDIVOp 0xE71

#define ORRShiftOp 0x2A
#define ANDShiftOp 0x0A
Expand Down
1 change: 1 addition & 0 deletions dyninstAPI/CMakeLists.txt
Expand Up @@ -135,6 +135,7 @@ set (SRC_LIST ${SRC_LIST}
elseif (PLATFORM MATCHES aarch64)
set (SRC_LIST ${SRC_LIST}
src/inst-aarch64.C
src/emit-aarch64.C
src/codegen-aarch64.C
src/parse-aarch64.C
src/RegisterConversion-aarch64.C
Expand Down
51 changes: 45 additions & 6 deletions dyninstAPI/src/codegen-aarch64.C
Expand Up @@ -123,16 +123,17 @@ void insnCodeGen::generateCall(codeGen &gen, Address from, Address to) {
void insnCodeGen::generateLongBranch(codeGen &gen,
Address from,
Address to,
bool isCall) {
bool isCall)
{
Register scratch = 0;

instPoint *point = gen.point();
if(!point)
{
if(!isCall)
{
scratch = 12; //#sasha test for springboard
//scratch = gen.rs()->getScratchRegister(gen);
//scratch = 12; //#sasha test for springboard
scratch = gen.rs()->getScratchRegister(gen);
}
else
{
Expand Down Expand Up @@ -200,7 +201,10 @@ void insnCodeGen::generateBranchViaTrap(codeGen &gen, Address from, Address to,
}
}

void insnCodeGen::generateAddSubShifted(codeGen &gen, insnCodeGen::AddSubOp op, int shift, int imm6, Register rm, Register rn, Register rd, bool is64bit) {
void insnCodeGen::generateAddSubShifted(
codeGen &gen, insnCodeGen::ArithOp op, int shift, int imm6, Register rm,
Register rn, Register rd, bool is64bit)
{
instruction insn;
insn.clear();

Expand All @@ -226,7 +230,9 @@ void insnCodeGen::generateAddSubShifted(codeGen &gen, insnCodeGen::AddSubOp op,
insnCodeGen::generate(gen, insn);
}

void insnCodeGen::generateAddSubImmediate(codeGen &gen, insnCodeGen::AddSubOp op, int shift, int imm12, Register rn, Register rd, bool is64bit) {
void insnCodeGen::generateAddSubImmediate(
codeGen &gen, insnCodeGen::ArithOp op, int shift, int imm12, Register rn, Register rd, bool is64bit)
{
instruction insn;
insn.clear();

Expand Down Expand Up @@ -271,7 +277,34 @@ void insnCodeGen::generateMul(codeGen &gen, Register rm, Register rn, Register r
insnCodeGen::generate(gen, insn);
}

void insnCodeGen::generateBitwiseOpShifted(codeGen &gen, insnCodeGen::BitwiseOp op, int shift, Register rm, int imm6, Register rn, Register rd, bool is64bit) {
//#sasha is rm or rn the denominator?
void insnCodeGen::generateDiv(
codeGen &gen, Register rm, Register rn, Register rd, bool is64bit)
{
instruction insn;
insn.clear();

// Set opcode
INSN_SET(insn, 20, 31, SDIVOp);

// Bits 12 to 15 are 1
INSN_SET(insn, 12, 15, 0xF);
// Bit 4 to 7 range has 0x1
INSN_SET(insn, 4, 7, 0x1);

//Set registers
INSN_SET(insn, 16, 19, rd);
INSN_SET(insn, 8, 11, rm);
INSN_SET(insn, 0, 3, rn);

insnCodeGen::generate(gen, insn);

}

void insnCodeGen::generateBitwiseOpShifted(
codeGen &gen, insnCodeGen::BitwiseOp op, int shift, Register rm, int imm6,
Register rn, Register rd, bool is64bit)
{
instruction insn;
insn.clear();

Expand Down Expand Up @@ -358,6 +391,12 @@ void insnCodeGen::generateMove(codeGen &gen, int imm16, int shift, Register rd,
insnCodeGen::generate(gen, insn);
}

void insnCodeGen::generateMove(
codeGen &gen, Register rd, Register rm, bool is64bit)
{
insnCodeGen::generateBitwiseOpShifted(gen, insnCodeGen::Or, 0, rm, 0, 0x1f, rd, is64bit);
}

void insnCodeGen::generateMoveSP(codeGen &gen, Register rn, Register rd, bool is64bit) {
instruction insn;
insn.clear();
Expand Down
14 changes: 11 additions & 3 deletions dyninstAPI/src/codegen-aarch64.h
Expand Up @@ -49,7 +49,7 @@ class insnCodeGen {
Store
};

enum AddSubOp {
enum ArithOp {
Add,
Sub
};
Expand Down Expand Up @@ -151,16 +151,24 @@ class insnCodeGen {

/** *** **/

static void generateAddSubShifted(codeGen &gen, AddSubOp op, int shift, int imm6, Register rm, Register rn, Register rd, bool is64bit);
static void generateAddSubShifted(
codeGen &gen, ArithOp op, int shift, int imm6, Register rm, Register rn, Register rd, bool is64bit);

static void generateAddSubImmediate(codeGen &gen, AddSubOp op, int shift, int imm12, Register rn, Register rd, bool is64bit);
static void generateAddSubImmediate(
codeGen &gen, ArithOp op, int shift, int imm12, Register rn, Register rd, bool is64bit);

static void generateMul(codeGen &gen, Register rm, Register rn, Register rd, bool is64bit);

static void generateDiv(codeGen &gen, Register rm, Register rn, Register rd, bool is64bit);

static void generateBitwiseOpShifted(codeGen &gen, BitwiseOp op, int shift, Register rm, int imm6, Register rn, Register rd, bool is64bit);

// This is for MOVK, MOVN, and MOVZ. For MOV use generateMoveToReg()
static void generateMove(codeGen &gen, int imm16, int shift, Register rd, MoveOp movOp);

// This is for MOV, which is an alias for ORR. See ARMv8 Documentation.
static void generateMove(codeGen &gen, Register rd, Register rm, bool is64bit = true);

static void generateMoveSP(codeGen &gen, Register rn, Register rd, bool is64bit);

static Register moveValueToReg(codeGen &gen, long int val, pdvector<Register> *exclude = NULL);
Expand Down
118 changes: 118 additions & 0 deletions dyninstAPI/src/emit-aarch64.C
@@ -0,0 +1,118 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

/*
* emit-aarch64.C - ARMv8 code generators (emitters)
*/

/*
#include <assert.h>
#include <stdio.h>
#include "common/src/Types.h"
#include "dyninstAPI/src/codegen.h"
#include "dyninstAPI/src/function.h"
#include "dyninstAPI/src/inst-x86.h"
#include "dyninstAPI/src/debug.h"
#include "dyninstAPI/src/ast.h"
#include "dyninstAPI/h/BPatch.h"
#include "dyninstAPI/h/BPatch_memoryAccess_NP.h"
#include "dyninstAPI/src/dynProcess.h"
#include "dyninstAPI/src/binaryEdit.h"
#include "dyninstAPI/src/image.h"
// get_index...
#include "dyninstAPI/src/dynThread.h"
#include "ABI.h"
#include "liveness.h"
#include "RegisterConversion.h"
*/


#include "dyninstAPI/src/emit-aarch64.h"
#include "dyninstAPI/src/registerSpace.h"


void EmitterAARCH64::emitLoadConst(Register dest, Address imm, codeGen &gen)
{
insnCodeGen::loadImmIntoReg<Address>(gen, dest, imm);
}


void EmitterAARCH64::emitLoad(Register dest, Address addr, int size, codeGen &gen)
{
Register scratch = gen.rs()->getScratchRegister(gen);

insnCodeGen::loadImmIntoReg<Address>(gen, scratch, addr);
insnCodeGen::generateMemAccess32or64(gen, insnCodeGen::Load, dest, scratch, 0, false);

gen.rs()->freeRegister(scratch);
gen.markRegDefined(dest);
}


void EmitterAARCH64::emitStore(Address addr, Register src, int size, codeGen &gen)
{
Register scratch = gen.rs()->getScratchRegister(gen);

insnCodeGen::loadImmIntoReg<Address>(gen, scratch, addr);
insnCodeGen::generateMemAccess32or64(gen, insnCodeGen::Store, src, scratch, 0, false);

gen.rs()->freeRegister(scratch);
gen.markRegDefined(src);
}


void EmitterAARCH64::emitOp(
unsigned opcode, Register dest, Register src1, Register src2, codeGen &gen)
{
// dest = src1
//generateMoveToReg(gen, dest, src1);

// dest = src1 + src2
if( opcode == plusOp )
insnCodeGen::generateAddSubShifted(gen, insnCodeGen::Add, 0, 0, src1, src2, dest, true);

// dest = src1 - src2
else if( opcode == minusOp )
insnCodeGen::generateAddSubShifted(gen, insnCodeGen::Sub, 0, 0, src1, src2, dest, true);

// dest = src1 / src2
else if( opcode == divOp )
insnCodeGen::generateDiv(gen, src1, src2, dest, true);

// dest = src1 * src2
else if( opcode == timesOp )
insnCodeGen::generateMul(gen, src1, src2, dest, true);

//gen.markRegDefined(dest); // #sasha should mark?
}


2 changes: 1 addition & 1 deletion dyninstAPI/src/emit-aarch64.h
Expand Up @@ -54,7 +54,7 @@ class EmitterAARCH64 : public Emitter {

virtual codeBufIndex_t emitIf(Register, Register, RegControl, codeGen &);

virtual void emitOp(unsigned, Register, Register, Register, codeGen &) { assert(0); }
virtual void emitOp(unsigned, Register, Register, Register, codeGen &);

virtual void emitOpImm(unsigned, unsigned, Register, Register, RegValue,
codeGen &) { assert(0); }
Expand Down
48 changes: 14 additions & 34 deletions dyninstAPI/src/inst-aarch64.C
Expand Up @@ -565,8 +565,8 @@ Register EmitterAARCH64::emitCall(opCode op,
assert(gen.rs());

//#sasha get correct register
//Register scratch = gen.rs()->getScratchRegister(gen);
Register scratch = 11;
Register scratch = gen.rs()->getScratchRegister(gen);
//Register scratch = 11;
insnCodeGen::loadImmIntoReg<Address>(gen, scratch, callee->addr());

instruction branchInsn;
Expand Down Expand Up @@ -731,7 +731,18 @@ void emitV(opCode op, Register src1, Register src2, Register dest,
registerSpace * /*rs*/, int size,
const instPoint * /* location */, AddressSpace *proc)
{
assert(0); //not implemented
switch(op){
case plusOp:
case minusOp:
case divOp:
case timesOp:
gen.codeEmitter()->emitOp(op, dest, src1, src2, gen);
break;
default:
//std::cout << "operation= " << op << endl;
assert(0); // Not implemented
break;
}
return;
}

Expand Down Expand Up @@ -1202,34 +1213,3 @@ codeBufIndex_t EmitterAARCH64::emitIf(
}


void EmitterAARCH64::emitLoadConst(Register dest, Address imm, codeGen &gen)
{
insnCodeGen::loadImmIntoReg<Address>(gen, dest, imm);
}


void EmitterAARCH64::emitLoad(Register dest, Address addr, int size, codeGen &gen)
{
Register scratch = gen.rs()->getScratchRegister(gen);

insnCodeGen::loadImmIntoReg<Address>(gen, scratch, addr);
insnCodeGen::generateMemAccess32or64(gen, insnCodeGen::Load, dest, scratch, 0, false);

gen.rs()->freeRegister(scratch);
gen.markRegDefined(dest);
}


void EmitterAARCH64::emitStore(Address addr, Register src, int size, codeGen &gen)
{
Register scratch = gen.rs()->getScratchRegister(gen);

insnCodeGen::loadImmIntoReg<Address>(gen, scratch, addr);
insnCodeGen::generateMemAccess32or64(gen, insnCodeGen::Store, src, scratch, 0, false);

gen.rs()->freeRegister(scratch);
gen.markRegDefined(src);
}



0 comments on commit 92115c5

Please sign in to comment.