https://gcc.gnu.org/g:dac2236d12583c43b7163fdb1d9d5bf49a3b5fd0
commit r13-9196-gdac2236d12583c43b7163fdb1d9d5bf49a3b5fd0 Author: Georg-Johann Lay <a...@gjlay.de> Date: Sat Nov 9 12:40:48 2024 +0100 AVR: target/117500 - Use output_operand_lossage in avr_print_operand. PR target/117500 gcc/ * config/avr/avr.cc (avr_print_operand) [code = 'i']: Use output_operand_lossage on bad operands instead of fatal_insn. (cherry picked from commit 02d7370966ac19af966b827b4c984e8a38fdf728) Diff: --- gcc/config/avr/avr.cc | 104 +++++++++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 40 deletions(-) diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index f5e53aba708e..d729936b7daa 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -3209,6 +3209,69 @@ avr_print_operand (FILE *file, rtx x, int code) rtx op = XEXP (XEXP (x, 0), 0); fprintf (file, "%s", reg_names[REGNO (op) + ij]); } + else if (code == 'i') + { + const int sfr0 = avr_arch->sfr_offset; + bool lossage_p = false; + + switch (GET_CODE (x)) + { + default: + lossage_p = true; + break; + + case CONST_INT: + { + const auto ival = INTVAL (x); + + if (io_address_operand (x, VOIDmode)) + { + if (AVR_HAVE_RAMPZ && ival == avr_addr.rampz) + fprintf (file, "__RAMPZ__"); + else if (AVR_HAVE_RAMPY && ival == avr_addr.rampy) + fprintf (file, "__RAMPY__"); + else if (AVR_HAVE_RAMPX && ival == avr_addr.rampx) + fprintf (file, "__RAMPX__"); + else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd) + fprintf (file, "__RAMPD__"); + else if ((AVR_XMEGA || AVR_TINY) && ival == avr_addr.ccp) + fprintf (file, "__CCP__"); + else if (ival == avr_addr.sreg) fprintf (file, "__SREG__"); + else if (ival == avr_addr.sp_l) fprintf (file, "__SP_L__"); + else if (ival == avr_addr.sp_h) fprintf (file, "__SP_H__"); + else + fprintf (file, HOST_WIDE_INT_PRINT_HEX, ival - sfr0); + } + else + output_operand_lossage + ("bad I/O address 0x" HOST_WIDE_INT_PRINT_HEX_PURE + " outside of valid range [0x%x, 0x%x] for %%i operand", + ival, sfr0, sfr0 + 0x3f); + } + break; // CONST_INT + + case MEM: + if (io_address_operand (XEXP (x, 0), VOIDmode)) + avr_print_operand (file, XEXP (x, 0), 'i'); + else + lossage_p = true; + break; + + case SYMBOL_REF: + if (io_address_operand (x, VOIDmode)) + { + rtx addr = plus_constant (HImode, x, -sfr0); + avr_print_operand_address (file, VOIDmode, addr); + } + else + lossage_p = true; + break; + } // switch code + + if (lossage_p) + output_operand_lossage ("%s operand cannot be used as %%i I/O " + "address operand", rtx_name[GET_CODE (x)]); + } // code = i else if (REG_P (x)) { if (x == zero_reg_rtx) @@ -3220,34 +3283,7 @@ avr_print_operand (FILE *file, rtx x, int code) } else if (CONST_INT_P (x)) { - HOST_WIDE_INT ival = INTVAL (x); - - if ('i' != code) - fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival + abcd); - else if (low_io_address_operand (x, VOIDmode) - || high_io_address_operand (x, VOIDmode)) - { - if (AVR_HAVE_RAMPZ && ival == avr_addr.rampz) - fprintf (file, "__RAMPZ__"); - else if (AVR_HAVE_RAMPY && ival == avr_addr.rampy) - fprintf (file, "__RAMPY__"); - else if (AVR_HAVE_RAMPX && ival == avr_addr.rampx) - fprintf (file, "__RAMPX__"); - else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd) - fprintf (file, "__RAMPD__"); - else if ((AVR_XMEGA || AVR_TINY) && ival == avr_addr.ccp) - fprintf (file, "__CCP__"); - else if (ival == avr_addr.sreg) fprintf (file, "__SREG__"); - else if (ival == avr_addr.sp_l) fprintf (file, "__SP_L__"); - else if (ival == avr_addr.sp_h) fprintf (file, "__SP_H__"); - else - { - fprintf (file, HOST_WIDE_INT_PRINT_HEX, - ival - avr_arch->sfr_offset); - } - } - else - fatal_insn ("bad address, not an I/O address:", x); + fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd); } else if (MEM_P (x)) { @@ -3267,10 +3303,6 @@ avr_print_operand (FILE *file, rtx x, int code) } output_addr_const (file, addr); } - else if (code == 'i') - { - avr_print_operand (file, addr, 'i'); - } else if (code == 'o') { if (GET_CODE (addr) != PLUS) @@ -3308,14 +3340,6 @@ avr_print_operand (FILE *file, rtx x, int code) else avr_print_operand_address (file, VOIDmode, addr); } - else if (code == 'i') - { - if (SYMBOL_REF_P (x) && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO)) - avr_print_operand_address - (file, VOIDmode, plus_constant (HImode, x, -avr_arch->sfr_offset)); - else - fatal_insn ("bad address, not an I/O address:", x); - } else if (code == 'x') { /* Constant progmem address - like used in jmp or call */