Bug 949668 - SpiderMonkey: Enum simplification. r=jandem

This commit is contained in:
Dan Gohman 2013-12-13 08:27:47 -08:00
parent cf80b63f42
commit d6a58ddb0b
17 changed files with 204 additions and 183 deletions

View File

@ -2841,9 +2841,9 @@ ICBinaryArith_Double::Compiler::generateStubCode(MacroAssembler &masm)
break;
case JSOP_MOD:
masm.setupUnalignedABICall(2, R0.scratchReg());
masm.passABIArg(FloatReg0);
masm.passABIArg(FloatReg1);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, NumberMod), MacroAssembler::DOUBLE);
masm.passABIArg(FloatReg0, MoveOp::DOUBLE);
masm.passABIArg(FloatReg1, MoveOp::DOUBLE);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, NumberMod), MoveOp::DOUBLE);
JS_ASSERT(ReturnFloatReg == FloatReg0);
break;
default:
@ -2968,7 +2968,7 @@ ICBinaryArith_DoubleWithInt32::Compiler::generateStubCode(MacroAssembler &masm)
masm.bind(&truncateABICall);
masm.push(intReg);
masm.setupUnalignedABICall(1, scratchReg);
masm.passABIArg(FloatReg0);
masm.passABIArg(FloatReg0, MoveOp::DOUBLE);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::ToInt32));
masm.storeCallResult(scratchReg);
masm.pop(intReg);
@ -3117,7 +3117,7 @@ ICUnaryArith_Double::Compiler::generateStubCode(MacroAssembler &masm)
masm.bind(&truncateABICall);
masm.setupUnalignedABICall(1, scratchReg);
masm.passABIArg(FloatReg0);
masm.passABIArg(FloatReg0, MoveOp::DOUBLE);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::ToInt32));
masm.storeCallResult(scratchReg);

