Bug 899139 - Part 4: Refactor lowering byte registers for x86. (r=jandem)

This commit is contained in:
Shu-yu Guo 2013-09-09 18:55:53 -07:00
parent 484a464b80
commit 6be713a75a
8 changed files with 115 additions and 141 deletions

View File

@ -2402,6 +2402,58 @@ LIRGenerator::visitLoadTypedArrayElementStatic(MLoadTypedArrayElementStatic *ins
return define(lir, ins);
}
bool
LIRGenerator::visitStoreTypedArrayElement(MStoreTypedArrayElement *ins)
{
JS_ASSERT(ins->elements()->type() == MIRType_Elements);
JS_ASSERT(ins->index()->type() == MIRType_Int32);
if (ins->isFloatArray()) {
JS_ASSERT_IF(ins->arrayType() == ScalarTypeRepresentation::TYPE_FLOAT32, ins->value()->type() == MIRType_Float32);
JS_ASSERT_IF(ins->arrayType() == ScalarTypeRepresentation::TYPE_FLOAT64, ins->value()->type() == MIRType_Double);
} else {
JS_ASSERT(ins->value()->type() == MIRType_Int32);
}
LUse elements = useRegister(ins->elements());
LAllocation index = useRegisterOrConstant(ins->index());
LAllocation value;
// For byte arrays, the value has to be in a byte register on x86.
if (ins->isByteArray())
value = useByteOpRegisterOrNonDoubleConstant(ins->value());
else
value = useRegisterOrNonDoubleConstant(ins->value());
return add(new LStoreTypedArrayElement(elements, index, value), ins);
}
bool
LIRGenerator::visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins)
{
JS_ASSERT(ins->elements()->type() == MIRType_Elements);
JS_ASSERT(ins->index()->type() == MIRType_Int32);
JS_ASSERT(ins->length()->type() == MIRType_Int32);
if (ins->isFloatArray()) {
JS_ASSERT_IF(ins->arrayType() == ScalarTypeRepresentation::TYPE_FLOAT32, ins->value()->type() == MIRType_Float32);
JS_ASSERT_IF(ins->arrayType() == ScalarTypeRepresentation::TYPE_FLOAT64, ins->value()->type() == MIRType_Double);
} else {
JS_ASSERT(ins->value()->type() == MIRType_Int32);
}
LUse elements = useRegister(ins->elements());
LAllocation length = useAnyOrConstant(ins->length());
LAllocation index = useRegisterOrConstant(ins->index());
LAllocation value;
// For byte arrays, the value has to be in a byte register on x86.
if (ins->isByteArray())
value = useByteOpRegisterOrNonDoubleConstant(ins->value());
else
value = useRegisterOrNonDoubleConstant(ins->value());
return add(new LStoreTypedArrayElementHole(elements, length, index, value), ins);
}
bool
LIRGenerator::visitLoadFixedSlot(MLoadFixedSlot *ins)
{
@ -2688,9 +2740,13 @@ LIRGenerator::visitSetElementCache(MSetElementCache *ins)
JS_ASSERT(ins->object()->type() == MIRType_Object);
JS_ASSERT(ins->index()->type() == MIRType_Value);
// Due to lack of registers on x86, we reuse the object register as a
// temporary. This register may be used in a 1-byte store, which on x86
// again has constraints; thus the use of |useByteOpRegister| over
// |useRegister| below.
LInstruction *lir;
if (ins->value()->type() == MIRType_Value) {
lir = new LSetElementCacheV(useRegister(ins->object()), tempToUnbox(),
lir = new LSetElementCacheV(useByteOpRegister(ins->object()), tempToUnbox(),
temp(), tempFloat());
if (!useBox(lir, LSetElementCacheV::Index, ins->index()))
@ -2699,7 +2755,7 @@ LIRGenerator::visitSetElementCache(MSetElementCache *ins)
return false;
} else {
lir = new LSetElementCacheT(
useRegister(ins->object()),
useByteOpRegister(ins->object()),
useRegisterOrConstant(ins->value()),
tempToUnbox(), temp(), tempFloat());

View File

@ -196,6 +196,8 @@ class LIRGenerator : public LIRGeneratorSpecific
bool visitLoadTypedArrayElement(MLoadTypedArrayElement *ins);
bool visitLoadTypedArrayElementHole(MLoadTypedArrayElementHole *ins);
bool visitLoadTypedArrayElementStatic(MLoadTypedArrayElementStatic *ins);
bool visitStoreTypedArrayElement(MStoreTypedArrayElement *ins);
bool visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins);
bool visitClampToUint8(MClampToUint8 *ins);
bool visitLoadFixedSlot(MLoadFixedSlot *ins);
bool visitStoreFixedSlot(MStoreFixedSlot *ins);

View File

@ -43,6 +43,18 @@ LIRGeneratorARM::useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Regi
return true;
}
LAllocation
LIRGeneratorARM::useByteOpRegister(MDefinition *mir)
{
return useRegister(mir);
}
LAllocation
LIRGeneratorARM::useByteOpRegisterOrNonDoubleConstant(MDefinition *mir)
{
return useRegisterOrNonDoubleConstant(mir);
}
bool
LIRGeneratorARM::lowerConstantDouble(double d, MInstruction *mir)
{
@ -386,42 +398,6 @@ LIRGeneratorARM::visitGuardObjectType(MGuardObjectType *ins)
return redefine(ins, ins->obj());
}
bool
LIRGeneratorARM::visitStoreTypedArrayElement(MStoreTypedArrayElement *ins)
{
JS_ASSERT(ins->elements()->type() == MIRType_Elements);
JS_ASSERT(ins->index()->type() == MIRType_Int32);
if (ins->isFloatArray())
JS_ASSERT(ins->value()->type() == MIRType_Double);
else
JS_ASSERT(ins->value()->type() == MIRType_Int32);
LUse elements = useRegister(ins->elements());
LAllocation index = useRegisterOrConstant(ins->index());
LAllocation value = useRegisterOrNonDoubleConstant(ins->value());
return add(new LStoreTypedArrayElement(elements, index, value), ins);
}
bool
LIRGeneratorARM::visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins)
{
JS_ASSERT(ins->elements()->type() == MIRType_Elements);
JS_ASSERT(ins->index()->type() == MIRType_Int32);
JS_ASSERT(ins->length()->type() == MIRType_Int32);
if (ins->isFloatArray())
JS_ASSERT(ins->value()->type() == MIRType_Double);
else
JS_ASSERT(ins->value()->type() == MIRType_Int32);
LUse elements = useRegister(ins->elements());
LAllocation length = useRegisterOrConstant(ins->length());
LAllocation index = useRegisterOrConstant(ins->index());
LAllocation value = useRegisterOrNonDoubleConstant(ins->value());
return add(new LStoreTypedArrayElementHole(elements, length, index, value), ins);
}
bool
LIRGeneratorARM::lowerUrshD(MUrsh *mir)
{

View File

@ -26,6 +26,11 @@ class LIRGeneratorARM : public LIRGeneratorShared
LUse::Policy policy = LUse::REGISTER, bool useAtStart = false);
bool useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Register reg1, Register reg2);
// x86 has constraints on what registers can be formatted for 1-byte
// stores and loads; on ARM all registers are okay.
LAllocation useByteOpRegister(MDefinition *mir);
LAllocation useByteOpRegisterOrNonDoubleConstant(MDefinition *mir);
inline LDefinition tempToUnbox() {
return LDefinition::BogusTemp();
}
@ -82,8 +87,6 @@ class LIRGeneratorARM : public LIRGeneratorShared
bool lowerPhi(MPhi *phi);
bool visitGuardShape(MGuardShape *ins);
bool visitGuardObjectType(MGuardObjectType *ins);
bool visitStoreTypedArrayElement(MStoreTypedArrayElement *ins);
bool visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins);
bool visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins);
bool visitAsmJSLoadHeap(MAsmJSLoadHeap *ins);
bool visitAsmJSStoreHeap(MAsmJSStoreHeap *ins);

