diff options
Diffstat (limited to 'js/src/jit/mips-shared/Assembler-mips-shared.h')
-rw-r--r-- | js/src/jit/mips-shared/Assembler-mips-shared.h | 83 |
1 files changed, 64 insertions, 19 deletions
diff --git a/js/src/jit/mips-shared/Assembler-mips-shared.h b/js/src/jit/mips-shared/Assembler-mips-shared.h index a619fa0e0..1640fdafc 100644 --- a/js/src/jit/mips-shared/Assembler-mips-shared.h +++ b/js/src/jit/mips-shared/Assembler-mips-shared.h @@ -525,21 +525,13 @@ class JOffImm26 } int32_t decode() { MOZ_ASSERT(!isInvalid()); - return (int32_t(data << 8) >> 6) + 4; + return int32_t(data << 8) >> 6; } explicit JOffImm26(int offset) - : data ((offset - 4) >> 2 & Imm26Mask) + : data (offset >> 2 & Imm26Mask) { MOZ_ASSERT((offset & 0x3) == 0); - MOZ_ASSERT(IsInRange(offset)); - } - static bool IsInRange(int offset) { - if ((offset - 4) < -536870912) - return false; - if ((offset - 4) > 536870908) - return false; - return true; } static const uint32_t INVALID = 0x20000000; JOffImm26() @@ -840,6 +832,27 @@ class AssemblerMIPSShared : public AssemblerShared TestForFalse }; + struct MixedJumpPatch + { + enum Kind { + NONE, + PATCHABLE, + CONDITIONAL, + }; + + BufferOffset src; + BufferOffset mid; + uintptr_t target; + Kind kind; + + MixedJumpPatch(BufferOffset src, uintptr_t target, Kind kind) + : src(src), + mid(BufferOffset()), + target(target), + kind(kind) + { } + }; + // :( this should be protected, but since CodeGenerator // wants to use it, It needs to go out here :( @@ -873,7 +886,7 @@ class AssemblerMIPSShared : public AssemblerShared }; js::Vector<RelativePatch, 8, SystemAllocPolicy> jumps_; - js::Vector<uint32_t, 8, SystemAllocPolicy> longJumps_; + js::Vector<MixedJumpPatch, 8, SystemAllocPolicy> mixedJumps_; CompactBufferWriter jumpRelocations_; CompactBufferWriter dataRelocations_; @@ -922,7 +935,9 @@ class AssemblerMIPSShared : public AssemblerShared public: void finish(); bool asmMergeWith(const AssemblerMIPSShared& other); - void executableCopy(void* buffer); + // Copy the assembly code to the given buffer, and perform any pending + // relocations relying on the target address. + void executableCopy(uint8_t* buffer); void copyJumpRelocationTable(uint8_t* dest); void copyDataRelocationTable(uint8_t* dest); void copyPreBarrierTable(uint8_t* dest); @@ -1197,8 +1212,9 @@ class AssemblerMIPSShared : public AssemblerShared // label operations void bind(Label* label, BufferOffset boff = BufferOffset()); void bindLater(Label* label, wasm::TrapDesc target); - virtual void bind(InstImm* inst, uintptr_t branch, uintptr_t target) = 0; + void bind(InstImm* inst, uintptr_t branch, uintptr_t target); virtual void Bind(uint8_t* rawCode, CodeOffset* label, const void* address) = 0; + void bind(RepatchLabel* label); void bind(CodeOffset* label) { label->bind(currentOffset()); } @@ -1240,16 +1256,21 @@ class AssemblerMIPSShared : public AssemblerShared writeRelocation(src); } - void addLongJump(BufferOffset src) { - enoughMemory_ &= longJumps_.append(src.getOffset()); + void addMixedJump(BufferOffset src, uintptr_t target, + MixedJumpPatch::Kind kind = MixedJumpPatch::NONE) + { + enoughMemory_ &= mixedJumps_.append(MixedJumpPatch(src, target, kind)); } + virtual void GenerateMixedJumps() = 0; + void PatchMixedJumps(uint8_t* buffer); + public: - size_t numLongJumps() const { - return longJumps_.length(); + size_t numMixedJumps() const { + return mixedJumps_.length(); } - uint32_t longJump(size_t i) { - return longJumps_[i]; + MixedJumpPatch& mixedJump(size_t i) { + return mixedJumps_[i]; } void flushBuffer() { @@ -1261,18 +1282,24 @@ class AssemblerMIPSShared : public AssemblerShared } static uint32_t NopSize() { return 4; } + static uint32_t PatchWrite_NearCallSize(); static void PatchWrite_Imm32(CodeLocationLabel label, Imm32 imm); + static void PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall); static uint32_t AlignDoubleArg(uint32_t offset) { return (offset + 1U) &~ 1U; } static uint8_t* NextInstruction(uint8_t* instruction, uint32_t* count = nullptr); + static Instruction* GetInstructionImmediateFromJump(Instruction* jump); + static void PatchMixedJump(uint8_t* src, uint8_t* mid, uint8_t* target); static void ToggleToJmp(CodeLocationLabel inst_); static void ToggleToCmp(CodeLocationLabel inst_); + static void UpdateLuiOriValue(Instruction* inst0, Instruction* inst1, uint32_t value); + void processCodeLabels(uint8_t* rawCode); bool bailed() { @@ -1487,6 +1514,10 @@ class InstJump : public Instruction uint32_t extractImm26Value() { return extractBitField(Imm26Shift + Imm26Bits - 1, Imm26Shift); } + void setJOffImm26(JOffImm26 off) { + // Reset immediate field and replace it + data = (data & ~Imm26Mask) | off.encode(); + } }; // Class for Loongson-specific instructions @@ -1516,6 +1547,20 @@ class InstGS : public Instruction { } }; +inline bool +IsUnaligned(const wasm::MemoryAccessDesc& access) +{ + if (!access.align()) + return false; + +#ifdef JS_CODEGEN_MIPS32 + if (access.type() == Scalar::Int64 && access.align() >= 4) + return false; +#endif + + return access.align() < access.byteSize(); +} + } // namespace jit } // namespace js |