Bug 1101356 mips part - MIPS Simulator: Support for calling functions that have three and four double parameters. r=rankov
authorJarda <bjdevel50@gmail.com>
Tue, 27 Jan 2015 18:58:17 +0100
changeset 239421 18bf5dc2cd4cbd53cb47785f6b1d8870054b7325
parent 239420 75fa71159fdc3fa6104cfc5a5f7653f7c368f274
child 239422 97692c7152d6c317d87aa14a619fbfdac1ee793a
push id497
push usermleibovic@mozilla.com
push dateWed, 28 Jan 2015 16:43:37 +0000
reviewersrankov
bugs1101356
milestone38.0a1
Bug 1101356 mips part - MIPS Simulator: Support for calling functions that have three and four double parameters. r=rankov
js/src/jit/mips/MacroAssembler-mips.cpp
js/src/jit/mips/Simulator-mips.cpp
js/src/jit/mips/Simulator-mips.h
--- a/js/src/jit/mips/MacroAssembler-mips.cpp
+++ b/js/src/jit/mips/MacroAssembler-mips.cpp
@@ -3467,16 +3467,18 @@ AssertValidABIFunctionType(uint32_t pass
       case Args_Int_Double:
       case Args_Float32_Float32:
       case Args_Double_Double:
       case Args_Double_Int:
       case Args_Double_DoubleInt:
       case Args_Double_DoubleDouble:
       case Args_Double_IntDouble:
       case Args_Int_IntDouble:
+      case Args_Double_DoubleDoubleDouble:
+      case Args_Double_DoubleDoubleDoubleDouble:
         break;
       default:
         MOZ_CRASH("Unexpected type");
     }
 }
 #endif
 
 void
--- a/js/src/jit/mips/Simulator-mips.cpp
+++ b/js/src/jit/mips/Simulator-mips.cpp
@@ -1546,16 +1546,24 @@ void
 Simulator::getFpArgs(double *x, double *y, int32_t *z)
 {
     *x = getFpuRegisterDouble(12);
     *y = getFpuRegisterDouble(14);
     *z = getRegister(a2);
 }
 
 void
+Simulator::getFpFromStack(int32_t *stack, double *x)
+{
+    MOZ_ASSERT(stack);
+    MOZ_ASSERT(x);
+    memcpy(x, stack, sizeof(double));
+}
+
+void
 Simulator::setCallResultDouble(double result)
 {
     setFpuRegisterDouble(f0, result);
 }
 
 void
 Simulator::setCallResultFloat(float result)
 {
@@ -1852,16 +1860,20 @@ typedef double (*Prototype_Double_Int)(i
 typedef int32_t (*Prototype_Int_Double)(double arg0);
 typedef float (*Prototype_Float32_Float32)(float arg0);
 
 typedef double (*Prototype_DoubleInt)(double arg0, int32_t arg1);
 typedef double (*Prototype_Double_IntDouble)(int32_t arg0, double arg1);
 typedef double (*Prototype_Double_DoubleDouble)(double arg0, double arg1);
 typedef int32_t (*Prototype_Int_IntDouble)(int32_t arg0, double arg1);
 
+typedef double (*Prototype_Double_DoubleDoubleDouble)(double arg0, double arg1, double arg2);
+typedef double (*Prototype_Double_DoubleDoubleDoubleDouble)(double arg0, double arg1,
+                                                            double arg2, double arg3);
+
 // Software interrupt instructions are used by the simulator to call into C++.
 void
 Simulator::softwareInterrupt(SimInstruction *instr)
 {
     int32_t func = instr->functionFieldRaw();
     uint32_t code = (func == ff_break) ? instr->bits(25, 6) : -1;
 
     // We first check if we met a call_rt_redirected.
@@ -2017,16 +2029,39 @@ Simulator::softwareInterrupt(SimInstruct
           case Args_Int_IntDouble: {
             int32_t ival = getRegister(a0);
             double dval0 = getDoubleFromRegisterPair(a2);
             Prototype_Int_IntDouble target = reinterpret_cast<Prototype_Int_IntDouble>(external);
             int32_t result = target(ival, dval0);
             setRegister(v0, result);
             break;
           }
+          case Args_Double_DoubleDoubleDouble: {
+            double dval0, dval1, dval2;
+            int32_t ival;
+            getFpArgs(&dval0, &dval1, &ival);
+            // the last argument is on stack
+            getFpFromStack(stack_pointer + 4, &dval2);
+            Prototype_Double_DoubleDoubleDouble target = reinterpret_cast<Prototype_Double_DoubleDoubleDouble>(external);
+            double dresult = target(dval0, dval1, dval2);
+            setCallResultDouble(dresult);
+            break;
+         }
+         case Args_Double_DoubleDoubleDoubleDouble: {
+            double dval0, dval1, dval2, dval3;
+            int32_t ival;
+            getFpArgs(&dval0, &dval1, &ival);
+            // the two last arguments are on stack
+            getFpFromStack(stack_pointer + 4, &dval2);
+            getFpFromStack(stack_pointer + 6, &dval3);
+            Prototype_Double_DoubleDoubleDoubleDouble target = reinterpret_cast<Prototype_Double_DoubleDoubleDoubleDouble>(external);
+            double dresult = target(dval0, dval1, dval2, dval3);
+            setCallResultDouble(dresult);
+            break;
+          }
           default:
             MOZ_CRASH("call");
         }
 
         setRegister(ra, saved_ra);
         set_pc(getRegister(ra));
 #endif
     } else if (func == ff_break && code <= kMaxStopCode) {
--- a/js/src/jit/mips/Simulator-mips.h
+++ b/js/src/jit/mips/Simulator-mips.h
@@ -292,16 +292,17 @@ class Simulator {
     };
     int16_t exceptions[kNumExceptions];
 
     // Exceptions.
     void signalExceptions();
 
     // Handle arguments and return value for runtime FP functions.
     void getFpArgs(double *x, double *y, int32_t *z);
+    void getFpFromStack(int32_t *stack, double *x);
 
     void setCallResultDouble(double result);
     void setCallResultFloat(float result);
     void setCallResult(int64_t res);
 
     void callInternal(uint8_t *entry);
 
     // Architecture state.