[aarch64-port-dev ] RFR(S/M): 8247766: [aarch64] guarantee(val < (1U << nbits)) failed: Field too big for insn
Andrew Haley
aph at redhat.com
Thu Jul 9 15:48:59 UTC 2020
On 07/07/2020 12:17, Patric Hedlin wrote:
> Dear all,
>
> I would like to ask for help to review the following change/update:
>
> Issue: https://bugs.openjdk.java.net/browse/JDK-8247766
> Webrev: http://cr.openjdk.java.net/~phedlin/tr8247766/
>
>
> C1 code generation for reading and writing stack-slots does not handle
> large immediate offsets on aarch64. This patch will ensure that
> immediate offsets are admissible for base+(immediate)offset encoding or,
> if this is not the case, will enforce an explicit address calculation to
> a scratch register. (Also correcting a small glitch in 9-bit signed
> immediate encoding check.)
This is all very complicated.
So it seems to me that there is a better way to do this. We already have
MacroAssembler::legitimize_address(), and you should use that.
Like so:
diff -r 7c59af4db158 src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Thu Jul 09 11:01:29 2020 -0400
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Thu Jul 09 11:36:02 2020 -0400
@@ -736,25 +736,32 @@
void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool pop_fpu_stack) {
if (src->is_single_cpu()) {
+ int index = dest->single_stack_ix();
if (is_reference_type(type)) {
- __ str(src->as_register(), frame_map()->address_for_slot(dest->single_stack_ix()));
+ __ str(src->as_register(),
+ __ legitimize_address(frame_map()->address_for_slot(index), BytesPerWord, rscratch1));
__ verify_oop(src->as_register());
} else if (type == T_METADATA || type == T_DOUBLE || type == T_ADDRESS) {
- __ str(src->as_register(), frame_map()->address_for_slot(dest->single_stack_ix()));
+ __ str(src->as_register(),
+ __ legitimize_address(frame_map()->address_for_slot(index), BytesPerWord, rscratch1));
} else {
- __ strw(src->as_register(), frame_map()->address_for_slot(dest->single_stack_ix()));
+ __ strw(src->as_register(),
+ __ legitimize_address(frame_map()->address_for_slot(index), BytesPerInt, rscratch1));
}
} else if (src->is_double_cpu()) {
Address dest_addr_LO = frame_map()->address_for_slot(dest->double_stack_ix(), lo_word_offset_in_bytes);
+ dest_addr_LO = __ legitimize_address(dest_addr_LO, BytesPerLong, rscratch1);
__ str(src->as_register_lo(), dest_addr_LO);
} else if (src->is_single_fpu()) {
Address dest_addr = frame_map()->address_for_slot(dest->single_stack_ix());
+ dest_addr = __ legitimize_address(dest_addr, BytesPerInt, rscratch1);
__ strs(src->as_float_reg(), dest_addr);
} else if (src->is_double_fpu()) {
Address dest_addr = frame_map()->address_for_slot(dest->double_stack_ix());
+ dest_addr = __ legitimize_address(dest_addr, BytesPerLong, rscratch1);
__ strd(src->as_double_reg(), dest_addr);
} else {
stack_offset_in_reach() seems to duplicate the functionality of offset_ok_for_immed(),
and it's only used in this one place. By all means please use the new is_uimm() and
is_simm() in offset_ok_for_immed().
--
Andrew Haley (he/him)
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
https://keybase.io/andrewhaley
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
More information about the hotspot-compiler-dev
mailing list