]>
Commit | Line | Data |
---|---|---|
5384b728 | 1 | 2002-07-29 Jakub Jelinek <jakub@redhat.com> |
2 | ||
3 | * gcc.dg/20020729-1.c: New test. | |
4 | ||
5 | 2002-05-17 Richard Sandiford <rsandifo@redhat.com> | |
6 | ||
7 | * expr.c (force_operand): Fix reversed move. | |
8 | ||
9 | Sat May 4 13:20:54 CEST 2002 Jan Hubicka <jh@suse.cz> | |
10 | ||
11 | * expr.c (force_operand): Use expand_simple_* to handle more | |
12 | cases. | |
13 | ||
14 | --- gcc/expr.c.jj 2002-05-07 12:45:49.000000000 +0200 | |
15 | +++ gcc/expr.c 2002-08-03 01:08:28.000000000 +0200 | |
16 | @@ -5434,16 +5434,13 @@ rtx | |
17 | force_operand (value, target) | |
18 | rtx value, target; | |
19 | { | |
20 | - optab binoptab = 0; | |
21 | - /* Use a temporary to force order of execution of calls to | |
22 | - `force_operand'. */ | |
23 | - rtx tmp; | |
24 | - rtx op2; | |
25 | + rtx op1, op2; | |
26 | /* Use subtarget as the target for operand 0 of a binary operation. */ | |
27 | rtx subtarget = get_subtarget (target); | |
28 | + enum rtx_code code = GET_CODE (value); | |
29 | ||
30 | /* Check for a PIC address load. */ | |
31 | - if ((GET_CODE (value) == PLUS || GET_CODE (value) == MINUS) | |
32 | + if ((code == PLUS || code == MINUS) | |
33 | && XEXP (value, 0) == pic_offset_table_rtx | |
34 | && (GET_CODE (XEXP (value, 1)) == SYMBOL_REF | |
35 | || GET_CODE (XEXP (value, 1)) == LABEL_REF | |
36 | @@ -5455,60 +5452,88 @@ force_operand (value, target) | |
37 | return subtarget; | |
38 | } | |
39 | ||
40 | - if (GET_CODE (value) == PLUS) | |
41 | - binoptab = add_optab; | |
42 | - else if (GET_CODE (value) == MINUS) | |
43 | - binoptab = sub_optab; | |
44 | - else if (GET_CODE (value) == MULT) | |
45 | + if (code == ZERO_EXTEND || code == SIGN_EXTEND) | |
46 | { | |
47 | - op2 = XEXP (value, 1); | |
48 | - if (!CONSTANT_P (op2) | |
49 | - && !(GET_CODE (op2) == REG && op2 != subtarget)) | |
50 | - subtarget = 0; | |
51 | - tmp = force_operand (XEXP (value, 0), subtarget); | |
52 | - return expand_mult (GET_MODE (value), tmp, | |
53 | - force_operand (op2, NULL_RTX), | |
54 | - target, 1); | |
55 | + if (!target) | |
56 | + target = gen_reg_rtx (GET_MODE (value)); | |
57 | + convert_move (target, force_operand (XEXP (value, 0), NULL), | |
58 | + code == ZERO_EXTEND); | |
59 | + return target; | |
60 | } | |
61 | ||
62 | - if (binoptab) | |
63 | + if (GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c') | |
64 | { | |
65 | op2 = XEXP (value, 1); | |
66 | - if (!CONSTANT_P (op2) | |
67 | - && !(GET_CODE (op2) == REG && op2 != subtarget)) | |
68 | + if (!CONSTANT_P (op2) && !(GET_CODE (op2) == REG && op2 != subtarget)) | |
69 | subtarget = 0; | |
70 | - if (binoptab == sub_optab && GET_CODE (op2) == CONST_INT) | |
71 | + if (code == MINUS && GET_CODE (op2) == CONST_INT) | |
72 | { | |
73 | - binoptab = add_optab; | |
74 | + code = PLUS; | |
75 | op2 = negate_rtx (GET_MODE (value), op2); | |
76 | } | |
77 | ||
78 | /* Check for an addition with OP2 a constant integer and our first | |
79 | - operand a PLUS of a virtual register and something else. In that | |
80 | - case, we want to emit the sum of the virtual register and the | |
81 | - constant first and then add the other value. This allows virtual | |
82 | - register instantiation to simply modify the constant rather than | |
83 | - creating another one around this addition. */ | |
84 | - if (binoptab == add_optab && GET_CODE (op2) == CONST_INT | |
85 | + operand a PLUS of a virtual register and something else. In that | |
86 | + case, we want to emit the sum of the virtual register and the | |
87 | + constant first and then add the other value. This allows virtual | |
88 | + register instantiation to simply modify the constant rather than | |
89 | + creating another one around this addition. */ | |
90 | + if (code == PLUS && GET_CODE (op2) == CONST_INT | |
91 | && GET_CODE (XEXP (value, 0)) == PLUS | |
92 | && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG | |
93 | && REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER | |
94 | && REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER) | |
95 | { | |
96 | - rtx temp = expand_binop (GET_MODE (value), binoptab, | |
97 | - XEXP (XEXP (value, 0), 0), op2, | |
98 | - subtarget, 0, OPTAB_LIB_WIDEN); | |
99 | - return expand_binop (GET_MODE (value), binoptab, temp, | |
100 | - force_operand (XEXP (XEXP (value, 0), 1), 0), | |
101 | - target, 0, OPTAB_LIB_WIDEN); | |
102 | + rtx temp = expand_simple_binop (GET_MODE (value), code, | |
103 | + XEXP (XEXP (value, 0), 0), op2, | |
104 | + subtarget, 0, OPTAB_LIB_WIDEN); | |
105 | + return expand_simple_binop (GET_MODE (value), code, temp, | |
106 | + force_operand (XEXP (XEXP (value, | |
107 | + 0), 1), 0), | |
108 | + target, 0, OPTAB_LIB_WIDEN); | |
109 | + } | |
110 | + | |
111 | + op1 = force_operand (XEXP (value, 0), subtarget); | |
112 | + op2 = force_operand (op2, NULL_RTX); | |
113 | + switch (code) | |
114 | + { | |
115 | + case MULT: | |
116 | + return expand_mult (GET_MODE (value), op1, op2, target, 1); | |
117 | + case DIV: | |
118 | + if (!INTEGRAL_MODE_P (GET_MODE (value))) | |
119 | + return expand_simple_binop (GET_MODE (value), code, op1, op2, | |
120 | + target, 1, OPTAB_LIB_WIDEN); | |
121 | + else | |
122 | + return expand_divmod (0, | |
123 | + FLOAT_MODE_P (GET_MODE (value)) | |
124 | + ? RDIV_EXPR : TRUNC_DIV_EXPR, | |
125 | + GET_MODE (value), op1, op2, target, 0); | |
126 | + break; | |
127 | + case MOD: | |
128 | + return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2, | |
129 | + target, 0); | |
130 | + break; | |
131 | + case UDIV: | |
132 | + return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2, | |
133 | + target, 1); | |
134 | + break; | |
135 | + case UMOD: | |
136 | + return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2, | |
137 | + target, 1); | |
138 | + break; | |
139 | + case ASHIFTRT: | |
140 | + return expand_simple_binop (GET_MODE (value), code, op1, op2, | |
141 | + target, 0, OPTAB_LIB_WIDEN); | |
142 | + break; | |
143 | + default: | |
144 | + return expand_simple_binop (GET_MODE (value), code, op1, op2, | |
145 | + target, 1, OPTAB_LIB_WIDEN); | |
146 | } | |
147 | - | |
148 | - tmp = force_operand (XEXP (value, 0), subtarget); | |
149 | - return expand_binop (GET_MODE (value), binoptab, tmp, | |
150 | - force_operand (op2, NULL_RTX), | |
151 | - target, 0, OPTAB_LIB_WIDEN); | |
152 | - /* We give UNSIGNEDP = 0 to expand_binop | |
153 | - because the only operations we are expanding here are signed ones. */ | |
154 | + } | |
155 | + if (GET_RTX_CLASS (code) == '1') | |
156 | + { | |
157 | + op1 = force_operand (XEXP (value, 0), NULL_RTX); | |
158 | + return expand_simple_unop (GET_MODE (value), code, op1, target, 0); | |
159 | } | |
160 | ||
161 | #ifdef INSN_SCHEDULING | |
162 | --- gcc/testsuite/gcc.dg/20020729-1.c.jj 2002-08-03 01:08:28.000000000 +0200 | |
163 | +++ gcc/testsuite/gcc.dg/20020729-1.c 2002-08-03 01:08:28.000000000 +0200 | |
164 | @@ -0,0 +1,51 @@ | |
165 | +/* { dg-do compile { target i?86-*-* } } */ | |
166 | +/* { dg-options "-O2 -march=k6" } */ | |
167 | + | |
168 | +static inline void * | |
169 | +baz (void *s, unsigned long c, unsigned int count) | |
170 | +{ | |
171 | + int d0, d1; | |
172 | + __asm__ __volatile__ ("" | |
173 | + : "=&c" (d0), "=&D" (d1) | |
174 | + :"a" (c), "q" (count), "0" (count / 4), "1" ((long) s) | |
175 | + :"memory"); | |
176 | + return s; | |
177 | +} | |
178 | + | |
179 | +struct A | |
180 | +{ | |
181 | + unsigned long *a; | |
182 | +}; | |
183 | + | |
184 | +inline static void * | |
185 | +bar (struct A *x, int y) | |
186 | +{ | |
187 | + char *ptr; | |
188 | + | |
189 | + ptr = (void *) x->a[y >> 12]; | |
190 | + ptr += y % (1UL << 12); | |
191 | + return (void *) ptr; | |
192 | +} | |
193 | + | |
194 | +int | |
195 | +foo (struct A *x, unsigned int *y, int z, int u) | |
196 | +{ | |
197 | + int a, b, c, d, e; | |
198 | + | |
199 | + z += *y; | |
200 | + c = z + u; | |
201 | + a = (z >> 12) + 1; | |
202 | + do | |
203 | + { | |
204 | + b = (a << 12); | |
205 | + d = b - z; | |
206 | + e = c - z; | |
207 | + if (e < d) | |
208 | + d = e; | |
209 | + baz (bar (x, z), 0, d); | |
210 | + z = b; | |
211 | + a++; | |
212 | + } | |
213 | + while (z < c); | |
214 | + return 0; | |
215 | +} |