public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: inline abort
@ 1998-05-14 11:09 Michael Meissner
  0 siblings, 0 replies; 10+ messages in thread
From: Michael Meissner @ 1998-05-14 11:09 UTC (permalink / raw)
  To: law; +Cc: egcs

| It means that we can't put a breakpoint on abort when debugging
| the compiler. :-)  And gdb's handling of random trap instructions
| may be less than ideal on some platforms -- kind-of depends on
| what signal the OS gives on a trap instruction.

With my new abort patches to print internal error and source/line #, putting a
breakpoint on abort will never be triggered unless you define USE_SYSTEM_ABORT.
That's why I put a breakpoint on exit in the .gdbinitrc file.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: inline abort
  1998-05-17 18:05 Michael Meissner
@ 1998-05-18 11:01 ` Jeffrey A Law
  0 siblings, 0 replies; 10+ messages in thread
From: Jeffrey A Law @ 1998-05-18 11:01 UTC (permalink / raw)
  To: Michael Meissner; +Cc: rth, egcs

  In message < 199805180105.VAA06094@tiktok.cygnus.com >you write:
  > | While I don't think it should ever automatically replace the 
  > | libc abort call (for POSIX and ISO reasons), I can see some use
  > | for __builtin_abort.  And if a program ever wanted to have that
  > | as the default, it could define abort to be __builtin_abort.
  > 
  > I would prefer to use another name for __builtin_abort (such as
  > __builtin_trap).  Otherwise, abort is the only routine that has a different
  > behavior than the __builtin_ counterpart.
Yes.  That would actually make the patch a lot better (IMHO).  What
we're really adding is builtin trap support, not a buildin "abort"
support.

jeff

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: inline abort
@ 1998-05-17 18:05 Michael Meissner
  1998-05-18 11:01 ` Jeffrey A Law
  0 siblings, 1 reply; 10+ messages in thread
From: Michael Meissner @ 1998-05-17 18:05 UTC (permalink / raw)
  To: rth; +Cc: egcs

| No it doesn't, since he wants to be able to make 
|
| 	if (pred) abort();
|
| use the conditional trap available on some machines.
|
| While I don't think it should ever automatically replace the 
| libc abort call (for POSIX and ISO reasons), I can see some use
| for __builtin_abort.  And if a program ever wanted to have that
| as the default, it could define abort to be __builtin_abort.

I would prefer to use another name for __builtin_abort (such as
__builtin_trap).  Otherwise, abort is the only routine that has a different
behavior than the __builtin_ counterpart.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: inline abort
  1998-05-16  9:15     ` Mark Mitchell
@ 1998-05-16 16:45       ` Richard Henderson
  0 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 1998-05-16 16:45 UTC (permalink / raw)
  To: mmitchell, jfc; +Cc: law, egcs

On Sat, May 16, 1998 at 09:17:18AM -0700, Mark Mitchell wrote:
> Is it possible to do this "at user-level" with a macro defining
> my_abort () to be asm ( "..." ) the asm is the correct trap
> instruction?  Perhaps that doesn't allow some of the optimizations you
> desire.  If it doesn't, I see the point of your patch, but I think it
> should be off by default.

No it doesn't, since he wants to be able to make 

	if (pred) abort();

use the conditional trap available on some machines.

While I don't think it should ever automatically replace the 
libc abort call (for POSIX and ISO reasons), I can see some use
for __builtin_abort.  And if a program ever wanted to have that
as the default, it could define abort to be __builtin_abort.


r~

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: inline abort
  1998-05-14 22:14     ` Jim Wilson
@ 1998-05-16 14:32       ` John Carr
  0 siblings, 0 replies; 10+ messages in thread
From: John Carr @ 1998-05-16 14:32 UTC (permalink / raw)
  To: Jim Wilson; +Cc: law, egcs

I did this work a long time ago, possibly before standards required
abort to flush buffers and certainly before that was standard
implemented behavior.  My inspiration for inline abort was noticing
that the abort function on my system was a trap instruction.

Is it OK to install the back end changes?


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: inline abort
  1998-05-14  5:03   ` John Carr
  1998-05-14 22:14     ` Jim Wilson
@ 1998-05-16  9:15     ` Mark Mitchell
  1998-05-16 16:45       ` Richard Henderson
  1 sibling, 1 reply; 10+ messages in thread
