Bug 1068355 - OdinMonkey: tidy up function call codegen (r=dougc)

--HG--
extra : rebase_source : 3d3ac4179d92691e757b29b0d12b70725c93ab3f
This commit is contained in:
Luke Wagner 2014-09-16 20:32:04 -05:00
parent 81c8b5ae6d
commit 4da6521eab
13 changed files with 131 additions and 110 deletions

View File

@ -8890,70 +8890,6 @@ CodeGenerator::visitHasClass(LHasClass *ins)
return true; return true;
} }
bool
CodeGenerator::visitAsmJSCall(LAsmJSCall *ins)
{
MAsmJSCall *mir = ins->mir();
#if defined(JS_CODEGEN_ARM)
if (!UseHardFpABI() && mir->callee().which() == MAsmJSCall::Callee::Builtin) {
// The soft ABI passes floating point arguments in GPRs. Since basically
// nothing is set up to handle this, the values are placed in the
// corresponding VFP registers, then transferred to GPRs immediately
// before the call. The mapping is sN <-> rN, where double registers
// can be treated as their two component single registers.
for (unsigned i = 0, e = ins->numOperands(); i < e; i++) {
LAllocation *a = ins->getOperand(i);
if (a->isFloatReg()) {
FloatRegister fr = ToFloatRegister(a);
if (fr.isDouble()) {
uint32_t srcId = fr.singleOverlay().id();
masm.ma_vxfer(fr, Register::FromCode(srcId), Register::FromCode(srcId + 1));
} else {
uint32_t srcId = fr.id();
masm.ma_vxfer(fr, Register::FromCode(srcId));
}
}
}
}
#endif
if (mir->spIncrement())
masm.freeStack(mir->spIncrement());
JS_ASSERT((sizeof(AsmJSFrame) + masm.framePushed()) % AsmJSStackAlignment == 0);
#ifdef DEBUG
static_assert(AsmJSStackAlignment >= ABIStackAlignment,
"The asm.js stack alignment should subsume the ABI-required alignment");
static_assert(AsmJSStackAlignment % ABIStackAlignment == 0,
"The asm.js stack alignment should subsume the ABI-required alignment");
Label ok;
masm.branchTestPtr(Assembler::Zero, StackPointer, Imm32(AsmJSStackAlignment - 1), &ok);
masm.breakpoint();
masm.bind(&ok);
#endif
MAsmJSCall::Callee callee = mir->callee();
switch (callee.which()) {
case MAsmJSCall::Callee::Internal:
masm.call(mir->desc(), callee.internal());
break;
case MAsmJSCall::Callee::Dynamic:
masm.call(mir->desc(), ToRegister(ins->getOperand(mir->dynamicCalleeOperandIndex())));
break;
case MAsmJSCall::Callee::Builtin:
masm.call(AsmJSImmPtr(callee.builtin()));
break;
}
if (mir->spIncrement())
masm.reserveStack(mir->spIncrement());
postAsmJSCall(ins);
return true;
}
bool bool
CodeGenerator::visitAsmJSParameter(LAsmJSParameter *lir) CodeGenerator::visitAsmJSParameter(LAsmJSParameter *lir)
{ {

View File

@ -301,7 +301,6 @@ class CodeGenerator : public CodeGeneratorSpecific
bool visitIsObject(LIsObject *lir); bool visitIsObject(LIsObject *lir);
bool visitHaveSameClass(LHaveSameClass *lir); bool visitHaveSameClass(LHaveSameClass *lir);
bool visitHasClass(LHasClass *lir); bool visitHasClass(LHasClass *lir);
bool visitAsmJSCall(LAsmJSCall *lir);
bool visitAsmJSParameter(LAsmJSParameter *lir); bool visitAsmJSParameter(LAsmJSParameter *lir);
bool visitAsmJSReturn(LAsmJSReturn *ret); bool visitAsmJSReturn(LAsmJSReturn *ret);
bool visitAsmJSVoidReturn(LAsmJSVoidReturn *ret); bool visitAsmJSVoidReturn(LAsmJSVoidReturn *ret);

View File

@ -1775,6 +1775,52 @@ CodeGeneratorARM::visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStati
MOZ_CRASH("NYI"); MOZ_CRASH("NYI");
} }
bool
CodeGeneratorARM::visitAsmJSCall(LAsmJSCall *ins)
{
MAsmJSCall *mir = ins->mir();
if (UseHardFpABI() || mir->callee().which() != MAsmJSCall::Callee::Builtin) {
emitAsmJSCall(ins);
return true;
}
// The soft ABI passes floating point arguments in GPRs. Since basically
// nothing is set up to handle this, the values are placed in the
// corresponding VFP registers, then transferred to GPRs immediately
// before the call. The mapping is sN <-> rN, where double registers
// can be treated as their two component single registers.
for (unsigned i = 0, e = ins->numOperands(); i < e; i++) {
LAllocation *a = ins->getOperand(i);
if (a->isFloatReg()) {
FloatRegister fr = ToFloatRegister(a);
if (fr.isDouble()) {
uint32_t srcId = fr.singleOverlay().id();
masm.ma_vxfer(fr, Register::FromCode(srcId), Register::FromCode(srcId + 1));
} else {
uint32_t srcId = fr.id();
masm.ma_vxfer(fr, Register::FromCode(srcId));
}
}
}
emitAsmJSCall(ins);
switch (mir->type()) {
case MIRType_Double:
masm.ma_vxfer(r0, r1, d0);
break;
case MIRType_Float32:
masm.as_vxfer(r0, InvalidReg, VFPRegister(d0).singleOverlay(), Assembler::CoreToFloat);
break;
default:
break;
}
return true;
}
bool bool
CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins) CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
{ {

View File

@ -194,6 +194,7 @@ class CodeGeneratorARM : public CodeGeneratorShared
bool visitNegF(LNegF *lir); bool visitNegF(LNegF *lir);
bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins); bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins);
bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins); bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins);
bool visitAsmJSCall(LAsmJSCall *ins);
bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins); bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins);
bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins); bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins);
bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins); bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins);
@ -205,23 +206,8 @@ class CodeGeneratorARM : public CodeGeneratorShared
bool visitForkJoinGetSlice(LForkJoinGetSlice *ins); bool visitForkJoinGetSlice(LForkJoinGetSlice *ins);
bool generateInvalidateEpilogue(); bool generateInvalidateEpilogue();
protected:
void postAsmJSCall(LAsmJSCall *lir) {
if (!UseHardFpABI() && lir->mir()->callee().which() == MAsmJSCall::Callee::Builtin) {
switch (lir->mir()->type()) {
case MIRType_Double:
masm.ma_vxfer(r0, r1, d0);
break;
case MIRType_Float32:
masm.as_vxfer(r0, InvalidReg, VFPRegister(d0).singleOverlay(),
Assembler::CoreToFloat);
break;
default:
break;
}
}
}
protected:
bool visitEffectiveAddress(LEffectiveAddress *ins); bool visitEffectiveAddress(LEffectiveAddress *ins);
bool visitUDiv(LUDiv *ins); bool visitUDiv(LUDiv *ins);
bool visitUMod(LUMod *ins); bool visitUMod(LUMod *ins);

