Bug 949668 - SpiderMonkey: Add a MoveOp::FLOAT32 r=jandem

This commit is contained in:
Dan Gohman 2013-12-17 08:46:37 -08:00
parent 63b60c0e6f
commit 9ef7bdfd67
8 changed files with 90 additions and 40 deletions

View File

@ -1206,7 +1206,7 @@ CodeGenerator::visitMoveGroup(LMoveGroup *group)
case LDefinition::BOX:
#endif
case LDefinition::GENERAL: kind = MoveOp::GENERAL; break;
case LDefinition::FLOAT32:
case LDefinition::FLOAT32: kind = MoveOp::FLOAT32; break;
case LDefinition::DOUBLE: kind = MoveOp::DOUBLE; break;
default: MOZ_ASSUME_UNREACHABLE("Unexpected move type");
}
@ -4124,7 +4124,7 @@ CodeGenerator::visitMathFunctionF(LMathFunctionF *ins)
JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg);
masm.setupUnalignedABICall(1, temp);
masm.passABIArg(input, MoveOp::DOUBLE);
masm.passABIArg(input, MoveOp::FLOAT32);
void *funptr = nullptr;
switch (ins->mir()->function()) {
@ -4141,7 +4141,7 @@ CodeGenerator::visitMathFunctionF(LMathFunctionF *ins)
MOZ_ASSUME_UNREACHABLE("Unknown or unsupported float32 math function");
}
masm.callWithABI(funptr, MoveOp::DOUBLE);
masm.callWithABI(funptr, MoveOp::FLOAT32);
return true;
}

View File

@ -115,6 +115,7 @@ class MoveOp
public:
enum Kind {
GENERAL,
FLOAT32,
DOUBLE
};

View File