View File

@ -37,6 +37,18 @@ LIRGeneratorX64::useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Regi
return true;
}
LAllocation
LIRGeneratorX64::useByteOpRegister(MDefinition *mir)
{
return useRegister(mir);
}
LAllocation
LIRGeneratorX64::useByteOpRegisterOrNonDoubleConstant(MDefinition *mir)
{
return useRegisterOrNonDoubleConstant(mir);
}
LDefinition
LIRGeneratorX64::tempToUnbox()
{
@ -98,46 +110,6 @@ LIRGeneratorX64::lowerUntypedPhiInput(MPhi *phi, uint32_t inputPosition, LBlock
lowerTypedPhiInput(phi, inputPosition, block, lirIndex);
}
bool
LIRGeneratorX64::visitStoreTypedArrayElement(MStoreTypedArrayElement *ins)
{
JS_ASSERT(ins->elements()->type() == MIRType_Elements);
JS_ASSERT(ins->index()->type() == MIRType_Int32);
if (ins->isFloatArray()) {
JS_ASSERT_IF(ins->arrayType() == ScalarTypeRepresentation::TYPE_FLOAT32, ins->value()->type() == MIRType_Float32);
JS_ASSERT_IF(ins->arrayType() == ScalarTypeRepresentation::TYPE_FLOAT64, ins->value()->type() == MIRType_Double);
} else {
JS_ASSERT(ins->value()->type() == MIRType_Int32);
}
LUse elements = useRegister(ins->elements());
LAllocation index = useRegisterOrConstant(ins->index());
LAllocation value = useRegisterOrNonDoubleConstant(ins->value());
return add(new LStoreTypedArrayElement(elements, index, value), ins);
}
bool
LIRGeneratorX64::visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins)
{
JS_ASSERT(ins->elements()->type() == MIRType_Elements);
JS_ASSERT(ins->index()->type() == MIRType_Int32);
JS_ASSERT(ins->length()->type() == MIRType_Int32);
if (ins->isFloatArray()) {
JS_ASSERT_IF(ins->arrayType() == ScalarTypeRepresentation::TYPE_FLOAT32, ins->value()->type() == MIRType_Float32);
JS_ASSERT_IF(ins->arrayType() == ScalarTypeRepresentation::TYPE_FLOAT64, ins->value()->type() == MIRType_Double);
} else {
JS_ASSERT(ins->value()->type() == MIRType_Int32);
}
LUse elements = useRegister(ins->elements());
LAllocation length = useAnyOrConstant(ins->length());
LAllocation index = useRegisterOrConstant(ins->index());
LAllocation value = useRegisterOrNonDoubleConstant(ins->value());
return add(new LStoreTypedArrayElementHole(elements, length, index, value), ins);
}
bool
LIRGeneratorX64::visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins)
{

View File

@ -28,6 +28,11 @@ class LIRGeneratorX64 : public LIRGeneratorX86Shared
LUse::Policy policy = LUse::REGISTER, bool useAtStart = false);
bool useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Register reg1, Register);
// x86 has constraints on what registers can be formatted for 1-byte
// stores and loads; on x64 all registers are okay.
LAllocation useByteOpRegister(MDefinition *mir);
LAllocation useByteOpRegisterOrNonDoubleConstant(MDefinition *mir);
LDefinition tempToUnbox();
LGetPropertyCacheT *newLGetPropertyCacheT(MGetPropertyCache *ins);
@ -37,8 +42,6 @@ class LIRGeneratorX64 : public LIRGeneratorX86Shared
bool visitBox(MBox *box);
bool visitUnbox(MUnbox *unbox);
bool visitReturn(MReturn *ret);
bool visitStoreTypedArrayElement(MStoreTypedArrayElement *ins);
bool visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins);
bool visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins);
bool visitAsmJSLoadHeap(MAsmJSLoadHeap *ins);
bool visitAsmJSStoreHeap(MAsmJSStoreHeap *ins);