View File

@ -1889,6 +1889,12 @@ CodeGeneratorMIPS::visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStat
MOZ_CRASH("NYI"); MOZ_CRASH("NYI");
} }
bool
CodeGeneratorMIPS::visitAsmJSCall(LAsmJSCall *ins)
{
emitAsmJSCall(ins);
}
bool bool
CodeGeneratorMIPS::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins) CodeGeneratorMIPS::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
{ {

View File

@ -247,6 +247,7 @@ class CodeGeneratorMIPS : public CodeGeneratorShared
bool visitNegF(LNegF *lir); bool visitNegF(LNegF *lir);
bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins); bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins);
bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins); bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins);
bool visitAsmJSCall(LAsmJSCall *ins);
bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins); bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins);
bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins); bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins);
bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins); bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins);
@ -259,9 +260,8 @@ class CodeGeneratorMIPS : public CodeGeneratorShared
bool visitForkJoinGetSlice(LForkJoinGetSlice *ins); bool visitForkJoinGetSlice(LForkJoinGetSlice *ins);
bool generateInvalidateEpilogue(); bool generateInvalidateEpilogue();
protected:
void postAsmJSCall(LAsmJSCall *lir) {}
protected:
bool visitEffectiveAddress(LEffectiveAddress *ins); bool visitEffectiveAddress(LEffectiveAddress *ins);
bool visitUDiv(LUDiv *ins); bool visitUDiv(LUDiv *ins);
bool visitUMod(LUMod *ins); bool visitUMod(LUMod *ins);

