From 9f96e589c94cdf6d275a2bfebc0202017acd0369 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2013 21:16:07 -0700 Subject: [PATCH] Bug 885169 - Spidermonkey: Alleviate register allocation constraints in ICGetElem_Arguments::Compiler::generateStubCode. r=nbp --- js/src/jit/BaselineIC.cpp | 3 ++- js/src/jit/arm/MacroAssembler-arm.h | 30 +++++++++++++++++++++++------ js/src/jit/x86/MacroAssembler-x86.h | 26 +++++++++++++++++++------ 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index ca883d1c2bba..bdfb5e857952 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -3970,7 +3970,7 @@ ICGetElem_Arguments::Compiler::generateStubCode(MacroAssembler &masm) regs = availableGeneralRegs(0); regs.takeUnchecked(objReg); regs.takeUnchecked(idxReg); - regs.takeUnchecked(scratchReg); + regs.take(scratchReg); Register argData = regs.takeAny(); Register tempReg = regs.takeAny(); @@ -3992,6 +3992,7 @@ ICGetElem_Arguments::Compiler::generateStubCode(MacroAssembler &masm) masm.addPtr(Imm32(ArgumentsData::offsetOfArgs()), argData); regs.add(scratchReg); regs.add(tempReg); + regs.add(argData); ValueOperand tempVal = regs.takeAnyValue(); masm.loadValue(BaseIndex(argData, idxReg, ScaleFromElemWidth(sizeof(Value))), tempVal); diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 5c8e52159d48..5cd54627f98b 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -954,12 +954,30 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void moveValue(const Value &val, const ValueOperand &dest); void moveValue(const ValueOperand &src, const ValueOperand &dest) { - JS_ASSERT(src.typeReg() != dest.payloadReg()); - JS_ASSERT(src.payloadReg() != dest.typeReg()); - if (src.typeReg() != dest.typeReg()) - ma_mov(src.typeReg(), dest.typeReg()); - if (src.payloadReg() != dest.payloadReg()) - ma_mov(src.payloadReg(), dest.payloadReg()); + Register s0 = src.typeReg(), d0 = dest.typeReg(), + s1 = src.payloadReg(), d1 = dest.payloadReg(); + + // Either one or both of the source registers could be the same as a + // destination register. + if (s1 == d0) { + if (s0 == d1) { + // If both are, this is just a swap of two registers. + JS_ASSERT(d1 != ScratchRegister); + JS_ASSERT(d0 != ScratchRegister); + ma_mov(d1, ScratchRegister); + ma_mov(d0, d1); + ma_mov(ScratchRegister, d0); + return; + } + // If only one is, copy that source first. + mozilla::Swap(s0, s1); + mozilla::Swap(d0, d1); + } + + if (s0 != d0) + ma_mov(s0, d0); + if (s1 != d1) + ma_mov(s1, d1); } void storeValue(ValueOperand val, Operand dst); diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index 5b3d579562fa..dcb8673f5fb9 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -113,12 +113,26 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared moveValue(val, dest.typeReg(), dest.payloadReg()); } void moveValue(const ValueOperand &src, const ValueOperand &dest) { - JS_ASSERT(src.typeReg() != dest.payloadReg()); - JS_ASSERT(src.payloadReg() != dest.typeReg()); - if (src.typeReg() != dest.typeReg()) - movl(src.typeReg(), dest.typeReg()); - if (src.payloadReg() != dest.payloadReg()) - movl(src.payloadReg(), dest.payloadReg()); + Register s0 = src.typeReg(), d0 = dest.typeReg(), + s1 = src.payloadReg(), d1 = dest.payloadReg(); + + // Either one or both of the source registers could be the same as a + // destination register. + if (s1 == d0) { + if (s0 == d1) { + // If both are, this is just a swap of two registers. + xchgl(d0, d1); + return; + } + // If only one is, copy that source first. + mozilla::Swap(s0, s1); + mozilla::Swap(d0, d1); + } + + if (s0 != d0) + movl(s0, d0); + if (s1 != d1) + movl(s1, d1); } /////////////////////////////////////////////////////////////////