-# DP: Fix for complex math on alpha
-
-I've tested this patch with building glibc and it enables it to compile, I
-haven't been able to test the resulting binaries yet, however. I assume
-this will fix the g77 problems too.
-
- * flow.c (insn_dead_p): Don't kill part of a complex number.
- * emit-rtl.c (gen_lowpart_common): Handle narrow complex reg values.
- (gen_highpart): Likewise.
- * calls.c (expand_call): Narrow complex variable uses two regs.
- * alpha/alpha.h (ALPHA_ARG_SIZE): Likewise.
- (HARD_REGNO_NREGS): Likewise.
-
-*** ../gcc/flow.c Tue Feb 4 18:34:01 1997
---- gcc/flow.c Sun Mar 16 09:17:52 1997
-***************
-*** 1819,1824 ****
---- 1819,1828 ----
- & ((REGSET_ELT_TYPE) 1
- << ((regno + n) % REGSET_ELT_BITS))) != 0)
- return 0;
-+
-+ /* Don't allow part of a complex number to be deleted. */
-+ if (GET_MODE_CLASS (GET_MODE (r)) == MODE_COMPLEX_FLOAT)
-+ return 0;
- }
+#! /bin/sh -e
- return 1;
-*** ../gcc/calls.c Sat Jan 4 18:43:38 1997
---- gcc/calls.c Sun Mar 16 09:54:39 1997
-***************
-*** 1893,1898 ****
---- 1893,1903 ----
- validize_mem (args[i].value), nregs,
- args[i].mode);
+# All lines beginning with `# DP:' are a description of the patch.
+# DP: Fix for complex math on alpha
-+ /* Indicate two regs used to hold a short complex arg. */
-+ if (GET_MODE_CLASS (args[i].mode) == MODE_COMPLEX_FLOAT
-+ && GET_MODE_SIZE (args[i].mode) <= UNITS_PER_WORD)
-+ nregs = 2;
+if [ $# -eq 3 -a "$2" = '-d' ]; then
+ pdir="-d $3"
+elif [ $# -ne 1 ]; then
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+fi
+case "$1" in
+ -patch) patch $pdir -f --no-backup-if-mismatch -p1 < $0;;
+ -unpatch) patch $pdir -f --no-backup-if-mismatch -R -p1 < $0;;
+ *)
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+esac
+exit 0
+
+(from Joel Klecker's original message):
+
+ I've tested this patch with building glibc and it enables it to compile, I
+ haven't been able to test the resulting binaries yet, however. I assume
+ this will fix the g77 problems too.
+
+ * flow.c (insn_dead_p): Don't kill part of a complex number.
+ * emit-rtl.c (gen_lowpart_common): Handle narrow complex reg values.
+ (gen_highpart): Likewise.
+ * calls.c (expand_call): Narrow complex variable uses two regs.
+ * alpha/alpha.h (ALPHA_ARG_SIZE): Likewise.
+ (HARD_REGNO_NREGS): Likewise.
+
+diff -ur gcc-2.95.2/gcc/calls.c gcc-2.95.2.patched/gcc/calls.c
+--- gcc-2.95.2/gcc/calls.c Fri May 7 21:58:39 1999
++++ gcc-2.95.2.patched/gcc/calls.c Sat Feb 19 14:26:21 2000
+@@ -1499,6 +1499,11 @@
+ validize_mem (args[i].value), nregs,
+ args[i].mode);
+
++ /* Indicate two regs used to hold a short complex arg. */
++ if (GET_MODE_CLASS (args[i].mode) == MODE_COMPLEX_FLOAT
++ && GET_MODE_SIZE (args[i].mode) <= UNITS_PER_WORD)
++ nregs = 2;
+
- /* Handle calls that pass values in multiple non-contiguous
- locations. The Irix 6 ABI has examples of this. */
- if (GET_CODE (reg) == PARALLEL)
-*** ../gcc/config/alpha/alpha.h Sun Jan 19 13:17:06 1997
---- gcc/config/alpha/alpha.h Sun Mar 16 14:39:59 1997
-***************
-*** 493,499 ****
- but can be less for certain modes in special long registers. */
-
- #define HARD_REGNO_NREGS(REGNO, MODE) \
-! ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
- /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
- On Alpha, the integer registers can hold any mode. The floating-point
---- 493,502 ----
- but can be less for certain modes in special long registers. */
-
- #define HARD_REGNO_NREGS(REGNO, MODE) \
-! ((GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
-! && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \
-! ? 2 \
-! : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-
- /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
- On Alpha, the integer registers can hold any mode. The floating-point
-***************
-*** 923,934 ****
- #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) (CUM) = 0
-
- /* Define intermediate macro to compute the size (in registers) of an argument
-! for the Alpha. */
-
- #define ALPHA_ARG_SIZE(MODE, TYPE, NAMED) \
-! ((MODE) != BLKmode \
-! ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \
-! : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
-
- /* Update the data in CUM to advance over an argument
- of mode MODE and data type TYPE.
---- 926,941 ----
- #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) (CUM) = 0
-
- /* Define intermediate macro to compute the size (in registers) of an argument
-! for the Alpha.
-! A short complex arg takes two registers. */
-
- #define ALPHA_ARG_SIZE(MODE, TYPE, NAMED) \
-! ((GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
-! && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \
-! ? 2 \
-! : ((MODE) != BLKmode
- \
-! ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \
-! : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
-
- /* Update the data in CUM to advance over an argument
- of mode MODE and data type TYPE.
---- gcc/gcc/emit-rtl.c.alpha Fri Jul 16 11:12:20 1999
-+++ gcc/emit-rtl.c Thu Jul 29 10:01:33 1999
-@@ -743,6 +743,17 @@ gen_lowpart_common (mode, x)
+ /* Handle calls that pass values in multiple non-contiguous
+ locations. The Irix 6 ABI has examples of this. */
+ if (GET_CODE (reg) == PARALLEL)
+diff -ur gcc-2.95.2/gcc/config/alpha/alpha.h gcc-2.95.2.patched/gcc/config/alpha/alpha.h
+--- gcc-2.95.2/gcc/config/alpha/alpha.h Fri Jun 25 01:09:12 1999
++++ gcc-2.95.2.patched/gcc/config/alpha/alpha.h Sat Feb 19 14:28:45 2000
+@@ -622,7 +622,10 @@
+ but can be less for certain modes in special long registers. */
+
+ #define HARD_REGNO_NREGS(REGNO, MODE) \
+- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
++ ((GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
++ && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \
++ ? 2 \
++ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+
+ /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
+ On Alpha, the integer registers can hold any mode. The floating-point
+@@ -1070,12 +1073,16 @@
+ #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) (CUM) = 0
+
+ /* Define intermediate macro to compute the size (in registers) of an argument
+- for the Alpha. */
++ for the Alpha.
++ A short complex arg takes two registers. */
+
+ #define ALPHA_ARG_SIZE(MODE, TYPE, NAMED) \
+-((MODE) != BLKmode \
+- ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \
+- : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
++ ((GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
++ && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \
++ ? 2 \
++ : ((MODE) != BLKmode \
++ ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \
++ : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
+
+ /* Update the data in CUM to advance over an argument
+ of mode MODE and data type TYPE.
+diff -ur gcc-2.95.2/gcc/emit-rtl.c gcc-2.95.2.patched/gcc/emit-rtl.c
+--- gcc-2.95.2/gcc/emit-rtl.c Wed Aug 11 03:28:52 1999
++++ gcc-2.95.2.patched/gcc/emit-rtl.c Sat Feb 19 14:31:19 2000
+@@ -749,6 +749,15 @@
&& ! HARD_REGNO_MODE_OK (REGNO (x) + word, mode)
&& HARD_REGNO_MODE_OK (REGNO (x), GET_MODE (x)))
return 0;
-+
+ else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_COMPLEX_FLOAT
+ && GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD
+ && REGNO (x) < FIRST_PSEUDO_REGISTER)
+ else
+ return gen_rtx (REG, mode, REGNO (x));
+ }
-+
else if (REGNO (x) < FIRST_PSEUDO_REGISTER
/* integrate.c can't handle parts of a return value register. */
&& (! REG_FUNCTION_VALUE_P (x)
-@@ -966,11 +977,6 @@ gen_realpart (mode, x)
+@@ -972,11 +981,6 @@
{
if (GET_CODE (x) == CONCAT && GET_MODE (XEXP (x, 0)) == mode)
return XEXP (x, 0);
else if (WORDS_BIG_ENDIAN)
return gen_highpart (mode, x);
else
-@@ -989,11 +995,6 @@ gen_imagpart (mode, x)
+@@ -995,11 +999,6 @@
return XEXP (x, 1);
else if (WORDS_BIG_ENDIAN)
return gen_lowpart (mode, x);
- && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
- && REG_P (x)
- && REGNO (x) < FIRST_PSEUDO_REGISTER)
-- fatal ("Unable to access imaginary part of complex value in a hard
-register on this target");
+- fatal ("Unable to access imaginary part of complex value in a hard register on this target");
else
return gen_highpart (mode, x);
}
-@@ -1128,6 +1129,16 @@ gen_highpart (mode, x)
+@@ -1134,6 +1133,16 @@
word = ((GET_MODE_SIZE (GET_MODE (x))
- MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD))
/ UNITS_PER_WORD);
+ else
+ return gen_rtx (REG, mode, REGNO (x) + 1);
+ }
-
+
if (REGNO (x) < FIRST_PSEUDO_REGISTER
/* integrate.c can't handle parts of a return value register. */
---
-Joel Klecker (aka Espy) Debian GNU/Linux Developer
-<URL:mailto:jk@espy.org> <URL:mailto:espy@debian.org>
-<URL:http://web.espy.org/> <URL:http://www.debian.org/>
+diff -ur gcc-2.95.2/gcc/flow.c gcc-2.95.2.patched/gcc/flow.c
+--- gcc-2.95.2/gcc/flow.c Wed Aug 4 03:09:48 1999
++++ gcc-2.95.2.patched/gcc/flow.c Sat Feb 19 14:34:02 2000
+@@ -2995,6 +2995,10 @@
+ while (--n > 0)
+ if (REGNO_REG_SET_P (needed, regno+n))
+ return 0;
++
++ /* Don't allow part of a complex number to be deleted. */
++ if (GET_MODE_CLASS (GET_MODE (r)) == MODE_COMPLEX_FLOAT)
++ return 0;
+ }
+
+ return 1;
+
+