Commit 91b6d666 authored by Junliang Yan's avatar Junliang Yan Committed by V8 LUCI CQ

s390: [liftoff] Fix jump table patching

Change-Id: I18181e0328353e14f9f5793779db4806b759ac9b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3212293Reviewed-by: 's avatarJoran Siu <joransiu@ca.ibm.com>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Junliang Yan <junyan@redhat.com>
Cr-Commit-Position: refs/heads/main@{#77310}
parent 388a80ba
...@@ -483,10 +483,10 @@ int Assembler::target_at(int pos) { ...@@ -483,10 +483,10 @@ int Assembler::target_at(int pos) {
if (imm16 == 0) return kEndOfChain; if (imm16 == 0) return kEndOfChain;
return pos + imm16; return pos + imm16;
} else if (LLILF == opcode || BRCL == opcode || LARL == opcode || } else if (LLILF == opcode || BRCL == opcode || LARL == opcode ||
BRASL == opcode) { BRASL == opcode || LGRL == opcode) {
int32_t imm32 = int32_t imm32 =
static_cast<int32_t>(instr & (static_cast<uint64_t>(0xFFFFFFFF))); static_cast<int32_t>(instr & (static_cast<uint64_t>(0xFFFFFFFF)));
if (LLILF != opcode) if (LLILF != opcode && LGRL != opcode)
imm32 <<= 1; // BR* + LARL treat immediate in # of halfwords imm32 <<= 1; // BR* + LARL treat immediate in # of halfwords
if (imm32 == 0) return kEndOfChain; if (imm32 == 0) return kEndOfChain;
return pos + imm32; return pos + imm32;
...@@ -527,6 +527,12 @@ void Assembler::target_at_put(int pos, int target_pos, bool* is_branch) { ...@@ -527,6 +527,12 @@ void Assembler::target_at_put(int pos, int target_pos, bool* is_branch) {
instr &= (~static_cast<uint64_t>(0xFFFFFFFF)); instr &= (~static_cast<uint64_t>(0xFFFFFFFF));
instr_at_put<SixByteInstr>(pos, instr | (imm32 >> 1)); instr_at_put<SixByteInstr>(pos, instr | (imm32 >> 1));
return; return;
} else if (LGRL == opcode) {
// Immediate is in # of bytes
int32_t imm32 = target_pos - pos;
instr &= (~static_cast<uint64_t>(0xFFFFFFFF));
instr_at_put<SixByteInstr>(pos, instr | imm32);
return;
} else if (LLILF == opcode) { } else if (LLILF == opcode) {
DCHECK(target_pos == kEndOfChain || target_pos >= 0); DCHECK(target_pos == kEndOfChain || target_pos >= 0);
// Emitted label constant, not part of a branch. // Emitted label constant, not part of a branch.
...@@ -557,7 +563,7 @@ int Assembler::max_reach_from(int pos) { ...@@ -557,7 +563,7 @@ int Assembler::max_reach_from(int pos) {
BRXHG == opcode) { BRXHG == opcode) {
return 16; return 16;
} else if (LLILF == opcode || BRCL == opcode || LARL == opcode || } else if (LLILF == opcode || BRCL == opcode || LARL == opcode ||
BRASL == opcode) { BRASL == opcode || LGRL == opcode) {
return 31; // Using 31 as workaround instead of 32 as return 31; // Using 31 as workaround instead of 32 as
// is_intn(x,32) doesn't work on 32-bit platforms. // is_intn(x,32) doesn't work on 32-bit platforms.
// llilf: Emitted label constant, not part of // llilf: Emitted label constant, not part of
...@@ -699,6 +705,10 @@ void Assembler::larl(Register r1, Label* l) { ...@@ -699,6 +705,10 @@ void Assembler::larl(Register r1, Label* l) {
larl(r1, Operand(branch_offset(l))); larl(r1, Operand(branch_offset(l)));
} }
void Assembler::lgrl(Register r1, Label* l) {
lgrl(r1, Operand(branch_offset(l)));
}
void Assembler::EnsureSpaceFor(int space_needed) { void Assembler::EnsureSpaceFor(int space_needed) {
if (buffer_space() <= (kGap + space_needed)) { if (buffer_space() <= (kGap + space_needed)) {
GrowBuffer(space_needed); GrowBuffer(space_needed);
......
...@@ -1281,6 +1281,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { ...@@ -1281,6 +1281,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
// Load Address Instructions // Load Address Instructions
void larl(Register r, Label* l); void larl(Register r, Label* l);
void lgrl(Register r, Label* l);
// Exception-generating instructions and debugging support // Exception-generating instructions and debugging support
void stop(Condition cond = al, int32_t code = kDefaultStopCode, void stop(Condition cond = al, int32_t code = kDefaultStopCode,
......
...@@ -6713,9 +6713,12 @@ EVALUATE(STHRL) { ...@@ -6713,9 +6713,12 @@ EVALUATE(STHRL) {
} }
EVALUATE(LGRL) { EVALUATE(LGRL) {
UNIMPLEMENTED(); DCHECK_OPCODE(LGRL);
USE(instr); DECODE_RIL_B_INSTRUCTION(r1, i2);
return 0; intptr_t offset = i2;
int64_t mem_val = ReadDW(get_pc() + offset);
set_register(r1, mem_val);
return length;
} }
EVALUATE(STGRL) { EVALUATE(STGRL) {
......
...@@ -211,18 +211,32 @@ void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index, ...@@ -211,18 +211,32 @@ void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index,
} }
bool JumpTableAssembler::EmitJumpSlot(Address target) { bool JumpTableAssembler::EmitJumpSlot(Address target) {
mov(r1, Operand(target, RelocInfo::CODE_TARGET)); intptr_t relative_target = reinterpret_cast<byte*>(target) - pc_;
b(r1);
if (!is_int32(relative_target / 2)) {
return false;
}
brcl(al, Operand(relative_target / 2));
nop(0); // make the slot align to 8 bytes
return true; return true;
} }
void JumpTableAssembler::EmitFarJumpSlot(Address target) { void JumpTableAssembler::EmitFarJumpSlot(Address target) {
JumpToInstructionStream(target); Label target_addr;
lgrl(ip, &target_addr); // 6 bytes
b(ip); // 8 bytes
CHECK_EQ(reinterpret_cast<Address>(pc_) & 0x7, 0); // Alignment
bind(&target_addr);
dp(target);
} }
// static // static
void JumpTableAssembler::PatchFarJumpSlot(Address slot, Address target) { void JumpTableAssembler::PatchFarJumpSlot(Address slot, Address target) {
UNREACHABLE(); Address target_addr = slot + 8;
reinterpret_cast<std::atomic<Address>*>(target_addr)
->store(target, std::memory_order_relaxed);
} }
void JumpTableAssembler::NopBytes(int bytes) { void JumpTableAssembler::NopBytes(int bytes) {
......
...@@ -201,8 +201,8 @@ class V8_EXPORT_PRIVATE JumpTableAssembler : public MacroAssembler { ...@@ -201,8 +201,8 @@ class V8_EXPORT_PRIVATE JumpTableAssembler : public MacroAssembler {
static constexpr int kLazyCompileTableSlotSize = 3 * kInstrSize; static constexpr int kLazyCompileTableSlotSize = 3 * kInstrSize;
#elif V8_TARGET_ARCH_S390X #elif V8_TARGET_ARCH_S390X
static constexpr int kJumpTableLineSize = 128; static constexpr int kJumpTableLineSize = 128;
static constexpr int kJumpTableSlotSize = 14; static constexpr int kJumpTableSlotSize = 8;
static constexpr int kFarJumpTableSlotSize = 14; static constexpr int kFarJumpTableSlotSize = 16;
static constexpr int kLazyCompileTableSlotSize = 20; static constexpr int kLazyCompileTableSlotSize = 20;
#elif V8_TARGET_ARCH_PPC64 #elif V8_TARGET_ARCH_PPC64
static constexpr int kJumpTableLineSize = 64; static constexpr int kJumpTableLineSize = 64;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment