Skip to content

Commit 454660d

Browse files
author
Hamlin Li
committed
8332900: RISC-V: refactor nativeInst_riscv.cpp and macroAssembler_riscv.cpp
Reviewed-by: fyang, luhenry
1 parent 67d6f3c commit 454660d

6 files changed

+434
-421
lines changed

src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ void ZBarrierSetAssembler::patch_barrier_relocation(address addr, int format) {
629629
case ZBarrierRelocationFormatMarkBadMask:
630630
case ZBarrierRelocationFormatStoreGoodBits:
631631
case ZBarrierRelocationFormatStoreBadMask:
632-
assert(NativeInstruction::is_li16u_at(addr), "invalide zgc barrier");
632+
assert(MacroAssembler::is_li16u_at(addr), "invalide zgc barrier");
633633
bytes = MacroAssembler::pd_patch_instruction_size(addr, (address)(uintptr_t)value);
634634
break;
635635
default:

src/hotspot/cpu/riscv/macroAssembler_riscv.cpp

Lines changed: 173 additions & 43 deletions
Large diffs are not rendered by default.

src/hotspot/cpu/riscv/macroAssembler_riscv.hpp

Lines changed: 223 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include "asm/assembler.inline.hpp"
3131
#include "code/vmreg.hpp"
3232
#include "metaprogramming/enableIf.hpp"
33-
#include "nativeInst_riscv.hpp"
3433
#include "oops/compressedOops.hpp"
3534
#include "utilities/powerOfTwo.hpp"
3635

@@ -42,14 +41,15 @@
4241
class MacroAssembler: public Assembler {
4342

4443
public:
44+
4545
MacroAssembler(CodeBuffer* code) : Assembler(code) {}
4646

4747
void safepoint_poll(Label& slow_path, bool at_return, bool acquire, bool in_nmethod);
4848

4949
// Alignment
5050
int align(int modulus, int extra_offset = 0);
5151

52-
static inline void assert_alignment(address pc, int alignment = NativeInstruction::instruction_size) {
52+
static inline void assert_alignment(address pc, int alignment = MacroAssembler::instruction_size) {
5353
assert(is_aligned(pc, alignment), "bad alignment");
5454
}
5555

@@ -1232,7 +1232,7 @@ class MacroAssembler: public Assembler {
12321232

12331233
address ic_call(address entry, jint method_index = 0);
12341234
static int ic_check_size();
1235-
int ic_check(int end_alignment = NativeInstruction::instruction_size);
1235+
int ic_check(int end_alignment = MacroAssembler::instruction_size);
12361236

12371237
// Support for memory inc/dec
12381238
// n.b. increment/decrement calls with an Address destination will
@@ -1542,6 +1542,226 @@ class MacroAssembler: public Assembler {
15421542
public:
15431543
void lightweight_lock(Register obj, Register tmp1, Register tmp2, Register tmp3, Label& slow);
15441544
void lightweight_unlock(Register obj, Register tmp1, Register tmp2, Register tmp3, Label& slow);
1545+
1546+
public:
1547+
enum {
1548+
// Refer to function emit_trampoline_stub.
1549+
trampoline_stub_instruction_size = 3 * instruction_size + wordSize, // auipc + ld + jr + target address
1550+
trampoline_stub_data_offset = 3 * instruction_size, // auipc + ld + jr
1551+
1552+
// movptr
1553+
movptr1_instruction_size = 6 * instruction_size, // lui, addi, slli, addi, slli, addi. See movptr1().
1554+
movptr2_instruction_size = 5 * instruction_size, // lui, lui, slli, add, addi. See movptr2().
1555+
load_pc_relative_instruction_size = 2 * instruction_size // auipc, ld
1556+
};
1557+
1558+
static bool is_load_pc_relative_at(address branch);
1559+
static bool is_li16u_at(address instr);
1560+
1561+
static bool is_trampoline_stub_at(address addr) {
1562+
// Ensure that the stub is exactly
1563+
// ld t0, L--->auipc + ld
1564+
// jr t0
1565+
// L:
1566+
1567+
// judge inst + register + imm
1568+
// 1). check the instructions: auipc + ld + jalr
1569+
// 2). check if auipc[11:7] == t0 and ld[11:7] == t0 and ld[19:15] == t0 && jr[19:15] == t0
1570+
// 3). check if the offset in ld[31:20] equals the data_offset
1571+
assert_cond(addr != nullptr);
1572+
const int instr_size = instruction_size;
1573+
if (is_auipc_at(addr) &&
1574+
is_ld_at(addr + instr_size) &&
1575+
is_jalr_at(addr + 2 * instr_size) &&
1576+
(extract_rd(addr) == x5) &&
1577+
(extract_rd(addr + instr_size) == x5) &&
1578+
(extract_rs1(addr + instr_size) == x5) &&
1579+
(extract_rs1(addr + 2 * instr_size) == x5) &&
1580+
(Assembler::extract(Assembler::ld_instr(addr + 4), 31, 20) == trampoline_stub_data_offset)) {
1581+
return true;
1582+
}
1583+
return false;
1584+
}
1585+
1586+
static bool is_call_at(address instr) {
1587+
if (is_jal_at(instr) || is_jalr_at(instr)) {
1588+
return true;
1589+
}
1590+
return false;
1591+
}
1592+
1593+
static bool is_jal_at(address instr) { assert_cond(instr != nullptr); return extract_opcode(instr) == 0b1101111; }
1594+
static bool is_jalr_at(address instr) { assert_cond(instr != nullptr); return extract_opcode(instr) == 0b1100111 && extract_funct3(instr) == 0b000; }
1595+
static bool is_branch_at(address instr) { assert_cond(instr != nullptr); return extract_opcode(instr) == 0b1100011; }
1596+
static bool is_ld_at(address instr) { assert_cond(instr != nullptr); return is_load_at(instr) && extract_funct3(instr) == 0b011; }
1597+
static bool is_load_at(address instr) { assert_cond(instr != nullptr); return extract_opcode(instr) == 0b0000011; }
1598+
static bool is_float_load_at(address instr) { assert_cond(instr != nullptr); return extract_opcode(instr) == 0b0000111; }
1599+
static bool is_auipc_at(address instr) { assert_cond(instr != nullptr); return extract_opcode(instr) == 0b0010111; }
1600+
static bool is_jump_at(address instr) { assert_cond(instr != nullptr); return is_branch_at(instr) || is_jal_at(instr) || is_jalr_at(instr); }
1601+
static bool is_add_at(address instr) { assert_cond(instr != nullptr); return extract_opcode(instr) == 0b0110011 && extract_funct3(instr) == 0b000; }
1602+
static bool is_addi_at(address instr) { assert_cond(instr != nullptr); return extract_opcode(instr) == 0b0010011 && extract_funct3(instr) == 0b000; }
1603+
static bool is_addiw_at(address instr) { assert_cond(instr != nullptr); return extract_opcode(instr) == 0b0011011 && extract_funct3(instr) == 0b000; }
1604+
static bool is_addiw_to_zr_at(address instr){ assert_cond(instr != nullptr); return is_addiw_at(instr) && extract_rd(instr) == zr; }
1605+
static bool is_lui_at(address instr) { assert_cond(instr != nullptr); return extract_opcode(instr) == 0b0110111; }
1606+
static bool is_lui_to_zr_at(address instr) { assert_cond(instr != nullptr); return is_lui_at(instr) && extract_rd(instr) == zr; }
1607+
1608+
static bool is_srli_at(address instr) {
1609+
assert_cond(instr != nullptr);
1610+
return extract_opcode(instr) == 0b0010011 &&
1611+
extract_funct3(instr) == 0b101 &&
1612+
Assembler::extract(((unsigned*)instr)[0], 31, 26) == 0b000000;
1613+
}
1614+
1615+
static bool is_slli_shift_at(address instr, uint32_t shift) {
1616+
assert_cond(instr != nullptr);
1617+
return (extract_opcode(instr) == 0b0010011 && // opcode field
1618+
extract_funct3(instr) == 0b001 && // funct3 field, select the type of operation
1619+
Assembler::extract(Assembler::ld_instr(instr), 25, 20) == shift); // shamt field
1620+
}
1621+
1622+
static bool is_movptr1_at(address instr);
1623+
static bool is_movptr2_at(address instr);
1624+
1625+
static bool is_lwu_to_zr(address instr);
1626+
1627+
private:
1628+
static Register extract_rs1(address instr);
1629+
static Register extract_rs2(address instr);
1630+
static Register extract_rd(address instr);
1631+
static uint32_t extract_opcode(address instr);
1632+
static uint32_t extract_funct3(address instr);
1633+
1634+
// the instruction sequence of movptr is as below:
1635+
// lui
1636+
// addi
1637+
// slli
1638+
// addi
1639+
// slli
1640+
// addi/jalr/load
1641+
static bool check_movptr1_data_dependency(address instr) {
1642+
address lui = instr;
1643+
address addi1 = lui + instruction_size;
1644+
address slli1 = addi1 + instruction_size;
1645+
address addi2 = slli1 + instruction_size;
1646+
address slli2 = addi2 + instruction_size;
1647+
address last_instr = slli2 + instruction_size;
1648+
return extract_rs1(addi1) == extract_rd(lui) &&
1649+
extract_rs1(addi1) == extract_rd(addi1) &&
1650+
extract_rs1(slli1) == extract_rd(addi1) &&
1651+
extract_rs1(slli1) == extract_rd(slli1) &&
1652+
extract_rs1(addi2) == extract_rd(slli1) &&
1653+
extract_rs1(addi2) == extract_rd(addi2) &&
1654+
extract_rs1(slli2) == extract_rd(addi2) &&
1655+
extract_rs1(slli2) == extract_rd(slli2) &&
1656+
extract_rs1(last_instr) == extract_rd(slli2);
1657+
}
1658+
1659+
// the instruction sequence of movptr2 is as below:
1660+
// lui
1661+
// lui
1662+
// slli
1663+
// add
1664+
// addi/jalr/load
1665+
static bool check_movptr2_data_dependency(address instr) {
1666+
address lui1 = instr;
1667+
address lui2 = lui1 + instruction_size;
1668+
address slli = lui2 + instruction_size;
1669+
address add = slli + instruction_size;
1670+
address last_instr = add + instruction_size;
1671+
return extract_rd(add) == extract_rd(lui2) &&
1672+
extract_rs1(add) == extract_rd(lui2) &&
1673+
extract_rs2(add) == extract_rd(slli) &&
1674+
extract_rs1(slli) == extract_rd(lui1) &&
1675+
extract_rd(slli) == extract_rd(lui1) &&
1676+
extract_rs1(last_instr) == extract_rd(add);
1677+
}
1678+
1679+
// the instruction sequence of li64 is as below:
1680+
// lui
1681+
// addi
1682+
// slli
1683+
// addi
1684+
// slli
1685+
// addi
1686+
// slli
1687+
// addi
1688+
static bool check_li64_data_dependency(address instr) {
1689+
address lui = instr;
1690+
address addi1 = lui + instruction_size;
1691+
address slli1 = addi1 + instruction_size;
1692+
address addi2 = slli1 + instruction_size;
1693+
address slli2 = addi2 + instruction_size;
1694+
address addi3 = slli2 + instruction_size;
1695+
address slli3 = addi3 + instruction_size;
1696+
address addi4 = slli3 + instruction_size;
1697+
return extract_rs1(addi1) == extract_rd(lui) &&
1698+
extract_rs1(addi1) == extract_rd(addi1) &&
1699+
extract_rs1(slli1) == extract_rd(addi1) &&
1700+
extract_rs1(slli1) == extract_rd(slli1) &&
1701+
extract_rs1(addi2) == extract_rd(slli1) &&
1702+
extract_rs1(addi2) == extract_rd(addi2) &&
1703+
extract_rs1(slli2) == extract_rd(addi2) &&
1704+
extract_rs1(slli2) == extract_rd(slli2) &&
1705+
extract_rs1(addi3) == extract_rd(slli2) &&
1706+
extract_rs1(addi3) == extract_rd(addi3) &&
1707+
extract_rs1(slli3) == extract_rd(addi3) &&
1708+
extract_rs1(slli3) == extract_rd(slli3) &&
1709+
extract_rs1(addi4) == extract_rd(slli3) &&
1710+
extract_rs1(addi4) == extract_rd(addi4);
1711+
}
1712+
1713+
// the instruction sequence of li16u is as below:
1714+
// lui
1715+
// srli
1716+
static bool check_li16u_data_dependency(address instr) {
1717+
address lui = instr;
1718+
address srli = lui + instruction_size;
1719+
1720+
return extract_rs1(srli) == extract_rd(lui) &&
1721+
extract_rs1(srli) == extract_rd(srli);
1722+
}
1723+
1724+
// the instruction sequence of li32 is as below:
1725+
// lui
1726+
// addiw
1727+
static bool check_li32_data_dependency(address instr) {
1728+
address lui = instr;
1729+
address addiw = lui + instruction_size;
1730+
1731+
return extract_rs1(addiw) == extract_rd(lui) &&
1732+
extract_rs1(addiw) == extract_rd(addiw);
1733+
}
1734+
1735+
// the instruction sequence of pc-relative is as below:
1736+
// auipc
1737+
// jalr/addi/load/float_load
1738+
static bool check_pc_relative_data_dependency(address instr) {
1739+
address auipc = instr;
1740+
address last_instr = auipc + instruction_size;
1741+
1742+
return extract_rs1(last_instr) == extract_rd(auipc);
1743+
}
1744+
1745+
// the instruction sequence of load_label is as below:
1746+
// auipc
1747+
// load
1748+
static bool check_load_pc_relative_data_dependency(address instr) {
1749+
address auipc = instr;
1750+
address load = auipc + instruction_size;
1751+
1752+
return extract_rd(load) == extract_rd(auipc) &&
1753+
extract_rs1(load) == extract_rd(load);
1754+
}
1755+
1756+
static bool is_li32_at(address instr);
1757+
static bool is_li64_at(address instr);
1758+
static bool is_pc_relative_at(address branch);
1759+
1760+
static bool is_membar(address addr) {
1761+
return (Bytes::get_native_u4(addr) & 0x7f) == 0b1111 && extract_funct3(addr) == 0;
1762+
}
1763+
static uint32_t get_membar_kind(address addr);
1764+
static void set_membar_kind(address addr, uint32_t order_kind);
15451765
};
15461766

15471767
#ifdef ASSERT

0 commit comments

Comments
 (0)