From: Cerion Armour-Brown Date: Thu, 16 Dec 2004 14:06:34 +0000 (+0000) Subject: Cleaned up hdefs.h, fleshed out hdefs.c X-Git-Tag: svn/VALGRIND_3_0_1^2~664 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8408b3c81d04cfd18d7d019ba7ee7fe3058d3878;p=thirdparty%2Fvalgrind.git Cleaned up hdefs.h, fleshed out hdefs.c git-svn-id: svn://svn.valgrind.org/vex/trunk@670 --- diff --git a/VEX/Makefile b/VEX/Makefile index bed2d78e4a..12aaed8ab7 100644 --- a/VEX/Makefile +++ b/VEX/Makefile @@ -9,6 +9,7 @@ PUB_HEADERS = pub/libvex_basictypes.h \ pub/libvex_guest_arm.h PRIV_HEADERS = priv/host-x86/hdefs.h \ + priv/host-arm/hdefs.h \ priv/host-generic/h_generic_regs.h \ priv/main/vex_globals.h \ priv/main/vex_util.h \ @@ -22,6 +23,7 @@ LIB_OBJS = priv/ir/irdefs.o \ priv/main/vex_globals.o \ priv/main/vex_util.o \ priv/host-x86/hdefs.o \ + priv/host-arm/hdefs.o \ priv/host-x86/isel.o \ priv/host-generic/h_generic_regs.o \ priv/host-generic/reg_alloc2.o \ @@ -106,6 +108,10 @@ priv/host-x86/hdefs.o: $(ALL_HEADERS) priv/host-x86/hdefs.c $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host-x86/hdefs.o \ -c priv/host-x86/hdefs.c +priv/host-arm/hdefs.o: $(ALL_HEADERS) priv/host-arm/hdefs.c + $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host-arm/hdefs.o \ + -c priv/host-arm/hdefs.c + priv/host-x86/isel.o: $(ALL_HEADERS) priv/host-x86/isel.c $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host-x86/isel.o \ -c priv/host-x86/isel.c diff --git a/VEX/priv/host-arm/hdefs.c b/VEX/priv/host-arm/hdefs.c new file mode 100644 index 0000000000..939bd0abba --- /dev/null +++ b/VEX/priv/host-arm/hdefs.c @@ -0,0 +1,684 @@ + +/*---------------------------------------------------------------*/ +/*--- ---*/ +/*--- This file (host-arm/hdefs.c) is ---*/ +/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/ +/*--- ---*/ +/*---------------------------------------------------------------*/ + +/* + This file is part of LibVEX, a library for dynamic binary + instrumentation and translation. + + Copyright (C) 2004 OpenWorks, LLP. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; Version 2 dated June 1991 of the + license. + + This program 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, or liability + for damages. See the GNU General Public License for more details. + + 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. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +*/ + +#include "libvex_basictypes.h" +#include "libvex.h" +#include "libvex_trc_values.h" + +#include "main/vex_util.h" +#include "host-generic/h_generic_regs.h" +#include "host-arm/hdefs.h" + + + +/* --------- Registers. --------- */ + +/* The usual HReg abstraction. There are 8 real int regs, + 6 real float regs, and 0 real vector regs. +*/ + + +/* --------- Registers. --------- */ + +void ppHRegARM ( HReg reg ) { + Int r; + static HChar* ireg32_names[16] + = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", + "r9", "r10", "r11", "r12", "r13", "r14", "r15" }; + + /* Be generic for all virtual regs. */ + if (hregIsVirtual(reg)) { + ppHReg(reg); + return; + } + /* But specific for real regs. */ + switch (hregClass(reg)) { + case HRcInt32: + r = hregNumber(reg); + vassert(r >= 0 && r < 16); + vex_printf("%s", ireg32_names[r]); + return; + default: + vpanic("ppHRegARM"); + } +} + +HReg hregARM_R0 ( void ) { return mkHReg(0, HRcInt32, False); } +HReg hregARM_R1 ( void ) { return mkHReg(1, HRcInt32, False); } +HReg hregARM_R2 ( void ) { return mkHReg(2, HRcInt32, False); } +HReg hregARM_R3 ( void ) { return mkHReg(3, HRcInt32, False); } +HReg hregARM_R4 ( void ) { return mkHReg(4, HRcInt32, False); } +HReg hregARM_R5 ( void ) { return mkHReg(5, HRcInt32, False); } +HReg hregARM_R6 ( void ) { return mkHReg(6, HRcInt32, False); } +HReg hregARM_R7 ( void ) { return mkHReg(7, HRcInt32, False); } +HReg hregARM_R8 ( void ) { return mkHReg(8, HRcInt32, False); } +HReg hregARM_R9 ( void ) { return mkHReg(9, HRcInt32, False); } +HReg hregARM_R10 ( void ) { return mkHReg(10, HRcInt32, False); } +HReg hregARM_R11 ( void ) { return mkHReg(11, HRcInt32, False); } +HReg hregARM_R12 ( void ) { return mkHReg(12, HRcInt32, False); } +HReg hregARM_R13 ( void ) { return mkHReg(13, HRcInt32, False); } +HReg hregARM_R14 ( void ) { return mkHReg(14, HRcInt32, False); } +HReg hregARM_R15 ( void ) { return mkHReg(15, HRcInt32, False); } + +void getAllocableRegs_ARM ( Int* nregs, HReg** arr ) { + *nregs = 20; + *arr = LibVEX_Alloc(*nregs * sizeof(HReg)); + (*arr)[0] = hregARM_R0(); + (*arr)[1] = hregARM_R1(); + (*arr)[2] = hregARM_R2(); + (*arr)[3] = hregARM_R3(); + (*arr)[4] = hregARM_R4(); + (*arr)[5] = hregARM_R5(); + (*arr)[6] = hregARM_R6(); + (*arr)[7] = hregARM_R7(); + (*arr)[8] = hregARM_R8(); + (*arr)[9] = hregARM_R9(); + (*arr)[10] = hregARM_R10(); + (*arr)[11] = hregARM_R11(); + (*arr)[12] = hregARM_R12(); + (*arr)[13] = hregARM_R13(); + (*arr)[14] = hregARM_R14(); + (*arr)[15] = hregARM_R15(); +} + + + +/* --------- Condition codes, ARM encoding. --------- */ + +HChar* showARMCondCode ( ARMCondCode cond ) { + switch (cond) { + case ARMccEQ: return "eq"; + case ARMccNE: return "ne"; + case ARMccHS: return "hs"; + case ARMccLO: return "lo"; + case ARMccMI: return "mi"; + case ARMccPL: return "pl"; + case ARMccVS: return "vs"; + case ARMccVC: return "vc"; + case ARMccHI: return "hi"; + case ARMccLS: return "ls"; + case ARMccGE: return "ge"; + case ARMccLT: return "lt"; + case ARMccGT: return "gt"; + case ARMccLE: return "le"; + case ARMccAL: return "al"; // default + case ARMccNV: return "nv"; + default: vpanic("showARMCondCode"); + } +} + + +/* --------- ARMAMode1: memory address expressions. --------- */ + +ARMAMode1* ARMAMode1_I12A ( ARMImm12A imm ) { + ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); + am->tag = ARMam1_I12A; + am->ARMam1.I12A.imm = imm; + return am; +} +ARMAMode1* ARMAMode1_ShlI ( HReg Rm, ARMImm5 imm ) { + ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); + am->tag = ARMam1_ShlI; + am->ARMam1.ShlI.Rm = Rm; + am->ARMam1.ShlI.imm = imm; + return am; +} +ARMAMode1* ARMAMode1_ShrI ( HReg Rm, ARMImm5 imm ) { + ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); + am->tag = ARMam1_ShrI; + am->ARMam1.ShrI.Rm = Rm; + am->ARMam1.ShrI.imm = imm; + return am; +} +ARMAMode1* ARMAMode1_SarI ( HReg Rm, ARMImm5 imm ) { + ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); + am->tag = ARMam1_SarI; + am->ARMam1.SarI.Rm = Rm; + am->ARMam1.SarI.imm = imm; + return am; +} +ARMAMode1* ARMAMode1_ShlR ( HReg Rm, HReg Rs ) { + ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); + am->tag = ARMam1_ShlR; + am->ARMam1.ShlR.Rm = Rm; + am->ARMam1.ShlR.Rs = Rs; + return am; +} +ARMAMode1* ARMAMode1_ShrR ( HReg Rm, HReg Rs ) { + ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); + am->tag = ARMam1_ShrR; + am->ARMam1.ShrR.Rm = Rm; + am->ARMam1.ShrR.Rs = Rs; + return am; +} +ARMAMode1* ARMAMode1_SarR ( HReg Rm, HReg Rs ) { + ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); + am->tag = ARMam1_SarR; + am->ARMam1.SarR.Rm = Rm; + am->ARMam1.SarR.Rs = Rs; + return am; +} + +ARMAMode1* dopyARMAMode1 ( ARMAMode1* am ) { + switch (am->tag) { + case ARMam1_I12A: + return ARMAMode1_I12A( am->ARMam1.I12A.imm ); + case ARMam1_ShlI: + return ARMAMode1_ShlI( am->ARMam1.ShlI.Rm, am->ARMam1.ShlI.imm ); + case ARMam1_ShrI: + return ARMAMode1_ShrI( am->ARMam1.ShrI.Rm, am->ARMam1.ShrI.imm ); + case ARMam1_SarI: + return ARMAMode1_SarI( am->ARMam1.SarI.Rm, am->ARMam1.SarI.imm ); + case ARMam1_ShlR: + return ARMAMode1_ShlR( am->ARMam1.ShlR.Rm, am->ARMam1.ShlR.Rs ); + case ARMam1_ShrR: + return ARMAMode1_ShrR( am->ARMam1.ShrR.Rm, am->ARMam1.ShrR.Rs ); + case ARMam1_SarR: + return ARMAMode1_SarR( am->ARMam1.SarR.Rm, am->ARMam1.SarR.Rs ); + default: + vpanic("dopyARMAMode1"); + } +} + +void ppARMAMode1 ( ARMAMode1* am ) { + switch (am->tag) { + case ARMam1_I12A: + case ARMam1_ShlI: + case ARMam1_ShrI: + case ARMam1_SarI: + case ARMam1_ShlR: + case ARMam1_ShrR: + case ARMam1_SarR: + vex_printf("ppARMAMode1: Not implemented"); + break; + default: + vpanic("ppARMAMode1"); + } +} + +/* +static void addRegUsage_ARMAMode1 ( HRegUsage* u, ARMAMode1* am ) { +static void mapRegs_ARMAMode1 ( HRegRemap* m, ARMAMode1* am ) { +*/ + + +/* --------- ARMAMode2: memory address expressions. --------- */ + +ARMAMode2* ARMAMode2_RI ( HReg Rn, ARMImm12 imm ) { + ARMAMode2* am = LibVEX_Alloc(sizeof(ARMAMode2)); + am->tag = ARMam2_RI; + am->ARMam2.RI.Rn = Rn; + am->ARMam2.RI.imm = imm; + return am; +} +ARMAMode2* ARMAMode2_RR ( HReg Rn, HReg Rm ) { + ARMAMode2* am = LibVEX_Alloc(sizeof(ARMAMode2)); + am->tag = ARMam2_RR; + am->ARMam2.RR.Rn = Rn; + am->ARMam2.RR.Rm = Rm; + return am; +} +ARMAMode2* ARMAMode2_RRS ( HReg Rn, HReg Rm, ARMImm5 shift ) { + ARMAMode2* am = LibVEX_Alloc(sizeof(ARMAMode2)); + am->tag = ARMam2_RRS; + am->ARMam2.RRS.Rn = Rn; + am->ARMam2.RRS.Rm = Rm; + am->ARMam2.RRS.shift = shift; + return am; +} + +ARMAMode2* dopyARMAMode2 ( ARMAMode2* am ) { + switch (am->tag) { + case ARMam2_RI: + return ARMAMode2_RI( am->ARMam2.RI.Rn, am->ARMam2.RI.imm ); + case ARMam2_RR: + return ARMAMode2_RR( am->ARMam2.RR.Rn, am->ARMam2.RR.Rm ); + case ARMam2_RRS: + return ARMAMode2_RRS( am->ARMam2.RRS.Rn, am->ARMam2.RRS.Rm, + am->ARMam2.RRS.shift ); + default: + vpanic("dopyARMAMode2"); + } +} + +void ppARMAMode2 ( ARMAMode2* am ) { + switch (am->tag) { + case ARMam2_RI: + case ARMam2_RR: + case ARMam2_RRS: + vex_printf("ppARMAMode2: Not implemented"); + break; + default: + vpanic("ppARMAMode2"); + } +} + +/* +static void addRegUsage_ARMAMode2 ( HRegUsage* u, ARMAMode1* am ) { +static void mapRegs_ARMAMode2 ( HRegRemap* m, ARMAMode1* am ) { +*/ + + +/* --------- ARMAMode3: memory address expressions. --------- */ + +ARMAMode3* ARMAMode3_RI ( HReg Rn, ARMImm8 imm ) { + ARMAMode3* am = LibVEX_Alloc(sizeof(ARMAMode3)); + am->tag = ARMam3_RI; + am->ARMam3.RI.Rn = Rn; + am->ARMam3.RI.imm = imm; + return am; +} +ARMAMode3* ARMAMode3_RR ( HReg Rn, HReg Rm ) { + ARMAMode3* am = LibVEX_Alloc(sizeof(ARMAMode3)); + am->tag = ARMam3_RR; + am->ARMam3.RR.Rn = Rn; + am->ARMam3.RR.Rm = Rm; + return am; +} + +ARMAMode3* dopyARMAMode3 ( ARMAMode3* am ) { + switch (am->tag) { + case ARMam3_RI: + return ARMAMode3_RI( am->ARMam3.RI.Rn, am->ARMam3.RI.imm ); + case ARMam3_RR: + return ARMAMode3_RR( am->ARMam3.RR.Rn, am->ARMam3.RR.Rm ); + default: + vpanic("dopyARMAMode3"); + } +} + +void ppARMAMode3 ( ARMAMode3* am ) { + switch (am->tag) { + case ARMam3_RI: + case ARMam3_RR: + vex_printf("ppARMAMode3: Not implemented"); + break; + default: + vpanic("ppARMAMode3"); + } +} + +/* +static void addRegUsage_ARMAMode1 ( HRegUsage* u, ARMAMode2* am ) { +static void mapRegs_ARMAMode2 ( HRegRemap* m, ARMAMode2* am ) { +*/ + +/* ------ Branch destination ------ */ + +ARMBranchDest* ARMBranchDest_Imm ( ARMImm24 imm24 ) { + ARMBranchDest* branch_dest = LibVEX_Alloc(sizeof(ARMBranchDest)); + branch_dest->tag = ARMbdImm; + branch_dest->ARMbd.Imm.imm24 = imm24; + return branch_dest; +} +ARMBranchDest* ARMBranchDest_Reg ( HReg reg ) { + ARMBranchDest* branch_dest = LibVEX_Alloc(sizeof(ARMBranchDest)); + branch_dest->tag = ARMbdReg; + branch_dest->ARMbd.Reg.reg = reg; + return branch_dest; +} + +void ppARMBranchDest ( ARMBranchDest* branch_dest ) { + switch (branch_dest->tag) { + case ARMbdImm: + case ARMbdReg: + vex_printf("ppARMBranchDest: Not implemented"); + break; + default: + vpanic("ppX86RM"); + } +} + + + + +/* --------- Instructions. --------- */ + +HChar* showARMAluOp ( ARMAluOp op ) { + switch (op) { + case ARMalu_And: return "and"; + case ARMalu_Orr: return "orr"; + case ARMalu_Eor: return "eor"; + case ARMalu_Sub: return "sub"; + case ARMalu_Rsb: return "rsb"; + case ARMalu_Add: return "add"; + case ARMalu_Adc: return "adc"; + case ARMalu_Sbc: return "sbc"; + case ARMalu_Rsc: return "rsc"; + case ARMalu_Tst: return "tst"; + case ARMalu_Teq: return "teq"; + case ARMalu_Cmp: return "cmp"; + case ARMalu_Cmn: return "cmn"; + case ARMalu_Mov: return "mov"; + case ARMalu_Mvn: return "mvn"; + case ARMalu_Bic: return "vic"; + default: vpanic("showARMAluOp"); + } +} + +/* --- Addressing Mode 1 --- */ +ARMInstr* ARMInstr_DPCmp ( ARMAluOp op, HReg Rn, + ARMAMode1 shifter_op ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_DPCmp; + i->ARMin.DPCmp.op = op; + i->ARMin.DPCmp.Rn = Rn; + i->ARMin.DPCmp.shifter_op = shifter_op; + return i; +} + +ARMInstr* ARMInstr_DPInstr1 ( ARMAluOp op, HReg Rd, + ARMAMode1 shifter_op ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_DPInstr1; + i->ARMin.DPInstr1.op = op; + i->ARMin.DPInstr1.Rd = Rd; + i->ARMin.DPInstr1.shifter_op = shifter_op; + return i; +} + +ARMInstr* ARMInstr_DPInstr2 ( ARMAluOp op, HReg Rd, HReg Rn, + ARMAMode1 shifter_op ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_DPInstr2; + i->ARMin.DPInstr2.op = op; + i->ARMin.DPInstr2.Rd = Rd; + i->ARMin.DPInstr2.Rn = Rn; + i->ARMin.DPInstr2.shifter_op = shifter_op; + return i; +} + +/* --- Addressing Mode 2 --- */ +ARMInstr* ARMInstr_LoadUB ( HReg Rd, ARMAMode2 addr_mode ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_LoadUB; + i->ARMin.LoadUB.Rd = Rd; + i->ARMin.LoadUB.addr_mode = addr_mode; + return i; +} + +ARMInstr* ARMInstr_StoreB ( HReg Rd, ARMAMode2 addr_mode ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_StoreB; + i->ARMin.StoreB.Rd = Rd; + i->ARMin.StoreB.addr_mode = addr_mode; + return i; +} + +ARMInstr* ARMInstr_LoadW ( HReg Rd, ARMAMode2 addr_mode ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_LoadW; + i->ARMin.LoadW.Rd = Rd; + i->ARMin.LoadW.addr_mode = addr_mode; + return i; +} + +ARMInstr* ARMInstr_StoreW ( HReg Rd, ARMAMode2 addr_mode ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_StoreW; + i->ARMin.StoreW.Rd = Rd; + i->ARMin.StoreW.addr_mode = addr_mode; + return i; +} + +/* --- Addressing Mode 3 --- */ +ARMInstr* ARMInstr_LoadSB ( HReg Rd, ARMAMode3 addr_mode ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_LoadSB; + i->ARMin.LoadSB.Rd = Rd; + i->ARMin.LoadSB.addr_mode = addr_mode; + return i; +} + +ARMInstr* ARMInstr_LoadUH ( HReg Rd, ARMAMode3 addr_mode ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_LoadUH; + i->ARMin.LoadUH.Rd = Rd; + i->ARMin.LoadUH.addr_mode = addr_mode; + return i; +} + +ARMInstr* ARMInstr_LoadSH ( HReg Rd, ARMAMode3 addr_mode ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_LoadSH; + i->ARMin.LoadSH.Rd = Rd; + i->ARMin.LoadSH.addr_mode = addr_mode; + return i; +} + +ARMInstr* ARMInstr_StoreH ( HReg Rd, ARMAMode3 addr_mode ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_StoreH; + i->ARMin.StoreH.Rd = Rd; + i->ARMin.StoreH.addr_mode = addr_mode; + return i; +} + +/* --- Branch --- */ +ARMInstr* ARMInstr_Branch ( ARMCondCode cond, ARMBranchDest dest ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_Branch; + i->ARMin.Branch.cond = cond; + i->ARMin.Branch.dest = dest; + return i; +} + +ARMInstr* ARMInstr_BranchL ( ARMBranchDest dest ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_BranchL; + i->ARMin.BranchL.dest = dest; + return i; +} + +/* --- Literal --- */ +ARMInstr* ARMInstr_Literal ( HReg reg, ARMImm12A imm12a ) { + ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); + i->tag = ARMin_Literal; + i->ARMin.Literal.reg = reg; + i->ARMin.Literal.imm12a = imm12a; + return i; +} + + +void ppARMInstr ( ARMInstr* i ) { + switch (i->tag) { + case ARMin_DPCmp: + case ARMin_DPInstr1: + case ARMin_DPInstr2: + case ARMin_LoadUB: + case ARMin_StoreB: + case ARMin_LoadW: + case ARMin_StoreW: + case ARMin_LoadSB: + case ARMin_LoadUH: + case ARMin_LoadSH: + case ARMin_StoreH: + case ARMin_Branch: + case ARMin_BranchL: + case ARMin_Literal: + vex_printf("ppARMInstr: Not implemented"); + break; + + default: + vpanic("ppARMInstr"); + } +} + + + + +/* --------- Helpers for register allocation. --------- */ + +void getRegUsage_ARMInstr ( HRegUsage* u, ARMInstr* i ) { +// Bool unary; + initHRegUsage(u); + switch (i->tag) { + case ARMin_DPCmp: + case ARMin_DPInstr1: + case ARMin_DPInstr2: + case ARMin_LoadUB: + case ARMin_StoreB: + case ARMin_LoadW: + case ARMin_StoreW: + case ARMin_LoadSB: + case ARMin_LoadUH: + case ARMin_LoadSH: + case ARMin_StoreH: + case ARMin_Branch: + case ARMin_BranchL: + case ARMin_Literal: + + default: + ppARMInstr(i); + vpanic("getRegUsage_ARMInstr"); + } +} + + +/* local helper */ +#if 0 +static void mapReg(HRegRemap* m, HReg* r) { + *r = lookupHRegRemap(m, *r); +} +#endif + +void mapRegs_ARMInstr ( HRegRemap* m, ARMInstr* i ) { + switch (i->tag) { + case ARMin_DPCmp: + case ARMin_DPInstr1: + case ARMin_DPInstr2: + case ARMin_LoadUB: + case ARMin_StoreB: + case ARMin_LoadW: + case ARMin_StoreW: + case ARMin_LoadSB: + case ARMin_LoadUH: + case ARMin_LoadSH: + case ARMin_StoreH: + case ARMin_Branch: + case ARMin_BranchL: + case ARMin_Literal: + + default: + ppARMInstr(i); + vpanic("getRegUsage_ARMInstr"); + } +} + +/* Figure out if i represents a reg-reg move, and if so assign the + source and destination to *src and *dst. If in doubt say No. Used + by the register allocator to do move coalescing. +*/ +Bool isMove_ARMInstr ( ARMInstr* i, HReg* src, HReg* dst ) { + return False; // No optimisations for now... +} + + +/* Generate x86 spill/reload instructions under the direction of the + register allocator. Note it's critical these don't write the + condition codes. */ + +ARMInstr* genSpill_ARM ( HReg rreg, Int offsetB ) { +// ARMAMode1* am; + vassert(offsetB >= 0); + vassert(!hregIsVirtual(rreg)); + + switch (hregClass(rreg)) { + + default: + ppHRegClass(hregClass(rreg)); + vpanic("genSpill_ARM: unimplemented regclass"); + } +} + +ARMInstr* genReload_ARM ( HReg rreg, Int offsetB ) { +// ARMAMode1* am; + vassert(offsetB >= 0); + vassert(!hregIsVirtual(rreg)); + + switch (hregClass(rreg)) { + + default: + ppHRegClass(hregClass(rreg)); + vpanic("genReload_ARM: unimplemented regclass"); + } +} + + +/* Emit an instruction into buf and return the number of bytes used. + Note that buf is not the insn's final place, and therefore it is + imperative to emit position-independent code. */ + +Int emit_ARMInstr ( UChar* buf, Int nbuf, ARMInstr* i ) { +// UInt irno, opc, opc_rr, subopc_imm, opc_imma, opc_cl, opc_imm, subopc; + +// UInt xtra; + UChar* p = &buf[0]; +// UChar* ptmp; + vassert(nbuf >= 32); + + switch (i->tag) { + case ARMin_DPCmp: + case ARMin_DPInstr1: + case ARMin_DPInstr2: + case ARMin_LoadUB: + case ARMin_StoreB: + case ARMin_LoadW: + case ARMin_StoreW: + case ARMin_LoadSB: + case ARMin_LoadUH: + case ARMin_LoadSH: + case ARMin_StoreH: + case ARMin_Branch: + case ARMin_BranchL: + case ARMin_Literal: + default: + goto bad; + } + + bad: + ppARMInstr(i); + vpanic("emit_ARMInstr"); + /*NOTREACHED*/ + +// done: + vassert(p - &buf[0] <= 32); + return p - &buf[0]; +} + + +/*---------------------------------------------------------------*/ +/*--- end host-x86/hdefs.c ---*/ +/*---------------------------------------------------------------*/ diff --git a/VEX/priv/host-arm/hdefs.h b/VEX/priv/host-arm/hdefs.h index 6ade681a28..fb19ad5691 100644 --- a/VEX/priv/host-arm/hdefs.h +++ b/VEX/priv/host-arm/hdefs.h @@ -121,13 +121,13 @@ typedef UInt ARMImm24; // Branch imm /* --- Addressing Mode 1 --- */ typedef enum { - ARMam_I12A, /* Imm12A: extended (rotated) immedate */ - ARMam_ShlI, /* ShlI reg Imm5 */ - ARMam_ShrI, /* ShrI reg Imm5 */ - ARMam_SarI, /* SarI reg Imm5 */ - ARMam_ShlR, /* ShlR reg reg */ - ARMam_ShrR, /* ShrR reg reg */ - ARMam_SarR, /* SarR reg reg */ + 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; @@ -162,12 +162,11 @@ typedef HReg Rm; HReg Rs; } SarR; - } ARMam; + } 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 ); @@ -184,9 +183,9 @@ extern void ppARMAMode1 ( ARMAMode1* ); /* --- Addressing Mode 2 --- */ typedef enum { - ARMam_RI12, /* Reg +/- Imm12 */ - ARMam_RR2, /* Reg +/- Reg */ - ARMam_RRS, /* Reg +/- (Reg << Imm5) */ + ARMam2_RI, /* Reg +/- Imm12 */ + ARMam2_RR, /* Reg +/- Reg */ + ARMam2_RRS, /* Reg +/- (Reg << Imm5) */ } ARMAMode2Tag; @@ -207,15 +206,15 @@ typedef HReg Rm; ARMImm5 shift; } RRS; - } ARMam; + } ARMam2; } ARMAMode2; -extern ARMAMode2* ARMAMode2_RI12 ( HReg, Int ); -extern ARMAMode2* ARMAMode2_RR2 ( HReg, HReg ); -extern ARMAMode2* ARMAMode2_RRS ( HReg, HReg, Int ); +extern ARMAMode2* ARMAMode2_RI ( HReg, ARMImm12 ); +extern ARMAMode2* ARMAMode2_RR ( HReg, HReg ); +extern ARMAMode2* ARMAMode2_RRS ( HReg, HReg, ARMImm5 ); -extern ARMAMode2* dopyARMMode2 ( ARMAMode2* ); +extern ARMAMode2* dopyARMAMode2 ( ARMAMode2* ); extern void ppARMAMode2 ( ARMAMode2* ); @@ -223,8 +222,8 @@ extern void ppARMAMode2 ( ARMAMode2* ); /* --- Addressing Mode 3 --- */ typedef enum { - ARMam_RI8, /* Reg +/- Imm8 */ - ARMam_RR3, /* Reg +/- Reg */ + ARMam3_RI, /* Reg +/- Imm8 */ + ARMam3_RR, /* Reg +/- Reg */ } ARMAMode3Tag; @@ -233,20 +232,20 @@ typedef ARMAMode3Tag tag; union { struct { - HReg reg; + HReg Rn; ARMImm8 imm; } RI; struct { HReg Rn; HReg Rm; } RR; - } ARMam; + } ARMam3; } ARMAMode3; -extern ARMAMode3* ARMAMode3_RI8 ( HReg, Int ); -extern ARMAMode3* ARMAMode3_RR3 ( HReg, HReg ); +extern ARMAMode3* ARMAMode3_RI ( HReg, ARMImm8 ); +extern ARMAMode3* ARMAMode3_RR ( HReg, HReg ); extern ARMAMode3* dopyARMAMode3 ( ARMAMode3* ); @@ -258,7 +257,7 @@ extern void ppARMAMode3 ( ARMAMode3* ); /* ------ Branch destination ------ */ typedef enum { - ARMbdImm24, + ARMbdImm, ARMbdReg } ARMBranchTag; @@ -268,8 +267,8 @@ typedef ARMBranchTag tag; union { struct { - ARMImm24 imm; - } Imm24; + ARMImm24 imm24; + } Imm; struct { HReg reg; } Reg; @@ -277,6 +276,10 @@ typedef } ARMBranchDest; +extern ARMBranchDest* ARMBranchDest_Imm ( ARMImm24 ); +extern ARMBranchDest* ARMBranchDest_Reg ( HReg ); + +extern void ppARMBranchDest ( ARMBranchDest* ); /* --------- Instructions. --------- */ @@ -285,11 +288,10 @@ typedef /* --- DPI's --- */ typedef enum { - ARMalu_And, ARMalu_Orr, ARMalu_Eor, // Logic + 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 - ARMalu_Bic // Bit clear + ARMalu_Mov, ARMalu_Mvn // Move } ARMAluOp; @@ -379,6 +381,7 @@ typedef } StoreH; + /* Branch */ struct { ARMCondCode cond; ARMBranchDest dest; @@ -387,7 +390,7 @@ typedef ARMBranchDest dest; } BranchL; // -- don't want to do conditional BLs - + /* Literal */ struct { HReg reg; ARMImm12A imm12a; @@ -417,10 +420,9 @@ extern ARMInstr* ARMInstr_Literal ( HReg, ARMImm12A ); extern void ppARMInstr ( ARMInstr* ); - -#if 0 /* 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* ); @@ -429,7 +431,6 @@ 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 #endif /* ndef __LIBVEX_ARMH_DEFS_H */