Bug 888578 - Extend ARM masm's floatArgsInGPR workaround to memory loads. r=mjrosenb

The move resolver doesn't understand using a pair of registers, which
we have to do on ARM softfp to pass doubles in the integer registers,
if they occur early enough in the argument list.  We had a workaround
(see uses of floatArgsInGPR) for when the argument is moved from a float
register; this change extends it to handle loading from memory.
This commit is contained in:
Jed Davis 2013-07-03 09:21:50 -04:00
Родитель 6f5a9609fd
Коммит 01058d2707
2 изменённых файлов: 32 добавлений и 6 удалений

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

@ -2995,8 +2995,10 @@ MacroAssemblerARMCompat::setupABICall(uint32_t args)
#else
usedSlots_ = 0;
#endif
floatArgsInGPR[0] = VFPRegister();
floatArgsInGPR[1] = VFPRegister();
floatArgsInGPR[0] = MoveOperand();
floatArgsInGPR[1] = MoveOperand();
floatArgsInGPRValid[0] = false;
floatArgsInGPRValid[1] = false;
}
void
@ -3081,7 +3083,8 @@ MacroAssemblerARMCompat::passABIArg(const MoveOperand &from)
MoveOperand dest;
if (GetIntArgReg(usedSlots_, 0, &destReg)) {
if (from.isDouble()) {
floatArgsInGPR[destReg.code() >> 1] = VFPRegister(from.floatReg());
floatArgsInGPR[destReg.code() >> 1] = from;
floatArgsInGPRValid[destReg.code() >> 1] = true;
useResolver = false;
} else if (from.isGeneralReg() && from.reg() == destReg) {
// No need to move anything
@ -3150,8 +3153,26 @@ MacroAssemblerARMCompat::callWithABIPre(uint32_t *stackAdjust)
emitter.finish();
}
for (int i = 0; i < 2; i++) {
if (!floatArgsInGPR[i].isInvalid())
ma_vxfer(floatArgsInGPR[i], Register::FromCode(i*2), Register::FromCode(i*2+1));
if (floatArgsInGPRValid[i]) {
MoveOperand from = floatArgsInGPR[i];
Register to0 = Register::FromCode(i * 2), to1 = Register::FromCode(i * 2 + 1);
if (from.isFloatReg()) {
ma_vxfer(VFPRegister(from.floatReg()), to0, to1);
} else {
JS_ASSERT(from.isFloatAddress());
// Note: We can safely use the MoveOperand's displacement here,
// even if the base is SP: MoveEmitter::toOperand adjusts
// SP-relative operands by the difference between the current
// stack usage and stackAdjust, which emitter.finish() resets
// to 0.
//
// Warning: if the offset isn't within [-255,+255] then this
// will assert-fail (or, if non-debug, load the wrong words).
// Nothing uses such an offset at the time of this writing.
ma_ldrd(EDtrAddr(from.base(), EDtrOffImm(from.disp())), to0, to1);
}
}
}
checkStackAlignment();

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

@ -420,7 +420,12 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
bool dynamicAlignment_;
bool enoughMemory_;
VFPRegister floatArgsInGPR[2];
// Used to work around the move resolver's lack of support for
// moving into register pairs, which the softfp ABI needs.
MoveResolver::MoveOperand floatArgsInGPR[2];
bool floatArgsInGPRValid[2];
// Compute space needed for the function call and set the properties of the
// callee. It returns the space which has to be allocated for calling the
// function.