blob: ad4e25b07bc3cd6dc6c833c1e45efe519fad5502 [file] [log] [blame]
/*---------------------------------------------------------------*/
/*--- ---*/
/*--- This file (hdefs.h) is ---*/
/*--- Copyright (C) OpenWorks LLP. All rights reserved. ---*/
/*--- ---*/
/*---------------------------------------------------------------*/
/*
This file is part of LibVEX, a library for dynamic binary
instrumentation and translation.
Copyright (C) 2004-2006 OpenWorks LLP. All rights reserved.
This library is made available under a dual licensing scheme.
If you link LibVEX against other code all of which is itself
licensed under the GNU General Public License, version 2 dated June
1991 ("GPL v2"), then you may use LibVEX under the terms of the GPL
v2, as appearing in the file LICENSE.GPL. If the file LICENSE.GPL
is missing, you can obtain a copy of the GPL v2 from the Free
Software Foundation Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301, USA.
For any other uses of LibVEX, you must first obtain a commercial
license from OpenWorks LLP. Please contact info@open-works.co.uk
for information about commercial licensing.
This software is provided by OpenWorks LLP "as is" and any express
or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose
are disclaimed. In no event shall OpenWorks LLP be liable for any
direct, indirect, incidental, special, exemplary, or consequential
damages (including, but not limited to, procurement of substitute
goods or services; loss of use, data, or profits; or business
interruption) however caused and on any theory of liability,
whether in contract, strict liability, or tort (including
negligence or otherwise) arising in any way out of the use of this
software, even if advised of the possibility of such damage.
Neither the names of the U.S. Department of Energy nor the
University of California nor the names of its contributors may be
used to endorse or promote products derived from this software
without prior written permission.
*/
#ifndef __LIBVEX_ARMH_DEFS_H
#define __LIBVEX_ARMH_DEFS_H
/* --------- Registers. --------- */
/* The usual HReg abstraction.
There are 16 general purpose regs.
*/
extern void ppHRegARM ( HReg );
extern HReg hregARM_R0 ( void );
extern HReg hregARM_R1 ( void );
extern HReg hregARM_R2 ( void );
extern HReg hregARM_R3 ( void );
extern HReg hregARM_R4 ( void );
extern HReg hregARM_R5 ( void );
extern HReg hregARM_R6 ( void );
extern HReg hregARM_R7 ( void );
extern HReg hregARM_R8 ( void );
extern HReg hregARM_R9 ( void );
extern HReg hregARM_R10 ( void );
extern HReg hregARM_R11 ( void );
extern HReg hregARM_R12 ( void );
extern HReg hregARM_R13 ( void );
extern HReg hregARM_R14 ( void );
extern HReg hregARM_R15 ( void );
#define GET_BP_REG() hregARM_R12() // x86 ebp
#define GET_SP_REG() hregARM_R13() // x86 esp
#define GET_LN_REG() hregARM_R14()
#define GET_PC_REG() hregARM_R15()
/* --------- Condition codes, Intel encoding. --------- */
typedef
enum {
ARMccEQ = 0, /* equal : Z=1 */
ARMccNE = 1, /* not equal : Z=0 */
ARMccHS = 2, /* >=u (higher or same) : C=1 */
ARMccLO = 3, /* <u (lower) : C=0 */
ARMccMI = 4, /* minus (negative) : N=1 */
ARMccPL = 5, /* plus (zero or +ve) : N=0 */
ARMccVS = 6, /* overflow : V=1 */
ARMccVC = 7, /* no overflow : V=0 */
ARMccHI = 8, /* >u (higher) : C=1 && Z=0 */
ARMccLS = 9, /* <=u (lower or same) : C=0 || Z=1 */
ARMccGE = 10, /* >=s (signed greater or equal) : N=V */
ARMccLT = 11, /* <s (signed less than) : N!=V */
ARMccGT = 12, /* >s (signed greater) : Z=0 && N=V */
ARMccLE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
ARMccAL = 14, /* always (unconditional) */
ARMccNV = 15 /* never (basically undefined meaning), deprecated */
}
ARMCondCode;
extern HChar* showARMCondCode ( ARMCondCode );
/* --------- Immediate types. --------- */
typedef UInt ARMImm4;
typedef UInt ARMImm5;
typedef UInt ARMImm8;
typedef UInt ARMImm12;
typedef UInt ARMImm24; // Branch imm
typedef
struct {
ARMImm8 imm;
ARMImm4 rot;
}
ARMImm12A; /* extended (rotated) immedate */
extern Bool mk_ARMImm12A ( UInt, ARMImm12A*);
/* --------- Memory address expressions (amodes). --------- */
/* --- Addressing Mode 1 --- */
typedef
enum {
ARMam1_I12A, /* Imm12A: extended (rotated) immedate */
ARMam1_ShlI, /* ShlI reg Imm5 */
ARMam1_ShrI, /* ShrI reg Imm5 */
ARMam1_SarI, /* SarI reg Imm5 */
ARMam1_ShlR, /* ShlR reg reg */
ARMam1_ShrR, /* ShrR reg reg */
ARMam1_SarR, /* SarR reg reg */
}
ARMAMode1Tag;
typedef
struct {
ARMAMode1Tag tag;
union {
struct {
ARMImm12A imm;
} I12A;
struct {
HReg Rm;
ARMImm5 imm;
} ShlI;
struct {
HReg Rm;
ARMImm5 imm;
} ShrI;
struct {
HReg Rm;
ARMImm5 imm;
} SarI;
struct {
HReg Rm;
HReg Rs;
} ShlR;
struct {
HReg Rm;
HReg Rs;
} ShrR;
struct {
HReg Rm;
HReg Rs;
} SarR;
} ARMam1;
}
ARMAMode1;
extern ARMAMode1* ARMAMode1_I12A ( ARMImm12A );
extern ARMAMode1* ARMAMode1_ShlI ( HReg, ARMImm5 );
extern ARMAMode1* ARMAMode1_ShrI ( HReg, ARMImm5 );
extern ARMAMode1* ARMAMode1_SarI ( HReg, ARMImm5 );
extern ARMAMode1* ARMAMode1_ShlR ( HReg, HReg );
extern ARMAMode1* ARMAMode1_ShrR ( HReg, HReg );
extern ARMAMode1* ARMAMode1_SarR ( HReg, HReg );
extern ARMAMode1* dopyARMAMode1 ( ARMAMode1* );
extern void ppARMAMode1 ( ARMAMode1* );
/* --- Addressing Mode 2 --- */
typedef
enum {
ARMam2_RI, /* Reg +/- Imm12 */
ARMam2_RR, /* Reg +/- Reg */
ARMam2_RRS, /* Reg +/- (Reg << Imm5) */
}
ARMAMode2Tag;
typedef
struct {
ARMAMode2Tag tag;
union {
struct {
HReg Rn;
ARMImm12 imm;
} RI;
struct {
HReg Rn;
HReg Rm;
} RR;
struct {
HReg Rn;
HReg Rm;
ARMImm5 shift;
} RRS;
} ARMam2;
}
ARMAMode2;
extern ARMAMode2* ARMAMode2_RI ( HReg, ARMImm12 );
extern ARMAMode2* ARMAMode2_RR ( HReg, HReg );
extern ARMAMode2* ARMAMode2_RRS ( HReg, HReg, ARMImm5 );
extern ARMAMode2* dopyARMAMode2 ( ARMAMode2* );
extern void ppARMAMode2 ( ARMAMode2* );
/* --- Addressing Mode 3 --- */
typedef
enum {
ARMam3_RI, /* Reg +/- Imm8 */
ARMam3_RR, /* Reg +/- Reg */
}
ARMAMode3Tag;
typedef
struct {
ARMAMode3Tag tag;
union {
struct {
HReg Rn;
ARMImm8 imm;
} RI;
struct {
HReg Rn;
HReg Rm;
} RR;
} ARMam3;
}
ARMAMode3;
extern ARMAMode3* ARMAMode3_RI ( HReg, ARMImm8 );
extern ARMAMode3* ARMAMode3_RR ( HReg, HReg );
extern ARMAMode3* dopyARMAMode3 ( ARMAMode3* );
extern void ppARMAMode3 ( ARMAMode3* );
/* ------ Branch destination ------ */
typedef
enum {
ARMbdImm,
ARMbdReg
}
ARMBranchTag;
typedef
struct {
ARMBranchTag tag;
union {
struct {
ARMImm24 imm24;
} Imm;
struct {
HReg reg;
} Reg;
} ARMbd;
}
ARMBranchDest;
extern ARMBranchDest* ARMBranchDest_Imm ( ARMImm24 );
extern ARMBranchDest* ARMBranchDest_Reg ( HReg );
extern void ppARMBranchDest ( ARMBranchDest* );
/* --------- Instructions. --------- */
/* --- DPI's --- */
typedef
enum {
ARMalu_AND, ARMalu_ORR, ARMalu_EOR, ARMalu_BIC, // Logic
ARMalu_SUB, ARMalu_RSB, ARMalu_ADD, ARMalu_ADC, ARMalu_SBC, ARMalu_RSC, // Arith
ARMalu_TST, ARMalu_TEQ, ARMalu_CMP, ARMalu_CMN, // Test
ARMalu_MOV, ARMalu_MVN // Move
}
ARMAluOp;
extern HChar* showARMAluOp ( ARMAluOp );
/* --------- */
typedef
enum {
ARMin_DPCmp,
ARMin_DPInstr1,
ARMin_DPInstr2,
ARMin_LoadUB,
ARMin_StoreB,
ARMin_LoadW,
ARMin_StoreW,
ARMin_LoadSB,
ARMin_LoadUH,
ARMin_LoadSH,
ARMin_StoreH,
ARMin_Branch,
ARMin_BranchL,
ARMin_Literal
}
ARMInstrTag;
typedef
struct {
ARMInstrTag tag;
union {
/* Addressing Mode 1 */
struct {
ARMAluOp op;
HReg Rn;
ARMAMode1* shifter_op;
} DPCmp; // test instrs - compare Rd with RIS and set flags
struct {
ARMAluOp op;
HReg Rd;
ARMAMode1* shifter_op;
} DPInstr1; // 1 reg: Mov
struct {
ARMAluOp op;
HReg Rd;
HReg Rn;
ARMAMode1* shifter_op;
} DPInstr2; // 2 regs: Logic, Arith, Bic
/* Addressing Mode 2 */
struct {
HReg Rd;
ARMAMode2* addr_mode;
} LoadUB;
struct {
HReg Rd;
ARMAMode2* addr_mode;
} StoreB;
struct {
HReg Rd;
ARMAMode2* addr_mode;
} LoadW;
struct {
HReg Rd;
ARMAMode2* addr_mode;
} StoreW;
/* Addressing Mode 3 */
struct {
HReg Rd;
ARMAMode3* addr_mode;
} LoadSB;
struct {
HReg Rd;
ARMAMode3* addr_mode;
} LoadUH;
struct {
HReg Rd;
ARMAMode3* addr_mode;
} LoadSH;
struct {
HReg Rd;
ARMAMode3* addr_mode;
} StoreH;
/* Branch */
struct {
ARMCondCode cond;
ARMBranchDest* dest;
} Branch;
struct {
ARMCondCode cond;
ARMBranchDest* dest;
} BranchL;
/* Literal */
struct {
HReg reg;
UInt imm;
} Literal; // -- reg = imm
} ARMin;
}
ARMInstr;
extern ARMInstr* ARMInstr_DPCmp ( ARMAluOp, HReg, ARMAMode1* );
extern ARMInstr* ARMInstr_DPInstr1 ( ARMAluOp, HReg, ARMAMode1* );
extern ARMInstr* ARMInstr_DPInstr2 ( ARMAluOp, HReg, HReg, ARMAMode1* );
extern ARMInstr* ARMInstr_LoadUB ( HReg, ARMAMode2* );
extern ARMInstr* ARMInstr_StoreB ( HReg, ARMAMode2* );
extern ARMInstr* ARMInstr_LoadW ( HReg, ARMAMode2* );
extern ARMInstr* ARMInstr_StoreW ( HReg, ARMAMode2* );
extern ARMInstr* ARMInstr_LoadSB ( HReg, ARMAMode3* );
extern ARMInstr* ARMInstr_LoadUH ( HReg, ARMAMode3* );
extern ARMInstr* ARMInstr_LoadSH ( HReg, ARMAMode3* );
extern ARMInstr* ARMInstr_StoreH ( HReg, ARMAMode3* );
extern ARMInstr* ARMInstr_Branch ( ARMCondCode, ARMBranchDest* );
extern ARMInstr* ARMInstr_BranchL ( ARMCondCode, ARMBranchDest* );
extern ARMInstr* ARMInstr_Literal ( HReg, UInt );
extern void ppARMInstr ( ARMInstr* );
/* Some functions that insulate the register allocator from details
of the underlying instruction set. */
extern void getAllocableRegs_ARM ( Int*, HReg** );
extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr* );
extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr* );
extern Bool isMove_ARMInstr ( ARMInstr*, HReg*, HReg* );
extern Int emit_ARMInstr ( UChar* buf, Int nbuf, ARMInstr* );
extern ARMInstr* genSpill_ARM ( HReg rreg, Int offset );
extern ARMInstr* genReload_ARM ( HReg rreg, Int offset );
extern void getAllocableRegs_ARM ( Int*, HReg** );
extern HInstrArray* iselBB_ARM ( IRBB* );
#endif /* ndef __LIBVEX_ARMH_DEFS_H */
/*---------------------------------------------------------------*/
/*--- end arm hdefs.h ---*/
/*---------------------------------------------------------------*/