fix sparc conditional trap failure
Richard Henderson
rth@redhat.com
Thu Jun 5 16:32:00 GMT 2003
DaveM found the problem and identified the cause. I cleaned
up the surrounding code a bit.
r~
* optabs.c (HAVE_conditional_trap): Provide default.
(gen_conditional_trap): Likewise.
(init_optabs): Merge init_traps.
(gen_cond_trap): Use prepare_operand. Restructure and avoid ifdef.
Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.175
diff -c -p -d -r1.175 optabs.c
*** optabs.c 4 Jun 2003 04:42:14 -0000 1.175
--- optabs.c 5 Jun 2003 16:24:20 -0000
*************** enum insn_code setcc_gen_code[NUM_RTX_CO
*** 88,93 ****
--- 88,98 ----
enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
#endif
+ /* 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 GTY(()) rtx trap_rtx;
+
static int add_equal_note PARAMS ((rtx, rtx, enum rtx_code, rtx, rtx));
static rtx widen_operand PARAMS ((rtx, enum machine_mode,
enum machine_mode, int, int));
*************** static inline optab init_optabv PARAMS (
*** 114,122 ****
static void init_libfuncs PARAMS ((optab, int, int, const char *, int));
static void init_integral_libfuncs PARAMS ((optab, const char *, int));
static void init_floating_libfuncs PARAMS ((optab, const char *, int));
- #ifdef HAVE_conditional_trap
- static void init_traps PARAMS ((void));
- #endif
static void emit_cmp_and_jump_insn_1 PARAMS ((rtx, rtx, enum machine_mode,
enum rtx_code, int, rtx));
static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
--- 119,124 ----
*************** static rtx expand_vector_unop PARAMS ((e
*** 128,133 ****
--- 130,140 ----
int));
static rtx widen_clz PARAMS ((enum machine_mode, rtx, rtx));
static rtx expand_parity PARAMS ((enum machine_mode, rtx, rtx));
+
+ #ifndef HAVE_conditional_trap
+ #define HAVE_conditional_trap 0
+ #define gen_conditional_trap(a,b) (abort (), NULL_RTX)
+ #endif
/* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
the result of operation CODE applied to OP0 (and OP1 if it is a binary
*************** init_optabs ()
*** 5806,5814 ****
gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
gcov_init_libfunc = init_one_libfunc ("__gcov_init");
! #ifdef HAVE_conditional_trap
! init_traps ();
! #endif
#ifdef INIT_TARGET_OPTABS
/* Allow the target to add more libcalls or rename some, etc. */
--- 5813,5820 ----
gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
gcov_init_libfunc = init_one_libfunc ("__gcov_init");
! if (HAVE_conditional_trap)
! trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
#ifdef INIT_TARGET_OPTABS
/* Allow the target to add more libcalls or rename some, etc. */
*************** init_optabs ()
*** 5816,5839 ****
#endif
}
- static GTY(()) rtx trap_rtx;
-
- #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 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. */
--- 5822,5827 ----
*************** gen_cond_trap (code, op1, op2, tcode)
*** 5843,5872 ****
rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
{
enum machine_mode mode = GET_MODE (op1);
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;
! start_sequence ();
! 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)
! {
! emit_insn (insn);
! insn = get_insns ();
! }
! end_sequence ();
! return insn;
}
! #endif
! return 0;
}
#include "gt-optabs.h"
--- 5831,5864 ----
rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
{
enum machine_mode mode = GET_MODE (op1);
+ enum insn_code icode;
+ rtx insn;
+
+ if (!HAVE_conditional_trap)
+ return 0;
if (mode == VOIDmode)
return 0;
! icode = cmp_optab->handlers[(int) mode].insn_code;
! if (icode == CODE_FOR_nothing)
! return 0;
!
! start_sequence ();
! op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
! op2 = prepare_operand (icode, op2, 0, mode, mode, 0);
! emit_insn (GEN_FCN (icode) (op1, op2));
!
! PUT_CODE (trap_rtx, code);
! insn = gen_conditional_trap (trap_rtx, tcode);
! if (insn)
{
! emit_insn (insn);
! insn = get_insns ();
}
! end_sequence ();
! return insn;
}
#include "gt-optabs.h"
Index: testsuite/gcc.c-torture/compile/20030605-1.c
===================================================================
RCS file: testsuite/gcc.c-torture/compile/20030605-1.c
diff -N testsuite/gcc.c-torture/compile/20030605-1.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.c-torture/compile/20030605-1.c 5 Jun 2003 16:28:04 -0000
***************
*** 0 ****
--- 1,12 ----
+ /* Test for proper preparation of the comparison operands for
+ generation of a conditional trap. Produced unrecognizable
+ rtl on Sparc. */
+
+ struct blah { char *b_data; };
+
+ void set_bh_page(struct blah *bh, unsigned long offset)
+ {
+ if ((1UL << 12 ) <= offset)
+ __builtin_trap() ;
+ bh->b_data = (char *)offset;
+ }
More information about the Gcc-patches
mailing list