diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index f62ea8a43deb99d8bfcb08f736c34cb3cc5dfee8..dc68675b2bc2550b2f8f5aa0d3f32e7505cfd70c 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -2602,6 +2602,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) @@ -2613,34 +2676,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)) { @@ -2660,10 +2696,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) @@ -2701,14 +2733,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 */