Dummy up MOV instructions, add/tweak comments.
Also reorder some things to help me see them on screen at the same time.
Change-Id: I398b46410f73d7853b5a1734f5c2a9e256b981bf
diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h
index db2d6e8..bc85dd8 100644
--- a/src/compiler/codegen/arm/ArmLIR.h
+++ b/src/compiler/codegen/arm/ArmLIR.h
@@ -285,8 +285,8 @@
/*
* The following enum defines the list of supported Thumb instructions by the
- * assembler. Their corresponding snippet positions will be defined in
- * Assemble.c.
+ * assembler. Their corresponding EncodingMap positions will be defined in
+ * Assemble.cc.
*/
typedef enum ArmOpcode {
kPseudoSuspendTarget = -15,
diff --git a/src/compiler/codegen/mips/MipsLIR.h b/src/compiler/codegen/mips/MipsLIR.h
index 320ec52..341e56b 100644
--- a/src/compiler/codegen/mips/MipsLIR.h
+++ b/src/compiler/codegen/mips/MipsLIR.h
@@ -327,8 +327,8 @@
/*
* The following enum defines the list of supported Thumb instructions by the
- * assembler. Their corresponding snippet positions will be defined in
- * Assemble.c.
+ * assembler. Their corresponding EncodingMap positions will be defined in
+ * Assemble.cc.
*/
typedef enum MipsOpCode {
kPseudoSuspendTarget = -15,
diff --git a/src/compiler/codegen/x86/Assemble.cc b/src/compiler/codegen/x86/Assemble.cc
index 722f7bb..8223db0 100644
--- a/src/compiler/codegen/x86/Assemble.cc
+++ b/src/compiler/codegen/x86/Assemble.cc
@@ -28,34 +28,34 @@
rm8_r8, rm32_r32, \
r8_rm8, r32_rm32, \
rax8_i8, rax32_i32, \
- rm8_i8_opcode, rm8_i8_modrm, \
- rm32_i32_opcode, rm32_i32_modrm, \
- rm32_i8_opcode, rm32_i8_modrm) \
+ rm8_i8_opcode, rm8_i8_modrm_opcode, \
+ rm32_i32_opcode, rm32_i32_modrm_opcode, \
+ rm32_i8_opcode, rm32_i8_modrm_opcode) \
{ kOp ## opcode ## RI, \
kRegImm, \
0, \
{ RegMem_Immediate: { rax8_i8, rax32_i32, \
- {rm8_i8_opcode, rm8_i8_modrm}, \
- {rm32_i32_opcode, rm32_i32_modrm}, \
- {rm32_i8_opcode, rm32_i8_modrm} } }, \
+ {rm8_i8_opcode, rm8_i8_modrm_opcode}, \
+ {rm32_i32_opcode, rm32_i32_modrm_opcode}, \
+ {rm32_i8_opcode, rm32_i8_modrm_opcode} } }, \
#opcode "RI", "" \
}, \
{ kOp ## opcode ## MI, \
kMemImm, \
0, \
{ RegMem_Immediate: { rax8_i8, rax32_i32, \
- {rm8_i8_opcode, rm8_i8_modrm}, \
- {rm32_i32_opcode, rm32_i32_modrm}, \
- {rm32_i8_opcode, rm32_i8_modrm} } }, \
+ {rm8_i8_opcode, rm8_i8_modrm_opcode}, \
+ {rm32_i32_opcode, rm32_i32_modrm_opcode}, \
+ {rm32_i8_opcode, rm32_i8_modrm_opcode} } }, \
#opcode "MI", "" \
}, \
{ kOp ## opcode ## AI, \
kArrayImm, \
0, \
{ RegMem_Immediate: { rax8_i8, rax32_i32, \
- {rm8_i8_opcode, rm8_i8_modrm}, \
- {rm32_i32_opcode, rm32_i32_modrm}, \
- {rm32_i8_opcode, rm32_i8_modrm} } }, \
+ {rm8_i8_opcode, rm8_i8_modrm_opcode}, \
+ {rm32_i32_opcode, rm32_i32_modrm_opcode}, \
+ {rm32_i8_opcode, rm32_i8_modrm_opcode} } }, \
#opcode "AI", "" \
}, \
{ kOp ## opcode ## RR, \
@@ -138,9 +138,72 @@
0x3A /* Reg8/RegMem8 */, 0x3B /* Reg32/RegMem32 */,
0x3C /* Rax8/imm8 opcode */, 0x3D /* Rax32/imm32 */,
0x80, 0x7 /* RegMem8/imm8 */,
- 0x81, 0x7 /* RegMem32/imm32 */, 0x83, 0x7 /* RegMem32/imm8 */)
+ 0x81, 0x7 /* RegMem32/imm32 */, 0x83, 0x7 /* RegMem32/imm8 */),
+ { kOpMovRI, kUnimplemented, 0 /* flags - TODO */ , { unused: 0 }, "MovRI", "" },
+ { kOpMovMI, kUnimplemented, 0 /* flags - TODO */ , { unused: 0 }, "MovMI", "" },
+ { kOpMovAI, kUnimplemented, 0 /* flags - TODO */ , { unused: 0 }, "MovAI", "" },
+ { kOpMovRR, kRegReg, 0 /* flags - TODO */, { Reg_RegMem: {0x8A, 0x8B} }, "MovRR", "" },
+ { kOpMovRM, kRegMem, 0 /* flags - TODO */, { Reg_RegMem: {0x8A, 0x8B} }, "MovRM", "" },
+ { kOpMovRA, kRegArray, 0 /* flags - TODO */, { Reg_RegMem: {0x8A, 0x8B} }, "MovRA", "" },
+ { kOpMovMR, kMemReg, 0 /* flags - TODO */, { RegMem_Reg: {0x88, 0x89} }, "MovMR", "" },
+ { kOpMovAR, kArrayReg, 0 /* flags - TODO */, { RegMem_Reg: {0x88, 0x89} }, "MovAR", "" }
};
+int oatGetInsnSize(LIR* lir)
+{
+ switch (EncodingMap[lir->opcode].kind) {
+ case kData:
+ return 4;
+ case kRegImm: {
+ int reg = lir->operands[0];
+ int imm = lir->operands[1];
+ return (reg == rAX ? 1 : 2) + // AX opcodes don't require the modrm byte
+ (IS_SIMM8(imm) ? 1 : 4); // 1 or 4 byte immediate
+ break;
+ }
+ case kMemImm: {
+ // int base = lir->operands[0];
+ int disp = lir->operands[1];
+ int imm = lir->operands[2];
+ return 2 + // opcode and modrm bytes
+ (disp == 0 ? 0 : (IS_SIMM8(disp) ? 1 : 4)) + // 0, 1 or 4 byte displacement
+ (IS_SIMM8(imm) ? 1 : 4); // 1 or 4 byte immediate
+ break;
+ }
+ case kArrayImm:
+ UNIMPLEMENTED(FATAL);
+ return 0;
+ case kRegReg:
+ return 2; // opcode and modrm
+ case kRegMem: {
+ // int reg = lir->operands[0];
+ // int base = lir->operands[1];
+ int disp = lir->operands[2];
+ return 2 + // opcode and modrm bytes
+ (disp == 0 ? 0 : (IS_SIMM8(disp) ? 1 : 4)); // 0, 1 or 4 byte displacement
+ break;
+ }
+ case kRegArray:
+ UNIMPLEMENTED(FATAL);
+ return 0;
+ case kMemReg: {
+ // int base = lir->operands[0];
+ int disp = lir->operands[1];
+ // int reg = lir->operands[2];
+ return 2 + // opcode and modrm bytes
+ (disp == 0 ? 0 : (IS_SIMM8(disp) ? 1 : 4)); // 0, 1 or 4 byte displacement
+ break;
+ }
+ case kArrayReg:
+ UNIMPLEMENTED(FATAL);
+ return 0;
+ case kUnimplemented:
+ UNIMPLEMENTED(FATAL);
+ return 0;
+ }
+ UNIMPLEMENTED(FATAL); // unreachable
+ return 0;
+}
/*
* Assemble the LIR into binary instruction format. Note that we may
@@ -341,58 +404,6 @@
#endif
}
-int oatGetInsnSize(LIR* lir)
-{
- switch (EncodingMap[lir->opcode].kind) {
- case kData:
- return 4;
- case kRegImm: {
- int reg = lir->operands[0];
- int imm = lir->operands[1];
- return (reg == rAX ? 1 : 2) + // AX opcodes don't require the modrm byte
- (IS_SIMM8(imm) ? 1 : 4); // 1 or 4 byte immediate
- break;
- }
- case kMemImm: {
- // int base = lir->operands[0];
- int disp = lir->operands[1];
- int imm = lir->operands[2];
- return 2 + // opcode and modrm bytes
- (disp == 0 ? 0 : (IS_SIMM8(disp) ? 1 : 4)) + // 0, 1 or 4 byte displacement
- (IS_SIMM8(imm) ? 1 : 4); // 1 or 4 byte immediate
- break;
- }
- case kArrayImm:
- UNIMPLEMENTED(FATAL);
- return 0;
- case kRegReg:
- return 2; // opcode and modrm
- case kRegMem: {
- // int reg = lir->operands[0];
- // int base = lir->operands[1];
- int disp = lir->operands[2];
- return 2 + // opcode and modrm bytes
- (disp == 0 ? 0 : (IS_SIMM8(disp) ? 1 : 4)); // 0, 1 or 4 byte displacement
- break;
- }
- case kRegArray:
- UNIMPLEMENTED(FATAL);
- return 0;
- case kMemReg: {
- // int base = lir->operands[0];
- int disp = lir->operands[1];
- // int reg = lir->operands[2];
- return 2 + // opcode and modrm bytes
- (disp == 0 ? 0 : (IS_SIMM8(disp) ? 1 : 4)); // 0, 1 or 4 byte displacement
- break;
- }
- case kArrayReg:
- UNIMPLEMENTED(FATAL);
- return 0;
- }
- UNIMPLEMENTED(FATAL); // unreachable
- return 0;
-}
/*
* Target-dependent offset assignment.
* independent.
diff --git a/src/compiler/codegen/x86/X86LIR.h b/src/compiler/codegen/x86/X86LIR.h
index 13488fe..32bb1f8 100644
--- a/src/compiler/codegen/x86/X86LIR.h
+++ b/src/compiler/codegen/x86/X86LIR.h
@@ -231,9 +231,9 @@
#define isPseudoOpcode(opCode) ((int)(opCode) < 0)
/*
- * The following enum defines the list of supported Thumb instructions by the
- * assembler. Their corresponding snippet positions will be defined in
- * Assemble.c.
+ * The following enum defines the list of supported X86 instructions by the
+ * assembler. Their corresponding EncodingMap positions will be defined in
+ * Assemble.cc.
*/
typedef enum X86OpCode {
kPseudoSuspendTarget = -15,
@@ -253,6 +253,23 @@
kPseudoNormalBlockLabel = -1,
kX86First,
kX8632BitData = kX86First, /* data [31..0] */
+ // Define groups of binary operations
+ // RI - Register Immediate - opcode reg, #immediate
+ // - lir operands - 0: reg, 1: immediate
+ // MI - Memory Immediate - opcode [base + disp], #immediate
+ // - lir operands - 0: base, 1: disp, 2: immediate
+ // AI - Array Immediate - opcode [base + index * scale + disp], #immediate
+ // - lir operands - 0: base, 1: index, 2: scale, 3: disp 4: immediate
+ // RR - Register Register - opcode reg1, reg2
+ // - lir operands - 0: reg1, 1: reg2
+ // RM - Register Memory - opcode reg, [base + disp]
+ // - lir operands - 0: reg, 1: base, 2: disp
+ // RA - Register Array - opcode reg, [base + index * scale + disp]
+ // - lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp
+ // MR - Memory Register - opcode [base + disp], reg
+ // - lir operands - 0: base, 1: disp, 2: reg
+ // AR - Array Register - opcode [base + index * scale + disp], reg
+ // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: reg
#define BinaryOpCode(opcode) \
opcode ## RI, opcode ## MI, opcode ##AI, \
opcode ## RR, opcode ## RM, opcode ##RA, \
@@ -265,10 +282,56 @@
BinaryOpCode(kOpSub),
BinaryOpCode(kOpXor),
BinaryOpCode(kOpCmp),
+ BinaryOpCode(kOpMov),
#undef BinaryOpCode
kX86Last
} X86OpCode;
+/* Instruction assembly fieldLoc kind */
+typedef enum X86EncodingKind {
+ kData, // Special case for raw data
+ kRegImm, kMemImm, kArrayImm, // RI, MI, AI instruction kinds
+ kRegReg, kRegMem, kRegArray, // RR, RM, RA instruction kinds
+ kMemReg, kArrayReg, // MR and AR instruction kinds
+ kUnimplemented // Encoding used when an instruction isn't yet implemented.
+} X86EncodingKind;
+
+/* A form of instruction with an opcode byte and a secondary opcode within the modrm byte */
+typedef struct OpcodeModRMOpcode {
+ uint8_t opcode; // 1 byte opcode
+ uint8_t modrm_opcode; // 3 bit opcode that gets encoded in the register bits of the modrm byte
+} OpcodeModRMOpcode;
+
+/* Struct used to define the EncodingMap positions for each X86 opcode */
+typedef struct X86EncodingMap {
+ X86OpCode opcode; // e.g. kOpAddRI
+ X86EncodingKind kind; // Used to discriminate in the union below
+ int flags;
+ union {
+ struct {
+ uint8_t rax8_i8_opcode;
+ uint8_t rax32_i32_opcode;
+ OpcodeModRMOpcode rm8_i8_opcode;
+ OpcodeModRMOpcode rm32_i32_opcode;
+ OpcodeModRMOpcode rm32_i8_opcode;
+ } RegMem_Immediate; // kind: kRegImm, kMemImm, kArrayImm
+ struct {
+ uint8_t r8_rm8_opcode;
+ uint8_t r32_rm32_opcode;
+ } Reg_RegMem; // kind: kRegReg, kRegMem, kRegArray
+ struct {
+ uint8_t rm8_r8_opcode;
+ uint8_t rm32_r32_opcode;
+ } RegMem_Reg; // kind: kMemReg, kArrayReg
+ // This is a convenience for static initialization where the kind doesn't require opcode data.
+ int unused; // kind: kData, kUnimplemented
+ } skeleton;
+ const char *name;
+ const char* fmt;
+} X86EncodingMap;
+
+extern X86EncodingMap EncodingMap[kX86Last];
+
// FIXME: mem barrier type - what do we do for x86?
#define kSY 0
#define kST 0
@@ -348,54 +411,13 @@
#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
-/* Instruction assembly fieldLoc kind */
-typedef enum X86EncodingKind {
- kData,
- kRegImm, kMemImm, kArrayImm,
- kRegReg, kRegMem, kRegArray,
- kMemReg, kArrayReg
-} X86EncodingKind;
-
-/* Struct used to define the snippet positions for each X86 opcode */
-typedef struct OpcodeModRMOpcode {
- uint8_t opcode;
- uint8_t modrm_opcode;
-} OpcodeModRMOpcode;
-
-typedef struct X86EncodingMap {
- X86OpCode opcode; // e.g. kOpAddRI
- X86EncodingKind kind; // Used to discriminate in the union below
- int flags;
- union {
- struct {
- uint8_t rax8_i8_opcode;
- uint8_t rax32_i32_opcode;
- OpcodeModRMOpcode rm8_i8_opcode;
- OpcodeModRMOpcode rm32_i32_opcode;
- OpcodeModRMOpcode rm32_i8_opcode;
- } RegMem_Immediate; // kind: kRegImm, kMemImm, kArrayImm
- struct {
- uint8_t r8_rm8_opcode;
- uint8_t r32_rm32_opcode;
- } Reg_RegMem; // kind: kRegReg, kRegMem, kRegArray,
- struct {
- uint8_t rm8_r8_opcode;
- uint8_t rm32_r32_opcode;
- } RegMem_Reg; // kind: kMemReg, kArrayReg
- int unused; // kind: kData
- } skeleton;
- const char *name;
- const char* fmt;
-} X86EncodingMap;
-
/* Keys for target-specific scheduling and other optimization hints */
typedef enum X86TargetOptHints {
kMaxHoistDistance,
} X86TargetOptHints;
-extern X86EncodingMap EncodingMap[kX86Last];
-#define IS_SIMM8(v) ((-128 <= (v)) && ((v) <= 128))
+#define IS_SIMM8(v) ((-128 <= (v)) && ((v) <= 127))
} // namespace art