< prev index next >
src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
Print this page
8248238: Adding Windows support to OpenJDK on AArch64
Summary: LP64 vs LLP64 changes to add Windows support
Contributed-by: Monica Beckwith <monica.beckwith@microsoft.com>, Ludovic Henry <luhenry@microsoft.com>
Reviewed-by:
8248238: Adding Windows support to OpenJDK on AArch64
Summary: Adding Windows support for AArch64
Contributed-by: Ludovic Henry <luhenry@microsoft.com>, Monica Beckwith <monica.beckwith@microsoft.com>
Reviewed-by:
*** 190,208 ****
virtual void _call_Unimplemented(address call_site) {
mov(rscratch2, call_site);
}
#define call_Unimplemented() _call_Unimplemented((address)__PRETTY_FUNCTION__)
// aliases defined in AARCH64 spec
template<class T>
inline void cmpw(Register Rd, T imm) { subsw(zr, Rd, imm); }
inline void cmp(Register Rd, unsigned char imm8) { subs(zr, Rd, imm8); }
! inline void cmp(Register Rd, unsigned imm) __attribute__ ((deprecated));
inline void cmnw(Register Rd, unsigned imm) { addsw(zr, Rd, imm); }
inline void cmn(Register Rd, unsigned imm) { adds(zr, Rd, imm); }
void cset(Register Rd, Assembler::Condition cond) {
--- 190,212 ----
virtual void _call_Unimplemented(address call_site) {
mov(rscratch2, call_site);
}
+ #ifdef _WIN64
+ #define call_Unimplemented() _call_Unimplemented((address)__FUNCSIG__)
+ #else
#define call_Unimplemented() _call_Unimplemented((address)__PRETTY_FUNCTION__)
+ #endif
// aliases defined in AARCH64 spec
template<class T>
inline void cmpw(Register Rd, T imm) { subsw(zr, Rd, imm); }
inline void cmp(Register Rd, unsigned char imm8) { subs(zr, Rd, imm8); }
! inline DEPRECATED void cmp(Register Rd, unsigned imm);
inline void cmnw(Register Rd, unsigned imm) { addsw(zr, Rd, imm); }
inline void cmn(Register Rd, unsigned imm) { adds(zr, Rd, imm); }
void cset(Register Rd, Assembler::Condition cond) {
*** 454,465 ****
// macro assembly operations needed for aarch64
// first two private routines for loading 32 bit or 64 bit constants
private:
! void mov_immediate64(Register dst, u_int64_t imm64);
! void mov_immediate32(Register dst, u_int32_t imm32);
int push(unsigned int bitset, Register stack);
int pop(unsigned int bitset, Register stack);
int push_fp(unsigned int bitset, Register stack);
--- 458,469 ----
// macro assembly operations needed for aarch64
// first two private routines for loading 32 bit or 64 bit constants
private:
! void mov_immediate64(Register dst, uint64_t imm64);
! void mov_immediate32(Register dst, uint32_t imm32);
int push(unsigned int bitset, Register stack);
int pop(unsigned int bitset, Register stack);
int push_fp(unsigned int bitset, Register stack);
*** 484,514 ****
// now mov instructions for loading absolute addresses and 32 or
// 64 bit integers
inline void mov(Register dst, address addr)
{
! mov_immediate64(dst, (u_int64_t)addr);
}
! inline void mov(Register dst, u_int64_t imm64)
{
mov_immediate64(dst, imm64);
}
! inline void movw(Register dst, u_int32_t imm32)
{
mov_immediate32(dst, imm32);
}
! inline void mov(Register dst, long l)
{
! mov(dst, (u_int64_t)l);
}
inline void mov(Register dst, int i)
{
! mov(dst, (long)i);
}
void mov(Register dst, RegisterOrConstant src) {
if (src.is_register())
mov(dst, src.as_register());
--- 488,518 ----
// now mov instructions for loading absolute addresses and 32 or
// 64 bit integers
inline void mov(Register dst, address addr)
{
! mov_immediate64(dst, (uint64_t)addr);
}
! inline void mov(Register dst, uint64_t imm64)
{
mov_immediate64(dst, imm64);
}
! inline void movw(Register dst, uint32_t imm32)
{
mov_immediate32(dst, imm32);
}
! inline void mov(Register dst, int64_t l)
{
! mov(dst, (uint64_t)l);
}
inline void mov(Register dst, int i)
{
! mov(dst, (int64_t)i);
}
void mov(Register dst, RegisterOrConstant src) {
if (src.is_register())
mov(dst, src.as_register());
*** 516,548 ****
mov(dst, src.as_constant());
}
void movptr(Register r, uintptr_t imm64);
! void mov(FloatRegister Vd, SIMD_Arrangement T, u_int32_t imm32);
void mov(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) {
orr(Vd, T, Vn, Vn);
}
public:
// Generalized Test Bit And Branch, including a "far" variety which
// spans more than 32KiB.
! void tbr(Condition cond, Register Rt, int bitpos, Label &dest, bool far = false) {
assert(cond == EQ || cond == NE, "must be");
! if (far)
cond = ~cond;
void (Assembler::* branch)(Register Rt, int bitpos, Label &L);
if (cond == Assembler::EQ)
branch = &Assembler::tbz;
else
branch = &Assembler::tbnz;
! if (far) {
Label L;
(this->*branch)(Rt, bitpos, L);
b(dest);
bind(L);
} else {
--- 520,552 ----
mov(dst, src.as_constant());
}
void movptr(Register r, uintptr_t imm64);
! void mov(FloatRegister Vd, SIMD_Arrangement T, uint32_t imm32);
void mov(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) {
orr(Vd, T, Vn, Vn);
}
public:
// Generalized Test Bit And Branch, including a "far" variety which
// spans more than 32KiB.
! void tbr(Condition cond, Register Rt, int bitpos, Label &dest, bool isfar = false) {
assert(cond == EQ || cond == NE, "must be");
! if (isfar)
cond = ~cond;
void (Assembler::* branch)(Register Rt, int bitpos, Label &L);
if (cond == Assembler::EQ)
branch = &Assembler::tbz;
else
branch = &Assembler::tbnz;
! if (isfar) {
Label L;
(this->*branch)(Rt, bitpos, L);
b(dest);
bind(L);
} else {
*** 1168,1178 ****
void add(Register Rd, Register Rn, RegisterOrConstant increment);
void addw(Register Rd, Register Rn, RegisterOrConstant increment);
void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
! void adrp(Register reg1, const Address &dest, unsigned long &byte_offset);
void tableswitch(Register index, jint lowbound, jint highbound,
Label &jumptable, Label &jumptable_end, int stride = 1) {
adr(rscratch1, jumptable);
subsw(rscratch2, index, lowbound);
--- 1172,1182 ----
void add(Register Rd, Register Rn, RegisterOrConstant increment);
void addw(Register Rd, Register Rn, RegisterOrConstant increment);
void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
! void adrp(Register reg1, const Address &dest, uint64_t &byte_offset);
void tableswitch(Register index, jint lowbound, jint highbound,
Label &jumptable, Label &jumptable_end, int stride = 1) {
adr(rscratch1, jumptable);
subsw(rscratch2, index, lowbound);
*** 1185,1195 ****
// Form an address from base + offset in Rd. Rd may or may not
// actually be used: you must use the Address that is returned. It
// is up to you to ensure that the shift provided matches the size
// of your data.
! Address form_address(Register Rd, Register base, long byte_offset, int shift);
// Return true iff an address is within the 48-bit AArch64 address
// space.
bool is_valid_AArch64_address(address a) {
return ((uint64_t)a >> 48) == 0;
--- 1189,1199 ----
// Form an address from base + offset in Rd. Rd may or may not
// actually be used: you must use the Address that is returned. It
// is up to you to ensure that the shift provided matches the size
// of your data.
! Address form_address(Register Rd, Register base, int64_t byte_offset, int shift);
// Return true iff an address is within the 48-bit AArch64 address
// space.
bool is_valid_AArch64_address(address a) {
return ((uint64_t)a >> 48) == 0;
*** 1210,1220 ****
void ldr_constant(Register dest, const Address &const_addr) {
if (NearCpool) {
ldr(dest, const_addr);
} else {
! unsigned long offset;
adrp(dest, InternalAddress(const_addr.target()), offset);
ldr(dest, Address(dest, offset));
}
}
--- 1214,1224 ----
void ldr_constant(Register dest, const Address &const_addr) {
if (NearCpool) {
ldr(dest, const_addr);
} else {
! uint64_t offset;
adrp(dest, InternalAddress(const_addr.target()), offset);
ldr(dest, Address(dest, offset));
}
}
*** 1235,1245 ****
void string_equals(Register a1, Register a2, Register result, Register cnt1,
int elem_size);
void fill_words(Register base, Register cnt, Register value);
! void zero_words(Register base, u_int64_t cnt);
void zero_words(Register ptr, Register cnt);
void zero_dcache_blocks(Register base, Register cnt);
static const int zero_words_block_size;
--- 1239,1249 ----
void string_equals(Register a1, Register a2, Register result, Register cnt1,
int elem_size);
void fill_words(Register base, Register cnt, Register value);
! void zero_words(Register base, uint64_t cnt);
void zero_words(Register ptr, Register cnt);
void zero_dcache_blocks(Register base, Register cnt);
static const int zero_words_block_size;
*** 1308,1318 ****
private:
// Returns an address on the stack which is reachable with a ldr/str of size
// Uses rscratch2 if the address is not directly reachable
Address spill_address(int size, int offset, Register tmp=rscratch2);
! bool merge_alignment_check(Register base, size_t size, long cur_offset, long prev_offset) const;
// Check whether two loads/stores can be merged into ldp/stp.
bool ldst_can_merge(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store) const;
// Merge current load/store with previous load/store into ldp/stp.
--- 1312,1322 ----
private:
// Returns an address on the stack which is reachable with a ldr/str of size
// Uses rscratch2 if the address is not directly reachable
Address spill_address(int size, int offset, Register tmp=rscratch2);
! bool merge_alignment_check(Register base, size_t size, int64_t cur_offset, int64_t prev_offset) const;
// Check whether two loads/stores can be merged into ldp/stp.
bool ldst_can_merge(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store) const;
// Merge current load/store with previous load/store into ldp/stp.
< prev index next >