[aarch64-port-dev ] RFR(S/M): 8247766: [aarch64] guarantee(val < (1U << nbits)) failed: Field too big for insn
Patric Hedlin
patric.hedlin at oracle.com
Mon Jul 27 10:02:49 UTC 2020
Hi Andrew,
On 2020-07-09 17:48, Andrew Haley wrote:
> 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().
>
I've refreshed the webrev (as discussed off-line), moving
legitimize_address() into the stack_slot_address() with additional
conditions related to the (well-aligned) frame slot address produced.
Use of is_simm9() and is_uimm12() is now using implementation in Assembler.
/Patric
More information about the aarch64-port-dev
mailing list