View File

@ -41,6 +41,18 @@ LIRGeneratorX86::useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Regi
return true;
}
LAllocation
LIRGeneratorX86::useByteOpRegister(MDefinition *mir)
{
return useFixed(mir, eax);
}
LAllocation
LIRGeneratorX86::useByteOpRegisterOrNonDoubleConstant(MDefinition *mir)
{
return useFixed(mir, eax);
}
bool
LIRGeneratorX86::visitBox(MBox *box)
{
@ -160,58 +172,6 @@ LIRGeneratorX86::lowerUntypedPhiInput(MPhi *phi, uint32_t inputPosition, LBlock
payload->setOperand(inputPosition, LUse(VirtualRegisterOfPayload(operand), LUse::ANY));
}
bool
LIRGeneratorX86::visitStoreTypedArrayElement(MStoreTypedArrayElement *ins)
{
JS_ASSERT(ins->elements()->type() == MIRType_Elements);
JS_ASSERT(ins->index()->type() == MIRType_Int32);
if (ins->isFloatArray()) {
JS_ASSERT_IF(ins->arrayType() == ScalarTypeRepresentation::TYPE_FLOAT64, ins->value()->type() == MIRType_Double);
JS_ASSERT_IF(ins->arrayType() == ScalarTypeRepresentation::TYPE_FLOAT32, ins->value()->type() == MIRType_Float32);
} else {
JS_ASSERT(ins->value()->type() == MIRType_Int32);
}
LUse elements = useRegister(ins->elements());
LAllocation index = useRegisterOrConstant(ins->index());
LAllocation value;
// For byte arrays, the value has to be in a byte register on x86.
if (ins->isByteArray())
value = useFixed(ins->value(), eax);
else
value = useRegisterOrNonDoubleConstant(ins->value());
return add(new LStoreTypedArrayElement(elements, index, value), ins);
}
bool
LIRGeneratorX86::visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins)
{
JS_ASSERT(ins->elements()->type() == MIRType_Elements);
JS_ASSERT(ins->index()->type() == MIRType_Int32);
JS_ASSERT(ins->length()->type() == MIRType_Int32);
if (ins->isFloatArray()) {
JS_ASSERT_IF(ins->arrayType() == ScalarTypeRepresentation::TYPE_FLOAT64, ins->value()->type() == MIRType_Double);
JS_ASSERT_IF(ins->arrayType() == ScalarTypeRepresentation::TYPE_FLOAT32, ins->value()->type() == MIRType_Float32);
} else {
JS_ASSERT(ins->value()->type() == MIRType_Int32);
}
LUse elements = useRegister(ins->elements());
LAllocation length = useAnyOrConstant(ins->length());
LAllocation index = useRegisterOrConstant(ins->index());
LAllocation value;
// For byte arrays, the value has to be in a byte register on x86.
if (ins->isByteArray())
value = useFixed(ins->value(), eax);
else
value = useRegisterOrNonDoubleConstant(ins->value());
return add(new LStoreTypedArrayElementHole(elements, length, index, value), ins);
}
bool
LIRGeneratorX86::visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins)
{
@ -269,11 +229,7 @@ LIRGeneratorX86::visitAsmJSStoreHeap(MAsmJSStoreHeap *ins)
switch (ins->viewType()) {
case ArrayBufferView::TYPE_INT8: case ArrayBufferView::TYPE_UINT8:
// It's a trap! On x86, the 1-byte store can only use one of
// {al,bl,cl,dl,ah,bh,ch,dh}. That means if the register allocator
// gives us one of {edi,esi,ebp,esp}, we're out of luck. (The formatter
// will assert on us.) Ideally, we'd just ask the register allocator to
// give us one of {al,bl,cl,dl}. For now, just useFixed(al).
// See comment for LIRGeneratorX86::useByteOpRegister.
lir = new LAsmJSStoreHeap(useRegister(ins->ptr()), useFixed(ins->value(), eax));
break;
case ArrayBufferView::TYPE_INT16: case ArrayBufferView::TYPE_UINT16:

View File

@ -26,6 +26,14 @@ class LIRGeneratorX86 : public LIRGeneratorX86Shared
LUse::Policy policy = LUse::REGISTER, bool useAtStart = false);
bool useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Register reg1, Register reg2);
// It's a trap! On x86, the 1-byte store can only use one of
// {al,bl,cl,dl,ah,bh,ch,dh}. That means if the register allocator
// gives us one of {edi,esi,ebp,esp}, we're out of luck. (The formatter
// will assert on us.) Ideally, we'd just ask the register allocator to
// give us one of {al,bl,cl,dl}. For now, just useFixed(al).
LAllocation useByteOpRegister(MDefinition *mir);
LAllocation useByteOpRegisterOrNonDoubleConstant(MDefinition *mir);
inline LDefinition tempToUnbox() {
return LDefinition::BogusTemp();
}
@ -40,8 +48,6 @@ class LIRGeneratorX86 : public LIRGeneratorX86Shared
bool visitBox(MBox *box);
bool visitUnbox(MUnbox *unbox);
bool visitReturn(MReturn *ret);
bool visitStoreTypedArrayElement(MStoreTypedArrayElement *ins);
bool visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins);
bool visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins);
bool visitAsmJSLoadHeap(MAsmJSLoadHeap *ins);
bool visitAsmJSStoreHeap(MAsmJSStoreHeap *ins);