View File

@ -50,7 +50,6 @@ class CodeGeneratorNone : public CodeGeneratorShared
ValueOperand ToOutValue(LInstruction *) { MOZ_CRASH(); } ValueOperand ToOutValue(LInstruction *) { MOZ_CRASH(); }
ValueOperand ToTempValue(LInstruction *, size_t) { MOZ_CRASH(); } ValueOperand ToTempValue(LInstruction *, size_t) { MOZ_CRASH(); }
bool generateInvalidateEpilogue() { MOZ_CRASH(); } bool generateInvalidateEpilogue() { MOZ_CRASH(); }
void postAsmJSCall(LAsmJSCall *) { MOZ_CRASH(); }
}; };
typedef CodeGeneratorNone CodeGeneratorSpecific; typedef CodeGeneratorNone CodeGeneratorSpecific;

View File

@ -1161,6 +1161,43 @@ CodeGeneratorShared::omitOverRecursedCheck() const
return frameSize() < 64 && !gen->performsCall(); return frameSize() < 64 && !gen->performsCall();
} }
void
CodeGeneratorShared::emitAsmJSCall(LAsmJSCall *ins)
{
MAsmJSCall *mir = ins->mir();
if (mir->spIncrement())
masm.freeStack(mir->spIncrement());
JS_ASSERT((sizeof(AsmJSFrame) + masm.framePushed()) % AsmJSStackAlignment == 0);
#ifdef DEBUG
static_assert(AsmJSStackAlignment >= ABIStackAlignment &&
AsmJSStackAlignment % ABIStackAlignment == 0,
"The asm.js stack alignment should subsume the ABI-required alignment");
Label ok;
masm.branchTestPtr(Assembler::Zero, StackPointer, Imm32(AsmJSStackAlignment - 1), &ok);
masm.breakpoint();
masm.bind(&ok);
#endif
MAsmJSCall::Callee callee = mir->callee();
switch (callee.which()) {
case MAsmJSCall::Callee::Internal:
masm.call(mir->desc(), callee.internal());
break;
case MAsmJSCall::Callee::Dynamic:
masm.call(mir->desc(), ToRegister(ins->getOperand(mir->dynamicCalleeOperandIndex())));
break;
case MAsmJSCall::Callee::Builtin:
masm.call(AsmJSImmPtr(callee.builtin()));
break;
}
if (mir->spIncrement())
masm.reserveStack(mir->spIncrement());
}
void void
CodeGeneratorShared::emitPreBarrier(Register base, const LAllocation *index) CodeGeneratorShared::emitPreBarrier(Register base, const LAllocation *index)
{ {

View File

@ -348,6 +348,8 @@ class CodeGeneratorShared : public LInstructionVisitor
bool emitTruncateDouble(FloatRegister src, Register dest, MInstruction *mir); bool emitTruncateDouble(FloatRegister src, Register dest, MInstruction *mir);
bool emitTruncateFloat32(FloatRegister src, Register dest, MInstruction *mir); bool emitTruncateFloat32(FloatRegister src, Register dest, MInstruction *mir);
void emitAsmJSCall(LAsmJSCall *ins);
void emitPreBarrier(Register base, const LAllocation *index); void emitPreBarrier(Register base, const LAllocation *index);
void emitPreBarrier(Address address); void emitPreBarrier(Address address);

View File

@ -240,6 +240,13 @@ CodeGeneratorX64::visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStati
MOZ_CRASH("NYI"); MOZ_CRASH("NYI");
} }
bool
CodeGeneratorX64::visitAsmJSCall(LAsmJSCall *ins)
{
emitAsmJSCall(ins);
return true;
}
bool bool
CodeGeneratorX64::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins) CodeGeneratorX64::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
{ {

View File

@ -41,6 +41,7 @@ class CodeGeneratorX64 : public CodeGeneratorX86Shared
bool visitTruncateFToInt32(LTruncateFToInt32 *ins); bool visitTruncateFToInt32(LTruncateFToInt32 *ins);
bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins); bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins);
bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins); bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins);
bool visitAsmJSCall(LAsmJSCall *ins);
bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins); bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins);
bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins); bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins);
bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins); bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins);
@ -49,8 +50,6 @@ class CodeGeneratorX64 : public CodeGeneratorX86Shared
bool visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins); bool visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins);
bool visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble *lir); bool visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble *lir);
bool visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32 *lir); bool visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32 *lir);
void postAsmJSCall(LAsmJSCall *lir) {}
}; };
typedef CodeGeneratorX64 CodeGeneratorSpecific; typedef CodeGeneratorX64 CodeGeneratorSpecific;

