1 # DP: Fix for complex math on alpha
3 I've tested this patch with building glibc and it enables it to compile, I
4 haven't been able to test the resulting binaries yet, however. I assume
5 this will fix the g77 problems too.
7 * flow.c (insn_dead_p): Don't kill part of a complex number.
8 * emit-rtl.c (gen_lowpart_common): Handle narrow complex reg values.
9 (gen_highpart): Likewise.
10 * calls.c (expand_call): Narrow complex variable uses two regs.
11 * alpha/alpha.h (ALPHA_ARG_SIZE): Likewise.
12 (HARD_REGNO_NREGS): Likewise.
14 *** ../gcc/flow.c Tue Feb 4 18:34:01 1997
15 --- gcc/flow.c Sun Mar 16 09:17:52 1997
19 & ((REGSET_ELT_TYPE) 1
20 << ((regno + n) % REGSET_ELT_BITS))) != 0)
23 + /* Don't allow part of a complex number to be deleted. */
24 + if (GET_MODE_CLASS (GET_MODE (r)) == MODE_COMPLEX_FLOAT)
29 *** ../gcc/calls.c Sat Jan 4 18:43:38 1997
30 --- gcc/calls.c Sun Mar 16 09:54:39 1997
34 validize_mem (args[i].value), nregs,
37 + /* Indicate two regs used to hold a short complex arg. */
38 + if (GET_MODE_CLASS (args[i].mode) == MODE_COMPLEX_FLOAT
39 + && GET_MODE_SIZE (args[i].mode) <= UNITS_PER_WORD)
42 /* Handle calls that pass values in multiple non-contiguous
43 locations. The Irix 6 ABI has examples of this. */
44 if (GET_CODE (reg) == PARALLEL)
45 *** ../gcc/config/alpha/alpha.h Sun Jan 19 13:17:06 1997
46 --- gcc/config/alpha/alpha.h Sun Mar 16 14:39:59 1997
49 but can be less for certain modes in special long registers. */
51 #define HARD_REGNO_NREGS(REGNO, MODE) \
52 ! ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
54 /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
55 On Alpha, the integer registers can hold any mode. The floating-point
57 but can be less for certain modes in special long registers. */
59 #define HARD_REGNO_NREGS(REGNO, MODE) \
60 ! ((GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
61 ! && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \
63 ! : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
65 /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
66 On Alpha, the integer registers can hold any mode. The floating-point
69 #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) (CUM) = 0
71 /* Define intermediate macro to compute the size (in registers) of an argument
74 #define ALPHA_ARG_SIZE(MODE, TYPE, NAMED) \
75 ! ((MODE) != BLKmode \
76 ! ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \
77 ! : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
79 /* Update the data in CUM to advance over an argument
80 of mode MODE and data type TYPE.
82 #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) (CUM) = 0
84 /* Define intermediate macro to compute the size (in registers) of an argument
86 ! A short complex arg takes two registers. */
88 #define ALPHA_ARG_SIZE(MODE, TYPE, NAMED) \
89 ! ((GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
90 ! && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \
92 ! : ((MODE) != BLKmode
94 ! ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \
95 ! : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
97 /* Update the data in CUM to advance over an argument
98 of mode MODE and data type TYPE.
99 --- gcc/gcc/emit-rtl.c.alpha Fri Jul 16 11:12:20 1999
100 +++ gcc/emit-rtl.c Thu Jul 29 10:01:33 1999
101 @@ -743,6 +743,17 @@ gen_lowpart_common (mode, x)
102 && ! HARD_REGNO_MODE_OK (REGNO (x) + word, mode)
103 && HARD_REGNO_MODE_OK (REGNO (x), GET_MODE (x)))
106 + else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_COMPLEX_FLOAT
107 + && GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD
108 + && REGNO (x) < FIRST_PSEUDO_REGISTER)
110 + if (REG_FUNCTION_VALUE_P (x))
111 + return gen_rtx (SUBREG, mode, x, 0);
113 + return gen_rtx (REG, mode, REGNO (x));
116 else if (REGNO (x) < FIRST_PSEUDO_REGISTER
117 /* integrate.c can't handle parts of a return value register. */
118 && (! REG_FUNCTION_VALUE_P (x)
119 @@ -966,11 +977,6 @@ gen_realpart (mode, x)
121 if (GET_CODE (x) == CONCAT && GET_MODE (XEXP (x, 0)) == mode)
123 - else if (WORDS_BIG_ENDIAN
124 - && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
126 - && REGNO (x) < FIRST_PSEUDO_REGISTER)
127 - fatal ("Unable to access real part of complex value in a hard register on this target");
128 else if (WORDS_BIG_ENDIAN)
129 return gen_highpart (mode, x);
131 @@ -989,11 +995,6 @@ gen_imagpart (mode, x)
133 else if (WORDS_BIG_ENDIAN)
134 return gen_lowpart (mode, x);
135 - else if (!WORDS_BIG_ENDIAN
136 - && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
138 - && REGNO (x) < FIRST_PSEUDO_REGISTER)
139 - fatal ("Unable to access imaginary part of complex value in a hard
140 register on this target");
142 return gen_highpart (mode, x);
144 @@ -1128,6 +1129,16 @@ gen_highpart (mode, x)
145 word = ((GET_MODE_SIZE (GET_MODE (x))
146 - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD))
149 + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_COMPLEX_FLOAT
150 + && GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD
151 + && REGNO (x) < FIRST_PSEUDO_REGISTER)
153 + if (REG_FUNCTION_VALUE_P (x))
154 + return gen_rtx (SUBREG, mode, x, 1);
156 + return gen_rtx (REG, mode, REGNO (x) + 1);
159 if (REGNO (x) < FIRST_PSEUDO_REGISTER
160 /* integrate.c can't handle parts of a return value register. */
162 Joel Klecker (aka Espy) Debian GNU/Linux Developer
163 <URL:mailto:jk@espy.org> <URL:mailto:espy@debian.org>
164 <URL:http://web.espy.org/> <URL:http://www.debian.org/>