]>
Commit | Line | Data |
---|---|---|
64f9f7bb JR |
1 | #! /bin/sh -e |
2 | ||
3 | # All lines beginning with `# DP:' are a description of the patch. | |
4 | # DP: Fix for complex math on alpha | |
5 | ||
6 | if [ $# -eq 3 -a "$2" = '-d' ]; then | |
7 | pdir="-d $3" | |
8 | elif [ $# -ne 1 ]; then | |
9 | echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" | |
10 | exit 1 | |
11 | fi | |
12 | case "$1" in | |
13 | -patch) patch $pdir -f --no-backup-if-mismatch -p1 < $0;; | |
14 | -unpatch) patch $pdir -f --no-backup-if-mismatch -R -p1 < $0;; | |
15 | *) | |
16 | echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" | |
17 | exit 1 | |
18 | esac | |
19 | exit 0 | |
20 | ||
21 | (from Joel Klecker's original message): | |
22 | ||
23 | I've tested this patch with building glibc and it enables it to compile, I | |
24 | haven't been able to test the resulting binaries yet, however. I assume | |
25 | this will fix the g77 problems too. | |
26 | ||
27 | * flow.c (insn_dead_p): Don't kill part of a complex number. | |
28 | * emit-rtl.c (gen_lowpart_common): Handle narrow complex reg values. | |
29 | (gen_highpart): Likewise. | |
30 | * calls.c (expand_call): Narrow complex variable uses two regs. | |
31 | * alpha/alpha.h (ALPHA_ARG_SIZE): Likewise. | |
32 | (HARD_REGNO_NREGS): Likewise. | |
33 | ||
34 | diff -ur gcc-2.95.2/gcc/calls.c gcc-2.95.2.patched/gcc/calls.c | |
35 | --- gcc-2.95.2/gcc/calls.c Fri May 7 21:58:39 1999 | |
36 | +++ gcc-2.95.2.patched/gcc/calls.c Sat Feb 19 14:26:21 2000 | |
37 | @@ -1499,6 +1499,11 @@ | |
38 | validize_mem (args[i].value), nregs, | |
39 | args[i].mode); | |
40 | ||
41 | + /* Indicate two regs used to hold a short complex arg. */ | |
42 | + if (GET_MODE_CLASS (args[i].mode) == MODE_COMPLEX_FLOAT | |
43 | + && GET_MODE_SIZE (args[i].mode) <= UNITS_PER_WORD) | |
44 | + nregs = 2; | |
45 | + | |
46 | /* Handle calls that pass values in multiple non-contiguous | |
47 | locations. The Irix 6 ABI has examples of this. */ | |
48 | if (GET_CODE (reg) == PARALLEL) | |
49 | diff -ur gcc-2.95.2/gcc/config/alpha/alpha.h gcc-2.95.2.patched/gcc/config/alpha/alpha.h | |
50 | --- gcc-2.95.2/gcc/config/alpha/alpha.h Fri Jun 25 01:09:12 1999 | |
51 | +++ gcc-2.95.2.patched/gcc/config/alpha/alpha.h Sat Feb 19 14:28:45 2000 | |
52 | @@ -622,7 +622,10 @@ | |
53 | but can be less for certain modes in special long registers. */ | |
54 | ||
55 | #define HARD_REGNO_NREGS(REGNO, MODE) \ | |
56 | - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) | |
57 | + ((GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \ | |
58 | + && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \ | |
59 | + ? 2 \ | |
60 | + : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) | |
61 | ||
62 | /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. | |
63 | On Alpha, the integer registers can hold any mode. The floating-point | |
64 | @@ -1070,12 +1073,16 @@ | |
65 | #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) (CUM) = 0 | |
66 | ||
67 | /* Define intermediate macro to compute the size (in registers) of an argument | |
68 | - for the Alpha. */ | |
69 | + for the Alpha. | |
70 | + A short complex arg takes two registers. */ | |
71 | ||
72 | #define ALPHA_ARG_SIZE(MODE, TYPE, NAMED) \ | |
73 | -((MODE) != BLKmode \ | |
74 | - ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \ | |
75 | - : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) | |
76 | + ((GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \ | |
77 | + && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \ | |
78 | + ? 2 \ | |
79 | + : ((MODE) != BLKmode \ | |
80 | + ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \ | |
81 | + : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)) | |
82 | ||
83 | /* Update the data in CUM to advance over an argument | |
84 | of mode MODE and data type TYPE. | |
85 | diff -ur gcc-2.95.2/gcc/emit-rtl.c gcc-2.95.2.patched/gcc/emit-rtl.c | |
86 | --- gcc-2.95.2/gcc/emit-rtl.c Wed Aug 11 03:28:52 1999 | |
87 | +++ gcc-2.95.2.patched/gcc/emit-rtl.c Sat Feb 19 14:31:19 2000 | |
88 | @@ -749,6 +749,15 @@ | |
89 | && ! HARD_REGNO_MODE_OK (REGNO (x) + word, mode) | |
90 | && HARD_REGNO_MODE_OK (REGNO (x), GET_MODE (x))) | |
91 | return 0; | |
92 | + else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_COMPLEX_FLOAT | |
93 | + && GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD | |
94 | + && REGNO (x) < FIRST_PSEUDO_REGISTER) | |
95 | + { | |
96 | + if (REG_FUNCTION_VALUE_P (x)) | |
97 | + return gen_rtx (SUBREG, mode, x, 0); | |
98 | + else | |
99 | + return gen_rtx (REG, mode, REGNO (x)); | |
100 | + } | |
101 | else if (REGNO (x) < FIRST_PSEUDO_REGISTER | |
102 | /* integrate.c can't handle parts of a return value register. */ | |
103 | && (! REG_FUNCTION_VALUE_P (x) | |
104 | @@ -972,11 +981,6 @@ | |
105 | { | |
106 | if (GET_CODE (x) == CONCAT && GET_MODE (XEXP (x, 0)) == mode) | |
107 | return XEXP (x, 0); | |
108 | - else if (WORDS_BIG_ENDIAN | |
109 | - && GET_MODE_BITSIZE (mode) < BITS_PER_WORD | |
110 | - && REG_P (x) | |
111 | - && REGNO (x) < FIRST_PSEUDO_REGISTER) | |
112 | - fatal ("Unable to access real part of complex value in a hard register on this target"); | |
113 | else if (WORDS_BIG_ENDIAN) | |
114 | return gen_highpart (mode, x); | |
115 | else | |
116 | @@ -995,11 +999,6 @@ | |
117 | return XEXP (x, 1); | |
118 | else if (WORDS_BIG_ENDIAN) | |
119 | return gen_lowpart (mode, x); | |
120 | - else if (!WORDS_BIG_ENDIAN | |
121 | - && GET_MODE_BITSIZE (mode) < BITS_PER_WORD | |
122 | - && REG_P (x) | |
123 | - && REGNO (x) < FIRST_PSEUDO_REGISTER) | |
124 | - fatal ("Unable to access imaginary part of complex value in a hard register on this target"); | |
125 | else | |
126 | return gen_highpart (mode, x); | |
127 | } | |
128 | @@ -1134,6 +1133,16 @@ | |
129 | word = ((GET_MODE_SIZE (GET_MODE (x)) | |
130 | - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)) | |
131 | / UNITS_PER_WORD); | |
132 | + | |
133 | + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_COMPLEX_FLOAT | |
134 | + && GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD | |
135 | + && REGNO (x) < FIRST_PSEUDO_REGISTER) | |
136 | + { | |
137 | + if (REG_FUNCTION_VALUE_P (x)) | |
138 | + return gen_rtx (SUBREG, mode, x, 1); | |
139 | + else | |
140 | + return gen_rtx (REG, mode, REGNO (x) + 1); | |
141 | + } | |
142 | ||
143 | if (REGNO (x) < FIRST_PSEUDO_REGISTER | |
144 | /* integrate.c can't handle parts of a return value register. */ | |
145 | diff -ur gcc-2.95.2/gcc/flow.c gcc-2.95.2.patched/gcc/flow.c | |
146 | --- gcc-2.95.2/gcc/flow.c Wed Aug 4 03:09:48 1999 | |
147 | +++ gcc-2.95.2.patched/gcc/flow.c Sat Feb 19 14:34:02 2000 | |
148 | @@ -2995,6 +2995,10 @@ | |
149 | while (--n > 0) | |
150 | if (REGNO_REG_SET_P (needed, regno+n)) | |
151 | return 0; | |
152 | + | |
153 | + /* Don't allow part of a complex number to be deleted. */ | |
154 | + if (GET_MODE_CLASS (GET_MODE (r)) == MODE_COMPLEX_FLOAT) | |
155 | + return 0; | |
156 | } | |
157 | ||
158 | return 1; | |
159 | ||
160 |