Merge "Implement the x86 initialize-type...from-code entry points." into ics-mr1-plus-art
diff --git a/src/compiler/codegen/x86/Assemble.cc b/src/compiler/codegen/x86/Assemble.cc
index fc9878e..d9cdabf 100644
--- a/src/compiler/codegen/x86/Assemble.cc
+++ b/src/compiler/codegen/x86/Assemble.cc
@@ -130,16 +130,16 @@
0x81, 0x7 /* RegMem32/imm32 */, 0x83, 0x7 /* RegMem32/imm8 */),
#undef ENCODING_MAP
- { kX86Imul16RRI, kRegRegImm, IS_TERTIARY_OP | SETS_CCODES, { 0x66, 0, 0x69, 0, 0, 0, 0, 2 }, "Imul16RRI", "" },
- { kX86Imul16RMI, kRegMemImm, IS_LOAD | IS_QUAD_OP | SETS_CCODES, { 0x66, 0, 0x69, 0, 0, 0, 0, 2 }, "Imul16RMI", "" },
- { kX86Imul16RAI, kRegArrayImm, IS_LOAD | IS_SEXTUPLE_OP | SETS_CCODES, { 0x66, 0, 0x69, 0, 0, 0, 0, 2 }, "Imul16RAI", "" },
+ { kX86Imul16RRI, kRegRegImm, IS_TERTIARY_OP | SETS_CCODES, { 0x66, 0, 0x69, 0, 0, 0, 0, 2 }, "Imul16RRI", "!0r,!1r,!2d" },
+ { kX86Imul16RMI, kRegMemImm, IS_LOAD | IS_QUAD_OP | SETS_CCODES, { 0x66, 0, 0x69, 0, 0, 0, 0, 2 }, "Imul16RMI", "!0r,[!1r+!2d],!3d" },
+ { kX86Imul16RAI, kRegArrayImm, IS_LOAD | IS_SEXTUPLE_OP | SETS_CCODES, { 0x66, 0, 0x69, 0, 0, 0, 0, 2 }, "Imul16RAI", "!0r,[!1r+!2r<<!3d+!4d],!5d" },
- { kX86Imul32RRI, kRegRegImm, IS_TERTIARY_OP | SETS_CCODES, { 0, 0, 0x69, 0, 0, 0, 0, 2 }, "Imul32RRI", "" },
- { kX86Imul32RMI, kRegMemImm, IS_LOAD | IS_QUAD_OP | SETS_CCODES, { 0, 0, 0x69, 0, 0, 0, 0, 2 }, "Imul32RMI", "" },
- { kX86Imul32RAI, kRegArrayImm, IS_LOAD | IS_SEXTUPLE_OP | SETS_CCODES, { 0, 0, 0x69, 0, 0, 0, 0, 2 }, "Imul32RAI", "" },
- { kX86Imul32RRI8, kRegRegImm, IS_TERTIARY_OP | SETS_CCODES, { 0, 0, 0x6B, 0, 0, 0, 0, 1 }, "Imul32RRI8", "" },
- { kX86Imul32RMI8, kRegMemImm, IS_LOAD | IS_QUAD_OP | SETS_CCODES, { 0, 0, 0x6B, 0, 0, 0, 0, 1 }, "Imul32RMI8", "" },
- { kX86Imul32RAI8, kRegArrayImm, IS_LOAD | IS_SEXTUPLE_OP | SETS_CCODES, { 0, 0, 0x6B, 0, 0, 0, 0, 1 }, "Imul32RAI8", "" },
+ { kX86Imul32RRI, kRegRegImm, IS_TERTIARY_OP | SETS_CCODES, { 0, 0, 0x69, 0, 0, 0, 0, 2 }, "Imul32RRI", "!0r,!1r,!2d" },
+ { kX86Imul32RMI, kRegMemImm, IS_LOAD | IS_QUAD_OP | SETS_CCODES, { 0, 0, 0x69, 0, 0, 0, 0, 2 }, "Imul32RMI", "!0r,[!1r+!2d],!3d" },
+ { kX86Imul32RAI, kRegArrayImm, IS_LOAD | IS_SEXTUPLE_OP | SETS_CCODES, { 0, 0, 0x69, 0, 0, 0, 0, 2 }, "Imul32RAI", "!0r,[!1r+!2r<<!3d+!4d],!5d" },
+ { kX86Imul32RRI8, kRegRegImm, IS_TERTIARY_OP | SETS_CCODES, { 0, 0, 0x6B, 0, 0, 0, 0, 1 }, "Imul32RRI8", "!0r,!1r,!2d" },
+ { kX86Imul32RMI8, kRegMemImm, IS_LOAD | IS_QUAD_OP | SETS_CCODES, { 0, 0, 0x6B, 0, 0, 0, 0, 1 }, "Imul32RMI8", "!0r,[!1r+!2d],!3d" },
+ { kX86Imul32RAI8, kRegArrayImm, IS_LOAD | IS_SEXTUPLE_OP | SETS_CCODES, { 0, 0, 0x6B, 0, 0, 0, 0, 1 }, "Imul32RAI8", "!0r,[!1r+!2r<<!3d+!4d],!5d" },
{ kX86Mov8MR, kMemReg, IS_STORE | IS_TERTIARY_OP, { 0, 0, 0x88, 0, 0, 0, 0, 0 }, "Mov8MR", "[!0r+!1d],!2r" },
{ kX86Mov8AR, kArrayReg, IS_STORE | IS_QUIN_OP, { 0, 0, 0x88, 0, 0, 0, 0, 0 }, "Mov8AR", "[!0r+!1r<<!2d+!3d],!4r" },
@@ -707,6 +707,63 @@
DCHECK_EQ(0, entry->skeleton.immediate_bytes);
}
+static void emitRegRegImm(CompilationUnit* cUnit, const X86EncodingMap* entry,
+ uint8_t reg1, uint8_t reg2, int32_t imm) {
+ if (entry->skeleton.prefix1 != 0) {
+ cUnit->codeBuffer.push_back(entry->skeleton.prefix1);
+ if (entry->skeleton.prefix2 != 0) {
+ cUnit->codeBuffer.push_back(entry->skeleton.prefix2);
+ }
+ } else {
+ DCHECK_EQ(0, entry->skeleton.prefix2);
+ }
+ cUnit->codeBuffer.push_back(entry->skeleton.opcode);
+ if (entry->skeleton.opcode == 0x0F) {
+ cUnit->codeBuffer.push_back(entry->skeleton.extra_opcode1);
+ if (entry->skeleton.extra_opcode1 == 0x38 || entry->skeleton.extra_opcode2 == 0x3A) {
+ cUnit->codeBuffer.push_back(entry->skeleton.extra_opcode2);
+ } else {
+ DCHECK_EQ(0, entry->skeleton.extra_opcode2);
+ }
+ } else {
+ DCHECK_EQ(0, entry->skeleton.extra_opcode1);
+ DCHECK_EQ(0, entry->skeleton.extra_opcode2);
+ }
+ if (FPREG(reg1)) {
+ reg1 = reg1 & FP_REG_MASK;
+ }
+ if (FPREG(reg2)) {
+ reg2 = reg2 & FP_REG_MASK;
+ }
+ DCHECK_LT(reg1, 8);
+ DCHECK_LT(reg2, 8);
+ uint8_t modrm = (3 << 6) | (reg1 << 3) | reg2;
+ cUnit->codeBuffer.push_back(modrm);
+ DCHECK_EQ(0, entry->skeleton.modrm_opcode);
+ DCHECK_EQ(0, entry->skeleton.ax_opcode);
+ switch (entry->skeleton.immediate_bytes) {
+ case 1:
+ DCHECK(IS_SIMM8(imm));
+ cUnit->codeBuffer.push_back(imm & 0xFF);
+ break;
+ case 2:
+ DCHECK(IS_SIMM16(imm));
+ cUnit->codeBuffer.push_back(imm & 0xFF);
+ cUnit->codeBuffer.push_back((imm >> 8) & 0xFF);
+ break;
+ case 4:
+ cUnit->codeBuffer.push_back(imm & 0xFF);
+ cUnit->codeBuffer.push_back((imm >> 8) & 0xFF);
+ cUnit->codeBuffer.push_back((imm >> 16) & 0xFF);
+ cUnit->codeBuffer.push_back((imm >> 24) & 0xFF);
+ break;
+ default:
+ LOG(FATAL) << "Unexpected immediate bytes (" << entry->skeleton.immediate_bytes
+ << ") for instruction: " << entry->name;
+ break;
+ }
+}
+
static void emitRegImm(CompilationUnit* cUnit, const X86EncodingMap* entry,
uint8_t reg, int imm) {
if (entry->skeleton.prefix1 != 0) {
@@ -1063,7 +1120,7 @@
}
void emitUnimplemented(CompilationUnit* cUnit, const X86EncodingMap* entry, LIR* lir) {
- UNIMPLEMENTED(WARNING) << "encoding for: " << entry->name;
+ UNIMPLEMENTED(WARNING) << "encoding kind for " << entry->name << " " << buildInsnString(entry->fmt, lir, 0);
for (int i = 0; i < oatGetInsnSize(lir); ++i) {
cUnit->codeBuffer.push_back(0xCC); // push breakpoint instruction - int 3
}
@@ -1239,6 +1296,9 @@
case kRegReg: // lir operands - 0: reg1, 1: reg2
emitRegReg(cUnit, entry, lir->operands[0], lir->operands[1]);
break;
+ case kRegRegImm:
+ emitRegRegImm(cUnit, entry, lir->operands[0], lir->operands[1], lir->operands[2]);
+ break;
case kRegImm: // lir operands - 0: reg, 1: immediate
emitRegImm(cUnit, entry, lir->operands[0], lir->operands[1]);
break;
diff --git a/src/compiler/codegen/x86/FP/X86FP.cc b/src/compiler/codegen/x86/FP/X86FP.cc
index 29aaeeb..fe0d149 100644
--- a/src/compiler/codegen/x86/FP/X86FP.cc
+++ b/src/compiler/codegen/x86/FP/X86FP.cc
@@ -16,8 +16,8 @@
namespace art {
-bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
- RegLocation rlSrc1, RegLocation rlSrc2) {
+static bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
+ RegLocation rlSrc1, RegLocation rlSrc2) {
X86OpCode op = kX86Nop;
RegLocation rlResult;
@@ -149,7 +149,7 @@
// These are easy to implement inline except when the src is > MAX_INT/LONG the result
// needs to be changed from 0x80000000 to 0x7FFFFFF (requires an in memory float/double
// literal constant to compare against).
- UNIMPLEMENTED(WARNING) << "inline [df]2i";
+ UNIMPLEMENTED(WARNING) << "inline [df]2i " << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
case Instruction::LONG_TO_DOUBLE:
case Instruction::FLOAT_TO_LONG:
case Instruction::LONG_TO_FLOAT:
diff --git a/src/compiler/codegen/x86/X86/Gen.cc b/src/compiler/codegen/x86/X86/Gen.cc
index f2dbc11..ffc5952 100644
--- a/src/compiler/codegen/x86/X86/Gen.cc
+++ b/src/compiler/codegen/x86/X86/Gen.cc
@@ -168,7 +168,7 @@
void genNegFloat(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc)
{
- UNIMPLEMENTED(WARNING) << "genNegFloat";
+ UNIMPLEMENTED(WARNING) << "genNegFloat " << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
newLIR0(cUnit, kX86Bkpt);
#if 0
RegLocation rlResult;
@@ -182,7 +182,7 @@
void genNegDouble(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc)
{
- UNIMPLEMENTED(WARNING) << "genNegDouble";
+ UNIMPLEMENTED(WARNING) << "genNegDouble" << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
newLIR0(cUnit, kX86Bkpt);
#if 0
RegLocation rlResult;
diff --git a/src/disassembler_x86.cc b/src/disassembler_x86.cc
index eb52d5a..d2c860b 100644
--- a/src/disassembler_x86.cc
+++ b/src/disassembler_x86.cc
@@ -383,13 +383,14 @@
reg_in_opcode = true;
break;
case 0xC0: case 0xC1:
+ case 0xD0: case 0xD1:
static const char* shift_opcodes[] =
{"rol", "ror", "rcl", "rcr", "shl", "shr", "unknown-shift", "sar"};
modrm_opcodes = shift_opcodes;
has_modrm = true;
reg_is_opcode = true;
store = true;
- immediate_bytes = 1;
+ immediate_bytes = ((*instr & 0xf0) == 0xc0) ? 1 : 0;
byte_operand = *instr == 0xC0;
break;
case 0xC3: opcode << "ret"; break;
diff --git a/src/oat/runtime/arm/runtime_support_arm.S b/src/oat/runtime/arm/runtime_support_arm.S
index e1323d6..2ef162e 100644
--- a/src/oat/runtime/arm/runtime_support_arm.S
+++ b/src/oat/runtime/arm/runtime_support_arm.S
@@ -369,7 +369,7 @@
SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
mov r2, r9 @ pass Thread::Current
mov r3, sp @ pass SP
- @ artInitializeTypeFromCode(uint32_t type_idx, Method* referrer, Thread*, SP)
+ @ artInitializeTypeAndVerifyAccessFromCode(uint32_t type_idx, Method* referrer, Thread*, SP)
bl artInitializeTypeAndVerifyAccessFromCode
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r0, #0 @ success if result is non-null
diff --git a/src/oat/runtime/support_math.cc b/src/oat/runtime/support_math.cc
index 7c6e0b1..cbffc2b 100644
--- a/src/oat/runtime/support_math.cc
+++ b/src/oat/runtime/support_math.cc
@@ -62,6 +62,10 @@
return -1;
}
+int64_t Lmul(int64_t a, int64_t b) {
+ return a * b;
+}
+
extern "C" int64_t artLdivFromCode(int64_t a, int64_t b) {
return a / b;
}
diff --git a/src/oat/runtime/x86/oat_support_entrypoints_x86.cc b/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
index 6720e3e..7ded2d1 100644
--- a/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
+++ b/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
@@ -71,6 +71,7 @@
extern int32_t CmplDouble(double a, double b);
extern int32_t CmpgFloat(float a, float b);
extern int32_t CmplFloat(float a, float b);
+extern int64_t Lmul(int64_t a, int64_t b);
extern "C" int32_t art_idiv_from_code(int32_t, int32_t);
extern "C" int32_t art_idivmod_from_code(int32_t, int32_t);
extern "C" int64_t art_ldiv_from_code(int64_t, int64_t);
@@ -163,31 +164,31 @@
points->pCmpgFloat = CmpgFloat;
points->pCmplDouble = CmplDouble;
points->pCmplFloat = CmplFloat;
- //points->pDadd = NULL;
- //points->pDdiv = NULL;
- //points->pDmul = NULL;
- //points->pDsub = NULL;
+ //points->pDadd = NULL; // Not needed on x86.
+ //points->pDdiv = NULL; // Not needed on x86.
+ //points->pDmul = NULL; // Not needed on x86.
+ //points->pDsub = NULL; // Not needed on x86.
//points->pF2d = NULL;
//points->pFmod = NULL;
//points->pI2d = NULL;
//points->pL2d = NULL;
//points->pD2f = NULL;
- //points->pFadd = NULL;
- //points->pFdiv = NULL;
+ //points->pFadd = NULL; // Not needed on x86.
+ //points->pFdiv = NULL; // Not needed on x86.
//points->pFmodf = NULL;
- //points->pFmul = NULL;
- //points->pFsub = NULL;
+ //points->pFmul = NULL; // Not needed on x86.
+ //points->pFsub = NULL; // Not needed on x86.
//points->pI2f = NULL;
//points->pL2f = NULL;
- //points->pD2iz = NULL;
- //points->pF2iz = NULL;
+ points->pD2iz = D2I;
+ points->pF2iz = F2I;
points->pIdiv = art_idiv_from_code;
points->pIdivmod = art_idivmod_from_code;
points->pD2l = D2L;
points->pF2l = F2L;
points->pLdiv = art_ldiv_from_code;
points->pLdivmod = art_ldivmod_from_code;
- //points->pLmul = NULL;
+ points->pLmul = Lmul;
points->pShlLong = art_lshl_from_code;
points->pShrLong = art_lshr_from_code;
points->pUshrLong = art_lushr_from_code;