Quick compiler: Single .so for all targets

With this CL, all targets can be built into a single .so (but
we're not yet doing so - the compiler driver needs to be reworked).

A new Codgen class is introduced (see compiler/codegen/codegen.h),
along with target-specific sub-classes ArmCodegen, MipsCodegens and
X86Codegen (see compiler/codegen/*/codegen_[Arm|Mips|X86].h).

Additional minor code, comment and format refactoring.  Some source
files combined, temporary header files deleted and a few file
renames to better identify their function.

Next up is combining the Quick and Portable .so files.

Note: building all targets into libdvm-compiler.so increases its
size by 140K bytes.  I'm inclined to not bother introducing conditional
compilation to limit code to the specific target - the added build and
testing complexity doesn't doesn't seem worth such a modest size savings.

Change-Id: Id9c5b4502ad6b77cdb31f71d3126f51a4f2e9dfe
diff --git a/src/compiler/codegen/arm/arm_lir.h b/src/compiler/codegen/arm/arm_lir.h
index 7955b1b..09b45b8 100644
--- a/src/compiler/codegen/arm/arm_lir.h
+++ b/src/compiler/codegen/arm/arm_lir.h
@@ -93,18 +93,19 @@
  * +========================+
  */
 
-/* Offset to distingish FP regs */
+// Offset to distingish FP regs.
 #define ARM_FP_REG_OFFSET 32
-/* Offset to distinguish DP FP regs */
+// Offset to distinguish DP FP regs.
 #define ARM_FP_DOUBLE 64
-/* First FP callee save */
+// First FP callee save.
 #define ARM_FP_CALLEE_SAVE_BASE 16
-/* Reg types */
+// Reg types.
 #define ARM_REGTYPE(x) (x & (ARM_FP_REG_OFFSET | ARM_FP_DOUBLE))
 #define ARM_FPREG(x) ((x & ARM_FP_REG_OFFSET) == ARM_FP_REG_OFFSET)
 #define ARM_LOWREG(x) ((x & 0x7) == x)
 #define ARM_DOUBLEREG(x) ((x & ARM_FP_DOUBLE) == ARM_FP_DOUBLE)
 #define ARM_SINGLEREG(x) (ARM_FPREG(x) && !ARM_DOUBLEREG(x))
+
 /*
  * Note: the low register of a floating point pair is sufficient to
  * create the name of a double, but require both names to be passed to
@@ -113,10 +114,10 @@
  * code that reg locations always describe doubles as a pair of singles.
  */
 #define ARM_S2D(x,y) ((x) | ARM_FP_DOUBLE)
-/* Mask to strip off fp flags */
+// Mask to strip off fp flags.
 #define ARM_FP_REG_MASK (ARM_FP_REG_OFFSET-1)
 
-/* RegisterLocation templates return values (r0, or r0/r1) */
+// RegisterLocation templates return values (r0, or r0/r1).
 #define ARM_LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r0, INVALID_REG,\
                           INVALID_SREG, INVALID_SREG}
 #define ARM_LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1, \
@@ -210,7 +211,7 @@
   dr15 = fr30 + ARM_FP_DOUBLE,
 };
 
-/* Target-independent aliases */
+// Target-independent aliases.
 #define rARM_ARG0 r0
 #define rARM_ARG1 r1
 #define rARM_ARG2 r2
@@ -224,7 +225,6 @@
 #define rARM_INVOKE_TGT rARM_LR
 #define rARM_COUNT INVALID_REG
 
