Mips portable floating point support

Fleshing out the portable floating point.

Change-Id: Ie7a6dcb168a4eb2a61a52e6d747da4118d54f3aa
diff --git a/src/compiler/codegen/mips/FP/MipsFP.cc b/src/compiler/codegen/mips/FP/MipsFP.cc
index 6a51f69..64061fe 100644
--- a/src/compiler/codegen/mips/FP/MipsFP.cc
+++ b/src/compiler/codegen/mips/FP/MipsFP.cc
@@ -61,8 +61,7 @@
 
     return false;
 #else
-    UNIMPLEMENTED(WARNING) << "Need Mips soft float implementation";
-    return false;
+    return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
 #endif
 }
 
@@ -112,8 +111,7 @@
     storeValueWide(cUnit, rlDest, rlResult);
     return false;
 #else
-    UNIMPLEMENTED(WARNING) << "Need Mips soft float implementation";
-    return false;
+    return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
 #endif
 }
 
@@ -181,49 +179,48 @@
     }
     return false;
 #else
-    UNIMPLEMENTED(WARNING) << "Need Mips soft float implementation";
-    return false;
+    return genConversionPortable(cUnit, mir);
 #endif
 }
 
 static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
                      RegLocation rlSrc1, RegLocation rlSrc2)
 {
-    UNIMPLEMENTED(WARNING) << "Need Mips implementation";
-    return false;
-#if 0
-    TemplateOpcode templateOpcode;
-    RegLocation rlResult = oatGetReturn(cUnit);
     bool wide = true;
+    int offset;
 
     switch(mir->dalvikInsn.opcode) {
         case OP_CMPL_FLOAT:
-            templateOpcode = TEMPLATE_CMPL_FLOAT_VFP;
+            offset = OFFSETOF_MEMBER(Thread, pCmplFloat);
             wide = false;
             break;
         case OP_CMPG_FLOAT:
-            templateOpcode = TEMPLATE_CMPG_FLOAT_VFP;
+            offset = OFFSETOF_MEMBER(Thread, pCmpgFloat);
             wide = false;
             break;
         case OP_CMPL_DOUBLE:
-            templateOpcode = TEMPLATE_CMPL_DOUBLE_VFP;
+            offset = OFFSETOF_MEMBER(Thread, pCmplDouble);
             break;
         case OP_CMPG_DOUBLE:
-            templateOpcode = TEMPLATE_CMPG_DOUBLE_VFP;
+            offset = OFFSETOF_MEMBER(Thread, pCmpgDouble);
             break;
         default:
             return true;
     }
-    loadValueAddress(cUnit, rlSrc1, r_A0);
-    oatClobber(cUnit, r_A0);
-    loadValueAddress(cUnit, rlSrc2, r_A1);
-    UNIMPLEMENTED(FATAL) << "Need callout to handler";
-#if 0
-    genDispatchToHandler(cUnit, templateOpcode);
-#endif
+    oatFlushAllRegs(cUnit);
+    oatLockCallTemps(cUnit);
+    if (wide) {
+        loadValueDirectWideFixed(cUnit, rlSrc1, rARG0, rARG1);
+        loadValueDirectWideFixed(cUnit, rlSrc2, rARG2, rARG3);
+    } else {
+        loadValueDirectFixed(cUnit, rlSrc1, rARG0);
+        loadValueDirectFixed(cUnit, rlSrc2, rARG1);
+    }
+    int rTgt = loadHelper(cUnit, offset);
+    opReg(cUnit, kOpBlx, rTgt);
+    RegLocation rlResult = oatGetReturn(cUnit);
     storeValue(cUnit, rlDest, rlResult);
     return false;
-#endif
 }
 
 } //  namespace art