View File

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mnde: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -1177,13 +1177,28 @@ CodeGenerator::visitMoveGroup(LMoveGroup *group)
const LAllocation *from = move.from();
const LAllocation *to = move.to();
LDefinition::Type type = move.type();
// No bogus moves.
JS_ASSERT(*from != *to);
JS_ASSERT(!from->isConstant());
JS_ASSERT(from->isDouble() == to->isDouble());
MoveOp::Kind kind = from->isDouble() ? MoveOp::DOUBLE : MoveOp::GENERAL;
MoveOp::Kind kind;
switch (type) {
case LDefinition::OBJECT:
case LDefinition::SLOTS:
#ifdef JS_NUNBOX32
case LDefinition::TYPE:
case LDefinition::PAYLOAD:
#else
case LDefinition::BOX:
#endif
case LDefinition::GENERAL: kind = MoveOp::GENERAL; break;
case LDefinition::FLOAT32:
case LDefinition::DOUBLE: kind = MoveOp::DOUBLE; break;
default: MOZ_ASSUME_UNREACHABLE("Unexpected move type");
}
if (!resolver.addMove(toMoveOperand(from), toMoveOperand(to), kind))
return false;
@ -3035,9 +3050,9 @@ bool CodeGenerator::visitAtan2D(LAtan2D *lir)
FloatRegister x = ToFloatRegister(lir->x());
masm.setupUnalignedABICall(2, temp);
masm.passABIArg(y);
masm.passABIArg(x);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaAtan2), MacroAssembler::DOUBLE);
masm.passABIArg(y, MoveOp::DOUBLE);
masm.passABIArg(x, MoveOp::DOUBLE);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaAtan2), MoveOp::DOUBLE);
JS_ASSERT(ToFloatRegister(lir->output()) == ReturnFloatReg);
return true;
@ -3050,9 +3065,9 @@ bool CodeGenerator::visitHypot(LHypot *lir)
FloatRegister y = ToFloatRegister(lir->y());
masm.setupUnalignedABICall(2, temp);
masm.passABIArg(x);
masm.passABIArg(y);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaHypot), MacroAssembler::DOUBLE);
masm.passABIArg(x, MoveOp::DOUBLE);
masm.passABIArg(y, MoveOp::DOUBLE);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaHypot), MoveOp::DOUBLE);
JS_ASSERT(ToFloatRegister(lir->output()) == ReturnFloatReg);
return true;
@ -3791,10 +3806,10 @@ CodeGenerator::visitPowI(LPowI *ins)
// its scratch register. We can therefore save an input register by
// reusing the scratch register to pass constants to callWithABI.
masm.setupUnalignedABICall(2, temp);
masm.passABIArg(value);
masm.passABIArg(value, MoveOp::DOUBLE);
masm.passABIArg(power);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::powi), MacroAssembler::DOUBLE);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::powi), MoveOp::DOUBLE);
JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg);
return true;
@ -3808,9 +3823,9 @@ CodeGenerator::visitPowD(LPowD *ins)
Register temp = ToRegister(ins->temp());
masm.setupUnalignedABICall(2, temp);
masm.passABIArg(value);
masm.passABIArg(power);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaPow), MacroAssembler::DOUBLE);
masm.passABIArg(value, MoveOp::DOUBLE);
masm.passABIArg(power, MoveOp::DOUBLE);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaPow), MoveOp::DOUBLE);
JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg);
return true;
@ -3826,7 +3841,7 @@ CodeGenerator::visitRandom(LRandom *ins)
masm.setupUnalignedABICall(1, temp2);
masm.passABIArg(temp);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, math_random_no_outparam), MacroAssembler::DOUBLE);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, math_random_no_outparam), MoveOp::DOUBLE);
JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg);
return true;
@ -3846,7 +3861,7 @@ CodeGenerator::visitMathFunctionD(LMathFunctionD *ins)
masm.movePtr(ImmPtr(mathCache), temp);
masm.passABIArg(temp);
}
masm.passABIArg(input);
masm.passABIArg(input, MoveOp::DOUBLE);
# define MAYBE_CACHED(fcn) (mathCache ? (void*)fcn ## _impl : (void*)fcn ## _uncached)
@ -3927,7 +3942,7 @@ CodeGenerator::visitMathFunctionD(LMathFunctionD *ins)
# undef MAYBE_CACHED
masm.callWithABI(funptr, MacroAssembler::DOUBLE);
masm.callWithABI(funptr, MoveOp::DOUBLE);
return true;
}
@ -3939,7 +3954,7 @@ CodeGenerator::visitMathFunctionF(LMathFunctionF *ins)
JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg);
masm.setupUnalignedABICall(1, temp);
masm.passABIArg(input);
masm.passABIArg(input, MoveOp::DOUBLE);
void *funptr = nullptr;
switch (ins->mir()->function()) {
@ -3956,7 +3971,7 @@ CodeGenerator::visitMathFunctionF(LMathFunctionF *ins)
MOZ_ASSUME_UNREACHABLE("Unknown or unsupported float32 math function");
}
masm.callWithABI(funptr, MacroAssembler::FLOAT);
masm.callWithABI(funptr, MoveOp::DOUBLE);
return true;
}
@ -3970,13 +3985,13 @@ CodeGenerator::visitModD(LModD *ins)
JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg);
masm.setupUnalignedABICall(2, temp);
masm.passABIArg(lhs);
masm.passABIArg(rhs);
masm.passABIArg(lhs, MoveOp::DOUBLE);
masm.passABIArg(rhs, MoveOp::DOUBLE);
if (gen->compilingAsmJS())
masm.callWithABI(AsmJSImm_ModD, MacroAssembler::DOUBLE);
masm.callWithABI(AsmJSImm_ModD, MoveOp::DOUBLE);
else
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, NumberMod), MacroAssembler::DOUBLE);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, NumberMod), MoveOp::DOUBLE);
return true;
}

View File

