diff options
author | Moonchild <moonchild@palemoon.org> | 2020-05-19 22:14:43 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-19 22:14:43 +0200 |
commit | 750b4c3a11e6ed4d92598072899b02c549f17d26 (patch) | |
tree | 75e1ec3ab5ecec3a0ec29a176a3b46ef33609b76 /js/src/jit/mips64/Assembler-mips64.cpp | |
parent | ffb32138cbe23dc275ec409770246739f9678cef (diff) | |
parent | 052a035958d43c3fb0a980c0c7a93ad2073afddf (diff) | |
download | UXP-750b4c3a11e6ed4d92598072899b02c549f17d26.tar UXP-750b4c3a11e6ed4d92598072899b02c549f17d26.tar.gz UXP-750b4c3a11e6ed4d92598072899b02c549f17d26.tar.lz UXP-750b4c3a11e6ed4d92598072899b02c549f17d26.tar.xz UXP-750b4c3a11e6ed4d92598072899b02c549f17d26.zip |
Merge pull request #1544 from FlyGoat/mips-upstream
Implements initial MIPS Support
Diffstat (limited to 'js/src/jit/mips64/Assembler-mips64.cpp')
-rw-r--r-- | js/src/jit/mips64/Assembler-mips64.cpp | 186 |
1 files changed, 4 insertions, 182 deletions
diff --git a/js/src/jit/mips64/Assembler-mips64.cpp b/js/src/jit/mips64/Assembler-mips64.cpp index 4d251f152..4f3eac094 100644 --- a/js/src/jit/mips64/Assembler-mips64.cpp +++ b/js/src/jit/mips64/Assembler-mips64.cpp @@ -87,7 +87,9 @@ js::jit::SA(FloatRegister r) void jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label, ReprotectCode reprotect) { - Instruction* inst = (Instruction*)jump_.raw(); + Instruction* inst; + + inst = AssemblerMIPSShared::GetInstructionImmediateFromJump((Instruction*)jump_.raw()); // Six instructions used in load 64-bit imm. MaybeAutoWritableJitCode awjc(inst, 6 * sizeof(uint32_t), reprotect); @@ -125,23 +127,6 @@ jit::PatchBackedge(CodeLocationJump& jump, CodeLocationLabel label, } } -void -Assembler::executableCopy(uint8_t* buffer) -{ - MOZ_ASSERT(isFinished); - m_buffer.executableCopy(buffer); - - // Patch all long jumps during code copy. - for (size_t i = 0; i < longJumps_.length(); i++) { - Instruction* inst = (Instruction*) ((uintptr_t)buffer + longJumps_[i]); - - uint64_t value = Assembler::ExtractLoad64Value(inst); - Assembler::UpdateLoad64Value(inst, (uint64_t)buffer + value); - } - - AutoFlushICache::setRange(uintptr_t(buffer), m_buffer.size()); -} - uintptr_t Assembler::GetPointer(uint8_t* instPtr) { @@ -243,155 +228,6 @@ Assembler::Bind(uint8_t* rawCode, CodeOffset* label, const void* address) } } -void -Assembler::bind(InstImm* inst, uintptr_t branch, uintptr_t target) -{ - int64_t offset = target - branch; - InstImm inst_bgezal = InstImm(op_regimm, zero, rt_bgezal, BOffImm16(0)); - InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0)); - - // If encoded offset is 4, then the jump must be short - if (BOffImm16(inst[0]).decode() == 4) { - MOZ_ASSERT(BOffImm16::IsInRange(offset)); - inst[0].setBOffImm16(BOffImm16(offset)); - inst[1].makeNop(); - return; - } - - // Generate the long jump for calls because return address has to be the - // address after the reserved block. - if (inst[0].encode() == inst_bgezal.encode()) { - addLongJump(BufferOffset(branch)); - Assembler::WriteLoad64Instructions(inst, ScratchRegister, target); - inst[4] = InstReg(op_special, ScratchRegister, zero, ra, ff_jalr).encode(); - // There is 1 nop after this. - return; - } - - if (BOffImm16::IsInRange(offset)) { - // Don't skip trailing nops can improve performance - // on Loongson3 platform. - bool skipNops = !isLoongson() && (inst[0].encode() != inst_bgezal.encode() && - inst[0].encode() != inst_beq.encode()); - - inst[0].setBOffImm16(BOffImm16(offset)); - inst[1].makeNop(); - - if (skipNops) { - inst[2] = InstImm(op_regimm, zero, rt_bgez, BOffImm16(5 * sizeof(uint32_t))).encode(); - // There are 4 nops after this - } - return; - } - - if (inst[0].encode() == inst_beq.encode()) { - // Handle long unconditional jump. - addLongJump(BufferOffset(branch)); - Assembler::WriteLoad64Instructions(inst, ScratchRegister, target); - inst[4] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode(); - // There is 1 nop after this. - } else { - // Handle long conditional jump. - inst[0] = invertBranch(inst[0], BOffImm16(7 * sizeof(uint32_t))); - // No need for a "nop" here because we can clobber scratch. - addLongJump(BufferOffset(branch + sizeof(uint32_t))); - Assembler::WriteLoad64Instructions(&inst[1], ScratchRegister, target); - inst[5] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode(); - // There is 1 nop after this. - } -} - -void -Assembler::bind(RepatchLabel* label) -{ - BufferOffset dest = nextOffset(); - if (label->used() && !oom()) { - // If the label has a use, then change this use to refer to - // the bound label; - BufferOffset b(label->offset()); - InstImm* inst = (InstImm*)editSrc(b); - InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0)); - uint64_t offset = dest.getOffset() - label->offset(); - - // If first instruction is lui, then this is a long jump. - // If second instruction is lui, then this is a loop backedge. - if (inst[0].extractOpcode() == (uint32_t(op_lui) >> OpcodeShift)) { - // For unconditional long branches generated by ma_liPatchable, - // such as under: - // jumpWithpatch - Assembler::UpdateLoad64Value(inst, dest.getOffset()); - } else if (inst[1].extractOpcode() == (uint32_t(op_lui) >> OpcodeShift) || - BOffImm16::IsInRange(offset)) - { - // Handle code produced by: - // backedgeJump - // branchWithCode - MOZ_ASSERT(BOffImm16::IsInRange(offset)); - MOZ_ASSERT(inst[0].extractOpcode() == (uint32_t(op_beq) >> OpcodeShift) || - inst[0].extractOpcode() == (uint32_t(op_bne) >> OpcodeShift) || - inst[0].extractOpcode() == (uint32_t(op_blez) >> OpcodeShift) || - inst[0].extractOpcode() == (uint32_t(op_bgtz) >> OpcodeShift)); - inst[0].setBOffImm16(BOffImm16(offset)); - } else if (inst[0].encode() == inst_beq.encode()) { - // Handle open long unconditional jumps created by - // MacroAssemblerMIPSShared::ma_b(..., wasm::Trap, ...). - // We need to add it to long jumps array here. - // See MacroAssemblerMIPS64::branchWithCode(). - MOZ_ASSERT(inst[1].encode() == NopInst); - MOZ_ASSERT(inst[2].encode() == NopInst); - MOZ_ASSERT(inst[3].encode() == NopInst); - MOZ_ASSERT(inst[4].encode() == NopInst); - MOZ_ASSERT(inst[5].encode() == NopInst); - addLongJump(BufferOffset(label->offset())); - Assembler::WriteLoad64Instructions(inst, ScratchRegister, dest.getOffset()); - inst[4] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode(); - } else { - // Handle open long conditional jumps created by - // MacroAssemblerMIPSShared::ma_b(..., wasm::Trap, ...). - inst[0] = invertBranch(inst[0], BOffImm16(7 * sizeof(uint32_t))); - // No need for a "nop" here because we can clobber scratch. - // We need to add it to long jumps array here. - // See MacroAssemblerMIPS64::branchWithCode(). - MOZ_ASSERT(inst[1].encode() == NopInst); - MOZ_ASSERT(inst[2].encode() == NopInst); - MOZ_ASSERT(inst[3].encode() == NopInst); - MOZ_ASSERT(inst[4].encode() == NopInst); - MOZ_ASSERT(inst[5].encode() == NopInst); - MOZ_ASSERT(inst[6].encode() == NopInst); - addLongJump(BufferOffset(label->offset() + sizeof(uint32_t))); - Assembler::WriteLoad64Instructions(&inst[1], ScratchRegister, dest.getOffset()); - inst[5] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode(); - } - } - label->bind(dest.getOffset()); -} - -uint32_t -Assembler::PatchWrite_NearCallSize() -{ - // Load an address needs 4 instructions, and a jump with a delay slot. - return (4 + 2) * sizeof(uint32_t); -} - -void -Assembler::PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall) -{ - Instruction* inst = (Instruction*) start.raw(); - uint8_t* dest = toCall.raw(); - - // Overwrite whatever instruction used to be here with a call. - // Always use long jump for two reasons: - // - Jump has to be the same size because of PatchWrite_NearCallSize. - // - Return address has to be at the end of replaced block. - // Short jump wouldn't be more efficient. - Assembler::WriteLoad64Instructions(inst, ScratchRegister, (uint64_t)dest); - inst[4] = InstReg(op_special, ScratchRegister, zero, ra, ff_jalr); - inst[5] = InstNOP(); - - // Ensure everyone sees the code that was just written into memory. - AutoFlushICache::flush(uintptr_t(inst), PatchWrite_NearCallSize()); -} - uint64_t Assembler::ExtractLoad64Value(Instruction* inst0) { @@ -453,19 +289,6 @@ Assembler::UpdateLoad64Value(Instruction* inst0, uint64_t value) } void -Assembler::WriteLoad64Instructions(Instruction* inst0, Register reg, uint64_t value) -{ - Instruction* inst1 = inst0->next(); - Instruction* inst2 = inst1->next(); - Instruction* inst3 = inst2->next(); - - *inst0 = InstImm(op_lui, zero, reg, Imm16::Lower(Imm32(value >> 32))); - *inst1 = InstImm(op_ori, reg, reg, Imm16::Upper(Imm32(value))); - *inst2 = InstReg(op_special, rs_one, reg, reg, 48 - 32, ff_dsrl32); - *inst3 = InstImm(op_ori, reg, reg, Imm16::Lower(Imm32(value))); -} - -void Assembler::PatchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue, ImmPtr expectedValue) { @@ -492,8 +315,7 @@ Assembler::PatchDataWithValueCheck(CodeLocationLabel label, PatchedImmPtr newVal void Assembler::PatchInstructionImmediate(uint8_t* code, PatchedImmPtr imm) { - InstImm* inst = (InstImm*)code; - Assembler::UpdateLoad64Value(inst, (uint64_t)imm.value); + Assembler::UpdateLoad64Value((Instruction*)code, (uint64_t)imm.value); } uint64_t |