1 ;;- Machine description for HP PA-RISC architecture for GNU C compiler
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by the Center for Software Science at the University
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
24 ;; This gcc Version 2 machine description is inspired by sparc.md and
27 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; Insn type. Used to default other attribute values.
31 ;; type "unary" insns have one input operand (1) and one output operand (0)
32 ;; type "binary" insns have two input operands (1,2) and one output (0)
35 "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,parallel_branch"
36 (const_string "binary"))
38 (define_attr "pa_combine_type"
39 "fmpy,faddsub,uncond_branch,addmove,none"
40 (const_string "none"))
42 ;; Processor type (for scheduling, not code generation) -- this attribute
43 ;; must exactly match the processor_type enumeration in pa.h.
45 ;; FIXME: Add 800 scheduling for completeness?
47 (define_attr "cpu" "700,7100,7100LC,7200,8000" (const (symbol_ref "pa_cpu_attr")))
49 ;; Length (in # of bytes).
50 (define_attr "length" ""
51 (cond [(eq_attr "type" "load,fpload")
52 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
53 (const_int 8) (const_int 4))
55 (eq_attr "type" "store,fpstore")
56 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
57 (const_int 8) (const_int 4))
59 (eq_attr "type" "binary,shift,nullshift")
60 (if_then_else (match_operand 2 "arith_operand" "")
61 (const_int 4) (const_int 12))
63 (eq_attr "type" "move,unary,shift,nullshift")
64 (if_then_else (match_operand 1 "arith_operand" "")
65 (const_int 4) (const_int 8))]
69 (define_asm_attributes
70 [(set_attr "length" "4")
71 (set_attr "type" "multi")])
73 ;; Attributes for instruction and branch scheduling
75 ;; For conditional branches.
76 (define_attr "in_branch_delay" "false,true"
77 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
78 (eq_attr "length" "4"))
80 (const_string "false")))
82 ;; Disallow instructions which use the FPU since they will tie up the FPU
83 ;; even if the instruction is nullified.
84 (define_attr "in_nullified_branch_delay" "false,true"
85 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch")
86 (eq_attr "length" "4"))
88 (const_string "false")))
90 ;; For calls and millicode calls. Allow unconditional branches in the
92 (define_attr "in_call_delay" "false,true"
93 (cond [(and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
94 (eq_attr "length" "4"))
96 (eq_attr "type" "uncond_branch")
97 (if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY")
100 (const_string "false"))]
101 (const_string "false")))
104 ;; Call delay slot description.
105 (define_delay (eq_attr "type" "call")
106 [(eq_attr "in_call_delay" "true") (nil) (nil)])
108 ;; millicode call delay slot description. Note it disallows delay slot
109 ;; when TARGET_PORTABLE_RUNTIME is true.
110 (define_delay (eq_attr "type" "milli")
111 [(and (eq_attr "in_call_delay" "true")
112 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0)))
115 ;; Return and other similar instructions.
116 (define_delay (eq_attr "type" "branch,parallel_branch")
117 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
119 ;; Floating point conditional branch delay slot description and
120 (define_delay (eq_attr "type" "fbranch")
121 [(eq_attr "in_branch_delay" "true")
122 (eq_attr "in_nullified_branch_delay" "true")
125 ;; Integer conditional branch delay slot description.
126 ;; Nullification of conditional branches on the PA is dependent on the
127 ;; direction of the branch. Forward branches nullify true and
128 ;; backward branches nullify false. If the direction is unknown
129 ;; then nullification is not allowed.
130 (define_delay (eq_attr "type" "cbranch")
131 [(eq_attr "in_branch_delay" "true")
132 (and (eq_attr "in_nullified_branch_delay" "true")
133 (attr_flag "forward"))
134 (and (eq_attr "in_nullified_branch_delay" "true")
135 (attr_flag "backward"))])
137 (define_delay (and (eq_attr "type" "uncond_branch")
138 (eq (symbol_ref "following_call (insn)")
140 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
142 ;; Function units of the HPPA. The following data is for the 700 CPUs
143 ;; (Mustang CPU + Timex FPU aka PA-89) because that's what I have the docs for.
144 ;; Scheduling instructions for PA-83 machines according to the Snake
145 ;; constraints shouldn't hurt.
147 ;; (define_function_unit {name} {num-units} {n-users} {test}
148 ;; {ready-delay} {issue-delay} [{conflict-list}])
151 ;; (Noted only for documentation; units that take one cycle do not need to
154 ;; (define_function_unit "alu" 1 0
155 ;; (and (eq_attr "type" "unary,shift,nullshift,binary,move,address")
156 ;; (eq_attr "cpu" "700"))
160 ;; Memory. Disregarding Cache misses, the Mustang memory times are:
161 ;; load: 2, fpload: 3
162 ;; store, fpstore: 3, no D-cache operations should be scheduled.
164 (define_function_unit "pa700memory" 1 0
165 (and (eq_attr "type" "load,fpload")
166 (eq_attr "cpu" "700")) 2 0)
167 (define_function_unit "pa700memory" 1 0
168 (and (eq_attr "type" "store,fpstore")
169 (eq_attr "cpu" "700")) 3 3)
171 ;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
173 ;; Instruction Time Unit Minimum Distance (unit contention)
180 ;; fmpyadd 3 ALU,MPY 2
181 ;; fmpysub 3 ALU,MPY 2
182 ;; fmpycfxt 3 ALU,MPY 2
185 ;; fdiv,sgl 10 MPY 10
186 ;; fdiv,dbl 12 MPY 12
187 ;; fsqrt,sgl 14 MPY 14
188 ;; fsqrt,dbl 18 MPY 18
190 (define_function_unit "pa700fp_alu" 1 0
191 (and (eq_attr "type" "fpcc")
192 (eq_attr "cpu" "700")) 4 2)
193 (define_function_unit "pa700fp_alu" 1 0
194 (and (eq_attr "type" "fpalu")
195 (eq_attr "cpu" "700")) 3 2)
196 (define_function_unit "pa700fp_mpy" 1 0
197 (and (eq_attr "type" "fpmulsgl,fpmuldbl")
198 (eq_attr "cpu" "700")) 3 2)
199 (define_function_unit "pa700fp_mpy" 1 0
200 (and (eq_attr "type" "fpdivsgl")
201 (eq_attr "cpu" "700")) 10 10)
202 (define_function_unit "pa700fp_mpy" 1 0
203 (and (eq_attr "type" "fpdivdbl")
204 (eq_attr "cpu" "700")) 12 12)
205 (define_function_unit "pa700fp_mpy" 1 0
206 (and (eq_attr "type" "fpsqrtsgl")
207 (eq_attr "cpu" "700")) 14 14)
208 (define_function_unit "pa700fp_mpy" 1 0
209 (and (eq_attr "type" "fpsqrtdbl")
210 (eq_attr "cpu" "700")) 18 18)
212 ;; Function units for the 7100 and 7150. The 7100/7150 can dual-issue
213 ;; floating point computations with non-floating point computations (fp loads
214 ;; and stores are not fp computations).
217 ;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
218 ;; take two cycles, during which no Dcache operations should be scheduled.
219 ;; Any special cases are handled in pa_adjust_cost. The 7100, 7150 and 7100LC
220 ;; all have the same memory characteristics if one disregards cache misses.
221 (define_function_unit "pa7100memory" 1 0
222 (and (eq_attr "type" "load,fpload")
223 (eq_attr "cpu" "7100,7100LC")) 2 0)
224 (define_function_unit "pa7100memory" 1 0
225 (and (eq_attr "type" "store,fpstore")
226 (eq_attr "cpu" "7100,7100LC")) 2 2)
228 ;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
230 ;; Instruction Time Unit Minimum Distance (unit contention)
237 ;; fmpyadd 2 ALU,MPY 1
238 ;; fmpysub 2 ALU,MPY 1
239 ;; fmpycfxt 2 ALU,MPY 1
243 ;; fdiv,dbl 15 DIV 15
245 ;; fsqrt,dbl 15 DIV 15
247 (define_function_unit "pa7100fp_alu" 1 0
248 (and (eq_attr "type" "fpcc,fpalu")
249 (eq_attr "cpu" "7100")) 2 1)
250 (define_function_unit "pa7100fp_mpy" 1 0
251 (and (eq_attr "type" "fpmulsgl,fpmuldbl")
252 (eq_attr "cpu" "7100")) 2 1)
253 (define_function_unit "pa7100fp_div" 1 0
254 (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
255 (eq_attr "cpu" "7100")) 8 8)
256 (define_function_unit "pa7100fp_div" 1 0
257 (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
258 (eq_attr "cpu" "7100")) 15 15)
260 ;; To encourage dual issue we define function units corresponding to
261 ;; the instructions which can be dual issued. This is a rather crude
262 ;; approximation, the "pa7100nonflop" test in particular could be refined.
263 (define_function_unit "pa7100flop" 1 1
265 (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
266 (eq_attr "cpu" "7100")) 1 1)
268 (define_function_unit "pa7100nonflop" 1 1
270 (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
271 (eq_attr "cpu" "7100")) 1 1)
274 ;; Memory subsystem works just like 7100/7150 (except for cache miss times which
275 ;; we don't model here).
277 ;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
278 ;; Note divides and sqrt flops lock the cpu until the flop is
279 ;; finished. fmpy and xmpyu (fmpyi) lock the cpu for one cycle.
280 ;; There's no way to avoid the penalty.
282 ;; Instruction Time Unit Minimum Distance (unit contention)
289 ;; fmpyadd,sgl 2 ALU,MPY 1
290 ;; fmpyadd,dbl 3 ALU,MPY 2
291 ;; fmpysub,sgl 2 ALU,MPY 1
292 ;; fmpysub,dbl 3 ALU,MPY 2
293 ;; fmpycfxt,sgl 2 ALU,MPY 1
294 ;; fmpycfxt,dbl 3 ALU,MPY 2
299 ;; fdiv,dbl 15 DIV 15
301 ;; fsqrt,dbl 15 DIV 15
303 (define_function_unit "pa7100LCfp_alu" 1 0
304 (and (eq_attr "type" "fpcc,fpalu")
305 (eq_attr "cpu" "7100LC,7200")) 2 1)
306 (define_function_unit "pa7100LCfp_mpy" 1 0
307 (and (eq_attr "type" "fpmulsgl")
308 (eq_attr "cpu" "7100LC,7200")) 2 1)
309 (define_function_unit "pa7100LCfp_mpy" 1 0
310 (and (eq_attr "type" "fpmuldbl")
311 (eq_attr "cpu" "7100LC,7200")) 3 2)
312 (define_function_unit "pa7100LCfp_div" 1 0
313 (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
314 (eq_attr "cpu" "7100LC,7200")) 8 8)
315 (define_function_unit "pa7100LCfp_div" 1 0
316 (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
317 (eq_attr "cpu" "7100LC,7200")) 15 15)
319 ;; Define the various functional units for dual-issue.
321 ;; There's only one floating point unit.
322 (define_function_unit "pa7100LCflop" 1 1
324 (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
325 (eq_attr "cpu" "7100LC,7200")) 1 1)
327 ;; Shifts and memory ops execute in only one of the integer ALUs
328 (define_function_unit "pa7100LCshiftmem" 1 1
330 (eq_attr "type" "shift,nullshift,load,fpload,store,fpstore")
331 (eq_attr "cpu" "7100LC,7200")) 1 1)
333 ;; We have two basic ALUs.
334 (define_function_unit "pa7100LCalu" 2 1
336 (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
337 (eq_attr "cpu" "7100LC,7200")) 1 1)
339 ;; I don't have complete information on the PA7200; however, most of
340 ;; what I've heard makes it look like a 7100LC without the store-store
341 ;; penalty. So that's how we'll model it.
343 ;; Memory. Disregarding Cache misses, memory loads and stores take
344 ;; two cycles. Any special cases are handled in pa_adjust_cost.
345 (define_function_unit "pa7200memory" 1 0
346 (and (eq_attr "type" "load,fpload,store,fpstore")
347 (eq_attr "cpu" "7200")) 2 0)
349 ;; I don't have detailed information on the PA7200 FP pipeline, so I
350 ;; treat it just like the 7100LC pipeline.
351 ;; Similarly for the multi-issue fake units.
354 ;; Scheduling for the PA8000 is somewhat different than scheduling for a
355 ;; traditional architecture.
357 ;; The PA8000 has a large (56) entry reorder buffer that is split between
358 ;; memory and non-memory operations.
360 ;; The PA800 can issue two memory and two non-memory operations per cycle to
361 ;; the function units. Similarly, the PA8000 can retire two memory and two
362 ;; non-memory operations per cycle.
364 ;; Given the large reorder buffer, the processor can hide most latencies.
365 ;; According to HP, they've got the best results by scheduling for retirement
366 ;; bandwidth with limited latency scheduling for floating point operations.
367 ;; Latency for integer operations and memory references is ignored.
369 ;; We claim floating point operations have a 2 cycle latency and are
370 ;; fully pipelined, except for div and sqrt which are not pipelined.
372 ;; It is not necessary to define the shifter and integer alu units.
374 ;; These first two define_unit_unit descriptions model retirement from
375 ;; the reorder buffer.
376 (define_function_unit "pa8000lsu" 2 1
378 (eq_attr "type" "load,fpload,store,fpstore")
379 (eq_attr "cpu" "8000")) 1 1)
381 (define_function_unit "pa8000alu" 2 1
383 (eq_attr "type" "!load,fpload,store,fpstore")
384 (eq_attr "cpu" "8000")) 1 1)
386 ;; Claim floating point ops have a 2 cycle latency, excluding div and
387 ;; sqrt, which are not pipelined and issue to different units.
388 (define_function_unit "pa8000fmac" 2 0
390 (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
391 (eq_attr "cpu" "8000")) 2 1)
393 (define_function_unit "pa8000fdiv" 2 1
395 (eq_attr "type" "fpdivsgl,fpsqrtsgl")
396 (eq_attr "cpu" "8000")) 17 17)
398 (define_function_unit "pa8000fdiv" 2 1
400 (eq_attr "type" "fpdivdbl,fpsqrtdbl")
401 (eq_attr "cpu" "8000")) 31 31)
404 ;; Compare instructions.
405 ;; This controls RTL generation and register allocation.
407 ;; We generate RTL for comparisons and branches by having the cmpxx
408 ;; patterns store away the operands. Then, the scc and bcc patterns
409 ;; emit RTL for both the compare and the branch.
412 (define_expand "cmpdi"
414 (compare:CC (match_operand:DI 0 "reg_or_0_operand" "")
415 (match_operand:DI 1 "register_operand" "")))]
420 hppa_compare_op0 = operands[0];
421 hppa_compare_op1 = operands[1];
422 hppa_branch_type = CMP_SI;
426 (define_expand "cmpsi"
428 (compare:CC (match_operand:SI 0 "reg_or_0_operand" "")
429 (match_operand:SI 1 "arith5_operand" "")))]
433 hppa_compare_op0 = operands[0];
434 hppa_compare_op1 = operands[1];
435 hppa_branch_type = CMP_SI;
439 (define_expand "cmpsf"
441 (compare:CCFP (match_operand:SF 0 "reg_or_0_operand" "")
442 (match_operand:SF 1 "reg_or_0_operand" "")))]
443 "! TARGET_SOFT_FLOAT"
446 hppa_compare_op0 = operands[0];
447 hppa_compare_op1 = operands[1];
448 hppa_branch_type = CMP_SF;
452 (define_expand "cmpdf"
454 (compare:CCFP (match_operand:DF 0 "reg_or_0_operand" "")
455 (match_operand:DF 1 "reg_or_0_operand" "")))]
456 "! TARGET_SOFT_FLOAT"
459 hppa_compare_op0 = operands[0];
460 hppa_compare_op1 = operands[1];
461 hppa_branch_type = CMP_DF;
467 (match_operator:CCFP 2 "comparison_operator"
468 [(match_operand:SF 0 "reg_or_0_operand" "fG")
469 (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
470 "! TARGET_SOFT_FLOAT"
471 "fcmp,sgl,%Y2 %f0,%f1"
472 [(set_attr "length" "4")
473 (set_attr "type" "fpcc")])
477 (match_operator:CCFP 2 "comparison_operator"
478 [(match_operand:DF 0 "reg_or_0_operand" "fG")
479 (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
480 "! TARGET_SOFT_FLOAT"
481 "fcmp,dbl,%Y2 %f0,%f1"
482 [(set_attr "length" "4")
483 (set_attr "type" "fpcc")])
488 [(set (match_operand:SI 0 "register_operand" "")
494 /* fp scc patterns rarely match, and are not a win on the PA. */
495 if (hppa_branch_type != CMP_SI)
497 /* set up operands from compare. */
498 operands[1] = hppa_compare_op0;
499 operands[2] = hppa_compare_op1;
500 /* fall through and generate default code */
504 [(set (match_operand:SI 0 "register_operand" "")
510 /* fp scc patterns rarely match, and are not a win on the PA. */
511 if (hppa_branch_type != CMP_SI)
513 operands[1] = hppa_compare_op0;
514 operands[2] = hppa_compare_op1;
518 [(set (match_operand:SI 0 "register_operand" "")
524 /* fp scc patterns rarely match, and are not a win on the PA. */
525 if (hppa_branch_type != CMP_SI)
527 operands[1] = hppa_compare_op0;
528 operands[2] = hppa_compare_op1;
532 [(set (match_operand:SI 0 "register_operand" "")
538 /* fp scc patterns rarely match, and are not a win on the PA. */
539 if (hppa_branch_type != CMP_SI)
541 operands[1] = hppa_compare_op0;
542 operands[2] = hppa_compare_op1;
546 [(set (match_operand:SI 0 "register_operand" "")
552 /* fp scc patterns rarely match, and are not a win on the PA. */
553 if (hppa_branch_type != CMP_SI)
555 operands[1] = hppa_compare_op0;
556 operands[2] = hppa_compare_op1;
560 [(set (match_operand:SI 0 "register_operand" "")
566 /* fp scc patterns rarely match, and are not a win on the PA. */
567 if (hppa_branch_type != CMP_SI)
569 operands[1] = hppa_compare_op0;
570 operands[2] = hppa_compare_op1;
573 (define_expand "sltu"
574 [(set (match_operand:SI 0 "register_operand" "")
575 (ltu:SI (match_dup 1)
580 if (hppa_branch_type != CMP_SI)
582 operands[1] = hppa_compare_op0;
583 operands[2] = hppa_compare_op1;
586 (define_expand "sgtu"
587 [(set (match_operand:SI 0 "register_operand" "")
588 (gtu:SI (match_dup 1)
593 if (hppa_branch_type != CMP_SI)
595 operands[1] = hppa_compare_op0;
596 operands[2] = hppa_compare_op1;
599 (define_expand "sleu"
600 [(set (match_operand:SI 0 "register_operand" "")
601 (leu:SI (match_dup 1)
606 if (hppa_branch_type != CMP_SI)
608 operands[1] = hppa_compare_op0;
609 operands[2] = hppa_compare_op1;
612 (define_expand "sgeu"
613 [(set (match_operand:SI 0 "register_operand" "")
614 (geu:SI (match_dup 1)
619 if (hppa_branch_type != CMP_SI)
621 operands[1] = hppa_compare_op0;
622 operands[2] = hppa_compare_op1;
625 ;; Instruction canonicalization puts immediate operands second, which
626 ;; is the reverse of what we want.
629 [(set (match_operand:SI 0 "register_operand" "=r")
630 (match_operator:SI 3 "comparison_operator"
631 [(match_operand:SI 1 "register_operand" "r")
632 (match_operand:SI 2 "arith11_operand" "rI")]))]
634 "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi 1,%0"
635 [(set_attr "type" "binary")
636 (set_attr "length" "8")])
639 [(set (match_operand:DI 0 "register_operand" "=r")
640 (match_operator:DI 3 "comparison_operator"
641 [(match_operand:DI 1 "register_operand" "r")
642 (match_operand:DI 2 "arith11_operand" "rI")]))]
644 "cmp%I2clr,*%B3 %2,%1,%0\;ldi 1,%0"
645 [(set_attr "type" "binary")
646 (set_attr "length" "8")])
648 (define_insn "iorscc"
649 [(set (match_operand:SI 0 "register_operand" "=r")
650 (ior:SI (match_operator:SI 3 "comparison_operator"
651 [(match_operand:SI 1 "register_operand" "r")
652 (match_operand:SI 2 "arith11_operand" "rI")])
653 (match_operator:SI 6 "comparison_operator"
654 [(match_operand:SI 4 "register_operand" "r")
655 (match_operand:SI 5 "arith11_operand" "rI")])))]
657 "{com%I2clr|cmp%I2clr},%S3 %2,%1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%4,%0\;ldi 1,%0"
658 [(set_attr "type" "binary")
659 (set_attr "length" "12")])
662 [(set (match_operand:DI 0 "register_operand" "=r")
663 (ior:DI (match_operator:DI 3 "comparison_operator"
664 [(match_operand:DI 1 "register_operand" "r")
665 (match_operand:DI 2 "arith11_operand" "rI")])
666 (match_operator:DI 6 "comparison_operator"
667 [(match_operand:DI 4 "register_operand" "r")
668 (match_operand:DI 5 "arith11_operand" "rI")])))]
670 "cmp%I2clr,*%S3 %2,%1,%%r0\;cmp%I5clr,*%B6 %5,%4,%0\;ldi 1,%0"
671 [(set_attr "type" "binary")
672 (set_attr "length" "12")])
674 ;; Combiner patterns for common operations performed with the output
675 ;; from an scc insn (negscc and incscc).
676 (define_insn "negscc"
677 [(set (match_operand:SI 0 "register_operand" "=r")
678 (neg:SI (match_operator:SI 3 "comparison_operator"
679 [(match_operand:SI 1 "register_operand" "r")
680 (match_operand:SI 2 "arith11_operand" "rI")])))]
682 "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi -1,%0"
683 [(set_attr "type" "binary")
684 (set_attr "length" "8")])
687 [(set (match_operand:DI 0 "register_operand" "=r")
688 (neg:DI (match_operator:DI 3 "comparison_operator"
689 [(match_operand:DI 1 "register_operand" "r")
690 (match_operand:DI 2 "arith11_operand" "rI")])))]
692 "cmp%I2clr,*%B3 %2,%1,%0\;ldi -1,%0"
693 [(set_attr "type" "binary")
694 (set_attr "length" "8")])
696 ;; Patterns for adding/subtracting the result of a boolean expression from
697 ;; a register. First we have special patterns that make use of the carry
698 ;; bit, and output only two instructions. For the cases we can't in
699 ;; general do in two instructions, the incscc pattern at the end outputs
700 ;; two or three instructions.
703 [(set (match_operand:SI 0 "register_operand" "=r")
704 (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
705 (match_operand:SI 3 "arith11_operand" "rI"))
706 (match_operand:SI 1 "register_operand" "r")))]
708 "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
709 [(set_attr "type" "binary")
710 (set_attr "length" "8")])
713 [(set (match_operand:DI 0 "register_operand" "=r")
714 (plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r")
715 (match_operand:DI 3 "arith11_operand" "rI"))
716 (match_operand:DI 1 "register_operand" "r")))]
718 "sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0"
719 [(set_attr "type" "binary")
720 (set_attr "length" "8")])
722 ; This need only accept registers for op3, since canonicalization
723 ; replaces geu with gtu when op3 is an integer.
725 [(set (match_operand:SI 0 "register_operand" "=r")
726 (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
727 (match_operand:SI 3 "register_operand" "r"))
728 (match_operand:SI 1 "register_operand" "r")))]
730 "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
731 [(set_attr "type" "binary")
732 (set_attr "length" "8")])
735 [(set (match_operand:DI 0 "register_operand" "=r")
736 (plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r")
737 (match_operand:DI 3 "register_operand" "r"))
738 (match_operand:DI 1 "register_operand" "r")))]
740 "sub %2,%3,%%r0\;add,dc %%r0,%1,%0"
741 [(set_attr "type" "binary")
742 (set_attr "length" "8")])
744 ; Match only integers for op3 here. This is used as canonical form of the
745 ; geu pattern when op3 is an integer. Don't match registers since we can't
746 ; make better code than the general incscc pattern.
748 [(set (match_operand:SI 0 "register_operand" "=r")
749 (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
750 (match_operand:SI 3 "int11_operand" "I"))
751 (match_operand:SI 1 "register_operand" "r")))]
753 "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
754 [(set_attr "type" "binary")
755 (set_attr "length" "8")])
758 [(set (match_operand:DI 0 "register_operand" "=r")
759 (plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r")
760 (match_operand:DI 3 "int11_operand" "I"))
761 (match_operand:DI 1 "register_operand" "r")))]
763 "addi %k3,%2,%%r0\;add,dc %%r0,%1,%0"
764 [(set_attr "type" "binary")
765 (set_attr "length" "8")])
767 (define_insn "incscc"
768 [(set (match_operand:SI 0 "register_operand" "=r,r")
769 (plus:SI (match_operator:SI 4 "comparison_operator"
770 [(match_operand:SI 2 "register_operand" "r,r")
771 (match_operand:SI 3 "arith11_operand" "rI,rI")])
772 (match_operand:SI 1 "register_operand" "0,?r")))]
775 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
776 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
777 [(set_attr "type" "binary,binary")
778 (set_attr "length" "8,12")])
781 [(set (match_operand:DI 0 "register_operand" "=r,r")
782 (plus:DI (match_operator:DI 4 "comparison_operator"
783 [(match_operand:DI 2 "register_operand" "r,r")
784 (match_operand:DI 3 "arith11_operand" "rI,rI")])
785 (match_operand:DI 1 "register_operand" "0,?r")))]
788 cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0
789 cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
790 [(set_attr "type" "binary,binary")
791 (set_attr "length" "8,12")])
794 [(set (match_operand:SI 0 "register_operand" "=r")
795 (minus:SI (match_operand:SI 1 "register_operand" "r")
796 (gtu:SI (match_operand:SI 2 "register_operand" "r")
797 (match_operand:SI 3 "arith11_operand" "rI"))))]
799 "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
800 [(set_attr "type" "binary")
801 (set_attr "length" "8")])
804 [(set (match_operand:DI 0 "register_operand" "=r")
805 (minus:DI (match_operand:DI 1 "register_operand" "r")
806 (gtu:DI (match_operand:DI 2 "register_operand" "r")
807 (match_operand:DI 3 "arith11_operand" "rI"))))]
809 "sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0"
810 [(set_attr "type" "binary")
811 (set_attr "length" "8")])
814 [(set (match_operand:SI 0 "register_operand" "=r")
815 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
816 (gtu:SI (match_operand:SI 2 "register_operand" "r")
817 (match_operand:SI 3 "arith11_operand" "rI")))
818 (match_operand:SI 4 "register_operand" "r")))]
820 "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
821 [(set_attr "type" "binary")
822 (set_attr "length" "8")])
825 [(set (match_operand:DI 0 "register_operand" "=r")
826 (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
827 (gtu:DI (match_operand:DI 2 "register_operand" "r")
828 (match_operand:DI 3 "arith11_operand" "rI")))
829 (match_operand:DI 4 "register_operand" "r")))]
831 "sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0"
832 [(set_attr "type" "binary")
833 (set_attr "length" "8")])
835 ; This need only accept registers for op3, since canonicalization
836 ; replaces ltu with leu when op3 is an integer.
838 [(set (match_operand:SI 0 "register_operand" "=r")
839 (minus:SI (match_operand:SI 1 "register_operand" "r")
840 (ltu:SI (match_operand:SI 2 "register_operand" "r")
841 (match_operand:SI 3 "register_operand" "r"))))]
843 "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
844 [(set_attr "type" "binary")
845 (set_attr "length" "8")])
848 [(set (match_operand:DI 0 "register_operand" "=r")
849 (minus:DI (match_operand:DI 1 "register_operand" "r")
850 (ltu:DI (match_operand:DI 2 "register_operand" "r")
851 (match_operand:DI 3 "register_operand" "r"))))]
853 "sub %2,%3,%%r0\;sub,db %1,%%r0,%0"
854 [(set_attr "type" "binary")
855 (set_attr "length" "8")])
858 [(set (match_operand:SI 0 "register_operand" "=r")
859 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
860 (ltu:SI (match_operand:SI 2 "register_operand" "r")
861 (match_operand:SI 3 "register_operand" "r")))
862 (match_operand:SI 4 "register_operand" "r")))]
864 "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
865 [(set_attr "type" "binary")
866 (set_attr "length" "8")])
869 [(set (match_operand:DI 0 "register_operand" "=r")
870 (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
871 (ltu:DI (match_operand:DI 2 "register_operand" "r")
872 (match_operand:DI 3 "register_operand" "r")))
873 (match_operand:DI 4 "register_operand" "r")))]
875 "sub %2,%3,%%r0\;sub,db %1,%4,%0"
876 [(set_attr "type" "binary")
877 (set_attr "length" "8")])
879 ; Match only integers for op3 here. This is used as canonical form of the
880 ; ltu pattern when op3 is an integer. Don't match registers since we can't
881 ; make better code than the general incscc pattern.
883 [(set (match_operand:SI 0 "register_operand" "=r")
884 (minus:SI (match_operand:SI 1 "register_operand" "r")
885 (leu:SI (match_operand:SI 2 "register_operand" "r")
886 (match_operand:SI 3 "int11_operand" "I"))))]
888 "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
889 [(set_attr "type" "binary")
890 (set_attr "length" "8")])
893 [(set (match_operand:DI 0 "register_operand" "=r")
894 (minus:DI (match_operand:DI 1 "register_operand" "r")
895 (leu:DI (match_operand:DI 2 "register_operand" "r")
896 (match_operand:DI 3 "int11_operand" "I"))))]
898 "addi %k3,%2,%%r0\;sub,db %1,%%r0,%0"
899 [(set_attr "type" "binary")
900 (set_attr "length" "8")])
903 [(set (match_operand:SI 0 "register_operand" "=r")
904 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
905 (leu:SI (match_operand:SI 2 "register_operand" "r")
906 (match_operand:SI 3 "int11_operand" "I")))
907 (match_operand:SI 4 "register_operand" "r")))]
909 "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
910 [(set_attr "type" "binary")
911 (set_attr "length" "8")])
914 [(set (match_operand:DI 0 "register_operand" "=r")
915 (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
916 (leu:DI (match_operand:DI 2 "register_operand" "r")
917 (match_operand:DI 3 "int11_operand" "I")))
918 (match_operand:DI 4 "register_operand" "r")))]
920 "addi %k3,%2,%%r0\;sub,db %1,%4,%0"
921 [(set_attr "type" "binary")
922 (set_attr "length" "8")])
924 (define_insn "decscc"
925 [(set (match_operand:SI 0 "register_operand" "=r,r")
926 (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
927 (match_operator:SI 4 "comparison_operator"
928 [(match_operand:SI 2 "register_operand" "r,r")
929 (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
932 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
933 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
934 [(set_attr "type" "binary,binary")
935 (set_attr "length" "8,12")])
938 [(set (match_operand:DI 0 "register_operand" "=r,r")
939 (minus:DI (match_operand:DI 1 "register_operand" "0,?r")
940 (match_operator:DI 4 "comparison_operator"
941 [(match_operand:DI 2 "register_operand" "r,r")
942 (match_operand:DI 3 "arith11_operand" "rI,rI")])))]
945 cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0
946 cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
947 [(set_attr "type" "binary,binary")
948 (set_attr "length" "8,12")])
950 ; Patterns for max and min. (There is no need for an earlyclobber in the
951 ; last alternative since the middle alternative will match if op0 == op1.)
953 (define_insn "sminsi3"
954 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
955 (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
956 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
959 {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
960 {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
961 {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
962 [(set_attr "type" "multi,multi,multi")
963 (set_attr "length" "8,8,8")])
965 (define_insn "smindi3"
966 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
967 (smin:DI (match_operand:DI 1 "register_operand" "%0,0,r")
968 (match_operand:DI 2 "arith11_operand" "r,I,M")))]
971 cmpclr,*> %2,%0,%%r0\;copy %2,%0
972 cmpiclr,*> %2,%0,%%r0\;ldi %2,%0
973 cmpclr,*> %1,%r2,%0\;copy %1,%0"
974 [(set_attr "type" "multi,multi,multi")
975 (set_attr "length" "8,8,8")])
977 (define_insn "uminsi3"
978 [(set (match_operand:SI 0 "register_operand" "=r,r")
979 (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
980 (match_operand:SI 2 "arith11_operand" "r,I")))]
983 {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
984 {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
985 [(set_attr "type" "multi,multi")
986 (set_attr "length" "8,8")])
988 (define_insn "umindi3"
989 [(set (match_operand:DI 0 "register_operand" "=r,r")
990 (umin:DI (match_operand:DI 1 "register_operand" "%0,0")
991 (match_operand:DI 2 "arith11_operand" "r,I")))]
994 cmpclr,*>> %2,%0,%%r0\;copy %2,%0
995 cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0"
996 [(set_attr "type" "multi,multi")
997 (set_attr "length" "8,8")])
999 (define_insn "smaxsi3"
1000 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1001 (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1002 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1005 {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
1006 {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
1007 {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
1008 [(set_attr "type" "multi,multi,multi")
1009 (set_attr "length" "8,8,8")])
1011 (define_insn "smaxdi3"
1012 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1013 (smax:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1014 (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1017 cmpclr,*< %2,%0,%%r0\;copy %2,%0
1018 cmpiclr,*< %2,%0,%%r0\;ldi %2,%0
1019 cmpclr,*< %1,%r2,%0\;copy %1,%0"
1020 [(set_attr "type" "multi,multi,multi")
1021 (set_attr "length" "8,8,8")])
1023 (define_insn "umaxsi3"
1024 [(set (match_operand:SI 0 "register_operand" "=r,r")
1025 (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
1026 (match_operand:SI 2 "arith11_operand" "r,I")))]
1029 {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
1030 {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
1031 [(set_attr "type" "multi,multi")
1032 (set_attr "length" "8,8")])
1034 (define_insn "umaxdi3"
1035 [(set (match_operand:DI 0 "register_operand" "=r,r")
1036 (umax:DI (match_operand:DI 1 "register_operand" "%0,0")
1037 (match_operand:DI 2 "arith11_operand" "r,I")))]
1040 cmpclr,*<< %2,%0,%%r0\;copy %2,%0
1041 cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0"
1042 [(set_attr "type" "multi,multi")
1043 (set_attr "length" "8,8")])
1045 (define_insn "abssi2"
1046 [(set (match_operand:SI 0 "register_operand" "=r")
1047 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
1049 "or,>= %%r0,%1,%0\;subi 0,%0,%0"
1050 [(set_attr "type" "multi")
1051 (set_attr "length" "8")])
1053 (define_insn "absdi2"
1054 [(set (match_operand:DI 0 "register_operand" "=r")
1055 (abs:DI (match_operand:DI 1 "register_operand" "r")))]
1057 "or,*>= %%r0,%1,%0\;subi 0,%0,%0"
1058 [(set_attr "type" "multi")
1059 (set_attr "length" "8")])
1061 ;;; Experimental conditional move patterns
1063 (define_expand "movsicc"
1064 [(set (match_operand:SI 0 "register_operand" "")
1066 (match_operator 1 "comparison_operator"
1069 (match_operand:SI 2 "reg_or_cint_move_operand" "")
1070 (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
1074 enum rtx_code code = GET_CODE (operands[1]);
1076 if (hppa_branch_type != CMP_SI)
1079 if (GET_MODE (hppa_compare_op0) != GET_MODE (hppa_compare_op1)
1080 || GET_MODE (hppa_compare_op0) != GET_MODE (operands[0]))
1083 /* operands[1] is currently the result of compare_from_rtx. We want to
1084 emit a compare of the original operands. */
1085 operands[1] = gen_rtx_fmt_ee (code, SImode, hppa_compare_op0, hppa_compare_op1);
1086 operands[4] = hppa_compare_op0;
1087 operands[5] = hppa_compare_op1;
1090 ;; We used to accept any register for op1.
1092 ;; However, it loses sometimes because the compiler will end up using
1093 ;; different registers for op0 and op1 in some critical cases. local-alloc
1094 ;; will not tie op0 and op1 because op0 is used in multiple basic blocks.
1096 ;; If/when global register allocation supports tying we should allow any
1097 ;; register for op1 again.
1099 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1101 (match_operator 2 "comparison_operator"
1102 [(match_operand:SI 3 "register_operand" "r,r,r,r")
1103 (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
1104 (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
1108 {com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0
1109 {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0
1110 {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0
1111 {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
1112 [(set_attr "type" "multi,multi,multi,nullshift")
1113 (set_attr "length" "8,8,8,8")])
1116 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1118 (match_operator 5 "comparison_operator"
1119 [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
1120 (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1121 (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1122 (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1125 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
1126 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
1127 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
1128 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
1129 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
1130 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
1131 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
1132 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
1133 [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1134 (set_attr "length" "8,8,8,8,8,8,8,8")])
1136 (define_expand "movdicc"
1137 [(set (match_operand:DI 0 "register_operand" "")
1139 (match_operator 1 "comparison_operator"
1142 (match_operand:DI 2 "reg_or_cint_move_operand" "")
1143 (match_operand:DI 3 "reg_or_cint_move_operand" "")))]
1147 enum rtx_code code = GET_CODE (operands[1]);
1149 if (hppa_branch_type != CMP_SI)
1152 if (GET_MODE (hppa_compare_op0) != GET_MODE (hppa_compare_op1)
1153 || GET_MODE (hppa_compare_op0) != GET_MODE (operands[0]))
1156 /* operands[1] is currently the result of compare_from_rtx. We want to
1157 emit a compare of the original operands. */
1158 operands[1] = gen_rtx_fmt_ee (code, DImode, hppa_compare_op0, hppa_compare_op1);
1159 operands[4] = hppa_compare_op0;
1160 operands[5] = hppa_compare_op1;
1163 ; We need the first constraint alternative in order to avoid
1164 ; earlyclobbers on all other alternatives.
1166 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
1168 (match_operator 2 "comparison_operator"
1169 [(match_operand:DI 3 "register_operand" "r,r,r,r,r")
1170 (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
1171 (match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
1175 cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0
1176 cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0
1177 cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0
1178 cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0
1179 cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0"
1180 [(set_attr "type" "multi,multi,multi,multi,nullshift")
1181 (set_attr "length" "8,8,8,8,8")])
1184 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1186 (match_operator 5 "comparison_operator"
1187 [(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r")
1188 (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1189 (match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1190 (match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1193 cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0
1194 cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0
1195 cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0
1196 cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0
1197 cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0
1198 cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0
1199 cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0
1200 cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0"
1201 [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1202 (set_attr "length" "8,8,8,8,8,8,8,8")])
1204 ;; Conditional Branches
1206 (define_expand "beq"
1208 (if_then_else (eq (match_dup 1) (match_dup 2))
1209 (label_ref (match_operand 0 "" ""))
1214 if (hppa_branch_type != CMP_SI)
1216 emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1));
1217 emit_bcond_fp (NE, operands[0]);
1220 /* set up operands from compare. */
1221 operands[1] = hppa_compare_op0;
1222 operands[2] = hppa_compare_op1;
1223 /* fall through and generate default code */
1226 (define_expand "bne"
1228 (if_then_else (ne (match_dup 1) (match_dup 2))
1229 (label_ref (match_operand 0 "" ""))
1234 if (hppa_branch_type != CMP_SI)
1236 emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1));
1237 emit_bcond_fp (NE, operands[0]);
1240 operands[1] = hppa_compare_op0;
1241 operands[2] = hppa_compare_op1;
1244 (define_expand "bgt"
1246 (if_then_else (gt (match_dup 1) (match_dup 2))
1247 (label_ref (match_operand 0 "" ""))
1252 if (hppa_branch_type != CMP_SI)
1254 emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1));
1255 emit_bcond_fp (NE, operands[0]);
1258 operands[1] = hppa_compare_op0;
1259 operands[2] = hppa_compare_op1;
1262 (define_expand "blt"
1264 (if_then_else (lt (match_dup 1) (match_dup 2))
1265 (label_ref (match_operand 0 "" ""))
1270 if (hppa_branch_type != CMP_SI)
1272 emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1));
1273 emit_bcond_fp (NE, operands[0]);
1276 operands[1] = hppa_compare_op0;
1277 operands[2] = hppa_compare_op1;
1280 (define_expand "bge"
1282 (if_then_else (ge (match_dup 1) (match_dup 2))
1283 (label_ref (match_operand 0 "" ""))
1288 if (hppa_branch_type != CMP_SI)
1290 emit_insn (gen_cmp_fp (GE, hppa_compare_op0, hppa_compare_op1));
1291 emit_bcond_fp (NE, operands[0]);
1294 operands[1] = hppa_compare_op0;
1295 operands[2] = hppa_compare_op1;
1298 (define_expand "ble"
1300 (if_then_else (le (match_dup 1) (match_dup 2))
1301 (label_ref (match_operand 0 "" ""))
1306 if (hppa_branch_type != CMP_SI)
1308 emit_insn (gen_cmp_fp (LE, hppa_compare_op0, hppa_compare_op1));
1309 emit_bcond_fp (NE, operands[0]);
1312 operands[1] = hppa_compare_op0;
1313 operands[2] = hppa_compare_op1;
1316 (define_expand "bgtu"
1318 (if_then_else (gtu (match_dup 1) (match_dup 2))
1319 (label_ref (match_operand 0 "" ""))
1324 if (hppa_branch_type != CMP_SI)
1326 operands[1] = hppa_compare_op0;
1327 operands[2] = hppa_compare_op1;
1330 (define_expand "bltu"
1332 (if_then_else (ltu (match_dup 1) (match_dup 2))
1333 (label_ref (match_operand 0 "" ""))
1338 if (hppa_branch_type != CMP_SI)
1340 operands[1] = hppa_compare_op0;
1341 operands[2] = hppa_compare_op1;
1344 (define_expand "bgeu"
1346 (if_then_else (geu (match_dup 1) (match_dup 2))
1347 (label_ref (match_operand 0 "" ""))
1352 if (hppa_branch_type != CMP_SI)
1354 operands[1] = hppa_compare_op0;
1355 operands[2] = hppa_compare_op1;
1358 (define_expand "bleu"
1360 (if_then_else (leu (match_dup 1) (match_dup 2))
1361 (label_ref (match_operand 0 "" ""))
1366 if (hppa_branch_type != CMP_SI)
1368 operands[1] = hppa_compare_op0;
1369 operands[2] = hppa_compare_op1;
1372 (define_expand "bltgt"
1374 (if_then_else (ltgt (match_dup 1) (match_dup 2))
1375 (label_ref (match_operand 0 "" ""))
1380 if (hppa_branch_type == CMP_SI)
1382 emit_insn (gen_cmp_fp (LTGT, hppa_compare_op0, hppa_compare_op1));
1383 emit_bcond_fp (NE, operands[0]);
1387 (define_expand "bunle"
1389 (if_then_else (unle (match_dup 1) (match_dup 2))
1390 (label_ref (match_operand 0 "" ""))
1395 if (hppa_branch_type == CMP_SI)
1397 emit_insn (gen_cmp_fp (UNLE, hppa_compare_op0, hppa_compare_op1));
1398 emit_bcond_fp (NE, operands[0]);
1402 (define_expand "bunlt"
1404 (if_then_else (unlt (match_dup 1) (match_dup 2))
1405 (label_ref (match_operand 0 "" ""))
1410 if (hppa_branch_type == CMP_SI)
1412 emit_insn (gen_cmp_fp (UNLT, hppa_compare_op0, hppa_compare_op1));
1413 emit_bcond_fp (NE, operands[0]);
1417 (define_expand "bunge"
1419 (if_then_else (unge (match_dup 1) (match_dup 2))
1420 (label_ref (match_operand 0 "" ""))
1425 if (hppa_branch_type == CMP_SI)
1427 emit_insn (gen_cmp_fp (UNGE, hppa_compare_op0, hppa_compare_op1));
1428 emit_bcond_fp (NE, operands[0]);
1432 (define_expand "bungt"
1434 (if_then_else (ungt (match_dup 1) (match_dup 2))
1435 (label_ref (match_operand 0 "" ""))
1440 if (hppa_branch_type == CMP_SI)
1442 emit_insn (gen_cmp_fp (UNGT, hppa_compare_op0, hppa_compare_op1));
1443 emit_bcond_fp (NE, operands[0]);
1447 (define_expand "buneq"
1449 (if_then_else (uneq (match_dup 1) (match_dup 2))
1450 (label_ref (match_operand 0 "" ""))
1455 if (hppa_branch_type == CMP_SI)
1457 emit_insn (gen_cmp_fp (UNEQ, hppa_compare_op0, hppa_compare_op1));
1458 emit_bcond_fp (NE, operands[0]);
1462 (define_expand "bunordered"
1464 (if_then_else (unordered (match_dup 1) (match_dup 2))
1465 (label_ref (match_operand 0 "" ""))
1470 if (hppa_branch_type == CMP_SI)
1472 emit_insn (gen_cmp_fp (UNORDERED, hppa_compare_op0, hppa_compare_op1));
1473 emit_bcond_fp (NE, operands[0]);
1477 (define_expand "bordered"
1479 (if_then_else (ordered (match_dup 1) (match_dup 2))
1480 (label_ref (match_operand 0 "" ""))
1485 if (hppa_branch_type == CMP_SI)
1487 emit_insn (gen_cmp_fp (ORDERED, hppa_compare_op0, hppa_compare_op1));
1488 emit_bcond_fp (NE, operands[0]);
1492 ;; Match the branch patterns.
1495 ;; Note a long backward conditional branch with an annulled delay slot
1496 ;; has a length of 12.
1500 (match_operator 3 "comparison_operator"
1501 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1502 (match_operand:SI 2 "arith5_operand" "rL")])
1503 (label_ref (match_operand 0 "" ""))
1508 return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1509 get_attr_length (insn), 0, insn);
1511 [(set_attr "type" "cbranch")
1512 (set (attr "length")
1513 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1516 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1519 (eq (symbol_ref "flag_pic") (const_int 0))
1523 ;; Match the negated branch.
1528 (match_operator 3 "comparison_operator"
1529 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1530 (match_operand:SI 2 "arith5_operand" "rL")])
1532 (label_ref (match_operand 0 "" ""))))]
1536 return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1537 get_attr_length (insn), 1, insn);
1539 [(set_attr "type" "cbranch")
1540 (set (attr "length")
1541 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1544 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1547 (eq (symbol_ref "flag_pic") (const_int 0))
1554 (match_operator 3 "comparison_operator"
1555 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1556 (match_operand:DI 2 "reg_or_0_operand" "rM")])
1557 (label_ref (match_operand 0 "" ""))
1562 return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1563 get_attr_length (insn), 0, insn);
1565 [(set_attr "type" "cbranch")
1566 (set (attr "length")
1567 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1570 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1573 (eq (symbol_ref "flag_pic") (const_int 0))
1577 ;; Match the negated branch.
1582 (match_operator 3 "comparison_operator"
1583 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1584 (match_operand:DI 2 "reg_or_0_operand" "rM")])
1586 (label_ref (match_operand 0 "" ""))))]
1590 return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1591 get_attr_length (insn), 1, insn);
1593 [(set_attr "type" "cbranch")
1594 (set (attr "length")
1595 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1598 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1601 (eq (symbol_ref "flag_pic") (const_int 0))
1607 (match_operator 3 "cmpib_comparison_operator"
1608 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1609 (match_operand:DI 2 "arith5_operand" "rL")])
1610 (label_ref (match_operand 0 "" ""))
1615 return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1616 get_attr_length (insn), 0, insn);
1618 [(set_attr "type" "cbranch")
1619 (set (attr "length")
1620 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1623 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1626 (eq (symbol_ref "flag_pic") (const_int 0))
1630 ;; Match the negated branch.
1635 (match_operator 3 "cmpib_comparison_operator"
1636 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1637 (match_operand:DI 2 "arith5_operand" "rL")])
1639 (label_ref (match_operand 0 "" ""))))]
1643 return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1644 get_attr_length (insn), 1, insn);
1646 [(set_attr "type" "cbranch")
1647 (set (attr "length")
1648 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1651 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1654 (eq (symbol_ref "flag_pic") (const_int 0))
1658 ;; Branch on Bit patterns.
1662 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1664 (match_operand:SI 1 "uint5_operand" ""))
1666 (label_ref (match_operand 2 "" ""))
1671 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1672 get_attr_length (insn), 0, insn, 0);
1674 [(set_attr "type" "cbranch")
1675 (set (attr "length")
1676 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1684 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1686 (match_operand:DI 1 "uint32_operand" ""))
1688 (label_ref (match_operand 2 "" ""))
1693 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1694 get_attr_length (insn), 0, insn, 0);
1696 [(set_attr "type" "cbranch")
1697 (set (attr "length")
1698 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1706 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1708 (match_operand:SI 1 "uint5_operand" ""))
1711 (label_ref (match_operand 2 "" ""))))]
1715 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1716 get_attr_length (insn), 1, insn, 0);
1718 [(set_attr "type" "cbranch")
1719 (set (attr "length")
1720 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1728 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1730 (match_operand:DI 1 "uint32_operand" ""))
1733 (label_ref (match_operand 2 "" ""))))]
1737 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1738 get_attr_length (insn), 1, insn, 0);
1740 [(set_attr "type" "cbranch")
1741 (set (attr "length")
1742 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1750 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1752 (match_operand:SI 1 "uint5_operand" ""))
1754 (label_ref (match_operand 2 "" ""))
1759 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1760 get_attr_length (insn), 0, insn, 1);
1762 [(set_attr "type" "cbranch")
1763 (set (attr "length")
1764 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1772 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1774 (match_operand:DI 1 "uint32_operand" ""))
1776 (label_ref (match_operand 2 "" ""))
1781 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1782 get_attr_length (insn), 0, insn, 1);
1784 [(set_attr "type" "cbranch")
1785 (set (attr "length")
1786 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1794 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1796 (match_operand:SI 1 "uint5_operand" ""))
1799 (label_ref (match_operand 2 "" ""))))]
1803 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1804 get_attr_length (insn), 1, insn, 1);
1806 [(set_attr "type" "cbranch")
1807 (set (attr "length")
1808 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1816 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1818 (match_operand:DI 1 "uint32_operand" ""))
1821 (label_ref (match_operand 2 "" ""))))]
1825 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1826 get_attr_length (insn), 1, insn, 1);
1828 [(set_attr "type" "cbranch")
1829 (set (attr "length")
1830 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1835 ;; Branch on Variable Bit patterns.
1839 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1841 (match_operand:SI 1 "register_operand" "q"))
1843 (label_ref (match_operand 2 "" ""))
1848 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1849 get_attr_length (insn), 0, insn, 0);
1851 [(set_attr "type" "cbranch")
1852 (set (attr "length")
1853 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1861 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1863 (match_operand:DI 1 "register_operand" "q"))
1865 (label_ref (match_operand 2 "" ""))
1870 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1871 get_attr_length (insn), 0, insn, 0);
1873 [(set_attr "type" "cbranch")
1874 (set (attr "length")
1875 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1883 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1885 (match_operand:SI 1 "register_operand" "q"))
1888 (label_ref (match_operand 2 "" ""))))]
1892 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1893 get_attr_length (insn), 1, insn, 0);
1895 [(set_attr "type" "cbranch")
1896 (set (attr "length")
1897 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1905 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1907 (match_operand:DI 1 "register_operand" "q"))
1910 (label_ref (match_operand 2 "" ""))))]
1914 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1915 get_attr_length (insn), 1, insn, 0);
1917 [(set_attr "type" "cbranch")
1918 (set (attr "length")
1919 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1927 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1929 (match_operand:SI 1 "register_operand" "q"))
1931 (label_ref (match_operand 2 "" ""))
1936 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1937 get_attr_length (insn), 0, insn, 1);
1939 [(set_attr "type" "cbranch")
1940 (set (attr "length")
1941 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1949 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1951 (match_operand:DI 1 "register_operand" "q"))
1953 (label_ref (match_operand 2 "" ""))
1958 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1959 get_attr_length (insn), 0, insn, 1);
1961 [(set_attr "type" "cbranch")
1962 (set (attr "length")
1963 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1971 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1973 (match_operand:SI 1 "register_operand" "q"))
1976 (label_ref (match_operand 2 "" ""))))]
1980 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1981 get_attr_length (insn), 1, insn, 1);
1983 [(set_attr "type" "cbranch")
1984 (set (attr "length")
1985 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1993 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1995 (match_operand:DI 1 "register_operand" "q"))
1998 (label_ref (match_operand 2 "" ""))))]
2002 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2003 get_attr_length (insn), 1, insn, 1);
2005 [(set_attr "type" "cbranch")
2006 (set (attr "length")
2007 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2012 ;; Floating point branches
2014 [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2015 (label_ref (match_operand 0 "" ""))
2017 "! TARGET_SOFT_FLOAT"
2020 if (INSN_ANNULLED_BRANCH_P (insn))
2021 return \"ftest\;b,n %0\";
2023 return \"ftest\;b%* %0\";
2025 [(set_attr "type" "fbranch")
2026 (set_attr "length" "8")])
2029 [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2031 (label_ref (match_operand 0 "" ""))))]
2032 "! TARGET_SOFT_FLOAT"
2035 if (INSN_ANNULLED_BRANCH_P (insn))
2036 return \"ftest\;add,tr %%r0,%%r0,%%r0\;b,n %0\";
2038 return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
2040 [(set_attr "type" "fbranch")
2041 (set_attr "length" "12")])
2043 ;; Move instructions
2045 (define_expand "movsi"
2046 [(set (match_operand:SI 0 "general_operand" "")
2047 (match_operand:SI 1 "general_operand" ""))]
2051 if (emit_move_sequence (operands, SImode, 0))
2055 ;; Reloading an SImode or DImode value requires a scratch register if
2056 ;; going in to or out of float point registers.
2058 (define_expand "reload_insi"
2059 [(set (match_operand:SI 0 "register_operand" "=Z")
2060 (match_operand:SI 1 "non_hard_reg_operand" ""))
2061 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2065 if (emit_move_sequence (operands, SImode, operands[2]))
2068 /* We don't want the clobber emitted, so handle this ourselves. */
2069 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2073 (define_expand "reload_outsi"
2074 [(set (match_operand:SI 0 "non_hard_reg_operand" "")
2075 (match_operand:SI 1 "register_operand" "Z"))
2076 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2080 if (emit_move_sequence (operands, SImode, operands[2]))
2083 /* We don't want the clobber emitted, so handle this ourselves. */
2084 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2088 ;;; pic symbol references
2091 [(set (match_operand:SI 0 "register_operand" "=r")
2092 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2093 (match_operand:SI 2 "symbolic_operand" ""))))]
2094 "flag_pic && operands[1] == pic_offset_table_rtx"
2096 [(set_attr "type" "load")
2097 (set_attr "length" "4")])
2100 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
2101 "=r,r,r,r,r,Q,*q,!f,f,*TR")
2102 (match_operand:SI 1 "move_operand"
2103 "r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
2104 "(register_operand (operands[0], SImode)
2105 || reg_or_0_operand (operands[1], SImode))
2106 && ! TARGET_SOFT_FLOAT"
2111 {zdepi|depwi,z} %Z1,%0
2118 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
2119 (set_attr "pa_combine_type" "addmove")
2120 (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
2123 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
2125 (match_operand:SI 1 "move_operand"
2126 "r,J,N,K,RQ,rM,rM"))]
2127 "(register_operand (operands[0], SImode)
2128 || reg_or_0_operand (operands[1], SImode))
2129 && TARGET_SOFT_FLOAT"
2134 {zdepi|depwi,z} %Z1,%0
2138 [(set_attr "type" "move,move,move,move,load,store,move")
2139 (set_attr "pa_combine_type" "addmove")
2140 (set_attr "length" "4,4,4,4,4,4,4")])
2143 [(set (match_operand:SI 0 "register_operand" "=r")
2144 (mem:SI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2145 (match_operand:SI 2 "register_operand" "r"))))]
2146 "! TARGET_DISABLE_INDEXING"
2147 "{ldwx|ldw} %2(%1),%0"
2148 [(set_attr "type" "load")
2149 (set_attr "length" "4")])
2152 [(set (match_operand:SI 0 "register_operand" "=r")
2153 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2154 (match_operand:SI 2 "basereg_operand" "r"))))]
2155 "! TARGET_DISABLE_INDEXING"
2156 "{ldwx|ldw} %1(%2),%0"
2157 [(set_attr "type" "load")
2158 (set_attr "length" "4")])
2160 ;; Load or store with base-register modification.
2162 (define_expand "pre_load"
2163 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2164 (mem (plus (match_operand 1 "register_operand" "")
2165 (match_operand 2 "pre_cint_operand" ""))))
2167 (plus (match_dup 1) (match_dup 2)))])]
2173 emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
2176 emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
2180 (define_insn "pre_ldw"
2181 [(set (match_operand:SI 0 "register_operand" "=r")
2182 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2183 (match_operand:SI 2 "pre_cint_operand" ""))))
2185 (plus:SI (match_dup 1) (match_dup 2)))]
2189 if (INTVAL (operands[2]) < 0)
2190 return \"{ldwm|ldw,mb} %2(%1),%0\";
2191 return \"{ldws|ldw},mb %2(%1),%0\";
2193 [(set_attr "type" "load")
2194 (set_attr "length" "4")])
2196 (define_insn "pre_ldd"
2197 [(set (match_operand:DI 0 "register_operand" "=r")
2198 (mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2199 (match_operand:DI 2 "pre_cint_operand" ""))))
2201 (plus:DI (match_dup 1) (match_dup 2)))]
2204 [(set_attr "type" "load")
2205 (set_attr "length" "4")])
2208 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2209 (match_operand:SI 1 "pre_cint_operand" "")))
2210 (match_operand:SI 2 "reg_or_0_operand" "rM"))
2212 (plus:SI (match_dup 0) (match_dup 1)))]
2216 if (INTVAL (operands[1]) < 0)
2217 return \"{stwm|stw,mb} %r2,%1(%0)\";
2218 return \"{stws|stw},mb %r2,%1(%0)\";
2220 [(set_attr "type" "store")
2221 (set_attr "length" "4")])
2224 [(set (match_operand:SI 0 "register_operand" "=r")
2225 (mem:SI (match_operand:SI 1 "register_operand" "+r")))
2227 (plus:SI (match_dup 1)
2228 (match_operand:SI 2 "post_cint_operand" "")))]
2232 if (INTVAL (operands[2]) > 0)
2233 return \"{ldwm|ldw,ma} %2(%1),%0\";
2234 return \"{ldws|ldw},ma %2(%1),%0\";
2236 [(set_attr "type" "load")
2237 (set_attr "length" "4")])
2239 (define_expand "post_store"
2240 [(parallel [(set (mem (match_operand 0 "register_operand" ""))
2241 (match_operand 1 "reg_or_0_operand" ""))
2244 (match_operand 2 "post_cint_operand" "")))])]
2250 emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
2253 emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
2257 (define_insn "post_stw"
2258 [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
2259 (match_operand:SI 1 "reg_or_0_operand" "rM"))
2261 (plus:SI (match_dup 0)
2262 (match_operand:SI 2 "post_cint_operand" "")))]
2266 if (INTVAL (operands[2]) > 0)
2267 return \"{stwm|stw,ma} %r1,%2(%0)\";
2268 return \"{stws|stw},ma %r1,%2(%0)\";
2270 [(set_attr "type" "store")
2271 (set_attr "length" "4")])
2273 (define_insn "post_std"
2274 [(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
2275 (match_operand:DI 1 "reg_or_0_operand" "rM"))
2277 (plus:DI (match_dup 0)
2278 (match_operand:DI 2 "post_cint_operand" "")))]
2281 [(set_attr "type" "store")
2282 (set_attr "length" "4")])
2284 ;; For loading the address of a label while generating PIC code.
2285 ;; Note since this pattern can be created at reload time (via movsi), all
2286 ;; the same rules for movsi apply here. (no new pseudos, no temporaries).
2288 [(set (match_operand 0 "pmode_register_operand" "=a")
2289 (match_operand 1 "pic_label_operand" ""))]
2293 rtx label_rtx = gen_label_rtx ();
2295 extern FILE *asm_out_file;
2297 xoperands[0] = operands[0];
2298 xoperands[1] = operands[1];
2299 xoperands[2] = label_rtx;
2300 output_asm_insn (\"{bl|b,l} .+8,%0\", xoperands);
2301 output_asm_insn (\"{depi|depwi} 0,31,2,%0\", xoperands);
2302 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
2303 CODE_LABEL_NUMBER (label_rtx));
2305 /* If we're trying to load the address of a label that happens to be
2306 close, then we can use a shorter sequence. */
2307 if (GET_CODE (operands[1]) == LABEL_REF
2308 && INSN_ADDRESSES_SET_P ()
2309 && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2310 - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2312 /* Prefixing with R% here is wrong, it extracts just 11 bits and is
2313 always non-negative. */
2314 output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2318 output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2319 output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2323 [(set_attr "type" "multi")
2324 (set_attr "length" "16")]) ; 12 or 16
2327 [(set (match_operand:SI 0 "register_operand" "=a")
2328 (plus:SI (match_operand:SI 1 "register_operand" "r")
2329 (high:SI (match_operand 2 "" ""))))]
2330 "symbolic_operand (operands[2], Pmode)
2331 && ! function_label_operand (operands[2], Pmode)
2334 [(set_attr "type" "binary")
2335 (set_attr "length" "4")])
2338 [(set (match_operand:DI 0 "register_operand" "=a")
2339 (plus:DI (match_operand:DI 1 "register_operand" "r")
2340 (high:DI (match_operand 2 "" ""))))]
2341 "symbolic_operand (operands[2], Pmode)
2342 && ! function_label_operand (operands[2], Pmode)
2346 [(set_attr "type" "binary")
2347 (set_attr "length" "4")])
2349 ; We need this to make sure CSE doesn't simplify a memory load with a
2350 ; symbolic address, whose content it think it knows. For PIC, what CSE
2351 ; think is the real value will be the address of that value.
2353 [(set (match_operand:SI 0 "register_operand" "=r")
2355 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2357 [(match_operand:SI 2 "symbolic_operand" "")] 0))))]
2363 return \"ldw RT'%G2(%1),%0\";
2365 [(set_attr "type" "load")
2366 (set_attr "length" "4")])
2369 [(set (match_operand:DI 0 "register_operand" "=r")
2371 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2373 [(match_operand:DI 2 "symbolic_operand" "")] 0))))]
2379 return \"ldd RT'%G2(%1),%0\";
2381 [(set_attr "type" "load")
2382 (set_attr "length" "4")])
2384 ;; Always use addil rather than ldil;add sequences. This allows the
2385 ;; HP linker to eliminate the dp relocation if the symbolic operand
2386 ;; lives in the TEXT space.
2388 [(set (match_operand:SI 0 "register_operand" "=a")
2389 (high:SI (match_operand 1 "" "")))]
2390 "symbolic_operand (operands[1], Pmode)
2391 && ! function_label_operand (operands[1], Pmode)
2392 && ! read_only_operand (operands[1], Pmode)
2396 if (TARGET_LONG_LOAD_STORE)
2397 return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
2399 return \"addil LR'%H1,%%r27\";
2401 [(set_attr "type" "binary")
2402 (set (attr "length")
2403 (if_then_else (eq (symbol_ref "TARGET_LONG_LOAD_STORE") (const_int 0))
2408 ;; This is for use in the prologue/epilogue code. We need it
2409 ;; to add large constants to a stack pointer or frame pointer.
2410 ;; Because of the additional %r1 pressure, we probably do not
2411 ;; want to use this in general code, so make it available
2412 ;; only after reload.
2414 [(set (match_operand:SI 0 "register_operand" "=!a,*r")
2415 (plus:SI (match_operand:SI 1 "register_operand" "r,r")
2416 (high:SI (match_operand 2 "const_int_operand" ""))))]
2420 ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2421 [(set_attr "type" "binary,binary")
2422 (set_attr "length" "4,8")])
2425 [(set (match_operand:DI 0 "register_operand" "=!a,*r")
2426 (plus:DI (match_operand:DI 1 "register_operand" "r,r")
2427 (high:DI (match_operand 2 "const_int_operand" ""))))]
2428 "reload_completed && TARGET_64BIT"
2431 ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2432 [(set_attr "type" "binary,binary")
2433 (set_attr "length" "4,8")])
2436 [(set (match_operand:SI 0 "register_operand" "=r")
2437 (high:SI (match_operand 1 "" "")))]
2438 "(!flag_pic || !symbolic_operand (operands[1], Pmode))
2439 && !is_function_label_plus_const (operands[1])"
2442 if (symbolic_operand (operands[1], Pmode))
2443 return \"ldil LR'%H1,%0\";
2445 return \"ldil L'%G1,%0\";
2447 [(set_attr "type" "move")
2448 (set_attr "length" "4")])
2451 [(set (match_operand:DI 0 "register_operand" "=r")
2452 (high:DI (match_operand 1 "const_int_operand" "")))]
2455 [(set_attr "type" "move")
2456 (set_attr "length" "4")])
2459 [(set (match_operand:DI 0 "register_operand" "=r")
2460 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2461 (match_operand:DI 2 "const_int_operand" "i")))]
2464 [(set_attr "type" "move")
2465 (set_attr "length" "4")])
2468 [(set (match_operand:SI 0 "register_operand" "=r")
2469 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2470 (match_operand:SI 2 "immediate_operand" "i")))]
2471 "!is_function_label_plus_const (operands[2])"
2474 if (flag_pic && symbolic_operand (operands[2], Pmode))
2476 else if (symbolic_operand (operands[2], Pmode))
2477 return \"ldo RR'%G2(%1),%0\";
2479 return \"ldo R'%G2(%1),%0\";
2481 [(set_attr "type" "move")
2482 (set_attr "length" "4")])
2484 ;; Now that a symbolic_address plus a constant is broken up early
2485 ;; in the compilation phase (for better CSE) we need a special
2486 ;; combiner pattern to load the symbolic address plus the constant
2487 ;; in only 2 instructions. (For cases where the symbolic address
2488 ;; was not a common subexpression.)
2490 [(set (match_operand:SI 0 "register_operand" "")
2491 (match_operand:SI 1 "symbolic_operand" ""))
2492 (clobber (match_operand:SI 2 "register_operand" ""))]
2493 "! (flag_pic && pic_label_operand (operands[1], SImode))"
2494 [(set (match_dup 2) (high:SI (match_dup 1)))
2495 (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
2498 ;; hppa_legitimize_address goes to a great deal of trouble to
2499 ;; create addresses which use indexing. In some cases, this
2500 ;; is a lose because there isn't any store instructions which
2501 ;; allow indexed addresses (with integer register source).
2503 ;; These define_splits try to turn a 3 insn store into
2504 ;; a 2 insn store with some creative RTL rewriting.
2506 [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2507 (match_operand:SI 1 "shadd_operand" ""))
2508 (plus:SI (match_operand:SI 2 "register_operand" "")
2509 (match_operand:SI 3 "const_int_operand" ""))))
2510 (match_operand:SI 4 "register_operand" ""))
2511 (clobber (match_operand:SI 5 "register_operand" ""))]
2513 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2515 (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2519 [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2520 (match_operand:SI 1 "shadd_operand" ""))
2521 (plus:SI (match_operand:SI 2 "register_operand" "")
2522 (match_operand:SI 3 "const_int_operand" ""))))
2523 (match_operand:HI 4 "register_operand" ""))
2524 (clobber (match_operand:SI 5 "register_operand" ""))]
2526 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2528 (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2532 [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2533 (match_operand:SI 1 "shadd_operand" ""))
2534 (plus:SI (match_operand:SI 2 "register_operand" "")
2535 (match_operand:SI 3 "const_int_operand" ""))))
2536 (match_operand:QI 4 "register_operand" ""))
2537 (clobber (match_operand:SI 5 "register_operand" ""))]
2539 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2541 (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2544 (define_expand "movhi"
2545 [(set (match_operand:HI 0 "general_operand" "")
2546 (match_operand:HI 1 "general_operand" ""))]
2550 if (emit_move_sequence (operands, HImode, 0))
2555 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!*f")
2556 (match_operand:HI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!*fM"))]
2557 "register_operand (operands[0], HImode)
2558 || reg_or_0_operand (operands[1], HImode)"
2563 {zdepi|depwi,z} %Z1,%0
2568 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
2569 (set_attr "pa_combine_type" "addmove")
2570 (set_attr "length" "4,4,4,4,4,4,4,4")])
2573 [(set (match_operand:HI 0 "register_operand" "=r")
2574 (mem:HI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2575 (match_operand:SI 2 "register_operand" "r"))))]
2576 "! TARGET_DISABLE_INDEXING"
2577 "{ldhx|ldh} %2(%1),%0"
2578 [(set_attr "type" "load")
2579 (set_attr "length" "4")])
2582 [(set (match_operand:HI 0 "register_operand" "=r")
2583 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
2584 (match_operand:SI 2 "basereg_operand" "r"))))]
2585 "! TARGET_DISABLE_INDEXING"
2586 "{ldhx|ldh} %1(%2),%0"
2587 [(set_attr "type" "load")
2588 (set_attr "length" "4")])
2590 ; Now zero extended variants.
2592 [(set (match_operand:SI 0 "register_operand" "=r")
2593 (zero_extend:SI (mem:HI
2595 (match_operand:SI 1 "basereg_operand" "r")
2596 (match_operand:SI 2 "register_operand" "r")))))]
2597 "! TARGET_DISABLE_INDEXING"
2598 "{ldhx|ldh} %2(%1),%0"
2599 [(set_attr "type" "load")
2600 (set_attr "length" "4")])
2603 [(set (match_operand:SI 0 "register_operand" "=r")
2604 (zero_extend:SI (mem:HI
2606 (match_operand:SI 1 "register_operand" "r")
2607 (match_operand:SI 2 "basereg_operand" "r")))))]
2608 "! TARGET_DISABLE_INDEXING"
2609 "{ldhx|ldh} %1(%2),%0"
2610 [(set_attr "type" "load")
2611 (set_attr "length" "4")])
2614 [(set (match_operand:HI 0 "register_operand" "=r")
2615 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2616 (match_operand:SI 2 "int5_operand" "L"))))
2618 (plus:SI (match_dup 1) (match_dup 2)))]
2620 "{ldhs|ldh},mb %2(%1),%0"
2621 [(set_attr "type" "load")
2622 (set_attr "length" "4")])
2624 ; And a zero extended variant.
2626 [(set (match_operand:SI 0 "register_operand" "=r")
2627 (zero_extend:SI (mem:HI
2629 (match_operand:SI 1 "register_operand" "+r")
2630 (match_operand:SI 2 "int5_operand" "L")))))
2632 (plus:SI (match_dup 1) (match_dup 2)))]
2634 "{ldhs|ldh},mb %2(%1),%0"
2635 [(set_attr "type" "load")
2636 (set_attr "length" "4")])
2639 [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2640 (match_operand:SI 1 "int5_operand" "L")))
2641 (match_operand:HI 2 "reg_or_0_operand" "rM"))
2643 (plus:SI (match_dup 0) (match_dup 1)))]
2645 "{sths|sth},mb %r2,%1(%0)"
2646 [(set_attr "type" "store")
2647 (set_attr "length" "4")])
2650 [(set (match_operand:HI 0 "register_operand" "=r")
2651 (high:HI (match_operand 1 "const_int_operand" "")))]
2654 [(set_attr "type" "move")
2655 (set_attr "length" "4")])
2658 [(set (match_operand:HI 0 "register_operand" "=r")
2659 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
2660 (match_operand 2 "const_int_operand" "")))]
2663 [(set_attr "type" "move")
2664 (set_attr "length" "4")])
2666 (define_expand "movqi"
2667 [(set (match_operand:QI 0 "general_operand" "")
2668 (match_operand:QI 1 "general_operand" ""))]
2672 if (emit_move_sequence (operands, QImode, 0))
2677 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!*f")
2678 (match_operand:QI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!*fM"))]
2679 "register_operand (operands[0], QImode)
2680 || reg_or_0_operand (operands[1], QImode)"
2685 {zdepi|depwi,z} %Z1,%0
2690 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
2691 (set_attr "pa_combine_type" "addmove")
2692 (set_attr "length" "4,4,4,4,4,4,4,4")])
2695 [(set (match_operand:QI 0 "register_operand" "=r")
2696 (mem:QI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2697 (match_operand:SI 2 "register_operand" "r"))))]
2698 "! TARGET_DISABLE_INDEXING"
2699 "{ldbx|ldb} %2(%1),%0"
2700 [(set_attr "type" "load")
2701 (set_attr "length" "4")])
2704 [(set (match_operand:QI 0 "register_operand" "=r")
2705 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
2706 (match_operand:SI 2 "basereg_operand" "r"))))]
2707 "! TARGET_DISABLE_INDEXING"
2708 "{ldbx|ldb} %1(%2),%0"
2709 [(set_attr "type" "load")
2710 (set_attr "length" "4")])
2712 ; Indexed byte load with zero extension to SImode or HImode.
2714 [(set (match_operand:SI 0 "register_operand" "=r")
2715 (zero_extend:SI (mem:QI
2717 (match_operand:SI 1 "basereg_operand" "r")
2718 (match_operand:SI 2 "register_operand" "r")))))]
2719 "! TARGET_DISABLE_INDEXING"
2720 "{ldbx|ldb} %2(%1),%0"
2721 [(set_attr "type" "load")
2722 (set_attr "length" "4")])
2725 [(set (match_operand:SI 0 "register_operand" "=r")
2726 (zero_extend:SI (mem:QI
2728 (match_operand:SI 1 "register_operand" "r")
2729 (match_operand:SI 2 "basereg_operand" "r")))))]
2730 "! TARGET_DISABLE_INDEXING"
2731 "{ldbx|ldb} %1(%2),%0"
2732 [(set_attr "type" "load")
2733 (set_attr "length" "4")])
2736 [(set (match_operand:HI 0 "register_operand" "=r")
2737 (zero_extend:HI (mem:QI
2739 (match_operand:SI 1 "basereg_operand" "r")
2740 (match_operand:SI 2 "register_operand" "r")))))]
2741 "! TARGET_DISABLE_INDEXING"
2742 "{ldbx|ldb} %2(%1),%0"
2743 [(set_attr "type" "load")
2744 (set_attr "length" "4")])
2747 [(set (match_operand:HI 0 "register_operand" "=r")
2748 (zero_extend:HI (mem:QI
2750 (match_operand:SI 1 "register_operand" "r")
2751 (match_operand:SI 2 "basereg_operand" "r")))))]
2752 "! TARGET_DISABLE_INDEXING"
2753 "{ldbx|ldb} %1(%2),%0"
2754 [(set_attr "type" "load")
2755 (set_attr "length" "4")])
2758 [(set (match_operand:QI 0 "register_operand" "=r")
2759 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2760 (match_operand:SI 2 "int5_operand" "L"))))
2761 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2763 "{ldbs|ldb},mb %2(%1),%0"
2764 [(set_attr "type" "load")
2765 (set_attr "length" "4")])
2767 ; Now the same thing with zero extensions.
2769 [(set (match_operand:SI 0 "register_operand" "=r")
2770 (zero_extend:SI (mem:QI (plus:SI
2771 (match_operand:SI 1 "register_operand" "+r")
2772 (match_operand:SI 2 "int5_operand" "L")))))
2773 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2775 "{ldbs|ldb},mb %2(%1),%0"
2776 [(set_attr "type" "load")
2777 (set_attr "length" "4")])
2780 [(set (match_operand:HI 0 "register_operand" "=r")
2781 (zero_extend:HI (mem:QI (plus:SI
2782 (match_operand:SI 1 "register_operand" "+r")
2783 (match_operand:SI 2 "int5_operand" "L")))))
2784 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2786 "{ldbs|ldb},mb %2(%1),%0"
2787 [(set_attr "type" "load")
2788 (set_attr "length" "4")])
2791 [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2792 (match_operand:SI 1 "int5_operand" "L")))
2793 (match_operand:QI 2 "reg_or_0_operand" "rM"))
2795 (plus:SI (match_dup 0) (match_dup 1)))]
2797 "{stbs|stb},mb %r2,%1(%0)"
2798 [(set_attr "type" "store")
2799 (set_attr "length" "4")])
2801 ;; The definition of this insn does not really explain what it does,
2802 ;; but it should suffice
2803 ;; that anything generated as this insn will be recognized as one
2804 ;; and that it will not successfully combine with anything.
2805 (define_expand "movstrsi"
2806 [(parallel [(set (match_operand:BLK 0 "" "")
2807 (match_operand:BLK 1 "" ""))
2808 (clobber (match_dup 7))
2809 (clobber (match_dup 8))
2810 (clobber (match_dup 4))
2811 (clobber (match_dup 5))
2812 (clobber (match_dup 6))
2813 (use (match_operand:SI 2 "arith_operand" ""))
2814 (use (match_operand:SI 3 "const_int_operand" ""))])]
2820 /* HP provides very fast block move library routine for the PA;
2821 this routine includes:
2823 4x4 byte at a time block moves,
2824 1x4 byte at a time with alignment checked at runtime with
2825 attempts to align the source and destination as needed
2828 With that in mind, here's the heuristics to try and guess when
2829 the inlined block move will be better than the library block
2832 If the size isn't constant, then always use the library routines.
2834 If the size is large in respect to the known alignment, then use
2835 the library routines.
2837 If the size is small in repsect to the known alignment, then open
2838 code the copy (since that will lead to better scheduling).
2840 Else use the block move pattern. */
2842 /* Undetermined size, use the library routine. */
2843 if (GET_CODE (operands[2]) != CONST_INT)
2846 size = INTVAL (operands[2]);
2847 align = INTVAL (operands[3]);
2848 align = align > 4 ? 4 : align;
2850 /* If size/alignment > 8 (eg size is large in respect to alignment),
2851 then use the library routines. */
2852 if (size / align > 16)
2855 /* This does happen, but not often enough to worry much about. */
2856 if (size / align < MOVE_RATIO)
2859 /* Fall through means we're going to use our block move pattern. */
2861 = change_address (operands[0], VOIDmode,
2862 copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
2864 = change_address (operands[1], VOIDmode,
2865 copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
2866 operands[4] = gen_reg_rtx (SImode);
2867 operands[5] = gen_reg_rtx (SImode);
2868 operands[6] = gen_reg_rtx (SImode);
2869 operands[7] = XEXP (operands[0], 0);
2870 operands[8] = XEXP (operands[1], 0);
2873 ;; The operand constraints are written like this to support both compile-time
2874 ;; and run-time determined byte count. If the count is run-time determined,
2875 ;; the register with the byte count is clobbered by the copying code, and
2876 ;; therefore it is forced to operand 2. If the count is compile-time
2877 ;; determined, we need two scratch registers for the unrolled code.
2878 (define_insn "movstrsi_internal"
2879 [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
2880 (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
2881 (clobber (match_dup 0))
2882 (clobber (match_dup 1))
2883 (clobber (match_operand:SI 2 "register_operand" "=r,r")) ;loop cnt/tmp
2884 (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp
2885 (clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
2886 (use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count
2887 (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
2889 "* return output_block_move (operands, !which_alternative);"
2890 [(set_attr "type" "multi,multi")])
2892 ;; Floating point move insns
2894 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2895 ;; to be reloaded by putting the constant into memory when
2896 ;; reg is a floating point register.
2898 ;; For integer registers we use ldil;ldo to set the appropriate
2901 ;; This must come before the movdf pattern, and it must be present
2902 ;; to handle obscure reloading cases.
2904 [(set (match_operand:DF 0 "register_operand" "=?r,f")
2905 (match_operand:DF 1 "" "?F,m"))]
2906 "GET_CODE (operands[1]) == CONST_DOUBLE
2907 && operands[1] != CONST0_RTX (DFmode)
2909 && ! TARGET_SOFT_FLOAT"
2910 "* return (which_alternative == 0 ? output_move_double (operands)
2911 : \"fldd%F1 %1,%0\");"
2912 [(set_attr "type" "move,fpload")
2913 (set_attr "length" "16,4")])
2915 (define_expand "movdf"
2916 [(set (match_operand:DF 0 "general_operand" "")
2917 (match_operand:DF 1 "general_operand" ""))]
2921 if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT)
2922 operands[1] = force_const_mem (DFmode, operands[1]);
2924 if (emit_move_sequence (operands, DFmode, 0))
2928 ;; Reloading an SImode or DImode value requires a scratch register if
2929 ;; going in to or out of float point registers.
2931 (define_expand "reload_indf"
2932 [(set (match_operand:DF 0 "register_operand" "=Z")
2933 (match_operand:DF 1 "non_hard_reg_operand" ""))
2934 (clobber (match_operand:DF 2 "register_operand" "=&r"))]
2938 if (emit_move_sequence (operands, DFmode, operands[2]))
2941 /* We don't want the clobber emitted, so handle this ourselves. */
2942 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2946 (define_expand "reload_outdf"
2947 [(set (match_operand:DF 0 "non_hard_reg_operand" "")
2948 (match_operand:DF 1 "register_operand" "Z"))
2949 (clobber (match_operand:DF 2 "register_operand" "=&r"))]
2953 if (emit_move_sequence (operands, DFmode, operands[2]))
2956 /* We don't want the clobber emitted, so handle this ourselves. */
2957 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2962 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
2963 "=f,*r,RQ,?o,?Q,f,*r,*r")
2964 (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
2965 "fG,*rG,f,*r,*r,RQ,o,RQ"))]
2966 "(register_operand (operands[0], DFmode)
2967 || reg_or_0_operand (operands[1], DFmode))
2968 && ! (GET_CODE (operands[1]) == CONST_DOUBLE
2969 && GET_CODE (operands[0]) == MEM)
2971 && ! TARGET_SOFT_FLOAT"
2974 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
2975 || operands[1] == CONST0_RTX (DFmode))
2976 return output_fp_move_double (operands);
2977 return output_move_double (operands);
2979 [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load")
2980 (set_attr "length" "4,8,4,8,16,4,8,16")])
2983 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
2985 (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
2987 "(register_operand (operands[0], DFmode)
2988 || reg_or_0_operand (operands[1], DFmode))
2990 && TARGET_SOFT_FLOAT"
2993 return output_move_double (operands);
2995 [(set_attr "type" "move,store,store,load,load")
2996 (set_attr "length" "8,8,16,8,16")])
2999 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
3000 "=r,r,r,r,r,Q,*q,!f,f,*TR")
3001 (match_operand:DF 1 "move_operand"
3002 "r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
3003 "(register_operand (operands[0], DFmode)
3004 || reg_or_0_operand (operands[1], DFmode))
3005 && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
3017 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
3018 (set_attr "pa_combine_type" "addmove")
3019 (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
3022 [(set (match_operand:DF 0 "register_operand" "=fx")
3023 (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
3024 (match_operand:SI 2 "register_operand" "r"))))]
3025 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3026 "{flddx|fldd} %2(%1),%0"
3027 [(set_attr "type" "fpload")
3028 (set_attr "length" "4")])
3031 [(set (match_operand:DF 0 "register_operand" "=fx")
3032 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
3033 (match_operand:SI 2 "basereg_operand" "r"))))]
3034 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3035 "{flddx|fldd} %1(%2),%0"
3036 [(set_attr "type" "fpload")
3037 (set_attr "length" "4")])
3040 [(set (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
3041 (match_operand:SI 2 "register_operand" "r")))
3042 (match_operand:DF 0 "register_operand" "fx"))]
3043 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3044 "{fstdx|fstd} %0,%2(%1)"
3045 [(set_attr "type" "fpstore")
3046 (set_attr "length" "4")])
3049 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
3050 (match_operand:SI 2 "basereg_operand" "r")))
3051 (match_operand:DF 0 "register_operand" "fx"))]
3052 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3053 "{fstdx|fstd} %0,%1(%2)"
3054 [(set_attr "type" "fpstore")
3055 (set_attr "length" "4")])
3057 (define_expand "movdi"
3058 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
3059 (match_operand:DI 1 "general_operand" ""))]
3063 if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT)
3064 operands[1] = force_const_mem (DImode, operands[1]);
3066 if (emit_move_sequence (operands, DImode, 0))
3070 (define_expand "reload_indi"
3071 [(set (match_operand:DI 0 "register_operand" "=Z")
3072 (match_operand:DI 1 "non_hard_reg_operand" ""))
3073 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
3077 if (emit_move_sequence (operands, DImode, operands[2]))
3080 /* We don't want the clobber emitted, so handle this ourselves. */
3081 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3085 (define_expand "reload_outdi"
3086 [(set (match_operand:DI 0 "general_operand" "")
3087 (match_operand:DI 1 "register_operand" "Z"))
3088 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
3092 if (emit_move_sequence (operands, DImode, operands[2]))
3095 /* We don't want the clobber emitted, so handle this ourselves. */
3096 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3101 [(set (match_operand:DI 0 "register_operand" "=r")
3102 (high:DI (match_operand 1 "" "")))]
3106 rtx op0 = operands[0];
3107 rtx op1 = operands[1];
3109 if (GET_CODE (op1) == CONST_INT)
3111 operands[0] = operand_subword (op0, 1, 0, DImode);
3112 output_asm_insn (\"ldil L'%1,%0\", operands);
3114 operands[0] = operand_subword (op0, 0, 0, DImode);
3115 if (INTVAL (op1) < 0)
3116 output_asm_insn (\"ldi -1,%0\", operands);
3118 output_asm_insn (\"ldi 0,%0\", operands);
3121 else if (GET_CODE (op1) == CONST_DOUBLE)
3123 operands[0] = operand_subword (op0, 1, 0, DImode);
3124 operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
3125 output_asm_insn (\"ldil L'%1,%0\", operands);
3127 operands[0] = operand_subword (op0, 0, 0, DImode);
3128 operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
3129 output_asm_insn (singlemove_string (operands), operands);
3135 [(set_attr "type" "move")
3136 (set_attr "length" "8")])
3139 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
3140 "=r,o,Q,r,r,r,f,f,*TR")
3141 (match_operand:DI 1 "general_operand"
3142 "rM,r,r,o*R,Q,i,fM,*TR,f"))]
3143 "(register_operand (operands[0], DImode)
3144 || reg_or_0_operand (operands[1], DImode))
3146 && ! TARGET_SOFT_FLOAT"
3149 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
3150 || (operands[1] == CONST0_RTX (DImode)))
3151 return output_fp_move_double (operands);
3152 return output_move_double (operands);
3154 [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore")
3155 (set_attr "length" "8,8,16,8,16,16,4,4,4")])
3158 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
3159 "=r,r,r,r,r,Q,*q,!f,f,*TR")
3160 (match_operand:DI 1 "move_operand"
3161 "r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
3162 "(register_operand (operands[0], DImode)
3163 || reg_or_0_operand (operands[1], DImode))
3164 && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
3176 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
3177 (set_attr "pa_combine_type" "addmove")
3178 (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
3181 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
3183 (match_operand:DI 1 "general_operand"
3185 "(register_operand (operands[0], DImode)
3186 || reg_or_0_operand (operands[1], DImode))
3188 && TARGET_SOFT_FLOAT"
3191 return output_move_double (operands);
3193 [(set_attr "type" "move,store,store,load,load,multi")
3194 (set_attr "length" "8,8,16,8,16,16")])
3197 [(set (match_operand:DI 0 "register_operand" "=r,&r")
3198 (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
3199 (match_operand:DI 2 "immediate_operand" "i,i")))]
3203 /* Don't output a 64 bit constant, since we can't trust the assembler to
3204 handle it correctly. */
3205 if (GET_CODE (operands[2]) == CONST_DOUBLE)
3206 operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
3207 if (which_alternative == 1)
3208 output_asm_insn (\"copy %1,%0\", operands);
3209 return \"ldo R'%G2(%R1),%R0\";
3211 [(set_attr "type" "move,move")
3212 (set_attr "length" "4,8")])
3214 ;; This pattern forces (set (reg:SF ...) (const_double ...))
3215 ;; to be reloaded by putting the constant into memory when
3216 ;; reg is a floating point register.
3218 ;; For integer registers we use ldil;ldo to set the appropriate
3221 ;; This must come before the movsf pattern, and it must be present
3222 ;; to handle obscure reloading cases.
3224 [(set (match_operand:SF 0 "register_operand" "=?r,f")
3225 (match_operand:SF 1 "" "?F,m"))]
3226 "GET_CODE (operands[1]) == CONST_DOUBLE
3227 && operands[1] != CONST0_RTX (SFmode)
3228 && ! TARGET_SOFT_FLOAT"
3229 "* return (which_alternative == 0 ? singlemove_string (operands)
3230 : \" fldw%F1 %1,%0\");"
3231 [(set_attr "type" "move,fpload")
3232 (set_attr "length" "8,4")])
3234 (define_expand "movsf"
3235 [(set (match_operand:SF 0 "general_operand" "")
3236 (match_operand:SF 1 "general_operand" ""))]
3240 if (emit_move_sequence (operands, SFmode, 0))
3244 ;; Reloading an SImode or DImode value requires a scratch register if
3245 ;; going in to or out of float point registers.
3247 (define_expand "reload_insf"
3248 [(set (match_operand:SF 0 "register_operand" "=Z")
3249 (match_operand:SF 1 "non_hard_reg_operand" ""))
3250 (clobber (match_operand:SF 2 "register_operand" "=&r"))]
3254 if (emit_move_sequence (operands, SFmode, operands[2]))
3257 /* We don't want the clobber emitted, so handle this ourselves. */
3258 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3262 (define_expand "reload_outsf"
3263 [(set (match_operand:SF 0 "non_hard_reg_operand" "")
3264 (match_operand:SF 1 "register_operand" "Z"))
3265 (clobber (match_operand:SF 2 "register_operand" "=&r"))]
3269 if (emit_move_sequence (operands, SFmode, operands[2]))
3272 /* We don't want the clobber emitted, so handle this ourselves. */
3273 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3278 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
3280 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
3281 "fG,rG,RQ,RQ,f,rG"))]
3282 "(register_operand (operands[0], SFmode)
3283 || reg_or_0_operand (operands[1], SFmode))
3284 && ! TARGET_SOFT_FLOAT"
3292 [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
3293 (set_attr "pa_combine_type" "addmove")
3294 (set_attr "length" "4,4,4,4,4,4")])
3297 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
3299 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
3301 "(register_operand (operands[0], SFmode)
3302 || reg_or_0_operand (operands[1], SFmode))
3303 && TARGET_SOFT_FLOAT"
3308 [(set_attr "type" "move,load,store")
3309 (set_attr "pa_combine_type" "addmove")
3310 (set_attr "length" "4,4,4")])
3313 [(set (match_operand:SF 0 "register_operand" "=fx")
3314 (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
3315 (match_operand:SI 2 "register_operand" "r"))))]
3316 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3317 "{fldwx|fldw} %2(%1),%0"
3318 [(set_attr "type" "fpload")
3319 (set_attr "length" "4")])
3322 [(set (match_operand:SF 0 "register_operand" "=fx")
3323 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
3324 (match_operand:SI 2 "basereg_operand" "r"))))]
3325 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3326 "{fldwx|fldw} %1(%2),%0"
3327 [(set_attr "type" "fpload")
3328 (set_attr "length" "4")])
3331 [(set (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
3332 (match_operand:SI 2 "register_operand" "r")))
3333 (match_operand:SF 0 "register_operand" "fx"))]
3334 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3335 "{fstwx|fstw} %0,%2(%1)"
3336 [(set_attr "type" "fpstore")
3337 (set_attr "length" "4")])
3340 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
3341 (match_operand:SI 2 "basereg_operand" "r")))
3342 (match_operand:SF 0 "register_operand" "fx"))]
3343 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3344 "{fstwx|fstw} %0,%1(%2)"
3345 [(set_attr "type" "fpstore")
3346 (set_attr "length" "4")])
3349 ;;- zero extension instructions
3350 ;; We have define_expand for zero extension patterns to make sure the
3351 ;; operands get loaded into registers. The define_insns accept
3352 ;; memory operands. This gives us better overall code than just
3353 ;; having a pattern that does or does not accept memory operands.
3355 (define_expand "zero_extendhisi2"
3356 [(set (match_operand:SI 0 "register_operand" "")
3358 (match_operand:HI 1 "register_operand" "")))]
3363 [(set (match_operand:SI 0 "register_operand" "=r,r")
3365 (match_operand:HI 1 "move_operand" "r,RQ")))]
3366 "GET_CODE (operands[1]) != CONST_INT"
3368 {extru|extrw,u} %1,31,16,%0
3370 [(set_attr "type" "shift,load")
3371 (set_attr "length" "4,4")])
3373 (define_expand "zero_extendqihi2"
3374 [(set (match_operand:HI 0 "register_operand" "")
3376 (match_operand:QI 1 "register_operand" "")))]
3381 [(set (match_operand:HI 0 "register_operand" "=r,r")
3383 (match_operand:QI 1 "move_operand" "r,RQ")))]
3384 "GET_CODE (operands[1]) != CONST_INT"
3386 {extru|extrw,u} %1,31,8,%0
3388 [(set_attr "type" "shift,load")
3389 (set_attr "length" "4,4")])
3391 (define_expand "zero_extendqisi2"
3392 [(set (match_operand:SI 0 "register_operand" "")
3394 (match_operand:QI 1 "register_operand" "")))]
3399 [(set (match_operand:SI 0 "register_operand" "=r,r")
3401 (match_operand:QI 1 "move_operand" "r,RQ")))]
3402 "GET_CODE (operands[1]) != CONST_INT"
3404 {extru|extrw,u} %1,31,8,%0
3406 [(set_attr "type" "shift,load")
3407 (set_attr "length" "4,4")])
3409 (define_insn "zero_extendqidi2"
3410 [(set (match_operand:DI 0 "register_operand" "=r")
3411 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
3413 "extrd,u %1,63,8,%0"
3414 [(set_attr "type" "shift")
3415 (set_attr "length" "4")])
3417 (define_insn "zero_extendhidi2"
3418 [(set (match_operand:DI 0 "register_operand" "=r")
3419 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
3421 "extrd,u %1,63,16,%0"
3422 [(set_attr "type" "shift")
3423 (set_attr "length" "4")])
3425 (define_insn "zero_extendsidi2"
3426 [(set (match_operand:DI 0 "register_operand" "=r")
3427 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3429 "extrd,u %1,63,32,%0"
3430 [(set_attr "type" "shift")
3431 (set_attr "length" "4")])
3433 ;;- sign extension instructions
3435 (define_insn "extendhisi2"
3436 [(set (match_operand:SI 0 "register_operand" "=r")
3437 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3439 "{extrs|extrw,s} %1,31,16,%0"
3440 [(set_attr "type" "shift")
3441 (set_attr "length" "4")])
3443 (define_insn "extendqihi2"
3444 [(set (match_operand:HI 0 "register_operand" "=r")
3445 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
3447 "{extrs|extrw,s} %1,31,8,%0"
3448 [(set_attr "type" "shift")
3449 (set_attr "length" "4")])
3451 (define_insn "extendqisi2"
3452 [(set (match_operand:SI 0 "register_operand" "=r")
3453 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3455 "{extrs|extrw,s} %1,31,8,%0"
3456 [(set_attr "type" "shift")
3457 (set_attr "length" "4")])
3459 (define_insn "extendqidi2"
3460 [(set (match_operand:DI 0 "register_operand" "=r")
3461 (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
3463 "extrd,s %1,63,8,%0"
3464 [(set_attr "type" "shift")
3465 (set_attr "length" "4")])
3467 (define_insn "extendhidi2"
3468 [(set (match_operand:DI 0 "register_operand" "=r")
3469 (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
3471 "extrd,s %1,63,16,%0"
3472 [(set_attr "type" "shift")
3473 (set_attr "length" "4")])
3475 (define_insn "extendsidi2"
3476 [(set (match_operand:DI 0 "register_operand" "=r")
3477 (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3479 "extrd,s %1,63,32,%0"
3480 [(set_attr "type" "shift")
3481 (set_attr "length" "4")])
3484 ;; Conversions between float and double.
3486 (define_insn "extendsfdf2"
3487 [(set (match_operand:DF 0 "register_operand" "=f")
3489 (match_operand:SF 1 "register_operand" "f")))]
3490 "! TARGET_SOFT_FLOAT"
3491 "{fcnvff|fcnv},sgl,dbl %1,%0"
3492 [(set_attr "type" "fpalu")
3493 (set_attr "length" "4")])
3495 (define_insn "truncdfsf2"
3496 [(set (match_operand:SF 0 "register_operand" "=f")
3498 (match_operand:DF 1 "register_operand" "f")))]
3499 "! TARGET_SOFT_FLOAT"
3500 "{fcnvff|fcnv},dbl,sgl %1,%0"
3501 [(set_attr "type" "fpalu")
3502 (set_attr "length" "4")])
3504 ;; Conversion between fixed point and floating point.
3505 ;; Note that among the fix-to-float insns
3506 ;; the ones that start with SImode come first.
3507 ;; That is so that an operand that is a CONST_INT
3508 ;; (and therefore lacks a specific machine mode).
3509 ;; will be recognized as SImode (which is always valid)
3510 ;; rather than as QImode or HImode.
3512 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
3513 ;; to be reloaded by putting the constant into memory.
3514 ;; It must come before the more general floatsisf2 pattern.
3516 [(set (match_operand:SF 0 "register_operand" "=f")
3517 (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
3518 "! TARGET_SOFT_FLOAT"
3519 "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
3520 [(set_attr "type" "fpalu")
3521 (set_attr "length" "8")])
3523 (define_insn "floatsisf2"
3524 [(set (match_operand:SF 0 "register_operand" "=f")
3525 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3526 "! TARGET_SOFT_FLOAT"
3527 "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
3528 [(set_attr "type" "fpalu")
3529 (set_attr "length" "4")])
3531 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
3532 ;; to be reloaded by putting the constant into memory.
3533 ;; It must come before the more general floatsidf2 pattern.
3535 [(set (match_operand:DF 0 "register_operand" "=f")
3536 (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
3537 "! TARGET_SOFT_FLOAT"
3538 "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
3539 [(set_attr "type" "fpalu")
3540 (set_attr "length" "8")])
3542 (define_insn "floatsidf2"
3543 [(set (match_operand:DF 0 "register_operand" "=f")
3544 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3545 "! TARGET_SOFT_FLOAT"
3546 "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
3547 [(set_attr "type" "fpalu")
3548 (set_attr "length" "4")])
3550 (define_expand "floatunssisf2"
3551 [(set (subreg:SI (match_dup 2) 1)
3552 (match_operand:SI 1 "register_operand" ""))
3553 (set (subreg:SI (match_dup 2) 0)
3555 (set (match_operand:SF 0 "register_operand" "")
3556 (float:SF (match_dup 2)))]
3557 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3562 emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
3565 operands[2] = gen_reg_rtx (DImode);
3568 (define_expand "floatunssidf2"
3569 [(set (subreg:SI (match_dup 2) 1)
3570 (match_operand:SI 1 "register_operand" ""))
3571 (set (subreg:SI (match_dup 2) 0)
3573 (set (match_operand:DF 0 "register_operand" "")
3574 (float:DF (match_dup 2)))]
3575 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3580 emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
3583 operands[2] = gen_reg_rtx (DImode);
3586 (define_insn "floatdisf2"
3587 [(set (match_operand:SF 0 "register_operand" "=f")
3588 (float:SF (match_operand:DI 1 "register_operand" "f")))]
3589 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3590 "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
3591 [(set_attr "type" "fpalu")
3592 (set_attr "length" "4")])
3594 (define_insn "floatdidf2"
3595 [(set (match_operand:DF 0 "register_operand" "=f")
3596 (float:DF (match_operand:DI 1 "register_operand" "f")))]
3597 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3598 "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
3599 [(set_attr "type" "fpalu")
3600 (set_attr "length" "4")])
3602 ;; Convert a float to an actual integer.
3603 ;; Truncation is performed as part of the conversion.
3605 (define_insn "fix_truncsfsi2"
3606 [(set (match_operand:SI 0 "register_operand" "=f")
3607 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3608 "! TARGET_SOFT_FLOAT"
3609 "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
3610 [(set_attr "type" "fpalu")
3611 (set_attr "length" "4")])
3613 (define_insn "fix_truncdfsi2"
3614 [(set (match_operand:SI 0 "register_operand" "=f")
3615 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3616 "! TARGET_SOFT_FLOAT"
3617 "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
3618 [(set_attr "type" "fpalu")
3619 (set_attr "length" "4")])
3621 (define_insn "fix_truncsfdi2"
3622 [(set (match_operand:DI 0 "register_operand" "=f")
3623 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3624 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3625 "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
3626 [(set_attr "type" "fpalu")
3627 (set_attr "length" "4")])
3629 (define_insn "fix_truncdfdi2"
3630 [(set (match_operand:DI 0 "register_operand" "=f")
3631 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3632 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3633 "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
3634 [(set_attr "type" "fpalu")
3635 (set_attr "length" "4")])
3637 (define_insn "floatunssidf2_pa20"
3638 [(set (match_operand:DF 0 "register_operand" "=f")
3639 (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
3640 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3642 [(set_attr "type" "fpalu")
3643 (set_attr "length" "4")])
3645 (define_insn "floatunssisf2_pa20"
3646 [(set (match_operand:SF 0 "register_operand" "=f")
3647 (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
3648 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3650 [(set_attr "type" "fpalu")
3651 (set_attr "length" "4")])
3653 (define_insn "floatunsdisf2"
3654 [(set (match_operand:SF 0 "register_operand" "=f")
3655 (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
3656 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3657 "fcnv,udw,sgl %1,%0"
3658 [(set_attr "type" "fpalu")
3659 (set_attr "length" "4")])
3661 (define_insn "floatunsdidf2"
3662 [(set (match_operand:DF 0 "register_operand" "=f")
3663 (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
3664 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3665 "fcnv,udw,dbl %1,%0"
3666 [(set_attr "type" "fpalu")
3667 (set_attr "length" "4")])
3669 (define_insn "fixuns_truncsfsi2"
3670 [(set (match_operand:SI 0 "register_operand" "=f")
3671 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3672 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3673 "fcnv,t,sgl,uw %1,%0"
3674 [(set_attr "type" "fpalu")
3675 (set_attr "length" "4")])
3677 (define_insn "fixuns_truncdfsi2"
3678 [(set (match_operand:SI 0 "register_operand" "=f")
3679 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3680 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3681 "fcnv,t,dbl,uw %1,%0"
3682 [(set_attr "type" "fpalu")
3683 (set_attr "length" "4")])
3685 (define_insn "fixuns_truncsfdi2"
3686 [(set (match_operand:DI 0 "register_operand" "=f")
3687 (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3688 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3689 "fcnv,t,sgl,udw %1,%0"
3690 [(set_attr "type" "fpalu")
3691 (set_attr "length" "4")])
3693 (define_insn "fixuns_truncdfdi2"
3694 [(set (match_operand:DI 0 "register_operand" "=f")
3695 (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3696 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3697 "fcnv,t,dbl,udw %1,%0"
3698 [(set_attr "type" "fpalu")
3699 (set_attr "length" "4")])
3701 ;;- arithmetic instructions
3703 (define_expand "adddi3"
3704 [(set (match_operand:DI 0 "register_operand" "")
3705 (plus:DI (match_operand:DI 1 "register_operand" "")
3706 (match_operand:DI 2 "arith_operand" "")))]
3710 ;; We allow arith_operand for operands2, even though strictly speaking it
3711 ;; we would prefer to us arith11_operand since that's what the hardware
3712 ;; can actually support.
3714 ;; But the price of the extra reload in that case is worth the simplicity
3715 ;; we get by allowing a trivial adddi3 expander to be used for both
3719 [(set (match_operand:DI 0 "register_operand" "=r")
3720 (plus:DI (match_operand:DI 1 "register_operand" "%r")
3721 (match_operand:DI 2 "arith_operand" "rI")))]
3725 if (GET_CODE (operands[2]) == CONST_INT)
3727 if (INTVAL (operands[2]) >= 0)
3728 return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
3730 return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
3733 return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
3735 [(set_attr "type" "binary")
3736 (set_attr "length" "8")])
3739 [(set (match_operand:DI 0 "register_operand" "=r,r")
3740 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3741 (match_operand:DI 2 "arith_operand" "r,J")))]
3744 {addl|add,l} %1,%2,%0
3746 [(set_attr "type" "binary,binary")
3747 (set_attr "pa_combine_type" "addmove")
3748 (set_attr "length" "4,4")])
3751 [(set (match_operand:DI 0 "register_operand" "=r")
3752 (plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3753 (match_operand:DI 2 "register_operand" "r")))]
3756 [(set_attr "type" "binary")
3757 (set_attr "length" "4")])
3760 [(set (match_operand:SI 0 "register_operand" "=r")
3761 (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3762 (match_operand:SI 2 "register_operand" "r")))]
3765 [(set_attr "type" "binary")
3766 (set_attr "length" "4")])
3768 ;; define_splits to optimize cases of adding a constant integer
3769 ;; to a register when the constant does not fit in 14 bits. */
3771 [(set (match_operand:SI 0 "register_operand" "")
3772 (plus:SI (match_operand:SI 1 "register_operand" "")
3773 (match_operand:SI 2 "const_int_operand" "")))
3774 (clobber (match_operand:SI 4 "register_operand" ""))]
3775 "! cint_ok_for_move (INTVAL (operands[2]))
3776 && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
3777 [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
3778 (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
3781 int val = INTVAL (operands[2]);
3782 int low = (val < 0) ? -0x2000 : 0x1fff;
3783 int rest = val - low;
3785 operands[2] = GEN_INT (rest);
3786 operands[3] = GEN_INT (low);
3790 [(set (match_operand:SI 0 "register_operand" "")
3791 (plus:SI (match_operand:SI 1 "register_operand" "")
3792 (match_operand:SI 2 "const_int_operand" "")))
3793 (clobber (match_operand:SI 4 "register_operand" ""))]
3794 "! cint_ok_for_move (INTVAL (operands[2]))"
3795 [(set (match_dup 4) (match_dup 2))
3796 (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
3800 HOST_WIDE_INT intval = INTVAL (operands[2]);
3802 /* Try dividing the constant by 2, then 4, and finally 8 to see
3803 if we can get a constant which can be loaded into a register
3804 in a single instruction (cint_ok_for_move).
3806 If that fails, try to negate the constant and subtract it
3807 from our input operand. */
3808 if (intval % 2 == 0 && cint_ok_for_move (intval / 2))
3810 operands[2] = GEN_INT (intval / 2);
3811 operands[3] = GEN_INT (2);
3813 else if (intval % 4 == 0 && cint_ok_for_move (intval / 4))
3815 operands[2] = GEN_INT (intval / 4);
3816 operands[3] = GEN_INT (4);
3818 else if (intval % 8 == 0 && cint_ok_for_move (intval / 8))
3820 operands[2] = GEN_INT (intval / 8);
3821 operands[3] = GEN_INT (8);
3823 else if (cint_ok_for_move (-intval))
3825 emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval)));
3826 emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
3833 (define_insn "addsi3"
3834 [(set (match_operand:SI 0 "register_operand" "=r,r")
3835 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3836 (match_operand:SI 2 "arith_operand" "r,J")))]
3839 {addl|add,l} %1,%2,%0
3841 [(set_attr "type" "binary,binary")
3842 (set_attr "pa_combine_type" "addmove")
3843 (set_attr "length" "4,4")])
3845 (define_expand "subdi3"
3846 [(set (match_operand:DI 0 "register_operand" "")
3847 (minus:DI (match_operand:DI 1 "register_operand" "")
3848 (match_operand:DI 2 "register_operand" "")))]
3853 [(set (match_operand:DI 0 "register_operand" "=r")
3854 (minus:DI (match_operand:DI 1 "register_operand" "r")
3855 (match_operand:DI 2 "register_operand" "r")))]
3857 "sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0"
3858 [(set_attr "type" "binary")
3859 (set_attr "length" "8")])
3862 [(set (match_operand:DI 0 "register_operand" "=r,r,q")
3863 (minus:DI (match_operand:DI 1 "arith11_operand" "r,I,U")
3864 (match_operand:DI 2 "register_operand" "r,r,r")))]
3870 [(set_attr "type" "binary,binary,move")
3871 (set_attr "length" "4,4,4")])
3873 (define_expand "subsi3"
3874 [(set (match_operand:SI 0 "register_operand" "")
3875 (minus:SI (match_operand:SI 1 "arith11_operand" "")
3876 (match_operand:SI 2 "register_operand" "")))]
3881 [(set (match_operand:SI 0 "register_operand" "=r,r")
3882 (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
3883 (match_operand:SI 2 "register_operand" "r,r")))]
3888 [(set_attr "type" "binary,binary")
3889 (set_attr "length" "4,4")])
3892 [(set (match_operand:SI 0 "register_operand" "=r,r,q")
3893 (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,S")
3894 (match_operand:SI 2 "register_operand" "r,r,r")))]
3900 [(set_attr "type" "binary,binary,move")
3901 (set_attr "length" "4,4,4")])
3903 ;; Clobbering a "register_operand" instead of a match_scratch
3904 ;; in operand3 of millicode calls avoids spilling %r1 and
3905 ;; produces better code.
3907 ;; The mulsi3 insns set up registers for the millicode call.
3908 (define_expand "mulsi3"
3909 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3910 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3911 (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
3912 (clobber (match_dup 3))
3913 (clobber (reg:SI 26))
3914 (clobber (reg:SI 25))
3915 (clobber (reg:SI 31))])
3916 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3920 if (TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT)
3922 rtx scratch = gen_reg_rtx (DImode);
3923 operands[1] = force_reg (SImode, operands[1]);
3924 operands[2] = force_reg (SImode, operands[2]);
3925 emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
3926 /* We do not want (subreg:SI (XX:DI) 1)) for TARGET_64BIT since
3927 that has no real meaning. */
3930 emit_insn (gen_rtx_SET (VOIDmode,
3932 gen_rtx_SUBREG (SImode, scratch, 0)));
3936 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3937 gen_rtx_SUBREG (SImode, scratch, 1)));
3940 operands[3] = gen_reg_rtx (SImode);
3943 (define_insn "umulsidi3"
3944 [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3945 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3946 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
3947 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
3949 [(set_attr "type" "fpmuldbl")
3950 (set_attr "length" "4")])
3953 [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3954 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3955 (match_operand:DI 2 "uint32_operand" "f")))]
3956 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && !TARGET_64BIT"
3958 [(set_attr "type" "fpmuldbl")
3959 (set_attr "length" "4")])
3962 [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3963 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3964 (match_operand:DI 2 "uint32_operand" "f")))]
3965 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
3967 [(set_attr "type" "fpmuldbl")
3968 (set_attr "length" "4")])
3971 [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
3972 (clobber (match_operand:SI 0 "register_operand" "=a"))
3973 (clobber (reg:SI 26))
3974 (clobber (reg:SI 25))
3975 (clobber (reg:SI 31))]
3977 "* return output_mul_insn (0, insn);"
3978 [(set_attr "type" "milli")
3979 (set (attr "length")
3981 ;; Target (or stub) within reach
3982 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3984 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3989 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3993 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3994 ;; same as NO_SPACE_REGS code
3995 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3997 (eq (symbol_ref "flag_pic")
4001 ;; Out of range and either PIC or PORTABLE_RUNTIME
4004 (define_expand "muldi3"
4005 [(set (match_operand:DI 0 "register_operand" "")
4006 (mult:DI (match_operand:DI 1 "register_operand" "")
4007 (match_operand:DI 2 "register_operand" "")))]
4008 "TARGET_64BIT && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
4011 rtx low_product = gen_reg_rtx (DImode);
4012 rtx cross_product1 = gen_reg_rtx (DImode);
4013 rtx cross_product2 = gen_reg_rtx (DImode);
4014 rtx cross_scratch = gen_reg_rtx (DImode);
4015 rtx cross_product = gen_reg_rtx (DImode);
4016 rtx op1l, op1r, op2l, op2r;
4017 rtx op1shifted, op2shifted;
4019 op1shifted = gen_reg_rtx (DImode);
4020 op2shifted = gen_reg_rtx (DImode);
4021 op1l = gen_reg_rtx (SImode);
4022 op1r = gen_reg_rtx (SImode);
4023 op2l = gen_reg_rtx (SImode);
4024 op2r = gen_reg_rtx (SImode);
4026 emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
4028 emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
4030 op1r = gen_rtx_SUBREG (SImode, operands[1], 0);
4031 op2r = gen_rtx_SUBREG (SImode, operands[2], 0);
4032 op1l = gen_rtx_SUBREG (SImode, op1shifted, 0);
4033 op2l = gen_rtx_SUBREG (SImode, op2shifted, 0);
4035 /* Emit multiplies for the cross products. */
4036 emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
4037 emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
4039 /* Emit a multiply for the low sub-word. */
4040 emit_insn (gen_umulsidi3 (low_product, op2r, op1r));
4042 /* Sum the cross products and shift them into proper position. */
4043 emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
4044 emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
4046 /* Add the cross product to the low product and store the result
4047 into the output operand . */
4048 emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
4052 ;;; Division and mod.
4053 (define_expand "divsi3"
4054 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
4055 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
4056 (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
4057 (clobber (match_dup 3))
4058 (clobber (match_dup 4))
4059 (clobber (reg:SI 26))
4060 (clobber (reg:SI 25))
4061 (clobber (reg:SI 31))])
4062 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
4066 operands[3] = gen_reg_rtx (SImode);
4067 operands[4] = gen_reg_rtx (SImode);
4069 operands[4] = gen_rtx_REG (SImode, 2);
4070 if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
4076 (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
4077 (clobber (match_operand:SI 1 "register_operand" "=a"))
4078 (clobber (match_operand:SI 2 "register_operand" "=&r"))
4079 (clobber (reg:SI 26))
4080 (clobber (reg:SI 25))
4081 (clobber (reg:SI 31))]
4084 return output_div_insn (operands, 0, insn);"
4085 [(set_attr "type" "milli")
4086 (set (attr "length")
4088 ;; Target (or stub) within reach
4089 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4091 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4096 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
4100 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
4101 ;; same as NO_SPACE_REGS code
4102 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4104 (eq (symbol_ref "flag_pic")
4108 ;; Out of range and either PIC or PORTABLE_RUNTIME
4111 (define_expand "udivsi3"
4112 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
4113 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
4114 (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
4115 (clobber (match_dup 3))
4116 (clobber (match_dup 4))
4117 (clobber (reg:SI 26))
4118 (clobber (reg:SI 25))
4119 (clobber (reg:SI 31))])
4120 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
4124 operands[3] = gen_reg_rtx (SImode);
4125 operands[4] = gen_reg_rtx (SImode);
4127 operands[4] = gen_rtx_REG (SImode, 2);
4128 if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
4134 (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
4135 (clobber (match_operand:SI 1 "register_operand" "=a"))
4136 (clobber (match_operand:SI 2 "register_operand" "=&r"))
4137 (clobber (reg:SI 26))
4138 (clobber (reg:SI 25))
4139 (clobber (reg:SI 31))]
4142 return output_div_insn (operands, 1, insn);"
4143 [(set_attr "type" "milli")
4144 (set (attr "length")
4146 ;; Target (or stub) within reach
4147 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4149 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4154 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
4158 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
4159 ;; same as NO_SPACE_REGS code
4160 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4162 (eq (symbol_ref "flag_pic")
4166 ;; Out of range and either PIC or PORTABLE_RUNTIME
4169 (define_expand "modsi3"
4170 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
4171 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
4172 (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
4173 (clobber (match_dup 3))
4174 (clobber (match_dup 4))
4175 (clobber (reg:SI 26))
4176 (clobber (reg:SI 25))
4177 (clobber (reg:SI 31))])
4178 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
4182 operands[4] = gen_reg_rtx (SImode);
4184 operands[4] = gen_rtx_REG (SImode, 2);
4185 operands[3] = gen_reg_rtx (SImode);
4189 [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
4190 (clobber (match_operand:SI 0 "register_operand" "=a"))
4191 (clobber (match_operand:SI 1 "register_operand" "=&r"))
4192 (clobber (reg:SI 26))
4193 (clobber (reg:SI 25))
4194 (clobber (reg:SI 31))]
4197 return output_mod_insn (0, insn);"
4198 [(set_attr "type" "milli")
4199 (set (attr "length")
4201 ;; Target (or stub) within reach
4202 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4204 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4209 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
4213 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
4214 ;; same as NO_SPACE_REGS code
4215 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4217 (eq (symbol_ref "flag_pic")
4221 ;; Out of range and either PIC or PORTABLE_RUNTIME
4224 (define_expand "umodsi3"
4225 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
4226 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
4227 (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
4228 (clobber (match_dup 3))
4229 (clobber (match_dup 4))
4230 (clobber (reg:SI 26))
4231 (clobber (reg:SI 25))
4232 (clobber (reg:SI 31))])
4233 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
4237 operands[4] = gen_reg_rtx (SImode);
4239 operands[4] = gen_rtx_REG (SImode, 2);
4240 operands[3] = gen_reg_rtx (SImode);
4244 [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
4245 (clobber (match_operand:SI 0 "register_operand" "=a"))
4246 (clobber (match_operand:SI 1 "register_operand" "=&r"))
4247 (clobber (reg:SI 26))
4248 (clobber (reg:SI 25))
4249 (clobber (reg:SI 31))]
4252 return output_mod_insn (1, insn);"
4253 [(set_attr "type" "milli")
4254 (set (attr "length")
4256 ;; Target (or stub) within reach
4257 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4259 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4264 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
4268 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
4269 ;; same as NO_SPACE_REGS code
4270 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4272 (eq (symbol_ref "flag_pic")
4276 ;; Out of range and either PIC or PORTABLE_RUNTIME
4279 ;;- and instructions
4280 ;; We define DImode `and` so with DImode `not` we can get
4281 ;; DImode `andn`. Other combinations are possible.
4283 (define_expand "anddi3"
4284 [(set (match_operand:DI 0 "register_operand" "")
4285 (and:DI (match_operand:DI 1 "arith_double_operand" "")
4286 (match_operand:DI 2 "arith_double_operand" "")))]
4290 if (! register_operand (operands[1], DImode)
4291 || ! register_operand (operands[2], DImode))
4292 /* Let GCC break this into word-at-a-time operations. */
4297 [(set (match_operand:DI 0 "register_operand" "=r")
4298 (and:DI (match_operand:DI 1 "register_operand" "%r")
4299 (match_operand:DI 2 "register_operand" "r")))]
4301 "and %1,%2,%0\;and %R1,%R2,%R0"
4302 [(set_attr "type" "binary")
4303 (set_attr "length" "8")])
4306 [(set (match_operand:DI 0 "register_operand" "=r,r")
4307 (and:DI (match_operand:DI 1 "register_operand" "%?r,0")
4308 (match_operand:DI 2 "and_operand" "rO,P")))]
4310 "* return output_64bit_and (operands); "
4311 [(set_attr "type" "binary")
4312 (set_attr "length" "4")])
4314 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
4315 ; constant with ldil;ldo.
4316 (define_insn "andsi3"
4317 [(set (match_operand:SI 0 "register_operand" "=r,r")
4318 (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
4319 (match_operand:SI 2 "and_operand" "rO,P")))]
4321 "* return output_and (operands); "
4322 [(set_attr "type" "binary,shift")
4323 (set_attr "length" "4,4")])
4326 [(set (match_operand:DI 0 "register_operand" "=r")
4327 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4328 (match_operand:DI 2 "register_operand" "r")))]
4330 "andcm %2,%1,%0\;andcm %R2,%R1,%R0"
4331 [(set_attr "type" "binary")
4332 (set_attr "length" "8")])
4335 [(set (match_operand:DI 0 "register_operand" "=r")
4336 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4337 (match_operand:DI 2 "register_operand" "r")))]
4340 [(set_attr "type" "binary")
4341 (set_attr "length" "4")])
4344 [(set (match_operand:SI 0 "register_operand" "=r")
4345 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4346 (match_operand:SI 2 "register_operand" "r")))]
4349 [(set_attr "type" "binary")
4350 (set_attr "length" "4")])
4352 (define_expand "iordi3"
4353 [(set (match_operand:DI 0 "register_operand" "")
4354 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4355 (match_operand:DI 2 "arith_double_operand" "")))]
4359 if (! register_operand (operands[1], DImode)
4360 || ! register_operand (operands[2], DImode))
4361 /* Let GCC break this into word-at-a-time operations. */
4366 [(set (match_operand:DI 0 "register_operand" "=r")
4367 (ior:DI (match_operand:DI 1 "register_operand" "%r")
4368 (match_operand:DI 2 "register_operand" "r")))]
4370 "or %1,%2,%0\;or %R1,%R2,%R0"
4371 [(set_attr "type" "binary")
4372 (set_attr "length" "8")])
4375 [(set (match_operand:DI 0 "register_operand" "=r,r")
4376 (ior:DI (match_operand:DI 1 "register_operand" "0,0")
4377 (match_operand:DI 2 "ior_operand" "M,i")))]
4379 "* return output_64bit_ior (operands); "
4380 [(set_attr "type" "binary,shift")
4381 (set_attr "length" "4,4")])
4384 [(set (match_operand:DI 0 "register_operand" "=r")
4385 (ior:DI (match_operand:DI 1 "register_operand" "%r")
4386 (match_operand:DI 2 "register_operand" "r")))]
4389 [(set_attr "type" "binary")
4390 (set_attr "length" "4")])
4392 ;; Need a define_expand because we've run out of CONST_OK... characters.
4393 (define_expand "iorsi3"
4394 [(set (match_operand:SI 0 "register_operand" "")
4395 (ior:SI (match_operand:SI 1 "register_operand" "")
4396 (match_operand:SI 2 "arith32_operand" "")))]
4400 if (! (ior_operand (operands[2], SImode)
4401 || register_operand (operands[2], SImode)))
4402 operands[2] = force_reg (SImode, operands[2]);
4406 [(set (match_operand:SI 0 "register_operand" "=r,r")
4407 (ior:SI (match_operand:SI 1 "register_operand" "0,0")
4408 (match_operand:SI 2 "ior_operand" "M,i")))]
4410 "* return output_ior (operands); "
4411 [(set_attr "type" "binary,shift")
4412 (set_attr "length" "4,4")])
4415 [(set (match_operand:SI 0 "register_operand" "=r")
4416 (ior:SI (match_operand:SI 1 "register_operand" "%r")
4417 (match_operand:SI 2 "register_operand" "r")))]
4420 [(set_attr "type" "binary")
4421 (set_attr "length" "4")])
4423 (define_expand "xordi3"
4424 [(set (match_operand:DI 0 "register_operand" "")
4425 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4426 (match_operand:DI 2 "arith_double_operand" "")))]
4430 if (! register_operand (operands[1], DImode)
4431 || ! register_operand (operands[2], DImode))
4432 /* Let GCC break this into word-at-a-time operations. */
4437 [(set (match_operand:DI 0 "register_operand" "=r")
4438 (xor:DI (match_operand:DI 1 "register_operand" "%r")
4439 (match_operand:DI 2 "register_operand" "r")))]
4441 "xor %1,%2,%0\;xor %R1,%R2,%R0"
4442 [(set_attr "type" "binary")
4443 (set_attr "length" "8")])
4446 [(set (match_operand:DI 0 "register_operand" "=r")
4447 (xor:DI (match_operand:DI 1 "register_operand" "%r")
4448 (match_operand:DI 2 "register_operand" "r")))]
4451 [(set_attr "type" "binary")
4452 (set_attr "length" "4")])
4454 (define_insn "xorsi3"
4455 [(set (match_operand:SI 0 "register_operand" "=r")
4456 (xor:SI (match_operand:SI 1 "register_operand" "%r")
4457 (match_operand:SI 2 "register_operand" "r")))]
4460 [(set_attr "type" "binary")
4461 (set_attr "length" "4")])
4463 (define_expand "negdi2"
4464 [(set (match_operand:DI 0 "register_operand" "")
4465 (neg:DI (match_operand:DI 1 "register_operand" "")))]
4470 [(set (match_operand:DI 0 "register_operand" "=r")
4471 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4473 "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
4474 [(set_attr "type" "unary")
4475 (set_attr "length" "8")])
4478 [(set (match_operand:DI 0 "register_operand" "=r")
4479 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4482 [(set_attr "type" "unary")
4483 (set_attr "length" "4")])
4485 (define_insn "negsi2"
4486 [(set (match_operand:SI 0 "register_operand" "=r")
4487 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
4490 [(set_attr "type" "unary")
4491 (set_attr "length" "4")])
4493 (define_expand "one_cmpldi2"
4494 [(set (match_operand:DI 0 "register_operand" "")
4495 (not:DI (match_operand:DI 1 "arith_double_operand" "")))]
4499 if (! register_operand (operands[1], DImode))
4504 [(set (match_operand:DI 0 "register_operand" "=r")
4505 (not:DI (match_operand:DI 1 "register_operand" "r")))]
4507 "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
4508 [(set_attr "type" "unary")
4509 (set_attr "length" "8")])
4512 [(set (match_operand:DI 0 "register_operand" "=r")
4513 (not:DI (match_operand:DI 1 "register_operand" "r")))]
4516 [(set_attr "type" "unary")
4517 (set_attr "length" "4")])
4519 (define_insn "one_cmplsi2"
4520 [(set (match_operand:SI 0 "register_operand" "=r")
4521 (not:SI (match_operand:SI 1 "register_operand" "r")))]
4524 [(set_attr "type" "unary")
4525 (set_attr "length" "4")])
4527 ;; Floating point arithmetic instructions.
4529 (define_insn "adddf3"
4530 [(set (match_operand:DF 0 "register_operand" "=f")
4531 (plus:DF (match_operand:DF 1 "register_operand" "f")
4532 (match_operand:DF 2 "register_operand" "f")))]
4533 "! TARGET_SOFT_FLOAT"
4535 [(set_attr "type" "fpalu")
4536 (set_attr "pa_combine_type" "faddsub")
4537 (set_attr "length" "4")])
4539 (define_insn "addsf3"
4540 [(set (match_operand:SF 0 "register_operand" "=f")
4541 (plus:SF (match_operand:SF 1 "register_operand" "f")
4542 (match_operand:SF 2 "register_operand" "f")))]
4543 "! TARGET_SOFT_FLOAT"
4545 [(set_attr "type" "fpalu")
4546 (set_attr "pa_combine_type" "faddsub")
4547 (set_attr "length" "4")])
4549 (define_insn "subdf3"
4550 [(set (match_operand:DF 0 "register_operand" "=f")
4551 (minus:DF (match_operand:DF 1 "register_operand" "f")
4552 (match_operand:DF 2 "register_operand" "f")))]
4553 "! TARGET_SOFT_FLOAT"
4555 [(set_attr "type" "fpalu")
4556 (set_attr "pa_combine_type" "faddsub")
4557 (set_attr "length" "4")])
4559 (define_insn "subsf3"
4560 [(set (match_operand:SF 0 "register_operand" "=f")
4561 (minus:SF (match_operand:SF 1 "register_operand" "f")
4562 (match_operand:SF 2 "register_operand" "f")))]
4563 "! TARGET_SOFT_FLOAT"
4565 [(set_attr "type" "fpalu")
4566 (set_attr "pa_combine_type" "faddsub")
4567 (set_attr "length" "4")])
4569 (define_insn "muldf3"
4570 [(set (match_operand:DF 0 "register_operand" "=f")
4571 (mult:DF (match_operand:DF 1 "register_operand" "f")
4572 (match_operand:DF 2 "register_operand" "f")))]
4573 "! TARGET_SOFT_FLOAT"
4575 [(set_attr "type" "fpmuldbl")
4576 (set_attr "pa_combine_type" "fmpy")
4577 (set_attr "length" "4")])
4579 (define_insn "mulsf3"
4580 [(set (match_operand:SF 0 "register_operand" "=f")
4581 (mult:SF (match_operand:SF 1 "register_operand" "f")
4582 (match_operand:SF 2 "register_operand" "f")))]
4583 "! TARGET_SOFT_FLOAT"
4585 [(set_attr "type" "fpmulsgl")
4586 (set_attr "pa_combine_type" "fmpy")
4587 (set_attr "length" "4")])
4589 (define_insn "divdf3"
4590 [(set (match_operand:DF 0 "register_operand" "=f")
4591 (div:DF (match_operand:DF 1 "register_operand" "f")
4592 (match_operand:DF 2 "register_operand" "f")))]
4593 "! TARGET_SOFT_FLOAT"
4595 [(set_attr "type" "fpdivdbl")
4596 (set_attr "length" "4")])
4598 (define_insn "divsf3"
4599 [(set (match_operand:SF 0 "register_operand" "=f")
4600 (div:SF (match_operand:SF 1 "register_operand" "f")
4601 (match_operand:SF 2 "register_operand" "f")))]
4602 "! TARGET_SOFT_FLOAT"
4604 [(set_attr "type" "fpdivsgl")
4605 (set_attr "length" "4")])
4607 (define_insn "negdf2"
4608 [(set (match_operand:DF 0 "register_operand" "=f")
4609 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
4610 "! TARGET_SOFT_FLOAT"
4614 return \"fneg,dbl %1,%0\";
4616 return \"fsub,dbl %%fr0,%1,%0\";
4618 [(set_attr "type" "fpalu")
4619 (set_attr "length" "4")])
4621 (define_insn "negsf2"
4622 [(set (match_operand:SF 0 "register_operand" "=f")
4623 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
4624 "! TARGET_SOFT_FLOAT"
4628 return \"fneg,sgl %1,%0\";
4630 return \"fsub,sgl %%fr0,%1,%0\";
4632 [(set_attr "type" "fpalu")
4633 (set_attr "length" "4")])
4635 (define_insn "absdf2"
4636 [(set (match_operand:DF 0 "register_operand" "=f")
4637 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
4638 "! TARGET_SOFT_FLOAT"
4640 [(set_attr "type" "fpalu")
4641 (set_attr "length" "4")])
4643 (define_insn "abssf2"
4644 [(set (match_operand:SF 0 "register_operand" "=f")
4645 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
4646 "! TARGET_SOFT_FLOAT"
4648 [(set_attr "type" "fpalu")
4649 (set_attr "length" "4")])
4651 (define_insn "sqrtdf2"
4652 [(set (match_operand:DF 0 "register_operand" "=f")
4653 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
4654 "! TARGET_SOFT_FLOAT"
4656 [(set_attr "type" "fpsqrtdbl")
4657 (set_attr "length" "4")])
4659 (define_insn "sqrtsf2"
4660 [(set (match_operand:SF 0 "register_operand" "=f")
4661 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
4662 "! TARGET_SOFT_FLOAT"
4664 [(set_attr "type" "fpsqrtsgl")
4665 (set_attr "length" "4")])
4667 ;; PA 2.0 floating point instructions
4671 [(set (match_operand:DF 0 "register_operand" "=f")
4672 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4673 (match_operand:DF 2 "register_operand" "f"))
4674 (match_operand:DF 3 "register_operand" "f")))]
4675 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4676 "fmpyfadd,dbl %1,%2,%3,%0"
4677 [(set_attr "type" "fpmuldbl")
4678 (set_attr "length" "4")])
4681 [(set (match_operand:DF 0 "register_operand" "=f")
4682 (plus:DF (match_operand:DF 1 "register_operand" "f")
4683 (mult:DF (match_operand:DF 2 "register_operand" "f")
4684 (match_operand:DF 3 "register_operand" "f"))))]
4685 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4686 "fmpyfadd,dbl %2,%3,%1,%0"
4687 [(set_attr "type" "fpmuldbl")
4688 (set_attr "length" "4")])
4691 [(set (match_operand:SF 0 "register_operand" "=f")
4692 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4693 (match_operand:SF 2 "register_operand" "f"))
4694 (match_operand:SF 3 "register_operand" "f")))]
4695 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4696 "fmpyfadd,sgl %1,%2,%3,%0"
4697 [(set_attr "type" "fpmulsgl")
4698 (set_attr "length" "4")])
4701 [(set (match_operand:SF 0 "register_operand" "=f")
4702 (plus:SF (match_operand:SF 1 "register_operand" "f")
4703 (mult:SF (match_operand:SF 2 "register_operand" "f")
4704 (match_operand:SF 3 "register_operand" "f"))))]
4705 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4706 "fmpyfadd,sgl %2,%3,%1,%0"
4707 [(set_attr "type" "fpmulsgl")
4708 (set_attr "length" "4")])
4710 ; fmpynfadd patterns
4712 [(set (match_operand:DF 0 "register_operand" "=f")
4713 (minus:DF (match_operand:DF 1 "register_operand" "f")
4714 (mult:DF (match_operand:DF 2 "register_operand" "f")
4715 (match_operand:DF 3 "register_operand" "f"))))]
4716 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4717 "fmpynfadd,dbl %2,%3,%1,%0"
4718 [(set_attr "type" "fpmuldbl")
4719 (set_attr "length" "4")])
4722 [(set (match_operand:SF 0 "register_operand" "=f")
4723 (minus:SF (match_operand:SF 1 "register_operand" "f")
4724 (mult:SF (match_operand:SF 2 "register_operand" "f")
4725 (match_operand:SF 3 "register_operand" "f"))))]
4726 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4727 "fmpynfadd,sgl %2,%3,%1,%0"
4728 [(set_attr "type" "fpmulsgl")
4729 (set_attr "length" "4")])
4733 [(set (match_operand:DF 0 "register_operand" "=f")
4734 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
4735 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4737 [(set_attr "type" "fpalu")
4738 (set_attr "length" "4")])
4741 [(set (match_operand:SF 0 "register_operand" "=f")
4742 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
4743 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4745 [(set_attr "type" "fpalu")
4746 (set_attr "length" "4")])
4748 ;; Generating a fused multiply sequence is a win for this case as it will
4749 ;; reduce the latency for the fused case without impacting the plain
4752 ;; Similar possibilities exist for fnegabs, shadd and other insns which
4753 ;; perform two operations with the result of the first feeding the second.
4755 [(set (match_operand:DF 0 "register_operand" "=f")
4756 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4757 (match_operand:DF 2 "register_operand" "f"))
4758 (match_operand:DF 3 "register_operand" "f")))
4759 (set (match_operand:DF 4 "register_operand" "=&f")
4760 (mult:DF (match_dup 1) (match_dup 2)))]
4761 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4762 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4763 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4765 [(set_attr "type" "fpmuldbl")
4766 (set_attr "length" "8")])
4768 ;; We want to split this up during scheduling since we want both insns
4769 ;; to schedule independently.
4771 [(set (match_operand:DF 0 "register_operand" "=f")
4772 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4773 (match_operand:DF 2 "register_operand" "f"))
4774 (match_operand:DF 3 "register_operand" "f")))
4775 (set (match_operand:DF 4 "register_operand" "=&f")
4776 (mult:DF (match_dup 1) (match_dup 2)))]
4777 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4778 [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
4779 (set (match_dup 0) (plus:DF (mult:DF (match_dup 1) (match_dup 2))
4784 [(set (match_operand:SF 0 "register_operand" "=f")
4785 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4786 (match_operand:SF 2 "register_operand" "f"))
4787 (match_operand:SF 3 "register_operand" "f")))
4788 (set (match_operand:SF 4 "register_operand" "=&f")
4789 (mult:SF (match_dup 1) (match_dup 2)))]
4790 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4791 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4792 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4794 [(set_attr "type" "fpmuldbl")
4795 (set_attr "length" "8")])
4797 ;; We want to split this up during scheduling since we want both insns
4798 ;; to schedule independently.
4800 [(set (match_operand:SF 0 "register_operand" "=f")
4801 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4802 (match_operand:SF 2 "register_operand" "f"))
4803 (match_operand:SF 3 "register_operand" "f")))
4804 (set (match_operand:SF 4 "register_operand" "=&f")
4805 (mult:SF (match_dup 1) (match_dup 2)))]
4806 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4807 [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
4808 (set (match_dup 0) (plus:SF (mult:SF (match_dup 1) (match_dup 2))
4812 ;; Negating a multiply can be faked by adding zero in a fused multiply-add
4815 [(set (match_operand:DF 0 "register_operand" "=f")
4816 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4817 (match_operand:DF 2 "register_operand" "f"))))]
4818 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4819 "fmpynfadd,dbl %1,%2,%%fr0,%0"
4820 [(set_attr "type" "fpmuldbl")
4821 (set_attr "length" "4")])
4824 [(set (match_operand:SF 0 "register_operand" "=f")
4825 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4826 (match_operand:SF 2 "register_operand" "f"))))]
4827 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4828 "fmpynfadd,sgl %1,%2,%%fr0,%0"
4829 [(set_attr "type" "fpmuldbl")
4830 (set_attr "length" "4")])
4833 [(set (match_operand:DF 0 "register_operand" "=f")
4834 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4835 (match_operand:DF 2 "register_operand" "f"))))
4836 (set (match_operand:DF 3 "register_operand" "=&f")
4837 (mult:DF (match_dup 1) (match_dup 2)))]
4838 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4839 && ! (reg_overlap_mentioned_p (operands[3], operands[1])
4840 || reg_overlap_mentioned_p (operands[3], operands[2])))"
4842 [(set_attr "type" "fpmuldbl")
4843 (set_attr "length" "8")])
4846 [(set (match_operand:DF 0 "register_operand" "=f")
4847 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4848 (match_operand:DF 2 "register_operand" "f"))))
4849 (set (match_operand:DF 3 "register_operand" "=&f")
4850 (mult:DF (match_dup 1) (match_dup 2)))]
4851 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4852 [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
4853 (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
4857 [(set (match_operand:SF 0 "register_operand" "=f")
4858 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4859 (match_operand:SF 2 "register_operand" "f"))))
4860 (set (match_operand:SF 3 "register_operand" "=&f")
4861 (mult:SF (match_dup 1) (match_dup 2)))]
4862 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4863 && ! (reg_overlap_mentioned_p (operands[3], operands[1])
4864 || reg_overlap_mentioned_p (operands[3], operands[2])))"
4866 [(set_attr "type" "fpmuldbl")
4867 (set_attr "length" "8")])
4870 [(set (match_operand:SF 0 "register_operand" "=f")
4871 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4872 (match_operand:SF 2 "register_operand" "f"))))
4873 (set (match_operand:SF 3 "register_operand" "=&f")
4874 (mult:SF (match_dup 1) (match_dup 2)))]
4875 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4876 [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
4877 (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
4880 ;; Now fused multiplies with the result of the multiply negated.
4882 [(set (match_operand:DF 0 "register_operand" "=f")
4883 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4884 (match_operand:DF 2 "register_operand" "f")))
4885 (match_operand:DF 3 "register_operand" "f")))]
4886 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4887 "fmpynfadd,dbl %1,%2,%3,%0"
4888 [(set_attr "type" "fpmuldbl")
4889 (set_attr "length" "4")])
4892 [(set (match_operand:SF 0 "register_operand" "=f")
4893 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4894 (match_operand:SF 2 "register_operand" "f")))
4895 (match_operand:SF 3 "register_operand" "f")))]
4896 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4897 "fmpynfadd,sgl %1,%2,%3,%0"
4898 [(set_attr "type" "fpmuldbl")
4899 (set_attr "length" "4")])
4902 [(set (match_operand:DF 0 "register_operand" "=f")
4903 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4904 (match_operand:DF 2 "register_operand" "f")))
4905 (match_operand:DF 3 "register_operand" "f")))
4906 (set (match_operand:DF 4 "register_operand" "=&f")
4907 (mult:DF (match_dup 1) (match_dup 2)))]
4908 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4909 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4910 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4912 [(set_attr "type" "fpmuldbl")
4913 (set_attr "length" "8")])
4916 [(set (match_operand:DF 0 "register_operand" "=f")
4917 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4918 (match_operand:DF 2 "register_operand" "f")))
4919 (match_operand:DF 3 "register_operand" "f")))
4920 (set (match_operand:DF 4 "register_operand" "=&f")
4921 (mult:DF (match_dup 1) (match_dup 2)))]
4922 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4923 [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
4924 (set (match_dup 0) (plus:DF (neg:DF (mult:DF (match_dup 1) (match_dup 2)))
4929 [(set (match_operand:SF 0 "register_operand" "=f")
4930 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4931 (match_operand:SF 2 "register_operand" "f")))
4932 (match_operand:SF 3 "register_operand" "f")))
4933 (set (match_operand:SF 4 "register_operand" "=&f")
4934 (mult:SF (match_dup 1) (match_dup 2)))]
4935 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4936 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4937 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4939 [(set_attr "type" "fpmuldbl")
4940 (set_attr "length" "8")])
4943 [(set (match_operand:SF 0 "register_operand" "=f")
4944 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4945 (match_operand:SF 2 "register_operand" "f")))
4946 (match_operand:SF 3 "register_operand" "f")))
4947 (set (match_operand:SF 4 "register_operand" "=&f")
4948 (mult:SF (match_dup 1) (match_dup 2)))]
4949 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4950 [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
4951 (set (match_dup 0) (plus:SF (neg:SF (mult:SF (match_dup 1) (match_dup 2)))
4956 [(set (match_operand:DF 0 "register_operand" "=f")
4957 (minus:DF (match_operand:DF 3 "register_operand" "f")
4958 (mult:DF (match_operand:DF 1 "register_operand" "f")
4959 (match_operand:DF 2 "register_operand" "f"))))
4960 (set (match_operand:DF 4 "register_operand" "=&f")
4961 (mult:DF (match_dup 1) (match_dup 2)))]
4962 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4963 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4964 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4966 [(set_attr "type" "fpmuldbl")
4967 (set_attr "length" "8")])
4970 [(set (match_operand:DF 0 "register_operand" "=f")
4971 (minus:DF (match_operand:DF 3 "register_operand" "f")
4972 (mult:DF (match_operand:DF 1 "register_operand" "f")
4973 (match_operand:DF 2 "register_operand" "f"))))
4974 (set (match_operand:DF 4 "register_operand" "=&f")
4975 (mult:DF (match_dup 1) (match_dup 2)))]
4976 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4977 [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
4978 (set (match_dup 0) (minus:DF (match_dup 3)
4979 (mult:DF (match_dup 1) (match_dup 2))))]
4983 [(set (match_operand:SF 0 "register_operand" "=f")
4984 (minus:SF (match_operand:SF 3 "register_operand" "f")
4985 (mult:SF (match_operand:SF 1 "register_operand" "f")
4986 (match_operand:SF 2 "register_operand" "f"))))
4987 (set (match_operand:SF 4 "register_operand" "=&f")
4988 (mult:SF (match_dup 1) (match_dup 2)))]
4989 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4990 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4991 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4993 [(set_attr "type" "fpmuldbl")
4994 (set_attr "length" "8")])
4997 [(set (match_operand:SF 0 "register_operand" "=f")
4998 (minus:SF (match_operand:SF 3 "register_operand" "f")
4999 (mult:SF (match_operand:SF 1 "register_operand" "f")
5000 (match_operand:SF 2 "register_operand" "f"))))
5001 (set (match_operand:SF 4 "register_operand" "=&f")
5002 (mult:SF (match_dup 1) (match_dup 2)))]
5003 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5004 [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
5005 (set (match_dup 0) (minus:SF (match_dup 3)
5006 (mult:SF (match_dup 1) (match_dup 2))))]
5010 [(set (match_operand:DF 0 "register_operand" "=f")
5011 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
5012 (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
5013 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5014 && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
5016 [(set_attr "type" "fpalu")
5017 (set_attr "length" "8")])
5020 [(set (match_operand:DF 0 "register_operand" "=f")
5021 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
5022 (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
5023 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5024 [(set (match_dup 2) (abs:DF (match_dup 1)))
5025 (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
5029 [(set (match_operand:SF 0 "register_operand" "=f")
5030 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
5031 (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
5032 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5033 && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
5035 [(set_attr "type" "fpalu")
5036 (set_attr "length" "8")])
5039 [(set (match_operand:SF 0 "register_operand" "=f")
5040 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
5041 (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
5042 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5043 [(set (match_dup 2) (abs:SF (match_dup 1)))
5044 (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
5047 ;;- Shift instructions
5049 ;; Optimized special case of shifting.
5052 [(set (match_operand:SI 0 "register_operand" "=r")
5053 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5057 [(set_attr "type" "load")
5058 (set_attr "length" "4")])
5061 [(set (match_operand:SI 0 "register_operand" "=r")
5062 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5066 [(set_attr "type" "load")
5067 (set_attr "length" "4")])
5070 [(set (match_operand:SI 0 "register_operand" "=r")
5071 (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
5072 (match_operand:SI 3 "shadd_operand" ""))
5073 (match_operand:SI 1 "register_operand" "r")))]
5075 "{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0} "
5076 [(set_attr "type" "binary")
5077 (set_attr "length" "4")])
5080 [(set (match_operand:DI 0 "register_operand" "=r")
5081 (plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
5082 (match_operand:DI 3 "shadd_operand" ""))
5083 (match_operand:DI 1 "register_operand" "r")))]
5085 "shladd,l %2,%O3,%1,%0"
5086 [(set_attr "type" "binary")
5087 (set_attr "length" "4")])
5089 (define_expand "ashlsi3"
5090 [(set (match_operand:SI 0 "register_operand" "")
5091 (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
5092 (match_operand:SI 2 "arith32_operand" "")))]
5096 if (GET_CODE (operands[2]) != CONST_INT)
5098 rtx temp = gen_reg_rtx (SImode);
5099 emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
5100 if (GET_CODE (operands[1]) == CONST_INT)
5101 emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
5103 emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
5106 /* Make sure both inputs are not constants,
5107 there are no patterns for that. */
5108 operands[1] = force_reg (SImode, operands[1]);
5112 [(set (match_operand:SI 0 "register_operand" "=r")
5113 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5114 (match_operand:SI 2 "const_int_operand" "n")))]
5116 "{zdep|depw,z} %1,%P2,%L2,%0"
5117 [(set_attr "type" "shift")
5118 (set_attr "length" "4")])
5120 ; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
5121 ; Doing it like this makes slightly better code since reload can
5122 ; replace a register with a known value in range -16..15 with a
5123 ; constant. Ideally, we would like to merge zvdep32 and zvdep_imm32,
5124 ; but since we have no more CONST_OK... characters, that is not
5126 (define_insn "zvdep32"
5127 [(set (match_operand:SI 0 "register_operand" "=r,r")
5128 (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
5129 (minus:SI (const_int 31)
5130 (match_operand:SI 2 "register_operand" "q,q"))))]
5133 {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
5134 {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
5135 [(set_attr "type" "shift,shift")
5136 (set_attr "length" "4,4")])
5138 (define_insn "zvdep_imm32"
5139 [(set (match_operand:SI 0 "register_operand" "=r")
5140 (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
5141 (minus:SI (const_int 31)
5142 (match_operand:SI 2 "register_operand" "q"))))]
5146 int x = INTVAL (operands[1]);
5147 operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
5148 operands[1] = GEN_INT ((x & 0xf) - 0x10);
5149 return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
5151 [(set_attr "type" "shift")
5152 (set_attr "length" "4")])
5154 (define_insn "vdepi_ior"
5155 [(set (match_operand:SI 0 "register_operand" "=r")
5156 (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
5157 (minus:SI (const_int 31)
5158 (match_operand:SI 2 "register_operand" "q")))
5159 (match_operand:SI 3 "register_operand" "0")))]
5160 ; accept ...0001...1, can this be generalized?
5161 "exact_log2 (INTVAL (operands[1]) + 1) >= 0"
5164 int x = INTVAL (operands[1]);
5165 operands[2] = GEN_INT (exact_log2 (x + 1));
5166 return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
5168 [(set_attr "type" "shift")
5169 (set_attr "length" "4")])
5171 (define_insn "vdepi_and"
5172 [(set (match_operand:SI 0 "register_operand" "=r")
5173 (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
5174 (minus:SI (const_int 31)
5175 (match_operand:SI 2 "register_operand" "q")))
5176 (match_operand:SI 3 "register_operand" "0")))]
5177 ; this can be generalized...!
5178 "INTVAL (operands[1]) == -2"
5181 int x = INTVAL (operands[1]);
5182 operands[2] = GEN_INT (exact_log2 ((~x) + 1));
5183 return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
5185 [(set_attr "type" "shift")
5186 (set_attr "length" "4")])
5188 (define_expand "ashldi3"
5189 [(set (match_operand:DI 0 "register_operand" "")
5190 (ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
5191 (match_operand:DI 2 "arith32_operand" "")))]
5195 if (GET_CODE (operands[2]) != CONST_INT)
5197 rtx temp = gen_reg_rtx (DImode);
5198 emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
5199 if (GET_CODE (operands[1]) == CONST_INT)
5200 emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
5202 emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
5205 /* Make sure both inputs are not constants,
5206 there are no patterns for that. */
5207 operands[1] = force_reg (DImode, operands[1]);
5211 [(set (match_operand:DI 0 "register_operand" "=r")
5212 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5213 (match_operand:DI 2 "const_int_operand" "n")))]
5215 "depd,z %1,%p2,%Q2,%0"
5216 [(set_attr "type" "shift")
5217 (set_attr "length" "4")])
5219 ; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
5220 ; Doing it like this makes slightly better code since reload can
5221 ; replace a register with a known value in range -16..15 with a
5222 ; constant. Ideally, we would like to merge zvdep64 and zvdep_imm64,
5223 ; but since we have no more CONST_OK... characters, that is not
5225 (define_insn "zvdep64"
5226 [(set (match_operand:DI 0 "register_operand" "=r,r")
5227 (ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
5228 (minus:DI (const_int 63)
5229 (match_operand:DI 2 "register_operand" "q,q"))))]
5232 depd,z %1,%%sar,64,%0
5233 depdi,z %1,%%sar,64,%0"
5234 [(set_attr "type" "shift,shift")
5235 (set_attr "length" "4,4")])
5237 (define_insn "zvdep_imm64"
5238 [(set (match_operand:DI 0 "register_operand" "=r")
5239 (ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
5240 (minus:DI (const_int 63)
5241 (match_operand:DI 2 "register_operand" "q"))))]
5245 int x = INTVAL (operands[1]);
5246 operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
5247 operands[1] = GEN_INT ((x & 0x1f) - 0x20);
5248 return \"depdi,z %1,%%sar,%2,%0\";
5250 [(set_attr "type" "shift")
5251 (set_attr "length" "4")])
5254 [(set (match_operand:DI 0 "register_operand" "=r")
5255 (ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
5256 (minus:DI (const_int 63)
5257 (match_operand:DI 2 "register_operand" "q")))
5258 (match_operand:DI 3 "register_operand" "0")))]
5259 ; accept ...0001...1, can this be generalized?
5260 "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) >= 0"
5263 int x = INTVAL (operands[1]);
5264 operands[2] = GEN_INT (exact_log2 (x + 1));
5265 return \"depdi -1,%%sar,%2,%0\";
5267 [(set_attr "type" "shift")
5268 (set_attr "length" "4")])
5271 [(set (match_operand:DI 0 "register_operand" "=r")
5272 (and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
5273 (minus:DI (const_int 63)
5274 (match_operand:DI 2 "register_operand" "q")))
5275 (match_operand:DI 3 "register_operand" "0")))]
5276 ; this can be generalized...!
5277 "TARGET_64BIT && INTVAL (operands[1]) == -2"
5280 int x = INTVAL (operands[1]);
5281 operands[2] = GEN_INT (exact_log2 ((~x) + 1));
5282 return \"depdi 0,%%sar,%2,%0\";
5284 [(set_attr "type" "shift")
5285 (set_attr "length" "4")])
5287 (define_expand "ashrsi3"
5288 [(set (match_operand:SI 0 "register_operand" "")
5289 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
5290 (match_operand:SI 2 "arith32_operand" "")))]
5294 if (GET_CODE (operands[2]) != CONST_INT)
5296 rtx temp = gen_reg_rtx (SImode);
5297 emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
5298 emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
5304 [(set (match_operand:SI 0 "register_operand" "=r")
5305 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5306 (match_operand:SI 2 "const_int_operand" "n")))]
5308 "{extrs|extrw,s} %1,%P2,%L2,%0"
5309 [(set_attr "type" "shift")
5310 (set_attr "length" "4")])
5312 (define_insn "vextrs32"
5313 [(set (match_operand:SI 0 "register_operand" "=r")
5314 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5315 (minus:SI (const_int 31)
5316 (match_operand:SI 2 "register_operand" "q"))))]
5318 "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
5319 [(set_attr "type" "shift")
5320 (set_attr "length" "4")])
5322 (define_expand "ashrdi3"
5323 [(set (match_operand:DI 0 "register_operand" "")
5324 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5325 (match_operand:DI 2 "arith32_operand" "")))]
5329 if (GET_CODE (operands[2]) != CONST_INT)
5331 rtx temp = gen_reg_rtx (DImode);
5332 emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
5333 emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
5339 [(set (match_operand:DI 0 "register_operand" "=r")
5340 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5341 (match_operand:DI 2 "const_int_operand" "n")))]
5343 "extrd,s %1,%p2,%Q2,%0"
5344 [(set_attr "type" "shift")
5345 (set_attr "length" "4")])
5347 (define_insn "vextrs64"
5348 [(set (match_operand:DI 0 "register_operand" "=r")
5349 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5350 (minus:DI (const_int 63)
5351 (match_operand:DI 2 "register_operand" "q"))))]
5353 "extrd,s %1,%%sar,64,%0"
5354 [(set_attr "type" "shift")
5355 (set_attr "length" "4")])
5357 (define_insn "lshrsi3"
5358 [(set (match_operand:SI 0 "register_operand" "=r,r")
5359 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
5360 (match_operand:SI 2 "arith32_operand" "q,n")))]
5363 {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
5364 {extru|extrw,u} %1,%P2,%L2,%0"
5365 [(set_attr "type" "shift")
5366 (set_attr "length" "4")])
5368 (define_insn "lshrdi3"
5369 [(set (match_operand:DI 0 "register_operand" "=r,r")
5370 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
5371 (match_operand:DI 2 "arith32_operand" "q,n")))]
5374 shrpd %%r0,%1,%%sar,%0
5375 extrd,u %1,%p2,%Q2,%0"
5376 [(set_attr "type" "shift")
5377 (set_attr "length" "4")])
5379 (define_insn "rotrsi3"
5380 [(set (match_operand:SI 0 "register_operand" "=r,r")
5381 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
5382 (match_operand:SI 2 "arith32_operand" "q,n")))]
5386 if (GET_CODE (operands[2]) == CONST_INT)
5388 operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
5389 return \"{shd|shrpw} %1,%1,%2,%0\";
5392 return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
5394 [(set_attr "type" "shift")
5395 (set_attr "length" "4")])
5397 (define_expand "rotlsi3"
5398 [(set (match_operand:SI 0 "register_operand" "")
5399 (rotate:SI (match_operand:SI 1 "register_operand" "")
5400 (match_operand:SI 2 "arith32_operand" "")))]
5404 if (GET_CODE (operands[2]) != CONST_INT)
5406 rtx temp = gen_reg_rtx (SImode);
5407 emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
5408 emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
5411 /* Else expand normally. */
5415 [(set (match_operand:SI 0 "register_operand" "=r")
5416 (rotate:SI (match_operand:SI 1 "register_operand" "r")
5417 (match_operand:SI 2 "const_int_operand" "n")))]
5421 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
5422 return \"{shd|shrpw} %1,%1,%2,%0\";
5424 [(set_attr "type" "shift")
5425 (set_attr "length" "4")])
5428 [(set (match_operand:SI 0 "register_operand" "=r")
5429 (match_operator:SI 5 "plus_xor_ior_operator"
5430 [(ashift:SI (match_operand:SI 1 "register_operand" "r")
5431 (match_operand:SI 3 "const_int_operand" "n"))
5432 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
5433 (match_operand:SI 4 "const_int_operand" "n"))]))]
5434 "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
5435 "{shd|shrpw} %1,%2,%4,%0"
5436 [(set_attr "type" "shift")
5437 (set_attr "length" "4")])
5440 [(set (match_operand:SI 0 "register_operand" "=r")
5441 (match_operator:SI 5 "plus_xor_ior_operator"
5442 [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
5443 (match_operand:SI 4 "const_int_operand" "n"))
5444 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5445 (match_operand:SI 3 "const_int_operand" "n"))]))]
5446 "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
5447 "{shd|shrpw} %1,%2,%4,%0"
5448 [(set_attr "type" "shift")
5449 (set_attr "length" "4")])
5452 [(set (match_operand:SI 0 "register_operand" "=r")
5453 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
5454 (match_operand:SI 2 "const_int_operand" ""))
5455 (match_operand:SI 3 "const_int_operand" "")))]
5456 "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) >= 0"
5459 int cnt = INTVAL (operands[2]) & 31;
5460 operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
5461 operands[2] = GEN_INT (31 - cnt);
5462 return \"{zdep|depw,z} %1,%2,%3,%0\";
5464 [(set_attr "type" "shift")
5465 (set_attr "length" "4")])
5467 ;; Unconditional and other jump instructions.
5469 (define_insn "return"
5471 "hppa_can_use_return_insn_p ()"
5475 return \"bve%* (%%r2)\";
5476 return \"bv%* %%r0(%%r2)\";
5478 [(set_attr "type" "branch")
5479 (set_attr "length" "4")])
5481 ;; Use a different pattern for functions which have non-trivial
5482 ;; epilogues so as not to confuse jump and reorg.
5483 (define_insn "return_internal"
5490 return \"bve%* (%%r2)\";
5491 return \"bv%* %%r0(%%r2)\";
5493 [(set_attr "type" "branch")
5494 (set_attr "length" "4")])
5496 (define_expand "prologue"
5499 "hppa_expand_prologue ();DONE;")
5501 (define_expand "sibcall_epilogue"
5506 hppa_expand_epilogue ();
5510 (define_expand "epilogue"
5515 /* Try to use the trivial return first. Else use the full
5517 if (hppa_can_use_return_insn_p ())
5518 emit_jump_insn (gen_return ());
5521 hppa_expand_epilogue ();
5522 emit_jump_insn (gen_return_internal ());
5527 ;; Special because we use the value placed in %r2 by the bl instruction
5528 ;; from within its delay slot to set the value for the 2nd parameter to
5530 (define_insn "call_profiler"
5531 [(unspec_volatile [(const_int 0)] 0)
5532 (use (match_operand:SI 0 "const_int_operand" ""))]
5534 "{bl|b,l} _mcount,%%r2\;ldo %0(%%r2),%%r25"
5535 [(set_attr "type" "multi")
5536 (set_attr "length" "8")])
5538 (define_insn "blockage"
5539 [(unspec_volatile [(const_int 2)] 0)]
5542 [(set_attr "length" "0")])
5545 [(set (pc) (label_ref (match_operand 0 "" "")))]
5549 extern int optimize;
5551 if (GET_MODE (insn) == SImode)
5554 /* An unconditional branch which can reach its target. */
5555 if (get_attr_length (insn) != 24
5556 && get_attr_length (insn) != 16)
5559 /* An unconditional branch which can not reach its target.
5561 We need to be able to use %r1 as a scratch register; however,
5562 we can never be sure whether or not it's got a live value in
5563 it. Therefore, we must restore its original value after the
5566 To make matters worse, we don't have a stack slot which we
5567 can always clobber. sp-12/sp-16 shouldn't ever have a live
5568 value during a non-optimizing compilation, so we use those
5569 slots for now. We don't support very long branches when
5570 optimizing -- they should be quite rare when optimizing.
5572 Really the way to go long term is a register scavenger; goto
5573 the target of the jump and find a register which we can use
5574 as a scratch to hold the value in %r1. */
5576 /* We don't know how to register scavenge yet. */
5580 /* First store %r1 into the stack. */
5581 output_asm_insn (\"stw %%r1,-16(%%r30)\", operands);
5583 /* Now load the target address into %r1 and do an indirect jump
5584 to the value specified in %r1. Be careful to generate PIC
5589 xoperands[0] = operands[0];
5590 xoperands[1] = gen_label_rtx ();
5592 output_asm_insn (\"{bl|b,l} .+8,%%r1\\n\\taddil L'%l0-%l1,%%r1\",
5594 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5595 CODE_LABEL_NUMBER (xoperands[1]));
5596 output_asm_insn (\"ldo R'%l0-%l1(%%r1),%%r1\\n\\tbv %%r0(%%r1)\",
5600 output_asm_insn (\"ldil L'%l0,%%r1\\n\\tbe R'%l0(%%sr4,%%r1)\", operands);;
5602 /* And restore the value of %r1 in the delay slot. We're not optimizing,
5603 so we know nothing else can be in the delay slot. */
5604 return \"ldw -16(%%r30),%%r1\";
5606 [(set_attr "type" "uncond_branch")
5607 (set_attr "pa_combine_type" "uncond_branch")
5608 (set (attr "length")
5609 (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 1))
5610 (if_then_else (lt (abs (minus (match_dup 0)
5611 (plus (pc) (const_int 8))))
5615 (ge (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
5617 (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
5622 ;; Subroutines of "casesi".
5623 ;; operand 0 is index
5624 ;; operand 1 is the minimum bound
5625 ;; operand 2 is the maximum bound - minimum bound + 1
5626 ;; operand 3 is CODE_LABEL for the table;
5627 ;; operand 4 is the CODE_LABEL to go to if index out of range.
5629 (define_expand "casesi"
5630 [(match_operand:SI 0 "general_operand" "")
5631 (match_operand:SI 1 "const_int_operand" "")
5632 (match_operand:SI 2 "const_int_operand" "")
5633 (match_operand 3 "" "")
5634 (match_operand 4 "" "")]
5638 if (GET_CODE (operands[0]) != REG)
5639 operands[0] = force_reg (SImode, operands[0]);
5641 if (operands[1] != const0_rtx)
5643 rtx reg = gen_reg_rtx (SImode);
5645 operands[1] = GEN_INT (-INTVAL (operands[1]));
5646 if (!INT_14_BITS (operands[1]))
5647 operands[1] = force_reg (SImode, operands[1]);
5648 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
5653 /* In 64bit mode we must make sure to wipe the upper bits of the register
5654 just in case the addition overflowed or we had random bits in the
5655 high part of the register. */
5658 rtx reg = gen_reg_rtx (DImode);
5659 emit_insn (gen_extendsidi2 (reg, operands[0]));
5660 operands[0] = gen_rtx_SUBREG (SImode, reg, 0);
5663 if (!INT_5_BITS (operands[2]))
5664 operands[2] = force_reg (SImode, operands[2]);
5666 emit_insn (gen_cmpsi (operands[0], operands[2]));
5667 emit_jump_insn (gen_bgtu (operands[4]));
5668 if (TARGET_BIG_SWITCH)
5670 rtx temp = gen_reg_rtx (SImode);
5671 emit_move_insn (temp, gen_rtx_PLUS (SImode, operands[0], operands[0]));
5674 emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
5678 (define_insn "casesi0"
5680 (mem:SI (plus:SI (pc)
5681 (match_operand:SI 0 "register_operand" "r")))
5682 (label_ref (match_operand 1 "" ""))))]
5685 [(set_attr "type" "multi")
5686 (set_attr "length" "8")])
5688 ;; Need nops for the calls because execution is supposed to continue
5689 ;; past; we don't want to nullify an instruction that we need.
5690 ;;- jump to subroutine
5692 (define_expand "call"
5693 [(parallel [(call (match_operand:SI 0 "" "")
5694 (match_operand 1 "" ""))
5695 (clobber (reg:SI 2))])]
5702 if (TARGET_PORTABLE_RUNTIME)
5703 op = force_reg (SImode, XEXP (operands[0], 0));
5705 op = XEXP (operands[0], 0);
5708 emit_move_insn (arg_pointer_rtx,
5709 gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
5712 /* Use two different patterns for calls to explicitly named functions
5713 and calls through function pointers. This is necessary as these two
5714 types of calls use different calling conventions, and CSE might try
5715 to change the named call into an indirect call in some cases (using
5716 two patterns keeps CSE from performing this optimization). */
5717 if (GET_CODE (op) == SYMBOL_REF)
5718 call_insn = emit_call_insn (gen_call_internal_symref (op, operands[1]));
5719 else if (TARGET_64BIT)
5721 rtx tmpreg = force_reg (word_mode, op);
5722 call_insn = emit_call_insn (gen_call_internal_reg_64bit (tmpreg,
5727 rtx tmpreg = gen_rtx_REG (word_mode, 22);
5728 emit_move_insn (tmpreg, force_reg (word_mode, op));
5729 call_insn = emit_call_insn (gen_call_internal_reg (operands[1]));
5734 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
5735 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5736 gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
5738 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
5740 /* After each call we must restore the PIC register, even if it
5741 doesn't appear to be used.
5743 This will set regs_ever_live for the callee saved register we
5744 stored the PIC register in. */
5745 emit_move_insn (pic_offset_table_rtx,
5746 gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
5751 (define_insn "call_internal_symref"
5752 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
5753 (match_operand 1 "" "i"))
5754 (clobber (reg:SI 2))
5755 (use (const_int 0))]
5756 "! TARGET_PORTABLE_RUNTIME"
5759 output_arg_descriptor (insn);
5760 return output_call (insn, operands[0], 0);
5762 [(set_attr "type" "call")
5763 (set (attr "length")
5764 ;; If we're sure that we can either reach the target or that the
5765 ;; linker can use a long-branch stub, then the length is 4 bytes.
5767 ;; For long-calls the length will be either 52 bytes (non-pic)
5768 ;; or 68 bytes (pic). */
5769 ;; Else we have to use a long-call;
5770 (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
5773 (if_then_else (eq (symbol_ref "flag_pic")
5778 (define_insn "call_internal_reg_64bit"
5779 [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
5780 (match_operand 1 "" "i"))
5781 (clobber (reg:SI 2))
5782 (use (const_int 1))]
5788 /* ??? Needs more work. Length computation, split into multiple insns,
5789 do not use %r22 directly, expose delay slot. */
5790 return \"ldd 16(%0),%%r2\;ldd 24(%0),%%r27\;bve,l (%%r2),%%r2\;nop\";
5792 [(set_attr "type" "dyncall")
5793 (set (attr "length") (const_int 16))])
5795 (define_insn "call_internal_reg"
5796 [(call (mem:SI (reg:SI 22))
5797 (match_operand 0 "" "i"))
5798 (clobber (reg:SI 2))
5799 (use (const_int 1))]
5805 /* First the special case for kernels, level 0 systems, etc. */
5806 if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
5807 return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
5809 /* Now the normal case -- we can reach $$dyncall directly or
5810 we're sure that we can get there via a long-branch stub.
5812 No need to check target flags as the length uniquely identifies
5813 the remaining cases. */
5814 if (get_attr_length (insn) == 8)
5815 return \".CALL\\tARGW0=GR\;{bl|b,l} $$dyncall,%%r31\;copy %%r31,%%r2\";
5817 /* Long millicode call, but we are not generating PIC or portable runtime
5819 if (get_attr_length (insn) == 12)
5820 return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
5822 /* Long millicode call for portable runtime. */
5823 if (get_attr_length (insn) == 20)
5824 return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr %%r0,%%r2\;bv,n %%r0(%%r31)\;nop\";
5826 /* If we're generating PIC code. */
5827 xoperands[0] = operands[0];
5828 xoperands[1] = gen_label_rtx ();
5829 output_asm_insn (\"{bl|b,l} .+8,%%r1\", xoperands);
5830 output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
5831 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5832 CODE_LABEL_NUMBER (xoperands[1]));
5833 output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
5834 output_asm_insn (\"blr %%r0,%%r2\", xoperands);
5835 output_asm_insn (\"bv,n %%r0(%%r1)\\n\\tnop\", xoperands);
5838 [(set_attr "type" "dyncall")
5839 (set (attr "length")
5841 ;; First NO_SPACE_REGS
5842 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
5846 ;; Target (or stub) within reach
5847 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
5849 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
5853 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
5854 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
5856 (eq (symbol_ref "flag_pic")
5860 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
5864 ;; Out of range PIC case
5867 (define_expand "call_value"
5868 [(parallel [(set (match_operand 0 "" "")
5869 (call (match_operand:SI 1 "" "")
5870 (match_operand 2 "" "")))
5871 (clobber (reg:SI 2))])]
5878 if (TARGET_PORTABLE_RUNTIME)
5879 op = force_reg (word_mode, XEXP (operands[1], 0));
5881 op = XEXP (operands[1], 0);
5884 emit_move_insn (arg_pointer_rtx,
5885 gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
5888 /* Use two different patterns for calls to explicitly named functions
5889 and calls through function pointers. This is necessary as these two
5890 types of calls use different calling conventions, and CSE might try
5891 to change the named call into an indirect call in some cases (using
5892 two patterns keeps CSE from performing this optimization). */
5893 if (GET_CODE (op) == SYMBOL_REF)
5894 call_insn = emit_call_insn (gen_call_value_internal_symref (operands[0],
5897 else if (TARGET_64BIT)
5899 rtx tmpreg = force_reg (word_mode, op);
5901 = emit_call_insn (gen_call_value_internal_reg_64bit (operands[0],
5907 rtx tmpreg = gen_rtx_REG (word_mode, 22);
5908 emit_move_insn (tmpreg, force_reg (word_mode, op));
5909 call_insn = emit_call_insn (gen_call_value_internal_reg (operands[0],
5914 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
5915 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5916 gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
5918 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
5920 /* After each call we must restore the PIC register, even if it
5921 doesn't appear to be used.
5923 This will set regs_ever_live for the callee saved register we
5924 stored the PIC register in. */
5925 emit_move_insn (pic_offset_table_rtx,
5926 gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
5931 (define_insn "call_value_internal_symref"
5932 [(set (match_operand 0 "" "=rf")
5933 (call (mem:SI (match_operand 1 "call_operand_address" ""))
5934 (match_operand 2 "" "i")))
5935 (clobber (reg:SI 2))
5936 (use (const_int 0))]
5937 ;;- Don't use operand 1 for most machines.
5938 "! TARGET_PORTABLE_RUNTIME"
5941 output_arg_descriptor (insn);
5942 return output_call (insn, operands[1], 0);
5944 [(set_attr "type" "call")
5945 (set (attr "length")
5946 ;; If we're sure that we can either reach the target or that the
5947 ;; linker can use a long-branch stub, then the length is 4 bytes.
5949 ;; For long-calls the length will be either 52 bytes (non-pic)
5950 ;; or 68 bytes (pic). */
5951 ;; Else we have to use a long-call;
5952 (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
5955 (if_then_else (eq (symbol_ref "flag_pic")
5960 (define_insn "call_value_internal_reg_64bit"
5961 [(set (match_operand 0 "" "=rf")
5962 (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
5963 (match_operand 2 "" "i")))
5964 (clobber (reg:SI 2))
5965 (use (const_int 1))]
5969 /* ??? Needs more work. Length computation, split into multiple insns,
5970 do not use %r22 directly, expose delay slot. */
5971 return \"ldd 16(%1),%%r2\;ldd 24(%1),%%r27\;bve,l (%%r2),%%r2\;nop\";
5973 [(set_attr "type" "dyncall")
5974 (set (attr "length") (const_int 16))])
5976 (define_insn "call_value_internal_reg"
5977 [(set (match_operand 0 "" "=rf")
5978 (call (mem:SI (reg:SI 22))
5979 (match_operand 1 "" "i")))
5980 (clobber (reg:SI 2))
5981 (use (const_int 1))]
5987 /* First the special case for kernels, level 0 systems, etc. */
5988 if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
5989 return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
5991 /* Now the normal case -- we can reach $$dyncall directly or
5992 we're sure that we can get there via a long-branch stub.
5994 No need to check target flags as the length uniquely identifies
5995 the remaining cases. */
5996 if (get_attr_length (insn) == 8)
5997 return \".CALL\\tARGW0=GR\;{bl|b,l} $$dyncall,%%r31\;copy %%r31,%%r2\";
5999 /* Long millicode call, but we are not generating PIC or portable runtime
6001 if (get_attr_length (insn) == 12)
6002 return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
6004 /* Long millicode call for portable runtime. */
6005 if (get_attr_length (insn) == 20)
6006 return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr %%r0,%%r2\;bv,n %%r0(%%r31)\;nop\";
6008 /* If we're generating PIC code. */
6009 xoperands[0] = operands[1];
6010 xoperands[1] = gen_label_rtx ();
6011 output_asm_insn (\"{bl|b,l} .+8,%%r1\", xoperands);
6012 output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
6013 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
6014 CODE_LABEL_NUMBER (xoperands[1]));
6015 output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
6016 output_asm_insn (\"blr %%r0,%%r2\", xoperands);
6017 output_asm_insn (\"bv,n %%r0(%%r1)\\n\\tnop\", xoperands);
6020 [(set_attr "type" "dyncall")
6021 (set (attr "length")
6023 ;; First NO_SPACE_REGS
6024 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
6028 ;; Target (or stub) within reach
6029 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
6031 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
6035 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
6036 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
6038 (eq (symbol_ref "flag_pic")
6042 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
6046 ;; Out of range PIC case
6049 ;; Call subroutine returning any type.
6051 (define_expand "untyped_call"
6052 [(parallel [(call (match_operand 0 "" "")
6054 (match_operand 1 "" "")
6055 (match_operand 2 "" "")])]
6061 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6063 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6065 rtx set = XVECEXP (operands[2], 0, i);
6066 emit_move_insn (SET_DEST (set), SET_SRC (set));
6069 /* The optimizer does not know that the call sets the function value
6070 registers we stored in the result block. We avoid problems by
6071 claiming that all hard registers are used and clobbered at this
6073 emit_insn (gen_blockage ());
6078 (define_expand "sibcall"
6079 [(parallel [(call (match_operand:SI 0 "" "")
6080 (match_operand 1 "" ""))
6081 (clobber (reg:SI 0))])]
6082 "! TARGET_PORTABLE_RUNTIME"
6088 op = XEXP (operands[0], 0);
6090 /* We do not allow indirect sibling calls. */
6091 call_insn = emit_call_insn (gen_sibcall_internal_symref (op, operands[1]));
6095 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
6096 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6097 gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
6099 /* After each call we must restore the PIC register, even if it
6100 doesn't appear to be used.
6102 This will set regs_ever_live for the callee saved register we
6103 stored the PIC register in. */
6104 emit_move_insn (pic_offset_table_rtx,
6105 gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
6110 (define_insn "sibcall_internal_symref"
6111 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
6112 (match_operand 1 "" "i"))
6113 (clobber (reg:SI 0))
6115 (use (const_int 0))]
6116 "! TARGET_PORTABLE_RUNTIME"
6119 output_arg_descriptor (insn);
6120 return output_call (insn, operands[0], 1);
6122 [(set_attr "type" "call")
6123 (set (attr "length")
6124 ;; If we're sure that we can either reach the target or that the
6125 ;; linker can use a long-branch stub, then the length is 4 bytes.
6127 ;; For long-calls the length will be either 52 bytes (non-pic)
6128 ;; or 68 bytes (pic). */
6129 ;; Else we have to use a long-call;
6130 (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
6133 (if_then_else (eq (symbol_ref "flag_pic")
6138 (define_expand "sibcall_value"
6139 [(parallel [(set (match_operand 0 "" "")
6140 (call (match_operand:SI 1 "" "")
6141 (match_operand 2 "" "")))
6142 (clobber (reg:SI 0))])]
6143 "! TARGET_PORTABLE_RUNTIME"
6149 op = XEXP (operands[1], 0);
6151 /* We do not allow indirect sibling calls. */
6152 call_insn = emit_call_insn (gen_sibcall_value_internal_symref (operands[0],
6157 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
6158 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6159 gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
6161 /* After each call we must restore the PIC register, even if it
6162 doesn't appear to be used.
6164 This will set regs_ever_live for the callee saved register we
6165 stored the PIC register in. */
6166 emit_move_insn (pic_offset_table_rtx,
6167 gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
6172 (define_insn "sibcall_value_internal_symref"
6173 [(set (match_operand 0 "" "=rf")
6174 (call (mem:SI (match_operand 1 "call_operand_address" ""))
6175 (match_operand 2 "" "i")))
6176 (clobber (reg:SI 0))
6178 (use (const_int 0))]
6179 ;;- Don't use operand 1 for most machines.
6180 "! TARGET_PORTABLE_RUNTIME"
6183 output_arg_descriptor (insn);
6184 return output_call (insn, operands[1], 1);
6186 [(set_attr "type" "call")
6187 (set (attr "length")
6188 ;; If we're sure that we can either reach the target or that the
6189 ;; linker can use a long-branch stub, then the length is 4 bytes.
6191 ;; For long-calls the length will be either 52 bytes (non-pic)
6192 ;; or 68 bytes (pic). */
6193 ;; Else we have to use a long-call;
6194 (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
6197 (if_then_else (eq (symbol_ref "flag_pic")
6206 [(set_attr "type" "move")
6207 (set_attr "length" "4")])
6209 ;; These are just placeholders so we know where branch tables
6211 (define_insn "begin_brtab"
6216 /* Only GAS actually supports this pseudo-op. */
6218 return \".begin_brtab\";
6222 [(set_attr "type" "move")
6223 (set_attr "length" "0")])
6225 (define_insn "end_brtab"
6230 /* Only GAS actually supports this pseudo-op. */
6232 return \".end_brtab\";
6236 [(set_attr "type" "move")
6237 (set_attr "length" "0")])
6239 ;;; EH does longjmp's from and within the data section. Thus,
6240 ;;; an interspace branch is required for the longjmp implementation.
6241 ;;; Registers r1 and r2 are not saved in the jmpbuf environment.
6242 ;;; Thus, they can be used as scratch registers for the jump.
6243 (define_expand "interspace_jump"
6245 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
6246 (clobber (match_dup 1))])]
6250 operands[1] = gen_rtx_REG (word_mode, 2);
6254 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
6255 (clobber (reg:SI 2))]
6257 "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
6258 [(set_attr "type" "branch")
6259 (set_attr "length" "12")])
6262 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
6263 (clobber (reg:DI 2))]
6265 "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
6266 [(set_attr "type" "branch")
6267 (set_attr "length" "12")])
6269 (define_expand "builtin_longjmp"
6270 [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
6274 /* The elements of the buffer are, in order: */
6275 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6276 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4));
6277 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
6278 rtx pv = gen_rtx_REG (Pmode, 1);
6280 /* This bit is the same as expand_builtin_longjmp. */
6281 emit_move_insn (hard_frame_pointer_rtx, fp);
6282 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6283 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6284 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6286 /* Load the label we are jumping through into r1 so that we know
6287 where to look for it when we get back to setjmp's function for
6288 restoring the gp. */
6289 emit_move_insn (pv, lab);
6290 emit_jump_insn (gen_interspace_jump (pv));
6294 ;;; Hope this is only within a function...
6295 (define_insn "indirect_jump"
6296 [(set (pc) (match_operand 0 "register_operand" "r"))]
6297 "GET_MODE (operands[0]) == word_mode"
6299 [(set_attr "type" "branch")
6300 (set_attr "length" "4")])
6302 (define_expand "extzv"
6303 [(set (match_operand 0 "register_operand" "")
6304 (zero_extract (match_operand 1 "register_operand" "")
6305 (match_operand 2 "uint32_operand" "")
6306 (match_operand 3 "uint32_operand" "")))]
6311 emit_insn (gen_extzv_64 (operands[0], operands[1],
6312 operands[2], operands[3]));
6314 emit_insn (gen_extzv_32 (operands[0], operands[1],
6315 operands[2], operands[3]));
6319 (define_insn "extzv_32"
6320 [(set (match_operand:SI 0 "register_operand" "=r")
6321 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
6322 (match_operand:SI 2 "uint5_operand" "")
6323 (match_operand:SI 3 "uint5_operand" "")))]
6325 "{extru|extrw,u} %1,%3+%2-1,%2,%0"
6326 [(set_attr "type" "shift")
6327 (set_attr "length" "4")])
6330 [(set (match_operand:SI 0 "register_operand" "=r")
6331 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
6333 (match_operand:SI 2 "register_operand" "q")))]
6335 "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
6336 [(set_attr "type" "shift")
6337 (set_attr "length" "4")])
6339 (define_insn "extzv_64"
6340 [(set (match_operand:DI 0 "register_operand" "=r")
6341 (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
6342 (match_operand:DI 2 "uint32_operand" "")
6343 (match_operand:DI 3 "uint32_operand" "")))]
6345 "extrd,u %1,%3+%2-1,%2,%0"
6346 [(set_attr "type" "shift")
6347 (set_attr "length" "4")])
6350 [(set (match_operand:DI 0 "register_operand" "=r")
6351 (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
6353 (match_operand:DI 2 "register_operand" "q")))]
6355 "extrd,u %1,%%sar,1,%0"
6356 [(set_attr "type" "shift")
6357 (set_attr "length" "4")])
6359 (define_expand "extv"
6360 [(set (match_operand 0 "register_operand" "")
6361 (sign_extract (match_operand 1 "register_operand" "")
6362 (match_operand 2 "uint32_operand" "")
6363 (match_operand 3 "uint32_operand" "")))]
6368 emit_insn (gen_extv_64 (operands[0], operands[1],
6369 operands[2], operands[3]));
6371 emit_insn (gen_extv_32 (operands[0], operands[1],
6372 operands[2], operands[3]));
6376 (define_insn "extv_32"
6377 [(set (match_operand:SI 0 "register_operand" "=r")
6378 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
6379 (match_operand:SI 2 "uint5_operand" "")
6380 (match_operand:SI 3 "uint5_operand" "")))]
6382 "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
6383 [(set_attr "type" "shift")
6384 (set_attr "length" "4")])
6387 [(set (match_operand:SI 0 "register_operand" "=r")
6388 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
6390 (match_operand:SI 2 "register_operand" "q")))]
6392 "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
6393 [(set_attr "type" "shift")
6394 (set_attr "length" "4")])
6396 (define_insn "extv_64"
6397 [(set (match_operand:DI 0 "register_operand" "=r")
6398 (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
6399 (match_operand:DI 2 "uint32_operand" "")
6400 (match_operand:DI 3 "uint32_operand" "")))]
6402 "extrd,s %1,%3+%2-1,%2,%0"
6403 [(set_attr "type" "shift")
6404 (set_attr "length" "4")])
6407 [(set (match_operand:DI 0 "register_operand" "=r")
6408 (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
6410 (match_operand:DI 2 "register_operand" "q")))]
6412 "extrd,s %1,%%sar,1,%0"
6413 [(set_attr "type" "shift")
6414 (set_attr "length" "4")])
6416 ;; Only specify the mode operands 0, the rest are assumed to be word_mode.
6417 (define_expand "insv"
6418 [(set (zero_extract (match_operand 0 "register_operand" "")
6419 (match_operand 1 "uint32_operand" "")
6420 (match_operand 2 "uint32_operand" ""))
6421 (match_operand 3 "arith5_operand" ""))]
6426 emit_insn (gen_insv_64 (operands[0], operands[1],
6427 operands[2], operands[3]));
6429 emit_insn (gen_insv_32 (operands[0], operands[1],
6430 operands[2], operands[3]));
6434 (define_insn "insv_32"
6435 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
6436 (match_operand:SI 1 "uint5_operand" "")
6437 (match_operand:SI 2 "uint5_operand" ""))
6438 (match_operand:SI 3 "arith5_operand" "r,L"))]
6441 {dep|depw} %3,%2+%1-1,%1,%0
6442 {depi|depwi} %3,%2+%1-1,%1,%0"
6443 [(set_attr "type" "shift,shift")
6444 (set_attr "length" "4,4")])
6446 ;; Optimize insertion of const_int values of type 1...1xxxx.
6448 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
6449 (match_operand:SI 1 "uint5_operand" "")
6450 (match_operand:SI 2 "uint5_operand" ""))
6451 (match_operand:SI 3 "const_int_operand" ""))]
6452 "(INTVAL (operands[3]) & 0x10) != 0 &&
6453 (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
6456 operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
6457 return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
6459 [(set_attr "type" "shift")
6460 (set_attr "length" "4")])
6462 (define_insn "insv_64"
6463 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
6464 (match_operand:DI 1 "uint32_operand" "")
6465 (match_operand:DI 2 "uint32_operand" ""))
6466 (match_operand:DI 3 "arith32_operand" "r,L"))]
6469 depd %3,%2+%1-1,%1,%0
6470 depdi %3,%2+%1-1,%1,%0"
6471 [(set_attr "type" "shift,shift")
6472 (set_attr "length" "4,4")])
6474 ;; Optimize insertion of const_int values of type 1...1xxxx.
6476 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
6477 (match_operand:DI 1 "uint32_operand" "")
6478 (match_operand:DI 2 "uint32_operand" ""))
6479 (match_operand:DI 3 "const_int_operand" ""))]
6480 "(INTVAL (operands[3]) & 0x10) != 0
6482 && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
6485 operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
6486 return \"depdi %3,%2+%1-1,%1,%0\";
6488 [(set_attr "type" "shift")
6489 (set_attr "length" "4")])
6492 [(set (match_operand:DI 0 "register_operand" "=r")
6493 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6496 "depd,z %1,31,32,%0"
6497 [(set_attr "type" "shift")
6498 (set_attr "length" "4")])
6500 ;; This insn is used for some loop tests, typically loops reversed when
6501 ;; strength reduction is used. It is actually created when the instruction
6502 ;; combination phase combines the special loop test. Since this insn
6503 ;; is both a jump insn and has an output, it must deal with its own
6504 ;; reloads, hence the `m' constraints. The `!' constraints direct reload
6505 ;; to not choose the register alternatives in the event a reload is needed.
6506 (define_insn "decrement_and_branch_until_zero"
6509 (match_operator 2 "comparison_operator"
6510 [(plus:SI (match_operand:SI 0 "register_operand" "+!r,!*f,!*m")
6511 (match_operand:SI 1 "int5_operand" "L,L,L"))
6513 (label_ref (match_operand 3 "" ""))
6516 (plus:SI (match_dup 0) (match_dup 1)))
6517 (clobber (match_scratch:SI 4 "=X,r,r"))]
6519 "* return output_dbra (operands, insn, which_alternative); "
6520 ;; Do not expect to understand this the first time through.
6521 [(set_attr "type" "cbranch,multi,multi")
6522 (set (attr "length")
6523 (if_then_else (eq_attr "alternative" "0")
6524 ;; Loop counter in register case
6525 ;; Short branch has length of 4
6526 ;; Long branch has length of 8
6527 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6532 ;; Loop counter in FP reg case.
6533 ;; Extra goo to deal with additional reload insns.
6534 (if_then_else (eq_attr "alternative" "1")
6535 (if_then_else (lt (match_dup 3) (pc))
6537 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
6542 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6546 ;; Loop counter in memory case.
6547 ;; Extra goo to deal with additional reload insns.
6548 (if_then_else (lt (match_dup 3) (pc))
6550 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
6555 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6558 (const_int 16))))))])
6563 (match_operator 2 "movb_comparison_operator"
6564 [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
6565 (label_ref (match_operand 3 "" ""))
6567 (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
6570 "* return output_movb (operands, insn, which_alternative, 0); "
6571 ;; Do not expect to understand this the first time through.
6572 [(set_attr "type" "cbranch,multi,multi,multi")
6573 (set (attr "length")
6574 (if_then_else (eq_attr "alternative" "0")
6575 ;; Loop counter in register case
6576 ;; Short branch has length of 4
6577 ;; Long branch has length of 8
6578 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6583 ;; Loop counter in FP reg case.
6584 ;; Extra goo to deal with additional reload insns.
6585 (if_then_else (eq_attr "alternative" "1")
6586 (if_then_else (lt (match_dup 3) (pc))
6588 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
6593 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6597 ;; Loop counter in memory or sar case.
6598 ;; Extra goo to deal with additional reload insns.
6600 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6603 (const_int 12)))))])
6605 ;; Handle negated branch.
6609 (match_operator 2 "movb_comparison_operator"
6610 [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
6612 (label_ref (match_operand 3 "" ""))))
6613 (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
6616 "* return output_movb (operands, insn, which_alternative, 1); "
6617 ;; Do not expect to understand this the first time through.
6618 [(set_attr "type" "cbranch,multi,multi,multi")
6619 (set (attr "length")
6620 (if_then_else (eq_attr "alternative" "0")
6621 ;; Loop counter in register case
6622 ;; Short branch has length of 4
6623 ;; Long branch has length of 8
6624 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6629 ;; Loop counter in FP reg case.
6630 ;; Extra goo to deal with additional reload insns.
6631 (if_then_else (eq_attr "alternative" "1")
6632 (if_then_else (lt (match_dup 3) (pc))
6634 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
6639 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6643 ;; Loop counter in memory or SAR case.
6644 ;; Extra goo to deal with additional reload insns.
6646 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6649 (const_int 12)))))])
6652 [(set (pc) (label_ref (match_operand 3 "" "" )))
6653 (set (match_operand:SI 0 "ireg_operand" "=r")
6654 (plus:SI (match_operand:SI 1 "ireg_operand" "r")
6655 (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
6656 "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
6659 return output_parallel_addb (operands, get_attr_length (insn));
6661 [(set_attr "type" "parallel_branch")
6662 (set (attr "length")
6663 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6669 [(set (pc) (label_ref (match_operand 2 "" "" )))
6670 (set (match_operand:SF 0 "ireg_operand" "=r")
6671 (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
6675 return output_parallel_movb (operands, get_attr_length (insn));
6677 [(set_attr "type" "parallel_branch")
6678 (set (attr "length")
6679 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
6685 [(set (pc) (label_ref (match_operand 2 "" "" )))
6686 (set (match_operand:SI 0 "ireg_operand" "=r")
6687 (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
6691 return output_parallel_movb (operands, get_attr_length (insn));
6693 [(set_attr "type" "parallel_branch")
6694 (set (attr "length")
6695 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
6701 [(set (pc) (label_ref (match_operand 2 "" "" )))
6702 (set (match_operand:HI 0 "ireg_operand" "=r")
6703 (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
6707 return output_parallel_movb (operands, get_attr_length (insn));
6709 [(set_attr "type" "parallel_branch")
6710 (set (attr "length")
6711 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
6717 [(set (pc) (label_ref (match_operand 2 "" "" )))
6718 (set (match_operand:QI 0 "ireg_operand" "=r")
6719 (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
6723 return output_parallel_movb (operands, get_attr_length (insn));
6725 [(set_attr "type" "parallel_branch")
6726 (set (attr "length")
6727 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
6733 [(set (match_operand 0 "register_operand" "=f")
6734 (mult (match_operand 1 "register_operand" "f")
6735 (match_operand 2 "register_operand" "f")))
6736 (set (match_operand 3 "register_operand" "+f")
6737 (plus (match_operand 4 "register_operand" "f")
6738 (match_operand 5 "register_operand" "f")))]
6739 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
6740 && reload_completed && fmpyaddoperands (operands)"
6743 if (GET_MODE (operands[0]) == DFmode)
6745 if (rtx_equal_p (operands[3], operands[5]))
6746 return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
6748 return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
6752 if (rtx_equal_p (operands[3], operands[5]))
6753 return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
6755 return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
6758 [(set_attr "type" "fpalu")
6759 (set_attr "length" "4")])
6762 [(set (match_operand 3 "register_operand" "+f")
6763 (plus (match_operand 4 "register_operand" "f")
6764 (match_operand 5 "register_operand" "f")))
6765 (set (match_operand 0 "register_operand" "=f")
6766 (mult (match_operand 1 "register_operand" "f")
6767 (match_operand 2 "register_operand" "f")))]
6768 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
6769 && reload_completed && fmpyaddoperands (operands)"
6772 if (GET_MODE (operands[0]) == DFmode)
6774 if (rtx_equal_p (operands[3], operands[5]))
6775 return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
6777 return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
6781 if (rtx_equal_p (operands[3], operands[5]))
6782 return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
6784 return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
6787 [(set_attr "type" "fpalu")
6788 (set_attr "length" "4")])
6791 [(set (match_operand 0 "register_operand" "=f")
6792 (mult (match_operand 1 "register_operand" "f")
6793 (match_operand 2 "register_operand" "f")))
6794 (set (match_operand 3 "register_operand" "+f")
6795 (minus (match_operand 4 "register_operand" "f")
6796 (match_operand 5 "register_operand" "f")))]
6797 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
6798 && reload_completed && fmpysuboperands (operands)"
6801 if (GET_MODE (operands[0]) == DFmode)
6802 return \"fmpysub,dbl %1,%2,%0,%5,%3\";
6804 return \"fmpysub,sgl %1,%2,%0,%5,%3\";
6806 [(set_attr "type" "fpalu")
6807 (set_attr "length" "4")])
6810 [(set (match_operand 3 "register_operand" "+f")
6811 (minus (match_operand 4 "register_operand" "f")
6812 (match_operand 5 "register_operand" "f")))
6813 (set (match_operand 0 "register_operand" "=f")
6814 (mult (match_operand 1 "register_operand" "f")
6815 (match_operand 2 "register_operand" "f")))]
6816 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
6817 && reload_completed && fmpysuboperands (operands)"
6820 if (GET_MODE (operands[0]) == DFmode)
6821 return \"fmpysub,dbl %1,%2,%0,%5,%3\";
6823 return \"fmpysub,sgl %1,%2,%0,%5,%3\";
6825 [(set_attr "type" "fpalu")
6826 (set_attr "length" "4")])
6828 ;; Clean up turds left by reload.
6830 [(set (match_operand 0 "reg_or_nonsymb_mem_operand" "")
6831 (match_operand 1 "register_operand" "fr"))
6832 (set (match_operand 2 "register_operand" "fr")
6834 "! TARGET_SOFT_FLOAT
6835 && GET_CODE (operands[0]) == MEM
6836 && ! MEM_VOLATILE_P (operands[0])
6837 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6838 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6839 && GET_MODE (operands[0]) == DFmode
6840 && GET_CODE (operands[1]) == REG
6841 && GET_CODE (operands[2]) == REG
6842 && ! side_effects_p (XEXP (operands[0], 0))
6843 && REGNO_REG_CLASS (REGNO (operands[1]))
6844 == REGNO_REG_CLASS (REGNO (operands[2]))"
6849 if (FP_REG_P (operands[1]))
6850 output_asm_insn (output_fp_move_double (operands), operands);
6852 output_asm_insn (output_move_double (operands), operands);
6854 if (rtx_equal_p (operands[1], operands[2]))
6857 xoperands[0] = operands[2];
6858 xoperands[1] = operands[1];
6860 if (FP_REG_P (xoperands[1]))
6861 output_asm_insn (output_fp_move_double (xoperands), xoperands);
6863 output_asm_insn (output_move_double (xoperands), xoperands);
6869 [(set (match_operand 0 "register_operand" "fr")
6870 (match_operand 1 "reg_or_nonsymb_mem_operand" ""))
6871 (set (match_operand 2 "register_operand" "fr")
6873 "! TARGET_SOFT_FLOAT
6874 && GET_CODE (operands[1]) == MEM
6875 && ! MEM_VOLATILE_P (operands[1])
6876 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6877 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6878 && GET_MODE (operands[0]) == DFmode
6879 && GET_CODE (operands[0]) == REG
6880 && GET_CODE (operands[2]) == REG
6881 && ! side_effects_p (XEXP (operands[1], 0))
6882 && REGNO_REG_CLASS (REGNO (operands[0]))
6883 == REGNO_REG_CLASS (REGNO (operands[2]))"
6888 if (FP_REG_P (operands[0]))
6889 output_asm_insn (output_fp_move_double (operands), operands);
6891 output_asm_insn (output_move_double (operands), operands);
6893 xoperands[0] = operands[2];
6894 xoperands[1] = operands[0];
6896 if (FP_REG_P (xoperands[1]))
6897 output_asm_insn (output_fp_move_double (xoperands), xoperands);
6899 output_asm_insn (output_move_double (xoperands), xoperands);
6904 ;; Flush the I and D cache line found at the address in operand 0.
6905 ;; This is used by the trampoline code for nested functions.
6906 ;; So long as the trampoline itself is less than 32 bytes this
6909 (define_insn "dcacheflush"
6910 [(unspec_volatile [(const_int 1)] 0)
6911 (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
6912 (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))]
6914 "fdc 0(%0)\;fdc 0(%1)\;sync"
6915 [(set_attr "type" "multi")
6916 (set_attr "length" "12")])
6918 (define_insn "icacheflush"
6919 [(unspec_volatile [(const_int 2)] 0)
6920 (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
6921 (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))
6922 (use (match_operand 2 "pmode_register_operand" "r"))
6923 (clobber (match_operand 3 "pmode_register_operand" "=&r"))
6924 (clobber (match_operand 4 "pmode_register_operand" "=&r"))]
6926 "mfsp %%sr0,%4\;ldsid (%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
6927 [(set_attr "type" "multi")
6928 (set_attr "length" "52")])
6930 ;; An out-of-line prologue.
6931 (define_insn "outline_prologue_call"
6932 [(unspec_volatile [(const_int 0)] 0)
6933 (clobber (reg:SI 31))
6934 (clobber (reg:SI 22))
6935 (clobber (reg:SI 21))
6936 (clobber (reg:SI 20))
6937 (clobber (reg:SI 19))
6938 (clobber (reg:SI 1))]
6942 extern int frame_pointer_needed;
6944 /* We need two different versions depending on whether or not we
6945 need a frame pointer. Also note that we return to the instruction
6946 immediately after the branch rather than two instructions after the
6947 break as normally is the case. */
6948 if (frame_pointer_needed)
6950 /* Must import the magic millicode routine(s). */
6951 output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
6953 if (TARGET_PORTABLE_RUNTIME)
6955 output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
6956 output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
6960 output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
6964 /* Must import the magic millicode routine(s). */
6965 output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
6967 if (TARGET_PORTABLE_RUNTIME)
6969 output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
6970 output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
6973 output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
6977 [(set_attr "type" "multi")
6978 (set_attr "length" "8")])
6980 ;; An out-of-line epilogue.
6981 (define_insn "outline_epilogue_call"
6982 [(unspec_volatile [(const_int 1)] 0)
6985 (clobber (reg:SI 31))
6986 (clobber (reg:SI 22))
6987 (clobber (reg:SI 21))
6988 (clobber (reg:SI 20))
6989 (clobber (reg:SI 19))
6990 (clobber (reg:SI 2))
6991 (clobber (reg:SI 1))]
6995 extern int frame_pointer_needed;
6997 /* We need two different versions depending on whether or not we
6998 need a frame pointer. Also note that we return to the instruction
6999 immediately after the branch rather than two instructions after the
7000 break as normally is the case. */
7001 if (frame_pointer_needed)
7003 /* Must import the magic millicode routine. */
7004 output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
7006 /* The out-of-line prologue will make sure we return to the right
7008 if (TARGET_PORTABLE_RUNTIME)
7010 output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
7011 output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
7015 output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
7019 /* Must import the magic millicode routine. */
7020 output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
7022 /* The out-of-line prologue will make sure we return to the right
7024 if (TARGET_PORTABLE_RUNTIME)
7026 output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
7027 output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
7030 output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
7034 [(set_attr "type" "multi")
7035 (set_attr "length" "8")])
7037 ;; Given a function pointer, canonicalize it so it can be
7038 ;; reliably compared to another function pointer. */
7039 (define_expand "canonicalize_funcptr_for_compare"
7040 [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
7041 (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
7042 (clobber (match_dup 2))
7043 (clobber (reg:SI 26))
7044 (clobber (reg:SI 22))
7045 (clobber (reg:SI 31))])
7046 (set (match_operand:SI 0 "register_operand" "")
7048 "! TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7051 operands[2] = gen_reg_rtx (SImode);
7052 if (GET_CODE (operands[1]) != REG)
7054 rtx tmp = gen_reg_rtx (Pmode);
7055 emit_move_insn (tmp, operands[1]);
7061 [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
7062 (clobber (match_operand:SI 0 "register_operand" "=a"))
7063 (clobber (reg:SI 26))
7064 (clobber (reg:SI 22))
7065 (clobber (reg:SI 31))]
7069 /* Must import the magic millicode routine. */
7070 output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
7072 /* This is absolutely amazing.
7074 First, copy our input parameter into %r29 just in case we don't
7075 need to call $$sh_func_adrs. */
7076 output_asm_insn (\"copy %%r26,%%r29\", NULL);
7078 /* Next, examine the low two bits in %r26, if they aren't 0x2, then
7079 we use %r26 unchanged. */
7080 if (get_attr_length (insn) == 32)
7081 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+24\", NULL);
7082 else if (get_attr_length (insn) == 40)
7083 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+32\", NULL);
7084 else if (get_attr_length (insn) == 44)
7085 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+36\", NULL);
7087 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+20\", NULL);
7089 /* Next, compare %r26 with 4096, if %r26 is less than or equal to
7090 4096, then we use %r26 unchanged. */
7091 if (get_attr_length (insn) == 32)
7092 output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+16\",
7094 else if (get_attr_length (insn) == 40)
7095 output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+24\",
7097 else if (get_attr_length (insn) == 44)
7098 output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+28\",
7101 output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+12\",
7104 /* Else call $$sh_func_adrs to extract the function's real add24. */
7105 return output_millicode_call (insn,
7106 gen_rtx_SYMBOL_REF (SImode,
7107 \"$$sh_func_adrs\"));
7109 [(set_attr "type" "multi")
7110 (set (attr "length")
7112 ;; Target (or stub) within reach
7113 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
7115 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
7120 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
7124 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
7125 ;; same as NO_SPACE_REGS code
7126 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
7128 (eq (symbol_ref "flag_pic")
7133 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
7137 ;; Out of range and PIC
7140 ;; On the PA, the PIC register is call clobbered, so it must
7141 ;; be saved & restored around calls by the caller. If the call
7142 ;; doesn't return normally (nonlocal goto, or an exception is
7143 ;; thrown), then the code at the exception handler label must
7144 ;; restore the PIC register.
7145 (define_expand "exception_receiver"
7147 "!TARGET_PORTABLE_RUNTIME && flag_pic"
7150 /* Load the PIC register from the stack slot (in our caller's
7152 emit_move_insn (pic_offset_table_rtx,
7153 gen_rtx_MEM (SImode,
7154 plus_constant (stack_pointer_rtx, -32)));
7155 emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx));
7156 emit_insn (gen_blockage ());