From 9e3e266c6ccb72a0e11975b24c4f236a88546052 Mon Sep 17 00:00:00 2001 From: Greg McGary Date: Mon, 28 Aug 2000 21:48:05 +0000 Subject: [PATCH] i386-protos.h (ix86_expand_compare): Add extern decl. * config/i386/i386-protos.h (ix86_expand_compare): Add extern decl. * config/i386/i386.c (ix86_expand_compare): Remove `static'. * config/i386/i386.md (trap, conditional_trap): New insn & expand. From-SVN: r36019 --- gcc/ChangeLog | 6 +++++ gcc/config/i386/i386-protos.h | 1 + gcc/config/i386/i386.c | 3 +-- gcc/config/i386/i386.md | 49 +++++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c8925f2f7f4..c049a2f35b7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2000-08-28 Greg McGary + + * config/i386/i386-protos.h (ix86_expand_compare): Add extern decl. + * config/i386/i386.c (ix86_expand_compare): Remove `static'. + * config/i386/i386.md (trap, conditional_trap): New insn & expand. + 2000-08-27 Greg McGary * cpplex.c (parse_string): Don't look for backslash diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index f5d075b5b0d..fb86b1b6f20 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -100,6 +100,7 @@ extern int ix86_unary_operator_ok PARAMS ((enum rtx_code, enum machine_mode, rtx[])); extern int ix86_match_ccmode PARAMS ((rtx, enum machine_mode)); extern rtx ix86_expand_fp_compare PARAMS ((enum rtx_code, rtx, rtx, rtx)); +extern rtx ix86_expand_compare PARAMS ((enum rtx_code)); extern int ix86_use_fcomi_compare PARAMS ((enum rtx_code)); extern void ix86_expand_branch PARAMS ((enum rtx_code, rtx)); extern int ix86_expand_setcc PARAMS ((enum rtx_code, rtx)); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index aa9b4973726..5ebf1c1c0c7 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -402,7 +402,6 @@ static rtx ix86_expand_int_compare PARAMS ((enum rtx_code, rtx, rtx)); static enum machine_mode ix86_fp_compare_mode PARAMS ((enum rtx_code)); static enum rtx_code ix86_prepare_fp_compare_args PARAMS ((enum rtx_code, rtx *, rtx *)); -static rtx ix86_expand_compare PARAMS ((enum rtx_code)); static rtx gen_push PARAMS ((rtx)); static int memory_address_length PARAMS ((rtx addr)); static int ix86_flags_dependant PARAMS ((rtx, rtx, enum attr_type)); @@ -4897,7 +4896,7 @@ ix86_expand_fp_compare (code, op0, op1, scratch) const0_rtx); } -static rtx +rtx ix86_expand_compare (code) enum rtx_code code; { diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index cada4dfcf56..7d4faf347cb 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -11129,3 +11129,52 @@ return \"call\\t%*%1\"; }" [(set_attr "type" "callv")]) + +(define_insn "trap" + [(trap_if (const_int 1) (const_int 5))] + "" + "int\\t$5") + +;;; ix86 doesn't have conditional trap instructions, but we fake them +;;; for the sake of bounds checking. By emitting bounds checks as +;;; conditional traps rather than as conditional jumps around +;;; unconditional traps we avoid introducing spurious basic-block +;;; boundaries and facilitate elimination of redundant checks. In +;;; honor of the too-inflexible-for-BPs `bound' instruction, we use +;;; interrupt 5. +;;; +;;; FIXME: Static branch prediction rules for ix86 are such that +;;; forward conditional branches predict as untaken. As implemented +;;; below, pseudo conditional traps violate that rule. We should use +;;; .pushsection/.popsection to place all of the `int 5's in a special +;;; section loaded at the end of the text segment and branch forward +;;; there on bounds-failure, and then jump back immediately (in case +;;; the system chooses to ignore bounds violations, or to report +;;; violations and continue execution). + +(define_expand "conditional_trap" + [(trap_if (match_operator 0 "comparison_operator" + [(match_dup 2) (const_int 0)]) + (match_operand 1 "const_int_operand" ""))] + "" + " +{ + emit_insn (gen_rtx_TRAP_IF (VOIDmode, + ix86_expand_compare (GET_CODE (operands[0])), + operands[1])); + DONE; +}") + +(define_insn "" + [(trap_if (match_operator 0 "comparison_operator" + [(reg 17) (const_int 0)]) + (match_operand 1 "const_int_operand" ""))] + "" + "* +{ + operands[2] = gen_label_rtx (); + output_asm_insn (\"j%c0\\t%l2\; int\\t%1\", operands); + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + CODE_LABEL_NUMBER (operands[2])); + RET; +}")