LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File ia64-trap-int-div.diff of Package gcc33 (Project openSUSE:Factory)

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)