From: Mark Mitchell @ 1998-05-16  9:15 UTC (permalink / raw)
  To: jfc; +Cc: law, egcs

>>>>> "John" == John Carr <jfc@MIT.EDU> writes:

    >> It means that we can't put a breakpoint on abort when debugging
    >> the compiler.

    John> It means you don't need to put a breakpoint on abort: the
    John> process stops on a trap and the debugger takes control.

    >> And gdb's handling of random trap instructions may be less than
    >> ideal on some platforms

    John> It works fine on Solaris.  I did see a debugger have
    John> problems on a different system a few years ago, probably
    John> because it used the same instruction to implement
    John> breakpoints.

    >> Or a different signal may be raised than SIGABRT when we hit
    >> one of these trap instructions.

    John> That is true.  You get a choice of several signals on
    John> Solaris but I don't think SIGABRT is one of them.  -ansi
    John> should disable use of trap calls to implement abort on
    John> systems where trap does not generate the correct signal.

I don't think it is a good idea to have this change enabled by
default.  Using -ansi to get ANSI behavior is reasonable, but this is
a major change in behavior.  Usually, without -ansi either some GNU
extensions are accepted that would't be, but the cases in which major
behavior is altered are rare.

Is it possible to do this "at user-level" with a macro defining
my_abort () to be asm ( "..." ) the asm is the correct trap
instruction?  Perhaps that doesn't allow some of the optimizations you
desire.  If it doesn't, I see the point of your patch, but I think it
should be off by default.

-- 
Mark Mitchell <mmitchell@usa.net>
http://home.earthlink.net/~mbmitchell
Consulting Services Available

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: inline abort
  1998-05-14  5:03   ` John Carr
@ 1998-05-14 22:14     ` Jim Wilson
  1998-05-16 14:32       ` John Carr
  1998-05-16  9:15     ` Mark Mitchell
  1 sibling, 1 reply; 10+ messages in thread
From: Jim Wilson @ 1998-05-14 22:14 UTC (permalink / raw)
  To: John Carr; +Cc: law, egcs

Ulrich Drepper had some very good comments on your inline abort patch.
He pointed me at the gnu/libc abort sources, and it turns out to be a lot
more complicated than one might think.

For instance, POSIX.1 requires that a call to abort runs fclose for every
open stream if the process is terminated.  I don't see how this can happen
if we use an inline trap instruction.

The ISO C standard says that abort must raise SIGABRT.  If the user has
a SIGABRT handler installed, we must call it.

Given the semantics of abort as defined by ISO C and POSIX, I don't see
how we can replace it with a trap instruction by default without breaking
some programs.  Hence this can work only as an option.

Jim

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: inline abort
  1998-04-18 17:53 John Carr
@ 1998-05-14  5:54 ` Jeffrey A Law
  1998-05-14  5:03   ` John Carr
  0 siblings, 1 reply; 10+ messages in thread
From: Jeffrey A Law @ 1998-05-14  5:54 UTC (permalink / raw)
  To: John Carr; +Cc: egcs

  In message <199804182233.SAA10103@jfc.>you write:
  > 
  > These changes cause abort calls to be compiled to inline trap
  > instructions.  This generally reduces code size and gives the
  > compiler more optimization opportunities by making basic blocks
  > longer.  Depending on chip and cache hit rates an untaken
  > conditional trap instruction may be faster or slower than a
  > conditional branch.
  > 
  > There is an assumption, which could be changed, that traps are
  > unrecoverable.
  > 
  > I include an implementation for SPARC and RS/6000.  The RS/6000
  > version may have sufferred some bit rot.  I haven't bootstrapped
  > it in a long time.
  > 
  > jump_optimize needs rewriting but I think everyone is afraid to touch it.
  > "temp" ... "temp4" are not good choices for variable names.
I'm not sure this is necessarily a good idea.

It means that we can't put a breakpoint on abort when debugging
the compiler. :-)  And gdb's handling of random trap instructions
may be less than ideal on some platforms -- kind-of depends on
what signal the OS gives on a trap instruction.

It means that a program can't set up a signal handler to catch
SIGABRT since the signal may never be raised.  Or a different
signal may be raised than SIGABRT when we hit one of these trap
instructions.

Maybe it would be useful an an option, but I don't think it should
be on by default.

Other opinions?

