MIPS switch table support

And 64-bit neg/add/sub (ouch! Mips has no carry bit...)

Change-Id: Ifb94324a0052d6069977fb8f22679b95890445d8
diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc
index b47fae1..8a23d5c 100644
--- a/src/compiler/codegen/arm/ArchFactory.cc
+++ b/src/compiler/codegen/arm/ArchFactory.cc
@@ -26,6 +26,32 @@
 
 void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset);
 
+bool genNegLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                RegLocation rlSrc)
+{
+    rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
+    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+    int zReg = oatAllocTemp(cUnit);
+    loadConstantNoClobber(cUnit, zReg, 0);
+    // Check for destructive overlap
+    if (rlResult.lowReg == rlSrc.highReg) {
+        int tReg = oatAllocTemp(cUnit);
+        opRegRegReg(cUnit, kOpSub, rlResult.lowReg,
+                    zReg, rlSrc.lowReg);
+        opRegRegReg(cUnit, kOpSbc, rlResult.highReg,
+                    zReg, tReg);
+        oatFreeTemp(cUnit, tReg);
+    } else {
+        opRegRegReg(cUnit, kOpSub, rlResult.lowReg,
+                    zReg, rlSrc.lowReg);
+        opRegRegReg(cUnit, kOpSbc, rlResult.highReg,
+                    zReg, rlSrc.highReg);
+    }
+    oatFreeTemp(cUnit, zReg);
+    storeValueWide(cUnit, rlDest, rlResult);
+    return false;
+}
+
 int loadHelper(CompilationUnit* cUnit, int offset)
 {
     loadWordDisp(cUnit, rSELF, offset, rLR);