]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Cleaned up hdefs.h, fleshed out hdefs.c
authorCerion Armour-Brown <cerion@valgrind.org>
Thu, 16 Dec 2004 14:06:34 +0000 (14:06 +0000)
committerCerion Armour-Brown <cerion@valgrind.org>
Thu, 16 Dec 2004 14:06:34 +0000 (14:06 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@670

VEX/Makefile
VEX/priv/host-arm/hdefs.c [new file with mode: 0644]
VEX/priv/host-arm/hdefs.h

index bed2d78e4a30668a8f1e9511485c9accb9300f82..12aaed8ab784464463cc09cc31d6eb836544db00 100644 (file)
@@ -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 (file)
index 0000000..939bd0a
--- /dev/null
@@ -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 ---*/
+/*---------------------------------------------------------------*/
index 6ade681a2851f59b9031b2420bbc08b0d566e784..fb19ad5691ed13455601798e4fa7764c3f592b2d 100644 (file)
@@ -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 */