jeff

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: inline abort
  1998-05-14  5:54 ` Jeffrey A Law
@ 1998-05-14  5:03   ` John Carr
  1998-05-14 22:14     ` Jim Wilson
  1998-05-16  9:15     ` Mark Mitchell
  0 siblings, 2 replies; 10+ messages in thread
From: John Carr @ 1998-05-14  5:03 UTC (permalink / raw)
  To: law; +Cc: egcs

> It means that we can't put a breakpoint on abort when debugging
> the compiler.

It means you don't need to put a breakpoint on abort: the process
stops on a trap and the debugger takes control.

>  And gdb's handling of random trap instructions
> may be less than ideal on some platforms

It works fine on Solaris.  I did see a debugger have problems on a
different system a few years ago, probably because it used the same
instruction to implement breakpoints.

> Or a different signal may be raised than SIGABRT when we hit one of
> these trap instructions.

That is true.  You get a choice of several signals on Solaris but I
don't think SIGABRT is one of them.  -ansi should disable use of trap
calls to implement abort on systems where trap does not generate the
correct signal.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* inline abort
@ 1998-04-18 17:53 John Carr
  1998-05-14  5:54 ` Jeffrey A Law
  0 siblings, 1 reply; 10+ messages in thread
From: John Carr @ 1998-04-18 17:53 UTC (permalink / raw)
  To: egcs

These changes cause abort calls to be compiled to inline trap
instructions.  This generally reduces code size and gives the
compiler more optimization opportunities by making basic blocks
longer.  Depending on chip and cache hit rates an untaken
conditional trap instruction may be faster or slower than a
conditional branch.

There is an assumption, which could be changed, that traps are
unrecoverable.

I include an implementation for SPARC and RS/6000.  The RS/6000
version may have sufferred some bit rot.  I haven't bootstrapped
it in a long time.

jump_optimize needs rewriting but I think everyone is afraid to touch it.
"temp" ... "temp4" are not good choices for variable names.


Sat Apr 18 15:58:35 1998  John Carr  <jfc@mit.edu>

	* haifa-sched.c (haifa_classify_insn): TRAP_IF is risky.
	(sched_analyze_2): Allow scheduling TRAP_IF.

	* reorg.c (mark_referenced_resources): Examine operands of TRAP_IF.

	* rtl.h (TRAP_CODE): New macro.

	* rtl.def (TRAP_IF): Change second operand type to rtx.

	* optabs.c (gen_cond_trap): New function.
	(init_traps): New function.
	(init_optabs): Call init_traps.
	* expr.h: Declare gen_cond_trap.

	* jump.c (jump_optimize): Optimize jumps to and around traps.

	* sparc.md: Define trap instructions.

	* rs6000.md: Define trap instructions.
	* rs6000.c (print_operand): New code 'V' for trap condition.
	(trap_comparison_operator): New function.

	* m88k.md: Update use of TRAP_IF.

	* tree.h (enum built_in_function): New value BUILT_IN_ABORT.
	* c-decl.c (init_decl_processing): abort is a builtin function.
	* cp/decl.c (init_decl_processing): abort is a builtin function.
	* expr.c (expand_builtin): Handle BUILT_IN_ABORT.
	* stmt.c (expand_end_bindings): Use trap instruction instead of
	calling abort.

*** haifa-sched.c~	Fri Apr 17 15:57:04 1998
--- haifa-sched.c	Sat Apr 18 15:56:25 1998
***************
*** 2579,2584 ****
--- 2579,2588 ----
  	      tmp_class =
  		WORST_CLASS (tmp_class,
  			   may_trap_exp (SET_SRC (XVECEXP (pat, 0, i)), 0));
+ 	      break;
+ 	    case TRAP_IF:
+ 	      tmp_class = TRAP_RISKY;
+ 	      break;
  	    default:;
  	    }
  	  insn_class = WORST_CLASS (insn_class, tmp_class);
***************
*** 2604,2609 ****
--- 2608,2617 ----
  	  tmp_class =
  	    WORST_CLASS (tmp_class,
  			 may_trap_exp (SET_SRC (pat), 0));
+ 	  break;
+ 	case TRAP_IF:
+ 	  tmp_class = TRAP_RISKY;
+ 	  break;
  	default:;
  	}
        insn_class = tmp_class;
***************
*** 3510,3519 ****
  	return;
        }
  
      case ASM_OPERANDS:
      case ASM_INPUT:
      case UNSPEC_VOLATILE:
-     case TRAP_IF:
        {
  	rtx u;
  
--- 3518,3531 ----
  	return;
        }
  
+     /* Force pending stores to memory in case a trap handler needs them.  */
+     case TRAP_IF:
+       flush_pending_lists (insn, 1);
+       break;
+ 
      case ASM_OPERANDS:
      case ASM_INPUT:
      case UNSPEC_VOLATILE:
        {
  	rtx u;
  
*** rtl.h~	Fri Apr 17 19:10:04 1998
--- rtl.h	Sat Apr 18 08:23:07 1998
***************
*** 578,583 ****
--- 578,584 ----
  
  /* For a TRAP_IF rtx, TRAP_CONDITION is an expression.  */
  #define TRAP_CONDITION(RTX) ((RTX)->fld[0].rtx)
+ #define TRAP_CODE(RTX) (RTX)->fld[1].rtx
  
  /* 1 in a SYMBOL_REF if it addresses this function's constants pool.  */
  #define CONSTANT_POOL_ADDRESS_P(RTX) ((RTX)->unchanging)
*** rtl.def~	Sat Apr  4 04:04:08 1998
--- rtl.def	Sat Apr 18 08:23:16 1998
***************
*** 502,508 ****
     Operand 1 is the condition.
     Operand 2 is the trap code.
     For an unconditional trap, make the condition (const_int 1).  */
! DEF_RTL_EXPR(TRAP_IF, "trap_if", "ei", 'x')
  
  /* ----------------------------------------------------------------------
     Primitive values for use in expressions.
--- 502,508 ----
     Operand 1 is the condition.
     Operand 2 is the trap code.
     For an unconditional trap, make the condition (const_int 1).  */
! DEF_RTL_EXPR(TRAP_IF, "trap_if", "ee", 'x')
  
  /* ----------------------------------------------------------------------
     Primitive values for use in expressions.
*** m88k.md~	Wed Apr  1 18:18:54 1998
--- m88k.md	Sat Apr 18 09:06:11 1998
***************
*** 2810,2816 ****
  
  ;; Division by 0 trap
  (define_insn "trap_divide_by_zero"
!   [(trap_if (const_int 1) 503)]
    ""
    "tb0 0,%#r0,503"
    [(set_attr "type" "weird")])
--- 2810,2816 ----
  
  ;; Division by 0 trap
  (define_insn "trap_divide_by_zero"
!   [(trap_if (const_int 1) (const_int 503))]
    ""
    "tb0 0,%#r0,503"
    [(set_attr "type" "weird")])
***************
*** 2822,2828 ****
  			  (const_int 0))
  		      (pc)
  		      (match_operand 1 "" "")))
!    (trap_if (const_int 1) 503)]
    ""
    "
  {
--- 2822,2828 ----
  			  (const_int 0))
  		      (pc)
  		      (match_operand 1 "" "")))
!    (trap_if (const_int 1) (const_int 503))]
    ""
    "
  {
***************
*** 3451,3457 ****
  (define_insn "tbnd"
    [(trap_if (gtu (match_operand:SI 0 "register_operand" "r")
  		 (match_operand:SI 1 "arith_operand" "rI"))
! 	    7)]
    ""
    "tbnd %r0,%1"
    [(set_attr "type" "weird")])
--- 3451,3457 ----
  (define_insn "tbnd"
    [(trap_if (gtu (match_operand:SI 0 "register_operand" "r")
  		 (match_operand:SI 1 "arith_operand" "rI"))
! 	    (const_int 7))]
    ""
    "tbnd %r0,%1"
    [(set_attr "type" "weird")])
***************
*** 3458,3464 ****
  
  ;; Just in case the optimizer decides to fold away the test.
  (define_insn ""
!   [(trap_if (const_int 1) 7)]
    ""
    "tbnd %#r31,0"
    [(set_attr "type" "weird")])
--- 3458,3464 ----
  
  ;; Just in case the optimizer decides to fold away the test.
  (define_insn ""
!   [(trap_if (const_int 1) (const_int 7))]
    ""
    "tbnd %#r31,0"
    [(set_attr "type" "weird")])
*** expr.h~	Sat Apr  4 14:53:20 1998
--- expr.h	Sat Apr 18 08:24:30 1998
***************
*** 660,665 ****
--- 660,668 ----
  
  /* Given a JUMP_INSN, return a description of the test being made.  */
  extern rtx get_condition PROTO((rtx, rtx *));
+ 
+ /* Generate a conditional trap instruction.  */
+ extern rtx gen_cond_trap PROTO((enum rtx_code, rtx, rtx, rtx));
  \f
  /* Functions from expr.c:  */
  
*** expr.c~	Fri Apr 17 15:55:16 1998
--- expr.c	Sat Apr 18 09:10:09 1998
***************
*** 8782,8787 ****
--- 8782,8797 ----
        break;
  #endif
  
+     case BUILT_IN_ABORT:
+ #ifdef HAVE_trap
+       if (HAVE_trap)
+ 	emit_insn (gen_trap ());
+       else
+ #endif
+ 	expand_call (exp, NULL_RTX, 1);
+       emit_barrier ();
+       return const0_rtx;
+ 
      case BUILT_IN_SETJMP:
        if (arglist == 0
  	  || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
*** c-decl.c~	Sat Apr  4 14:52:50 1998
--- c-decl.c	Sat Apr 18 09:09:47 1998
***************
*** 3425,3431 ****
  	 to avoid spurious "control drops through" warnings.  */
        /* Don't specify the argument types, to avoid errors
  	 from certain code which isn't valid in ANSI but which exists.  */
!       temp = builtin_function ("abort", void_ftype_any, NOT_BUILT_IN,
  			       NULL_PTR);
        TREE_THIS_VOLATILE (temp) = 1;
        TREE_SIDE_EFFECTS (temp) = 1;
--- 3425,3431 ----
  	 to avoid spurious "control drops through" warnings.  */
        /* Don't specify the argument types, to avoid errors
  	 from certain code which isn't valid in ANSI but which exists.  */
!       temp = builtin_function ("abort", void_ftype_any, BUILT_IN_ABORT,
  			       NULL_PTR);
        TREE_THIS_VOLATILE (temp) = 1;
        TREE_SIDE_EFFECTS (temp) = 1;
*** tree.h~	Fri Apr 17 18:46:57 1998
--- tree.h	Sat Apr 18 09:09:20 1998
***************
*** 108,113 ****
--- 108,114 ----
    BUILT_IN_RETURN,
    BUILT_IN_SETJMP,
    BUILT_IN_LONGJMP,
+   BUILT_IN_ABORT,
  
    /* Various hooks for the DWARF 2 __throw routine.  */
    BUILT_IN_FP, BUILT_IN_SP,
*** reorg.c~	Fri Apr 17 15:57:25 1998
--- reorg.c	Sat Apr 18 09:47:11 1998
***************
*** 340,350 ****
  
      case UNSPEC_VOLATILE:
      case ASM_INPUT:
-     case TRAP_IF:
        /* Traditional asm's are always volatile.  */
        res->volatil = 1;
        return;
  
      case ASM_OPERANDS:
        res->volatil = MEM_VOLATILE_P (x);
  
--- 340,353 ----
  
      case UNSPEC_VOLATILE:
      case ASM_INPUT:
        /* Traditional asm's are always volatile.  */
        res->volatil = 1;
        return;
  
+     case TRAP_IF:
+       res->volatil = 1;
+       break;
+ 
      case ASM_OPERANDS:
        res->volatil = MEM_VOLATILE_P (x);
  
*** stmt.c~	Fri Apr 17 15:57:26 1998
--- stmt.c	Sat Apr 18 09:10:29 1998
***************
*** 2960,2967 ****
  	    emit_label (not_this);
  	  }
        /* If label is not recognized, abort.  */
!       emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "abort"), 0,
! 			 VOIDmode, 0);
        emit_barrier ();
        emit_label (afterward);
      }
--- 2960,2972 ----
  	    emit_label (not_this);
  	  }
        /* If label is not recognized, abort.  */
! #ifdef HAVE_trap
!       if (HAVE_trap)
! 	emit_insn (gen_trap ());
!       else
! #endif
! 	emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "abort"), 0,
! 			   VOIDmode, 0);
        emit_barrier ();
        emit_label (afterward);
      }
*** jump.c	1998/04/16 23:56:11	1.17
--- jump.c	1998/04/18 20:17:12
*************** jump_optimize (f, cross_jump, noop_moves
*** 1897,1902 ****
--- 1897,1976 ----
  		  continue;
  		}
  	    }
+ #ifdef HAVE_trap
+ 	  /* Detect a conditional jump jumping over an unconditional trap.  */
+ 	  else if (HAVE_trap
+ 		   && this_is_condjump && ! this_is_simplejump
+ 		   && reallabelprev != 0
+ 		   && GET_CODE (reallabelprev) == INSN
+ 		   && GET_CODE (PATTERN (reallabelprev)) == TRAP_IF
+ 		   && TRAP_CONDITION (PATTERN (reallabelprev)) == const_true_rtx
+ 		   && prev_active_insn (reallabelprev) == insn
+ 		   && no_labels_between_p (insn, reallabelprev)
+ 		   && (temp2 = get_condition (insn, &temp4))
+ 		   && can_reverse_comparison_p (temp2, insn))
+ 	    {
+ 	      rtx new = gen_cond_trap (reverse_condition (GET_CODE (temp2)),
+ 				       XEXP (temp2, 0), XEXP (temp2, 1),
+ 				       TRAP_CODE (PATTERN (reallabelprev)));
+ 
+ 	      if (new)
+ 		{
+ 		  emit_insn_before (new, temp4);
+ 		  delete_insn (reallabelprev);
+ 		  delete_jump (insn);
+ 		  changed = 1;
+ 		  continue;
+ 		}
+ 	    }
+ 	  /* Detect a jump jumping to an unconditional trap.  */
+ 	  else if (HAVE_trap && this_is_condjump
+ 		   && (temp = next_active_insn (JUMP_LABEL (insn)))
+ 		   && GET_CODE (temp) == INSN
+ 		   && GET_CODE (PATTERN (temp)) == TRAP_IF
+ 		   && (this_is_simplejump
+ 		       || (temp2 = get_condition (insn, &temp4))))
+ 	    {
+ 	      rtx tc = TRAP_CONDITION (PATTERN (temp));
+ 
+ 	      if (tc == const_true_rtx
+ 		  || (! this_is_simplejump && rtx_equal_p (temp2, tc)))
+ 		{
+ 		  rtx new;
+ 		  /* Replace an unconditional jump to a trap with a trap.  */
+ 		  if (this_is_simplejump)
+ 		    {
+ 		      emit_barrier_after (emit_insn_before (gen_trap (), insn));
+ 		      delete_jump (insn);
+ 		      changed = 1;
+ 		      continue;
+ 		    }
+ 		  new = gen_cond_trap (GET_CODE (temp2), XEXP (temp2, 0),
+ 				       XEXP (temp2, 1),
+ 				       TRAP_CODE (PATTERN (temp)));
+ 		  if (new)
+ 		    {
+ 		      emit_insn_before (new, temp4);
+ 		      delete_jump (insn);
+ 		      changed = 1;
+ 		      continue;
+ 		    }
+ 		}
+ 	      /* If the trap condition and jump condition are mutually
+ 		 exclusive, redirect the jump to the following insn.  */
+ 	      else if (GET_RTX_CLASS (GET_CODE (tc)) == '<'
+ 		       && ! this_is_simplejump
+ 		       && swap_condition (GET_CODE (temp2)) == GET_CODE (tc)
+ 		       && rtx_equal_p (XEXP (tc, 0), XEXP (temp2, 0))
+ 		       && rtx_equal_p (XEXP (tc, 1), XEXP (temp2, 1))
+ 		       && redirect_jump (insn, get_label_after (temp)))
+ 		{
+ 		  changed = 1;
+ 		  continue;
+ 		}
+ 	    }
+ #endif
+ 
  	  /* Detect a conditional jump jumping over an unconditional jump.  */
  
  	  else if ((this_is_condjump || this_is_condjump_in_parallel)
*** cp/decl.c~	Fri Apr 17 15:57:42 1998
--- cp/decl.c	Sat Apr 18 17:42:48 1998
***************
*** 5466,5472 ****
        /* Declare these functions volatile
  	 to avoid spurious "control drops through" warnings.  */
        temp = builtin_function ("abort", void_ftype,
! 			       NOT_BUILT_IN, NULL_PTR);
        TREE_THIS_VOLATILE (temp) = 1;
        TREE_SIDE_EFFECTS (temp) = 1;
        /* Well, these are actually ANSI, but we can't set DECL_BUILT_IN on
--- 5466,5472 ----
        /* Declare these functions volatile
  	 to avoid spurious "control drops through" warnings.  */
        temp = builtin_function ("abort", void_ftype,
! 			       BUILT_IN_ABORT, NULL_PTR);
        TREE_THIS_VOLATILE (temp) = 1;
        TREE_SIDE_EFFECTS (temp) = 1;
        /* Well, these are actually ANSI, but we can't set DECL_BUILT_IN on
*** sparc.md~	Sat Apr 18 07:46:12 1998
--- sparc.md	Sat Apr 18 17:34:20 1998
***************
*** 6607,6609 ****
--- 6607,6645 ----
    [(unspec_volatile [(const_int 0)] 4)]
    "flag_pic"
    "")
+ \f
+ (define_insn "trap"
+   [(trap_if (const_int 1) (const_int 5))]
+   ""
+   "ta 5"
+   [(set_attr "type" "misc")])
+ 
+ (define_expand "conditional_trap"
+   [(trap_if (match_operator 0 "noov_compare_op"
+ 			    [(match_dup 2) (match_dup 3)])
+ 	    (match_operand:SI 1 "arith_operand" ""))]
+   ""
+   "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
+ 				  sparc_compare_op0, sparc_compare_op1);
+    operands[3] = const0_rtx;")
+ 
+ (define_insn ""
+   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
+ 	    (match_operand:SI 1 "arith_operand" "rM"))]
+   ""
+   "t%C0 %1"
+   [(set_attr "type" "misc")])
+ 
+ (define_insn ""
+   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
+ 	    (match_operand:SI 1 "arith_operand" "rM"))]
+   "TARGET_V9"
+   "t%C0 %%xcc,%1"
+   [(set_attr "type" "misc")])
+ \f
+ ;; A noop move of the condition register must be recognized even though
+ ;; it will be deleted. 
+ (define_insn ""
+   [(set (reg 100) (reg 100))]
+   ""
+   "")
*** optabs.c.orig	Sat Apr 18 16:59:33 1998
--- optabs.c	Sat Apr 18 17:23:58 1998
***************
*** 246,251 ****
--- 246,252 ----
  static void init_libfuncs PROTO((optab, int, int, char *, int));
  static void init_integral_libfuncs PROTO((optab, char *, int));
  static void init_floating_libfuncs PROTO((optab, char *, int));
+ static void init_traps PROTO((void));
  \f
  /* Add a REG_EQUAL note to the last insn in SEQ.  TARGET is being set to
     the result of operation CODE applied to OP0 (and OP1 if it is a binary
***************
*** 4379,4385 ****
    chkr_copy_bitmap_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_copy_bitmap");
    chkr_check_exec_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_check_exec");
    chkr_check_str_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_check_str");
! 
  #ifdef INIT_TARGET_OPTABS
    /* Allow the target to add more libcalls or rename some, etc.  */
    INIT_TARGET_OPTABS;
--- 4380,4388 ----
    chkr_copy_bitmap_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_copy_bitmap");
    chkr_check_exec_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_check_exec");
    chkr_check_str_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_check_str");
! #ifdef HAVE_conditional_trap
!   init_traps ();
! #endif
  #ifdef INIT_TARGET_OPTABS
    /* Allow the target to add more libcalls or rename some, etc.  */
    INIT_TARGET_OPTABS;
***************
*** 4402,4404 ****
--- 4405,4452 ----
    return x;
  }
  #endif /* BROKEN_LDEXP */
+ \f
+ #ifdef HAVE_conditional_trap
+ /* The insn generating function can not take an rtx_code argument.
+    TRAP_RTX is used as an rtx argument.  Its code is replaced with
+    the code to be used in the trap insn and all other fields are
+    ignored.  */
+ static rtx trap_rtx;
+ 
+ static void
+ init_traps ()
+ {
+   if (HAVE_conditional_trap)
+     trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
+ }
+ #endif
+ 
+ /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
+    CODE.  Return 0 on failure.  */
+ 
+ rtx
+ gen_cond_trap (code, op1, op2, tcode)
+      enum rtx_code code;
+      rtx op1, op2, tcode;
+ {
+   enum machine_mode mode = GET_MODE (op1);
+   enum insn_code icode;
+ 
+   if (mode == VOIDmode)
+     return 0;
+ 
+ #ifdef HAVE_conditional_trap
+   if (HAVE_conditional_trap
+       && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
+     {
+       rtx insn;
+       emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
+       PUT_CODE (trap_rtx, code);
+       insn = gen_conditional_trap (trap_rtx, tcode);
+       if (insn)
+ 	return insn;
+     }
+ #endif
+ 
+   return 0;
+ }
*** rs6000.md~	Wed Apr  1 18:18:57 1998
--- rs6000.md	Sat Apr 18 17:21:10 1998
***************
*** 9661,9663 ****
--- 9661,9685 ----
    "
  { operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
  			 const0_rtx); }")
+ \f
+ (define_insn "trap"
+   [(trap_if (const_int 1) (const_int 0))]
+   ""
+   "{t 31,0,0|trap}")
+ 
+ (define_expand "conditional_trap"
+   [(trap_if (match_operator 0 "trap_comparison_operator"
+ 			    [(match_dup 2) (match_dup 3)])
+ 	    (match_operand 1 "const_int_operand" ""))]
+   ""
+   "if (rs6000_compare_fp_p || operands[1] != const0_rtx) FAIL;
+    operands[2] = rs6000_compare_op0;
+    operands[3] = rs6000_compare_op1;")
+ 
+ (define_insn ""
+   [(trap_if (match_operator 0 "trap_comparison_operator"
+                             [(match_operand:SI 1 "register_operand" "r")
+                              (match_operand:SI 2 "reg_or_short_operand" "rI")])
+ 	    (const_int 0))]
+   ""
+   "t%V0%I2 %1,%2")
*** rs6000.c~	Sat Apr  4 14:54:45 1998
--- rs6000.c	Sat Apr 18 17:39:51 1998
***************
*** 1969,1974 ****
--- 1969,1985 ----
  
    return 1;
  }
+ 
+ int
+ trap_comparison_operator (op, mode)
+     rtx op;
+     enum machine_mode mode;
+ {
+   if (mode != VOIDmode && mode != GET_MODE (op))
+     return 0;
+   return (GET_RTX_CLASS (GET_CODE (op)) == '<'
+           || GET_CODE (op) == EQ || GET_CODE (op) == NE);
+ }
  \f
  /* Return 1 if ANDOP is a mask that has no bits on that are not in the
     mask required to convert the result of a rotate insn into a shift
***************
*** 2867,2872 ****
--- 2878,2923 ----
  		     reg_names[SMALL_DATA_REG]);
  	}
        return;
+ 
+     case 'V':
+       /* Print the trap code for this operand.  */
+       switch (GET_CODE (x))
+         {
+         case EQ:
+           fputs ("eq", file);   /* 4 */
+           break;
+         case NE:
+           fputs ("ne", file);   /* 24 */
+           break;
+         case LT:
+           fputs ("lt", file);   /* 16 */
+           break;
+         case LE:
+           fputs ("le", file);   /* 20 */
+           break;
+         case GT:
+           fputs ("gt", file);   /* 8 */
+           break;
+         case GE:
+           fputs ("ge", file);   /* 12 */
+           break;
+         case LTU:
+           fputs ("llt", file);  /* 2 */
+ 
+           break;
+         case LEU:
+           fputs ("lle", file);  /* 6 */
+           break;
+         case GTU:
+           fputs ("lgt", file);  /* 1 */
+           break;
+         case GEU:
+           fputs ("lge", file);  /* 5 */
+           break;
+         default:
+           abort ();
+         }
+       break;
  			    
      case 0:
        if (GET_CODE (x) == REG)

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~1998-05-18 11:01 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-05-14 11:09 inline abort Michael Meissner
  -- strict thread matches above, loose matches on Subject: below --
1998-05-17 18:05 Michael Meissner
1998-05-18 11:01 ` Jeffrey A Law
1998-04-18 17:53 John Carr
1998-05-14  5:54 ` Jeffrey A Law
1998-05-14  5:03   ` John Carr
1998-05-14 22:14     ` Jim Wilson
1998-05-16 14:32       ` John Carr
1998-05-16  9:15     ` Mark Mitchell
1998-05-16 16:45       ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).