Bug 949668 - SpiderMonkey: Add an LDefinition::Float32 r=jandem

This commit is contained in:
Dan Gohman 2013-12-13 08:27:47 -08:00
Родитель 371b480533
Коммит 12ce37d8aa
13 изменённых файлов: 52 добавлений и 33 удалений

Просмотреть файл

@ -1127,7 +1127,9 @@ BacktrackingAllocator::populateSafepoints()
if (ins == reg->ins() && !reg->isTemp()) { if (ins == reg->ins() && !reg->isTemp()) {
DebugOnly<LDefinition*> def = reg->def(); DebugOnly<LDefinition*> def = reg->def();
JS_ASSERT_IF(def->policy() == LDefinition::MUST_REUSE_INPUT, JS_ASSERT_IF(def->policy() == LDefinition::MUST_REUSE_INPUT,
def->type() == LDefinition::GENERAL || def->type() == LDefinition::DOUBLE); def->type() == LDefinition::GENERAL ||
def->type() == LDefinition::FLOAT32 ||
def->type() == LDefinition::DOUBLE);
continue; continue;
} }

Просмотреть файл

@ -196,10 +196,11 @@ static const char * const TypeChars[] =
{ {
"i", // INTEGER "i", // INTEGER
"o", // OBJECT "o", // OBJECT
"f", // DOUBLE "f", // FLOAT32
"d", // DOUBLE
#ifdef JS_NUNBOX32 #ifdef JS_NUNBOX32
"t", // TYPE "t", // TYPE
"d" // PAYLOAD "p" // PAYLOAD
#elif JS_PUNBOX64 #elif JS_PUNBOX64
"x" // BOX "x" // BOX
#endif #endif

Просмотреть файл

@ -446,7 +446,8 @@ class LDefinition
GENERAL, // Generic, integer or pointer-width data (GPR). GENERAL, // Generic, integer or pointer-width data (GPR).
OBJECT, // Pointer that may be collected as garbage (GPR). OBJECT, // Pointer that may be collected as garbage (GPR).
SLOTS, // Slots/elements pointer that may be moved by minor GCs (GPR). SLOTS, // Slots/elements pointer that may be moved by minor GCs (GPR).
DOUBLE, // 64-bit point value (FPU). FLOAT32, // 32-bit floating-point value (FPU).
DOUBLE, // 64-bit floating-point value (FPU).
#ifdef JS_NUNBOX32 #ifdef JS_NUNBOX32
// A type virtual register must be followed by a payload virtual // A type virtual register must be followed by a payload virtual
// register, as both will be tracked as a single gcthing. // register, as both will be tracked as a single gcthing.
@ -540,8 +541,9 @@ class LDefinition
case MIRType_Object: case MIRType_Object:
return LDefinition::OBJECT; return LDefinition::OBJECT;
case MIRType_Double: case MIRType_Double:
case MIRType_Float32:
return LDefinition::DOUBLE; return LDefinition::DOUBLE;
case MIRType_Float32:
return LDefinition::FLOAT32;
#if defined(JS_PUNBOX64) #if defined(JS_PUNBOX64)
case MIRType_Value: case MIRType_Value:
return LDefinition::BOX; return LDefinition::BOX;

Просмотреть файл

@ -515,7 +515,9 @@ LinearScanAllocator::populateSafepoints()
if (ins == reg->ins() && !reg->isTemp()) { if (ins == reg->ins() && !reg->isTemp()) {
DebugOnly<LDefinition*> def = reg->def(); DebugOnly<LDefinition*> def = reg->def();
JS_ASSERT_IF(def->policy() == LDefinition::MUST_REUSE_INPUT, JS_ASSERT_IF(def->policy() == LDefinition::MUST_REUSE_INPUT,
def->type() == LDefinition::GENERAL || def->type() == LDefinition::DOUBLE); def->type() == LDefinition::GENERAL ||
def->type() == LDefinition::FLOAT32 ||
def->type() == LDefinition::DOUBLE);
continue; continue;
} }
@ -792,7 +794,7 @@ LinearScanAllocator::allocateSlotFor(const LiveInterval *interval)
LinearScanVirtualRegister *reg = &vregs[interval->vreg()]; LinearScanVirtualRegister *reg = &vregs[interval->vreg()];
SlotList *freed; SlotList *freed;
if (reg->type() == LDefinition::DOUBLE) if (reg->type() == LDefinition::DOUBLE || reg->type() == LDefinition::FLOAT32)
freed = &finishedDoubleSlots_; freed = &finishedDoubleSlots_;
#ifdef JS_NUNBOX32 #ifdef JS_NUNBOX32
else if (IsNunbox(reg)) else if (IsNunbox(reg))

Просмотреть файл

@ -468,6 +468,7 @@ AddRegisterToSafepoint(LSafepoint *safepoint, AnyRegister reg, const LDefinition
JS_ASSERT(def.type() == LDefinition::GENERAL || JS_ASSERT(def.type() == LDefinition::GENERAL ||
def.type() == LDefinition::DOUBLE || def.type() == LDefinition::DOUBLE ||
def.type() == LDefinition::FLOAT32 ||
def.type() == LDefinition::OBJECT); def.type() == LDefinition::OBJECT);
if (def.type() == LDefinition::OBJECT) if (def.type() == LDefinition::OBJECT)

Просмотреть файл

@ -136,7 +136,7 @@ static inline bool
DefinitionCompatibleWith(LInstruction *ins, const LDefinition *def, LAllocation alloc) DefinitionCompatibleWith(LInstruction *ins, const LDefinition *def, LAllocation alloc)
{ {
if (ins->isPhi()) { if (ins->isPhi()) {
if (def->type() == LDefinition::DOUBLE) if (def->type() == LDefinition::DOUBLE || def->type() == LDefinition::FLOAT32)
return alloc.isFloatReg() || alloc.kind() == LAllocation::DOUBLE_SLOT; return alloc.isFloatReg() || alloc.kind() == LAllocation::DOUBLE_SLOT;
return alloc.isGeneralReg() || alloc.kind() == LAllocation::STACK_SLOT; return alloc.isGeneralReg() || alloc.kind() == LAllocation::STACK_SLOT;
} }
@ -145,7 +145,7 @@ DefinitionCompatibleWith(LInstruction *ins, const LDefinition *def, LAllocation
case LDefinition::DEFAULT: case LDefinition::DEFAULT:
if (!alloc.isRegister()) if (!alloc.isRegister())
return false; return false;
return alloc.isFloatReg() == (def->type() == LDefinition::DOUBLE); return alloc.isFloatReg() == (def->type() == LDefinition::DOUBLE || def->type() == LDefinition::FLOAT32);
case LDefinition::PRESET: case LDefinition::PRESET:
return alloc == *def->output(); return alloc == *def->output();
case LDefinition::MUST_REUSE_INPUT: case LDefinition::MUST_REUSE_INPUT:
@ -473,7 +473,7 @@ class VirtualRegister
return intervals_.insert(found, interval); return intervals_.insert(found, interval);
} }
bool isDouble() const { bool isDouble() const {
return def_->type() == LDefinition::DOUBLE; return def_->type() == LDefinition::DOUBLE || def_->type() == LDefinition::FLOAT32;
} }
LiveInterval *intervalFor(CodePosition pos); LiveInterval *intervalFor(CodePosition pos);

Просмотреть файл

@ -659,7 +659,7 @@ LIRGenerator::visitTest(MTest *test)
temp0 = LDefinition::BogusTemp(); temp0 = LDefinition::BogusTemp();
temp1 = LDefinition::BogusTemp(); temp1 = LDefinition::BogusTemp();
} }
LTestVAndBranch *lir = new(alloc()) LTestVAndBranch(ifTrue, ifFalse, tempFloat(), temp0, temp1); LTestVAndBranch *lir = new(alloc()) LTestVAndBranch(ifTrue, ifFalse, tempDouble(), temp0, temp1);
if (!useBox(lir, LTestVAndBranch::Input, opd)) if (!useBox(lir, LTestVAndBranch::Input, opd))
return false; return false;
return add(lir, test); return add(lir, test);
@ -1026,7 +1026,7 @@ LIRGenerator::visitTypeOf(MTypeOf *ins)
bool bool
LIRGenerator::visitToId(MToId *ins) LIRGenerator::visitToId(MToId *ins)
{ {
LToIdV *lir = new(alloc()) LToIdV(tempFloat()); LToIdV *lir = new(alloc()) LToIdV(tempDouble());
if (!useBox(lir, LToIdV::Object, ins->lhs())) if (!useBox(lir, LToIdV::Object, ins->lhs()))
return false; return false;
if (!useBox(lir, LToIdV::Index, ins->rhs())) if (!useBox(lir, LToIdV::Index, ins->rhs()))
@ -1175,7 +1175,7 @@ bool
LIRGenerator::visitRound(MRound *ins) LIRGenerator::visitRound(MRound *ins)
{ {
JS_ASSERT(ins->num()->type() == MIRType_Double); JS_ASSERT(ins->num()->type() == MIRType_Double);
LRound *lir = new(alloc()) LRound(useRegister(ins->num()), tempFloat()); LRound *lir = new(alloc()) LRound(useRegister(ins->num()), tempDouble());
if (!assignSnapshot(lir)) if (!assignSnapshot(lir))
return false; return false;
return define(lir, ins); return define(lir, ins);
@ -1754,7 +1754,7 @@ LIRGenerator::visitToInt32(MToInt32 *convert)
switch (opd->type()) { switch (opd->type()) {
case MIRType_Value: case MIRType_Value:
{ {
LValueToInt32 *lir = new(alloc()) LValueToInt32(tempFloat(), temp(), LValueToInt32::NORMAL); LValueToInt32 *lir = new(alloc()) LValueToInt32(tempDouble(), temp(), LValueToInt32::NORMAL);
if (!useBox(lir, LValueToInt32::Input, opd)) if (!useBox(lir, LValueToInt32::Input, opd))
return false; return false;
return assignSnapshot(lir) && define(lir, convert) && assignSafepoint(lir, convert); return assignSnapshot(lir) && define(lir, convert) && assignSafepoint(lir, convert);
@ -1799,7 +1799,7 @@ LIRGenerator::visitTruncateToInt32(MTruncateToInt32 *truncate)
switch (opd->type()) { switch (opd->type()) {
case MIRType_Value: case MIRType_Value:
{ {
LValueToInt32 *lir = new(alloc()) LValueToInt32(tempFloat(), temp(), LValueToInt32::TRUNCATE); LValueToInt32 *lir = new(alloc()) LValueToInt32(tempDouble(), temp(), LValueToInt32::TRUNCATE);
if (!useBox(lir, LValueToInt32::Input, opd)) if (!useBox(lir, LValueToInt32::Input, opd))
return false; return false;
return assignSnapshot(lir) && define(lir, truncate) && assignSafepoint(lir, truncate); return assignSnapshot(lir) && define(lir, truncate) && assignSafepoint(lir, truncate);
@ -2025,7 +2025,7 @@ LIRGenerator::visitMaybeToDoubleElement(MMaybeToDoubleElement *ins)
LMaybeToDoubleElement *lir = new(alloc()) LMaybeToDoubleElement(useRegisterAtStart(ins->elements()), LMaybeToDoubleElement *lir = new(alloc()) LMaybeToDoubleElement(useRegisterAtStart(ins->elements()),
useRegisterAtStart(ins->value()), useRegisterAtStart(ins->value()),
tempFloat()); tempDouble());
return defineBox(lir, ins); return defineBox(lir, ins);
} }
@ -2342,7 +2342,7 @@ LIRGenerator::visitNot(MNot *ins)
temp1 = LDefinition::BogusTemp(); temp1 = LDefinition::BogusTemp();
} }
LNotV *lir = new(alloc()) LNotV(tempFloat(), temp0, temp1); LNotV *lir = new(alloc()) LNotV(tempDouble(), temp0, temp1);
if (!useBox(lir, LNotV::Input, op)) if (!useBox(lir, LNotV::Input, op))
return false; return false;
return define(lir, ins); return define(lir, ins);
@ -2625,7 +2625,7 @@ LIRGenerator::visitClampToUint8(MClampToUint8 *ins)
case MIRType_Value: case MIRType_Value:
{ {
LClampVToUint8 *lir = new(alloc()) LClampVToUint8(tempFloat()); LClampVToUint8 *lir = new(alloc()) LClampVToUint8(tempDouble());
if (!useBox(lir, LClampVToUint8::Input, in)) if (!useBox(lir, LClampVToUint8::Input, in))
return false; return false;
return assignSnapshot(lir) && define(lir, ins) && assignSafepoint(lir, ins); return assignSnapshot(lir) && define(lir, ins) && assignSafepoint(lir, ins);
@ -2912,15 +2912,15 @@ LIRGenerator::visitAssertRange(MAssertRange *ins)
break; break;
case MIRType_Double: case MIRType_Double:
lir = new(alloc()) LAssertRangeD(useRegister(input), tempFloat()); lir = new(alloc()) LAssertRangeD(useRegister(input), tempDouble());
break; break;
case MIRType_Float32: case MIRType_Float32:
lir = new(alloc()) LAssertRangeF(useRegister(input), tempFloat()); lir = new(alloc()) LAssertRangeF(useRegister(input), tempFloat32());
break; break;
case MIRType_Value: case MIRType_Value:
lir = new(alloc()) LAssertRangeV(tempToUnbox(), tempFloat(), tempFloat()); lir = new(alloc()) LAssertRangeV(tempToUnbox(), tempDouble(), tempDouble());
if (!useBox(lir, LAssertRangeV::Input, input)) if (!useBox(lir, LAssertRangeV::Input, input))
return false; return false;
break; break;
@ -3026,7 +3026,7 @@ LIRGenerator::visitSetElementCache(MSetElementCache *ins)
LInstruction *lir; LInstruction *lir;
if (ins->value()->type() == MIRType_Value) { if (ins->value()->type() == MIRType_Value) {
lir = new(alloc()) LSetElementCacheV(useByteOpRegister(ins->object()), tempToUnbox(), lir = new(alloc()) LSetElementCacheV(useByteOpRegister(ins->object()), tempToUnbox(),
temp(), tempFloat()); temp(), tempDouble());
if (!useBox(lir, LSetElementCacheV::Index, ins->index())) if (!useBox(lir, LSetElementCacheV::Index, ins->index()))
return false; return false;
@ -3035,7 +3035,7 @@ LIRGenerator::visitSetElementCache(MSetElementCache *ins)
} else { } else {
lir = new(alloc()) LSetElementCacheT(useByteOpRegister(ins->object()), lir = new(alloc()) LSetElementCacheT(useByteOpRegister(ins->object()),
useRegisterOrConstant(ins->value()), useRegisterOrConstant(ins->value()),
tempToUnbox(), temp(), tempFloat()); tempToUnbox(), temp(), tempDouble());
if (!useBox(lir, LSetElementCacheT::Index, ins->index())) if (!useBox(lir, LSetElementCacheT::Index, ins->index()))
return false; return false;

Просмотреть файл

@ -369,7 +369,7 @@ class RegisterAllocator
static inline AnyRegister static inline AnyRegister
GetFixedRegister(const LDefinition *def, const LUse *use) GetFixedRegister(const LDefinition *def, const LUse *use)
{ {
return def->type() == LDefinition::DOUBLE return (def->type() == LDefinition::DOUBLE || def->type() == LDefinition::FLOAT32)
? AnyRegister(FloatRegister::FromCode(use->registerCode())) ? AnyRegister(FloatRegister::FromCode(use->registerCode()))
: AnyRegister(Register::FromCode(use->registerCode())); : AnyRegister(Register::FromCode(use->registerCode()));
} }

Просмотреть файл

@ -28,7 +28,9 @@ StupidAllocator::stackLocation(uint32_t vreg)
if (def->policy() == LDefinition::PRESET && def->output()->isArgument()) if (def->policy() == LDefinition::PRESET && def->output()->isArgument())
return def->output(); return def->output();
return new(alloc()) LStackSlot(DefaultStackSlot(vreg), def->type() == LDefinition::DOUBLE); return new(alloc()) LStackSlot(DefaultStackSlot(vreg),
def->type() == LDefinition::DOUBLE ||
def->type() == LDefinition::FLOAT32);
} }
StupidAllocator::RegisterIndex StupidAllocator::RegisterIndex
@ -162,7 +164,7 @@ StupidAllocator::allocateRegister(LInstruction *ins, uint32_t vreg)
for (size_t i = 0; i < registerCount; i++) { for (size_t i = 0; i < registerCount; i++) {
AnyRegister reg = registers[i].reg; AnyRegister reg = registers[i].reg;
if (reg.isFloat() != (def->type() == LDefinition::DOUBLE)) if (reg.isFloat() != (def->type() == LDefinition::DOUBLE || def->type() == LDefinition::FLOAT32))
continue; continue;
// Skip the register if it is in use for an allocated input or output. // Skip the register if it is in use for an allocated input or output.

Просмотреть файл

@ -362,7 +362,7 @@ LIRGeneratorARM::newLTableSwitch(const LAllocation &in, const LDefinition &input
LTableSwitchV * LTableSwitchV *
LIRGeneratorARM::newLTableSwitchV(MTableSwitch *tableswitch) LIRGeneratorARM::newLTableSwitchV(MTableSwitch *tableswitch)
{ {
return new(alloc()) LTableSwitchV(temp(), tempFloat(), tableswitch); return new(alloc()) LTableSwitchV(temp(), tempDouble(), tableswitch);
} }
bool bool

Просмотреть файл

@ -149,12 +149,14 @@ LIRGeneratorShared::defineReturn(LInstruction *lir, MDefinition *mir)
#endif #endif
break; break;
case MIRType_Float32: case MIRType_Float32:
lir->setDef(0, LDefinition(vreg, LDefinition::FLOAT32, LFloatReg(ReturnFloatReg)));
break;
case MIRType_Double: case MIRType_Double:
lir->setDef(0, LDefinition(vreg, LDefinition::DOUBLE, LFloatReg(ReturnFloatReg))); lir->setDef(0, LDefinition(vreg, LDefinition::DOUBLE, LFloatReg(ReturnFloatReg)));
break; break;
default: default:
LDefinition::Type type = LDefinition::TypeFrom(mir->type()); LDefinition::Type type = LDefinition::TypeFrom(mir->type());
JS_ASSERT(type != LDefinition::DOUBLE); JS_ASSERT(type != LDefinition::DOUBLE && type != LDefinition::FLOAT32);
lir->setDef(0, LDefinition(vreg, type, LGeneralReg(ReturnReg))); lir->setDef(0, LDefinition(vreg, type, LGeneralReg(ReturnReg)));
break; break;
} }
@ -421,7 +423,13 @@ LIRGeneratorShared::tempFixed(Register reg)
} }
LDefinition LDefinition
LIRGeneratorShared::tempFloat() LIRGeneratorShared::tempFloat32()
{
return temp(LDefinition::FLOAT32);
}
LDefinition
LIRGeneratorShared::tempDouble()
{ {
return temp(LDefinition::DOUBLE); return temp(LDefinition::DOUBLE);
} }

Просмотреть файл

@ -104,7 +104,8 @@ class LIRGeneratorShared : public MInstructionVisitorWithDefaults
// These create temporary register requests. // These create temporary register requests.
inline LDefinition temp(LDefinition::Type type = LDefinition::GENERAL, inline LDefinition temp(LDefinition::Type type = LDefinition::GENERAL,
LDefinition::Policy policy = LDefinition::DEFAULT); LDefinition::Policy policy = LDefinition::DEFAULT);
inline LDefinition tempFloat(); inline LDefinition tempFloat32();
inline LDefinition tempDouble();
inline LDefinition tempCopy(MDefinition *input, uint32_t reusedInput); inline LDefinition tempCopy(MDefinition *input, uint32_t reusedInput);
// Note that the fixed register has a GENERAL type. // Note that the fixed register has a GENERAL type.

Просмотреть файл

@ -27,7 +27,7 @@ LIRGeneratorX86Shared::newLTableSwitch(const LAllocation &in, const LDefinition
LTableSwitchV * LTableSwitchV *
LIRGeneratorX86Shared::newLTableSwitchV(MTableSwitch *tableswitch) LIRGeneratorX86Shared::newLTableSwitchV(MTableSwitch *tableswitch)
{ {
return new(alloc()) LTableSwitchV(temp(), tempFloat(), temp(), tableswitch); return new(alloc()) LTableSwitchV(temp(), tempDouble(), temp(), tableswitch);
} }
bool bool
@ -333,7 +333,7 @@ LIRGeneratorX86Shared::lowerTruncateDToInt32(MTruncateToInt32 *ins)
MDefinition *opd = ins->input(); MDefinition *opd = ins->input();
JS_ASSERT(opd->type() == MIRType_Double); JS_ASSERT(opd->type() == MIRType_Double);
LDefinition maybeTemp = Assembler::HasSSE3() ? LDefinition::BogusTemp() : tempFloat(); LDefinition maybeTemp = Assembler::HasSSE3() ? LDefinition::BogusTemp() : tempDouble();
return define(new(alloc()) LTruncateDToInt32(useRegister(opd), maybeTemp), ins); return define(new(alloc()) LTruncateDToInt32(useRegister(opd), maybeTemp), ins);
} }
@ -343,6 +343,6 @@ LIRGeneratorX86Shared::lowerTruncateFToInt32(MTruncateToInt32 *ins)
MDefinition *opd = ins->input(); MDefinition *opd = ins->input();
JS_ASSERT(opd->type() == MIRType_Float32); JS_ASSERT(opd->type() == MIRType_Float32);
LDefinition maybeTemp = Assembler::HasSSE3() ? LDefinition::BogusTemp() : tempFloat(); LDefinition maybeTemp = Assembler::HasSSE3() ? LDefinition::BogusTemp() : tempFloat32();
return define(new(alloc()) LTruncateFToInt32(useRegister(opd), maybeTemp), ins); return define(new(alloc()) LTruncateFToInt32(useRegister(opd), maybeTemp), ins);
} }