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