This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, ARM] Avoid aborts in arm_print_operand


There are a number of sanity checks in arm_print_operand that call abort
if they fail.  However, several of these can be tripped by a bogus user
asm statement.  This patch changes the aborts to use
output_operand_lossage which is more friendly to the user if it's their
fault (and should avoid some spurious bug reports in future).

Tested on an arm-unknown-elf cross.

R.
2004-10-12  Richard Earnshaw  <rearnsha@arm.com>

	* arm.c (arm_print_operand): Use output_operand_lossage where possible
	rather than aborting.


Index: arm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.410
diff -p -r1.410 arm.c
*** arm.c	12 Oct 2004 15:38:28 -0000	1.410
--- arm.c	12 Oct 2004 16:39:44 -0000
*************** arm_print_operand (FILE *stream, rtx x, 
*** 10287,10294 ****
      case '?':
        if (arm_ccfsm_state == 3 || arm_ccfsm_state == 4)
  	{
! 	  if (TARGET_THUMB || current_insn_predicate != NULL)
! 	    abort ();
  
  	  fputs (arm_condition_codes[arm_current_cc], stream);
  	}
--- 10287,10303 ----
      case '?':
        if (arm_ccfsm_state == 3 || arm_ccfsm_state == 4)
  	{
! 	  if (TARGET_THUMB)
! 	    {
! 	      output_operand_lossage ("predicated Thumb instruction");
! 	      break;
! 	    }
! 	  if (current_insn_predicate != NULL)
! 	    {
! 	      output_operand_lossage
! 		("predicated instruction in conditional sequence");
! 	      break;
! 	    }
  
  	  fputs (arm_condition_codes[arm_current_cc], stream);
  	}
*************** arm_print_operand (FILE *stream, rtx x, 
*** 10297,10303 ****
  	  enum arm_cond_code code;
  
  	  if (TARGET_THUMB)
! 	    abort ();
  
  	  code = get_arm_condition_code (current_insn_predicate);
  	  fputs (arm_condition_codes[code], stream);
--- 10306,10315 ----
  	  enum arm_cond_code code;
  
  	  if (TARGET_THUMB)
! 	    {
! 	      output_operand_lossage ("predicated Thumb instruction");
! 	      break;
! 	    }
  
  	  code = get_arm_condition_code (current_insn_predicate);
  	  fputs (arm_condition_codes[code], stream);
*************** arm_print_operand (FILE *stream, rtx x, 
*** 10389,10408 ****
  	 of the memory location is actually held in one of the registers
  	 being overwritten by the load.  */
      case 'Q':
!       if (REGNO (x) > LAST_ARM_REGNUM)
! 	abort ();
        asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 1 : 0));
        return;
  
      case 'R':
!       if (REGNO (x) > LAST_ARM_REGNUM)
! 	abort ();
        asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 0 : 1));
        return;
  
      case 'H':
!       if (REGNO (x) > LAST_ARM_REGNUM)
! 	abort ();
        asm_fprintf (stream, "%r", REGNO (x) + 1);
        return;
  
--- 10401,10432 ----
  	 of the memory location is actually held in one of the registers
  	 being overwritten by the load.  */
      case 'Q':
!       if (GET_CODE (x) != REG || REGNO (x) > LAST_ARM_REGNUM)
! 	{
! 	  output_operand_lossage ("invalid operand for code '%c'", code);
! 	  return;
! 	}
! 
        asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 1 : 0));
        return;
  
      case 'R':
!       if (GET_CODE (x) != REG || REGNO (x) > LAST_ARM_REGNUM)
! 	{
! 	  output_operand_lossage ("invalid operand for code '%c'", code);
! 	  return;
! 	}
! 
        asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 0 : 1));
        return;
  
      case 'H':
!       if (GET_CODE (x) != REG || REGNO (x) > LAST_ARM_REGNUM)
! 	{
! 	  output_operand_lossage ("invalid operand for code '%c'", code);
! 	  return;
! 	}
! 
        asm_fprintf (stream, "%r", REGNO (x) + 1);
        return;
  
