]>
Commit | Line | Data |
---|---|---|
b7849684 | 1 | ;;- Machine description for HP PA-RISC architecture for GCC compiler |
1fd9ac1e | 2 | ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, |
d1885651 | 3 | ;; 2002, 2003, 2004 Free Software Foundation, Inc. |
c733e074 | 4 | ;; Contributed by the Center for Software Science at the University |
876662ef | 5 | ;; of Utah. |
c733e074 | 6 | |
b7849684 | 7 | ;; This file is part of GCC. |
c733e074 | 8 | |
b7849684 | 9 | ;; GCC is free software; you can redistribute it and/or modify |
c733e074 TM |
10 | ;; it under the terms of the GNU General Public License as published by |
11 | ;; the Free Software Foundation; either version 2, or (at your option) | |
12 | ;; any later version. | |
13 | ||
b7849684 | 14 | ;; GCC is distributed in the hope that it will be useful, |
c733e074 TM |
15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | ;; GNU General Public License for more details. | |
18 | ||
19 | ;; You should have received a copy of the GNU General Public License | |
b7849684 | 20 | ;; along with GCC; see the file COPYING. If not, write to |
3f63df56 RK |
21 | ;; the Free Software Foundation, 59 Temple Place - Suite 330, |
22 | ;; Boston, MA 02111-1307, USA. | |
c733e074 TM |
23 | |
24 | ;; This gcc Version 2 machine description is inspired by sparc.md and | |
25 | ;; mips.md. | |
26 | ||
27 | ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. | |
28 | ||
29 | ;; Insn type. Used to default other attribute values. | |
30 | ||
31 | ;; type "unary" insns have one input operand (1) and one output operand (0) | |
32 | ;; type "binary" insns have two input operands (1,2) and one output (0) | |
33 | ||
34 | (define_attr "type" | |
03d1cb6d | 35 | "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,parallel_branch" |
c733e074 TM |
36 | (const_string "binary")) |
37 | ||
c4bb6b38 JL |
38 | (define_attr "pa_combine_type" |
39 | "fmpy,faddsub,uncond_branch,addmove,none" | |
40 | (const_string "none")) | |
41 | ||
c47decad JL |
42 | ;; Processor type (for scheduling, not code generation) -- this attribute |
43 | ;; must exactly match the processor_type enumeration in pa.h. | |
44 | ;; | |
45 | ;; FIXME: Add 800 scheduling for completeness? | |
46 | ||
fae15c93 | 47 | (define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr"))) |
c47decad | 48 | |
36a29453 | 49 | ;; Length (in # of bytes). |
c733e074 TM |
50 | (define_attr "length" "" |
51 | (cond [(eq_attr "type" "load,fpload") | |
52 | (if_then_else (match_operand 1 "symbolic_memory_operand" "") | |
4c2164b7 | 53 | (const_int 8) (const_int 4)) |
c733e074 TM |
54 | |
55 | (eq_attr "type" "store,fpstore") | |
56 | (if_then_else (match_operand 0 "symbolic_memory_operand" "") | |
4c2164b7 | 57 | (const_int 8) (const_int 4)) |
c733e074 | 58 | |
c47decad | 59 | (eq_attr "type" "binary,shift,nullshift") |
c733e074 | 60 | (if_then_else (match_operand 2 "arith_operand" "") |
4c2164b7 | 61 | (const_int 4) (const_int 12)) |
c733e074 | 62 | |
c47decad | 63 | (eq_attr "type" "move,unary,shift,nullshift") |
c733e074 | 64 | (if_then_else (match_operand 1 "arith_operand" "") |
4c2164b7 | 65 | (const_int 4) (const_int 8))] |
c733e074 | 66 | |
4c2164b7 | 67 | (const_int 4))) |
c733e074 TM |
68 | |
69 | (define_asm_attributes | |
4c2164b7 | 70 | [(set_attr "length" "4") |
c733e074 TM |
71 | (set_attr "type" "multi")]) |
72 | ||
73 | ;; Attributes for instruction and branch scheduling | |
74 | ||
f854c12c | 75 | ;; For conditional branches. |
3bf1c6b5 | 76 | (define_attr "in_branch_delay" "false,true" |
03d1cb6d | 77 | (if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch") |
4c2164b7 | 78 | (eq_attr "length" "4")) |
3bf1c6b5 JL |
79 | (const_string "true") |
80 | (const_string "false"))) | |
c733e074 | 81 | |
99457156 JL |
82 | ;; Disallow instructions which use the FPU since they will tie up the FPU |
83 | ;; even if the instruction is nullified. | |
84 | (define_attr "in_nullified_branch_delay" "false,true" | |
03d1cb6d | 85 | (if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch") |
4c2164b7 | 86 | (eq_attr "length" "4")) |
99457156 JL |
87 | (const_string "true") |
88 | (const_string "false"))) | |
89 | ||
2f95ebc2 | 90 | ;; For calls and millicode calls. Allow unconditional branches in the |
f854c12c JL |
91 | ;; delay slot. |
92 | (define_attr "in_call_delay" "false,true" | |
03d1cb6d | 93 | (cond [(and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch") |
f854c12c JL |
94 | (eq_attr "length" "4")) |
95 | (const_string "true") | |
96 | (eq_attr "type" "uncond_branch") | |
97 | (if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY") | |
98 | (const_int 0)) | |
99 | (const_string "true") | |
100 | (const_string "false"))] | |
101 | (const_string "false"))) | |
f854c12c JL |
102 | |
103 | ||
b1092901 | 104 | ;; Call delay slot description. |
c4bb6b38 | 105 | (define_delay (eq_attr "type" "call") |
f854c12c JL |
106 | [(eq_attr "in_call_delay" "true") (nil) (nil)]) |
107 | ||
a02aa5b0 | 108 | ;; Millicode call delay slot description. |
f726ea7d | 109 | (define_delay (eq_attr "type" "milli") |
a02aa5b0 | 110 | [(eq_attr "in_call_delay" "true") (nil) (nil)]) |
f726ea7d | 111 | |
b1092901 | 112 | ;; Return and other similar instructions. |
03d1cb6d | 113 | (define_delay (eq_attr "type" "btable_branch,branch,parallel_branch") |
3bf1c6b5 | 114 | [(eq_attr "in_branch_delay" "true") (nil) (nil)]) |
c733e074 | 115 | |
99457156 | 116 | ;; Floating point conditional branch delay slot description and |
e9cfad81 | 117 | (define_delay (eq_attr "type" "fbranch") |
876662ef | 118 | [(eq_attr "in_branch_delay" "true") |
99457156 | 119 | (eq_attr "in_nullified_branch_delay" "true") |
e9cfad81 | 120 | (nil)]) |
c733e074 | 121 | |
e9cfad81 | 122 | ;; Integer conditional branch delay slot description. |
99457156 | 123 | ;; Nullification of conditional branches on the PA is dependent on the |
f65590a9 JL |
124 | ;; direction of the branch. Forward branches nullify true and |
125 | ;; backward branches nullify false. If the direction is unknown | |
126 | ;; then nullification is not allowed. | |
e9cfad81 | 127 | (define_delay (eq_attr "type" "cbranch") |
2f95ebc2 TG |
128 | [(eq_attr "in_branch_delay" "true") |
129 | (and (eq_attr "in_nullified_branch_delay" "true") | |
99457156 JL |
130 | (attr_flag "forward")) |
131 | (and (eq_attr "in_nullified_branch_delay" "true") | |
132 | (attr_flag "backward"))]) | |
c733e074 | 133 | |
c4bb6b38 JL |
134 | (define_delay (and (eq_attr "type" "uncond_branch") |
135 | (eq (symbol_ref "following_call (insn)") | |
136 | (const_int 0))) | |
137 | [(eq_attr "in_branch_delay" "true") (nil) (nil)]) | |
138 | ||
c733e074 | 139 | ;; Memory. Disregarding Cache misses, the Mustang memory times are: |
c47decad | 140 | ;; load: 2, fpload: 3 |
c733e074 | 141 | ;; store, fpstore: 3, no D-cache operations should be scheduled. |
c733e074 | 142 | |
c47decad | 143 | ;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT. |
c733e074 TM |
144 | ;; Timings: |
145 | ;; Instruction Time Unit Minimum Distance (unit contention) | |
146 | ;; fcpy 3 ALU 2 | |
147 | ;; fabs 3 ALU 2 | |
148 | ;; fadd 3 ALU 2 | |
149 | ;; fsub 3 ALU 2 | |
150 | ;; fcmp 3 ALU 2 | |
151 | ;; fcnv 3 ALU 2 | |
152 | ;; fmpyadd 3 ALU,MPY 2 | |
153 | ;; fmpysub 3 ALU,MPY 2 | |
154 | ;; fmpycfxt 3 ALU,MPY 2 | |
155 | ;; fmpy 3 MPY 2 | |
156 | ;; fmpyi 3 MPY 2 | |
157 | ;; fdiv,sgl 10 MPY 10 | |
158 | ;; fdiv,dbl 12 MPY 12 | |
159 | ;; fsqrt,sgl 14 MPY 14 | |
160 | ;; fsqrt,dbl 18 MPY 18 | |
fae15c93 VM |
161 | ;; |
162 | ;; We don't model fmpyadd/fmpysub properly as those instructions | |
163 | ;; keep both the FP ALU and MPY units busy. Given that these | |
164 | ;; processors are obsolete, I'm not going to spend the time to | |
165 | ;; model those instructions correctly. | |
c733e074 | 166 | |
fae15c93 VM |
167 | (define_automaton "pa700") |
168 | (define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700") | |
169 | ||
170 | (define_insn_reservation "W0" 4 | |
c47decad | 171 | (and (eq_attr "type" "fpcc") |
fae15c93 VM |
172 | (eq_attr "cpu" "700")) |
173 | "fpalu_700*2") | |
174 | ||
175 | (define_insn_reservation "W1" 3 | |
c47decad | 176 | (and (eq_attr "type" "fpalu") |
fae15c93 VM |
177 | (eq_attr "cpu" "700")) |
178 | "fpalu_700*2") | |
179 | ||
180 | (define_insn_reservation "W2" 3 | |
c47decad | 181 | (and (eq_attr "type" "fpmulsgl,fpmuldbl") |
fae15c93 VM |
182 | (eq_attr "cpu" "700")) |
183 | "fpmpy_700*2") | |
184 | ||
185 | (define_insn_reservation "W3" 10 | |
c47decad | 186 | (and (eq_attr "type" "fpdivsgl") |
fae15c93 VM |
187 | (eq_attr "cpu" "700")) |
188 | "fpmpy_700*10") | |
189 | ||
190 | (define_insn_reservation "W4" 12 | |
c47decad | 191 | (and (eq_attr "type" "fpdivdbl") |
fae15c93 VM |
192 | (eq_attr "cpu" "700")) |
193 | "fpmpy_700*12") | |
194 | ||
195 | (define_insn_reservation "W5" 14 | |
c47decad | 196 | (and (eq_attr "type" "fpsqrtsgl") |
fae15c93 VM |
197 | (eq_attr "cpu" "700")) |
198 | "fpmpy_700*14") | |
199 | ||
200 | (define_insn_reservation "W6" 18 | |
c47decad | 201 | (and (eq_attr "type" "fpsqrtdbl") |
fae15c93 VM |
202 | (eq_attr "cpu" "700")) |
203 | "fpmpy_700*18") | |
204 | ||
205 | (define_insn_reservation "W7" 2 | |
5d50fab3 | 206 | (and (eq_attr "type" "load") |
fae15c93 VM |
207 | (eq_attr "cpu" "700")) |
208 | "mem_700") | |
209 | ||
5d50fab3 JL |
210 | (define_insn_reservation "W8" 2 |
211 | (and (eq_attr "type" "fpload") | |
212 | (eq_attr "cpu" "700")) | |
213 | "mem_700") | |
214 | ||
215 | (define_insn_reservation "W9" 3 | |
216 | (and (eq_attr "type" "store") | |
217 | (eq_attr "cpu" "700")) | |
218 | "mem_700*3") | |
219 | ||
220 | (define_insn_reservation "W10" 3 | |
221 | (and (eq_attr "type" "fpstore") | |
fae15c93 VM |
222 | (eq_attr "cpu" "700")) |
223 | "mem_700*3") | |
224 | ||
5d50fab3 | 225 | (define_insn_reservation "W11" 1 |
fae15c93 VM |
226 | (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore") |
227 | (eq_attr "cpu" "700")) | |
228 | "dummy_700") | |
c47decad | 229 | |
5d50fab3 JL |
230 | ;; We have a bypass for all computations in the FP unit which feed an |
231 | ;; FP store as long as the sizes are the same. | |
232 | (define_bypass 2 "W1,W2" "W10" "hppa_fpstore_bypass_p") | |
233 | (define_bypass 9 "W3" "W10" "hppa_fpstore_bypass_p") | |
234 | (define_bypass 11 "W4" "W10" "hppa_fpstore_bypass_p") | |
235 | (define_bypass 13 "W5" "W10" "hppa_fpstore_bypass_p") | |
236 | (define_bypass 17 "W6" "W10" "hppa_fpstore_bypass_p") | |
237 | ||
238 | ;; We have an "anti-bypass" for FP loads which feed an FP store. | |
239 | (define_bypass 4 "W8" "W10" "hppa_fpstore_bypass_p") | |
240 | ||
c47decad JL |
241 | ;; Function units for the 7100 and 7150. The 7100/7150 can dual-issue |
242 | ;; floating point computations with non-floating point computations (fp loads | |
243 | ;; and stores are not fp computations). | |
244 | ;; | |
c47decad JL |
245 | ;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also |
246 | ;; take two cycles, during which no Dcache operations should be scheduled. | |
247 | ;; Any special cases are handled in pa_adjust_cost. The 7100, 7150 and 7100LC | |
248 | ;; all have the same memory characteristics if one disregards cache misses. | |
5d50fab3 | 249 | ;; |
c47decad | 250 | ;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV. |
5d50fab3 JL |
251 | ;; There's no value in modeling the ALU and MUL separately though |
252 | ;; since there can never be a functional unit conflict given the | |
253 | ;; latency and issue rates for those units. | |
254 | ;; | |
c47decad JL |
255 | ;; Timings: |
256 | ;; Instruction Time Unit Minimum Distance (unit contention) | |
257 | ;; fcpy 2 ALU 1 | |
258 | ;; fabs 2 ALU 1 | |
259 | ;; fadd 2 ALU 1 | |
260 | ;; fsub 2 ALU 1 | |
261 | ;; fcmp 2 ALU 1 | |
262 | ;; fcnv 2 ALU 1 | |
263 | ;; fmpyadd 2 ALU,MPY 1 | |
264 | ;; fmpysub 2 ALU,MPY 1 | |
265 | ;; fmpycfxt 2 ALU,MPY 1 | |
266 | ;; fmpy 2 MPY 1 | |
267 | ;; fmpyi 2 MPY 1 | |
268 | ;; fdiv,sgl 8 DIV 8 | |
269 | ;; fdiv,dbl 15 DIV 15 | |
270 | ;; fsqrt,sgl 8 DIV 8 | |
271 | ;; fsqrt,dbl 15 DIV 15 | |
272 | ||
fae15c93 VM |
273 | (define_automaton "pa7100") |
274 | (define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100") | |
275 | ||
276 | (define_insn_reservation "X0" 2 | |
277 | (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl") | |
278 | (eq_attr "cpu" "7100")) | |
279 | "f_7100,fpmac_7100") | |
280 | ||
281 | (define_insn_reservation "X1" 8 | |
c47decad | 282 | (and (eq_attr "type" "fpdivsgl,fpsqrtsgl") |
fae15c93 VM |
283 | (eq_attr "cpu" "7100")) |
284 | "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7") | |
c47decad | 285 | |
fae15c93 VM |
286 | (define_insn_reservation "X2" 15 |
287 | (and (eq_attr "type" "fpdivdbl,fpsqrtdbl") | |
288 | (eq_attr "cpu" "7100")) | |
289 | "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14") | |
c47decad | 290 | |
fae15c93 | 291 | (define_insn_reservation "X3" 2 |
5d50fab3 | 292 | (and (eq_attr "type" "load") |
fae15c93 VM |
293 | (eq_attr "cpu" "7100")) |
294 | "i_7100+mem_7100") | |
c47decad | 295 | |
fae15c93 | 296 | (define_insn_reservation "X4" 2 |
5d50fab3 JL |
297 | (and (eq_attr "type" "fpload") |
298 | (eq_attr "cpu" "7100")) | |
299 | "i_7100+mem_7100") | |
300 | ||
301 | (define_insn_reservation "X5" 2 | |
302 | (and (eq_attr "type" "store") | |
303 | (eq_attr "cpu" "7100")) | |
304 | "i_7100+mem_7100,mem_7100") | |
305 | ||
306 | (define_insn_reservation "X6" 2 | |
307 | (and (eq_attr "type" "fpstore") | |
fae15c93 VM |
308 | (eq_attr "cpu" "7100")) |
309 | "i_7100+mem_7100,mem_7100") | |
c47decad | 310 | |
5d50fab3 | 311 | (define_insn_reservation "X7" 1 |
fae15c93 VM |
312 | (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore") |
313 | (eq_attr "cpu" "7100")) | |
314 | "i_7100") | |
c47decad | 315 | |
5d50fab3 JL |
316 | ;; We have a bypass for all computations in the FP unit which feed an |
317 | ;; FP store as long as the sizes are the same. | |
318 | (define_bypass 1 "X0" "X6" "hppa_fpstore_bypass_p") | |
319 | (define_bypass 7 "X1" "X6" "hppa_fpstore_bypass_p") | |
320 | (define_bypass 14 "X2" "X6" "hppa_fpstore_bypass_p") | |
321 | ||
322 | ;; We have an "anti-bypass" for FP loads which feed an FP store. | |
323 | (define_bypass 3 "X4" "X6" "hppa_fpstore_bypass_p") | |
324 | ||
c47decad | 325 | ;; The 7100LC has three floating-point units: ALU, MUL, and DIV. |
5d50fab3 JL |
326 | ;; There's no value in modeling the ALU and MUL separately though |
327 | ;; since there can never be a functional unit conflict that | |
328 | ;; can be avoided given the latency, issue rates and mandatory | |
329 | ;; one cycle cpu-wide lock for a double precision fp multiply. | |
330 | ;; | |
c47decad JL |
331 | ;; Timings: |
332 | ;; Instruction Time Unit Minimum Distance (unit contention) | |
333 | ;; fcpy 2 ALU 1 | |
334 | ;; fabs 2 ALU 1 | |
335 | ;; fadd 2 ALU 1 | |
336 | ;; fsub 2 ALU 1 | |
337 | ;; fcmp 2 ALU 1 | |
338 | ;; fcnv 2 ALU 1 | |
339 | ;; fmpyadd,sgl 2 ALU,MPY 1 | |
340 | ;; fmpyadd,dbl 3 ALU,MPY 2 | |
341 | ;; fmpysub,sgl 2 ALU,MPY 1 | |
342 | ;; fmpysub,dbl 3 ALU,MPY 2 | |
343 | ;; fmpycfxt,sgl 2 ALU,MPY 1 | |
344 | ;; fmpycfxt,dbl 3 ALU,MPY 2 | |
345 | ;; fmpy,sgl 2 MPY 1 | |
346 | ;; fmpy,dbl 3 MPY 2 | |
347 | ;; fmpyi 3 MPY 2 | |
348 | ;; fdiv,sgl 8 DIV 8 | |
349 | ;; fdiv,dbl 15 DIV 15 | |
350 | ;; fsqrt,sgl 8 DIV 8 | |
351 | ;; fsqrt,dbl 15 DIV 15 | |
fae15c93 VM |
352 | ;; |
353 | ;; The PA7200 is just like the PA7100LC except that there is | |
354 | ;; no store-store penalty. | |
355 | ;; | |
356 | ;; The PA7300 is just like the PA7200 except that there is | |
357 | ;; no store-load penalty. | |
358 | ;; | |
359 | ;; Note there are some aspects of the 7100LC we are not modeling | |
360 | ;; at the moment. I'll be reviewing the 7100LC scheduling info | |
361 | ;; shortly and updating this description. | |
362 | ;; | |
363 | ;; load-load pairs | |
364 | ;; store-store pairs | |
fae15c93 VM |
365 | ;; other issue modeling |
366 | ||
367 | (define_automaton "pa7100lc") | |
368 | (define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc") | |
5d50fab3 | 369 | (define_cpu_unit "fpmac_7100lc" "pa7100lc") |
fae15c93 VM |
370 | (define_cpu_unit "mem_7100lc" "pa7100lc") |
371 | ||
3193c415 JL |
372 | ;; Double precision multiplies lock the entire CPU for one |
373 | ;; cycle. There is no way to avoid this lock and trying to | |
374 | ;; schedule around the lock is pointless and thus there is no | |
5d50fab3 JL |
375 | ;; value in trying to model this lock. |
376 | ;; | |
377 | ;; Not modeling the lock allows us to treat fp multiplies just | |
378 | ;; like any other FP alu instruction. It allows for a smaller | |
379 | ;; DFA and may reduce register pressure. | |
380 | (define_insn_reservation "Y0" 2 | |
381 | (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl") | |
fae15c93 | 382 | (eq_attr "cpu" "7100LC,7200,7300")) |
5d50fab3 | 383 | "f_7100lc,fpmac_7100lc") |
fae15c93 | 384 | |
3193c415 JL |
385 | ;; fp division and sqrt instructions lock the entire CPU for |
386 | ;; 7 cycles (single precision) or 14 cycles (double precision). | |
387 | ;; There is no way to avoid this lock and trying to schedule | |
388 | ;; around the lock is pointless and thus there is no value in | |
389 | ;; trying to model this lock. Not modeling the lock allows | |
390 | ;; for a smaller DFA and may reduce register pressure. | |
5d50fab3 | 391 | (define_insn_reservation "Y1" 1 |
3193c415 | 392 | (and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl") |
fae15c93 | 393 | (eq_attr "cpu" "7100LC,7200,7300")) |
3193c415 | 394 | "f_7100lc") |
c47decad | 395 | |
5d50fab3 JL |
396 | (define_insn_reservation "Y2" 2 |
397 | (and (eq_attr "type" "load") | |
398 | (eq_attr "cpu" "7100LC,7200,7300")) | |
399 | "i1_7100lc+mem_7100lc") | |
400 | ||
3193c415 | 401 | (define_insn_reservation "Y3" 2 |
5d50fab3 | 402 | (and (eq_attr "type" "fpload") |
fae15c93 VM |
403 | (eq_attr "cpu" "7100LC,7200,7300")) |
404 | "i1_7100lc+mem_7100lc") | |
c47decad | 405 | |
3193c415 | 406 | (define_insn_reservation "Y4" 2 |
5d50fab3 JL |
407 | (and (eq_attr "type" "store") |
408 | (eq_attr "cpu" "7100LC")) | |
409 | "i1_7100lc+mem_7100lc,mem_7100lc") | |
410 | ||
411 | (define_insn_reservation "Y5" 2 | |
412 | (and (eq_attr "type" "fpstore") | |
fae15c93 VM |
413 | (eq_attr "cpu" "7100LC")) |
414 | "i1_7100lc+mem_7100lc,mem_7100lc") | |
c47decad | 415 | |
5d50fab3 | 416 | (define_insn_reservation "Y6" 1 |
fae15c93 VM |
417 | (and (eq_attr "type" "shift,nullshift") |
418 | (eq_attr "cpu" "7100LC,7200,7300")) | |
419 | "i1_7100lc") | |
2da05a5b | 420 | |
5d50fab3 | 421 | (define_insn_reservation "Y7" 1 |
fae15c93 VM |
422 | (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift") |
423 | (eq_attr "cpu" "7100LC,7200,7300")) | |
424 | "(i0_7100lc|i1_7100lc)") | |
2da05a5b | 425 | |
fae15c93 | 426 | ;; The 7200 has a store-load penalty |
5d50fab3 JL |
427 | (define_insn_reservation "Y8" 2 |
428 | (and (eq_attr "type" "store") | |
429 | (eq_attr "cpu" "7200")) | |
430 | "i1_7100lc,mem_7100lc") | |
431 | ||
432 | (define_insn_reservation "Y9" 2 | |
433 | (and (eq_attr "type" "fpstore") | |
fae15c93 | 434 | (eq_attr "cpu" "7200")) |
3193c415 | 435 | "i1_7100lc,mem_7100lc") |
2da05a5b | 436 | |
fae15c93 | 437 | ;; The 7300 has no penalty for store-store or store-load |
5d50fab3 JL |
438 | (define_insn_reservation "Y10" 2 |
439 | (and (eq_attr "type" "store") | |
fae15c93 | 440 | (eq_attr "cpu" "7300")) |
3193c415 | 441 | "i1_7100lc") |
c47decad | 442 | |
5d50fab3 JL |
443 | (define_insn_reservation "Y11" 2 |
444 | (and (eq_attr "type" "fpstore") | |
445 | (eq_attr "cpu" "7300")) | |
446 | "i1_7100lc") | |
447 | ||
448 | ;; We have an "anti-bypass" for FP loads which feed an FP store. | |
449 | (define_bypass 3 "Y3" "Y5,Y9,Y11" "hppa_fpstore_bypass_p") | |
450 | ||
17d1971d JQ |
451 | ;; Scheduling for the PA8000 is somewhat different than scheduling for a |
452 | ;; traditional architecture. | |
e14b50ce | 453 | ;; |
17d1971d JQ |
454 | ;; The PA8000 has a large (56) entry reorder buffer that is split between |
455 | ;; memory and non-memory operations. | |
e14b50ce | 456 | ;; |
fae15c93 VM |
457 | ;; The PA8000 can issue two memory and two non-memory operations per cycle to |
458 | ;; the function units, with the exception of branches and multi-output | |
459 | ;; instructions. The PA8000 can retire two non-memory operations per cycle | |
460 | ;; and two memory operations per cycle, only one of which may be a store. | |
e14b50ce | 461 | ;; |
17d1971d JQ |
462 | ;; Given the large reorder buffer, the processor can hide most latencies. |
463 | ;; According to HP, they've got the best results by scheduling for retirement | |
464 | ;; bandwidth with limited latency scheduling for floating point operations. | |
465 | ;; Latency for integer operations and memory references is ignored. | |
466 | ;; | |
17d1971d | 467 | ;; |
fae15c93 VM |
468 | ;; We claim floating point operations have a 2 cycle latency and are |
469 | ;; fully pipelined, except for div and sqrt which are not pipelined and | |
470 | ;; take from 17 to 31 cycles to complete. | |
17d1971d | 471 | ;; |
fae15c93 VM |
472 | ;; It's worth noting that there is no way to saturate all the functional |
473 | ;; units on the PA8000 as there is not enough issue bandwidth. | |
474 | ||
475 | (define_automaton "pa8000") | |
476 | (define_cpu_unit "inm0_8000, inm1_8000, im0_8000, im1_8000" "pa8000") | |
477 | (define_cpu_unit "rnm0_8000, rnm1_8000, rm0_8000, rm1_8000" "pa8000") | |
478 | (define_cpu_unit "store_8000" "pa8000") | |
479 | (define_cpu_unit "f0_8000, f1_8000" "pa8000") | |
480 | (define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000") | |
481 | (define_reservation "inm_8000" "inm0_8000 | inm1_8000") | |
482 | (define_reservation "im_8000" "im0_8000 | im1_8000") | |
483 | (define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000") | |
484 | (define_reservation "rm_8000" "rm0_8000 | rm1_8000") | |
485 | (define_reservation "f_8000" "f0_8000 | f1_8000") | |
486 | (define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000") | |
487 | ||
488 | ;; We can issue any two memops per cycle, but we can only retire | |
489 | ;; one memory store per cycle. We assume that the reorder buffer | |
490 | ;; will hide any memory latencies per HP's recommendation. | |
491 | (define_insn_reservation "Z0" 0 | |
17d1971d | 492 | (and |
fae15c93 VM |
493 | (eq_attr "type" "load,fpload") |
494 | (eq_attr "cpu" "8000")) | |
495 | "im_8000,rm_8000") | |
17d1971d | 496 | |
fae15c93 | 497 | (define_insn_reservation "Z1" 0 |
17d1971d | 498 | (and |
fae15c93 VM |
499 | (eq_attr "type" "store,fpstore") |
500 | (eq_attr "cpu" "8000")) | |
501 | "im_8000,rm_8000+store_8000") | |
502 | ||
503 | ;; We can issue and retire two non-memory operations per cycle with | |
504 | ;; a few exceptions (branches). This group catches those we want | |
505 | ;; to assume have zero latency. | |
506 | (define_insn_reservation "Z2" 0 | |
17d1971d | 507 | (and |
03d1cb6d | 508 | (eq_attr "type" "!load,fpload,store,fpstore,uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch,fpcc,fpalu,fpmulsgl,fpmuldbl,fpsqrtsgl,fpsqrtdbl,fpdivsgl,fpdivdbl") |
fae15c93 VM |
509 | (eq_attr "cpu" "8000")) |
510 | "inm_8000,rnm_8000") | |
17d1971d | 511 | |
fae15c93 VM |
512 | ;; Branches use both slots in the non-memory issue and |
513 | ;; retirement unit. | |
514 | (define_insn_reservation "Z3" 0 | |
17d1971d | 515 | (and |
03d1cb6d | 516 | (eq_attr "type" "uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch") |
fae15c93 VM |
517 | (eq_attr "cpu" "8000")) |
518 | "inm0_8000+inm1_8000,rnm0_8000+rnm1_8000") | |
519 | ||
520 | ;; We partial latency schedule the floating point units. | |
521 | ;; They can issue/retire two at a time in the non-memory | |
522 | ;; units. We fix their latency at 2 cycles and they | |
523 | ;; are fully pipelined. | |
524 | (define_insn_reservation "Z4" 1 | |
525 | (and | |
526 | (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl") | |
527 | (eq_attr "cpu" "8000")) | |
528 | "inm_8000,f_8000,rnm_8000") | |
529 | ||
530 | ;; The fdivsqrt units are not pipelined and have a very long latency. | |
531 | ;; To keep the DFA from exploding, we do not show all the | |
532 | ;; reservations for the divsqrt unit. | |
533 | (define_insn_reservation "Z5" 17 | |
534 | (and | |
535 | (eq_attr "type" "fpdivsgl,fpsqrtsgl") | |
536 | (eq_attr "cpu" "8000")) | |
537 | "inm_8000,fdivsqrt_8000*6,rnm_8000") | |
538 | ||
539 | (define_insn_reservation "Z6" 31 | |
540 | (and | |
541 | (eq_attr "type" "fpdivdbl,fpsqrtdbl") | |
542 | (eq_attr "cpu" "8000")) | |
543 | "inm_8000,fdivsqrt_8000*6,rnm_8000") | |
17d1971d | 544 | |
e14b50ce | 545 | |
c733e074 TM |
546 | \f |
547 | ;; Compare instructions. | |
548 | ;; This controls RTL generation and register allocation. | |
549 | ||
876662ef | 550 | ;; We generate RTL for comparisons and branches by having the cmpxx |
c733e074 TM |
551 | ;; patterns store away the operands. Then, the scc and bcc patterns |
552 | ;; emit RTL for both the compare and the branch. | |
553 | ;; | |
554 | ||
520babc7 JL |
555 | (define_expand "cmpdi" |
556 | [(set (reg:CC 0) | |
557 | (compare:CC (match_operand:DI 0 "reg_or_0_operand" "") | |
558 | (match_operand:DI 1 "register_operand" "")))] | |
559 | "TARGET_64BIT" | |
560 | ||
561 | " | |
562 | { | |
563 | hppa_compare_op0 = operands[0]; | |
564 | hppa_compare_op1 = operands[1]; | |
565 | hppa_branch_type = CMP_SI; | |
566 | DONE; | |
567 | }") | |
568 | ||
c733e074 TM |
569 | (define_expand "cmpsi" |
570 | [(set (reg:CC 0) | |
571 | (compare:CC (match_operand:SI 0 "reg_or_0_operand" "") | |
572 | (match_operand:SI 1 "arith5_operand" "")))] | |
573 | "" | |
574 | " | |
575 | { | |
576 | hppa_compare_op0 = operands[0]; | |
577 | hppa_compare_op1 = operands[1]; | |
578 | hppa_branch_type = CMP_SI; | |
579 | DONE; | |
580 | }") | |
581 | ||
582 | (define_expand "cmpsf" | |
583 | [(set (reg:CCFP 0) | |
222727e8 JL |
584 | (compare:CCFP (match_operand:SF 0 "reg_or_0_operand" "") |
585 | (match_operand:SF 1 "reg_or_0_operand" "")))] | |
925cf581 | 586 | "! TARGET_SOFT_FLOAT" |
c733e074 TM |
587 | " |
588 | { | |
589 | hppa_compare_op0 = operands[0]; | |
590 | hppa_compare_op1 = operands[1]; | |
591 | hppa_branch_type = CMP_SF; | |
592 | DONE; | |
593 | }") | |
594 | ||
595 | (define_expand "cmpdf" | |
596 | [(set (reg:CCFP 0) | |
222727e8 JL |
597 | (compare:CCFP (match_operand:DF 0 "reg_or_0_operand" "") |
598 | (match_operand:DF 1 "reg_or_0_operand" "")))] | |
925cf581 | 599 | "! TARGET_SOFT_FLOAT" |
c733e074 TM |
600 | " |
601 | { | |
602 | hppa_compare_op0 = operands[0]; | |
603 | hppa_compare_op1 = operands[1]; | |
604 | hppa_branch_type = CMP_DF; | |
605 | DONE; | |
606 | }") | |
607 | ||
608 | (define_insn "" | |
2f95ebc2 TG |
609 | [(set (reg:CCFP 0) |
610 | (match_operator:CCFP 2 "comparison_operator" | |
0b27d5dd TG |
611 | [(match_operand:SF 0 "reg_or_0_operand" "fG") |
612 | (match_operand:SF 1 "reg_or_0_operand" "fG")]))] | |
925cf581 | 613 | "! TARGET_SOFT_FLOAT" |
55abf18a | 614 | "fcmp,sgl,%Y2 %f0,%f1" |
c47decad JL |
615 | [(set_attr "length" "4") |
616 | (set_attr "type" "fpcc")]) | |
c733e074 TM |
617 | |
618 | (define_insn "" | |
2f95ebc2 TG |
619 | [(set (reg:CCFP 0) |
620 | (match_operator:CCFP 2 "comparison_operator" | |
0b27d5dd TG |
621 | [(match_operand:DF 0 "reg_or_0_operand" "fG") |
622 | (match_operand:DF 1 "reg_or_0_operand" "fG")]))] | |
925cf581 | 623 | "! TARGET_SOFT_FLOAT" |
55abf18a | 624 | "fcmp,dbl,%Y2 %f0,%f1" |
c47decad JL |
625 | [(set_attr "length" "4") |
626 | (set_attr "type" "fpcc")]) | |
c733e074 | 627 | |
8c7d377f JDA |
628 | ;; Provide a means to emit the movccfp0 and movccfp1 optimization |
629 | ;; placeholders. This is necessary in rare situations when a | |
630 | ;; placeholder is re-emitted (see PR 8705). | |
631 | ||
632 | (define_expand "movccfp" | |
633 | [(set (reg:CCFP 0) | |
634 | (match_operand 0 "const_int_operand" ""))] | |
635 | "! TARGET_SOFT_FLOAT" | |
636 | " | |
637 | { | |
638 | if ((unsigned HOST_WIDE_INT) INTVAL (operands[0]) > 1) | |
639 | FAIL; | |
640 | }") | |
641 | ||
642 | ;; The following patterns are optimization placeholders. In almost | |
8d46398e JDA |
643 | ;; all cases, the user of the condition code will be simplified and the |
644 | ;; original condition code setting insn should be eliminated. | |
645 | ||
8c7d377f | 646 | (define_insn "*movccfp0" |
8d46398e JDA |
647 | [(set (reg:CCFP 0) |
648 | (const_int 0))] | |
649 | "! TARGET_SOFT_FLOAT" | |
8c7d377f | 650 | "fcmp,dbl,= %%fr0,%%fr0" |
8d46398e JDA |
651 | [(set_attr "length" "4") |
652 | (set_attr "type" "fpcc")]) | |
653 | ||
8c7d377f | 654 | (define_insn "*movccfp1" |
8d46398e JDA |
655 | [(set (reg:CCFP 0) |
656 | (const_int 1))] | |
657 | "! TARGET_SOFT_FLOAT" | |
8c7d377f | 658 | "fcmp,dbl,!= %%fr0,%%fr0" |
8d46398e JDA |
659 | [(set_attr "length" "4") |
660 | (set_attr "type" "fpcc")]) | |
661 | ||
c733e074 TM |
662 | ;; scc insns. |
663 | ||
c733e074 TM |
664 | (define_expand "seq" |
665 | [(set (match_operand:SI 0 "register_operand" "") | |
d2a94ec0 | 666 | (eq:SI (match_dup 1) |
c733e074 | 667 | (match_dup 2)))] |
520babc7 | 668 | "!TARGET_64BIT" |
c733e074 TM |
669 | " |
670 | { | |
23c6329e | 671 | /* fp scc patterns rarely match, and are not a win on the PA. */ |
c733e074 | 672 | if (hppa_branch_type != CMP_SI) |
23c6329e | 673 | FAIL; |
c733e074 TM |
674 | /* set up operands from compare. */ |
675 | operands[1] = hppa_compare_op0; | |
676 | operands[2] = hppa_compare_op1; | |
677 | /* fall through and generate default code */ | |
678 | }") | |
679 | ||
680 | (define_expand "sne" | |
876662ef | 681 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 682 | (ne:SI (match_dup 1) |
c733e074 | 683 | (match_dup 2)))] |
520babc7 | 684 | "!TARGET_64BIT" |
c733e074 TM |
685 | " |
686 | { | |
23c6329e | 687 | /* fp scc patterns rarely match, and are not a win on the PA. */ |
c733e074 | 688 | if (hppa_branch_type != CMP_SI) |
23c6329e | 689 | FAIL; |
c733e074 TM |
690 | operands[1] = hppa_compare_op0; |
691 | operands[2] = hppa_compare_op1; | |
692 | }") | |
693 | ||
694 | (define_expand "slt" | |
876662ef | 695 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 696 | (lt:SI (match_dup 1) |
c733e074 | 697 | (match_dup 2)))] |
520babc7 | 698 | "!TARGET_64BIT" |
c733e074 TM |
699 | " |
700 | { | |
23c6329e | 701 | /* fp scc patterns rarely match, and are not a win on the PA. */ |
c733e074 | 702 | if (hppa_branch_type != CMP_SI) |
23c6329e | 703 | FAIL; |
c733e074 TM |
704 | operands[1] = hppa_compare_op0; |
705 | operands[2] = hppa_compare_op1; | |
706 | }") | |
707 | ||
708 | (define_expand "sgt" | |
876662ef | 709 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 710 | (gt:SI (match_dup 1) |
c733e074 | 711 | (match_dup 2)))] |
520babc7 | 712 | "!TARGET_64BIT" |
c733e074 TM |
713 | " |
714 | { | |
23c6329e | 715 | /* fp scc patterns rarely match, and are not a win on the PA. */ |
c733e074 | 716 | if (hppa_branch_type != CMP_SI) |
23c6329e | 717 | FAIL; |
c733e074 TM |
718 | operands[1] = hppa_compare_op0; |
719 | operands[2] = hppa_compare_op1; | |
720 | }") | |
721 | ||
722 | (define_expand "sle" | |
876662ef | 723 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 724 | (le:SI (match_dup 1) |
c733e074 | 725 | (match_dup 2)))] |
520babc7 | 726 | "!TARGET_64BIT" |
c733e074 TM |
727 | " |
728 | { | |
23c6329e | 729 | /* fp scc patterns rarely match, and are not a win on the PA. */ |
c733e074 | 730 | if (hppa_branch_type != CMP_SI) |
23c6329e | 731 | FAIL; |
c733e074 TM |
732 | operands[1] = hppa_compare_op0; |
733 | operands[2] = hppa_compare_op1; | |
734 | }") | |
735 | ||
736 | (define_expand "sge" | |
876662ef | 737 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 738 | (ge:SI (match_dup 1) |
c733e074 | 739 | (match_dup 2)))] |
520babc7 | 740 | "!TARGET_64BIT" |
c733e074 TM |
741 | " |
742 | { | |
23c6329e | 743 | /* fp scc patterns rarely match, and are not a win on the PA. */ |
c733e074 | 744 | if (hppa_branch_type != CMP_SI) |
23c6329e | 745 | FAIL; |
c733e074 TM |
746 | operands[1] = hppa_compare_op0; |
747 | operands[2] = hppa_compare_op1; | |
748 | }") | |
749 | ||
750 | (define_expand "sltu" | |
876662ef | 751 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 752 | (ltu:SI (match_dup 1) |
c733e074 | 753 | (match_dup 2)))] |
520babc7 | 754 | "!TARGET_64BIT" |
c733e074 TM |
755 | " |
756 | { | |
757 | if (hppa_branch_type != CMP_SI) | |
758 | FAIL; | |
759 | operands[1] = hppa_compare_op0; | |
760 | operands[2] = hppa_compare_op1; | |
761 | }") | |
762 | ||
763 | (define_expand "sgtu" | |
876662ef | 764 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 765 | (gtu:SI (match_dup 1) |
c733e074 | 766 | (match_dup 2)))] |
520babc7 | 767 | "!TARGET_64BIT" |
c733e074 TM |
768 | " |
769 | { | |
770 | if (hppa_branch_type != CMP_SI) | |
771 | FAIL; | |
772 | operands[1] = hppa_compare_op0; | |
773 | operands[2] = hppa_compare_op1; | |
774 | }") | |
775 | ||
776 | (define_expand "sleu" | |
876662ef | 777 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 778 | (leu:SI (match_dup 1) |
c733e074 | 779 | (match_dup 2)))] |
520babc7 | 780 | "!TARGET_64BIT" |
c733e074 TM |
781 | " |
782 | { | |
783 | if (hppa_branch_type != CMP_SI) | |
784 | FAIL; | |
785 | operands[1] = hppa_compare_op0; | |
786 | operands[2] = hppa_compare_op1; | |
787 | }") | |
788 | ||
789 | (define_expand "sgeu" | |
876662ef | 790 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 791 | (geu:SI (match_dup 1) |
c733e074 | 792 | (match_dup 2)))] |
520babc7 | 793 | "!TARGET_64BIT" |
c733e074 TM |
794 | " |
795 | { | |
796 | if (hppa_branch_type != CMP_SI) | |
797 | FAIL; | |
798 | operands[1] = hppa_compare_op0; | |
799 | operands[2] = hppa_compare_op1; | |
800 | }") | |
801 | ||
802 | ;; Instruction canonicalization puts immediate operands second, which | |
803 | ;; is the reverse of what we want. | |
804 | ||
fd0214cd | 805 | (define_insn "scc" |
6f672dc0 | 806 | [(set (match_operand:SI 0 "register_operand" "=r") |
d2a94ec0 | 807 | (match_operator:SI 3 "comparison_operator" |
6f672dc0 | 808 | [(match_operand:SI 1 "register_operand" "r") |
2f95ebc2 | 809 | (match_operand:SI 2 "arith11_operand" "rI")]))] |
c733e074 | 810 | "" |
f38b27c7 | 811 | "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi 1,%0" |
6f672dc0 | 812 | [(set_attr "type" "binary") |
4c2164b7 | 813 | (set_attr "length" "8")]) |
c733e074 | 814 | |
520babc7 JL |
815 | (define_insn "" |
816 | [(set (match_operand:DI 0 "register_operand" "=r") | |
817 | (match_operator:DI 3 "comparison_operator" | |
818 | [(match_operand:DI 1 "register_operand" "r") | |
819 | (match_operand:DI 2 "arith11_operand" "rI")]))] | |
820 | "TARGET_64BIT" | |
821 | "cmp%I2clr,*%B3 %2,%1,%0\;ldi 1,%0" | |
822 | [(set_attr "type" "binary") | |
823 | (set_attr "length" "8")]) | |
824 | ||
2f95ebc2 TG |
825 | (define_insn "iorscc" |
826 | [(set (match_operand:SI 0 "register_operand" "=r") | |
827 | (ior:SI (match_operator:SI 3 "comparison_operator" | |
828 | [(match_operand:SI 1 "register_operand" "r") | |
829 | (match_operand:SI 2 "arith11_operand" "rI")]) | |
830 | (match_operator:SI 6 "comparison_operator" | |
831 | [(match_operand:SI 4 "register_operand" "r") | |
832 | (match_operand:SI 5 "arith11_operand" "rI")])))] | |
833 | "" | |
f38b27c7 | 834 | "{com%I2clr|cmp%I2clr},%S3 %2,%1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%4,%0\;ldi 1,%0" |
2f95ebc2 | 835 | [(set_attr "type" "binary") |
c47decad | 836 | (set_attr "length" "12")]) |
2f95ebc2 | 837 | |
520babc7 JL |
838 | (define_insn "" |
839 | [(set (match_operand:DI 0 "register_operand" "=r") | |
840 | (ior:DI (match_operator:DI 3 "comparison_operator" | |
841 | [(match_operand:DI 1 "register_operand" "r") | |
842 | (match_operand:DI 2 "arith11_operand" "rI")]) | |
843 | (match_operator:DI 6 "comparison_operator" | |
844 | [(match_operand:DI 4 "register_operand" "r") | |
845 | (match_operand:DI 5 "arith11_operand" "rI")])))] | |
846 | "TARGET_64BIT" | |
847 | "cmp%I2clr,*%S3 %2,%1,%%r0\;cmp%I5clr,*%B6 %5,%4,%0\;ldi 1,%0" | |
848 | [(set_attr "type" "binary") | |
849 | (set_attr "length" "12")]) | |
850 | ||
fd0214cd | 851 | ;; Combiner patterns for common operations performed with the output |
2f95ebc2 | 852 | ;; from an scc insn (negscc and incscc). |
fd0214cd | 853 | (define_insn "negscc" |
6f672dc0 | 854 | [(set (match_operand:SI 0 "register_operand" "=r") |
2878315f | 855 | (neg:SI (match_operator:SI 3 "comparison_operator" |
6f672dc0 | 856 | [(match_operand:SI 1 "register_operand" "r") |
2f95ebc2 | 857 | (match_operand:SI 2 "arith11_operand" "rI")])))] |
fd0214cd | 858 | "" |
f38b27c7 | 859 | "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi -1,%0" |
6f672dc0 | 860 | [(set_attr "type" "binary") |
4c2164b7 | 861 | (set_attr "length" "8")]) |
6f672dc0 | 862 | |
520babc7 JL |
863 | (define_insn "" |
864 | [(set (match_operand:DI 0 "register_operand" "=r") | |
865 | (neg:DI (match_operator:DI 3 "comparison_operator" | |
866 | [(match_operand:DI 1 "register_operand" "r") | |
867 | (match_operand:DI 2 "arith11_operand" "rI")])))] | |
868 | "TARGET_64BIT" | |
869 | "cmp%I2clr,*%B3 %2,%1,%0\;ldi -1,%0" | |
870 | [(set_attr "type" "binary") | |
871 | (set_attr "length" "8")]) | |
872 | ||
6f672dc0 TG |
873 | ;; Patterns for adding/subtracting the result of a boolean expression from |
874 | ;; a register. First we have special patterns that make use of the carry | |
875 | ;; bit, and output only two instructions. For the cases we can't in | |
876 | ;; general do in two instructions, the incscc pattern at the end outputs | |
877 | ;; two or three instructions. | |
878 | ||
879 | (define_insn "" | |
880 | [(set (match_operand:SI 0 "register_operand" "=r") | |
881 | (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r") | |
882 | (match_operand:SI 3 "arith11_operand" "rI")) | |
883 | (match_operand:SI 1 "register_operand" "r")))] | |
884 | "" | |
f38b27c7 | 885 | "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0" |
6f672dc0 | 886 | [(set_attr "type" "binary") |
4c2164b7 | 887 | (set_attr "length" "8")]) |
6f672dc0 | 888 | |
520babc7 JL |
889 | (define_insn "" |
890 | [(set (match_operand:DI 0 "register_operand" "=r") | |
891 | (plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r") | |
892 | (match_operand:DI 3 "arith11_operand" "rI")) | |
893 | (match_operand:DI 1 "register_operand" "r")))] | |
894 | "TARGET_64BIT" | |
895 | "sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0" | |
896 | [(set_attr "type" "binary") | |
897 | (set_attr "length" "8")]) | |
898 | ||
6f672dc0 TG |
899 | ; This need only accept registers for op3, since canonicalization |
900 | ; replaces geu with gtu when op3 is an integer. | |
901 | (define_insn "" | |
902 | [(set (match_operand:SI 0 "register_operand" "=r") | |
903 | (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r") | |
904 | (match_operand:SI 3 "register_operand" "r")) | |
905 | (match_operand:SI 1 "register_operand" "r")))] | |
906 | "" | |
f38b27c7 | 907 | "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0" |
6f672dc0 | 908 | [(set_attr "type" "binary") |
4c2164b7 | 909 | (set_attr "length" "8")]) |
6f672dc0 | 910 | |
520babc7 JL |
911 | (define_insn "" |
912 | [(set (match_operand:DI 0 "register_operand" "=r") | |
913 | (plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r") | |
914 | (match_operand:DI 3 "register_operand" "r")) | |
915 | (match_operand:DI 1 "register_operand" "r")))] | |
916 | "TARGET_64BIT" | |
917 | "sub %2,%3,%%r0\;add,dc %%r0,%1,%0" | |
918 | [(set_attr "type" "binary") | |
919 | (set_attr "length" "8")]) | |
920 | ||
6f672dc0 TG |
921 | ; Match only integers for op3 here. This is used as canonical form of the |
922 | ; geu pattern when op3 is an integer. Don't match registers since we can't | |
923 | ; make better code than the general incscc pattern. | |
924 | (define_insn "" | |
925 | [(set (match_operand:SI 0 "register_operand" "=r") | |
926 | (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r") | |
927 | (match_operand:SI 3 "int11_operand" "I")) | |
928 | (match_operand:SI 1 "register_operand" "r")))] | |
929 | "" | |
f38b27c7 | 930 | "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0" |
fd0214cd | 931 | [(set_attr "type" "binary") |
4c2164b7 | 932 | (set_attr "length" "8")]) |
fd0214cd | 933 | |
520babc7 JL |
934 | (define_insn "" |
935 | [(set (match_operand:DI 0 "register_operand" "=r") | |
936 | (plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r") | |
937 | (match_operand:DI 3 "int11_operand" "I")) | |
938 | (match_operand:DI 1 "register_operand" "r")))] | |
939 | "TARGET_64BIT" | |
940 | "addi %k3,%2,%%r0\;add,dc %%r0,%1,%0" | |
941 | [(set_attr "type" "binary") | |
942 | (set_attr "length" "8")]) | |
943 | ||
fd0214cd JL |
944 | (define_insn "incscc" |
945 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
6f672dc0 TG |
946 | (plus:SI (match_operator:SI 4 "comparison_operator" |
947 | [(match_operand:SI 2 "register_operand" "r,r") | |
948 | (match_operand:SI 3 "arith11_operand" "rI,rI")]) | |
949 | (match_operand:SI 1 "register_operand" "0,?r")))] | |
950 | "" | |
951 | "@ | |
f38b27c7 JL |
952 | {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0 |
953 | {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0" | |
6f672dc0 | 954 | [(set_attr "type" "binary,binary") |
4c2164b7 | 955 | (set_attr "length" "8,12")]) |
6f672dc0 | 956 | |
520babc7 JL |
957 | (define_insn "" |
958 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
959 | (plus:DI (match_operator:DI 4 "comparison_operator" | |
960 | [(match_operand:DI 2 "register_operand" "r,r") | |
961 | (match_operand:DI 3 "arith11_operand" "rI,rI")]) | |
962 | (match_operand:DI 1 "register_operand" "0,?r")))] | |
963 | "TARGET_64BIT" | |
964 | "@ | |
965 | cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0 | |
966 | cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0" | |
967 | [(set_attr "type" "binary,binary") | |
968 | (set_attr "length" "8,12")]) | |
969 | ||
6f672dc0 TG |
970 | (define_insn "" |
971 | [(set (match_operand:SI 0 "register_operand" "=r") | |
972 | (minus:SI (match_operand:SI 1 "register_operand" "r") | |
973 | (gtu:SI (match_operand:SI 2 "register_operand" "r") | |
974 | (match_operand:SI 3 "arith11_operand" "rI"))))] | |
975 | "" | |
f38b27c7 | 976 | "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0" |
6f672dc0 | 977 | [(set_attr "type" "binary") |
4c2164b7 | 978 | (set_attr "length" "8")]) |
6f672dc0 | 979 | |
520babc7 JL |
980 | (define_insn "" |
981 | [(set (match_operand:DI 0 "register_operand" "=r") | |
982 | (minus:DI (match_operand:DI 1 "register_operand" "r") | |
983 | (gtu:DI (match_operand:DI 2 "register_operand" "r") | |
984 | (match_operand:DI 3 "arith11_operand" "rI"))))] | |
985 | "TARGET_64BIT" | |
986 | "sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0" | |
987 | [(set_attr "type" "binary") | |
988 | (set_attr "length" "8")]) | |
989 | ||
2f95ebc2 TG |
990 | (define_insn "" |
991 | [(set (match_operand:SI 0 "register_operand" "=r") | |
992 | (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") | |
993 | (gtu:SI (match_operand:SI 2 "register_operand" "r") | |
994 | (match_operand:SI 3 "arith11_operand" "rI"))) | |
995 | (match_operand:SI 4 "register_operand" "r")))] | |
996 | "" | |
f38b27c7 | 997 | "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0" |
2f95ebc2 TG |
998 | [(set_attr "type" "binary") |
999 | (set_attr "length" "8")]) | |
1000 | ||
520babc7 JL |
1001 | (define_insn "" |
1002 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1003 | (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r") | |
1004 | (gtu:DI (match_operand:DI 2 "register_operand" "r") | |
1005 | (match_operand:DI 3 "arith11_operand" "rI"))) | |
1006 | (match_operand:DI 4 "register_operand" "r")))] | |
1007 | "TARGET_64BIT" | |
1008 | "sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0" | |
1009 | [(set_attr "type" "binary") | |
1010 | (set_attr "length" "8")]) | |
1011 | ||
6f672dc0 TG |
1012 | ; This need only accept registers for op3, since canonicalization |
1013 | ; replaces ltu with leu when op3 is an integer. | |
1014 | (define_insn "" | |
1015 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1016 | (minus:SI (match_operand:SI 1 "register_operand" "r") | |
1017 | (ltu:SI (match_operand:SI 2 "register_operand" "r") | |
1018 | (match_operand:SI 3 "register_operand" "r"))))] | |
1019 | "" | |
f38b27c7 | 1020 | "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0" |
6f672dc0 | 1021 | [(set_attr "type" "binary") |
4c2164b7 | 1022 | (set_attr "length" "8")]) |
6f672dc0 | 1023 | |
520babc7 JL |
1024 | (define_insn "" |
1025 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1026 | (minus:DI (match_operand:DI 1 "register_operand" "r") | |
1027 | (ltu:DI (match_operand:DI 2 "register_operand" "r") | |
1028 | (match_operand:DI 3 "register_operand" "r"))))] | |
1029 | "TARGET_64BIT" | |
1030 | "sub %2,%3,%%r0\;sub,db %1,%%r0,%0" | |
1031 | [(set_attr "type" "binary") | |
1032 | (set_attr "length" "8")]) | |
1033 | ||
2f95ebc2 TG |
1034 | (define_insn "" |
1035 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1036 | (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") | |
1037 | (ltu:SI (match_operand:SI 2 "register_operand" "r") | |
1038 | (match_operand:SI 3 "register_operand" "r"))) | |
1039 | (match_operand:SI 4 "register_operand" "r")))] | |
1040 | "" | |
f38b27c7 | 1041 | "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0" |
2f95ebc2 TG |
1042 | [(set_attr "type" "binary") |
1043 | (set_attr "length" "8")]) | |
1044 | ||
520babc7 JL |
1045 | (define_insn "" |
1046 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1047 | (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r") | |
1048 | (ltu:DI (match_operand:DI 2 "register_operand" "r") | |
1049 | (match_operand:DI 3 "register_operand" "r"))) | |
1050 | (match_operand:DI 4 "register_operand" "r")))] | |
1051 | "TARGET_64BIT" | |
1052 | "sub %2,%3,%%r0\;sub,db %1,%4,%0" | |
1053 | [(set_attr "type" "binary") | |
1054 | (set_attr "length" "8")]) | |
1055 | ||
6f672dc0 TG |
1056 | ; Match only integers for op3 here. This is used as canonical form of the |
1057 | ; ltu pattern when op3 is an integer. Don't match registers since we can't | |
1058 | ; make better code than the general incscc pattern. | |
1059 | (define_insn "" | |
1060 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1061 | (minus:SI (match_operand:SI 1 "register_operand" "r") | |
1062 | (leu:SI (match_operand:SI 2 "register_operand" "r") | |
1063 | (match_operand:SI 3 "int11_operand" "I"))))] | |
1064 | "" | |
f38b27c7 | 1065 | "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0" |
6f672dc0 | 1066 | [(set_attr "type" "binary") |
4c2164b7 | 1067 | (set_attr "length" "8")]) |
6f672dc0 | 1068 | |
520babc7 JL |
1069 | (define_insn "" |
1070 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1071 | (minus:DI (match_operand:DI 1 "register_operand" "r") | |
1072 | (leu:DI (match_operand:DI 2 "register_operand" "r") | |
1073 | (match_operand:DI 3 "int11_operand" "I"))))] | |
1074 | "TARGET_64BIT" | |
1075 | "addi %k3,%2,%%r0\;sub,db %1,%%r0,%0" | |
1076 | [(set_attr "type" "binary") | |
1077 | (set_attr "length" "8")]) | |
1078 | ||
2f95ebc2 TG |
1079 | (define_insn "" |
1080 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1081 | (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") | |
1082 | (leu:SI (match_operand:SI 2 "register_operand" "r") | |
1083 | (match_operand:SI 3 "int11_operand" "I"))) | |
1084 | (match_operand:SI 4 "register_operand" "r")))] | |
1085 | "" | |
f38b27c7 | 1086 | "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0" |
2f95ebc2 TG |
1087 | [(set_attr "type" "binary") |
1088 | (set_attr "length" "8")]) | |
1089 | ||
520babc7 JL |
1090 | (define_insn "" |
1091 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1092 | (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r") | |
1093 | (leu:DI (match_operand:DI 2 "register_operand" "r") | |
1094 | (match_operand:DI 3 "int11_operand" "I"))) | |
1095 | (match_operand:DI 4 "register_operand" "r")))] | |
1096 | "TARGET_64BIT" | |
1097 | "addi %k3,%2,%%r0\;sub,db %1,%4,%0" | |
1098 | [(set_attr "type" "binary") | |
1099 | (set_attr "length" "8")]) | |
1100 | ||
6f672dc0 TG |
1101 | (define_insn "decscc" |
1102 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1103 | (minus:SI (match_operand:SI 1 "register_operand" "0,?r") | |
1104 | (match_operator:SI 4 "comparison_operator" | |
1105 | [(match_operand:SI 2 "register_operand" "r,r") | |
1106 | (match_operand:SI 3 "arith11_operand" "rI,rI")])))] | |
1107 | "" | |
1108 | "@ | |
f38b27c7 JL |
1109 | {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0 |
1110 | {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0" | |
fd0214cd | 1111 | [(set_attr "type" "binary,binary") |
4c2164b7 | 1112 | (set_attr "length" "8,12")]) |
ac153498 | 1113 | |
520babc7 JL |
1114 | (define_insn "" |
1115 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
1116 | (minus:DI (match_operand:DI 1 "register_operand" "0,?r") | |
1117 | (match_operator:DI 4 "comparison_operator" | |
1118 | [(match_operand:DI 2 "register_operand" "r,r") | |
1119 | (match_operand:DI 3 "arith11_operand" "rI,rI")])))] | |
1120 | "TARGET_64BIT" | |
1121 | "@ | |
1122 | cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0 | |
1123 | cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0" | |
1124 | [(set_attr "type" "binary,binary") | |
1125 | (set_attr "length" "8,12")]) | |
1126 | ||
751a3523 JL |
1127 | ; Patterns for max and min. (There is no need for an earlyclobber in the |
1128 | ; last alternative since the middle alternative will match if op0 == op1.) | |
1129 | ||
99457156 JL |
1130 | (define_insn "sminsi3" |
1131 | [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
751a3523 JL |
1132 | (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r") |
1133 | (match_operand:SI 2 "arith11_operand" "r,I,M")))] | |
99457156 JL |
1134 | "" |
1135 | "@ | |
f38b27c7 JL |
1136 | {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0 |
1137 | {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0 | |
1138 | {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0" | |
99457156 | 1139 | [(set_attr "type" "multi,multi,multi") |
4c2164b7 | 1140 | (set_attr "length" "8,8,8")]) |
99457156 | 1141 | |
520babc7 JL |
1142 | (define_insn "smindi3" |
1143 | [(set (match_operand:DI 0 "register_operand" "=r,r,r") | |
1144 | (smin:DI (match_operand:DI 1 "register_operand" "%0,0,r") | |
1145 | (match_operand:DI 2 "arith11_operand" "r,I,M")))] | |
1146 | "TARGET_64BIT" | |
1147 | "@ | |
1148 | cmpclr,*> %2,%0,%%r0\;copy %2,%0 | |
1149 | cmpiclr,*> %2,%0,%%r0\;ldi %2,%0 | |
1150 | cmpclr,*> %1,%r2,%0\;copy %1,%0" | |
1151 | [(set_attr "type" "multi,multi,multi") | |
1152 | (set_attr "length" "8,8,8")]) | |
1153 | ||
99457156 JL |
1154 | (define_insn "uminsi3" |
1155 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1156 | (umin:SI (match_operand:SI 1 "register_operand" "%0,0") | |
1157 | (match_operand:SI 2 "arith11_operand" "r,I")))] | |
1158 | "" | |
1159 | "@ | |
f38b27c7 JL |
1160 | {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0 |
1161 | {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0" | |
99457156 | 1162 | [(set_attr "type" "multi,multi") |
4c2164b7 | 1163 | (set_attr "length" "8,8")]) |
99457156 | 1164 | |
520babc7 JL |
1165 | (define_insn "umindi3" |
1166 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
1167 | (umin:DI (match_operand:DI 1 "register_operand" "%0,0") | |
1168 | (match_operand:DI 2 "arith11_operand" "r,I")))] | |
1169 | "TARGET_64BIT" | |
1170 | "@ | |
1171 | cmpclr,*>> %2,%0,%%r0\;copy %2,%0 | |
1172 | cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0" | |
1173 | [(set_attr "type" "multi,multi") | |
1174 | (set_attr "length" "8,8")]) | |
1175 | ||
99457156 JL |
1176 | (define_insn "smaxsi3" |
1177 | [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
751a3523 JL |
1178 | (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r") |
1179 | (match_operand:SI 2 "arith11_operand" "r,I,M")))] | |
99457156 JL |
1180 | "" |
1181 | "@ | |
f38b27c7 JL |
1182 | {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0 |
1183 | {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0 | |
1184 | {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0" | |
99457156 | 1185 | [(set_attr "type" "multi,multi,multi") |
4c2164b7 | 1186 | (set_attr "length" "8,8,8")]) |
99457156 | 1187 | |
520babc7 JL |
1188 | (define_insn "smaxdi3" |
1189 | [(set (match_operand:DI 0 "register_operand" "=r,r,r") | |
1190 | (smax:DI (match_operand:DI 1 "register_operand" "%0,0,r") | |
1191 | (match_operand:DI 2 "arith11_operand" "r,I,M")))] | |
1192 | "TARGET_64BIT" | |
1193 | "@ | |
1194 | cmpclr,*< %2,%0,%%r0\;copy %2,%0 | |
1195 | cmpiclr,*< %2,%0,%%r0\;ldi %2,%0 | |
1196 | cmpclr,*< %1,%r2,%0\;copy %1,%0" | |
1197 | [(set_attr "type" "multi,multi,multi") | |
1198 | (set_attr "length" "8,8,8")]) | |
1199 | ||
99457156 JL |
1200 | (define_insn "umaxsi3" |
1201 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1202 | (umax:SI (match_operand:SI 1 "register_operand" "%0,0") | |
1203 | (match_operand:SI 2 "arith11_operand" "r,I")))] | |
1204 | "" | |
1205 | "@ | |
f38b27c7 JL |
1206 | {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0 |
1207 | {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0" | |
99457156 | 1208 | [(set_attr "type" "multi,multi") |
4c2164b7 | 1209 | (set_attr "length" "8,8")]) |
68944452 | 1210 | |
520babc7 JL |
1211 | (define_insn "umaxdi3" |
1212 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
1213 | (umax:DI (match_operand:DI 1 "register_operand" "%0,0") | |
1214 | (match_operand:DI 2 "arith11_operand" "r,I")))] | |
1215 | "TARGET_64BIT" | |
1216 | "@ | |
1217 | cmpclr,*<< %2,%0,%%r0\;copy %2,%0 | |
1218 | cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0" | |
1219 | [(set_attr "type" "multi,multi") | |
1220 | (set_attr "length" "8,8")]) | |
1221 | ||
68944452 JL |
1222 | (define_insn "abssi2" |
1223 | [(set (match_operand:SI 0 "register_operand" "=r") | |
77c87273 | 1224 | (abs:SI (match_operand:SI 1 "register_operand" "r")))] |
68944452 | 1225 | "" |
15838c69 | 1226 | "or,>= %%r0,%1,%0\;subi 0,%0,%0" |
68944452 JL |
1227 | [(set_attr "type" "multi") |
1228 | (set_attr "length" "8")]) | |
1229 | ||
520babc7 JL |
1230 | (define_insn "absdi2" |
1231 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1232 | (abs:DI (match_operand:DI 1 "register_operand" "r")))] | |
1233 | "TARGET_64BIT" | |
1234 | "or,*>= %%r0,%1,%0\;subi 0,%0,%0" | |
1235 | [(set_attr "type" "multi") | |
1236 | (set_attr "length" "8")]) | |
1237 | ||
78878730 | 1238 | ;;; Experimental conditional move patterns |
ac153498 | 1239 | |
014a4565 JL |
1240 | (define_expand "movsicc" |
1241 | [(set (match_operand:SI 0 "register_operand" "") | |
1242 | (if_then_else:SI | |
1243 | (match_operator 1 "comparison_operator" | |
549fd8ff RK |
1244 | [(match_dup 4) |
1245 | (match_dup 5)]) | |
014a4565 JL |
1246 | (match_operand:SI 2 "reg_or_cint_move_operand" "") |
1247 | (match_operand:SI 3 "reg_or_cint_move_operand" "")))] | |
1248 | "" | |
1249 | " | |
1250 | { | |
1251 | enum rtx_code code = GET_CODE (operands[1]); | |
1252 | ||
1253 | if (hppa_branch_type != CMP_SI) | |
1254 | FAIL; | |
1255 | ||
520babc7 JL |
1256 | if (GET_MODE (hppa_compare_op0) != GET_MODE (hppa_compare_op1) |
1257 | || GET_MODE (hppa_compare_op0) != GET_MODE (operands[0])) | |
1258 | FAIL; | |
1259 | ||
014a4565 JL |
1260 | /* operands[1] is currently the result of compare_from_rtx. We want to |
1261 | emit a compare of the original operands. */ | |
ad2c71b7 | 1262 | operands[1] = gen_rtx_fmt_ee (code, SImode, hppa_compare_op0, hppa_compare_op1); |
014a4565 JL |
1263 | operands[4] = hppa_compare_op0; |
1264 | operands[5] = hppa_compare_op1; | |
1265 | }") | |
1266 | ||
b1f10727 JL |
1267 | ;; We used to accept any register for op1. |
1268 | ;; | |
1269 | ;; However, it loses sometimes because the compiler will end up using | |
1270 | ;; different registers for op0 and op1 in some critical cases. local-alloc | |
1271 | ;; will not tie op0 and op1 because op0 is used in multiple basic blocks. | |
1272 | ;; | |
1273 | ;; If/when global register allocation supports tying we should allow any | |
1274 | ;; register for op1 again. | |
78878730 | 1275 | (define_insn "" |
b1f10727 | 1276 | [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") |
78878730 | 1277 | (if_then_else:SI |
15c2086a | 1278 | (match_operator 2 "comparison_operator" |
b1f10727 JL |
1279 | [(match_operand:SI 3 "register_operand" "r,r,r,r") |
1280 | (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")]) | |
1281 | (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K") | |
78878730 TG |
1282 | (const_int 0)))] |
1283 | "" | |
1284 | "@ | |
15c2086a JL |
1285 | {com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0 |
1286 | {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0 | |
1287 | {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0 | |
1288 | {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0" | |
b1f10727 JL |
1289 | [(set_attr "type" "multi,multi,multi,nullshift") |
1290 | (set_attr "length" "8,8,8,8")]) | |
78878730 TG |
1291 | |
1292 | (define_insn "" | |
1293 | [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r") | |
202571cd | 1294 | (if_then_else:SI |
ac153498 | 1295 | (match_operator 5 "comparison_operator" |
78878730 TG |
1296 | [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r") |
1297 | (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")]) | |
1298 | (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K") | |
1299 | (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))] | |
ac153498 | 1300 | "" |
202571cd | 1301 | "@ |
f38b27c7 JL |
1302 | {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0 |
1303 | {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0 | |
1304 | {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0 | |
1305 | {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0 | |
1306 | {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0 | |
1307 | {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0 | |
1308 | {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0 | |
1309 | {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0" | |
c47decad | 1310 | [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift") |
4c2164b7 | 1311 | (set_attr "length" "8,8,8,8,8,8,8,8")]) |
ac153498 | 1312 | |
520babc7 JL |
1313 | (define_expand "movdicc" |
1314 | [(set (match_operand:DI 0 "register_operand" "") | |
1315 | (if_then_else:DI | |
1316 | (match_operator 1 "comparison_operator" | |
1317 | [(match_dup 4) | |
1318 | (match_dup 5)]) | |
1319 | (match_operand:DI 2 "reg_or_cint_move_operand" "") | |
1320 | (match_operand:DI 3 "reg_or_cint_move_operand" "")))] | |
1321 | "TARGET_64BIT" | |
1322 | " | |
1323 | { | |
1324 | enum rtx_code code = GET_CODE (operands[1]); | |
1325 | ||
1326 | if (hppa_branch_type != CMP_SI) | |
1327 | FAIL; | |
1328 | ||
1329 | if (GET_MODE (hppa_compare_op0) != GET_MODE (hppa_compare_op1) | |
1330 | || GET_MODE (hppa_compare_op0) != GET_MODE (operands[0])) | |
1331 | FAIL; | |
1332 | ||
1333 | /* operands[1] is currently the result of compare_from_rtx. We want to | |
1334 | emit a compare of the original operands. */ | |
1335 | operands[1] = gen_rtx_fmt_ee (code, DImode, hppa_compare_op0, hppa_compare_op1); | |
1336 | operands[4] = hppa_compare_op0; | |
1337 | operands[5] = hppa_compare_op1; | |
1338 | }") | |
1339 | ||
1340 | ; We need the first constraint alternative in order to avoid | |
1341 | ; earlyclobbers on all other alternatives. | |
1342 | (define_insn "" | |
1343 | [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r") | |
1344 | (if_then_else:DI | |
15c2086a | 1345 | (match_operator 2 "comparison_operator" |
520babc7 JL |
1346 | [(match_operand:DI 3 "register_operand" "r,r,r,r,r") |
1347 | (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")]) | |
1348 | (match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K") | |
1349 | (const_int 0)))] | |
1350 | "TARGET_64BIT" | |
1351 | "@ | |
15c2086a JL |
1352 | cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0 |
1353 | cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0 | |
1354 | cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0 | |
1355 | cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0 | |
1356 | cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0" | |
520babc7 JL |
1357 | [(set_attr "type" "multi,multi,multi,multi,nullshift") |
1358 | (set_attr "length" "8,8,8,8,8")]) | |
1359 | ||
1360 | (define_insn "" | |
1361 | [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r") | |
1362 | (if_then_else:DI | |
1363 | (match_operator 5 "comparison_operator" | |
1364 | [(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r") | |
1365 | (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")]) | |
1366 | (match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K") | |
1367 | (match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))] | |
1368 | "TARGET_64BIT" | |
1369 | "@ | |
1370 | cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0 | |
1371 | cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0 | |
1372 | cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0 | |
1373 | cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0 | |
1374 | cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0 | |
1375 | cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0 | |
1376 | cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0 | |
1377 | cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0" | |
1378 | [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift") | |
1379 | (set_attr "length" "8,8,8,8,8,8,8,8")]) | |
1380 | ||
ac153498 | 1381 | ;; Conditional Branches |
c733e074 TM |
1382 | |
1383 | (define_expand "beq" | |
1384 | [(set (pc) | |
1385 | (if_then_else (eq (match_dup 1) (match_dup 2)) | |
1386 | (label_ref (match_operand 0 "" "")) | |
1387 | (pc)))] | |
1388 | "" | |
1389 | " | |
1390 | { | |
1391 | if (hppa_branch_type != CMP_SI) | |
1392 | { | |
1393 | emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1)); | |
1394 | emit_bcond_fp (NE, operands[0]); | |
1395 | DONE; | |
1396 | } | |
1397 | /* set up operands from compare. */ | |
1398 | operands[1] = hppa_compare_op0; | |
1399 | operands[2] = hppa_compare_op1; | |
1400 | /* fall through and generate default code */ | |
1401 | }") | |
1402 | ||
1403 | (define_expand "bne" | |
1404 | [(set (pc) | |
1405 | (if_then_else (ne (match_dup 1) (match_dup 2)) | |
1406 | (label_ref (match_operand 0 "" "")) | |
1407 | (pc)))] | |
1408 | "" | |
1409 | " | |
1410 | { | |
1411 | if (hppa_branch_type != CMP_SI) | |
1412 | { | |
1413 | emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1)); | |
1414 | emit_bcond_fp (NE, operands[0]); | |
1415 | DONE; | |
1416 | } | |
1417 | operands[1] = hppa_compare_op0; | |
1418 | operands[2] = hppa_compare_op1; | |
1419 | }") | |
1420 | ||
1421 | (define_expand "bgt" | |
1422 | [(set (pc) | |
1423 | (if_then_else (gt (match_dup 1) (match_dup 2)) | |
1424 | (label_ref (match_operand 0 "" "")) | |
1425 | (pc)))] | |
1426 | "" | |
1427 | " | |
1428 | { | |
1429 | if (hppa_branch_type != CMP_SI) | |
1430 | { | |
1431 | emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1)); | |
1432 | emit_bcond_fp (NE, operands[0]); | |
1433 | DONE; | |
1434 | } | |
1435 | operands[1] = hppa_compare_op0; | |
1436 | operands[2] = hppa_compare_op1; | |
1437 | }") | |
1438 | ||
1439 | (define_expand "blt" | |
1440 | [(set (pc) | |
1441 | (if_then_else (lt (match_dup 1) (match_dup 2)) | |
1442 | (label_ref (match_operand 0 "" "")) | |
1443 | (pc)))] | |
1444 | "" | |
1445 | " | |
1446 | { | |
1447 | if (hppa_branch_type != CMP_SI) | |
1448 | { | |
1449 | emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1)); | |
1450 | emit_bcond_fp (NE, operands[0]); | |
1451 | DONE; | |
1452 | } | |
1453 | operands[1] = hppa_compare_op0; | |
1454 | operands[2] = hppa_compare_op1; | |
1455 | }") | |
1456 | ||
1457 | (define_expand "bge" | |
1458 | [(set (pc) | |
1459 | (if_then_else (ge (match_dup 1) (match_dup 2)) | |
1460 | (label_ref (match_operand 0 "" "")) | |
1461 | (pc)))] | |
1462 | "" | |
1463 | " | |
1464 | { | |
1465 | if (hppa_branch_type != CMP_SI) | |
1466 | { | |
1467 | emit_insn (gen_cmp_fp (GE, hppa_compare_op0, hppa_compare_op1)); | |
1468 | emit_bcond_fp (NE, operands[0]); | |
1469 | DONE; | |
1470 | } | |
1471 | operands[1] = hppa_compare_op0; | |
1472 | operands[2] = hppa_compare_op1; | |
1473 | }") | |
1474 | ||
1475 | (define_expand "ble" | |
1476 | [(set (pc) | |
1477 | (if_then_else (le (match_dup 1) (match_dup 2)) | |
1478 | (label_ref (match_operand 0 "" "")) | |
1479 | (pc)))] | |
1480 | "" | |
1481 | " | |
1482 | { | |
1483 | if (hppa_branch_type != CMP_SI) | |
1484 | { | |
1485 | emit_insn (gen_cmp_fp (LE, hppa_compare_op0, hppa_compare_op1)); | |
1486 | emit_bcond_fp (NE, operands[0]); | |
1487 | DONE; | |
1488 | } | |
1489 | operands[1] = hppa_compare_op0; | |
1490 | operands[2] = hppa_compare_op1; | |
1491 | }") | |
1492 | ||
1493 | (define_expand "bgtu" | |
1494 | [(set (pc) | |
1495 | (if_then_else (gtu (match_dup 1) (match_dup 2)) | |
1496 | (label_ref (match_operand 0 "" "")) | |
1497 | (pc)))] | |
1498 | "" | |
1499 | " | |
1500 | { | |
1501 | if (hppa_branch_type != CMP_SI) | |
1502 | FAIL; | |
1503 | operands[1] = hppa_compare_op0; | |
1504 | operands[2] = hppa_compare_op1; | |
1505 | }") | |
1506 | ||
1507 | (define_expand "bltu" | |
1508 | [(set (pc) | |
1509 | (if_then_else (ltu (match_dup 1) (match_dup 2)) | |
1510 | (label_ref (match_operand 0 "" "")) | |
1511 | (pc)))] | |
1512 | "" | |
1513 | " | |
1514 | { | |
1515 | if (hppa_branch_type != CMP_SI) | |
1516 | FAIL; | |
1517 | operands[1] = hppa_compare_op0; | |
1518 | operands[2] = hppa_compare_op1; | |
1519 | }") | |
1520 | ||
1521 | (define_expand "bgeu" | |
1522 | [(set (pc) | |
1523 | (if_then_else (geu (match_dup 1) (match_dup 2)) | |
1524 | (label_ref (match_operand 0 "" "")) | |
1525 | (pc)))] | |
1526 | "" | |
1527 | " | |
1528 | { | |
1529 | if (hppa_branch_type != CMP_SI) | |
1530 | FAIL; | |
1531 | operands[1] = hppa_compare_op0; | |
1532 | operands[2] = hppa_compare_op1; | |
1533 | }") | |
1534 | ||
1535 | (define_expand "bleu" | |
1536 | [(set (pc) | |
1537 | (if_then_else (leu (match_dup 1) (match_dup 2)) | |
1538 | (label_ref (match_operand 0 "" "")) | |
1539 | (pc)))] | |
1540 | "" | |
1541 | " | |
1542 | { | |
1543 | if (hppa_branch_type != CMP_SI) | |
1544 | FAIL; | |
1545 | operands[1] = hppa_compare_op0; | |
1546 | operands[2] = hppa_compare_op1; | |
1547 | }") | |
1548 | ||
becf1647 DA |
1549 | (define_expand "bltgt" |
1550 | [(set (pc) | |
1551 | (if_then_else (ltgt (match_dup 1) (match_dup 2)) | |
1552 | (label_ref (match_operand 0 "" "")) | |
1553 | (pc)))] | |
1554 | "" | |
1555 | " | |
1556 | { | |
1557 | if (hppa_branch_type == CMP_SI) | |
1558 | FAIL; | |
1559 | emit_insn (gen_cmp_fp (LTGT, hppa_compare_op0, hppa_compare_op1)); | |
1560 | emit_bcond_fp (NE, operands[0]); | |
1561 | DONE; | |
1562 | }") | |
1563 | ||
1564 | (define_expand "bunle" | |
1565 | [(set (pc) | |
1566 | (if_then_else (unle (match_dup 1) (match_dup 2)) | |
1567 | (label_ref (match_operand 0 "" "")) | |
1568 | (pc)))] | |
1569 | "" | |
1570 | " | |
1571 | { | |
1572 | if (hppa_branch_type == CMP_SI) | |
1573 | FAIL; | |
1574 | emit_insn (gen_cmp_fp (UNLE, hppa_compare_op0, hppa_compare_op1)); | |
1575 | emit_bcond_fp (NE, operands[0]); | |
1576 | DONE; | |
1577 | }") | |
1578 | ||
1579 | (define_expand "bunlt" | |
1580 | [(set (pc) | |
1581 | (if_then_else (unlt (match_dup 1) (match_dup 2)) | |
1582 | (label_ref (match_operand 0 "" "")) | |
1583 | (pc)))] | |
1584 | "" | |
1585 | " | |
1586 | { | |
1587 | if (hppa_branch_type == CMP_SI) | |
1588 | FAIL; | |
1589 | emit_insn (gen_cmp_fp (UNLT, hppa_compare_op0, hppa_compare_op1)); | |
1590 | emit_bcond_fp (NE, operands[0]); | |
1591 | DONE; | |
1592 | }") | |
1593 | ||
1594 | (define_expand "bunge" | |
1595 | [(set (pc) | |
1596 | (if_then_else (unge (match_dup 1) (match_dup 2)) | |
1597 | (label_ref (match_operand 0 "" "")) | |
1598 | (pc)))] | |
1599 | "" | |
1600 | " | |
1601 | { | |
1602 | if (hppa_branch_type == CMP_SI) | |
1603 | FAIL; | |
1604 | emit_insn (gen_cmp_fp (UNGE, hppa_compare_op0, hppa_compare_op1)); | |
1605 | emit_bcond_fp (NE, operands[0]); | |
1606 | DONE; | |
1607 | }") | |
1608 | ||
1609 | (define_expand "bungt" | |
1610 | [(set (pc) | |
1611 | (if_then_else (ungt (match_dup 1) (match_dup 2)) | |
1612 | (label_ref (match_operand 0 "" "")) | |
1613 | (pc)))] | |
1614 | "" | |
1615 | " | |
1616 | { | |
1617 | if (hppa_branch_type == CMP_SI) | |
1618 | FAIL; | |
1619 | emit_insn (gen_cmp_fp (UNGT, hppa_compare_op0, hppa_compare_op1)); | |
1620 | emit_bcond_fp (NE, operands[0]); | |
1621 | DONE; | |
1622 | }") | |
1623 | ||
1624 | (define_expand "buneq" | |
1625 | [(set (pc) | |
1626 | (if_then_else (uneq (match_dup 1) (match_dup 2)) | |
1627 | (label_ref (match_operand 0 "" "")) | |
1628 | (pc)))] | |
1629 | "" | |
1630 | " | |
1631 | { | |
1632 | if (hppa_branch_type == CMP_SI) | |
1633 | FAIL; | |
1634 | emit_insn (gen_cmp_fp (UNEQ, hppa_compare_op0, hppa_compare_op1)); | |
1635 | emit_bcond_fp (NE, operands[0]); | |
1636 | DONE; | |
1637 | }") | |
1638 | ||
1639 | (define_expand "bunordered" | |
1640 | [(set (pc) | |
1641 | (if_then_else (unordered (match_dup 1) (match_dup 2)) | |
1642 | (label_ref (match_operand 0 "" "")) | |
1643 | (pc)))] | |
1644 | "" | |
1645 | " | |
1646 | { | |
1647 | if (hppa_branch_type == CMP_SI) | |
1648 | FAIL; | |
1649 | emit_insn (gen_cmp_fp (UNORDERED, hppa_compare_op0, hppa_compare_op1)); | |
1650 | emit_bcond_fp (NE, operands[0]); | |
1651 | DONE; | |
1652 | }") | |
1653 | ||
1654 | (define_expand "bordered" | |
1655 | [(set (pc) | |
1656 | (if_then_else (ordered (match_dup 1) (match_dup 2)) | |
1657 | (label_ref (match_operand 0 "" "")) | |
1658 | (pc)))] | |
1659 | "" | |
1660 | " | |
1661 | { | |
1662 | if (hppa_branch_type == CMP_SI) | |
1663 | FAIL; | |
1664 | emit_insn (gen_cmp_fp (ORDERED, hppa_compare_op0, hppa_compare_op1)); | |
1665 | emit_bcond_fp (NE, operands[0]); | |
1666 | DONE; | |
1667 | }") | |
1668 | ||
c733e074 TM |
1669 | ;; Match the branch patterns. |
1670 | ||
99457156 JL |
1671 | |
1672 | ;; Note a long backward conditional branch with an annulled delay slot | |
2f95ebc2 | 1673 | ;; has a length of 12. |
c733e074 TM |
1674 | (define_insn "" |
1675 | [(set (pc) | |
1676 | (if_then_else | |
1677 | (match_operator 3 "comparison_operator" | |
dcaeffef | 1678 | [(match_operand:SI 1 "reg_or_0_operand" "rM") |
2bc0b543 | 1679 | (match_operand:SI 2 "arith5_operand" "rL")]) |
c733e074 TM |
1680 | (label_ref (match_operand 0 "" "")) |
1681 | (pc)))] | |
1682 | "" | |
1683 | "* | |
1684 | { | |
2f95ebc2 | 1685 | return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), |
99457156 | 1686 | get_attr_length (insn), 0, insn); |
c733e074 | 1687 | }" |
99457156 | 1688 | [(set_attr "type" "cbranch") |
2f95ebc2 | 1689 | (set (attr "length") |
4bcb9e3f JL |
1690 | (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) |
1691 | (const_int 8184)) | |
1692 | (const_int 4) | |
1693 | (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) | |
1694 | (const_int 262100)) | |
1695 | (const_int 8) | |
1696 | (eq (symbol_ref "flag_pic") (const_int 0)) | |
1697 | (const_int 20)] | |
1698 | (const_int 28)))]) | |
c733e074 TM |
1699 | |
1700 | ;; Match the negated branch. | |
1701 | ||
1702 | (define_insn "" | |
1703 | [(set (pc) | |
1704 | (if_then_else | |
1705 | (match_operator 3 "comparison_operator" | |
dcaeffef | 1706 | [(match_operand:SI 1 "reg_or_0_operand" "rM") |
2bc0b543 | 1707 | (match_operand:SI 2 "arith5_operand" "rL")]) |
c733e074 TM |
1708 | (pc) |
1709 | (label_ref (match_operand 0 "" ""))))] | |
1710 | "" | |
1711 | "* | |
1712 | { | |
2f95ebc2 | 1713 | return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), |
99457156 | 1714 | get_attr_length (insn), 1, insn); |
c733e074 | 1715 | }" |
99457156 | 1716 | [(set_attr "type" "cbranch") |
2f95ebc2 | 1717 | (set (attr "length") |
4bcb9e3f JL |
1718 | (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) |
1719 | (const_int 8184)) | |
1720 | (const_int 4) | |
1721 | (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) | |
1722 | (const_int 262100)) | |
1723 | (const_int 8) | |
1724 | (eq (symbol_ref "flag_pic") (const_int 0)) | |
1725 | (const_int 20)] | |
1726 | (const_int 28)))]) | |
99457156 | 1727 | |
520babc7 JL |
1728 | (define_insn "" |
1729 | [(set (pc) | |
1730 | (if_then_else | |
1731 | (match_operator 3 "comparison_operator" | |
1732 | [(match_operand:DI 1 "reg_or_0_operand" "rM") | |
1733 | (match_operand:DI 2 "reg_or_0_operand" "rM")]) | |
1734 | (label_ref (match_operand 0 "" "")) | |
1735 | (pc)))] | |
1736 | "TARGET_64BIT" | |
1737 | "* | |
1738 | { | |
1739 | return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), | |
1740 | get_attr_length (insn), 0, insn); | |
1741 | }" | |
1742 | [(set_attr "type" "cbranch") | |
1743 | (set (attr "length") | |
1744 | (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) | |
1745 | (const_int 8184)) | |
1746 | (const_int 4) | |
1747 | (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) | |
1748 | (const_int 262100)) | |
1749 | (const_int 8) | |
1750 | (eq (symbol_ref "flag_pic") (const_int 0)) | |
1751 | (const_int 20)] | |
1752 | (const_int 28)))]) | |
1753 | ||
1754 | ;; Match the negated branch. | |
1755 | ||
1756 | (define_insn "" | |
1757 | [(set (pc) | |
1758 | (if_then_else | |
1759 | (match_operator 3 "comparison_operator" | |
1760 | [(match_operand:DI 1 "reg_or_0_operand" "rM") | |
1761 | (match_operand:DI 2 "reg_or_0_operand" "rM")]) | |
1762 | (pc) | |
1763 | (label_ref (match_operand 0 "" ""))))] | |
1764 | "TARGET_64BIT" | |
1765 | "* | |
1766 | { | |
1767 | return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), | |
1768 | get_attr_length (insn), 1, insn); | |
1769 | }" | |
1770 | [(set_attr "type" "cbranch") | |
1771 | (set (attr "length") | |
1772 | (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) | |
1773 | (const_int 8184)) | |
1774 | (const_int 4) | |
1775 | (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) | |
1776 | (const_int 262100)) | |
1777 | (const_int 8) | |
1778 | (eq (symbol_ref "flag_pic") (const_int 0)) | |
1779 | (const_int 20)] | |
1780 | (const_int 28)))]) | |
1781 | (define_insn "" | |
1782 | [(set (pc) | |
1783 | (if_then_else | |
1784 | (match_operator 3 "cmpib_comparison_operator" | |
1785 | [(match_operand:DI 1 "reg_or_0_operand" "rM") | |
1786 | (match_operand:DI 2 "arith5_operand" "rL")]) | |
1787 | (label_ref (match_operand 0 "" "")) | |
1788 | (pc)))] | |
1789 | "TARGET_64BIT" | |
1790 | "* | |
1791 | { | |
1792 | return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), | |
1793 | get_attr_length (insn), 0, insn); | |
1794 | }" | |
1795 | [(set_attr "type" "cbranch") | |
1796 | (set (attr "length") | |
1797 | (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) | |
1798 | (const_int 8184)) | |
1799 | (const_int 4) | |
1800 | (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) | |
1801 | (const_int 262100)) | |
1802 | (const_int 8) | |
1803 | (eq (symbol_ref "flag_pic") (const_int 0)) | |
1804 | (const_int 20)] | |
1805 | (const_int 28)))]) | |
1806 | ||
1807 | ;; Match the negated branch. | |
1808 | ||
1809 | (define_insn "" | |
1810 | [(set (pc) | |
1811 | (if_then_else | |
1812 | (match_operator 3 "cmpib_comparison_operator" | |
1813 | [(match_operand:DI 1 "reg_or_0_operand" "rM") | |
1814 | (match_operand:DI 2 "arith5_operand" "rL")]) | |
1815 | (pc) | |
1816 | (label_ref (match_operand 0 "" ""))))] | |
1817 | "TARGET_64BIT" | |
1818 | "* | |
1819 | { | |
1820 | return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), | |
1821 | get_attr_length (insn), 1, insn); | |
1822 | }" | |
1823 | [(set_attr "type" "cbranch") | |
1824 | (set (attr "length") | |
1825 | (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) | |
1826 | (const_int 8184)) | |
1827 | (const_int 4) | |
1828 | (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) | |
1829 | (const_int 262100)) | |
1830 | (const_int 8) | |
1831 | (eq (symbol_ref "flag_pic") (const_int 0)) | |
1832 | (const_int 20)] | |
1833 | (const_int 28)))]) | |
1834 | ||
99457156 | 1835 | ;; Branch on Bit patterns. |
e19ee659 TG |
1836 | (define_insn "" |
1837 | [(set (pc) | |
1838 | (if_then_else | |
1839 | (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") | |
1840 | (const_int 1) | |
1841 | (match_operand:SI 1 "uint5_operand" "")) | |
1842 | (const_int 0)) | |
ff0a4409 JL |
1843 | (label_ref (match_operand 2 "" "")) |
1844 | (pc)))] | |
e19ee659 TG |
1845 | "" |
1846 | "* | |
1847 | { | |
2f95ebc2 | 1848 | return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), |
ff0a4409 | 1849 | get_attr_length (insn), 0, insn, 0); |
e19ee659 | 1850 | }" |
99457156 | 1851 | [(set_attr "type" "cbranch") |
2f95ebc2 | 1852 | (set (attr "length") |
ff0a4409 | 1853 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) |
6a73009d | 1854 | (const_int 8184)) |
ff0a4409 JL |
1855 | (const_int 4) |
1856 | (const_int 8)))]) | |
1857 | ||
520babc7 JL |
1858 | (define_insn "" |
1859 | [(set (pc) | |
1860 | (if_then_else | |
1861 | (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r") | |
1862 | (const_int 1) | |
1863 | (match_operand:DI 1 "uint32_operand" "")) | |
1864 | (const_int 0)) | |
1865 | (label_ref (match_operand 2 "" "")) | |
1866 | (pc)))] | |
1867 | "TARGET_64BIT" | |
1868 | "* | |
1869 | { | |
1870 | return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
1871 | get_attr_length (insn), 0, insn, 0); | |
1872 | }" | |
1873 | [(set_attr "type" "cbranch") | |
1874 | (set (attr "length") | |
1875 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
1876 | (const_int 8184)) | |
1877 | (const_int 4) | |
1878 | (const_int 8)))]) | |
1879 | ||
ff0a4409 JL |
1880 | (define_insn "" |
1881 | [(set (pc) | |
1882 | (if_then_else | |
1883 | (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") | |
1884 | (const_int 1) | |
1885 | (match_operand:SI 1 "uint5_operand" "")) | |
1886 | (const_int 0)) | |
1887 | (pc) | |
1888 | (label_ref (match_operand 2 "" ""))))] | |
1889 | "" | |
1890 | "* | |
1891 | { | |
1892 | return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
1893 | get_attr_length (insn), 1, insn, 0); | |
1894 | }" | |
1895 | [(set_attr "type" "cbranch") | |
1896 | (set (attr "length") | |
1897 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
6a73009d | 1898 | (const_int 8184)) |
4c2164b7 JL |
1899 | (const_int 4) |
1900 | (const_int 8)))]) | |
e19ee659 | 1901 | |
520babc7 JL |
1902 | (define_insn "" |
1903 | [(set (pc) | |
1904 | (if_then_else | |
1905 | (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r") | |
1906 | (const_int 1) | |
1907 | (match_operand:DI 1 "uint32_operand" "")) | |
1908 | (const_int 0)) | |
1909 | (pc) | |
1910 | (label_ref (match_operand 2 "" ""))))] | |
1911 | "TARGET_64BIT" | |
1912 | "* | |
1913 | { | |
1914 | return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
1915 | get_attr_length (insn), 1, insn, 0); | |
1916 | }" | |
1917 | [(set_attr "type" "cbranch") | |
1918 | (set (attr "length") | |
1919 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
1920 | (const_int 8184)) | |
1921 | (const_int 4) | |
1922 | (const_int 8)))]) | |
1923 | ||
e19ee659 TG |
1924 | (define_insn "" |
1925 | [(set (pc) | |
1926 | (if_then_else | |
1927 | (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") | |
1928 | (const_int 1) | |
1929 | (match_operand:SI 1 "uint5_operand" "")) | |
1930 | (const_int 0)) | |
ff0a4409 JL |
1931 | (label_ref (match_operand 2 "" "")) |
1932 | (pc)))] | |
e19ee659 TG |
1933 | "" |
1934 | "* | |
1935 | { | |
2f95ebc2 | 1936 | return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), |
ff0a4409 | 1937 | get_attr_length (insn), 0, insn, 1); |
e19ee659 | 1938 | }" |
99457156 | 1939 | [(set_attr "type" "cbranch") |
2f95ebc2 | 1940 | (set (attr "length") |
ff0a4409 | 1941 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) |
6a73009d | 1942 | (const_int 8184)) |
ff0a4409 JL |
1943 | (const_int 4) |
1944 | (const_int 8)))]) | |
1945 | ||
520babc7 JL |
1946 | (define_insn "" |
1947 | [(set (pc) | |
1948 | (if_then_else | |
1949 | (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r") | |
1950 | (const_int 1) | |
1951 | (match_operand:DI 1 "uint32_operand" "")) | |
1952 | (const_int 0)) | |
1953 | (label_ref (match_operand 2 "" "")) | |
1954 | (pc)))] | |
1955 | "TARGET_64BIT" | |
1956 | "* | |
1957 | { | |
1958 | return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
1959 | get_attr_length (insn), 0, insn, 1); | |
1960 | }" | |
1961 | [(set_attr "type" "cbranch") | |
1962 | (set (attr "length") | |
1963 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
1964 | (const_int 8184)) | |
1965 | (const_int 4) | |
1966 | (const_int 8)))]) | |
1967 | ||
ff0a4409 JL |
1968 | (define_insn "" |
1969 | [(set (pc) | |
1970 | (if_then_else | |
1971 | (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") | |
1972 | (const_int 1) | |
1973 | (match_operand:SI 1 "uint5_operand" "")) | |
1974 | (const_int 0)) | |
1975 | (pc) | |
1976 | (label_ref (match_operand 2 "" ""))))] | |
1977 | "" | |
1978 | "* | |
1979 | { | |
1980 | return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
1981 | get_attr_length (insn), 1, insn, 1); | |
1982 | }" | |
1983 | [(set_attr "type" "cbranch") | |
1984 | (set (attr "length") | |
1985 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
6a73009d JL |
1986 | (const_int 8184)) |
1987 | (const_int 4) | |
1988 | (const_int 8)))]) | |
1989 | ||
520babc7 JL |
1990 | (define_insn "" |
1991 | [(set (pc) | |
1992 | (if_then_else | |
1993 | (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r") | |
1994 | (const_int 1) | |
1995 | (match_operand:DI 1 "uint32_operand" "")) | |
1996 | (const_int 0)) | |
1997 | (pc) | |
1998 | (label_ref (match_operand 2 "" ""))))] | |
1999 | "TARGET_64BIT" | |
2000 | "* | |
2001 | { | |
2002 | return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
2003 | get_attr_length (insn), 1, insn, 1); | |
2004 | }" | |
2005 | [(set_attr "type" "cbranch") | |
2006 | (set (attr "length") | |
2007 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
2008 | (const_int 8184)) | |
2009 | (const_int 4) | |
2010 | (const_int 8)))]) | |
2011 | ||
6a73009d JL |
2012 | ;; Branch on Variable Bit patterns. |
2013 | (define_insn "" | |
2014 | [(set (pc) | |
2015 | (if_then_else | |
2016 | (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") | |
2017 | (const_int 1) | |
2018 | (match_operand:SI 1 "register_operand" "q")) | |
2019 | (const_int 0)) | |
2020 | (label_ref (match_operand 2 "" "")) | |
2021 | (pc)))] | |
2022 | "" | |
2023 | "* | |
2024 | { | |
2025 | return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
2026 | get_attr_length (insn), 0, insn, 0); | |
2027 | }" | |
2028 | [(set_attr "type" "cbranch") | |
2029 | (set (attr "length") | |
2030 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
2031 | (const_int 8184)) | |
2032 | (const_int 4) | |
2033 | (const_int 8)))]) | |
2034 | ||
520babc7 JL |
2035 | (define_insn "" |
2036 | [(set (pc) | |
2037 | (if_then_else | |
2038 | (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r") | |
2039 | (const_int 1) | |
2040 | (match_operand:DI 1 "register_operand" "q")) | |
2041 | (const_int 0)) | |
2042 | (label_ref (match_operand 2 "" "")) | |
2043 | (pc)))] | |
2044 | "TARGET_64BIT" | |
2045 | "* | |
2046 | { | |
2047 | return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
2048 | get_attr_length (insn), 0, insn, 0); | |
2049 | }" | |
2050 | [(set_attr "type" "cbranch") | |
2051 | (set (attr "length") | |
2052 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
2053 | (const_int 8184)) | |
2054 | (const_int 4) | |
2055 | (const_int 8)))]) | |
2056 | ||
6a73009d JL |
2057 | (define_insn "" |
2058 | [(set (pc) | |
2059 | (if_then_else | |
2060 | (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") | |
2061 | (const_int 1) | |
2062 | (match_operand:SI 1 "register_operand" "q")) | |
2063 | (const_int 0)) | |
2064 | (pc) | |
2065 | (label_ref (match_operand 2 "" ""))))] | |
2066 | "" | |
2067 | "* | |
2068 | { | |
2069 | return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
2070 | get_attr_length (insn), 1, insn, 0); | |
2071 | }" | |
2072 | [(set_attr "type" "cbranch") | |
2073 | (set (attr "length") | |
2074 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
2075 | (const_int 8184)) | |
2076 | (const_int 4) | |
2077 | (const_int 8)))]) | |
2078 | ||
520babc7 JL |
2079 | (define_insn "" |
2080 | [(set (pc) | |
2081 | (if_then_else | |
2082 | (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r") | |
2083 | (const_int 1) | |
2084 | (match_operand:DI 1 "register_operand" "q")) | |
2085 | (const_int 0)) | |
2086 | (pc) | |
2087 | (label_ref (match_operand 2 "" ""))))] | |
2088 | "TARGET_64BIT" | |
2089 | "* | |
2090 | { | |
2091 | return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
2092 | get_attr_length (insn), 1, insn, 0); | |
2093 | }" | |
2094 | [(set_attr "type" "cbranch") | |
2095 | (set (attr "length") | |
2096 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
2097 | (const_int 8184)) | |
2098 | (const_int 4) | |
2099 | (const_int 8)))]) | |
2100 | ||
6a73009d JL |
2101 | (define_insn "" |
2102 | [(set (pc) | |
2103 | (if_then_else | |
2104 | (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") | |
2105 | (const_int 1) | |
2106 | (match_operand:SI 1 "register_operand" "q")) | |
2107 | (const_int 0)) | |
2108 | (label_ref (match_operand 2 "" "")) | |
2109 | (pc)))] | |
2110 | "" | |
2111 | "* | |
2112 | { | |
2113 | return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
2114 | get_attr_length (insn), 0, insn, 1); | |
2115 | }" | |
2116 | [(set_attr "type" "cbranch") | |
2117 | (set (attr "length") | |
2118 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
2119 | (const_int 8184)) | |
2120 | (const_int 4) | |
2121 | (const_int 8)))]) | |
2122 | ||
520babc7 JL |
2123 | (define_insn "" |
2124 | [(set (pc) | |
2125 | (if_then_else | |
2126 | (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r") | |
2127 | (const_int 1) | |
2128 | (match_operand:DI 1 "register_operand" "q")) | |
2129 | (const_int 0)) | |
2130 | (label_ref (match_operand 2 "" "")) | |
2131 | (pc)))] | |
2132 | "TARGET_64BIT" | |
2133 | "* | |
2134 | { | |
2135 | return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
2136 | get_attr_length (insn), 0, insn, 1); | |
2137 | }" | |
2138 | [(set_attr "type" "cbranch") | |
2139 | (set (attr "length") | |
2140 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
2141 | (const_int 8184)) | |
2142 | (const_int 4) | |
2143 | (const_int 8)))]) | |
2144 | ||
6a73009d JL |
2145 | (define_insn "" |
2146 | [(set (pc) | |
2147 | (if_then_else | |
2148 | (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") | |
2149 | (const_int 1) | |
2150 | (match_operand:SI 1 "register_operand" "q")) | |
2151 | (const_int 0)) | |
2152 | (pc) | |
2153 | (label_ref (match_operand 2 "" ""))))] | |
2154 | "" | |
2155 | "* | |
2156 | { | |
2157 | return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
2158 | get_attr_length (insn), 1, insn, 1); | |
2159 | }" | |
2160 | [(set_attr "type" "cbranch") | |
2161 | (set (attr "length") | |
2162 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
2163 | (const_int 8184)) | |
4c2164b7 JL |
2164 | (const_int 4) |
2165 | (const_int 8)))]) | |
99457156 | 2166 | |
520babc7 JL |
2167 | (define_insn "" |
2168 | [(set (pc) | |
2169 | (if_then_else | |
2170 | (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r") | |
2171 | (const_int 1) | |
2172 | (match_operand:DI 1 "register_operand" "q")) | |
2173 | (const_int 0)) | |
2174 | (pc) | |
2175 | (label_ref (match_operand 2 "" ""))))] | |
2176 | "TARGET_64BIT" | |
2177 | "* | |
2178 | { | |
2179 | return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn), | |
2180 | get_attr_length (insn), 1, insn, 1); | |
2181 | }" | |
2182 | [(set_attr "type" "cbranch") | |
2183 | (set (attr "length") | |
2184 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
2185 | (const_int 8184)) | |
2186 | (const_int 4) | |
2187 | (const_int 8)))]) | |
2188 | ||
c733e074 | 2189 | ;; Floating point branches |
c733e074 TM |
2190 | (define_insn "" |
2191 | [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0)) | |
2192 | (label_ref (match_operand 0 "" "")) | |
2193 | (pc)))] | |
925cf581 | 2194 | "! TARGET_SOFT_FLOAT" |
e9cfad81 JL |
2195 | "* |
2196 | { | |
2197 | if (INSN_ANNULLED_BRANCH_P (insn)) | |
55abf18a | 2198 | return \"ftest\;b,n %0\"; |
e9cfad81 | 2199 | else |
55abf18a | 2200 | return \"ftest\;b%* %0\"; |
e9cfad81 JL |
2201 | }" |
2202 | [(set_attr "type" "fbranch") | |
4c2164b7 | 2203 | (set_attr "length" "8")]) |
c733e074 TM |
2204 | |
2205 | (define_insn "" | |
2206 | [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0)) | |
2207 | (pc) | |
2208 | (label_ref (match_operand 0 "" ""))))] | |
925cf581 | 2209 | "! TARGET_SOFT_FLOAT" |
e9cfad81 JL |
2210 | "* |
2211 | { | |
2212 | if (INSN_ANNULLED_BRANCH_P (insn)) | |
55abf18a | 2213 | return \"ftest\;add,tr %%r0,%%r0,%%r0\;b,n %0\"; |
e9cfad81 | 2214 | else |
55abf18a | 2215 | return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\"; |
e9cfad81 JL |
2216 | }" |
2217 | [(set_attr "type" "fbranch") | |
4c2164b7 | 2218 | (set_attr "length" "12")]) |
c733e074 TM |
2219 | |
2220 | ;; Move instructions | |
2221 | ||
2222 | (define_expand "movsi" | |
2223 | [(set (match_operand:SI 0 "general_operand" "") | |
2224 | (match_operand:SI 1 "general_operand" ""))] | |
2225 | "" | |
2226 | " | |
2227 | { | |
d2a94ec0 | 2228 | if (emit_move_sequence (operands, SImode, 0)) |
c733e074 TM |
2229 | DONE; |
2230 | }") | |
2231 | ||
0fc4f911 RK |
2232 | ;; Reloading an SImode or DImode value requires a scratch register if |
2233 | ;; going in to or out of float point registers. | |
2234 | ||
2235 | (define_expand "reload_insi" | |
2236 | [(set (match_operand:SI 0 "register_operand" "=Z") | |
2237 | (match_operand:SI 1 "non_hard_reg_operand" "")) | |
2238 | (clobber (match_operand:SI 2 "register_operand" "=&r"))] | |
2239 | "" | |
2240 | " | |
2241 | { | |
2242 | if (emit_move_sequence (operands, SImode, operands[2])) | |
2243 | DONE; | |
2244 | ||
2245 | /* We don't want the clobber emitted, so handle this ourselves. */ | |
ad2c71b7 | 2246 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); |
0fc4f911 RK |
2247 | DONE; |
2248 | }") | |
2249 | ||
2250 | (define_expand "reload_outsi" | |
2251 | [(set (match_operand:SI 0 "non_hard_reg_operand" "") | |
2252 | (match_operand:SI 1 "register_operand" "Z")) | |
2253 | (clobber (match_operand:SI 2 "register_operand" "=&r"))] | |
2254 | "" | |
2255 | " | |
2256 | { | |
2257 | if (emit_move_sequence (operands, SImode, operands[2])) | |
2258 | DONE; | |
2259 | ||
2260 | /* We don't want the clobber emitted, so handle this ourselves. */ | |
ad2c71b7 | 2261 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); |
0fc4f911 RK |
2262 | DONE; |
2263 | }") | |
2264 | ||
c733e074 | 2265 | (define_insn "" |
d8f95bed JDA |
2266 | [(set (match_operand:SI 0 "move_dest_operand" |
2267 | "=r,r,r,r,r,r,Q,!*q,!*f,*f,T") | |
2268 | (match_operand:SI 1 "move_src_operand" | |
2269 | "A,r,J,N,K,RQ,rM,!rM,!*fM,RT,*f"))] | |
925cf581 TG |
2270 | "(register_operand (operands[0], SImode) |
2271 | || reg_or_0_operand (operands[1], SImode)) | |
d8f95bed | 2272 | && !TARGET_SOFT_FLOAT" |
c733e074 | 2273 | "@ |
f8eb41cc | 2274 | ldw RT'%A1,%0 |
b16656f6 | 2275 | copy %1,%0 |
ac153498 | 2276 | ldi %1,%0 |
6f672dc0 | 2277 | ldil L'%1,%0 |
f38b27c7 | 2278 | {zdepi|depwi,z} %Z1,%0 |
c733e074 TM |
2279 | ldw%M1 %1,%0 |
2280 | stw%M0 %r1,%0 | |
cb524f44 | 2281 | mtsar %r1 |
55abf18a | 2282 | fcpy,sgl %f1,%0 |
2414e0e2 JL |
2283 | fldw%F1 %1,%0 |
2284 | fstw%F0 %1,%0" | |
f8eb41cc | 2285 | [(set_attr "type" "load,move,move,move,shift,load,store,move,fpalu,fpload,fpstore") |
c4bb6b38 | 2286 | (set_attr "pa_combine_type" "addmove") |
f8eb41cc | 2287 | (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")]) |
ac153498 | 2288 | |
925cf581 | 2289 | (define_insn "" |
d8f95bed JDA |
2290 | [(set (match_operand:SI 0 "indexed_memory_operand" "=R") |
2291 | (match_operand:SI 1 "register_operand" "f"))] | |
2292 | "!TARGET_SOFT_FLOAT | |
2293 | && !TARGET_DISABLE_INDEXING | |
2294 | && reload_completed" | |
2295 | "fstw%F0 %1,%0" | |
2296 | [(set_attr "type" "fpstore") | |
2297 | (set_attr "pa_combine_type" "addmove") | |
2298 | (set_attr "length" "4")]) | |
2299 | ||
2300 | ; Rewrite RTL using an indexed store. This will allow the insn that | |
2301 | ; computes the address to be deleted if the register it sets is dead. | |
2302 | (define_peephole2 | |
2303 | [(set (match_operand:SI 0 "register_operand" "") | |
2304 | (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "") | |
2305 | (const_int 4)) | |
2306 | (match_operand:SI 2 "register_operand" ""))) | |
2307 | (set (mem:SI (match_dup 0)) | |
2308 | (match_operand:SI 3 "reg_or_0_operand" ""))] | |
2309 | "!TARGET_SOFT_FLOAT | |
2310 | && REG_OK_FOR_BASE_P (operands[2]) | |
2311 | && FP_REGNO_P (REGNO (operands[3]))" | |
2312 | [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2))) | |
2313 | (match_dup 3)) | |
2314 | (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4)) | |
2315 | (match_dup 2)))] | |
2316 | "") | |
2317 | ||
2318 | (define_peephole2 | |
2319 | [(set (match_operand:SI 0 "register_operand" "") | |
2320 | (plus:SI (match_operand:SI 2 "register_operand" "") | |
2321 | (mult:SI (match_operand:SI 1 "register_operand" "") | |
2322 | (const_int 4)))) | |
2323 | (set (mem:SI (match_dup 0)) | |
2324 | (match_operand:SI 3 "register_operand" ""))] | |
2325 | "!TARGET_SOFT_FLOAT | |
2326 | && REG_OK_FOR_BASE_P (operands[2]) | |
2327 | && FP_REGNO_P (REGNO (operands[3]))" | |
2328 | [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2))) | |
2329 | (match_dup 3)) | |
2330 | (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4)) | |
2331 | (match_dup 2)))] | |
2332 | "") | |
2333 | ||
2334 | (define_peephole2 | |
2335 | [(set (match_operand:DI 0 "register_operand" "") | |
2336 | (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "") | |
2337 | (const_int 4)) | |
2338 | (match_operand:DI 2 "register_operand" ""))) | |
2339 | (set (mem:SI (match_dup 0)) | |
2340 | (match_operand:SI 3 "register_operand" ""))] | |
2341 | "!TARGET_SOFT_FLOAT | |
2342 | && TARGET_64BIT | |
2343 | && REG_OK_FOR_BASE_P (operands[2]) | |
2344 | && FP_REGNO_P (REGNO (operands[3]))" | |
2345 | [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2))) | |
2346 | (match_dup 3)) | |
2347 | (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4)) | |
2348 | (match_dup 2)))] | |
2349 | "") | |
2350 | ||
2351 | (define_peephole2 | |
2352 | [(set (match_operand:DI 0 "register_operand" "") | |
2353 | (plus:DI (match_operand:DI 2 "register_operand" "") | |
2354 | (mult:DI (match_operand:DI 1 "register_operand" "") | |
2355 | (const_int 4)))) | |
2356 | (set (mem:SI (match_dup 0)) | |
2357 | (match_operand:SI 3 "register_operand" ""))] | |
2358 | "!TARGET_SOFT_FLOAT | |
2359 | && TARGET_64BIT | |
2360 | && REG_OK_FOR_BASE_P (operands[2]) | |
2361 | && FP_REGNO_P (REGNO (operands[3]))" | |
2362 | [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2))) | |
2363 | (match_dup 3)) | |
2364 | (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4)) | |
2365 | (match_dup 2)))] | |
2366 | "") | |
2367 | ||
2368 | (define_peephole2 | |
2369 | [(set (match_operand:SI 0 "register_operand" "") | |
2370 | (plus:SI (match_operand:SI 1 "register_operand" "") | |
2371 | (match_operand:SI 2 "register_operand" ""))) | |
2372 | (set (mem:SI (match_dup 0)) | |
2373 | (match_operand:SI 3 "register_operand" ""))] | |
2374 | "!TARGET_SOFT_FLOAT | |
2375 | && REG_OK_FOR_BASE_P (operands[1]) | |
2376 | && (TARGET_NO_SPACE_REGS | |
2377 | || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2]))) | |
2378 | && FP_REGNO_P (REGNO (operands[3]))" | |
2379 | [(set (mem:SI (plus:SI (match_dup 1) (match_dup 2))) | |
2380 | (match_dup 3)) | |
2381 | (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))] | |
2382 | "") | |
2383 | ||
2384 | (define_peephole2 | |
2385 | [(set (match_operand:SI 0 "register_operand" "") | |
2386 | (plus:SI (match_operand:SI 1 "register_operand" "") | |
2387 | (match_operand:SI 2 "register_operand" ""))) | |
2388 | (set (mem:SI (match_dup 0)) | |
2389 | (match_operand:SI 3 "register_operand" ""))] | |
2390 | "!TARGET_SOFT_FLOAT | |
2391 | && REG_OK_FOR_BASE_P (operands[2]) | |
2392 | && (TARGET_NO_SPACE_REGS | |
2393 | || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2]))) | |
2394 | && FP_REGNO_P (REGNO (operands[3]))" | |
2395 | [(set (mem:SI (plus:SI (match_dup 2) (match_dup 1))) | |
2396 | (match_dup 3)) | |
2397 | (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))] | |
2398 | "") | |
2399 | ||
2400 | (define_peephole2 | |
2401 | [(set (match_operand:DI 0 "register_operand" "") | |
2402 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
2403 | (match_operand:DI 2 "register_operand" ""))) | |
2404 | (set (mem:SI (match_dup 0)) | |
2405 | (match_operand:SI 3 "register_operand" ""))] | |
2406 | "!TARGET_SOFT_FLOAT | |
2407 | && TARGET_64BIT | |
2408 | && REG_OK_FOR_BASE_P (operands[1]) | |
2409 | && (TARGET_NO_SPACE_REGS | |
2410 | || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2]))) | |
2411 | && FP_REGNO_P (REGNO (operands[3]))" | |
2412 | [(set (mem:SI (plus:DI (match_dup 1) (match_dup 2))) | |
2413 | (match_dup 3)) | |
2414 | (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] | |
2415 | "") | |
2416 | ||
2417 | (define_peephole2 | |
2418 | [(set (match_operand:DI 0 "register_operand" "") | |
2419 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
2420 | (match_operand:DI 2 "register_operand" ""))) | |
2421 | (set (mem:SI (match_dup 0)) | |
2422 | (match_operand:SI 3 "register_operand" ""))] | |
2423 | "!TARGET_SOFT_FLOAT | |
2424 | && TARGET_64BIT | |
2425 | && REG_OK_FOR_BASE_P (operands[2]) | |
2426 | && (TARGET_NO_SPACE_REGS | |
2427 | || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2]))) | |
2428 | && FP_REGNO_P (REGNO (operands[3]))" | |
2429 | [(set (mem:SI (plus:DI (match_dup 2) (match_dup 1))) | |
2430 | (match_dup 3)) | |
2431 | (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))] | |
2432 | "") | |
2433 | ||
2434 | (define_insn "" | |
2435 | [(set (match_operand:SI 0 "move_dest_operand" | |
2436 | "=r,r,r,r,r,r,Q,!*q") | |
2437 | (match_operand:SI 1 "move_src_operand" | |
2438 | "A,r,J,N,K,RQ,rM,!rM"))] | |
925cf581 TG |
2439 | "(register_operand (operands[0], SImode) |
2440 | || reg_or_0_operand (operands[1], SImode)) | |
2441 | && TARGET_SOFT_FLOAT" | |
2442 | "@ | |
f8eb41cc | 2443 | ldw RT'%A1,%0 |
925cf581 TG |
2444 | copy %1,%0 |
2445 | ldi %1,%0 | |
2446 | ldil L'%1,%0 | |
f38b27c7 | 2447 | {zdepi|depwi,z} %Z1,%0 |
925cf581 TG |
2448 | ldw%M1 %1,%0 |
2449 | stw%M0 %r1,%0 | |
2450 | mtsar %r1" | |
f8eb41cc | 2451 | [(set_attr "type" "load,move,move,move,move,load,store,move") |
c4bb6b38 | 2452 | (set_attr "pa_combine_type" "addmove") |
f8eb41cc | 2453 | (set_attr "length" "4,4,4,4,4,4,4,4")]) |
925cf581 | 2454 | |
d8f95bed | 2455 | ;; Load or store with base-register modification. |
31d4f31f JL |
2456 | (define_insn "" |
2457 | [(set (match_operand:SI 0 "register_operand" "=r") | |
d8f95bed JDA |
2458 | (mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r") |
2459 | (match_operand:DI 2 "int5_operand" "L")))) | |
2460 | (set (match_dup 1) | |
2461 | (plus:DI (match_dup 1) (match_dup 2)))] | |
2462 | "TARGET_64BIT" | |
2463 | "ldw,mb %2(%1),%0" | |
31d4f31f JL |
2464 | [(set_attr "type" "load") |
2465 | (set_attr "length" "4")]) | |
2466 | ||
d8f95bed | 2467 | ; And a zero extended variant. |
68944452 | 2468 | (define_insn "" |
d8f95bed JDA |
2469 | [(set (match_operand:DI 0 "register_operand" "=r") |
2470 | (zero_extend:DI (mem:SI | |
2471 | (plus:DI | |
2472 | (match_operand:DI 1 "register_operand" "+r") | |
2473 | (match_operand:DI 2 "int5_operand" "L"))))) | |
2474 | (set (match_dup 1) | |
2475 | (plus:DI (match_dup 1) (match_dup 2)))] | |
2476 | "TARGET_64BIT" | |
2477 | "ldw,mb %2(%1),%0" | |
68944452 JL |
2478 | [(set_attr "type" "load") |
2479 | (set_attr "length" "4")]) | |
2480 | ||
30d1e848 JL |
2481 | (define_expand "pre_load" |
2482 | [(parallel [(set (match_operand:SI 0 "register_operand" "") | |
2483 | (mem (plus (match_operand 1 "register_operand" "") | |
2484 | (match_operand 2 "pre_cint_operand" "")))) | |
2485 | (set (match_dup 1) | |
2486 | (plus (match_dup 1) (match_dup 2)))])] | |
2487 | "" | |
2488 | " | |
2489 | { | |
520babc7 JL |
2490 | if (TARGET_64BIT) |
2491 | { | |
2492 | emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2])); | |
2493 | DONE; | |
2494 | } | |
30d1e848 JL |
2495 | emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2])); |
2496 | DONE; | |
2497 | }") | |
2498 | ||
2499 | (define_insn "pre_ldw" | |
305123ba | 2500 | [(set (match_operand:SI 0 "register_operand" "=r") |
1b8b89f1 | 2501 | (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r") |
ac153498 | 2502 | (match_operand:SI 2 "pre_cint_operand" "")))) |
305123ba | 2503 | (set (match_dup 1) |
ac153498 TG |
2504 | (plus:SI (match_dup 1) (match_dup 2)))] |
2505 | "" | |
2506 | "* | |
2507 | { | |
2508 | if (INTVAL (operands[2]) < 0) | |
f38b27c7 JL |
2509 | return \"{ldwm|ldw,mb} %2(%1),%0\"; |
2510 | return \"{ldws|ldw},mb %2(%1),%0\"; | |
ac153498 TG |
2511 | }" |
2512 | [(set_attr "type" "load") | |
4c2164b7 | 2513 | (set_attr "length" "4")]) |
ac153498 | 2514 | |
520babc7 JL |
2515 | (define_insn "pre_ldd" |
2516 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2517 | (mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r") | |
2518 | (match_operand:DI 2 "pre_cint_operand" "")))) | |
2519 | (set (match_dup 1) | |
2520 | (plus:DI (match_dup 1) (match_dup 2)))] | |
2521 | "TARGET_64BIT" | |
2522 | "ldd,mb %2(%1),%0" | |
2523 | [(set_attr "type" "load") | |
2524 | (set_attr "length" "4")]) | |
2525 | ||
30d1e848 | 2526 | (define_insn "" |
1b8b89f1 | 2527 | [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r") |
305123ba JL |
2528 | (match_operand:SI 1 "pre_cint_operand" ""))) |
2529 | (match_operand:SI 2 "reg_or_0_operand" "rM")) | |
2530 | (set (match_dup 0) | |
2531 | (plus:SI (match_dup 0) (match_dup 1)))] | |
ac153498 TG |
2532 | "" |
2533 | "* | |
2534 | { | |
305123ba | 2535 | if (INTVAL (operands[1]) < 0) |
f38b27c7 JL |
2536 | return \"{stwm|stw,mb} %r2,%1(%0)\"; |
2537 | return \"{stws|stw},mb %r2,%1(%0)\"; | |
ac153498 TG |
2538 | }" |
2539 | [(set_attr "type" "store") | |
4c2164b7 | 2540 | (set_attr "length" "4")]) |
c733e074 | 2541 | |
30d1e848 | 2542 | (define_insn "" |
305123ba | 2543 | [(set (match_operand:SI 0 "register_operand" "=r") |
1b8b89f1 | 2544 | (mem:SI (match_operand:SI 1 "register_operand" "+r"))) |
1b84b6f8 JL |
2545 | (set (match_dup 1) |
2546 | (plus:SI (match_dup 1) | |
c1fab105 JL |
2547 | (match_operand:SI 2 "post_cint_operand" "")))] |
2548 | "" | |
2549 | "* | |
2550 | { | |
2551 | if (INTVAL (operands[2]) > 0) | |
f38b27c7 JL |
2552 | return \"{ldwm|ldw,ma} %2(%1),%0\"; |
2553 | return \"{ldws|ldw},ma %2(%1),%0\"; | |
c1fab105 JL |
2554 | }" |
2555 | [(set_attr "type" "load") | |
4c2164b7 | 2556 | (set_attr "length" "4")]) |
c1fab105 | 2557 | |
30d1e848 JL |
2558 | (define_expand "post_store" |
2559 | [(parallel [(set (mem (match_operand 0 "register_operand" "")) | |
2560 | (match_operand 1 "reg_or_0_operand" "")) | |
2561 | (set (match_dup 0) | |
2562 | (plus (match_dup 0) | |
2563 | (match_operand 2 "post_cint_operand" "")))])] | |
2564 | "" | |
2565 | " | |
2566 | { | |
520babc7 JL |
2567 | if (TARGET_64BIT) |
2568 | { | |
2569 | emit_insn (gen_post_std (operands[0], operands[1], operands[2])); | |
2570 | DONE; | |
2571 | } | |
30d1e848 JL |
2572 | emit_insn (gen_post_stw (operands[0], operands[1], operands[2])); |
2573 | DONE; | |
2574 | }") | |
2575 | ||
2576 | (define_insn "post_stw" | |
1b8b89f1 | 2577 | [(set (mem:SI (match_operand:SI 0 "register_operand" "+r")) |
305123ba JL |
2578 | (match_operand:SI 1 "reg_or_0_operand" "rM")) |
2579 | (set (match_dup 0) | |
2580 | (plus:SI (match_dup 0) | |
c1fab105 JL |
2581 | (match_operand:SI 2 "post_cint_operand" "")))] |
2582 | "" | |
2583 | "* | |
2584 | { | |
2585 | if (INTVAL (operands[2]) > 0) | |
f38b27c7 JL |
2586 | return \"{stwm|stw,ma} %r1,%2(%0)\"; |
2587 | return \"{stws|stw},ma %r1,%2(%0)\"; | |
c1fab105 JL |
2588 | }" |
2589 | [(set_attr "type" "store") | |
4c2164b7 | 2590 | (set_attr "length" "4")]) |
c1fab105 | 2591 | |
520babc7 JL |
2592 | (define_insn "post_std" |
2593 | [(set (mem:DI (match_operand:DI 0 "register_operand" "+r")) | |
2594 | (match_operand:DI 1 "reg_or_0_operand" "rM")) | |
2595 | (set (match_dup 0) | |
2596 | (plus:DI (match_dup 0) | |
2597 | (match_operand:DI 2 "post_cint_operand" "")))] | |
2598 | "TARGET_64BIT" | |
2599 | "std,ma %r1,%2(%0)" | |
2600 | [(set_attr "type" "store") | |
2601 | (set_attr "length" "4")]) | |
2602 | ||
b3d9ecf0 | 2603 | ;; For loading the address of a label while generating PIC code. |
6bb36601 JL |
2604 | ;; Note since this pattern can be created at reload time (via movsi), all |
2605 | ;; the same rules for movsi apply here. (no new pseudos, no temporaries). | |
b3d9ecf0 | 2606 | (define_insn "" |
124c9423 | 2607 | [(set (match_operand 0 "pmode_register_operand" "=a") |
b3d9ecf0 | 2608 | (match_operand 1 "pic_label_operand" ""))] |
03d1cb6d | 2609 | "TARGET_PA_20" |
c733e074 TM |
2610 | "* |
2611 | { | |
c733e074 TM |
2612 | rtx xoperands[3]; |
2613 | extern FILE *asm_out_file; | |
2614 | ||
2615 | xoperands[0] = operands[0]; | |
2616 | xoperands[1] = operands[1]; | |
03d1cb6d | 2617 | xoperands[2] = gen_label_rtx (); |
3d9268b6 | 2618 | |
03d1cb6d JDA |
2619 | (*targetm.asm_out.internal_label) (asm_out_file, \"L\", |
2620 | CODE_LABEL_NUMBER (xoperands[2])); | |
2621 | output_asm_insn (\"mfia %0\", xoperands); | |
6bb36601 JL |
2622 | |
2623 | /* If we're trying to load the address of a label that happens to be | |
2624 | close, then we can use a shorter sequence. */ | |
2625 | if (GET_CODE (operands[1]) == LABEL_REF | |
9d98a694 AO |
2626 | && INSN_ADDRESSES_SET_P () |
2627 | && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0))) | |
2628 | - INSN_ADDRESSES (INSN_UID (insn))) < 8100) | |
03d1cb6d JDA |
2629 | output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands); |
2630 | else | |
6bb36601 | 2631 | { |
03d1cb6d JDA |
2632 | output_asm_insn (\"addil L%%%1-%2,%0\", xoperands); |
2633 | output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands); | |
6bb36601 | 2634 | } |
03d1cb6d JDA |
2635 | return \"\"; |
2636 | }" | |
2637 | [(set_attr "type" "multi") | |
2638 | (set_attr "length" "12")]) ; 8 or 12 | |
2639 | ||
2640 | (define_insn "" | |
2641 | [(set (match_operand 0 "pmode_register_operand" "=a") | |
2642 | (match_operand 1 "pic_label_operand" ""))] | |
2643 | "!TARGET_PA_20" | |
2644 | "* | |
2645 | { | |
2646 | rtx xoperands[3]; | |
2647 | extern FILE *asm_out_file; | |
2648 | ||
2649 | xoperands[0] = operands[0]; | |
2650 | xoperands[1] = operands[1]; | |
2651 | xoperands[2] = gen_label_rtx (); | |
2652 | ||
2653 | output_asm_insn (\"bl .+8,%0\", xoperands); | |
2654 | output_asm_insn (\"depi 0,31,2,%0\", xoperands); | |
2655 | (*targetm.asm_out.internal_label) (asm_out_file, \"L\", | |
2656 | CODE_LABEL_NUMBER (xoperands[2])); | |
2657 | ||
2658 | /* If we're trying to load the address of a label that happens to be | |
2659 | close, then we can use a shorter sequence. */ | |
2660 | if (GET_CODE (operands[1]) == LABEL_REF | |
2661 | && INSN_ADDRESSES_SET_P () | |
2662 | && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0))) | |
2663 | - INSN_ADDRESSES (INSN_UID (insn))) < 8100) | |
2664 | output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands); | |
6bb36601 JL |
2665 | else |
2666 | { | |
03d1cb6d JDA |
2667 | output_asm_insn (\"addil L%%%1-%2,%0\", xoperands); |
2668 | output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands); | |
6bb36601 | 2669 | } |
c733e074 | 2670 | return \"\"; |
6bb36601 | 2671 | }" |
c733e074 | 2672 | [(set_attr "type" "multi") |
6bb36601 JL |
2673 | (set_attr "length" "16")]) ; 12 or 16 |
2674 | ||
2a0a6f69 | 2675 | (define_insn "" |
520babc7 JL |
2676 | [(set (match_operand:SI 0 "register_operand" "=a") |
2677 | (plus:SI (match_operand:SI 1 "register_operand" "r") | |
2678 | (high:SI (match_operand 2 "" ""))))] | |
2679 | "symbolic_operand (operands[2], Pmode) | |
2680 | && ! function_label_operand (operands[2], Pmode) | |
7ee72796 | 2681 | && flag_pic" |
520babc7 JL |
2682 | "addil LT'%G2,%1" |
2683 | [(set_attr "type" "binary") | |
2684 | (set_attr "length" "4")]) | |
2685 | ||
2686 | (define_insn "" | |
2687 | [(set (match_operand:DI 0 "register_operand" "=a") | |
2688 | (plus:DI (match_operand:DI 1 "register_operand" "r") | |
2689 | (high:DI (match_operand 2 "" ""))))] | |
6bb36601 | 2690 | "symbolic_operand (operands[2], Pmode) |
519104fe | 2691 | && ! function_label_operand (operands[2], Pmode) |
520babc7 | 2692 | && TARGET_64BIT |
7ee72796 | 2693 | && flag_pic" |
6bb36601 JL |
2694 | "addil LT'%G2,%1" |
2695 | [(set_attr "type" "binary") | |
2696 | (set_attr "length" "4")]) | |
c733e074 | 2697 | |
44552b6a JL |
2698 | ;; Always use addil rather than ldil;add sequences. This allows the |
2699 | ;; HP linker to eliminate the dp relocation if the symbolic operand | |
2700 | ;; lives in the TEXT space. | |
9c36061e JL |
2701 | (define_insn "" |
2702 | [(set (match_operand:SI 0 "register_operand" "=a") | |
9f309ba3 | 2703 | (high:SI (match_operand 1 "" "")))] |
2f95ebc2 | 2704 | "symbolic_operand (operands[1], Pmode) |
519104fe KG |
2705 | && ! function_label_operand (operands[1], Pmode) |
2706 | && ! read_only_operand (operands[1], Pmode) | |
6bb36601 | 2707 | && ! flag_pic" |
c3d4f633 JL |
2708 | "* |
2709 | { | |
2710 | if (TARGET_LONG_LOAD_STORE) | |
2711 | return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\"; | |
2712 | else | |
2713 | return \"addil LR'%H1,%%r27\"; | |
2714 | }" | |
9c36061e | 2715 | [(set_attr "type" "binary") |
c3d4f633 JL |
2716 | (set (attr "length") |
2717 | (if_then_else (eq (symbol_ref "TARGET_LONG_LOAD_STORE") (const_int 0)) | |
2718 | (const_int 4) | |
2719 | (const_int 8)))]) | |
2720 | ||
9c36061e | 2721 | |
2f95ebc2 | 2722 | ;; This is for use in the prologue/epilogue code. We need it |
c1fab105 JL |
2723 | ;; to add large constants to a stack pointer or frame pointer. |
2724 | ;; Because of the additional %r1 pressure, we probably do not | |
2725 | ;; want to use this in general code, so make it available | |
2726 | ;; only after reload. | |
fc82f2f1 | 2727 | (define_insn "" |
c1fab105 | 2728 | [(set (match_operand:SI 0 "register_operand" "=!a,*r") |
3913f03a RK |
2729 | (plus:SI (match_operand:SI 1 "register_operand" "r,r") |
2730 | (high:SI (match_operand 2 "const_int_operand" ""))))] | |
c1fab105 JL |
2731 | "reload_completed" |
2732 | "@ | |
2733 | addil L'%G2,%1 | |
f38b27c7 | 2734 | ldil L'%G2,%0\;{addl|add,l} %0,%1,%0" |
c1fab105 | 2735 | [(set_attr "type" "binary,binary") |
4c2164b7 | 2736 | (set_attr "length" "4,8")]) |
c1fab105 | 2737 | |
520babc7 JL |
2738 | (define_insn "" |
2739 | [(set (match_operand:DI 0 "register_operand" "=!a,*r") | |
2740 | (plus:DI (match_operand:DI 1 "register_operand" "r,r") | |
2741 | (high:DI (match_operand 2 "const_int_operand" ""))))] | |
2742 | "reload_completed && TARGET_64BIT" | |
2743 | "@ | |
2744 | addil L'%G2,%1 | |
2745 | ldil L'%G2,%0\;{addl|add,l} %0,%1,%0" | |
2746 | [(set_attr "type" "binary,binary") | |
2747 | (set_attr "length" "4,8")]) | |
2748 | ||
c733e074 TM |
2749 | (define_insn "" |
2750 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2751 | (high:SI (match_operand 1 "" "")))] | |
519104fe | 2752 | "(!flag_pic || !symbolic_operand (operands[1], Pmode)) |
6bb36601 | 2753 | && !is_function_label_plus_const (operands[1])" |
65d5cba8 RK |
2754 | "* |
2755 | { | |
2756 | if (symbolic_operand (operands[1], Pmode)) | |
ad238e4b | 2757 | return \"ldil LR'%H1,%0\"; |
65d5cba8 RK |
2758 | else |
2759 | return \"ldil L'%G1,%0\"; | |
2760 | }" | |
c733e074 | 2761 | [(set_attr "type" "move") |
4c2164b7 | 2762 | (set_attr "length" "4")]) |
c733e074 | 2763 | |
520babc7 JL |
2764 | (define_insn "" |
2765 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2766 | (high:DI (match_operand 1 "const_int_operand" "")))] | |
2767 | "TARGET_64BIT" | |
2768 | "ldil L'%G1,%0"; | |
2769 | [(set_attr "type" "move") | |
2770 | (set_attr "length" "4")]) | |
2771 | ||
2772 | (define_insn "" | |
2773 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2774 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
2775 | (match_operand:DI 2 "const_int_operand" "i")))] | |
2776 | "TARGET_64BIT" | |
2777 | "ldo R'%G2(%1),%0"; | |
2778 | [(set_attr "type" "move") | |
2779 | (set_attr "length" "4")]) | |
2780 | ||
c733e074 TM |
2781 | (define_insn "" |
2782 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2783 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
907f67cc | 2784 | (match_operand:SI 2 "immediate_operand" "i")))] |
8d768fa2 | 2785 | "!is_function_label_plus_const (operands[2])" |
6bb36601 JL |
2786 | "* |
2787 | { | |
a205e34b | 2788 | if (flag_pic && symbolic_operand (operands[2], Pmode)) |
6bb36601 | 2789 | abort (); |
65d5cba8 RK |
2790 | else if (symbolic_operand (operands[2], Pmode)) |
2791 | return \"ldo RR'%G2(%1),%0\"; | |
6bb36601 JL |
2792 | else |
2793 | return \"ldo R'%G2(%1),%0\"; | |
2794 | }" | |
c47decad JL |
2795 | [(set_attr "type" "move") |
2796 | (set_attr "length" "4")]) | |
c733e074 | 2797 | |
26915fa9 JL |
2798 | ;; Now that a symbolic_address plus a constant is broken up early |
2799 | ;; in the compilation phase (for better CSE) we need a special | |
2800 | ;; combiner pattern to load the symbolic address plus the constant | |
2f95ebc2 | 2801 | ;; in only 2 instructions. (For cases where the symbolic address |
26915fa9 JL |
2802 | ;; was not a common subexpression.) |
2803 | (define_split | |
2804 | [(set (match_operand:SI 0 "register_operand" "") | |
b16656f6 | 2805 | (match_operand:SI 1 "symbolic_operand" "")) |
26915fa9 | 2806 | (clobber (match_operand:SI 2 "register_operand" ""))] |
6bb36601 | 2807 | "! (flag_pic && pic_label_operand (operands[1], SImode))" |
26915fa9 JL |
2808 | [(set (match_dup 2) (high:SI (match_dup 1))) |
2809 | (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))] | |
2810 | "") | |
2811 | ||
78c0acfd JL |
2812 | ;; hppa_legitimize_address goes to a great deal of trouble to |
2813 | ;; create addresses which use indexing. In some cases, this | |
2814 | ;; is a lose because there isn't any store instructions which | |
2815 | ;; allow indexed addresses (with integer register source). | |
2816 | ;; | |
2817 | ;; These define_splits try to turn a 3 insn store into | |
2818 | ;; a 2 insn store with some creative RTL rewriting. | |
2819 | (define_split | |
2820 | [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "") | |
2821 | (match_operand:SI 1 "shadd_operand" "")) | |
2822 | (plus:SI (match_operand:SI 2 "register_operand" "") | |
2823 | (match_operand:SI 3 "const_int_operand" "")))) | |
2824 | (match_operand:SI 4 "register_operand" "")) | |
2825 | (clobber (match_operand:SI 5 "register_operand" ""))] | |
2826 | "" | |
2827 | [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1)) | |
2828 | (match_dup 2))) | |
2829 | (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))] | |
2830 | "") | |
2831 | ||
2832 | (define_split | |
2833 | [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "") | |
2834 | (match_operand:SI 1 "shadd_operand" "")) | |
2835 | (plus:SI (match_operand:SI 2 "register_operand" "") | |
2836 | (match_operand:SI 3 "const_int_operand" "")))) | |
2837 | (match_operand:HI 4 "register_operand" "")) | |
2838 | (clobber (match_operand:SI 5 "register_operand" ""))] | |
2839 | "" | |
2840 | [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1)) | |
2841 | (match_dup 2))) | |
2842 | (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))] | |
2843 | "") | |
2844 | ||
2845 | (define_split | |
2846 | [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "") | |
2847 | (match_operand:SI 1 "shadd_operand" "")) | |
2848 | (plus:SI (match_operand:SI 2 "register_operand" "") | |
2849 | (match_operand:SI 3 "const_int_operand" "")))) | |
2850 | (match_operand:QI 4 "register_operand" "")) | |
2851 | (clobber (match_operand:SI 5 "register_operand" ""))] | |
2852 | "" | |
2853 | [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1)) | |
2854 | (match_dup 2))) | |
2855 | (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))] | |
2856 | "") | |
2857 | ||
c733e074 TM |
2858 | (define_expand "movhi" |
2859 | [(set (match_operand:HI 0 "general_operand" "") | |
2860 | (match_operand:HI 1 "general_operand" ""))] | |
2861 | "" | |
2862 | " | |
2863 | { | |
d2a94ec0 | 2864 | if (emit_move_sequence (operands, HImode, 0)) |
c733e074 TM |
2865 | DONE; |
2866 | }") | |
2867 | ||
2868 | (define_insn "" | |
d8f95bed JDA |
2869 | [(set (match_operand:HI 0 "move_dest_operand" |
2870 | "=r,r,r,r,r,Q,!*q,!*f") | |
2871 | (match_operand:HI 1 "move_src_operand" | |
2872 | "r,J,N,K,RQ,rM,!rM,!*fM"))] | |
4d72c241 | 2873 | "register_operand (operands[0], HImode) |
29ed7081 | 2874 | || reg_or_0_operand (operands[1], HImode)" |
c733e074 | 2875 | "@ |
b16656f6 | 2876 | copy %1,%0 |
ac153498 | 2877 | ldi %1,%0 |
6f672dc0 | 2878 | ldil L'%1,%0 |
f38b27c7 | 2879 | {zdepi|depwi,z} %Z1,%0 |
c733e074 | 2880 | ldh%M1 %1,%0 |
d2a94ec0 | 2881 | sth%M0 %r1,%0 |
ac153498 | 2882 | mtsar %r1 |
55abf18a | 2883 | fcpy,sgl %f1,%0" |
c47decad | 2884 | [(set_attr "type" "move,move,move,shift,load,store,move,fpalu") |
c4bb6b38 | 2885 | (set_attr "pa_combine_type" "addmove") |
4c2164b7 | 2886 | (set_attr "length" "4,4,4,4,4,4,4,4")]) |
c733e074 | 2887 | |
31d4f31f JL |
2888 | (define_insn "" |
2889 | [(set (match_operand:HI 0 "register_operand" "=r") | |
d8f95bed JDA |
2890 | (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r") |
2891 | (match_operand:SI 2 "int5_operand" "L")))) | |
2892 | (set (match_dup 1) | |
2893 | (plus:SI (match_dup 1) (match_dup 2)))] | |
2894 | "" | |
2895 | "{ldhs|ldh},mb %2(%1),%0" | |
31d4f31f JL |
2896 | [(set_attr "type" "load") |
2897 | (set_attr "length" "4")]) | |
2898 | ||
68944452 JL |
2899 | (define_insn "" |
2900 | [(set (match_operand:HI 0 "register_operand" "=r") | |
d8f95bed JDA |
2901 | (mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r") |
2902 | (match_operand:DI 2 "int5_operand" "L")))) | |
2903 | (set (match_dup 1) | |
2904 | (plus:DI (match_dup 1) (match_dup 2)))] | |
2905 | "TARGET_64BIT" | |
2906 | "ldh,mb %2(%1),%0" | |
68944452 JL |
2907 | [(set_attr "type" "load") |
2908 | (set_attr "length" "4")]) | |
2909 | ||
d8f95bed | 2910 | ; And a zero extended variant. |
31d4f31f | 2911 | (define_insn "" |
d8f95bed JDA |
2912 | [(set (match_operand:DI 0 "register_operand" "=r") |
2913 | (zero_extend:DI (mem:HI | |
2914 | (plus:DI | |
2915 | (match_operand:DI 1 "register_operand" "+r") | |
2916 | (match_operand:DI 2 "int5_operand" "L"))))) | |
2917 | (set (match_dup 1) | |
2918 | (plus:DI (match_dup 1) (match_dup 2)))] | |
2919 | "TARGET_64BIT" | |
2920 | "ldh,mb %2(%1),%0" | |
31d4f31f JL |
2921 | [(set_attr "type" "load") |
2922 | (set_attr "length" "4")]) | |
2923 | ||
2924 | (define_insn "" | |
2925 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2926 | (zero_extend:SI (mem:HI | |
2927 | (plus:SI | |
d8f95bed JDA |
2928 | (match_operand:SI 1 "register_operand" "+r") |
2929 | (match_operand:SI 2 "int5_operand" "L"))))) | |
305123ba | 2930 | (set (match_dup 1) |
ac153498 | 2931 | (plus:SI (match_dup 1) (match_dup 2)))] |
57b3a4f1 | 2932 | "" |
f38b27c7 | 2933 | "{ldhs|ldh},mb %2(%1),%0" |
ac153498 | 2934 | [(set_attr "type" "load") |
4c2164b7 | 2935 | (set_attr "length" "4")]) |
ac153498 | 2936 | |
31d4f31f JL |
2937 | (define_insn "" |
2938 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2939 | (zero_extend:SI (mem:HI | |
d8f95bed JDA |
2940 | (plus:DI |
2941 | (match_operand:DI 1 "register_operand" "+r") | |
2942 | (match_operand:DI 2 "int5_operand" "L"))))) | |
31d4f31f | 2943 | (set (match_dup 1) |
d8f95bed JDA |
2944 | (plus:DI (match_dup 1) (match_dup 2)))] |
2945 | "TARGET_64BIT" | |
2946 | "ldh,mb %2(%1),%0" | |
31d4f31f JL |
2947 | [(set_attr "type" "load") |
2948 | (set_attr "length" "4")]) | |
2949 | ||
ac153498 | 2950 | (define_insn "" |
1b8b89f1 | 2951 | [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r") |
305123ba JL |
2952 | (match_operand:SI 1 "int5_operand" "L"))) |
2953 | (match_operand:HI 2 "reg_or_0_operand" "rM")) | |
2954 | (set (match_dup 0) | |
2955 | (plus:SI (match_dup 0) (match_dup 1)))] | |
ac153498 | 2956 | "" |
f38b27c7 | 2957 | "{sths|sth},mb %r2,%1(%0)" |
ac153498 | 2958 | [(set_attr "type" "store") |
4c2164b7 | 2959 | (set_attr "length" "4")]) |
ac153498 | 2960 | |
d8f95bed JDA |
2961 | (define_insn "" |
2962 | [(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r") | |
2963 | (match_operand:DI 1 "int5_operand" "L"))) | |
2964 | (match_operand:HI 2 "reg_or_0_operand" "rM")) | |
2965 | (set (match_dup 0) | |
2966 | (plus:DI (match_dup 0) (match_dup 1)))] | |
2967 | "TARGET_64BIT" | |
2968 | "sth,mb %r2,%1(%0)" | |
2969 | [(set_attr "type" "store") | |
2970 | (set_attr "length" "4")]) | |
2971 | ||
ac153498 TG |
2972 | (define_insn "" |
2973 | [(set (match_operand:HI 0 "register_operand" "=r") | |
b8e42321 JDA |
2974 | (plus:HI (match_operand:HI 1 "register_operand" "r") |
2975 | (match_operand 2 "const_int_operand" "J")))] | |
6bb36601 | 2976 | "" |
b8e42321 JDA |
2977 | "ldo %2(%1),%0" |
2978 | [(set_attr "type" "binary") | |
2979 | (set_attr "pa_combine_type" "addmove") | |
c47decad | 2980 | (set_attr "length" "4")]) |
c733e074 TM |
2981 | |
2982 | (define_expand "movqi" | |
2983 | [(set (match_operand:QI 0 "general_operand" "") | |
2984 | (match_operand:QI 1 "general_operand" ""))] | |
2985 | "" | |
2986 | " | |
2987 | { | |
d2a94ec0 | 2988 | if (emit_move_sequence (operands, QImode, 0)) |
c733e074 TM |
2989 | DONE; |
2990 | }") | |
2991 | ||
2992 | (define_insn "" | |
d8f95bed JDA |
2993 | [(set (match_operand:QI 0 "move_dest_operand" |
2994 | "=r,r,r,r,r,Q,!*q,!*f") | |
2995 | (match_operand:QI 1 "move_src_operand" | |
2996 | "r,J,N,K,RQ,rM,!rM,!*fM"))] | |
4d72c241 | 2997 | "register_operand (operands[0], QImode) |
29ed7081 | 2998 | || reg_or_0_operand (operands[1], QImode)" |
c733e074 | 2999 | "@ |
b16656f6 | 3000 | copy %1,%0 |
ac153498 | 3001 | ldi %1,%0 |
6f672dc0 | 3002 | ldil L'%1,%0 |
f38b27c7 | 3003 | {zdepi|depwi,z} %Z1,%0 |
c733e074 | 3004 | ldb%M1 %1,%0 |
d2a94ec0 | 3005 | stb%M0 %r1,%0 |
ac153498 | 3006 | mtsar %r1 |
55abf18a | 3007 | fcpy,sgl %f1,%0" |
c47decad | 3008 | [(set_attr "type" "move,move,move,shift,load,store,move,fpalu") |
c4bb6b38 | 3009 | (set_attr "pa_combine_type" "addmove") |
4c2164b7 | 3010 | (set_attr "length" "4,4,4,4,4,4,4,4")]) |
c733e074 | 3011 | |
31d4f31f JL |
3012 | (define_insn "" |
3013 | [(set (match_operand:QI 0 "register_operand" "=r") | |
d8f95bed JDA |
3014 | (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r") |
3015 | (match_operand:SI 2 "int5_operand" "L")))) | |
3016 | (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))] | |
3017 | "" | |
3018 | "{ldbs|ldb},mb %2(%1),%0" | |
31d4f31f JL |
3019 | [(set_attr "type" "load") |
3020 | (set_attr "length" "4")]) | |
3021 | ||
68944452 JL |
3022 | (define_insn "" |
3023 | [(set (match_operand:QI 0 "register_operand" "=r") | |
d8f95bed JDA |
3024 | (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r") |
3025 | (match_operand:DI 2 "int5_operand" "L")))) | |
3026 | (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))] | |
3027 | "TARGET_64BIT" | |
3028 | "ldb,mb %2(%1),%0" | |
68944452 JL |
3029 | [(set_attr "type" "load") |
3030 | (set_attr "length" "4")]) | |
3031 | ||
d8f95bed | 3032 | ; Now the same thing with zero extensions. |
31d4f31f | 3033 | (define_insn "" |
d8f95bed JDA |
3034 | [(set (match_operand:DI 0 "register_operand" "=r") |
3035 | (zero_extend:DI (mem:QI (plus:DI | |
3036 | (match_operand:DI 1 "register_operand" "+r") | |
3037 | (match_operand:DI 2 "int5_operand" "L"))))) | |
3038 | (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))] | |
3039 | "TARGET_64BIT" | |
3040 | "ldb,mb %2(%1),%0" | |
31d4f31f JL |
3041 | [(set_attr "type" "load") |
3042 | (set_attr "length" "4")]) | |
3043 | ||
3044 | (define_insn "" | |
3045 | [(set (match_operand:SI 0 "register_operand" "=r") | |
d8f95bed JDA |
3046 | (zero_extend:SI (mem:QI (plus:SI |
3047 | (match_operand:SI 1 "register_operand" "+r") | |
3048 | (match_operand:SI 2 "int5_operand" "L"))))) | |
305123ba | 3049 | (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))] |
c733e074 | 3050 | "" |
f38b27c7 | 3051 | "{ldbs|ldb},mb %2(%1),%0" |
b7a4467d | 3052 | [(set_attr "type" "load") |
4c2164b7 | 3053 | (set_attr "length" "4")]) |
d2a94ec0 | 3054 | |
31d4f31f JL |
3055 | (define_insn "" |
3056 | [(set (match_operand:SI 0 "register_operand" "=r") | |
d8f95bed JDA |
3057 | (zero_extend:SI (mem:QI (plus:DI |
3058 | (match_operand:DI 1 "register_operand" "+r") | |
3059 | (match_operand:DI 2 "int5_operand" "L"))))) | |
3060 | (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))] | |
3061 | "TARGET_64BIT" | |
3062 | "ldb,mb %2(%1),%0" | |
31d4f31f JL |
3063 | [(set_attr "type" "load") |
3064 | (set_attr "length" "4")]) | |
3065 | ||
3066 | (define_insn "" | |
3067 | [(set (match_operand:HI 0 "register_operand" "=r") | |
3068 | (zero_extend:HI (mem:QI (plus:SI | |
1b8b89f1 | 3069 | (match_operand:SI 1 "register_operand" "+r") |
31d4f31f JL |
3070 | (match_operand:SI 2 "int5_operand" "L"))))) |
3071 | (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))] | |
3072 | "" | |
f38b27c7 | 3073 | "{ldbs|ldb},mb %2(%1),%0" |
31d4f31f JL |
3074 | [(set_attr "type" "load") |
3075 | (set_attr "length" "4")]) | |
3076 | ||
d8f95bed JDA |
3077 | (define_insn "" |
3078 | [(set (match_operand:HI 0 "register_operand" "=r") | |
3079 | (zero_extend:HI (mem:QI (plus:DI | |
3080 | (match_operand:DI 1 "register_operand" "+r") | |
3081 | (match_operand:DI 2 "int5_operand" "L"))))) | |
3082 | (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))] | |
3083 | "TARGET_64BIT" | |
3084 | "ldb,mb %2(%1),%0" | |
3085 | [(set_attr "type" "load") | |
3086 | (set_attr "length" "4")]) | |
3087 | ||
d2a94ec0 | 3088 | (define_insn "" |
1b8b89f1 | 3089 | [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r") |
305123ba JL |
3090 | (match_operand:SI 1 "int5_operand" "L"))) |
3091 | (match_operand:QI 2 "reg_or_0_operand" "rM")) | |
3092 | (set (match_dup 0) | |
3093 | (plus:SI (match_dup 0) (match_dup 1)))] | |
ac153498 | 3094 | "" |
f38b27c7 | 3095 | "{stbs|stb},mb %r2,%1(%0)" |
ac153498 | 3096 | [(set_attr "type" "store") |
4c2164b7 | 3097 | (set_attr "length" "4")]) |
d2a94ec0 | 3098 | |
d8f95bed JDA |
3099 | (define_insn "" |
3100 | [(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r") | |
3101 | (match_operand:DI 1 "int5_operand" "L"))) | |
3102 | (match_operand:QI 2 "reg_or_0_operand" "rM")) | |
3103 | (set (match_dup 0) | |
3104 | (plus:DI (match_dup 0) (match_dup 1)))] | |
3105 | "TARGET_64BIT" | |
3106 | "stb,mb %r2,%1(%0)" | |
3107 | [(set_attr "type" "store") | |
3108 | (set_attr "length" "4")]) | |
3109 | ||
c733e074 | 3110 | ;; The definition of this insn does not really explain what it does, |
cdc9103c JDA |
3111 | ;; but it should suffice that anything generated as this insn will be |
3112 | ;; recognized as a movstrsi operation, and that it will not successfully | |
3113 | ;; combine with anything. | |
c733e074 | 3114 | (define_expand "movstrsi" |
e9a25f70 JL |
3115 | [(parallel [(set (match_operand:BLK 0 "" "") |
3116 | (match_operand:BLK 1 "" "")) | |
907f67cc TG |
3117 | (clobber (match_dup 4)) |
3118 | (clobber (match_dup 5)) | |
e9a25f70 | 3119 | (clobber (match_dup 6)) |
cdc9103c JDA |
3120 | (clobber (match_dup 7)) |
3121 | (clobber (match_dup 8)) | |
c733e074 TM |
3122 | (use (match_operand:SI 2 "arith_operand" "")) |
3123 | (use (match_operand:SI 3 "const_int_operand" ""))])] | |
cdc9103c | 3124 | "!TARGET_64BIT && optimize > 0" |
c733e074 TM |
3125 | " |
3126 | { | |
68944452 | 3127 | int size, align; |
e9a25f70 | 3128 | |
68944452 JL |
3129 | /* HP provides very fast block move library routine for the PA; |
3130 | this routine includes: | |
3131 | ||
3132 | 4x4 byte at a time block moves, | |
3133 | 1x4 byte at a time with alignment checked at runtime with | |
3134 | attempts to align the source and destination as needed | |
3135 | 1x1 byte loop | |
3136 | ||
3137 | With that in mind, here's the heuristics to try and guess when | |
3138 | the inlined block move will be better than the library block | |
3139 | move: | |
3140 | ||
3141 | If the size isn't constant, then always use the library routines. | |
3142 | ||
3143 | If the size is large in respect to the known alignment, then use | |
3144 | the library routines. | |
3145 | ||
cdc9103c | 3146 | If the size is small in respect to the known alignment, then open |
68944452 JL |
3147 | code the copy (since that will lead to better scheduling). |
3148 | ||
3149 | Else use the block move pattern. */ | |
3150 | ||
3151 | /* Undetermined size, use the library routine. */ | |
3152 | if (GET_CODE (operands[2]) != CONST_INT) | |
3153 | FAIL; | |
3154 | ||
3155 | size = INTVAL (operands[2]); | |
3156 | align = INTVAL (operands[3]); | |
3157 | align = align > 4 ? 4 : align; | |
3158 | ||
cdc9103c | 3159 | /* If size/alignment is large, then use the library routines. */ |
e9a25f70 | 3160 | if (size / align > 16) |
68944452 | 3161 | FAIL; |
c733e074 | 3162 | |
68944452 | 3163 | /* This does happen, but not often enough to worry much about. */ |
e9a25f70 | 3164 | if (size / align < MOVE_RATIO) |
68944452 JL |
3165 | FAIL; |
3166 | ||
3167 | /* Fall through means we're going to use our block move pattern. */ | |
e9a25f70 | 3168 | operands[0] |
792760b9 RK |
3169 | = replace_equiv_address (operands[0], |
3170 | copy_to_mode_reg (SImode, XEXP (operands[0], 0))); | |
e9a25f70 | 3171 | operands[1] |
792760b9 RK |
3172 | = replace_equiv_address (operands[1], |
3173 | copy_to_mode_reg (SImode, XEXP (operands[1], 0))); | |
907f67cc TG |
3174 | operands[4] = gen_reg_rtx (SImode); |
3175 | operands[5] = gen_reg_rtx (SImode); | |
e9a25f70 | 3176 | operands[6] = gen_reg_rtx (SImode); |
cdc9103c JDA |
3177 | operands[7] = gen_reg_rtx (SImode); |
3178 | operands[8] = gen_reg_rtx (SImode); | |
c733e074 TM |
3179 | }") |
3180 | ||
3181 | ;; The operand constraints are written like this to support both compile-time | |
cdc9103c JDA |
3182 | ;; and run-time determined byte counts. The expander and output_block_move |
3183 | ;; only support compile-time determined counts at this time. | |
3184 | ;; | |
3185 | ;; If the count is run-time determined, the register with the byte count | |
3186 | ;; is clobbered by the copying code, and therefore it is forced to operand 2. | |
3187 | ;; | |
3188 | ;; We used to clobber operands 0 and 1. However, a change to regrename.c | |
3189 | ;; broke this semantic for pseudo registers. We can't use match_scratch | |
3190 | ;; as this requires two registers in the class R1_REGS when the MEMs for | |
3191 | ;; operands 0 and 1 are both equivalent to symbolic MEMs. Thus, we are | |
3192 | ;; forced to internally copy operands 0 and 1 to operands 7 and 8, | |
3193 | ;; respectively. We then split or peephole optimize after reload. | |
3194 | (define_insn "movstrsi_prereload" | |
8f00386e JH |
3195 | [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r")) |
3196 | (mem:BLK (match_operand:SI 1 "register_operand" "r,r"))) | |
907f67cc | 3197 | (clobber (match_operand:SI 2 "register_operand" "=r,r")) ;loop cnt/tmp |
cdc9103c | 3198 | (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp1 |
68944452 | 3199 | (clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2 |
cdc9103c JDA |
3200 | (clobber (match_operand:SI 7 "register_operand" "=&r,&r")) ;item tmp3 |
3201 | (clobber (match_operand:SI 8 "register_operand" "=&r,&r")) ;item tmp4 | |
c733e074 TM |
3202 | (use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count |
3203 | (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment | |
520babc7 | 3204 | "!TARGET_64BIT" |
cdc9103c JDA |
3205 | "#" |
3206 | [(set_attr "type" "multi,multi")]) | |
3207 | ||
3208 | (define_split | |
3209 | [(parallel [(set (mem:BLK (match_operand:SI 0 "register_operand" "")) | |
3210 | (mem:BLK (match_operand:SI 1 "register_operand" ""))) | |
3211 | (clobber (match_operand:SI 2 "register_operand" "")) | |
3212 | (clobber (match_operand:SI 3 "register_operand" "")) | |
3213 | (clobber (match_operand:SI 6 "register_operand" "")) | |
3214 | (clobber (match_operand:SI 7 "register_operand" "")) | |
3215 | (clobber (match_operand:SI 8 "register_operand" "")) | |
3216 | (use (match_operand:SI 4 "arith_operand" "")) | |
3217 | (use (match_operand:SI 5 "const_int_operand" ""))])] | |
3218 | "!TARGET_64BIT && reload_completed && !flag_peephole2" | |
3219 | [(set (match_dup 7) (match_dup 0)) | |
3220 | (set (match_dup 8) (match_dup 1)) | |
3221 | (parallel [(set (mem:BLK (match_dup 7)) (mem:BLK (match_dup 8))) | |
3222 | (clobber (match_dup 2)) | |
3223 | (clobber (match_dup 3)) | |
3224 | (clobber (match_dup 6)) | |
3225 | (clobber (match_dup 7)) | |
3226 | (clobber (match_dup 8)) | |
3227 | (use (match_dup 4)) | |
3228 | (use (match_dup 5)) | |
3229 | (const_int 0)])] | |
3230 | "") | |
3231 | ||
3232 | (define_peephole2 | |
3233 | [(parallel [(set (mem:BLK (match_operand:SI 0 "register_operand" "")) | |
3234 | (mem:BLK (match_operand:SI 1 "register_operand" ""))) | |
3235 | (clobber (match_operand:SI 2 "register_operand" "")) | |
3236 | (clobber (match_operand:SI 3 "register_operand" "")) | |
3237 | (clobber (match_operand:SI 6 "register_operand" "")) | |
3238 | (clobber (match_operand:SI 7 "register_operand" "")) | |
3239 | (clobber (match_operand:SI 8 "register_operand" "")) | |
3240 | (use (match_operand:SI 4 "arith_operand" "")) | |
3241 | (use (match_operand:SI 5 "const_int_operand" ""))])] | |
3242 | "!TARGET_64BIT" | |
3243 | [(parallel [(set (mem:BLK (match_dup 7)) (mem:BLK (match_dup 8))) | |
3244 | (clobber (match_dup 2)) | |
3245 | (clobber (match_dup 3)) | |
3246 | (clobber (match_dup 6)) | |
3247 | (clobber (match_dup 7)) | |
3248 | (clobber (match_dup 8)) | |
3249 | (use (match_dup 4)) | |
3250 | (use (match_dup 5)) | |
3251 | (const_int 0)])] | |
3252 | " | |
3253 | { | |
3254 | if (dead_or_set_p (curr_insn, operands[0])) | |
3255 | operands[7] = operands[0]; | |
3256 | else | |
3257 | emit_insn (gen_rtx_SET (VOIDmode, operands[7], operands[0])); | |
3258 | ||
3259 | if (dead_or_set_p (curr_insn, operands[1])) | |
3260 | operands[8] = operands[1]; | |
3261 | else | |
3262 | emit_insn (gen_rtx_SET (VOIDmode, operands[8], operands[1])); | |
3263 | }") | |
3264 | ||
3265 | (define_insn "movstrsi_postreload" | |
3266 | [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r")) | |
3267 | (mem:BLK (match_operand:SI 1 "register_operand" "r,r"))) | |
3268 | (clobber (match_operand:SI 2 "register_operand" "=r,r")) ;loop cnt/tmp | |
3269 | (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp1 | |
3270 | (clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2 | |
3271 | (clobber (match_dup 0)) | |
3272 | (clobber (match_dup 1)) | |
3273 | (use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count | |
3274 | (use (match_operand:SI 5 "const_int_operand" "n,n")) ;alignment | |
3275 | (const_int 0)] | |
3276 | "!TARGET_64BIT && reload_completed" | |
3277 | "* return output_block_move (operands, !which_alternative);" | |
3278 | [(set_attr "type" "multi,multi")]) | |
3279 | ||
3280 | (define_expand "movstrdi" | |
3281 | [(parallel [(set (match_operand:BLK 0 "" "") | |
3282 | (match_operand:BLK 1 "" "")) | |
3283 | (clobber (match_dup 4)) | |
3284 | (clobber (match_dup 5)) | |
3285 | (clobber (match_dup 6)) | |
3286 | (clobber (match_dup 7)) | |
3287 | (clobber (match_dup 8)) | |
3288 | (use (match_operand:DI 2 "arith_operand" "")) | |
3289 | (use (match_operand:DI 3 "const_int_operand" ""))])] | |
3290 | "TARGET_64BIT && optimize > 0" | |
3291 | " | |
3292 | { | |
3293 | int size, align; | |
3294 | ||
3295 | /* HP provides very fast block move library routine for the PA; | |
3296 | this routine includes: | |
3297 | ||
3298 | 4x4 byte at a time block moves, | |
3299 | 1x4 byte at a time with alignment checked at runtime with | |
3300 | attempts to align the source and destination as needed | |
3301 | 1x1 byte loop | |
3302 | ||
3303 | With that in mind, here's the heuristics to try and guess when | |
3304 | the inlined block move will be better than the library block | |
3305 | move: | |
3306 | ||
3307 | If the size isn't constant, then always use the library routines. | |
3308 | ||
3309 | If the size is large in respect to the known alignment, then use | |
3310 | the library routines. | |
3311 | ||
3312 | If the size is small in respect to the known alignment, then open | |
3313 | code the copy (since that will lead to better scheduling). | |
3314 | ||
3315 | Else use the block move pattern. */ | |
3316 | ||
3317 | /* Undetermined size, use the library routine. */ | |
3318 | if (GET_CODE (operands[2]) != CONST_INT) | |
3319 | FAIL; | |
3320 | ||
3321 | size = INTVAL (operands[2]); | |
3322 | align = INTVAL (operands[3]); | |
3323 | align = align > 8 ? 8 : align; | |
3324 | ||
3325 | /* If size/alignment is large, then use the library routines. */ | |
3326 | if (size / align > 16) | |
3327 | FAIL; | |
3328 | ||
3329 | /* This does happen, but not often enough to worry much about. */ | |
3330 | if (size / align < MOVE_RATIO) | |
3331 | FAIL; | |
3332 | ||
3333 | /* Fall through means we're going to use our block move pattern. */ | |
3334 | operands[0] | |
3335 | = replace_equiv_address (operands[0], | |
3336 | copy_to_mode_reg (DImode, XEXP (operands[0], 0))); | |
3337 | operands[1] | |
3338 | = replace_equiv_address (operands[1], | |
3339 | copy_to_mode_reg (DImode, XEXP (operands[1], 0))); | |
3340 | operands[4] = gen_reg_rtx (DImode); | |
3341 | operands[5] = gen_reg_rtx (DImode); | |
3342 | operands[6] = gen_reg_rtx (DImode); | |
3343 | operands[7] = gen_reg_rtx (DImode); | |
3344 | operands[8] = gen_reg_rtx (DImode); | |
3345 | }") | |
3346 | ||
3347 | ;; The operand constraints are written like this to support both compile-time | |
3348 | ;; and run-time determined byte counts. The expander and output_block_move | |
3349 | ;; only support compile-time determined counts at this time. | |
3350 | ;; | |
3351 | ;; If the count is run-time determined, the register with the byte count | |
3352 | ;; is clobbered by the copying code, and therefore it is forced to operand 2. | |
3353 | ;; | |
3354 | ;; We used to clobber operands 0 and 1. However, a change to regrename.c | |
3355 | ;; broke this semantic for pseudo registers. We can't use match_scratch | |
3356 | ;; as this requires two registers in the class R1_REGS when the MEMs for | |
3357 | ;; operands 0 and 1 are both equivalent to symbolic MEMs. Thus, we are | |
3358 | ;; forced to internally copy operands 0 and 1 to operands 7 and 8, | |
3359 | ;; respectively. We then split or peephole optimize after reload. | |
3360 | (define_insn "movstrdi_prereload" | |
3361 | [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r")) | |
3362 | (mem:BLK (match_operand:DI 1 "register_operand" "r,r"))) | |
3363 | (clobber (match_operand:DI 2 "register_operand" "=r,r")) ;loop cnt/tmp | |
3364 | (clobber (match_operand:DI 3 "register_operand" "=&r,&r")) ;item tmp1 | |
3365 | (clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2 | |
3366 | (clobber (match_operand:DI 7 "register_operand" "=&r,&r")) ;item tmp3 | |
3367 | (clobber (match_operand:DI 8 "register_operand" "=&r,&r")) ;item tmp4 | |
3368 | (use (match_operand:DI 4 "arith_operand" "J,2")) ;byte count | |
3369 | (use (match_operand:DI 5 "const_int_operand" "n,n"))] ;alignment | |
3370 | "TARGET_64BIT" | |
3371 | "#" | |
3372 | [(set_attr "type" "multi,multi")]) | |
3373 | ||
3374 | (define_split | |
3375 | [(parallel [(set (mem:BLK (match_operand:DI 0 "register_operand" "")) | |
3376 | (mem:BLK (match_operand:DI 1 "register_operand" ""))) | |
3377 | (clobber (match_operand:DI 2 "register_operand" "")) | |
3378 | (clobber (match_operand:DI 3 "register_operand" "")) | |
3379 | (clobber (match_operand:DI 6 "register_operand" "")) | |
3380 | (clobber (match_operand:DI 7 "register_operand" "")) | |
3381 | (clobber (match_operand:DI 8 "register_operand" "")) | |
3382 | (use (match_operand:DI 4 "arith_operand" "")) | |
3383 | (use (match_operand:DI 5 "const_int_operand" ""))])] | |
3384 | "TARGET_64BIT && reload_completed && !flag_peephole2" | |
3385 | [(set (match_dup 7) (match_dup 0)) | |
3386 | (set (match_dup 8) (match_dup 1)) | |
3387 | (parallel [(set (mem:BLK (match_dup 7)) (mem:BLK (match_dup 8))) | |
3388 | (clobber (match_dup 2)) | |
3389 | (clobber (match_dup 3)) | |
3390 | (clobber (match_dup 6)) | |
3391 | (clobber (match_dup 7)) | |
3392 | (clobber (match_dup 8)) | |
3393 | (use (match_dup 4)) | |
3394 | (use (match_dup 5)) | |
3395 | (const_int 0)])] | |
3396 | "") | |
3397 | ||
3398 | (define_peephole2 | |
3399 | [(parallel [(set (mem:BLK (match_operand:DI 0 "register_operand" "")) | |
3400 | (mem:BLK (match_operand:DI 1 "register_operand" ""))) | |
3401 | (clobber (match_operand:DI 2 "register_operand" "")) | |
3402 | (clobber (match_operand:DI 3 "register_operand" "")) | |
3403 | (clobber (match_operand:DI 6 "register_operand" "")) | |
3404 | (clobber (match_operand:DI 7 "register_operand" "")) | |
3405 | (clobber (match_operand:DI 8 "register_operand" "")) | |
3406 | (use (match_operand:DI 4 "arith_operand" "")) | |
3407 | (use (match_operand:DI 5 "const_int_operand" ""))])] | |
3408 | "TARGET_64BIT" | |
3409 | [(parallel [(set (mem:BLK (match_dup 7)) (mem:BLK (match_dup 8))) | |
3410 | (clobber (match_dup 2)) | |
3411 | (clobber (match_dup 3)) | |
3412 | (clobber (match_dup 6)) | |
3413 | (clobber (match_dup 7)) | |
3414 | (clobber (match_dup 8)) | |
3415 | (use (match_dup 4)) | |
3416 | (use (match_dup 5)) | |
3417 | (const_int 0)])] | |
3418 | " | |
3419 | { | |
3420 | if (dead_or_set_p (curr_insn, operands[0])) | |
3421 | operands[7] = operands[0]; | |
3422 | else | |
3423 | emit_insn (gen_rtx_SET (VOIDmode, operands[7], operands[0])); | |
3424 | ||
3425 | if (dead_or_set_p (curr_insn, operands[1])) | |
3426 | operands[8] = operands[1]; | |
3427 | else | |
3428 | emit_insn (gen_rtx_SET (VOIDmode, operands[8], operands[1])); | |
3429 | }") | |
3430 | ||
3431 | (define_insn "movstrdi_postreload" | |
3432 | [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r")) | |
3433 | (mem:BLK (match_operand:DI 1 "register_operand" "r,r"))) | |
3434 | (clobber (match_operand:DI 2 "register_operand" "=r,r")) ;loop cnt/tmp | |
3435 | (clobber (match_operand:DI 3 "register_operand" "=&r,&r")) ;item tmp1 | |
3436 | (clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2 | |
3437 | (clobber (match_dup 0)) | |
3438 | (clobber (match_dup 1)) | |
3439 | (use (match_operand:DI 4 "arith_operand" "J,2")) ;byte count | |
3440 | (use (match_operand:DI 5 "const_int_operand" "n,n")) ;alignment | |
3441 | (const_int 0)] | |
3442 | "TARGET_64BIT && reload_completed" | |
c733e074 | 3443 | "* return output_block_move (operands, !which_alternative);" |
876662ef | 3444 | [(set_attr "type" "multi,multi")]) |
cdc9103c JDA |
3445 | |
3446 | (define_expand "clrstrsi" | |
3447 | [(parallel [(set (match_operand:BLK 0 "" "") | |
3448 | (const_int 0)) | |
3449 | (clobber (match_dup 3)) | |
3450 | (clobber (match_dup 4)) | |
3451 | (use (match_operand:SI 1 "arith_operand" "")) | |
3452 | (use (match_operand:SI 2 "const_int_operand" ""))])] | |
3453 | "!TARGET_64BIT && optimize > 0" | |
3454 | " | |
3455 | { | |
3456 | int size, align; | |
3457 | ||
3458 | /* Undetermined size, use the library routine. */ | |
3459 | if (GET_CODE (operands[1]) != CONST_INT) | |
3460 | FAIL; | |
3461 | ||
3462 | size = INTVAL (operands[1]); | |
3463 | align = INTVAL (operands[2]); | |
3464 | align = align > 4 ? 4 : align; | |
3465 | ||
3466 | /* If size/alignment is large, then use the library routines. */ | |
3467 | if (size / align > 16) | |
3468 | FAIL; | |
3469 | ||
3470 | /* This does happen, but not often enough to worry much about. */ | |
3471 | if (size / align < MOVE_RATIO) | |
3472 | FAIL; | |
3473 | ||
3474 | /* Fall through means we're going to use our block clear pattern. */ | |
3475 | operands[0] | |
3476 | = replace_equiv_address (operands[0], | |
3477 | copy_to_mode_reg (SImode, XEXP (operands[0], 0))); | |
3478 | operands[3] = gen_reg_rtx (SImode); | |
3479 | operands[4] = gen_reg_rtx (SImode); | |
3480 | }") | |
3481 | ||
3482 | (define_insn "clrstrsi_prereload" | |
3483 | [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r")) | |
3484 | (const_int 0)) | |
3485 | (clobber (match_operand:SI 1 "register_operand" "=r,r")) ;loop cnt/tmp | |
3486 | (clobber (match_operand:SI 4 "register_operand" "=&r,&r")) ;tmp1 | |
3487 | (use (match_operand:SI 2 "arith_operand" "J,1")) ;byte count | |
3488 | (use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment | |
3489 | "!TARGET_64BIT" | |
3490 | "#" | |
3491 | [(set_attr "type" "multi,multi")]) | |
3492 | ||
3493 | (define_split | |
3494 | [(parallel [(set (mem:BLK (match_operand:SI 0 "register_operand" "")) | |
3495 | (const_int 0)) | |
3496 | (clobber (match_operand:SI 1 "register_operand" "")) | |
3497 | (clobber (match_operand:SI 4 "register_operand" "")) | |
3498 | (use (match_operand:SI 2 "arith_operand" "")) | |
3499 | (use (match_operand:SI 3 "const_int_operand" ""))])] | |
3500 | "!TARGET_64BIT && reload_completed && !flag_peephole2" | |
3501 | [(set (match_dup 4) (match_dup 0)) | |
3502 | (parallel [(set (mem:BLK (match_dup 4)) (const_int 0)) | |
3503 | (clobber (match_dup 1)) | |
3504 | (clobber (match_dup 4)) | |
3505 | (use (match_dup 2)) | |
3506 | (use (match_dup 3)) | |
3507 | (const_int 0)])] | |
3508 | "") | |
3509 | ||
3510 | (define_peephole2 | |
3511 | [(parallel [(set (mem:BLK (match_operand:SI 0 "register_operand" "")) | |
3512 | (const_int 0)) | |
3513 | (clobber (match_operand:SI 1 "register_operand" "")) | |
3514 | (clobber (match_operand:SI 4 "register_operand" "")) | |
3515 | (use (match_operand:SI 2 "arith_operand" "")) | |
3516 | (use (match_operand:SI 3 "const_int_operand" ""))])] | |
3517 | "!TARGET_64BIT" | |
3518 | [(parallel [(set (mem:BLK (match_dup 4)) (const_int 0)) | |
3519 | (clobber (match_dup 1)) | |
3520 | (clobber (match_dup 4)) | |
3521 | (use (match_dup 2)) | |
3522 | (use (match_dup 3)) | |
3523 | (const_int 0)])] | |
3524 | " | |
3525 | { | |
3526 | if (dead_or_set_p (curr_insn, operands[0])) | |
3527 | operands[4] = operands[0]; | |
3528 | else | |
3529 | emit_insn (gen_rtx_SET (VOIDmode, operands[4], operands[0])); | |
3530 | }") | |
3531 | ||
3532 | (define_insn "clrstrsi_postreload" | |
3533 | [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r")) | |
3534 | (const_int 0)) | |
3535 | (clobber (match_operand:SI 1 "register_operand" "=r,r")) ;loop cnt/tmp | |
3536 | (clobber (match_dup 0)) | |
3537 | (use (match_operand:SI 2 "arith_operand" "J,1")) ;byte count | |
3538 | (use (match_operand:SI 3 "const_int_operand" "n,n")) ;alignment | |
3539 | (const_int 0)] | |
3540 | "!TARGET_64BIT && reload_completed" | |
3541 | "* return output_block_clear (operands, !which_alternative);" | |
3542 | [(set_attr "type" "multi,multi")]) | |
3543 | ||
3544 | (define_expand "clrstrdi" | |
3545 | [(parallel [(set (match_operand:BLK 0 "" "") | |
3546 | (const_int 0)) | |
3547 | (clobber (match_dup 3)) | |
3548 | (clobber (match_dup 4)) | |
3549 | (use (match_operand:DI 1 "arith_operand" "")) | |
3550 | (use (match_operand:DI 2 "const_int_operand" ""))])] | |
3551 | "TARGET_64BIT && optimize > 0" | |
3552 | " | |
3553 | { | |
3554 | int size, align; | |
3555 | ||
3556 | /* Undetermined size, use the library routine. */ | |
3557 | if (GET_CODE (operands[1]) != CONST_INT) | |
3558 | FAIL; | |
3559 | ||
3560 | size = INTVAL (operands[1]); | |
3561 | align = INTVAL (operands[2]); | |
3562 | align = align > 8 ? 8 : align; | |
3563 | ||
3564 | /* If size/alignment is large, then use the library routines. */ | |
3565 | if (size / align > 16) | |
3566 | FAIL; | |
3567 | ||
3568 | /* This does happen, but not often enough to worry much about. */ | |
3569 | if (size / align < MOVE_RATIO) | |
3570 | FAIL; | |
3571 | ||
3572 | /* Fall through means we're going to use our block clear pattern. */ | |
3573 | operands[0] | |
3574 | = replace_equiv_address (operands[0], | |
3575 | copy_to_mode_reg (DImode, XEXP (operands[0], 0))); | |
3576 | operands[3] = gen_reg_rtx (DImode); | |
3577 | operands[4] = gen_reg_rtx (DImode); | |
3578 | }") | |
3579 | ||
3580 | (define_insn "clrstrdi_prereload" | |
3581 | [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r")) | |
3582 | (const_int 0)) | |
3583 | (clobber (match_operand:DI 1 "register_operand" "=r,r")) ;loop cnt/tmp | |
3584 | (clobber (match_operand:DI 4 "register_operand" "=&r,&r")) ;item tmp1 | |
3585 | (use (match_operand:DI 2 "arith_operand" "J,1")) ;byte count | |
3586 | (use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment | |
3587 | "TARGET_64BIT" | |
3588 | "#" | |
3589 | [(set_attr "type" "multi,multi")]) | |
3590 | ||
3591 | (define_split | |
3592 | [(parallel [(set (mem:BLK (match_operand:DI 0 "register_operand" "")) | |
3593 | (const_int 0)) | |
3594 | (clobber (match_operand:DI 1 "register_operand" "")) | |
3595 | (clobber (match_operand:DI 4 "register_operand" "")) | |
3596 | (use (match_operand:DI 2 "arith_operand" "")) | |
3597 | (use (match_operand:DI 3 "const_int_operand" ""))])] | |
3598 | "TARGET_64BIT && reload_completed && !flag_peephole2" | |
3599 | [(set (match_dup 4) (match_dup 0)) | |
3600 | (parallel [(set (mem:BLK (match_dup 4)) (const_int 0)) | |
3601 | (clobber (match_dup 1)) | |
3602 | (clobber (match_dup 4)) | |
3603 | (use (match_dup 2)) | |
3604 | (use (match_dup 3)) | |
3605 | (const_int 0)])] | |
3606 | "") | |
3607 | ||
3608 | (define_peephole2 | |
3609 | [(parallel [(set (mem:BLK (match_operand:DI 0 "register_operand" "")) | |
3610 | (const_int 0)) | |
3611 | (clobber (match_operand:DI 1 "register_operand" "")) | |
3612 | (clobber (match_operand:DI 4 "register_operand" "")) | |
3613 | (use (match_operand:DI 2 "arith_operand" "")) | |
3614 | (use (match_operand:DI 3 "const_int_operand" ""))])] | |
3615 | "TARGET_64BIT" | |
3616 | [(parallel [(set (mem:BLK (match_dup 4)) (const_int 0)) | |
3617 | (clobber (match_dup 1)) | |
3618 | (clobber (match_dup 4)) | |
3619 | (use (match_dup 2)) | |
3620 | (use (match_dup 3)) | |
3621 | (const_int 0)])] | |
3622 | " | |
3623 | { | |
3624 | if (dead_or_set_p (curr_insn, operands[0])) | |
3625 | operands[4] = operands[0]; | |
3626 | else | |
3627 | emit_insn (gen_rtx_SET (VOIDmode, operands[4], operands[0])); | |
3628 | }") | |
3629 | ||
3630 | (define_insn "clrstrdi_postreload" | |
3631 | [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r")) | |
3632 | (const_int 0)) | |
3633 | (clobber (match_operand:DI 1 "register_operand" "=r,r")) ;loop cnt/tmp | |
3634 | (clobber (match_dup 0)) | |
3635 | (use (match_operand:DI 2 "arith_operand" "J,1")) ;byte count | |
3636 | (use (match_operand:DI 3 "const_int_operand" "n,n")) ;alignment | |
3637 | (const_int 0)] | |
3638 | "TARGET_64BIT && reload_completed" | |
3639 | "* return output_block_clear (operands, !which_alternative);" | |
3640 | [(set_attr "type" "multi,multi")]) | |
c733e074 TM |
3641 | \f |
3642 | ;; Floating point move insns | |
3643 | ||
3644 | ;; This pattern forces (set (reg:DF ...) (const_double ...)) | |
ae98fe09 RS |
3645 | ;; to be reloaded by putting the constant into memory when |
3646 | ;; reg is a floating point register. | |
3647 | ;; | |
3648 | ;; For integer registers we use ldil;ldo to set the appropriate | |
3649 | ;; value. | |
2f95ebc2 | 3650 | ;; |
ae98fe09 RS |
3651 | ;; This must come before the movdf pattern, and it must be present |
3652 | ;; to handle obscure reloading cases. | |
c733e074 | 3653 | (define_insn "" |
cda0f51e | 3654 | [(set (match_operand:DF 0 "register_operand" "=?r,f") |
925cf581 | 3655 | (match_operand:DF 1 "" "?F,m"))] |
222727e8 | 3656 | "GET_CODE (operands[1]) == CONST_DOUBLE |
925cf581 | 3657 | && operands[1] != CONST0_RTX (DFmode) |
520babc7 | 3658 | && !TARGET_64BIT |
d8f95bed | 3659 | && !TARGET_SOFT_FLOAT" |
ae98fe09 | 3660 | "* return (which_alternative == 0 ? output_move_double (operands) |
2414e0e2 | 3661 | : \"fldd%F1 %1,%0\");" |
ae98fe09 | 3662 | [(set_attr "type" "move,fpload") |
4c2164b7 | 3663 | (set_attr "length" "16,4")]) |
c733e074 TM |
3664 | |
3665 | (define_expand "movdf" | |
3666 | [(set (match_operand:DF 0 "general_operand" "") | |
3667 | (match_operand:DF 1 "general_operand" ""))] | |
3668 | "" | |
3669 | " | |
3670 | { | |
520babc7 | 3671 | if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT) |
d8f95bed | 3672 | operands[1] = force_const_mem (DFmode, operands[1]); |
520babc7 | 3673 | |
d2a94ec0 | 3674 | if (emit_move_sequence (operands, DFmode, 0)) |
c733e074 TM |
3675 | DONE; |
3676 | }") | |
3677 | ||
0fc4f911 RK |
3678 | ;; Reloading an SImode or DImode value requires a scratch register if |
3679 | ;; going in to or out of float point registers. | |
3680 | ||
3681 | (define_expand "reload_indf" | |
3682 | [(set (match_operand:DF 0 "register_operand" "=Z") | |
3683 | (match_operand:DF 1 "non_hard_reg_operand" "")) | |
3684 | (clobber (match_operand:DF 2 "register_operand" "=&r"))] | |
3685 | "" | |
3686 | " | |
3687 | { | |
3688 | if (emit_move_sequence (operands, DFmode, operands[2])) | |
3689 | DONE; | |
3690 | ||
3691 | /* We don't want the clobber emitted, so handle this ourselves. */ | |
ad2c71b7 | 3692 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); |
0fc4f911 RK |
3693 | DONE; |
3694 | }") | |
3695 | ||
3696 | (define_expand "reload_outdf" | |
3697 | [(set (match_operand:DF 0 "non_hard_reg_operand" "") | |
3698 | (match_operand:DF 1 "register_operand" "Z")) | |
3699 | (clobber (match_operand:DF 2 "register_operand" "=&r"))] | |
3700 | "" | |
3701 | " | |
3702 | { | |
3703 | if (emit_move_sequence (operands, DFmode, operands[2])) | |
3704 | DONE; | |
3705 | ||
3706 | /* We don't want the clobber emitted, so handle this ourselves. */ | |
ad2c71b7 | 3707 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); |
0fc4f911 RK |
3708 | DONE; |
3709 | }") | |
3710 | ||
c733e074 | 3711 | (define_insn "" |
d8f95bed JDA |
3712 | [(set (match_operand:DF 0 "move_dest_operand" |
3713 | "=f,*r,Q,?o,?Q,f,*r,*r") | |
222727e8 | 3714 | (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" |
a89974a2 | 3715 | "fG,*rG,f,*r,*r,RQ,o,RQ"))] |
925cf581 TG |
3716 | "(register_operand (operands[0], DFmode) |
3717 | || reg_or_0_operand (operands[1], DFmode)) | |
d8f95bed JDA |
3718 | && !(GET_CODE (operands[1]) == CONST_DOUBLE |
3719 | && GET_CODE (operands[0]) == MEM) | |
3720 | && !TARGET_64BIT | |
3721 | && !TARGET_SOFT_FLOAT" | |
c733e074 TM |
3722 | "* |
3723 | { | |
2f95ebc2 | 3724 | if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]) |
222727e8 | 3725 | || operands[1] == CONST0_RTX (DFmode)) |
c733e074 TM |
3726 | return output_fp_move_double (operands); |
3727 | return output_move_double (operands); | |
3728 | }" | |
9d53c942 JL |
3729 | [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load") |
3730 | (set_attr "length" "4,8,4,8,16,4,8,16")]) | |
c733e074 | 3731 | |
925cf581 | 3732 | (define_insn "" |
d8f95bed JDA |
3733 | [(set (match_operand:DF 0 "indexed_memory_operand" "=R") |
3734 | (match_operand:DF 1 "reg_or_0_operand" "f"))] | |
3735 | "!TARGET_SOFT_FLOAT | |
3736 | && !TARGET_DISABLE_INDEXING | |
3737 | && reload_completed" | |
3738 | "fstd%F0 %1,%0" | |
3739 | [(set_attr "type" "fpstore") | |
3740 | (set_attr "pa_combine_type" "addmove") | |
3741 | (set_attr "length" "4")]) | |
3742 | ||
3743 | (define_peephole2 | |
3744 | [(set (match_operand:SI 0 "register_operand" "") | |
3745 | (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "") | |
3746 | (const_int 8)) | |
3747 | (match_operand:SI 2 "register_operand" ""))) | |
3748 | (set (mem:DF (match_dup 0)) | |
3749 | (match_operand:DF 3 "register_operand" ""))] | |
3750 | "!TARGET_SOFT_FLOAT | |
3751 | && REG_OK_FOR_BASE_P (operands[2]) | |
3752 | && FP_REGNO_P (REGNO (operands[3]))" | |
3753 | [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2))) | |
3754 | (match_dup 3)) | |
3755 | (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8)) | |
3756 | (match_dup 2)))] | |
3757 | "") | |
3758 | ||
3759 | (define_peephole2 | |
3760 | [(set (match_operand:SI 0 "register_operand" "") | |
3761 | (plus:SI (match_operand:SI 2 "register_operand" "") | |
3762 | (mult:SI (match_operand:SI 1 "register_operand" "") | |
3763 | (const_int 8)))) | |
3764 | (set (mem:DF (match_dup 0)) | |
3765 | (match_operand:DF 3 "register_operand" ""))] | |
3766 | "!TARGET_SOFT_FLOAT | |
3767 | && REG_OK_FOR_BASE_P (operands[2]) | |
3768 | && FP_REGNO_P (REGNO (operands[3]))" | |
3769 | [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2))) | |
3770 | (match_dup 3)) | |
3771 | (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8)) | |
3772 | (match_dup 2)))] | |
3773 | "") | |
3774 | ||
3775 | (define_peephole2 | |
3776 | [(set (match_operand:DI 0 "register_operand" "") | |
3777 | (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "") | |
3778 | (const_int 8)) | |
3779 | (match_operand:DI 2 "register_operand" ""))) | |
3780 | (set (mem:DF (match_dup 0)) | |
3781 | (match_operand:DF 3 "register_operand" ""))] | |
3782 | "!TARGET_SOFT_FLOAT | |
3783 | && TARGET_64BIT | |
3784 | && REG_OK_FOR_BASE_P (operands[2]) | |
3785 | && FP_REGNO_P (REGNO (operands[3]))" | |
3786 | [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2))) | |
3787 | (match_dup 3)) | |
3788 | (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8)) | |
3789 | (match_dup 2)))] | |
3790 | "") | |
3791 | ||
3792 | (define_peephole2 | |
3793 | [(set (match_operand:DI 0 "register_operand" "") | |
3794 | (plus:DI (match_operand:DI 2 "register_operand" "") | |
3795 | (mult:DI (match_operand:DI 1 "register_operand" "") | |
3796 | (const_int 8)))) | |
3797 | (set (mem:DF (match_dup 0)) | |
3798 | (match_operand:DF 3 "register_operand" ""))] | |
3799 | "!TARGET_SOFT_FLOAT | |
3800 | && TARGET_64BIT | |
3801 | && REG_OK_FOR_BASE_P (operands[2]) | |
3802 | && FP_REGNO_P (REGNO (operands[3]))" | |
3803 | [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2))) | |
3804 | (match_dup 3)) | |
3805 | (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8)) | |
3806 | (match_dup 2)))] | |
3807 | "") | |
3808 | ||
3809 | (define_peephole2 | |
3810 | [(set (match_operand:SI 0 "register_operand" "") | |
3811 | (plus:SI (match_operand:SI 1 "register_operand" "") | |
3812 | (match_operand:SI 2 "register_operand" ""))) | |
3813 | (set (mem:DF (match_dup 0)) | |
3814 | (match_operand:DF 3 "register_operand" ""))] | |
3815 | "!TARGET_SOFT_FLOAT | |
3816 | && REG_OK_FOR_BASE_P (operands[1]) | |
3817 | && (TARGET_NO_SPACE_REGS | |
3818 | || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2]))) | |
3819 | && FP_REGNO_P (REGNO (operands[3]))" | |
3820 | [(set (mem:DF (plus:SI (match_dup 1) (match_dup 2))) | |
3821 | (match_dup 3)) | |
3822 | (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))] | |
3823 | "") | |
3824 | ||
3825 | (define_peephole2 | |
3826 | [(set (match_operand:SI 0 "register_operand" "") | |
3827 | (plus:SI (match_operand:SI 1 "register_operand" "") | |
3828 | (match_operand:SI 2 "register_operand" ""))) | |
3829 | (set (mem:DF (match_dup 0)) | |
3830 | (match_operand:DF 3 "register_operand" ""))] | |
3831 | "!TARGET_SOFT_FLOAT | |
3832 | && REG_OK_FOR_BASE_P (operands[2]) | |
3833 | && (TARGET_NO_SPACE_REGS | |
3834 | || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2]))) | |
3835 | && FP_REGNO_P (REGNO (operands[3]))" | |
3836 | [(set (mem:DF (plus:SI (match_dup 2) (match_dup 1))) | |
3837 | (match_dup 3)) | |
3838 | (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))] | |
3839 | "") | |
3840 | ||
3841 | (define_peephole2 | |
3842 | [(set (match_operand:DI 0 "register_operand" "") | |
3843 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
3844 | (match_operand:DI 2 "register_operand" ""))) | |
3845 | (set (mem:DF (match_dup 0)) | |
3846 | (match_operand:DF 3 "register_operand" ""))] | |
3847 | "!TARGET_SOFT_FLOAT | |
3848 | && TARGET_64BIT | |
3849 | && REG_OK_FOR_BASE_P (operands[1]) | |
3850 | && (TARGET_NO_SPACE_REGS | |
3851 | || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2]))) | |
3852 | && FP_REGNO_P (REGNO (operands[3]))" | |
3853 | [(set (mem:DF (plus:DI (match_dup 1) (match_dup 2))) | |
3854 | (match_dup 3)) | |
3855 | (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] | |
3856 | "") | |
3857 | ||
3858 | (define_peephole2 | |
3859 | [(set (match_operand:DI 0 "register_operand" "") | |
3860 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
3861 | (match_operand:DI 2 "register_operand" ""))) | |
3862 | (set (mem:DF (match_dup 0)) | |
3863 | (match_operand:DF 3 "register_operand" ""))] | |
3864 | "!TARGET_SOFT_FLOAT | |
3865 | && TARGET_64BIT | |
3866 | && REG_OK_FOR_BASE_P (operands[2]) | |
3867 | && (TARGET_NO_SPACE_REGS | |
3868 | || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2]))) | |
3869 | && FP_REGNO_P (REGNO (operands[3]))" | |
3870 | [(set (mem:DF (plus:DI (match_dup 2) (match_dup 1))) | |
3871 | (match_dup 3)) | |
3872 | (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))] | |
3873 | "") | |
3874 | ||
3875 | (define_insn "" | |
3876 | [(set (match_operand:DF 0 "move_dest_operand" | |
bad883f8 | 3877 | "=r,?o,?Q,r,r") |
925cf581 | 3878 | (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" |
d8f95bed | 3879 | "rG,r,r,o,RQ"))] |
925cf581 TG |
3880 | "(register_operand (operands[0], DFmode) |
3881 | || reg_or_0_operand (operands[1], DFmode)) | |
d8f95bed | 3882 | && !TARGET_64BIT |
925cf581 TG |
3883 | && TARGET_SOFT_FLOAT" |
3884 | "* | |
3885 | { | |
3886 | return output_move_double (operands); | |
3887 | }" | |
3888 | [(set_attr "type" "move,store,store,load,load") | |
3889 | (set_attr "length" "8,8,16,8,16")]) | |
3890 | ||
520babc7 | 3891 | (define_insn "" |
d8f95bed JDA |
3892 | [(set (match_operand:DF 0 "move_dest_operand" |
3893 | "=!*r,*r,*r,*r,*r,Q,!*q,f,f,T") | |
3894 | (match_operand:DF 1 "move_src_operand" | |
3895 | "!*r,J,N,K,RQ,*rM,!*rM,fM,RT,f"))] | |
520babc7 JL |
3896 | "(register_operand (operands[0], DFmode) |
3897 | || reg_or_0_operand (operands[1], DFmode)) | |
d8f95bed | 3898 | && !TARGET_SOFT_FLOAT && TARGET_64BIT" |
520babc7 JL |
3899 | "@ |
3900 | copy %1,%0 | |
3901 | ldi %1,%0 | |
3902 | ldil L'%1,%0 | |
3903 | depdi,z %z1,%0 | |
3904 | ldd%M1 %1,%0 | |
3905 | std%M0 %r1,%0 | |
3906 | mtsar %r1 | |
3907 | fcpy,dbl %f1,%0 | |
3908 | fldd%F1 %1,%0 | |
3909 | fstd%F0 %1,%0" | |
3910 | [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore") | |
3911 | (set_attr "pa_combine_type" "addmove") | |
3912 | (set_attr "length" "4,4,4,4,4,4,4,4,4,4")]) | |
3913 | ||
d8f95bed | 3914 | \f |
c733e074 | 3915 | (define_expand "movdi" |
d8f95bed | 3916 | [(set (match_operand:DI 0 "general_operand" "") |
c733e074 TM |
3917 | (match_operand:DI 1 "general_operand" ""))] |
3918 | "" | |
3919 | " | |
3920 | { | |
520babc7 | 3921 | if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT) |
d8f95bed | 3922 | operands[1] = force_const_mem (DImode, operands[1]); |
520babc7 | 3923 | |
d2a94ec0 | 3924 | if (emit_move_sequence (operands, DImode, 0)) |
c733e074 TM |
3925 | DONE; |
3926 | }") | |
3927 | ||
0fc4f911 | 3928 | (define_expand "reload_indi" |
1984b4af | 3929 | [(set (match_operand:DI 0 "register_operand" "=Z") |
0fc4f911 | 3930 | (match_operand:DI 1 "non_hard_reg_operand" "")) |
f8b20fd0 | 3931 | (clobber (match_operand:SI 2 "register_operand" "=&r"))] |
0fc4f911 RK |
3932 | "" |
3933 | " | |
3934 | { | |
3935 | if (emit_move_sequence (operands, DImode, operands[2])) | |
3936 | DONE; | |
3937 | ||
3938 | /* We don't want the clobber emitted, so handle this ourselves. */ | |
ad2c71b7 | 3939 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); |
0fc4f911 RK |
3940 | DONE; |
3941 | }") | |
3942 | ||
3943 | (define_expand "reload_outdi" | |
75d71b2f | 3944 | [(set (match_operand:DI 0 "non_hard_reg_operand" "") |
1984b4af | 3945 | (match_operand:DI 1 "register_operand" "Z")) |
f8b20fd0 | 3946 | (clobber (match_operand:SI 2 "register_operand" "=&r"))] |
0fc4f911 RK |
3947 | "" |
3948 | " | |
3949 | { | |
3950 | if (emit_move_sequence (operands, DImode, operands[2])) | |
3951 | DONE; | |
3952 | ||
3953 | /* We don't want the clobber emitted, so handle this ourselves. */ | |
ad2c71b7 | 3954 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); |
0fc4f911 RK |
3955 | DONE; |
3956 | }") | |
3957 | ||
53a66787 TG |
3958 | (define_insn "" |
3959 | [(set (match_operand:DI 0 "register_operand" "=r") | |
3960 | (high:DI (match_operand 1 "" "")))] | |
520babc7 | 3961 | "!TARGET_64BIT" |
53a66787 TG |
3962 | "* |
3963 | { | |
3964 | rtx op0 = operands[0]; | |
3965 | rtx op1 = operands[1]; | |
3966 | ||
3967 | if (GET_CODE (op1) == CONST_INT) | |
3968 | { | |
3969 | operands[0] = operand_subword (op0, 1, 0, DImode); | |
3970 | output_asm_insn (\"ldil L'%1,%0\", operands); | |
3971 | ||
3972 | operands[0] = operand_subword (op0, 0, 0, DImode); | |
3973 | if (INTVAL (op1) < 0) | |
ac153498 | 3974 | output_asm_insn (\"ldi -1,%0\", operands); |
53a66787 | 3975 | else |
ac153498 | 3976 | output_asm_insn (\"ldi 0,%0\", operands); |
876662ef | 3977 | return \"\"; |
53a66787 TG |
3978 | } |
3979 | else if (GET_CODE (op1) == CONST_DOUBLE) | |
3980 | { | |
3981 | operands[0] = operand_subword (op0, 1, 0, DImode); | |
5dee33ac | 3982 | operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1)); |
53a66787 TG |
3983 | output_asm_insn (\"ldil L'%1,%0\", operands); |
3984 | ||
3985 | operands[0] = operand_subword (op0, 0, 0, DImode); | |
5dee33ac | 3986 | operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1)); |
53a66787 | 3987 | output_asm_insn (singlemove_string (operands), operands); |
876662ef | 3988 | return \"\"; |
53a66787 TG |
3989 | } |
3990 | else | |
3991 | abort (); | |
3992 | }" | |
3993 | [(set_attr "type" "move") | |
4c2164b7 | 3994 | (set_attr "length" "8")]) |
53a66787 | 3995 | |
c733e074 | 3996 | (define_insn "" |
d8f95bed JDA |
3997 | [(set (match_operand:DI 0 "move_dest_operand" |
3998 | "=r,o,Q,r,r,r,*f,*f,T") | |
c733e074 | 3999 | (match_operand:DI 1 "general_operand" |
d8f95bed | 4000 | "rM,r,r,o*R,Q,i,*fM,RT,*f"))] |
925cf581 TG |
4001 | "(register_operand (operands[0], DImode) |
4002 | || reg_or_0_operand (operands[1], DImode)) | |
d8f95bed JDA |
4003 | && !TARGET_64BIT |
4004 | && !TARGET_SOFT_FLOAT" | |
c733e074 TM |
4005 | "* |
4006 | { | |
222727e8 JL |
4007 | if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]) |
4008 | || (operands[1] == CONST0_RTX (DImode))) | |
c733e074 TM |
4009 | return output_fp_move_double (operands); |
4010 | return output_move_double (operands); | |
4011 | }" | |
c47decad | 4012 | [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore") |
9d53c942 | 4013 | (set_attr "length" "8,8,16,8,16,16,4,4,4")]) |
c733e074 | 4014 | |
520babc7 | 4015 | (define_insn "" |
d8f95bed JDA |
4016 | [(set (match_operand:DI 0 "move_dest_operand" |
4017 | "=r,r,r,r,r,r,Q,!*q,!*f,*f,T") | |
4018 | (match_operand:DI 1 "move_src_operand" | |
4019 | "A,r,J,N,K,RQ,rM,!rM,!*fM,RT,*f"))] | |
520babc7 JL |
4020 | "(register_operand (operands[0], DImode) |
4021 | || reg_or_0_operand (operands[1], DImode)) | |
d8f95bed | 4022 | && !TARGET_SOFT_FLOAT && TARGET_64BIT" |
520babc7 | 4023 | "@ |
f8eb41cc | 4024 | ldd RT'%A1,%0 |
520babc7 JL |
4025 | copy %1,%0 |
4026 | ldi %1,%0 | |
4027 | ldil L'%1,%0 | |
4028 | depdi,z %z1,%0 | |
4029 | ldd%M1 %1,%0 | |
4030 | std%M0 %r1,%0 | |
4031 | mtsar %r1 | |
4032 | fcpy,dbl %f1,%0 | |
4033 | fldd%F1 %1,%0 | |
4034 | fstd%F0 %1,%0" | |
f8eb41cc | 4035 | [(set_attr "type" "load,move,move,move,shift,load,store,move,fpalu,fpload,fpstore") |
520babc7 | 4036 | (set_attr "pa_combine_type" "addmove") |
f8eb41cc | 4037 | (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")]) |
520babc7 | 4038 | |
925cf581 | 4039 | (define_insn "" |
d8f95bed JDA |
4040 | [(set (match_operand:DI 0 "indexed_memory_operand" "=R") |
4041 | (match_operand:DI 1 "register_operand" "f"))] | |
4042 | "!TARGET_SOFT_FLOAT | |
4043 | && TARGET_64BIT | |
4044 | && !TARGET_DISABLE_INDEXING | |
4045 | && reload_completed" | |
4046 | "fstd%F0 %1,%0" | |
4047 | [(set_attr "type" "fpstore") | |
4048 | (set_attr "pa_combine_type" "addmove") | |
4049 | (set_attr "length" "4")]) | |
4050 | ||
4051 | (define_peephole2 | |
4052 | [(set (match_operand:DI 0 "register_operand" "") | |
4053 | (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "") | |
4054 | (const_int 8)) | |
4055 | (match_operand:DI 2 "register_operand" ""))) | |
4056 | (set (mem:DI (match_dup 0)) | |
4057 | (match_operand:DI 3 "register_operand" ""))] | |
4058 | "!TARGET_SOFT_FLOAT | |
4059 | && TARGET_64BIT | |
4060 | && REG_OK_FOR_BASE_P (operands[2]) | |
4061 | && FP_REGNO_P (REGNO (operands[3]))" | |
4062 | [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2))) | |
4063 | (match_dup 3)) | |
4064 | (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8)) | |
4065 | (match_dup 2)))] | |
4066 | "") | |
4067 | ||
4068 | (define_peephole2 | |
4069 | [(set (match_operand:DI 0 "register_operand" "") | |
4070 | (plus:DI (match_operand:DI 2 "register_operand" "") | |
4071 | (mult:DI (match_operand:DI 1 "register_operand" "") | |
4072 | (const_int 8)))) | |
4073 | (set (mem:DI (match_dup 0)) | |
4074 | (match_operand:DI 3 "register_operand" ""))] | |
4075 | "!TARGET_SOFT_FLOAT | |
4076 | && TARGET_64BIT | |
4077 | && REG_OK_FOR_BASE_P (operands[2]) | |
4078 | && FP_REGNO_P (REGNO (operands[3]))" | |
4079 | [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2))) | |
4080 | (match_dup 3)) | |
4081 | (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8)) | |
4082 | (match_dup 2)))] | |
4083 | "") | |
4084 | ||
4085 | (define_peephole2 | |
4086 | [(set (match_operand:DI 0 "register_operand" "") | |
4087 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
4088 | (match_operand:DI 2 "register_operand" ""))) | |
4089 | (set (mem:DI (match_dup 0)) | |
4090 | (match_operand:DI 3 "register_operand" ""))] | |
4091 | "!TARGET_SOFT_FLOAT | |
4092 | && TARGET_64BIT | |
4093 | && REG_OK_FOR_BASE_P (operands[1]) | |
4094 | && (TARGET_NO_SPACE_REGS | |
4095 | || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2]))) | |
4096 | && FP_REGNO_P (REGNO (operands[3]))" | |
4097 | [(set (mem:DI (plus:DI (match_dup 1) (match_dup 2))) | |
4098 | (match_dup 3)) | |
4099 | (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] | |
4100 | "") | |
4101 | ||
4102 | (define_peephole2 | |
4103 | [(set (match_operand:DI 0 "register_operand" "") | |
4104 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
4105 | (match_operand:DI 2 "register_operand" ""))) | |
4106 | (set (mem:DI (match_dup 0)) | |
4107 | (match_operand:DI 3 "register_operand" ""))] | |
4108 | "!TARGET_SOFT_FLOAT | |
4109 | && TARGET_64BIT | |
4110 | && REG_OK_FOR_BASE_P (operands[2]) | |
4111 | && (TARGET_NO_SPACE_REGS | |
4112 | || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2]))) | |
4113 | && FP_REGNO_P (REGNO (operands[3]))" | |
4114 | [(set (mem:DI (plus:DI (match_dup 2) (match_dup 1))) | |
4115 | (match_dup 3)) | |
4116 | (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))] | |
4117 | "") | |
4118 | ||
4119 | (define_insn "" | |
4120 | [(set (match_operand:DI 0 "move_dest_operand" | |
bad883f8 | 4121 | "=r,o,Q,r,r,r") |
925cf581 TG |
4122 | (match_operand:DI 1 "general_operand" |
4123 | "rM,r,r,o,Q,i"))] | |
4124 | "(register_operand (operands[0], DImode) | |
4125 | || reg_or_0_operand (operands[1], DImode)) | |
d8f95bed | 4126 | && !TARGET_64BIT |
925cf581 TG |
4127 | && TARGET_SOFT_FLOAT" |
4128 | "* | |
4129 | { | |
4130 | return output_move_double (operands); | |
4131 | }" | |
cc5c9c48 | 4132 | [(set_attr "type" "move,store,store,load,load,multi") |
925cf581 TG |
4133 | (set_attr "length" "8,8,16,8,16,16")]) |
4134 | ||
53a66787 | 4135 | (define_insn "" |
d13a220a | 4136 | [(set (match_operand:DI 0 "register_operand" "=r,&r") |
53a66787 | 4137 | (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r") |
907f67cc | 4138 | (match_operand:DI 2 "immediate_operand" "i,i")))] |
520babc7 | 4139 | "!TARGET_64BIT" |
53a66787 TG |
4140 | "* |
4141 | { | |
4142 | /* Don't output a 64 bit constant, since we can't trust the assembler to | |
4143 | handle it correctly. */ | |
4144 | if (GET_CODE (operands[2]) == CONST_DOUBLE) | |
5dee33ac | 4145 | operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2])); |
53a66787 TG |
4146 | if (which_alternative == 1) |
4147 | output_asm_insn (\"copy %1,%0\", operands); | |
4148 | return \"ldo R'%G2(%R1),%R0\"; | |
4149 | }" | |
c47decad JL |
4150 | [(set_attr "type" "move,move") |
4151 | (set_attr "length" "4,8")]) | |
53a66787 | 4152 | |
ae98fe09 RS |
4153 | ;; This pattern forces (set (reg:SF ...) (const_double ...)) |
4154 | ;; to be reloaded by putting the constant into memory when | |
4155 | ;; reg is a floating point register. | |
4156 | ;; | |
4157 | ;; For integer registers we use ldil;ldo to set the appropriate | |
4158 | ;; value. | |
2f95ebc2 | 4159 | ;; |
ae98fe09 RS |
4160 | ;; This must come before the movsf pattern, and it must be present |
4161 | ;; to handle obscure reloading cases. | |
4162 | (define_insn "" | |
cda0f51e | 4163 | [(set (match_operand:SF 0 "register_operand" "=?r,f") |
925cf581 | 4164 | (match_operand:SF 1 "" "?F,m"))] |
ae98fe09 | 4165 | "GET_CODE (operands[1]) == CONST_DOUBLE |
925cf581 TG |
4166 | && operands[1] != CONST0_RTX (SFmode) |
4167 | && ! TARGET_SOFT_FLOAT" | |
ae98fe09 | 4168 | "* return (which_alternative == 0 ? singlemove_string (operands) |
2414e0e2 | 4169 | : \" fldw%F1 %1,%0\");" |
ae98fe09 | 4170 | [(set_attr "type" "move,fpload") |
4c2164b7 | 4171 | (set_attr "length" "8,4")]) |
ae98fe09 | 4172 | |
c733e074 TM |
4173 | (define_expand "movsf" |
4174 | [(set (match_operand:SF 0 "general_operand" "") | |
4175 | (match_operand:SF 1 "general_operand" ""))] | |
4176 | "" | |
4177 | " | |
4178 | { | |
d2a94ec0 | 4179 | if (emit_move_sequence (operands, SFmode, 0)) |
c733e074 TM |
4180 | DONE; |
4181 | }") | |
4182 | ||
0fc4f911 RK |
4183 | ;; Reloading an SImode or DImode value requires a scratch register if |
4184 | ;; going in to or out of float point registers. | |
4185 | ||
4186 | (define_expand "reload_insf" | |
4187 | [(set (match_operand:SF 0 "register_operand" "=Z") | |
4188 | (match_operand:SF 1 "non_hard_reg_operand" "")) | |
4189 | (clobber (match_operand:SF 2 "register_operand" "=&r"))] | |
4190 | "" | |
4191 | " | |
4192 | { | |
4193 | if (emit_move_sequence (operands, SFmode, operands[2])) | |
4194 | DONE; | |
4195 | ||
4196 | /* We don't want the clobber emitted, so handle this ourselves. */ | |
ad2c71b7 | 4197 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); |
0fc4f911 RK |
4198 | DONE; |
4199 | }") | |
4200 | ||
4201 | (define_expand "reload_outsf" | |
4202 | [(set (match_operand:SF 0 "non_hard_reg_operand" "") | |
4203 | (match_operand:SF 1 "register_operand" "Z")) | |
4204 | (clobber (match_operand:SF 2 "register_operand" "=&r"))] | |
4205 | "" | |
4206 | " | |
4207 | { | |
4208 | if (emit_move_sequence (operands, SFmode, operands[2])) | |
4209 | DONE; | |
4210 | ||
4211 | /* We don't want the clobber emitted, so handle this ourselves. */ | |
ad2c71b7 | 4212 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); |
0fc4f911 RK |
4213 | DONE; |
4214 | }") | |
4215 | ||
c733e074 | 4216 | (define_insn "" |
d8f95bed JDA |
4217 | [(set (match_operand:SF 0 "move_dest_operand" |
4218 | "=f,!*r,f,*r,Q,Q") | |
222727e8 | 4219 | (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" |
d8f95bed | 4220 | "fG,!*rG,RQ,RQ,f,*rG"))] |
925cf581 TG |
4221 | "(register_operand (operands[0], SFmode) |
4222 | || reg_or_0_operand (operands[1], SFmode)) | |
d8f95bed | 4223 | && !TARGET_SOFT_FLOAT" |
c733e074 | 4224 | "@ |
55abf18a | 4225 | fcpy,sgl %f1,%0 |
222727e8 | 4226 | copy %r1,%0 |
2414e0e2 | 4227 | fldw%F1 %1,%0 |
c733e074 | 4228 | ldw%M1 %1,%0 |
d8f95bed | 4229 | fstw%F0 %1,%0 |
c733e074 | 4230 | stw%M0 %r1,%0" |
04e1baee | 4231 | [(set_attr "type" "fpalu,move,fpload,load,fpstore,store") |
c4bb6b38 | 4232 | (set_attr "pa_combine_type" "addmove") |
4c2164b7 | 4233 | (set_attr "length" "4,4,4,4,4,4")]) |
1d01c176 | 4234 | |
925cf581 | 4235 | (define_insn "" |
d8f95bed JDA |
4236 | [(set (match_operand:SF 0 "indexed_memory_operand" "=R") |
4237 | (match_operand:SF 1 "register_operand" "f"))] | |
4238 | "!TARGET_SOFT_FLOAT | |
4239 | && !TARGET_DISABLE_INDEXING | |
4240 | && reload_completed" | |
4241 | "fstw%F0 %1,%0" | |
4242 | [(set_attr "type" "fpstore") | |
4243 | (set_attr "pa_combine_type" "addmove") | |
4244 | (set_attr "length" "4")]) | |
4245 | ||
4246 | (define_peephole2 | |
4247 | [(set (match_operand:SI 0 "register_operand" "") | |
4248 | (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "") | |
4249 | (const_int 4)) | |
4250 | (match_operand:SI 2 "register_operand" ""))) | |
4251 | (set (mem:SF (match_dup 0)) | |
4252 | (match_operand:SF 3 "register_operand" ""))] | |
4253 | "!TARGET_SOFT_FLOAT | |
4254 | && REG_OK_FOR_BASE_P (operands[2]) | |
4255 | && FP_REGNO_P (REGNO (operands[3]))" | |
4256 | [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2))) | |
4257 | (match_dup 3)) | |
4258 | (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4)) | |
4259 | (match_dup 2)))] | |
4260 | "") | |
4261 | ||
4262 | (define_peephole2 | |
4263 | [(set (match_operand:SI 0 "register_operand" "") | |
4264 | (plus:SI (match_operand:SI 2 "register_operand" "") | |
4265 | (mult:SI (match_operand:SI 1 "register_operand" "") | |
4266 | (const_int 4)))) | |
4267 | (set (mem:SF (match_dup 0)) | |
4268 | (match_operand:SF 3 "register_operand" ""))] | |
4269 | "!TARGET_SOFT_FLOAT | |
4270 | && REG_OK_FOR_BASE_P (operands[2]) | |
4271 | && FP_REGNO_P (REGNO (operands[3]))" | |
4272 | [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2))) | |
4273 | (match_dup 3)) | |
4274 | (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4)) | |
4275 | (match_dup 2)))] | |
4276 | "") | |
4277 | ||
4278 | (define_peephole2 | |
4279 | [(set (match_operand:DI 0 "register_operand" "") | |
4280 | (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "") | |
4281 | (const_int 4)) | |
4282 | (match_operand:DI 2 "register_operand" ""))) | |
4283 | (set (mem:SF (match_dup 0)) | |
4284 | (match_operand:SF 3 "register_operand" ""))] | |
4285 | "!TARGET_SOFT_FLOAT | |
4286 | && TARGET_64BIT | |
4287 | && REG_OK_FOR_BASE_P (operands[2]) | |
4288 | && FP_REGNO_P (REGNO (operands[3]))" | |
4289 | [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2))) | |
4290 | (match_dup 3)) | |
4291 | (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4)) | |
4292 | (match_dup 2)))] | |
4293 | "") | |
4294 | ||
4295 | (define_peephole2 | |
4296 | [(set (match_operand:DI 0 "register_operand" "") | |
4297 | (plus:DI (match_operand:DI 2 "register_operand" "") | |
4298 | (mult:DI (match_operand:DI 1 "register_operand" "") | |
4299 | (const_int 4)))) | |
4300 | (set (mem:SF (match_dup 0)) | |
4301 | (match_operand:SF 3 "register_operand" ""))] | |
4302 | "!TARGET_SOFT_FLOAT | |
4303 | && TARGET_64BIT | |
4304 | && REG_OK_FOR_BASE_P (operands[2]) | |
4305 | && FP_REGNO_P (REGNO (operands[3]))" | |
4306 | [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2))) | |
4307 | (match_dup 3)) | |
4308 | (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4)) | |
4309 | (match_dup 2)))] | |
4310 | "") | |
4311 | ||
4312 | (define_peephole2 | |
4313 | [(set (match_operand:SI 0 "register_operand" "") | |
4314 | (plus:SI (match_operand:SI 1 "register_operand" "") | |
4315 | (match_operand:SI 2 "register_operand" ""))) | |
4316 | (set (mem:SF (match_dup 0)) | |
4317 | (match_operand:SF 3 "register_operand" ""))] | |
4318 | "!TARGET_SOFT_FLOAT | |
4319 | && REG_OK_FOR_BASE_P (operands[1]) | |
4320 | && (TARGET_NO_SPACE_REGS | |
4321 | || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2]))) | |
4322 | && FP_REGNO_P (REGNO (operands[3]))" | |
4323 | [(set (mem:SF (plus:SI (match_dup 1) (match_dup 2))) | |
4324 | (match_dup 3)) | |
4325 | (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))] | |
4326 | "") | |
4327 | ||
4328 | (define_peephole2 | |
4329 | [(set (match_operand:SI 0 "register_operand" "") | |
4330 | (plus:SI (match_operand:SI 1 "register_operand" "") | |
4331 | (match_operand:SI 2 "register_operand" ""))) | |
4332 | (set (mem:SF (match_dup 0)) | |
4333 | (match_operand:SF 3 "register_operand" ""))] | |
4334 | "!TARGET_SOFT_FLOAT | |
4335 | && REG_OK_FOR_BASE_P (operands[2]) | |
4336 | && (TARGET_NO_SPACE_REGS | |
4337 | || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2]))) | |
4338 | && FP_REGNO_P (REGNO (operands[3]))" | |
4339 | [(set (mem:SF (plus:SI (match_dup 2) (match_dup 1))) | |
4340 | (match_dup 3)) | |
4341 | (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))] | |
4342 | "") | |
4343 | ||
4344 | (define_peephole2 | |
4345 | [(set (match_operand:DI 0 "register_operand" "") | |
4346 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
4347 | (match_operand:DI 2 "register_operand" ""))) | |
4348 | (set (mem:SF (match_dup 0)) | |
4349 | (match_operand:SF 3 "register_operand" ""))] | |
4350 | "!TARGET_SOFT_FLOAT | |
4351 | && TARGET_64BIT | |
4352 | && REG_OK_FOR_BASE_P (operands[1]) | |
4353 | && (TARGET_NO_SPACE_REGS | |
4354 | || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2]))) | |
4355 | && FP_REGNO_P (REGNO (operands[3]))" | |
4356 | [(set (mem:SF (plus:DI (match_dup 1) (match_dup 2))) | |
4357 | (match_dup 3)) | |
4358 | (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] | |
4359 | "") | |
4360 | ||
4361 | (define_peephole2 | |
4362 | [(set (match_operand:DI 0 "register_operand" "") | |
4363 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
4364 | (match_operand:DI 2 "register_operand" ""))) | |
4365 | (set (mem:SF (match_dup 0)) | |
4366 | (match_operand:SF 3 "register_operand" ""))] | |
4367 | "!TARGET_SOFT_FLOAT | |
4368 | && TARGET_64BIT | |
4369 | && REG_OK_FOR_BASE_P (operands[2]) | |
4370 | && (TARGET_NO_SPACE_REGS | |
4371 | || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2]))) | |
4372 | && FP_REGNO_P (REGNO (operands[3]))" | |
4373 | [(set (mem:SF (plus:DI (match_dup 2) (match_dup 1))) | |
4374 | (match_dup 3)) | |
4375 | (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))] | |
4376 | "") | |
4377 | ||
4378 | (define_insn "" | |
4379 | [(set (match_operand:SF 0 "move_dest_operand" | |
925cf581 TG |
4380 | "=r,r,Q") |
4381 | (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" | |
7a8940aa | 4382 | "rG,RQ,rG"))] |
925cf581 TG |
4383 | "(register_operand (operands[0], SFmode) |
4384 | || reg_or_0_operand (operands[1], SFmode)) | |
4385 | && TARGET_SOFT_FLOAT" | |
4386 | "@ | |
4387 | copy %r1,%0 | |
4388 | ldw%M1 %1,%0 | |
4389 | stw%M0 %r1,%0" | |
4390 | [(set_attr "type" "move,load,store") | |
c4bb6b38 | 4391 | (set_attr "pa_combine_type" "addmove") |
925cf581 TG |
4392 | (set_attr "length" "4,4,4")]) |
4393 | ||
c733e074 | 4394 | \f |
68944452 | 4395 | |
c733e074 | 4396 | ;;- zero extension instructions |
44cfd512 JL |
4397 | ;; We have define_expand for zero extension patterns to make sure the |
4398 | ;; operands get loaded into registers. The define_insns accept | |
4399 | ;; memory operands. This gives us better overall code than just | |
4400 | ;; having a pattern that does or does not accept memory operands. | |
c733e074 | 4401 | |
44cfd512 JL |
4402 | (define_expand "zero_extendqihi2" |
4403 | [(set (match_operand:HI 0 "register_operand" "") | |
c733e074 | 4404 | (zero_extend:HI |
44cfd512 | 4405 | (match_operand:QI 1 "register_operand" "")))] |
c733e074 | 4406 | "" |
44cfd512 JL |
4407 | "") |
4408 | ||
4409 | (define_insn "" | |
4410 | [(set (match_operand:HI 0 "register_operand" "=r,r") | |
4411 | (zero_extend:HI | |
d8f95bed | 4412 | (match_operand:QI 1 "move_src_operand" "r,RQ")))] |
44cfd512 | 4413 | "GET_CODE (operands[1]) != CONST_INT" |
c733e074 | 4414 | "@ |
f38b27c7 | 4415 | {extru|extrw,u} %1,31,8,%0 |
c733e074 | 4416 | ldb%M1 %1,%0" |
c47decad JL |
4417 | [(set_attr "type" "shift,load") |
4418 | (set_attr "length" "4,4")]) | |
c733e074 | 4419 | |
44cfd512 JL |
4420 | (define_expand "zero_extendqisi2" |
4421 | [(set (match_operand:SI 0 "register_operand" "") | |
c733e074 | 4422 | (zero_extend:SI |
44cfd512 | 4423 | (match_operand:QI 1 "register_operand" "")))] |
c733e074 | 4424 | "" |
44cfd512 JL |
4425 | "") |
4426 | ||
4427 | (define_insn "" | |
4428 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
4429 | (zero_extend:SI | |
d8f95bed | 4430 | (match_operand:QI 1 "move_src_operand" "r,RQ")))] |
44cfd512 | 4431 | "GET_CODE (operands[1]) != CONST_INT" |
c733e074 | 4432 | "@ |
f38b27c7 | 4433 | {extru|extrw,u} %1,31,8,%0 |
c733e074 | 4434 | ldb%M1 %1,%0" |
c47decad JL |
4435 | [(set_attr "type" "shift,load") |
4436 | (set_attr "length" "4,4")]) | |
6f672dc0 | 4437 | |
d8f95bed JDA |
4438 | (define_expand "zero_extendhisi2" |
4439 | [(set (match_operand:SI 0 "register_operand" "") | |
4440 | (zero_extend:SI | |
4441 | (match_operand:HI 1 "register_operand" "")))] | |
4442 | "" | |
4443 | "") | |
4444 | ||
4445 | (define_insn "" | |
4446 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
4447 | (zero_extend:SI | |
4448 | (match_operand:HI 1 "move_src_operand" "r,RQ")))] | |
4449 | "GET_CODE (operands[1]) != CONST_INT" | |
4450 | "@ | |
4451 | {extru|extrw,u} %1,31,16,%0 | |
4452 | ldh%M1 %1,%0" | |
4453 | [(set_attr "type" "shift,load") | |
4454 | (set_attr "length" "4,4")]) | |
4455 | ||
4456 | (define_expand "zero_extendqidi2" | |
4457 | [(set (match_operand:DI 0 "register_operand" "") | |
4458 | (zero_extend:DI | |
4459 | (match_operand:QI 1 "register_operand" "")))] | |
520babc7 | 4460 | "TARGET_64BIT" |
d8f95bed | 4461 | "") |
520babc7 | 4462 | |
d8f95bed JDA |
4463 | (define_insn "" |
4464 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
4465 | (zero_extend:DI | |
4466 | (match_operand:QI 1 "move_src_operand" "r,RQ")))] | |
4467 | "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT" | |
4468 | "@ | |
4469 | extrd,u %1,63,8,%0 | |
4470 | ldb%M1 %1,%0" | |
4471 | [(set_attr "type" "shift,load") | |
4472 | (set_attr "length" "4,4")]) | |
4473 | ||
4474 | (define_expand "zero_extendhidi2" | |
4475 | [(set (match_operand:DI 0 "register_operand" "") | |
4476 | (zero_extend:DI | |
4477 | (match_operand:HI 1 "register_operand" "")))] | |
520babc7 | 4478 | "TARGET_64BIT" |
d8f95bed | 4479 | "") |
520babc7 | 4480 | |
d8f95bed JDA |
4481 | (define_insn "" |
4482 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
4483 | (zero_extend:DI | |
4484 | (match_operand:HI 1 "move_src_operand" "r,RQ")))] | |
4485 | "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT" | |
4486 | "@ | |
4487 | extrd,u %1,63,16,%0 | |
4488 | ldh%M1 %1,%0" | |
4489 | [(set_attr "type" "shift,load") | |
4490 | (set_attr "length" "4,4")]) | |
4491 | ||
4492 | (define_expand "zero_extendsidi2" | |
4493 | [(set (match_operand:DI 0 "register_operand" "") | |
4494 | (zero_extend:DI | |
4495 | (match_operand:SI 1 "register_operand" "")))] | |
520babc7 | 4496 | "TARGET_64BIT" |
d8f95bed JDA |
4497 | "") |
4498 | ||
4499 | (define_insn "" | |
4500 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
4501 | (zero_extend:DI | |
4502 | (match_operand:SI 1 "move_src_operand" "r,RQ")))] | |
4503 | "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT" | |
4504 | "@ | |
4505 | extrd,u %1,63,32,%0 | |
4506 | ldw%M1 %1,%0" | |
4507 | [(set_attr "type" "shift,load") | |
4508 | (set_attr "length" "4,4")]) | |
520babc7 | 4509 | |
c733e074 | 4510 | ;;- sign extension instructions |
c733e074 TM |
4511 | |
4512 | (define_insn "extendhisi2" | |
4513 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4514 | (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))] | |
4515 | "" | |
f38b27c7 | 4516 | "{extrs|extrw,s} %1,31,16,%0" |
c47decad JL |
4517 | [(set_attr "type" "shift") |
4518 | (set_attr "length" "4")]) | |
c733e074 TM |
4519 | |
4520 | (define_insn "extendqihi2" | |
4521 | [(set (match_operand:HI 0 "register_operand" "=r") | |
4522 | (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))] | |
4523 | "" | |
f38b27c7 | 4524 | "{extrs|extrw,s} %1,31,8,%0" |
c47decad JL |
4525 | [(set_attr "type" "shift") |
4526 | (set_attr "length" "4")]) | |
c733e074 TM |
4527 | |
4528 | (define_insn "extendqisi2" | |
4529 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4530 | (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))] | |
4531 | "" | |
f38b27c7 | 4532 | "{extrs|extrw,s} %1,31,8,%0" |
c47decad JL |
4533 | [(set_attr "type" "shift") |
4534 | (set_attr "length" "4")]) | |
520babc7 JL |
4535 | |
4536 | (define_insn "extendqidi2" | |
4537 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4538 | (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))] | |
4539 | "TARGET_64BIT" | |
4540 | "extrd,s %1,63,8,%0" | |
4541 | [(set_attr "type" "shift") | |
4542 | (set_attr "length" "4")]) | |
4543 | ||
4544 | (define_insn "extendhidi2" | |
4545 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4546 | (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))] | |
4547 | "TARGET_64BIT" | |
4548 | "extrd,s %1,63,16,%0" | |
4549 | [(set_attr "type" "shift") | |
4550 | (set_attr "length" "4")]) | |
4551 | ||
4552 | (define_insn "extendsidi2" | |
4553 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4554 | (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))] | |
4555 | "TARGET_64BIT" | |
4556 | "extrd,s %1,63,32,%0" | |
4557 | [(set_attr "type" "shift") | |
4558 | (set_attr "length" "4")]) | |
4559 | ||
c733e074 TM |
4560 | \f |
4561 | ;; Conversions between float and double. | |
4562 | ||
4563 | (define_insn "extendsfdf2" | |
0b27d5dd | 4564 | [(set (match_operand:DF 0 "register_operand" "=f") |
c733e074 | 4565 | (float_extend:DF |
0b27d5dd | 4566 | (match_operand:SF 1 "register_operand" "f")))] |
925cf581 | 4567 | "! TARGET_SOFT_FLOAT" |
f38b27c7 | 4568 | "{fcnvff|fcnv},sgl,dbl %1,%0" |
c47decad JL |
4569 | [(set_attr "type" "fpalu") |
4570 | (set_attr "length" "4")]) | |
c733e074 TM |
4571 | |
4572 | (define_insn "truncdfsf2" | |
0b27d5dd | 4573 | [(set (match_operand:SF 0 "register_operand" "=f") |
c733e074 | 4574 | (float_truncate:SF |
0b27d5dd | 4575 | (match_operand:DF 1 "register_operand" "f")))] |
925cf581 | 4576 | "! TARGET_SOFT_FLOAT" |
f38b27c7 | 4577 | "{fcnvff|fcnv},dbl,sgl %1,%0" |
c47decad JL |
4578 | [(set_attr "type" "fpalu") |
4579 | (set_attr "length" "4")]) | |
c733e074 TM |
4580 | |
4581 | ;; Conversion between fixed point and floating point. | |
4582 | ;; Note that among the fix-to-float insns | |
4583 | ;; the ones that start with SImode come first. | |
4584 | ;; That is so that an operand that is a CONST_INT | |
4585 | ;; (and therefore lacks a specific machine mode). | |
4586 | ;; will be recognized as SImode (which is always valid) | |
4587 | ;; rather than as QImode or HImode. | |
4588 | ||
4589 | ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...))) | |
4590 | ;; to be reloaded by putting the constant into memory. | |
4591 | ;; It must come before the more general floatsisf2 pattern. | |
4592 | (define_insn "" | |
cda0f51e | 4593 | [(set (match_operand:SF 0 "register_operand" "=f") |
c733e074 | 4594 | (float:SF (match_operand:SI 1 "const_int_operand" "m")))] |
925cf581 | 4595 | "! TARGET_SOFT_FLOAT" |
f38b27c7 | 4596 | "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0" |
c733e074 | 4597 | [(set_attr "type" "fpalu") |
4c2164b7 | 4598 | (set_attr "length" "8")]) |
c733e074 TM |
4599 | |
4600 | (define_insn "floatsisf2" | |
cda0f51e | 4601 | [(set (match_operand:SF 0 "register_operand" "=f") |
0b27d5dd | 4602 | (float:SF (match_operand:SI 1 "register_operand" "f")))] |
925cf581 | 4603 | "! TARGET_SOFT_FLOAT" |
f38b27c7 | 4604 | "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0" |
c47decad JL |
4605 | [(set_attr "type" "fpalu") |
4606 | (set_attr "length" "4")]) | |
c733e074 TM |
4607 | |
4608 | ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...))) | |
4609 | ;; to be reloaded by putting the constant into memory. | |
4610 | ;; It must come before the more general floatsidf2 pattern. | |
4611 | (define_insn "" | |
cda0f51e | 4612 | [(set (match_operand:DF 0 "register_operand" "=f") |
c733e074 | 4613 | (float:DF (match_operand:SI 1 "const_int_operand" "m")))] |
925cf581 | 4614 | "! TARGET_SOFT_FLOAT" |
f38b27c7 | 4615 | "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0" |
c733e074 | 4616 | [(set_attr "type" "fpalu") |
4c2164b7 | 4617 | (set_attr "length" "8")]) |
c733e074 TM |
4618 | |
4619 | (define_insn "floatsidf2" | |
cda0f51e | 4620 | [(set (match_operand:DF 0 "register_operand" "=f") |
0b27d5dd | 4621 | (float:DF (match_operand:SI 1 "register_operand" "f")))] |
925cf581 | 4622 | "! TARGET_SOFT_FLOAT" |
f38b27c7 | 4623 | "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0" |
c47decad JL |
4624 | [(set_attr "type" "fpalu") |
4625 | (set_attr "length" "4")]) | |
cb524f44 TG |
4626 | |
4627 | (define_expand "floatunssisf2" | |
ddef6bc7 | 4628 | [(set (subreg:SI (match_dup 2) 4) |
cb524f44 | 4629 | (match_operand:SI 1 "register_operand" "")) |
4ff3bd5f | 4630 | (set (subreg:SI (match_dup 2) 0) |
cb524f44 | 4631 | (const_int 0)) |
d177a3ef | 4632 | (set (match_operand:SF 0 "register_operand" "") |
cb524f44 | 4633 | (float:SF (match_dup 2)))] |
13ee407e | 4634 | "TARGET_PA_11 && ! TARGET_SOFT_FLOAT" |
06bcc178 JL |
4635 | " |
4636 | { | |
4637 | if (TARGET_PA_20) | |
4638 | { | |
4639 | emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1])); | |
4640 | DONE; | |
4641 | } | |
4642 | operands[2] = gen_reg_rtx (DImode); | |
4643 | }") | |
cb524f44 TG |
4644 | |
4645 | (define_expand "floatunssidf2" | |
ddef6bc7 | 4646 | [(set (subreg:SI (match_dup 2) 4) |
cb524f44 TG |
4647 | (match_operand:SI 1 "register_operand" "")) |
4648 | (set (subreg:SI (match_dup 2) 0) | |
4649 | (const_int 0)) | |
d177a3ef | 4650 | (set (match_operand:DF 0 "register_operand" "") |
cb524f44 | 4651 | (float:DF (match_dup 2)))] |
13ee407e | 4652 | "TARGET_PA_11 && ! TARGET_SOFT_FLOAT" |
06bcc178 JL |
4653 | " |
4654 | { | |
4655 | if (TARGET_PA_20) | |
4656 | { | |
4657 | emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1])); | |
4658 | DONE; | |
4659 | } | |
4660 | operands[2] = gen_reg_rtx (DImode); | |
4661 | }") | |
cb524f44 TG |
4662 | |
4663 | (define_insn "floatdisf2" | |
cda0f51e | 4664 | [(set (match_operand:SF 0 "register_operand" "=f") |
0b27d5dd | 4665 | (float:SF (match_operand:DI 1 "register_operand" "f")))] |
13ee407e | 4666 | "TARGET_PA_11 && ! TARGET_SOFT_FLOAT" |
f38b27c7 | 4667 | "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0" |
c47decad JL |
4668 | [(set_attr "type" "fpalu") |
4669 | (set_attr "length" "4")]) | |
cb524f44 TG |
4670 | |
4671 | (define_insn "floatdidf2" | |
cda0f51e | 4672 | [(set (match_operand:DF 0 "register_operand" "=f") |
0b27d5dd | 4673 | (float:DF (match_operand:DI 1 "register_operand" "f")))] |
13ee407e | 4674 | "TARGET_PA_11 && ! TARGET_SOFT_FLOAT" |
f38b27c7 | 4675 | "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0" |
c47decad JL |
4676 | [(set_attr "type" "fpalu") |
4677 | (set_attr "length" "4")]) | |
c733e074 TM |
4678 | |
4679 | ;; Convert a float to an actual integer. | |
4680 | ;; Truncation is performed as part of the conversion. | |
4681 | ||
4682 | (define_insn "fix_truncsfsi2" | |
0b27d5dd TG |
4683 | [(set (match_operand:SI 0 "register_operand" "=f") |
4684 | (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] | |
925cf581 | 4685 | "! TARGET_SOFT_FLOAT" |
f38b27c7 | 4686 | "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0" |
c47decad JL |
4687 | [(set_attr "type" "fpalu") |
4688 | (set_attr "length" "4")]) | |
c733e074 TM |
4689 | |
4690 | (define_insn "fix_truncdfsi2" | |
0b27d5dd TG |
4691 | [(set (match_operand:SI 0 "register_operand" "=f") |
4692 | (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] | |
925cf581 | 4693 | "! TARGET_SOFT_FLOAT" |
f38b27c7 | 4694 | "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0" |
c47decad JL |
4695 | [(set_attr "type" "fpalu") |
4696 | (set_attr "length" "4")]) | |
c733e074 | 4697 | |
cb524f44 | 4698 | (define_insn "fix_truncsfdi2" |
0b27d5dd TG |
4699 | [(set (match_operand:DI 0 "register_operand" "=f") |
4700 | (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] | |
13ee407e | 4701 | "TARGET_PA_11 && ! TARGET_SOFT_FLOAT" |
f38b27c7 | 4702 | "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0" |
c47decad JL |
4703 | [(set_attr "type" "fpalu") |
4704 | (set_attr "length" "4")]) | |
cb524f44 TG |
4705 | |
4706 | (define_insn "fix_truncdfdi2" | |
0b27d5dd TG |
4707 | [(set (match_operand:DI 0 "register_operand" "=f") |
4708 | (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] | |
13ee407e | 4709 | "TARGET_PA_11 && ! TARGET_SOFT_FLOAT" |
f38b27c7 | 4710 | "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0" |
c47decad JL |
4711 | [(set_attr "type" "fpalu") |
4712 | (set_attr "length" "4")]) | |
06bcc178 JL |
4713 | |
4714 | (define_insn "floatunssidf2_pa20" | |
4715 | [(set (match_operand:DF 0 "register_operand" "=f") | |
4716 | (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))] | |
4717 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
4718 | "fcnv,uw,dbl %1,%0" | |
4719 | [(set_attr "type" "fpalu") | |
4720 | (set_attr "length" "4")]) | |
4721 | ||
4722 | (define_insn "floatunssisf2_pa20" | |
4723 | [(set (match_operand:SF 0 "register_operand" "=f") | |
4724 | (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))] | |
4725 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
4726 | "fcnv,uw,sgl %1,%0" | |
4727 | [(set_attr "type" "fpalu") | |
4728 | (set_attr "length" "4")]) | |
4729 | ||
4730 | (define_insn "floatunsdisf2" | |
4731 | [(set (match_operand:SF 0 "register_operand" "=f") | |
4732 | (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))] | |
4733 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
4734 | "fcnv,udw,sgl %1,%0" | |
4735 | [(set_attr "type" "fpalu") | |
4736 | (set_attr "length" "4")]) | |
4737 | ||
4738 | (define_insn "floatunsdidf2" | |
4739 | [(set (match_operand:DF 0 "register_operand" "=f") | |
4740 | (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))] | |
4741 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
4742 | "fcnv,udw,dbl %1,%0" | |
4743 | [(set_attr "type" "fpalu") | |
4744 | (set_attr "length" "4")]) | |
4745 | ||
4746 | (define_insn "fixuns_truncsfsi2" | |
4747 | [(set (match_operand:SI 0 "register_operand" "=f") | |
4748 | (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] | |
4749 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
4750 | "fcnv,t,sgl,uw %1,%0" | |
4751 | [(set_attr "type" "fpalu") | |
4752 | (set_attr "length" "4")]) | |
4753 | ||
4754 | (define_insn "fixuns_truncdfsi2" | |
4755 | [(set (match_operand:SI 0 "register_operand" "=f") | |
4756 | (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] | |
4757 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
4758 | "fcnv,t,dbl,uw %1,%0" | |
4759 | [(set_attr "type" "fpalu") | |
4760 | (set_attr "length" "4")]) | |
4761 | ||
4762 | (define_insn "fixuns_truncsfdi2" | |
4763 | [(set (match_operand:DI 0 "register_operand" "=f") | |
4764 | (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] | |
4765 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
4766 | "fcnv,t,sgl,udw %1,%0" | |
4767 | [(set_attr "type" "fpalu") | |
4768 | (set_attr "length" "4")]) | |
4769 | ||
4770 | (define_insn "fixuns_truncdfdi2" | |
4771 | [(set (match_operand:DI 0 "register_operand" "=f") | |
4772 | (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] | |
4773 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
4774 | "fcnv,t,dbl,udw %1,%0" | |
4775 | [(set_attr "type" "fpalu") | |
4776 | (set_attr "length" "4")]) | |
c733e074 TM |
4777 | \f |
4778 | ;;- arithmetic instructions | |
4779 | ||
9d142e3f JL |
4780 | (define_expand "adddi3" |
4781 | [(set (match_operand:DI 0 "register_operand" "") | |
4782 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
a18c2c5f | 4783 | (match_operand:DI 2 "adddi3_operand" "")))] |
9d142e3f | 4784 | "" |
a18c2c5f | 4785 | "") |
520babc7 | 4786 | |
9d142e3f | 4787 | (define_insn "" |
c733e074 TM |
4788 | [(set (match_operand:DI 0 "register_operand" "=r") |
4789 | (plus:DI (match_operand:DI 1 "register_operand" "%r") | |
47abc309 | 4790 | (match_operand:DI 2 "arith11_operand" "rI")))] |
520babc7 | 4791 | "!TARGET_64BIT" |
876662ef TG |
4792 | "* |
4793 | { | |
4794 | if (GET_CODE (operands[2]) == CONST_INT) | |
4795 | { | |
4796 | if (INTVAL (operands[2]) >= 0) | |
f38b27c7 | 4797 | return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\"; |
876662ef | 4798 | else |
f38b27c7 | 4799 | return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\"; |
876662ef TG |
4800 | } |
4801 | else | |
f38b27c7 | 4802 | return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\"; |
876662ef | 4803 | }" |
c47decad JL |
4804 | [(set_attr "type" "binary") |
4805 | (set_attr "length" "8")]) | |
c733e074 | 4806 | |
520babc7 JL |
4807 | (define_insn "" |
4808 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
4809 | (plus:DI (match_operand:DI 1 "register_operand" "%r,r") | |
4810 | (match_operand:DI 2 "arith_operand" "r,J")))] | |
4811 | "TARGET_64BIT" | |
4812 | "@ | |
d8f95bed | 4813 | add,l %1,%2,%0 |
520babc7 JL |
4814 | ldo %2(%1),%0" |
4815 | [(set_attr "type" "binary,binary") | |
4816 | (set_attr "pa_combine_type" "addmove") | |
4817 | (set_attr "length" "4,4")]) | |
4818 | ||
4819 | (define_insn "" | |
4820 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4821 | (plus:DI (not:DI (match_operand:DI 1 "register_operand" "r")) | |
4822 | (match_operand:DI 2 "register_operand" "r")))] | |
4823 | "TARGET_64BIT" | |
4824 | "uaddcm %2,%1,%0" | |
4825 | [(set_attr "type" "binary") | |
4826 | (set_attr "length" "4")]) | |
4827 | ||
d5db6922 TG |
4828 | (define_insn "" |
4829 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4830 | (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r")) | |
4831 | (match_operand:SI 2 "register_operand" "r")))] | |
4832 | "" | |
c47decad JL |
4833 | "uaddcm %2,%1,%0" |
4834 | [(set_attr "type" "binary") | |
4835 | (set_attr "length" "4")]) | |
d5db6922 | 4836 | |
08cddb03 JL |
4837 | ;; define_splits to optimize cases of adding a constant integer |
4838 | ;; to a register when the constant does not fit in 14 bits. */ | |
4839 | (define_split | |
4840 | [(set (match_operand:SI 0 "register_operand" "") | |
4841 | (plus:SI (match_operand:SI 1 "register_operand" "") | |
4842 | (match_operand:SI 2 "const_int_operand" ""))) | |
4843 | (clobber (match_operand:SI 4 "register_operand" ""))] | |
2f95ebc2 | 4844 | "! cint_ok_for_move (INTVAL (operands[2])) |
ea9f550a | 4845 | && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)" |
08cddb03 JL |
4846 | [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2))) |
4847 | (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))] | |
4848 | " | |
4849 | { | |
4850 | int val = INTVAL (operands[2]); | |
4851 | int low = (val < 0) ? -0x2000 : 0x1fff; | |
4852 | int rest = val - low; | |
4853 | ||
4854 | operands[2] = GEN_INT (rest); | |
4855 | operands[3] = GEN_INT (low); | |
4856 | }") | |
4857 | ||
4858 | (define_split | |
4859 | [(set (match_operand:SI 0 "register_operand" "") | |
4860 | (plus:SI (match_operand:SI 1 "register_operand" "") | |
4861 | (match_operand:SI 2 "const_int_operand" ""))) | |
4862 | (clobber (match_operand:SI 4 "register_operand" ""))] | |
4863 | "! cint_ok_for_move (INTVAL (operands[2]))" | |
4864 | [(set (match_dup 4) (match_dup 2)) | |
4865 | (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3)) | |
4866 | (match_dup 1)))] | |
4867 | " | |
4868 | { | |
bd1fd7fb | 4869 | HOST_WIDE_INT intval = INTVAL (operands[2]); |
08cddb03 | 4870 | |
b16656f6 | 4871 | /* Try dividing the constant by 2, then 4, and finally 8 to see |
08cddb03 | 4872 | if we can get a constant which can be loaded into a register |
141b2e9f JL |
4873 | in a single instruction (cint_ok_for_move). |
4874 | ||
4875 | If that fails, try to negate the constant and subtract it | |
4876 | from our input operand. */ | |
08cddb03 JL |
4877 | if (intval % 2 == 0 && cint_ok_for_move (intval / 2)) |
4878 | { | |
b16656f6 | 4879 | operands[2] = GEN_INT (intval / 2); |
08cddb03 JL |
4880 | operands[3] = GEN_INT (2); |
4881 | } | |
4882 | else if (intval % 4 == 0 && cint_ok_for_move (intval / 4)) | |
4883 | { | |
b16656f6 | 4884 | operands[2] = GEN_INT (intval / 4); |
08cddb03 JL |
4885 | operands[3] = GEN_INT (4); |
4886 | } | |
4887 | else if (intval % 8 == 0 && cint_ok_for_move (intval / 8)) | |
4888 | { | |
b16656f6 | 4889 | operands[2] = GEN_INT (intval / 8); |
08cddb03 JL |
4890 | operands[3] = GEN_INT (8); |
4891 | } | |
141b2e9f JL |
4892 | else if (cint_ok_for_move (-intval)) |
4893 | { | |
ad2c71b7 | 4894 | emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval))); |
141b2e9f JL |
4895 | emit_insn (gen_subsi3 (operands[0], operands[1], operands[4])); |
4896 | DONE; | |
4897 | } | |
2f95ebc2 | 4898 | else |
08cddb03 JL |
4899 | FAIL; |
4900 | }") | |
4901 | ||
c733e074 TM |
4902 | (define_insn "addsi3" |
4903 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
4904 | (plus:SI (match_operand:SI 1 "register_operand" "%r,r") | |
4905 | (match_operand:SI 2 "arith_operand" "r,J")))] | |
4906 | "" | |
4907 | "@ | |
f38b27c7 | 4908 | {addl|add,l} %1,%2,%0 |
c47decad JL |
4909 | ldo %2(%1),%0" |
4910 | [(set_attr "type" "binary,binary") | |
c4bb6b38 | 4911 | (set_attr "pa_combine_type" "addmove") |
c47decad | 4912 | (set_attr "length" "4,4")]) |
c733e074 | 4913 | |
9d142e3f JL |
4914 | (define_expand "subdi3" |
4915 | [(set (match_operand:DI 0 "register_operand" "") | |
4916 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
4917 | (match_operand:DI 2 "register_operand" "")))] | |
4918 | "" | |
4919 | "") | |
4920 | ||
4921 | (define_insn "" | |
c733e074 TM |
4922 | [(set (match_operand:DI 0 "register_operand" "=r") |
4923 | (minus:DI (match_operand:DI 1 "register_operand" "r") | |
4924 | (match_operand:DI 2 "register_operand" "r")))] | |
520babc7 | 4925 | "!TARGET_64BIT" |
f38b27c7 | 4926 | "sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0" |
c47decad JL |
4927 | [(set_attr "type" "binary") |
4928 | (set_attr "length" "8")]) | |
c733e074 | 4929 | |
520babc7 | 4930 | (define_insn "" |
f5d1c3de JDA |
4931 | [(set (match_operand:DI 0 "register_operand" "=r,r,!q") |
4932 | (minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U") | |
4933 | (match_operand:DI 2 "register_operand" "r,r,!r")))] | |
520babc7 JL |
4934 | "TARGET_64BIT" |
4935 | "@ | |
4936 | sub %1,%2,%0 | |
4937 | subi %1,%2,%0 | |
4938 | mtsarcm %2" | |
4939 | [(set_attr "type" "binary,binary,move") | |
4940 | (set_attr "length" "4,4,4")]) | |
4941 | ||
635d1437 JL |
4942 | (define_expand "subsi3" |
4943 | [(set (match_operand:SI 0 "register_operand" "") | |
4944 | (minus:SI (match_operand:SI 1 "arith11_operand" "") | |
4945 | (match_operand:SI 2 "register_operand" "")))] | |
4946 | "" | |
4947 | "") | |
4948 | ||
4949 | (define_insn "" | |
c733e074 TM |
4950 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
4951 | (minus:SI (match_operand:SI 1 "arith11_operand" "r,I") | |
4952 | (match_operand:SI 2 "register_operand" "r,r")))] | |
635d1437 | 4953 | "!TARGET_PA_20" |
c733e074 TM |
4954 | "@ |
4955 | sub %1,%2,%0 | |
c47decad JL |
4956 | subi %1,%2,%0" |
4957 | [(set_attr "type" "binary,binary") | |
4958 | (set_attr "length" "4,4")]) | |
c733e074 | 4959 | |
635d1437 | 4960 | (define_insn "" |
f5d1c3de JDA |
4961 | [(set (match_operand:SI 0 "register_operand" "=r,r,!q") |
4962 | (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,!S") | |
4963 | (match_operand:SI 2 "register_operand" "r,r,!r")))] | |
635d1437 JL |
4964 | "TARGET_PA_20" |
4965 | "@ | |
4966 | sub %1,%2,%0 | |
4967 | subi %1,%2,%0 | |
4968 | mtsarcm %2" | |
4969 | [(set_attr "type" "binary,binary,move") | |
4970 | (set_attr "length" "4,4,4")]) | |
4971 | ||
29ed7081 JL |
4972 | ;; Clobbering a "register_operand" instead of a match_scratch |
4973 | ;; in operand3 of millicode calls avoids spilling %r1 and | |
4974 | ;; produces better code. | |
c733e074 | 4975 | |
29ed7081 | 4976 | ;; The mulsi3 insns set up registers for the millicode call. |
c733e074 | 4977 | (define_expand "mulsi3" |
d8f95bed JDA |
4978 | [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" "")) |
4979 | (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" "")) | |
c733e074 | 4980 | (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) |
0b27d5dd | 4981 | (clobber (match_dup 3)) |
c733e074 TM |
4982 | (clobber (reg:SI 26)) |
4983 | (clobber (reg:SI 25)) | |
7d8b1412 | 4984 | (clobber (match_dup 4))]) |
c733e074 TM |
4985 | (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] |
4986 | "" | |
d2a94ec0 TM |
4987 | " |
4988 | { | |
7d8b1412 | 4989 | operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31); |
d8f95bed | 4990 | if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT) |
d2a94ec0 TM |
4991 | { |
4992 | rtx scratch = gen_reg_rtx (DImode); | |
dc4e989c TG |
4993 | operands[1] = force_reg (SImode, operands[1]); |
4994 | operands[2] = force_reg (SImode, operands[2]); | |
d2a94ec0 | 4995 | emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2])); |
d8f95bed JDA |
4996 | emit_insn (gen_movsi (operands[0], |
4997 | gen_rtx_SUBREG (SImode, scratch, | |
4998 | GET_MODE_SIZE (SImode)))); | |
d2a94ec0 TM |
4999 | DONE; |
5000 | } | |
0b27d5dd | 5001 | operands[3] = gen_reg_rtx (SImode); |
d2a94ec0 TM |
5002 | }") |
5003 | ||
5004 | (define_insn "umulsidi3" | |
0b27d5dd TG |
5005 | [(set (match_operand:DI 0 "nonimmediate_operand" "=f") |
5006 | (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f")) | |
5007 | (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))] | |
13ee407e | 5008 | "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT" |
d2a94ec0 | 5009 | "xmpyu %1,%2,%0" |
c47decad JL |
5010 | [(set_attr "type" "fpmuldbl") |
5011 | (set_attr "length" "4")]) | |
c733e074 | 5012 | |
2f95ebc2 | 5013 | (define_insn "" |
0b27d5dd TG |
5014 | [(set (match_operand:DI 0 "nonimmediate_operand" "=f") |
5015 | (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f")) | |
5016 | (match_operand:DI 2 "uint32_operand" "f")))] | |
520babc7 | 5017 | "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && !TARGET_64BIT" |
2f95ebc2 | 5018 | "xmpyu %1,%R2,%0" |
c47decad JL |
5019 | [(set_attr "type" "fpmuldbl") |
5020 | (set_attr "length" "4")]) | |
2f95ebc2 | 5021 | |
520babc7 JL |
5022 | (define_insn "" |
5023 | [(set (match_operand:DI 0 "nonimmediate_operand" "=f") | |
5024 | (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f")) | |
5025 | (match_operand:DI 2 "uint32_operand" "f")))] | |
5026 | "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && TARGET_64BIT" | |
5027 | "xmpyu %1,%2R,%0" | |
5028 | [(set_attr "type" "fpmuldbl") | |
5029 | (set_attr "length" "4")]) | |
5030 | ||
c733e074 TM |
5031 | (define_insn "" |
5032 | [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) | |
29ed7081 | 5033 | (clobber (match_operand:SI 0 "register_operand" "=a")) |
c733e074 TM |
5034 | (clobber (reg:SI 26)) |
5035 | (clobber (reg:SI 25)) | |
5036 | (clobber (reg:SI 31))] | |
7d8b1412 | 5037 | "!TARGET_64BIT" |
f854c12c | 5038 | "* return output_mul_insn (0, insn);" |
f726ea7d | 5039 | [(set_attr "type" "milli") |
611ad29e | 5040 | (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))]) |
c733e074 | 5041 | |
7d8b1412 AM |
5042 | (define_insn "" |
5043 | [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) | |
5044 | (clobber (match_operand:SI 0 "register_operand" "=a")) | |
5045 | (clobber (reg:SI 26)) | |
5046 | (clobber (reg:SI 25)) | |
5047 | (clobber (reg:SI 2))] | |
5048 | "TARGET_64BIT" | |
5049 | "* return output_mul_insn (0, insn);" | |
5050 | [(set_attr "type" "milli") | |
611ad29e | 5051 | (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))]) |
7d8b1412 | 5052 | |
520babc7 JL |
5053 | (define_expand "muldi3" |
5054 | [(set (match_operand:DI 0 "register_operand" "") | |
5055 | (mult:DI (match_operand:DI 1 "register_operand" "") | |
5056 | (match_operand:DI 2 "register_operand" "")))] | |
5057 | "TARGET_64BIT && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT" | |
5058 | " | |
5059 | { | |
5060 | rtx low_product = gen_reg_rtx (DImode); | |
5061 | rtx cross_product1 = gen_reg_rtx (DImode); | |
5062 | rtx cross_product2 = gen_reg_rtx (DImode); | |
5063 | rtx cross_scratch = gen_reg_rtx (DImode); | |
5064 | rtx cross_product = gen_reg_rtx (DImode); | |
5065 | rtx op1l, op1r, op2l, op2r; | |
5066 | rtx op1shifted, op2shifted; | |
5067 | ||
5068 | op1shifted = gen_reg_rtx (DImode); | |
5069 | op2shifted = gen_reg_rtx (DImode); | |
5070 | op1l = gen_reg_rtx (SImode); | |
5071 | op1r = gen_reg_rtx (SImode); | |
5072 | op2l = gen_reg_rtx (SImode); | |
5073 | op2r = gen_reg_rtx (SImode); | |
5074 | ||
5075 | emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1], | |
5076 | GEN_INT (32))); | |
5077 | emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2], | |
5078 | GEN_INT (32))); | |
512672fd JL |
5079 | op1r = gen_rtx_SUBREG (SImode, operands[1], 4); |
5080 | op2r = gen_rtx_SUBREG (SImode, operands[2], 4); | |
5081 | op1l = gen_rtx_SUBREG (SImode, op1shifted, 4); | |
5082 | op2l = gen_rtx_SUBREG (SImode, op2shifted, 4); | |
520babc7 JL |
5083 | |
5084 | /* Emit multiplies for the cross products. */ | |
5085 | emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l)); | |
5086 | emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r)); | |
5087 | ||
5088 | /* Emit a multiply for the low sub-word. */ | |
bc3cb712 | 5089 | emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r))); |
520babc7 JL |
5090 | |
5091 | /* Sum the cross products and shift them into proper position. */ | |
5092 | emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2)); | |
5093 | emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32))); | |
5094 | ||
5095 | /* Add the cross product to the low product and store the result | |
5096 | into the output operand . */ | |
5097 | emit_insn (gen_adddi3 (operands[0], cross_product, low_product)); | |
5098 | DONE; | |
5099 | }") | |
5100 | ||
c733e074 | 5101 | ;;; Division and mod. |
c733e074 | 5102 | (define_expand "divsi3" |
d8f95bed JDA |
5103 | [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" "")) |
5104 | (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" "")) | |
c733e074 | 5105 | (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25))) |
b16656f6 | 5106 | (clobber (match_dup 3)) |
6c0c4022 | 5107 | (clobber (match_dup 4)) |
c733e074 TM |
5108 | (clobber (reg:SI 26)) |
5109 | (clobber (reg:SI 25)) | |
7d8b1412 | 5110 | (clobber (match_dup 5))]) |
c733e074 TM |
5111 | (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] |
5112 | "" | |
5113 | " | |
5114 | { | |
c210e6ae | 5115 | operands[3] = gen_reg_rtx (SImode); |
520babc7 | 5116 | if (TARGET_64BIT) |
7d8b1412 AM |
5117 | { |
5118 | operands[5] = gen_rtx_REG (SImode, 2); | |
5119 | operands[4] = operands[5]; | |
5120 | } | |
5121 | else | |
5122 | { | |
5123 | operands[5] = gen_rtx_REG (SImode, 31); | |
5124 | operands[4] = gen_reg_rtx (SImode); | |
5125 | } | |
c210e6ae TG |
5126 | if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0)) |
5127 | DONE; | |
c733e074 TM |
5128 | }") |
5129 | ||
5130 | (define_insn "" | |
5131 | [(set (reg:SI 29) | |
c210e6ae | 5132 | (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" ""))) |
29ed7081 | 5133 | (clobber (match_operand:SI 1 "register_operand" "=a")) |
6c0c4022 | 5134 | (clobber (match_operand:SI 2 "register_operand" "=&r")) |
c733e074 TM |
5135 | (clobber (reg:SI 26)) |
5136 | (clobber (reg:SI 25)) | |
5137 | (clobber (reg:SI 31))] | |
7d8b1412 | 5138 | "!TARGET_64BIT" |
2f95ebc2 TG |
5139 | "* |
5140 | return output_div_insn (operands, 0, insn);" | |
f726ea7d | 5141 | [(set_attr "type" "milli") |
611ad29e | 5142 | (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))]) |
c733e074 | 5143 | |
7d8b1412 AM |
5144 | (define_insn "" |
5145 | [(set (reg:SI 29) | |
5146 | (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" ""))) | |
5147 | (clobber (match_operand:SI 1 "register_operand" "=a")) | |
5148 | (clobber (match_operand:SI 2 "register_operand" "=&r")) | |
5149 | (clobber (reg:SI 26)) | |
5150 | (clobber (reg:SI 25)) | |
5151 | (clobber (reg:SI 2))] | |
5152 | "TARGET_64BIT" | |
5153 | "* | |
5154 | return output_div_insn (operands, 0, insn);" | |
5155 | [(set_attr "type" "milli") | |
611ad29e | 5156 | (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))]) |
7d8b1412 | 5157 | |
c733e074 | 5158 | (define_expand "udivsi3" |
d8f95bed JDA |
5159 | [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" "")) |
5160 | (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" "")) | |
c733e074 | 5161 | (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25))) |
b16656f6 | 5162 | (clobber (match_dup 3)) |
6c0c4022 | 5163 | (clobber (match_dup 4)) |
c733e074 TM |
5164 | (clobber (reg:SI 26)) |
5165 | (clobber (reg:SI 25)) | |
7d8b1412 | 5166 | (clobber (match_dup 5))]) |
c733e074 TM |
5167 | (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] |
5168 | "" | |
5169 | " | |
5170 | { | |
c210e6ae | 5171 | operands[3] = gen_reg_rtx (SImode); |
a02aa5b0 | 5172 | |
520babc7 | 5173 | if (TARGET_64BIT) |
7d8b1412 AM |
5174 | { |
5175 | operands[5] = gen_rtx_REG (SImode, 2); | |
5176 | operands[4] = operands[5]; | |
5177 | } | |
5178 | else | |
5179 | { | |
5180 | operands[5] = gen_rtx_REG (SImode, 31); | |
5181 | operands[4] = gen_reg_rtx (SImode); | |
5182 | } | |
c210e6ae TG |
5183 | if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1)) |
5184 | DONE; | |
c733e074 TM |
5185 | }") |
5186 | ||
5187 | (define_insn "" | |
5188 | [(set (reg:SI 29) | |
c210e6ae | 5189 | (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" ""))) |
29ed7081 | 5190 | (clobber (match_operand:SI 1 "register_operand" "=a")) |
6c0c4022 | 5191 | (clobber (match_operand:SI 2 "register_operand" "=&r")) |
c733e074 TM |
5192 | (clobber (reg:SI 26)) |
5193 | (clobber (reg:SI 25)) | |
5194 | (clobber (reg:SI 31))] | |
7d8b1412 | 5195 | "!TARGET_64BIT" |
2f95ebc2 TG |
5196 | "* |
5197 | return output_div_insn (operands, 1, insn);" | |
f726ea7d | 5198 | [(set_attr "type" "milli") |
611ad29e | 5199 | (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))]) |
c733e074 | 5200 | |
7d8b1412 AM |
5201 | (define_insn "" |
5202 | [(set (reg:SI 29) | |
5203 | (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" ""))) | |
5204 | (clobber (match_operand:SI 1 "register_operand" "=a")) | |
5205 | (clobber (match_operand:SI 2 "register_operand" "=&r")) | |
5206 | (clobber (reg:SI 26)) | |
5207 | (clobber (reg:SI 25)) | |
5208 | (clobber (reg:SI 2))] | |
5209 | "TARGET_64BIT" | |
5210 | "* | |
5211 | return output_div_insn (operands, 1, insn);" | |
5212 | [(set_attr "type" "milli") | |
611ad29e | 5213 | (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))]) |
7d8b1412 | 5214 | |
c733e074 | 5215 | (define_expand "modsi3" |
d8f95bed JDA |
5216 | [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" "")) |
5217 | (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" "")) | |
c733e074 | 5218 | (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25))) |
b16656f6 | 5219 | (clobber (match_dup 3)) |
6c0c4022 | 5220 | (clobber (match_dup 4)) |
c733e074 TM |
5221 | (clobber (reg:SI 26)) |
5222 | (clobber (reg:SI 25)) | |
7d8b1412 | 5223 | (clobber (match_dup 5))]) |
c733e074 TM |
5224 | (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] |
5225 | "" | |
5226 | " | |
5227 | { | |
520babc7 | 5228 | if (TARGET_64BIT) |
7d8b1412 AM |
5229 | { |
5230 | operands[5] = gen_rtx_REG (SImode, 2); | |
5231 | operands[4] = operands[5]; | |
5232 | } | |
5233 | else | |
5234 | { | |
5235 | operands[5] = gen_rtx_REG (SImode, 31); | |
5236 | operands[4] = gen_reg_rtx (SImode); | |
5237 | } | |
c210e6ae | 5238 | operands[3] = gen_reg_rtx (SImode); |
c733e074 | 5239 | }") |
876662ef | 5240 | |
c733e074 TM |
5241 | (define_insn "" |
5242 | [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25))) | |
29ed7081 | 5243 | (clobber (match_operand:SI 0 "register_operand" "=a")) |
15c2086a | 5244 | (clobber (match_operand:SI 1 "register_operand" "=&r")) |
c733e074 TM |
5245 | (clobber (reg:SI 26)) |
5246 | (clobber (reg:SI 25)) | |
5247 | (clobber (reg:SI 31))] | |
7d8b1412 | 5248 | "!TARGET_64BIT" |
c733e074 | 5249 | "* |
f854c12c | 5250 | return output_mod_insn (0, insn);" |
f726ea7d | 5251 | [(set_attr "type" "milli") |
611ad29e | 5252 | (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))]) |
c733e074 | 5253 | |
7d8b1412 AM |
5254 | (define_insn "" |
5255 | [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25))) | |
5256 | (clobber (match_operand:SI 0 "register_operand" "=a")) | |
5257 | (clobber (match_operand:SI 1 "register_operand" "=&r")) | |
5258 | (clobber (reg:SI 26)) | |
5259 | (clobber (reg:SI 25)) | |
5260 | (clobber (reg:SI 2))] | |
5261 | "TARGET_64BIT" | |
5262 | "* | |
5263 | return output_mod_insn (0, insn);" | |
5264 | [(set_attr "type" "milli") | |
611ad29e | 5265 | (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))]) |
7d8b1412 | 5266 | |
c733e074 | 5267 | (define_expand "umodsi3" |
d8f95bed JDA |
5268 | [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" "")) |
5269 | (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" "")) | |
c733e074 | 5270 | (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25))) |
b16656f6 | 5271 | (clobber (match_dup 3)) |
6c0c4022 | 5272 | (clobber (match_dup 4)) |
c733e074 TM |
5273 | (clobber (reg:SI 26)) |
5274 | (clobber (reg:SI 25)) | |
7d8b1412 | 5275 | (clobber (match_dup 5))]) |
c733e074 TM |
5276 | (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] |
5277 | "" | |
5278 | " | |
5279 | { | |
520babc7 | 5280 | if (TARGET_64BIT) |
7d8b1412 AM |
5281 | { |
5282 | operands[5] = gen_rtx_REG (SImode, 2); | |
5283 | operands[4] = operands[5]; | |
5284 | } | |
5285 | else | |
5286 | { | |
5287 | operands[5] = gen_rtx_REG (SImode, 31); | |
5288 | operands[4] = gen_reg_rtx (SImode); | |
5289 | } | |
c210e6ae | 5290 | operands[3] = gen_reg_rtx (SImode); |
c733e074 TM |
5291 | }") |
5292 | ||
5293 | (define_insn "" | |
5294 | [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25))) | |
29ed7081 | 5295 | (clobber (match_operand:SI 0 "register_operand" "=a")) |
15c2086a | 5296 | (clobber (match_operand:SI 1 "register_operand" "=&r")) |
c733e074 TM |
5297 | (clobber (reg:SI 26)) |
5298 | (clobber (reg:SI 25)) | |
5299 | (clobber (reg:SI 31))] | |
7d8b1412 | 5300 | "!TARGET_64BIT" |
c733e074 | 5301 | "* |
f854c12c | 5302 | return output_mod_insn (1, insn);" |
f726ea7d | 5303 | [(set_attr "type" "milli") |
611ad29e | 5304 | (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))]) |
c733e074 | 5305 | |
7d8b1412 AM |
5306 | (define_insn "" |
5307 | [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25))) | |
5308 | (clobber (match_operand:SI 0 "register_operand" "=a")) | |
5309 | (clobber (match_operand:SI 1 "register_operand" "=&r")) | |
5310 | (clobber (reg:SI 26)) | |
5311 | (clobber (reg:SI 25)) | |
5312 | (clobber (reg:SI 2))] | |
5313 | "TARGET_64BIT" | |
5314 | "* | |
5315 | return output_mod_insn (1, insn);" | |
5316 | [(set_attr "type" "milli") | |
611ad29e | 5317 | (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))]) |
7d8b1412 | 5318 | |
c733e074 TM |
5319 | ;;- and instructions |
5320 | ;; We define DImode `and` so with DImode `not` we can get | |
5321 | ;; DImode `andn`. Other combinations are possible. | |
5322 | ||
5323 | (define_expand "anddi3" | |
5324 | [(set (match_operand:DI 0 "register_operand" "") | |
3914c31f JDA |
5325 | (and:DI (match_operand:DI 1 "and_operand" "") |
5326 | (match_operand:DI 2 "and_operand" "")))] | |
c733e074 TM |
5327 | "" |
5328 | " | |
5329 | { | |
3914c31f JDA |
5330 | if (TARGET_64BIT) |
5331 | { | |
5332 | /* One operand must be a register operand. */ | |
5333 | if (!register_operand (operands[1], DImode) | |
5334 | && !register_operand (operands[2], DImode)) | |
5335 | FAIL; | |
5336 | } | |
5337 | else | |
5338 | { | |
5339 | /* Both operands must be register operands. */ | |
5340 | if (!register_operand (operands[1], DImode) | |
5341 | || !register_operand (operands[2], DImode)) | |
5342 | FAIL; | |
5343 | } | |
c733e074 TM |
5344 | }") |
5345 | ||
5346 | (define_insn "" | |
5347 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5348 | (and:DI (match_operand:DI 1 "register_operand" "%r") | |
5349 | (match_operand:DI 2 "register_operand" "r")))] | |
520babc7 | 5350 | "!TARGET_64BIT" |
c733e074 | 5351 | "and %1,%2,%0\;and %R1,%R2,%R0" |
c47decad JL |
5352 | [(set_attr "type" "binary") |
5353 | (set_attr "length" "8")]) | |
c733e074 | 5354 | |
520babc7 JL |
5355 | (define_insn "" |
5356 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
5357 | (and:DI (match_operand:DI 1 "register_operand" "%?r,0") | |
5358 | (match_operand:DI 2 "and_operand" "rO,P")))] | |
5359 | "TARGET_64BIT" | |
5360 | "* return output_64bit_and (operands); " | |
5361 | [(set_attr "type" "binary") | |
5362 | (set_attr "length" "4")]) | |
5363 | ||
dadae817 | 5364 | ; The ? for op1 makes reload prefer zdepi instead of loading a huge |
2f95ebc2 | 5365 | ; constant with ldil;ldo. |
c733e074 | 5366 | (define_insn "andsi3" |
876662ef | 5367 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
dadae817 | 5368 | (and:SI (match_operand:SI 1 "register_operand" "%?r,0") |
876662ef | 5369 | (match_operand:SI 2 "and_operand" "rO,P")))] |
c733e074 | 5370 | "" |
34f921d8 | 5371 | "* return output_and (operands); " |
c47decad JL |
5372 | [(set_attr "type" "binary,shift") |
5373 | (set_attr "length" "4,4")]) | |
c733e074 TM |
5374 | |
5375 | (define_insn "" | |
5376 | [(set (match_operand:DI 0 "register_operand" "=r") | |
876662ef TG |
5377 | (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) |
5378 | (match_operand:DI 2 "register_operand" "r")))] | |
520babc7 | 5379 | "!TARGET_64BIT" |
c733e074 | 5380 | "andcm %2,%1,%0\;andcm %R2,%R1,%R0" |
c47decad JL |
5381 | [(set_attr "type" "binary") |
5382 | (set_attr "length" "8")]) | |
c733e074 | 5383 | |
520babc7 JL |
5384 | (define_insn "" |
5385 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5386 | (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) | |
5387 | (match_operand:DI 2 "register_operand" "r")))] | |
5388 | "TARGET_64BIT" | |
5389 | "andcm %2,%1,%0" | |
5390 | [(set_attr "type" "binary") | |
5391 | (set_attr "length" "4")]) | |
5392 | ||
c733e074 TM |
5393 | (define_insn "" |
5394 | [(set (match_operand:SI 0 "register_operand" "=r") | |
876662ef TG |
5395 | (and:SI (not:SI (match_operand:SI 1 "register_operand" "r")) |
5396 | (match_operand:SI 2 "register_operand" "r")))] | |
c733e074 | 5397 | "" |
c47decad JL |
5398 | "andcm %2,%1,%0" |
5399 | [(set_attr "type" "binary") | |
5400 | (set_attr "length" "4")]) | |
c733e074 TM |
5401 | |
5402 | (define_expand "iordi3" | |
5403 | [(set (match_operand:DI 0 "register_operand" "") | |
3914c31f JDA |
5404 | (ior:DI (match_operand:DI 1 "ior_operand" "") |
5405 | (match_operand:DI 2 "ior_operand" "")))] | |
c733e074 TM |
5406 | "" |
5407 | " | |
5408 | { | |
3914c31f JDA |
5409 | if (TARGET_64BIT) |
5410 | { | |
5411 | /* One operand must be a register operand. */ | |
5412 | if (!register_operand (operands[1], DImode) | |
5413 | && !register_operand (operands[2], DImode)) | |
5414 | FAIL; | |
5415 | } | |
5416 | else | |
5417 | { | |
5418 | /* Both operands must be register operands. */ | |
5419 | if (!register_operand (operands[1], DImode) | |
5420 | || !register_operand (operands[2], DImode)) | |
5421 | FAIL; | |
5422 | } | |
c733e074 TM |
5423 | }") |
5424 | ||
5425 | (define_insn "" | |
5426 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5427 | (ior:DI (match_operand:DI 1 "register_operand" "%r") | |
5428 | (match_operand:DI 2 "register_operand" "r")))] | |
520babc7 | 5429 | "!TARGET_64BIT" |
c733e074 | 5430 | "or %1,%2,%0\;or %R1,%R2,%R0" |
c47decad JL |
5431 | [(set_attr "type" "binary") |
5432 | (set_attr "length" "8")]) | |
c733e074 | 5433 | |
520babc7 JL |
5434 | (define_insn "" |
5435 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
5436 | (ior:DI (match_operand:DI 1 "register_operand" "0,0") | |
5437 | (match_operand:DI 2 "ior_operand" "M,i")))] | |
5438 | "TARGET_64BIT" | |
5439 | "* return output_64bit_ior (operands); " | |
5440 | [(set_attr "type" "binary,shift") | |
5441 | (set_attr "length" "4,4")]) | |
5442 | ||
5443 | (define_insn "" | |
5444 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5445 | (ior:DI (match_operand:DI 1 "register_operand" "%r") | |
5446 | (match_operand:DI 2 "register_operand" "r")))] | |
5447 | "TARGET_64BIT" | |
5448 | "or %1,%2,%0" | |
5449 | [(set_attr "type" "binary") | |
5450 | (set_attr "length" "4")]) | |
5451 | ||
d5db6922 TG |
5452 | ;; Need a define_expand because we've run out of CONST_OK... characters. |
5453 | (define_expand "iorsi3" | |
5454 | [(set (match_operand:SI 0 "register_operand" "") | |
5455 | (ior:SI (match_operand:SI 1 "register_operand" "") | |
5456 | (match_operand:SI 2 "arith32_operand" "")))] | |
5457 | "" | |
5458 | " | |
5459 | { | |
74c3447c JM |
5460 | if (! (ior_operand (operands[2], SImode) |
5461 | || register_operand (operands[2], SImode))) | |
d5db6922 TG |
5462 | operands[2] = force_reg (SImode, operands[2]); |
5463 | }") | |
5464 | ||
9a82d0bb | 5465 | (define_insn "" |
c47decad JL |
5466 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
5467 | (ior:SI (match_operand:SI 1 "register_operand" "0,0") | |
5468 | (match_operand:SI 2 "ior_operand" "M,i")))] | |
9a82d0bb | 5469 | "" |
34f921d8 | 5470 | "* return output_ior (operands); " |
c47decad JL |
5471 | [(set_attr "type" "binary,shift") |
5472 | (set_attr "length" "4,4")]) | |
9a82d0bb | 5473 | |
d5db6922 | 5474 | (define_insn "" |
9a82d0bb JL |
5475 | [(set (match_operand:SI 0 "register_operand" "=r") |
5476 | (ior:SI (match_operand:SI 1 "register_operand" "%r") | |
5477 | (match_operand:SI 2 "register_operand" "r")))] | |
c733e074 | 5478 | "" |
c47decad JL |
5479 | "or %1,%2,%0" |
5480 | [(set_attr "type" "binary") | |
5481 | (set_attr "length" "4")]) | |
c733e074 TM |
5482 | |
5483 | (define_expand "xordi3" | |
5484 | [(set (match_operand:DI 0 "register_operand" "") | |
3914c31f JDA |
5485 | (xor:DI (match_operand:DI 1 "register_operand" "") |
5486 | (match_operand:DI 2 "register_operand" "")))] | |
c733e074 TM |
5487 | "" |
5488 | " | |
5489 | { | |
c733e074 TM |
5490 | }") |
5491 | ||
5492 | (define_insn "" | |
5493 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5494 | (xor:DI (match_operand:DI 1 "register_operand" "%r") | |
5495 | (match_operand:DI 2 "register_operand" "r")))] | |
520babc7 | 5496 | "!TARGET_64BIT" |
c733e074 | 5497 | "xor %1,%2,%0\;xor %R1,%R2,%R0" |
c47decad JL |
5498 | [(set_attr "type" "binary") |
5499 | (set_attr "length" "8")]) | |
c733e074 | 5500 | |
520babc7 JL |
5501 | (define_insn "" |
5502 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5503 | (xor:DI (match_operand:DI 1 "register_operand" "%r") | |
5504 | (match_operand:DI 2 "register_operand" "r")))] | |
5505 | "TARGET_64BIT" | |
5506 | "xor %1,%2,%0" | |
5507 | [(set_attr "type" "binary") | |
5508 | (set_attr "length" "4")]) | |
5509 | ||
c733e074 TM |
5510 | (define_insn "xorsi3" |
5511 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5512 | (xor:SI (match_operand:SI 1 "register_operand" "%r") | |
5513 | (match_operand:SI 2 "register_operand" "r")))] | |
5514 | "" | |
c47decad JL |
5515 | "xor %1,%2,%0" |
5516 | [(set_attr "type" "binary") | |
5517 | (set_attr "length" "4")]) | |
c733e074 | 5518 | |
4aa95f0d JL |
5519 | (define_expand "negdi2" |
5520 | [(set (match_operand:DI 0 "register_operand" "") | |
5521 | (neg:DI (match_operand:DI 1 "register_operand" "")))] | |
5522 | "" | |
5523 | "") | |
5524 | ||
5525 | (define_insn "" | |
c733e074 TM |
5526 | [(set (match_operand:DI 0 "register_operand" "=r") |
5527 | (neg:DI (match_operand:DI 1 "register_operand" "r")))] | |
520babc7 | 5528 | "!TARGET_64BIT" |
f38b27c7 | 5529 | "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0" |
c733e074 | 5530 | [(set_attr "type" "unary") |
4c2164b7 | 5531 | (set_attr "length" "8")]) |
c733e074 | 5532 | |
520babc7 JL |
5533 | (define_insn "" |
5534 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5535 | (neg:DI (match_operand:DI 1 "register_operand" "r")))] | |
5536 | "TARGET_64BIT" | |
5537 | "sub %%r0,%1,%0" | |
5538 | [(set_attr "type" "unary") | |
5539 | (set_attr "length" "4")]) | |
5540 | ||
c733e074 TM |
5541 | (define_insn "negsi2" |
5542 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5543 | (neg:SI (match_operand:SI 1 "register_operand" "r")))] | |
5544 | "" | |
3b5e5fb3 | 5545 | "sub %%r0,%1,%0" |
c47decad JL |
5546 | [(set_attr "type" "unary") |
5547 | (set_attr "length" "4")]) | |
c733e074 TM |
5548 | |
5549 | (define_expand "one_cmpldi2" | |
5550 | [(set (match_operand:DI 0 "register_operand" "") | |
3914c31f | 5551 | (not:DI (match_operand:DI 1 "register_operand" "")))] |
c733e074 TM |
5552 | "" |
5553 | " | |
5554 | { | |
c733e074 TM |
5555 | }") |
5556 | ||
5557 | (define_insn "" | |
5558 | [(set (match_operand:DI 0 "register_operand" "=r") | |
876662ef | 5559 | (not:DI (match_operand:DI 1 "register_operand" "r")))] |
520babc7 | 5560 | "!TARGET_64BIT" |
3b5e5fb3 | 5561 | "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0" |
c733e074 | 5562 | [(set_attr "type" "unary") |
4c2164b7 | 5563 | (set_attr "length" "8")]) |
c733e074 | 5564 | |
520babc7 JL |
5565 | (define_insn "" |
5566 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5567 | (not:DI (match_operand:DI 1 "register_operand" "r")))] | |
5568 | "TARGET_64BIT" | |
5569 | "uaddcm %%r0,%1,%0" | |
5570 | [(set_attr "type" "unary") | |
5571 | (set_attr "length" "4")]) | |
5572 | ||
c733e074 TM |
5573 | (define_insn "one_cmplsi2" |
5574 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5575 | (not:SI (match_operand:SI 1 "register_operand" "r")))] | |
5576 | "" | |
3b5e5fb3 | 5577 | "uaddcm %%r0,%1,%0" |
c47decad JL |
5578 | [(set_attr "type" "unary") |
5579 | (set_attr "length" "4")]) | |
c733e074 TM |
5580 | \f |
5581 | ;; Floating point arithmetic instructions. | |
5582 | ||
5583 | (define_insn "adddf3" | |
0b27d5dd TG |
5584 | [(set (match_operand:DF 0 "register_operand" "=f") |
5585 | (plus:DF (match_operand:DF 1 "register_operand" "f") | |
5586 | (match_operand:DF 2 "register_operand" "f")))] | |
925cf581 | 5587 | "! TARGET_SOFT_FLOAT" |
c733e074 | 5588 | "fadd,dbl %1,%2,%0" |
c47decad | 5589 | [(set_attr "type" "fpalu") |
c4bb6b38 | 5590 | (set_attr "pa_combine_type" "faddsub") |
c47decad | 5591 | (set_attr "length" "4")]) |
c733e074 TM |
5592 | |
5593 | (define_insn "addsf3" | |
0b27d5dd TG |
5594 | [(set (match_operand:SF 0 "register_operand" "=f") |
5595 | (plus:SF (match_operand:SF 1 "register_operand" "f") | |
5596 | (match_operand:SF 2 "register_operand" "f")))] | |
925cf581 | 5597 | "! TARGET_SOFT_FLOAT" |
c733e074 | 5598 | "fadd,sgl %1,%2,%0" |
c47decad | 5599 | [(set_attr "type" "fpalu") |
c4bb6b38 | 5600 | (set_attr "pa_combine_type" "faddsub") |
c47decad | 5601 | (set_attr "length" "4")]) |
c733e074 TM |
5602 | |
5603 | (define_insn "subdf3" | |
0b27d5dd TG |
5604 | [(set (match_operand:DF 0 "register_operand" "=f") |
5605 | (minus:DF (match_operand:DF 1 "register_operand" "f") | |
5606 | (match_operand:DF 2 "register_operand" "f")))] | |
925cf581 | 5607 | "! TARGET_SOFT_FLOAT" |
c733e074 | 5608 | "fsub,dbl %1,%2,%0" |
c47decad | 5609 | [(set_attr "type" "fpalu") |
c4bb6b38 | 5610 | (set_attr "pa_combine_type" "faddsub") |
c47decad | 5611 | (set_attr "length" "4")]) |
c733e074 TM |
5612 | |
5613 | (define_insn "subsf3" | |
0b27d5dd TG |
5614 | [(set (match_operand:SF 0 "register_operand" "=f") |
5615 | (minus:SF (match_operand:SF 1 "register_operand" "f") | |
5616 | (match_operand:SF 2 "register_operand" "f")))] | |
925cf581 | 5617 | "! TARGET_SOFT_FLOAT" |
c733e074 | 5618 | "fsub,sgl %1,%2,%0" |
c47decad | 5619 | [(set_attr "type" "fpalu") |
c4bb6b38 | 5620 | (set_attr "pa_combine_type" "faddsub") |
c47decad | 5621 | (set_attr "length" "4")]) |
c733e074 TM |
5622 | |
5623 | (define_insn "muldf3" | |
0b27d5dd TG |
5624 | [(set (match_operand:DF 0 "register_operand" "=f") |
5625 | (mult:DF (match_operand:DF 1 "register_operand" "f") | |
5626 | (match_operand:DF 2 "register_operand" "f")))] | |
925cf581 | 5627 | "! TARGET_SOFT_FLOAT" |
c733e074 | 5628 | "fmpy,dbl %1,%2,%0" |
c47decad | 5629 | [(set_attr "type" "fpmuldbl") |
c4bb6b38 | 5630 | (set_attr "pa_combine_type" "fmpy") |
c47decad | 5631 | (set_attr "length" "4")]) |
c733e074 TM |
5632 | |
5633 | (define_insn "mulsf3" | |
0b27d5dd TG |
5634 | [(set (match_operand:SF 0 "register_operand" "=f") |
5635 | (mult:SF (match_operand:SF 1 "register_operand" "f") | |
5636 | (match_operand:SF 2 "register_operand" "f")))] | |
925cf581 | 5637 | "! TARGET_SOFT_FLOAT" |
c733e074 | 5638 | "fmpy,sgl %1,%2,%0" |
c47decad | 5639 | [(set_attr "type" "fpmulsgl") |
c4bb6b38 | 5640 | (set_attr "pa_combine_type" "fmpy") |
c47decad | 5641 | (set_attr "length" "4")]) |
c733e074 TM |
5642 | |
5643 | (define_insn "divdf3" | |
0b27d5dd TG |
5644 | [(set (match_operand:DF 0 "register_operand" "=f") |
5645 | (div:DF (match_operand:DF 1 "register_operand" "f") | |
5646 | (match_operand:DF 2 "register_operand" "f")))] | |
925cf581 | 5647 | "! TARGET_SOFT_FLOAT" |
c733e074 | 5648 | "fdiv,dbl %1,%2,%0" |
c47decad JL |
5649 | [(set_attr "type" "fpdivdbl") |
5650 | (set_attr "length" "4")]) | |
c733e074 TM |
5651 | |
5652 | (define_insn "divsf3" | |
0b27d5dd TG |
5653 | [(set (match_operand:SF 0 "register_operand" "=f") |
5654 | (div:SF (match_operand:SF 1 "register_operand" "f") | |
5655 | (match_operand:SF 2 "register_operand" "f")))] | |
925cf581 | 5656 | "! TARGET_SOFT_FLOAT" |
c733e074 | 5657 | "fdiv,sgl %1,%2,%0" |
c47decad JL |
5658 | [(set_attr "type" "fpdivsgl") |
5659 | (set_attr "length" "4")]) | |
c733e074 | 5660 | |
8270e11f JDA |
5661 | ;; Processors prior to PA 2.0 don't have a fneg instruction. Fast |
5662 | ;; negation can be done by subtracting from plus zero. However, this | |
5663 | ;; violates the IEEE standard when negating plus and minus zero. | |
5664 | (define_expand "negdf2" | |
5665 | [(parallel [(set (match_operand:DF 0 "register_operand" "") | |
5666 | (neg:DF (match_operand:DF 1 "register_operand" ""))) | |
5667 | (use (match_dup 2))])] | |
5668 | "! TARGET_SOFT_FLOAT" | |
5669 | { | |
5670 | if (TARGET_PA_20 || flag_unsafe_math_optimizations) | |
5671 | emit_insn (gen_negdf2_fast (operands[0], operands[1])); | |
5672 | else | |
5673 | { | |
5692c7bc ZW |
5674 | operands[2] = force_reg (DFmode, |
5675 | CONST_DOUBLE_FROM_REAL_VALUE (dconstm1, DFmode)); | |
8270e11f JDA |
5676 | emit_insn (gen_muldf3 (operands[0], operands[1], operands[2])); |
5677 | } | |
5678 | DONE; | |
5679 | }) | |
5680 | ||
5681 | (define_insn "negdf2_fast" | |
0b27d5dd TG |
5682 | [(set (match_operand:DF 0 "register_operand" "=f") |
5683 | (neg:DF (match_operand:DF 1 "register_operand" "f")))] | |
8270e11f | 5684 | "! TARGET_SOFT_FLOAT && (TARGET_PA_20 || flag_unsafe_math_optimizations)" |
a366a40a JL |
5685 | "* |
5686 | { | |
5687 | if (TARGET_PA_20) | |
5688 | return \"fneg,dbl %1,%0\"; | |
5689 | else | |
5690 | return \"fsub,dbl %%fr0,%1,%0\"; | |
5691 | }" | |
c47decad JL |
5692 | [(set_attr "type" "fpalu") |
5693 | (set_attr "length" "4")]) | |
c733e074 | 5694 | |
8270e11f JDA |
5695 | (define_expand "negsf2" |
5696 | [(parallel [(set (match_operand:SF 0 "register_operand" "") | |
5697 | (neg:SF (match_operand:SF 1 "register_operand" ""))) | |
5698 | (use (match_dup 2))])] | |
5699 | "! TARGET_SOFT_FLOAT" | |
5700 | { | |
5701 | if (TARGET_PA_20 || flag_unsafe_math_optimizations) | |
5702 | emit_insn (gen_negsf2_fast (operands[0], operands[1])); | |
5703 | else | |
5704 | { | |
5692c7bc ZW |
5705 | operands[2] = force_reg (SFmode, |
5706 | CONST_DOUBLE_FROM_REAL_VALUE (dconstm1, SFmode)); | |
8270e11f JDA |
5707 | emit_insn (gen_mulsf3 (operands[0], operands[1], operands[2])); |
5708 | } | |
5709 | DONE; | |
5710 | }) | |
5711 | ||
5712 | (define_insn "negsf2_fast" | |
0b27d5dd TG |
5713 | [(set (match_operand:SF 0 "register_operand" "=f") |
5714 | (neg:SF (match_operand:SF 1 "register_operand" "f")))] | |
8270e11f | 5715 | "! TARGET_SOFT_FLOAT && (TARGET_PA_20 || flag_unsafe_math_optimizations)" |
a366a40a JL |
5716 | "* |
5717 | { | |
5718 | if (TARGET_PA_20) | |
5719 | return \"fneg,sgl %1,%0\"; | |
5720 | else | |
5721 | return \"fsub,sgl %%fr0,%1,%0\"; | |
5722 | }" | |
c47decad JL |
5723 | [(set_attr "type" "fpalu") |
5724 | (set_attr "length" "4")]) | |
c733e074 TM |
5725 | |
5726 | (define_insn "absdf2" | |
0b27d5dd TG |
5727 | [(set (match_operand:DF 0 "register_operand" "=f") |
5728 | (abs:DF (match_operand:DF 1 "register_operand" "f")))] | |
925cf581 | 5729 | "! TARGET_SOFT_FLOAT" |
cb432e02 | 5730 | "fabs,dbl %1,%0" |
c47decad JL |
5731 | [(set_attr "type" "fpalu") |
5732 | (set_attr "length" "4")]) | |
c733e074 TM |
5733 | |
5734 | (define_insn "abssf2" | |
0b27d5dd TG |
5735 | [(set (match_operand:SF 0 "register_operand" "=f") |
5736 | (abs:SF (match_operand:SF 1 "register_operand" "f")))] | |
925cf581 | 5737 | "! TARGET_SOFT_FLOAT" |
c733e074 | 5738 | "fabs,sgl %1,%0" |
c47decad JL |
5739 | [(set_attr "type" "fpalu") |
5740 | (set_attr "length" "4")]) | |
c733e074 TM |
5741 | |
5742 | (define_insn "sqrtdf2" | |
0b27d5dd TG |
5743 | [(set (match_operand:DF 0 "register_operand" "=f") |
5744 | (sqrt:DF (match_operand:DF 1 "register_operand" "f")))] | |
925cf581 | 5745 | "! TARGET_SOFT_FLOAT" |
c733e074 | 5746 | "fsqrt,dbl %1,%0" |
c47decad JL |
5747 | [(set_attr "type" "fpsqrtdbl") |
5748 | (set_attr "length" "4")]) | |
c733e074 TM |
5749 | |
5750 | (define_insn "sqrtsf2" | |
0b27d5dd TG |
5751 | [(set (match_operand:SF 0 "register_operand" "=f") |
5752 | (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] | |
925cf581 | 5753 | "! TARGET_SOFT_FLOAT" |
c733e074 | 5754 | "fsqrt,sgl %1,%0" |
c47decad JL |
5755 | [(set_attr "type" "fpsqrtsgl") |
5756 | (set_attr "length" "4")]) | |
729f8bf2 JQ |
5757 | |
5758 | ;; PA 2.0 floating point instructions | |
5759 | ||
5760 | ; fmpyfadd patterns | |
5761 | (define_insn "" | |
5762 | [(set (match_operand:DF 0 "register_operand" "=f") | |
5763 | (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f") | |
5764 | (match_operand:DF 2 "register_operand" "f")) | |
5765 | (match_operand:DF 3 "register_operand" "f")))] | |
5766 | "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" | |
5767 | "fmpyfadd,dbl %1,%2,%3,%0" | |
5768 | [(set_attr "type" "fpmuldbl") | |
5769 | (set_attr "length" "4")]) | |
5770 | ||
5771 | (define_insn "" | |
5772 | [(set (match_operand:DF 0 "register_operand" "=f") | |
5773 | (plus:DF (match_operand:DF 1 "register_operand" "f") | |
5774 | (mult:DF (match_operand:DF 2 "register_operand" "f") | |
5775 | (match_operand:DF 3 "register_operand" "f"))))] | |
5776 | "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" | |
5777 | "fmpyfadd,dbl %2,%3,%1,%0" | |
5778 | [(set_attr "type" "fpmuldbl") | |
5779 | (set_attr "length" "4")]) | |
5780 | ||
5781 | (define_insn "" | |
5782 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5783 | (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f") | |
5784 | (match_operand:SF 2 "register_operand" "f")) | |
5785 | (match_operand:SF 3 "register_operand" "f")))] | |
5786 | "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" | |
5787 | "fmpyfadd,sgl %1,%2,%3,%0" | |
5788 | [(set_attr "type" "fpmulsgl") | |
5789 | (set_attr "length" "4")]) | |
5790 | ||
5791 | (define_insn "" | |
5792 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5793 | (plus:SF (match_operand:SF 1 "register_operand" "f") | |
5794 | (mult:SF (match_operand:SF 2 "register_operand" "f") | |
5795 | (match_operand:SF 3 "register_operand" "f"))))] | |
5796 | "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" | |
5797 | "fmpyfadd,sgl %2,%3,%1,%0" | |
5798 | [(set_attr "type" "fpmulsgl") | |
5799 | (set_attr "length" "4")]) | |
5800 | ||
5801 | ; fmpynfadd patterns | |
5802 | (define_insn "" | |
5803 | [(set (match_operand:DF 0 "register_operand" "=f") | |
5804 | (minus:DF (match_operand:DF 1 "register_operand" "f") | |
5805 | (mult:DF (match_operand:DF 2 "register_operand" "f") | |
5806 | (match_operand:DF 3 "register_operand" "f"))))] | |
5807 | "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" | |
5808 | "fmpynfadd,dbl %2,%3,%1,%0" | |
5809 | [(set_attr "type" "fpmuldbl") | |
5810 | (set_attr "length" "4")]) | |
5811 | ||
5812 | (define_insn "" | |
5813 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5814 | (minus:SF (match_operand:SF 1 "register_operand" "f") | |
5815 | (mult:SF (match_operand:SF 2 "register_operand" "f") | |
5816 | (match_operand:SF 3 "register_operand" "f"))))] | |
5817 | "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" | |
5818 | "fmpynfadd,sgl %2,%3,%1,%0" | |
5819 | [(set_attr "type" "fpmulsgl") | |
5820 | (set_attr "length" "4")]) | |
5821 | ||
5822 | ; fnegabs patterns | |
5823 | (define_insn "" | |
5824 | [(set (match_operand:DF 0 "register_operand" "=f") | |
5825 | (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))] | |
5826 | "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" | |
5827 | "fnegabs,dbl %1,%0" | |
5828 | [(set_attr "type" "fpalu") | |
5829 | (set_attr "length" "4")]) | |
5830 | ||
5831 | (define_insn "" | |
5832 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5833 | (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))] | |
5834 | "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" | |
5835 | "fnegabs,sgl %1,%0" | |
5836 | [(set_attr "type" "fpalu") | |
5837 | (set_attr "length" "4")]) | |
5838 | ||
9a40d6bc JL |
5839 | ;; Generating a fused multiply sequence is a win for this case as it will |
5840 | ;; reduce the latency for the fused case without impacting the plain | |
5841 | ;; multiply case. | |
5842 | ;; | |
5843 | ;; Similar possibilities exist for fnegabs, shadd and other insns which | |
5844 | ;; perform two operations with the result of the first feeding the second. | |
5845 | (define_insn "" | |
5846 | [(set (match_operand:DF 0 "register_operand" "=f") | |
5847 | (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f") | |
5848 | (match_operand:DF 2 "register_operand" "f")) | |
5849 | (match_operand:DF 3 "register_operand" "f"))) | |
5850 | (set (match_operand:DF 4 "register_operand" "=&f") | |
5851 | (mult:DF (match_dup 1) (match_dup 2)))] | |
b2153414 JE |
5852 | "(! TARGET_SOFT_FLOAT && TARGET_PA_20 |
5853 | && ! (reg_overlap_mentioned_p (operands[4], operands[1]) | |
5854 | || reg_overlap_mentioned_p (operands[4], operands[2])))" | |
9a40d6bc JL |
5855 | "#" |
5856 | [(set_attr "type" "fpmuldbl") | |
5857 | (set_attr "length" "8")]) | |
5858 | ||
5859 | ;; We want to split this up during scheduling since we want both insns | |
5860 | ;; to schedule independently. | |
5861 | (define_split | |
3794967f JDA |
5862 | [(set (match_operand:DF 0 "register_operand" "") |
5863 | (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "") | |
5864 | (match_operand:DF 2 "register_operand" "")) | |
5865 | (match_operand:DF 3 "register_operand" ""))) | |
5866 | (set (match_operand:DF 4 "register_operand" "") | |
9a40d6bc JL |
5867 | (mult:DF (match_dup 1) (match_dup 2)))] |
5868 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
5869 | [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2))) | |
5870 | (set (match_dup 0) (plus:DF (mult:DF (match_dup 1) (match_dup 2)) | |
5871 | (match_dup 3)))] | |
5872 | "") | |
5873 | ||
5874 | (define_insn "" | |
5875 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5876 | (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f") | |
5877 | (match_operand:SF 2 "register_operand" "f")) | |
5878 | (match_operand:SF 3 "register_operand" "f"))) | |
5879 | (set (match_operand:SF 4 "register_operand" "=&f") | |
5880 | (mult:SF (match_dup 1) (match_dup 2)))] | |
b2153414 JE |
5881 | "(! TARGET_SOFT_FLOAT && TARGET_PA_20 |
5882 | && ! (reg_overlap_mentioned_p (operands[4], operands[1]) | |
5883 | || reg_overlap_mentioned_p (operands[4], operands[2])))" | |
9a40d6bc JL |
5884 | "#" |
5885 | [(set_attr "type" "fpmuldbl") | |
5886 | (set_attr "length" "8")]) | |
5887 | ||
5888 | ;; We want to split this up during scheduling since we want both insns | |
5889 | ;; to schedule independently. | |
5890 | (define_split | |
3794967f JDA |
5891 | [(set (match_operand:SF 0 "register_operand" "") |
5892 | (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "") | |
5893 | (match_operand:SF 2 "register_operand" "")) | |
5894 | (match_operand:SF 3 "register_operand" ""))) | |
5895 | (set (match_operand:SF 4 "register_operand" "") | |
9a40d6bc JL |
5896 | (mult:SF (match_dup 1) (match_dup 2)))] |
5897 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
5898 | [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2))) | |
5899 | (set (match_dup 0) (plus:SF (mult:SF (match_dup 1) (match_dup 2)) | |
5900 | (match_dup 3)))] | |
5901 | "") | |
5902 | ||
5903 | ;; Negating a multiply can be faked by adding zero in a fused multiply-add | |
5904 | ;; instruction. | |
5905 | (define_insn "" | |
5906 | [(set (match_operand:DF 0 "register_operand" "=f") | |
5907 | (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f") | |
5908 | (match_operand:DF 2 "register_operand" "f"))))] | |
5909 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
04299876 | 5910 | "fmpynfadd,dbl %1,%2,%%fr0,%0" |
9a40d6bc JL |
5911 | [(set_attr "type" "fpmuldbl") |
5912 | (set_attr "length" "4")]) | |
5913 | ||
5914 | (define_insn "" | |
5915 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5916 | (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f") | |
5917 | (match_operand:SF 2 "register_operand" "f"))))] | |
5918 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
04299876 | 5919 | "fmpynfadd,sgl %1,%2,%%fr0,%0" |
9a40d6bc JL |
5920 | [(set_attr "type" "fpmuldbl") |
5921 | (set_attr "length" "4")]) | |
5922 | ||
5923 | (define_insn "" | |
5924 | [(set (match_operand:DF 0 "register_operand" "=f") | |
5925 | (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f") | |
5926 | (match_operand:DF 2 "register_operand" "f")))) | |
5927 | (set (match_operand:DF 3 "register_operand" "=&f") | |
5928 | (mult:DF (match_dup 1) (match_dup 2)))] | |
b2153414 JE |
5929 | "(! TARGET_SOFT_FLOAT && TARGET_PA_20 |
5930 | && ! (reg_overlap_mentioned_p (operands[3], operands[1]) | |
5931 | || reg_overlap_mentioned_p (operands[3], operands[2])))" | |
9a40d6bc JL |
5932 | "#" |
5933 | [(set_attr "type" "fpmuldbl") | |
5934 | (set_attr "length" "8")]) | |
5935 | ||
5936 | (define_split | |
3794967f JDA |
5937 | [(set (match_operand:DF 0 "register_operand" "") |
5938 | (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "") | |
5939 | (match_operand:DF 2 "register_operand" "")))) | |
5940 | (set (match_operand:DF 3 "register_operand" "") | |
9a40d6bc JL |
5941 | (mult:DF (match_dup 1) (match_dup 2)))] |
5942 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
5943 | [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2))) | |
5944 | (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))] | |
5945 | "") | |
5946 | ||
5947 | (define_insn "" | |
5948 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5949 | (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f") | |
5950 | (match_operand:SF 2 "register_operand" "f")))) | |
5951 | (set (match_operand:SF 3 "register_operand" "=&f") | |
5952 | (mult:SF (match_dup 1) (match_dup 2)))] | |
b2153414 JE |
5953 | "(! TARGET_SOFT_FLOAT && TARGET_PA_20 |
5954 | && ! (reg_overlap_mentioned_p (operands[3], operands[1]) | |
5955 | || reg_overlap_mentioned_p (operands[3], operands[2])))" | |
9a40d6bc JL |
5956 | "#" |
5957 | [(set_attr "type" "fpmuldbl") | |
5958 | (set_attr "length" "8")]) | |
5959 | ||
5960 | (define_split | |
3794967f JDA |
5961 | [(set (match_operand:SF 0 "register_operand" "") |
5962 | (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "") | |
5963 | (match_operand:SF 2 "register_operand" "")))) | |
5964 | (set (match_operand:SF 3 "register_operand" "") | |
9a40d6bc JL |
5965 | (mult:SF (match_dup 1) (match_dup 2)))] |
5966 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
5967 | [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2))) | |
5968 | (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))] | |
5969 | "") | |
5970 | ||
5971 | ;; Now fused multiplies with the result of the multiply negated. | |
5972 | (define_insn "" | |
5973 | [(set (match_operand:DF 0 "register_operand" "=f") | |
5974 | (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f") | |
5975 | (match_operand:DF 2 "register_operand" "f"))) | |
5976 | (match_operand:DF 3 "register_operand" "f")))] | |
5977 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
5978 | "fmpynfadd,dbl %1,%2,%3,%0" | |
5979 | [(set_attr "type" "fpmuldbl") | |
5980 | (set_attr "length" "4")]) | |
5981 | ||
5982 | (define_insn "" | |
5983 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5984 | (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f") | |
5985 | (match_operand:SF 2 "register_operand" "f"))) | |
5986 | (match_operand:SF 3 "register_operand" "f")))] | |
5987 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
5988 | "fmpynfadd,sgl %1,%2,%3,%0" | |
5989 | [(set_attr "type" "fpmuldbl") | |
5990 | (set_attr "length" "4")]) | |
5991 | ||
5992 | (define_insn "" | |
5993 | [(set (match_operand:DF 0 "register_operand" "=f") | |
5994 | (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f") | |
5995 | (match_operand:DF 2 "register_operand" "f"))) | |
5996 | (match_operand:DF 3 "register_operand" "f"))) | |
5997 | (set (match_operand:DF 4 "register_operand" "=&f") | |
5998 | (mult:DF (match_dup 1) (match_dup 2)))] | |
b2153414 JE |
5999 | "(! TARGET_SOFT_FLOAT && TARGET_PA_20 |
6000 | && ! (reg_overlap_mentioned_p (operands[4], operands[1]) | |
6001 | || reg_overlap_mentioned_p (operands[4], operands[2])))" | |
9a40d6bc JL |
6002 | "#" |
6003 | [(set_attr "type" "fpmuldbl") | |
6004 | (set_attr "length" "8")]) | |
6005 | ||
6006 | (define_split | |
3794967f JDA |
6007 | [(set (match_operand:DF 0 "register_operand" "") |
6008 | (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "") | |
6009 | (match_operand:DF 2 "register_operand" ""))) | |
6010 | (match_operand:DF 3 "register_operand" ""))) | |
6011 | (set (match_operand:DF 4 "register_operand" "") | |
9a40d6bc JL |
6012 | (mult:DF (match_dup 1) (match_dup 2)))] |
6013 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
6014 | [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2))) | |
6015 | (set (match_dup 0) (plus:DF (neg:DF (mult:DF (match_dup 1) (match_dup 2))) | |
6016 | (match_dup 3)))] | |
6017 | "") | |
6018 | ||
6019 | (define_insn "" | |
6020 | [(set (match_operand:SF 0 "register_operand" "=f") | |
6021 | (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f") | |
6022 | (match_operand:SF 2 "register_operand" "f"))) | |
6023 | (match_operand:SF 3 "register_operand" "f"))) | |
6024 | (set (match_operand:SF 4 "register_operand" "=&f") | |
6025 | (mult:SF (match_dup 1) (match_dup 2)))] | |
b2153414 JE |
6026 | "(! TARGET_SOFT_FLOAT && TARGET_PA_20 |
6027 | && ! (reg_overlap_mentioned_p (operands[4], operands[1]) | |
6028 | || reg_overlap_mentioned_p (operands[4], operands[2])))" | |
9a40d6bc JL |
6029 | "#" |
6030 | [(set_attr "type" "fpmuldbl") | |
6031 | (set_attr "length" "8")]) | |
6032 | ||
6033 | (define_split | |
3794967f JDA |
6034 | [(set (match_operand:SF 0 "register_operand" "") |
6035 | (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "") | |
6036 | (match_operand:SF 2 "register_operand" ""))) | |
6037 | (match_operand:SF 3 "register_operand" ""))) | |
6038 | (set (match_operand:SF 4 "register_operand" "") | |
9a40d6bc JL |
6039 | (mult:SF (match_dup 1) (match_dup 2)))] |
6040 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
6041 | [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2))) | |
6042 | (set (match_dup 0) (plus:SF (neg:SF (mult:SF (match_dup 1) (match_dup 2))) | |
6043 | (match_dup 3)))] | |
6044 | "") | |
6045 | ||
6046 | (define_insn "" | |
6047 | [(set (match_operand:DF 0 "register_operand" "=f") | |
6048 | (minus:DF (match_operand:DF 3 "register_operand" "f") | |
6049 | (mult:DF (match_operand:DF 1 "register_operand" "f") | |
6050 | (match_operand:DF 2 "register_operand" "f")))) | |
6051 | (set (match_operand:DF 4 "register_operand" "=&f") | |
6052 | (mult:DF (match_dup 1) (match_dup 2)))] | |
b2153414 JE |
6053 | "(! TARGET_SOFT_FLOAT && TARGET_PA_20 |
6054 | && ! (reg_overlap_mentioned_p (operands[4], operands[1]) | |
6055 | || reg_overlap_mentioned_p (operands[4], operands[2])))" | |
9a40d6bc JL |
6056 | "#" |
6057 | [(set_attr "type" "fpmuldbl") | |
6058 | (set_attr "length" "8")]) | |
6059 | ||
6060 | (define_split | |
3794967f JDA |
6061 | [(set (match_operand:DF 0 "register_operand" "") |
6062 | (minus:DF (match_operand:DF 3 "register_operand" "") | |
6063 | (mult:DF (match_operand:DF 1 "register_operand" "") | |
6064 | (match_operand:DF 2 "register_operand" "")))) | |
6065 | (set (match_operand:DF 4 "register_operand" "") | |
9a40d6bc JL |
6066 | (mult:DF (match_dup 1) (match_dup 2)))] |
6067 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
6068 | [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2))) | |
6069 | (set (match_dup 0) (minus:DF (match_dup 3) | |
6070 | (mult:DF (match_dup 1) (match_dup 2))))] | |
6071 | "") | |
6072 | ||
6073 | (define_insn "" | |
6074 | [(set (match_operand:SF 0 "register_operand" "=f") | |
6075 | (minus:SF (match_operand:SF 3 "register_operand" "f") | |
6076 | (mult:SF (match_operand:SF 1 "register_operand" "f") | |
6077 | (match_operand:SF 2 "register_operand" "f")))) | |
6078 | (set (match_operand:SF 4 "register_operand" "=&f") | |
6079 | (mult:SF (match_dup 1) (match_dup 2)))] | |
b2153414 JE |
6080 | "(! TARGET_SOFT_FLOAT && TARGET_PA_20 |
6081 | && ! (reg_overlap_mentioned_p (operands[4], operands[1]) | |
6082 | || reg_overlap_mentioned_p (operands[4], operands[2])))" | |
9a40d6bc JL |
6083 | "#" |
6084 | [(set_attr "type" "fpmuldbl") | |
6085 | (set_attr "length" "8")]) | |
6086 | ||
6087 | (define_split | |
3794967f JDA |
6088 | [(set (match_operand:SF 0 "register_operand" "") |
6089 | (minus:SF (match_operand:SF 3 "register_operand" "") | |
6090 | (mult:SF (match_operand:SF 1 "register_operand" "") | |
6091 | (match_operand:SF 2 "register_operand" "")))) | |
6092 | (set (match_operand:SF 4 "register_operand" "") | |
9a40d6bc JL |
6093 | (mult:SF (match_dup 1) (match_dup 2)))] |
6094 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" | |
6095 | [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2))) | |
6096 | (set (match_dup 0) (minus:SF (match_dup 3) | |
6097 | (mult:SF (match_dup 1) (match_dup 2))))] | |
6098 | "") | |
6099 | ||
6100 | (define_insn "" | |
6101 | [(set (match_operand:DF 0 "register_operand" "=f") | |
6102 | (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f")))) | |
6103 | (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))] | |
b2153414 JE |
6104 | "(! TARGET_SOFT_FLOAT && TARGET_PA_20 |
6105 | && ! reg_overlap_mentioned_p (operands[2], operands[1]))" | |
9a40d6bc JL |
6106 | "#" |
6107 | [(set_attr "type" "fpalu") | |
6108 | (set_attr "length" "8")]) | |
6109 | ||
6110 | (define_split | |
3794967f JDA |
6111 | [(set (match_operand:DF 0 "register_operand" "") |
6112 | (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "")))) | |
6113 | (set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))] | |
9a40d6bc JL |
6114 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" |
6115 | [(set (match_dup 2) (abs:DF (match_dup 1))) | |
6116 | (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))] | |
6117 | "") | |
6118 | ||
6119 | (define_insn "" | |
6120 | [(set (match_operand:SF 0 "register_operand" "=f") | |
6121 | (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f")))) | |
6122 | (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))] | |
b2153414 JE |
6123 | "(! TARGET_SOFT_FLOAT && TARGET_PA_20 |
6124 | && ! reg_overlap_mentioned_p (operands[2], operands[1]))" | |
9a40d6bc JL |
6125 | "#" |
6126 | [(set_attr "type" "fpalu") | |
6127 | (set_attr "length" "8")]) | |
6128 | ||
6129 | (define_split | |
3794967f JDA |
6130 | [(set (match_operand:SF 0 "register_operand" "") |
6131 | (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "")))) | |
6132 | (set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))] | |
9a40d6bc JL |
6133 | "! TARGET_SOFT_FLOAT && TARGET_PA_20" |
6134 | [(set (match_dup 2) (abs:SF (match_dup 1))) | |
6135 | (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))] | |
6136 | "") | |
c733e074 TM |
6137 | \f |
6138 | ;;- Shift instructions | |
6139 | ||
6140 | ;; Optimized special case of shifting. | |
6141 | ||
6142 | (define_insn "" | |
6143 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6144 | (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") | |
6145 | (const_int 24)))] | |
6146 | "" | |
907f67cc TG |
6147 | "ldb%M1 %1,%0" |
6148 | [(set_attr "type" "load") | |
4c2164b7 | 6149 | (set_attr "length" "4")]) |
907f67cc TG |
6150 | |
6151 | (define_insn "" | |
6152 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6153 | (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") | |
6154 | (const_int 16)))] | |
6155 | "" | |
6156 | "ldh%M1 %1,%0" | |
6157 | [(set_attr "type" "load") | |
4c2164b7 | 6158 | (set_attr "length" "4")]) |
c733e074 TM |
6159 | |
6160 | (define_insn "" | |
6161 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6162 | (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") | |
b8be8876 | 6163 | (match_operand:SI 3 "shadd_operand" "")) |
81722625 | 6164 | (match_operand:SI 1 "register_operand" "r")))] |
c733e074 | 6165 | "" |
f38b27c7 | 6166 | "{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0} " |
c47decad JL |
6167 | [(set_attr "type" "binary") |
6168 | (set_attr "length" "4")]) | |
c733e074 | 6169 | |
520babc7 JL |
6170 | (define_insn "" |
6171 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6172 | (plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r") | |
6173 | (match_operand:DI 3 "shadd_operand" "")) | |
6174 | (match_operand:DI 1 "register_operand" "r")))] | |
6175 | "TARGET_64BIT" | |
6176 | "shladd,l %2,%O3,%1,%0" | |
6177 | [(set_attr "type" "binary") | |
6178 | (set_attr "length" "4")]) | |
6179 | ||
c733e074 TM |
6180 | (define_expand "ashlsi3" |
6181 | [(set (match_operand:SI 0 "register_operand" "") | |
95246213 | 6182 | (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "") |
ba0443bb | 6183 | (match_operand:SI 2 "arith32_operand" "")))] |
c733e074 TM |
6184 | "" |
6185 | " | |
6186 | { | |
6187 | if (GET_CODE (operands[2]) != CONST_INT) | |
6188 | { | |
6189 | rtx temp = gen_reg_rtx (SImode); | |
6f672dc0 | 6190 | emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2])); |
c210e6ae | 6191 | if (GET_CODE (operands[1]) == CONST_INT) |
93b69d0f | 6192 | emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp)); |
c210e6ae TG |
6193 | else |
6194 | emit_insn (gen_zvdep32 (operands[0], operands[1], temp)); | |
c733e074 TM |
6195 | DONE; |
6196 | } | |
2f95ebc2 | 6197 | /* Make sure both inputs are not constants, |
c210e6ae | 6198 | there are no patterns for that. */ |
56a65d12 | 6199 | operands[1] = force_reg (SImode, operands[1]); |
c733e074 TM |
6200 | }") |
6201 | ||
6202 | (define_insn "" | |
56a65d12 TG |
6203 | [(set (match_operand:SI 0 "register_operand" "=r") |
6204 | (ashift:SI (match_operand:SI 1 "register_operand" "r") | |
6205 | (match_operand:SI 2 "const_int_operand" "n")))] | |
6206 | "" | |
f38b27c7 | 6207 | "{zdep|depw,z} %1,%P2,%L2,%0" |
c47decad | 6208 | [(set_attr "type" "shift") |
4c2164b7 | 6209 | (set_attr "length" "4")]) |
c733e074 | 6210 | |
93b69d0f | 6211 | ; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle. |
95246213 TG |
6212 | ; Doing it like this makes slightly better code since reload can |
6213 | ; replace a register with a known value in range -16..15 with a | |
93b69d0f | 6214 | ; constant. Ideally, we would like to merge zvdep32 and zvdep_imm32, |
95246213 TG |
6215 | ; but since we have no more CONST_OK... characters, that is not |
6216 | ; possible. | |
cb524f44 | 6217 | (define_insn "zvdep32" |
56a65d12 TG |
6218 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
6219 | (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L") | |
6220 | (minus:SI (const_int 31) | |
6221 | (match_operand:SI 2 "register_operand" "q,q"))))] | |
6222 | "" | |
6223 | "@ | |
f38b27c7 JL |
6224 | {zvdep %1,32,%0|depw,z %1,%%sar,32,%0} |
6225 | {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}" | |
c47decad JL |
6226 | [(set_attr "type" "shift,shift") |
6227 | (set_attr "length" "4,4")]) | |
c733e074 | 6228 | |
93b69d0f | 6229 | (define_insn "zvdep_imm32" |
95246213 TG |
6230 | [(set (match_operand:SI 0 "register_operand" "=r") |
6231 | (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "") | |
6232 | (minus:SI (const_int 31) | |
6233 | (match_operand:SI 2 "register_operand" "q"))))] | |
6234 | "" | |
6235 | "* | |
6236 | { | |
6237 | int x = INTVAL (operands[1]); | |
6238 | operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1)); | |
6239 | operands[1] = GEN_INT ((x & 0xf) - 0x10); | |
f38b27c7 | 6240 | return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\"; |
c47decad JL |
6241 | }" |
6242 | [(set_attr "type" "shift") | |
6243 | (set_attr "length" "4")]) | |
95246213 | 6244 | |
2f95ebc2 TG |
6245 | (define_insn "vdepi_ior" |
6246 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6247 | (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "") | |
6248 | (minus:SI (const_int 31) | |
6249 | (match_operand:SI 2 "register_operand" "q"))) | |
6250 | (match_operand:SI 3 "register_operand" "0")))] | |
6251 | ; accept ...0001...1, can this be generalized? | |
6252 | "exact_log2 (INTVAL (operands[1]) + 1) >= 0" | |
6253 | "* | |
6254 | { | |
6255 | int x = INTVAL (operands[1]); | |
6256 | operands[2] = GEN_INT (exact_log2 (x + 1)); | |
f38b27c7 | 6257 | return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\"; |
c47decad JL |
6258 | }" |
6259 | [(set_attr "type" "shift") | |
6260 | (set_attr "length" "4")]) | |
2f95ebc2 TG |
6261 | |
6262 | (define_insn "vdepi_and" | |
6263 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6264 | (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "") | |
6265 | (minus:SI (const_int 31) | |
6266 | (match_operand:SI 2 "register_operand" "q"))) | |
6267 | (match_operand:SI 3 "register_operand" "0")))] | |
6268 | ; this can be generalized...! | |
520babc7 JL |
6269 | "INTVAL (operands[1]) == -2" |
6270 | "* | |
6271 | { | |
6272 | int x = INTVAL (operands[1]); | |
6273 | operands[2] = GEN_INT (exact_log2 ((~x) + 1)); | |
6274 | return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\"; | |
6275 | }" | |
6276 | [(set_attr "type" "shift") | |
6277 | (set_attr "length" "4")]) | |
6278 | ||
6279 | (define_expand "ashldi3" | |
6280 | [(set (match_operand:DI 0 "register_operand" "") | |
6281 | (ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "") | |
6282 | (match_operand:DI 2 "arith32_operand" "")))] | |
6283 | "TARGET_64BIT" | |
6284 | " | |
6285 | { | |
6286 | if (GET_CODE (operands[2]) != CONST_INT) | |
6287 | { | |
6288 | rtx temp = gen_reg_rtx (DImode); | |
6289 | emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2])); | |
6290 | if (GET_CODE (operands[1]) == CONST_INT) | |
6291 | emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp)); | |
6292 | else | |
6293 | emit_insn (gen_zvdep64 (operands[0], operands[1], temp)); | |
6294 | DONE; | |
6295 | } | |
6296 | /* Make sure both inputs are not constants, | |
6297 | there are no patterns for that. */ | |
6298 | operands[1] = force_reg (DImode, operands[1]); | |
6299 | }") | |
6300 | ||
6301 | (define_insn "" | |
6302 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6303 | (ashift:DI (match_operand:DI 1 "register_operand" "r") | |
6304 | (match_operand:DI 2 "const_int_operand" "n")))] | |
6305 | "TARGET_64BIT" | |
6306 | "depd,z %1,%p2,%Q2,%0" | |
6307 | [(set_attr "type" "shift") | |
6308 | (set_attr "length" "4")]) | |
6309 | ||
6310 | ; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle. | |
6311 | ; Doing it like this makes slightly better code since reload can | |
6312 | ; replace a register with a known value in range -16..15 with a | |
6313 | ; constant. Ideally, we would like to merge zvdep64 and zvdep_imm64, | |
6314 | ; but since we have no more CONST_OK... characters, that is not | |
6315 | ; possible. | |
6316 | (define_insn "zvdep64" | |
6317 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
6318 | (ashift:DI (match_operand:DI 1 "arith5_operand" "r,L") | |
6319 | (minus:DI (const_int 63) | |
6320 | (match_operand:DI 2 "register_operand" "q,q"))))] | |
6321 | "TARGET_64BIT" | |
6322 | "@ | |
6323 | depd,z %1,%%sar,64,%0 | |
6324 | depdi,z %1,%%sar,64,%0" | |
6325 | [(set_attr "type" "shift,shift") | |
6326 | (set_attr "length" "4,4")]) | |
6327 | ||
6328 | (define_insn "zvdep_imm64" | |
6329 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6330 | (ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "") | |
6331 | (minus:DI (const_int 63) | |
6332 | (match_operand:DI 2 "register_operand" "q"))))] | |
6333 | "TARGET_64BIT" | |
6334 | "* | |
6335 | { | |
6336 | int x = INTVAL (operands[1]); | |
6337 | operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1)); | |
6338 | operands[1] = GEN_INT ((x & 0x1f) - 0x20); | |
6339 | return \"depdi,z %1,%%sar,%2,%0\"; | |
6340 | }" | |
6341 | [(set_attr "type" "shift") | |
6342 | (set_attr "length" "4")]) | |
6343 | ||
6344 | (define_insn "" | |
6345 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6346 | (ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "") | |
6347 | (minus:DI (const_int 63) | |
6348 | (match_operand:DI 2 "register_operand" "q"))) | |
6349 | (match_operand:DI 3 "register_operand" "0")))] | |
6350 | ; accept ...0001...1, can this be generalized? | |
6351 | "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) >= 0" | |
6352 | "* | |
6353 | { | |
6354 | int x = INTVAL (operands[1]); | |
6355 | operands[2] = GEN_INT (exact_log2 (x + 1)); | |
6356 | return \"depdi -1,%%sar,%2,%0\"; | |
6357 | }" | |
6358 | [(set_attr "type" "shift") | |
6359 | (set_attr "length" "4")]) | |
6360 | ||
6361 | (define_insn "" | |
6362 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6363 | (and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "") | |
6364 | (minus:DI (const_int 63) | |
6365 | (match_operand:DI 2 "register_operand" "q"))) | |
6366 | (match_operand:DI 3 "register_operand" "0")))] | |
6367 | ; this can be generalized...! | |
6368 | "TARGET_64BIT && INTVAL (operands[1]) == -2" | |
2f95ebc2 TG |
6369 | "* |
6370 | { | |
6371 | int x = INTVAL (operands[1]); | |
6372 | operands[2] = GEN_INT (exact_log2 ((~x) + 1)); | |
520babc7 | 6373 | return \"depdi 0,%%sar,%2,%0\"; |
c47decad JL |
6374 | }" |
6375 | [(set_attr "type" "shift") | |
6376 | (set_attr "length" "4")]) | |
2f95ebc2 | 6377 | |
c733e074 TM |
6378 | (define_expand "ashrsi3" |
6379 | [(set (match_operand:SI 0 "register_operand" "") | |
6380 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "") | |
ba0443bb | 6381 | (match_operand:SI 2 "arith32_operand" "")))] |
c733e074 TM |
6382 | "" |
6383 | " | |
6384 | { | |
6385 | if (GET_CODE (operands[2]) != CONST_INT) | |
6386 | { | |
6387 | rtx temp = gen_reg_rtx (SImode); | |
6f672dc0 | 6388 | emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2])); |
cb524f44 | 6389 | emit_insn (gen_vextrs32 (operands[0], operands[1], temp)); |
c733e074 TM |
6390 | DONE; |
6391 | } | |
6392 | }") | |
6393 | ||
6394 | (define_insn "" | |
56a65d12 TG |
6395 | [(set (match_operand:SI 0 "register_operand" "=r") |
6396 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
6397 | (match_operand:SI 2 "const_int_operand" "n")))] | |
6398 | "" | |
f38b27c7 | 6399 | "{extrs|extrw,s} %1,%P2,%L2,%0" |
c47decad | 6400 | [(set_attr "type" "shift") |
4c2164b7 | 6401 | (set_attr "length" "4")]) |
c733e074 | 6402 | |
cb524f44 | 6403 | (define_insn "vextrs32" |
56a65d12 TG |
6404 | [(set (match_operand:SI 0 "register_operand" "=r") |
6405 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
6406 | (minus:SI (const_int 31) | |
6407 | (match_operand:SI 2 "register_operand" "q"))))] | |
6408 | "" | |
f38b27c7 | 6409 | "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}" |
c47decad JL |
6410 | [(set_attr "type" "shift") |
6411 | (set_attr "length" "4")]) | |
c733e074 | 6412 | |
520babc7 JL |
6413 | (define_expand "ashrdi3" |
6414 | [(set (match_operand:DI 0 "register_operand" "") | |
6415 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
6416 | (match_operand:DI 2 "arith32_operand" "")))] | |
6417 | "TARGET_64BIT" | |
6418 | " | |
6419 | { | |
6420 | if (GET_CODE (operands[2]) != CONST_INT) | |
6421 | { | |
6422 | rtx temp = gen_reg_rtx (DImode); | |
6423 | emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2])); | |
6424 | emit_insn (gen_vextrs64 (operands[0], operands[1], temp)); | |
6425 | DONE; | |
6426 | } | |
6427 | }") | |
6428 | ||
6429 | (define_insn "" | |
6430 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6431 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
6432 | (match_operand:DI 2 "const_int_operand" "n")))] | |
6433 | "TARGET_64BIT" | |
6434 | "extrd,s %1,%p2,%Q2,%0" | |
6435 | [(set_attr "type" "shift") | |
6436 | (set_attr "length" "4")]) | |
6437 | ||
6438 | (define_insn "vextrs64" | |
6439 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6440 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
6441 | (minus:DI (const_int 63) | |
6442 | (match_operand:DI 2 "register_operand" "q"))))] | |
6443 | "TARGET_64BIT" | |
6444 | "extrd,s %1,%%sar,64,%0" | |
6445 | [(set_attr "type" "shift") | |
6446 | (set_attr "length" "4")]) | |
6447 | ||
cb524f44 | 6448 | (define_insn "lshrsi3" |
95246213 TG |
6449 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
6450 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") | |
6451 | (match_operand:SI 2 "arith32_operand" "q,n")))] | |
c733e074 | 6452 | "" |
95246213 | 6453 | "@ |
f38b27c7 JL |
6454 | {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0} |
6455 | {extru|extrw,u} %1,%P2,%L2,%0" | |
c47decad | 6456 | [(set_attr "type" "shift") |
4c2164b7 | 6457 | (set_attr "length" "4")]) |
c733e074 | 6458 | |
520babc7 JL |
6459 | (define_insn "lshrdi3" |
6460 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
6461 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r") | |
6462 | (match_operand:DI 2 "arith32_operand" "q,n")))] | |
6463 | "TARGET_64BIT" | |
6464 | "@ | |
6465 | shrpd %%r0,%1,%%sar,%0 | |
6466 | extrd,u %1,%p2,%Q2,%0" | |
6467 | [(set_attr "type" "shift") | |
6468 | (set_attr "length" "4")]) | |
6469 | ||
cb524f44 | 6470 | (define_insn "rotrsi3" |
95246213 TG |
6471 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
6472 | (rotatert:SI (match_operand:SI 1 "register_operand" "r,r") | |
6473 | (match_operand:SI 2 "arith32_operand" "q,n")))] | |
cb524f44 TG |
6474 | "" |
6475 | "* | |
c733e074 | 6476 | { |
cb524f44 | 6477 | if (GET_CODE (operands[2]) == CONST_INT) |
95246213 TG |
6478 | { |
6479 | operands[2] = GEN_INT (INTVAL (operands[2]) & 31); | |
f38b27c7 | 6480 | return \"{shd|shrpw} %1,%1,%2,%0\"; |
95246213 | 6481 | } |
cb524f44 | 6482 | else |
f38b27c7 | 6483 | return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\"; |
34f921d8 | 6484 | }" |
c47decad | 6485 | [(set_attr "type" "shift") |
4c2164b7 | 6486 | (set_attr "length" "4")]) |
cb524f44 | 6487 | |
db4237a4 JL |
6488 | (define_expand "rotlsi3" |
6489 | [(set (match_operand:SI 0 "register_operand" "") | |
6490 | (rotate:SI (match_operand:SI 1 "register_operand" "") | |
6491 | (match_operand:SI 2 "arith32_operand" "")))] | |
6492 | "" | |
6493 | " | |
6494 | { | |
6495 | if (GET_CODE (operands[2]) != CONST_INT) | |
6496 | { | |
6497 | rtx temp = gen_reg_rtx (SImode); | |
6498 | emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2])); | |
6499 | emit_insn (gen_rotrsi3 (operands[0], operands[1], temp)); | |
6500 | DONE; | |
6501 | } | |
6502 | /* Else expand normally. */ | |
6503 | }") | |
6504 | ||
6505 | (define_insn "" | |
6506 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6507 | (rotate:SI (match_operand:SI 1 "register_operand" "r") | |
6508 | (match_operand:SI 2 "const_int_operand" "n")))] | |
6509 | "" | |
6510 | "* | |
6511 | { | |
6512 | operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31); | |
f38b27c7 | 6513 | return \"{shd|shrpw} %1,%1,%2,%0\"; |
db4237a4 JL |
6514 | }" |
6515 | [(set_attr "type" "shift") | |
6516 | (set_attr "length" "4")]) | |
6517 | ||
c733e074 | 6518 | (define_insn "" |
cb524f44 TG |
6519 | [(set (match_operand:SI 0 "register_operand" "=r") |
6520 | (match_operator:SI 5 "plus_xor_ior_operator" | |
6521 | [(ashift:SI (match_operand:SI 1 "register_operand" "r") | |
6522 | (match_operand:SI 3 "const_int_operand" "n")) | |
6523 | (lshiftrt:SI (match_operand:SI 2 "register_operand" "r") | |
6524 | (match_operand:SI 4 "const_int_operand" "n"))]))] | |
6525 | "INTVAL (operands[3]) + INTVAL (operands[4]) == 32" | |
f38b27c7 | 6526 | "{shd|shrpw} %1,%2,%4,%0" |
c47decad | 6527 | [(set_attr "type" "shift") |
4c2164b7 | 6528 | (set_attr "length" "4")]) |
cb524f44 TG |
6529 | |
6530 | (define_insn "" | |
6531 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6532 | (match_operator:SI 5 "plus_xor_ior_operator" | |
6533 | [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r") | |
6534 | (match_operand:SI 4 "const_int_operand" "n")) | |
6535 | (ashift:SI (match_operand:SI 1 "register_operand" "r") | |
6536 | (match_operand:SI 3 "const_int_operand" "n"))]))] | |
6537 | "INTVAL (operands[3]) + INTVAL (operands[4]) == 32" | |
f38b27c7 | 6538 | "{shd|shrpw} %1,%2,%4,%0" |
c47decad | 6539 | [(set_attr "type" "shift") |
4c2164b7 | 6540 | (set_attr "length" "4")]) |
56a65d12 TG |
6541 | |
6542 | (define_insn "" | |
6543 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6544 | (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") | |
6545 | (match_operand:SI 2 "const_int_operand" "")) | |
6546 | (match_operand:SI 3 "const_int_operand" "")))] | |
6547 | "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) >= 0" | |
6548 | "* | |
6549 | { | |
6550 | int cnt = INTVAL (operands[2]) & 31; | |
6551 | operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt))); | |
6552 | operands[2] = GEN_INT (31 - cnt); | |
f38b27c7 | 6553 | return \"{zdep|depw,z} %1,%2,%3,%0\"; |
34f921d8 | 6554 | }" |
c47decad | 6555 | [(set_attr "type" "shift") |
4c2164b7 | 6556 | (set_attr "length" "4")]) |
c733e074 TM |
6557 | \f |
6558 | ;; Unconditional and other jump instructions. | |
6559 | ||
2caa0ddf | 6560 | ;; This can only be used in a leaf function, so we do |
7ea9fcc6 | 6561 | ;; not need to use the PIC register when generating PIC code. |
c1fab105 | 6562 | (define_insn "return" |
d492b096 JDA |
6563 | [(return) |
6564 | (use (reg:SI 2)) | |
6565 | (const_int 0)] | |
c1fab105 | 6566 | "hppa_can_use_return_insn_p ()" |
79077c3f JL |
6567 | "* |
6568 | { | |
6569 | if (TARGET_PA_20) | |
6570 | return \"bve%* (%%r2)\"; | |
6571 | return \"bv%* %%r0(%%r2)\"; | |
6572 | }" | |
c47decad JL |
6573 | [(set_attr "type" "branch") |
6574 | (set_attr "length" "4")]) | |
c1fab105 | 6575 | |
7ea9fcc6 | 6576 | ;; Emit a different pattern for functions which have non-trivial |
b0213198 JL |
6577 | ;; epilogues so as not to confuse jump and reorg. |
6578 | (define_insn "return_internal" | |
1c217171 | 6579 | [(return) |
d492b096 JDA |
6580 | (use (reg:SI 2)) |
6581 | (const_int 1)] | |
611ad29e | 6582 | "" |
79077c3f JL |
6583 | "* |
6584 | { | |
6585 | if (TARGET_PA_20) | |
6586 | return \"bve%* (%%r2)\"; | |
6587 | return \"bv%* %%r0(%%r2)\"; | |
6588 | }" | |
c47decad JL |
6589 | [(set_attr "type" "branch") |
6590 | (set_attr "length" "4")]) | |
b0213198 | 6591 | |
611ad29e | 6592 | ;; This is used for eh returns which bypass the return stub. |
823fbbce JDA |
6593 | (define_insn "return_external_pic" |
6594 | [(return) | |
611ad29e JDA |
6595 | (clobber (reg:SI 1)) |
6596 | (use (reg:SI 2))] | |
98857de8 JDA |
6597 | "!TARGET_NO_SPACE_REGS |
6598 | && !TARGET_PA_20 | |
6599 | && flag_pic && current_function_calls_eh_return" | |
823fbbce JDA |
6600 | "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)" |
6601 | [(set_attr "type" "branch") | |
6602 | (set_attr "length" "12")]) | |
6603 | ||
b0213198 JL |
6604 | (define_expand "prologue" |
6605 | [(const_int 0)] | |
6606 | "" | |
6607 | "hppa_expand_prologue ();DONE;") | |
6608 | ||
520babc7 JL |
6609 | (define_expand "sibcall_epilogue" |
6610 | [(return)] | |
6611 | "" | |
6612 | " | |
6613 | { | |
6614 | hppa_expand_epilogue (); | |
6615 | DONE; | |
6616 | }") | |
6617 | ||
b0213198 JL |
6618 | (define_expand "epilogue" |
6619 | [(return)] | |
6620 | "" | |
6621 | " | |
6622 | { | |
2f95ebc2 | 6623 | /* Try to use the trivial return first. Else use the full |
b0213198 JL |
6624 | epilogue. */ |
6625 | if (hppa_can_use_return_insn_p ()) | |
823fbbce | 6626 | emit_jump_insn (gen_return ()); |
b0213198 JL |
6627 | else |
6628 | { | |
2caa0ddf JL |
6629 | rtx x; |
6630 | ||
b0213198 | 6631 | hppa_expand_epilogue (); |
823fbbce | 6632 | |
611ad29e JDA |
6633 | /* EH returns bypass the normal return stub. Thus, we must do an |
6634 | interspace branch to return from functions that call eh_return. | |
90330d31 JDA |
6635 | This is only a problem for returns from shared code on ports |
6636 | using space registers. */ | |
6637 | if (!TARGET_NO_SPACE_REGS | |
98857de8 | 6638 | && !TARGET_PA_20 |
90330d31 | 6639 | && flag_pic && current_function_calls_eh_return) |
611ad29e | 6640 | x = gen_return_external_pic (); |
7ea9fcc6 JDA |
6641 | else |
6642 | x = gen_return_internal (); | |
611ad29e | 6643 | |
2caa0ddf | 6644 | emit_jump_insn (x); |
b0213198 JL |
6645 | } |
6646 | DONE; | |
6647 | }") | |
6648 | ||
a3d4c92f RC |
6649 | ; Used by hppa_profile_hook to load the starting address of the current |
6650 | ; function; operand 1 contains the address of the label in operand 3 | |
6651 | (define_insn "load_offset_label_address" | |
6652 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6653 | (plus:SI (match_operand:SI 1 "register_operand" "r") | |
6654 | (minus:SI (match_operand:SI 2 "" "") | |
6655 | (label_ref:SI (match_operand 3 "" "")))))] | |
b0213198 | 6656 | "" |
a3d4c92f RC |
6657 | "ldo %2-%l3(%1),%0" |
6658 | [(set_attr "type" "multi") | |
6659 | (set_attr "length" "4")]) | |
6660 | ||
6661 | ; Output a code label and load its address. | |
6662 | (define_insn "lcla1" | |
6663 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6664 | (label_ref:SI (match_operand 1 "" ""))) | |
6665 | (const_int 0)] | |
6666 | "!TARGET_PA_20" | |
1c7a8112 AM |
6667 | "* |
6668 | { | |
a3d4c92f | 6669 | output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands); |
4977bab6 | 6670 | (*targetm.asm_out.internal_label) (asm_out_file, \"L\", |
a3d4c92f | 6671 | CODE_LABEL_NUMBER (operands[1])); |
1c7a8112 AM |
6672 | return \"\"; |
6673 | }" | |
c47decad JL |
6674 | [(set_attr "type" "multi") |
6675 | (set_attr "length" "8")]) | |
b0213198 | 6676 | |
a3d4c92f RC |
6677 | (define_insn "lcla2" |
6678 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6679 | (label_ref:SI (match_operand 1 "" ""))) | |
6680 | (const_int 0)] | |
6681 | "TARGET_PA_20" | |
6682 | "* | |
6683 | { | |
6684 | (*targetm.asm_out.internal_label) (asm_out_file, \"L\", | |
6685 | CODE_LABEL_NUMBER (operands[1])); | |
6686 | return \"mfia %0\"; | |
6687 | }" | |
6688 | [(set_attr "type" "move") | |
6689 | (set_attr "length" "4")]) | |
6690 | ||
f57f12c3 JL |
6691 | (define_insn "blockage" |
6692 | [(unspec_volatile [(const_int 2)] 0)] | |
6693 | "" | |
6694 | "" | |
6695 | [(set_attr "length" "0")]) | |
6696 | ||
c733e074 TM |
6697 | (define_insn "jump" |
6698 | [(set (pc) (label_ref (match_operand 0 "" "")))] | |
6699 | "" | |
87c16668 JL |
6700 | "* |
6701 | { | |
87c16668 JL |
6702 | /* An unconditional branch which can reach its target. */ |
6703 | if (get_attr_length (insn) != 24 | |
6704 | && get_attr_length (insn) != 16) | |
55abf18a | 6705 | return \"b%* %l0\"; |
87c16668 | 6706 | |
685d0e07 | 6707 | return output_lbranch (operands[0], insn); |
87c16668 | 6708 | }" |
f854c12c | 6709 | [(set_attr "type" "uncond_branch") |
c4bb6b38 | 6710 | (set_attr "pa_combine_type" "uncond_branch") |
f854c12c | 6711 | (set (attr "length") |
87c16668 JL |
6712 | (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 1)) |
6713 | (if_then_else (lt (abs (minus (match_dup 0) | |
6714 | (plus (pc) (const_int 8)))) | |
6715 | (const_int 8184)) | |
6716 | (const_int 4) | |
6717 | (const_int 8)) | |
6718 | (ge (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) | |
6719 | (const_int 262100)) | |
6720 | (if_then_else (eq (symbol_ref "flag_pic") (const_int 0)) | |
6721 | (const_int 16) | |
6722 | (const_int 24))] | |
6723 | (const_int 4)))]) | |
c733e074 | 6724 | |
03d1cb6d JDA |
6725 | ;;; Hope this is only within a function... |
6726 | (define_insn "indirect_jump" | |
6727 | [(set (pc) (match_operand 0 "register_operand" "r"))] | |
6728 | "GET_MODE (operands[0]) == word_mode" | |
6729 | "bv%* %%r0(%0)" | |
6730 | [(set_attr "type" "branch") | |
6731 | (set_attr "length" "4")]) | |
6732 | ||
6733 | ;;; This jump is used in branch tables where the insn length is fixed. | |
6734 | ;;; The length of this insn is adjusted if the delay slot is not filled. | |
6735 | (define_insn "short_jump" | |
6736 | [(set (pc) (label_ref (match_operand 0 "" ""))) | |
6737 | (const_int 0)] | |
6738 | "" | |
6739 | "b%* %l0%#" | |
6740 | [(set_attr "type" "btable_branch") | |
6741 | (set_attr "length" "4")]) | |
6742 | ||
876662ef TG |
6743 | ;; Subroutines of "casesi". |
6744 | ;; operand 0 is index | |
6745 | ;; operand 1 is the minimum bound | |
6746 | ;; operand 2 is the maximum bound - minimum bound + 1 | |
6747 | ;; operand 3 is CODE_LABEL for the table; | |
6748 | ;; operand 4 is the CODE_LABEL to go to if index out of range. | |
6749 | ||
6750 | (define_expand "casesi" | |
6751 | [(match_operand:SI 0 "general_operand" "") | |
6752 | (match_operand:SI 1 "const_int_operand" "") | |
6753 | (match_operand:SI 2 "const_int_operand" "") | |
6754 | (match_operand 3 "" "") | |
6755 | (match_operand 4 "" "")] | |
6756 | "" | |
6757 | " | |
6758 | { | |
6759 | if (GET_CODE (operands[0]) != REG) | |
6760 | operands[0] = force_reg (SImode, operands[0]); | |
6761 | ||
6762 | if (operands[1] != const0_rtx) | |
6763 | { | |
03d1cb6d | 6764 | rtx index = gen_reg_rtx (SImode); |
876662ef | 6765 | |
6f672dc0 | 6766 | operands[1] = GEN_INT (-INTVAL (operands[1])); |
876662ef TG |
6767 | if (!INT_14_BITS (operands[1])) |
6768 | operands[1] = force_reg (SImode, operands[1]); | |
03d1cb6d JDA |
6769 | emit_insn (gen_addsi3 (index, operands[0], operands[1])); |
6770 | operands[0] = index; | |
876662ef TG |
6771 | } |
6772 | ||
520babc7 JL |
6773 | /* In 64bit mode we must make sure to wipe the upper bits of the register |
6774 | just in case the addition overflowed or we had random bits in the | |
6775 | high part of the register. */ | |
6776 | if (TARGET_64BIT) | |
6777 | { | |
03d1cb6d JDA |
6778 | rtx index = gen_reg_rtx (DImode); |
6779 | ||
6780 | emit_insn (gen_extendsidi2 (index, operands[0])); | |
6781 | operands[0] = gen_rtx_SUBREG (SImode, index, 4); | |
520babc7 JL |
6782 | } |
6783 | ||
3e056efc | 6784 | if (!INT_5_BITS (operands[2])) |
876662ef TG |
6785 | operands[2] = force_reg (SImode, operands[2]); |
6786 | ||
03d1cb6d JDA |
6787 | /* This branch prevents us finding an insn for the delay slot of the |
6788 | following vectored branch. It might be possible to use the delay | |
6789 | slot if an index value of -1 was used to transfer to the out-of-range | |
6790 | label. In order to do this, we would have to output the -1 vector | |
6791 | element after the delay insn. The casesi output code would have to | |
6792 | check if the casesi insn is in a delay branch sequence and output | |
6793 | the delay insn if one is found. If this was done, then it might | |
6794 | then be worthwhile to split the casesi patterns to improve scheduling. | |
6795 | However, it's not clear that all this extra complexity is worth | |
6796 | the effort. */ | |
3e056efc JL |
6797 | emit_insn (gen_cmpsi (operands[0], operands[2])); |
6798 | emit_jump_insn (gen_bgtu (operands[4])); | |
03d1cb6d | 6799 | |
3e056efc JL |
6800 | if (TARGET_BIG_SWITCH) |
6801 | { | |
03d1cb6d JDA |
6802 | if (TARGET_64BIT) |
6803 | { | |
6804 | rtx tmp1 = gen_reg_rtx (DImode); | |
6805 | rtx tmp2 = gen_reg_rtx (DImode); | |
6806 | ||
6807 | emit_jump_insn (gen_casesi64p (operands[0], operands[3], | |
6808 | tmp1, tmp2)); | |
6809 | } | |
6810 | else | |
6811 | { | |
6812 | rtx tmp1 = gen_reg_rtx (SImode); | |
6813 | ||
6814 | if (flag_pic) | |
6815 | { | |
6816 | rtx tmp2 = gen_reg_rtx (SImode); | |
6817 | ||
6818 | emit_jump_insn (gen_casesi32p (operands[0], operands[3], | |
6819 | tmp1, tmp2)); | |
6820 | } | |
6821 | else | |
6822 | emit_jump_insn (gen_casesi32 (operands[0], operands[3], tmp1)); | |
6823 | } | |
3e056efc | 6824 | } |
03d1cb6d JDA |
6825 | else |
6826 | emit_jump_insn (gen_casesi0 (operands[0], operands[3])); | |
876662ef TG |
6827 | DONE; |
6828 | }") | |
6829 | ||
03d1cb6d JDA |
6830 | ;;; The rtl for this pattern doesn't accurately describe what the insn |
6831 | ;;; actually does, particularly when case-vector elements are exploded | |
6832 | ;;; in pa_reorg. However, the initial SET in these patterns must show | |
6833 | ;;; the connection of the insn to the following jump table. | |
876662ef | 6834 | (define_insn "casesi0" |
03d1cb6d JDA |
6835 | [(set (pc) (mem:SI (plus:SI |
6836 | (mult:SI (match_operand:SI 0 "register_operand" "r") | |
6837 | (const_int 4)) | |
6838 | (label_ref (match_operand 1 "" "")))))] | |
c733e074 | 6839 | "" |
03d1cb6d | 6840 | "blr,n %0,%%r0\;nop" |
c47decad | 6841 | [(set_attr "type" "multi") |
3e056efc | 6842 | (set_attr "length" "8")]) |
876662ef | 6843 | |
03d1cb6d JDA |
6844 | ;;; 32-bit code, absolute branch table. |
6845 | (define_insn "casesi32" | |
6846 | [(set (pc) (mem:SI (plus:SI | |
6847 | (mult:SI (match_operand:SI 0 "register_operand" "r") | |
6848 | (const_int 4)) | |
6849 | (label_ref (match_operand 1 "" ""))))) | |
6850 | (clobber (match_operand:SI 2 "register_operand" "=&r"))] | |
6851 | "!TARGET_64BIT && TARGET_BIG_SWITCH" | |
6852 | "ldil L'%l1,%2\;ldo R'%l1(%2),%2\;{ldwx|ldw},s %0(%2),%2\;bv,n %%r0(%2)" | |
6853 | [(set_attr "type" "multi") | |
6854 | (set_attr "length" "16")]) | |
6855 | ||
6856 | ;;; 32-bit code, relative branch table. | |
6857 | (define_insn "casesi32p" | |
6858 | [(set (pc) (mem:SI (plus:SI | |
6859 | (mult:SI (match_operand:SI 0 "register_operand" "r") | |
6860 | (const_int 4)) | |
6861 | (label_ref (match_operand 1 "" ""))))) | |
6862 | (clobber (match_operand:SI 2 "register_operand" "=&a")) | |
6863 | (clobber (match_operand:SI 3 "register_operand" "=&r"))] | |
6864 | "!TARGET_64BIT && TARGET_BIG_SWITCH" | |
6865 | "{bl .+8,%2\;depi 0,31,2,%2|mfia %2}\;ldo {16|20}(%2),%2\;\ | |
6866 | {ldwx|ldw},s %0(%2),%3\;{addl|add,l} %2,%3,%3\;bv,n %%r0(%3)" | |
6867 | [(set_attr "type" "multi") | |
6868 | (set (attr "length") | |
6869 | (if_then_else (ne (symbol_ref "TARGET_PA_20") (const_int 0)) | |
6870 | (const_int 20) | |
6871 | (const_int 24)))]) | |
6872 | ||
6873 | ;;; 64-bit code, 32-bit relative branch table. | |
6874 | (define_insn "casesi64p" | |
6875 | [(set (pc) (mem:DI (plus:DI | |
6876 | (mult:DI (sign_extend:DI | |
6877 | (match_operand:SI 0 "register_operand" "r")) | |
6878 | (const_int 8)) | |
6879 | (label_ref (match_operand 1 "" ""))))) | |
6880 | (clobber (match_operand:DI 2 "register_operand" "=&r")) | |
6881 | (clobber (match_operand:DI 3 "register_operand" "=&r"))] | |
6882 | "TARGET_64BIT && TARGET_BIG_SWITCH" | |
6883 | "mfia %2\;ldo 24(%2),%2\;ldw,s %0(%2),%3\;extrd,s %3,63,32,%3\;\ | |
6884 | add,l %2,%3,%3\;bv,n %%r0(%3)" | |
6885 | [(set_attr "type" "multi") | |
6886 | (set_attr "length" "24")]) | |
6887 | ||
6888 | ||
6889 | ;; Call patterns. | |
c733e074 TM |
6890 | ;;- jump to subroutine |
6891 | ||
6892 | (define_expand "call" | |
2f95ebc2 TG |
6893 | [(parallel [(call (match_operand:SI 0 "" "") |
6894 | (match_operand 1 "" "")) | |
6895 | (clobber (reg:SI 2))])] | |
6896 | "" | |
6897 | " | |
c733e074 | 6898 | { |
611ad29e JDA |
6899 | rtx op, call_insn; |
6900 | rtx nb = operands[1]; | |
2f95ebc2 | 6901 | |
279c9bde | 6902 | if (TARGET_PORTABLE_RUNTIME) |
4d72c241 | 6903 | op = force_reg (SImode, XEXP (operands[0], 0)); |
5cf2759e | 6904 | else |
4d72c241 | 6905 | op = XEXP (operands[0], 0); |
5d5c8541 | 6906 | |
520babc7 | 6907 | if (TARGET_64BIT) |
4677862a JDA |
6908 | { |
6909 | if (!virtuals_instantiated) | |
6910 | emit_move_insn (arg_pointer_rtx, | |
6911 | gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx, | |
6912 | GEN_INT (64))); | |
6913 | else | |
6914 | { | |
6915 | /* The loop pass can generate new libcalls after the virtual | |
6916 | registers are instantiated when fpregs are disabled because | |
6917 | the only method that we have for doing DImode multiplication | |
6918 | is with a libcall. This could be trouble if we haven't | |
6919 | allocated enough space for the outgoing arguments. */ | |
6920 | if (INTVAL (nb) > current_function_outgoing_args_size) | |
6921 | abort (); | |
6922 | ||
6923 | emit_move_insn (arg_pointer_rtx, | |
6924 | gen_rtx_PLUS (word_mode, stack_pointer_rtx, | |
6925 | GEN_INT (STACK_POINTER_OFFSET + 64))); | |
6926 | } | |
6927 | } | |
520babc7 | 6928 | |
5d5c8541 JL |
6929 | /* Use two different patterns for calls to explicitly named functions |
6930 | and calls through function pointers. This is necessary as these two | |
6931 | types of calls use different calling conventions, and CSE might try | |
6932 | to change the named call into an indirect call in some cases (using | |
611ad29e JDA |
6933 | two patterns keeps CSE from performing this optimization). |
6934 | ||
6935 | We now use even more call patterns as there was a subtle bug in | |
6936 | attempting to restore the pic register after a call using a simple | |
6937 | move insn. During reload, a instruction involving a pseudo register | |
6938 | with no explicit dependence on the PIC register can be converted | |
6939 | to an equivalent load from memory using the PIC register. If we | |
6940 | emit a simple move to restore the PIC register in the initial rtl | |
6941 | generation, then it can potentially be repositioned during scheduling. | |
6942 | and an instruction that eventually uses the PIC register may end up | |
6943 | between the call and the PIC register restore. | |
6944 | ||
6945 | This only worked because there is a post call group of instructions | |
6946 | that are scheduled with the call. These instructions are included | |
6947 | in the same basic block as the call. However, calls can throw in | |
6948 | C++ code and a basic block has to terminate at the call if the call | |
6949 | can throw. This results in the PIC register restore being scheduled | |
6950 | independently from the call. So, we now hide the save and restore | |
6951 | of the PIC register in the call pattern until after reload. Then, | |
6952 | we split the moves out. A small side benefit is that we now don't | |
6953 | need to have a use of the PIC register in the return pattern and | |
6954 | the final save/restore operation is not needed. | |
6955 | ||
6956 | I elected to just clobber %r4 in the PIC patterns and use it instead | |
6957 | of trying to force hppa_pic_save_rtx () to a callee saved register. | |
6958 | This might have required a new register class and constraint. It | |
6959 | was also simpler to just handle the restore from a register than a | |
6960 | generic pseudo. */ | |
6961 | if (TARGET_64BIT) | |
520babc7 | 6962 | { |
611ad29e JDA |
6963 | if (GET_CODE (op) == SYMBOL_REF) |
6964 | call_insn = emit_call_insn (gen_call_symref_64bit (op, nb)); | |
6965 | else | |
6966 | { | |
6967 | op = force_reg (word_mode, op); | |
6968 | call_insn = emit_call_insn (gen_call_reg_64bit (op, nb)); | |
6969 | } | |
520babc7 | 6970 | } |
5d5c8541 | 6971 | else |
6a73009d | 6972 | { |
611ad29e JDA |
6973 | if (GET_CODE (op) == SYMBOL_REF) |
6974 | { | |
6975 | if (flag_pic) | |
6976 | call_insn = emit_call_insn (gen_call_symref_pic (op, nb)); | |
6977 | else | |
6978 | call_insn = emit_call_insn (gen_call_symref (op, nb)); | |
6979 | } | |
6980 | else | |
6981 | { | |
6982 | rtx tmpreg = gen_rtx_REG (word_mode, 22); | |
6bb36601 | 6983 | |
611ad29e JDA |
6984 | emit_move_insn (tmpreg, force_reg (word_mode, op)); |
6985 | if (flag_pic) | |
6986 | call_insn = emit_call_insn (gen_call_reg_pic (nb)); | |
6987 | else | |
6988 | call_insn = emit_call_insn (gen_call_reg (nb)); | |
6989 | } | |
4d72c241 | 6990 | } |
611ad29e | 6991 | |
4d72c241 | 6992 | DONE; |
c733e074 TM |
6993 | }") |
6994 | ||
611ad29e JDA |
6995 | ;; We use function calls to set the attribute length of calls and millicode |
6996 | ;; calls. This is necessary because of the large variety of call sequences. | |
6997 | ;; Implementing the calculation in rtl is difficult as well as ugly. As | |
6998 | ;; we need the same calculation in several places, maintenance becomes a | |
6999 | ;; nightmare. | |
7000 | ;; | |
7001 | ;; However, this has a subtle impact on branch shortening. When the | |
7002 | ;; expression used to set the length attribute of an instruction depends | |
7003 | ;; on a relative address (e.g., pc or a branch address), genattrtab | |
7004 | ;; notes that the insn's length is variable, and attempts to determine a | |
7005 | ;; worst-case default length and code to compute an insn's current length. | |
7006 | ||
7007 | ;; The use of a function call hides the variable dependence of our calls | |
7008 | ;; and millicode calls. The result is genattrtab doesn't treat the operation | |
7009 | ;; as variable and it only generates code for the default case using our | |
7010 | ;; function call. Because of this, calls and millicode calls have a fixed | |
7011 | ;; length in the branch shortening pass, and some branches will use a longer | |
7012 | ;; code sequence than necessary. However, the length of any given call | |
7013 | ;; will still reflect its final code location and it may be shorter than | |
7014 | ;; the initial length estimate. | |
7015 | ||
7016 | ;; It's possible to trick genattrtab by adding an expression involving `pc' | |
7017 | ;; in the set. However, when genattrtab hits a function call in its attempt | |
7018 | ;; to compute the default length, it marks the result as unknown and sets | |
7019 | ;; the default result to MAX_INT ;-( One possible fix that would allow | |
7020 | ;; calls to participate in branch shortening would be to make the call to | |
7021 | ;; insn_default_length a target option. Then, we could massage unknown | |
7022 | ;; results. Another fix might be to change genattrtab so that it just does | |
7023 | ;; the call in the variable case as it already does for the fixed case. | |
7024 | ||
7025 | (define_insn "call_symref" | |
1b8079e9 | 7026 | [(call (mem:SI (match_operand 0 "call_operand_address" "")) |
2f95ebc2 | 7027 | (match_operand 1 "" "i")) |
a02aa5b0 | 7028 | (clobber (reg:SI 1)) |
2f95ebc2 TG |
7029 | (clobber (reg:SI 2)) |
7030 | (use (const_int 0))] | |
611ad29e | 7031 | "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" |
2f95ebc2 | 7032 | "* |
c733e074 | 7033 | { |
5d5c8541 | 7034 | output_arg_descriptor (insn); |
520babc7 | 7035 | return output_call (insn, operands[0], 0); |
c733e074 | 7036 | }" |
2f95ebc2 | 7037 | [(set_attr "type" "call") |
a02aa5b0 | 7038 | (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))]) |
5d5c8541 | 7039 | |
611ad29e JDA |
7040 | (define_insn "call_symref_pic" |
7041 | [(call (mem:SI (match_operand 0 "call_operand_address" "")) | |
520babc7 | 7042 | (match_operand 1 "" "i")) |
611ad29e | 7043 | (clobber (reg:SI 1)) |
520babc7 | 7044 | (clobber (reg:SI 2)) |
611ad29e JDA |
7045 | (clobber (reg:SI 4)) |
7046 | (use (reg:SI 19)) | |
7047 | (use (const_int 0))] | |
7048 | "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" | |
7049 | "* | |
7050 | { | |
7051 | output_arg_descriptor (insn); | |
7052 | return output_call (insn, operands[0], 0); | |
7053 | }" | |
7054 | [(set_attr "type" "call") | |
7055 | (set (attr "length") | |
7056 | (plus (symbol_ref "attr_length_call (insn, 0)") | |
7057 | (symbol_ref "attr_length_save_restore_dltp (insn)")))]) | |
7058 | ||
7059 | ;; Split out the PIC register save and restore after reload. This is | |
131efcd8 JDA |
7060 | ;; done only if the function returns. As the split is done after reload, |
7061 | ;; there are some situations in which we unnecessarily save and restore | |
7062 | ;; %r4. This happens when there is a single call and the PIC register | |
7063 | ;; is "dead" after the call. This isn't easy to fix as the usage of | |
7064 | ;; the PIC register isn't completely determined until the reload pass. | |
611ad29e JDA |
7065 | (define_split |
7066 | [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" "")) | |
7067 | (match_operand 1 "" "")) | |
7068 | (clobber (reg:SI 1)) | |
7069 | (clobber (reg:SI 2)) | |
7070 | (clobber (reg:SI 4)) | |
7071 | (use (reg:SI 19)) | |
7072 | (use (const_int 0))])] | |
7073 | "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT | |
7074 | && reload_completed | |
7075 | && !find_reg_note (insn, REG_NORETURN, NULL_RTX)" | |
7076 | [(set (reg:SI 4) (reg:SI 19)) | |
7077 | (parallel [(call (mem:SI (match_dup 0)) | |
7078 | (match_dup 1)) | |
7079 | (clobber (reg:SI 1)) | |
7080 | (clobber (reg:SI 2)) | |
7081 | (use (reg:SI 19)) | |
7082 | (use (const_int 0))]) | |
7083 | (set (reg:SI 19) (reg:SI 4))] | |
7084 | "") | |
7085 | ||
7086 | ;; Remove the clobber of register 4 when optimizing. This has to be | |
7087 | ;; done with a peephole optimization rather than a split because the | |
7088 | ;; split sequence for a call must be longer than one instruction. | |
7089 | (define_peephole2 | |
7090 | [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" "")) | |
7091 | (match_operand 1 "" "")) | |
7092 | (clobber (reg:SI 1)) | |
7093 | (clobber (reg:SI 2)) | |
7094 | (clobber (reg:SI 4)) | |
7095 | (use (reg:SI 19)) | |
7096 | (use (const_int 0))])] | |
7097 | "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed" | |
7098 | [(parallel [(call (mem:SI (match_dup 0)) | |
7099 | (match_dup 1)) | |
7100 | (clobber (reg:SI 1)) | |
7101 | (clobber (reg:SI 2)) | |
7102 | (use (reg:SI 19)) | |
7103 | (use (const_int 0))])] | |
7104 | "") | |
7105 | ||
7106 | (define_insn "*call_symref_pic_post_reload" | |
7107 | [(call (mem:SI (match_operand 0 "call_operand_address" "")) | |
7108 | (match_operand 1 "" "i")) | |
7109 | (clobber (reg:SI 1)) | |
7110 | (clobber (reg:SI 2)) | |
7111 | (use (reg:SI 19)) | |
7112 | (use (const_int 0))] | |
7113 | "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" | |
7114 | "* | |
7115 | { | |
7116 | output_arg_descriptor (insn); | |
7117 | return output_call (insn, operands[0], 0); | |
7118 | }" | |
7119 | [(set_attr "type" "call") | |
7120 | (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))]) | |
7121 | ||
7122 | ;; This pattern is split if it is necessary to save and restore the | |
7123 | ;; PIC register. | |
7124 | (define_insn "call_symref_64bit" | |
7125 | [(call (mem:SI (match_operand 0 "call_operand_address" "")) | |
7126 | (match_operand 1 "" "i")) | |
7127 | (clobber (reg:DI 1)) | |
7128 | (clobber (reg:DI 2)) | |
7129 | (clobber (reg:DI 4)) | |
7130 | (use (reg:DI 27)) | |
7131 | (use (reg:DI 29)) | |
7132 | (use (const_int 0))] | |
520babc7 JL |
7133 | "TARGET_64BIT" |
7134 | "* | |
7135 | { | |
611ad29e JDA |
7136 | output_arg_descriptor (insn); |
7137 | return output_call (insn, operands[0], 0); | |
7138 | }" | |
7139 | [(set_attr "type" "call") | |
7140 | (set (attr "length") | |
7141 | (plus (symbol_ref "attr_length_call (insn, 0)") | |
7142 | (symbol_ref "attr_length_save_restore_dltp (insn)")))]) | |
7143 | ||
7144 | ;; Split out the PIC register save and restore after reload. This is | |
131efcd8 JDA |
7145 | ;; done only if the function returns. As the split is done after reload, |
7146 | ;; there are some situations in which we unnecessarily save and restore | |
7147 | ;; %r4. This happens when there is a single call and the PIC register | |
7148 | ;; is "dead" after the call. This isn't easy to fix as the usage of | |
7149 | ;; the PIC register isn't completely determined until the reload pass. | |
611ad29e JDA |
7150 | (define_split |
7151 | [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" "")) | |
7152 | (match_operand 1 "" "")) | |
7153 | (clobber (reg:DI 1)) | |
7154 | (clobber (reg:DI 2)) | |
7155 | (clobber (reg:DI 4)) | |
7156 | (use (reg:DI 27)) | |
7157 | (use (reg:DI 29)) | |
7158 | (use (const_int 0))])] | |
7159 | "TARGET_64BIT | |
7160 | && reload_completed | |
7161 | && !find_reg_note (insn, REG_NORETURN, NULL_RTX)" | |
7162 | [(set (reg:DI 4) (reg:DI 27)) | |
7163 | (parallel [(call (mem:SI (match_dup 0)) | |
7164 | (match_dup 1)) | |
7165 | (clobber (reg:DI 1)) | |
7166 | (clobber (reg:DI 2)) | |
7167 | (use (reg:DI 27)) | |
7168 | (use (reg:DI 29)) | |
7169 | (use (const_int 0))]) | |
7170 | (set (reg:DI 27) (reg:DI 4))] | |
7171 | "") | |
7172 | ||
7173 | ;; Remove the clobber of register 4 when optimizing. This has to be | |
7174 | ;; done with a peephole optimization rather than a split because the | |
7175 | ;; split sequence for a call must be longer than one instruction. | |
7176 | (define_peephole2 | |
7177 | [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" "")) | |
7178 | (match_operand 1 "" "")) | |
7179 | (clobber (reg:DI 1)) | |
7180 | (clobber (reg:DI 2)) | |
7181 | (clobber (reg:DI 4)) | |
7182 | (use (reg:DI 27)) | |
7183 | (use (reg:DI 29)) | |
7184 | (use (const_int 0))])] | |
7185 | "TARGET_64BIT && reload_completed" | |
7186 | [(parallel [(call (mem:SI (match_dup 0)) | |
7187 | (match_dup 1)) | |
7188 | (clobber (reg:DI 1)) | |
7189 | (clobber (reg:DI 2)) | |
7190 | (use (reg:DI 27)) | |
7191 | (use (reg:DI 29)) | |
7192 | (use (const_int 0))])] | |
7193 | "") | |
7194 | ||
7195 | (define_insn "*call_symref_64bit_post_reload" | |
7196 | [(call (mem:SI (match_operand 0 "call_operand_address" "")) | |
7197 | (match_operand 1 "" "i")) | |
7198 | (clobber (reg:DI 1)) | |
7199 | (clobber (reg:DI 2)) | |
7200 | (use (reg:DI 27)) | |
7201 | (use (reg:DI 29)) | |
7202 | (use (const_int 0))] | |
7203 | "TARGET_64BIT" | |
7204 | "* | |
7205 | { | |
7206 | output_arg_descriptor (insn); | |
7207 | return output_call (insn, operands[0], 0); | |
7208 | }" | |
7209 | [(set_attr "type" "call") | |
7210 | (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))]) | |
7211 | ||
7212 | (define_insn "call_reg" | |
7213 | [(call (mem:SI (reg:SI 22)) | |
7214 | (match_operand 0 "" "i")) | |
7215 | (clobber (reg:SI 1)) | |
7216 | (clobber (reg:SI 2)) | |
7217 | (use (const_int 1))] | |
7218 | "!TARGET_64BIT" | |
7219 | "* | |
7220 | { | |
7221 | return output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); | |
520babc7 JL |
7222 | }" |
7223 | [(set_attr "type" "dyncall") | |
611ad29e | 7224 | (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))]) |
520babc7 | 7225 | |
611ad29e JDA |
7226 | ;; This pattern is split if it is necessary to save and restore the |
7227 | ;; PIC register. | |
7228 | (define_insn "call_reg_pic" | |
6a73009d JL |
7229 | [(call (mem:SI (reg:SI 22)) |
7230 | (match_operand 0 "" "i")) | |
a02aa5b0 | 7231 | (clobber (reg:SI 1)) |
2f95ebc2 | 7232 | (clobber (reg:SI 2)) |
611ad29e JDA |
7233 | (clobber (reg:SI 4)) |
7234 | (use (reg:SI 19)) | |
2f95ebc2 | 7235 | (use (const_int 1))] |
611ad29e | 7236 | "!TARGET_64BIT" |
f726ea7d JL |
7237 | "* |
7238 | { | |
611ad29e JDA |
7239 | return output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); |
7240 | }" | |
7241 | [(set_attr "type" "dyncall") | |
7242 | (set (attr "length") | |
7243 | (plus (symbol_ref "attr_length_indirect_call (insn)") | |
7244 | (symbol_ref "attr_length_save_restore_dltp (insn)")))]) | |
105ce113 | 7245 | |
611ad29e | 7246 | ;; Split out the PIC register save and restore after reload. This is |
131efcd8 JDA |
7247 | ;; done only if the function returns. As the split is done after reload, |
7248 | ;; there are some situations in which we unnecessarily save and restore | |
7249 | ;; %r4. This happens when there is a single call and the PIC register | |
7250 | ;; is "dead" after the call. This isn't easy to fix as the usage of | |
7251 | ;; the PIC register isn't completely determined until the reload pass. | |
611ad29e JDA |
7252 | (define_split |
7253 | [(parallel [(call (mem:SI (reg:SI 22)) | |
7254 | (match_operand 0 "" "")) | |
7255 | (clobber (reg:SI 1)) | |
7256 | (clobber (reg:SI 2)) | |
7257 | (clobber (reg:SI 4)) | |
7258 | (use (reg:SI 19)) | |
7259 | (use (const_int 1))])] | |
7260 | "!TARGET_64BIT | |
7261 | && reload_completed | |
7262 | && !find_reg_note (insn, REG_NORETURN, NULL_RTX)" | |
7263 | [(set (reg:SI 4) (reg:SI 19)) | |
7264 | (parallel [(call (mem:SI (reg:SI 22)) | |
7265 | (match_dup 0)) | |
7266 | (clobber (reg:SI 1)) | |
7267 | (clobber (reg:SI 2)) | |
7268 | (use (reg:SI 19)) | |
7269 | (use (const_int 1))]) | |
7270 | (set (reg:SI 19) (reg:SI 4))] | |
7271 | "") | |
6a73009d | 7272 | |
611ad29e JDA |
7273 | ;; Remove the clobber of register 4 when optimizing. This has to be |
7274 | ;; done with a peephole optimization rather than a split because the | |
7275 | ;; split sequence for a call must be longer than one instruction. | |
7276 | (define_peephole2 | |
7277 | [(parallel [(call (mem:SI (reg:SI 22)) | |
7278 | (match_operand 0 "" "")) | |
7279 | (clobber (reg:SI 1)) | |
7280 | (clobber (reg:SI 2)) | |
7281 | (clobber (reg:SI 4)) | |
7282 | (use (reg:SI 19)) | |
7283 | (use (const_int 1))])] | |
7284 | "!TARGET_64BIT && reload_completed" | |
7285 | [(parallel [(call (mem:SI (reg:SI 22)) | |
7286 | (match_dup 0)) | |
7287 | (clobber (reg:SI 1)) | |
7288 | (clobber (reg:SI 2)) | |
7289 | (use (reg:SI 19)) | |
7290 | (use (const_int 1))])] | |
7291 | "") | |
6a73009d | 7292 | |
611ad29e JDA |
7293 | (define_insn "*call_reg_pic_post_reload" |
7294 | [(call (mem:SI (reg:SI 22)) | |
7295 | (match_operand 0 "" "i")) | |
7296 | (clobber (reg:SI 1)) | |
7297 | (clobber (reg:SI 2)) | |
7298 | (use (reg:SI 19)) | |
7299 | (use (const_int 1))] | |
7300 | "!TARGET_64BIT" | |
7301 | "* | |
7302 | { | |
7303 | return output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); | |
7304 | }" | |
7305 | [(set_attr "type" "dyncall") | |
7306 | (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))]) | |
7307 | ||
7308 | ;; This pattern is split if it is necessary to save and restore the | |
7309 | ;; PIC register. | |
7310 | (define_insn "call_reg_64bit" | |
7311 | [(call (mem:SI (match_operand:DI 0 "register_operand" "r")) | |
7312 | (match_operand 1 "" "i")) | |
7313 | (clobber (reg:DI 2)) | |
7314 | (clobber (reg:DI 4)) | |
7315 | (use (reg:DI 27)) | |
7316 | (use (reg:DI 29)) | |
7317 | (use (const_int 1))] | |
7318 | "TARGET_64BIT" | |
7319 | "* | |
7320 | { | |
7321 | return output_indirect_call (insn, operands[0]); | |
7322 | }" | |
7323 | [(set_attr "type" "dyncall") | |
7324 | (set (attr "length") | |
7325 | (plus (symbol_ref "attr_length_indirect_call (insn)") | |
7326 | (symbol_ref "attr_length_save_restore_dltp (insn)")))]) | |
6a73009d | 7327 | |
611ad29e | 7328 | ;; Split out the PIC register save and restore after reload. This is |
131efcd8 JDA |
7329 | ;; done only if the function returns. As the split is done after reload, |
7330 | ;; there are some situations in which we unnecessarily save and restore | |
7331 | ;; %r4. This happens when there is a single call and the PIC register | |
7332 | ;; is "dead" after the call. This isn't easy to fix as the usage of | |
7333 | ;; the PIC register isn't completely determined until the reload pass. | |
611ad29e JDA |
7334 | (define_split |
7335 | [(parallel [(call (mem:SI (match_operand 0 "register_operand" "")) | |
7336 | (match_operand 1 "" "")) | |
7337 | (clobber (reg:DI 2)) | |
7338 | (clobber (reg:DI 4)) | |
7339 | (use (reg:DI 27)) | |
7340 | (use (reg:DI 29)) | |
7341 | (use (const_int 1))])] | |
7342 | "TARGET_64BIT | |
7343 | && reload_completed | |
7344 | && !find_reg_note (insn, REG_NORETURN, NULL_RTX)" | |
7345 | [(set (reg:DI 4) (reg:DI 27)) | |
7346 | (parallel [(call (mem:SI (match_dup 0)) | |
7347 | (match_dup 1)) | |
7348 | (clobber (reg:DI 2)) | |
7349 | (use (reg:DI 27)) | |
7350 | (use (reg:DI 29)) | |
7351 | (use (const_int 1))]) | |
7352 | (set (reg:DI 27) (reg:DI 4))] | |
7353 | "") | |
6a73009d | 7354 | |
611ad29e JDA |
7355 | ;; Remove the clobber of register 4 when optimizing. This has to be |
7356 | ;; done with a peephole optimization rather than a split because the | |
7357 | ;; split sequence for a call must be longer than one instruction. | |
7358 | (define_peephole2 | |
7359 | [(parallel [(call (mem:SI (match_operand 0 "register_operand" "")) | |
7360 | (match_operand 1 "" "")) | |
7361 | (clobber (reg:DI 2)) | |
7362 | (clobber (reg:DI 4)) | |
7363 | (use (reg:DI 27)) | |
7364 | (use (reg:DI 29)) | |
7365 | (use (const_int 1))])] | |
7366 | "TARGET_64BIT && reload_completed" | |
7367 | [(parallel [(call (mem:SI (match_dup 0)) | |
7368 | (match_dup 1)) | |
7369 | (clobber (reg:DI 2)) | |
7370 | (use (reg:DI 27)) | |
7371 | (use (reg:DI 29)) | |
7372 | (use (const_int 1))])] | |
7373 | "") | |
6a73009d | 7374 | |
611ad29e JDA |
7375 | (define_insn "*call_reg_64bit_post_reload" |
7376 | [(call (mem:SI (match_operand:DI 0 "register_operand" "r")) | |
7377 | (match_operand 1 "" "i")) | |
7378 | (clobber (reg:DI 2)) | |
7379 | (use (reg:DI 27)) | |
7380 | (use (reg:DI 29)) | |
7381 | (use (const_int 1))] | |
7382 | "TARGET_64BIT" | |
7383 | "* | |
7384 | { | |
7385 | return output_indirect_call (insn, operands[0]); | |
f726ea7d | 7386 | }" |
2f95ebc2 | 7387 | [(set_attr "type" "dyncall") |
611ad29e | 7388 | (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))]) |
c733e074 TM |
7389 | |
7390 | (define_expand "call_value" | |
7391 | [(parallel [(set (match_operand 0 "" "") | |
7392 | (call (match_operand:SI 1 "" "") | |
7393 | (match_operand 2 "" ""))) | |
c733e074 | 7394 | (clobber (reg:SI 2))])] |
c733e074 TM |
7395 | "" |
7396 | " | |
7397 | { | |
611ad29e JDA |
7398 | rtx op, call_insn; |
7399 | rtx dst = operands[0]; | |
7400 | rtx nb = operands[2]; | |
2f95ebc2 | 7401 | |
279c9bde | 7402 | if (TARGET_PORTABLE_RUNTIME) |
611ad29e | 7403 | op = force_reg (SImode, XEXP (operands[1], 0)); |
5cf2759e | 7404 | else |
4d72c241 | 7405 | op = XEXP (operands[1], 0); |
5d5c8541 | 7406 | |
520babc7 | 7407 | if (TARGET_64BIT) |
4677862a JDA |
7408 | { |
7409 | if (!virtuals_instantiated) | |
7410 | emit_move_insn (arg_pointer_rtx, | |
7411 | gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx, | |
7412 | GEN_INT (64))); | |
7413 | else | |
7414 | { | |
7415 | /* The loop pass can generate new libcalls after the virtual | |
7416 | registers are instantiated when fpregs are disabled because | |
7417 | the only method that we have for doing DImode multiplication | |
7418 | is with a libcall. This could be trouble if we haven't | |
7419 | allocated enough space for the outgoing arguments. */ | |
7420 | if (INTVAL (nb) > current_function_outgoing_args_size) | |
7421 | abort (); | |
7422 | ||
7423 | emit_move_insn (arg_pointer_rtx, | |
7424 | gen_rtx_PLUS (word_mode, stack_pointer_rtx, | |
7425 | GEN_INT (STACK_POINTER_OFFSET + 64))); | |
7426 | } | |
7427 | } | |
520babc7 | 7428 | |
5d5c8541 JL |
7429 | /* Use two different patterns for calls to explicitly named functions |
7430 | and calls through function pointers. This is necessary as these two | |
7431 | types of calls use different calling conventions, and CSE might try | |
7432 | to change the named call into an indirect call in some cases (using | |
611ad29e JDA |
7433 | two patterns keeps CSE from performing this optimization). |
7434 | ||
7435 | We now use even more call patterns as there was a subtle bug in | |
7436 | attempting to restore the pic register after a call using a simple | |
7437 | move insn. During reload, a instruction involving a pseudo register | |
7438 | with no explicit dependence on the PIC register can be converted | |
7439 | to an equivalent load from memory using the PIC register. If we | |
7440 | emit a simple move to restore the PIC register in the initial rtl | |
7441 | generation, then it can potentially be repositioned during scheduling. | |
7442 | and an instruction that eventually uses the PIC register may end up | |
7443 | between the call and the PIC register restore. | |
7444 | ||
7445 | This only worked because there is a post call group of instructions | |
7446 | that are scheduled with the call. These instructions are included | |
7447 | in the same basic block as the call. However, calls can throw in | |
7448 | C++ code and a basic block has to terminate at the call if the call | |
7449 | can throw. This results in the PIC register restore being scheduled | |
7450 | independently from the call. So, we now hide the save and restore | |
7451 | of the PIC register in the call pattern until after reload. Then, | |
7452 | we split the moves out. A small side benefit is that we now don't | |
7453 | need to have a use of the PIC register in the return pattern and | |
7454 | the final save/restore operation is not needed. | |
7455 | ||
7456 | I elected to just clobber %r4 in the PIC patterns and use it instead | |
7457 | of trying to force hppa_pic_save_rtx () to a callee saved register. | |
7458 | This might have required a new register class and constraint. It | |
7459 | was also simpler to just handle the restore from a register than a | |
7460 | generic pseudo. */ | |
7461 | if (TARGET_64BIT) | |
520babc7 | 7462 | { |
611ad29e JDA |
7463 | if (GET_CODE (op) == SYMBOL_REF) |
7464 | call_insn = emit_call_insn (gen_call_val_symref_64bit (dst, op, nb)); | |
7465 | else | |
7466 | { | |
7467 | op = force_reg (word_mode, op); | |
7468 | call_insn = emit_call_insn (gen_call_val_reg_64bit (dst, op, nb)); | |
7469 | } | |
520babc7 | 7470 | } |
5d5c8541 | 7471 | else |
6a73009d | 7472 | { |
611ad29e JDA |
7473 | if (GET_CODE (op) == SYMBOL_REF) |
7474 | { | |
7475 | if (flag_pic) | |
7476 | call_insn = emit_call_insn (gen_call_val_symref_pic (dst, op, nb)); | |
7477 | else | |
7478 | call_insn = emit_call_insn (gen_call_val_symref (dst, op, nb)); | |
7479 | } | |
7480 | else | |
7481 | { | |
7482 | rtx tmpreg = gen_rtx_REG (word_mode, 22); | |
6bb36601 | 7483 | |
611ad29e JDA |
7484 | emit_move_insn (tmpreg, force_reg (word_mode, op)); |
7485 | if (flag_pic) | |
7486 | call_insn = emit_call_insn (gen_call_val_reg_pic (dst, nb)); | |
7487 | else | |
7488 | call_insn = emit_call_insn (gen_call_val_reg (dst, nb)); | |
7489 | } | |
4d72c241 | 7490 | } |
611ad29e | 7491 | |
4d72c241 | 7492 | DONE; |
c733e074 TM |
7493 | }") |
7494 | ||
611ad29e | 7495 | (define_insn "call_val_symref" |
44571d6e | 7496 | [(set (match_operand 0 "" "") |
1b8079e9 | 7497 | (call (mem:SI (match_operand 1 "call_operand_address" "")) |
5d5c8541 | 7498 | (match_operand 2 "" "i"))) |
a02aa5b0 | 7499 | (clobber (reg:SI 1)) |
5d5c8541 JL |
7500 | (clobber (reg:SI 2)) |
7501 | (use (const_int 0))] | |
611ad29e | 7502 | "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" |
c733e074 TM |
7503 | "* |
7504 | { | |
5d5c8541 | 7505 | output_arg_descriptor (insn); |
520babc7 | 7506 | return output_call (insn, operands[1], 0); |
c733e074 | 7507 | }" |
2f95ebc2 | 7508 | [(set_attr "type" "call") |
a02aa5b0 | 7509 | (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))]) |
5d5c8541 | 7510 | |
611ad29e | 7511 | (define_insn "call_val_symref_pic" |
44571d6e | 7512 | [(set (match_operand 0 "" "") |
611ad29e JDA |
7513 | (call (mem:SI (match_operand 1 "call_operand_address" "")) |
7514 | (match_operand 2 "" "i"))) | |
7515 | (clobber (reg:SI 1)) | |
520babc7 | 7516 | (clobber (reg:SI 2)) |
611ad29e JDA |
7517 | (clobber (reg:SI 4)) |
7518 | (use (reg:SI 19)) | |
7519 | (use (const_int 0))] | |
7520 | "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" | |
7521 | "* | |
7522 | { | |
7523 | output_arg_descriptor (insn); | |
7524 | return output_call (insn, operands[1], 0); | |
7525 | }" | |
7526 | [(set_attr "type" "call") | |
7527 | (set (attr "length") | |
7528 | (plus (symbol_ref "attr_length_call (insn, 0)") | |
7529 | (symbol_ref "attr_length_save_restore_dltp (insn)")))]) | |
7530 | ||
7531 | ;; Split out the PIC register save and restore after reload. This is | |
131efcd8 JDA |
7532 | ;; done only if the function returns. As the split is done after reload, |
7533 | ;; there are some situations in which we unnecessarily save and restore | |
7534 | ;; %r4. This happens when there is a single call and the PIC register | |
7535 | ;; is "dead" after the call. This isn't easy to fix as the usage of | |
7536 | ;; the PIC register isn't completely determined until the reload pass. | |
611ad29e JDA |
7537 | (define_split |
7538 | [(parallel [(set (match_operand 0 "" "") | |
7539 | (call (mem:SI (match_operand 1 "call_operand_address" "")) | |
7540 | (match_operand 2 "" ""))) | |
7541 | (clobber (reg:SI 1)) | |
7542 | (clobber (reg:SI 2)) | |
7543 | (clobber (reg:SI 4)) | |
7544 | (use (reg:SI 19)) | |
7545 | (use (const_int 0))])] | |
7546 | "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT | |
7547 | && reload_completed | |
7548 | && !find_reg_note (insn, REG_NORETURN, NULL_RTX)" | |
7549 | [(set (reg:SI 4) (reg:SI 19)) | |
7550 | (parallel [(set (match_dup 0) | |
7551 | (call (mem:SI (match_dup 1)) | |
7552 | (match_dup 2))) | |
7553 | (clobber (reg:SI 1)) | |
7554 | (clobber (reg:SI 2)) | |
7555 | (use (reg:SI 19)) | |
7556 | (use (const_int 0))]) | |
7557 | (set (reg:SI 19) (reg:SI 4))] | |
7558 | "") | |
7559 | ||
7560 | ;; Remove the clobber of register 4 when optimizing. This has to be | |
7561 | ;; done with a peephole optimization rather than a split because the | |
7562 | ;; split sequence for a call must be longer than one instruction. | |
7563 | (define_peephole2 | |
7564 | [(parallel [(set (match_operand 0 "" "") | |
7565 | (call (mem:SI (match_operand 1 "call_operand_address" "")) | |
7566 | (match_operand 2 "" ""))) | |
7567 | (clobber (reg:SI 1)) | |
7568 | (clobber (reg:SI 2)) | |
7569 | (clobber (reg:SI 4)) | |
7570 | (use (reg:SI 19)) | |
7571 | (use (const_int 0))])] | |
7572 | "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed" | |
7573 | [(parallel [(set (match_dup 0) | |
7574 | (call (mem:SI (match_dup 1)) | |
7575 | (match_dup 2))) | |
7576 | (clobber (reg:SI 1)) | |
7577 | (clobber (reg:SI 2)) | |
7578 | (use (reg:SI 19)) | |
7579 | (use (const_int 0))])] | |
7580 | "") | |
7581 | ||
7582 | (define_insn "*call_val_symref_pic_post_reload" | |
7583 | [(set (match_operand 0 "" "") | |
7584 | (call (mem:SI (match_operand 1 "call_operand_address" "")) | |
7585 | (match_operand 2 "" "i"))) | |
7586 | (clobber (reg:SI 1)) | |
7587 | (clobber (reg:SI 2)) | |
7588 | (use (reg:SI 19)) | |
7589 | (use (const_int 0))] | |
7590 | "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" | |
7591 | "* | |
7592 | { | |
7593 | output_arg_descriptor (insn); | |
7594 | return output_call (insn, operands[1], 0); | |
7595 | }" | |
7596 | [(set_attr "type" "call") | |
7597 | (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))]) | |
7598 | ||
7599 | ;; This pattern is split if it is necessary to save and restore the | |
7600 | ;; PIC register. | |
7601 | (define_insn "call_val_symref_64bit" | |
7602 | [(set (match_operand 0 "" "") | |
7603 | (call (mem:SI (match_operand 1 "call_operand_address" "")) | |
7604 | (match_operand 2 "" "i"))) | |
7605 | (clobber (reg:DI 1)) | |
7606 | (clobber (reg:DI 2)) | |
7607 | (clobber (reg:DI 4)) | |
7608 | (use (reg:DI 27)) | |
7609 | (use (reg:DI 29)) | |
7610 | (use (const_int 0))] | |
520babc7 JL |
7611 | "TARGET_64BIT" |
7612 | "* | |
7613 | { | |
611ad29e JDA |
7614 | output_arg_descriptor (insn); |
7615 | return output_call (insn, operands[1], 0); | |
7616 | }" | |
7617 | [(set_attr "type" "call") | |
7618 | (set (attr "length") | |
7619 | (plus (symbol_ref "attr_length_call (insn, 0)") | |
7620 | (symbol_ref "attr_length_save_restore_dltp (insn)")))]) | |
7621 | ||
7622 | ;; Split out the PIC register save and restore after reload. This is | |
131efcd8 JDA |
7623 | ;; done only if the function returns. As the split is done after reload, |
7624 | ;; there are some situations in which we unnecessarily save and restore | |
7625 | ;; %r4. This happens when there is a single call and the PIC register | |
7626 | ;; is "dead" after the call. This isn't easy to fix as the usage of | |
7627 | ;; the PIC register isn't completely determined until the reload pass. | |
611ad29e JDA |
7628 | (define_split |
7629 | [(parallel [(set (match_operand 0 "" "") | |
7630 | (call (mem:SI (match_operand 1 "call_operand_address" "")) | |
7631 | (match_operand 2 "" ""))) | |
7632 | (clobber (reg:DI 1)) | |
7633 | (clobber (reg:DI 2)) | |
7634 | (clobber (reg:DI 4)) | |
7635 | (use (reg:DI 27)) | |
7636 | (use (reg:DI 29)) | |
7637 | (use (const_int 0))])] | |
7638 | "TARGET_64BIT | |
7639 | && reload_completed | |
7640 | && !find_reg_note (insn, REG_NORETURN, NULL_RTX)" | |
7641 | [(set (reg:DI 4) (reg:DI 27)) | |
7642 | (parallel [(set (match_dup 0) | |
7643 | (call (mem:SI (match_dup 1)) | |
7644 | (match_dup 2))) | |
7645 | (clobber (reg:DI 1)) | |
7646 | (clobber (reg:DI 2)) | |
7647 | (use (reg:DI 27)) | |
7648 | (use (reg:DI 29)) | |
7649 | (use (const_int 0))]) | |
7650 | (set (reg:DI 27) (reg:DI 4))] | |
7651 | "") | |
7652 | ||
7653 | ;; Remove the clobber of register 4 when optimizing. This has to be | |
7654 | ;; done with a peephole optimization rather than a split because the | |
7655 | ;; split sequence for a call must be longer than one instruction. | |
7656 | (define_peephole2 | |
7657 | [(parallel [(set (match_operand 0 "" "") | |
7658 | (call (mem:SI (match_operand 1 "call_operand_address" "")) | |
7659 | (match_operand 2 "" ""))) | |
7660 | (clobber (reg:DI 1)) | |
7661 | (clobber (reg:DI 2)) | |
7662 | (clobber (reg:DI 4)) | |
7663 | (use (reg:DI 27)) | |
7664 | (use (reg:DI 29)) | |
7665 | (use (const_int 0))])] | |
7666 | "TARGET_64BIT && reload_completed" | |
7667 | [(parallel [(set (match_dup 0) | |
7668 | (call (mem:SI (match_dup 1)) | |
7669 | (match_dup 2))) | |
7670 | (clobber (reg:DI 1)) | |
7671 | (clobber (reg:DI 2)) | |
7672 | (use (reg:DI 27)) | |
7673 | (use (reg:DI 29)) | |
7674 | (use (const_int 0))])] | |
7675 | "") | |
7676 | ||
7677 | (define_insn "*call_val_symref_64bit_post_reload" | |
7678 | [(set (match_operand 0 "" "") | |
7679 | (call (mem:SI (match_operand 1 "call_operand_address" "")) | |
7680 | (match_operand 2 "" "i"))) | |
7681 | (clobber (reg:DI 1)) | |
7682 | (clobber (reg:DI 2)) | |
7683 | (use (reg:DI 27)) | |
7684 | (use (reg:DI 29)) | |
7685 | (use (const_int 0))] | |
7686 | "TARGET_64BIT" | |
7687 | "* | |
7688 | { | |
7689 | output_arg_descriptor (insn); | |
7690 | return output_call (insn, operands[1], 0); | |
7691 | }" | |
7692 | [(set_attr "type" "call") | |
7693 | (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))]) | |
7694 | ||
7695 | (define_insn "call_val_reg" | |
7696 | [(set (match_operand 0 "" "") | |
7697 | (call (mem:SI (reg:SI 22)) | |
7698 | (match_operand 1 "" "i"))) | |
7699 | (clobber (reg:SI 1)) | |
7700 | (clobber (reg:SI 2)) | |
7701 | (use (const_int 1))] | |
7702 | "!TARGET_64BIT" | |
7703 | "* | |
7704 | { | |
7705 | return output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); | |
520babc7 JL |
7706 | }" |
7707 | [(set_attr "type" "dyncall") | |
611ad29e | 7708 | (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))]) |
520babc7 | 7709 | |
611ad29e JDA |
7710 | ;; This pattern is split if it is necessary to save and restore the |
7711 | ;; PIC register. | |
7712 | (define_insn "call_val_reg_pic" | |
44571d6e | 7713 | [(set (match_operand 0 "" "") |
6a73009d JL |
7714 | (call (mem:SI (reg:SI 22)) |
7715 | (match_operand 1 "" "i"))) | |
a02aa5b0 | 7716 | (clobber (reg:SI 1)) |
5d5c8541 | 7717 | (clobber (reg:SI 2)) |
611ad29e JDA |
7718 | (clobber (reg:SI 4)) |
7719 | (use (reg:SI 19)) | |
5d5c8541 | 7720 | (use (const_int 1))] |
611ad29e | 7721 | "!TARGET_64BIT" |
f726ea7d JL |
7722 | "* |
7723 | { | |
611ad29e JDA |
7724 | return output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); |
7725 | }" | |
7726 | [(set_attr "type" "dyncall") | |
7727 | (set (attr "length") | |
7728 | (plus (symbol_ref "attr_length_indirect_call (insn)") | |
7729 | (symbol_ref "attr_length_save_restore_dltp (insn)")))]) | |
6a73009d | 7730 | |
611ad29e | 7731 | ;; Split out the PIC register save and restore after reload. This is |
131efcd8 JDA |
7732 | ;; done only if the function returns. As the split is done after reload, |
7733 | ;; there are some situations in which we unnecessarily save and restore | |
7734 | ;; %r4. This happens when there is a single call and the PIC register | |
7735 | ;; is "dead" after the call. This isn't easy to fix as the usage of | |
7736 | ;; the PIC register isn't completely determined until the reload pass. | |
611ad29e JDA |
7737 | (define_split |
7738 | [(parallel [(set (match_operand 0 "" "") | |
7739 | (call (mem:SI (reg:SI 22)) | |
7740 | (match_operand 1 "" ""))) | |
7741 | (clobber (reg:SI 1)) | |
7742 | (clobber (reg:SI 2)) | |
7743 | (clobber (reg:SI 4)) | |
7744 | (use (reg:SI 19)) | |
7745 | (use (const_int 1))])] | |
7746 | "!TARGET_64BIT | |
7747 | && reload_completed | |
7748 | && !find_reg_note (insn, REG_NORETURN, NULL_RTX)" | |
7749 | [(set (reg:SI 4) (reg:SI 19)) | |
7750 | (parallel [(set (match_dup 0) | |
7751 | (call (mem:SI (reg:SI 22)) | |
7752 | (match_dup 1))) | |
7753 | (clobber (reg:SI 1)) | |
7754 | (clobber (reg:SI 2)) | |
7755 | (use (reg:SI 19)) | |
7756 | (use (const_int 1))]) | |
7757 | (set (reg:SI 19) (reg:SI 4))] | |
7758 | "") | |
6a73009d | 7759 | |
611ad29e JDA |
7760 | ;; Remove the clobber of register 4 when optimizing. This has to be |
7761 | ;; done with a peephole optimization rather than a split because the | |
7762 | ;; split sequence for a call must be longer than one instruction. | |
7763 | (define_peephole2 | |
7764 | [(parallel [(set (match_operand 0 "" "") | |
7765 | (call (mem:SI (reg:SI 22)) | |
7766 | (match_operand 1 "" ""))) | |
7767 | (clobber (reg:SI 1)) | |
7768 | (clobber (reg:SI 2)) | |
7769 | (clobber (reg:SI 4)) | |
7770 | (use (reg:SI 19)) | |
7771 | (use (const_int 1))])] | |
7772 | "!TARGET_64BIT && reload_completed" | |
7773 | [(parallel [(set (match_dup 0) | |
7774 | (call (mem:SI (reg:SI 22)) | |
7775 | (match_dup 1))) | |
7776 | (clobber (reg:SI 1)) | |
7777 | (clobber (reg:SI 2)) | |
7778 | (use (reg:SI 19)) | |
7779 | (use (const_int 1))])] | |
7780 | "") | |
6a73009d | 7781 | |
611ad29e JDA |
7782 | (define_insn "*call_val_reg_pic_post_reload" |
7783 | [(set (match_operand 0 "" "") | |
7784 | (call (mem:SI (reg:SI 22)) | |
7785 | (match_operand 1 "" "i"))) | |
7786 | (clobber (reg:SI 1)) | |
7787 | (clobber (reg:SI 2)) | |
7788 | (use (reg:SI 19)) | |
7789 | (use (const_int 1))] | |
7790 | "!TARGET_64BIT" | |
7791 | "* | |
7792 | { | |
7793 | return output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); | |
7794 | }" | |
7795 | [(set_attr "type" "dyncall") | |
7796 | (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))]) | |
6a73009d | 7797 | |
611ad29e JDA |
7798 | ;; This pattern is split if it is necessary to save and restore the |
7799 | ;; PIC register. | |
7800 | (define_insn "call_val_reg_64bit" | |
7801 | [(set (match_operand 0 "" "") | |
7802 | (call (mem:SI (match_operand:DI 1 "register_operand" "r")) | |
7803 | (match_operand 2 "" "i"))) | |
7804 | (clobber (reg:DI 2)) | |
7805 | (clobber (reg:DI 4)) | |
7806 | (use (reg:DI 27)) | |
7807 | (use (reg:DI 29)) | |
7808 | (use (const_int 1))] | |
7809 | "TARGET_64BIT" | |
7810 | "* | |
7811 | { | |
7812 | return output_indirect_call (insn, operands[1]); | |
7813 | }" | |
7814 | [(set_attr "type" "dyncall") | |
7815 | (set (attr "length") | |
7816 | (plus (symbol_ref "attr_length_indirect_call (insn)") | |
7817 | (symbol_ref "attr_length_save_restore_dltp (insn)")))]) | |
6a73009d | 7818 | |
611ad29e | 7819 | ;; Split out the PIC register save and restore after reload. This is |
131efcd8 JDA |
7820 | ;; done only if the function returns. As the split is done after reload, |
7821 | ;; there are some situations in which we unnecessarily save and restore | |
7822 | ;; %r4. This happens when there is a single call and the PIC register | |
7823 | ;; is "dead" after the call. This isn't easy to fix as the usage of | |
7824 | ;; the PIC register isn't completely determined until the reload pass. | |
611ad29e JDA |
7825 | (define_split |
7826 | [(parallel [(set (match_operand 0 "" "") | |
7827 | (call (mem:SI (match_operand:DI 1 "register_operand" "")) | |
7828 | (match_operand 2 "" ""))) | |
7829 | (clobber (reg:DI 2)) | |
7830 | (clobber (reg:DI 4)) | |
7831 | (use (reg:DI 27)) | |
7832 | (use (reg:DI 29)) | |
7833 | (use (const_int 1))])] | |
7834 | "TARGET_64BIT | |
7835 | && reload_completed | |
7836 | && !find_reg_note (insn, REG_NORETURN, NULL_RTX)" | |
7837 | [(set (reg:DI 4) (reg:DI 27)) | |
7838 | (parallel [(set (match_dup 0) | |
7839 | (call (mem:SI (match_dup 1)) | |
7840 | (match_dup 2))) | |
7841 | (clobber (reg:DI 2)) | |
7842 | (use (reg:DI 27)) | |
7843 | (use (reg:DI 29)) | |
7844 | (use (const_int 1))]) | |
7845 | (set (reg:DI 27) (reg:DI 4))] | |
7846 | "") | |
6a73009d | 7847 | |
611ad29e JDA |
7848 | ;; Remove the clobber of register 4 when optimizing. This has to be |
7849 | ;; done with a peephole optimization rather than a split because the | |
7850 | ;; split sequence for a call must be longer than one instruction. | |
7851 | (define_peephole2 | |
7852 | [(parallel [(set (match_operand 0 "" "") | |
7853 | (call (mem:SI (match_operand:DI 1 "register_operand" "")) | |
7854 | (match_operand 2 "" ""))) | |
7855 | (clobber (reg:DI 2)) | |
7856 | (clobber (reg:DI 4)) | |
7857 | (use (reg:DI 27)) | |
7858 | (use (reg:DI 29)) | |
7859 | (use (const_int 1))])] | |
7860 | "TARGET_64BIT && reload_completed" | |
7861 | [(parallel [(set (match_dup 0) | |
7862 | (call (mem:SI (match_dup 1)) | |
7863 | (match_dup 2))) | |
7864 | (clobber (reg:DI 2)) | |
7865 | (use (reg:DI 27)) | |
7866 | (use (reg:DI 29)) | |
7867 | (use (const_int 1))])] | |
7868 | "") | |
7869 | ||
7870 | (define_insn "*call_val_reg_64bit_post_reload" | |
7871 | [(set (match_operand 0 "" "") | |
7872 | (call (mem:SI (match_operand:DI 1 "register_operand" "r")) | |
7873 | (match_operand 2 "" "i"))) | |
7874 | (clobber (reg:DI 2)) | |
7875 | (use (reg:DI 27)) | |
7876 | (use (reg:DI 29)) | |
7877 | (use (const_int 1))] | |
7878 | "TARGET_64BIT" | |
7879 | "* | |
7880 | { | |
7881 | return output_indirect_call (insn, operands[1]); | |
f726ea7d | 7882 | }" |
2f95ebc2 | 7883 | [(set_attr "type" "dyncall") |
611ad29e | 7884 | (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))]) |
c733e074 | 7885 | |
dfeddf46 JL |
7886 | ;; Call subroutine returning any type. |
7887 | ||
7888 | (define_expand "untyped_call" | |
7889 | [(parallel [(call (match_operand 0 "" "") | |
7890 | (const_int 0)) | |
7891 | (match_operand 1 "" "") | |
7892 | (match_operand 2 "" "")])] | |
7893 | "" | |
7894 | " | |
7895 | { | |
7896 | int i; | |
7897 | ||
0499c2e4 | 7898 | emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx)); |
dfeddf46 JL |
7899 | |
7900 | for (i = 0; i < XVECLEN (operands[2], 0); i++) | |
7901 | { | |
7902 | rtx set = XVECEXP (operands[2], 0, i); | |
7903 | emit_move_insn (SET_DEST (set), SET_SRC (set)); | |
7904 | } | |
7905 | ||
7906 | /* The optimizer does not know that the call sets the function value | |
7907 | registers we stored in the result block. We avoid problems by | |
7908 | claiming that all hard registers are used and clobbered at this | |
7909 | point. */ | |
7910 | emit_insn (gen_blockage ()); | |
7911 | ||
7912 | DONE; | |
7913 | }") | |
520babc7 JL |
7914 | |
7915 | (define_expand "sibcall" | |
a02aa5b0 JDA |
7916 | [(call (match_operand:SI 0 "" "") |
7917 | (match_operand 1 "" ""))] | |
7918 | "!TARGET_PORTABLE_RUNTIME" | |
520babc7 JL |
7919 | " |
7920 | { | |
4677862a JDA |
7921 | rtx op, call_insn; |
7922 | rtx nb = operands[1]; | |
520babc7 JL |
7923 | |
7924 | op = XEXP (operands[0], 0); | |
7925 | ||
a02aa5b0 | 7926 | if (TARGET_64BIT) |
4677862a JDA |
7927 | { |
7928 | if (!virtuals_instantiated) | |
7929 | emit_move_insn (arg_pointer_rtx, | |
7930 | gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx, | |
7931 | GEN_INT (64))); | |
7932 | else | |
7933 | { | |
7934 | /* The loop pass can generate new libcalls after the virtual | |
7935 | registers are instantiated when fpregs are disabled because | |
7936 | the only method that we have for doing DImode multiplication | |
7937 | is with a libcall. This could be trouble if we haven't | |
7938 | allocated enough space for the outgoing arguments. */ | |
7939 | if (INTVAL (nb) > current_function_outgoing_args_size) | |
7940 | abort (); | |
7941 | ||
7942 | emit_move_insn (arg_pointer_rtx, | |
7943 | gen_rtx_PLUS (word_mode, stack_pointer_rtx, | |
7944 | GEN_INT (STACK_POINTER_OFFSET + 64))); | |
7945 | } | |
7946 | } | |
a02aa5b0 JDA |
7947 | |
7948 | /* Indirect sibling calls are not allowed. */ | |
7949 | if (TARGET_64BIT) | |
7950 | call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]); | |
7951 | else | |
7952 | call_insn = gen_sibcall_internal_symref (op, operands[1]); | |
7953 | ||
7954 | call_insn = emit_call_insn (call_insn); | |
7955 | ||
7956 | if (TARGET_64BIT) | |
7957 | use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx); | |
520babc7 | 7958 | |
611ad29e | 7959 | /* We don't have to restore the PIC register. */ |
520babc7 | 7960 | if (flag_pic) |
611ad29e | 7961 | use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx); |
520babc7 | 7962 | |
520babc7 JL |
7963 | DONE; |
7964 | }") | |
7965 | ||
7966 | (define_insn "sibcall_internal_symref" | |
7967 | [(call (mem:SI (match_operand 0 "call_operand_address" "")) | |
7968 | (match_operand 1 "" "i")) | |
a02aa5b0 | 7969 | (clobber (reg:SI 1)) |
520babc7 JL |
7970 | (use (reg:SI 2)) |
7971 | (use (const_int 0))] | |
a02aa5b0 | 7972 | "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" |
520babc7 JL |
7973 | "* |
7974 | { | |
7975 | output_arg_descriptor (insn); | |
7976 | return output_call (insn, operands[0], 1); | |
7977 | }" | |
7978 | [(set_attr "type" "call") | |
a02aa5b0 JDA |
7979 | (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))]) |
7980 | ||
7981 | (define_insn "sibcall_internal_symref_64bit" | |
7982 | [(call (mem:SI (match_operand 0 "call_operand_address" "")) | |
7983 | (match_operand 1 "" "i")) | |
611ad29e JDA |
7984 | (clobber (reg:DI 1)) |
7985 | (use (reg:DI 2)) | |
a02aa5b0 JDA |
7986 | (use (const_int 0))] |
7987 | "TARGET_64BIT" | |
7988 | "* | |
7989 | { | |
7990 | output_arg_descriptor (insn); | |
7991 | return output_call (insn, operands[0], 1); | |
7992 | }" | |
7993 | [(set_attr "type" "call") | |
7994 | (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))]) | |
520babc7 JL |
7995 | |
7996 | (define_expand "sibcall_value" | |
a02aa5b0 | 7997 | [(set (match_operand 0 "" "") |
520babc7 | 7998 | (call (match_operand:SI 1 "" "") |
a02aa5b0 JDA |
7999 | (match_operand 2 "" "")))] |
8000 | "!TARGET_PORTABLE_RUNTIME" | |
520babc7 JL |
8001 | " |
8002 | { | |
4677862a JDA |
8003 | rtx op, call_insn; |
8004 | rtx nb = operands[1]; | |
520babc7 JL |
8005 | |
8006 | op = XEXP (operands[1], 0); | |
8007 | ||
a02aa5b0 | 8008 | if (TARGET_64BIT) |
4677862a JDA |
8009 | { |
8010 | if (!virtuals_instantiated) | |
8011 | emit_move_insn (arg_pointer_rtx, | |
8012 | gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx, | |
8013 | GEN_INT (64))); | |
8014 | else | |
8015 | { | |
8016 | /* The loop pass can generate new libcalls after the virtual | |
8017 | registers are instantiated when fpregs are disabled because | |
8018 | the only method that we have for doing DImode multiplication | |
8019 | is with a libcall. This could be trouble if we haven't | |
8020 | allocated enough space for the outgoing arguments. */ | |
8021 | if (INTVAL (nb) > current_function_outgoing_args_size) | |
8022 | abort (); | |
8023 | ||
8024 | emit_move_insn (arg_pointer_rtx, | |
8025 | gen_rtx_PLUS (word_mode, stack_pointer_rtx, | |
8026 | GEN_INT (STACK_POINTER_OFFSET + 64))); | |
8027 | } | |
8028 | } | |
a02aa5b0 JDA |
8029 | |
8030 | /* Indirect sibling calls are not allowed. */ | |
8031 | if (TARGET_64BIT) | |
8032 | call_insn | |
8033 | = gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]); | |
8034 | else | |
8035 | call_insn | |
8036 | = gen_sibcall_value_internal_symref (operands[0], op, operands[2]); | |
8037 | ||
8038 | call_insn = emit_call_insn (call_insn); | |
8039 | ||
8040 | if (TARGET_64BIT) | |
8041 | use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx); | |
8042 | ||
611ad29e | 8043 | /* We don't have to restore the PIC register. */ |
520babc7 | 8044 | if (flag_pic) |
611ad29e | 8045 | use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx); |
520babc7 | 8046 | |
520babc7 JL |
8047 | DONE; |
8048 | }") | |
8049 | ||
8050 | (define_insn "sibcall_value_internal_symref" | |
44571d6e | 8051 | [(set (match_operand 0 "" "") |
520babc7 JL |
8052 | (call (mem:SI (match_operand 1 "call_operand_address" "")) |
8053 | (match_operand 2 "" "i"))) | |
a02aa5b0 | 8054 | (clobber (reg:SI 1)) |
520babc7 JL |
8055 | (use (reg:SI 2)) |
8056 | (use (const_int 0))] | |
a02aa5b0 | 8057 | "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" |
520babc7 JL |
8058 | "* |
8059 | { | |
8060 | output_arg_descriptor (insn); | |
8061 | return output_call (insn, operands[1], 1); | |
8062 | }" | |
8063 | [(set_attr "type" "call") | |
a02aa5b0 JDA |
8064 | (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))]) |
8065 | ||
8066 | (define_insn "sibcall_value_internal_symref_64bit" | |
44571d6e | 8067 | [(set (match_operand 0 "" "") |
a02aa5b0 JDA |
8068 | (call (mem:SI (match_operand 1 "call_operand_address" "")) |
8069 | (match_operand 2 "" "i"))) | |
611ad29e JDA |
8070 | (clobber (reg:DI 1)) |
8071 | (use (reg:DI 2)) | |
a02aa5b0 JDA |
8072 | (use (const_int 0))] |
8073 | "TARGET_64BIT" | |
8074 | "* | |
8075 | { | |
8076 | output_arg_descriptor (insn); | |
8077 | return output_call (insn, operands[1], 1); | |
8078 | }" | |
8079 | [(set_attr "type" "call") | |
8080 | (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))]) | |
520babc7 | 8081 | |
c733e074 TM |
8082 | (define_insn "nop" |
8083 | [(const_int 0)] | |
8084 | "" | |
c47decad JL |
8085 | "nop" |
8086 | [(set_attr "type" "move") | |
8087 | (set_attr "length" "4")]) | |
c733e074 | 8088 | |
ad238e4b JL |
8089 | ;; These are just placeholders so we know where branch tables |
8090 | ;; begin and end. | |
8091 | (define_insn "begin_brtab" | |
8092 | [(const_int 1)] | |
251ffdee JL |
8093 | "" |
8094 | "* | |
8095 | { | |
8096 | /* Only GAS actually supports this pseudo-op. */ | |
8097 | if (TARGET_GAS) | |
8098 | return \".begin_brtab\"; | |
8099 | else | |
8100 | return \"\"; | |
8101 | }" | |
ad238e4b JL |
8102 | [(set_attr "type" "move") |
8103 | (set_attr "length" "0")]) | |
8104 | ||
8105 | (define_insn "end_brtab" | |
8106 | [(const_int 2)] | |
251ffdee JL |
8107 | "" |
8108 | "* | |
8109 | { | |
8110 | /* Only GAS actually supports this pseudo-op. */ | |
8111 | if (TARGET_GAS) | |
8112 | return \".end_brtab\"; | |
8113 | else | |
8114 | return \"\"; | |
8115 | }" | |
ad238e4b JL |
8116 | [(set_attr "type" "move") |
8117 | (set_attr "length" "0")]) | |
8118 | ||
cd0e1e48 JDA |
8119 | ;;; EH does longjmp's from and within the data section. Thus, |
8120 | ;;; an interspace branch is required for the longjmp implementation. | |
90330d31 JDA |
8121 | ;;; Registers r1 and r2 are used as scratch registers for the jump |
8122 | ;;; when necessary. | |
520babc7 JL |
8123 | (define_expand "interspace_jump" |
8124 | [(parallel | |
8125 | [(set (pc) (match_operand 0 "pmode_register_operand" "a")) | |
8126 | (clobber (match_dup 1))])] | |
cd0e1e48 | 8127 | "" |
520babc7 JL |
8128 | " |
8129 | { | |
8130 | operands[1] = gen_rtx_REG (word_mode, 2); | |
8131 | }") | |
8132 | ||
90330d31 JDA |
8133 | (define_insn "" |
8134 | [(set (pc) (match_operand 0 "pmode_register_operand" "a")) | |
8135 | (clobber (reg:SI 2))] | |
8136 | "TARGET_PA_20 && !TARGET_64BIT" | |
8137 | "bve%* (%0)" | |
8138 | [(set_attr "type" "branch") | |
8139 | (set_attr "length" "4")]) | |
8140 | ||
8141 | (define_insn "" | |
8142 | [(set (pc) (match_operand 0 "pmode_register_operand" "a")) | |
8143 | (clobber (reg:SI 2))] | |
8144 | "TARGET_NO_SPACE_REGS && !TARGET_64BIT" | |
8145 | "be%* 0(%%sr4,%0)" | |
8146 | [(set_attr "type" "branch") | |
8147 | (set_attr "length" "4")]) | |
8148 | ||
520babc7 JL |
8149 | (define_insn "" |
8150 | [(set (pc) (match_operand 0 "pmode_register_operand" "a")) | |
8151 | (clobber (reg:SI 2))] | |
8152 | "!TARGET_64BIT" | |
8153 | "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)" | |
8154 | [(set_attr "type" "branch") | |
8155 | (set_attr "length" "12")]) | |
8156 | ||
8157 | (define_insn "" | |
8158 | [(set (pc) (match_operand 0 "pmode_register_operand" "a")) | |
8159 | (clobber (reg:DI 2))] | |
8160 | "TARGET_64BIT" | |
90330d31 | 8161 | "bve%* (%0)" |
cd0e1e48 | 8162 | [(set_attr "type" "branch") |
90330d31 | 8163 | (set_attr "length" "4")]) |
cd0e1e48 JDA |
8164 | |
8165 | (define_expand "builtin_longjmp" | |
8166 | [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)] | |
8167 | "" | |
8168 | " | |
8169 | { | |
8170 | /* The elements of the buffer are, in order: */ | |
8171 | rtx fp = gen_rtx_MEM (Pmode, operands[0]); | |
0eac2984 JL |
8172 | rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], |
8173 | POINTER_SIZE / BITS_PER_UNIT)); | |
8174 | rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], | |
8175 | (POINTER_SIZE * 2) / BITS_PER_UNIT)); | |
cd0e1e48 JDA |
8176 | rtx pv = gen_rtx_REG (Pmode, 1); |
8177 | ||
8178 | /* This bit is the same as expand_builtin_longjmp. */ | |
8179 | emit_move_insn (hard_frame_pointer_rtx, fp); | |
8180 | emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX); | |
8181 | emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx)); | |
8182 | emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); | |
8183 | ||
8184 | /* Load the label we are jumping through into r1 so that we know | |
8185 | where to look for it when we get back to setjmp's function for | |
8186 | restoring the gp. */ | |
8187 | emit_move_insn (pv, lab); | |
5c8cfcd6 JDA |
8188 | |
8189 | /* Prevent the insns above from being scheduled into the delay slot | |
8190 | of the interspace jump because the space register could change. */ | |
8191 | emit_insn (gen_blockage ()); | |
8192 | ||
cd0e1e48 JDA |
8193 | emit_jump_insn (gen_interspace_jump (pv)); |
8194 | emit_barrier (); | |
8195 | DONE; | |
8196 | }") | |
5c8cfcd6 | 8197 | |
561af708 | 8198 | ;;; Operands 2 and 3 are assumed to be CONST_INTs. |
14a774a9 | 8199 | (define_expand "extzv" |
520babc7 JL |
8200 | [(set (match_operand 0 "register_operand" "") |
8201 | (zero_extract (match_operand 1 "register_operand" "") | |
8202 | (match_operand 2 "uint32_operand" "") | |
8203 | (match_operand 3 "uint32_operand" "")))] | |
14a774a9 RK |
8204 | "" |
8205 | " | |
8206 | { | |
561af708 JDA |
8207 | HOST_WIDE_INT len = INTVAL (operands[2]); |
8208 | HOST_WIDE_INT pos = INTVAL (operands[3]); | |
8209 | ||
8210 | /* PA extraction insns don't support zero length bitfields or fields | |
8211 | extending beyond the left or right-most bits. Also, we reject lengths | |
8212 | equal to a word as they are better handled by the move patterns. */ | |
8213 | if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD) | |
8214 | FAIL; | |
8215 | ||
8216 | /* From mips.md: extract_bit_field doesn't verify that our source | |
8217 | matches the predicate, so check it again here. */ | |
8218 | if (!register_operand (operands[1], VOIDmode)) | |
0d2f38ee OH |
8219 | FAIL; |
8220 | ||
520babc7 | 8221 | if (TARGET_64BIT) |
9d6b7c09 JDA |
8222 | emit_insn (gen_extzv_64 (operands[0], operands[1], |
8223 | operands[2], operands[3])); | |
520babc7 | 8224 | else |
561af708 JDA |
8225 | emit_insn (gen_extzv_32 (operands[0], operands[1], |
8226 | operands[2], operands[3])); | |
520babc7 | 8227 | DONE; |
14a774a9 RK |
8228 | }") |
8229 | ||
520babc7 | 8230 | (define_insn "extzv_32" |
c733e074 TM |
8231 | [(set (match_operand:SI 0 "register_operand" "=r") |
8232 | (zero_extract:SI (match_operand:SI 1 "register_operand" "r") | |
9d6b7c09 JDA |
8233 | (match_operand:SI 2 "uint5_operand" "") |
8234 | (match_operand:SI 3 "uint5_operand" "")))] | |
c733e074 | 8235 | "" |
f38b27c7 | 8236 | "{extru|extrw,u} %1,%3+%2-1,%2,%0" |
c47decad JL |
8237 | [(set_attr "type" "shift") |
8238 | (set_attr "length" "4")]) | |
c733e074 | 8239 | |
2f95ebc2 TG |
8240 | (define_insn "" |
8241 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8242 | (zero_extract:SI (match_operand:SI 1 "register_operand" "r") | |
8243 | (const_int 1) | |
15c2086a | 8244 | (match_operand:SI 2 "register_operand" "q")))] |
2f95ebc2 | 8245 | "" |
f38b27c7 | 8246 | "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}" |
c47decad JL |
8247 | [(set_attr "type" "shift") |
8248 | (set_attr "length" "4")]) | |
2f95ebc2 | 8249 | |
520babc7 JL |
8250 | (define_insn "extzv_64" |
8251 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8252 | (zero_extract:DI (match_operand:DI 1 "register_operand" "r") | |
8253 | (match_operand:DI 2 "uint32_operand" "") | |
8254 | (match_operand:DI 3 "uint32_operand" "")))] | |
8255 | "TARGET_64BIT" | |
8256 | "extrd,u %1,%3+%2-1,%2,%0" | |
8257 | [(set_attr "type" "shift") | |
8258 | (set_attr "length" "4")]) | |
8259 | ||
8260 | (define_insn "" | |
8261 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8262 | (zero_extract:DI (match_operand:DI 1 "register_operand" "r") | |
8263 | (const_int 1) | |
15c2086a | 8264 | (match_operand:DI 2 "register_operand" "q")))] |
520babc7 JL |
8265 | "TARGET_64BIT" |
8266 | "extrd,u %1,%%sar,1,%0" | |
8267 | [(set_attr "type" "shift") | |
8268 | (set_attr "length" "4")]) | |
8269 | ||
561af708 | 8270 | ;;; Operands 2 and 3 are assumed to be CONST_INTs. |
14a774a9 | 8271 | (define_expand "extv" |
520babc7 JL |
8272 | [(set (match_operand 0 "register_operand" "") |
8273 | (sign_extract (match_operand 1 "register_operand" "") | |
8274 | (match_operand 2 "uint32_operand" "") | |
8275 | (match_operand 3 "uint32_operand" "")))] | |
14a774a9 RK |
8276 | "" |
8277 | " | |
8278 | { | |
561af708 JDA |
8279 | HOST_WIDE_INT len = INTVAL (operands[2]); |
8280 | HOST_WIDE_INT pos = INTVAL (operands[3]); | |
8281 | ||
8282 | /* PA extraction insns don't support zero length bitfields or fields | |
8283 | extending beyond the left or right-most bits. Also, we reject lengths | |
8284 | equal to a word as they are better handled by the move patterns. */ | |
8285 | if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD) | |
8286 | FAIL; | |
8287 | ||
8288 | /* From mips.md: extract_bit_field doesn't verify that our source | |
8289 | matches the predicate, so check it again here. */ | |
8290 | if (!register_operand (operands[1], VOIDmode)) | |
0d2f38ee OH |
8291 | FAIL; |
8292 | ||
520babc7 | 8293 | if (TARGET_64BIT) |
9d6b7c09 JDA |
8294 | emit_insn (gen_extv_64 (operands[0], operands[1], |
8295 | operands[2], operands[3])); | |
520babc7 | 8296 | else |
561af708 JDA |
8297 | emit_insn (gen_extv_32 (operands[0], operands[1], |
8298 | operands[2], operands[3])); | |
520babc7 | 8299 | DONE; |
14a774a9 RK |
8300 | }") |
8301 | ||
520babc7 | 8302 | (define_insn "extv_32" |
c733e074 TM |
8303 | [(set (match_operand:SI 0 "register_operand" "=r") |
8304 | (sign_extract:SI (match_operand:SI 1 "register_operand" "r") | |
9d6b7c09 JDA |
8305 | (match_operand:SI 2 "uint5_operand" "") |
8306 | (match_operand:SI 3 "uint5_operand" "")))] | |
c733e074 | 8307 | "" |
f38b27c7 | 8308 | "{extrs|extrw,s} %1,%3+%2-1,%2,%0" |
c47decad JL |
8309 | [(set_attr "type" "shift") |
8310 | (set_attr "length" "4")]) | |
c733e074 | 8311 | |
2f95ebc2 TG |
8312 | (define_insn "" |
8313 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8314 | (sign_extract:SI (match_operand:SI 1 "register_operand" "r") | |
8315 | (const_int 1) | |
15c2086a | 8316 | (match_operand:SI 2 "register_operand" "q")))] |
520babc7 | 8317 | "!TARGET_64BIT" |
f38b27c7 | 8318 | "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}" |
c47decad JL |
8319 | [(set_attr "type" "shift") |
8320 | (set_attr "length" "4")]) | |
2f95ebc2 | 8321 | |
520babc7 JL |
8322 | (define_insn "extv_64" |
8323 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8324 | (sign_extract:DI (match_operand:DI 1 "register_operand" "r") | |
8325 | (match_operand:DI 2 "uint32_operand" "") | |
8326 | (match_operand:DI 3 "uint32_operand" "")))] | |
8327 | "TARGET_64BIT" | |
8328 | "extrd,s %1,%3+%2-1,%2,%0" | |
8329 | [(set_attr "type" "shift") | |
8330 | (set_attr "length" "4")]) | |
8331 | ||
8332 | (define_insn "" | |
8333 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8334 | (sign_extract:DI (match_operand:DI 1 "register_operand" "r") | |
8335 | (const_int 1) | |
15c2086a | 8336 | (match_operand:DI 2 "register_operand" "q")))] |
520babc7 JL |
8337 | "TARGET_64BIT" |
8338 | "extrd,s %1,%%sar,1,%0" | |
8339 | [(set_attr "type" "shift") | |
8340 | (set_attr "length" "4")]) | |
8341 | ||
561af708 | 8342 | ;;; Operands 1 and 2 are assumed to be CONST_INTs. |
14a774a9 | 8343 | (define_expand "insv" |
520babc7 JL |
8344 | [(set (zero_extract (match_operand 0 "register_operand" "") |
8345 | (match_operand 1 "uint32_operand" "") | |
8346 | (match_operand 2 "uint32_operand" "")) | |
8347 | (match_operand 3 "arith5_operand" ""))] | |
14a774a9 RK |
8348 | "" |
8349 | " | |
8350 | { | |
561af708 JDA |
8351 | HOST_WIDE_INT len = INTVAL (operands[1]); |
8352 | HOST_WIDE_INT pos = INTVAL (operands[2]); | |
8353 | ||
8354 | /* PA insertion insns don't support zero length bitfields or fields | |
8355 | extending beyond the left or right-most bits. Also, we reject lengths | |
8356 | equal to a word as they are better handled by the move patterns. */ | |
8357 | if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD) | |
8358 | FAIL; | |
8359 | ||
8360 | /* From mips.md: insert_bit_field doesn't verify that our destination | |
8361 | matches the predicate, so check it again here. */ | |
8362 | if (!register_operand (operands[0], VOIDmode)) | |
8363 | FAIL; | |
8364 | ||
520babc7 | 8365 | if (TARGET_64BIT) |
9d6b7c09 JDA |
8366 | emit_insn (gen_insv_64 (operands[0], operands[1], |
8367 | operands[2], operands[3])); | |
520babc7 | 8368 | else |
561af708 JDA |
8369 | emit_insn (gen_insv_32 (operands[0], operands[1], |
8370 | operands[2], operands[3])); | |
520babc7 | 8371 | DONE; |
14a774a9 RK |
8372 | }") |
8373 | ||
520babc7 | 8374 | (define_insn "insv_32" |
51c2b9d1 | 8375 | [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r") |
9d6b7c09 JDA |
8376 | (match_operand:SI 1 "uint5_operand" "") |
8377 | (match_operand:SI 2 "uint5_operand" "")) | |
51c2b9d1 | 8378 | (match_operand:SI 3 "arith5_operand" "r,L"))] |
c733e074 | 8379 | "" |
51c2b9d1 | 8380 | "@ |
f38b27c7 JL |
8381 | {dep|depw} %3,%2+%1-1,%1,%0 |
8382 | {depi|depwi} %3,%2+%1-1,%1,%0" | |
c47decad JL |
8383 | [(set_attr "type" "shift,shift") |
8384 | (set_attr "length" "4,4")]) | |
51c2b9d1 TG |
8385 | |
8386 | ;; Optimize insertion of const_int values of type 1...1xxxx. | |
8387 | (define_insn "" | |
8388 | [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") | |
8389 | (match_operand:SI 1 "uint5_operand" "") | |
8390 | (match_operand:SI 2 "uint5_operand" "")) | |
8391 | (match_operand:SI 3 "const_int_operand" ""))] | |
8392 | "(INTVAL (operands[3]) & 0x10) != 0 && | |
51723711 | 8393 | (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0" |
51c2b9d1 TG |
8394 | "* |
8395 | { | |
6f672dc0 | 8396 | operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10); |
f38b27c7 | 8397 | return \"{depi|depwi} %3,%2+%1-1,%1,%0\"; |
c47decad JL |
8398 | }" |
8399 | [(set_attr "type" "shift") | |
8400 | (set_attr "length" "4")]) | |
c733e074 | 8401 | |
520babc7 JL |
8402 | (define_insn "insv_64" |
8403 | [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r") | |
8404 | (match_operand:DI 1 "uint32_operand" "") | |
8405 | (match_operand:DI 2 "uint32_operand" "")) | |
8406 | (match_operand:DI 3 "arith32_operand" "r,L"))] | |
8407 | "TARGET_64BIT" | |
8408 | "@ | |
8409 | depd %3,%2+%1-1,%1,%0 | |
8410 | depdi %3,%2+%1-1,%1,%0" | |
8411 | [(set_attr "type" "shift,shift") | |
8412 | (set_attr "length" "4,4")]) | |
8413 | ||
8414 | ;; Optimize insertion of const_int values of type 1...1xxxx. | |
8415 | (define_insn "" | |
8416 | [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") | |
8417 | (match_operand:DI 1 "uint32_operand" "") | |
8418 | (match_operand:DI 2 "uint32_operand" "")) | |
8419 | (match_operand:DI 3 "const_int_operand" ""))] | |
8420 | "(INTVAL (operands[3]) & 0x10) != 0 | |
8421 | && TARGET_64BIT | |
8422 | && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0" | |
8423 | "* | |
8424 | { | |
8425 | operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10); | |
8426 | return \"depdi %3,%2+%1-1,%1,%0\"; | |
8427 | }" | |
8428 | [(set_attr "type" "shift") | |
8429 | (set_attr "length" "4")]) | |
8430 | ||
8431 | (define_insn "" | |
8432 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8433 | (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
8434 | (const_int 32)))] | |
8435 | "TARGET_64BIT" | |
8436 | "depd,z %1,31,32,%0" | |
8437 | [(set_attr "type" "shift") | |
8438 | (set_attr "length" "4")]) | |
8439 | ||
53a66787 TG |
8440 | ;; This insn is used for some loop tests, typically loops reversed when |
8441 | ;; strength reduction is used. It is actually created when the instruction | |
8442 | ;; combination phase combines the special loop test. Since this insn | |
ad2c71b7 | 8443 | ;; is both a jump insn and has an output, it must deal with its own |
53a66787 TG |
8444 | ;; reloads, hence the `m' constraints. The `!' constraints direct reload |
8445 | ;; to not choose the register alternatives in the event a reload is needed. | |
53a66787 TG |
8446 | (define_insn "decrement_and_branch_until_zero" |
8447 | [(set (pc) | |
8448 | (if_then_else | |
6d9d0ca1 | 8449 | (match_operator 2 "comparison_operator" |
1fd9ac1e | 8450 | [(plus:SI |
2e396476 | 8451 | (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*m") |
1fd9ac1e | 8452 | (match_operand:SI 1 "int5_operand" "L,L,L")) |
6d9d0ca1 JL |
8453 | (const_int 0)]) |
8454 | (label_ref (match_operand 3 "" "")) | |
53a66787 TG |
8455 | (pc))) |
8456 | (set (match_dup 0) | |
6d9d0ca1 | 8457 | (plus:SI (match_dup 0) (match_dup 1))) |
f65590a9 JL |
8458 | (clobber (match_scratch:SI 4 "=X,r,r"))] |
8459 | "" | |
6f45095d | 8460 | "* return output_dbra (operands, insn, which_alternative); " |
2f95ebc2 | 8461 | ;; Do not expect to understand this the first time through. |
98b2d887 JL |
8462 | [(set_attr "type" "cbranch,multi,multi") |
8463 | (set (attr "length") | |
8464 | (if_then_else (eq_attr "alternative" "0") | |
8465 | ;; Loop counter in register case | |
4c2164b7 JL |
8466 | ;; Short branch has length of 4 |
8467 | ;; Long branch has length of 8 | |
8468 | (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) | |
6a73009d | 8469 | (const_int 8184)) |
4c2164b7 JL |
8470 | (const_int 4) |
8471 | (const_int 8)) | |
f65590a9 | 8472 | |
f65590a9 JL |
8473 | ;; Loop counter in FP reg case. |
8474 | ;; Extra goo to deal with additional reload insns. | |
8475 | (if_then_else (eq_attr "alternative" "1") | |
8476 | (if_then_else (lt (match_dup 3) (pc)) | |
2f95ebc2 | 8477 | (if_then_else |
4c2164b7 | 8478 | (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24)))) |
6a73009d | 8479 | (const_int 8184)) |
4c2164b7 JL |
8480 | (const_int 24) |
8481 | (const_int 28)) | |
2f95ebc2 | 8482 | (if_then_else |
4c2164b7 | 8483 | (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) |
6a73009d | 8484 | (const_int 8184)) |
4c2164b7 JL |
8485 | (const_int 24) |
8486 | (const_int 28))) | |
f65590a9 JL |
8487 | ;; Loop counter in memory case. |
8488 | ;; Extra goo to deal with additional reload insns. | |
8489 | (if_then_else (lt (match_dup 3) (pc)) | |
2f95ebc2 | 8490 | (if_then_else |
4c2164b7 | 8491 | (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) |
6a73009d | 8492 | (const_int 8184)) |
4c2164b7 JL |
8493 | (const_int 12) |
8494 | (const_int 16)) | |
2f95ebc2 | 8495 | (if_then_else |
4c2164b7 | 8496 | (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) |
6a73009d | 8497 | (const_int 8184)) |
4c2164b7 JL |
8498 | (const_int 12) |
8499 | (const_int 16))))))]) | |
53a66787 | 8500 | |
98b2d887 JL |
8501 | (define_insn "" |
8502 | [(set (pc) | |
8503 | (if_then_else | |
8504 | (match_operator 2 "movb_comparison_operator" | |
b1092901 | 8505 | [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)]) |
98b2d887 JL |
8506 | (label_ref (match_operand 3 "" "")) |
8507 | (pc))) | |
2e396476 | 8508 | (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q") |
98b2d887 JL |
8509 | (match_dup 1))] |
8510 | "" | |
8511 | "* return output_movb (operands, insn, which_alternative, 0); " | |
2f95ebc2 | 8512 | ;; Do not expect to understand this the first time through. |
b1092901 | 8513 | [(set_attr "type" "cbranch,multi,multi,multi") |
98b2d887 JL |
8514 | (set (attr "length") |
8515 | (if_then_else (eq_attr "alternative" "0") | |
8516 | ;; Loop counter in register case | |
4c2164b7 JL |
8517 | ;; Short branch has length of 4 |
8518 | ;; Long branch has length of 8 | |
8519 | (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) | |
6a73009d | 8520 | (const_int 8184)) |
4c2164b7 JL |
8521 | (const_int 4) |
8522 | (const_int 8)) | |
98b2d887 JL |
8523 | |
8524 | ;; Loop counter in FP reg case. | |
8525 | ;; Extra goo to deal with additional reload insns. | |
8526 | (if_then_else (eq_attr "alternative" "1") | |
8527 | (if_then_else (lt (match_dup 3) (pc)) | |
2f95ebc2 | 8528 | (if_then_else |
4c2164b7 | 8529 | (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) |
6a73009d | 8530 | (const_int 8184)) |
4c2164b7 JL |
8531 | (const_int 12) |
8532 | (const_int 16)) | |
2f95ebc2 | 8533 | (if_then_else |
4c2164b7 | 8534 | (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) |
6a73009d | 8535 | (const_int 8184)) |
4c2164b7 JL |
8536 | (const_int 12) |
8537 | (const_int 16))) | |
b1092901 | 8538 | ;; Loop counter in memory or sar case. |
98b2d887 | 8539 | ;; Extra goo to deal with additional reload insns. |
2f95ebc2 | 8540 | (if_then_else |
4c2164b7 | 8541 | (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) |
6a73009d | 8542 | (const_int 8184)) |
4c2164b7 JL |
8543 | (const_int 8) |
8544 | (const_int 12)))))]) | |
98b2d887 JL |
8545 | |
8546 | ;; Handle negated branch. | |
8547 | (define_insn "" | |
8548 | [(set (pc) | |
8549 | (if_then_else | |
8550 | (match_operator 2 "movb_comparison_operator" | |
b1092901 | 8551 | [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)]) |
98b2d887 JL |
8552 | (pc) |
8553 | (label_ref (match_operand 3 "" "")))) | |
2e396476 | 8554 | (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q") |
98b2d887 JL |
8555 | (match_dup 1))] |
8556 | "" | |
8557 | "* return output_movb (operands, insn, which_alternative, 1); " | |
2f95ebc2 | 8558 | ;; Do not expect to understand this the first time through. |
b1092901 | 8559 | [(set_attr "type" "cbranch,multi,multi,multi") |
98b2d887 JL |
8560 | (set (attr "length") |
8561 | (if_then_else (eq_attr "alternative" "0") | |
8562 | ;; Loop counter in register case | |
4c2164b7 JL |
8563 | ;; Short branch has length of 4 |
8564 | ;; Long branch has length of 8 | |
8565 | (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) | |
6a73009d | 8566 | (const_int 8184)) |
4c2164b7 JL |
8567 | (const_int 4) |
8568 | (const_int 8)) | |
98b2d887 JL |
8569 | |
8570 | ;; Loop counter in FP reg case. | |
8571 | ;; Extra goo to deal with additional reload insns. | |
8572 | (if_then_else (eq_attr "alternative" "1") | |
8573 | (if_then_else (lt (match_dup 3) (pc)) | |
2f95ebc2 | 8574 | (if_then_else |
4c2164b7 | 8575 | (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) |
6a73009d | 8576 | (const_int 8184)) |
4c2164b7 JL |
8577 | (const_int 12) |
8578 | (const_int 16)) | |
2f95ebc2 | 8579 | (if_then_else |
4c2164b7 | 8580 | (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) |
6a73009d | 8581 | (const_int 8184)) |
4c2164b7 JL |
8582 | (const_int 12) |
8583 | (const_int 16))) | |
b1092901 | 8584 | ;; Loop counter in memory or SAR case. |
98b2d887 | 8585 | ;; Extra goo to deal with additional reload insns. |
2f95ebc2 | 8586 | (if_then_else |
4c2164b7 | 8587 | (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) |
6a73009d | 8588 | (const_int 8184)) |
4c2164b7 JL |
8589 | (const_int 8) |
8590 | (const_int 12)))))]) | |
98b2d887 | 8591 | |
e45539c0 JL |
8592 | (define_insn "" |
8593 | [(set (pc) (label_ref (match_operand 3 "" "" ))) | |
eb5a4898 JL |
8594 | (set (match_operand:SI 0 "ireg_operand" "=r") |
8595 | (plus:SI (match_operand:SI 1 "ireg_operand" "r") | |
e45539c0 | 8596 | (match_operand:SI 2 "ireg_or_int5_operand" "rL")))] |
51723711 | 8597 | "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]" |
e45539c0 JL |
8598 | "* |
8599 | { | |
8600 | return output_parallel_addb (operands, get_attr_length (insn)); | |
8601 | }" | |
8602 | [(set_attr "type" "parallel_branch") | |
8603 | (set (attr "length") | |
8604 | (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) | |
8605 | (const_int 8184)) | |
8606 | (const_int 4) | |
8607 | (const_int 8)))]) | |
8608 | ||
8609 | (define_insn "" | |
8610 | [(set (pc) (label_ref (match_operand 2 "" "" ))) | |
eb5a4898 | 8611 | (set (match_operand:SF 0 "ireg_operand" "=r") |
e45539c0 JL |
8612 | (match_operand:SF 1 "ireg_or_int5_operand" "rL"))] |
8613 | "reload_completed" | |
8614 | "* | |
8615 | { | |
8616 | return output_parallel_movb (operands, get_attr_length (insn)); | |
8617 | }" | |
8618 | [(set_attr "type" "parallel_branch") | |
8619 | (set (attr "length") | |
8620 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
8621 | (const_int 8184)) | |
8622 | (const_int 4) | |
8623 | (const_int 8)))]) | |
8624 | ||
8625 | (define_insn "" | |
8626 | [(set (pc) (label_ref (match_operand 2 "" "" ))) | |
eb5a4898 | 8627 | (set (match_operand:SI 0 "ireg_operand" "=r") |
e45539c0 JL |
8628 | (match_operand:SI 1 "ireg_or_int5_operand" "rL"))] |
8629 | "reload_completed" | |
8630 | "* | |
8631 | { | |
8632 | return output_parallel_movb (operands, get_attr_length (insn)); | |
8633 | }" | |
8634 | [(set_attr "type" "parallel_branch") | |
8635 | (set (attr "length") | |
8636 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
8637 | (const_int 8184)) | |
8638 | (const_int 4) | |
8639 | (const_int 8)))]) | |
8640 | ||
8641 | (define_insn "" | |
8642 | [(set (pc) (label_ref (match_operand 2 "" "" ))) | |
eb5a4898 | 8643 | (set (match_operand:HI 0 "ireg_operand" "=r") |
e45539c0 JL |
8644 | (match_operand:HI 1 "ireg_or_int5_operand" "rL"))] |
8645 | "reload_completed" | |
8646 | "* | |
8647 | { | |
8648 | return output_parallel_movb (operands, get_attr_length (insn)); | |
8649 | }" | |
8650 | [(set_attr "type" "parallel_branch") | |
8651 | (set (attr "length") | |
8652 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
8653 | (const_int 8184)) | |
8654 | (const_int 4) | |
8655 | (const_int 8)))]) | |
8656 | ||
8657 | (define_insn "" | |
8658 | [(set (pc) (label_ref (match_operand 2 "" "" ))) | |
eb5a4898 | 8659 | (set (match_operand:QI 0 "ireg_operand" "=r") |
e45539c0 JL |
8660 | (match_operand:QI 1 "ireg_or_int5_operand" "rL"))] |
8661 | "reload_completed" | |
8662 | "* | |
8663 | { | |
8664 | return output_parallel_movb (operands, get_attr_length (insn)); | |
8665 | }" | |
8666 | [(set_attr "type" "parallel_branch") | |
8667 | (set (attr "length") | |
8668 | (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) | |
8669 | (const_int 8184)) | |
8670 | (const_int 4) | |
8671 | (const_int 8)))]) | |
8672 | ||
e45539c0 JL |
8673 | (define_insn "" |
8674 | [(set (match_operand 0 "register_operand" "=f") | |
8675 | (mult (match_operand 1 "register_operand" "f") | |
8676 | (match_operand 2 "register_operand" "f"))) | |
8677 | (set (match_operand 3 "register_operand" "+f") | |
8678 | (plus (match_operand 4 "register_operand" "f") | |
8679 | (match_operand 5 "register_operand" "f")))] | |
13ee407e | 8680 | "TARGET_PA_11 && ! TARGET_SOFT_FLOAT |
e45539c0 JL |
8681 | && reload_completed && fmpyaddoperands (operands)" |
8682 | "* | |
8683 | { | |
8684 | if (GET_MODE (operands[0]) == DFmode) | |
8685 | { | |
8686 | if (rtx_equal_p (operands[3], operands[5])) | |
8687 | return \"fmpyadd,dbl %1,%2,%0,%4,%3\"; | |
8688 | else | |
8689 | return \"fmpyadd,dbl %1,%2,%0,%5,%3\"; | |
8690 | } | |
8691 | else | |
8692 | { | |
8693 | if (rtx_equal_p (operands[3], operands[5])) | |
8694 | return \"fmpyadd,sgl %1,%2,%0,%4,%3\"; | |
8695 | else | |
8696 | return \"fmpyadd,sgl %1,%2,%0,%5,%3\"; | |
8697 | } | |
8698 | }" | |
8699 | [(set_attr "type" "fpalu") | |
8700 | (set_attr "length" "4")]) | |
8701 | ||
8702 | (define_insn "" | |
0b27d5dd TG |
8703 | [(set (match_operand 3 "register_operand" "+f") |
8704 | (plus (match_operand 4 "register_operand" "f") | |
8705 | (match_operand 5 "register_operand" "f"))) | |
8706 | (set (match_operand 0 "register_operand" "=f") | |
8707 | (mult (match_operand 1 "register_operand" "f") | |
8708 | (match_operand 2 "register_operand" "f")))] | |
13ee407e | 8709 | "TARGET_PA_11 && ! TARGET_SOFT_FLOAT |
c4bb6b38 | 8710 | && reload_completed && fmpyaddoperands (operands)" |
2c871711 JL |
8711 | "* |
8712 | { | |
8713 | if (GET_MODE (operands[0]) == DFmode) | |
19386a3e JL |
8714 | { |
8715 | if (rtx_equal_p (operands[3], operands[5])) | |
8716 | return \"fmpyadd,dbl %1,%2,%0,%4,%3\"; | |
8717 | else | |
8718 | return \"fmpyadd,dbl %1,%2,%0,%5,%3\"; | |
8719 | } | |
2c871711 | 8720 | else |
19386a3e JL |
8721 | { |
8722 | if (rtx_equal_p (operands[3], operands[5])) | |
8723 | return \"fmpyadd,sgl %1,%2,%0,%4,%3\"; | |
8724 | else | |
8725 | return \"fmpyadd,sgl %1,%2,%0,%5,%3\"; | |
8726 | } | |
c4bb6b38 JL |
8727 | }" |
8728 | [(set_attr "type" "fpalu") | |
8729 | (set_attr "length" "4")]) | |
2c871711 | 8730 | |
c4bb6b38 | 8731 | (define_insn "" |
0b27d5dd TG |
8732 | [(set (match_operand 0 "register_operand" "=f") |
8733 | (mult (match_operand 1 "register_operand" "f") | |
8734 | (match_operand 2 "register_operand" "f"))) | |
8735 | (set (match_operand 3 "register_operand" "+f") | |
8736 | (minus (match_operand 4 "register_operand" "f") | |
8737 | (match_operand 5 "register_operand" "f")))] | |
13ee407e | 8738 | "TARGET_PA_11 && ! TARGET_SOFT_FLOAT |
c4bb6b38 | 8739 | && reload_completed && fmpysuboperands (operands)" |
2c871711 JL |
8740 | "* |
8741 | { | |
8742 | if (GET_MODE (operands[0]) == DFmode) | |
8743 | return \"fmpysub,dbl %1,%2,%0,%5,%3\"; | |
8744 | else | |
8745 | return \"fmpysub,sgl %1,%2,%0,%5,%3\"; | |
c4bb6b38 JL |
8746 | }" |
8747 | [(set_attr "type" "fpalu") | |
8748 | (set_attr "length" "4")]) | |
2c871711 | 8749 | |
c4bb6b38 | 8750 | (define_insn "" |
0b27d5dd TG |
8751 | [(set (match_operand 3 "register_operand" "+f") |
8752 | (minus (match_operand 4 "register_operand" "f") | |
8753 | (match_operand 5 "register_operand" "f"))) | |
8754 | (set (match_operand 0 "register_operand" "=f") | |
8755 | (mult (match_operand 1 "register_operand" "f") | |
8756 | (match_operand 2 "register_operand" "f")))] | |
13ee407e | 8757 | "TARGET_PA_11 && ! TARGET_SOFT_FLOAT |
c4bb6b38 | 8758 | && reload_completed && fmpysuboperands (operands)" |
2c871711 JL |
8759 | "* |
8760 | { | |
8761 | if (GET_MODE (operands[0]) == DFmode) | |
8762 | return \"fmpysub,dbl %1,%2,%0,%5,%3\"; | |
8763 | else | |
8764 | return \"fmpysub,sgl %1,%2,%0,%5,%3\"; | |
c4bb6b38 JL |
8765 | }" |
8766 | [(set_attr "type" "fpalu") | |
8767 | (set_attr "length" "4")]) | |
0002b1a8 | 8768 | |
ad238e4b JL |
8769 | ;; Clean up turds left by reload. |
8770 | (define_peephole | |
d8f95bed | 8771 | [(set (match_operand 0 "move_dest_operand" "") |
63e7fe9b JL |
8772 | (match_operand 1 "register_operand" "fr")) |
8773 | (set (match_operand 2 "register_operand" "fr") | |
ad238e4b | 8774 | (match_dup 0))] |
d8f95bed | 8775 | "!TARGET_SOFT_FLOAT |
ad238e4b JL |
8776 | && GET_CODE (operands[0]) == MEM |
8777 | && ! MEM_VOLATILE_P (operands[0]) | |
8778 | && GET_MODE (operands[0]) == GET_MODE (operands[1]) | |
8779 | && GET_MODE (operands[0]) == GET_MODE (operands[2]) | |
8780 | && GET_MODE (operands[0]) == DFmode | |
63e7fe9b JL |
8781 | && GET_CODE (operands[1]) == REG |
8782 | && GET_CODE (operands[2]) == REG | |
f0501149 | 8783 | && ! side_effects_p (XEXP (operands[0], 0)) |
ad238e4b JL |
8784 | && REGNO_REG_CLASS (REGNO (operands[1])) |
8785 | == REGNO_REG_CLASS (REGNO (operands[2]))" | |
8786 | "* | |
8787 | { | |
ad238e4b JL |
8788 | rtx xoperands[2]; |
8789 | ||
8790 | if (FP_REG_P (operands[1])) | |
8791 | output_asm_insn (output_fp_move_double (operands), operands); | |
8792 | else | |
8793 | output_asm_insn (output_move_double (operands), operands); | |
8794 | ||
8795 | if (rtx_equal_p (operands[1], operands[2])) | |
8796 | return \"\"; | |
8797 | ||
8798 | xoperands[0] = operands[2]; | |
8799 | xoperands[1] = operands[1]; | |
8800 | ||
8801 | if (FP_REG_P (xoperands[1])) | |
8802 | output_asm_insn (output_fp_move_double (xoperands), xoperands); | |
8803 | else | |
8804 | output_asm_insn (output_move_double (xoperands), xoperands); | |
8805 | ||
8806 | return \"\"; | |
8807 | }") | |
8808 | ||
0f05dcc2 | 8809 | (define_peephole |
63e7fe9b | 8810 | [(set (match_operand 0 "register_operand" "fr") |
d8f95bed | 8811 | (match_operand 1 "move_src_operand" "")) |
63e7fe9b | 8812 | (set (match_operand 2 "register_operand" "fr") |
0f05dcc2 | 8813 | (match_dup 1))] |
d8f95bed | 8814 | "!TARGET_SOFT_FLOAT |
0f05dcc2 JL |
8815 | && GET_CODE (operands[1]) == MEM |
8816 | && ! MEM_VOLATILE_P (operands[1]) | |
8817 | && GET_MODE (operands[0]) == GET_MODE (operands[1]) | |
8818 | && GET_MODE (operands[0]) == GET_MODE (operands[2]) | |
8819 | && GET_MODE (operands[0]) == DFmode | |
63e7fe9b JL |
8820 | && GET_CODE (operands[0]) == REG |
8821 | && GET_CODE (operands[2]) == REG | |
f0501149 | 8822 | && ! side_effects_p (XEXP (operands[1], 0)) |
63e7fe9b | 8823 | && REGNO_REG_CLASS (REGNO (operands[0])) |
0f05dcc2 JL |
8824 | == REGNO_REG_CLASS (REGNO (operands[2]))" |
8825 | "* | |
8826 | { | |
0f05dcc2 JL |
8827 | rtx xoperands[2]; |
8828 | ||
8829 | if (FP_REG_P (operands[0])) | |
8830 | output_asm_insn (output_fp_move_double (operands), operands); | |
8831 | else | |
8832 | output_asm_insn (output_move_double (operands), operands); | |
8833 | ||
8834 | xoperands[0] = operands[2]; | |
8835 | xoperands[1] = operands[0]; | |
8836 | ||
8837 | if (FP_REG_P (xoperands[1])) | |
8838 | output_asm_insn (output_fp_move_double (xoperands), xoperands); | |
8839 | else | |
8840 | output_asm_insn (output_move_double (xoperands), xoperands); | |
8841 | ||
8842 | return \"\"; | |
8843 | }") | |
8844 | ||
3914c31f JDA |
8845 | ;; Flush the I and D cache lines from the start address (operand0) |
8846 | ;; to the end address (operand1). No lines are flushed if the end | |
8847 | ;; address is less than the start address (unsigned). | |
8848 | ;; | |
8849 | ;; Because the range of memory flushed is variable and the size of | |
8850 | ;; a MEM can only be a CONST_INT, the patterns specify that they | |
8851 | ;; perform an unspecified volatile operation on all memory. | |
8852 | ;; | |
8853 | ;; The address range for an icache flush must lie within a single | |
8854 | ;; space on targets with non-equivalent space registers. | |
8855 | ;; | |
0002b1a8 | 8856 | ;; This is used by the trampoline code for nested functions. |
3914c31f JDA |
8857 | ;; |
8858 | ;; Operand 0 contains the start address. | |
8859 | ;; Operand 1 contains the end address. | |
8860 | ;; Operand 2 contains the line length to use. | |
8861 | ;; Operand 3 contains the start address (clobbered). | |
8862 | ;; Operands 4 and 5 (icacheflush) are clobbered scratch registers. | |
bdc87462 | 8863 | (define_insn "dcacheflush" |
3914c31f JDA |
8864 | [(const_int 1) |
8865 | (unspec_volatile [(mem:BLK (scratch))] 0) | |
8866 | (use (match_operand 0 "pmode_register_operand" "r")) | |
8867 | (use (match_operand 1 "pmode_register_operand" "r")) | |
8868 | (use (match_operand 2 "pmode_register_operand" "r")) | |
8869 | (clobber (match_scratch 3 "=&0"))] | |
0002b1a8 | 8870 | "" |
3914c31f JDA |
8871 | "* |
8872 | { | |
8873 | if (TARGET_64BIT) | |
8874 | return \"cmpb,*<<=,n %3,%1,.\;fdc,m %2(%3)\;sync\"; | |
8875 | else | |
8876 | return \"cmpb,<<=,n %3,%1,.\;fdc,m %2(%3)\;sync\"; | |
8877 | }" | |
c47decad JL |
8878 | [(set_attr "type" "multi") |
8879 | (set_attr "length" "12")]) | |
bdc87462 TG |
8880 | |
8881 | (define_insn "icacheflush" | |
3914c31f JDA |
8882 | [(const_int 2) |
8883 | (unspec_volatile [(mem:BLK (scratch))] 0) | |
8884 | (use (match_operand 0 "pmode_register_operand" "r")) | |
8885 | (use (match_operand 1 "pmode_register_operand" "r")) | |
1c784a0e | 8886 | (use (match_operand 2 "pmode_register_operand" "r")) |
3914c31f JDA |
8887 | (clobber (match_scratch 3 "=&0")) |
8888 | (clobber (match_operand 4 "pmode_register_operand" "=&r")) | |
8889 | (clobber (match_operand 5 "pmode_register_operand" "=&r"))] | |
bdc87462 | 8890 | "" |
3914c31f JDA |
8891 | "* |
8892 | { | |
8893 | if (TARGET_64BIT) | |
8894 | return \"mfsp %%sr0,%5\;ldsid (%3),%4\;mtsp %4,%%sr0\;cmpb,*<<=,n %3,%1,.\;fic,m %2(%%sr0,%3)\;sync\;mtsp %5,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop\"; | |
8895 | else | |
8896 | return \"mfsp %%sr0,%5\;ldsid (%3),%4\;mtsp %4,%%sr0\;cmpb,<<=,n %3,%1,.\;fic,m %2(%%sr0,%3)\;sync\;mtsp %5,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop\"; | |
8897 | }" | |
c47decad JL |
8898 | [(set_attr "type" "multi") |
8899 | (set_attr "length" "52")]) | |
9e18f575 JL |
8900 | |
8901 | ;; An out-of-line prologue. | |
8902 | (define_insn "outline_prologue_call" | |
8903 | [(unspec_volatile [(const_int 0)] 0) | |
8904 | (clobber (reg:SI 31)) | |
8905 | (clobber (reg:SI 22)) | |
8906 | (clobber (reg:SI 21)) | |
8907 | (clobber (reg:SI 20)) | |
8908 | (clobber (reg:SI 19)) | |
8909 | (clobber (reg:SI 1))] | |
8910 | "" | |
8911 | "* | |
8912 | { | |
e63ffc38 | 8913 | extern int frame_pointer_needed; |
9e18f575 | 8914 | |
e63ffc38 JL |
8915 | /* We need two different versions depending on whether or not we |
8916 | need a frame pointer. Also note that we return to the instruction | |
8917 | immediately after the branch rather than two instructions after the | |
8918 | break as normally is the case. */ | |
8919 | if (frame_pointer_needed) | |
9e18f575 | 8920 | { |
e63ffc38 JL |
8921 | /* Must import the magic millicode routine(s). */ |
8922 | output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL); | |
8923 | ||
8924 | if (TARGET_PORTABLE_RUNTIME) | |
8925 | { | |
8926 | output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL); | |
8927 | output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\", | |
8928 | NULL); | |
8929 | } | |
8930 | else | |
f38b27c7 | 8931 | output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL); |
9e18f575 JL |
8932 | } |
8933 | else | |
e63ffc38 JL |
8934 | { |
8935 | /* Must import the magic millicode routine(s). */ | |
8936 | output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL); | |
8937 | ||
8938 | if (TARGET_PORTABLE_RUNTIME) | |
8939 | { | |
8940 | output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL); | |
8941 | output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL); | |
8942 | } | |
8943 | else | |
f38b27c7 | 8944 | output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL); |
e63ffc38 | 8945 | } |
9e18f575 JL |
8946 | return \"\"; |
8947 | }" | |
8948 | [(set_attr "type" "multi") | |
8949 | (set_attr "length" "8")]) | |
8950 | ||
8951 | ;; An out-of-line epilogue. | |
8952 | (define_insn "outline_epilogue_call" | |
8953 | [(unspec_volatile [(const_int 1)] 0) | |
8954 | (use (reg:SI 29)) | |
8955 | (use (reg:SI 28)) | |
8956 | (clobber (reg:SI 31)) | |
8957 | (clobber (reg:SI 22)) | |
8958 | (clobber (reg:SI 21)) | |
8959 | (clobber (reg:SI 20)) | |
8960 | (clobber (reg:SI 19)) | |
8961 | (clobber (reg:SI 2)) | |
8962 | (clobber (reg:SI 1))] | |
8963 | "" | |
8964 | "* | |
8965 | { | |
e63ffc38 | 8966 | extern int frame_pointer_needed; |
9e18f575 | 8967 | |
e63ffc38 JL |
8968 | /* We need two different versions depending on whether or not we |
8969 | need a frame pointer. Also note that we return to the instruction | |
8970 | immediately after the branch rather than two instructions after the | |
8971 | break as normally is the case. */ | |
8972 | if (frame_pointer_needed) | |
9e18f575 | 8973 | { |
e63ffc38 JL |
8974 | /* Must import the magic millicode routine. */ |
8975 | output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL); | |
8976 | ||
8977 | /* The out-of-line prologue will make sure we return to the right | |
8978 | instruction. */ | |
8979 | if (TARGET_PORTABLE_RUNTIME) | |
8980 | { | |
8981 | output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL); | |
8982 | output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\", | |
8983 | NULL); | |
8984 | } | |
8985 | else | |
f38b27c7 | 8986 | output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL); |
9e18f575 JL |
8987 | } |
8988 | else | |
e63ffc38 JL |
8989 | { |
8990 | /* Must import the magic millicode routine. */ | |
8991 | output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL); | |
8992 | ||
8993 | /* The out-of-line prologue will make sure we return to the right | |
8994 | instruction. */ | |
8995 | if (TARGET_PORTABLE_RUNTIME) | |
8996 | { | |
8997 | output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL); | |
8998 | output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL); | |
8999 | } | |
9000 | else | |
f38b27c7 | 9001 | output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL); |
e63ffc38 | 9002 | } |
9e18f575 JL |
9003 | return \"\"; |
9004 | }" | |
9005 | [(set_attr "type" "multi") | |
9006 | (set_attr "length" "8")]) | |
9007 | ||
ea06b0ed JL |
9008 | ;; Given a function pointer, canonicalize it so it can be |
9009 | ;; reliably compared to another function pointer. */ | |
9010 | (define_expand "canonicalize_funcptr_for_compare" | |
9011 | [(set (reg:SI 26) (match_operand:SI 1 "register_operand" "")) | |
9012 | (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0)) | |
9013 | (clobber (match_dup 2)) | |
9014 | (clobber (reg:SI 26)) | |
9015 | (clobber (reg:SI 22)) | |
9016 | (clobber (reg:SI 31))]) | |
9017 | (set (match_operand:SI 0 "register_operand" "") | |
9018 | (reg:SI 29))] | |
9e1ab8c1 | 9019 | "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" |
ea06b0ed JL |
9020 | " |
9021 | { | |
9e1ab8c1 JDA |
9022 | if (TARGET_ELF32) |
9023 | { | |
9024 | rtx canonicalize_funcptr_for_compare_libfunc | |
9025 | = init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL); | |
9026 | ||
9027 | emit_library_call_value (canonicalize_funcptr_for_compare_libfunc, | |
9028 | operands[0], LCT_NORMAL, Pmode, | |
9029 | 1, operands[1], Pmode); | |
9030 | DONE; | |
9031 | } | |
9032 | ||
ea06b0ed JL |
9033 | operands[2] = gen_reg_rtx (SImode); |
9034 | if (GET_CODE (operands[1]) != REG) | |
458c16f7 JL |
9035 | { |
9036 | rtx tmp = gen_reg_rtx (Pmode); | |
9037 | emit_move_insn (tmp, operands[1]); | |
9038 | operands[1] = tmp; | |
9039 | } | |
ea06b0ed JL |
9040 | }") |
9041 | ||
9042 | (define_insn "" | |
b46de15e JL |
9043 | [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0)) |
9044 | (clobber (match_operand:SI 0 "register_operand" "=a")) | |
9045 | (clobber (reg:SI 26)) | |
9046 | (clobber (reg:SI 22)) | |
9047 | (clobber (reg:SI 31))] | |
520babc7 | 9048 | "!TARGET_64BIT" |
b46de15e JL |
9049 | "* |
9050 | { | |
a02aa5b0 JDA |
9051 | int length = get_attr_length (insn); |
9052 | rtx xoperands[2]; | |
9053 | ||
9054 | xoperands[0] = GEN_INT (length - 8); | |
9055 | xoperands[1] = GEN_INT (length - 16); | |
9056 | ||
b46de15e JL |
9057 | /* Must import the magic millicode routine. */ |
9058 | output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL); | |
9059 | ||
956d6950 | 9060 | /* This is absolutely amazing. |
b46de15e JL |
9061 | |
9062 | First, copy our input parameter into %r29 just in case we don't | |
9063 | need to call $$sh_func_adrs. */ | |
9064 | output_asm_insn (\"copy %%r26,%%r29\", NULL); | |
a02aa5b0 | 9065 | output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL); |
b46de15e JL |
9066 | |
9067 | /* Next, examine the low two bits in %r26, if they aren't 0x2, then | |
9068 | we use %r26 unchanged. */ | |
a02aa5b0 JDA |
9069 | output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands); |
9070 | output_asm_insn (\"ldi 4096,%%r31\", NULL); | |
b46de15e JL |
9071 | |
9072 | /* Next, compare %r26 with 4096, if %r26 is less than or equal to | |
a02aa5b0 JDA |
9073 | 4096, then again we use %r26 unchanged. */ |
9074 | output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands); | |
b46de15e | 9075 | |
a02aa5b0 | 9076 | /* Finally, call $$sh_func_adrs to extract the function's real add24. */ |
b46de15e | 9077 | return output_millicode_call (insn, |
c5c76735 | 9078 | gen_rtx_SYMBOL_REF (SImode, |
a02aa5b0 | 9079 | \"$$sh_func_adrs\")); |
b46de15e JL |
9080 | }" |
9081 | [(set_attr "type" "multi") | |
611ad29e JDA |
9082 | (set (attr "length") |
9083 | (plus (symbol_ref "attr_length_millicode_call (insn)") | |
9084 | (const_int 20)))]) | |
b46de15e | 9085 | |
c133e33c MS |
9086 | ;; On the PA, the PIC register is call clobbered, so it must |
9087 | ;; be saved & restored around calls by the caller. If the call | |
9088 | ;; doesn't return normally (nonlocal goto, or an exception is | |
9089 | ;; thrown), then the code at the exception handler label must | |
9090 | ;; restore the PIC register. | |
9091 | (define_expand "exception_receiver" | |
9092 | [(const_int 4)] | |
823fbbce | 9093 | "flag_pic" |
c133e33c MS |
9094 | " |
9095 | { | |
0c263f4e JDA |
9096 | /* On the 64-bit port, we need a blockage because there is |
9097 | confusion regarding the dependence of the restore on the | |
9098 | frame pointer. As a result, the frame pointer and pic | |
9099 | register restores sometimes are interchanged erroneously. */ | |
9100 | if (TARGET_64BIT) | |
9101 | emit_insn (gen_blockage ()); | |
823fbbce JDA |
9102 | /* Restore the PIC register using hppa_pic_save_rtx (). The |
9103 | PIC register is not saved in the frame in 64-bit ABI. */ | |
9104 | emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ()); | |
611ad29e | 9105 | emit_insn (gen_blockage ()); |
c133e33c MS |
9106 | DONE; |
9107 | }") | |
5c8cfcd6 JDA |
9108 | |
9109 | (define_expand "builtin_setjmp_receiver" | |
9110 | [(label_ref (match_operand 0 "" ""))] | |
9111 | "flag_pic" | |
9112 | " | |
9113 | { | |
0c263f4e JDA |
9114 | if (TARGET_64BIT) |
9115 | emit_insn (gen_blockage ()); | |
5c8cfcd6 JDA |
9116 | /* Restore the PIC register. Hopefully, this will always be from |
9117 | a stack slot. The only registers that are valid after a | |
9118 | builtin_longjmp are the stack and frame pointers. */ | |
d777856d | 9119 | emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ()); |
611ad29e | 9120 | emit_insn (gen_blockage ()); |
5c8cfcd6 JDA |
9121 | DONE; |
9122 | }") | |
685d0e07 JDA |
9123 | |
9124 | ;; Allocate new stack space and update the saved stack pointer in the | |
9125 | ;; frame marker. The HP C compilers also copy additional words in the | |
9126 | ;; frame marker. The 64-bit compiler copies words at -48, -32 and -24. | |
9127 | ;; The 32-bit compiler copies the word at -16 (Static Link). We | |
9128 | ;; currently don't copy these values. | |
9129 | ;; | |
9130 | ;; Since the copy of the frame marker can't be done atomically, I | |
9131 | ;; suspect that using it for unwind purposes may be somewhat unreliable. | |
9132 | ;; The HP compilers appear to raise the stack and copy the frame | |
9133 | ;; marker in a strict instruction sequence. This suggests that the | |
9134 | ;; unwind library may check for an alloca sequence when ALLOCA_FRAME | |
9135 | ;; is set in the callinfo data. We currently don't set ALLOCA_FRAME | |
9136 | ;; as GAS doesn't support it, or try to keep the instructions emitted | |
9137 | ;; here in strict sequence. | |
9138 | (define_expand "allocate_stack" | |
9139 | [(match_operand 0 "" "") | |
9140 | (match_operand 1 "" "")] | |
9141 | "" | |
9142 | " | |
9143 | { | |
3ffa9dc1 JDA |
9144 | rtx addr; |
9145 | ||
685d0e07 JDA |
9146 | /* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx |
9147 | in operand 0 before adjusting the stack. */ | |
9148 | emit_move_insn (operands[0], virtual_stack_dynamic_rtx); | |
9149 | anti_adjust_stack (operands[1]); | |
9150 | if (TARGET_HPUX_UNWIND_LIBRARY) | |
9151 | { | |
3ffa9dc1 JDA |
9152 | addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, |
9153 | GEN_INT (TARGET_64BIT ? -8 : -4)); | |
9154 | emit_move_insn (gen_rtx_MEM (word_mode, addr), frame_pointer_rtx); | |
9155 | } | |
9156 | if (!TARGET_64BIT && flag_pic) | |
9157 | { | |
9158 | rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32)); | |
9159 | emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx); | |
685d0e07 JDA |
9160 | } |
9161 | DONE; | |
9162 | }") |