Bug 1101356 mips part - MIPS Simulator: Support for calling functions that have three and four double parameters. r=rankov
--- 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.