From 8990864a53fa04f44ecf8bff65a6dc9cdd67cb1c Mon Sep 17 00:00:00 2001 From: Robbin Ehn Date: Fri, 19 Apr 2024 10:05:24 +0000 Subject: [PATCH] 8330156: RISC-V: Range check auipc + signed 12 imm instruction Reviewed-by: fyang, mli, tonyp --- src/hotspot/cpu/riscv/macroAssembler_riscv.cpp | 2 +- src/hotspot/cpu/riscv/macroAssembler_riscv.hpp | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index 4704fbcaf75..26eacc3ec6f 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -721,7 +721,7 @@ void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Reg void MacroAssembler::la(Register Rd, const address addr) { int64_t offset = addr - pc(); - if (is_simm32(offset)) { + if (is_valid_32bit_offset(offset)) { auipc(Rd, (int32_t)offset + 0x800); //0x800, Note:the 11th sign bit addi(Rd, Rd, ((int64_t)offset << 52) >> 52); } else { diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 75c0f9ba305..508b23df128 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -678,6 +678,14 @@ private: int pop_v(unsigned int bitset, Register stack); #endif // COMPILER2 + // The signed 20-bit upper imm can materialize at most negative 0xF...F80000000, two G. + // The following signed 12-bit imm can at max subtract 0x800, two K, from that previously loaded two G. + bool is_valid_32bit_offset(int64_t x) { + constexpr int64_t twoG = (2 * G); + constexpr int64_t twoK = (2 * K); + return x < (twoG - twoK) && x >= (-twoG - twoK); + } + public: void push_reg(Register Rs); void pop_reg(Register Rd); @@ -833,7 +841,7 @@ public: void NAME(Register Rd, address dest) { \ assert_cond(dest != nullptr); \ int64_t distance = dest - pc(); \ - if (is_simm32(distance)) { \ + if (is_valid_32bit_offset(distance)) { \ auipc(Rd, (int32_t)distance + 0x800); \ Assembler::NAME(Rd, Rd, ((int32_t)distance << 20) >> 20); \ } else { \ @@ -890,7 +898,7 @@ public: void NAME(FloatRegister Rd, address dest, Register temp = t0) { \ assert_cond(dest != nullptr); \ int64_t distance = dest - pc(); \ - if (is_simm32(distance)) { \ + if (is_valid_32bit_offset(distance)) { \ auipc(temp, (int32_t)distance + 0x800); \ Assembler::NAME(Rd, temp, ((int32_t)distance << 20) >> 20); \ } else { \ @@ -951,7 +959,7 @@ public: assert_cond(dest != nullptr); \ assert_different_registers(Rs, temp); \ int64_t distance = dest - pc(); \ - if (is_simm32(distance)) { \ + if (is_valid_32bit_offset(distance)) { \ auipc(temp, (int32_t)distance + 0x800); \ Assembler::NAME(Rs, temp, ((int32_t)distance << 20) >> 20); \ } else { \ @@ -996,7 +1004,7 @@ public: void NAME(FloatRegister Rs, address dest, Register temp = t0) { \ assert_cond(dest != nullptr); \ int64_t distance = dest - pc(); \ - if (is_simm32(distance)) { \ + if (is_valid_32bit_offset(distance)) { \ auipc(temp, (int32_t)distance + 0x800); \ Assembler::NAME(Rs, temp, ((int32_t)distance << 20) >> 20); \ } else { \