mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-02 07:10:23 +00:00
8386669: AArch64: Distinguish ldr and ldrw literal instructions in NativeInstruction
Reviewed-by: aph, adinn
This commit is contained in:
parent
ef5b328ce5
commit
be837e6e61
@ -124,14 +124,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// The first instruction of the nmethod entry barrier is an ldr (literal)
|
||||
// The first instruction of the nmethod entry barrier is an ldrw (literal)
|
||||
// instruction. Verify that it's really there, so the offsets are not skewed.
|
||||
bool NativeNMethodBarrier::check_barrier(err_msg& msg) const {
|
||||
uint32_t* addr = (uint32_t*) instruction_address();
|
||||
uint32_t inst = *addr;
|
||||
if ((inst & 0xff000000) != 0x18000000) {
|
||||
msg.print("Nmethod entry barrier did not start with ldr (literal) as expected. "
|
||||
"Addr: " PTR_FORMAT " Code: " UINT32_FORMAT, p2i(addr), inst);
|
||||
NativeInstruction* ni = nativeInstruction_at(instruction_address());
|
||||
if (!ni->is_ldrw_gpr_literal()) {
|
||||
msg.print("Nmethod entry barrier did not start with ldrw (literal) as expected. "
|
||||
"Addr: " PTR_FORMAT " Code: " UINT32_FORMAT, p2i(instruction_address()), ni->encoding());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@ -123,7 +123,7 @@ void NativeCall::insert(address code_pos, address entry) { Unimplemented(); }
|
||||
void NativeMovConstReg::verify() {
|
||||
if (! (nativeInstruction_at(instruction_address())->is_movz() ||
|
||||
is_adrp_at(instruction_address()) ||
|
||||
is_ldr_literal_at(instruction_address())) ) {
|
||||
is_load_literal_at(instruction_address())) ) {
|
||||
fatal("should be MOVZ or ADRP or LDR (literal)");
|
||||
}
|
||||
}
|
||||
@ -270,17 +270,17 @@ bool NativeInstruction::is_safepoint_poll() {
|
||||
// a safepoint_poll is implemented in two steps as either
|
||||
//
|
||||
// adrp(reg, polling_page);
|
||||
// ldr(zr, [reg, #offset]);
|
||||
// ldrw(zr, [reg, #offset]);
|
||||
//
|
||||
// or
|
||||
//
|
||||
// mov(reg, polling_page);
|
||||
// ldr(zr, [reg, #offset]);
|
||||
// ldrw(zr, [reg, #offset]);
|
||||
//
|
||||
// or
|
||||
//
|
||||
// ldr(reg, [rthread, #offset]);
|
||||
// ldr(zr, [reg, #offset]);
|
||||
// ldrw(zr, [reg, #offset]);
|
||||
//
|
||||
// however, we cannot rely on the polling page address load always
|
||||
// directly preceding the read from the page. C1 does that but C2
|
||||
@ -301,11 +301,21 @@ bool NativeInstruction::is_adrp_at(address instr) {
|
||||
return (Instruction_aarch64::extract(insn, 31, 24) & 0b10011111) == 0b10010000;
|
||||
}
|
||||
|
||||
bool NativeInstruction::is_ldr_literal_at(address instr) {
|
||||
bool NativeInstruction::is_load_literal_at(address instr) {
|
||||
unsigned insn = *(unsigned*)instr;
|
||||
return (Instruction_aarch64::extract(insn, 29, 24) & 0b011011) == 0b00011000;
|
||||
}
|
||||
|
||||
bool NativeInstruction::is_ldr_gpr_literal_at(address instr) {
|
||||
unsigned insn = *(unsigned*)instr;
|
||||
return Instruction_aarch64::extract(insn, 31, 24) == 0b01011000;
|
||||
}
|
||||
|
||||
bool NativeInstruction::is_ldrw_gpr_literal_at(address instr) {
|
||||
unsigned insn = *(unsigned*)instr;
|
||||
return Instruction_aarch64::extract(insn, 31, 24) == 0b00011000;
|
||||
}
|
||||
|
||||
bool NativeInstruction::is_ldrw_to_zr(address instr) {
|
||||
unsigned insn = *(unsigned*)instr;
|
||||
return (Instruction_aarch64::extract(insn, 31, 22) == 0b1011100101 &&
|
||||
|
||||
@ -107,10 +107,22 @@ public:
|
||||
|
||||
static bool is_adrp_at(address instr);
|
||||
|
||||
static bool is_ldr_literal_at(address instr);
|
||||
static bool is_load_literal_at(address instr);
|
||||
|
||||
bool is_ldr_literal() {
|
||||
return is_ldr_literal_at(addr_at(0));
|
||||
bool is_load_literal() {
|
||||
return is_load_literal_at(addr_at(0));
|
||||
}
|
||||
|
||||
static bool is_ldr_gpr_literal_at(address instr);
|
||||
|
||||
bool is_ldr_gpr_literal() {
|
||||
return is_ldr_gpr_literal_at(addr_at(0));
|
||||
}
|
||||
|
||||
static bool is_ldrw_gpr_literal_at(address instr);
|
||||
|
||||
bool is_ldrw_gpr_literal() {
|
||||
return is_ldrw_gpr_literal_at(addr_at(0));
|
||||
}
|
||||
|
||||
static bool is_ldrw_to_zr(address instr);
|
||||
@ -125,7 +137,7 @@ public:
|
||||
}
|
||||
|
||||
static bool maybe_cpool_ref(address instr) {
|
||||
return is_adrp_at(instr) || is_ldr_literal_at(instr);
|
||||
return is_adrp_at(instr) || is_load_literal_at(instr);
|
||||
}
|
||||
|
||||
bool is_Membar() {
|
||||
@ -267,7 +279,7 @@ public:
|
||||
return addr_at(instruction_size);
|
||||
else if (is_adrp_at(instruction_address()))
|
||||
return addr_at(2*4);
|
||||
else if (is_ldr_literal_at(instruction_address()))
|
||||
else if (is_load_literal_at(instruction_address()))
|
||||
return(addr_at(4));
|
||||
assert(false, "Unknown instruction in NativeMovConstReg");
|
||||
return nullptr;
|
||||
|
||||
@ -41,7 +41,7 @@ void Relocation::pd_set_data_value(address x, bool verify_only) {
|
||||
case relocInfo::oop_type:
|
||||
{
|
||||
oop_Relocation *reloc = (oop_Relocation *)this;
|
||||
if (NativeInstruction::is_ldr_literal_at(addr())) {
|
||||
if (NativeInstruction::is_load_literal_at(addr())) {
|
||||
address constptr = (address)code()->oop_addr_at(reloc->oop_index());
|
||||
bytes = MacroAssembler::pd_patch_instruction_size(addr(), constptr);
|
||||
assert(*(address*)constptr == x, "error in oop relocation");
|
||||
|
||||
@ -488,4 +488,27 @@ TEST_VM(AssemblerAArch64, merge_ldst_after_expand) {
|
||||
asm_check((const unsigned int *)code.insts()->start(), insns, sizeof insns / sizeof insns[0]);
|
||||
}
|
||||
|
||||
TEST_VM(AssemblerAArch64, native_instruction_load_predicates) {
|
||||
static uint32_t insns[] = {
|
||||
0x58000000, // ldr x0, #0
|
||||
0x18000000, // ldr w0, #0
|
||||
0x1C000000, // ldr s0, #0 (VR bit set to 1, enabling SIMD/FP register)
|
||||
};
|
||||
|
||||
NativeInstruction* ni_ldr = nativeInstruction_at(&insns[0]);
|
||||
EXPECT_TRUE(ni_ldr->is_load_literal());
|
||||
EXPECT_TRUE(ni_ldr->is_ldr_gpr_literal());
|
||||
EXPECT_FALSE(ni_ldr->is_ldrw_gpr_literal());
|
||||
|
||||
NativeInstruction* ni_ldrw = nativeInstruction_at(&insns[1]);
|
||||
EXPECT_TRUE(ni_ldrw->is_load_literal());
|
||||
EXPECT_FALSE(ni_ldrw->is_ldr_gpr_literal());
|
||||
EXPECT_TRUE(ni_ldrw->is_ldrw_gpr_literal());
|
||||
|
||||
NativeInstruction* ni_ldrs = nativeInstruction_at(&insns[2]);
|
||||
EXPECT_TRUE(ni_ldrs->is_load_literal());
|
||||
EXPECT_FALSE(ni_ldrs->is_ldr_gpr_literal());
|
||||
EXPECT_FALSE(ni_ldrs->is_ldrw_gpr_literal());
|
||||
}
|
||||
|
||||
#endif // AARCH64
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user