mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 899139 - Part 4: Refactor lowering byte registers for x86. (r=jandem)
This commit is contained in:
parent
484a464b80
commit
6be713a75a
@ -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());
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user