-/* Shift encodings */
 enum ArmShiftEncodings {
   kArmLsl = 0x0,
   kArmLsr = 0x1,
@@ -238,326 +238,216 @@
  * Assemble.cc.
  */
 enum ArmOpcode {
-  /************************************************************************/
   kArmFirst = 0,
-  kArm16BitData = kArmFirst, /* DATA   [0] rd[15..0] */
-  kThumbAdcRR,       /* adc   [0100000101] rm[5..3] rd[2..0] */
-  kThumbAddRRI3,     /* add(1)  [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/
-  kThumbAddRI8,      /* add(2)  [00110] rd[10..8] imm_8[7..0] */
-  kThumbAddRRR,      /* add(3)  [0001100] rm[8..6] rn[5..3] rd[2..0] */
-  kThumbAddRRLH,     /* add(4)  [01000100] H12[01] rm[5..3] rd[2..0] */
-  kThumbAddRRHL,     /* add(4)  [01001000] H12[10] rm[5..3] rd[2..0] */
-  kThumbAddRRHH,     /* add(4)  [01001100] H12[11] rm[5..3] rd[2..0] */
-  kThumbAddPcRel,    /* add(5)  [10100] rd[10..8] imm_8[7..0] */
-  kThumbAddSpRel,    /* add(6)  [10101] rd[10..8] imm_8[7..0] */
-  kThumbAddSpI7,     /* add(7)  [101100000] imm_7[6..0] */
-  kThumbAndRR,       /* and   [0100000000] rm[5..3] rd[2..0] */
-  kThumbAsrRRI5,     /* asr(1)  [00010] imm_5[10..6] rm[5..3] rd[2..0] */
-  kThumbAsrRR,       /* asr(2)  [0100000100] rs[5..3] rd[2..0] */
-  kThumbBCond,       /* b(1)  [1101] cond[11..8] offset_8[7..0] */
-  kThumbBUncond,     /* b(2)  [11100] offset_11[10..0] */
-  kThumbBicRR,       /* bic   [0100001110] rm[5..3] rd[2..0] */
-  kThumbBkpt,        /* bkpt  [10111110] imm_8[7..0] */
-  kThumbBlx1,        /* blx(1)  [111] H[10] offset_11[10..0] */
-  kThumbBlx2,        /* blx(1)  [111] H[01] offset_11[10..0] */
-  kThumbBl1,         /* blx(1)  [111] H[10] offset_11[10..0] */
-  kThumbBl2,         /* blx(1)  [111] H[11] offset_11[10..0] */
-  kThumbBlxR,        /* blx(2)  [010001111] rm[6..3] [000] */
-  kThumbBx,          /* bx    [010001110] H2[6..6] rm[5..3] SBZ[000] */
-  kThumbCmnRR,       /* cmn   [0100001011] rm[5..3] rd[2..0] */
-  kThumbCmpRI8,      /* cmp(1)  [00101] rn[10..8] imm_8[7..0] */
-  kThumbCmpRR,       /* cmp(2)  [0100001010] rm[5..3] rd[2..0] */
-  kThumbCmpLH,       /* cmp(3)  [01000101] H12[01] rm[5..3] rd[2..0] */
-  kThumbCmpHL,       /* cmp(3)  [01000110] H12[10] rm[5..3] rd[2..0] */
-  kThumbCmpHH,       /* cmp(3)  [01000111] H12[11] rm[5..3] rd[2..0] */
-  kThumbEorRR,       /* eor   [0100000001] rm[5..3] rd[2..0] */
-  kThumbLdmia,       /* ldmia   [11001] rn[10..8] reglist [7..0] */
-  kThumbLdrRRI5,     /* ldr(1)  [01101] imm_5[10..6] rn[5..3] rd[2..0] */
-  kThumbLdrRRR,      /* ldr(2)  [0101100] rm[8..6] rn[5..3] rd[2..0] */
-  kThumbLdrPcRel,    /* ldr(3)  [01001] rd[10..8] imm_8[7..0] */
-  kThumbLdrSpRel,    /* ldr(4)  [10011] rd[10..8] imm_8[7..0] */
-  kThumbLdrbRRI5,    /* ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0] */
-  kThumbLdrbRRR,     /* ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0] */
-  kThumbLdrhRRI5,    /* ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0] */
-  kThumbLdrhRRR,     /* ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0] */
-  kThumbLdrsbRRR,    /* ldrsb   [0101011] rm[8..6] rn[5..3] rd[2..0] */
-  kThumbLdrshRRR,    /* ldrsh   [0101111] rm[8..6] rn[5..3] rd[2..0] */
-  kThumbLslRRI5,     /* lsl(1)  [00000] imm_5[10..6] rm[5..3] rd[2..0] */
-  kThumbLslRR,       /* lsl(2)  [0100000010] rs[5..3] rd[2..0] */
-  kThumbLsrRRI5,     /* lsr(1)  [00001] imm_5[10..6] rm[5..3] rd[2..0] */
-  kThumbLsrRR,       /* lsr(2)  [0100000011] rs[5..3] rd[2..0] */
-  kThumbMovImm,      /* mov(1)  [00100] rd[10..8] imm_8[7..0] */
-  kThumbMovRR,       /* mov(2)  [0001110000] rn[5..3] rd[2..0] */
-  kThumbMovRR_H2H,   /* mov(3)  [01000111] H12[11] rm[5..3] rd[2..0] */
-  kThumbMovRR_H2L,   /* mov(3)  [01000110] H12[01] rm[5..3] rd[2..0] */
-  kThumbMovRR_L2H,   /* mov(3)  [01000101] H12[10] rm[5..3] rd[2..0] */
-  kThumbMul,         /* mul   [0100001101] rm[5..3] rd[2..0] */
-  kThumbMvn,         /* mvn   [0100001111] rm[5..3] rd[2..0] */
-  kThumbNeg,         /* neg   [0100001001] rm[5..3] rd[2..0] */
-  kThumbOrr,         /* orr   [0100001100] rm[5..3] rd[2..0] */
-  kThumbPop,         /* pop   [1011110] r[8..8] rl[7..0] */
-  kThumbPush,        /* push  [1011010] r[8..8] rl[7..0] */
-  kThumbRorRR,       /* ror   [0100000111] rs[5..3] rd[2..0] */
-  kThumbSbc,         /* sbc   [0100000110] rm[5..3] rd[2..0] */
-  kThumbStmia,       /* stmia   [11000] rn[10..8] reglist [7.. 0] */
-  kThumbStrRRI5,     /* str(1)  [01100] imm_5[10..6] rn[5..3] rd[2..0] */
-  kThumbStrRRR,      /* str(2)  [0101000] rm[8..6] rn[5..3] rd[2..0] */
-  kThumbStrSpRel,    /* str(3)  [10010] rd[10..8] imm_8[7..0] */
-  kThumbStrbRRI5,    /* strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0] */
-  kThumbStrbRRR,     /* strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0] */
-  kThumbStrhRRI5,    /* strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0] */
-  kThumbStrhRRR,     /* strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0] */
-  kThumbSubRRI3,     /* sub(1)  [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/
-  kThumbSubRI8,      /* sub(2)  [00111] rd[10..8] imm_8[7..0] */
-  kThumbSubRRR,      /* sub(3)  [0001101] rm[8..6] rn[5..3] rd[2..0] */
-  kThumbSubSpI7,     /* sub(4)  [101100001] imm_7[6..0] */
-  kThumbSwi,         /* swi   [11011111] imm_8[7..0] */
-  kThumbTst,         /* tst   [0100001000] rm[5..3] rn[2..0] */
-  kThumb2Vldrs,      /* vldr low  sx [111011011001] rn[19..16] rd[15-12]
-                       [1010] imm_8[7..0] */
-  kThumb2Vldrd,      /* vldr low  dx [111011011001] rn[19..16] rd[15-12]
-                        [1011] imm_8[7..0] */
-  kThumb2Vmuls,      /* vmul vd, vn, vm [111011100010] rn[19..16]
-                        rd[15-12] [10100000] rm[3..0] */
-  kThumb2Vmuld,      /* vmul vd, vn, vm [111011100010] rn[19..16]
-                        rd[15-12] [10110000] rm[3..0] */
-  kThumb2Vstrs,      /* vstr low  sx [111011011000] rn[19..16] rd[15-12]
-                        [1010] imm_8[7..0] */
-  kThumb2Vstrd,      /* vstr low  dx [111011011000] rn[19..16] rd[15-12]
-                        [1011] imm_8[7..0] */
-  kThumb2Vsubs,      /* vsub vd, vn, vm [111011100011] rn[19..16]
-                        rd[15-12] [10100040] rm[3..0] */
-  kThumb2Vsubd,      /* vsub vd, vn, vm [111011100011] rn[19..16]
-                        rd[15-12] [10110040] rm[3..0] */
-  kThumb2Vadds,      /* vadd vd, vn, vm [111011100011] rn[19..16]
-                        rd[15-12] [10100000] rm[3..0] */
-  kThumb2Vaddd,      /* vadd vd, vn, vm [111011100011] rn[19..16]
-                        rd[15-12] [10110000] rm[3..0] */
-  kThumb2Vdivs,      /* vdiv vd, vn, vm [111011101000] rn[19..16]
-                        rd[15-12] [10100000] rm[3..0] */
-  kThumb2Vdivd,      /* vdiv vd, vn, vm [111011101000] rn[19..16]
-                        rd[15-12] [10110000] rm[3..0] */
-  kThumb2VcvtIF,     /* vcvt.F32 vd, vm [1110111010111000] vd[15..12]
-                        [10101100] vm[3..0] */
-  kThumb2VcvtID,     /* vcvt.F64 vd, vm [1110111010111000] vd[15..12]
-                       [10111100] vm[3..0] */
-  kThumb2VcvtFI,     /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
-                       [10101100] vm[3..0] */
-  kThumb2VcvtDI,     /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
-                       [10111100] vm[3..0] */
-  kThumb2VcvtFd,     /* vcvt.F64.F32 vd, vm [1110111010110111] vd[15..12]
-                       [10101100] vm[3..0] */
-  kThumb2VcvtDF,     /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12]
-                       [10111100] vm[3..0] */
-  kThumb2Vsqrts,     /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12]
-                       [10101100] vm[3..0] */
-  kThumb2Vsqrtd,     /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12]
-                       [10111100] vm[3..0] */
-  kThumb2MovImmShift,/* mov(T2) rd, #<const> [11110] i [00001001111]
-                       imm3 rd[11..8] imm8 */
-  kThumb2MovImm16,   /* mov(T3) rd, #<const> [11110] i [0010100] imm4 [0]
-                       imm3 rd[11..8] imm8 */
-  kThumb2StrRRI12,   /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
-                       rn[19..16] rt[15..12] imm12[11..0] */
-  kThumb2LdrRRI12,   /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
-                       rn[19..16] rt[15..12] imm12[11..0] */
-  kThumb2StrRRI8Predec, /* str(Imm,T4) rd,[rn,#-imm8] [111110000100]
-                       rn[19..16] rt[15..12] [1100] imm[7..0]*/
-  kThumb2LdrRRI8Predec, /* ldr(Imm,T4) rd,[rn,#-imm8] [111110000101]
-                       rn[19..16] rt[15..12] [1100] imm[7..0]*/
-  kThumb2Cbnz,       /* cbnz rd,<label> [101110] i [1] imm5[7..3]
-                       rn[2..0] */
-  kThumb2Cbz,        /* cbn rd,<label> [101100] i [1] imm5[7..3]
-                       rn[2..0] */
-  kThumb2AddRRI12,   /* add rd, rn, #imm12 [11110] i [100000] rn[19..16]
-                       [0] imm3[14..12] rd[11..8] imm8[7..0] */
-  kThumb2MovRR,      /* mov rd, rm [11101010010011110000] rd[11..8]
-                       [0000] rm[3..0] */
-  kThumb2Vmovs,      /* vmov.f32 vd, vm [111011101] D [110000]
-                       vd[15..12] 101001] M [0] vm[3..0] */
-  kThumb2Vmovd,      /* vmov.f64 vd, vm [111011101] D [110000]
-                       vd[15..12] 101101] M [0] vm[3..0] */
-  kThumb2Ldmia,      /* ldmia  [111010001001[ rn[19..16] mask[15..0] */
-  kThumb2Stmia,      /* stmia  [111010001000[ rn[19..16] mask[15..0] */
-  kThumb2AddRRR,     /* add [111010110000] rn[19..16] [0000] rd[11..8]
-                        [0000] rm[3..0] */
-  kThumb2SubRRR,     /* sub [111010111010] rn[19..16] [0000] rd[11..8]
-                       [0000] rm[3..0] */
-  kThumb2SbcRRR,     /* sbc [111010110110] rn[19..16] [0000] rd[11..8]
-                       [0000] rm[3..0] */
-  kThumb2CmpRR,      /* cmp [111010111011] rn[19..16] [0000] [1111]
-                       [0000] rm[3..0] */
-  kThumb2SubRRI12,   /* sub rd, rn, #imm12 [11110] i [01010] rn[19..16]
-                       [0] imm3[14..12] rd[11..8] imm8[7..0] */
-  kThumb2MvnImm12,   /* mov(T2) rd, #<const> [11110] i [00011011110]
-                       imm3 rd[11..8] imm8 */
-  kThumb2Sel,        /* sel rd, rn, rm [111110101010] rn[19-16] rd[11-8]
-                       rm[3-0] */
-  kThumb2Ubfx,       /* ubfx rd,rn,#lsb,#width [111100111100] rn[19..16]
-                       [0] imm3[14-12] rd[11-8] w[4-0] */
-  kThumb2Sbfx,       /* ubfx rd,rn,#lsb,#width [111100110100] rn[19..16]
-                       [0] imm3[14-12] rd[11-8] w[4-0] */
-  kThumb2LdrRRR,     /* ldr rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
-                       rt[15-12] [000000] imm[5-4] rm[3-0] */
-  kThumb2LdrhRRR,    /* ldrh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
-                       rt[15-12] [000000] imm[5-4] rm[3-0] */
-  kThumb2LdrshRRR,   /* ldrsh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
-                       rt[15-12] [000000] imm[5-4] rm[3-0] */
-  kThumb2LdrbRRR,    /* ldrb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
-                       rt[15-12] [000000] imm[5-4] rm[3-0] */
-  kThumb2LdrsbRRR,   /* ldrsb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
-                       rt[15-12] [000000] imm[5-4] rm[3-0] */
-  kThumb2StrRRR,     /* str rt,[rn,rm,LSL #imm] [111110000100] rn[19-16]
-                       rt[15-12] [000000] imm[5-4] rm[3-0] */
-  kThumb2StrhRRR,    /* str rt,[rn,rm,LSL #imm] [111110000010] rn[19-16]
-                       rt[15-12] [000000] imm[5-4] rm[3-0] */
-  kThumb2StrbRRR,    /* str rt,[rn,rm,LSL #imm] [111110000000] rn[19-16]
-                       rt[15-12] [000000] imm[5-4] rm[3-0] */
-  kThumb2LdrhRRI12,  /* ldrh rt,[rn,#imm12] [111110001011]
-                       rt[15..12] rn[19..16] imm12[11..0] */
-  kThumb2LdrshRRI12, /* ldrsh rt,[rn,#imm12] [111110011011]
-                       rt[15..12] rn[19..16] imm12[11..0] */
-  kThumb2LdrbRRI12,  /* ldrb rt,[rn,#imm12] [111110001001]
-                       rt[15..12] rn[19..16] imm12[11..0] */
-  kThumb2LdrsbRRI12, /* ldrsb rt,[rn,#imm12] [111110011001]
-                       rt[15..12] rn[19..16] imm12[11..0] */
-  kThumb2StrhRRI12,  /* strh rt,[rn,#imm12] [111110001010]
-                       rt[15..12] rn[19..16] imm12[11..0] */
-  kThumb2StrbRRI12,  /* strb rt,[rn,#imm12] [111110001000]
-                       rt[15..12] rn[19..16] imm12[11..0] */
-  kThumb2Pop,        /* pop   [1110100010111101] list[15-0]*/
-  kThumb2Push,       /* push  [1110100100101101] list[15-0]*/
-  kThumb2CmpRI8,     /* cmp rn, #<const> [11110] i [011011] rn[19-16] [0]
-                       imm3 [1111] imm8[7..0] */
-  kThumb2AdcRRR,     /* adc [111010110101] rn[19..16] [0000] rd[11..8]
-                       [0000] rm[3..0] */
-  kThumb2AndRRR,     /* and [111010100000] rn[19..16] [0000] rd[11..8]
-                       [0000] rm[3..0] */
-  kThumb2BicRRR,     /* bic [111010100010] rn[19..16] [0000] rd[11..8]
-                       [0000] rm[3..0] */
-  kThumb2CmnRR,      /* cmn [111010110001] rn[19..16] [0000] [1111]
-                       [0000] rm[3..0] */
-  kThumb2EorRRR,     /* eor [111010101000] rn[19..16] [0000] rd[11..8]
-                       [0000] rm[3..0] */
-  kThumb2MulRRR,     /* mul [111110110000] rn[19..16] [1111] rd[11..8]
-                       [0000] rm[3..0] */
-  kThumb2MnvRR,      /* mvn [11101010011011110] rd[11-8] [0000]
-                       rm[3..0] */
-  kThumb2RsubRRI8,   /* rsub [111100011100] rn[19..16] [0000] rd[11..8]
-                       imm8[7..0] */
-  kThumb2NegRR,      /* actually rsub rd, rn, #0 */
-  kThumb2OrrRRR,     /* orr [111010100100] rn[19..16] [0000] rd[11..8]
-                       [0000] rm[3..0] */
-  kThumb2TstRR,      /* tst [111010100001] rn[19..16] [0000] [1111]
-                       [0000] rm[3..0] */
-  kThumb2LslRRR,     /* lsl [111110100000] rn[19..16] [1111] rd[11..8]
-                       [0000] rm[3..0] */
-  kThumb2LsrRRR,     /* lsr [111110100010] rn[19..16] [1111] rd[11..8]
-                        [0000] rm[3..0] */
-  kThumb2AsrRRR,     /* asr [111110100100] rn[19..16] [1111] rd[11..8]
-                       [0000] rm[3..0] */
-  kThumb2RorRRR,     /* ror [111110100110] rn[19..16] [1111] rd[11..8]
-                       [0000] rm[3..0] */
-  kThumb2LslRRI5,    /* lsl [11101010010011110] imm[14.12] rd[11..8]
-                       [00] rm[3..0] */
-  kThumb2LsrRRI5,    /* lsr [11101010010011110] imm[14.12] rd[11..8]
-                       [01] rm[3..0] */
-  kThumb2AsrRRI5,    /* asr [11101010010011110] imm[14.12] rd[11..8]
-                       [10] rm[3..0] */
-  kThumb2RorRRI5,    /* ror [11101010010011110] imm[14.12] rd[11..8]
-                       [11] rm[3..0] */
-  kThumb2BicRRI8,    /* bic [111100000010] rn[19..16] [0] imm3
-                       rd[11..8] imm8 */
-  kThumb2AndRRI8,    /* bic [111100000000] rn[19..16] [0] imm3
-                       rd[11..8] imm8 */
-  kThumb2OrrRRI8,    /* orr [111100000100] rn[19..16] [0] imm3
-                       rd[11..8] imm8 */
-  kThumb2EorRRI8,    /* eor [111100001000] rn[19..16] [0] imm3
-                       rd[11..8] imm8 */
-  kThumb2AddRRI8,    /* add [111100001000] rn[19..16] [0] imm3
-                       rd[11..8] imm8 */
-  kThumb2AdcRRI8,    /* adc [111100010101] rn[19..16] [0] imm3
-                       rd[11..8] imm8 */
-  kThumb2SubRRI8,    /* sub [111100011011] rn[19..16] [0] imm3
-                       rd[11..8] imm8 */
-  kThumb2SbcRRI8,    /* sbc [111100010111] rn[19..16] [0] imm3
-                       rd[11..8] imm8 */
-  kThumb2It,         /* it [10111111] firstcond[7-4] mask[3-0] */
-  kThumb2Fmstat,     /* fmstat [11101110111100011111101000010000] */
-  kThumb2Vcmpd,      /* vcmp [111011101] D [11011] rd[15-12] [1011]
-                        E [1] M [0] rm[3-0] */
-  kThumb2Vcmps,      /* vcmp [111011101] D [11010] rd[15-12] [1011]
-                        E [1] M [0] rm[3-0] */
-  kThumb2LdrPcRel12, /* ldr rd,[pc,#imm12] [1111100011011111] rt[15-12]
-                        imm12[11-0] */
-  kThumb2BCond,      /* b<c> [1110] S cond[25-22] imm6[21-16] [10]
-                        J1 [0] J2 imm11[10..0] */
-  kThumb2Vmovd_RR,   /* vmov [111011101] D [110000] vd[15-12 [101101]
-                        M [0] vm[3-0] */
-  kThumb2Vmovs_RR,   /* vmov [111011101] D [110000] vd[15-12 [101001]
-                        M [0] vm[3-0] */
-  kThumb2Fmrs,       /* vmov [111011100000] vn[19-16] rt[15-12] [1010]
-                        N [0010000] */
-  kThumb2Fmsr,       /* vmov [111011100001] vn[19-16] rt[15-12] [1010]
-                        N [0010000] */
-  kThumb2Fmrrd,      /* vmov [111011000100] rt2[19-16] rt[15-12]
-                        [101100] M [1] vm[3-0] */
-  kThumb2Fmdrr,      /* vmov [111011000101] rt2[19-16] rt[15-12]
-                        [101100] M [1] vm[3-0] */
-  kThumb2Vabsd,      /* vabs.f64 [111011101] D [110000] rd[15-12]
-                        [1011110] M [0] vm[3-0] */
-  kThumb2Vabss,      /* vabs.f32 [111011101] D [110000] rd[15-12]
-                        [1010110] M [0] vm[3-0] */
-  kThumb2Vnegd,      /* vneg.f64 [111011101] D [110000] rd[15-12]
-                        [1011110] M [0] vm[3-0] */
-  kThumb2Vnegs,      /* vneg.f32 [111011101] D [110000] rd[15-12]
-                        [1010110] M [0] vm[3-0] */
-  kThumb2Vmovs_IMM8, /* vmov.f32 [111011101] D [11] imm4h[19-16] vd[15-12]
-                        [10100000] imm4l[3-0] */
-  kThumb2Vmovd_IMM8, /* vmov.f64 [111011101] D [11] imm4h[19-16] vd[15-12]
-                        [10110000] imm4l[3-0] */
-  kThumb2Mla,        /* mla [111110110000] rn[19-16] ra[15-12] rd[7-4]
-                        [0000] rm[3-0] */
-  kThumb2Umull,      /* umull [111110111010] rn[19-16], rdlo[15-12]
-                        rdhi[11-8] [0000] rm[3-0] */
-  kThumb2Ldrex,      /* ldrex [111010000101] rn[19-16] rt[11-8] [1111]
-                        imm8[7-0] */
-  kThumb2Strex,      /* strex [111010000100] rn[19-16] rt[11-8] rd[11-8]
-                        imm8[7-0] */
-  kThumb2Clrex,      /* clrex [111100111011111110000111100101111] */
-  kThumb2Bfi,        /* bfi [111100110110] rn[19-16] [0] imm3[14-12]
-                        rd[11-8] imm2[7-6] [0] msb[4-0] */
-  kThumb2Bfc,        /* bfc [11110011011011110] [0] imm3[14-12]
-                        rd[11-8] imm2[7-6] [0] msb[4-0] */
-  kThumb2Dmb,        /* dmb [1111001110111111100011110101] option[3-0] */
-  kThumb2LdrPcReln12,/* ldr rd,[pc,-#imm12] [1111100011011111] rt[15-12]
-                        imm12[11-0] */
-  kThumb2Stm,        /* stm <list> [111010010000] rn[19-16] 000 rl[12-0] */
-  kThumbUndefined,   /* undefined [11011110xxxxxxxx] */
-  kThumb2VPopCS,     /* vpop <list of callee save fp singles (s16+) */
-  kThumb2VPushCS,    /* vpush <list callee save fp singles (s16+) */
-  kThumb2Vldms,      /* vldms rd, <list> */
-  kThumb2Vstms,      /* vstms rd, <list> */
-  kThumb2BUncond,    /* b <label> */
-  kThumb2MovImm16H,  /* similar to kThumb2MovImm16, but target high hw */
-  kThumb2AddPCR,     /* Thumb2 2-operand add with hard-coded PC target */
-  kThumb2Adr,        /* Special purpose encoding of ADR for switch tables */
-  kThumb2MovImm16LST,/* Special purpose version for switch table use */
-  kThumb2MovImm16HST,/* Special purpose version for switch table use */
-  kThumb2LdmiaWB,    /* ldmia  [111010011001[ rn[19..16] mask[15..0] */
-  kThumb2SubsRRI12,  /* setflags encoding */
-  kThumb2OrrRRRs,    /* orrx [111010100101] rn[19..16] [0000] rd[11..8]
-                        [0000] rm[3..0] */
-  kThumb2Push1,      /* t3 encoding of push */
-  kThumb2Pop1,       /* t3 encoding of pop */
-  kThumb2RsubRRR,    /* rsb [111010111101] rn[19..16] [0000] rd[11..8]
-                       [0000] rm[3..0] */
-  kThumb2Smull,      /* smull [111110111000] rn[19-16], rdlo[15-12]
-                        rdhi[11-8] [0000] rm[3-0] */
+  kArm16BitData = kArmFirst, // DATA   [0] rd[15..0].
+  kThumbAdcRR,       // adc   [0100000101] rm[5..3] rd[2..0].
+  kThumbAddRRI3,     // add(1)  [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/
+  kThumbAddRI8,      // add(2)  [00110] rd[10..8] imm_8[7..0].
+  kThumbAddRRR,      // add(3)  [0001100] rm[8..6] rn[5..3] rd[2..0].
+  kThumbAddRRLH,     // add(4)  [01000100] H12[01] rm[5..3] rd[2..0].
+  kThumbAddRRHL,     // add(4)  [01001000] H12[10] rm[5..3] rd[2..0].
+  kThumbAddRRHH,     // add(4)  [01001100] H12[11] rm[5..3] rd[2..0].
+  kThumbAddPcRel,    // add(5)  [10100] rd[10..8] imm_8[7..0].
+  kThumbAddSpRel,    // add(6)  [10101] rd[10..8] imm_8[7..0].
+  kThumbAddSpI7,     // add(7)  [101100000] imm_7[6..0].
+  kThumbAndRR,       // and   [0100000000] rm[5..3] rd[2..0].
+  kThumbAsrRRI5,     // asr(1)  [00010] imm_5[10..6] rm[5..3] rd[2..0].
+  kThumbAsrRR,       // asr(2)  [0100000100] rs[5..3] rd[2..0].
+  kThumbBCond,       // b(1)  [1101] cond[11..8] offset_8[7..0].
+  kThumbBUncond,     // b(2)  [11100] offset_11[10..0].
+  kThumbBicRR,       // bic   [0100001110] rm[5..3] rd[2..0].
+  kThumbBkpt,        // bkpt  [10111110] imm_8[7..0].
+  kThumbBlx1,        // blx(1)  [111] H[10] offset_11[10..0].
+  kThumbBlx2,        // blx(1)  [111] H[01] offset_11[10..0].
+  kThumbBl1,         // blx(1)  [111] H[10] offset_11[10..0].
+  kThumbBl2,         // blx(1)  [111] H[11] offset_11[10..0].
+  kThumbBlxR,        // blx(2)  [010001111] rm[6..3] [000].
+  kThumbBx,          // bx    [010001110] H2[6..6] rm[5..3] SBZ[000].
+  kThumbCmnRR,       // cmn   [0100001011] rm[5..3] rd[2..0].
+  kThumbCmpRI8,      // cmp(1)  [00101] rn[10..8] imm_8[7..0].
+  kThumbCmpRR,       // cmp(2)  [0100001010] rm[5..3] rd[2..0].
+  kThumbCmpLH,       // cmp(3)  [01000101] H12[01] rm[5..3] rd[2..0].
+  kThumbCmpHL,       // cmp(3)  [01000110] H12[10] rm[5..3] rd[2..0].
+  kThumbCmpHH,       // cmp(3)  [01000111] H12[11] rm[5..3] rd[2..0].
+  kThumbEorRR,       // eor   [0100000001] rm[5..3] rd[2..0].
+  kThumbLdmia,       // ldmia   [11001] rn[10..8] reglist [7..0].
+  kThumbLdrRRI5,     // ldr(1)  [01101] imm_5[10..6] rn[5..3] rd[2..0].
+  kThumbLdrRRR,      // ldr(2)  [0101100] rm[8..6] rn[5..3] rd[2..0].
+  kThumbLdrPcRel,    // ldr(3)  [01001] rd[10..8] imm_8[7..0].
+  kThumbLdrSpRel,    // ldr(4)  [10011] rd[10..8] imm_8[7..0].
+  kThumbLdrbRRI5,    // ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0].
+  kThumbLdrbRRR,     // ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0].
+  kThumbLdrhRRI5,    // ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0].
+  kThumbLdrhRRR,     // ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0].
+  kThumbLdrsbRRR,    // ldrsb   [0101011] rm[8..6] rn[5..3] rd[2..0].
+  kThumbLdrshRRR,    // ldrsh   [0101111] rm[8..6] rn[5..3] rd[2..0].
+  kThumbLslRRI5,     // lsl(1)  [00000] imm_5[10..6] rm[5..3] rd[2..0].
+  kThumbLslRR,       // lsl(2)  [0100000010] rs[5..3] rd[2..0].
+  kThumbLsrRRI5,     // lsr(1)  [00001] imm_5[10..6] rm[5..3] rd[2..0].
+  kThumbLsrRR,       // lsr(2)  [0100000011] rs[5..3] rd[2..0].
+  kThumbMovImm,      // mov(1)  [00100] rd[10..8] imm_8[7..0].
+  kThumbMovRR,       // mov(2)  [0001110000] rn[5..3] rd[2..0].
+  kThumbMovRR_H2H,   // mov(3)  [01000111] H12[11] rm[5..3] rd[2..0].
+  kThumbMovRR_H2L,   // mov(3)  [01000110] H12[01] rm[5..3] rd[2..0].
+  kThumbMovRR_L2H,   // mov(3)  [01000101] H12[10] rm[5..3] rd[2..0].
+  kThumbMul,         // mul   [0100001101] rm[5..3] rd[2..0].
+  kThumbMvn,         // mvn   [0100001111] rm[5..3] rd[2..0].
+  kThumbNeg,         // neg   [0100001001] rm[5..3] rd[2..0].
+  kThumbOrr,         // orr   [0100001100] rm[5..3] rd[2..0].
+  kThumbPop,         // pop   [1011110] r[8..8] rl[7..0].
+  kThumbPush,        // push  [1011010] r[8..8] rl[7..0].
+  kThumbRorRR,       // ror   [0100000111] rs[5..3] rd[2..0].
+  kThumbSbc,         // sbc   [0100000110] rm[5..3] rd[2..0].
+  kThumbStmia,       // stmia   [11000] rn[10..8] reglist [7.. 0].
+  kThumbStrRRI5,     // str(1)  [01100] imm_5[10..6] rn[5..3] rd[2..0].
+  kThumbStrRRR,      // str(2)  [0101000] rm[8..6] rn[5..3] rd[2..0].
+  kThumbStrSpRel,    // str(3)  [10010] rd[10..8] imm_8[7..0].
+  kThumbStrbRRI5,    // strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0].
+  kThumbStrbRRR,     // strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0].
+  kThumbStrhRRI5,    // strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0].
+  kThumbStrhRRR,     // strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0].
+  kThumbSubRRI3,     // sub(1)  [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/
+  kThumbSubRI8,      // sub(2)  [00111] rd[10..8] imm_8[7..0].
+  kThumbSubRRR,      // sub(3)  [0001101] rm[8..6] rn[5..3] rd[2..0].
+  kThumbSubSpI7,     // sub(4)  [101100001] imm_7[6..0].
+  kThumbSwi,         // swi   [11011111] imm_8[7..0].
+  kThumbTst,         // tst   [0100001000] rm[5..3] rn[2..0].
+  kThumb2Vldrs,      // vldr low  sx [111011011001] rn[19..16] rd[15-12] [1010] imm_8[7..0].
+  kThumb2Vldrd,      // vldr low  dx [111011011001] rn[19..16] rd[15-12] [1011] imm_8[7..0].
+  kThumb2Vmuls,      // vmul vd, vn, vm [111011100010] rn[19..16] rd[15-12] [10100000] rm[3..0].
+  kThumb2Vmuld,      // vmul vd, vn, vm [111011100010] rn[19..16] rd[15-12] [10110000] rm[3..0].
+  kThumb2Vstrs,      // vstr low  sx [111011011000] rn[19..16] rd[15-12] [1010] imm_8[7..0].
+  kThumb2Vstrd,      // vstr low  dx [111011011000] rn[19..16] rd[15-12] [1011] imm_8[7..0].
+  kThumb2Vsubs,      // vsub vd, vn, vm [111011100011] rn[19..16] rd[15-12] [10100040] rm[3..0].
+  kThumb2Vsubd,      // vsub vd, vn, vm [111011100011] rn[19..16] rd[15-12] [10110040] rm[3..0].
+  kThumb2Vadds,      // vadd vd, vn, vm [111011100011] rn[19..16] rd[15-12] [10100000] rm[3..0].
+  kThumb2Vaddd,      // vadd vd, vn, vm [111011100011] rn[19..16] rd[15-12] [10110000] rm[3..0].
+  kThumb2Vdivs,      // vdiv vd, vn, vm [111011101000] rn[19..16] rd[15-12] [10100000] rm[3..0].
+  kThumb2Vdivd,      // vdiv vd, vn, vm [111011101000] rn[19..16] rd[15-12] [10110000] rm[3..0].
+  kThumb2VcvtIF,     // vcvt.F32 vd, vm [1110111010111000] vd[15..12] [10101100] vm[3..0].
+  kThumb2VcvtID,     // vcvt.F64 vd, vm [1110111010111000] vd[15..12] [10111100] vm[3..0].
+  kThumb2VcvtFI,     // vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12] [10101100] vm[3..0].
+  kThumb2VcvtDI,     // vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12] [10111100] vm[3..0].
+  kThumb2VcvtFd,     // vcvt.F64.F32 vd, vm [1110111010110111] vd[15..12] [10101100] vm[3..0].
+  kThumb2VcvtDF,     // vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12] [10111100] vm[3..0].
+  kThumb2Vsqrts,     // vsqrt.f32 vd, vm [1110111010110001] vd[15..12] [10101100] vm[3..0].
+  kThumb2Vsqrtd,     // vsqrt.f64 vd, vm [1110111010110001] vd[15..12] [10111100] vm[3..0].
+  kThumb2MovImmShift,// mov(T2) rd, #<const> [11110] i [00001001111] imm3 rd[11..8] imm8.
+  kThumb2MovImm16,   // mov(T3) rd, #<const> [11110] i [0010100] imm4 [0] imm3 rd[11..8] imm8.
+  kThumb2StrRRI12,   // str(Imm,T3) rd,[rn,#imm12] [111110001100] rn[19..16] rt[15..12] imm12[11..0].
+  kThumb2LdrRRI12,   // str(Imm,T3) rd,[rn,#imm12] [111110001100] rn[19..16] rt[15..12] imm12[11..0].
+  kThumb2StrRRI8Predec, // str(Imm,T4) rd,[rn,#-imm8] [111110000100] rn[19..16] rt[15..12] [1100] imm[7..0]*/
+  kThumb2LdrRRI8Predec, // ldr(Imm,T4) rd,[rn,#-imm8] [111110000101] rn[19..16] rt[15..12] [1100] imm[7..0]*/
+  kThumb2Cbnz,       // cbnz rd,<label> [101110] i [1] imm5[7..3] rn[2..0].
+  kThumb2Cbz,        // cbn rd,<label> [101100] i [1] imm5[7..3] rn[2..0].
+  kThumb2AddRRI12,   // add rd, rn, #imm12 [11110] i [100000] rn[19..16] [0] imm3[14..12] rd[11..8] imm8[7..0].
+  kThumb2MovRR,      // mov rd, rm [11101010010011110000] rd[11..8] [0000] rm[3..0].
+  kThumb2Vmovs,      // vmov.f32 vd, vm [111011101] D [110000] vd[15..12] 101001] M [0] vm[3..0].
+  kThumb2Vmovd,      // vmov.f64 vd, vm [111011101] D [110000] vd[15..12] 101101] M [0] vm[3..0].
+  kThumb2Ldmia,      // ldmia  [111010001001[ rn[19..16] mask[15..0].
+  kThumb2Stmia,      // stmia  [111010001000[ rn[19..16] mask[15..0].
+  kThumb2AddRRR,     // add [111010110000] rn[19..16] [0000] rd[11..8] [0000] rm[3..0].
+  kThumb2SubRRR,     // sub [111010111010] rn[19..16] [0000] rd[11..8] [0000] rm[3..0].
+  kThumb2SbcRRR,     // sbc [111010110110] rn[19..16] [0000] rd[11..8] [0000] rm[3..0].
+  kThumb2CmpRR,      // cmp [111010111011] rn[19..16] [0000] [1111] [0000] rm[3..0].
+  kThumb2SubRRI12,   // sub rd, rn, #imm12 [11110] i [01010] rn[19..16] [0] imm3[14..12] rd[11..8] imm8[7..0].
+  kThumb2MvnImm12,   // mov(T2) rd, #<const> [11110] i [00011011110] imm3 rd[11..8] imm8.
+  kThumb2Sel,        // sel rd, rn, rm [111110101010] rn[19-16] rd[11-8] rm[3-0].
+  kThumb2Ubfx,       // ubfx rd,rn,#lsb,#width [111100111100] rn[19..16] [0] imm3[14-12] rd[11-8] w[4-0].
+  kThumb2Sbfx,       // ubfx rd,rn,#lsb,#width [111100110100] rn[19..16] [0] imm3[14-12] rd[11-8] w[4-0].
+  kThumb2LdrRRR,     // ldr rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] rt[15-12] [000000] imm[5-4] rm[3-0].
+  kThumb2LdrhRRR,    // ldrh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] rt[15-12] [000000] imm[5-4] rm[3-0].
+  kThumb2LdrshRRR,   // ldrsh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] rt[15-12] [000000] imm[5-4] rm[3-0].
+  kThumb2LdrbRRR,    // ldrb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] rt[15-12] [000000] imm[5-4] rm[3-0].
+  kThumb2LdrsbRRR,   // ldrsb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] rt[15-12] [000000] imm[5-4] rm[3-0].
+  kThumb2StrRRR,     // str rt,[rn,rm,LSL #imm] [111110000100] rn[19-16] rt[15-12] [000000] imm[5-4] rm[3-0].
+  kThumb2StrhRRR,    // str rt,[rn,rm,LSL #imm] [111110000010] rn[19-16] rt[15-12] [000000] imm[5-4] rm[3-0].
+  kThumb2StrbRRR,    // str rt,[rn,rm,LSL #imm] [111110000000] rn[19-16] rt[15-12] [000000] imm[5-4] rm[3-0].
+  kThumb2LdrhRRI12,  // ldrh rt,[rn,#imm12] [111110001011] rt[15..12] rn[19..16] imm12[11..0].
+  kThumb2LdrshRRI12, // ldrsh rt,[rn,#imm12] [111110011011] rt[15..12] rn[19..16] imm12[11..0].
+  kThumb2LdrbRRI12,  // ldrb rt,[rn,#imm12] [111110001001] rt[15..12] rn[19..16] imm12[11..0].
+  kThumb2LdrsbRRI12, // ldrsb rt,[rn,#imm12] [111110011001] rt[15..12] rn[19..16] imm12[11..0].
+  kThumb2StrhRRI12,  // strh rt,[rn,#imm12] [111110001010] rt[15..12] rn[19..16] imm12[11..0].
+  kThumb2StrbRRI12,  // strb rt,[rn,#imm12] [111110001000] rt[15..12] rn[19..16] imm12[11..0].
+  kThumb2Pop,        // pop   [1110100010111101] list[15-0]*/
+  kThumb2Push,       // push  [1110100100101101] list[15-0]*/
+  kThumb2CmpRI8,     // cmp rn, #<const> [11110] i [011011] rn[19-16] [0] imm3 [1111] imm8[7..0].
+  kThumb2AdcRRR,     // adc [111010110101] rn[19..16] [0000] rd[11..8] [0000] rm[3..0].
+  kThumb2AndRRR,     // and [111010100000] rn[19..16] [0000] rd[11..8] [0000] rm[3..0].
+  kThumb2BicRRR,     // bic [111010100010] rn[19..16] [0000] rd[11..8] [0000] rm[3..0].
+  kThumb2CmnRR,      // cmn [111010110001] rn[19..16] [0000] [1111] [0000] rm[3..0].
+  kThumb2EorRRR,     // eor [111010101000] rn[19..16] [0000] rd[11..8] [0000] rm[3..0].
+  kThumb2MulRRR,     // mul [111110110000] rn[19..16] [1111] rd[11..8] [0000] rm[3..0].
+  kThumb2MnvRR,      // mvn [11101010011011110] rd[11-8] [0000] rm[3..0].
+  kThumb2RsubRRI8,   // rsub [111100011100] rn[19..16] [0000] rd[11..8] imm8[7..0].
+  kThumb2NegRR,      // actually rsub rd, rn, #0.
+  kThumb2OrrRRR,     // orr [111010100100] rn[19..16] [0000] rd[11..8] [0000] rm[3..0].
+  kThumb2TstRR,      // tst [111010100001] rn[19..16] [0000] [1111] [0000] rm[3..0].
+  kThumb2LslRRR,     // lsl [111110100000] rn[19..16] [1111] rd[11..8] [0000] rm[3..0].
+  kThumb2LsrRRR,     // lsr [111110100010] rn[19..16] [1111] rd[11..8] [0000] rm[3..0].
+  kThumb2AsrRRR,     // asr [111110100100] rn[19..16] [1111] rd[11..8] [0000] rm[3..0].
+  kThumb2RorRRR,     // ror [111110100110] rn[19..16] [1111] rd[11..8] [0000] rm[3..0].
+  kThumb2LslRRI5,    // lsl [11101010010011110] imm[14.12] rd[11..8] [00] rm[3..0].
+  kThumb2LsrRRI5,    // lsr [11101010010011110] imm[14.12] rd[11..8] [01] rm[3..0].
+  kThumb2AsrRRI5,    // asr [11101010010011110] imm[14.12] rd[11..8] [10] rm[3..0].
+  kThumb2RorRRI5,    // ror [11101010010011110] imm[14.12] rd[11..8] [11] rm[3..0].
+  kThumb2BicRRI8,    // bic [111100000010] rn[19..16] [0] imm3 rd[11..8] imm8.
+  kThumb2AndRRI8,    // bic [111100000000] rn[19..16] [0] imm3 rd[11..8] imm8.
+  kThumb2OrrRRI8,    // orr [111100000100] rn[19..16] [0] imm3 rd[11..8] imm8.
+  kThumb2EorRRI8,    // eor [111100001000] rn[19..16] [0] imm3 rd[11..8] imm8.
+  kThumb2AddRRI8,    // add [111100001000] rn[19..16] [0] imm3 rd[11..8] imm8.
+  kThumb2AdcRRI8,    // adc [111100010101] rn[19..16] [0] imm3 rd[11..8] imm8.
+  kThumb2SubRRI8,    // sub [111100011011] rn[19..16] [0] imm3 rd[11..8] imm8.
+  kThumb2SbcRRI8,    // sbc [111100010111] rn[19..16] [0] imm3 rd[11..8] imm8.
+  kThumb2It,         // it [10111111] firstcond[7-4] mask[3-0].
+  kThumb2Fmstat,     // fmstat [11101110111100011111101000010000].
+  kThumb2Vcmpd,      // vcmp [111011101] D [11011] rd[15-12] [1011] E [1] M [0] rm[3-0].
+  kThumb2Vcmps,      // vcmp [111011101] D [11010] rd[15-12] [1011] E [1] M [0] rm[3-0].
+  kThumb2LdrPcRel12, // ldr rd,[pc,#imm12] [1111100011011111] rt[15-12] imm12[11-0].
+  kThumb2BCond,      // b<c> [1110] S cond[25-22] imm6[21-16] [10] J1 [0] J2 imm11[10..0].
+  kThumb2Vmovd_RR,   // vmov [111011101] D [110000] vd[15-12 [101101] M [0] vm[3-0].
+  kThumb2Vmovs_RR,   // vmov [111011101] D [110000] vd[15-12 [101001] M [0] vm[3-0].
+  kThumb2Fmrs,       // vmov [111011100000] vn[19-16] rt[15-12] [1010] N [0010000].
+  kThumb2Fmsr,       // vmov [111011100001] vn[19-16] rt[15-12] [1010] N [0010000].
+  kThumb2Fmrrd,      // vmov [111011000100] rt2[19-16] rt[15-12] [101100] M [1] vm[3-0].
+  kThumb2Fmdrr,      // vmov [111011000101] rt2[19-16] rt[15-12] [101100] M [1] vm[3-0].
+  kThumb2Vabsd,      // vabs.f64 [111011101] D [110000] rd[15-12] [1011110] M [0] vm[3-0].
+  kThumb2Vabss,      // vabs.f32 [111011101] D [110000] rd[15-12] [1010110] M [0] vm[3-0].
+  kThumb2Vnegd,      // vneg.f64 [111011101] D [110000] rd[15-12] [1011110] M [0] vm[3-0].
+  kThumb2Vnegs,      // vneg.f32 [111011101] D [110000] rd[15-12] [1010110] M [0] vm[3-0].
+  kThumb2Vmovs_IMM8, // vmov.f32 [111011101] D [11] imm4h[19-16] vd[15-12] [10100000] imm4l[3-0].
+  kThumb2Vmovd_IMM8, // vmov.f64 [111011101] D [11] imm4h[19-16] vd[15-12] [10110000] imm4l[3-0].
+  kThumb2Mla,        // mla [111110110000] rn[19-16] ra[15-12] rd[7-4] [0000] rm[3-0].
+  kThumb2Umull,      // umull [111110111010] rn[19-16], rdlo[15-12] rdhi[11-8] [0000] rm[3-0].
+  kThumb2Ldrex,      // ldrex [111010000101] rn[19-16] rt[11-8] [1111] imm8[7-0].
+  kThumb2Strex,      // strex [111010000100] rn[19-16] rt[11-8] rd[11-8] imm8[7-0].
+  kThumb2Clrex,      // clrex [111100111011111110000111100101111].
+  kThumb2Bfi,        // bfi [111100110110] rn[19-16] [0] imm3[14-12] rd[11-8] imm2[7-6] [0] msb[4-0].
+  kThumb2Bfc,        // bfc [11110011011011110] [0] imm3[14-12] rd[11-8] imm2[7-6] [0] msb[4-0].
+  kThumb2Dmb,        // dmb [1111001110111111100011110101] option[3-0].
+  kThumb2LdrPcReln12,// ldr rd,[pc,-#imm12] [1111100011011111] rt[15-12] imm12[11-0].
+  kThumb2Stm,        // stm <list> [111010010000] rn[19-16] 000 rl[12-0].
+  kThumbUndefined,   // undefined [11011110xxxxxxxx].
+  kThumb2VPopCS,     // vpop <list of callee save fp singles (s16+).
+  kThumb2VPushCS,    // vpush <list callee save fp singles (s16+).
+  kThumb2Vldms,      // vldms rd, <list>.
+  kThumb2Vstms,      // vstms rd, <list>.
+  kThumb2BUncond,    // b <label>.
+  kThumb2MovImm16H,  // similar to kThumb2MovImm16, but target high hw.
+  kThumb2AddPCR,     // Thumb2 2-operand add with hard-coded PC target.
+  kThumb2Adr,        // Special purpose encoding of ADR for switch tables.
+  kThumb2MovImm16LST,// Special purpose version for switch table use.
+  kThumb2MovImm16HST,// Special purpose version for switch table use.
+  kThumb2LdmiaWB,    // ldmia  [111010011001[ rn[19..16] mask[15..0].
+  kThumb2SubsRRI12,  // setflags encoding.
+  kThumb2OrrRRRs,    // orrx [111010100101] rn[19..16] [0000] rd[11..8] [0000] rm[3..0].
+  kThumb2Push1,      // t3 encoding of push.
+  kThumb2Pop1,       // t3 encoding of pop.
+  kThumb2RsubRRR,    // rsb [111010111101] rn[19..16] [0000] rd[11..8] [0000] rm[3..0].
+  kThumb2Smull,      // smull [111110111000] rn[19-16], rdlo[15-12] rdhi[11-8] [0000] rm[3-0].
   kArmLast,
 };
 
