mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1184959 part 4 - MIPS MoveEmitter: Add support for pairs of registers. r=rankov
This commit is contained in:
parent
a313c62745
commit
eb2bcc5d0d
@ -534,6 +534,12 @@ hasMultiAlias() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// In order to handle functions such as int(*)(int, double) where the first
|
||||
// argument is a general purpose register, and the second argument is a floating
|
||||
// point register, we have to store the double content into 2 general purpose
|
||||
// registers, namely a2 and a3.
|
||||
#define JS_CODEGEN_REGISTER_PAIR 1
|
||||
|
||||
// See the comments above AsmJSMappedSize in AsmJSValidate.h for more info.
|
||||
// TODO: Implement this for MIPS. Note that it requires Codegen to respect the
|
||||
// offset field of AsmJSHeapAccess.
|
||||
|
@ -23,18 +23,18 @@ using namespace js::jit;
|
||||
|
||||
ABIArgGenerator::ABIArgGenerator()
|
||||
: usedArgSlots_(0),
|
||||
firstArgFloat(false),
|
||||
firstArgFloatSize_(0),
|
||||
useGPRForFloats_(false),
|
||||
current_()
|
||||
{}
|
||||
|
||||
ABIArg
|
||||
ABIArgGenerator::next(MIRType type)
|
||||
{
|
||||
FloatRegister::RegType regType;
|
||||
Register destReg;
|
||||
switch (type) {
|
||||
case MIRType_Int32:
|
||||
case MIRType_Pointer:
|
||||
Register destReg;
|
||||
if (GetIntArgReg(usedArgSlots_, &destReg))
|
||||
current_ = ABIArg(destReg);
|
||||
else
|
||||
@ -42,19 +42,34 @@ ABIArgGenerator::next(MIRType type)
|
||||
usedArgSlots_++;
|
||||
break;
|
||||
case MIRType_Float32:
|
||||
case MIRType_Double:
|
||||
regType = (type == MIRType_Double ? FloatRegister::Double : FloatRegister::Single);
|
||||
if (!usedArgSlots_) {
|
||||
current_ = ABIArg(FloatRegister(FloatRegisters::f12, regType));
|
||||
usedArgSlots_ += 2;
|
||||
firstArgFloat = true;
|
||||
} else if (usedArgSlots_ <= 2) {
|
||||
// NOTE: We will use f14 always. This is not compatible with
|
||||
// system ABI. We will have to introduce some infrastructure
|
||||
// changes if we have to use system ABI here.
|
||||
current_ = ABIArg(FloatRegister(FloatRegisters::f14, regType));
|
||||
current_ = ABIArg(f12.asSingle());
|
||||
firstArgFloatSize_ = 1;
|
||||
} else if (usedArgSlots_ == firstArgFloatSize_) {
|
||||
current_ = ABIArg(f14.asSingle());
|
||||
} else if (useGPRForFloats_ && GetIntArgReg(usedArgSlots_, &destReg)) {
|
||||
current_ = ABIArg(destReg);
|
||||
} else {
|
||||
if (usedArgSlots_ < NumIntArgRegs)
|
||||
usedArgSlots_ = NumIntArgRegs;
|
||||
current_ = ABIArg(usedArgSlots_ * sizeof(intptr_t));
|
||||
}
|
||||
usedArgSlots_++;
|
||||
break;
|
||||
case MIRType_Double:
|
||||
if (!usedArgSlots_) {
|
||||
current_ = ABIArg(f12);
|
||||
usedArgSlots_ = 2;
|
||||
firstArgFloatSize_ = 2;
|
||||
} else if (usedArgSlots_ == firstArgFloatSize_) {
|
||||
current_ = ABIArg(f14);
|
||||
usedArgSlots_ = 4;
|
||||
} else if (useGPRForFloats_ && usedArgSlots_ <= 2) {
|
||||
current_ = ABIArg(a2, a3);
|
||||
usedArgSlots_ = 4;
|
||||
} else {
|
||||
if (usedArgSlots_ < NumIntArgRegs)
|
||||
usedArgSlots_ = NumIntArgRegs;
|
||||
usedArgSlots_ += usedArgSlots_ % 2;
|
||||
current_ = ABIArg(usedArgSlots_ * sizeof(intptr_t));
|
||||
usedArgSlots_ += 2;
|
||||
@ -64,8 +79,8 @@ ABIArgGenerator::next(MIRType type)
|
||||
MOZ_CRASH("Unexpected argument type");
|
||||
}
|
||||
return current_;
|
||||
|
||||
}
|
||||
|
||||
const Register ABIArgGenerator::NonArgReturnReg0 = t0;
|
||||
const Register ABIArgGenerator::NonArgReturnReg1 = t1;
|
||||
const Register ABIArgGenerator::NonArg_VolatileReg = v0;
|
||||
|
@ -80,7 +80,10 @@ static const uint32_t NumCallTempNonArgRegs = mozilla::ArrayLength(CallTempNonAr
|
||||
class ABIArgGenerator
|
||||
{
|
||||
unsigned usedArgSlots_;
|
||||
bool firstArgFloat;
|
||||
unsigned firstArgFloatSize_;
|
||||
// Note: This is not compliant with the system ABI. The Lowering phase
|
||||
// expects to lower an MAsmJSParameter to only one register.
|
||||
bool useGPRForFloats_;
|
||||
ABIArg current_;
|
||||
|
||||
public:
|
||||
@ -88,6 +91,10 @@ class ABIArgGenerator
|
||||
ABIArg next(MIRType argType);
|
||||
ABIArg& current() { return current_; }
|
||||
|
||||
void enforceO32ABI() {
|
||||
useGPRForFloats_ = true;
|
||||
}
|
||||
|
||||
uint32_t stackBytesConsumedSoFar() const {
|
||||
if (usedArgSlots_ <= 4)
|
||||
return ShadowStackSpace;
|
||||
|
@ -255,16 +255,14 @@ MoveEmitterMIPS::emitDoubleMove(const MoveOperand& from, const MoveOperand& to)
|
||||
if (from.isFloatReg()) {
|
||||
if (to.isFloatReg()) {
|
||||
masm.moveDouble(from.floatReg(), to.floatReg());
|
||||
} else if (to.isGeneralReg()) {
|
||||
} else if (to.isGeneralRegPair()) {
|
||||
// Used for passing double parameter in a2,a3 register pair.
|
||||
// Two moves are added for one double parameter by
|
||||
// MacroAssemblerMIPSCompat::passABIArg
|
||||
if(to.reg() == a2)
|
||||
masm.moveFromDoubleLo(from.floatReg(), a2);
|
||||
else if(to.reg() == a3)
|
||||
masm.moveFromDoubleHi(from.floatReg(), a3);
|
||||
else
|
||||
MOZ_CRASH("Invalid emitDoubleMove arguments.");
|
||||
// MacroAssembler::passABIArg
|
||||
MOZ_ASSERT(to.evenReg() == a2 && to.oddReg() == a3,
|
||||
"Invalid emitDoubleMove arguments.");
|
||||
masm.moveFromDoubleLo(from.floatReg(), a2);
|
||||
masm.moveFromDoubleHi(from.floatReg(), a3);
|
||||
} else {
|
||||
MOZ_ASSERT(to.isMemory());
|
||||
masm.storeDouble(from.floatReg(), getAdjustedAddress(to));
|
||||
@ -272,24 +270,15 @@ MoveEmitterMIPS::emitDoubleMove(const MoveOperand& from, const MoveOperand& to)
|
||||
} else if (to.isFloatReg()) {
|
||||
MOZ_ASSERT(from.isMemory());
|
||||
masm.loadDouble(getAdjustedAddress(from), to.floatReg());
|
||||
} else if (to.isGeneralReg()) {
|
||||
} else if (to.isGeneralRegPair()) {
|
||||
// Used for passing double parameter in a2,a3 register pair.
|
||||
// Two moves are added for one double parameter by
|
||||
// MacroAssemblerMIPSCompat::passABIArg
|
||||
if (from.isMemory()) {
|
||||
if(to.reg() == a2)
|
||||
masm.loadPtr(getAdjustedAddress(from), a2);
|
||||
else if(to.reg() == a3)
|
||||
masm.loadPtr(Address(from.base(), getAdjustedOffset(from) + sizeof(uint32_t)), a3);
|
||||
else
|
||||
MOZ_CRASH("Invalid emitDoubleMove arguments.");
|
||||
} else {
|
||||
// Used for moving a double parameter from the same source. See Bug 1123874.
|
||||
if(to.reg() == a2 || to.reg() == a3)
|
||||
masm.ma_move(to.reg(), from.reg());
|
||||
else
|
||||
MOZ_CRASH("Invalid emitDoubleMove arguments.");
|
||||
}
|
||||
// MacroAssembler::passABIArg
|
||||
MOZ_ASSERT(from.isMemory());
|
||||
MOZ_ASSERT(to.evenReg() == a2 && to.oddReg() == a3,
|
||||
"Invalid emitDoubleMove arguments.");
|
||||
masm.loadPtr(getAdjustedAddress(from), a2);
|
||||
masm.loadPtr(Address(from.base(), getAdjustedOffset(from) + sizeof(uint32_t)), a3);
|
||||
} else {
|
||||
MOZ_ASSERT(from.isMemory());
|
||||
MOZ_ASSERT(to.isMemory());
|
||||
|
Loading…
Reference in New Issue
Block a user