Patches to x86 compilation to fix vm tests on emulator.
not-int and not-long were unimplemented previously.
cmp-long would return the wrong value with Long.MIN_VALUE.
rem-double and rem-float now use a c helper. This is because fprem may
not fully compute the result on the first invocation and would need to
be looped to completion.
Change-Id: Idf5f6349a63b19d395a3d89434b5b35c430ae3d3
diff --git a/src/compiler/codegen/x86/X86/Factory.cc b/src/compiler/codegen/x86/X86/Factory.cc
index c5186c6..8b02aed 100644
--- a/src/compiler/codegen/x86/X86/Factory.cc
+++ b/src/compiler/codegen/x86/X86/Factory.cc
@@ -138,6 +138,7 @@
X86OpCode opcode = kX86Bkpt;
switch (op) {
case kOpNeg: opcode = kX86Neg32R; break;
+ case kOpNot: opcode = kX86Not32R; break;
case kOpBlx: opcode = kX86CallR; break;
default:
LOG(FATAL) << "Bad case in opReg " << op;
diff --git a/src/compiler/codegen/x86/X86/Gen.cc b/src/compiler/codegen/x86/X86/Gen.cc
index 597eda1..f5466ee 100644
--- a/src/compiler/codegen/x86/X86/Gen.cc
+++ b/src/compiler/codegen/x86/X86/Gen.cc
@@ -262,11 +262,13 @@
// Compute (r1:r0) = (r1:r0) - (r3:r2)
opRegReg(cUnit, kOpSub, r0, r2); // r0 = r0 - r2
opRegReg(cUnit, kOpSbc, r1, r3); // r1 = r1 - r3 - CF
+ newLIR2(cUnit, kX86Set8R, r2, kX86CondL); // r2 = (r1:r0) < (r3:r2) ? 1 : 0
+ newLIR2(cUnit, kX86Movzx8RR, r2, r2);
+ opReg(cUnit, kOpNeg, r2); // r2 = -r2
opRegReg(cUnit, kOpOr, r0, r1); // r0 = high | low - sets ZF
newLIR2(cUnit, kX86Set8R, r0, kX86CondNz); // r0 = (r1:r0) != (r3:r2) ? 1 : 0
newLIR2(cUnit, kX86Movzx8RR, r0, r0);
- opRegImm(cUnit, kOpAsr, r1, 31); // r1 = high >> 31
- opRegReg(cUnit, kOpOr, r0, r1); // r0 holds result
+ opRegReg(cUnit, kOpOr, r0, r2); // r0 = r0 | r2
RegLocation rlResult = LOC_C_RETURN;
storeValue(cUnit, rlDest, rlResult);
}
diff --git a/src/oat/runtime/x86/runtime_support_x86.S b/src/oat/runtime/x86/runtime_support_x86.S
index 76590a4..37a023a 100644
--- a/src/oat/runtime/x86/runtime_support_x86.S
+++ b/src/oat/runtime/x86/runtime_support_x86.S
@@ -406,32 +406,32 @@
NO_ARG_DOWNCALL art_test_suspend, artTestSuspendFromCode, ret
DEFINE_FUNCTION art_fmod_from_code
- movl %ebx, -4(%esp) // put hi arg2 into memory
- movl %edx, -8(%esp) // put lo arg2 into memory
- fldl -8(%esp) // push arg2 onto fp stack
- movl %ecx, -4(%esp) // put hi arg1 into memory
- movl %eax, -8(%esp) // put lo arg1 into memory
- fldl -8(%esp) // push arg1 onto fp stack
- fprem1 // calculate IEEE remainder
- fstpl -8(%esp) // pop return value off fp stack
- movsd -8(%esp), %xmm0 // place into %xmm0
+ subl LITERAL(12), %esp // alignment padding
+ pushl %ebx // pass arg4 b.hi
+ pushl %edx // pass arg3 b.lo
+ pushl %ecx // pass arg2 a.hi
+ pushl %eax // pass arg1 a.lo
+ call SYMBOL(fmod) // (jdouble a, jdouble b)
+ fstpl (%esp) // pop return value off fp stack
+ movsd (%esp), %xmm0 // place into %xmm0
+ addl LITERAL(28), %esp // pop arguments
ret
DEFINE_FUNCTION art_fmodf_from_code
- movl %ecx, -4(%esp) // put arg2 into memory
- fld -4(%esp) // push arg2 onto fp stack
- movl %eax, -4(%esp) // put arg1 into memory
- fld -4(%esp) // push arg1 onto fp stack
- fprem1 // calculate IEEE remainder
- fstp -4(%esp) // pop return value off fp stack
- movss -4(%esp), %xmm0 // place into %xmm0
+ pushl %eax // alignment padding
+ pushl %ecx // pass arg2 b
+ pushl %eax // pass arg1 a
+ call SYMBOL(fmodf) // (jfloat a, jfloat b)
+ fstp (%esp) // pop return value off fp stack
+ movss (%esp), %xmm0 // place into %xmm0
+ addl LITERAL(12), %esp // pop arguments
ret
DEFINE_FUNCTION art_l2d_from_code
pushl %eax // alignment padding
- pushl %ecx // pass arg2
- pushl %eax // pass arg1
- call SYMBOL(art_l2d) // (jlong a, Thread*, SP)
+ pushl %ecx // pass arg2 a.hi
+ pushl %eax // pass arg1 a.lo
+ call SYMBOL(art_l2d) // (jlong a)
fstpl (%esp) // pop return value off fp stack
movsd (%esp), %xmm0 // place into %xmm0
addl LITERAL(12), %esp // pop arguments
@@ -439,9 +439,9 @@
DEFINE_FUNCTION art_l2f_from_code
pushl %eax // alignment padding
- pushl %ecx // pass arg2
- pushl %eax // pass arg1
- call SYMBOL(art_l2f) // (jlong a, Thread*, SP)
+ pushl %ecx // pass arg2 a.hi
+ pushl %eax // pass arg1 a.lo
+ call SYMBOL(art_l2f) // (jlong a)
fstp (%esp) // pop return value off fp stack
movss (%esp), %xmm0 // place into %xmm0
addl LITERAL(12), %esp // pop arguments
@@ -449,16 +449,16 @@
DEFINE_FUNCTION art_d2l_from_code
pushl %eax // alignment padding
- pushl %ecx // pass arg2
- pushl %eax // pass arg1
- call SYMBOL(art_d2l) // (jdouble a, Thread*, SP)
+ pushl %ecx // pass arg2 a.hi
+ pushl %eax // pass arg1 a.lo
+ call SYMBOL(art_d2l) // (jdouble a)
addl LITERAL(12), %esp // pop arguments
ret
DEFINE_FUNCTION art_f2l_from_code
subl LITERAL(8), %esp // alignment padding
- pushl %eax // pass arg1
- call SYMBOL(art_f2l) // (jfloat a, Thread*, SP)
+ pushl %eax // pass arg1 a
+ call SYMBOL(art_f2l) // (jfloat a)
addl LITERAL(12), %esp // pop arguments
ret
@@ -477,31 +477,31 @@
DEFINE_FUNCTION art_ldiv_from_code
subl LITERAL(12), %esp // alignment padding
- pushl %ebx // pass arg4
- pushl %edx // pass arg3
- pushl %ecx // pass arg2
- pushl %eax // pass arg1
- call SYMBOL(artLdivFromCode) // (jlong a, jlong b, Thread*, SP)
+ pushl %ebx // pass arg4 b.hi
+ pushl %edx // pass arg3 b.lo
+ pushl %ecx // pass arg2 a.hi
+ pushl %eax // pass arg1 a.lo
+ call SYMBOL(artLdivFromCode) // (jlong a, jlong b)
addl LITERAL(28), %esp // pop arguments
ret
DEFINE_FUNCTION art_ldivmod_from_code
subl LITERAL(12), %esp // alignment padding
- pushl %ebx // pass arg4
- pushl %edx // pass arg3
- pushl %ecx // pass arg2
- pushl %eax // pass arg1
- call SYMBOL(artLdivmodFromCode) // (jlong a, jlong b, Thread*, SP)
+ pushl %ebx // pass arg4 b.hi
+ pushl %edx // pass arg3 b.lo
+ pushl %ecx // pass arg2 a.hi
+ pushl %eax // pass arg1 a.lo
+ call SYMBOL(artLdivmodFromCode) // (jlong a, jlong b)
addl LITERAL(28), %esp // pop arguments
ret
DEFINE_FUNCTION art_lmul_from_code
subl LITERAL(12), %esp // alignment padding
- pushl %ebx // pass arg4
- pushl %edx // pass arg3
- pushl %ecx // pass arg2
- pushl %eax // pass arg1
- call SYMBOL(artLmulFromCode) // (jlong a, jlong b, Thread*, SP)
+ pushl %ebx // pass arg4 b.hi
+ pushl %edx // pass arg3 b.lo
+ pushl %ecx // pass arg2 a.hi
+ pushl %eax // pass arg1 a.lo
+ call SYMBOL(artLmulFromCode) // (jlong a, jlong b)
addl LITERAL(28), %esp // pop arguments
ret