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;