aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorJohn Carr <jfc@mit.edu>1998-06-17 16:14:09 +0000
committerJohn Carr <jfc@gcc.gnu.org>1998-06-17 16:14:09 +0000
commite0cd077072ade89c9aee0cabc8be0c5a6ebb23cf (patch)
treebc08309af18e3e3b81d9dde6d23a1abd41673ffe /gcc/optabs.c
parent4fdf79cb6764f8c57b4c4deaabd6131850535263 (diff)
downloadgcc-e0cd077072ade89c9aee0cabc8be0c5a6ebb23cf.zip
gcc-e0cd077072ade89c9aee0cabc8be0c5a6ebb23cf.tar.gz
gcc-e0cd077072ade89c9aee0cabc8be0c5a6ebb23cf.tar.bz2
haifa-sched.c (haifa_classify_insn): TRAP_IF is risky.
* 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 function code BUILT_IN_TRAP. * c-decl.c (init_decl_processing): New builtin __builtin_trap. * expr.c (expand_builtin): Handle BUILT_IN_TRAP. * expr.c (expand_builtin): Error if __builtin_longjmp second argument is not 1. From-SVN: r20543
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index c00562f..8a2697b 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -246,6 +246,7 @@ static optab init_optab PROTO((enum rtx_code));
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));
/* 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
@@ -4380,6 +4381,10 @@ init_optabs ()
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,3 +4407,50 @@ ldexp(x,n)
return x;
}
#endif /* BROKEN_LDEXP */
+
+#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.
+
+ ??? Will need to change to support garbage collection. */
+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;
+}