diff mbox series

[avr] Fix PR117500: Don't ICE on invalid asm operands.

Message ID 94f17a32-69ae-42ca-988a-d7e396d013b7@gjlay.de
State New
Headers show
Series [avr] Fix PR117500: Don't ICE on invalid asm operands. | expand

Commit Message

Georg-Johann Lay Nov. 9, 2024, 11:51 a.m. UTC
This patch avoids an internal compiler error when a %i gets an operand
that's not valid for %i.  It uses output_operand_lossage that outputs
an ordinary error.

Ok to apply?

Johann

--

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.

Comments

Denis Chertykov Nov. 10, 2024, 7:03 p.m. UTC | #1
сб, 9 нояб. 2024 г. в 15:51, Georg-Johann Lay <avr@gjlay.de>:
>
> This patch avoids an internal compiler error when a %i gets an operand
> that's not valid for %i.  It uses output_operand_lossage that outputs
> an ordinary error.
>
> Ok to apply?

Ok, please apply.

Denis.
>
> Johann
>
> --
>
> 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.
diff mbox series

Patch

    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.

diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index 0dca7458d77..39108fa8e3b 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 */