115 lines
4.1 KiB
Diff
115 lines
4.1 KiB
Diff
|
|
Feature for SAP. See Novell Bugzilla #57953, #116769, GCC PR23485 and
|
||
|
|
feature request 2159 .
|
||
|
|
|
||
|
|
The patches for the above GCC PR generate the trap unconditionally, and
|
||
|
|
change libgcc (which we can't do in a service pack). This patch introduces
|
||
|
|
a -mtrap-int-div option (which also activates inlining of divisions if not
|
||
|
|
already active), which makes div by zero trap and hence send a SIGFPE.
|
||
|
|
|
||
|
|
This also include a fix for the max-throughput DFmode division from
|
||
|
|
http://gcc.gnu.org/ml/gcc-patches/2004-03/msg00419.html:
|
||
|
|
|
||
|
|
2004-03-04 Steve Ellcey <sje@cup.hp.com>
|
||
|
|
|
||
|
|
* config/ia64/ia64.md (divdf3_internal_thr): Fix algorithm.
|
||
|
|
|
||
|
|
================================================================================
|
||
|
|
--- gcc/config/ia64/ia64.c
|
||
|
|
+++ gcc/config/ia64/ia64.c
|
||
|
|
@@ -4356,6 +4356,11 @@
|
||
|
|
target_flags &= ~MASK_INLINE_FLOAT_DIV_THR;
|
||
|
|
}
|
||
|
|
|
||
|
|
+ if (TARGET_TRAP_INT_DIV && !TARGET_INLINE_INT_DIV)
|
||
|
|
+ {
|
||
|
|
+ target_flags |= MASK_INLINE_INT_DIV_THR;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
if (TARGET_INLINE_INT_DIV_LAT && TARGET_INLINE_INT_DIV_THR)
|
||
|
|
{
|
||
|
|
warning ("cannot optimize integer division for both latency and throughput");
|
||
|
|
--- gcc/config/ia64/ia64.h
|
||
|
|
+++ gcc/config/ia64/ia64.h
|
||
|
|
@@ -93,6 +93,8 @@
|
||
|
|
|
||
|
|
#define MASK_INLINE_INT_DIV_THR 0x00001000 /* inline div, max throughput. */
|
||
|
|
|
||
|
|
+#define MASK_TRAP_INT_DIV 0x00002000 /* div by 0 generates trap. */
|
||
|
|
+
|
||
|
|
#define MASK_DWARF2_ASM 0x40000000 /* test dwarf2 line info via gas. */
|
||
|
|
|
||
|
|
#define TARGET_BIG_ENDIAN (target_flags & MASK_BIG_ENDIAN)
|
||
|
|
@@ -131,6 +133,8 @@
|
||
|
|
#define TARGET_INLINE_INT_DIV \
|
||
|
|
(target_flags & (MASK_INLINE_INT_DIV_LAT | MASK_INLINE_INT_DIV_THR))
|
||
|
|
|
||
|
|
+#define TARGET_TRAP_INT_DIV (target_flags & MASK_TRAP_INT_DIV)
|
||
|
|
+
|
||
|
|
#define TARGET_DWARF2_ASM (target_flags & MASK_DWARF2_ASM)
|
||
|
|
|
||
|
|
/* If the assembler supports thread-local storage, assume that the
|
||
|
|
@@ -197,6 +201,8 @@
|
||
|
|
N_("Generate inline integer division, optimize for latency") }, \
|
||
|
|
{ "inline-int-divide-max-throughput", MASK_INLINE_INT_DIV_THR, \
|
||
|
|
N_("Generate inline integer division, optimize for throughput") },\
|
||
|
|
+ { "trap-int-div", MASK_TRAP_INT_DIV, \
|
||
|
|
+ N_("Generate a trap on integer division by zero") }, \
|
||
|
|
{ "dwarf2-asm", MASK_DWARF2_ASM, \
|
||
|
|
N_("Enable Dwarf 2 line debug info via GNU as")}, \
|
||
|
|
{ "no-dwarf2-asm", -MASK_DWARF2_ASM, \
|
||
|
|
--- gcc/config/ia64/ia64.md
|
||
|
|
+++ gcc/config/ia64/ia64.md
|
||
|
|
@@ -2050,6 +2050,10 @@
|
||
|
|
twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode);
|
||
|
|
twon34 = force_reg (TFmode, twon34);
|
||
|
|
|
||
|
|
+ if (TARGET_TRAP_INT_DIV)
|
||
|
|
+ emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (SImode),
|
||
|
|
+ CONST1_RTX (SImode)));
|
||
|
|
+
|
||
|
|
emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
|
||
|
|
|
||
|
|
emit_insn (gen_fix_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
|
||
|
|
@@ -2107,6 +2111,10 @@
|
||
|
|
twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode);
|
||
|
|
twon34 = force_reg (TFmode, twon34);
|
||
|
|
|
||
|
|
+ if (TARGET_TRAP_INT_DIV)
|
||
|
|
+ emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (SImode),
|
||
|
|
+ CONST1_RTX (SImode)));
|
||
|
|
+
|
||
|
|
emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
|
||
|
|
|
||
|
|
emit_insn (gen_fixuns_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
|
||
|
|
@@ -2431,6 +2439,10 @@
|
||
|
|
op2_tf = gen_reg_rtx (TFmode);
|
||
|
|
expand_float (op2_tf, operands[2], 0);
|
||
|
|
|
||
|
|
+ if (TARGET_TRAP_INT_DIV)
|
||
|
|
+ emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (DImode),
|
||
|
|
+ CONST1_RTX (DImode)));
|
||
|
|
+
|
||
|
|
if (TARGET_INLINE_INT_DIV_LAT)
|
||
|
|
emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
|
||
|
|
else
|
||
|
|
@@ -2477,6 +2489,10 @@
|
||
|
|
op2_tf = gen_reg_rtx (TFmode);
|
||
|
|
expand_float (op2_tf, operands[2], 1);
|
||
|
|
|
||
|
|
+ if (TARGET_TRAP_INT_DIV)
|
||
|
|
+ emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (DImode),
|
||
|
|
+ CONST1_RTX (DImode)));
|
||
|
|
+
|
||
|
|
if (TARGET_INLINE_INT_DIV_LAT)
|
||
|
|
emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
|
||
|
|
else
|
||
|
|
@@ -3167,7 +3183,7 @@
|
||
|
|
(cond_exec (ne (match_dup 5) (const_int 0))
|
||
|
|
(parallel [(set (match_dup 9)
|
||
|
|
(float_truncate:DF
|
||
|
|
- (mult:TF (match_dup 7) (match_dup 3))))
|
||
|
|
+ (mult:TF (match_dup 7) (match_dup 6))))
|
||
|
|
(use (const_int 1))]))
|
||
|
|
(cond_exec (ne (match_dup 5) (const_int 0))
|
||
|
|
(parallel [(set (match_dup 4)
|