Looking at some AArch64 code, we seem to encode lots of immediates with adrp+add, but some, unencodeable by adrp with mov.
enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{
Register dst_reg = as_Register($dst$$reg);
address con = (address)$src$$constant;
...
if (! __ is_valid_AArch64_address(con) ||
con < (address)(uintptr_t)os::vm_page_size()) {
__ mov(dst_reg, con);
} else {
uint64_t offset;
__ adrp(dst_reg, con, offset);
__ add(dst_reg, dst_reg, offset);
}
...
}
There is also a shortcut to use mov when constant is below page size. Why page size, though? I wonder if this is a shortcut to mean "small immediates", so that we end up doing single-instruction movn/movz that are able to do 16-bit immediates? This might not be as great when pages are 64K?
enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{
Register dst_reg = as_Register($dst$$reg);
address con = (address)$src$$constant;
...
if (! __ is_valid_AArch64_address(con) ||
con < (address)(uintptr_t)os::vm_page_size()) {
__ mov(dst_reg, con);
} else {
uint64_t offset;
__ adrp(dst_reg, con, offset);
__ add(dst_reg, dst_reg, offset);
}
...
}
There is also a shortcut to use mov when constant is below page size. Why page size, though? I wonder if this is a shortcut to mean "small immediates", so that we end up doing single-instruction movn/movz that are able to do 16-bit immediates? This might not be as great when pages are 64K?