-/* DMB option encodings */
 enum ArmOpDmbOptions {
   kSY = 0xf,
   kST = 0xe,
@@ -567,43 +457,40 @@
   kNSHST = 0x6
 };
 
-/* Bit flags describing the behavior of each native opcode */
-/* Instruction assembly field_loc kind */
+// Instruction assembly field_loc kind.
 enum ArmEncodingKind {
   kFmtUnused,
-  kFmtBitBlt,    /* Bit string using end/start */
-  kFmtDfp,       /* Double FP reg */
-  kFmtSfp,       /* Single FP reg */
-  kFmtModImm,    /* Shifted 8-bit immed using [26,14..12,7..0] */
-  kFmtImm16,     /* Zero-extended immed using [26,19..16,14..12,7..0] */
-  kFmtImm6,      /* Encoded branch target using [9,7..3]0 */
-  kFmtImm12,     /* Zero-extended immediate using [26,14..12,7..0] */
-  kFmtShift,     /* Shift descriptor, [14..12,7..4] */
-  kFmtLsb,       /* least significant bit using [14..12][7..6] */
-  kFmtBWidth,    /* bit-field width, encoded as width-1 */
-  kFmtShift5,    /* Shift count, [14..12,7..6] */
-  kFmtBrOffset,  /* Signed extended [26,11,13,21-16,10-0]:0 */
-  kFmtFPImm,     /* Encoded floating point immediate */
-  kFmtOff24,     /* 24-bit Thumb2 unconditional branch encoding */
+  kFmtBitBlt,    // Bit string using end/start.
+  kFmtDfp,       // Double FP reg.
+  kFmtSfp,       // Single FP reg.
+  kFmtModImm,    // Shifted 8-bit immed using [26,14..12,7..0].
+  kFmtImm16,     // Zero-extended immed using [26,19..16,14..12,7..0].
+  kFmtImm6,      // Encoded branch target using [9,7..3]0.
+  kFmtImm12,     // Zero-extended immediate using [26,14..12,7..0].
+  kFmtShift,     // Shift descriptor, [14..12,7..4].
+  kFmtLsb,       // least significant bit using [14..12][7..6].
+  kFmtBWidth,    // bit-field width, encoded as width-1.
+  kFmtShift5,    // Shift count, [14..12,7..6].
+  kFmtBrOffset,  // Signed extended [26,11,13,21-16,10-0]:0.
+  kFmtFPImm,     // Encoded floating point immediate.
+  kFmtOff24,     // 24-bit Thumb2 unconditional branch encoding.
 };
 
