diff options
Diffstat (limited to 'src/compiler/codegen')
| -rw-r--r-- | src/compiler/codegen/CodegenFactory.cc | 9 | ||||
| -rw-r--r-- | src/compiler/codegen/GenCommon.cc | 50 | ||||
| -rw-r--r-- | src/compiler/codegen/MethodCodegenDriver.cc | 16 | ||||
| -rw-r--r-- | src/compiler/codegen/x86/ArchFactory.cc | 36 | ||||
| -rw-r--r-- | src/compiler/codegen/x86/Assemble.cc | 30 | ||||
| -rw-r--r-- | src/compiler/codegen/x86/FP/X86FP.cc | 4 | ||||
| -rw-r--r-- | src/compiler/codegen/x86/X86/Factory.cc | 72 | ||||
| -rw-r--r-- | src/compiler/codegen/x86/X86LIR.h | 1 | ||||
| -rw-r--r-- | src/compiler/codegen/x86/x86/ArchVariant.cc | 8 |
9 files changed, 91 insertions, 135 deletions
diff --git a/src/compiler/codegen/CodegenFactory.cc b/src/compiler/codegen/CodegenFactory.cc index e1df1a5b45..1b64af2b37 100644 --- a/src/compiler/codegen/CodegenFactory.cc +++ b/src/compiler/codegen/CodegenFactory.cc @@ -273,14 +273,16 @@ void storeValueWide(CompilationUnit* cUnit, RegLocation rlDest, */ void markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg) { -#if defined(TARGET_X86) - UNIMPLEMENTED(WARNING) << "markGCCard"; -#else int regCardBase = oatAllocTemp(cUnit); int regCardNo = oatAllocTemp(cUnit); LIR* branchOver = opCmpImmBranch(cUnit, kCondEq, valReg, 0, NULL); +#if !defined(TARGET_X86) loadWordDisp(cUnit, rSELF, Thread::CardTableOffset().Int32Value(), regCardBase); +#else + newLIR2(cUnit, kX86Mov32RT, regCardBase, + Thread::CardTableOffset().Int32Value()); +#endif opRegRegImm(cUnit, kOpLsr, regCardNo, tgtAddrReg, GC_CARD_SHIFT); storeBaseIndexed(cUnit, regCardBase, regCardNo, regCardBase, 0, kUnsignedByte); @@ -288,7 +290,6 @@ void markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg) branchOver->target = (LIR*)target; oatFreeTemp(cUnit, regCardBase); oatFreeTemp(cUnit, regCardNo); -#endif } /* Utilities to load the current Method* */ diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc index f63ad4c3ca..b45fbaa685 100644 --- a/src/compiler/codegen/GenCommon.cc +++ b/src/compiler/codegen/GenCommon.cc @@ -637,6 +637,9 @@ void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc, rBase = oatAllocTemp(cUnit); loadWordDisp(cUnit, rlMethod.lowReg, Method::DeclaringClassOffset().Int32Value(), rBase); + if (oatIsTemp(cUnit, rlMethod.lowReg)) { + oatFreeTemp(cUnit, rlMethod.lowReg); + } } else { // Medium path, static storage base in a different class which // requires checks that the other class is initialized. @@ -1412,6 +1415,9 @@ void genArrayObjPut(CompilationUnit* cUnit, MIR* mir, RegLocation rlArray, storeBaseIndexedDisp(cUnit, NULL, rlArray.lowReg, rlIndex.lowReg, scale, dataOffset, rlSrc.lowReg, INVALID_REG, kWord, INVALID_SREG); + if (oatIsTemp(cUnit, rlIndex.lowReg)) { + oatFreeTemp(cUnit, rlIndex.lowReg); + } #else int regPtr; if (oatIsTemp(cUnit, rlArray.lowReg)) { @@ -1582,7 +1588,11 @@ void genArrayPut(CompilationUnit* cUnit, MIR* mir, OpSize size, genRegMemCheck(cUnit, kCondUge, rlIndex.lowReg, rlArray.lowReg, lenOffset, mir, kThrowArrayBounds); } - rlSrc = loadValue(cUnit, rlSrc, regClass); + if ((size == kLong) || (size == kDouble)) { + rlSrc = loadValueWide(cUnit, rlSrc, regClass); + } else { + rlSrc = loadValue(cUnit, rlSrc, regClass); + } storeBaseIndexedDisp(cUnit, NULL, rlArray.lowReg, rlIndex.lowReg, scale, dataOffset, rlSrc.lowReg, rlSrc.highReg, size, INVALID_SREG); #else @@ -2136,6 +2146,10 @@ bool genArithOpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, case Instruction::ADD_LONG_2ADDR: #if defined(TARGET_MIPS) return genAddLong(cUnit, mir, rlDest, rlSrc1, rlSrc2); +#elif defined(TARGET_X86) + callOut = true; + retReg = rRET0; + funcOffset = OFFSETOF_MEMBER(Thread, pLadd); #else firstOp = kOpAdd; secondOp = kOpAdc; @@ -2145,11 +2159,14 @@ bool genArithOpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, case Instruction::SUB_LONG_2ADDR: #if defined(TARGET_MIPS) return genSubLong(cUnit, mir, rlDest, rlSrc1, rlSrc2); -#else +#elif defined(TARGET_X86) + callOut = true; + retReg = rRET0; + funcOffset = OFFSETOF_MEMBER(Thread, pLsub); +#endif firstOp = kOpSub; secondOp = kOpSbc; break; -#endif case Instruction::MUL_LONG: case Instruction::MUL_LONG_2ADDR: callOut = true; @@ -2174,16 +2191,31 @@ bool genArithOpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, break; case Instruction::AND_LONG_2ADDR: case Instruction::AND_LONG: +#if defined(TARGET_X86) + callOut = true; + retReg = rRET0; + funcOffset = OFFSETOF_MEMBER(Thread, pLand); +#endif firstOp = kOpAnd; secondOp = kOpAnd; break; case Instruction::OR_LONG: case Instruction::OR_LONG_2ADDR: +#if defined(TARGET_X86) + callOut = true; + retReg = rRET0; + funcOffset = OFFSETOF_MEMBER(Thread, pLor); +#endif firstOp = kOpOr; secondOp = kOpOr; break; case Instruction::XOR_LONG: case Instruction::XOR_LONG_2ADDR: +#if defined(TARGET_X86) + callOut = true; + retReg = rRET0; + funcOffset = OFFSETOF_MEMBER(Thread, pLxor); +#endif firstOp = kOpXor; secondOp = kOpXor; break; @@ -2198,30 +2230,26 @@ bool genArithOpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, } else { oatFlushAllRegs(cUnit); /* Send everything to home location */ if (checkZero) { -#if defined(TARGET_X86) - UNIMPLEMENTED(FATAL); -#else loadValueDirectWideFixed(cUnit, rlSrc2, rARG2, rARG3); +#if !defined(TARGET_X86) int rTgt = loadHelper(cUnit, funcOffset); #endif - loadValueDirectWideFixed(cUnit, rlSrc1, rARG0, rARG1); int tReg = oatAllocTemp(cUnit); #if defined(TARGET_ARM) newLIR4(cUnit, kThumb2OrrRRRs, tReg, rARG2, rARG3, 0); oatFreeTemp(cUnit, tReg); genCheck(cUnit, kCondEq, mir, kThrowDivZero); #else -#if defined(TARGET_X86) - UNIMPLEMENTED(FATAL); -#else opRegRegReg(cUnit, kOpOr, tReg, rARG2, rARG3); #endif genImmedCheck(cUnit, kCondEq, tReg, 0, mir, kThrowDivZero); oatFreeTemp(cUnit, tReg); -#endif + loadValueDirectWideFixed(cUnit, rlSrc1, rARG0, rARG1); #if !defined(TARGET_X86) opReg(cUnit, kOpBlx, rTgt); oatFreeTemp(cUnit, rTgt); +#else + opThreadMem(cUnit, kOpBlx, funcOffset); #endif } else { callRuntimeHelperRegLocationRegLocation(cUnit, funcOffset, diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc index 671eb7344c..205a65ad2c 100644 --- a/src/compiler/codegen/MethodCodegenDriver.cc +++ b/src/compiler/codegen/MethodCodegenDriver.cc @@ -186,22 +186,22 @@ bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir, case Instruction::NOP: break; - case Instruction::MOVE_EXCEPTION: + case Instruction::MOVE_EXCEPTION: { + int exOffset = Thread::ExceptionOffset().Int32Value(); + rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); #if defined(TARGET_X86) - UNIMPLEMENTED(WARNING) << "Instruction::MOVE_EXCEPTION"; + newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset); + newLIR2(cUnit, kX86Mov32TI, exOffset, 0); #else - int exOffset; - int resetReg; - exOffset = Thread::ExceptionOffset().Int32Value(); - resetReg = oatAllocTemp(cUnit); - rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); + int resetReg = oatAllocTemp(cUnit); loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg); loadConstant(cUnit, resetReg, 0); storeWordDisp(cUnit, rSELF, exOffset, resetReg); storeValue(cUnit, rlDest, rlResult); + oatFreeTemp(cUnit, resetReg); #endif break; - + } case Instruction::RETURN_VOID: if (!cUnit->attrs & METHOD_IS_LEAF) { genSuspendTest(cUnit, mir); diff --git a/src/compiler/codegen/x86/ArchFactory.cc b/src/compiler/codegen/x86/ArchFactory.cc index eec1cbd375..bd95afbf76 100644 --- a/src/compiler/codegen/x86/ArchFactory.cc +++ b/src/compiler/codegen/x86/ArchFactory.cc @@ -24,42 +24,6 @@ namespace art { -bool genAddLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2) -{ - rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg); - rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg); - RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); - /* - * [v1 v0] = [a1 a0] + [a3 a2]; - * add v0,a2,a0 - * adc v1,a3,a1 - */ - - opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc2.lowReg, rlSrc1.lowReg); - opRegRegReg(cUnit, kOpAdc, rlResult.highReg, rlSrc2.highReg, rlSrc1.highReg); - storeValueWide(cUnit, rlDest, rlResult); - return false; -} - -bool genSubLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2) -{ - rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg); - rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg); - RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); - /* - * [v1 v0] = [a1 a0] - [a3 a2]; - * sub v0,a0,a2 - * sbb v1,a1,a3 - */ - - opRegRegReg(cUnit, kOpSub, rlResult.lowReg, rlSrc1.lowReg, rlSrc2.lowReg); - opRegRegReg(cUnit, kOpSbc, rlResult.highReg, rlSrc1.highReg, rlSrc2.highReg); - storeValueWide(cUnit, rlDest, rlResult); - return false; -} - bool genNegLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, RegLocation rlSrc) { diff --git a/src/compiler/codegen/x86/Assemble.cc b/src/compiler/codegen/x86/Assemble.cc index b9dd9787ab..b62b5b4d53 100644 --- a/src/compiler/codegen/x86/Assemble.cc +++ b/src/compiler/codegen/x86/Assemble.cc @@ -279,6 +279,10 @@ ENCODING_MAP(Cmp, IS_LOAD, { kX86Set8M, kMemCond, IS_STORE | IS_TERTIARY_OP, { 0, 0, 0x0F, 0x90, 0, 0, 0, 0 }, "Set8M", "!2c [!0r+!1d]" }, { kX86Set8A, kArrayCond, IS_STORE | IS_QUIN_OP, { 0, 0, 0x0F, 0x90, 0, 0, 0, 0 }, "Set8A", "!4c [!0r+!1r<<!2d+!3d]" }, + // TODO: load/store? + // Encode the modrm opcode as an extra opcode byte to avoid computation during assembly. + { kX86Mfence, kReg, NO_OPERAND, { 0, 0, 0x0F, 0xAE, 0, 6, 0, 0 }, "Mfence", "" }, + EXT_0F_ENCODING_MAP(Imul16, 0x66, 0xAF), EXT_0F_ENCODING_MAP(Imul32, 0x00, 0xAF), EXT_0F_ENCODING_MAP(Movzx8, 0x00, 0xB6), @@ -945,12 +949,12 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, intptr_t startAd LIR *lir; AssemblerStatus res = kSuccess; // Assume success + const bool kVerbosePcFixup = false; for (lir = (LIR *) cUnit->firstLIRInsn; lir; lir = NEXT_LIR(lir)) { if (lir->opcode < 0) { continue; } - if (lir->flags.isNop) { continue; } @@ -970,8 +974,10 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, intptr_t startAd intptr_t target = targetLIR->offset; delta = target - pc; if (IS_SIMM8(delta) != IS_SIMM8(lir->operands[0])) { - LOG(INFO) << "Retry for JCC growth at " << lir->offset - << " delta: " << delta << " old delta: " << lir->operands[0]; + if (kVerbosePcFixup) { + LOG(INFO) << "Retry for JCC growth at " << lir->offset + << " delta: " << delta << " old delta: " << lir->operands[0]; + } lir->opcode = kX86Jcc32; oatSetupResourceMasks(lir); res = kRetryAll; @@ -994,10 +1000,14 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, intptr_t startAd if (!(cUnit->disableOpt & (1 << kSafeOptimizations)) && lir->operands[0] == 0) { // Useless branch lir->flags.isNop = true; - LOG(INFO) << "Retry for useless branch at " << lir->offset; + if (kVerbosePcFixup) { + LOG(INFO) << "Retry for useless branch at " << lir->offset; + } res = kRetryAll; } else if (IS_SIMM8(delta) != IS_SIMM8(lir->operands[0])) { - LOG(INFO) << "Retry for JMP growth at " << lir->offset; + if (kVerbosePcFixup) { + LOG(INFO) << "Retry for JMP growth at " << lir->offset; + } lir->opcode = kX86Jmp32; oatSetupResourceMasks(lir); res = kRetryAll; @@ -1028,8 +1038,14 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, intptr_t startAd DCHECK_EQ(0, entry->skeleton.prefix1); DCHECK_EQ(0, entry->skeleton.prefix2); cUnit->codeBuffer.push_back(entry->skeleton.opcode); - DCHECK_EQ(0, entry->skeleton.extra_opcode1); - DCHECK_EQ(0, entry->skeleton.extra_opcode2); + if (entry->skeleton.extra_opcode1 != 0) { + cUnit->codeBuffer.push_back(entry->skeleton.extra_opcode1); + if (entry->skeleton.extra_opcode2 != 0) { + cUnit->codeBuffer.push_back(entry->skeleton.extra_opcode2); + } + } else { + DCHECK_EQ(0, entry->skeleton.extra_opcode2); + } DCHECK_EQ(0, entry->skeleton.modrm_opcode); DCHECK_EQ(0, entry->skeleton.ax_opcode); DCHECK_EQ(0, entry->skeleton.immediate_bytes); diff --git a/src/compiler/codegen/x86/FP/X86FP.cc b/src/compiler/codegen/x86/FP/X86FP.cc index c91664055c..29aaeeb372 100644 --- a/src/compiler/codegen/x86/FP/X86FP.cc +++ b/src/compiler/codegen/x86/FP/X86FP.cc @@ -204,8 +204,8 @@ static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest, srcReg2 = S2D(rlSrc2.lowReg, rlSrc2.highReg); } rlDest = oatGetDest(cUnit, mir, 0); - RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); - opRegImm(cUnit, kOpMov, rlResult.lowReg, unorderedGt ? 1 : 0); + RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); + loadConstantNoClobber(cUnit, rlResult.lowReg, unorderedGt ? 1 : 0); if (single) { newLIR2(cUnit, kX86UcomissRR, srcReg1, srcReg2); } else { diff --git a/src/compiler/codegen/x86/X86/Factory.cc b/src/compiler/codegen/x86/X86/Factory.cc index aef5879cc4..4987c2856c 100644 --- a/src/compiler/codegen/x86/X86/Factory.cc +++ b/src/compiler/codegen/x86/X86/Factory.cc @@ -147,6 +147,7 @@ LIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc) { LIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1, int value) { X86OpCode opcode = kX86Bkpt; bool byteImm = IS_SIMM8(value); + DCHECK(!FPREG(rDestSrc1)); switch (op) { case kOpLsl: opcode = kX86Sal32RI; break; case kOpLsr: opcode = kX86Shr32RI; break; @@ -159,15 +160,7 @@ LIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1, int value) { case kOpSub: opcode = byteImm ? kX86Sub32RI8 : kX86Sub32RI; break; case kOpXor: opcode = byteImm ? kX86Xor32RI8 : kX86Xor32RI; break; case kOpCmp: opcode = byteImm ? kX86Cmp32RI8 : kX86Cmp32RI; break; - case kOpMov: { - if (value == 0) { // turn "mov reg, 0" into "xor reg, reg" - opcode = kX86Xor32RR; - value = rDestSrc1; - } else { - opcode = kX86Mov32RI; - } - break; - } + case kOpMov: return loadConstantNoClobber(cUnit, rDestSrc1, value); case kOpMul: opcode = byteImm ? kX86Imul32RRI8 : kX86Imul32RRI; return newLIR3(cUnit, opcode, rDestSrc1, rDestSrc1, value); @@ -410,59 +403,6 @@ LIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase, #endif } -/* store value base base + scaled index. */ -LIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase, - int rIndex, int rSrc, int scale, OpSize size) -{ - UNIMPLEMENTED(WARNING) << "storeBaseIndexed"; - return NULL; -#if 0 - LIR *first = NULL; - LIR *res; - X86OpCode opcode = kX86Nop; - int rNewIndex = rIndex; - int tReg = oatAllocTemp(cUnit); - - if (FPREG(rSrc)) { - DCHECK(SINGLEREG(rSrc)); - DCHECK((size == kWord) || (size == kSingle)); - size = kSingle; - } else { - if (size == kSingle) - size = kWord; - } - - if (!scale) { - first = newLIR3(cUnit, kX86Addu, tReg , rBase, rIndex); - } else { - first = opRegRegImm(cUnit, kOpLsl, tReg, rIndex, scale); - newLIR3(cUnit, kX86Addu, tReg , rBase, tReg); - } - - switch (size) { - case kSingle: - opcode = kX86Fswc1; - break; - case kWord: - opcode = kX86Sw; - break; - case kUnsignedHalf: - case kSignedHalf: - opcode = kX86Sh; - break; - case kUnsignedByte: - case kSignedByte: - opcode = kX86Sb; - break; - default: - LOG(FATAL) << "Bad case in storeBaseIndexed"; - } - res = newLIR3(cUnit, opcode, rSrc, 0, tReg); - oatFreeTemp(cUnit, rNewIndex); - return first; -#endif -} - LIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask) { UNIMPLEMENTED(WARNING) << "loadMultiple"; @@ -686,6 +626,14 @@ LIR* storeBaseIndexedDisp(CompilationUnit *cUnit, MIR *mir, return store; } +/* store value base base + scaled index. */ +LIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase, int rIndex, int rSrc, int scale, + OpSize size) +{ + return storeBaseIndexedDisp(cUnit, NULL, rBase, rIndex, scale, 0, + rSrc, INVALID_REG, size, INVALID_SREG); +} + LIR *storeBaseDisp(CompilationUnit *cUnit, int rBase, int displacement, int rSrc, OpSize size) { return storeBaseIndexedDisp(cUnit, NULL, rBase, INVALID_REG, 0, displacement, rSrc, INVALID_REG, size, INVALID_SREG); diff --git a/src/compiler/codegen/x86/X86LIR.h b/src/compiler/codegen/x86/X86LIR.h index 9b9fc6ba5f..378c24de68 100644 --- a/src/compiler/codegen/x86/X86LIR.h +++ b/src/compiler/codegen/x86/X86LIR.h @@ -436,6 +436,7 @@ enum X86OpCode { Binary0fOpCode(kX86Movdxr), // move into xmm from gpr Binary0fOpCode(kX86Movdrx), // move into reg from xmm kX86Set8R, kX86Set8M, kX86Set8A,// set byte depending on condition operand + kX86Mfence, // memory barrier Binary0fOpCode(kX86Imul16), // 16bit multiply Binary0fOpCode(kX86Imul32), // 32bit multiply Binary0fOpCode(kX86Movzx8), // zero-extend 8-bit value diff --git a/src/compiler/codegen/x86/x86/ArchVariant.cc b/src/compiler/codegen/x86/x86/ArchVariant.cc index 944311c3e3..2bb84d7137 100644 --- a/src/compiler/codegen/x86/x86/ArchVariant.cc +++ b/src/compiler/codegen/x86/x86/ArchVariant.cc @@ -49,13 +49,11 @@ int dvmCompilerTargetOptHint(int key) return res; } -void oatGenMemBarrier(CompilationUnit *cUnit, int barrierKind) +void oatGenMemBarrier(CompilationUnit *cUnit, int /* barrierKind */) { #if ANDROID_SMP != 0 - UNIMPLEMENTED(WARNING) << "oatGenMemBarrier"; -#if 0 - newLIR1(cUnit, kX86Sync, barrierKind); -#endif + // TODO: optimize fences + newLIR0(cUnit, kX86Mfence); #endif } |