summaryrefslogtreecommitdiff
path: root/src/compiler/codegen/GenInvoke.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/codegen/GenInvoke.cc')
-rw-r--r--src/compiler/codegen/GenInvoke.cc39
1 files changed, 35 insertions, 4 deletions
diff --git a/src/compiler/codegen/GenInvoke.cc b/src/compiler/codegen/GenInvoke.cc
index 9f1d58e304..f1653aa4b0 100644
--- a/src/compiler/codegen/GenInvoke.cc
+++ b/src/compiler/codegen/GenInvoke.cc
@@ -665,7 +665,7 @@ bool genInlinedCharAt(CompilationUnit* cUnit, CallInfo* info)
bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin)
{
-#if defined(TARGET_ARM)
+#if defined(TARGET_ARM) || defined(TARGET_X86)
RegLocation rlSrc1 = info->args[0];
RegLocation rlSrc2 = info->args[1];
rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
@@ -673,10 +673,19 @@ bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin)
RegLocation rlDest = inlineTarget(cUnit, info);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
+#if defined(TARGET_ARM)
opIT(cUnit, (isMin) ? kArmCondGt : kArmCondLt, "E");
opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc2.lowReg);
opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc1.lowReg);
genBarrier(cUnit);
+#elif defined(TARGET_X86)
+ LIR* branch = newLIR2(cUnit, kX86Jcc8, 0, isMin ? kX86CondG : kX86CondL);
+ opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc1.lowReg);
+ LIR* branch2 = newLIR1(cUnit, kX86Jmp8, 0);
+ branch->target = newLIR0(cUnit, kPseudoTargetLabel);
+ opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc2.lowReg);
+ branch2->target = newLIR0(cUnit, kPseudoTargetLabel);
+#endif
storeValue(cUnit, rlDest, rlResult);
return true;
#else
@@ -688,7 +697,7 @@ bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin)
bool genInlinedStringIsEmptyOrLength(CompilationUnit* cUnit, CallInfo* info,
bool isEmpty)
{
-#if defined(TARGET_ARM)
+#if defined(TARGET_ARM) || defined(TARGET_X86)
// dst = src.length();
RegLocation rlObj = info->args[0];
rlObj = loadValue(cUnit, rlObj, kCoreReg);
@@ -699,9 +708,14 @@ bool genInlinedStringIsEmptyOrLength(CompilationUnit* cUnit, CallInfo* info,
rlResult.lowReg);
if (isEmpty) {
// dst = (dst == 0);
+#if defined(TARGET_ARM)
int tReg = oatAllocTemp(cUnit);
opRegReg(cUnit, kOpNeg, tReg, rlResult.lowReg);
opRegRegReg(cUnit, kOpAdc, rlResult.lowReg, rlResult.lowReg, tReg);
+#elif defined(TARGET_X86)
+ opRegImm(cUnit, kOpSub, rlResult.lowReg, 1);
+ opRegImm(cUnit, kOpLsr, rlResult.lowReg, 31);
+#endif
}
storeValue(cUnit, rlDest, rlResult);
return true;
@@ -712,7 +726,7 @@ bool genInlinedStringIsEmptyOrLength(CompilationUnit* cUnit, CallInfo* info,
bool genInlinedAbsInt(CompilationUnit *cUnit, CallInfo* info)
{
-#if defined(TARGET_ARM)
+#if defined(TARGET_ARM) || defined(TARGET_X86)
RegLocation rlSrc = info->args[0];
rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
RegLocation rlDest = inlineTarget(cUnit, info);
@@ -745,6 +759,24 @@ bool genInlinedAbsLong(CompilationUnit *cUnit, CallInfo* info)
opRegReg(cUnit, kOpXor, rlResult.highReg, signReg);
storeValueWide(cUnit, rlDest, rlResult);
return true;
+#elif defined(TARGET_X86)
+ // Reuse source registers to avoid running out of temps
+ RegLocation rlSrc = info->args[0];
+ rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
+ RegLocation rlDest = inlineTargetWide(cUnit, info);
+ RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+ opRegCopyWide(cUnit, rlResult.lowReg, rlResult.highReg, rlSrc.lowReg, rlSrc.highReg);
+ oatFreeTemp(cUnit, rlSrc.lowReg);
+ oatFreeTemp(cUnit, rlSrc.highReg);
+ int signReg = oatAllocTemp(cUnit);
+ // abs(x) = y<=x>>31, (x+y)^y.
+ opRegRegImm(cUnit, kOpAsr, signReg, rlResult.highReg, 31);
+ opRegReg(cUnit, kOpAdd, rlResult.lowReg, signReg);
+ opRegReg(cUnit, kOpAdc, rlResult.highReg, signReg);
+ opRegReg(cUnit, kOpXor, rlResult.lowReg, signReg);
+ opRegReg(cUnit, kOpXor, rlResult.highReg, signReg);
+ storeValueWide(cUnit, rlDest, rlResult);
+ return true;
#else
return false;
#endif
@@ -782,7 +814,6 @@ bool genInlinedIndexOf(CompilationUnit* cUnit, CallInfo* info,
bool zeroBased)
{
#if defined(TARGET_ARM)
-
oatClobberCalleeSave(cUnit);
oatLockCallTemps(cUnit); // Using fixed registers
int regPtr = rARG0;