Bug 891083 - Make the ImmWord version of x64's movq always use smaller immediate fields when possible; use movWithPatch when a patchable 64-bit immediate field is needed. Also, implement movq_i32r, which is useful for immediates in the range [INT32_MIN, 0). r=sstangl

This commit is contained in:
Dan Gohman 2013-07-08 19:28:20 -07:00
parent 939a471dee
commit 5afb769bde
3 changed files with 36 additions and 19 deletions

View File

@ -1675,10 +1675,18 @@ public:
m_formatter.immediate32(imm);
}
// Intentionally left undefined. If you need this operation, consider
// naming it movq_i32r_signExtended to highlight the fact the operand size
// is not 32; the 32-bit immediate is sign-extended.
void movq_i32r(int imm, RegisterID dst);
// Note that this instruction sign-extends its 32-bit immediate field to 64
// bits and loads the 64-bit value into a 64-bit register.
//
// Note also that this is similar to the movl_i32r instruction, except that
// movl_i32r *zero*-extends its 32-bit immediate, and it has smaller code
// size, so it's preferred for values which could use either.
void movq_i32r(int imm, RegisterID dst) {
spew("movq $%d, %s",
imm, nameIReg(dst));
m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, dst);
m_formatter.immediate32(imm);
}
void movq_i64r(int64_t imm, RegisterID dst)
{

View File

@ -362,13 +362,28 @@ class Assembler : public AssemblerX86Shared
}
CodeOffsetLabel movWithPatch(const ImmWord &word, const Register &dest) {
movq(word, dest);
masm.movq_i64r(word.value, dest.code());
return masm.currentOffset();
}
// Load an ImmWord value into a register. Note that this instruction will
// attempt to optimize its immediate field size. When a full 64-bit
// immediate is needed for a relocation, use movWithPatch.
void movq(ImmWord word, const Register &dest) {
// Load a 64-bit immediate into a register. If the value falls into
// certain ranges, we can use specialized instructions which have
// smaller encodings.
if (word.value <= UINT32_MAX) {
// movl has a 32-bit unsigned (effectively) immediate field.
masm.movl_i32r((uint32_t)word.value, dest.code());
} else if ((intptr_t)word.value >= INT32_MIN && (intptr_t)word.value <= INT32_MAX) {
// movq has a 32-bit signed immediate field.
masm.movq_i32r((int32_t)(intptr_t)word.value, dest.code());
} else {
// Otherwise use movabs.
masm.movq_i64r(word.value, dest.code());
}
}
void movq(ImmGCPtr ptr, const Register &dest) {
masm.movq_i64r(ptr.value, dest.code());
writeDataRelocation(ptr);
@ -523,17 +538,8 @@ class Assembler : public AssemblerX86Shared
}
void mov(ImmWord word, const Register &dest) {
// If the word value is in [0,UINT32_MAX], we can use the more compact
// movl instruction, which has a 32-bit immediate field which it
// zero-extends into the 64-bit register.
if (word.value <= UINT32_MAX) {
uint32_t value32 = static_cast<uint32_t>(word.value);
Imm32 imm32(static_cast<int32_t>(value32));
movl(imm32, dest);
} else {
movq(word, dest);
}
}
void mov(const Imm32 &imm32, const Register &dest) {
movl(imm32, dest);
}

View File

@ -161,9 +161,12 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
template <typename T>
void storeValue(const Value &val, const T &dest) {
jsval_layout jv = JSVAL_TO_IMPL(val);
movq(ImmWord(jv.asBits), ScratchReg);
if (val.isMarkable())
if (val.isMarkable()) {
movWithPatch(ImmWord(jv.asBits), ScratchReg);
writeDataRelocation(val);
} else {
mov(ImmWord(jv.asBits), ScratchReg);
}
movq(ScratchReg, Operand(dest));
}
void storeValue(ValueOperand val, BaseIndex dest) {
@ -213,7 +216,7 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
void moveValue(const Value &val, const Register &dest) {
jsval_layout jv = JSVAL_TO_IMPL(val);
movq(ImmWord(jv.asPtr), dest);
movWithPatch(ImmWord(jv.asPtr), dest);
writeDataRelocation(val);
}
void moveValue(const Value &src, const ValueOperand &dest) {