]>
Commit | Line | Data |
---|---|---|
c733e074 TM |
1 | ;;- Machine description for HP PA-RISC architecture for GNU C compiler |
2 | ;; Copyright (C) 1992 Free Software Foundation, Inc. | |
3 | ;; Contributed by the Center for Software Science at the University | |
876662ef | 4 | ;; of Utah. |
c733e074 TM |
5 | |
6 | ;; This file is part of GNU CC. | |
7 | ||
8 | ;; GNU CC is free software; you can redistribute it and/or modify | |
9 | ;; it under the terms of the GNU General Public License as published by | |
10 | ;; the Free Software Foundation; either version 2, or (at your option) | |
11 | ;; any later version. | |
12 | ||
13 | ;; GNU CC is distributed in the hope that it will be useful, | |
14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | ;; GNU General Public License for more details. | |
17 | ||
18 | ;; You should have received a copy of the GNU General Public License | |
19 | ;; along with GNU CC; see the file COPYING. If not, write to | |
20 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
21 | ||
22 | ;; This gcc Version 2 machine description is inspired by sparc.md and | |
23 | ;; mips.md. | |
24 | ||
25 | ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. | |
26 | ||
27 | ;; Insn type. Used to default other attribute values. | |
28 | ||
29 | ;; type "unary" insns have one input operand (1) and one output operand (0) | |
30 | ;; type "binary" insns have two input operands (1,2) and one output (0) | |
31 | ||
32 | (define_attr "type" | |
e9cfad81 | 33 | "move,unary,binary,compare,load,store,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmul,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,misc,milli" |
c733e074 TM |
34 | (const_string "binary")) |
35 | ||
c733e074 TM |
36 | ;; Length (in # of insns). |
37 | (define_attr "length" "" | |
38 | (cond [(eq_attr "type" "load,fpload") | |
39 | (if_then_else (match_operand 1 "symbolic_memory_operand" "") | |
40 | (const_int 2) (const_int 1)) | |
41 | ||
42 | (eq_attr "type" "store,fpstore") | |
43 | (if_then_else (match_operand 0 "symbolic_memory_operand" "") | |
44 | (const_int 2) (const_int 1)) | |
45 | ||
c733e074 TM |
46 | (eq_attr "type" "binary") |
47 | (if_then_else (match_operand 2 "arith_operand" "") | |
48 | (const_int 1) (const_int 3)) | |
49 | ||
50 | (eq_attr "type" "move,unary") | |
51 | (if_then_else (match_operand 1 "arith_operand" "") | |
52 | (const_int 1) (const_int 2))] | |
53 | ||
54 | (const_int 1))) | |
55 | ||
56 | (define_asm_attributes | |
57 | [(set_attr "length" "1") | |
58 | (set_attr "type" "multi")]) | |
59 | ||
60 | ;; Attributes for instruction and branch scheduling | |
61 | ||
3bf1c6b5 | 62 | (define_attr "in_branch_delay" "false,true" |
e9cfad81 | 63 | (if_then_else (and (eq_attr "type" "!branch,cbranch,fbranch,call,dyncall,multi,milli") |
3bf1c6b5 JL |
64 | (eq_attr "length" "1")) |
65 | (const_string "true") | |
66 | (const_string "false"))) | |
c733e074 | 67 | |
e9cfad81 JL |
68 | ;; Unconditional branch, call, and millicode call delay slot description. |
69 | (define_delay (eq_attr "type" "branch,call,milli") | |
3bf1c6b5 | 70 | [(eq_attr "in_branch_delay" "true") (nil) (nil)]) |
c733e074 | 71 | |
e9cfad81 JL |
72 | ;; Floating point conditional branch delay slot description. |
73 | (define_delay (eq_attr "type" "fbranch") | |
876662ef TG |
74 | [(eq_attr "in_branch_delay" "true") |
75 | (eq_attr "in_branch_delay" "true") | |
e9cfad81 | 76 | (nil)]) |
c733e074 | 77 | |
e9cfad81 JL |
78 | ;; Integer conditional branch delay slot description. |
79 | (define_delay (eq_attr "type" "cbranch") | |
29662692 | 80 | [(eq_attr "in_branch_delay" "true") (nil) (nil)]) |
c733e074 TM |
81 | |
82 | ;; Function units of the HPPA. The following data is for the "Snake" | |
83 | ;; (Mustang CPU + Timex FPU) because that's what I have the docs for. | |
84 | ;; Scheduling instructions for PA-83 machines according to the Snake | |
85 | ;; constraints shouldn't hurt. | |
86 | ||
87 | ;; (define_function_unit {name} {num-units} {n-users} {test} | |
c8e18a2b | 88 | ;; {ready-delay} {issue-delay} [{conflict-list}]) |
c733e074 TM |
89 | |
90 | ;; The integer ALU. | |
91 | ;; (Noted only for documentation; units that take one cycle do not need to | |
92 | ;; be specified.) | |
93 | ||
94 | ;; (define_function_unit "alu" 1 0 | |
95 | ;; (eq_attr "type" "unary,binary,move,address") 1 0) | |
96 | ||
97 | ||
98 | ;; Memory. Disregarding Cache misses, the Mustang memory times are: | |
10849233 | 99 | ;; load: 2 |
c733e074 TM |
100 | ;; store, fpstore: 3, no D-cache operations should be scheduled. |
101 | ;; fpload: 3 (really 2 for flops, but I don't think we can specify that). | |
102 | ||
10849233 | 103 | (define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0) |
c733e074 TM |
104 | (define_function_unit "memory" 1 1 (eq_attr "type" "store,fpstore") 3 0) |
105 | (define_function_unit "memory" 1 1 (eq_attr "type" "fpload") 3 0) | |
106 | ||
107 | ;; The Timex has two floating-point units: ALU, and MUL/DIV/SQRT unit. | |
108 | ;; Timings: | |
109 | ;; Instruction Time Unit Minimum Distance (unit contention) | |
110 | ;; fcpy 3 ALU 2 | |
111 | ;; fabs 3 ALU 2 | |
112 | ;; fadd 3 ALU 2 | |
113 | ;; fsub 3 ALU 2 | |
114 | ;; fcmp 3 ALU 2 | |
115 | ;; fcnv 3 ALU 2 | |
116 | ;; fmpyadd 3 ALU,MPY 2 | |
117 | ;; fmpysub 3 ALU,MPY 2 | |
118 | ;; fmpycfxt 3 ALU,MPY 2 | |
119 | ;; fmpy 3 MPY 2 | |
120 | ;; fmpyi 3 MPY 2 | |
121 | ;; fdiv,sgl 10 MPY 10 | |
122 | ;; fdiv,dbl 12 MPY 12 | |
123 | ;; fsqrt,sgl 14 MPY 14 | |
124 | ;; fsqrt,dbl 18 MPY 18 | |
125 | ||
742ba40c | 126 | (define_function_unit "fp_alu" 1 0 (eq_attr "type" "fpcc") 4 2) |
c733e074 TM |
127 | (define_function_unit "fp_alu" 1 0 (eq_attr "type" "fpalu") 3 2) |
128 | (define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpmul") 3 2) | |
129 | (define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpdivsgl") 10 10) | |
130 | (define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpdivdbl") 12 12) | |
131 | (define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpsqrtsgl") 14 14) | |
132 | (define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpsqrtdbl") 18 18) | |
133 | \f | |
134 | ;; Compare instructions. | |
135 | ;; This controls RTL generation and register allocation. | |
136 | ||
876662ef | 137 | ;; We generate RTL for comparisons and branches by having the cmpxx |
c733e074 TM |
138 | ;; patterns store away the operands. Then, the scc and bcc patterns |
139 | ;; emit RTL for both the compare and the branch. | |
140 | ;; | |
141 | ||
142 | (define_expand "cmpsi" | |
143 | [(set (reg:CC 0) | |
144 | (compare:CC (match_operand:SI 0 "reg_or_0_operand" "") | |
145 | (match_operand:SI 1 "arith5_operand" "")))] | |
146 | "" | |
147 | " | |
148 | { | |
149 | hppa_compare_op0 = operands[0]; | |
150 | hppa_compare_op1 = operands[1]; | |
151 | hppa_branch_type = CMP_SI; | |
152 | DONE; | |
153 | }") | |
154 | ||
155 | (define_expand "cmpsf" | |
156 | [(set (reg:CCFP 0) | |
157 | (compare:CCFP (match_operand:SF 0 "register_operand" "") | |
158 | (match_operand:SF 1 "register_operand" "")))] | |
159 | "" | |
160 | " | |
161 | { | |
162 | hppa_compare_op0 = operands[0]; | |
163 | hppa_compare_op1 = operands[1]; | |
164 | hppa_branch_type = CMP_SF; | |
165 | DONE; | |
166 | }") | |
167 | ||
168 | (define_expand "cmpdf" | |
169 | [(set (reg:CCFP 0) | |
170 | (compare:CCFP (match_operand:DF 0 "register_operand" "") | |
171 | (match_operand:DF 1 "register_operand" "")))] | |
172 | "" | |
173 | " | |
174 | { | |
175 | hppa_compare_op0 = operands[0]; | |
176 | hppa_compare_op1 = operands[1]; | |
177 | hppa_branch_type = CMP_DF; | |
178 | DONE; | |
179 | }") | |
180 | ||
181 | (define_insn "" | |
182 | [(set (reg:CCFP 0) | |
183 | (match_operator:CCFP 2 "comparison_operator" | |
53a66787 TG |
184 | [(match_operand:SF 0 "register_operand" "fx") |
185 | (match_operand:SF 1 "register_operand" "fx")]))] | |
c733e074 TM |
186 | "" |
187 | "fcmp,sgl,%Y2 %0,%1" | |
188 | [(set_attr "type" "fpcc")]) | |
189 | ||
190 | (define_insn "" | |
191 | [(set (reg:CCFP 0) | |
192 | (match_operator:CCFP 2 "comparison_operator" | |
53a66787 TG |
193 | [(match_operand:DF 0 "register_operand" "fx") |
194 | (match_operand:DF 1 "register_operand" "fx")]))] | |
c733e074 TM |
195 | "" |
196 | "fcmp,dbl,%Y2 %0,%1" | |
197 | [(set_attr "type" "fpcc")]) | |
198 | ||
199 | ;; scc insns. | |
200 | ||
201 | (define_insn "" | |
202 | [(set (match_operand:SI 0 "register_operand" "=r") | |
203 | (match_operator:CCFP 1 "comparison_operator" [(reg:CCFP 0) | |
204 | (const_int 0)]))] | |
205 | "" | |
206 | "copy 0,%0\;ftest\;ldi 1,%0" | |
207 | [(set_attr "type" "unary") | |
208 | (set_attr "length" "3")]) | |
209 | ||
210 | (define_expand "seq" | |
211 | [(set (match_operand:SI 0 "register_operand" "") | |
d2a94ec0 | 212 | (eq:SI (match_dup 1) |
c733e074 TM |
213 | (match_dup 2)))] |
214 | "" | |
215 | " | |
216 | { | |
217 | if (hppa_branch_type != CMP_SI) | |
218 | { | |
219 | emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1)); | |
220 | emit_insn (gen_scond_fp (EQ, operands[0])); | |
221 | DONE; | |
222 | } | |
223 | /* set up operands from compare. */ | |
224 | operands[1] = hppa_compare_op0; | |
225 | operands[2] = hppa_compare_op1; | |
226 | /* fall through and generate default code */ | |
227 | }") | |
228 | ||
229 | (define_expand "sne" | |
876662ef | 230 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 231 | (ne:SI (match_dup 1) |
c733e074 TM |
232 | (match_dup 2)))] |
233 | "" | |
234 | " | |
235 | { | |
236 | if (hppa_branch_type != CMP_SI) | |
237 | { | |
238 | emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1)); | |
239 | emit_insn (gen_scond_fp (NE, operands[0])); | |
240 | DONE; | |
241 | } | |
242 | operands[1] = hppa_compare_op0; | |
243 | operands[2] = hppa_compare_op1; | |
244 | }") | |
245 | ||
246 | (define_expand "slt" | |
876662ef | 247 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 248 | (lt:SI (match_dup 1) |
c733e074 TM |
249 | (match_dup 2)))] |
250 | "" | |
251 | " | |
252 | { | |
253 | if (hppa_branch_type != CMP_SI) | |
254 | { | |
255 | emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1)); | |
256 | emit_insn (gen_scond_fp (LT, operands[0])); | |
257 | DONE; | |
258 | } | |
259 | operands[1] = hppa_compare_op0; | |
260 | operands[2] = hppa_compare_op1; | |
261 | }") | |
262 | ||
263 | (define_expand "sgt" | |
876662ef | 264 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 265 | (gt:SI (match_dup 1) |
c733e074 TM |
266 | (match_dup 2)))] |
267 | "" | |
268 | " | |
269 | { | |
270 | if (hppa_branch_type != CMP_SI) | |
271 | { | |
272 | emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1)); | |
273 | emit_insn (gen_scond_fp (GT, operands[0])); | |
274 | DONE; | |
275 | } | |
276 | operands[1] = hppa_compare_op0; | |
277 | operands[2] = hppa_compare_op1; | |
278 | }") | |
279 | ||
280 | (define_expand "sle" | |
876662ef | 281 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 282 | (le:SI (match_dup 1) |
c733e074 TM |
283 | (match_dup 2)))] |
284 | "" | |
285 | " | |
286 | { | |
287 | if (hppa_branch_type != CMP_SI) | |
288 | { | |
289 | emit_insn (gen_cmp_fp (LE, hppa_compare_op0, hppa_compare_op1)); | |
290 | emit_insn (gen_scond_fp (LE, operands[0])); | |
291 | DONE; | |
292 | } | |
293 | operands[1] = hppa_compare_op0; | |
294 | operands[2] = hppa_compare_op1; | |
295 | }") | |
296 | ||
297 | (define_expand "sge" | |
876662ef | 298 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 299 | (ge:SI (match_dup 1) |
c733e074 TM |
300 | (match_dup 2)))] |
301 | "" | |
302 | " | |
303 | { | |
304 | if (hppa_branch_type != CMP_SI) | |
305 | { | |
306 | emit_insn (gen_cmp_fp (GE, hppa_compare_op0, hppa_compare_op1)); | |
307 | emit_insn (gen_scond_fp (GE, operands[0])); | |
308 | DONE; | |
309 | } | |
310 | operands[1] = hppa_compare_op0; | |
311 | operands[2] = hppa_compare_op1; | |
312 | }") | |
313 | ||
314 | (define_expand "sltu" | |
876662ef | 315 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 316 | (ltu:SI (match_dup 1) |
c733e074 TM |
317 | (match_dup 2)))] |
318 | "" | |
319 | " | |
320 | { | |
321 | if (hppa_branch_type != CMP_SI) | |
322 | FAIL; | |
323 | operands[1] = hppa_compare_op0; | |
324 | operands[2] = hppa_compare_op1; | |
325 | }") | |
326 | ||
327 | (define_expand "sgtu" | |
876662ef | 328 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 329 | (gtu:SI (match_dup 1) |
c733e074 TM |
330 | (match_dup 2)))] |
331 | "" | |
332 | " | |
333 | { | |
334 | if (hppa_branch_type != CMP_SI) | |
335 | FAIL; | |
336 | operands[1] = hppa_compare_op0; | |
337 | operands[2] = hppa_compare_op1; | |
338 | }") | |
339 | ||
340 | (define_expand "sleu" | |
876662ef | 341 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 342 | (leu:SI (match_dup 1) |
c733e074 TM |
343 | (match_dup 2)))] |
344 | "" | |
345 | " | |
346 | { | |
347 | if (hppa_branch_type != CMP_SI) | |
348 | FAIL; | |
349 | operands[1] = hppa_compare_op0; | |
350 | operands[2] = hppa_compare_op1; | |
351 | }") | |
352 | ||
353 | (define_expand "sgeu" | |
876662ef | 354 | [(set (match_operand:SI 0 "register_operand" "") |
d2a94ec0 | 355 | (geu:SI (match_dup 1) |
c733e074 TM |
356 | (match_dup 2)))] |
357 | "" | |
358 | " | |
359 | { | |
360 | if (hppa_branch_type != CMP_SI) | |
361 | FAIL; | |
362 | operands[1] = hppa_compare_op0; | |
363 | operands[2] = hppa_compare_op1; | |
364 | }") | |
365 | ||
366 | ;; Instruction canonicalization puts immediate operands second, which | |
367 | ;; is the reverse of what we want. | |
368 | ||
fd0214cd | 369 | (define_insn "scc" |
c733e074 | 370 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
d2a94ec0 | 371 | (match_operator:SI 3 "comparison_operator" |
c733e074 TM |
372 | [(match_operand:SI 1 "register_operand" "r,r") |
373 | (match_operand:SI 2 "arith11_operand" "r,I")]))] | |
374 | "" | |
375 | "* | |
376 | { | |
377 | if (which_alternative == 0) | |
378 | return \"comclr,%N3 %1,%2,%0\;ldi 1,%0\"; | |
379 | else | |
380 | { | |
381 | if (!(GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE)) | |
382 | PUT_CODE (operands[3], reverse_relop (GET_CODE (operands[3]))); | |
876662ef | 383 | return \"comiclr,%N3 %2,%1,%0\;ldi 1,%0\"; |
c733e074 TM |
384 | } |
385 | }" | |
876662ef TG |
386 | [(set_attr "type" "binary,binary") |
387 | (set_attr "length" "2,2")]) | |
c733e074 | 388 | |
fd0214cd JL |
389 | ;; Combiner patterns for common operations performed with the output |
390 | ;; from an scc insn (negscc and incscc). | |
391 | (define_insn "negscc" | |
392 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
393 | (neg (match_operator:SI 3 "comparison_operator" | |
394 | [(match_operand:SI 1 "register_operand" "r,r") | |
395 | (match_operand:SI 2 "arith11_operand" "r,I")])))] | |
396 | "" | |
397 | "* | |
398 | { | |
399 | if (which_alternative == 0) | |
400 | return \"comclr,%N3 %1,%2,%0\;ldi -1,%0\"; | |
401 | else | |
402 | { | |
403 | if (!(GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE)) | |
404 | PUT_CODE (operands[3], reverse_relop (GET_CODE (operands[3]))); | |
405 | return \"comiclr,%N3 %2,%1,%0\;ldi -1,%0\"; | |
406 | } | |
407 | }" | |
408 | [(set_attr "type" "binary") | |
409 | (set_attr "length" "2")]) | |
410 | ||
411 | ;; add/sub the output from an scc with another operand. This simply | |
412 | ;; adds or subtracts 1 from the other operand. | |
413 | (define_insn "incscc" | |
414 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
415 | (match_operator 5 "incscc_operator" | |
416 | [(match_operand:SI 1 "register_operand" "0,r") | |
417 | (match_operator:SI 4 "comparison_operator" | |
418 | [(match_operand:SI 2 "register_operand" "r,r") | |
419 | (match_operand:SI 3 "arith11_operand" "rI,rI")])]))] | |
420 | ||
421 | "" | |
422 | "* | |
423 | { | |
424 | if (GET_CODE (operands[3]) != CONST_INT) | |
425 | output_asm_insn (\"comclr,%N4 %2,%3,0\", operands); | |
426 | else | |
427 | { | |
428 | if (! (GET_CODE (operands[4]) == EQ || GET_CODE (operands[4]) == NE)) | |
429 | PUT_CODE (operands[4], reverse_relop (GET_CODE (operands[4]))); | |
430 | output_asm_insn (\"comiclr,%N4 %3,%2,0\", operands); | |
431 | } | |
432 | if (which_alternative == 0) | |
433 | { | |
434 | if (GET_CODE (operands[5]) == MINUS) | |
435 | return \"addi -1,%0,%0\"; | |
436 | else | |
437 | return \"addi 1,%0,%0\"; | |
438 | } | |
439 | else | |
440 | { | |
441 | if (GET_CODE (operands[5]) == MINUS) | |
442 | return \"addi,tr -1,%1,%0\;copy %1,%0\"; | |
443 | else | |
444 | return \"addi,tr 1,%1,%0\;copy %1,%0\"; | |
445 | } | |
446 | }" | |
447 | [(set_attr "type" "binary,binary") | |
448 | (set_attr "length" "2,3")]) | |
449 | ||
c733e074 TM |
450 | ;; Conditionals |
451 | ||
452 | (define_expand "beq" | |
453 | [(set (pc) | |
454 | (if_then_else (eq (match_dup 1) (match_dup 2)) | |
455 | (label_ref (match_operand 0 "" "")) | |
456 | (pc)))] | |
457 | "" | |
458 | " | |
459 | { | |
460 | if (hppa_branch_type != CMP_SI) | |
461 | { | |
462 | emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1)); | |
463 | emit_bcond_fp (NE, operands[0]); | |
464 | DONE; | |
465 | } | |
466 | /* set up operands from compare. */ | |
467 | operands[1] = hppa_compare_op0; | |
468 | operands[2] = hppa_compare_op1; | |
469 | /* fall through and generate default code */ | |
470 | }") | |
471 | ||
472 | (define_expand "bne" | |
473 | [(set (pc) | |
474 | (if_then_else (ne (match_dup 1) (match_dup 2)) | |
475 | (label_ref (match_operand 0 "" "")) | |
476 | (pc)))] | |
477 | "" | |
478 | " | |
479 | { | |
480 | if (hppa_branch_type != CMP_SI) | |
481 | { | |
482 | emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1)); | |
483 | emit_bcond_fp (NE, operands[0]); | |
484 | DONE; | |
485 | } | |
486 | operands[1] = hppa_compare_op0; | |
487 | operands[2] = hppa_compare_op1; | |
488 | }") | |
489 | ||
490 | (define_expand "bgt" | |
491 | [(set (pc) | |
492 | (if_then_else (gt (match_dup 1) (match_dup 2)) | |
493 | (label_ref (match_operand 0 "" "")) | |
494 | (pc)))] | |
495 | "" | |
496 | " | |
497 | { | |
498 | if (hppa_branch_type != CMP_SI) | |
499 | { | |
500 | emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1)); | |
501 | emit_bcond_fp (NE, operands[0]); | |
502 | DONE; | |
503 | } | |
504 | operands[1] = hppa_compare_op0; | |
505 | operands[2] = hppa_compare_op1; | |
506 | }") | |
507 | ||
508 | (define_expand "blt" | |
509 | [(set (pc) | |
510 | (if_then_else (lt (match_dup 1) (match_dup 2)) | |
511 | (label_ref (match_operand 0 "" "")) | |
512 | (pc)))] | |
513 | "" | |
514 | " | |
515 | { | |
516 | if (hppa_branch_type != CMP_SI) | |
517 | { | |
518 | emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1)); | |
519 | emit_bcond_fp (NE, operands[0]); | |
520 | DONE; | |
521 | } | |
522 | operands[1] = hppa_compare_op0; | |
523 | operands[2] = hppa_compare_op1; | |
524 | }") | |
525 | ||
526 | (define_expand "bge" | |
527 | [(set (pc) | |
528 | (if_then_else (ge (match_dup 1) (match_dup 2)) | |
529 | (label_ref (match_operand 0 "" "")) | |
530 | (pc)))] | |
531 | "" | |
532 | " | |
533 | { | |
534 | if (hppa_branch_type != CMP_SI) | |
535 | { | |
536 | emit_insn (gen_cmp_fp (GE, hppa_compare_op0, hppa_compare_op1)); | |
537 | emit_bcond_fp (NE, operands[0]); | |
538 | DONE; | |
539 | } | |
540 | operands[1] = hppa_compare_op0; | |
541 | operands[2] = hppa_compare_op1; | |
542 | }") | |
543 | ||
544 | (define_expand "ble" | |
545 | [(set (pc) | |
546 | (if_then_else (le (match_dup 1) (match_dup 2)) | |
547 | (label_ref (match_operand 0 "" "")) | |
548 | (pc)))] | |
549 | "" | |
550 | " | |
551 | { | |
552 | if (hppa_branch_type != CMP_SI) | |
553 | { | |
554 | emit_insn (gen_cmp_fp (LE, hppa_compare_op0, hppa_compare_op1)); | |
555 | emit_bcond_fp (NE, operands[0]); | |
556 | DONE; | |
557 | } | |
558 | operands[1] = hppa_compare_op0; | |
559 | operands[2] = hppa_compare_op1; | |
560 | }") | |
561 | ||
562 | (define_expand "bgtu" | |
563 | [(set (pc) | |
564 | (if_then_else (gtu (match_dup 1) (match_dup 2)) | |
565 | (label_ref (match_operand 0 "" "")) | |
566 | (pc)))] | |
567 | "" | |
568 | " | |
569 | { | |
570 | if (hppa_branch_type != CMP_SI) | |
571 | FAIL; | |
572 | operands[1] = hppa_compare_op0; | |
573 | operands[2] = hppa_compare_op1; | |
574 | }") | |
575 | ||
576 | (define_expand "bltu" | |
577 | [(set (pc) | |
578 | (if_then_else (ltu (match_dup 1) (match_dup 2)) | |
579 | (label_ref (match_operand 0 "" "")) | |
580 | (pc)))] | |
581 | "" | |
582 | " | |
583 | { | |
584 | if (hppa_branch_type != CMP_SI) | |
585 | FAIL; | |
586 | operands[1] = hppa_compare_op0; | |
587 | operands[2] = hppa_compare_op1; | |
588 | }") | |
589 | ||
590 | (define_expand "bgeu" | |
591 | [(set (pc) | |
592 | (if_then_else (geu (match_dup 1) (match_dup 2)) | |
593 | (label_ref (match_operand 0 "" "")) | |
594 | (pc)))] | |
595 | "" | |
596 | " | |
597 | { | |
598 | if (hppa_branch_type != CMP_SI) | |
599 | FAIL; | |
600 | operands[1] = hppa_compare_op0; | |
601 | operands[2] = hppa_compare_op1; | |
602 | }") | |
603 | ||
604 | (define_expand "bleu" | |
605 | [(set (pc) | |
606 | (if_then_else (leu (match_dup 1) (match_dup 2)) | |
607 | (label_ref (match_operand 0 "" "")) | |
608 | (pc)))] | |
609 | "" | |
610 | " | |
611 | { | |
612 | if (hppa_branch_type != CMP_SI) | |
613 | FAIL; | |
614 | operands[1] = hppa_compare_op0; | |
615 | operands[2] = hppa_compare_op1; | |
616 | }") | |
617 | ||
618 | ;; Match the branch patterns. | |
619 | ||
620 | (define_insn "" | |
621 | [(set (pc) | |
622 | (if_then_else | |
623 | (match_operator 3 "comparison_operator" | |
624 | [(match_operand:SI 1 "register_operand" "r,r") | |
625 | (match_operand:SI 2 "arith5_operand" "r,L")]) | |
626 | (label_ref (match_operand 0 "" "")) | |
627 | (pc)))] | |
628 | "" | |
629 | "* | |
630 | { | |
631 | if (which_alternative == 0) | |
632 | return (get_attr_length (insn) == 1 | |
633 | ? \"comb,%C3 %1,%2,%0%#\" : \"comclr,%N3 %1,%2,0\;bl %0,0%#\"); | |
634 | { | |
635 | enum rtx_code comp_code = GET_CODE (operands[3]); | |
636 | if (!(comp_code == EQ || comp_code == NE)) | |
637 | PUT_CODE (operands[3], reverse_relop (comp_code)); | |
638 | if (get_attr_length (insn) == 1) | |
876662ef | 639 | return \"comib,%C3 %2,%1,%0%#\"; |
c733e074 | 640 | else |
876662ef | 641 | return \"comiclr,%N3 %2,%1,0\;bl %0,0%#\"; |
c733e074 TM |
642 | } |
643 | }" | |
644 | [(set_attr "type" "cbranch") | |
645 | (set (attr "length") (if_then_else (lt (abs (minus (match_dup 0) | |
646 | (plus (pc) (const_int 2)))) | |
647 | (const_int 1023)) | |
648 | (const_int 1) | |
649 | (const_int 2)))]) | |
650 | ||
651 | ;; Match the negated branch. | |
652 | ||
653 | (define_insn "" | |
654 | [(set (pc) | |
655 | (if_then_else | |
656 | (match_operator 3 "comparison_operator" | |
657 | [(match_operand:SI 1 "register_operand" "r,r") | |
658 | (match_operand:SI 2 "arith5_operand" "r,L")]) | |
659 | (pc) | |
660 | (label_ref (match_operand 0 "" ""))))] | |
661 | "" | |
662 | "* | |
663 | { | |
664 | if (which_alternative == 0) | |
665 | return (get_attr_length (insn) == 1 | |
666 | ? \"comb,%N3 %1,%2,%0%#\" : \"comclr,%C3 %1,%2,0\;bl %0,0%#\"); | |
667 | { | |
668 | enum rtx_code comp_code = GET_CODE (operands[3]); | |
669 | if (!(comp_code == EQ || comp_code == NE)) | |
670 | PUT_CODE (operands[3], reverse_relop (comp_code)); | |
671 | if (get_attr_length (insn) == 1) | |
876662ef | 672 | return \"comib,%N3 %2,%1,%0%#\"; |
c733e074 | 673 | else |
876662ef | 674 | return \"comiclr,%C3 %2,%1,0%#\;bl %0,0%#\"; |
c733e074 TM |
675 | } |
676 | }" | |
677 | [(set_attr "type" "cbranch") | |
678 | (set (attr "length") (if_then_else (lt (abs (minus (match_dup 0) | |
679 | (plus (pc) (const_int 2)))) | |
680 | (const_int 1023)) | |
681 | (const_int 1) | |
682 | (const_int 2)))]) | |
683 | ||
684 | ;; Floating point branches | |
685 | ||
686 | (define_insn "" | |
687 | [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0)) | |
688 | (label_ref (match_operand 0 "" "")) | |
689 | (pc)))] | |
690 | "" | |
e9cfad81 JL |
691 | "* |
692 | { | |
693 | if (INSN_ANNULLED_BRANCH_P (insn)) | |
694 | return \"ftest\;bl,n %0,0\"; | |
695 | else | |
696 | return \"ftest\;bl%* %0,0\"; | |
697 | }" | |
698 | [(set_attr "type" "fbranch") | |
c733e074 TM |
699 | (set_attr "length" "2")]) |
700 | ||
701 | (define_insn "" | |
702 | [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0)) | |
703 | (pc) | |
704 | (label_ref (match_operand 0 "" ""))))] | |
705 | "" | |
e9cfad81 JL |
706 | "* |
707 | { | |
708 | if (INSN_ANNULLED_BRANCH_P (insn)) | |
709 | return \"ftest\;add,tr 0,0,0\;bl,n %0,0\"; | |
710 | else | |
711 | return \"ftest\;add,tr 0,0,0\;bl%* %0,0\"; | |
712 | }" | |
713 | [(set_attr "type" "fbranch") | |
c733e074 TM |
714 | (set_attr "length" "3")]) |
715 | ||
716 | ;; Move instructions | |
717 | ||
718 | (define_expand "movsi" | |
719 | [(set (match_operand:SI 0 "general_operand" "") | |
720 | (match_operand:SI 1 "general_operand" ""))] | |
721 | "" | |
722 | " | |
723 | { | |
d2a94ec0 | 724 | if (emit_move_sequence (operands, SImode, 0)) |
c733e074 TM |
725 | DONE; |
726 | }") | |
727 | ||
d2a94ec0 TM |
728 | ;; Reloading an SImode or DImode value requires a scratch register if |
729 | ;; going in to or out of float point registers. | |
730 | ||
731 | (define_expand "reload_insi" | |
732 | [(set (match_operand:SI 0 "register_operand" "=z") | |
733 | (match_operand:SI 1 "general_operand" "")) | |
734 | (clobber (match_operand:SI 2 "register_operand" "=&r"))] | |
735 | "" | |
736 | " | |
737 | { | |
738 | if (emit_move_sequence (operands, SImode, operands[2])) | |
739 | DONE; | |
740 | ||
741 | /* We don't want the clobber emitted, so handle this ourselves. */ | |
742 | emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); | |
743 | DONE; | |
744 | }") | |
745 | ||
746 | (define_expand "reload_outsi" | |
747 | [(set (match_operand:SI 0 "general_operand" "") | |
748 | (match_operand:SI 1 "register_operand""z")) | |
749 | (clobber (match_operand:SI 2 "register_operand" "=&r"))] | |
750 | "" | |
751 | " | |
752 | { | |
753 | if (emit_move_sequence (operands, SImode, operands[2])) | |
754 | DONE; | |
755 | ||
756 | /* We don't want the clobber emitted, so handle this ourselves. */ | |
757 | emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); | |
758 | DONE; | |
759 | }") | |
760 | ||
d2a94ec0 TM |
761 | ;;; Experimental |
762 | ||
fd0214cd JL |
763 | (define_insn "cmov" |
764 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
765 | (if_then_else:SI | |
766 | (match_operator 5 "comparison_operator" | |
767 | [(match_operand:SI 3 "register_operand" "r,r") | |
768 | (match_operand:SI 4 "arith5_operand" "rL,rL")]) | |
769 | (match_operand:SI 1 "arith11_operand" "0,rI") | |
770 | (match_operand:SI 2 "arith11_operand" "rI,0")))] | |
771 | "" | |
772 | "* | |
773 | { | |
774 | if (GET_CODE (operands[4]) == CONST_INT) | |
775 | { | |
776 | if (! (GET_CODE (operands[5]) == EQ || GET_CODE (operands[5]) == NE)) | |
777 | PUT_CODE (operands[5], reverse_relop (GET_CODE (operands[5]))); | |
778 | output_asm_insn (\"comiclr,%C5 %4,%3,0\", operands); | |
779 | } | |
780 | else | |
781 | output_asm_insn (\"comclr,%C5 %3,%4,0\", operands); | |
782 | if (which_alternative == 0) | |
783 | { | |
784 | if (GET_CODE (operands[2]) == CONST_INT) | |
785 | output_asm_insn (\"ldo %2(0),%0\", operands); | |
786 | else | |
787 | output_asm_insn (\"copy %2,%0\", operands); | |
788 | } | |
789 | else | |
790 | { | |
791 | if (GET_CODE (operands[1]) == CONST_INT) | |
792 | output_asm_insn (\"ldo %1(0),%0\", operands); | |
793 | else | |
794 | output_asm_insn (\"copy %1,%0\", operands); | |
795 | } | |
796 | return \"\"; | |
797 | }" | |
798 | [(set_attr "type" "multi,multi") | |
799 | (set_attr "length" "2,2")]) | |
800 | ||
d2a94ec0 TM |
801 | (define_insn "" |
802 | [(set (match_operand:SI 0 "fp_reg_operand" "=fx") | |
803 | (match_operand:SI 1 "short_memory_operand" "T"))] | |
804 | "" | |
805 | "fldws%F1 %1,%0" | |
806 | [(set_attr "type" "fpload") | |
807 | (set_attr "length" "1")]) | |
808 | ||
809 | (define_insn "" | |
810 | [(set (match_operand:SI 0 "short_memory_operand" "=T") | |
811 | (match_operand:SI 1 "fp_reg_operand" "fx"))] | |
812 | "" | |
813 | "fstws%F0 %1,%0" | |
814 | [(set_attr "type" "fpstore") | |
815 | (set_attr "length" "1")]) | |
816 | ||
13d39dbc | 817 | ;;; pic symbol references |
d2a94ec0 TM |
818 | |
819 | (define_insn "" | |
820 | [(set (match_operand:SI 0 "register_operand" "=r") | |
821 | (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") | |
822 | (match_operand:SI 2 "symbolic_operand" ""))))] | |
823 | "flag_pic && operands[1] == pic_offset_table_rtx" | |
824 | "ldw T'%2(%1),%0" | |
825 | [(set_attr "type" "load") | |
826 | (set_attr "length" "1")]) | |
827 | ||
c733e074 TM |
828 | (define_insn "" |
829 | [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" | |
cb524f44 TG |
830 | "=r,r,Q,*q,!*r,!fx,!fx") |
831 | (match_operand:SI 1 "move_operand" "rM,Q,rM,rM,!fxy,!*r,!fx"))] | |
4d72c241 | 832 | "register_operand (operands[0], SImode) |
29ed7081 | 833 | || reg_or_0_operand (operands[1], SImode)" |
c733e074 TM |
834 | "@ |
835 | copy %r1,%0 | |
836 | ldw%M1 %1,%0 | |
837 | stw%M0 %r1,%0 | |
cb524f44 | 838 | mtsar %r1 |
c733e074 TM |
839 | fstws %1,-16(30)\;ldw -16(30),%0 |
840 | stw %1,-16(30)\;fldws -16(30),%0 | |
841 | fcpy,sgl %1,%0" | |
cb524f44 TG |
842 | [(set_attr "type" "move,load,store,move,load,fpload,fpalu") |
843 | (set_attr "length" "1,1,1,1,2,2,1")]) | |
c733e074 TM |
844 | |
845 | ;; For pic | |
846 | (define_insn "" | |
847 | [(set (match_operand:SI 0 "register_operand" "=r") | |
848 | (match_operand:SI 1 "pic_operand" "i")) | |
849 | (clobber (match_scratch:SI 2 "=a"))] | |
850 | "" | |
851 | "* | |
852 | { | |
853 | rtx label_rtx = gen_label_rtx (); | |
854 | rtx xoperands[3]; | |
855 | extern FILE *asm_out_file; | |
856 | ||
857 | xoperands[0] = operands[0]; | |
858 | xoperands[1] = operands[1]; | |
859 | xoperands[2] = label_rtx; | |
860 | output_asm_insn (\"bl .+8,%0\;addil L'%1-%2,%0\", xoperands); | |
861 | ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label_rtx)); | |
d2a94ec0 | 862 | output_asm_insn (\"ldo R'%1-%2(1),%0\", xoperands); |
c733e074 TM |
863 | return \"\"; |
864 | } | |
865 | " | |
866 | [(set_attr "type" "multi") | |
867 | (set_attr "length" "3")]) | |
868 | ||
869 | (define_insn "" | |
870 | [(set (match_operand:SI 0 "register_operand" "=r") | |
907f67cc TG |
871 | (match_operand:SI 1 "const_int_operand" ""))] |
872 | "INT_14_BITS (operands[1]) || (INTVAL (operands[1]) & 0x7ff) == 0" | |
c733e074 TM |
873 | "* |
874 | { | |
875 | if (INT_14_BITS (operands[1])) | |
876 | return \"ldo %1(0),%0\"; | |
877 | else | |
878 | return \"ldil L'%1,%0\"; | |
879 | }" | |
880 | [(set_attr "type" "move") | |
881 | (set_attr "length" "1")]) | |
882 | ||
51c2b9d1 TG |
883 | (define_insn "" |
884 | [(set (match_operand:SI 0 "register_operand" "=r") | |
907f67cc | 885 | (match_operand:SI 1 "depi_cint_operand" ""))] |
51c2b9d1 TG |
886 | "" |
887 | "* | |
888 | { | |
876662ef TG |
889 | rtx xoperands[4]; |
890 | xoperands[0] = operands[0]; | |
891 | compute_xdepi_operands_from_integer (INTVAL (operands[1]), xoperands); | |
892 | output_asm_insn (\"zdepi %1,%2,%3,%0\", xoperands); | |
893 | return \"\"; | |
ba0443bb TG |
894 | }" |
895 | [(set_attr "type" "move") | |
896 | (set_attr "length" "1")]) | |
51c2b9d1 | 897 | |
c733e074 | 898 | (define_insn "" |
58939c25 | 899 | [(set (match_operand:SI 0 "register_operand" "=a,&?*r") |
53a66787 | 900 | (plus:SI (match_operand:SI 1 "register_operand" "r,r") |
c733e074 | 901 | (high:SI (match_operand 2 "" ""))))] |
9c36061e | 902 | "!TARGET_KERNEL" |
53a66787 TG |
903 | "@ |
904 | addil L'%G2,%1 | |
905 | ldil L'%G2,%0\;add %0,%1,%0" | |
876662ef | 906 | [(set_attr "type" "binary,binary") |
53a66787 TG |
907 | (set_attr "length" "1,2")]) |
908 | ||
9c36061e JL |
909 | (define_insn "" |
910 | [(set (match_operand:SI 0 "register_operand" "=a") | |
911 | (plus:SI (match_operand:SI 1 "register_operand" "r") | |
912 | (high:SI (match_operand 2 "" ""))))] | |
913 | "TARGET_KERNEL" | |
914 | "@ | |
915 | addil L'%G2,%1" | |
916 | [(set_attr "type" "binary") | |
917 | (set_attr "length" "1")]) | |
918 | ||
53a66787 TG |
919 | (define_split |
920 | [(set (match_operand:SI 0 "register_operand" "") | |
921 | (plus:SI (match_operand:SI 1 "register_operand" "") | |
907f67cc TG |
922 | (high:SI (match_operand 2 "" "")))) |
923 | (clobber (match_scratch:SI 3 ""))] | |
53a66787 | 924 | "reload_completed && REGNO (operands[0]) != 1" |
907f67cc TG |
925 | [(set (match_dup 3) (high:SI (match_dup 2))) |
926 | (set (match_dup 0) (plus:SI (match_dup 3) (match_dup 1)))] | |
53a66787 | 927 | "") |
c733e074 | 928 | |
d2a94ec0 TM |
929 | (define_insn "" |
930 | [(set (match_operand:SI 0 "register_operand" "=r") | |
931 | (high:SI (match_operand:SI 1 "function_label_operand" "")))] | |
932 | "TARGET_SHARED_LIBS" | |
933 | "ldil LP'%G1,%0" | |
934 | [(set_attr "type" "move") | |
935 | (set_attr "length" "1")]) | |
936 | ||
c733e074 TM |
937 | (define_insn "" |
938 | [(set (match_operand:SI 0 "register_operand" "=r") | |
939 | (high:SI (match_operand 1 "" "")))] | |
940 | "check_pic (1)" | |
941 | "ldil L'%G1,%0" | |
942 | [(set_attr "type" "move") | |
943 | (set_attr "length" "1")]) | |
944 | ||
945 | (define_insn "" | |
946 | [(set (match_operand:HI 0 "register_operand" "=r") | |
947 | (high:HI (match_operand 1 "" "")))] | |
948 | "check_pic (1)" | |
949 | "ldil L'%G1,%0" | |
950 | [(set_attr "type" "move") | |
951 | (set_attr "length" "1")]) | |
952 | ||
d2a94ec0 TM |
953 | (define_insn "" |
954 | [(set (match_operand:SI 0 "register_operand" "=r") | |
955 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
956 | (match_operand:SI 2 "function_label_operand" ""))) | |
957 | (clobber (match_operand:SI 3 "register_operand" "=r"))] | |
958 | "TARGET_SHARED_LIBS" | |
959 | "ldo RP'%G2(%1),%0\;extru,= %0,31,1,%3\;ldw -4(%%r27),%3\;add %0,%3,%0" | |
960 | [(set_attr "type" "multi") | |
961 | (set_attr "length" "4")]) | |
962 | ||
c733e074 TM |
963 | (define_insn "" |
964 | [(set (match_operand:SI 0 "register_operand" "=r") | |
965 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
907f67cc | 966 | (match_operand:SI 2 "immediate_operand" "i")))] |
c733e074 TM |
967 | "" |
968 | "ldo R'%G2(%1),%0" | |
969 | ;; Need to set length for this arith insn because operand2 | |
970 | ;; is not an "arith_operand". | |
971 | [(set_attr "length" "1")]) | |
972 | ||
c733e074 TM |
973 | (define_expand "movhi" |
974 | [(set (match_operand:HI 0 "general_operand" "") | |
975 | (match_operand:HI 1 "general_operand" ""))] | |
976 | "" | |
977 | " | |
978 | { | |
d2a94ec0 | 979 | if (emit_move_sequence (operands, HImode, 0)) |
c733e074 TM |
980 | DONE; |
981 | }") | |
982 | ||
983 | (define_insn "" | |
83692f15 JL |
984 | [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q,!*r,!fx,!fx") |
985 | (match_operand:HI 1 "move_operand" "rM,Q,rM,fx,*r,!fx"))] | |
4d72c241 | 986 | "register_operand (operands[0], HImode) |
29ed7081 | 987 | || reg_or_0_operand (operands[1], HImode)" |
c733e074 TM |
988 | "@ |
989 | copy %r1,%0 | |
990 | ldh%M1 %1,%0 | |
d2a94ec0 TM |
991 | sth%M0 %r1,%0 |
992 | fstws %1,-16(30)\;ldw -16(30),%0 | |
993 | stw %1,-16(30)\;fldws -16(30),%0 | |
994 | fcpy,sgl %1,%0" | |
b7a4467d | 995 | [(set_attr "type" "move,load,store,load,fpload,fpalu") |
d2a94ec0 | 996 | (set_attr "length" "1,1,1,2,2,1")]) |
c733e074 TM |
997 | |
998 | (define_insn "" | |
999 | [(set (match_operand:HI 0 "register_operand" "=r") | |
907f67cc TG |
1000 | (match_operand:HI 1 "const_int_operand" ""))] |
1001 | "INT_14_BITS (operands[1]) || (INTVAL (operands[1]) & 0x7ff) == 0" | |
c733e074 TM |
1002 | "* |
1003 | { | |
1004 | if (INT_14_BITS (operands[1])) | |
1005 | return \"ldo %1(0),%0\"; | |
1006 | else | |
1007 | return \"ldil L'%1,%0\"; | |
1008 | }" | |
1009 | [(set_attr "type" "move") | |
1010 | (set_attr "length" "1")]) | |
1011 | ||
57b3a4f1 TG |
1012 | (define_insn "" |
1013 | [(set (match_operand:HI 0 "register_operand" "=r") | |
907f67cc | 1014 | (match_operand:HI 1 "depi_cint_operand" ""))] |
57b3a4f1 TG |
1015 | "" |
1016 | "* | |
1017 | { | |
876662ef TG |
1018 | rtx xoperands[4]; |
1019 | xoperands[0] = operands[0]; | |
1020 | compute_xdepi_operands_from_integer (INTVAL (operands[1]), xoperands); | |
1021 | output_asm_insn (\"zdepi %1,%2,%3,%0\", xoperands); | |
1022 | return \"\"; | |
57b3a4f1 TG |
1023 | }" |
1024 | [(set_attr "type" "move") | |
1025 | (set_attr "length" "1")]) | |
1026 | ||
c733e074 TM |
1027 | (define_insn "" |
1028 | [(set (match_operand:HI 0 "register_operand" "=r") | |
1029 | (lo_sum:HI (match_operand:HI 1 "register_operand" "r") | |
907f67cc | 1030 | (match_operand 2 "immediate_operand" "i")))] |
c733e074 TM |
1031 | "" |
1032 | "ldo R'%G2(%1),%0" | |
1033 | [(set_attr "length" "1")]) | |
1034 | ||
1035 | (define_expand "movqi" | |
1036 | [(set (match_operand:QI 0 "general_operand" "") | |
1037 | (match_operand:QI 1 "general_operand" ""))] | |
1038 | "" | |
1039 | " | |
1040 | { | |
d2a94ec0 | 1041 | if (emit_move_sequence (operands, QImode, 0)) |
c733e074 TM |
1042 | DONE; |
1043 | }") | |
1044 | ||
1045 | (define_insn "" | |
83692f15 JL |
1046 | [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q,!*r,!fx,!fx") |
1047 | (match_operand:QI 1 "move_operand" "rM,Q,rM,fx,*r,fx"))] | |
4d72c241 | 1048 | "register_operand (operands[0], QImode) |
29ed7081 | 1049 | || reg_or_0_operand (operands[1], QImode)" |
c733e074 TM |
1050 | "@ |
1051 | copy %r1,%0 | |
1052 | ldb%M1 %1,%0 | |
d2a94ec0 TM |
1053 | stb%M0 %r1,%0 |
1054 | fstws %1,-16(30)\;ldw -16(30),%0 | |
1055 | stw %1,-16(30)\;fldws -16(30),%0 | |
1056 | fcpy,sgl %1,%0" | |
b7a4467d | 1057 | [(set_attr "type" "move,load,store,load,fpload,fpalu") |
d2a94ec0 | 1058 | (set_attr "length" "1,1,1,2,2,1")]) |
c733e074 TM |
1059 | |
1060 | (define_insn "" | |
1061 | [(set (match_operand:QI 0 "register_operand" "=r") | |
1062 | (match_operand:QI 1 "immediate_operand" "J"))] | |
1063 | "" | |
1064 | "ldo %1(0),%0" | |
1065 | [(set_attr "type" "move") | |
1066 | (set_attr "length" "1")]) | |
1067 | ||
1068 | (define_insn "" | |
1069 | [(set (match_operand:QI 0 "register_operand" "=r") | |
1070 | (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r") | |
907f67cc | 1071 | (match_operand 2 "immediate_operand" "i")) 0))] |
c733e074 TM |
1072 | "" |
1073 | "ldo R'%G2(%1),%0" | |
1074 | [(set_attr "length" "1")]) | |
1075 | ||
d2a94ec0 | 1076 | ;; Sneaky ways of using index modes |
dc4e989c TG |
1077 | ;; We don't use unscaled modes since they can't be used unless we can tell |
1078 | ;; which of the registers is the base and which is the index, due to PA's | |
1079 | ;; idea of segment selection using the top bits of the base register. | |
d2a94ec0 TM |
1080 | |
1081 | (define_insn "" | |
1082 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1083 | (mem:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") | |
1084 | (const_int 4)) | |
1085 | (match_operand:SI 2 "register_operand" "r"))))] | |
5ce4a058 | 1086 | "! TARGET_DISABLE_INDEXING" |
d2a94ec0 | 1087 | "ldwx,s %1(0,%2),%0" |
b7a4467d | 1088 | [(set_attr "type" "load") |
d2a94ec0 TM |
1089 | (set_attr "length" "1")]) |
1090 | ||
dc4e989c TG |
1091 | ; this will never match |
1092 | ;(define_insn "" | |
1093 | ; [(set (match_operand:SI 0 "register_operand" "=r") | |
1094 | ; (mem:SI (match_operand:SI 1 "register_operand" "+r"))) | |
1095 | ; (set (match_dup 1) | |
1096 | ; (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") | |
1097 | ; (const_int 4)) | |
1098 | ; (match_dup 1)))] | |
5ce4a058 | 1099 | ; "! TARGET_DISABLE_INDEXING" |
dc4e989c | 1100 | ; "ldwx,sm %2(0,%1),%0" |
b7a4467d | 1101 | ; [(set_attr "type" "load") |
dc4e989c | 1102 | ; (set_attr "length" "1")]) |
d2a94ec0 TM |
1103 | |
1104 | (define_insn "" | |
1105 | [(set (match_operand:HI 0 "register_operand" "=r") | |
1106 | (mem:HI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") | |
1107 | (const_int 2)) | |
1108 | (match_operand:SI 1 "register_operand" "r"))))] | |
5ce4a058 | 1109 | "! TARGET_DISABLE_INDEXING" |
d2a94ec0 | 1110 | "ldhx,s %2(0,%1),%0" |
b7a4467d | 1111 | [(set_attr "type" "load") |
d2a94ec0 TM |
1112 | (set_attr "length" "1")]) |
1113 | ||
dc4e989c TG |
1114 | ; this will never match |
1115 | ;(define_insn "" | |
1116 | ; [(set (match_operand:HI 0 "register_operand" "=r") | |
1117 | ; (mem:HI (match_operand:SI 1 "register_operand" "+r"))) | |
1118 | ; (set (match_dup 1) | |
1119 | ; (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") | |
1120 | ; (const_int 2)) | |
1121 | ; (match_dup 1)))] | |
5ce4a058 | 1122 | ; "! TARGET_DISABLE_INDEXING" |
dc4e989c | 1123 | ; "ldhx,sm %2(0,%1),%0" |
b7a4467d | 1124 | ; [(set_attr "type" "load") |
dc4e989c | 1125 | ; (set_attr "length" "1")]) |
d2a94ec0 | 1126 | |
c733e074 TM |
1127 | ;; The definition of this insn does not really explain what it does, |
1128 | ;; but it should suffice | |
1129 | ;; that anything generated as this insn will be recognized as one | |
1130 | ;; and that it will not successfully combine with anything. | |
1131 | (define_expand "movstrsi" | |
1132 | [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) | |
1133 | (mem:BLK (match_operand:BLK 1 "general_operand" ""))) | |
1134 | (clobber (match_dup 0)) | |
1135 | (clobber (match_dup 1)) | |
907f67cc TG |
1136 | (clobber (match_dup 4)) |
1137 | (clobber (match_dup 5)) | |
c733e074 TM |
1138 | (use (match_operand:SI 2 "arith_operand" "")) |
1139 | (use (match_operand:SI 3 "const_int_operand" ""))])] | |
1140 | "" | |
1141 | " | |
1142 | { | |
876662ef | 1143 | /* If the blocks are not at least word-aligned and rather big (>16 items), |
c733e074 TM |
1144 | or the size is indeterminate, don't inline the copy code. A |
1145 | procedure call is better since it can check the alignment at | |
1146 | runtime and make the optimal decisions. */ | |
876662ef | 1147 | if (INTVAL (operands[3]) < 4 |
c733e074 TM |
1148 | && (GET_CODE (operands[2]) != CONST_INT |
1149 | || (INTVAL (operands[2]) / INTVAL (operands[3]) > 16))) | |
1150 | FAIL; | |
1151 | ||
1152 | operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); | |
1153 | operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); | |
907f67cc TG |
1154 | operands[4] = gen_reg_rtx (SImode); |
1155 | operands[5] = gen_reg_rtx (SImode); | |
c733e074 TM |
1156 | }") |
1157 | ||
1158 | ;; The operand constraints are written like this to support both compile-time | |
1159 | ;; and run-time determined byte count. If the count is run-time determined, | |
1160 | ;; the register with the byte count is clobbered by the copying code, and | |
1161 | ;; therefore it is forced to operand 2. If the count is compile-time | |
1162 | ;; determined, we need two scratch registers for the unrolled code. | |
1163 | (define_insn "" | |
58939c25 TG |
1164 | [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r")) |
1165 | (mem:BLK (match_operand:SI 1 "register_operand" "+r,r"))) | |
c733e074 TM |
1166 | (clobber (match_dup 0)) |
1167 | (clobber (match_dup 1)) | |
907f67cc TG |
1168 | (clobber (match_operand:SI 2 "register_operand" "=r,r")) ;loop cnt/tmp |
1169 | (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp | |
c733e074 TM |
1170 | (use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count |
1171 | (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment | |
1172 | "" | |
1173 | "* return output_block_move (operands, !which_alternative);" | |
876662ef | 1174 | [(set_attr "type" "multi,multi")]) |
c733e074 TM |
1175 | \f |
1176 | ;; Floating point move insns | |
1177 | ||
1178 | ;; This pattern forces (set (reg:DF ...) (const_double ...)) | |
1179 | ;; to be reloaded by putting the constant into memory. | |
1180 | ;; It must come before the more general movdf pattern. | |
c228001d JL |
1181 | ;; In the 3rd alternative case -- we know we will not be using a |
1182 | ;; general register, so we can be sure length is just 1. | |
c733e074 | 1183 | (define_insn "" |
53a66787 | 1184 | [(set (match_operand:DF 0 "general_operand" "=?r,r,fx") |
c733e074 TM |
1185 | (match_operand:DF 1 "" "?E,G,m"))] |
1186 | "GET_CODE (operands[1]) == CONST_DOUBLE" | |
1187 | "* | |
1188 | { | |
1189 | switch (which_alternative) | |
1190 | { | |
1191 | case 0: | |
1192 | return output_move_double (operands); | |
1193 | case 1: | |
1194 | return \"copy 0,%0\;copy 0,%R0\"; | |
1195 | case 2: | |
1196 | return output_fp_move_double (operands); | |
1197 | } | |
1198 | }" | |
1199 | [(set_attr "type" "load,move,fpload") | |
c228001d | 1200 | (set_attr "length" "3,2,1")]) |
c733e074 TM |
1201 | |
1202 | (define_expand "movdf" | |
1203 | [(set (match_operand:DF 0 "general_operand" "") | |
1204 | (match_operand:DF 1 "general_operand" ""))] | |
1205 | "" | |
1206 | " | |
1207 | { | |
d2a94ec0 | 1208 | if (emit_move_sequence (operands, DFmode, 0)) |
c733e074 TM |
1209 | DONE; |
1210 | }") | |
1211 | ||
1212 | (define_insn "" | |
1213 | [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" | |
83692f15 | 1214 | "=fx,*r,Q,?Q,fx,*&r,?fx,?*r") |
c733e074 | 1215 | (match_operand:DF 1 "reg_or_nonsymb_mem_operand" |
d2a94ec0 TM |
1216 | "fx,*r,fx,*r,Q,Q,*r,fx"))] |
1217 | "register_operand (operands[0], DFmode) | |
1218 | || register_operand (operands[1], DFmode)" | |
c733e074 TM |
1219 | "* |
1220 | { | |
1221 | if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) | |
1222 | return output_fp_move_double (operands); | |
1223 | return output_move_double (operands); | |
1224 | }" | |
b7a4467d | 1225 | [(set_attr "type" "fpalu,move,fpstore,store,fpload,load,fpload,load") |
c733e074 TM |
1226 | (set_attr "length" "1,2,1,2,1,2,3,3")]) |
1227 | ||
1d01c176 TG |
1228 | (define_insn "" |
1229 | [(set (match_operand:DF 0 "register_operand" "=fx") | |
1230 | (mem:DF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") | |
1231 | (const_int 8)) | |
1232 | (match_operand:SI 2 "register_operand" "r"))))] | |
1233 | "! TARGET_DISABLE_INDEXING" | |
1234 | "flddx,s %1(0,%2),%0" | |
1235 | [(set_attr "type" "fpload") | |
1236 | (set_attr "length" "1")]) | |
1237 | ||
1238 | (define_insn "" | |
1239 | [(set (mem:DF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") | |
1240 | (const_int 8)) | |
1241 | (match_operand:SI 2 "register_operand" "r"))) | |
1242 | (match_operand:DF 0 "register_operand" "fx"))] | |
1243 | "! TARGET_DISABLE_INDEXING" | |
1244 | "fstdx,s %0,%1(0,%2)" | |
1245 | [(set_attr "type" "fpstore") | |
1246 | (set_attr "length" "1")]) | |
1247 | ||
c733e074 TM |
1248 | (define_expand "movdi" |
1249 | [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "") | |
1250 | (match_operand:DI 1 "general_operand" ""))] | |
1251 | "" | |
1252 | " | |
1253 | { | |
d2a94ec0 | 1254 | if (emit_move_sequence (operands, DImode, 0)) |
c733e074 TM |
1255 | DONE; |
1256 | }") | |
1257 | ||
d2a94ec0 TM |
1258 | (define_expand "reload_indi" |
1259 | [(set (match_operand:DI 0 "register_operand" "=z") | |
1260 | (match_operand:DI 1 "general_operand" "")) | |
1261 | (clobber (match_operand:SI 2 "register_operand" "=&r"))] | |
1262 | "" | |
1263 | " | |
1264 | { | |
1265 | if (emit_move_sequence (operands, DImode, operands[2])) | |
1266 | DONE; | |
1267 | ||
1268 | /* We don't want the clobber emitted, so handle this ourselves. */ | |
1269 | emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); | |
1270 | DONE; | |
1271 | }") | |
1272 | ||
1273 | (define_expand "reload_outdi" | |
1274 | [(set (match_operand:DI 0 "general_operand" "") | |
1275 | (match_operand:DI 1 "register_operand" "z")) | |
1276 | (clobber (match_operand:SI 2 "register_operand" "=&r"))] | |
1277 | "" | |
1278 | " | |
1279 | { | |
1280 | if (emit_move_sequence (operands, DImode, operands[2])) | |
1281 | DONE; | |
1282 | ||
1283 | /* We don't want the clobber emitted, so handle this ourselves. */ | |
1284 | emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); | |
1285 | DONE; | |
1286 | }") | |
1287 | ||
53a66787 TG |
1288 | (define_insn "" |
1289 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1290 | (high:DI (match_operand 1 "" "")))] | |
1291 | "check_pic (1)" | |
1292 | "* | |
1293 | { | |
1294 | rtx op0 = operands[0]; | |
1295 | rtx op1 = operands[1]; | |
1296 | ||
1297 | if (GET_CODE (op1) == CONST_INT) | |
1298 | { | |
1299 | operands[0] = operand_subword (op0, 1, 0, DImode); | |
1300 | output_asm_insn (\"ldil L'%1,%0\", operands); | |
1301 | ||
1302 | operands[0] = operand_subword (op0, 0, 0, DImode); | |
1303 | if (INTVAL (op1) < 0) | |
1304 | output_asm_insn (\"ldo -1(0),%0\", operands); | |
1305 | else | |
1306 | output_asm_insn (\"ldo 0(0),%0\", operands); | |
876662ef | 1307 | return \"\"; |
53a66787 TG |
1308 | } |
1309 | else if (GET_CODE (op1) == CONST_DOUBLE) | |
1310 | { | |
1311 | operands[0] = operand_subword (op0, 1, 0, DImode); | |
1312 | operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1)); | |
1313 | output_asm_insn (\"ldil L'%1,%0\", operands); | |
1314 | ||
1315 | operands[0] = operand_subword (op0, 0, 0, DImode); | |
1316 | operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1)); | |
1317 | output_asm_insn (singlemove_string (operands), operands); | |
876662ef | 1318 | return \"\"; |
53a66787 TG |
1319 | } |
1320 | else | |
1321 | abort (); | |
1322 | }" | |
1323 | [(set_attr "type" "move") | |
1324 | (set_attr "length" "2")]) | |
1325 | ||
d2a94ec0 TM |
1326 | ;;; Experimental |
1327 | ||
1328 | (define_insn "" | |
1329 | [(set (match_operand:DI 0 "fp_reg_operand" "=fx") | |
1330 | (match_operand:DI 1 "short_memory_operand" "T"))] | |
1331 | "" | |
1332 | "fldds%F1 %1,%0" | |
1333 | [(set_attr "type" "fpload") | |
1334 | (set_attr "length" "1")]) | |
1335 | ||
1336 | (define_insn "" | |
1337 | [(set (match_operand:DI 0 "short_memory_operand" "=T") | |
1338 | (match_operand:DI 1 "fp_reg_operand" "fx"))] | |
1339 | "" | |
1340 | "fstds%F0 %1,%0" | |
1341 | [(set_attr "type" "fpstore") | |
1342 | (set_attr "length" "1")]) | |
1343 | ||
c733e074 TM |
1344 | (define_insn "" |
1345 | [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" | |
83692f15 | 1346 | "=r,Q,&r,&r,fx,fx,*r") |
c733e074 | 1347 | (match_operand:DI 1 "general_operand" |
83692f15 | 1348 | "r,r,Q,i,*r,fx,fx"))] |
4d72c241 | 1349 | "register_operand (operands[0], DImode) |
29ed7081 | 1350 | || reg_or_0_operand (operands[1], DImode)" |
c733e074 TM |
1351 | "* |
1352 | { | |
1353 | if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) | |
1354 | return output_fp_move_double (operands); | |
1355 | return output_move_double (operands); | |
1356 | }" | |
b7a4467d JL |
1357 | ;; Use move in the last type.. This case happens often with xmpyu |
1358 | ;; and in nearly all cases we only access the data from the first | |
1359 | ;; of the two loads generated, and that can't stall on a data conflict | |
fc6cef11 | 1360 | ;; because of the second load. |
b7a4467d JL |
1361 | [(set_attr "type" "move,store,load,misc,fpload,fpalu,move") |
1362 | (set_attr "length" "2,3,3,3,3,1,3")]) | |
c733e074 | 1363 | |
53a66787 TG |
1364 | (define_insn "" |
1365 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
1366 | (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r") | |
907f67cc | 1367 | (match_operand:DI 2 "immediate_operand" "i,i")))] |
53a66787 TG |
1368 | "" |
1369 | "* | |
1370 | { | |
1371 | /* Don't output a 64 bit constant, since we can't trust the assembler to | |
1372 | handle it correctly. */ | |
1373 | if (GET_CODE (operands[2]) == CONST_DOUBLE) | |
1374 | operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2])); | |
1375 | if (which_alternative == 1) | |
1376 | output_asm_insn (\"copy %1,%0\", operands); | |
1377 | return \"ldo R'%G2(%R1),%R0\"; | |
1378 | }" | |
1379 | ;; Need to set length for this arith insn because operand2 | |
1380 | ;; is not an "arith_operand". | |
1381 | [(set_attr "length" "1,2")]) | |
1382 | ||
c733e074 TM |
1383 | (define_expand "movsf" |
1384 | [(set (match_operand:SF 0 "general_operand" "") | |
1385 | (match_operand:SF 1 "general_operand" ""))] | |
1386 | "" | |
1387 | " | |
1388 | { | |
d2a94ec0 | 1389 | if (emit_move_sequence (operands, SFmode, 0)) |
c733e074 TM |
1390 | DONE; |
1391 | }") | |
1392 | ||
1393 | (define_insn "" | |
1394 | [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" | |
83692f15 | 1395 | "=fx,r,*r,fx,fx,r,Q,Q") |
c733e074 | 1396 | (match_operand:SF 1 "reg_or_nonsymb_mem_operand" |
83692f15 | 1397 | "fx,r,!fx,!*r,Q,Q,fx,r"))] |
4d72c241 JL |
1398 | "register_operand (operands[0], SFmode) |
1399 | || register_operand (operands[1], SFmode)" | |
c733e074 | 1400 | "@ |
57b3a4f1 | 1401 | fcpy,sgl %1,%0 |
c733e074 TM |
1402 | copy %1,%0 |
1403 | fstws %1,-16(0,30)\;ldw -16(0,30),%0 | |
1404 | stw %r1,-16(0,30)\;fldws -16(0,30),%0 | |
1405 | fldws%F1 %1,%0 | |
1406 | ldw%M1 %1,%0 | |
1407 | fstws%F0 %r1,%0 | |
1408 | stw%M0 %r1,%0" | |
b7a4467d | 1409 | [(set_attr "type" "fpalu,move,load,fpload,fpload,load,fpstore,store") |
c733e074 | 1410 | (set_attr "length" "1,1,2,2,1,1,1,1")]) |
1d01c176 TG |
1411 | |
1412 | (define_insn "" | |
1413 | [(set (match_operand:SF 0 "register_operand" "=fx") | |
1414 | (mem:SF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") | |
1415 | (const_int 4)) | |
1416 | (match_operand:SI 2 "register_operand" "r"))))] | |
1417 | "! TARGET_DISABLE_INDEXING" | |
1418 | "fldwx,s %1(0,%2),%0" | |
1419 | [(set_attr "type" "fpload") | |
1420 | (set_attr "length" "1")]) | |
1421 | ||
1422 | (define_insn "" | |
1423 | [(set (mem:SF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") | |
1424 | (const_int 4)) | |
1425 | (match_operand:SI 2 "register_operand" "r"))) | |
1426 | (match_operand:SF 0 "register_operand" "fx"))] | |
1427 | "! TARGET_DISABLE_INDEXING" | |
1428 | "fstwx,s %0,%1(0,%2)" | |
1429 | [(set_attr "type" "fpstore") | |
1430 | (set_attr "length" "1")]) | |
c733e074 TM |
1431 | \f |
1432 | ;;- zero extension instructions | |
1433 | ||
1434 | ;; Note that the one starting from HImode comes before those for QImode | |
1435 | ;; so that a constant operand will match HImode, not QImode. | |
1436 | ||
1437 | (define_expand "zero_extendhisi2" | |
1438 | [(set (match_operand:SI 0 "register_operand" "") | |
1439 | (zero_extend:SI | |
1440 | (match_operand:HI 1 "general_operand" "")))] | |
1441 | "" | |
1442 | " | |
1443 | { | |
1444 | if (GET_CODE (operand1) == MEM | |
1445 | && symbolic_operand (XEXP (operand1, 0), Pmode)) | |
1446 | { | |
1447 | rtx temp = copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode, | |
1448 | XEXP (operand1, 0))); | |
1449 | operands[1] = gen_rtx (MEM, HImode, | |
1450 | gen_rtx (LO_SUM, Pmode, | |
1451 | temp, XEXP (operand1, 0))); | |
1452 | } | |
1453 | }") | |
1454 | ||
1455 | (define_insn "" | |
1456 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1457 | (zero_extend:SI | |
1458 | (match_operand:HI 1 "reg_or_nonsymb_mem_operand" "r,Q")))] | |
1459 | "" | |
1460 | "@ | |
1461 | extru %1,31,16,%0 | |
1462 | ldh%M1 %1,%0" | |
1463 | [(set_attr "type" "unary,load")]) | |
1464 | ||
1465 | (define_expand "zero_extendqihi2" | |
1466 | [(set (match_operand:HI 0 "register_operand" "") | |
1467 | (zero_extend:HI | |
1468 | (match_operand:QI 1 "general_operand" "")))] | |
1469 | "" | |
1470 | " | |
1471 | { | |
1472 | if (GET_CODE (operand1) == MEM | |
1473 | && symbolic_operand (XEXP (operand1, 0), Pmode)) | |
1474 | { | |
1475 | rtx temp = copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode, | |
1476 | XEXP (operand1, 0))); | |
1477 | operands[1] = gen_rtx (MEM, QImode, | |
1478 | gen_rtx (LO_SUM, Pmode, | |
1479 | temp, XEXP (operand1, 0))); | |
1480 | } | |
1481 | }") | |
1482 | ||
1483 | (define_insn "" | |
1484 | [(set (match_operand:HI 0 "register_operand" "=r,r") | |
1485 | (zero_extend:HI | |
1486 | (match_operand:QI 1 "reg_or_nonsymb_mem_operand" "r,Q")))] | |
1487 | "" | |
1488 | "@ | |
1489 | extru %1,31,8,%0 | |
1490 | ldb%M1 %1,%0" | |
1491 | [(set_attr "type" "unary,load") | |
876662ef | 1492 | (set_attr "length" "1,1")]) |
c733e074 TM |
1493 | |
1494 | (define_expand "zero_extendqisi2" | |
1495 | [(set (match_operand:SI 0 "register_operand" "") | |
1496 | (zero_extend:SI | |
1497 | (match_operand:QI 1 "general_operand" "")))] | |
1498 | "" | |
1499 | " | |
1500 | { | |
1501 | if (GET_CODE (operand1) == MEM | |
1502 | && symbolic_operand (XEXP (operand1, 0), Pmode)) | |
1503 | { | |
1504 | rtx temp = copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode, | |
1505 | XEXP (operand1, 0))); | |
1506 | operand1 = gen_rtx (MEM, QImode, | |
1507 | gen_rtx (LO_SUM, Pmode, | |
1508 | temp, XEXP (operand1, 0))); | |
1509 | emit_insn (gen_rtx (SET, VOIDmode, operand0, | |
1510 | gen_rtx (ZERO_EXTEND, SImode, operand1))); | |
1511 | DONE; | |
1512 | } | |
1513 | }") | |
1514 | ||
1515 | (define_insn "" | |
1516 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1517 | (zero_extend:SI | |
1518 | (match_operand:QI 1 "reg_or_nonsymb_mem_operand" "r,Q")))] | |
1519 | "" | |
1520 | "@ | |
1521 | extru %1,31,8,%0 | |
1522 | ldb%M1 %1,%0" | |
1523 | [(set_attr "type" "unary,load") | |
876662ef | 1524 | (set_attr "length" "1,1")]) |
c733e074 TM |
1525 | \f |
1526 | ;;- sign extension instructions | |
1527 | ;; Note that the one starting from HImode comes before those for QImode | |
1528 | ;; so that a constant operand will match HImode, not QImode. | |
1529 | ||
1530 | (define_insn "extendhisi2" | |
1531 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1532 | (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))] | |
1533 | "" | |
1534 | "extrs %1,31,16,%0" | |
1535 | [(set_attr "type" "unary")]) | |
1536 | ||
1537 | (define_insn "extendqihi2" | |
1538 | [(set (match_operand:HI 0 "register_operand" "=r") | |
1539 | (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))] | |
1540 | "" | |
1541 | "extrs %1,31,8,%0" | |
1542 | [(set_attr "type" "unary")]) | |
1543 | ||
1544 | (define_insn "extendqisi2" | |
1545 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1546 | (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))] | |
1547 | "" | |
1548 | "extrs %1,31,8,%0" | |
1549 | [(set_attr "type" "unary")]) | |
1550 | \f | |
1551 | ;; Conversions between float and double. | |
1552 | ||
1553 | (define_insn "extendsfdf2" | |
53a66787 | 1554 | [(set (match_operand:DF 0 "register_operand" "=fx") |
c733e074 | 1555 | (float_extend:DF |
53a66787 | 1556 | (match_operand:SF 1 "register_operand" "fx")))] |
c733e074 TM |
1557 | "" |
1558 | "fcnvff,sgl,dbl %1,%0" | |
1559 | [(set_attr "type" "fpalu")]) | |
1560 | ||
1561 | (define_insn "truncdfsf2" | |
53a66787 | 1562 | [(set (match_operand:SF 0 "register_operand" "=fx") |
c733e074 | 1563 | (float_truncate:SF |
53a66787 | 1564 | (match_operand:DF 1 "register_operand" "fx")))] |
c733e074 TM |
1565 | "" |
1566 | "fcnvff,dbl,sgl %1,%0" | |
1567 | [(set_attr "type" "fpalu")]) | |
1568 | ||
1569 | ;; Conversion between fixed point and floating point. | |
1570 | ;; Note that among the fix-to-float insns | |
1571 | ;; the ones that start with SImode come first. | |
1572 | ;; That is so that an operand that is a CONST_INT | |
1573 | ;; (and therefore lacks a specific machine mode). | |
1574 | ;; will be recognized as SImode (which is always valid) | |
1575 | ;; rather than as QImode or HImode. | |
1576 | ||
1577 | ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...))) | |
1578 | ;; to be reloaded by putting the constant into memory. | |
1579 | ;; It must come before the more general floatsisf2 pattern. | |
c228001d JL |
1580 | ;; Note length will always be 2 since we know we are loading |
1581 | ;; operand 1 from memory and the target is a FP register. | |
c733e074 | 1582 | (define_insn "" |
53a66787 | 1583 | [(set (match_operand:SF 0 "general_operand" "=fx") |
c733e074 TM |
1584 | (float:SF (match_operand:SI 1 "const_int_operand" "m")))] |
1585 | "" | |
cb524f44 | 1586 | "fldws %1,%0\;fcnvxf,sgl,sgl %0,%0" |
c733e074 | 1587 | [(set_attr "type" "fpalu") |
c228001d | 1588 | (set_attr "length" "2")]) |
c733e074 | 1589 | |
c228001d JL |
1590 | ;; Note length will always be 1 since we only allow FP registers |
1591 | ;; for the source and target. | |
c733e074 | 1592 | (define_insn "floatsisf2" |
53a66787 | 1593 | [(set (match_operand:SF 0 "general_operand" "=fx") |
7e985738 | 1594 | (float:SF (match_operand:SI 1 "register_operand" "fx")))] |
c733e074 | 1595 | "" |
cb524f44 | 1596 | "fcnvxf,sgl,sgl %1,%0" |
c733e074 | 1597 | [(set_attr "type" "fpalu") |
c228001d | 1598 | (set_attr "length" "1")]) |
c733e074 TM |
1599 | |
1600 | ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...))) | |
1601 | ;; to be reloaded by putting the constant into memory. | |
1602 | ;; It must come before the more general floatsidf2 pattern. | |
c228001d JL |
1603 | ;; Note length will always be 2 since we know we are loading |
1604 | ;; operand 1 from memory and the target is a FP register. | |
c733e074 | 1605 | (define_insn "" |
53a66787 | 1606 | [(set (match_operand:DF 0 "general_operand" "=fx") |
c733e074 TM |
1607 | (float:DF (match_operand:SI 1 "const_int_operand" "m")))] |
1608 | "" | |
cb524f44 | 1609 | "fldws %1,%0\;fcnvxf,sgl,dbl %0,%0" |
c733e074 | 1610 | [(set_attr "type" "fpalu") |
c228001d | 1611 | (set_attr "length" "2")]) |
c733e074 | 1612 | |
c228001d JL |
1613 | ;; Note length will always be 1 since we only allow FP registers |
1614 | ;; for the source and target. | |
c733e074 | 1615 | (define_insn "floatsidf2" |
53a66787 | 1616 | [(set (match_operand:DF 0 "general_operand" "=fx") |
7e985738 | 1617 | (float:DF (match_operand:SI 1 "register_operand" "fx")))] |
c733e074 | 1618 | "" |
cb524f44 TG |
1619 | "fcnvxf,sgl,dbl %1,%0" |
1620 | [(set_attr "type" "fpalu") | |
1621 | (set_attr "length" "1")]) | |
1622 | ||
1623 | (define_expand "floatunssisf2" | |
1624 | [(set (subreg:SI (match_dup 2) 1) | |
1625 | (match_operand:SI 1 "register_operand" "")) | |
1626 | (set (subreg:SI (match_dup 2) 0) | |
1627 | (const_int 0)) | |
1628 | (set (match_operand:SF 0 "general_operand" "") | |
1629 | (float:SF (match_dup 2)))] | |
1630 | "" | |
1631 | "operands[2] = gen_reg_rtx (DImode);") | |
1632 | ||
1633 | (define_expand "floatunssidf2" | |
1634 | [(set (subreg:SI (match_dup 2) 1) | |
1635 | (match_operand:SI 1 "register_operand" "")) | |
1636 | (set (subreg:SI (match_dup 2) 0) | |
1637 | (const_int 0)) | |
1638 | (set (match_operand:DF 0 "general_operand" "") | |
1639 | (float:DF (match_dup 2)))] | |
1640 | "" | |
1641 | "operands[2] = gen_reg_rtx (DImode);") | |
1642 | ||
1643 | (define_insn "floatdisf2" | |
1644 | [(set (match_operand:SF 0 "general_operand" "=fx") | |
1645 | (float:SF (match_operand:DI 1 "register_operand" "fx")))] | |
1646 | "" | |
1647 | "fcnvxf,dbl,sgl %1,%0" | |
1648 | [(set_attr "type" "fpalu") | |
1649 | (set_attr "length" "1")]) | |
1650 | ||
1651 | (define_insn "floatdidf2" | |
1652 | [(set (match_operand:DF 0 "general_operand" "=fx") | |
1653 | (float:DF (match_operand:DI 1 "register_operand" "fx")))] | |
1654 | "" | |
1655 | "fcnvxf,dbl,dbl %1,%0" | |
c733e074 | 1656 | [(set_attr "type" "fpalu") |
c228001d | 1657 | (set_attr "length" "1")]) |
c733e074 TM |
1658 | |
1659 | ;; Convert a float to an actual integer. | |
1660 | ;; Truncation is performed as part of the conversion. | |
1661 | ||
1662 | (define_insn "fix_truncsfsi2" | |
53a66787 TG |
1663 | [(set (match_operand:SI 0 "register_operand" "=r,fx") |
1664 | (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "fx,fx")))) | |
1665 | (clobber (match_scratch:SI 2 "=&fx,X"))] | |
c733e074 TM |
1666 | "" |
1667 | "@ | |
1668 | fcnvfxt,sgl,sgl %1,%2\;fstws %2,-16(30)\;ldw -16(30),%0 | |
1669 | fcnvfxt,sgl,sgl %1,%0" | |
1670 | [(set_attr "type" "fpalu,fpalu") | |
1671 | (set_attr "length" "3,1")]) | |
1672 | ||
1673 | (define_insn "fix_truncdfsi2" | |
53a66787 TG |
1674 | [(set (match_operand:SI 0 "register_operand" "=r,fx") |
1675 | (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "fx,fx")))) | |
1676 | (clobber (match_scratch:SI 2 "=&fx,X"))] | |
c733e074 TM |
1677 | "" |
1678 | "@ | |
1679 | fcnvfxt,dbl,sgl %1,%2\;fstws %2,-16(30)\;ldw -16(30),%0 | |
1680 | fcnvfxt,dbl,sgl %1,%0" | |
1681 | [(set_attr "type" "fpalu,fpalu") | |
1682 | (set_attr "length" "3,1")]) | |
1683 | ||
cb524f44 TG |
1684 | (define_insn "fix_truncsfdi2" |
1685 | [(set (match_operand:DI 0 "register_operand" "=fx") | |
1686 | (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "fx"))))] | |
1687 | "" | |
1688 | "fcnvfxt,sgl,dbl %1,%0" | |
1689 | [(set_attr "type" "fpalu") | |
1690 | (set_attr "length" "1")]) | |
1691 | ||
1692 | (define_insn "fix_truncdfdi2" | |
1693 | [(set (match_operand:DI 0 "register_operand" "=fx") | |
1694 | (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "fx"))))] | |
1695 | "" | |
1696 | "fcnvfxt,dbl,dbl %1,%0" | |
1697 | [(set_attr "type" "fpalu") | |
1698 | (set_attr "length" "1")]) | |
c733e074 TM |
1699 | \f |
1700 | ;;- arithmetic instructions | |
1701 | ||
1702 | (define_insn "adddi3" | |
1703 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1704 | (plus:DI (match_operand:DI 1 "register_operand" "%r") | |
876662ef | 1705 | (match_operand:DI 2 "arith11_operand" "rI")))] |
c733e074 | 1706 | "" |
876662ef TG |
1707 | "* |
1708 | { | |
1709 | if (GET_CODE (operands[2]) == CONST_INT) | |
1710 | { | |
1711 | if (INTVAL (operands[2]) >= 0) | |
1a72c2b7 | 1712 | return \"addi %2,%R1,%R0\;addc %1,0,%0\"; |
876662ef | 1713 | else |
1a72c2b7 | 1714 | return \"addi %2,%R1,%R0\;subb %1,0,%0\"; |
876662ef TG |
1715 | } |
1716 | else | |
1717 | return \"add %R2,%R1,%R0\;addc %2,%1,%0\"; | |
1718 | }" | |
1719 | [(set_attr "length" "2")]) | |
c733e074 TM |
1720 | |
1721 | (define_insn "addsi3" | |
1722 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1723 | (plus:SI (match_operand:SI 1 "register_operand" "%r,r") | |
1724 | (match_operand:SI 2 "arith_operand" "r,J")))] | |
1725 | "" | |
1726 | "@ | |
1727 | add %1,%2,%0 | |
1728 | ldo %2(%1),%0") | |
1729 | ||
1730 | (define_insn "subdi3" | |
1731 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1732 | (minus:DI (match_operand:DI 1 "register_operand" "r") | |
1733 | (match_operand:DI 2 "register_operand" "r")))] | |
1734 | "" | |
1735 | "sub %R1,%R2,%R0\;subb %1,%2,%0" | |
1736 | [(set_attr "length" "2")]) | |
1737 | ||
c733e074 TM |
1738 | (define_insn "subsi3" |
1739 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1740 | (minus:SI (match_operand:SI 1 "arith11_operand" "r,I") | |
1741 | (match_operand:SI 2 "register_operand" "r,r")))] | |
1742 | "" | |
1743 | "@ | |
1744 | sub %1,%2,%0 | |
1745 | subi %1,%2,%0") | |
1746 | ||
29ed7081 JL |
1747 | ;; Clobbering a "register_operand" instead of a match_scratch |
1748 | ;; in operand3 of millicode calls avoids spilling %r1 and | |
1749 | ;; produces better code. | |
c733e074 | 1750 | |
29ed7081 | 1751 | ;; The mulsi3 insns set up registers for the millicode call. |
c733e074 | 1752 | (define_expand "mulsi3" |
dc4e989c TG |
1753 | [(set (reg:SI 26) (match_operand:SI 1 "srcsi_operand" "")) |
1754 | (set (reg:SI 25) (match_operand:SI 2 "srcsi_operand" "")) | |
c733e074 | 1755 | (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) |
29ed7081 | 1756 | (clobber (match_operand:SI 3 "register_operand" "")) |
c733e074 TM |
1757 | (clobber (reg:SI 26)) |
1758 | (clobber (reg:SI 25)) | |
1759 | (clobber (reg:SI 31))]) | |
1760 | (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] | |
1761 | "" | |
d2a94ec0 TM |
1762 | " |
1763 | { | |
5ce4a058 | 1764 | if (TARGET_SNAKE && ! TARGET_DISABLE_FPREGS) |
d2a94ec0 TM |
1765 | { |
1766 | rtx scratch = gen_reg_rtx (DImode); | |
dc4e989c TG |
1767 | operands[1] = force_reg (SImode, operands[1]); |
1768 | operands[2] = force_reg (SImode, operands[2]); | |
d2a94ec0 TM |
1769 | emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2])); |
1770 | emit_insn (gen_rtx (SET, VOIDmode, | |
1771 | operands[0], | |
1772 | gen_rtx (SUBREG, SImode, scratch, 1))); | |
1773 | DONE; | |
1774 | } | |
29ed7081 | 1775 | operands[3] = gen_reg_rtx(SImode); |
d2a94ec0 TM |
1776 | }") |
1777 | ||
1778 | (define_insn "umulsidi3" | |
1779 | [(set (match_operand:DI 0 "register_operand" "=x") | |
1780 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "x")) | |
1781 | (zero_extend:DI (match_operand:SI 2 "register_operand" "x"))))] | |
5ce4a058 | 1782 | "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS" |
d2a94ec0 TM |
1783 | "xmpyu %1,%2,%0" |
1784 | [(set_attr "type" "fpmul")]) | |
c733e074 TM |
1785 | |
1786 | (define_insn "" | |
1787 | [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) | |
29ed7081 | 1788 | (clobber (match_operand:SI 0 "register_operand" "=a")) |
c733e074 TM |
1789 | (clobber (reg:SI 26)) |
1790 | (clobber (reg:SI 25)) | |
1791 | (clobber (reg:SI 31))] | |
1792 | "" | |
1793 | "* return output_mul_insn (0);" | |
1794 | [(set_attr "type" "milli")]) | |
1795 | ||
1796 | ;;; Division and mod. | |
c733e074 TM |
1797 | (define_expand "divsi3" |
1798 | [(set (reg:SI 26) (match_operand:SI 1 "srcsi_operand" "")) | |
1799 | (set (reg:SI 25) (match_operand:SI 2 "srcsi_operand" "")) | |
1800 | (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25))) | |
29ed7081 | 1801 | (clobber (match_operand:SI 3 "register_operand" "")) |
c733e074 TM |
1802 | (clobber (reg:SI 26)) |
1803 | (clobber (reg:SI 25)) | |
1804 | (clobber (reg:SI 31))]) | |
1805 | (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] | |
1806 | "" | |
1807 | " | |
1808 | { | |
29ed7081 | 1809 | operands[3] = gen_reg_rtx(SImode); |
c733e074 TM |
1810 | if (!(GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const(operands, 0))) |
1811 | { | |
1812 | emit_move_insn (gen_rtx (REG, SImode, 26), operands[1]); | |
1813 | emit_move_insn (gen_rtx (REG, SImode, 25), operands[2]); | |
1814 | emit | |
1815 | (gen_rtx | |
1816 | (PARALLEL, VOIDmode, | |
1817 | gen_rtvec (5, gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 29), | |
1818 | gen_rtx (DIV, SImode, | |
1819 | gen_rtx (REG, SImode, 26), | |
1820 | gen_rtx (REG, SImode, 25))), | |
29ed7081 | 1821 | gen_rtx (CLOBBER, VOIDmode, operands[3]), |
c733e074 TM |
1822 | gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)), |
1823 | gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)), | |
1824 | gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31))))); | |
1825 | emit_move_insn (operands[0], gen_rtx (REG, SImode, 29)); | |
1826 | } | |
1827 | DONE; | |
1828 | }") | |
1829 | ||
1830 | (define_insn "" | |
1831 | [(set (reg:SI 29) | |
1832 | (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" ""))) | |
29ed7081 | 1833 | (clobber (match_operand:SI 1 "register_operand" "=a")) |
c733e074 TM |
1834 | (clobber (reg:SI 26)) |
1835 | (clobber (reg:SI 25)) | |
1836 | (clobber (reg:SI 31))] | |
1837 | "" | |
1838 | "* | |
1839 | return output_div_insn (operands, 0);" | |
1840 | [(set_attr "type" "milli")]) | |
1841 | ||
1842 | (define_expand "udivsi3" | |
1843 | [(set (reg:SI 26) (match_operand:SI 1 "srcsi_operand" "")) | |
1844 | (set (reg:SI 25) (match_operand:SI 2 "srcsi_operand" "")) | |
1845 | (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25))) | |
29ed7081 | 1846 | (clobber (match_operand:SI 3 "register_operand" "")) |
c733e074 TM |
1847 | (clobber (reg:SI 26)) |
1848 | (clobber (reg:SI 25)) | |
1849 | (clobber (reg:SI 31))]) | |
1850 | (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] | |
1851 | "" | |
1852 | " | |
1853 | { | |
29ed7081 | 1854 | operands[3] = gen_reg_rtx(SImode); |
c733e074 TM |
1855 | if (!(GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const(operands, 1))) |
1856 | { | |
1857 | emit_move_insn (gen_rtx (REG, SImode, 26), operands[1]); | |
1858 | emit_move_insn (gen_rtx (REG, SImode, 25), operands[2]); | |
1859 | emit | |
1860 | (gen_rtx | |
1861 | (PARALLEL, VOIDmode, | |
1862 | gen_rtvec (5, gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 29), | |
1863 | gen_rtx (UDIV, SImode, | |
1864 | gen_rtx (REG, SImode, 26), | |
1865 | gen_rtx (REG, SImode, 25))), | |
29ed7081 | 1866 | gen_rtx (CLOBBER, VOIDmode, operands[3]), |
c733e074 TM |
1867 | gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)), |
1868 | gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)), | |
1869 | gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31))))); | |
1870 | emit_move_insn (operands[0], gen_rtx (REG, SImode, 29)); | |
1871 | } | |
1872 | DONE; | |
1873 | }") | |
1874 | ||
1875 | (define_insn "" | |
1876 | [(set (reg:SI 29) | |
1877 | (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" ""))) | |
29ed7081 | 1878 | (clobber (match_operand:SI 1 "register_operand" "=a")) |
c733e074 TM |
1879 | (clobber (reg:SI 26)) |
1880 | (clobber (reg:SI 25)) | |
1881 | (clobber (reg:SI 31))] | |
1882 | "" | |
1883 | "* | |
1884 | return output_div_insn (operands, 1);" | |
1885 | [(set_attr "type" "milli")]) | |
1886 | ||
1887 | (define_expand "modsi3" | |
1888 | [(set (reg:SI 26) (match_operand:SI 1 "srcsi_operand" "")) | |
1889 | (set (reg:SI 25) (match_operand:SI 2 "srcsi_operand" "")) | |
1890 | (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25))) | |
29ed7081 | 1891 | (clobber (match_operand:SI 3 "register_operand" "")) |
c733e074 TM |
1892 | (clobber (reg:SI 26)) |
1893 | (clobber (reg:SI 25)) | |
1894 | (clobber (reg:SI 31))]) | |
1895 | (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] | |
1896 | "" | |
1897 | " | |
1898 | { | |
29ed7081 | 1899 | operands[3] = gen_reg_rtx(SImode); |
c733e074 TM |
1900 | emit_move_insn (gen_rtx (REG, SImode, 26), operands[1]); |
1901 | emit_move_insn (gen_rtx (REG, SImode, 25), operands[2]); | |
1902 | emit | |
1903 | (gen_rtx | |
1904 | (PARALLEL, VOIDmode, | |
1905 | gen_rtvec (5, gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 29), | |
1906 | gen_rtx (MOD, SImode, | |
1907 | gen_rtx (REG, SImode, 26), | |
1908 | gen_rtx (REG, SImode, 25))), | |
29ed7081 | 1909 | gen_rtx (CLOBBER, VOIDmode, operands[3]), |
c733e074 TM |
1910 | gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)), |
1911 | gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)), | |
1912 | gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31))))); | |
1913 | emit_move_insn (operands[0], gen_rtx (REG, SImode, 29)); | |
1914 | DONE; | |
1915 | }") | |
876662ef | 1916 | |
c733e074 TM |
1917 | (define_insn "" |
1918 | [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25))) | |
29ed7081 | 1919 | (clobber (match_operand:SI 0 "register_operand" "=a")) |
c733e074 TM |
1920 | (clobber (reg:SI 26)) |
1921 | (clobber (reg:SI 25)) | |
1922 | (clobber (reg:SI 31))] | |
1923 | "" | |
1924 | "* | |
1925 | return output_mod_insn (0);" | |
1926 | [(set_attr "type" "milli")]) | |
1927 | ||
1928 | (define_expand "umodsi3" | |
1929 | [(set (reg:SI 26) (match_operand:SI 1 "srcsi_operand" "")) | |
1930 | (set (reg:SI 25) (match_operand:SI 2 "srcsi_operand" "")) | |
1931 | (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25))) | |
29ed7081 | 1932 | (clobber (match_operand:SI 3 "register_operand" "")) |
c733e074 TM |
1933 | (clobber (reg:SI 26)) |
1934 | (clobber (reg:SI 25)) | |
1935 | (clobber (reg:SI 31))]) | |
1936 | (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] | |
1937 | "" | |
1938 | " | |
1939 | { | |
29ed7081 | 1940 | operands[3] = gen_reg_rtx(SImode); |
c733e074 TM |
1941 | emit_move_insn (gen_rtx (REG, SImode, 26), operands[1]); |
1942 | emit_move_insn (gen_rtx (REG, SImode, 25), operands[2]); | |
1943 | emit | |
1944 | (gen_rtx | |
1945 | (PARALLEL, VOIDmode, | |
1946 | gen_rtvec (5, gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 29), | |
1947 | gen_rtx (UMOD, SImode, | |
1948 | gen_rtx (REG, SImode, 26), | |
1949 | gen_rtx (REG, SImode, 25))), | |
29ed7081 | 1950 | gen_rtx (CLOBBER, VOIDmode, operands[3]), |
c733e074 TM |
1951 | gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)), |
1952 | gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)), | |
1953 | gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31))))); | |
1954 | emit_move_insn (operands[0], gen_rtx (REG, SImode, 29)); | |
1955 | DONE; | |
1956 | }") | |
1957 | ||
1958 | (define_insn "" | |
1959 | [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25))) | |
29ed7081 | 1960 | (clobber (match_operand:SI 0 "register_operand" "=a")) |
c733e074 TM |
1961 | (clobber (reg:SI 26)) |
1962 | (clobber (reg:SI 25)) | |
1963 | (clobber (reg:SI 31))] | |
1964 | "" | |
1965 | "* | |
1966 | return output_mod_insn (1);" | |
1967 | [(set_attr "type" "milli")]) | |
1968 | ||
1969 | ;;- and instructions | |
1970 | ;; We define DImode `and` so with DImode `not` we can get | |
1971 | ;; DImode `andn`. Other combinations are possible. | |
1972 | ||
1973 | (define_expand "anddi3" | |
1974 | [(set (match_operand:DI 0 "register_operand" "") | |
1975 | (and:DI (match_operand:DI 1 "arith_double_operand" "") | |
1976 | (match_operand:DI 2 "arith_double_operand" "")))] | |
1977 | "" | |
1978 | " | |
1979 | { | |
1980 | if (! register_operand (operands[1], DImode) | |
1981 | || ! register_operand (operands[2], DImode)) | |
1982 | /* Let GCC break this into word-at-a-time operations. */ | |
1983 | FAIL; | |
1984 | }") | |
1985 | ||
1986 | (define_insn "" | |
1987 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1988 | (and:DI (match_operand:DI 1 "register_operand" "%r") | |
1989 | (match_operand:DI 2 "register_operand" "r")))] | |
1990 | "" | |
1991 | "and %1,%2,%0\;and %R1,%R2,%R0" | |
1992 | [(set_attr "length" "2")]) | |
1993 | ||
1994 | (define_insn "andsi3" | |
876662ef TG |
1995 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
1996 | (and:SI (match_operand:SI 1 "register_operand" "%r,0") | |
1997 | (match_operand:SI 2 "and_operand" "rO,P")))] | |
c733e074 | 1998 | "" |
907f67cc | 1999 | "* return output_and (operands); ") |
c733e074 TM |
2000 | |
2001 | (define_insn "" | |
2002 | [(set (match_operand:DI 0 "register_operand" "=r") | |
876662ef TG |
2003 | (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) |
2004 | (match_operand:DI 2 "register_operand" "r")))] | |
c733e074 TM |
2005 | "" |
2006 | "andcm %2,%1,%0\;andcm %R2,%R1,%R0" | |
2007 | [(set_attr "length" "2")]) | |
2008 | ||
2009 | (define_insn "" | |
2010 | [(set (match_operand:SI 0 "register_operand" "=r") | |
876662ef TG |
2011 | (and:SI (not:SI (match_operand:SI 1 "register_operand" "r")) |
2012 | (match_operand:SI 2 "register_operand" "r")))] | |
c733e074 | 2013 | "" |
876662ef | 2014 | "andcm %2,%1,%0") |
c733e074 TM |
2015 | |
2016 | (define_expand "iordi3" | |
2017 | [(set (match_operand:DI 0 "register_operand" "") | |
2018 | (ior:DI (match_operand:DI 1 "arith_double_operand" "") | |
2019 | (match_operand:DI 2 "arith_double_operand" "")))] | |
2020 | "" | |
2021 | " | |
2022 | { | |
2023 | if (! register_operand (operands[1], DImode) | |
2024 | || ! register_operand (operands[2], DImode)) | |
2025 | /* Let GCC break this into word-at-a-time operations. */ | |
2026 | FAIL; | |
2027 | }") | |
2028 | ||
2029 | (define_insn "" | |
2030 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2031 | (ior:DI (match_operand:DI 1 "register_operand" "%r") | |
2032 | (match_operand:DI 2 "register_operand" "r")))] | |
2033 | "" | |
2034 | "or %1,%2,%0\;or %R1,%R2,%R0" | |
2035 | [(set_attr "length" "2")]) | |
2036 | ||
2037 | (define_insn "iorsi3" | |
876662ef TG |
2038 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
2039 | (ior:SI (match_operand:SI 1 "register_operand" "%r,0") | |
2040 | (match_operand:SI 2 "ior_operand" "r,n")))] | |
c733e074 | 2041 | "" |
907f67cc | 2042 | "* return output_ior (operands); ") |
c733e074 TM |
2043 | |
2044 | (define_expand "xordi3" | |
2045 | [(set (match_operand:DI 0 "register_operand" "") | |
2046 | (xor:DI (match_operand:DI 1 "arith_double_operand" "") | |
2047 | (match_operand:DI 2 "arith_double_operand" "")))] | |
2048 | "" | |
2049 | " | |
2050 | { | |
2051 | if (! register_operand (operands[1], DImode) | |
2052 | || ! register_operand (operands[2], DImode)) | |
2053 | /* Let GCC break this into word-at-a-time operations. */ | |
2054 | FAIL; | |
2055 | }") | |
2056 | ||
2057 | (define_insn "" | |
2058 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2059 | (xor:DI (match_operand:DI 1 "register_operand" "%r") | |
2060 | (match_operand:DI 2 "register_operand" "r")))] | |
2061 | "" | |
2062 | "xor %1,%2,%0\;xor %R1,%R2,%R0" | |
2063 | [(set_attr "length" "2")]) | |
2064 | ||
2065 | (define_insn "xorsi3" | |
2066 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2067 | (xor:SI (match_operand:SI 1 "register_operand" "%r") | |
2068 | (match_operand:SI 2 "register_operand" "r")))] | |
2069 | "" | |
58939c25 | 2070 | "xor %1,%2,%0") |
c733e074 TM |
2071 | |
2072 | (define_insn "negdi2" | |
2073 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2074 | (neg:DI (match_operand:DI 1 "register_operand" "r")))] | |
2075 | "" | |
2076 | "sub 0,%R1,%R0\;subb 0,%1,%0" | |
2077 | [(set_attr "type" "unary") | |
2078 | (set_attr "length" "2")]) | |
2079 | ||
2080 | (define_insn "negsi2" | |
2081 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2082 | (neg:SI (match_operand:SI 1 "register_operand" "r")))] | |
2083 | "" | |
876662ef | 2084 | "sub 0,%1,%0" |
c733e074 TM |
2085 | [(set_attr "type" "unary")]) |
2086 | ||
2087 | (define_expand "one_cmpldi2" | |
2088 | [(set (match_operand:DI 0 "register_operand" "") | |
2089 | (not:DI (match_operand:DI 1 "arith_double_operand" "")))] | |
2090 | "" | |
2091 | " | |
2092 | { | |
2093 | if (! register_operand (operands[1], DImode)) | |
2094 | FAIL; | |
2095 | }") | |
2096 | ||
2097 | (define_insn "" | |
2098 | [(set (match_operand:DI 0 "register_operand" "=r") | |
876662ef | 2099 | (not:DI (match_operand:DI 1 "register_operand" "r")))] |
c733e074 TM |
2100 | "" |
2101 | "uaddcm 0,%1,%0\;uaddcm 0,%R1,%R0" | |
2102 | [(set_attr "type" "unary") | |
2103 | (set_attr "length" "2")]) | |
2104 | ||
2105 | (define_insn "one_cmplsi2" | |
2106 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2107 | (not:SI (match_operand:SI 1 "register_operand" "r")))] | |
2108 | "" | |
2109 | "uaddcm 0,%1,%0" | |
2110 | [(set_attr "type" "unary")]) | |
2111 | \f | |
2112 | ;; Floating point arithmetic instructions. | |
2113 | ||
2114 | (define_insn "adddf3" | |
53a66787 TG |
2115 | [(set (match_operand:DF 0 "register_operand" "=fx") |
2116 | (plus:DF (match_operand:DF 1 "register_operand" "fx") | |
2117 | (match_operand:DF 2 "register_operand" "fx")))] | |
c733e074 TM |
2118 | "" |
2119 | "fadd,dbl %1,%2,%0" | |
2120 | [(set_attr "type" "fpalu")]) | |
2121 | ||
2122 | (define_insn "addsf3" | |
53a66787 TG |
2123 | [(set (match_operand:SF 0 "register_operand" "=fx") |
2124 | (plus:SF (match_operand:SF 1 "register_operand" "fx") | |
2125 | (match_operand:SF 2 "register_operand" "fx")))] | |
c733e074 TM |
2126 | "" |
2127 | "fadd,sgl %1,%2,%0" | |
2128 | [(set_attr "type" "fpalu")]) | |
2129 | ||
2130 | (define_insn "subdf3" | |
53a66787 TG |
2131 | [(set (match_operand:DF 0 "register_operand" "=fx") |
2132 | (minus:DF (match_operand:DF 1 "register_operand" "fx") | |
2133 | (match_operand:DF 2 "register_operand" "fx")))] | |
c733e074 TM |
2134 | "" |
2135 | "fsub,dbl %1,%2,%0" | |
2136 | [(set_attr "type" "fpalu")]) | |
2137 | ||
2138 | (define_insn "subsf3" | |
53a66787 TG |
2139 | [(set (match_operand:SF 0 "register_operand" "=fx") |
2140 | (minus:SF (match_operand:SF 1 "register_operand" "fx") | |
2141 | (match_operand:SF 2 "register_operand" "fx")))] | |
c733e074 TM |
2142 | "" |
2143 | "fsub,sgl %1,%2,%0" | |
2144 | [(set_attr "type" "fpalu")]) | |
2145 | ||
2146 | (define_insn "muldf3" | |
53a66787 TG |
2147 | [(set (match_operand:DF 0 "register_operand" "=fx") |
2148 | (mult:DF (match_operand:DF 1 "register_operand" "fx") | |
2149 | (match_operand:DF 2 "register_operand" "fx")))] | |
c733e074 TM |
2150 | "" |
2151 | "fmpy,dbl %1,%2,%0" | |
2152 | [(set_attr "type" "fpmul")]) | |
2153 | ||
2154 | (define_insn "mulsf3" | |
53a66787 TG |
2155 | [(set (match_operand:SF 0 "register_operand" "=fx") |
2156 | (mult:SF (match_operand:SF 1 "register_operand" "fx") | |
2157 | (match_operand:SF 2 "register_operand" "fx")))] | |
c733e074 TM |
2158 | "" |
2159 | "fmpy,sgl %1,%2,%0" | |
2160 | [(set_attr "type" "fpmul")]) | |
2161 | ||
2162 | (define_insn "divdf3" | |
53a66787 TG |
2163 | [(set (match_operand:DF 0 "register_operand" "=fx") |
2164 | (div:DF (match_operand:DF 1 "register_operand" "fx") | |
2165 | (match_operand:DF 2 "register_operand" "fx")))] | |
c733e074 TM |
2166 | "" |
2167 | "fdiv,dbl %1,%2,%0" | |
2168 | [(set_attr "type" "fpdivdbl")]) | |
2169 | ||
2170 | (define_insn "divsf3" | |
53a66787 TG |
2171 | [(set (match_operand:SF 0 "register_operand" "=fx") |
2172 | (div:SF (match_operand:SF 1 "register_operand" "fx") | |
2173 | (match_operand:SF 2 "register_operand" "fx")))] | |
c733e074 TM |
2174 | "" |
2175 | "fdiv,sgl %1,%2,%0" | |
2176 | [(set_attr "type" "fpdivsgl")]) | |
2177 | ||
2178 | (define_insn "negdf2" | |
53a66787 TG |
2179 | [(set (match_operand:DF 0 "register_operand" "=fx") |
2180 | (neg:DF (match_operand:DF 1 "register_operand" "fx")))] | |
c733e074 TM |
2181 | "" |
2182 | "fsub,dbl 0,%1,%0" | |
2183 | [(set_attr "type" "fpalu")]) | |
2184 | ||
2185 | (define_insn "negsf2" | |
53a66787 TG |
2186 | [(set (match_operand:SF 0 "register_operand" "=fx") |
2187 | (neg:SF (match_operand:SF 1 "register_operand" "fx")))] | |
c733e074 TM |
2188 | "" |
2189 | "fsub,sgl 0, %1,%0" | |
2190 | [(set_attr "type" "fpalu")]) | |
2191 | ||
2192 | (define_insn "absdf2" | |
53a66787 TG |
2193 | [(set (match_operand:DF 0 "register_operand" "=fx") |
2194 | (abs:DF (match_operand:DF 1 "register_operand" "fx")))] | |
c733e074 | 2195 | "" |
cb432e02 | 2196 | "fabs,dbl %1,%0" |
c733e074 TM |
2197 | [(set_attr "type" "fpalu")]) |
2198 | ||
2199 | (define_insn "abssf2" | |
53a66787 TG |
2200 | [(set (match_operand:SF 0 "register_operand" "=fx") |
2201 | (abs:SF (match_operand:SF 1 "register_operand" "fx")))] | |
c733e074 TM |
2202 | "" |
2203 | "fabs,sgl %1,%0" | |
2204 | [(set_attr "type" "fpalu")]) | |
2205 | ||
2206 | (define_insn "sqrtdf2" | |
53a66787 TG |
2207 | [(set (match_operand:DF 0 "register_operand" "=fx") |
2208 | (sqrt:DF (match_operand:DF 1 "register_operand" "fx")))] | |
c733e074 TM |
2209 | "" |
2210 | "fsqrt,dbl %1,%0" | |
2211 | [(set_attr "type" "fpsqrtdbl")]) | |
2212 | ||
2213 | (define_insn "sqrtsf2" | |
53a66787 TG |
2214 | [(set (match_operand:SF 0 "register_operand" "=fx") |
2215 | (sqrt:SF (match_operand:SF 1 "register_operand" "fx")))] | |
c733e074 TM |
2216 | "" |
2217 | "fsqrt,sgl %1,%0" | |
2218 | [(set_attr "type" "fpsqrtsgl")]) | |
2219 | \f | |
2220 | ;;- Shift instructions | |
2221 | ||
2222 | ;; Optimized special case of shifting. | |
2223 | ||
2224 | (define_insn "" | |
2225 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2226 | (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") | |
2227 | (const_int 24)))] | |
2228 | "" | |
907f67cc TG |
2229 | "ldb%M1 %1,%0" |
2230 | [(set_attr "type" "load") | |
2231 | (set_attr "length" "1")]) | |
2232 | ||
2233 | (define_insn "" | |
2234 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2235 | (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") | |
2236 | (const_int 16)))] | |
2237 | "" | |
2238 | "ldh%M1 %1,%0" | |
2239 | [(set_attr "type" "load") | |
2240 | (set_attr "length" "1")]) | |
c733e074 | 2241 | |
9bb77117 | 2242 | ;; Using shadd_operand works around a bug in reload. For 2.4 fix |
101e8cc1 | 2243 | ;; reload and use register_operand instead. |
c733e074 TM |
2244 | (define_insn "" |
2245 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2246 | (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") | |
2247 | (const_int 2)) | |
9bb77117 | 2248 | (match_operand:SI 1 "shadd_operand" "r")))] |
c733e074 TM |
2249 | "" |
2250 | "sh1add %2,%1,%0") | |
2251 | ||
2252 | (define_insn "" | |
2253 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2254 | (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") | |
2255 | (const_int 4)) | |
9bb77117 | 2256 | (match_operand:SI 1 "shadd_operand" "r")))] |
c733e074 TM |
2257 | "" |
2258 | "sh2add %2,%1,%0") | |
2259 | ||
2260 | (define_insn "" | |
2261 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2262 | (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") | |
2263 | (const_int 8)) | |
9bb77117 | 2264 | (match_operand:SI 1 "shadd_operand" "r")))] |
c733e074 TM |
2265 | "" |
2266 | "sh3add %2,%1,%0") | |
2267 | ||
c733e074 TM |
2268 | (define_expand "ashlsi3" |
2269 | [(set (match_operand:SI 0 "register_operand" "") | |
2270 | (ashift:SI (match_operand:SI 1 "register_operand" "") | |
ba0443bb | 2271 | (match_operand:SI 2 "arith32_operand" "")))] |
c733e074 TM |
2272 | "" |
2273 | " | |
2274 | { | |
2275 | if (GET_CODE (operands[2]) != CONST_INT) | |
2276 | { | |
2277 | rtx temp = gen_reg_rtx (SImode); | |
cb524f44 TG |
2278 | emit_insn (gen_subsi3 (temp, |
2279 | gen_rtx (CONST_INT, VOIDmode, 31), | |
2280 | operands[2])); | |
2281 | emit_insn (gen_zvdep32 (operands[0], operands[1], temp)); | |
c733e074 TM |
2282 | DONE; |
2283 | } | |
2284 | }") | |
2285 | ||
2286 | (define_insn "" | |
2287 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2288 | (ashift:SI (match_operand:SI 1 "register_operand" "r") | |
ba0443bb | 2289 | (match_operand:SI 2 "const_int_operand" "n")))] |
c733e074 TM |
2290 | "" |
2291 | "* | |
2292 | { | |
876662ef TG |
2293 | rtx xoperands[4]; |
2294 | xoperands[0] = operands[0]; | |
2295 | xoperands[1] = operands[1]; | |
2296 | xoperands[2] = gen_rtx (CONST_INT, VOIDmode, | |
2297 | 31 - (INTVAL (operands[2]) & 31)); | |
2298 | xoperands[3] = gen_rtx (CONST_INT, VOIDmode, | |
2299 | 32 - (INTVAL (operands[2]) & 31)); | |
2300 | output_asm_insn (\"zdep %1,%2,%3,%0\", xoperands); | |
2301 | return \"\"; | |
c733e074 TM |
2302 | }") |
2303 | ||
cb524f44 | 2304 | (define_insn "zvdep32" |
c733e074 TM |
2305 | [(set (match_operand:SI 0 "register_operand" "=r") |
2306 | (ashift:SI (match_operand:SI 1 "register_operand" "r") | |
2307 | (minus:SI (const_int 31) | |
cb524f44 | 2308 | (match_operand:SI 2 "register_operand" "q"))))] |
c733e074 TM |
2309 | "" |
2310 | "zvdep %1,32,%0") | |
2311 | ||
2312 | (define_expand "ashrsi3" | |
2313 | [(set (match_operand:SI 0 "register_operand" "") | |
2314 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "") | |
ba0443bb | 2315 | (match_operand:SI 2 "arith32_operand" "")))] |
c733e074 TM |
2316 | "" |
2317 | " | |
2318 | { | |
2319 | if (GET_CODE (operands[2]) != CONST_INT) | |
2320 | { | |
2321 | rtx temp = gen_reg_rtx (SImode); | |
cb524f44 TG |
2322 | emit_insn (gen_subsi3 (temp, |
2323 | gen_rtx (CONST_INT, VOIDmode, 31), | |
2324 | operands[2])); | |
2325 | emit_insn (gen_vextrs32 (operands[0], operands[1], temp)); | |
c733e074 TM |
2326 | DONE; |
2327 | } | |
2328 | }") | |
2329 | ||
2330 | (define_insn "" | |
2331 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2332 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
ba0443bb | 2333 | (match_operand:SI 2 "const_int_operand" "n")))] |
c733e074 TM |
2334 | "" |
2335 | "* | |
2336 | { | |
876662ef TG |
2337 | rtx xoperands[4]; |
2338 | xoperands[0] = operands[0]; | |
2339 | xoperands[1] = operands[1]; | |
2340 | xoperands[2] = gen_rtx (CONST_INT, VOIDmode, | |
2341 | 31 - (INTVAL (operands[2]) & 31)); | |
2342 | xoperands[3] = gen_rtx (CONST_INT, VOIDmode, | |
2343 | 32 - (INTVAL (operands[2]) & 31)); | |
2344 | output_asm_insn (\"extrs %1,%2,%3,%0\", xoperands); | |
2345 | return \"\"; | |
c733e074 TM |
2346 | }") |
2347 | ||
cb524f44 | 2348 | (define_insn "vextrs32" |
c733e074 TM |
2349 | [(set (match_operand:SI 0 "register_operand" "=r") |
2350 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
ba0443bb | 2351 | (minus:SI (const_int 31) |
cb524f44 | 2352 | (match_operand:SI 2 "register_operand" "q"))))] |
c733e074 TM |
2353 | "" |
2354 | "vextrs %1,32,%0") | |
2355 | ||
cb524f44 TG |
2356 | (define_insn "lshrsi3" |
2357 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2358 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
2359 | (match_operand:SI 2 "arith32_operand" "qn")))] | |
c733e074 | 2360 | "" |
cb524f44 | 2361 | "* |
c733e074 | 2362 | { |
cb524f44 | 2363 | if (GET_CODE (operands[2]) == CONST_INT) |
c733e074 | 2364 | { |
cb524f44 TG |
2365 | operands[3] = gen_rtx (CONST_INT, VOIDmode, |
2366 | 32 - (INTVAL (operands[2]) & 31)); | |
2367 | operands[2] = gen_rtx (CONST_INT, VOIDmode, | |
2368 | 31 - (INTVAL (operands[2]) & 31)); | |
2369 | return \"extru %1,%2,%3,%0\"; | |
c733e074 | 2370 | } |
cb524f44 TG |
2371 | else |
2372 | return \"vshd 0,%1,%0\"; | |
c733e074 TM |
2373 | }") |
2374 | ||
cb524f44 TG |
2375 | (define_insn "rotrsi3" |
2376 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2377 | (rotatert:SI (match_operand:SI 1 "register_operand" "r") | |
2378 | (match_operand:SI 2 "arith32_operand" "qn")))] | |
2379 | "" | |
2380 | "* | |
c733e074 | 2381 | { |
cb524f44 TG |
2382 | if (GET_CODE (operands[2]) == CONST_INT) |
2383 | return \"shd %1,%1,%2,%0\"; | |
2384 | else | |
2385 | return \"vshd %1,%1,%0\"; | |
2386 | }" | |
2387 | [(set_attr "type" "binary") | |
2388 | (set_attr "length" "1")]) | |
2389 | ||
2390 | (define_insn "rotlsi3" | |
2391 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2392 | (rotatert:SI (match_operand:SI 1 "register_operand" "r") | |
2393 | (match_operand:SI 2 "const_int_operand" "n")))] | |
2394 | "" | |
2395 | "* | |
2396 | { | |
2397 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (32 - INTVAL (operands[2])) & 31); | |
2398 | return \"shd %1,%1,%2,%0\"; | |
2399 | }" | |
2400 | [(set_attr "type" "binary") | |
2401 | (set_attr "length" "1")]) | |
c733e074 TM |
2402 | |
2403 | (define_insn "" | |
cb524f44 TG |
2404 | [(set (match_operand:SI 0 "register_operand" "=r") |
2405 | (match_operator:SI 5 "plus_xor_ior_operator" | |
2406 | [(ashift:SI (match_operand:SI 1 "register_operand" "r") | |
2407 | (match_operand:SI 3 "const_int_operand" "n")) | |
2408 | (lshiftrt:SI (match_operand:SI 2 "register_operand" "r") | |
2409 | (match_operand:SI 4 "const_int_operand" "n"))]))] | |
2410 | "INTVAL (operands[3]) + INTVAL (operands[4]) == 32" | |
2411 | "shd %1,%2,%4,%0" | |
2412 | [(set_attr "type" "binary") | |
2413 | (set_attr "length" "1")]) | |
2414 | ||
2415 | (define_insn "" | |
2416 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2417 | (match_operator:SI 5 "plus_xor_ior_operator" | |
2418 | [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r") | |
2419 | (match_operand:SI 4 "const_int_operand" "n")) | |
2420 | (ashift:SI (match_operand:SI 1 "register_operand" "r") | |
2421 | (match_operand:SI 3 "const_int_operand" "n"))]))] | |
2422 | "INTVAL (operands[3]) + INTVAL (operands[4]) == 32" | |
2423 | "shd %1,%2,%4,%0" | |
2424 | [(set_attr "type" "binary") | |
2425 | (set_attr "length" "1")]) | |
c733e074 TM |
2426 | \f |
2427 | ;; Unconditional and other jump instructions. | |
2428 | ||
2429 | (define_insn "jump" | |
2430 | [(set (pc) (label_ref (match_operand 0 "" "")))] | |
2431 | "" | |
2432 | "bl%* %l0,0" | |
2433 | [(set_attr "type" "branch")]) | |
2434 | ||
876662ef TG |
2435 | ;; Subroutines of "casesi". |
2436 | ;; operand 0 is index | |
2437 | ;; operand 1 is the minimum bound | |
2438 | ;; operand 2 is the maximum bound - minimum bound + 1 | |
2439 | ;; operand 3 is CODE_LABEL for the table; | |
2440 | ;; operand 4 is the CODE_LABEL to go to if index out of range. | |
2441 | ||
2442 | (define_expand "casesi" | |
2443 | [(match_operand:SI 0 "general_operand" "") | |
2444 | (match_operand:SI 1 "const_int_operand" "") | |
2445 | (match_operand:SI 2 "const_int_operand" "") | |
2446 | (match_operand 3 "" "") | |
2447 | (match_operand 4 "" "")] | |
2448 | "" | |
2449 | " | |
2450 | { | |
2451 | if (GET_CODE (operands[0]) != REG) | |
2452 | operands[0] = force_reg (SImode, operands[0]); | |
2453 | ||
2454 | if (operands[1] != const0_rtx) | |
2455 | { | |
2456 | rtx reg = gen_reg_rtx (SImode); | |
2457 | ||
2458 | operands[1] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1])); | |
2459 | if (!INT_14_BITS (operands[1])) | |
2460 | operands[1] = force_reg (SImode, operands[1]); | |
2461 | emit_insn (gen_addsi3 (reg, operands[0], operands[1])); | |
2462 | ||
2463 | operands[0] = reg; | |
2464 | } | |
2465 | ||
2466 | if (!INT_11_BITS (operands[2])) | |
2467 | operands[2] = force_reg (SImode, operands[2]); | |
2468 | ||
58939c25 TG |
2469 | emit_jump_insn (gen_casesi0 (operands[0], operands[2], |
2470 | operands[3], operands[4])); | |
876662ef TG |
2471 | DONE; |
2472 | }") | |
2473 | ||
2474 | (define_insn "casesi0" | |
c733e074 | 2475 | [(set (pc) |
876662ef TG |
2476 | (if_then_else (leu (match_operand:SI 0 "register_operand" "r") |
2477 | (match_operand:SI 1 "arith11_operand" "rI")) | |
2478 | (plus:SI (mem:SI (plus:SI (pc) (match_dup 0))) | |
2479 | (label_ref (match_operand 2 "" ""))) | |
c733e074 | 2480 | (pc))) |
876662ef | 2481 | (use (label_ref (match_operand 3 "" "")))] |
c733e074 TM |
2482 | "" |
2483 | "* | |
2484 | { | |
2485 | if (GET_CODE (operands[1]) == CONST_INT) | |
2486 | { | |
876662ef TG |
2487 | operands[1] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[1])); |
2488 | return \"addi,uv %1,%0,0\;blr,n %0,0\;b,n %l3\"; | |
c733e074 TM |
2489 | } |
2490 | else | |
2491 | { | |
876662ef | 2492 | return \"sub,>> %0,%1,0\;blr,n %0,0\;b,n %l3\"; |
c733e074 | 2493 | } |
c733e074 | 2494 | }" |
876662ef TG |
2495 | [(set_attr "length" "3")]) |
2496 | ||
2497 | ||
c733e074 TM |
2498 | ;; Need nops for the calls because execution is supposed to continue |
2499 | ;; past; we don't want to nullify an instruction that we need. | |
2500 | ;;- jump to subroutine | |
2501 | ||
2502 | (define_expand "call" | |
2503 | [(parallel [(call (match_operand:SI 0 "" "") | |
2504 | (match_operand 1 "" "")) | |
2505 | (clobber (reg:SI 31)) | |
2506 | (clobber (reg:SI 2))])] | |
2507 | "" | |
2508 | " | |
2509 | { | |
4d72c241 JL |
2510 | rtx op; |
2511 | ||
5cf2759e | 2512 | if (TARGET_LONG_CALLS) |
4d72c241 | 2513 | op = force_reg (SImode, XEXP (operands[0], 0)); |
5cf2759e | 2514 | else |
4d72c241 JL |
2515 | op = XEXP (operands[0], 0); |
2516 | emit_call_insn (gen_call_internal (op, operands[1])); | |
2517 | if (flag_pic) | |
2518 | { | |
2519 | if (!hppa_save_pic_table_rtx) | |
2520 | hppa_save_pic_table_rtx = gen_reg_rtx (Pmode); | |
2521 | emit_insn (gen_rtx (SET, VOIDmode, | |
2522 | gen_rtx (REG, Pmode, 19), hppa_save_pic_table_rtx)); | |
2523 | } | |
2524 | DONE; | |
c733e074 TM |
2525 | }") |
2526 | ||
4d72c241 | 2527 | (define_insn "call_internal" |
c733e074 TM |
2528 | [(call (mem:SI (match_operand:SI 0 "call_operand_address" "r,S")) |
2529 | (match_operand 1 "" "i,i")) | |
2530 | (clobber (reg:SI 31)) | |
2531 | (clobber (reg:SI 2))] | |
2532 | "" | |
2533 | "* | |
2534 | { | |
2535 | if (which_alternative == 0) | |
2536 | return \"copy %0,22\;.CALL\\tARGW0=GR\;bl $$dyncall,31\;copy 31,2\"; | |
2537 | else | |
2538 | { | |
2539 | output_arg_descriptor (insn); | |
2540 | return \"bl %0,2%#\"; | |
2541 | } | |
2542 | }" | |
2543 | [(set_attr "type" "dyncall,call") | |
2544 | (set_attr "length" "3,1")]) | |
2545 | ||
2546 | (define_expand "call_value" | |
2547 | [(parallel [(set (match_operand 0 "" "") | |
2548 | (call (match_operand:SI 1 "" "") | |
2549 | (match_operand 2 "" ""))) | |
2550 | (clobber (reg:SI 31)) | |
2551 | (clobber (reg:SI 2))])] | |
2552 | ;;- Don't use operand 1 for most machines. | |
2553 | "" | |
2554 | " | |
2555 | { | |
4d72c241 JL |
2556 | rtx op; |
2557 | ||
5cf2759e | 2558 | if (TARGET_LONG_CALLS) |
4d72c241 | 2559 | op = force_reg (SImode, XEXP (operands[1], 0)); |
5cf2759e | 2560 | else |
4d72c241 JL |
2561 | op = XEXP (operands[1], 0); |
2562 | emit_call_insn (gen_call_value_internal (operands[0], op, operands[2])); | |
2563 | if (flag_pic) | |
2564 | { | |
2565 | if (!hppa_save_pic_table_rtx) | |
2566 | hppa_save_pic_table_rtx = gen_reg_rtx (Pmode); | |
2567 | emit_insn (gen_rtx (SET, VOIDmode, | |
2568 | gen_rtx (REG, Pmode, 19), hppa_save_pic_table_rtx)); | |
2569 | } | |
2570 | DONE; | |
c733e074 TM |
2571 | }") |
2572 | ||
4d72c241 | 2573 | (define_insn "call_value_internal" |
c733e074 TM |
2574 | [(set (match_operand 0 "" "=rfx,rfx") |
2575 | (call (mem:SI (match_operand:SI 1 "call_operand_address" "r,S")) | |
2576 | (match_operand 2 "" "i,i"))) | |
2577 | (clobber (reg:SI 31)) | |
2578 | (clobber (reg:SI 2))] | |
2579 | ;;- Don't use operand 1 for most machines. | |
2580 | "" | |
2581 | "* | |
2582 | { | |
2583 | if (which_alternative == 0) | |
2584 | return \"copy %1,22\;.CALL\\tARGW0=GR\;bl $$dyncall,31\;copy 31,2\"; | |
2585 | else | |
2586 | { | |
2587 | output_arg_descriptor (insn); | |
3bf1c6b5 | 2588 | return \"bl %1,2%#\"; |
c733e074 TM |
2589 | } |
2590 | }" | |
3bf1c6b5 JL |
2591 | [(set_attr "type" "dyncall,call") |
2592 | (set_attr "length" "3,1")]) | |
c733e074 TM |
2593 | |
2594 | (define_insn "nop" | |
2595 | [(const_int 0)] | |
2596 | "" | |
2597 | "nop") | |
2598 | ||
2599 | ;;; Hope this is only within a function... | |
2600 | (define_insn "indirect_jump" | |
2601 | [(set (pc) (match_operand:SI 0 "register_operand" "r"))] | |
2602 | "" | |
29662692 | 2603 | "bv%* 0(%0)" |
c733e074 TM |
2604 | [(set_attr "type" "branch")]) |
2605 | ||
2606 | (define_insn "extzv" | |
2607 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2608 | (zero_extract:SI (match_operand:SI 1 "register_operand" "r") | |
2609 | (match_operand:SI 2 "uint5_operand" "") | |
2610 | (match_operand:SI 3 "uint5_operand" "")))] | |
2611 | "" | |
2612 | "extru %1,%3+%2-1,%2,%0") | |
2613 | ||
2614 | (define_insn "extv" | |
2615 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2616 | (sign_extract:SI (match_operand:SI 1 "register_operand" "r") | |
2617 | (match_operand:SI 2 "uint5_operand" "") | |
2618 | (match_operand:SI 3 "uint5_operand" "")))] | |
2619 | "" | |
2620 | "extrs %1,%3+%2-1,%2,%0") | |
2621 | ||
2622 | (define_insn "insv" | |
51c2b9d1 | 2623 | [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r") |
c733e074 TM |
2624 | (match_operand:SI 1 "uint5_operand" "") |
2625 | (match_operand:SI 2 "uint5_operand" "")) | |
51c2b9d1 | 2626 | (match_operand:SI 3 "arith5_operand" "r,L"))] |
c733e074 | 2627 | "" |
51c2b9d1 TG |
2628 | "@ |
2629 | dep %3,%2+%1-1,%1,%0 | |
2630 | depi %3,%2+%1-1,%1,%0") | |
2631 | ||
2632 | ;; Optimize insertion of const_int values of type 1...1xxxx. | |
2633 | (define_insn "" | |
2634 | [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") | |
2635 | (match_operand:SI 1 "uint5_operand" "") | |
2636 | (match_operand:SI 2 "uint5_operand" "")) | |
2637 | (match_operand:SI 3 "const_int_operand" ""))] | |
2638 | "(INTVAL (operands[3]) & 0x10) != 0 && | |
2639 | (~INTVAL (operands[3]) & (1L << INTVAL (operands[1])) - 1 & ~0xf) == 0" | |
2640 | "* | |
2641 | { | |
2642 | operands[3] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[3]) & 0xf) - 0x10); | |
2643 | return \"depi %3,%2+%1-1,%1,%0\"; | |
2644 | }") | |
c733e074 | 2645 | |
53a66787 TG |
2646 | ;; This insn is used for some loop tests, typically loops reversed when |
2647 | ;; strength reduction is used. It is actually created when the instruction | |
2648 | ;; combination phase combines the special loop test. Since this insn | |
2649 | ;; is both a jump insn and has an output, it must deal with it's own | |
2650 | ;; reloads, hence the `m' constraints. The `!' constraints direct reload | |
2651 | ;; to not choose the register alternatives in the event a reload is needed. | |
2652 | ||
2653 | (define_insn "decrement_and_branch_until_zero" | |
2654 | [(set (pc) | |
2655 | (if_then_else | |
2656 | (ge (plus:SI (match_operand:SI 0 "register_operand" "+!r,m") | |
2657 | (const_int -1)) | |
2658 | (const_int 0)) | |
2659 | (label_ref (match_operand 1 "" "")) | |
2660 | (pc))) | |
2661 | (set (match_dup 0) | |
2662 | (plus:SI (match_dup 0) | |
2663 | (const_int -1))) | |
2664 | (clobber (match_scratch:SI 2 "=X,r"))] | |
2665 | "find_reg_note (insn, REG_NONNEG, 0)" | |
2666 | "* | |
2667 | { | |
2668 | if (which_alternative == 0) | |
2669 | if (get_attr_length (insn) == 1) | |
2670 | return \"addib,>= -1,%0,%1%#\"; | |
2671 | else | |
2672 | return \"addi,< -1,%0,%0\;bl %1,0%#\"; | |
2673 | else | |
2674 | { | |
2675 | output_asm_insn (\"ldw %0,%2\;ldo -1(%2),%2\;stw %2,%0\", operands); | |
2676 | if (get_attr_length (insn) == 4) | |
2677 | return \"comb,> 0,%2,%1%#\"; | |
2678 | else | |
2679 | return \"comclr,<= 0,%2,0\;bl %1,0%#\"; | |
2680 | } | |
2681 | }" | |
2682 | [(set_attr "type" "cbranch") | |
2683 | (set (attr "length") | |
2684 | (if_then_else (eq (symbol_ref "which_alternative") (const_int 0)) | |
2685 | (if_then_else (lt (abs (minus (match_dup 1) | |
2686 | (plus (pc) (const_int 2)))) | |
2687 | (const_int 1023)) | |
2688 | (const_int 1) | |
2689 | (const_int 2)) | |
2690 | (if_then_else (lt (match_dup 1) | |
2691 | (pc)) | |
2692 | (if_then_else | |
2693 | (lt (abs (minus (match_dup 1) | |
2694 | (plus (pc) | |
2695 | (const_int 5)))) | |
2696 | (const_int 1023)) | |
2697 | (const_int 4) | |
2698 | (const_int 5)) | |
2699 | (if_then_else | |
2700 | (lt (abs (minus (match_dup 1) | |
2701 | (plus (pc) | |
2702 | (const_int 2)))) | |
2703 | (const_int 1023)) | |
2704 | (const_int 4) | |
2705 | (const_int 5)))))]) | |
2706 | ||
2707 | ||
2c871711 JL |
2708 | ;; The next four peepholes take advantage of the new 5 operand |
2709 | ;; fmpy{add,sub} instructions available on 1.1 CPUS. Basically | |
2710 | ;; fmpyadd performs a multiply and add/sub of independent operands | |
2711 | ;; at the same time. Because the operands must be independent | |
2712 | ;; combine will not try to combine such insns... Thus we have | |
2713 | ;; to use a peephole. | |
2714 | (define_peephole | |
2715 | [(set (match_operand 0 "register_operand" "=fx") | |
2716 | (mult (match_operand 1 "register_operand" "fx") | |
2717 | (match_operand 2 "register_operand" "fx"))) | |
2718 | (set (match_operand 3 "register_operand" "+fx") | |
2719 | (plus (match_operand 4 "register_operand" "fx") | |
2720 | (match_operand 5 "register_operand" "fx")))] | |
2721 | "TARGET_SNAKE && fmpyaddoperands (operands)" | |
2722 | "* | |
2723 | { | |
2724 | if (GET_MODE (operands[0]) == DFmode) | |
19386a3e | 2725 | { |
1a3b6bdd | 2726 | if (rtx_equal_p (operands[5], operands[3])) |
19386a3e JL |
2727 | return \"fmpyadd,dbl %1,%2,%0,%4,%3\"; |
2728 | else | |
2729 | return \"fmpyadd,dbl %1,%2,%0,%5,%3\"; | |
2730 | } | |
2c871711 | 2731 | else |
19386a3e | 2732 | { |
1a3b6bdd | 2733 | if (rtx_equal_p (operands[5], operands[3])) |
19386a3e JL |
2734 | return \"fmpyadd,sgl %1,%2,%0,%4,%3\"; |
2735 | else | |
2736 | return \"fmpyadd,sgl %1,%2,%0,%5,%3\"; | |
2737 | } | |
2c871711 JL |
2738 | }") |
2739 | ||
2740 | ||
2741 | (define_peephole | |
2742 | [(set (match_operand 3 "register_operand" "+fx") | |
2743 | (plus (match_operand 4 "register_operand" "fx") | |
2744 | (match_operand 5 "register_operand" "fx"))) | |
2745 | (set (match_operand 0 "register_operand" "=fx") | |
2746 | (mult (match_operand 1 "register_operand" "fx") | |
2747 | (match_operand 2 "register_operand" "fx")))] | |
2748 | "TARGET_SNAKE && fmpyaddoperands (operands)" | |
2749 | "* | |
2750 | { | |
2751 | if (GET_MODE (operands[0]) == DFmode) | |
19386a3e JL |
2752 | { |
2753 | if (rtx_equal_p (operands[3], operands[5])) | |
2754 | return \"fmpyadd,dbl %1,%2,%0,%4,%3\"; | |
2755 | else | |
2756 | return \"fmpyadd,dbl %1,%2,%0,%5,%3\"; | |
2757 | } | |
2c871711 | 2758 | else |
19386a3e JL |
2759 | { |
2760 | if (rtx_equal_p (operands[3], operands[5])) | |
2761 | return \"fmpyadd,sgl %1,%2,%0,%4,%3\"; | |
2762 | else | |
2763 | return \"fmpyadd,sgl %1,%2,%0,%5,%3\"; | |
2764 | } | |
2c871711 JL |
2765 | }") |
2766 | ||
2767 | ;; Note fsub subtracts the second operand from the first while fmpysub | |
2768 | ;; does the opposite for the subtraction operands! | |
2769 | (define_peephole | |
2770 | [(set (match_operand 0 "register_operand" "=fx") | |
2771 | (mult (match_operand 1 "register_operand" "fx") | |
2772 | (match_operand 2 "register_operand" "fx"))) | |
2773 | (set (match_operand 3 "register_operand" "+fx") | |
2774 | (minus (match_operand 4 "register_operand" "fx") | |
2775 | (match_operand 5 "register_operand" "fx")))] | |
2776 | "TARGET_SNAKE && fmpysuboperands (operands)" | |
2777 | "* | |
2778 | { | |
2779 | if (GET_MODE (operands[0]) == DFmode) | |
2780 | return \"fmpysub,dbl %1,%2,%0,%5,%3\"; | |
2781 | else | |
2782 | return \"fmpysub,sgl %1,%2,%0,%5,%3\"; | |
2783 | }") | |
2784 | ||
2785 | (define_peephole | |
2786 | [(set (match_operand 3 "register_operand" "+fx") | |
2787 | (minus (match_operand 4 "register_operand" "fx") | |
2788 | (match_operand 5 "register_operand" "fx"))) | |
2789 | (set (match_operand 0 "register_operand" "=fx") | |
2790 | (mult (match_operand 1 "register_operand" "fx") | |
2791 | (match_operand 2 "register_operand" "fx")))] | |
2792 | "TARGET_SNAKE && fmpysuboperands (operands)" | |
2793 | "* | |
2794 | { | |
2795 | if (GET_MODE (operands[0]) == DFmode) | |
2796 | return \"fmpysub,dbl %1,%2,%0,%5,%3\"; | |
2797 | else | |
2798 | return \"fmpysub,sgl %1,%2,%0,%5,%3\"; | |
2799 | }") | |
2800 | ||
53a66787 | 2801 | |
c733e074 TM |
2802 | ;;- Local variables: |
2803 | ;;- mode:emacs-lisp | |
2804 | ;;- comment-start: ";;- " | |
2805 | ;;- eval: (set-syntax-table (copy-sequence (syntax-table))) | |
2806 | ;;- eval: (modify-syntax-entry ?[ "(]") | |
2807 | ;;- eval: (modify-syntax-entry ?] ")[") | |
2808 | ;;- eval: (modify-syntax-entry ?{ "(}") | |
2809 | ;;- eval: (modify-syntax-entry ?} "){") | |
2810 | ;;- End: |