summaryrefslogtreecommitdiffstats
path: root/vm/compiler/codegen/arm/Assemble.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm/compiler/codegen/arm/Assemble.c')
-rw-r--r--vm/compiler/codegen/arm/Assemble.c353
1 files changed, 267 insertions, 86 deletions
diff --git a/vm/compiler/codegen/arm/Assemble.c b/vm/compiler/codegen/arm/Assemble.c
index f9961cef5..5a870147f 100644
--- a/vm/compiler/codegen/arm/Assemble.c
+++ b/vm/compiler/codegen/arm/Assemble.c
@@ -25,20 +25,23 @@
/*
* opcode: ArmOpCode enum
* skeleton: pre-designated bit-pattern for this opcode
+ * k0: key to applying ds/de
* ds: dest start bit position
* de: dest end bit position
+ * k1: key to applying s1s/s1e
* s1s: src1 start bit position
* s1e: src1 end bit position
+ * k2: key to applying s2s/s2e
* s2s: src2 start bit position
* s2e: src2 end bit position
* operands: number of operands (for sanity check purposes)
* name: mnemonic name
* fmt: for pretty-prining
*/
-#define ENCODING_MAP(opcode, skeleton, ds, de, s1s, s1e, s2s, s2e, operands, \
- name, fmt, size) \
- {skeleton, {{ds, de}, {s1s, s1e}, {s2s, s2e}}, opcode, operands, name, \
- fmt, size}
+#define ENCODING_MAP(opcode, skeleton, k0, ds, de, k1, s1s, s1e, k2, s2s, s2e, \
+ operands, name, fmt, size) \
+ {skeleton, {{k0, ds, de}, {k1, s1s, s1e}, {k2, s2s, s2e}}, \
+ opcode, operands, name, fmt, size}
/* Instruction dump string format keys: !pf, where "!" is the start
* of the key, "p" is which numeric operand to use and "f" is the
@@ -65,226 +68,371 @@
*/
/* NOTE: must be kept in sync with enum ArmOpcode from ArmLIR.h */
ArmEncodingMap EncodingMap[ARM_LAST] = {
- ENCODING_MAP(ARM_16BIT_DATA, 0x0000, 15, 0, -1, -1, -1, -1,
+ ENCODING_MAP(ARM_16BIT_DATA, 0x0000,
+ BITBLT, 15, 0, UNUSED, -1, -1, UNUSED, -1, -1,
IS_UNARY_OP,
"data", "0x!0h(!0d)", 1),
- ENCODING_MAP(THUMB_ADC, 0x4140, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_ADC, 0x4140,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"adc", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_ADD_RRI3, 0x1c00, 2, 0, 5, 3, 8, 6,
+ ENCODING_MAP(THUMB_ADD_RRI3, 0x1c00,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 8, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"add", "r!0d, r!1d, #!2d", 1),
- ENCODING_MAP(THUMB_ADD_RI8, 0x3000, 10, 8, 7, 0, -1, -1,
+ ENCODING_MAP(THUMB_ADD_RI8, 0x3000,
+ BITBLT, 10, 8, BITBLT, 7, 0, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"add", "r!0d, r!0d, #!1d", 1),
- ENCODING_MAP(THUMB_ADD_RRR, 0x1800, 2, 0, 5, 3, 8, 6,
+ ENCODING_MAP(THUMB_ADD_RRR, 0x1800,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 8, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"add", "r!0d, r!1d, r!2d", 1),
- ENCODING_MAP(THUMB_ADD_RR_LH, 0x4440, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_ADD_RR_LH, 0x4440,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"add",
"r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_ADD_RR_HL, 0x4480, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_ADD_RR_HL, 0x4480,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"add", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_ADD_RR_HH, 0x44c0, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_ADD_RR_HH, 0x44c0,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"add", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_ADD_PC_REL, 0xa000, 10, 8, 7, 0, -1, -1,
+ ENCODING_MAP(THUMB_ADD_PC_REL, 0xa000,
+ BITBLT, 10, 8, BITBLT, 7, 0, UNUSED, -1, -1,
IS_TERTIARY_OP | CLOBBER_DEST,
"add", "r!0d, pc, #!1E", 1),
- ENCODING_MAP(THUMB_ADD_SP_REL, 0xa800, 10, 8, 7, 0, -1, -1,
+ ENCODING_MAP(THUMB_ADD_SP_REL, 0xa800,
+ BITBLT, 10, 8, BITBLT, 7, 0, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"add", "r!0d, sp, #!1E", 1),
- ENCODING_MAP(THUMB_ADD_SPI7, 0xb000, 6, 0, -1, -1, -1, -1,
+ ENCODING_MAP(THUMB_ADD_SPI7, 0xb000,
+ BITBLT, 6, 0, UNUSED, -1, -1, UNUSED, -1, -1,
IS_UNARY_OP | CLOBBER_DEST,
"add", "sp, #!0d*4", 1),
- ENCODING_MAP(THUMB_AND_RR, 0x4000, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_AND_RR, 0x4000,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"and", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_ASR, 0x1000, 2, 0, 5, 3, 10, 6,
+ ENCODING_MAP(THUMB_ASR, 0x1000,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 10, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"asr", "r!0d, r!1d, #!2d", 1),
- ENCODING_MAP(THUMB_ASRV, 0x4100, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_ASRV, 0x4100,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"asr", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_B_COND, 0xd000, 7, 0, 11, 8, -1, -1,
+ ENCODING_MAP(THUMB_B_COND, 0xd000,
+ BITBLT, 7, 0, BITBLT, 11, 8, UNUSED, -1, -1,
IS_BINARY_OP | IS_BRANCH,
"!1c", "!0t", 1),
- ENCODING_MAP(THUMB_B_UNCOND, 0xe000, 10, 0, -1, -1, -1, -1,
+ ENCODING_MAP(THUMB_B_UNCOND, 0xe000,
+ BITBLT, 10, 0, UNUSED, -1, -1, UNUSED, -1, -1,
NO_OPERAND | IS_BRANCH,
"b", "!0t", 1),
- ENCODING_MAP(THUMB_BIC, 0x4380, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_BIC, 0x4380,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"bic", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_BKPT, 0xbe00, 7, 0, -1, -1, -1, -1,
+ ENCODING_MAP(THUMB_BKPT, 0xbe00,
+ BITBLT, 7, 0, UNUSED, -1, -1, UNUSED, -1, -1,
IS_UNARY_OP | IS_BRANCH,
"bkpt", "!0d", 1),
- ENCODING_MAP(THUMB_BLX_1, 0xf000, 10, 0, -1, -1, -1, -1,
+ ENCODING_MAP(THUMB_BLX_1, 0xf000,
+ BITBLT, 10, 0, UNUSED, -1, -1, UNUSED, -1, -1,
IS_BINARY_OP | IS_BRANCH,
"blx_1", "!0u", 1),
- ENCODING_MAP(THUMB_BLX_2, 0xe800, 10, 0, -1, -1, -1, -1,
+ ENCODING_MAP(THUMB_BLX_2, 0xe800,
+ BITBLT, 10, 0, UNUSED, -1, -1, UNUSED, -1, -1,
IS_BINARY_OP | IS_BRANCH,
"blx_2", "!0v", 1),
- ENCODING_MAP(THUMB_BL_1, 0xf000, 10, 0, -1, -1, -1, -1,
+ ENCODING_MAP(THUMB_BL_1, 0xf000,
+ BITBLT, 10, 0, UNUSED, -1, -1, UNUSED, -1, -1,
IS_UNARY_OP | IS_BRANCH,
"bl_1", "!0u", 1),
- ENCODING_MAP(THUMB_BL_2, 0xf800, 10, 0, -1, -1, -1, -1,
+ ENCODING_MAP(THUMB_BL_2, 0xf800,
+ BITBLT, 10, 0, UNUSED, -1, -1, UNUSED, -1, -1,
IS_UNARY_OP | IS_BRANCH,
"bl_2", "!0v", 1),
- ENCODING_MAP(THUMB_BLX_R, 0x4780, 6, 3, -1, -1, -1, -1,
+ ENCODING_MAP(THUMB_BLX_R, 0x4780,
+ BITBLT, 6, 3, UNUSED, -1, -1, UNUSED, -1, -1,
IS_UNARY_OP | IS_BRANCH,
"blx", "r!0d", 1),
- ENCODING_MAP(THUMB_BX, 0x4700, 6, 3, -1, -1, -1, -1,
+ ENCODING_MAP(THUMB_BX, 0x4700,
+ BITBLT, 6, 3, UNUSED, -1, -1, UNUSED, -1, -1,
IS_UNARY_OP | IS_BRANCH,
"bx", "r!0d", 1),
- ENCODING_MAP(THUMB_CMN, 0x42c0, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_CMN, 0x42c0,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP,
"cmn", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_CMP_RI8, 0x2800, 10, 8, 7, 0, -1, -1,
+ ENCODING_MAP(THUMB_CMP_RI8, 0x2800,
+ BITBLT, 10, 8, BITBLT, 7, 0, UNUSED, -1, -1,
IS_BINARY_OP,
"cmp", "r!0d, #!1d", 1),
- ENCODING_MAP(THUMB_CMP_RR, 0x4280, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_CMP_RR, 0x4280,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP,
"cmp", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_CMP_LH, 0x4540, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_CMP_LH, 0x4540,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP,
"cmp", "r!0d, r!1D", 1),
- ENCODING_MAP(THUMB_CMP_HL, 0x4580, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_CMP_HL, 0x4580,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP,
"cmp", "r!0D, r!1d", 1),
- ENCODING_MAP(THUMB_CMP_HH, 0x45c0, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_CMP_HH, 0x45c0,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP,
"cmp", "r!0D, r!1D", 1),
- ENCODING_MAP(THUMB_EOR, 0x4040, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_EOR, 0x4040,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"eor", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_LDMIA, 0xc800, 10, 8, 7, 0, -1, -1,
+ ENCODING_MAP(THUMB_LDMIA, 0xc800,
+ BITBLT, 10, 8, BITBLT, 7, 0, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST | CLOBBER_SRC1,
"ldmia", "r!0d!!, <!1R>", 1),
- ENCODING_MAP(THUMB_LDR_RRI5, 0x6800, 2, 0, 5, 3, 10, 6,
+ ENCODING_MAP(THUMB_LDR_RRI5, 0x6800,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 10, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"ldr", "r!0d, [r!1d, #!2E]", 1),
- ENCODING_MAP(THUMB_LDR_RRR, 0x5800, 2, 0, 5, 3, 8, 6,
+ ENCODING_MAP(THUMB_LDR_RRR, 0x5800,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 8, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"ldr", "r!0d, [r!1d, r!2d]", 1),
- ENCODING_MAP(THUMB_LDR_PC_REL, 0x4800, 10, 8, 7, 0, -1, -1,
+ ENCODING_MAP(THUMB_LDR_PC_REL, 0x4800,
+ BITBLT, 10, 8, BITBLT, 7, 0, UNUSED, -1, -1,
IS_TERTIARY_OP | CLOBBER_DEST,
"ldr", "r!0d, [pc, #!1E]", 1),
- ENCODING_MAP(THUMB_LDR_SP_REL, 0x9800, 10, 8, 7, 0, -1, -1,
+ ENCODING_MAP(THUMB_LDR_SP_REL, 0x9800,
+ BITBLT, 10, 8, BITBLT, 7, 0, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"ldr", "r!0d, [sp, #!1E]", 1),
- ENCODING_MAP(THUMB_LDRB_RRI5, 0x7800, 2, 0, 5, 3, 10, 6,
+ ENCODING_MAP(THUMB_LDRB_RRI5, 0x7800,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 10, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"ldrb", "r!0d, [r!1d, #2d]", 1),
- ENCODING_MAP(THUMB_LDRB_RRR, 0x5c00, 2, 0, 5, 3, 8, 6,
+ ENCODING_MAP(THUMB_LDRB_RRR, 0x5c00,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 8, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"ldrb", "r!0d, [r!1d, r!2d]", 1),
- ENCODING_MAP(THUMB_LDRH_RRI5, 0x8800, 2, 0, 5, 3, 10, 6,
+ ENCODING_MAP(THUMB_LDRH_RRI5, 0x8800,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 10, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"ldrh", "r!0d, [r!1d, #!2F]", 1),
- ENCODING_MAP(THUMB_LDRH_RRR, 0x5a00, 2, 0, 5, 3, 8, 6,
+ ENCODING_MAP(THUMB_LDRH_RRR, 0x5a00,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 8, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"ldrh", "r!0d, [r!1d, r!2d]", 1),
- ENCODING_MAP(THUMB_LDRSB_RRR, 0x5600, 2, 0, 5, 3, 8, 6,
+ ENCODING_MAP(THUMB_LDRSB_RRR, 0x5600,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 8, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"ldrsb", "r!0d, [r!1d, r!2d]", 1),
- ENCODING_MAP(THUMB_LDRSH_RRR, 0x5e00, 2, 0, 5, 3, 8, 6,
+ ENCODING_MAP(THUMB_LDRSH_RRR, 0x5e00,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 8, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"ldrsh", "r!0d, [r!1d, r!2d]", 1),
- ENCODING_MAP(THUMB_LSL, 0x0000, 2, 0, 5, 3, 10, 6,
+ ENCODING_MAP(THUMB_LSL, 0x0000,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 10, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"lsl", "r!0d, r!1d, #!2d", 1),
- ENCODING_MAP(THUMB_LSLV, 0x4080, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_LSLV, 0x4080,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"lsl", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_LSR, 0x0800, 2, 0, 5, 3, 10, 6,
+ ENCODING_MAP(THUMB_LSR, 0x0800,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 10, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"lsr", "r!0d, r!1d, #!2d", 1),
- ENCODING_MAP(THUMB_LSRV, 0x40c0, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_LSRV, 0x40c0,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"lsr", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_MOV_IMM, 0x2000, 10, 8, 7, 0, -1, -1,
+ ENCODING_MAP(THUMB_MOV_IMM, 0x2000,
+ BITBLT, 10, 8, BITBLT, 7, 0, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"mov", "r!0d, #!1d", 1),
- ENCODING_MAP(THUMB_MOV_RR, 0x1c00, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_MOV_RR, 0x1c00,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"mov", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_MOV_RR_H2H, 0x46c0, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_MOV_RR_H2H, 0x46c0,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"mov", "r!0D, r!1D", 1),
- ENCODING_MAP(THUMB_MOV_RR_H2L, 0x4640, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_MOV_RR_H2L, 0x4640,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"mov", "r!0d, r!1D", 1),
- ENCODING_MAP(THUMB_MOV_RR_L2H, 0x4680, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_MOV_RR_L2H, 0x4680,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"mov", "r!0D, r!1d", 1),
- ENCODING_MAP(THUMB_MUL, 0x4340, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_MUL, 0x4340,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"mul", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_MVN, 0x43c0, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_MVN, 0x43c0,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"mvn", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_NEG, 0x4240, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_NEG, 0x4240,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"neg", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_ORR, 0x4300, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_ORR, 0x4300,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"orr", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_POP, 0xbc00, 8, 0, -1, -1, -1, -1,
+ ENCODING_MAP(THUMB_POP, 0xbc00,
+ BITBLT, 8, 0, UNUSED, -1, -1, UNUSED, -1, -1,
IS_UNARY_OP,
"pop", "<!0R>", 1),
- ENCODING_MAP(THUMB_PUSH, 0xb400, 8, 0, -1, -1, -1, -1,
+ ENCODING_MAP(THUMB_PUSH, 0xb400,
+ BITBLT, 8, 0, UNUSED, -1, -1, UNUSED, -1, -1,
IS_UNARY_OP,
"push", "<!0R>", 1),
- ENCODING_MAP(THUMB_ROR, 0x41c0, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_ROR, 0x41c0,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"ror", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_SBC, 0x4180, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_SBC, 0x4180,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"sbc", "r!0d, r!1d", 1),
- ENCODING_MAP(THUMB_STMIA, 0xc000, 10, 8, 7, 0, -1, -1,
+ ENCODING_MAP(THUMB_STMIA, 0xc000,
+ BITBLT, 10, 8, BITBLT, 7, 0, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_SRC1,
"stmia", "r!0d!!, <!1R>", 1),
- ENCODING_MAP(THUMB_STR_RRI5, 0x6000, 2, 0, 5, 3, 10, 6,
+ ENCODING_MAP(THUMB_STR_RRI5, 0x6000,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 10, 6,
IS_TERTIARY_OP,
"str", "r!0d, [r!1d, #!2E]", 1),
- ENCODING_MAP(THUMB_STR_RRR, 0x5000, 2, 0, 5, 3, 8, 6,
+ ENCODING_MAP(THUMB_STR_RRR, 0x5000,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 8, 6,
IS_TERTIARY_OP,
"str", "r!0d, [r!1d, r!2d]", 1),
- ENCODING_MAP(THUMB_STR_SP_REL, 0x9000, 10, 8, 7, 0, -1, -1,
+ ENCODING_MAP(THUMB_STR_SP_REL, 0x9000,
+ BITBLT, 10, 8, BITBLT, 7, 0, UNUSED, -1, -1,
IS_BINARY_OP,
"str", "r!0d, [sp, #!1E]", 1),
- ENCODING_MAP(THUMB_STRB_RRI5, 0x7000, 2, 0, 5, 3, 10, 6,
+ ENCODING_MAP(THUMB_STRB_RRI5, 0x7000,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 10, 6,
IS_TERTIARY_OP,
"strb", "r!0d, [r!1d, #!2d]", 1),
- ENCODING_MAP(THUMB_STRB_RRR, 0x5400, 2, 0, 5, 3, 8, 6,
+ ENCODING_MAP(THUMB_STRB_RRR, 0x5400,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 8, 6,
IS_TERTIARY_OP,
"strb", "r!0d, [r!1d, r!2d]", 1),
- ENCODING_MAP(THUMB_STRH_RRI5, 0x8000, 2, 0, 5, 3, 10, 6,
+ ENCODING_MAP(THUMB_STRH_RRI5, 0x8000,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 10, 6,
IS_TERTIARY_OP,
"strh", "r!0d, [r!1d, #!2F]", 1),
- ENCODING_MAP(THUMB_STRH_RRR, 0x5200, 2, 0, 5, 3, 8, 6,
+ ENCODING_MAP(THUMB_STRH_RRR, 0x5200,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 8, 6,
IS_TERTIARY_OP,
"strh", "r!0d, [r!1d, r!2d]", 1),
- ENCODING_MAP(THUMB_SUB_RRI3, 0x1e00, 2, 0, 5, 3, 8, 6,
+ ENCODING_MAP(THUMB_SUB_RRI3, 0x1e00,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 8, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"sub", "r!0d, r!1d, #!2d]", 1),
- ENCODING_MAP(THUMB_SUB_RI8, 0x3800, 10, 8, 7, 0, -1, -1,
+ ENCODING_MAP(THUMB_SUB_RI8, 0x3800,
+ BITBLT, 10, 8, BITBLT, 7, 0, UNUSED, -1, -1,
IS_BINARY_OP | CLOBBER_DEST,
"sub", "r!0d, #!1d", 1),
- ENCODING_MAP(THUMB_SUB_RRR, 0x1a00, 2, 0, 5, 3, 8, 6,
+ ENCODING_MAP(THUMB_SUB_RRR, 0x1a00,
+ BITBLT, 2, 0, BITBLT, 5, 3, BITBLT, 8, 6,
IS_TERTIARY_OP | CLOBBER_DEST,
"sub", "r!0d, r!1d, r!2d", 1),
- ENCODING_MAP(THUMB_SUB_SPI7, 0xb080, 6, 0, -1, -1, -1, -1,
+ ENCODING_MAP(THUMB_SUB_SPI7, 0xb080,
+ BITBLT, 6, 0, UNUSED, -1, -1, UNUSED, -1, -1,
IS_UNARY_OP | CLOBBER_DEST,
"sub", "sp, #!0d", 1),
- ENCODING_MAP(THUMB_SWI, 0xdf00, 7, 0, -1, -1, -1, -1,
+ ENCODING_MAP(THUMB_SWI, 0xdf00,
+ BITBLT, 7, 0, UNUSED, -1, -1, UNUSED, -1, -1,
IS_UNARY_OP | IS_BRANCH,
"swi", "!0d", 1),
- ENCODING_MAP(THUMB_TST, 0x4200, 2, 0, 5, 3, -1, -1,
+ ENCODING_MAP(THUMB_TST, 0x4200,
+ BITBLT, 2, 0, BITBLT, 5, 3, UNUSED, -1, -1,
IS_UNARY_OP,
"tst", "r!0d, r!1d", 1),
+ ENCODING_MAP(THUMB2_VLDRS, 0xed900a00,
+ SFP, 22, 12, BITBLT, 19, 16, BITBLT, 7, 0,
+ IS_TERTIARY_OP,
+ "vldr", "s!0d, [r!1d, #!2E]", 2),
+ ENCODING_MAP(THUMB2_VLDRD, 0xed900b00,
+ DFP, 22, 12, BITBLT, 19, 16, BITBLT, 7, 0,
+ IS_TERTIARY_OP,
+ "vldr", "d!0d, [r!1d, #!2E]", 2),
+ ENCODING_MAP(THUMB2_VMULS, 0xee200a00,
+ SFP, 22, 12, SFP, 7, 16, SFP, 5, 0,
+ IS_TERTIARY_OP,
+ "vmuls", "s!0d, s!1d, s!2d", 2),
+ ENCODING_MAP(THUMB2_VMULD, 0xee200b00,
+ DFP, 22, 12, DFP, 7, 16, DFP, 5, 0,
+ IS_TERTIARY_OP,
+ "vmuld", "d!0d, d!1d, d!2d", 2),
+ ENCODING_MAP(THUMB2_VSTRS, 0xed800a00,
+ SFP, 22, 12, BITBLT, 19, 16, BITBLT, 7, 0,
+ IS_TERTIARY_OP,
+ "vstr", "s!0d, [r!1d, #!2E]", 2),
+ ENCODING_MAP(THUMB2_VSTRD, 0xed800b00,
+ DFP, 22, 12, BITBLT, 19, 16, BITBLT, 7, 0,
+ IS_TERTIARY_OP,
+ "vstr", "d!0d, [r!1d, #!2E]", 2),
+ ENCODING_MAP(THUMB2_VSUBS, 0xee300a40,
+ SFP, 22, 12, SFP, 7, 16, SFP, 5, 0,
+ IS_TERTIARY_OP,
+ "vsub", "s!0d, s!1d, s!2d", 2),
+ ENCODING_MAP(THUMB2_VSUBD, 0xee300b40,
+ DFP, 22, 12, DFP, 7, 16, DFP, 5, 0,
+ IS_TERTIARY_OP,
+ "vsub", "d!0d, s!1d, s!2d", 2),
+ ENCODING_MAP(THUMB2_VADDS, 0xee300a00,
+ SFP, 22, 12, SFP, 7, 16, SFP, 5, 0,
+ IS_TERTIARY_OP,
+ "vadd", "s!0d, s!1d, s!2d", 2),
+ ENCODING_MAP(THUMB2_VADDD, 0xee300b00,
+ DFP, 22, 12, DFP, 7, 16, DFP, 5, 0,
+ IS_TERTIARY_OP,
+ "vadd", "d!0d, s!1d, s!2d", 2),
+ ENCODING_MAP(THUMB2_VDIVS, 0xee800a00,
+ SFP, 22, 12, SFP, 7, 16, SFP, 5, 0,
+ IS_TERTIARY_OP,
+ "vdivs", "s!0d, s!1d, s!2d", 2),
+ ENCODING_MAP(THUMB2_VDIVD, 0xee800b00,
+ DFP, 22, 12, DFP, 7, 16, DFP, 5, 0,
+ IS_TERTIARY_OP,
+ "vdivs", "s!0d, s!1d, s!2d", 2),
+ ENCODING_MAP(THUMB2_VCVTIF, 0xeeb80ac0,
+ SFP, 22, 12, SFP, 5, 0, UNUSED, -1, -1,
+ IS_BINARY_OP,
+ "vcvf.f32", "s!0d, s!1d", 2),
+ ENCODING_MAP(THUMB2_VCVTID, 0xeeb80bc0,
+ DFP, 22, 12, SFP, 5, 0, UNUSED, -1, -1,
+ IS_BINARY_OP,
+ "vcvf.f64", "s!0d, s!1d", 2),
+ ENCODING_MAP(THUMB2_VCVTFI, 0xeebd0ac0,
+ SFP, 22, 12, SFP, 5, 0, UNUSED, -1, -1,
+ IS_BINARY_OP,
+ "vcvf.s32.f32", "s!0d, s!1d", 2),
+ ENCODING_MAP(THUMB2_VCVTDI, 0xeebd0bc0,
+ SFP, 22, 12, DFP, 5, 0, UNUSED, -1, -1,
+ IS_BINARY_OP,
+ "vcvf.s32.f64", "s!0d, s!1d", 2),
+ ENCODING_MAP(THUMB2_VCVTFD, 0xeeb70ac0,
+ DFP, 22, 12, SFP, 5, 0, UNUSED, -1, -1,
+ IS_BINARY_OP,
+ "vcvf.f64.f32", "s!0d, s!1d", 2),
+ ENCODING_MAP(THUMB2_VCVTDF, 0xeeb70bc0,
+ SFP, 22, 12, DFP, 5, 0, UNUSED, -1, -1,
+ IS_BINARY_OP,
+ "vcvf.f32.f64", "s!0d, s!1d", 2),
};
#define PADDING_MOV_R0_R0 0x1C00
@@ -387,18 +535,50 @@ static bool assembleInstructions(CompilationUnit *cUnit, intptr_t startAddr)
}
ArmEncodingMap *encoder = &EncodingMap[lir->opCode];
- short bits = encoder->skeleton;
+ u4 bits = encoder->skeleton;
int i;
for (i = 0; i < 3; i++) {
- short value;
- if (encoder->fieldLoc[i].end != -1) {
- value = (lir->operands[i] << encoder->fieldLoc[i].start) &
- ((1 << (encoder->fieldLoc[i].end + 1)) - 1);
- bits |= value;
-
+ u4 value;
+ switch(encoder->fieldLoc[i].kind) {
+ case UNUSED:
+ break;
+ case BITBLT:
+ value = (lir->operands[i] << encoder->fieldLoc[i].start) &
+ ((1 << (encoder->fieldLoc[i].end + 1)) - 1);
+ bits |= value;
+ break;
+ case DFP:
+ /* Snag the 1-bit slice and position it */
+ value = ((lir->operands[i] & 0x10) >> 4) <<
+ encoder->fieldLoc[i].end;
+ /* Extract and position the 4-bit slice */
+ value |= (lir->operands[i] & 0x0f) <<
+ encoder->fieldLoc[i].start;
+ bits |= value;
+ break;
+ case SFP:
+ /* Snag the 1-bit slice and position it */
+ value = (lir->operands[i] & 0x1) <<
+ encoder->fieldLoc[i].end;
+ /* Extract and position the 4-bit slice */
+ value |= ((lir->operands[i] & 0x1e) >> 1) <<
+ encoder->fieldLoc[i].start;
+ bits |= value;
+ break;
+ case IMMSHIFT8:
+ case IMM12:
+ value = ((lir->operands[i] & 0x800) >> 11) << 26;
+ value |= ((lir->operands[i] & 0x700) >> 8) << 12;
+ value |= lir->operands[i] & 0x0ff;
+ break;
+ default:
+ assert(0);
}
}
- *bufferAddr++ = bits;
+ if (encoder->size == 2) {
+ *bufferAddr++ = (bits >> 16) & 0xffff;
+ }
+ *bufferAddr++ = bits & 0xffff;
}
return false;
}
@@ -459,7 +639,8 @@ void dvmCompilerAssembleLIR(CompilationUnit *cUnit, JitTranslationInfo *info)
armLIR = NEXT_LIR(armLIR)) {
armLIR->generic.offset = offset;
if (armLIR->opCode >= 0 && !armLIR->isNop) {
- offset += 2;
+ armLIR->size = EncodingMap[armLIR->opCode].size * 2;
+ offset += armLIR->size;
} else if (armLIR->opCode == ARM_PSEUDO_ALIGN4) {
if (offset & 0x2) {
offset += 2;