*************** arm_print_operand (FILE *stream, rtx x, 
*** 10423,10428 ****
--- 10447,10458 ----
        if (x == const_true_rtx)
  	return;
  
+       if (!COMPARISON_P (x))
+ 	{
+ 	  output_operand_lossage ("invalid operand for code '%c'", code);
+ 	  return;
+ 	}
+ 
        fputs (arm_condition_codes[get_arm_condition_code (x)],
  	     stream);
        return;
*************** arm_print_operand (FILE *stream, rtx x, 
*** 10431,10437 ****
        /* CONST_TRUE_RTX means not always -- i.e. never.  We shouldn't ever
  	 want to do that.  */
        if (x == const_true_rtx)
! 	abort ();
  
        fputs (arm_condition_codes[ARM_INVERSE_CONDITION_CODE
  				 (get_arm_condition_code (x))],
--- 10461,10475 ----
        /* CONST_TRUE_RTX means not always -- i.e. never.  We shouldn't ever
  	 want to do that.  */
        if (x == const_true_rtx)
! 	{
! 	  output_operand_lossage ("instruction never exectued");
! 	  return;
! 	}
!       if (!COMPARISON_P (x))
! 	{
! 	  output_operand_lossage ("invalid operand for code '%c'", code);
! 	  return;
! 	}
  
        fputs (arm_condition_codes[ARM_INVERSE_CONDITION_CODE
  				 (get_arm_condition_code (x))],
*************** arm_print_operand (FILE *stream, rtx x, 
*** 10463,10469 ****
  	int mode = GET_MODE (x);
  
  	if (GET_CODE (x) != REG || REGNO_REG_CLASS (REGNO (x)) != CIRRUS_REGS)
! 	  abort ();
  
  	fprintf (stream, "mv%s%s",
  		 mode == DFmode ? "d"
--- 10501,10510 ----
  	int mode = GET_MODE (x);
  
  	if (GET_CODE (x) != REG || REGNO_REG_CLASS (REGNO (x)) != CIRRUS_REGS)
! 	  {
! 	    output_operand_lossage ("invalid operand for code '%c'", code);
! 	    return;
! 	  }
  
  	fprintf (stream, "mv%s%s",
  		 mode == DFmode ? "d"
*************** arm_print_operand (FILE *stream, rtx x, 
*** 10479,10485 ****
  	  || REGNO (x) < FIRST_IWMMXT_GR_REGNUM
  	  || REGNO (x) > LAST_IWMMXT_GR_REGNUM)
  	/* Bad value for wCG register number.  */
! 	abort ();
        else
  	fprintf (stream, "%d", REGNO (x) - FIRST_IWMMXT_GR_REGNUM);
        return;
--- 10520,10530 ----
  	  || REGNO (x) < FIRST_IWMMXT_GR_REGNUM
  	  || REGNO (x) > LAST_IWMMXT_GR_REGNUM)
  	/* Bad value for wCG register number.  */
! 	{
! 	  output_operand_lossage ("invalid operand for code '%c'", code);
! 	  return;
! 	}
! 
        else
  	fprintf (stream, "%d", REGNO (x) - FIRST_IWMMXT_GR_REGNUM);
        return;
*************** arm_print_operand (FILE *stream, rtx x, 
*** 10490,10496 ****
  	  || INTVAL (x) < 0
  	  || INTVAL (x) >= 16)
  	/* Bad value for wC register number.  */
! 	abort ();
        else
  	{
  	  static const char * wc_reg_names [16] =
--- 10535,10545 ----
  	  || INTVAL (x) < 0
  	  || INTVAL (x) >= 16)
  	/* Bad value for wC register number.  */
! 	{
! 	  output_operand_lossage ("invalid operand for code '%c'", code);
! 	  return;
! 	}
! 
        else
  	{
  	  static const char * wc_reg_names [16] =
*************** arm_print_operand (FILE *stream, rtx x, 
*** 10512,10526 ****
  	int num;
  
  	if (mode != DImode && mode != DFmode)
! 	  abort ();
  
  	if (GET_CODE (x) != REG
  	    || !IS_VFP_REGNUM (REGNO (x)))
! 	  abort ();
  
  	num = REGNO(x) - FIRST_VFP_REGNUM;
  	if (num & 1)
! 	  abort ();
  
  	fprintf (stream, "d%d", num >> 1);
        }
--- 10561,10584 ----
  	int num;
  
  	if (mode != DImode && mode != DFmode)
! 	  {
! 	    output_operand_lossage ("invalid operand for code '%c'", code);
! 	    return;
! 	  }
  
  	if (GET_CODE (x) != REG
  	    || !IS_VFP_REGNUM (REGNO (x)))
! 	  {
! 	    output_operand_lossage ("invalid operand for code '%c'", code);
! 	    return;
! 	  }
  
  	num = REGNO(x) - FIRST_VFP_REGNUM;
  	if (num & 1)
! 	  {
! 	    output_operand_lossage ("invalid operand for code '%c'", code);
! 	    return;
! 	  }
  
  	fprintf (stream, "d%d", num >> 1);
        }
*************** arm_print_operand (FILE *stream, rtx x, 
*** 10528,10534 ****
  
      default:
        if (x == 0)
! 	abort ();
  
        if (GET_CODE (x) == REG)
  	asm_fprintf (stream, "%r", REGNO (x));
--- 10586,10595 ----
  
      default:
        if (x == 0)
! 	{
! 	  output_operand_lossage ("missing operand");
! 	  return;
! 	}
  
        if (GET_CODE (x) == REG)
  	asm_fprintf (stream, "%r", REGNO (x));

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]