-/* Struct used to define the snippet positions for each Thumb opcode */
+// Struct used to define the snippet positions for each Thumb opcode.
 struct ArmEncodingMap {
   uint32_t skeleton;
   struct {
     ArmEncodingKind kind;
-    int end;   /* end for kFmtBitBlt, 1-bit slice end for FP regs */
-    int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
+    int end;   // end for kFmtBitBlt, 1-bit slice end for FP regs.
+    int start; // start for kFmtBitBlt, 4-bit slice end for FP regs.
   } field_loc[4];
   ArmOpcode opcode;
   uint64_t flags;
   const char* name;
   const char* fmt;
-  int size;   /* Size in bytes */
+  int size;   // Note: size is in bytes.
 };
 
-extern const ArmEncodingMap EncodingMap[kArmLast];
-
 }  // namespace art
 
 #endif  // ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_
diff --git a/src/compiler/codegen/arm/assemble_arm.cc b/src/compiler/codegen/arm/assemble_arm.cc
index 8cb0b97..93c979b 100644
--- a/src/compiler/codegen/arm/assemble_arm.cc
+++ b/src/compiler/codegen/arm/assemble_arm.cc
@@ -15,6 +15,7 @@
  */
 
 #include "arm_lir.h"
+#include "codegen_arm.h"
 #include "../codegen_util.h"
 
 namespace art {
@@ -75,7 +76,7 @@
  *  [!] escape.  To insert "!", use "!!"
  */
 /* NOTE: must be kept in sync with enum ArmOpcode from LIR.h */
-const ArmEncodingMap EncodingMap[kArmLast] = {
+const ArmEncodingMap ArmCodegen::EncodingMap[kArmLast] = {
     ENCODING_MAP(kArm16BitData,    0x0000,
                  kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1,
                  kFmtUnused, -1, -1, IS_UNARY_OP, "data", "0x!0h(!0d)", 2),
@@ -987,8 +988,7 @@
  * discover that pc-relative displacements may not fit the selected
  * instruction.
  */
-AssemblerStatus AssembleInstructions(CompilationUnit* cu,
-                    uintptr_t start_addr)
+AssemblerStatus ArmCodegen::AssembleInstructions(CompilationUnit* cu, uintptr_t start_addr)
 {
   LIR* lir;
   AssemblerStatus res = kSuccess;  // Assume success
@@ -1361,7 +1361,7 @@
   return res;
 }
 
-int GetInsnSize(LIR* lir)
+int ArmCodegen::GetInsnSize(LIR* lir)
 {
   return EncodingMap[lir->opcode].size;
 }
@@ -1369,7 +1369,7 @@
 /*
  * Target-dependent offset assignment.
  */
-int AssignInsnOffsets(CompilationUnit* cu)
+int ArmCodegen::AssignInsnOffsets(CompilationUnit* cu)
 {
   LIR* arm_lir;
   int offset = 0;
diff --git a/src/compiler/codegen/arm/call_arm.cc b/src/compiler/codegen/arm/call_arm.cc
index 775b25d..950105c 100644
--- a/src/compiler/codegen/arm/call_arm.cc
+++ b/src/compiler/codegen/arm/call_arm.cc
@@ -19,6 +19,7 @@
 #include "oat_compilation_unit.h"
 #include "oat/runtime/oat_support_entrypoints.h"
 #include "arm_lir.h"
+#include "codegen_arm.h"
 #include "../codegen_util.h"
 #include "../ralloc_util.h"
 
@@ -37,7 +38,7 @@
  * there.  NOTE: all live arg registers must be locked prior to this call
  * to avoid having them allocated as a temp by downstream utilities.
  */
-RegLocation ArgLoc(CompilationUnit* cu, RegLocation loc)
+RegLocation ArmCodegen::ArgLoc(CompilationUnit* cu, RegLocation loc)
 {
   int arg_num = InPosition(cu, loc.s_reg_low);
   if (loc.wide) {
@@ -67,15 +68,16 @@
  * the frame, we can't use the normal LoadValue() because it assumed
  * a proper frame - and we're frameless.
  */
-RegLocation LoadArg(CompilationUnit* cu, RegLocation loc)
+static RegLocation LoadArg(CompilationUnit* cu, RegLocation loc)
 {
+  Codegen* cg = cu->cg.get();
   if (loc.location == kLocDalvikFrame) {
     int start = (InPosition(cu, loc.s_reg_low) + 1) * sizeof(uint32_t);
     loc.low_reg = AllocTemp(cu);
-    LoadWordDisp(cu, rARM_SP, start, loc.low_reg);
+    cg->LoadWordDisp(cu, rARM_SP, start, loc.low_reg);
     if (loc.wide) {
       loc.high_reg = AllocTemp(cu);
-      LoadWordDisp(cu, rARM_SP, start + sizeof(uint32_t), loc.high_reg);
+      cg->LoadWordDisp(cu, rARM_SP, start + sizeof(uint32_t), loc.high_reg);
     }
     loc.location = kLocPhysReg;
   }
@@ -122,7 +124,8 @@
 }
 
 /* Used for the "verbose" listing */
-void GenPrintLabel(CompilationUnit *cu, MIR* mir)
+//TODO:  move to common code
+void ArmCodegen::GenPrintLabel(CompilationUnit *cu, MIR* mir)
 {
   /* Mark the beginning of a Dalvik instruction for line tracking */
   char* inst_str = cu->verbose ?
@@ -138,6 +141,7 @@
 static MIR* SpecialIGet(CompilationUnit* cu, BasicBlock** bb, MIR* mir,
                         OpSize size, bool long_or_double, bool is_object)
 {
+  Codegen* cg = cu->cg.get();
   int field_offset;
   bool is_volatile;
   uint32_t field_idx = mir->dalvikInsn.vC;
@@ -147,7 +151,7 @@
   }
   RegLocation rl_obj = GetSrc(cu, mir, 0);
   LockLiveArgs(cu, mir);
-  rl_obj = ArgLoc(cu, rl_obj);
+  rl_obj = ArmCodegen::ArgLoc(cu, rl_obj);
   RegLocation rl_dest;
   if (long_or_double) {
     rl_dest = GetReturnWide(cu, false);
@@ -155,16 +159,17 @@
     rl_dest = GetReturn(cu, false);
   }
   // Point of no return - no aborts after this
-  GenPrintLabel(cu, mir);
+  ArmCodegen::GenPrintLabel(cu, mir);
   rl_obj = LoadArg(cu, rl_obj);
-  GenIGet(cu, field_idx, mir->optimization_flags, size, rl_dest, rl_obj,
-          long_or_double, is_object);
+  cg->GenIGet(cu, field_idx, mir->optimization_flags, size, rl_dest, rl_obj,
+              long_or_double, is_object);
   return GetNextMir(cu, bb, mir);
 }
 
 static MIR* SpecialIPut(CompilationUnit* cu, BasicBlock** bb, MIR* mir,
                         OpSize size, bool long_or_double, bool is_object)
 {
+  Codegen* cg = cu->cg.get();
   int field_offset;
   bool is_volatile;
   uint32_t field_idx = mir->dalvikInsn.vC;
@@ -182,24 +187,25 @@
     rl_src = GetSrc(cu, mir, 0);
     rl_obj = GetSrc(cu, mir, 1);
   }
-  rl_src = ArgLoc(cu, rl_src);
-  rl_obj = ArgLoc(cu, rl_obj);
+  rl_src = ArmCodegen::ArgLoc(cu, rl_src);
+  rl_obj = ArmCodegen::ArgLoc(cu, rl_obj);
   // Reject if source is split across registers & frame
   if (rl_obj.location == kLocInvalid) {
     ResetRegPool(cu);
     return NULL;
   }
   // Point of no return - no aborts after this
-  GenPrintLabel(cu, mir);
+  ArmCodegen::GenPrintLabel(cu, mir);
   rl_obj = LoadArg(cu, rl_obj);
   rl_src = LoadArg(cu, rl_src);
-  GenIPut(cu, field_idx, mir->optimization_flags, size, rl_src, rl_obj,
-          long_or_double, is_object);
+  cg->GenIPut(cu, field_idx, mir->optimization_flags, size, rl_src, rl_obj,
+              long_or_double, is_object);
   return GetNextMir(cu, bb, mir);
 }
 
 static MIR* SpecialIdentity(CompilationUnit* cu, MIR* mir)
 {
+  Codegen* cg = cu->cg.get();
   RegLocation rl_src;
   RegLocation rl_dest;
   bool wide = (mir->ssa_rep->num_uses == 2);
@@ -211,18 +217,18 @@
     rl_dest = GetReturn(cu, false);
   }
   LockLiveArgs(cu, mir);
-  rl_src = ArgLoc(cu, rl_src);
+  rl_src = ArmCodegen::ArgLoc(cu, rl_src);
   if (rl_src.location == kLocInvalid) {
     ResetRegPool(cu);
     return NULL;
   }
   // Point of no return - no aborts after this
-  GenPrintLabel(cu, mir);
+  ArmCodegen::GenPrintLabel(cu, mir);
   rl_src = LoadArg(cu, rl_src);
   if (wide) {
-    StoreValueWide(cu, rl_dest, rl_src);
+    cg->StoreValueWide(cu, rl_dest, rl_src);
   } else {
-    StoreValue(cu, rl_dest, rl_src);
+    cg->StoreValue(cu, rl_dest, rl_src);
   }
   return mir;
 }
@@ -230,8 +236,8 @@
 /*
  * Special-case code genration for simple non-throwing leaf methods.
  */
-void GenSpecialCase(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
-                    SpecialCaseHandler special_case)
+void ArmCodegen::GenSpecialCase(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
+                                SpecialCaseHandler special_case)
 {
    cu->current_dalvik_offset = mir->offset;
    MIR* next_mir = NULL;
@@ -241,7 +247,7 @@
        next_mir = mir;
        break;
      case kConstFunction:
-       GenPrintLabel(cu, mir);
+       ArmCodegen::GenPrintLabel(cu, mir);
        LoadConstant(cu, rARM_RET0, mir->dalvikInsn.vB);
        next_mir = GetNextMir(cu, &bb, mir);
        break;
@@ -292,7 +298,7 @@
    if (next_mir != NULL) {
     cu->current_dalvik_offset = next_mir->offset;
     if (special_case != kIdentity) {
-      GenPrintLabel(cu, next_mir);
+      ArmCodegen::GenPrintLabel(cu, next_mir);
     }
     NewLIR1(cu, kThumbBx, rARM_LR);
     cu->core_spill_mask = 0;
@@ -324,8 +330,7 @@
  *   add   rARM_PC, r_disp   ; This is the branch from which we compute displacement
  *   cbnz  r_idx, lp
  */
-void GenSparseSwitch(CompilationUnit* cu, uint32_t table_offset,
-                     RegLocation rl_src)
+void ArmCodegen::GenSparseSwitch(CompilationUnit* cu, uint32_t table_offset, RegLocation rl_src)
 {
   const uint16_t* table = cu->insns + cu->current_dalvik_offset + table_offset;
   if (cu->verbose) {
@@ -363,7 +368,7 @@
   NewLIR2(cu, kThumb2LdmiaWB, rBase, (1 << r_key) | (1 << r_disp));
   OpRegReg(cu, kOpCmp, r_key, rl_src.low_reg);
   // Go if match. NOTE: No instruction set switch here - must stay Thumb2
-  OpIT(cu, kArmCondEq, "");
+  OpIT(cu, kCondEq, "");
   LIR* switch_branch = NewLIR1(cu, kThumb2AddPCR, r_disp);
   tab_rec->anchor = switch_branch;
   // Needs to use setflags encoding here
@@ -372,8 +377,7 @@
 }
 
 
-void GenPackedSwitch(CompilationUnit* cu, uint32_t table_offset,
-                     RegLocation rl_src)
+void ArmCodegen::GenPackedSwitch(CompilationUnit* cu, uint32_t table_offset, RegLocation rl_src)
 {
   const uint16_t* table = cu->insns + cu->current_dalvik_offset + table_offset;
   if (cu->verbose) {
@@ -429,7 +433,7 @@
  *
  * Total size is 4+(width * size + 1)/2 16-bit code units.
  */
-void GenFillArrayData(CompilationUnit* cu, uint32_t table_offset, RegLocation rl_src)
+void ArmCodegen::GenFillArrayData(CompilationUnit* cu, uint32_t table_offset, RegLocation rl_src)
 {
   const uint16_t* table = cu->insns + cu->current_dalvik_offset + table_offset;
   // Add the table to the list - we'll process it later
@@ -481,7 +485,7 @@
  * preserved.
  *
  */
-void GenMonitorEnter(CompilationUnit* cu, int opt_flags, RegLocation rl_src)
+void ArmCodegen::GenMonitorEnter(CompilationUnit* cu, int opt_flags, RegLocation rl_src)
 {
   FlushAllRegs(cu);
   DCHECK_EQ(LW_SHAPE_THIN, 0);
@@ -497,11 +501,11 @@
   NewLIR4(cu, kThumb2Bfi, r2, r1, 0, LW_LOCK_OWNER_SHIFT - 1);
   NewLIR3(cu, kThumb2Bfc, r1, LW_HASH_STATE_SHIFT, LW_LOCK_OWNER_SHIFT - 1);
   OpRegImm(cu, kOpCmp, r1, 0);
-  OpIT(cu, kArmCondEq, "");
+  OpIT(cu, kCondEq, "");
   NewLIR4(cu, kThumb2Strex, r1, r2, r0,
           Object::MonitorOffset().Int32Value() >> 2);
   OpRegImm(cu, kOpCmp, r1, 0);
-  OpIT(cu, kArmCondNe, "T");
+  OpIT(cu, kCondNe, "T");
   // Go expensive route - artLockObjectFromCode(self, obj);
   LoadWordDisp(cu, rARM_SELF, ENTRYPOINT_OFFSET(pLockObjectFromCode), rARM_LR);
   ClobberCalleeSave(cu);
@@ -516,7 +520,7 @@
  * a zero recursion count, it's safe to punch it back to the
  * initial, unlock thin state with a store word.
  */
-void GenMonitorExit(CompilationUnit* cu, int opt_flags, RegLocation rl_src)
+void ArmCodegen::GenMonitorExit(CompilationUnit* cu, int opt_flags, RegLocation rl_src)
 {
   DCHECK_EQ(LW_SHAPE_THIN, 0);
   FlushAllRegs(cu);
@@ -532,7 +536,7 @@
   OpRegImm(cu, kOpLsl, r2, LW_LOCK_OWNER_SHIFT);
   NewLIR3(cu, kThumb2Bfc, r1, LW_HASH_STATE_SHIFT, LW_LOCK_OWNER_SHIFT - 1);
   OpRegReg(cu, kOpSub, r1, r2);
-  OpIT(cu, kArmCondEq, "EE");
+  OpIT(cu, kCondEq, "EE");
   StoreWordDisp(cu, r0, Object::MonitorOffset().Int32Value(), r3);
   // Go expensive route - UnlockObjectFromCode(obj);
   LoadWordDisp(cu, rARM_SELF, ENTRYPOINT_OFFSET(pUnlockObjectFromCode), rARM_LR);
@@ -545,7 +549,7 @@
 /*
  * Mark garbage collection card. Skip if the value we're storing is null.
  */
-void MarkGCCard(CompilationUnit* cu, int val_reg, int tgt_addr_reg)
+void ArmCodegen::MarkGCCard(CompilationUnit* cu, int val_reg, int tgt_addr_reg)
 {
   int reg_card_base = AllocTemp(cu);
   int reg_card_no = AllocTemp(cu);
@@ -560,8 +564,7 @@
   FreeTemp(cu, reg_card_no);
 }
 
-void GenEntrySequence(CompilationUnit* cu, RegLocation* ArgLocs,
-                      RegLocation rl_method)
+void ArmCodegen::GenEntrySequence(CompilationUnit* cu, RegLocation* ArgLocs, RegLocation rl_method)
 {
   int spill_count = cu->num_core_spills + cu->num_fp_spills;
   /*
@@ -614,7 +617,7 @@
   FreeTemp(cu, r3);
 }
 
-void GenExitSequence(CompilationUnit* cu)
+void ArmCodegen::GenExitSequence(CompilationUnit* cu)
 {
   int spill_count = cu->num_core_spills + cu->num_fp_spills;
   /*
diff --git a/src/compiler/codegen/arm/codegen_arm.h b/src/compiler/codegen/arm/codegen_arm.h
new file mode 100644
index 0000000..4737d8c
--- /dev/null
+++ b/src/compiler/codegen/arm/codegen_arm.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_COMPILER_CODEGEN_ARM_CODEGENARM_H_
+#define ART_SRC_COMPILER_CODEGEN_ARM_CODEGENARM_H_
+
+#include "../../compiler_internals.h"
+
+namespace art {
+
+class ArmCodegen : public Codegen {
+  public:
+    // Required for target - codegen helpers.
+    virtual bool SmallLiteralDivide(CompilationUnit* cu, Instruction::Code dalvik_opcode,
+                                    RegLocation rl_src, RegLocation rl_dest, int lit);
+    virtual int LoadHelper(CompilationUnit* cu, int offset);
+    virtual LIR* LoadBaseDisp(CompilationUnit* cu, int rBase, int displacement, int r_dest,
+                              OpSize size, int s_reg);
+    virtual LIR* LoadBaseDispWide(CompilationUnit* cu, int rBase, int displacement, int r_dest_lo,
+                                  int r_dest_hi, int s_reg);
+    virtual LIR* LoadBaseIndexed(CompilationUnit* cu, int rBase, int r_index, int r_dest, int scale,
+                                 OpSize size);
+    virtual LIR* LoadBaseIndexedDisp(CompilationUnit *cu, int rBase, int r_index, int scale,
+                                     int displacement, int r_dest, int r_dest_hi, OpSize size,
+                                     int s_reg);
+    virtual LIR* LoadConstantNoClobber(CompilationUnit* cu, int r_dest, int value);
+    virtual LIR* LoadConstantValueWide(CompilationUnit* cu, int r_dest_lo, int r_dest_hi,
+                                       int val_lo, int val_hi);
+    virtual void LoadPair(CompilationUnit* cu, int base, int low_reg, int high_reg);
+    virtual LIR* StoreBaseDisp(CompilationUnit* cu, int rBase, int displacement, int r_src,
+                               OpSize size);
+    virtual LIR* StoreBaseDispWide(CompilationUnit* cu, int rBase, int displacement, int r_src_lo,
+                                   int r_src_hi);
+    virtual LIR* StoreBaseIndexed(CompilationUnit* cu, int rBase, int r_index, int r_src, int scale,
+                                 OpSize size);
+    virtual LIR* StoreBaseIndexedDisp(CompilationUnit *cu, int rBase, int r_index, int scale,
+                                      int displacement, int r_src, int r_src_hi, OpSize size,
+                                      int s_reg);
+    virtual void MarkGCCard(CompilationUnit* cu, int val_reg, int tgt_addr_reg);
+
+    // Required for target - register utilities.
+    virtual bool IsFpReg(int reg);
+    virtual bool SameRegType(int reg1, int reg2);
+    virtual int AllocTypedTemp(CompilationUnit* cu, bool fp_hint, int reg_class);
+    virtual int AllocTypedTempPair(CompilationUnit* cu, bool fp_hint, int reg_class);
+    virtual int S2d(int low_reg, int high_reg);
+    virtual int TargetReg(SpecialTargetRegister reg);
+    virtual RegisterInfo* GetRegInfo(CompilationUnit* cu, int reg);
+    virtual RegLocation GetReturnAlt(CompilationUnit* cu);
+    virtual RegLocation GetReturnWideAlt(CompilationUnit* cu);
+    virtual RegLocation LocCReturn();
+    virtual RegLocation LocCReturnDouble();
+    virtual RegLocation LocCReturnFloat();
+    virtual RegLocation LocCReturnWide();
+    virtual uint32_t FpRegMask();
+    virtual uint64_t GetRegMaskCommon(CompilationUnit* cu, int reg);
+    virtual void AdjustSpillMask(CompilationUnit* cu);
+    virtual void ClobberCalleeSave(CompilationUnit *cu);
+    virtual void FlushReg(CompilationUnit* cu, int reg);
+    virtual void FlushRegWide(CompilationUnit* cu, int reg1, int reg2);
+    virtual void FreeCallTemps(CompilationUnit* cu);
+    virtual void FreeRegLocTemps(CompilationUnit* cu, RegLocation rl_keep, RegLocation rl_free);
+    virtual void LockCallTemps(CompilationUnit* cu);
+    virtual void MarkPreservedSingle(CompilationUnit* cu, int v_reg, int reg);
+    virtual void CompilerInitializeRegAlloc(CompilationUnit* cu);
+
+    // Required for target - miscellaneous.
+    virtual AssemblerStatus AssembleInstructions(CompilationUnit* cu, uintptr_t start_addr);
+    virtual void DumpResourceMask(LIR* lir, uint64_t mask, const char* prefix);
+    virtual void SetupTargetResourceMasks(CompilationUnit* cu, LIR* lir);
+    virtual const char* GetTargetInstFmt(int opcode);
+    virtual const char* GetTargetInstName(int opcode);
+    virtual int AssignInsnOffsets(CompilationUnit* cu);
+    virtual std::string BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr);
+    virtual uint64_t GetPCUseDefEncoding();
+    virtual uint64_t GetTargetInstFlags(int opcode);
+    virtual int GetInsnSize(LIR* lir);
+    virtual bool IsUnconditionalBranch(LIR* lir);
+
+    // Required for target - Dalvik-level generators.
+    virtual bool GenAddLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+                            RegLocation rl_src2);
+    virtual bool GenAndLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+                            RegLocation rl_src2);
+    virtual bool GenArithOpDouble(CompilationUnit* cu, Instruction::Code opcode,
+                                  RegLocation rl_dest, RegLocation rl_src1,
+                                  RegLocation rl_src2);
+    virtual bool GenArithOpFloat(CompilationUnit *cu, Instruction::Code opcode, RegLocation rl_dest,
+                                 RegLocation rl_src1, RegLocation rl_src2);
+    virtual bool GenCmpFP(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest,
+                          RegLocation rl_src1, RegLocation rl_src2);
+    virtual bool GenConversion(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest,
+                               RegLocation rl_src);
+    virtual bool GenInlinedCas32(CompilationUnit* cu, CallInfo* info, bool need_write_barrier);
+    virtual bool GenInlinedMinMaxInt(CompilationUnit *cu, CallInfo* info, bool is_min);
+    virtual bool GenInlinedSqrt(CompilationUnit* cu, CallInfo* info);
+    virtual bool GenNegLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src);
+    virtual bool GenOrLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+                           RegLocation rl_src2);
+    virtual bool GenSubLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+                            RegLocation rl_src2);
+    virtual bool GenXorLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+                            RegLocation rl_src2);
+    virtual LIR* GenRegMemCheck(CompilationUnit* cu, ConditionCode c_code, int reg1, int base,
+                                int offset, ThrowKind kind);
+    virtual RegLocation GenDivRem(CompilationUnit* cu, RegLocation rl_dest, int reg_lo, int reg_hi,
+                                  bool is_div);
+    virtual RegLocation GenDivRemLit(CompilationUnit* cu, RegLocation rl_dest, int reg_lo, int lit,
+                                     bool is_div);
+    virtual void GenCmpLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+                            RegLocation rl_src2);
+    virtual void GenDivZeroCheck(CompilationUnit* cu, int reg_lo, int reg_hi);
+    virtual void GenEntrySequence(CompilationUnit* cu, RegLocation* ArgLocs,
+                                  RegLocation rl_method);
+    virtual void GenExitSequence(CompilationUnit* cu);
+    virtual void GenFillArrayData(CompilationUnit* cu, uint32_t table_offset,
+                                  RegLocation rl_src);
+    virtual void GenFusedFPCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir, bool gt_bias,
+                                     bool is_double);
+    virtual void GenFusedLongCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir);
+    virtual void GenMemBarrier(CompilationUnit* cu, MemBarrierKind barrier_kind);
+    virtual void GenMonitorEnter(CompilationUnit* cu, int opt_flags, RegLocation rl_src);
+    virtual void GenMonitorExit(CompilationUnit* cu, int opt_flags, RegLocation rl_src);
+    virtual void GenMultiplyByTwoBitMultiplier(CompilationUnit* cu, RegLocation rl_src,
+                                               RegLocation rl_result, int lit, int first_bit,
+                                               int second_bit);
+    virtual void GenNegDouble(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src);
+    virtual void GenNegFloat(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src);
+    virtual void GenPackedSwitch(CompilationUnit* cu, uint32_t table_offset,
+                                 RegLocation rl_src);
+    virtual void GenSparseSwitch(CompilationUnit* cu, uint32_t table_offset,
+                                 RegLocation rl_src);
+    virtual void GenSpecialCase(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
+                                SpecialCaseHandler special_case);
+
+    // Required for target - single operation generators.
+    virtual LIR* OpUnconditionalBranch(CompilationUnit* cu, LIR* target);
+    virtual LIR* OpCmpBranch(CompilationUnit* cu, ConditionCode cond, int src1, int src2,
+                             LIR* target);
+    virtual LIR* OpCmpImmBranch(CompilationUnit* cu, ConditionCode cond, int reg, int check_value,
+                                LIR* target);
+    virtual LIR* OpCondBranch(CompilationUnit* cu, ConditionCode cc, LIR* target);
+    virtual LIR* OpDecAndBranch(CompilationUnit* cu, ConditionCode c_code, int reg,
+                                LIR* target);
+    virtual LIR* OpFpRegCopy(CompilationUnit* cu, int r_dest, int r_src);
+    virtual LIR* OpIT(CompilationUnit* cu, ConditionCode cond, const char* guide);
+    virtual LIR* OpMem(CompilationUnit* cu, OpKind op, int rBase, int disp);
+    virtual LIR* OpPcRelLoad(CompilationUnit* cu, int reg, LIR* target);
+    virtual LIR* OpReg(CompilationUnit* cu, OpKind op, int r_dest_src);
+    virtual LIR* OpRegCopy(CompilationUnit* cu, int r_dest, int r_src);
+    virtual LIR* OpRegCopyNoInsert(CompilationUnit* cu, int r_dest, int r_src);
+    virtual LIR* OpRegImm(CompilationUnit* cu, OpKind op, int r_dest_src1, int value);
+    virtual LIR* OpRegMem(CompilationUnit* cu, OpKind op, int r_dest, int rBase, int offset);
+    virtual LIR* OpRegReg(CompilationUnit* cu, OpKind op, int r_dest_src1, int r_src2);
+    virtual LIR* OpRegRegImm(CompilationUnit* cu, OpKind op, int r_dest, int r_src1, int value);
+    virtual LIR* OpRegRegReg(CompilationUnit* cu, OpKind op, int r_dest, int r_src1,
+                             int r_src2);
+    virtual LIR* OpTestSuspend(CompilationUnit* cu, LIR* target);
+    virtual LIR* OpThreadMem(CompilationUnit* cu, OpKind op, int thread_offset);
+    virtual LIR* OpVldm(CompilationUnit* cu, int rBase, int count);
+    virtual LIR* OpVstm(CompilationUnit* cu, int rBase, int count);
+    virtual void OpLea(CompilationUnit* cu, int rBase, int reg1, int reg2, int scale,
+                       int offset);
+    virtual void OpRegCopyWide(CompilationUnit* cu, int dest_lo, int dest_hi, int src_lo,
+                               int src_hi);
+    virtual void OpTlsCmp(CompilationUnit* cu, int offset, int val);
+
+    static RegLocation ArgLoc(CompilationUnit* cu, RegLocation loc);
+    LIR* LoadBaseDispBody(CompilationUnit* cu, int rBase, int displacement, int r_dest,
+                          int r_dest_hi, OpSize size, int s_reg);
+    LIR* StoreBaseDispBody(CompilationUnit* cu, int rBase, int displacement, int r_src,
+                           int r_src_hi, OpSize size);
+    static void GenPrintLabel(CompilationUnit *cu, MIR* mir);
+    static LIR* OpRegRegRegShift(CompilationUnit* cu, OpKind op, int r_dest, int r_src1,
+                                 int r_src2, int shift);
+    static LIR* OpRegRegShift(CompilationUnit* cu, OpKind op, int r_dest_src1, int r_src2,
+                              int shift);
+    static const ArmEncodingMap EncodingMap[kArmLast];
+    static int EncodeShift(int code, int amount);
+    static int ModifiedImmediate(uint32_t value);
+    static ArmConditionCode ArmConditionEncoding(ConditionCode code);
+};
+
+}  // namespace art
+
+#endif  // ART_SRC_COMPILER_CODEGEN_ARM_CODEGENARM_H_
diff --git a/src/compiler/codegen/arm/fp_arm.cc b/src/compiler/codegen/arm/fp_arm.cc
index 46695b9..a9ea916 100644
--- a/src/compiler/codegen/arm/fp_arm.cc
+++ b/src/compiler/codegen/arm/fp_arm.cc
@@ -15,13 +15,14 @@
  */
 
 #include "arm_lir.h"
+#include "codegen_arm.h"
 #include "../codegen_util.h"
 #include "../ralloc_util.h"
 
 namespace art {
 
-bool GenArithOpFloat(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest,
-                     RegLocation rl_src1, RegLocation rl_src2)
+bool ArmCodegen::GenArithOpFloat(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest,
+                                 RegLocation rl_src1, RegLocation rl_src2)
 {
   int op = kThumbBkpt;
   RegLocation rl_result;
@@ -63,8 +64,8 @@
   return false;
 }
 
-bool GenArithOpDouble(CompilationUnit* cu, Instruction::Code opcode,
-                      RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2)
+bool ArmCodegen::GenArithOpDouble(CompilationUnit* cu, Instruction::Code opcode,
+                                  RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2)
 {
   int op = kThumbBkpt;
   RegLocation rl_result;
@@ -108,8 +109,8 @@
   return false;
 }
 
-bool GenConversion(CompilationUnit* cu, Instruction::Code opcode,
-                   RegLocation rl_dest, RegLocation rl_src)
+bool ArmCodegen::GenConversion(CompilationUnit* cu, Instruction::Code opcode,
+                               RegLocation rl_dest, RegLocation rl_src)
 {
   int op = kThumbBkpt;
   int src_reg;
@@ -161,8 +162,8 @@
   return false;
 }
 
-void GenFusedFPCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
-                         bool gt_bias, bool is_double)
+void ArmCodegen::GenFusedFPCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir, bool gt_bias,
+                                     bool is_double)
 {
   LIR* label_list = cu->block_label_list;
   LIR* target = &label_list[bb->taken->id];
@@ -215,8 +216,8 @@
 }
 
 
-bool GenCmpFP(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest,
-        RegLocation rl_src1, RegLocation rl_src2)
+bool ArmCodegen::GenCmpFP(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest,
+                          RegLocation rl_src1, RegLocation rl_src2)
 {
   bool is_double;
   int default_result;
@@ -261,12 +262,12 @@
   DCHECK(!ARM_FPREG(rl_result.low_reg));
   NewLIR0(cu, kThumb2Fmstat);
 
-  OpIT(cu, (default_result == -1) ? kArmCondGt : kArmCondMi, "");
+  OpIT(cu, (default_result == -1) ? kCondGt : kCondMi, "");
   NewLIR2(cu, kThumb2MovImmShift, rl_result.low_reg,
           ModifiedImmediate(-default_result)); // Must not alter ccodes
   GenBarrier(cu);
 
-  OpIT(cu, kArmCondEq, "");
+  OpIT(cu, kCondEq, "");
   LoadConstant(cu, rl_result.low_reg, 0);
   GenBarrier(cu);
 
@@ -274,7 +275,7 @@
   return false;
 }
 
-void GenNegFloat(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
+void ArmCodegen::GenNegFloat(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
 {
   RegLocation rl_result;
   rl_src = LoadValue(cu, rl_src, kFPReg);
@@ -283,7 +284,7 @@
   StoreValue(cu, rl_dest, rl_result);
 }
 
-void GenNegDouble(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
+void ArmCodegen::GenNegDouble(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
 {
   RegLocation rl_result;
   rl_src = LoadValueWide(cu, rl_src, kFPReg);
@@ -293,7 +294,7 @@
   StoreValueWide(cu, rl_dest, rl_result);
 }
 
-bool GenInlinedSqrt(CompilationUnit* cu, CallInfo* info) {
+bool ArmCodegen::GenInlinedSqrt(CompilationUnit* cu, CallInfo* info) {
   DCHECK_EQ(cu->instruction_set, kThumb2);
   LIR *branch;
   RegLocation rl_src = info->args[0];
diff --git a/src/compiler/codegen/arm/int_arm.cc b/src/compiler/codegen/arm/int_arm.cc
index 45fe807..0a6abd2 100644
--- a/src/compiler/codegen/arm/int_arm.cc
+++ b/src/compiler/codegen/arm/int_arm.cc
@@ -19,12 +19,13 @@
 #include "oat_compilation_unit.h"
 #include "oat/runtime/oat_support_entrypoints.h"
 #include "arm_lir.h"
+#include "codegen_arm.h"
 #include "../codegen_util.h"
 #include "../ralloc_util.h"
 
 namespace art {
 
-LIR* OpCmpBranch(CompilationUnit* cu, ConditionCode cond, int src1,
+LIR* ArmCodegen::OpCmpBranch(CompilationUnit* cu, ConditionCode cond, int src1,
          int src2, LIR* target)
 {
   OpRegReg(cu, kOpCmp, src1, src2);
@@ -41,14 +42,15 @@
  * met, and an "E" means the instruction is executed if the condition
  * is not met.
  */
-LIR* OpIT(CompilationUnit* cu, ArmConditionCode code, const char* guide)
+LIR* ArmCodegen::OpIT(CompilationUnit* cu, ConditionCode ccode, const char* guide)
 {
   int mask;
-  int cond_bit = code & 1;
-  int alt_bit = cond_bit ^ 1;
   int mask3 = 0;
   int mask2 = 0;
   int mask1 = 0;
+  ArmConditionCode code = ArmConditionEncoding(ccode);
+  int cond_bit = code & 1;
+  int alt_bit = cond_bit ^ 1;
 
   //Note: case fallthroughs intentional
   switch (strlen(guide)) {
@@ -84,8 +86,8 @@
  *     neg   rX
  * done:
  */
-void GenCmpLong(CompilationUnit* cu, RegLocation rl_dest,
-        RegLocation rl_src1, RegLocation rl_src2)
+void ArmCodegen::GenCmpLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+                            RegLocation rl_src2)
 {
   LIR* target1;
   LIR* target2;
@@ -99,7 +101,7 @@
   OpRegRegReg(cu, kOpSub, t_reg, rl_src1.low_reg, rl_src2.low_reg);
   LIR* branch3 = OpCondBranch(cu, kCondEq, NULL);
 
-  OpIT(cu, kArmCondHi, "E");
+  OpIT(cu, kCondHi, "E");
   NewLIR2(cu, kThumb2MovImmShift, t_reg, ModifiedImmediate(-1));
   LoadConstant(cu, t_reg, 1);
   GenBarrier(cu);
@@ -119,7 +121,7 @@
   branch3->target = branch1->target;
 }
 
-void GenFusedLongCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir)
+void ArmCodegen::GenFusedLongCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir)
 {
   LIR* label_list = cu->block_label_list;
   LIR* taken = &label_list[bb->taken->id];
@@ -168,8 +170,8 @@
  * Generate a register comparison to an immediate and branch.  Caller
  * is responsible for setting branch target field.
  */
-LIR* OpCmpImmBranch(CompilationUnit* cu, ConditionCode cond, int reg,
-          int check_value, LIR* target)
+LIR* ArmCodegen::OpCmpImmBranch(CompilationUnit* cu, ConditionCode cond, int reg, int check_value,
+                                LIR* target)
 {
   LIR* branch;
   int mod_imm;
@@ -194,12 +196,13 @@
   branch->target = target;
   return branch;
 }
-LIR* OpRegCopyNoInsert(CompilationUnit* cu, int r_dest, int r_src)
+
+LIR* ArmCodegen::OpRegCopyNoInsert(CompilationUnit* cu, int r_dest, int r_src)
 {
   LIR* res;
   int opcode;
   if (ARM_FPREG(r_dest) || ARM_FPREG(r_src))
-    return FpRegCopy(cu, r_dest, r_src);
+    return OpFpRegCopy(cu, r_dest, r_src);
   if (ARM_LOWREG(r_dest) && ARM_LOWREG(r_src))
     opcode = kThumbMovRR;
   else if (!ARM_LOWREG(r_dest) && !ARM_LOWREG(r_src))
@@ -215,15 +218,15 @@
   return res;
 }
 
-LIR* OpRegCopy(CompilationUnit* cu, int r_dest, int r_src)
+LIR* ArmCodegen::OpRegCopy(CompilationUnit* cu, int r_dest, int r_src)
 {
   LIR* res = OpRegCopyNoInsert(cu, r_dest, r_src);
   AppendLIR(cu, res);
   return res;
 }
 
-void OpRegCopyWide(CompilationUnit* cu, int dest_lo, int dest_hi,
-               int src_lo, int src_hi)
+void ArmCodegen::OpRegCopyWide(CompilationUnit* cu, int dest_lo, int dest_hi, int src_lo,
+                               int src_hi)
 {
   bool dest_fp = ARM_FPREG(dest_lo) && ARM_FPREG(dest_hi);
   bool src_fp = ARM_FPREG(src_lo) && ARM_FPREG(src_hi);
@@ -278,8 +281,8 @@
 };
 
 // Integer division by constant via reciprocal multiply (Hacker's Delight, 10-4)
-bool SmallLiteralDivide(CompilationUnit* cu, Instruction::Code dalvik_opcode,
-                        RegLocation rl_src, RegLocation rl_dest, int lit)
+bool ArmCodegen::SmallLiteralDivide(CompilationUnit* cu, Instruction::Code dalvik_opcode,
+                                    RegLocation rl_src, RegLocation rl_dest, int lit)
 {
   if ((lit < 0) || (lit >= static_cast<int>(sizeof(magic_table)/sizeof(magic_table[0])))) {
     return false;
@@ -323,26 +326,28 @@
   return true;
 }
 
-LIR* GenRegMemCheck(CompilationUnit* cu, ConditionCode c_code,
+LIR* ArmCodegen::GenRegMemCheck(CompilationUnit* cu, ConditionCode c_code,
                     int reg1, int base, int offset, ThrowKind kind)
 {
   LOG(FATAL) << "Unexpected use of GenRegMemCheck for Arm";
   return NULL;
 }
 
-RegLocation GenDivRemLit(CompilationUnit* cu, RegLocation rl_dest, int reg1, int lit, bool is_div)
+RegLocation ArmCodegen::GenDivRemLit(CompilationUnit* cu, RegLocation rl_dest, int reg1, int lit,
+                                     bool is_div)
 {
   LOG(FATAL) << "Unexpected use of GenDivRemLit for Arm";
   return rl_dest;
 }
 
-RegLocation GenDivRem(CompilationUnit* cu, RegLocation rl_dest, int reg1, int reg2, bool is_div)
+RegLocation ArmCodegen::GenDivRem(CompilationUnit* cu, RegLocation rl_dest, int reg1, int reg2,
+                                  bool is_div)
 {
   LOG(FATAL) << "Unexpected use of GenDivRem for Arm";
   return rl_dest;
 }
 
-bool GenInlinedMinMaxInt(CompilationUnit *cu, CallInfo* info, bool is_min)
+bool ArmCodegen::GenInlinedMinMaxInt(CompilationUnit *cu, CallInfo* info, bool is_min)
 {
   DCHECK_EQ(cu->instruction_set, kThumb2);
   RegLocation rl_src1 = info->args[0];
@@ -352,7 +357,7 @@
   RegLocation rl_dest = InlineTarget(cu, info);
   RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
   OpRegReg(cu, kOpCmp, rl_src1.low_reg, rl_src2.low_reg);
-  OpIT(cu, (is_min) ? kArmCondGt : kArmCondLt, "E");
+  OpIT(cu, (is_min) ? kCondGt : kCondLt, "E");
   OpRegReg(cu, kOpMov, rl_result.low_reg, rl_src2.low_reg);
   OpRegReg(cu, kOpMov, rl_result.low_reg, rl_src1.low_reg);
   GenBarrier(cu);
@@ -360,17 +365,17 @@
   return true;
 }
 
-void OpLea(CompilationUnit* cu, int rBase, int reg1, int reg2, int scale, int offset)
+void ArmCodegen::OpLea(CompilationUnit* cu, int rBase, int reg1, int reg2, int scale, int offset)
 {
   LOG(FATAL) << "Unexpected use of OpLea for Arm";
 }
 
-void OpTlsCmp(CompilationUnit* cu, int offset, int val)
+void ArmCodegen::OpTlsCmp(CompilationUnit* cu, int offset, int val)
 {
   LOG(FATAL) << "Unexpected use of OpTlsCmp for Arm";
 }
 
-bool GenInlinedCas32(CompilationUnit* cu, CallInfo* info, bool need_write_barrier) {
+bool ArmCodegen::GenInlinedCas32(CompilationUnit* cu, CallInfo* info, bool need_write_barrier) {
   DCHECK_EQ(cu->instruction_set, kThumb2);
   // Unused - RegLocation rl_src_unsafe = info->args[0];
   RegLocation rl_src_obj= info->args[1];  // Object - known non-null
@@ -417,7 +422,7 @@
   OpRegReg(cu, kOpCmp, r_old_value, rl_expected.low_reg);
   FreeTemp(cu, r_old_value);  // Now unneeded.
   RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
-  OpIT(cu, kArmCondEq, "TE");
+  OpIT(cu, kCondEq, "TE");
   NewLIR4(cu, kThumb2Strex, rl_result.low_reg, rl_new_value.low_reg, r_ptr, 0);
   FreeTemp(cu, r_ptr);  // Now unneeded.
   OpRegImm(cu, kOpXor, rl_result.low_reg, 1);
@@ -428,24 +433,24 @@
   return true;
 }
 
-LIR* OpPcRelLoad(CompilationUnit* cu, int reg, LIR* target)
+LIR* ArmCodegen::OpPcRelLoad(CompilationUnit* cu, int reg, LIR* target)
 {
   return RawLIR(cu, cu->current_dalvik_offset, kThumb2LdrPcRel12, reg, 0, 0, 0, 0, target);
 }
 
-LIR* OpVldm(CompilationUnit* cu, int rBase, int count)
+LIR* ArmCodegen::OpVldm(CompilationUnit* cu, int rBase, int count)
 {
   return NewLIR3(cu, kThumb2Vldms, rBase, fr0, count);
 }
 
-LIR* OpVstm(CompilationUnit* cu, int rBase, int count)
+LIR* ArmCodegen::OpVstm(CompilationUnit* cu, int rBase, int count)
 {
   return NewLIR3(cu, kThumb2Vstms, rBase, fr0, count);
 }
 
-void GenMultiplyByTwoBitMultiplier(CompilationUnit* cu, RegLocation rl_src,
-                                   RegLocation rl_result, int lit,
-                                   int first_bit, int second_bit)
+void ArmCodegen::GenMultiplyByTwoBitMultiplier(CompilationUnit* cu, RegLocation rl_src,
+                                               RegLocation rl_result, int lit,
+                                               int first_bit, int second_bit)
 {
   OpRegRegRegShift(cu, kOpAdd, rl_result.low_reg, rl_src.low_reg, rl_src.low_reg,
                    EncodeShift(kArmLsl, second_bit - first_bit));
@@ -454,7 +459,7 @@
   }
 }
 
-void GenDivZeroCheck(CompilationUnit* cu, int reg_lo, int reg_hi)
+void ArmCodegen::GenDivZeroCheck(CompilationUnit* cu, int reg_lo, int reg_hi)
 {
   int t_reg = AllocTemp(cu);
   NewLIR4(cu, kThumb2OrrRRRs, t_reg, reg_lo, reg_hi, 0);
@@ -463,21 +468,21 @@
 }
 
 // Test suspend flag, return target of taken suspend branch
-LIR* OpTestSuspend(CompilationUnit* cu, LIR* target)
+LIR* ArmCodegen::OpTestSuspend(CompilationUnit* cu, LIR* target)
 {
   NewLIR2(cu, kThumbSubRI8, rARM_SUSPEND, 1);
   return OpCondBranch(cu, (target == NULL) ? kCondEq : kCondNe, target);
 }
 
 // Decrement register and branch on condition
-LIR* OpDecAndBranch(CompilationUnit* cu, ConditionCode c_code, int reg, LIR* target)
+LIR* ArmCodegen::OpDecAndBranch(CompilationUnit* cu, ConditionCode c_code, int reg, LIR* target)
 {
   // Combine sub & test using sub setflags encoding here
   NewLIR3(cu, kThumb2SubsRRI12, reg, reg, 1);
   return OpCondBranch(cu, c_code, target);
 }
 
-void GenMemBarrier(CompilationUnit* cu, MemBarrierKind barrier_kind)
+void ArmCodegen::GenMemBarrier(CompilationUnit* cu, MemBarrierKind barrier_kind)
 {
 #if ANDROID_SMP != 0
   int dmb_flavor;
@@ -497,8 +502,7 @@
 #endif
 }
 
-bool GenNegLong(CompilationUnit* cu, RegLocation rl_dest,
-                RegLocation rl_src)
+bool ArmCodegen::GenNegLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
 {
   rl_src = LoadValueWide(cu, rl_src, kCoreReg);
   RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
@@ -519,36 +523,36 @@
   return false;
 }
 
-bool GenAddLong(CompilationUnit* cu, RegLocation rl_dest,
-                RegLocation rl_src1, RegLocation rl_src2)
+bool ArmCodegen::GenAddLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+                            RegLocation rl_src2)
 {
   LOG(FATAL) << "Unexpected use of GenAddLong for Arm";
   return false;
 }
 
-bool GenSubLong(CompilationUnit* cu, RegLocation rl_dest,
-                RegLocation rl_src1, RegLocation rl_src2)
+bool ArmCodegen::GenSubLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+                            RegLocation rl_src2)
 {
   LOG(FATAL) << "Unexpected use of GenSubLong for Arm";
   return false;
 }
 
-bool GenAndLong(CompilationUnit* cu, RegLocation rl_dest,
-                RegLocation rl_src1, RegLocation rl_src2)
+bool ArmCodegen::GenAndLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+                            RegLocation rl_src2)
 {
   LOG(FATAL) << "Unexpected use of GenAndLong for Arm";
   return false;
 }
 
-bool GenOrLong(CompilationUnit* cu, RegLocation rl_dest,
-               RegLocation rl_src1, RegLocation rl_src2)
+bool ArmCodegen::GenOrLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+                           RegLocation rl_src2)
 {
   LOG(FATAL) << "Unexpected use of GenOrLong for Arm";
   return false;
 }
 
-bool GenXorLong(CompilationUnit* cu, RegLocation rl_dest,
-               RegLocation rl_src1, RegLocation rl_src2)
+bool ArmCodegen::GenXorLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+                            RegLocation rl_src2)
 {
   LOG(FATAL) << "Unexpected use of genXoLong for Arm";
   return false;
diff --git a/src/compiler/codegen/arm/target_arm.cc b/src/compiler/codegen/arm/target_arm.cc
index 9c12237..272dc46 100644
--- a/src/compiler/codegen/arm/target_arm.cc
+++ b/src/compiler/codegen/arm/target_arm.cc
@@ -16,6 +16,7 @@
 
 #include "../../compiler_internals.h"
 #include "arm_lir.h"
+#include "codegen_arm.h"
 #include "../ralloc_util.h"
 #include "../codegen_util.h"
 
@@ -34,32 +35,32 @@
 static int fp_temps[] = {fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
                         fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15};
 
-RegLocation LocCReturn()
+RegLocation ArmCodegen::LocCReturn()
 {
   RegLocation res = ARM_LOC_C_RETURN;
   return res;
 }
 
-RegLocation LocCReturnWide()
+RegLocation ArmCodegen::LocCReturnWide()
 {
   RegLocation res = ARM_LOC_C_RETURN_WIDE;
   return res;
 }
 
-RegLocation LocCReturnFloat()
+RegLocation ArmCodegen::LocCReturnFloat()
 {
   RegLocation res = ARM_LOC_C_RETURN_FLOAT;
   return res;
 }
 
-RegLocation LocCReturnDouble()
+RegLocation ArmCodegen::LocCReturnDouble()
 {
   RegLocation res = ARM_LOC_C_RETURN_DOUBLE;
   return res;
 }
 
 // Return a target-dependent special register.
-int TargetReg(SpecialTargetRegister reg) {
+int ArmCodegen::TargetReg(SpecialTargetRegister reg) {
   int res = INVALID_REG;
   switch (reg) {
     case kSelf: res = rARM_SELF; break;
@@ -85,37 +86,19 @@
 
 
 // Create a double from a pair of singles.
-int S2d(int low_reg, int high_reg)
+int ArmCodegen::S2d(int low_reg, int high_reg)
 {
   return ARM_S2D(low_reg, high_reg);
 }
 
-// Is reg a single or double?
-bool FpReg(int reg)
-{
-  return ARM_FPREG(reg);
-}
-
-// Is reg a single?
-bool SingleReg(int reg)
-{
-  return ARM_SINGLEREG(reg);
-}
-
-// Is reg a double?
-bool DoubleReg(int reg)
-{
-  return ARM_DOUBLEREG(reg);
-}
-
 // Return mask to strip off fp reg flags and bias.
-uint32_t FpRegMask()
+uint32_t ArmCodegen::FpRegMask()
 {
   return ARM_FP_REG_MASK;
 }
 
 // True if both regs single, both core or both double.
-bool SameRegType(int reg1, int reg2)
+bool ArmCodegen::SameRegType(int reg1, int reg2)
 {
   return (ARM_REGTYPE(reg1) == ARM_REGTYPE(reg2));
 }
@@ -123,7 +106,7 @@
 /*
  * Decode the register id.
  */
-uint64_t GetRegMaskCommon(CompilationUnit* cu, int reg)
+uint64_t ArmCodegen::GetRegMaskCommon(CompilationUnit* cu, int reg)
 {
   uint64_t seed;
   int shift;
@@ -140,17 +123,17 @@
   return (seed << shift);
 }
 
-uint64_t GetPCUseDefEncoding()
+uint64_t ArmCodegen::GetPCUseDefEncoding()
 {
   return ENCODE_ARM_REG_PC;
 }
 
-void SetupTargetResourceMasks(CompilationUnit* cu, LIR* lir)
+void ArmCodegen::SetupTargetResourceMasks(CompilationUnit* cu, LIR* lir)
 {
   DCHECK_EQ(cu->instruction_set, kThumb2);
 
   // Thumb2 specific setup
-  uint64_t flags = EncodingMap[lir->opcode].flags;
+  uint64_t flags = ArmCodegen::EncodingMap[lir->opcode].flags;
   int opcode = lir->opcode;
 
   if (flags & REG_DEF_SP) {
@@ -221,7 +204,7 @@
   }
 }
 
-ArmConditionCode ArmConditionEncoding(ConditionCode ccode)
+ArmConditionCode ArmCodegen::ArmConditionEncoding(ConditionCode ccode)
 {
   ArmConditionCode res;
   switch (ccode) {
@@ -334,7 +317,7 @@
  * Interpret a format string and build a string no longer than size
  * See format key in Assemble.c.
  */
-std::string BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr)
+std::string ArmCodegen::BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr)
 {
   std::string buf;
   int i;
@@ -473,7 +456,7 @@
   return buf;
 }
 
-void DumpResourceMask(LIR* arm_lir, uint64_t mask, const char* prefix)
+void ArmCodegen::DumpResourceMask(LIR* arm_lir, uint64_t mask, const char* prefix)
 {
   char buf[256];
   buf[0] = 0;
@@ -519,30 +502,21 @@
   }
 }
 
-bool BranchUnconditional(LIR* lir)
+bool ArmCodegen::IsUnconditionalBranch(LIR* lir)
 {
   return ((lir->opcode == kThumbBUncond) || (lir->opcode == kThumb2BUncond));
 }
 
-/* Common initialization routine for an architecture family */
-bool ArchInit()
+bool InitArmCodegen(CompilationUnit* cu)
 {
-  int i;
-
-  for (i = 0; i < kArmLast; i++) {
-    if (EncodingMap[i].opcode != i) {
-      LOG(FATAL) << "Encoding order for " << EncodingMap[i].name
+  cu->cg.reset(new ArmCodegen());
+  for (int i = 0; i < kArmLast; i++) {
+    if (ArmCodegen::EncodingMap[i].opcode != i) {
+      LOG(FATAL) << "Encoding order for " << ArmCodegen::EncodingMap[i].name
                  << " is wrong: expecting " << i << ", seeing "
-                 << static_cast<int>(EncodingMap[i].opcode);
+                 << static_cast<int>(ArmCodegen::EncodingMap[i].opcode);
     }
   }
-
-  return ArchVariantInit();
-}
-
-/* Architecture-specific initializations and checks go here */
-bool ArchVariantInit(void)
-{
   return true;
 }
 
@@ -550,7 +524,7 @@
  * Alloc a pair of core registers, or a double.  Low reg in low byte,
  * high reg in next byte.
  */
-int AllocTypedTempPair(CompilationUnit* cu, bool fp_hint, int reg_class)
+int ArmCodegen::AllocTypedTempPair(CompilationUnit* cu, bool fp_hint, int reg_class)
 {
   int high_reg;
   int low_reg;
@@ -567,14 +541,14 @@
   return res;
 }
 
-int AllocTypedTemp(CompilationUnit* cu, bool fp_hint, int reg_class)
+int ArmCodegen::AllocTypedTemp(CompilationUnit* cu, bool fp_hint, int reg_class)
 {
   if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg))
     return AllocTempFloat(cu);
   return AllocTemp(cu);
 }
 
-void CompilerInitializeRegAlloc(CompilationUnit* cu)
+void ArmCodegen::CompilerInitializeRegAlloc(CompilationUnit* cu)
 {
   int num_regs = sizeof(core_regs)/sizeof(*core_regs);
   int num_reserved = sizeof(ReservedRegs)/sizeof(*ReservedRegs);
@@ -629,7 +603,7 @@
   }
 }
 
-void FreeRegLocTemps(CompilationUnit* cu, RegLocation rl_keep,
+void ArmCodegen::FreeRegLocTemps(CompilationUnit* cu, RegLocation rl_keep,
                      RegLocation rl_free)
 {
   if ((rl_free.low_reg != rl_keep.low_reg) && (rl_free.low_reg != rl_keep.high_reg) &&
@@ -645,7 +619,7 @@
  * machinery is in place, always spill lr.
  */
 
-void AdjustSpillMask(CompilationUnit* cu)
+void ArmCodegen::AdjustSpillMask(CompilationUnit* cu)
 {
   cu->core_spill_mask |= (1 << rARM_LR);
   cu->num_core_spills++;
@@ -657,7 +631,7 @@
  * include any holes in the mask.  Associate holes with
  * Dalvik register INVALID_VREG (0xFFFFU).
  */
-void MarkPreservedSingle(CompilationUnit* cu, int v_reg, int reg)
+void ArmCodegen::MarkPreservedSingle(CompilationUnit* cu, int v_reg, int reg)
 {
   DCHECK_GE(reg, ARM_FP_REG_MASK + ARM_FP_CALLEE_SAVE_BASE);
   reg = (reg & ARM_FP_REG_MASK) - ARM_FP_CALLEE_SAVE_BASE;
@@ -673,7 +647,7 @@
   cu->fp_spill_mask = ((1 << cu->num_fp_spills) - 1) << ARM_FP_CALLEE_SAVE_BASE;
 }
 
-void FlushRegWide(CompilationUnit* cu, int reg1, int reg2)
+void ArmCodegen::FlushRegWide(CompilationUnit* cu, int reg1, int reg2)
 {
   RegisterInfo* info1 = GetRegInfo(cu, reg1);
   RegisterInfo* info2 = GetRegInfo(cu, reg2);
@@ -696,7 +670,7 @@
   }
 }
 
-void FlushReg(CompilationUnit* cu, int reg)
+void ArmCodegen::FlushReg(CompilationUnit* cu, int reg)
 {
   RegisterInfo* info = GetRegInfo(cu, reg);
   if (info->live && info->dirty) {
@@ -707,12 +681,12 @@
 }
 
 /* Give access to the target-dependent FP register encoding to common code */
-bool IsFpReg(int reg) {
+bool ArmCodegen::IsFpReg(int reg) {
   return ARM_FPREG(reg);
 }
 
 /* Clobber all regs that might be used by an external C call */
-void ClobberCalleeSave(CompilationUnit *cu)
+void ArmCodegen::ClobberCalleeSave(CompilationUnit *cu)
 {
   Clobber(cu, r0);
   Clobber(cu, r1);
@@ -738,7 +712,7 @@
   Clobber(cu, fr15);
 }
 
-RegLocation GetReturnWideAlt(CompilationUnit* cu)
+RegLocation ArmCodegen::GetReturnWideAlt(CompilationUnit* cu)
 {
   RegLocation res = LocCReturnWide();
   res.low_reg = r2;
@@ -751,7 +725,7 @@
   return res;
 }
 
-RegLocation GetReturnAlt(CompilationUnit* cu)
+RegLocation ArmCodegen::GetReturnAlt(CompilationUnit* cu)
 {
   RegLocation res = LocCReturn();
   res.low_reg = r1;
@@ -760,14 +734,14 @@
   return res;
 }
 
-RegisterInfo* GetRegInfo(CompilationUnit* cu, int reg)
+RegisterInfo* ArmCodegen::GetRegInfo(CompilationUnit* cu, int reg)
 {
   return ARM_FPREG(reg) ? &cu->reg_pool->FPRegs[reg & ARM_FP_REG_MASK]
       : &cu->reg_pool->core_regs[reg];
 }
 
 /* To be used when explicitly managing register use */
-void LockCallTemps(CompilationUnit* cu)
+void ArmCodegen::LockCallTemps(CompilationUnit* cu)
 {
   LockTemp(cu, r0);
   LockTemp(cu, r1);
@@ -776,7 +750,7 @@
 }
 
 /* To be used when explicitly managing register use */
-void FreeCallTemps(CompilationUnit* cu)
+void ArmCodegen::FreeCallTemps(CompilationUnit* cu)
 {
   FreeTemp(cu, r0);
   FreeTemp(cu, r1);
@@ -784,25 +758,25 @@
   FreeTemp(cu, r3);
 }
 
-int LoadHelper(CompilationUnit* cu, int offset)
+int ArmCodegen::LoadHelper(CompilationUnit* cu, int offset)
 {
   LoadWordDisp(cu, rARM_SELF, offset, rARM_LR);
   return rARM_LR;
 }
 
-uint64_t GetTargetInstFlags(int opcode)
+uint64_t ArmCodegen::GetTargetInstFlags(int opcode)
 {
-  return EncodingMap[opcode].flags;
+  return ArmCodegen::EncodingMap[opcode].flags;
 }
 
-const char* GetTargetInstName(int opcode)
+const char* ArmCodegen::GetTargetInstName(int opcode)
 {
-  return EncodingMap[opcode].name;
+  return ArmCodegen::EncodingMap[opcode].name;
 }
 
-const char* GetTargetInstFmt(int opcode)
+const char* ArmCodegen::GetTargetInstFmt(int opcode)
 {
-  return EncodingMap[opcode].fmt;
+  return ArmCodegen::EncodingMap[opcode].fmt;
 }
 
 }  // namespace art
diff --git a/src/compiler/codegen/arm/utility_arm.cc b/src/compiler/codegen/arm/utility_arm.cc
index b064135..d1bf14e 100644
--- a/src/compiler/codegen/arm/utility_arm.cc
+++ b/src/compiler/codegen/arm/utility_arm.cc
@@ -15,6 +15,7 @@
  */
 
 #include "arm_lir.h"
+#include "codegen_arm.h"
 #include "../codegen_util.h"
 #include "../ralloc_util.h"
 
@@ -57,7 +58,7 @@
   }
   LIR* load_pc_rel = RawLIR(cu, cu->current_dalvik_offset, kThumb2Vldrs,
                           r_dest, r15pc, 0, 0, 0, data_target);
-  SetMemRefType(load_pc_rel, true, kLiteral);
+  SetMemRefType(cu, load_pc_rel, true, kLiteral);
   load_pc_rel->alias_info = reinterpret_cast<uintptr_t>(data_target);
   AppendLIR(cu, load_pc_rel);
   return load_pc_rel;
@@ -86,7 +87,7 @@
  * Determine whether value can be encoded as a Thumb2 modified
  * immediate.  If not, return -1.  If so, return i:imm3:a:bcdefgh form.
  */
-int ModifiedImmediate(uint32_t value)
+int ArmCodegen::ModifiedImmediate(uint32_t value)
 {
    int z_leading;
    int z_trailing;
@@ -124,7 +125,7 @@
  * 1) r_dest is freshly returned from AllocTemp or
  * 2) The codegen is under fixed register usage
  */
-LIR* LoadConstantNoClobber(CompilationUnit* cu, int r_dest, int value)
+LIR* ArmCodegen::LoadConstantNoClobber(CompilationUnit* cu, int r_dest, int value)
 {
   LIR* res;
   int mod_imm;
@@ -160,7 +161,7 @@
   }
   LIR* load_pc_rel = RawLIR(cu, cu->current_dalvik_offset,
                           kThumb2LdrPcRel12, r_dest, 0, 0, 0, 0, data_target);
-  SetMemRefType(load_pc_rel, true, kLiteral);
+  SetMemRefType(cu, load_pc_rel, true, kLiteral);
   load_pc_rel->alias_info = reinterpret_cast<uintptr_t>(data_target);
   res = load_pc_rel;
   AppendLIR(cu, load_pc_rel);
@@ -175,13 +176,14 @@
   return res;
 }
 
-LIR* OpBranchUnconditional(CompilationUnit* cu, OpKind op)
+LIR* ArmCodegen::OpUnconditionalBranch(CompilationUnit* cu, LIR* target)
 {
-  DCHECK_EQ(op, kOpUncondBr);
-  return NewLIR1(cu, kThumbBUncond, 0 /* offset to be patched */);
+  LIR* res = NewLIR1(cu, kThumbBUncond, 0 /* offset to be patched  during assembly*/);
+  res->target = target;
+  return res;
 }
 
-LIR* OpCondBranch(CompilationUnit* cu, ConditionCode cc, LIR* target)
+LIR* ArmCodegen::OpCondBranch(CompilationUnit* cu, ConditionCode cc, LIR* target)
 {
   LIR* branch = NewLIR2(cu, kThumb2BCond, 0 /* offset to be patched */,
                         ArmConditionEncoding(cc));
@@ -189,7 +191,7 @@
   return branch;
 }
 
-LIR* OpReg(CompilationUnit* cu, OpKind op, int r_dest_src)
+LIR* ArmCodegen::OpReg(CompilationUnit* cu, OpKind op, int r_dest_src)
 {
   ArmOpcode opcode = kThumbBkpt;
   switch (op) {
@@ -202,8 +204,8 @@
   return NewLIR1(cu, opcode, r_dest_src);
 }
 
-LIR* OpRegRegShift(CompilationUnit* cu, OpKind op, int r_dest_src1,
-                   int r_src2, int shift)
+LIR* ArmCodegen::OpRegRegShift(CompilationUnit* cu, OpKind op, int r_dest_src1, int r_src2,
+                               int shift)
 {
   bool thumb_form = ((shift == 0) && ARM_LOWREG(r_dest_src1) && ARM_LOWREG(r_src2));
   ArmOpcode opcode = kThumbBkpt;
@@ -318,13 +320,13 @@
   }
 }
 
-LIR* OpRegReg(CompilationUnit* cu, OpKind op, int r_dest_src1, int r_src2)
+LIR* ArmCodegen::OpRegReg(CompilationUnit* cu, OpKind op, int r_dest_src1, int r_src2)
 {
   return OpRegRegShift(cu, op, r_dest_src1, r_src2, 0);
 }
 
-LIR* OpRegRegRegShift(CompilationUnit* cu, OpKind op, int r_dest, int r_src1,
-            int r_src2, int shift)
+LIR* ArmCodegen::OpRegRegRegShift(CompilationUnit* cu, OpKind op, int r_dest, int r_src1,
+                                  int r_src2, int shift)
 {
   ArmOpcode opcode = kThumbBkpt;
   bool thumb_form = (shift == 0) && ARM_LOWREG(r_dest) && ARM_LOWREG(r_src1) &&
@@ -390,14 +392,12 @@
   }
 }
 
-LIR* OpRegRegReg(CompilationUnit* cu, OpKind op, int r_dest, int r_src1,
-                 int r_src2)
+LIR* ArmCodegen::OpRegRegReg(CompilationUnit* cu, OpKind op, int r_dest, int r_src1, int r_src2)
 {
   return OpRegRegRegShift(cu, op, r_dest, r_src1, r_src2, 0);
 }
 
-LIR* OpRegRegImm(CompilationUnit* cu, OpKind op, int r_dest, int r_src1,
-                 int value)
+LIR* ArmCodegen::OpRegRegImm(CompilationUnit* cu, OpKind op, int r_dest, int r_src1, int value)
 {
   LIR* res;
   bool neg = (value < 0);
@@ -518,7 +518,7 @@
 }
 
 /* Handle Thumb-only variants here - otherwise punt to OpRegRegImm */
-LIR* OpRegImm(CompilationUnit* cu, OpKind op, int r_dest_src1, int value)
+LIR* ArmCodegen::OpRegImm(CompilationUnit* cu, OpKind op, int r_dest_src1, int value)
 {
   bool neg = (value < 0);
   int abs_value = (neg) ? -value : value;
@@ -597,8 +597,8 @@
   return res;
 }
 
-LIR* LoadConstantValueWide(CompilationUnit* cu, int r_dest_lo, int r_dest_hi,
-               int val_lo, int val_hi)
+LIR* ArmCodegen::LoadConstantValueWide(CompilationUnit* cu, int r_dest_lo, int r_dest_hi,
+                                       int val_lo, int val_hi)
 {
   int encoded_imm = EncodeImmDouble(val_lo, val_hi);
   LIR* res;
@@ -614,7 +614,7 @@
       LIR* load_pc_rel =
           RawLIR(cu, cu->current_dalvik_offset, kThumb2Vldrd,
                  S2d(r_dest_lo, r_dest_hi), r15pc, 0, 0, 0, data_target);
-      SetMemRefType(load_pc_rel, true, kLiteral);
+      SetMemRefType(cu, load_pc_rel, true, kLiteral);
       load_pc_rel->alias_info = reinterpret_cast<uintptr_t>(data_target);
       AppendLIR(cu, load_pc_rel);
       res = load_pc_rel;
@@ -626,12 +626,12 @@
   return res;
 }
 
-int EncodeShift(int code, int amount) {
+int ArmCodegen::EncodeShift(int code, int amount) {
   return ((amount & 0x1f) << 2) | code;
 }
 
-LIR* LoadBaseIndexed(CompilationUnit* cu, int rBase, int r_index, int r_dest,
-                     int scale, OpSize size)
+LIR* ArmCodegen::LoadBaseIndexed(CompilationUnit* cu, int rBase, int r_index, int r_dest,
+                                 int scale, OpSize size)
 {
   bool all_low_regs = ARM_LOWREG(rBase) && ARM_LOWREG(r_index) && ARM_LOWREG(r_dest);
   LIR* load;
@@ -695,8 +695,8 @@
   return load;
 }
 
-LIR* StoreBaseIndexed(CompilationUnit* cu, int rBase, int r_index, int r_src,
-                      int scale, OpSize size)
+LIR* ArmCodegen::StoreBaseIndexed(CompilationUnit* cu, int rBase, int r_index, int r_src,
+                                  int scale, OpSize size)
 {
   bool all_low_regs = ARM_LOWREG(rBase) && ARM_LOWREG(r_index) && ARM_LOWREG(r_src);
   LIR* store;
@@ -761,10 +761,10 @@
  * on base (which must have an associated s_reg and MIR).  If not
  * performing null check, incoming MIR can be null.
  */
-LIR* LoadBaseDispBody(CompilationUnit* cu, int rBase,
-                      int displacement, int r_dest, int r_dest_hi, OpSize size,
-                      int s_reg)
+LIR* ArmCodegen::LoadBaseDispBody(CompilationUnit* cu, int rBase, int displacement, int r_dest,
+                                  int r_dest_hi, OpSize size, int s_reg)
 {
+  Codegen* cg = cu->cg.get();
   LIR* res;
   LIR* load;
   ArmOpcode opcode = kThumbBkpt;
@@ -780,7 +780,7 @@
       if (ARM_FPREG(r_dest)) {
         if (ARM_SINGLEREG(r_dest)) {
           DCHECK(ARM_FPREG(r_dest_hi));
-          r_dest = S2d(r_dest, r_dest_hi);
+          r_dest = cg->S2d(r_dest, r_dest_hi);
         }
         opcode = kThumb2Vldrd;
         if (displacement <= 1020) {
@@ -865,36 +865,34 @@
     load = res = NewLIR3(cu, opcode, r_dest, rBase, encoded_disp);
   } else {
     int reg_offset = AllocTemp(cu);
-    res = LoadConstant(cu, reg_offset, encoded_disp);
-    load = LoadBaseIndexed(cu, rBase, reg_offset, r_dest, 0, size);
+    res = cg->LoadConstant(cu, reg_offset, encoded_disp);
+    load = cg->LoadBaseIndexed(cu, rBase, reg_offset, r_dest, 0, size);
     FreeTemp(cu, reg_offset);
   }
 
   // TODO: in future may need to differentiate Dalvik accesses w/ spills
   if (rBase == rARM_SP) {
-    AnnotateDalvikRegAccess(load, displacement >> 2, true /* is_load */, is64bit);
+    AnnotateDalvikRegAccess(cu, load, displacement >> 2, true /* is_load */, is64bit);
   }
   return load;
 }
 
-LIR* LoadBaseDisp(CompilationUnit* cu, int rBase,
-                  int displacement, int r_dest, OpSize size, int s_reg)
+LIR* ArmCodegen::LoadBaseDisp(CompilationUnit* cu, int rBase, int displacement, int r_dest,
+                              OpSize size, int s_reg)
 {
-  return LoadBaseDispBody(cu, rBase, displacement, r_dest, -1, size,
-                          s_reg);
+  return LoadBaseDispBody(cu, rBase, displacement, r_dest, -1, size, s_reg);
 }
 
- LIR* LoadBaseDispWide(CompilationUnit* cu, int rBase,
-                       int displacement, int r_dest_lo, int r_dest_hi, int s_reg)
+LIR* ArmCodegen::LoadBaseDispWide(CompilationUnit* cu, int rBase, int displacement, int r_dest_lo,
+                                  int r_dest_hi, int s_reg)
 {
-  return LoadBaseDispBody(cu, rBase, displacement, r_dest_lo, r_dest_hi,
-                          kLong, s_reg);
+  return LoadBaseDispBody(cu, rBase, displacement, r_dest_lo, r_dest_hi, kLong, s_reg);
 }
 
 
-LIR* StoreBaseDispBody(CompilationUnit* cu, int rBase, int displacement,
-                       int r_src, int r_src_hi, OpSize size)
-{
+LIR* ArmCodegen::StoreBaseDispBody(CompilationUnit* cu, int rBase, int displacement,
+                                   int r_src, int r_src_hi, OpSize size) {
+  Codegen* cg = cu->cg.get();
   LIR* res, *store;
   ArmOpcode opcode = kThumbBkpt;
   bool short_form = false;
@@ -913,7 +911,7 @@
       }
       if (ARM_SINGLEREG(r_src)) {
         DCHECK(ARM_FPREG(r_src_hi));
-        r_src = S2d(r_src, r_src_hi);
+        r_src = cg->S2d(r_src, r_src_hi);
       }
       opcode = kThumb2Vstrd;
       if (displacement <= 1020) {
@@ -971,37 +969,36 @@
     store = res = NewLIR3(cu, opcode, r_src, rBase, encoded_disp);
   } else {
     int r_scratch = AllocTemp(cu);
-    res = LoadConstant(cu, r_scratch, encoded_disp);
-    store = StoreBaseIndexed(cu, rBase, r_scratch, r_src, 0, size);
+    res = cg->LoadConstant(cu, r_scratch, encoded_disp);
+    store = cg->StoreBaseIndexed(cu, rBase, r_scratch, r_src, 0, size);
     FreeTemp(cu, r_scratch);
   }
 
   // TODO: In future, may need to differentiate Dalvik & spill accesses
   if (rBase == rARM_SP) {
-    AnnotateDalvikRegAccess(store, displacement >> 2, false /* is_load */,
-                            is64bit);
+    AnnotateDalvikRegAccess(cu, store, displacement >> 2, false /* is_load */, is64bit);
   }
   return res;
 }
 
-LIR* StoreBaseDisp(CompilationUnit* cu, int rBase, int displacement,
-                   int r_src, OpSize size)
+LIR* ArmCodegen::StoreBaseDisp(CompilationUnit* cu, int rBase, int displacement, int r_src,
+                               OpSize size)
 {
   return StoreBaseDispBody(cu, rBase, displacement, r_src, -1, size);
 }
 
-LIR* StoreBaseDispWide(CompilationUnit* cu, int rBase, int displacement,
-                       int r_src_lo, int r_src_hi)
+LIR* ArmCodegen::StoreBaseDispWide(CompilationUnit* cu, int rBase, int displacement,
+                                   int r_src_lo, int r_src_hi)
 {
   return StoreBaseDispBody(cu, rBase, displacement, r_src_lo, r_src_hi, kLong);
 }
 
-void LoadPair(CompilationUnit* cu, int base, int low_reg, int high_reg)
+void ArmCodegen::LoadPair(CompilationUnit* cu, int base, int low_reg, int high_reg)
 {
   LoadBaseDispWide(cu, base, 0, low_reg, high_reg, INVALID_SREG);
 }
 
-LIR* FpRegCopy(CompilationUnit* cu, int r_dest, int r_src)
+LIR* ArmCodegen::OpFpRegCopy(CompilationUnit* cu, int r_dest, int r_src)
 {
   int opcode;
   DCHECK_EQ(ARM_DOUBLEREG(r_dest), ARM_DOUBLEREG(r_src));
@@ -1022,38 +1019,35 @@
   return res;
 }
 
-LIR* OpThreadMem(CompilationUnit* cu, OpKind op, int thread_offset)
+LIR* ArmCodegen::OpThreadMem(CompilationUnit* cu, OpKind op, int thread_offset)
 {
   LOG(FATAL) << "Unexpected use of OpThreadMem for Arm";
   return NULL;
 }
 
-LIR* OpMem(CompilationUnit* cu, OpKind op, int rBase, int disp)
+LIR* ArmCodegen::OpMem(CompilationUnit* cu, OpKind op, int rBase, int disp)
 {
   LOG(FATAL) << "Unexpected use of OpMem for Arm";
   return NULL;
 }
 
-LIR* StoreBaseIndexedDisp(CompilationUnit *cu,
-                          int rBase, int r_index, int scale, int displacement,
-                          int r_src, int r_src_hi,
-                          OpSize size, int s_reg)
+LIR* ArmCodegen::StoreBaseIndexedDisp(CompilationUnit *cu, int rBase, int r_index, int scale,
+                                      int displacement, int r_src, int r_src_hi, OpSize size,
+                                      int s_reg)
 {
   LOG(FATAL) << "Unexpected use of StoreBaseIndexedDisp for Arm";
   return NULL;
 }
 
-LIR* OpRegMem(CompilationUnit *cu, OpKind op, int r_dest, int rBase,
-              int offset)
+LIR* ArmCodegen::OpRegMem(CompilationUnit *cu, OpKind op, int r_dest, int rBase, int offset)
 {
   LOG(FATAL) << "Unexpected use of OpRegMem for Arm";
   return NULL;
 }
 
-LIR* LoadBaseIndexedDisp(CompilationUnit *cu,
-                         int rBase, int r_index, int scale, int displacement,
-                         int r_dest, int r_dest_hi,
-                         OpSize size, int s_reg)
+LIR* ArmCodegen::LoadBaseIndexedDisp(CompilationUnit *cu, int rBase, int r_index, int scale,
+                                     int displacement, int r_dest, int r_dest_hi, OpSize size,
+                                     int s_reg)
 {
   LOG(FATAL) << "Unexpected use of LoadBaseIndexedDisp for Arm";
   return NULL;