@ -2152,9 +2152,19 @@ GetIntArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t *paddi
}
static inline uint32_t
GetFloatArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t *padding)
GetFloat32ArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t *padding)
{
JS_ASSERT(usedFloatArgs >= NumFloatArgRegs);
uint32_t intSlots = 0;
if (usedIntArgs > NumIntArgRegs)
intSlots = usedIntArgs - NumIntArgRegs;
uint32_t float32Slots = usedFloatArgs - NumFloatArgRegs;
return (intSlots + float32Slots + *padding) * STACK_SLOT_SIZE;
}
static inline uint32_t
GetDoubleArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t *padding)
{
JS_ASSERT(usedFloatArgs >= NumFloatArgRegs);
uint32_t intSlots = 0;
if (usedIntArgs > NumIntArgRegs) {

View File

@ -3515,18 +3515,20 @@ MacroAssemblerARMCompat::passABIArg(const MoveOperand &from, MoveOp::Kind kind)
if (!enoughMemory_)
return;
switch (kind) {
case MoveOp::FLOAT32:
case MoveOp::DOUBLE: {
FloatRegister fr;
if (GetFloatArgReg(usedIntSlots_, usedFloatSlots_, &fr)) {
if (!from.isFloatReg() || from.floatReg() != fr) {
enoughMemory_ = moveResolver_.addMove(from, MoveOperand(fr), MoveOp::DOUBLE);
if (from.isFloatReg() && from.floatReg() == fr) {
// Nothing to do; the value is in the right register already
return;
}
// else nothing to do; the value is in the right register already
to = MoveOperand(fr);
} else {
// If (and only if) the integer registers have started spilling, do we
// need to take the double register's alignment into account
// need to take the register's alignment into account
uint32_t disp = GetFloatArgStackDisp(usedIntSlots_, usedFloatSlots_, &padding_);
enoughMemory_ = moveResolver_.addMove(from, MoveOperand(sp, disp), MoveOp::DOUBLE);
to = MoveOperand(sp, disp);
}
usedFloatSlots_++;
break;
@ -3534,13 +3536,14 @@ MacroAssemblerARMCompat::passABIArg(const MoveOperand &from, MoveOp::Kind kind)
case MoveOp::GENERAL: {
Register r;
if (GetIntArgReg(usedIntSlots_, usedFloatSlots_, &r)) {
if (!from.isGeneralReg() || from.reg() != r) {
enoughMemory_ = moveResolver_.addMove(from, MoveOperand(r), MoveOp::GENERAL);
if (from.isGeneralReg() && from.reg() == r) {
// Nothing to do; the value is in the right register already
return;
}
// else nothing to do; the value is in the right register already
to = MoveOperand(r);
} else {
uint32_t disp = GetIntArgStackDisp(usedIntSlots_, usedFloatSlots_, &padding_);
enoughMemory_ = moveResolver_.addMove(from, MoveOperand(sp, disp), MoveOp::GENERAL);
to = MoveOperand(sp, disp);
}
usedIntSlots_++;
break;
@ -3549,6 +3552,7 @@ MacroAssemblerARMCompat::passABIArg(const MoveOperand &from, MoveOp::Kind kind)
MOZ_ASSUME_UNREACHABLE("Unexpected argument kind");
}
enoughMemory_ = moveResolver_.addMove(from, to, kind);
}
#else
@ -3566,6 +3570,7 @@ MacroAssemblerARMCompat::passABIArg(const MoveOperand &from, MoveOp::Kind kind)
usedSlots_ = (usedSlots_ + 1) & ~1;
increment = 2;
break;
case MoveOp::FLOAT32:
case MoveOp::GENERAL:
break;
default:
@ -3575,7 +3580,7 @@ MacroAssemblerARMCompat::passABIArg(const MoveOperand &from, MoveOp::Kind kind)
Register destReg;
MoveOperand dest;
if (GetIntArgReg(usedSlots_, 0, &destReg)) {
if (kind == MoveOp::DOUBLE) {
if (kind == MoveOp::DOUBLE || kind == MoveOp::FLOAT32) {
floatArgsInGPR[destReg.code() >> 1] = from;
floatArgsInGPRValid[destReg.code() >> 1] = true;
useResolver = false;

View File

@ -108,7 +108,9 @@ MoveEmitterARM::breakCycle(const MoveOperand &from, const MoveOperand &to, MoveO
//
// This case handles (A -> B), which we reach first. We save B, then allow
// the original move to continue.
if (kind == MoveOp::DOUBLE) {
switch (kind) {
case MoveOp::FLOAT32:
case MoveOp::DOUBLE:
if (to.isMemory()) {
FloatRegister temp = ScratchFloatReg;
masm.ma_vldr(toOperand(to, true), temp);
@ -116,7 +118,8 @@ MoveEmitterARM::breakCycle(const MoveOperand &from, const MoveOperand &to, MoveO
} else {
masm.ma_vstr(to.floatReg(), cycleSlot());
}
} else {
break;
case MoveOp::GENERAL:
// an non-vfp value
if (to.isMemory()) {
Register temp = tempReg();
@ -130,6 +133,9 @@ MoveEmitterARM::breakCycle(const MoveOperand &from, const MoveOperand &to, MoveO
}
masm.ma_str(to.reg(), cycleSlot());
}
break;
default:
MOZ_ASSUME_UNREACHABLE("Unexpected move kind");
}
}
@ -142,7 +148,9 @@ MoveEmitterARM::completeCycle(const MoveOperand &from, const MoveOperand &to, Mo
//
// This case handles (B -> A), which we reach last. We emit a move from the
// saved value of B, to A.
if (kind == MoveOp::DOUBLE) {
switch (kind) {
case MoveOp::FLOAT32:
case MoveOp::DOUBLE:
if (to.isMemory()) {
FloatRegister temp = ScratchFloatReg;
masm.ma_vldr(cycleSlot(), temp);
@ -150,7 +158,8 @@ MoveEmitterARM::completeCycle(const MoveOperand &from, const MoveOperand &to, Mo
} else {
masm.ma_vldr(cycleSlot(), to.floatReg());
}
} else {
break;
case MoveOp::GENERAL:
if (to.isMemory()) {
Register temp = tempReg();
masm.ma_ldr(cycleSlot(), temp);
@ -162,6 +171,9 @@ MoveEmitterARM::completeCycle(const MoveOperand &from, const MoveOperand &to, Mo
}
masm.ma_ldr(cycleSlot(), to.reg());
}
break;
default:
MOZ_ASSUME_UNREACHABLE("Unexpected move kind");
}
}
@ -248,10 +260,17 @@ MoveEmitterARM::emit(const MoveOp &move)
inCycle_ = true;
}
if (move.kind() == MoveOp::DOUBLE)
switch (move.kind()) {
case MoveOp::FLOAT32:
case MoveOp::DOUBLE:
emitDoubleMove(from, to);
else
break;
case MoveOp::GENERAL:
emitMove(from, to);
break;
default:
MOZ_ASSUME_UNREACHABLE("Unexpected move kind");
}
}
void

View File

@ -128,10 +128,17 @@ MoveEmitterX86::emit(const MoveResolver &moves)
}
// A normal move which is not part of a cycle.
if (move.kind() == MoveOp::DOUBLE)
switch (move.kind()) {
case MoveOp::FLOAT32:
case MoveOp::DOUBLE:
emitDoubleMove(from, to);
else
break;
case MoveOp::GENERAL:
emitGeneralMove(from, to);
break;
default:
MOZ_ASSUME_UNREACHABLE("Unexpected move kind");
}
}
}
@ -212,15 +219,21 @@ MoveEmitterX86::breakCycle(const MoveOperand &to, MoveOp::Kind kind)
//
// This case handles (A -> B), which we reach first. We save B, then allow
// the original move to continue.
if (kind == MoveOp::DOUBLE) {
switch (kind) {
case MoveOp::FLOAT32:
case MoveOp::DOUBLE:
if (to.isMemory()) {
masm.loadDouble(toAddress(to), ScratchFloatReg);
masm.storeDouble(ScratchFloatReg, cycleSlot());
} else {
masm.storeDouble(to.floatReg(), cycleSlot());
}
} else {
break;
case MoveOp::GENERAL:
masm.Push(toOperand(to));
break;
default:
MOZ_ASSUME_UNREACHABLE("Unexpected move kind");
}
}
@ -233,19 +246,25 @@ MoveEmitterX86::completeCycle(const MoveOperand &to, MoveOp::Kind kind)
//
// This case handles (B -> A), which we reach last. We emit a move from the
// saved value of B, to A.
if (kind == MoveOp::DOUBLE) {
switch (kind) {
case MoveOp::FLOAT32:
case MoveOp::DOUBLE:
if (to.isMemory()) {
masm.loadDouble(cycleSlot(), ScratchFloatReg);
masm.storeDouble(ScratchFloatReg, toAddress(to));
} else {
masm.loadDouble(cycleSlot(), to.floatReg());
}
} else {
break;
case MoveOp::GENERAL:
if (to.isMemory()) {
masm.Pop(toPopOperand(to));
} else {
masm.Pop(to.reg());
}
break;
default:
MOZ_ASSUME_UNREACHABLE("Unexpected move kind");
}
}

View File

@ -138,6 +138,7 @@ MacroAssemblerX64::passABIArg(const MoveOperand &from, MoveOp::Kind kind)
{
MoveOperand to;
switch (kind) {
case MoveOp::FLOAT32:
case MoveOp::DOUBLE: {
FloatRegister dest;
if (GetFloatArgReg(passedIntArgs_, passedFloatArgs_++, &dest)) {
@ -149,11 +150,11 @@ MacroAssemblerX64::passABIArg(const MoveOperand &from, MoveOp::Kind kind)
} else {
to = MoveOperand(StackPointer, stackForCall_);
switch (kind) {
case MoveOp::FLOAT32: stackForCall_ += sizeof(float); break;
case MoveOp::DOUBLE: stackForCall_ += sizeof(double); break;
default: MOZ_ASSUME_UNREACHABLE("Unexpected float register class argument kind");
}
}
enoughMemory_ = moveResolver_.addMove(from, to, MoveOp::DOUBLE);
break;
}
case MoveOp::GENERAL: {
@ -168,12 +169,13 @@ MacroAssemblerX64::passABIArg(const MoveOperand &from, MoveOp::Kind kind)
to = MoveOperand(StackPointer, stackForCall_);
stackForCall_ += sizeof(int64_t);
}
enoughMemory_ = moveResolver_.addMove(from, to, MoveOp::GENERAL);
break;
}
default:
MOZ_ASSUME_UNREACHABLE("Unexpected argument kind");
}
enoughMemory_ = moveResolver_.addMove(from, to, kind);
}
void

View File

@ -168,17 +168,12 @@ MacroAssemblerX86::passABIArg(const MoveOperand &from, MoveOp::Kind kind)
++passedArgs_;
MoveOperand to = MoveOperand(StackPointer, stackForCall_);
switch (kind) {
case MoveOp::DOUBLE:
stackForCall_ += sizeof(double);
enoughMemory_ &= moveResolver_.addMove(from, to, MoveOp::DOUBLE);
break;
case MoveOp::GENERAL:
stackForCall_ += sizeof(int32_t);
enoughMemory_ &= moveResolver_.addMove(from, to, MoveOp::GENERAL);
break;
default:
MOZ_ASSUME_UNREACHABLE("Unexpected argument kind");
case MoveOp::FLOAT32: stackForCall_ += sizeof(float); break;
case MoveOp::DOUBLE: stackForCall_ += sizeof(double); break;
case MoveOp::GENERAL: stackForCall_ += sizeof(int32_t); break;
default: MOZ_ASSUME_UNREACHABLE("Unexpected argument kind");
}
enoughMemory_ &= moveResolver_.addMove(from, to, kind);
}
void
@ -243,8 +238,7 @@ MacroAssemblerX86::callWithABIPost(uint32_t stackAdjust, MoveOp::Kind result)
fstp(Operand(esp, 0));
loadDouble(Operand(esp, 0), ReturnFloatReg);
freeStack(sizeof(double));
}
if (result == MoveOp::FLOAT32) {
} else if (result == MoveOp::FLOAT32) {
reserveStack(sizeof(float));
fstp32(Operand(esp, 0));
loadFloat(Operand(esp, 0), ReturnFloatReg);