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.
@@ -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 */