@ -865,12 +865,12 @@ class MacroAssembler : public MacroAssemblerSpecific
// been made so that a safepoint can be made at that location.
template <typename T>
void callWithABINoProfiling(const T &fun, Result result = GENERAL) {
void callWithABINoProfiling(const T &fun, MoveOp::Kind result = MoveOp::GENERAL) {
MacroAssemblerSpecific::callWithABI(fun, result);
}
template <typename T>
void callWithABI(const T &fun, Result result = GENERAL) {
void callWithABI(const T &fun, MoveOp::Kind result = MoveOp::GENERAL) {
leaveSPSFrame();
callWithABINoProfiling(fun, result);
reenterSPSFrame();

View File

@ -18,38 +18,39 @@ namespace jit {
// guaranteed that Operand looks like this on all ISAs.
class MoveOperand
{
public:
enum Kind {
// A register in the "integer", aka "general purpose", class.
REG,
// A register in the "float" register class.
FLOAT_REG,
ADDRESS,
FLOAT_ADDRESS,
// A memory region.
MEMORY,
// The address of a memory region.
EFFECTIVE_ADDRESS
};
private:
Kind kind_;
uint32_t code_;
int32_t disp_;
public:
enum AddressKind {
MEMORY = ADDRESS,
EFFECTIVE = EFFECTIVE_ADDRESS,
FLOAT = FLOAT_ADDRESS
};
MoveOperand()
{ }
explicit MoveOperand(const Register &reg) : kind_(REG), code_(reg.code())
{ }
explicit MoveOperand(const FloatRegister &reg) : kind_(FLOAT_REG), code_(reg.code())
{ }
MoveOperand(const Register &reg, int32_t disp, AddressKind addrKind = MEMORY)
: kind_((Kind) addrKind),
MoveOperand(const Register &reg, int32_t disp, Kind kind = MEMORY)
: kind_(kind),
code_(reg.code()),
disp_(disp)
{
JS_ASSERT(isMemoryOrEffectiveAddress());
// With a zero offset, this is a plain reg-to-reg move.
if (disp == 0 && addrKind == EFFECTIVE)
if (disp == 0 && kind_ == EFFECTIVE_ADDRESS)
kind_ = REG;
}
MoveOperand(const MoveOperand &other)
@ -63,18 +64,15 @@ class MoveOperand
bool isGeneralReg() const {
return kind_ == REG;
}
bool isDouble() const {
return kind_ == FLOAT_REG || kind_ == FLOAT_ADDRESS;
}
bool isMemory() const {
return kind_ == ADDRESS;
}
bool isFloatAddress() const {
return kind_ == FLOAT_ADDRESS;
return kind_ == MEMORY;
}
bool isEffectiveAddress() const {
return kind_ == EFFECTIVE_ADDRESS;
}
bool isMemoryOrEffectiveAddress() const {
return isMemory() || isEffectiveAddress();
}
Register reg() const {
JS_ASSERT(isGeneralReg());
return Register::FromCode(code_);
@ -84,10 +82,11 @@ class MoveOperand
return FloatRegister::FromCode(code_);
}
Register base() const {
JS_ASSERT(isMemory() || isEffectiveAddress() || isFloatAddress());
JS_ASSERT(isMemoryOrEffectiveAddress());
return Register::FromCode(code_);
}
int32_t disp() const {
JS_ASSERT(isMemoryOrEffectiveAddress());
return disp_;
}
@ -96,7 +95,7 @@ class MoveOperand
return false;
if (code_ != other.code_)
return false;
if (isMemory() || isEffectiveAddress())
if (isMemoryOrEffectiveAddress())
return disp_ == other.disp_;
return true;
}

View File

@ -3508,13 +3508,14 @@ MacroAssemblerARMCompat::setupUnalignedABICall(uint32_t args, const Register &sc
}
#ifdef JS_CPU_ARM_HARDFP
void
MacroAssemblerARMCompat::passABIArg(const MoveOperand &from)
MacroAssemblerARMCompat::passABIArg(const MoveOperand &from, MoveOp::Kind kind)
{
MoveOperand to;
++passedArgs_;
if (!enoughMemory_)
return;
if (from.isDouble()) {
switch (kind) {
case MoveOp::DOUBLE: {
FloatRegister fr;
if (GetFloatArgReg(usedIntSlots_, usedFloatSlots_, &fr)) {
if (!from.isFloatReg() || from.floatReg() != fr) {
@ -3528,7 +3529,9 @@ MacroAssemblerARMCompat::passABIArg(const MoveOperand &from)
enoughMemory_ = moveResolver_.addMove(from, MoveOperand(sp, disp), MoveOp::DOUBLE);
}
usedFloatSlots_++;
} else {
break;
}
case MoveOp::GENERAL: {
Register r;
if (GetIntArgReg(usedIntSlots_, usedFloatSlots_, &r)) {
if (!from.isGeneralReg() || from.reg() != r) {
@ -3540,31 +3543,39 @@ MacroAssemblerARMCompat::passABIArg(const MoveOperand &from)
enoughMemory_ = moveResolver_.addMove(from, MoveOperand(sp, disp), MoveOp::GENERAL);
}
usedIntSlots_++;
break;
}
default:
MOZ_ASSUME_UNREACHABLE("Unexpected argument kind");
}
}
#else
void
MacroAssemblerARMCompat::passABIArg(const MoveOperand &from)
MacroAssemblerARMCompat::passABIArg(const MoveOperand &from, MoveOp::Kind kind)
{
MoveOperand to;
uint32_t increment = 1;
bool useResolver = true;
++passedArgs_;
MoveOp::Kind kind = MoveOp::GENERAL;
if (from.isDouble()) {
switch (kind) {
case MoveOp::DOUBLE:
// Double arguments need to be rounded up to the nearest doubleword
// boundary, even if it is in a register!
usedSlots_ = (usedSlots_ + 1) & ~1;
increment = 2;
kind = MoveOp::DOUBLE;
break;
case MoveOp::GENERAL:
break;
default:
MOZ_ASSUME_UNREACHABLE("Unexpected argument kind");
}
Register destReg;
MoveOperand dest;
if (GetIntArgReg(usedSlots_, 0, &destReg)) {
if (from.isDouble()) {
if (kind == MoveOp::DOUBLE) {
floatArgsInGPR[destReg.code() >> 1] = from;
floatArgsInGPRValid[destReg.code() >> 1] = true;
useResolver = false;
@ -3588,13 +3599,13 @@ MacroAssemblerARMCompat::passABIArg(const MoveOperand &from)
void
MacroAssemblerARMCompat::passABIArg(const Register &reg)
{
passABIArg(MoveOperand(reg));
passABIArg(MoveOperand(reg), MoveOp::GENERAL);
}
void
MacroAssemblerARMCompat::passABIArg(const FloatRegister &freg)
MacroAssemblerARMCompat::passABIArg(const FloatRegister &freg, MoveOp::Kind kind)
{
passABIArg(MoveOperand(freg));
passABIArg(MoveOperand(freg), kind);
}
void MacroAssemblerARMCompat::checkStackAlignment()
@ -3642,7 +3653,7 @@ MacroAssemblerARMCompat::callWithABIPre(uint32_t *stackAdjust)
if (from.isFloatReg()) {
ma_vxfer(VFPRegister(from.floatReg()), to0, to1);
} else {
JS_ASSERT(from.isFloatAddress());
JS_ASSERT(from.isMemory());
// 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
@ -3664,25 +3675,25 @@ MacroAssemblerARMCompat::callWithABIPre(uint32_t *stackAdjust)
}
void
MacroAssemblerARMCompat::callWithABIPost(uint32_t stackAdjust, Result result)
MacroAssemblerARMCompat::callWithABIPost(uint32_t stackAdjust, MoveOp::Kind result)
{
if (secondScratchReg_ != lr)
ma_mov(secondScratchReg_, lr);
switch (result) {
case DOUBLE:
case MoveOp::DOUBLE:
#ifndef JS_CPU_ARM_HARDFP
// Move double from r0/r1 to ReturnFloatReg.
as_vxfer(r0, r1, ReturnFloatReg, CoreToFloat);
break;
#endif
case FLOAT:
case MoveOp::FLOAT32:
#ifndef JS_CPU_ARM_HARDFP
// Move float32 from r0 to ReturnFloatReg.
as_vxfer(r0, InvalidReg, VFPRegister(d0).singleOverlay(), CoreToFloat);
break;
#endif
case GENERAL:
case MoveOp::GENERAL:
break;
default:
@ -3702,7 +3713,7 @@ MacroAssemblerARMCompat::callWithABIPost(uint32_t stackAdjust, Result result)
}
void
MacroAssemblerARMCompat::callWithABI(void *fun, Result result)
MacroAssemblerARMCompat::callWithABI(void *fun, MoveOp::Kind result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
@ -3711,7 +3722,7 @@ MacroAssemblerARMCompat::callWithABI(void *fun, Result result)
}
void
MacroAssemblerARMCompat::callWithABI(AsmJSImmPtr imm, Result result)
MacroAssemblerARMCompat::callWithABI(AsmJSImmPtr imm, MoveOp::Kind result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
@ -3720,7 +3731,7 @@ MacroAssemblerARMCompat::callWithABI(AsmJSImmPtr imm, Result result)
}
void
MacroAssemblerARMCompat::callWithABI(const Address &fun, Result result)
MacroAssemblerARMCompat::callWithABI(const Address &fun, MoveOp::Kind result)
{
// Load the callee in r12, no instruction between the ldr and call
// should clobber it. Note that we can't use fun.base because it may

View File

@ -485,12 +485,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
setFramePushed(framePushed_ + value);
}
public:
enum Result {
GENERAL,
DOUBLE,
FLOAT
};
MacroAssemblerARMCompat()
: inCall_(false),
enoughMemory_(true),
@ -1409,9 +1403,9 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
// automatically adjusted. It is extremely important that esp-relative
// addresses are computed *after* setupABICall(). Furthermore, no
// operations should be emitted while setting arguments.
void passABIArg(const MoveOperand &from);
void passABIArg(const MoveOperand &from, MoveOp::Kind kind);
void passABIArg(const Register &reg);
void passABIArg(const FloatRegister &reg);
void passABIArg(const FloatRegister &reg, MoveOp::Kind kind);
void passABIArg(const ValueOperand &regs);
protected:
@ -1419,13 +1413,13 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
private:
void callWithABIPre(uint32_t *stackAdjust);
void callWithABIPost(uint32_t stackAdjust, Result result);
void callWithABIPost(uint32_t stackAdjust, MoveOp::Kind result);
public:
// Emits a call to a C/C++ function, resolving all argument moves.
void callWithABI(void *fun, Result result = GENERAL);
void callWithABI(AsmJSImmPtr imm, Result result = GENERAL);
void callWithABI(const Address &fun, Result result = GENERAL);
void callWithABI(void *fun, MoveOp::Kind result = MoveOp::GENERAL);
void callWithABI(AsmJSImmPtr imm, MoveOp::Kind result = MoveOp::GENERAL);
void callWithABI(const Address &fun, MoveOp::Kind result = MoveOp::GENERAL);
CodeOffsetLabel labelForPatch() {
return CodeOffsetLabel(nextOffset().getOffset());

View File

@ -58,7 +58,7 @@ MoveEmitterARM::spillSlot() const
Operand
MoveEmitterARM::toOperand(const MoveOperand &operand, bool isFloat) const
{
if (operand.isMemory() || operand.isEffectiveAddress() || operand.isFloatAddress()) {
if (operand.isMemoryOrEffectiveAddress()) {
if (operand.base() != StackPointer) {
JS_ASSERT(operand.disp() < 1024 && operand.disp() > -1024);
return Operand(operand.base(), operand.disp());
@ -193,7 +193,7 @@ MoveEmitterARM::emitMove(const MoveOperand &from, const MoveOperand &to)
MOZ_ASSUME_UNREACHABLE("strange move!");
}
} else if (to.isGeneralReg()) {
JS_ASSERT(from.isMemory() || from.isEffectiveAddress());
JS_ASSERT(from.isMemoryOrEffectiveAddress());
if (from.isMemory())
masm.ma_ldr(toOperand(from, false), to.reg());
else
@ -202,7 +202,7 @@ MoveEmitterARM::emitMove(const MoveOperand &from, const MoveOperand &to)
// Memory to memory gpr move.
Register reg = tempReg();
JS_ASSERT(from.isMemory() || from.isEffectiveAddress());
JS_ASSERT(from.isMemoryOrEffectiveAddress());
if (from.isMemory())
masm.ma_ldr(toOperand(from, false), reg);
else

View File

@ -735,22 +735,22 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
MoveOperand from;
switch (f.argProperties(explicitArg)) {
case VMFunction::WordByValue:
masm.passABIArg(MoveOperand(argsBase, argDisp));
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL);
argDisp += sizeof(void *);
break;
case VMFunction::DoubleByValue:
// Values should be passed by reference, not by value, so we
// assert that the argument is a double-precision float.
JS_ASSERT(f.argPassedInFloatReg(explicitArg));
masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::FLOAT));
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::DOUBLE);
argDisp += sizeof(double);
break;
case VMFunction::WordByRef:
masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE));
masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS), MoveOp::GENERAL);
argDisp += sizeof(void *);
break;
case VMFunction::DoubleByRef:
masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE));
masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS), MoveOp::GENERAL);
argDisp += 2 * sizeof(void *);
break;
}

View File

@ -768,7 +768,7 @@ CodeGeneratorShared::visitOutOfLineTruncateSlow(OutOfLineTruncateSlow *ool)
}
masm.setupUnalignedABICall(1, dest);
masm.passABIArg(src);
masm.passABIArg(src, MoveOp::DOUBLE);
if (gen->compilingAsmJS())
masm.callWithABI(AsmJSImm_ToInt32);
else

View File

@ -170,7 +170,7 @@ MoveEmitterX86::toAddress(const MoveOperand &operand) const
Operand
MoveEmitterX86::toOperand(const MoveOperand &operand) const
{
if (operand.isMemory() || operand.isEffectiveAddress() || operand.isFloatAddress())
if (operand.isMemoryOrEffectiveAddress())
return Operand(toAddress(operand));
if (operand.isGeneralReg())
return Operand(operand.reg());
@ -255,7 +255,7 @@ MoveEmitterX86::emitGeneralMove(const MoveOperand &from, const MoveOperand &to)
if (from.isGeneralReg()) {
masm.mov(from.reg(), toOperand(to));
} else if (to.isGeneralReg()) {
JS_ASSERT(from.isMemory() || from.isEffectiveAddress());
JS_ASSERT(from.isMemoryOrEffectiveAddress());
if (from.isMemory())
masm.loadPtr(toAddress(from), to.reg());
else

View File

@ -134,10 +134,11 @@ MacroAssemblerX64::setupUnalignedABICall(uint32_t args, const Register &scratch)
}
void
MacroAssemblerX64::passABIArg(const MoveOperand &from)
MacroAssemblerX64::passABIArg(const MoveOperand &from, MoveOp::Kind kind)
{
MoveOperand to;
if (from.isDouble()) {
switch (kind) {
case MoveOp::DOUBLE: {
FloatRegister dest;
if (GetFloatArgReg(passedIntArgs_, passedFloatArgs_++, &dest)) {
if (from.isFloatReg() && from.floatReg() == dest) {
@ -147,10 +148,15 @@ MacroAssemblerX64::passABIArg(const MoveOperand &from)
to = MoveOperand(dest);
} else {
to = MoveOperand(StackPointer, stackForCall_);
stackForCall_ += sizeof(double);
switch (kind) {
case MoveOp::DOUBLE: stackForCall_ += sizeof(double); break;
default: MOZ_ASSUME_UNREACHABLE("Unexpected float register class argument kind");
}
}
enoughMemory_ = moveResolver_.addMove(from, to, MoveOp::DOUBLE);
} else {
break;
}
case MoveOp::GENERAL: {
Register dest;
if (GetIntArgReg(passedIntArgs_++, passedFloatArgs_, &dest)) {
if (from.isGeneralReg() && from.reg() == dest) {
@ -163,19 +169,23 @@ MacroAssemblerX64::passABIArg(const MoveOperand &from)
stackForCall_ += sizeof(int64_t);
}
enoughMemory_ = moveResolver_.addMove(from, to, MoveOp::GENERAL);
break;
}
default:
MOZ_ASSUME_UNREACHABLE("Unexpected argument kind");
}
}
void
MacroAssemblerX64::passABIArg(const Register &reg)
{
passABIArg(MoveOperand(reg));
passABIArg(MoveOperand(reg), MoveOp::GENERAL);
}
void
MacroAssemblerX64::passABIArg(const FloatRegister &reg)
MacroAssemblerX64::passABIArg(const FloatRegister &reg, MoveOp::Kind kind)
{
passABIArg(MoveOperand(reg));
passABIArg(MoveOperand(reg), kind);
}
void
@ -219,7 +229,7 @@ MacroAssemblerX64::callWithABIPre(uint32_t *stackAdjust)
}
void
MacroAssemblerX64::callWithABIPost(uint32_t stackAdjust, Result result)
MacroAssemblerX64::callWithABIPost(uint32_t stackAdjust, MoveOp::Kind result)
{
freeStack(stackAdjust);
if (dynamicAlignment_)
@ -230,7 +240,7 @@ MacroAssemblerX64::callWithABIPost(uint32_t stackAdjust, Result result)
}
void
MacroAssemblerX64::callWithABI(void *fun, Result result)
MacroAssemblerX64::callWithABI(void *fun, MoveOp::Kind result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
@ -239,7 +249,7 @@ MacroAssemblerX64::callWithABI(void *fun, Result result)
}
void
MacroAssemblerX64::callWithABI(AsmJSImmPtr imm, Result result)
MacroAssemblerX64::callWithABI(AsmJSImmPtr imm, MoveOp::Kind result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
@ -259,7 +269,7 @@ IsIntArgReg(Register reg)
}
void
MacroAssemblerX64::callWithABI(Address fun, Result result)
MacroAssemblerX64::callWithABI(Address fun, MoveOp::Kind result)
{
if (IsIntArgReg(fun.base)) {
// Callee register may be clobbered for an argument. Move the callee to

View File

@ -79,12 +79,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
using MacroAssemblerX86Shared::callWithExitFrame;
using MacroAssemblerX86Shared::branch32;
enum Result {
GENERAL,
DOUBLE,
FLOAT
};
MacroAssemblerX64()
: inCall_(false),
enoughMemory_(true)
@ -1199,19 +1193,19 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
// automatically adjusted. It is extremely important that esp-relative
// addresses are computed *after* setupABICall(). Furthermore, no
// operations should be emitted while setting arguments.
void passABIArg(const MoveOperand &from);
void passABIArg(const MoveOperand &from, MoveOp::Kind kind);
void passABIArg(const Register &reg);
void passABIArg(const FloatRegister &reg);
void passABIArg(const FloatRegister &reg, MoveOp::Kind kind);
private:
void callWithABIPre(uint32_t *stackAdjust);
void callWithABIPost(uint32_t stackAdjust, Result result);
void callWithABIPost(uint32_t stackAdjust, MoveOp::Kind result);
public:
// Emits a call to a C/C++ function, resolving all argument moves.
void callWithABI(void *fun, Result result = GENERAL);
void callWithABI(AsmJSImmPtr imm, Result result = GENERAL);
void callWithABI(Address fun, Result result = GENERAL);
void callWithABI(void *fun, MoveOp::Kind result = MoveOp::GENERAL);
void callWithABI(AsmJSImmPtr imm, MoveOp::Kind result = MoveOp::GENERAL);
void callWithABI(Address fun, MoveOp::Kind result = MoveOp::GENERAL);
void handleFailureWithHandler(void *handler);
void handleFailureWithHandlerTail();

View File

@ -586,25 +586,24 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
size_t argDisp = 0;
// Copy arguments.
if (f.explicitArgs) {
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
MoveOperand from;
switch (f.argProperties(explicitArg)) {
case VMFunction::WordByValue:
if (f.argPassedInFloatReg(explicitArg))
masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::FLOAT));
else
masm.passABIArg(MoveOperand(argsBase, argDisp));
argDisp += sizeof(void *);
break;
case VMFunction::WordByRef:
masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE));
argDisp += sizeof(void *);
break;
case VMFunction::DoubleByValue:
case VMFunction::DoubleByRef:
MOZ_ASSUME_UNREACHABLE("NYI: x64 callVM should not be used with 128bits values.");
}
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
MoveOperand from;
switch (f.argProperties(explicitArg)) {
case VMFunction::WordByValue:
if (f.argPassedInFloatReg(explicitArg))
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::DOUBLE);
else
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL);
argDisp += sizeof(void *);
break;
case VMFunction::WordByRef:
masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
MoveOp::GENERAL);
argDisp += sizeof(void *);
break;
case VMFunction::DoubleByValue:
case VMFunction::DoubleByRef:
MOZ_ASSUME_UNREACHABLE("NYI: x64 callVM should not be used with 128bits values.");
}
}

View File

@ -900,7 +900,7 @@ CodeGeneratorX86::visitOutOfLineTruncate(OutOfLineTruncate *ool)
saveVolatile(output);
masm.setupUnalignedABICall(1, output);
masm.passABIArg(input);
masm.passABIArg(input, MoveOp::DOUBLE);
if (gen->compilingAsmJS())
masm.callWithABI(AsmJSImm_ToInt32);
else
@ -991,7 +991,7 @@ CodeGeneratorX86::visitOutOfLineTruncateFloat32(OutOfLineTruncateFloat32 *ool)
masm.push(input);
masm.setupUnalignedABICall(1, output);
masm.cvtss2sd(input, input);
masm.passABIArg(input);
masm.passABIArg(input, MoveOp::DOUBLE);
if (gen->compilingAsmJS())
masm.callWithABI(AsmJSImm_ToInt32);

View File

@ -163,29 +163,34 @@ MacroAssemblerX86::setupUnalignedABICall(uint32_t args, const Register &scratch)
}
void
MacroAssemblerX86::passABIArg(const MoveOperand &from)
MacroAssemblerX86::passABIArg(const MoveOperand &from, MoveOp::Kind kind)
{
++passedArgs_;
MoveOperand to = MoveOperand(StackPointer, stackForCall_);
if (from.isDouble()) {
switch (kind) {
case MoveOp::DOUBLE:
stackForCall_ += sizeof(double);
enoughMemory_ &= moveResolver_.addMove(from, to, MoveOp::DOUBLE);
} else {
break;
case MoveOp::GENERAL:
stackForCall_ += sizeof(int32_t);
enoughMemory_ &= moveResolver_.addMove(from, to, MoveOp::GENERAL);
break;
default:
MOZ_ASSUME_UNREACHABLE("Unexpected argument kind");
}
}
void
MacroAssemblerX86::passABIArg(const Register &reg)
{
passABIArg(MoveOperand(reg));
passABIArg(MoveOperand(reg), MoveOp::GENERAL);
}
void
MacroAssemblerX86::passABIArg(const FloatRegister &reg)
MacroAssemblerX86::passABIArg(const FloatRegister &reg, MoveOp::Kind kind)
{
passABIArg(MoveOperand(reg));
passABIArg(MoveOperand(reg), kind);
}
void
@ -230,16 +235,16 @@ MacroAssemblerX86::callWithABIPre(uint32_t *stackAdjust)
}
void
MacroAssemblerX86::callWithABIPost(uint32_t stackAdjust, Result result)
MacroAssemblerX86::callWithABIPost(uint32_t stackAdjust, MoveOp::Kind result)
{
freeStack(stackAdjust);
if (result == DOUBLE) {
if (result == MoveOp::DOUBLE) {
reserveStack(sizeof(double));
fstp(Operand(esp, 0));
loadDouble(Operand(esp, 0), ReturnFloatReg);
freeStack(sizeof(double));
}
if (result == FLOAT) {
if (result == MoveOp::FLOAT32) {
reserveStack(sizeof(float));
fstp32(Operand(esp, 0));
loadFloat(Operand(esp, 0), ReturnFloatReg);
@ -253,7 +258,7 @@ MacroAssemblerX86::callWithABIPost(uint32_t stackAdjust, Result result)
}
void
MacroAssemblerX86::callWithABI(void *fun, Result result)
MacroAssemblerX86::callWithABI(void *fun, MoveOp::Kind result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
@ -262,7 +267,7 @@ MacroAssemblerX86::callWithABI(void *fun, Result result)
}
void
MacroAssemblerX86::callWithABI(AsmJSImmPtr fun, Result result)
MacroAssemblerX86::callWithABI(AsmJSImmPtr fun, MoveOp::Kind result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
@ -271,7 +276,7 @@ MacroAssemblerX86::callWithABI(AsmJSImmPtr fun, Result result)
}
void
MacroAssemblerX86::callWithABI(const Address &fun, Result result)
MacroAssemblerX86::callWithABI(const Address &fun, MoveOp::Kind result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);

View File

@ -70,12 +70,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
using MacroAssemblerX86Shared::callWithExitFrame;
using MacroAssemblerX86Shared::branch32;
enum Result {
GENERAL,
DOUBLE,
FLOAT
};
MacroAssemblerX86()
: inCall_(false),
enoughMemory_(true)
@ -1043,19 +1037,19 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
// automatically adjusted. It is extremely important that esp-relative
// addresses are computed *after* setupABICall(). Furthermore, no
// operations should be emitted while setting arguments.
void passABIArg(const MoveOperand &from);
void passABIArg(const MoveOperand &from, MoveOp::Kind kind);
void passABIArg(const Register &reg);
void passABIArg(const FloatRegister &reg);
void passABIArg(const FloatRegister &reg, MoveOp::Kind kind);
private:
void callWithABIPre(uint32_t *stackAdjust);
void callWithABIPost(uint32_t stackAdjust, Result result);
void callWithABIPost(uint32_t stackAdjust, MoveOp::Kind result);
public:
// Emits a call to a C/C++ function, resolving all argument moves.
void callWithABI(void *fun, Result result = GENERAL);
void callWithABI(AsmJSImmPtr fun, Result result = GENERAL);
void callWithABI(const Address &fun, Result result = GENERAL);
void callWithABI(void *fun, MoveOp::Kind result = MoveOp::GENERAL);
void callWithABI(AsmJSImmPtr fun, MoveOp::Kind result = MoveOp::GENERAL);
void callWithABI(const Address &fun, MoveOp::Kind result = MoveOp::GENERAL);
// Used from within an Exit frame to handle a pending exception.
void handleFailureWithHandler(void *handler);

View File

@ -614,31 +614,31 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
size_t argDisp = 0;
// Copy arguments.
if (f.explicitArgs) {
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
MoveOperand from;
switch (f.argProperties(explicitArg)) {
case VMFunction::WordByValue:
masm.passABIArg(MoveOperand(argsBase, argDisp));
argDisp += sizeof(void *);
break;
case VMFunction::DoubleByValue:
// We don't pass doubles in float registers on x86, so no need
// to check for argPassedInFloatReg.
masm.passABIArg(MoveOperand(argsBase, argDisp));
argDisp += sizeof(void *);
masm.passABIArg(MoveOperand(argsBase, argDisp));
argDisp += sizeof(void *);
break;
case VMFunction::WordByRef:
masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE));
argDisp += sizeof(void *);
break;
case VMFunction::DoubleByRef:
masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE));
argDisp += 2 * sizeof(void *);
break;
}
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
MoveOperand from;
switch (f.argProperties(explicitArg)) {
case VMFunction::WordByValue:
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL);
argDisp += sizeof(void *);
break;
case VMFunction::DoubleByValue:
// We don't pass doubles in float registers on x86, so no need
// to check for argPassedInFloatReg.
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL);
argDisp += sizeof(void *);
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL);
argDisp += sizeof(void *);
break;
case VMFunction::WordByRef:
masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
MoveOp::GENERAL);
argDisp += sizeof(void *);
break;
case VMFunction::DoubleByRef:
masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
MoveOp::GENERAL);
argDisp += 2 * sizeof(void *);
break;
}
}