Implement various missing parts of the X86 compiler

Change-Id: I76f08580600befe268328f8cf7102c6146460c5e
diff --git a/src/compiler/codegen/x86/ArchFactory.cc b/src/compiler/codegen/x86/ArchFactory.cc
index bd95afb..e668250 100644
--- a/src/compiler/codegen/x86/ArchFactory.cc
+++ b/src/compiler/codegen/x86/ArchFactory.cc
@@ -24,30 +24,94 @@
 
 namespace art {
 
+bool genAddLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+  loadValueDirectWideFixed(cUnit, rlSrc1, r2, r3);
+  // Compute (r1:r0) = (r1:r0) + (r2:r3)
+  opRegReg(cUnit, kOpAdd, r0, r2);  // r0 = r0 + r2
+  opRegReg(cUnit, kOpAdc, r1, r3);  // r1 = r1 + r3 + CF
+  RegLocation rlResult = {kLocPhysReg, 1, 0, 0,  0, 0, 1, r0, r1, INVALID_SREG};
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+bool genSubLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+  loadValueDirectWideFixed(cUnit, rlSrc1, r2, r3);
+  // Compute (r1:r0) = (r1:r0) + (r2:r3)
+  opRegReg(cUnit, kOpSub, r0, r2);  // r0 = r0 - r2
+  opRegReg(cUnit, kOpSbc, r1, r3);  // r1 = r1 - r3 - CF
+  RegLocation rlResult = {kLocPhysReg, 1, 0, 0,  0, 0, 1, r0, r1, INVALID_SREG};
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+bool genAndLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+  loadValueDirectWideFixed(cUnit, rlSrc1, r2, r3);
+  // Compute (r1:r0) = (r1:r0) + (r2:r3)
+  opRegReg(cUnit, kOpAnd, r0, r2);  // r0 = r0 - r2
+  opRegReg(cUnit, kOpAnd, r1, r3);  // r1 = r1 - r3 - CF
+  RegLocation rlResult = {kLocPhysReg, 1, 0, 0,  0, 0, 1, r0, r1, INVALID_SREG};
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+bool genOrLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+  loadValueDirectWideFixed(cUnit, rlSrc1, r2, r3);
+  // Compute (r1:r0) = (r1:r0) + (r2:r3)
+  opRegReg(cUnit, kOpOr, r0, r2);  // r0 = r0 - r2
+  opRegReg(cUnit, kOpOr, r1, r3);  // r1 = r1 - r3 - CF
+  RegLocation rlResult = {kLocPhysReg, 1, 0, 0,  0, 0, 1, r0, r1, INVALID_SREG};
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+bool genXorLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+  loadValueDirectWideFixed(cUnit, rlSrc1, r2, r3);
+  // Compute (r1:r0) = (r1:r0) + (r2:r3)
+  opRegReg(cUnit, kOpXor, r0, r2);  // r0 = r0 - r2
+  opRegReg(cUnit, kOpXor, r1, r3);  // r1 = r1 - r3 - CF
+  RegLocation rlResult = {kLocPhysReg, 1, 0, 0,  0, 0, 1, r0, r1, INVALID_SREG};
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
 bool genNegLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
                 RegLocation rlSrc)
 {
-    UNIMPLEMENTED(WARNING) << "genNegLong";
-#if 0
-    rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
-    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-    /*
-     *  [v1 v0] =  -[a1 a0]
-     *    negu    v0,a0
-     *    negu    v1,a1
-     *    sltu    t1,r_zero
-     *    subu    v1,v1,t1
-     */
-
-    opRegReg(cUnit, kOpNeg, rlResult.lowReg, rlSrc.lowReg);
-    opRegReg(cUnit, kOpNeg, rlResult.highReg, rlSrc.highReg);
-    int tReg = oatAllocTemp(cUnit);
-    newLIR3(cUnit, kX86Sltu, tReg, r_ZERO, rlResult.lowReg);
-    opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlResult.highReg, tReg);
-    oatFreeTemp(cUnit, tReg);
-    storeValueWide(cUnit, rlDest, rlResult);
-#endif
-    return false;
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc, r0, r1);
+  // Compute (r1:r0) = -(r1:r0)
+  opRegReg(cUnit, kOpNeg, r0, r0);  // r0 = -r0
+  opRegImm(cUnit, kOpAdc, r1, 0);   // r1 = r1 + CF
+  opRegReg(cUnit, kOpNeg, r1, r1);  // r1 = -r1
+  RegLocation rlResult = {kLocPhysReg, 1, 0, 0,  0, 0, 1, r0, r1, INVALID_SREG};
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
 }
 
 void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset);