From 1f34a22bc4cb6944dcdbd3d3c1684aefff9e47a2 Mon Sep 17 00:00:00 2001 From: Lars T Hansen Date: Thu, 29 Dec 2016 07:23:33 +0100 Subject: [PATCH] Bug 1319388 - Add add32ToPtrWithPatch and patchAdd32ToPtr to MacroAssembler. r=jandem --HG-- extra : rebase_source : a50b733c713c75916e66d5635beda3e60bd1bc73 --- js/src/jit/MacroAssembler.h | 7 +++++++ js/src/jit/arm/MacroAssembler-arm-inl.h | 18 ++++++++++++++++++ js/src/jit/arm/MacroAssembler-arm.cpp | 6 ++++++ js/src/jit/arm/MacroAssembler-arm.h | 2 ++ js/src/jit/arm64/MacroAssembler-arm64-inl.h | 12 ++++++++++++ js/src/jit/mips32/MacroAssembler-mips32-inl.h | 12 ++++++++++++ js/src/jit/mips64/MacroAssembler-mips64-inl.h | 12 ++++++++++++ js/src/jit/x64/Assembler-x64.h | 9 +++++++++ js/src/jit/x64/BaseAssembler-x64.h | 11 +++++++++++ js/src/jit/x64/MacroAssembler-x64-inl.h | 15 +++++++++++++++ js/src/jit/x86-shared/Assembler-x86-shared.h | 5 +++++ js/src/jit/x86/MacroAssembler-x86-inl.h | 15 +++++++++++++++ 12 files changed, 124 insertions(+) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index f63bcff15437..7c35363fd6eb 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -779,6 +779,13 @@ class MacroAssembler : public MacroAssemblerSpecific inline void addFloat32(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH; + // Compute dest=src+imm where `src` and `dest` are pointer registers; `src` + // may be SP, and `src` may equal `dest`. `dest` should not normally be SP, + // as stack probes are required for large negative immediates. The offset + // returned from add32ToPtrWithPatch() must be passed to patchAdd32ToPtr(). + inline CodeOffset add32ToPtrWithPatch(Register src, Register dest) PER_ARCH; + inline void patchAdd32ToPtr(CodeOffset offset, Imm32 imm) PER_ARCH; + inline void addDouble(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH; inline void addConstantDouble(double d, FloatRegister dest) DEFINED_ON(x86); diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index afa3aaab825b..4dc9912e400a 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -309,6 +309,24 @@ MacroAssembler::add64(Imm64 imm, Register64 dest) ma_adc(imm.hi(), dest.high, scratch, LeaveCC); } +CodeOffset +MacroAssembler::add32ToPtrWithPatch(Register src, Register dest) +{ + ScratchRegisterScope scratch(*this); + CodeOffset offs = CodeOffset(currentOffset()); + ma_movPatchable(Imm32(0), scratch, Always); + ma_add(src, scratch, dest); + return offs; +} + +void +MacroAssembler::patchAdd32ToPtr(CodeOffset offset, Imm32 imm) +{ + ScratchRegisterScope scratch(*this); + ma_mov_patch(imm, scratch, Always, + HasMOVWT() ? L_MOVWT : L_LDR, offsetToInstruction(offset)); +} + void MacroAssembler::addDouble(FloatRegister src, FloatRegister dest) { diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 39b74c193e7e..98817d7be88f 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -375,6 +375,12 @@ MacroAssemblerARM::ma_mov_patch(ImmPtr imm, Register dest, Assembler::Condition ma_mov_patch(Imm32(int32_t(imm.value)), dest, c, rs, i); } +Instruction* +MacroAssemblerARM::offsetToInstruction(CodeOffset offs) +{ + return editSrc(BufferOffset(offs.offset())); +} + void MacroAssemblerARM::ma_mov(Register src, Register dest, SBit s, Assembler::Condition c) { diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index bce3d416a37c..1a7aad4462ea 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -130,6 +130,8 @@ class MacroAssemblerARM : public Assembler static void ma_mov_patch(ImmPtr imm, Register dest, Assembler::Condition c, RelocStyle rs, Instruction* i); + Instruction* offsetToInstruction(CodeOffset offs); + // ALU based ops // mov void ma_mov(Register src, Register dest, SBit s = LeaveCC, Condition c = Always); diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index e08393fcc41a..176ab31834fb 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -312,6 +312,18 @@ MacroAssembler::add64(Imm64 imm, Register64 dest) Add(ARMRegister(dest.reg, 64), ARMRegister(dest.reg, 64), Operand(imm.value)); } +CodeOffset +MacroAssembler::add32ToPtrWithPatch(Register src, Register dest) +{ + MOZ_CRASH("NYI - add32ToPtrWithPatch"); +} + +void +MacroAssembler::patchAdd32ToPtr(CodeOffset offset, Imm32 imm) +{ + MOZ_CRASH("NYI - patchAdd32ToPtr"); +} + void MacroAssembler::addDouble(FloatRegister src, FloatRegister dest) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index 4331e050ef67..a669ad0c7962 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -163,6 +163,18 @@ MacroAssembler::add64(Imm64 imm, Register64 dest) ma_addu(dest.high, dest.high, imm.hi()); } +CodeOffset +MacroAssembler::add32ToPtrWithPatch(Register src, Register dest) +{ + MOZ_CRASH("NYI - add32ToPtrWithPatch"); +} + +void +MacroAssembler::patchAdd32ToPtr(CodeOffset offset, Imm32 imm) +{ + MOZ_CRASH("NYI - patchAdd32ToPtr"); +} + void MacroAssembler::subPtr(Register src, Register dest) { diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h index a07619b94a74..b8dde2e8f9ca 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64-inl.h +++ b/js/src/jit/mips64/MacroAssembler-mips64-inl.h @@ -200,6 +200,18 @@ MacroAssembler::add64(Imm64 imm, Register64 dest) ma_daddu(dest.reg, ScratchRegister); } +CodeOffset +MacroAssembler::add32ToPtrWithPatch(Register src, Register dest) +{ + MOZ_CRASH("NYI - add32ToPtrWithPatch"); +} + +void +MacroAssembler::patchAdd32ToPtr(CodeOffset offset, Imm32 imm) +{ + MOZ_CRASH("NYI - patchAdd32ToPtr"); +} + void MacroAssembler::subPtr(Register src, Register dest) { diff --git a/js/src/jit/x64/Assembler-x64.h b/js/src/jit/x64/Assembler-x64.h index 30e384158d09..6d16f3c6db00 100644 --- a/js/src/jit/x64/Assembler-x64.h +++ b/js/src/jit/x64/Assembler-x64.h @@ -360,6 +360,11 @@ class Assembler : public AssemblerX86Shared return movWithPatch(ImmWord(uintptr_t(imm.value)), dest); } + // This is for patching during code generation, not after. + void patchAddq(CodeOffset offset, int32_t n) { + X86Encoding::SetInt32(masm.data() + offset.offset(), n); + } + // 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. @@ -554,6 +559,10 @@ class Assembler : public AssemblerX86Shared void addq(Imm32 imm, Register dest) { masm.addq_ir(imm.value, dest.encoding()); } + CodeOffset addqWithPatch(Imm32 imm, Register dest) { + masm.addq_i32r(imm.value, dest.encoding()); + return CodeOffset(masm.currentOffset()); + } void addq(Imm32 imm, const Operand& dest) { switch (dest.kind()) { case Operand::REG: diff --git a/js/src/jit/x64/BaseAssembler-x64.h b/js/src/jit/x64/BaseAssembler-x64.h index f26fedc07d2e..803acbe17ddd 100644 --- a/js/src/jit/x64/BaseAssembler-x64.h +++ b/js/src/jit/x64/BaseAssembler-x64.h @@ -53,6 +53,17 @@ class BaseAssemblerX64 : public BaseAssembler } } + void addq_i32r(int32_t imm, RegisterID dst) + { + // 32-bit immediate always, for patching. + spew("addq $0x%04x, %s", imm, GPReg64Name(dst)); + if (dst == rax) + m_formatter.oneByteOp64(OP_ADD_EAXIv); + else + m_formatter.oneByteOp64(OP_GROUP1_EvIz, dst, GROUP1_OP_ADD); + m_formatter.immediate32(imm); + } + void addq_im(int32_t imm, int32_t offset, RegisterID base) { spew("addq $%d, " MEM_ob, imm, ADDR_ob(offset, base)); diff --git a/js/src/jit/x64/MacroAssembler-x64-inl.h b/js/src/jit/x64/MacroAssembler-x64-inl.h index f7a70e68e443..6c736943f325 100644 --- a/js/src/jit/x64/MacroAssembler-x64-inl.h +++ b/js/src/jit/x64/MacroAssembler-x64-inl.h @@ -207,6 +207,21 @@ MacroAssembler::add64(Imm64 imm, Register64 dest) addPtr(ImmWord(imm.value), dest.reg); } +CodeOffset +MacroAssembler::add32ToPtrWithPatch(Register src, Register dest) +{ + if (src != dest) + movePtr(src, dest); + addqWithPatch(Imm32(0), dest); + return CodeOffset(currentOffset()); +} + +void +MacroAssembler::patchAdd32ToPtr(CodeOffset offset, Imm32 imm) +{ + patchAddq(offset, imm.value); +} + void MacroAssembler::subPtr(Register src, Register dest) { diff --git a/js/src/jit/x86-shared/Assembler-x86-shared.h b/js/src/jit/x86-shared/Assembler-x86-shared.h index 4bf5a0d29e36..ce9b043bd66b 100644 --- a/js/src/jit/x86-shared/Assembler-x86-shared.h +++ b/js/src/jit/x86-shared/Assembler-x86-shared.h @@ -1075,6 +1075,11 @@ class AssemblerX86Shared : public AssemblerShared X86Encoding::SetRel32(code + farJumpOffset, code + targetOffset); } + // This is for patching during code generation, not after. + void patchAddl(CodeOffset offset, int32_t n) { + X86Encoding::SetInt32(masm.data() + offset.offset(), n); + } + CodeOffset twoByteNop() { return CodeOffset(masm.twoByteNop().offset()); } diff --git a/js/src/jit/x86/MacroAssembler-x86-inl.h b/js/src/jit/x86/MacroAssembler-x86-inl.h index 2415c8bc7fe8..30f134a70116 100644 --- a/js/src/jit/x86/MacroAssembler-x86-inl.h +++ b/js/src/jit/x86/MacroAssembler-x86-inl.h @@ -191,6 +191,21 @@ MacroAssembler::addConstantDouble(double d, FloatRegister dest) propagateOOM(dbl->uses.append(CodeOffset(masm.size()))); } +CodeOffset +MacroAssembler::add32ToPtrWithPatch(Register src, Register dest) +{ + if (src != dest) + movePtr(src, dest); + addlWithPatch(Imm32(0), dest); + return CodeOffset(currentOffset()); +} + +void +MacroAssembler::patchAdd32ToPtr(CodeOffset offset, Imm32 imm) +{ + patchAddl(offset, imm.value); +} + void MacroAssembler::subPtr(Register src, Register dest) {