View File

@ -331,6 +331,33 @@ CodeGeneratorX86::visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic
return true; return true;
} }
bool
CodeGeneratorX86::visitAsmJSCall(LAsmJSCall *ins)
{
MAsmJSCall *mir = ins->mir();
emitAsmJSCall(ins);
if (IsFloatingPointType(mir->type()) && mir->callee().which() == MAsmJSCall::Callee::Builtin) {
if (mir->type() == MIRType_Float32) {
masm.reserveStack(sizeof(float));
Operand op(esp, 0);
masm.fstp32(op);
masm.loadFloat32(op, ReturnFloat32Reg);
masm.freeStack(sizeof(float));
} else {
JS_ASSERT(mir->type() == MIRType_Double);
masm.reserveStack(sizeof(double));
Operand op(esp, 0);
masm.fstp(op);
masm.loadDouble(op, ReturnDoubleReg);
masm.freeStack(sizeof(double));
}
}
return true;
}
bool bool
CodeGeneratorX86::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins) CodeGeneratorX86::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
{ {
@ -547,28 +574,6 @@ CodeGeneratorX86::visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins)
return true; return true;
} }
void
CodeGeneratorX86::postAsmJSCall(LAsmJSCall *lir)
{
MAsmJSCall *mir = lir->mir();
if (!IsFloatingPointType(mir->type()) || mir->callee().which() != MAsmJSCall::Callee::Builtin)
return;
if (mir->type() == MIRType_Float32) {
masm.reserveStack(sizeof(float));
Operand op(esp, 0);
masm.fstp32(op);
masm.loadFloat32(op, ReturnFloat32Reg);
masm.freeStack(sizeof(float));
} else {
masm.reserveStack(sizeof(double));
Operand op(esp, 0);
masm.fstp(op);
masm.loadDouble(op, ReturnDoubleReg);
masm.freeStack(sizeof(double));
}
}
void void
DispatchIonCache::initializeAddCacheState(LInstruction *ins, AddCacheState *addState) DispatchIonCache::initializeAddCacheState(LInstruction *ins, AddCacheState *addState)
{ {

View File

@ -58,6 +58,7 @@ class CodeGeneratorX86 : public CodeGeneratorX86Shared
bool visitTruncateFToInt32(LTruncateFToInt32 *ins); bool visitTruncateFToInt32(LTruncateFToInt32 *ins);
bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins); bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins);
bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins); bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins);
bool visitAsmJSCall(LAsmJSCall *ins);
bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins); bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins);
bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins); bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins);
bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins); bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins);
@ -67,8 +68,6 @@ class CodeGeneratorX86 : public CodeGeneratorX86Shared
bool visitOutOfLineTruncate(OutOfLineTruncate *ool); bool visitOutOfLineTruncate(OutOfLineTruncate *ool);
bool visitOutOfLineTruncateFloat32(OutOfLineTruncateFloat32 *ool); bool visitOutOfLineTruncateFloat32(OutOfLineTruncateFloat32 *ool);
void postAsmJSCall(LAsmJSCall *lir);
}; };
typedef CodeGeneratorX86 CodeGeneratorSpecific; typedef CodeGeneratorX86 CodeGeneratorSpecific;