1 ;;- Machine description for HP PA-RISC architecture for GNU C compiler
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
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]));
2089 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
2090 "=r,r,r,r,r,r,Q,*q,!f,f,*TR")
2091 (match_operand:SI 1 "move_operand"
2092 "A,r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
2093 "(register_operand (operands[0], SImode)
2094 || reg_or_0_operand (operands[1], SImode))
2095 && ! TARGET_SOFT_FLOAT"
2101 {zdepi|depwi,z} %Z1,%0
2108 [(set_attr "type" "load,move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
2109 (set_attr "pa_combine_type" "addmove")
2110 (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
2113 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
2114 "=r,r,r,r,r,r,Q,*q")
2115 (match_operand:SI 1 "move_operand"
2116 "A,r,J,N,K,RQ,rM,rM"))]
2117 "(register_operand (operands[0], SImode)
2118 || reg_or_0_operand (operands[1], SImode))
2119 && TARGET_SOFT_FLOAT"
2125 {zdepi|depwi,z} %Z1,%0
2129 [(set_attr "type" "load,move,move,move,move,load,store,move")
2130 (set_attr "pa_combine_type" "addmove")
2131 (set_attr "length" "4,4,4,4,4,4,4,4")])
2134 [(set (match_operand:SI 0 "register_operand" "=r")
2135 (mem:SI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2136 (match_operand:SI 2 "register_operand" "r"))))]
2137 "! TARGET_DISABLE_INDEXING"
2138 "{ldwx|ldw} %2(%1),%0"
2139 [(set_attr "type" "load")
2140 (set_attr "length" "4")])
2143 [(set (match_operand:SI 0 "register_operand" "=r")
2144 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2145 (match_operand:SI 2 "basereg_operand" "r"))))]
2146 "! TARGET_DISABLE_INDEXING"
2147 "{ldwx|ldw} %1(%2),%0"
2148 [(set_attr "type" "load")
2149 (set_attr "length" "4")])
2151 ;; Load or store with base-register modification.
2153 (define_expand "pre_load"
2154 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2155 (mem (plus (match_operand 1 "register_operand" "")
2156 (match_operand 2 "pre_cint_operand" ""))))
2158 (plus (match_dup 1) (match_dup 2)))])]
2164 emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
2167 emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
2171 (define_insn "pre_ldw"
2172 [(set (match_operand:SI 0 "register_operand" "=r")
2173 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2174 (match_operand:SI 2 "pre_cint_operand" ""))))
2176 (plus:SI (match_dup 1) (match_dup 2)))]
2180 if (INTVAL (operands[2]) < 0)
2181 return \"{ldwm|ldw,mb} %2(%1),%0\";
2182 return \"{ldws|ldw},mb %2(%1),%0\";
2184 [(set_attr "type" "load")
2185 (set_attr "length" "4")])
2187 (define_insn "pre_ldd"
2188 [(set (match_operand:DI 0 "register_operand" "=r")
2189 (mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2190 (match_operand:DI 2 "pre_cint_operand" ""))))
2192 (plus:DI (match_dup 1) (match_dup 2)))]
2195 [(set_attr "type" "load")
2196 (set_attr "length" "4")])
2199 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2200 (match_operand:SI 1 "pre_cint_operand" "")))
2201 (match_operand:SI 2 "reg_or_0_operand" "rM"))
2203 (plus:SI (match_dup 0) (match_dup 1)))]
2207 if (INTVAL (operands[1]) < 0)
2208 return \"{stwm|stw,mb} %r2,%1(%0)\";
2209 return \"{stws|stw},mb %r2,%1(%0)\";
2211 [(set_attr "type" "store")
2212 (set_attr "length" "4")])
2215 [(set (match_operand:SI 0 "register_operand" "=r")
2216 (mem:SI (match_operand:SI 1 "register_operand" "+r")))
2218 (plus:SI (match_dup 1)
2219 (match_operand:SI 2 "post_cint_operand" "")))]
2223 if (INTVAL (operands[2]) > 0)
2224 return \"{ldwm|ldw,ma} %2(%1),%0\";
2225 return \"{ldws|ldw},ma %2(%1),%0\";
2227 [(set_attr "type" "load")
2228 (set_attr "length" "4")])
2230 (define_expand "post_store"
2231 [(parallel [(set (mem (match_operand 0 "register_operand" ""))
2232 (match_operand 1 "reg_or_0_operand" ""))
2235 (match_operand 2 "post_cint_operand" "")))])]
2241 emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
2244 emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
2248 (define_insn "post_stw"
2249 [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
2250 (match_operand:SI 1 "reg_or_0_operand" "rM"))
2252 (plus:SI (match_dup 0)
2253 (match_operand:SI 2 "post_cint_operand" "")))]
2257 if (INTVAL (operands[2]) > 0)
2258 return \"{stwm|stw,ma} %r1,%2(%0)\";
2259 return \"{stws|stw},ma %r1,%2(%0)\";
2261 [(set_attr "type" "store")
2262 (set_attr "length" "4")])
2264 (define_insn "post_std"
2265 [(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
2266 (match_operand:DI 1 "reg_or_0_operand" "rM"))
2268 (plus:DI (match_dup 0)
2269 (match_operand:DI 2 "post_cint_operand" "")))]
2272 [(set_attr "type" "store")
2273 (set_attr "length" "4")])
2275 ;; For loading the address of a label while generating PIC code.
2276 ;; Note since this pattern can be created at reload time (via movsi), all
2277 ;; the same rules for movsi apply here. (no new pseudos, no temporaries).
2279 [(set (match_operand 0 "pmode_register_operand" "=a")
2280 (match_operand 1 "pic_label_operand" ""))]
2284 rtx label_rtx = gen_label_rtx ();
2286 extern FILE *asm_out_file;
2288 xoperands[0] = operands[0];
2289 xoperands[1] = operands[1];
2290 xoperands[2] = label_rtx;
2291 output_asm_insn (\"{bl|b,l} .+8,%0\", xoperands);
2292 output_asm_insn (\"{depi|depwi} 0,31,2,%0\", xoperands);
2293 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
2294 CODE_LABEL_NUMBER (label_rtx));
2296 /* If we're trying to load the address of a label that happens to be
2297 close, then we can use a shorter sequence. */
2298 if (GET_CODE (operands[1]) == LABEL_REF
2299 && INSN_ADDRESSES_SET_P ()
2300 && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2301 - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2303 /* Prefixing with R% here is wrong, it extracts just 11 bits and is
2304 always non-negative. */
2305 output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2309 output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2310 output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2314 [(set_attr "type" "multi")
2315 (set_attr "length" "16")]) ; 12 or 16
2318 [(set (match_operand:SI 0 "register_operand" "=a")
2319 (plus:SI (match_operand:SI 1 "register_operand" "r")
2320 (high:SI (match_operand 2 "" ""))))]
2321 "symbolic_operand (operands[2], Pmode)
2322 && ! function_label_operand (operands[2], Pmode)
2325 [(set_attr "type" "binary")
2326 (set_attr "length" "4")])
2329 [(set (match_operand:DI 0 "register_operand" "=a")
2330 (plus:DI (match_operand:DI 1 "register_operand" "r")
2331 (high:DI (match_operand 2 "" ""))))]
2332 "symbolic_operand (operands[2], Pmode)
2333 && ! function_label_operand (operands[2], Pmode)
2337 [(set_attr "type" "binary")
2338 (set_attr "length" "4")])
2340 ;; Always use addil rather than ldil;add sequences. This allows the
2341 ;; HP linker to eliminate the dp relocation if the symbolic operand
2342 ;; lives in the TEXT space.
2344 [(set (match_operand:SI 0 "register_operand" "=a")
2345 (high:SI (match_operand 1 "" "")))]
2346 "symbolic_operand (operands[1], Pmode)
2347 && ! function_label_operand (operands[1], Pmode)
2348 && ! read_only_operand (operands[1], Pmode)
2352 if (TARGET_LONG_LOAD_STORE)
2353 return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
2355 return \"addil LR'%H1,%%r27\";
2357 [(set_attr "type" "binary")
2358 (set (attr "length")
2359 (if_then_else (eq (symbol_ref "TARGET_LONG_LOAD_STORE") (const_int 0))
2364 ;; This is for use in the prologue/epilogue code. We need it
2365 ;; to add large constants to a stack pointer or frame pointer.
2366 ;; Because of the additional %r1 pressure, we probably do not
2367 ;; want to use this in general code, so make it available
2368 ;; only after reload.
2370 [(set (match_operand:SI 0 "register_operand" "=!a,*r")
2371 (plus:SI (match_operand:SI 1 "register_operand" "r,r")
2372 (high:SI (match_operand 2 "const_int_operand" ""))))]
2376 ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2377 [(set_attr "type" "binary,binary")
2378 (set_attr "length" "4,8")])
2381 [(set (match_operand:DI 0 "register_operand" "=!a,*r")
2382 (plus:DI (match_operand:DI 1 "register_operand" "r,r")
2383 (high:DI (match_operand 2 "const_int_operand" ""))))]
2384 "reload_completed && TARGET_64BIT"
2387 ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2388 [(set_attr "type" "binary,binary")
2389 (set_attr "length" "4,8")])
2392 [(set (match_operand:SI 0 "register_operand" "=r")
2393 (high:SI (match_operand 1 "" "")))]
2394 "(!flag_pic || !symbolic_operand (operands[1], Pmode))
2395 && !is_function_label_plus_const (operands[1])"
2398 if (symbolic_operand (operands[1], Pmode))
2399 return \"ldil LR'%H1,%0\";
2401 return \"ldil L'%G1,%0\";
2403 [(set_attr "type" "move")
2404 (set_attr "length" "4")])
2407 [(set (match_operand:DI 0 "register_operand" "=r")
2408 (high:DI (match_operand 1 "const_int_operand" "")))]
2411 [(set_attr "type" "move")
2412 (set_attr "length" "4")])
2415 [(set (match_operand:DI 0 "register_operand" "=r")
2416 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2417 (match_operand:DI 2 "const_int_operand" "i")))]
2420 [(set_attr "type" "move")
2421 (set_attr "length" "4")])
2424 [(set (match_operand:SI 0 "register_operand" "=r")
2425 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2426 (match_operand:SI 2 "immediate_operand" "i")))]
2427 "!is_function_label_plus_const (operands[2])"
2430 if (flag_pic && symbolic_operand (operands[2], Pmode))
2432 else if (symbolic_operand (operands[2], Pmode))
2433 return \"ldo RR'%G2(%1),%0\";
2435 return \"ldo R'%G2(%1),%0\";
2437 [(set_attr "type" "move")
2438 (set_attr "length" "4")])
2440 ;; Now that a symbolic_address plus a constant is broken up early
2441 ;; in the compilation phase (for better CSE) we need a special
2442 ;; combiner pattern to load the symbolic address plus the constant
2443 ;; in only 2 instructions. (For cases where the symbolic address
2444 ;; was not a common subexpression.)
2446 [(set (match_operand:SI 0 "register_operand" "")
2447 (match_operand:SI 1 "symbolic_operand" ""))
2448 (clobber (match_operand:SI 2 "register_operand" ""))]
2449 "! (flag_pic && pic_label_operand (operands[1], SImode))"
2450 [(set (match_dup 2) (high:SI (match_dup 1)))
2451 (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
2454 ;; hppa_legitimize_address goes to a great deal of trouble to
2455 ;; create addresses which use indexing. In some cases, this
2456 ;; is a lose because there isn't any store instructions which
2457 ;; allow indexed addresses (with integer register source).
2459 ;; These define_splits try to turn a 3 insn store into
2460 ;; a 2 insn store with some creative RTL rewriting.
2462 [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2463 (match_operand:SI 1 "shadd_operand" ""))
2464 (plus:SI (match_operand:SI 2 "register_operand" "")
2465 (match_operand:SI 3 "const_int_operand" ""))))
2466 (match_operand:SI 4 "register_operand" ""))
2467 (clobber (match_operand:SI 5 "register_operand" ""))]
2469 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2471 (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2475 [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2476 (match_operand:SI 1 "shadd_operand" ""))
2477 (plus:SI (match_operand:SI 2 "register_operand" "")
2478 (match_operand:SI 3 "const_int_operand" ""))))
2479 (match_operand:HI 4 "register_operand" ""))
2480 (clobber (match_operand:SI 5 "register_operand" ""))]
2482 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2484 (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2488 [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2489 (match_operand:SI 1 "shadd_operand" ""))
2490 (plus:SI (match_operand:SI 2 "register_operand" "")
2491 (match_operand:SI 3 "const_int_operand" ""))))
2492 (match_operand:QI 4 "register_operand" ""))
2493 (clobber (match_operand:SI 5 "register_operand" ""))]
2495 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2497 (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2500 (define_expand "movhi"
2501 [(set (match_operand:HI 0 "general_operand" "")
2502 (match_operand:HI 1 "general_operand" ""))]
2506 if (emit_move_sequence (operands, HImode, 0))
2511 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!*f")
2512 (match_operand:HI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!*fM"))]
2513 "register_operand (operands[0], HImode)
2514 || reg_or_0_operand (operands[1], HImode)"
2519 {zdepi|depwi,z} %Z1,%0
2524 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
2525 (set_attr "pa_combine_type" "addmove")
2526 (set_attr "length" "4,4,4,4,4,4,4,4")])
2529 [(set (match_operand:HI 0 "register_operand" "=r")
2530 (mem:HI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2531 (match_operand:SI 2 "register_operand" "r"))))]
2532 "! TARGET_DISABLE_INDEXING"
2533 "{ldhx|ldh} %2(%1),%0"
2534 [(set_attr "type" "load")
2535 (set_attr "length" "4")])
2538 [(set (match_operand:HI 0 "register_operand" "=r")
2539 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
2540 (match_operand:SI 2 "basereg_operand" "r"))))]
2541 "! TARGET_DISABLE_INDEXING"
2542 "{ldhx|ldh} %1(%2),%0"
2543 [(set_attr "type" "load")
2544 (set_attr "length" "4")])
2546 ; Now zero extended variants.
2548 [(set (match_operand:SI 0 "register_operand" "=r")
2549 (zero_extend:SI (mem:HI
2551 (match_operand:SI 1 "basereg_operand" "r")
2552 (match_operand:SI 2 "register_operand" "r")))))]
2553 "! TARGET_DISABLE_INDEXING"
2554 "{ldhx|ldh} %2(%1),%0"
2555 [(set_attr "type" "load")
2556 (set_attr "length" "4")])
2559 [(set (match_operand:SI 0 "register_operand" "=r")
2560 (zero_extend:SI (mem:HI
2562 (match_operand:SI 1 "register_operand" "r")
2563 (match_operand:SI 2 "basereg_operand" "r")))))]
2564 "! TARGET_DISABLE_INDEXING"
2565 "{ldhx|ldh} %1(%2),%0"
2566 [(set_attr "type" "load")
2567 (set_attr "length" "4")])
2570 [(set (match_operand:HI 0 "register_operand" "=r")
2571 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2572 (match_operand:SI 2 "int5_operand" "L"))))
2574 (plus:SI (match_dup 1) (match_dup 2)))]
2576 "{ldhs|ldh},mb %2(%1),%0"
2577 [(set_attr "type" "load")
2578 (set_attr "length" "4")])
2580 ; And a zero extended variant.
2582 [(set (match_operand:SI 0 "register_operand" "=r")
2583 (zero_extend:SI (mem:HI
2585 (match_operand:SI 1 "register_operand" "+r")
2586 (match_operand:SI 2 "int5_operand" "L")))))
2588 (plus:SI (match_dup 1) (match_dup 2)))]
2590 "{ldhs|ldh},mb %2(%1),%0"
2591 [(set_attr "type" "load")
2592 (set_attr "length" "4")])
2595 [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2596 (match_operand:SI 1 "int5_operand" "L")))
2597 (match_operand:HI 2 "reg_or_0_operand" "rM"))
2599 (plus:SI (match_dup 0) (match_dup 1)))]
2601 "{sths|sth},mb %r2,%1(%0)"
2602 [(set_attr "type" "store")
2603 (set_attr "length" "4")])
2606 [(set (match_operand:HI 0 "register_operand" "=r")
2607 (high:HI (match_operand 1 "const_int_operand" "")))]
2610 [(set_attr "type" "move")
2611 (set_attr "length" "4")])
2614 [(set (match_operand:HI 0 "register_operand" "=r")
2615 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
2616 (match_operand 2 "const_int_operand" "")))]
2619 [(set_attr "type" "move")
2620 (set_attr "length" "4")])
2622 (define_expand "movqi"
2623 [(set (match_operand:QI 0 "general_operand" "")
2624 (match_operand:QI 1 "general_operand" ""))]
2628 if (emit_move_sequence (operands, QImode, 0))
2633 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!*f")
2634 (match_operand:QI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!*fM"))]
2635 "register_operand (operands[0], QImode)
2636 || reg_or_0_operand (operands[1], QImode)"
2641 {zdepi|depwi,z} %Z1,%0
2646 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
2647 (set_attr "pa_combine_type" "addmove")
2648 (set_attr "length" "4,4,4,4,4,4,4,4")])
2651 [(set (match_operand:QI 0 "register_operand" "=r")
2652 (mem:QI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2653 (match_operand:SI 2 "register_operand" "r"))))]
2654 "! TARGET_DISABLE_INDEXING"
2655 "{ldbx|ldb} %2(%1),%0"
2656 [(set_attr "type" "load")
2657 (set_attr "length" "4")])
2660 [(set (match_operand:QI 0 "register_operand" "=r")
2661 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
2662 (match_operand:SI 2 "basereg_operand" "r"))))]
2663 "! TARGET_DISABLE_INDEXING"
2664 "{ldbx|ldb} %1(%2),%0"
2665 [(set_attr "type" "load")
2666 (set_attr "length" "4")])
2668 ; Indexed byte load with zero extension to SImode or HImode.
2670 [(set (match_operand:SI 0 "register_operand" "=r")
2671 (zero_extend:SI (mem:QI
2673 (match_operand:SI 1 "basereg_operand" "r")
2674 (match_operand:SI 2 "register_operand" "r")))))]
2675 "! TARGET_DISABLE_INDEXING"
2676 "{ldbx|ldb} %2(%1),%0"
2677 [(set_attr "type" "load")
2678 (set_attr "length" "4")])
2681 [(set (match_operand:SI 0 "register_operand" "=r")
2682 (zero_extend:SI (mem:QI
2684 (match_operand:SI 1 "register_operand" "r")
2685 (match_operand:SI 2 "basereg_operand" "r")))))]
2686 "! TARGET_DISABLE_INDEXING"
2687 "{ldbx|ldb} %1(%2),%0"
2688 [(set_attr "type" "load")
2689 (set_attr "length" "4")])
2692 [(set (match_operand:HI 0 "register_operand" "=r")
2693 (zero_extend:HI (mem:QI
2695 (match_operand:SI 1 "basereg_operand" "r")
2696 (match_operand:SI 2 "register_operand" "r")))))]
2697 "! TARGET_DISABLE_INDEXING"
2698 "{ldbx|ldb} %2(%1),%0"
2699 [(set_attr "type" "load")
2700 (set_attr "length" "4")])
2703 [(set (match_operand:HI 0 "register_operand" "=r")
2704 (zero_extend:HI (mem:QI
2706 (match_operand:SI 1 "register_operand" "r")
2707 (match_operand:SI 2 "basereg_operand" "r")))))]
2708 "! TARGET_DISABLE_INDEXING"
2709 "{ldbx|ldb} %1(%2),%0"
2710 [(set_attr "type" "load")
2711 (set_attr "length" "4")])
2714 [(set (match_operand:QI 0 "register_operand" "=r")
2715 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2716 (match_operand:SI 2 "int5_operand" "L"))))
2717 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2719 "{ldbs|ldb},mb %2(%1),%0"
2720 [(set_attr "type" "load")
2721 (set_attr "length" "4")])
2723 ; Now the same thing with zero extensions.
2725 [(set (match_operand:SI 0 "register_operand" "=r")
2726 (zero_extend:SI (mem:QI (plus:SI
2727 (match_operand:SI 1 "register_operand" "+r")
2728 (match_operand:SI 2 "int5_operand" "L")))))
2729 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2731 "{ldbs|ldb},mb %2(%1),%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 (plus:SI
2738 (match_operand:SI 1 "register_operand" "+r")
2739 (match_operand:SI 2 "int5_operand" "L")))))
2740 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2742 "{ldbs|ldb},mb %2(%1),%0"
2743 [(set_attr "type" "load")
2744 (set_attr "length" "4")])
2747 [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2748 (match_operand:SI 1 "int5_operand" "L")))
2749 (match_operand:QI 2 "reg_or_0_operand" "rM"))
2751 (plus:SI (match_dup 0) (match_dup 1)))]
2753 "{stbs|stb},mb %r2,%1(%0)"
2754 [(set_attr "type" "store")
2755 (set_attr "length" "4")])
2757 ;; The definition of this insn does not really explain what it does,
2758 ;; but it should suffice
2759 ;; that anything generated as this insn will be recognized as one
2760 ;; and that it will not successfully combine with anything.
2761 (define_expand "movstrsi"
2762 [(parallel [(set (match_operand:BLK 0 "" "")
2763 (match_operand:BLK 1 "" ""))
2764 (clobber (match_dup 7))
2765 (clobber (match_dup 8))
2766 (clobber (match_dup 4))
2767 (clobber (match_dup 5))
2768 (clobber (match_dup 6))
2769 (use (match_operand:SI 2 "arith_operand" ""))
2770 (use (match_operand:SI 3 "const_int_operand" ""))])]
2776 /* HP provides very fast block move library routine for the PA;
2777 this routine includes:
2779 4x4 byte at a time block moves,
2780 1x4 byte at a time with alignment checked at runtime with
2781 attempts to align the source and destination as needed
2784 With that in mind, here's the heuristics to try and guess when
2785 the inlined block move will be better than the library block
2788 If the size isn't constant, then always use the library routines.
2790 If the size is large in respect to the known alignment, then use
2791 the library routines.
2793 If the size is small in repsect to the known alignment, then open
2794 code the copy (since that will lead to better scheduling).
2796 Else use the block move pattern. */
2798 /* Undetermined size, use the library routine. */
2799 if (GET_CODE (operands[2]) != CONST_INT)
2802 size = INTVAL (operands[2]);
2803 align = INTVAL (operands[3]);
2804 align = align > 4 ? 4 : align;
2806 /* If size/alignment > 8 (eg size is large in respect to alignment),
2807 then use the library routines. */
2808 if (size / align > 16)
2811 /* This does happen, but not often enough to worry much about. */
2812 if (size / align < MOVE_RATIO)
2815 /* Fall through means we're going to use our block move pattern. */
2817 = replace_equiv_address (operands[0],
2818 copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
2820 = replace_equiv_address (operands[1],
2821 copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
2822 operands[4] = gen_reg_rtx (SImode);
2823 operands[5] = gen_reg_rtx (SImode);
2824 operands[6] = gen_reg_rtx (SImode);
2825 operands[7] = XEXP (operands[0], 0);
2826 operands[8] = XEXP (operands[1], 0);
2829 ;; The operand constraints are written like this to support both compile-time
2830 ;; and run-time determined byte count. If the count is run-time determined,
2831 ;; the register with the byte count is clobbered by the copying code, and
2832 ;; therefore it is forced to operand 2. If the count is compile-time
2833 ;; determined, we need two scratch registers for the unrolled code.
2834 (define_insn "movstrsi_internal"
2835 [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
2836 (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
2837 (clobber (match_dup 0))
2838 (clobber (match_dup 1))
2839 (clobber (match_operand:SI 2 "register_operand" "=r,r")) ;loop cnt/tmp
2840 (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp
2841 (clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
2842 (use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count
2843 (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
2845 "* return output_block_move (operands, !which_alternative);"
2846 [(set_attr "type" "multi,multi")])
2848 ;; Floating point move insns
2850 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2851 ;; to be reloaded by putting the constant into memory when
2852 ;; reg is a floating point register.
2854 ;; For integer registers we use ldil;ldo to set the appropriate
2857 ;; This must come before the movdf pattern, and it must be present
2858 ;; to handle obscure reloading cases.
2860 [(set (match_operand:DF 0 "register_operand" "=?r,f")
2861 (match_operand:DF 1 "" "?F,m"))]
2862 "GET_CODE (operands[1]) == CONST_DOUBLE
2863 && operands[1] != CONST0_RTX (DFmode)
2865 && ! TARGET_SOFT_FLOAT"
2866 "* return (which_alternative == 0 ? output_move_double (operands)
2867 : \"fldd%F1 %1,%0\");"
2868 [(set_attr "type" "move,fpload")
2869 (set_attr "length" "16,4")])
2871 (define_expand "movdf"
2872 [(set (match_operand:DF 0 "general_operand" "")
2873 (match_operand:DF 1 "general_operand" ""))]
2877 if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT)
2878 operands[1] = force_const_mem (DFmode, operands[1]);
2880 if (emit_move_sequence (operands, DFmode, 0))
2884 ;; Reloading an SImode or DImode value requires a scratch register if
2885 ;; going in to or out of float point registers.
2887 (define_expand "reload_indf"
2888 [(set (match_operand:DF 0 "register_operand" "=Z")
2889 (match_operand:DF 1 "non_hard_reg_operand" ""))
2890 (clobber (match_operand:DF 2 "register_operand" "=&r"))]
2894 if (emit_move_sequence (operands, DFmode, operands[2]))
2897 /* We don't want the clobber emitted, so handle this ourselves. */
2898 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2902 (define_expand "reload_outdf"
2903 [(set (match_operand:DF 0 "non_hard_reg_operand" "")
2904 (match_operand:DF 1 "register_operand" "Z"))
2905 (clobber (match_operand:DF 2 "register_operand" "=&r"))]
2909 if (emit_move_sequence (operands, DFmode, operands[2]))
2912 /* We don't want the clobber emitted, so handle this ourselves. */
2913 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2918 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
2919 "=f,*r,RQ,?o,?Q,f,*r,*r")
2920 (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
2921 "fG,*rG,f,*r,*r,RQ,o,RQ"))]
2922 "(register_operand (operands[0], DFmode)
2923 || reg_or_0_operand (operands[1], DFmode))
2924 && ! (GET_CODE (operands[1]) == CONST_DOUBLE
2925 && GET_CODE (operands[0]) == MEM)
2927 && ! TARGET_SOFT_FLOAT"
2930 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
2931 || operands[1] == CONST0_RTX (DFmode))
2932 return output_fp_move_double (operands);
2933 return output_move_double (operands);
2935 [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load")
2936 (set_attr "length" "4,8,4,8,16,4,8,16")])
2939 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
2941 (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
2943 "(register_operand (operands[0], DFmode)
2944 || reg_or_0_operand (operands[1], DFmode))
2946 && TARGET_SOFT_FLOAT"
2949 return output_move_double (operands);
2951 [(set_attr "type" "move,store,store,load,load")
2952 (set_attr "length" "8,8,16,8,16")])
2955 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
2956 "=r,r,r,r,r,Q,*q,!f,f,*TR")
2957 (match_operand:DF 1 "move_operand"
2958 "r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
2959 "(register_operand (operands[0], DFmode)
2960 || reg_or_0_operand (operands[1], DFmode))
2961 && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
2973 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
2974 (set_attr "pa_combine_type" "addmove")
2975 (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
2978 [(set (match_operand:DF 0 "register_operand" "=fx")
2979 (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2980 (match_operand:SI 2 "register_operand" "r"))))]
2981 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2982 "{flddx|fldd} %2(%1),%0"
2983 [(set_attr "type" "fpload")
2984 (set_attr "length" "4")])
2987 [(set (match_operand:DF 0 "register_operand" "=fx")
2988 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
2989 (match_operand:SI 2 "basereg_operand" "r"))))]
2990 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2991 "{flddx|fldd} %1(%2),%0"
2992 [(set_attr "type" "fpload")
2993 (set_attr "length" "4")])
2996 [(set (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2997 (match_operand:SI 2 "register_operand" "r")))
2998 (match_operand:DF 0 "register_operand" "fx"))]
2999 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3000 "{fstdx|fstd} %0,%2(%1)"
3001 [(set_attr "type" "fpstore")
3002 (set_attr "length" "4")])
3005 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
3006 (match_operand:SI 2 "basereg_operand" "r")))
3007 (match_operand:DF 0 "register_operand" "fx"))]
3008 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3009 "{fstdx|fstd} %0,%1(%2)"
3010 [(set_attr "type" "fpstore")
3011 (set_attr "length" "4")])
3013 (define_expand "movdi"
3014 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
3015 (match_operand:DI 1 "general_operand" ""))]
3019 if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT)
3020 operands[1] = force_const_mem (DImode, operands[1]);
3022 if (emit_move_sequence (operands, DImode, 0))
3026 (define_expand "reload_indi"
3027 [(set (match_operand:DI 0 "register_operand" "=Z")
3028 (match_operand:DI 1 "non_hard_reg_operand" ""))
3029 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
3033 if (emit_move_sequence (operands, DImode, operands[2]))
3036 /* We don't want the clobber emitted, so handle this ourselves. */
3037 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3041 (define_expand "reload_outdi"
3042 [(set (match_operand:DI 0 "non_hard_reg_operand" "")
3043 (match_operand:DI 1 "register_operand" "Z"))
3044 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
3048 if (emit_move_sequence (operands, DImode, operands[2]))
3051 /* We don't want the clobber emitted, so handle this ourselves. */
3052 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3057 [(set (match_operand:DI 0 "register_operand" "=r")
3058 (high:DI (match_operand 1 "" "")))]
3062 rtx op0 = operands[0];
3063 rtx op1 = operands[1];
3065 if (GET_CODE (op1) == CONST_INT)
3067 operands[0] = operand_subword (op0, 1, 0, DImode);
3068 output_asm_insn (\"ldil L'%1,%0\", operands);
3070 operands[0] = operand_subword (op0, 0, 0, DImode);
3071 if (INTVAL (op1) < 0)
3072 output_asm_insn (\"ldi -1,%0\", operands);
3074 output_asm_insn (\"ldi 0,%0\", operands);
3077 else if (GET_CODE (op1) == CONST_DOUBLE)
3079 operands[0] = operand_subword (op0, 1, 0, DImode);
3080 operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
3081 output_asm_insn (\"ldil L'%1,%0\", operands);
3083 operands[0] = operand_subword (op0, 0, 0, DImode);
3084 operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
3085 output_asm_insn (singlemove_string (operands), operands);
3091 [(set_attr "type" "move")
3092 (set_attr "length" "8")])
3095 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
3096 "=r,o,Q,r,r,r,f,f,*TR")
3097 (match_operand:DI 1 "general_operand"
3098 "rM,r,r,o*R,Q,i,fM,*TR,f"))]
3099 "(register_operand (operands[0], DImode)
3100 || reg_or_0_operand (operands[1], DImode))
3102 && ! TARGET_SOFT_FLOAT"
3105 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
3106 || (operands[1] == CONST0_RTX (DImode)))
3107 return output_fp_move_double (operands);
3108 return output_move_double (operands);
3110 [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore")
3111 (set_attr "length" "8,8,16,8,16,16,4,4,4")])
3114 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
3115 "=r,r,r,r,r,r,Q,*q,!f,f,*TR")
3116 (match_operand:DI 1 "move_operand"
3117 "A,r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
3118 "(register_operand (operands[0], DImode)
3119 || reg_or_0_operand (operands[1], DImode))
3120 && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
3133 [(set_attr "type" "load,move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
3134 (set_attr "pa_combine_type" "addmove")
3135 (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
3138 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
3140 (match_operand:DI 1 "general_operand"
3142 "(register_operand (operands[0], DImode)
3143 || reg_or_0_operand (operands[1], DImode))
3145 && TARGET_SOFT_FLOAT"
3148 return output_move_double (operands);
3150 [(set_attr "type" "move,store,store,load,load,multi")
3151 (set_attr "length" "8,8,16,8,16,16")])
3154 [(set (match_operand:DI 0 "register_operand" "=r,&r")
3155 (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
3156 (match_operand:DI 2 "immediate_operand" "i,i")))]
3160 /* Don't output a 64 bit constant, since we can't trust the assembler to
3161 handle it correctly. */
3162 if (GET_CODE (operands[2]) == CONST_DOUBLE)
3163 operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
3164 if (which_alternative == 1)
3165 output_asm_insn (\"copy %1,%0\", operands);
3166 return \"ldo R'%G2(%R1),%R0\";
3168 [(set_attr "type" "move,move")
3169 (set_attr "length" "4,8")])
3171 ;; This pattern forces (set (reg:SF ...) (const_double ...))
3172 ;; to be reloaded by putting the constant into memory when
3173 ;; reg is a floating point register.
3175 ;; For integer registers we use ldil;ldo to set the appropriate
3178 ;; This must come before the movsf pattern, and it must be present
3179 ;; to handle obscure reloading cases.
3181 [(set (match_operand:SF 0 "register_operand" "=?r,f")
3182 (match_operand:SF 1 "" "?F,m"))]
3183 "GET_CODE (operands[1]) == CONST_DOUBLE
3184 && operands[1] != CONST0_RTX (SFmode)
3185 && ! TARGET_SOFT_FLOAT"
3186 "* return (which_alternative == 0 ? singlemove_string (operands)
3187 : \" fldw%F1 %1,%0\");"
3188 [(set_attr "type" "move,fpload")
3189 (set_attr "length" "8,4")])
3191 (define_expand "movsf"
3192 [(set (match_operand:SF 0 "general_operand" "")
3193 (match_operand:SF 1 "general_operand" ""))]
3197 if (emit_move_sequence (operands, SFmode, 0))
3201 ;; Reloading an SImode or DImode value requires a scratch register if
3202 ;; going in to or out of float point registers.
3204 (define_expand "reload_insf"
3205 [(set (match_operand:SF 0 "register_operand" "=Z")
3206 (match_operand:SF 1 "non_hard_reg_operand" ""))
3207 (clobber (match_operand:SF 2 "register_operand" "=&r"))]
3211 if (emit_move_sequence (operands, SFmode, operands[2]))
3214 /* We don't want the clobber emitted, so handle this ourselves. */
3215 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3219 (define_expand "reload_outsf"
3220 [(set (match_operand:SF 0 "non_hard_reg_operand" "")
3221 (match_operand:SF 1 "register_operand" "Z"))
3222 (clobber (match_operand:SF 2 "register_operand" "=&r"))]
3226 if (emit_move_sequence (operands, SFmode, operands[2]))
3229 /* We don't want the clobber emitted, so handle this ourselves. */
3230 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3235 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
3237 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
3238 "fG,rG,RQ,RQ,f,rG"))]
3239 "(register_operand (operands[0], SFmode)
3240 || reg_or_0_operand (operands[1], SFmode))
3241 && ! TARGET_SOFT_FLOAT"
3249 [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
3250 (set_attr "pa_combine_type" "addmove")
3251 (set_attr "length" "4,4,4,4,4,4")])
3254 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
3256 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
3258 "(register_operand (operands[0], SFmode)
3259 || reg_or_0_operand (operands[1], SFmode))
3260 && TARGET_SOFT_FLOAT"
3265 [(set_attr "type" "move,load,store")
3266 (set_attr "pa_combine_type" "addmove")
3267 (set_attr "length" "4,4,4")])
3270 [(set (match_operand:SF 0 "register_operand" "=fx")
3271 (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
3272 (match_operand:SI 2 "register_operand" "r"))))]
3273 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3274 "{fldwx|fldw} %2(%1),%0"
3275 [(set_attr "type" "fpload")
3276 (set_attr "length" "4")])
3279 [(set (match_operand:SF 0 "register_operand" "=fx")
3280 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
3281 (match_operand:SI 2 "basereg_operand" "r"))))]
3282 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3283 "{fldwx|fldw} %1(%2),%0"
3284 [(set_attr "type" "fpload")
3285 (set_attr "length" "4")])
3288 [(set (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
3289 (match_operand:SI 2 "register_operand" "r")))
3290 (match_operand:SF 0 "register_operand" "fx"))]
3291 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3292 "{fstwx|fstw} %0,%2(%1)"
3293 [(set_attr "type" "fpstore")
3294 (set_attr "length" "4")])
3297 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
3298 (match_operand:SI 2 "basereg_operand" "r")))
3299 (match_operand:SF 0 "register_operand" "fx"))]
3300 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3301 "{fstwx|fstw} %0,%1(%2)"
3302 [(set_attr "type" "fpstore")
3303 (set_attr "length" "4")])
3306 ;;- zero extension instructions
3307 ;; We have define_expand for zero extension patterns to make sure the
3308 ;; operands get loaded into registers. The define_insns accept
3309 ;; memory operands. This gives us better overall code than just
3310 ;; having a pattern that does or does not accept memory operands.
3312 (define_expand "zero_extendhisi2"
3313 [(set (match_operand:SI 0 "register_operand" "")
3315 (match_operand:HI 1 "register_operand" "")))]
3320 [(set (match_operand:SI 0 "register_operand" "=r,r")
3322 (match_operand:HI 1 "move_operand" "r,RQ")))]
3323 "GET_CODE (operands[1]) != CONST_INT"
3325 {extru|extrw,u} %1,31,16,%0
3327 [(set_attr "type" "shift,load")
3328 (set_attr "length" "4,4")])
3330 (define_expand "zero_extendqihi2"
3331 [(set (match_operand:HI 0 "register_operand" "")
3333 (match_operand:QI 1 "register_operand" "")))]
3338 [(set (match_operand:HI 0 "register_operand" "=r,r")
3340 (match_operand:QI 1 "move_operand" "r,RQ")))]
3341 "GET_CODE (operands[1]) != CONST_INT"
3343 {extru|extrw,u} %1,31,8,%0
3345 [(set_attr "type" "shift,load")
3346 (set_attr "length" "4,4")])
3348 (define_expand "zero_extendqisi2"
3349 [(set (match_operand:SI 0 "register_operand" "")
3351 (match_operand:QI 1 "register_operand" "")))]
3356 [(set (match_operand:SI 0 "register_operand" "=r,r")
3358 (match_operand:QI 1 "move_operand" "r,RQ")))]
3359 "GET_CODE (operands[1]) != CONST_INT"
3361 {extru|extrw,u} %1,31,8,%0
3363 [(set_attr "type" "shift,load")
3364 (set_attr "length" "4,4")])
3366 (define_insn "zero_extendqidi2"
3367 [(set (match_operand:DI 0 "register_operand" "=r")
3368 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
3370 "extrd,u %1,63,8,%0"
3371 [(set_attr "type" "shift")
3372 (set_attr "length" "4")])
3374 (define_insn "zero_extendhidi2"
3375 [(set (match_operand:DI 0 "register_operand" "=r")
3376 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
3378 "extrd,u %1,63,16,%0"
3379 [(set_attr "type" "shift")
3380 (set_attr "length" "4")])
3382 (define_insn "zero_extendsidi2"
3383 [(set (match_operand:DI 0 "register_operand" "=r")
3384 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3386 "extrd,u %1,63,32,%0"
3387 [(set_attr "type" "shift")
3388 (set_attr "length" "4")])
3390 ;;- sign extension instructions
3392 (define_insn "extendhisi2"
3393 [(set (match_operand:SI 0 "register_operand" "=r")
3394 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3396 "{extrs|extrw,s} %1,31,16,%0"
3397 [(set_attr "type" "shift")
3398 (set_attr "length" "4")])
3400 (define_insn "extendqihi2"
3401 [(set (match_operand:HI 0 "register_operand" "=r")
3402 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
3404 "{extrs|extrw,s} %1,31,8,%0"
3405 [(set_attr "type" "shift")
3406 (set_attr "length" "4")])
3408 (define_insn "extendqisi2"
3409 [(set (match_operand:SI 0 "register_operand" "=r")
3410 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3412 "{extrs|extrw,s} %1,31,8,%0"
3413 [(set_attr "type" "shift")
3414 (set_attr "length" "4")])
3416 (define_insn "extendqidi2"
3417 [(set (match_operand:DI 0 "register_operand" "=r")
3418 (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
3420 "extrd,s %1,63,8,%0"
3421 [(set_attr "type" "shift")
3422 (set_attr "length" "4")])
3424 (define_insn "extendhidi2"
3425 [(set (match_operand:DI 0 "register_operand" "=r")
3426 (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
3428 "extrd,s %1,63,16,%0"
3429 [(set_attr "type" "shift")
3430 (set_attr "length" "4")])
3432 (define_insn "extendsidi2"
3433 [(set (match_operand:DI 0 "register_operand" "=r")
3434 (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3436 "extrd,s %1,63,32,%0"
3437 [(set_attr "type" "shift")
3438 (set_attr "length" "4")])
3441 ;; Conversions between float and double.
3443 (define_insn "extendsfdf2"
3444 [(set (match_operand:DF 0 "register_operand" "=f")
3446 (match_operand:SF 1 "register_operand" "f")))]
3447 "! TARGET_SOFT_FLOAT"
3448 "{fcnvff|fcnv},sgl,dbl %1,%0"
3449 [(set_attr "type" "fpalu")
3450 (set_attr "length" "4")])
3452 (define_insn "truncdfsf2"
3453 [(set (match_operand:SF 0 "register_operand" "=f")
3455 (match_operand:DF 1 "register_operand" "f")))]
3456 "! TARGET_SOFT_FLOAT"
3457 "{fcnvff|fcnv},dbl,sgl %1,%0"
3458 [(set_attr "type" "fpalu")
3459 (set_attr "length" "4")])
3461 ;; Conversion between fixed point and floating point.
3462 ;; Note that among the fix-to-float insns
3463 ;; the ones that start with SImode come first.
3464 ;; That is so that an operand that is a CONST_INT
3465 ;; (and therefore lacks a specific machine mode).
3466 ;; will be recognized as SImode (which is always valid)
3467 ;; rather than as QImode or HImode.
3469 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
3470 ;; to be reloaded by putting the constant into memory.
3471 ;; It must come before the more general floatsisf2 pattern.
3473 [(set (match_operand:SF 0 "register_operand" "=f")
3474 (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
3475 "! TARGET_SOFT_FLOAT"
3476 "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
3477 [(set_attr "type" "fpalu")
3478 (set_attr "length" "8")])
3480 (define_insn "floatsisf2"
3481 [(set (match_operand:SF 0 "register_operand" "=f")
3482 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3483 "! TARGET_SOFT_FLOAT"
3484 "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
3485 [(set_attr "type" "fpalu")
3486 (set_attr "length" "4")])
3488 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
3489 ;; to be reloaded by putting the constant into memory.
3490 ;; It must come before the more general floatsidf2 pattern.
3492 [(set (match_operand:DF 0 "register_operand" "=f")
3493 (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
3494 "! TARGET_SOFT_FLOAT"
3495 "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
3496 [(set_attr "type" "fpalu")
3497 (set_attr "length" "8")])
3499 (define_insn "floatsidf2"
3500 [(set (match_operand:DF 0 "register_operand" "=f")
3501 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3502 "! TARGET_SOFT_FLOAT"
3503 "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
3504 [(set_attr "type" "fpalu")
3505 (set_attr "length" "4")])
3507 (define_expand "floatunssisf2"
3508 [(set (subreg:SI (match_dup 2) 4)
3509 (match_operand:SI 1 "register_operand" ""))
3510 (set (subreg:SI (match_dup 2) 4)
3512 (set (match_operand:SF 0 "register_operand" "")
3513 (float:SF (match_dup 2)))]
3514 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3519 emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
3522 operands[2] = gen_reg_rtx (DImode);
3525 (define_expand "floatunssidf2"
3526 [(set (subreg:SI (match_dup 2) 4)
3527 (match_operand:SI 1 "register_operand" ""))
3528 (set (subreg:SI (match_dup 2) 0)
3530 (set (match_operand:DF 0 "register_operand" "")
3531 (float:DF (match_dup 2)))]
3532 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3537 emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
3540 operands[2] = gen_reg_rtx (DImode);
3543 (define_insn "floatdisf2"
3544 [(set (match_operand:SF 0 "register_operand" "=f")
3545 (float:SF (match_operand:DI 1 "register_operand" "f")))]
3546 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3547 "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
3548 [(set_attr "type" "fpalu")
3549 (set_attr "length" "4")])
3551 (define_insn "floatdidf2"
3552 [(set (match_operand:DF 0 "register_operand" "=f")
3553 (float:DF (match_operand:DI 1 "register_operand" "f")))]
3554 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3555 "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
3556 [(set_attr "type" "fpalu")
3557 (set_attr "length" "4")])
3559 ;; Convert a float to an actual integer.
3560 ;; Truncation is performed as part of the conversion.
3562 (define_insn "fix_truncsfsi2"
3563 [(set (match_operand:SI 0 "register_operand" "=f")
3564 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3565 "! TARGET_SOFT_FLOAT"
3566 "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
3567 [(set_attr "type" "fpalu")
3568 (set_attr "length" "4")])
3570 (define_insn "fix_truncdfsi2"
3571 [(set (match_operand:SI 0 "register_operand" "=f")
3572 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3573 "! TARGET_SOFT_FLOAT"
3574 "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
3575 [(set_attr "type" "fpalu")
3576 (set_attr "length" "4")])
3578 (define_insn "fix_truncsfdi2"
3579 [(set (match_operand:DI 0 "register_operand" "=f")
3580 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3581 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3582 "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
3583 [(set_attr "type" "fpalu")
3584 (set_attr "length" "4")])
3586 (define_insn "fix_truncdfdi2"
3587 [(set (match_operand:DI 0 "register_operand" "=f")
3588 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3589 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3590 "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
3591 [(set_attr "type" "fpalu")
3592 (set_attr "length" "4")])
3594 (define_insn "floatunssidf2_pa20"
3595 [(set (match_operand:DF 0 "register_operand" "=f")
3596 (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
3597 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3599 [(set_attr "type" "fpalu")
3600 (set_attr "length" "4")])
3602 (define_insn "floatunssisf2_pa20"
3603 [(set (match_operand:SF 0 "register_operand" "=f")
3604 (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
3605 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3607 [(set_attr "type" "fpalu")
3608 (set_attr "length" "4")])
3610 (define_insn "floatunsdisf2"
3611 [(set (match_operand:SF 0 "register_operand" "=f")
3612 (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
3613 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3614 "fcnv,udw,sgl %1,%0"
3615 [(set_attr "type" "fpalu")
3616 (set_attr "length" "4")])
3618 (define_insn "floatunsdidf2"
3619 [(set (match_operand:DF 0 "register_operand" "=f")
3620 (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
3621 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3622 "fcnv,udw,dbl %1,%0"
3623 [(set_attr "type" "fpalu")
3624 (set_attr "length" "4")])
3626 (define_insn "fixuns_truncsfsi2"
3627 [(set (match_operand:SI 0 "register_operand" "=f")
3628 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3629 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3630 "fcnv,t,sgl,uw %1,%0"
3631 [(set_attr "type" "fpalu")
3632 (set_attr "length" "4")])
3634 (define_insn "fixuns_truncdfsi2"
3635 [(set (match_operand:SI 0 "register_operand" "=f")
3636 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3637 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3638 "fcnv,t,dbl,uw %1,%0"
3639 [(set_attr "type" "fpalu")
3640 (set_attr "length" "4")])
3642 (define_insn "fixuns_truncsfdi2"
3643 [(set (match_operand:DI 0 "register_operand" "=f")
3644 (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3645 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3646 "fcnv,t,sgl,udw %1,%0"
3647 [(set_attr "type" "fpalu")
3648 (set_attr "length" "4")])
3650 (define_insn "fixuns_truncdfdi2"
3651 [(set (match_operand:DI 0 "register_operand" "=f")
3652 (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3653 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3654 "fcnv,t,dbl,udw %1,%0"
3655 [(set_attr "type" "fpalu")
3656 (set_attr "length" "4")])
3658 ;;- arithmetic instructions
3660 (define_expand "adddi3"
3661 [(set (match_operand:DI 0 "register_operand" "")
3662 (plus:DI (match_operand:DI 1 "register_operand" "")
3663 (match_operand:DI 2 "arith_operand" "")))]
3667 ;; We allow arith_operand for operands2, even though strictly speaking it
3668 ;; we would prefer to us arith11_operand since that's what the hardware
3669 ;; can actually support.
3671 ;; But the price of the extra reload in that case is worth the simplicity
3672 ;; we get by allowing a trivial adddi3 expander to be used for both
3676 [(set (match_operand:DI 0 "register_operand" "=r")
3677 (plus:DI (match_operand:DI 1 "register_operand" "%r")
3678 (match_operand:DI 2 "arith_operand" "rI")))]
3682 if (GET_CODE (operands[2]) == CONST_INT)
3684 if (INTVAL (operands[2]) >= 0)
3685 return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
3687 return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
3690 return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
3692 [(set_attr "type" "binary")
3693 (set_attr "length" "8")])
3696 [(set (match_operand:DI 0 "register_operand" "=r,r")
3697 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3698 (match_operand:DI 2 "arith_operand" "r,J")))]
3701 {addl|add,l} %1,%2,%0
3703 [(set_attr "type" "binary,binary")
3704 (set_attr "pa_combine_type" "addmove")
3705 (set_attr "length" "4,4")])
3708 [(set (match_operand:DI 0 "register_operand" "=r")
3709 (plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3710 (match_operand:DI 2 "register_operand" "r")))]
3713 [(set_attr "type" "binary")
3714 (set_attr "length" "4")])
3717 [(set (match_operand:SI 0 "register_operand" "=r")
3718 (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3719 (match_operand:SI 2 "register_operand" "r")))]
3722 [(set_attr "type" "binary")
3723 (set_attr "length" "4")])
3725 ;; define_splits to optimize cases of adding a constant integer
3726 ;; to a register when the constant does not fit in 14 bits. */
3728 [(set (match_operand:SI 0 "register_operand" "")
3729 (plus:SI (match_operand:SI 1 "register_operand" "")
3730 (match_operand:SI 2 "const_int_operand" "")))
3731 (clobber (match_operand:SI 4 "register_operand" ""))]
3732 "! cint_ok_for_move (INTVAL (operands[2]))
3733 && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
3734 [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
3735 (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
3738 int val = INTVAL (operands[2]);
3739 int low = (val < 0) ? -0x2000 : 0x1fff;
3740 int rest = val - low;
3742 operands[2] = GEN_INT (rest);
3743 operands[3] = GEN_INT (low);
3747 [(set (match_operand:SI 0 "register_operand" "")
3748 (plus:SI (match_operand:SI 1 "register_operand" "")
3749 (match_operand:SI 2 "const_int_operand" "")))
3750 (clobber (match_operand:SI 4 "register_operand" ""))]
3751 "! cint_ok_for_move (INTVAL (operands[2]))"
3752 [(set (match_dup 4) (match_dup 2))
3753 (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
3757 HOST_WIDE_INT intval = INTVAL (operands[2]);
3759 /* Try dividing the constant by 2, then 4, and finally 8 to see
3760 if we can get a constant which can be loaded into a register
3761 in a single instruction (cint_ok_for_move).
3763 If that fails, try to negate the constant and subtract it
3764 from our input operand. */
3765 if (intval % 2 == 0 && cint_ok_for_move (intval / 2))
3767 operands[2] = GEN_INT (intval / 2);
3768 operands[3] = GEN_INT (2);
3770 else if (intval % 4 == 0 && cint_ok_for_move (intval / 4))
3772 operands[2] = GEN_INT (intval / 4);
3773 operands[3] = GEN_INT (4);
3775 else if (intval % 8 == 0 && cint_ok_for_move (intval / 8))
3777 operands[2] = GEN_INT (intval / 8);
3778 operands[3] = GEN_INT (8);
3780 else if (cint_ok_for_move (-intval))
3782 emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval)));
3783 emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
3790 (define_insn "addsi3"
3791 [(set (match_operand:SI 0 "register_operand" "=r,r")
3792 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3793 (match_operand:SI 2 "arith_operand" "r,J")))]
3796 {addl|add,l} %1,%2,%0
3798 [(set_attr "type" "binary,binary")
3799 (set_attr "pa_combine_type" "addmove")
3800 (set_attr "length" "4,4")])
3802 (define_expand "subdi3"
3803 [(set (match_operand:DI 0 "register_operand" "")
3804 (minus:DI (match_operand:DI 1 "register_operand" "")
3805 (match_operand:DI 2 "register_operand" "")))]
3810 [(set (match_operand:DI 0 "register_operand" "=r")
3811 (minus:DI (match_operand:DI 1 "register_operand" "r")
3812 (match_operand:DI 2 "register_operand" "r")))]
3814 "sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0"
3815 [(set_attr "type" "binary")
3816 (set_attr "length" "8")])
3819 [(set (match_operand:DI 0 "register_operand" "=r,r,q")
3820 (minus:DI (match_operand:DI 1 "arith11_operand" "r,I,U")
3821 (match_operand:DI 2 "register_operand" "r,r,r")))]
3827 [(set_attr "type" "binary,binary,move")
3828 (set_attr "length" "4,4,4")])
3830 (define_expand "subsi3"
3831 [(set (match_operand:SI 0 "register_operand" "")
3832 (minus:SI (match_operand:SI 1 "arith11_operand" "")
3833 (match_operand:SI 2 "register_operand" "")))]
3838 [(set (match_operand:SI 0 "register_operand" "=r,r")
3839 (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
3840 (match_operand:SI 2 "register_operand" "r,r")))]
3845 [(set_attr "type" "binary,binary")
3846 (set_attr "length" "4,4")])
3849 [(set (match_operand:SI 0 "register_operand" "=r,r,q")
3850 (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,S")
3851 (match_operand:SI 2 "register_operand" "r,r,r")))]
3857 [(set_attr "type" "binary,binary,move")
3858 (set_attr "length" "4,4,4")])
3860 ;; Clobbering a "register_operand" instead of a match_scratch
3861 ;; in operand3 of millicode calls avoids spilling %r1 and
3862 ;; produces better code.
3864 ;; The mulsi3 insns set up registers for the millicode call.
3865 (define_expand "mulsi3"
3866 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3867 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3868 (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
3869 (clobber (match_dup 3))
3870 (clobber (reg:SI 26))
3871 (clobber (reg:SI 25))
3872 (clobber (match_dup 4))])
3873 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3877 operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
3878 if (TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT)
3880 rtx scratch = gen_reg_rtx (DImode);
3881 operands[1] = force_reg (SImode, operands[1]);
3882 operands[2] = force_reg (SImode, operands[2]);
3883 emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
3884 /* We do not want (subreg:SI (XX:DI) 1)) for TARGET_64BIT since
3885 that has no real meaning. */
3888 emit_insn (gen_rtx_SET (VOIDmode,
3890 gen_rtx_SUBREG (SImode, scratch, 0)));
3894 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3895 gen_rtx_SUBREG (SImode, scratch, GET_MODE_SIZE (SImode))));
3898 operands[3] = gen_reg_rtx (SImode);
3901 (define_insn "umulsidi3"
3902 [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3903 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3904 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
3905 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
3907 [(set_attr "type" "fpmuldbl")
3908 (set_attr "length" "4")])
3911 [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3912 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3913 (match_operand:DI 2 "uint32_operand" "f")))]
3914 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && !TARGET_64BIT"
3916 [(set_attr "type" "fpmuldbl")
3917 (set_attr "length" "4")])
3920 [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3921 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3922 (match_operand:DI 2 "uint32_operand" "f")))]
3923 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
3925 [(set_attr "type" "fpmuldbl")
3926 (set_attr "length" "4")])
3929 [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
3930 (clobber (match_operand:SI 0 "register_operand" "=a"))
3931 (clobber (reg:SI 26))
3932 (clobber (reg:SI 25))
3933 (clobber (reg:SI 31))]
3935 "* return output_mul_insn (0, insn);"
3936 [(set_attr "type" "milli")
3937 (set (attr "length")
3939 ;; Target (or stub) within reach
3940 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3942 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3947 (ne (symbol_ref "flag_pic")
3951 ;; Out of reach PORTABLE_RUNTIME
3952 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
3956 ;; Out of reach, can use ble
3960 [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
3961 (clobber (match_operand:SI 0 "register_operand" "=a"))
3962 (clobber (reg:SI 26))
3963 (clobber (reg:SI 25))
3964 (clobber (reg:SI 2))]
3966 "* return output_mul_insn (0, insn);"
3967 [(set_attr "type" "milli")
3968 (set (attr "length") (const_int 4))])
3970 (define_expand "muldi3"
3971 [(set (match_operand:DI 0 "register_operand" "")
3972 (mult:DI (match_operand:DI 1 "register_operand" "")
3973 (match_operand:DI 2 "register_operand" "")))]
3974 "TARGET_64BIT && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
3977 rtx low_product = gen_reg_rtx (DImode);
3978 rtx cross_product1 = gen_reg_rtx (DImode);
3979 rtx cross_product2 = gen_reg_rtx (DImode);
3980 rtx cross_scratch = gen_reg_rtx (DImode);
3981 rtx cross_product = gen_reg_rtx (DImode);
3982 rtx op1l, op1r, op2l, op2r;
3983 rtx op1shifted, op2shifted;
3985 op1shifted = gen_reg_rtx (DImode);
3986 op2shifted = gen_reg_rtx (DImode);
3987 op1l = gen_reg_rtx (SImode);
3988 op1r = gen_reg_rtx (SImode);
3989 op2l = gen_reg_rtx (SImode);
3990 op2r = gen_reg_rtx (SImode);
3992 emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
3994 emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
3996 op1r = gen_rtx_SUBREG (SImode, operands[1], 0);
3997 op2r = gen_rtx_SUBREG (SImode, operands[2], 0);
3998 op1l = gen_rtx_SUBREG (SImode, op1shifted, 0);
3999 op2l = gen_rtx_SUBREG (SImode, op2shifted, 0);
4001 /* Emit multiplies for the cross products. */
4002 emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
4003 emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
4005 /* Emit a multiply for the low sub-word. */
4006 emit_insn (gen_umulsidi3 (low_product, op2r, op1r));
4008 /* Sum the cross products and shift them into proper position. */
4009 emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
4010 emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
4012 /* Add the cross product to the low product and store the result
4013 into the output operand . */
4014 emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
4018 ;;; Division and mod.
4019 (define_expand "divsi3"
4020 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
4021 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
4022 (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
4023 (clobber (match_dup 3))
4024 (clobber (match_dup 4))
4025 (clobber (reg:SI 26))
4026 (clobber (reg:SI 25))
4027 (clobber (match_dup 5))])
4028 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
4032 operands[3] = gen_reg_rtx (SImode);
4035 operands[5] = gen_rtx_REG (SImode, 2);
4036 operands[4] = operands[5];
4040 operands[5] = gen_rtx_REG (SImode, 31);
4041 operands[4] = gen_reg_rtx (SImode);
4043 if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
4049 (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
4050 (clobber (match_operand:SI 1 "register_operand" "=a"))
4051 (clobber (match_operand:SI 2 "register_operand" "=&r"))
4052 (clobber (reg:SI 26))
4053 (clobber (reg:SI 25))
4054 (clobber (reg:SI 31))]
4057 return output_div_insn (operands, 0, insn);"
4058 [(set_attr "type" "milli")
4059 (set (attr "length")
4061 ;; Target (or stub) within reach
4062 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4064 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4069 (ne (symbol_ref "flag_pic")
4073 ;; Out of reach PORTABLE_RUNTIME
4074 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4078 ;; Out of reach, can use ble
4083 (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
4084 (clobber (match_operand:SI 1 "register_operand" "=a"))
4085 (clobber (match_operand:SI 2 "register_operand" "=&r"))
4086 (clobber (reg:SI 26))
4087 (clobber (reg:SI 25))
4088 (clobber (reg:SI 2))]
4091 return output_div_insn (operands, 0, insn);"
4092 [(set_attr "type" "milli")
4093 (set (attr "length") (const_int 4))])
4095 (define_expand "udivsi3"
4096 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
4097 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
4098 (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
4099 (clobber (match_dup 3))
4100 (clobber (match_dup 4))
4101 (clobber (reg:SI 26))
4102 (clobber (reg:SI 25))
4103 (clobber (match_dup 5))])
4104 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
4108 operands[3] = gen_reg_rtx (SImode);
4111 operands[5] = gen_rtx_REG (SImode, 2);
4112 operands[4] = operands[5];
4116 operands[5] = gen_rtx_REG (SImode, 31);
4117 operands[4] = gen_reg_rtx (SImode);
4119 if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
4125 (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
4126 (clobber (match_operand:SI 1 "register_operand" "=a"))
4127 (clobber (match_operand:SI 2 "register_operand" "=&r"))
4128 (clobber (reg:SI 26))
4129 (clobber (reg:SI 25))
4130 (clobber (reg:SI 31))]
4133 return output_div_insn (operands, 1, insn);"
4134 [(set_attr "type" "milli")
4135 (set (attr "length")
4137 ;; Target (or stub) within reach
4138 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4140 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4145 (ne (symbol_ref "flag_pic")
4149 ;; Out of reach PORTABLE_RUNTIME
4150 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4154 ;; Out of reach, can use ble
4159 (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
4160 (clobber (match_operand:SI 1 "register_operand" "=a"))
4161 (clobber (match_operand:SI 2 "register_operand" "=&r"))
4162 (clobber (reg:SI 26))
4163 (clobber (reg:SI 25))
4164 (clobber (reg:SI 2))]
4167 return output_div_insn (operands, 1, insn);"
4168 [(set_attr "type" "milli")
4169 (set (attr "length") (const_int 4))])
4171 (define_expand "modsi3"
4172 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
4173 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
4174 (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
4175 (clobber (match_dup 3))
4176 (clobber (match_dup 4))
4177 (clobber (reg:SI 26))
4178 (clobber (reg:SI 25))
4179 (clobber (match_dup 5))])
4180 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
4186 operands[5] = gen_rtx_REG (SImode, 2);
4187 operands[4] = operands[5];
4191 operands[5] = gen_rtx_REG (SImode, 31);
4192 operands[4] = gen_reg_rtx (SImode);
4194 operands[3] = gen_reg_rtx (SImode);
4198 [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
4199 (clobber (match_operand:SI 0 "register_operand" "=a"))
4200 (clobber (match_operand:SI 1 "register_operand" "=&r"))
4201 (clobber (reg:SI 26))
4202 (clobber (reg:SI 25))
4203 (clobber (reg:SI 31))]
4206 return output_mod_insn (0, insn);"
4207 [(set_attr "type" "milli")
4208 (set (attr "length")
4210 ;; Target (or stub) within reach
4211 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4213 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4218 (ne (symbol_ref "flag_pic")
4222 ;; Out of reach PORTABLE_RUNTIME
4223 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4227 ;; Out of reach, can use ble
4231 [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
4232 (clobber (match_operand:SI 0 "register_operand" "=a"))
4233 (clobber (match_operand:SI 1 "register_operand" "=&r"))
4234 (clobber (reg:SI 26))
4235 (clobber (reg:SI 25))
4236 (clobber (reg:SI 2))]
4239 return output_mod_insn (0, insn);"
4240 [(set_attr "type" "milli")
4241 (set (attr "length") (const_int 4))])
4243 (define_expand "umodsi3"
4244 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
4245 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
4246 (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
4247 (clobber (match_dup 3))
4248 (clobber (match_dup 4))
4249 (clobber (reg:SI 26))
4250 (clobber (reg:SI 25))
4251 (clobber (match_dup 5))])
4252 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
4258 operands[5] = gen_rtx_REG (SImode, 2);
4259 operands[4] = operands[5];
4263 operands[5] = gen_rtx_REG (SImode, 31);
4264 operands[4] = gen_reg_rtx (SImode);
4266 operands[3] = gen_reg_rtx (SImode);
4270 [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
4271 (clobber (match_operand:SI 0 "register_operand" "=a"))
4272 (clobber (match_operand:SI 1 "register_operand" "=&r"))
4273 (clobber (reg:SI 26))
4274 (clobber (reg:SI 25))
4275 (clobber (reg:SI 31))]
4278 return output_mod_insn (1, insn);"
4279 [(set_attr "type" "milli")
4280 (set (attr "length")
4282 ;; Target (or stub) within reach
4283 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4285 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4290 (ne (symbol_ref "flag_pic")
4294 ;; Out of reach PORTABLE_RUNTIME
4295 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4299 ;; Out of reach, can use ble
4303 [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
4304 (clobber (match_operand:SI 0 "register_operand" "=a"))
4305 (clobber (match_operand:SI 1 "register_operand" "=&r"))
4306 (clobber (reg:SI 26))
4307 (clobber (reg:SI 25))
4308 (clobber (reg:SI 2))]
4311 return output_mod_insn (1, insn);"
4312 [(set_attr "type" "milli")
4313 (set (attr "length") (const_int 4))])
4315 ;;- and instructions
4316 ;; We define DImode `and` so with DImode `not` we can get
4317 ;; DImode `andn`. Other combinations are possible.
4319 (define_expand "anddi3"
4320 [(set (match_operand:DI 0 "register_operand" "")
4321 (and:DI (match_operand:DI 1 "arith_double_operand" "")
4322 (match_operand:DI 2 "arith_double_operand" "")))]
4326 if (! register_operand (operands[1], DImode)
4327 || ! register_operand (operands[2], DImode))
4328 /* Let GCC break this into word-at-a-time operations. */
4333 [(set (match_operand:DI 0 "register_operand" "=r")
4334 (and:DI (match_operand:DI 1 "register_operand" "%r")
4335 (match_operand:DI 2 "register_operand" "r")))]
4337 "and %1,%2,%0\;and %R1,%R2,%R0"
4338 [(set_attr "type" "binary")
4339 (set_attr "length" "8")])
4342 [(set (match_operand:DI 0 "register_operand" "=r,r")
4343 (and:DI (match_operand:DI 1 "register_operand" "%?r,0")
4344 (match_operand:DI 2 "and_operand" "rO,P")))]
4346 "* return output_64bit_and (operands); "
4347 [(set_attr "type" "binary")
4348 (set_attr "length" "4")])
4350 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
4351 ; constant with ldil;ldo.
4352 (define_insn "andsi3"
4353 [(set (match_operand:SI 0 "register_operand" "=r,r")
4354 (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
4355 (match_operand:SI 2 "and_operand" "rO,P")))]
4357 "* return output_and (operands); "
4358 [(set_attr "type" "binary,shift")
4359 (set_attr "length" "4,4")])
4362 [(set (match_operand:DI 0 "register_operand" "=r")
4363 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4364 (match_operand:DI 2 "register_operand" "r")))]
4366 "andcm %2,%1,%0\;andcm %R2,%R1,%R0"
4367 [(set_attr "type" "binary")
4368 (set_attr "length" "8")])
4371 [(set (match_operand:DI 0 "register_operand" "=r")
4372 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4373 (match_operand:DI 2 "register_operand" "r")))]
4376 [(set_attr "type" "binary")
4377 (set_attr "length" "4")])
4380 [(set (match_operand:SI 0 "register_operand" "=r")
4381 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4382 (match_operand:SI 2 "register_operand" "r")))]
4385 [(set_attr "type" "binary")
4386 (set_attr "length" "4")])
4388 (define_expand "iordi3"
4389 [(set (match_operand:DI 0 "register_operand" "")
4390 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4391 (match_operand:DI 2 "arith_double_operand" "")))]
4395 if (! register_operand (operands[1], DImode)
4396 || ! register_operand (operands[2], DImode))
4397 /* Let GCC break this into word-at-a-time operations. */
4402 [(set (match_operand:DI 0 "register_operand" "=r")
4403 (ior:DI (match_operand:DI 1 "register_operand" "%r")
4404 (match_operand:DI 2 "register_operand" "r")))]
4406 "or %1,%2,%0\;or %R1,%R2,%R0"
4407 [(set_attr "type" "binary")
4408 (set_attr "length" "8")])
4411 [(set (match_operand:DI 0 "register_operand" "=r,r")
4412 (ior:DI (match_operand:DI 1 "register_operand" "0,0")
4413 (match_operand:DI 2 "ior_operand" "M,i")))]
4415 "* return output_64bit_ior (operands); "
4416 [(set_attr "type" "binary,shift")
4417 (set_attr "length" "4,4")])
4420 [(set (match_operand:DI 0 "register_operand" "=r")
4421 (ior:DI (match_operand:DI 1 "register_operand" "%r")
4422 (match_operand:DI 2 "register_operand" "r")))]
4425 [(set_attr "type" "binary")
4426 (set_attr "length" "4")])
4428 ;; Need a define_expand because we've run out of CONST_OK... characters.
4429 (define_expand "iorsi3"
4430 [(set (match_operand:SI 0 "register_operand" "")
4431 (ior:SI (match_operand:SI 1 "register_operand" "")
4432 (match_operand:SI 2 "arith32_operand" "")))]
4436 if (! (ior_operand (operands[2], SImode)
4437 || register_operand (operands[2], SImode)))
4438 operands[2] = force_reg (SImode, operands[2]);
4442 [(set (match_operand:SI 0 "register_operand" "=r,r")
4443 (ior:SI (match_operand:SI 1 "register_operand" "0,0")
4444 (match_operand:SI 2 "ior_operand" "M,i")))]
4446 "* return output_ior (operands); "
4447 [(set_attr "type" "binary,shift")
4448 (set_attr "length" "4,4")])
4451 [(set (match_operand:SI 0 "register_operand" "=r")
4452 (ior:SI (match_operand:SI 1 "register_operand" "%r")
4453 (match_operand:SI 2 "register_operand" "r")))]
4456 [(set_attr "type" "binary")
4457 (set_attr "length" "4")])
4459 (define_expand "xordi3"
4460 [(set (match_operand:DI 0 "register_operand" "")
4461 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4462 (match_operand:DI 2 "arith_double_operand" "")))]
4466 if (! register_operand (operands[1], DImode)
4467 || ! register_operand (operands[2], DImode))
4468 /* Let GCC break this into word-at-a-time operations. */
4473 [(set (match_operand:DI 0 "register_operand" "=r")
4474 (xor:DI (match_operand:DI 1 "register_operand" "%r")
4475 (match_operand:DI 2 "register_operand" "r")))]
4477 "xor %1,%2,%0\;xor %R1,%R2,%R0"
4478 [(set_attr "type" "binary")
4479 (set_attr "length" "8")])
4482 [(set (match_operand:DI 0 "register_operand" "=r")
4483 (xor:DI (match_operand:DI 1 "register_operand" "%r")
4484 (match_operand:DI 2 "register_operand" "r")))]
4487 [(set_attr "type" "binary")
4488 (set_attr "length" "4")])
4490 (define_insn "xorsi3"
4491 [(set (match_operand:SI 0 "register_operand" "=r")
4492 (xor:SI (match_operand:SI 1 "register_operand" "%r")
4493 (match_operand:SI 2 "register_operand" "r")))]
4496 [(set_attr "type" "binary")
4497 (set_attr "length" "4")])
4499 (define_expand "negdi2"
4500 [(set (match_operand:DI 0 "register_operand" "")
4501 (neg:DI (match_operand:DI 1 "register_operand" "")))]
4506 [(set (match_operand:DI 0 "register_operand" "=r")
4507 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4509 "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
4510 [(set_attr "type" "unary")
4511 (set_attr "length" "8")])
4514 [(set (match_operand:DI 0 "register_operand" "=r")
4515 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4518 [(set_attr "type" "unary")
4519 (set_attr "length" "4")])
4521 (define_insn "negsi2"
4522 [(set (match_operand:SI 0 "register_operand" "=r")
4523 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
4526 [(set_attr "type" "unary")
4527 (set_attr "length" "4")])
4529 (define_expand "one_cmpldi2"
4530 [(set (match_operand:DI 0 "register_operand" "")
4531 (not:DI (match_operand:DI 1 "arith_double_operand" "")))]
4535 if (! register_operand (operands[1], DImode))
4540 [(set (match_operand:DI 0 "register_operand" "=r")
4541 (not:DI (match_operand:DI 1 "register_operand" "r")))]
4543 "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
4544 [(set_attr "type" "unary")
4545 (set_attr "length" "8")])
4548 [(set (match_operand:DI 0 "register_operand" "=r")
4549 (not:DI (match_operand:DI 1 "register_operand" "r")))]
4552 [(set_attr "type" "unary")
4553 (set_attr "length" "4")])
4555 (define_insn "one_cmplsi2"
4556 [(set (match_operand:SI 0 "register_operand" "=r")
4557 (not:SI (match_operand:SI 1 "register_operand" "r")))]
4560 [(set_attr "type" "unary")
4561 (set_attr "length" "4")])
4563 ;; Floating point arithmetic instructions.
4565 (define_insn "adddf3"
4566 [(set (match_operand:DF 0 "register_operand" "=f")
4567 (plus:DF (match_operand:DF 1 "register_operand" "f")
4568 (match_operand:DF 2 "register_operand" "f")))]
4569 "! TARGET_SOFT_FLOAT"
4571 [(set_attr "type" "fpalu")
4572 (set_attr "pa_combine_type" "faddsub")
4573 (set_attr "length" "4")])
4575 (define_insn "addsf3"
4576 [(set (match_operand:SF 0 "register_operand" "=f")
4577 (plus:SF (match_operand:SF 1 "register_operand" "f")
4578 (match_operand:SF 2 "register_operand" "f")))]
4579 "! TARGET_SOFT_FLOAT"
4581 [(set_attr "type" "fpalu")
4582 (set_attr "pa_combine_type" "faddsub")
4583 (set_attr "length" "4")])
4585 (define_insn "subdf3"
4586 [(set (match_operand:DF 0 "register_operand" "=f")
4587 (minus:DF (match_operand:DF 1 "register_operand" "f")
4588 (match_operand:DF 2 "register_operand" "f")))]
4589 "! TARGET_SOFT_FLOAT"
4591 [(set_attr "type" "fpalu")
4592 (set_attr "pa_combine_type" "faddsub")
4593 (set_attr "length" "4")])
4595 (define_insn "subsf3"
4596 [(set (match_operand:SF 0 "register_operand" "=f")
4597 (minus:SF (match_operand:SF 1 "register_operand" "f")
4598 (match_operand:SF 2 "register_operand" "f")))]
4599 "! TARGET_SOFT_FLOAT"
4601 [(set_attr "type" "fpalu")
4602 (set_attr "pa_combine_type" "faddsub")
4603 (set_attr "length" "4")])
4605 (define_insn "muldf3"
4606 [(set (match_operand:DF 0 "register_operand" "=f")
4607 (mult:DF (match_operand:DF 1 "register_operand" "f")
4608 (match_operand:DF 2 "register_operand" "f")))]
4609 "! TARGET_SOFT_FLOAT"
4611 [(set_attr "type" "fpmuldbl")
4612 (set_attr "pa_combine_type" "fmpy")
4613 (set_attr "length" "4")])
4615 (define_insn "mulsf3"
4616 [(set (match_operand:SF 0 "register_operand" "=f")
4617 (mult:SF (match_operand:SF 1 "register_operand" "f")
4618 (match_operand:SF 2 "register_operand" "f")))]
4619 "! TARGET_SOFT_FLOAT"
4621 [(set_attr "type" "fpmulsgl")
4622 (set_attr "pa_combine_type" "fmpy")
4623 (set_attr "length" "4")])
4625 (define_insn "divdf3"
4626 [(set (match_operand:DF 0 "register_operand" "=f")
4627 (div:DF (match_operand:DF 1 "register_operand" "f")
4628 (match_operand:DF 2 "register_operand" "f")))]
4629 "! TARGET_SOFT_FLOAT"
4631 [(set_attr "type" "fpdivdbl")
4632 (set_attr "length" "4")])
4634 (define_insn "divsf3"
4635 [(set (match_operand:SF 0 "register_operand" "=f")
4636 (div:SF (match_operand:SF 1 "register_operand" "f")
4637 (match_operand:SF 2 "register_operand" "f")))]
4638 "! TARGET_SOFT_FLOAT"
4640 [(set_attr "type" "fpdivsgl")
4641 (set_attr "length" "4")])
4643 (define_insn "negdf2"
4644 [(set (match_operand:DF 0 "register_operand" "=f")
4645 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
4646 "! TARGET_SOFT_FLOAT"
4650 return \"fneg,dbl %1,%0\";
4652 return \"fsub,dbl %%fr0,%1,%0\";
4654 [(set_attr "type" "fpalu")
4655 (set_attr "length" "4")])
4657 (define_insn "negsf2"
4658 [(set (match_operand:SF 0 "register_operand" "=f")
4659 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
4660 "! TARGET_SOFT_FLOAT"
4664 return \"fneg,sgl %1,%0\";
4666 return \"fsub,sgl %%fr0,%1,%0\";
4668 [(set_attr "type" "fpalu")
4669 (set_attr "length" "4")])
4671 (define_insn "absdf2"
4672 [(set (match_operand:DF 0 "register_operand" "=f")
4673 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
4674 "! TARGET_SOFT_FLOAT"
4676 [(set_attr "type" "fpalu")
4677 (set_attr "length" "4")])
4679 (define_insn "abssf2"
4680 [(set (match_operand:SF 0 "register_operand" "=f")
4681 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
4682 "! TARGET_SOFT_FLOAT"
4684 [(set_attr "type" "fpalu")
4685 (set_attr "length" "4")])
4687 (define_insn "sqrtdf2"
4688 [(set (match_operand:DF 0 "register_operand" "=f")
4689 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
4690 "! TARGET_SOFT_FLOAT"
4692 [(set_attr "type" "fpsqrtdbl")
4693 (set_attr "length" "4")])
4695 (define_insn "sqrtsf2"
4696 [(set (match_operand:SF 0 "register_operand" "=f")
4697 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
4698 "! TARGET_SOFT_FLOAT"
4700 [(set_attr "type" "fpsqrtsgl")
4701 (set_attr "length" "4")])
4703 ;; PA 2.0 floating point instructions
4707 [(set (match_operand:DF 0 "register_operand" "=f")
4708 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4709 (match_operand:DF 2 "register_operand" "f"))
4710 (match_operand:DF 3 "register_operand" "f")))]
4711 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4712 "fmpyfadd,dbl %1,%2,%3,%0"
4713 [(set_attr "type" "fpmuldbl")
4714 (set_attr "length" "4")])
4717 [(set (match_operand:DF 0 "register_operand" "=f")
4718 (plus:DF (match_operand:DF 1 "register_operand" "f")
4719 (mult:DF (match_operand:DF 2 "register_operand" "f")
4720 (match_operand:DF 3 "register_operand" "f"))))]
4721 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4722 "fmpyfadd,dbl %2,%3,%1,%0"
4723 [(set_attr "type" "fpmuldbl")
4724 (set_attr "length" "4")])
4727 [(set (match_operand:SF 0 "register_operand" "=f")
4728 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4729 (match_operand:SF 2 "register_operand" "f"))
4730 (match_operand:SF 3 "register_operand" "f")))]
4731 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4732 "fmpyfadd,sgl %1,%2,%3,%0"
4733 [(set_attr "type" "fpmulsgl")
4734 (set_attr "length" "4")])
4737 [(set (match_operand:SF 0 "register_operand" "=f")
4738 (plus:SF (match_operand:SF 1 "register_operand" "f")
4739 (mult:SF (match_operand:SF 2 "register_operand" "f")
4740 (match_operand:SF 3 "register_operand" "f"))))]
4741 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4742 "fmpyfadd,sgl %2,%3,%1,%0"
4743 [(set_attr "type" "fpmulsgl")
4744 (set_attr "length" "4")])
4746 ; fmpynfadd patterns
4748 [(set (match_operand:DF 0 "register_operand" "=f")
4749 (minus:DF (match_operand:DF 1 "register_operand" "f")
4750 (mult:DF (match_operand:DF 2 "register_operand" "f")
4751 (match_operand:DF 3 "register_operand" "f"))))]
4752 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4753 "fmpynfadd,dbl %2,%3,%1,%0"
4754 [(set_attr "type" "fpmuldbl")
4755 (set_attr "length" "4")])
4758 [(set (match_operand:SF 0 "register_operand" "=f")
4759 (minus:SF (match_operand:SF 1 "register_operand" "f")
4760 (mult:SF (match_operand:SF 2 "register_operand" "f")
4761 (match_operand:SF 3 "register_operand" "f"))))]
4762 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4763 "fmpynfadd,sgl %2,%3,%1,%0"
4764 [(set_attr "type" "fpmulsgl")
4765 (set_attr "length" "4")])
4769 [(set (match_operand:DF 0 "register_operand" "=f")
4770 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
4771 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4773 [(set_attr "type" "fpalu")
4774 (set_attr "length" "4")])
4777 [(set (match_operand:SF 0 "register_operand" "=f")
4778 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
4779 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4781 [(set_attr "type" "fpalu")
4782 (set_attr "length" "4")])
4784 ;; Generating a fused multiply sequence is a win for this case as it will
4785 ;; reduce the latency for the fused case without impacting the plain
4788 ;; Similar possibilities exist for fnegabs, shadd and other insns which
4789 ;; perform two operations with the result of the first feeding the second.
4791 [(set (match_operand:DF 0 "register_operand" "=f")
4792 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4793 (match_operand:DF 2 "register_operand" "f"))
4794 (match_operand:DF 3 "register_operand" "f")))
4795 (set (match_operand:DF 4 "register_operand" "=&f")
4796 (mult:DF (match_dup 1) (match_dup 2)))]
4797 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4798 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4799 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4801 [(set_attr "type" "fpmuldbl")
4802 (set_attr "length" "8")])
4804 ;; We want to split this up during scheduling since we want both insns
4805 ;; to schedule independently.
4807 [(set (match_operand:DF 0 "register_operand" "=f")
4808 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4809 (match_operand:DF 2 "register_operand" "f"))
4810 (match_operand:DF 3 "register_operand" "f")))
4811 (set (match_operand:DF 4 "register_operand" "=&f")
4812 (mult:DF (match_dup 1) (match_dup 2)))]
4813 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4814 [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
4815 (set (match_dup 0) (plus:DF (mult:DF (match_dup 1) (match_dup 2))
4820 [(set (match_operand:SF 0 "register_operand" "=f")
4821 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4822 (match_operand:SF 2 "register_operand" "f"))
4823 (match_operand:SF 3 "register_operand" "f")))
4824 (set (match_operand:SF 4 "register_operand" "=&f")
4825 (mult:SF (match_dup 1) (match_dup 2)))]
4826 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4827 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4828 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4830 [(set_attr "type" "fpmuldbl")
4831 (set_attr "length" "8")])
4833 ;; We want to split this up during scheduling since we want both insns
4834 ;; to schedule independently.
4836 [(set (match_operand:SF 0 "register_operand" "=f")
4837 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4838 (match_operand:SF 2 "register_operand" "f"))
4839 (match_operand:SF 3 "register_operand" "f")))
4840 (set (match_operand:SF 4 "register_operand" "=&f")
4841 (mult:SF (match_dup 1) (match_dup 2)))]
4842 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4843 [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
4844 (set (match_dup 0) (plus:SF (mult:SF (match_dup 1) (match_dup 2))
4848 ;; Negating a multiply can be faked by adding zero in a fused multiply-add
4851 [(set (match_operand:DF 0 "register_operand" "=f")
4852 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4853 (match_operand:DF 2 "register_operand" "f"))))]
4854 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4855 "fmpynfadd,dbl %1,%2,%%fr0,%0"
4856 [(set_attr "type" "fpmuldbl")
4857 (set_attr "length" "4")])
4860 [(set (match_operand:SF 0 "register_operand" "=f")
4861 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4862 (match_operand:SF 2 "register_operand" "f"))))]
4863 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4864 "fmpynfadd,sgl %1,%2,%%fr0,%0"
4865 [(set_attr "type" "fpmuldbl")
4866 (set_attr "length" "4")])
4869 [(set (match_operand:DF 0 "register_operand" "=f")
4870 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4871 (match_operand:DF 2 "register_operand" "f"))))
4872 (set (match_operand:DF 3 "register_operand" "=&f")
4873 (mult:DF (match_dup 1) (match_dup 2)))]
4874 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4875 && ! (reg_overlap_mentioned_p (operands[3], operands[1])
4876 || reg_overlap_mentioned_p (operands[3], operands[2])))"
4878 [(set_attr "type" "fpmuldbl")
4879 (set_attr "length" "8")])
4882 [(set (match_operand:DF 0 "register_operand" "=f")
4883 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4884 (match_operand:DF 2 "register_operand" "f"))))
4885 (set (match_operand:DF 3 "register_operand" "=&f")
4886 (mult:DF (match_dup 1) (match_dup 2)))]
4887 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4888 [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
4889 (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
4893 [(set (match_operand:SF 0 "register_operand" "=f")
4894 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4895 (match_operand:SF 2 "register_operand" "f"))))
4896 (set (match_operand:SF 3 "register_operand" "=&f")
4897 (mult:SF (match_dup 1) (match_dup 2)))]
4898 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4899 && ! (reg_overlap_mentioned_p (operands[3], operands[1])
4900 || reg_overlap_mentioned_p (operands[3], operands[2])))"
4902 [(set_attr "type" "fpmuldbl")
4903 (set_attr "length" "8")])
4906 [(set (match_operand:SF 0 "register_operand" "=f")
4907 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4908 (match_operand:SF 2 "register_operand" "f"))))
4909 (set (match_operand:SF 3 "register_operand" "=&f")
4910 (mult:SF (match_dup 1) (match_dup 2)))]
4911 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4912 [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
4913 (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
4916 ;; Now fused multiplies with the result of the multiply negated.
4918 [(set (match_operand:DF 0 "register_operand" "=f")
4919 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4920 (match_operand:DF 2 "register_operand" "f")))
4921 (match_operand:DF 3 "register_operand" "f")))]
4922 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4923 "fmpynfadd,dbl %1,%2,%3,%0"
4924 [(set_attr "type" "fpmuldbl")
4925 (set_attr "length" "4")])
4928 [(set (match_operand:SF 0 "register_operand" "=f")
4929 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4930 (match_operand:SF 2 "register_operand" "f")))
4931 (match_operand:SF 3 "register_operand" "f")))]
4932 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4933 "fmpynfadd,sgl %1,%2,%3,%0"
4934 [(set_attr "type" "fpmuldbl")
4935 (set_attr "length" "4")])
4938 [(set (match_operand:DF 0 "register_operand" "=f")
4939 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4940 (match_operand:DF 2 "register_operand" "f")))
4941 (match_operand:DF 3 "register_operand" "f")))
4942 (set (match_operand:DF 4 "register_operand" "=&f")
4943 (mult:DF (match_dup 1) (match_dup 2)))]
4944 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4945 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4946 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4948 [(set_attr "type" "fpmuldbl")
4949 (set_attr "length" "8")])
4952 [(set (match_operand:DF 0 "register_operand" "=f")
4953 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4954 (match_operand:DF 2 "register_operand" "f")))
4955 (match_operand:DF 3 "register_operand" "f")))
4956 (set (match_operand:DF 4 "register_operand" "=&f")
4957 (mult:DF (match_dup 1) (match_dup 2)))]
4958 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4959 [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
4960 (set (match_dup 0) (plus:DF (neg:DF (mult:DF (match_dup 1) (match_dup 2)))
4965 [(set (match_operand:SF 0 "register_operand" "=f")
4966 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4967 (match_operand:SF 2 "register_operand" "f")))
4968 (match_operand:SF 3 "register_operand" "f")))
4969 (set (match_operand:SF 4 "register_operand" "=&f")
4970 (mult:SF (match_dup 1) (match_dup 2)))]
4971 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4972 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4973 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4975 [(set_attr "type" "fpmuldbl")
4976 (set_attr "length" "8")])
4979 [(set (match_operand:SF 0 "register_operand" "=f")
4980 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4981 (match_operand:SF 2 "register_operand" "f")))
4982 (match_operand:SF 3 "register_operand" "f")))
4983 (set (match_operand:SF 4 "register_operand" "=&f")
4984 (mult:SF (match_dup 1) (match_dup 2)))]
4985 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4986 [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
4987 (set (match_dup 0) (plus:SF (neg:SF (mult:SF (match_dup 1) (match_dup 2)))
4992 [(set (match_operand:DF 0 "register_operand" "=f")
4993 (minus:DF (match_operand:DF 3 "register_operand" "f")
4994 (mult:DF (match_operand:DF 1 "register_operand" "f")
4995 (match_operand:DF 2 "register_operand" "f"))))
4996 (set (match_operand:DF 4 "register_operand" "=&f")
4997 (mult:DF (match_dup 1) (match_dup 2)))]
4998 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4999 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
5000 || reg_overlap_mentioned_p (operands[4], operands[2])))"
5002 [(set_attr "type" "fpmuldbl")
5003 (set_attr "length" "8")])
5006 [(set (match_operand:DF 0 "register_operand" "=f")
5007 (minus:DF (match_operand:DF 3 "register_operand" "f")
5008 (mult:DF (match_operand:DF 1 "register_operand" "f")
5009 (match_operand:DF 2 "register_operand" "f"))))
5010 (set (match_operand:DF 4 "register_operand" "=&f")
5011 (mult:DF (match_dup 1) (match_dup 2)))]
5012 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5013 [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
5014 (set (match_dup 0) (minus:DF (match_dup 3)
5015 (mult:DF (match_dup 1) (match_dup 2))))]
5019 [(set (match_operand:SF 0 "register_operand" "=f")
5020 (minus:SF (match_operand:SF 3 "register_operand" "f")
5021 (mult:SF (match_operand:SF 1 "register_operand" "f")
5022 (match_operand:SF 2 "register_operand" "f"))))
5023 (set (match_operand:SF 4 "register_operand" "=&f")
5024 (mult:SF (match_dup 1) (match_dup 2)))]
5025 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5026 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
5027 || reg_overlap_mentioned_p (operands[4], operands[2])))"
5029 [(set_attr "type" "fpmuldbl")
5030 (set_attr "length" "8")])
5033 [(set (match_operand:SF 0 "register_operand" "=f")
5034 (minus:SF (match_operand:SF 3 "register_operand" "f")
5035 (mult:SF (match_operand:SF 1 "register_operand" "f")
5036 (match_operand:SF 2 "register_operand" "f"))))
5037 (set (match_operand:SF 4 "register_operand" "=&f")
5038 (mult:SF (match_dup 1) (match_dup 2)))]
5039 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5040 [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
5041 (set (match_dup 0) (minus:SF (match_dup 3)
5042 (mult:SF (match_dup 1) (match_dup 2))))]
5046 [(set (match_operand:DF 0 "register_operand" "=f")
5047 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
5048 (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
5049 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5050 && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
5052 [(set_attr "type" "fpalu")
5053 (set_attr "length" "8")])
5056 [(set (match_operand:DF 0 "register_operand" "=f")
5057 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
5058 (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
5059 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5060 [(set (match_dup 2) (abs:DF (match_dup 1)))
5061 (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
5065 [(set (match_operand:SF 0 "register_operand" "=f")
5066 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
5067 (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
5068 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5069 && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
5071 [(set_attr "type" "fpalu")
5072 (set_attr "length" "8")])
5075 [(set (match_operand:SF 0 "register_operand" "=f")
5076 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
5077 (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
5078 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5079 [(set (match_dup 2) (abs:SF (match_dup 1)))
5080 (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
5083 ;;- Shift instructions
5085 ;; Optimized special case of shifting.
5088 [(set (match_operand:SI 0 "register_operand" "=r")
5089 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5093 [(set_attr "type" "load")
5094 (set_attr "length" "4")])
5097 [(set (match_operand:SI 0 "register_operand" "=r")
5098 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5102 [(set_attr "type" "load")
5103 (set_attr "length" "4")])
5106 [(set (match_operand:SI 0 "register_operand" "=r")
5107 (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
5108 (match_operand:SI 3 "shadd_operand" ""))
5109 (match_operand:SI 1 "register_operand" "r")))]
5111 "{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0} "
5112 [(set_attr "type" "binary")
5113 (set_attr "length" "4")])
5116 [(set (match_operand:DI 0 "register_operand" "=r")
5117 (plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
5118 (match_operand:DI 3 "shadd_operand" ""))
5119 (match_operand:DI 1 "register_operand" "r")))]
5121 "shladd,l %2,%O3,%1,%0"
5122 [(set_attr "type" "binary")
5123 (set_attr "length" "4")])
5125 (define_expand "ashlsi3"
5126 [(set (match_operand:SI 0 "register_operand" "")
5127 (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
5128 (match_operand:SI 2 "arith32_operand" "")))]
5132 if (GET_CODE (operands[2]) != CONST_INT)
5134 rtx temp = gen_reg_rtx (SImode);
5135 emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
5136 if (GET_CODE (operands[1]) == CONST_INT)
5137 emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
5139 emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
5142 /* Make sure both inputs are not constants,
5143 there are no patterns for that. */
5144 operands[1] = force_reg (SImode, operands[1]);
5148 [(set (match_operand:SI 0 "register_operand" "=r")
5149 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5150 (match_operand:SI 2 "const_int_operand" "n")))]
5152 "{zdep|depw,z} %1,%P2,%L2,%0"
5153 [(set_attr "type" "shift")
5154 (set_attr "length" "4")])
5156 ; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
5157 ; Doing it like this makes slightly better code since reload can
5158 ; replace a register with a known value in range -16..15 with a
5159 ; constant. Ideally, we would like to merge zvdep32 and zvdep_imm32,
5160 ; but since we have no more CONST_OK... characters, that is not
5162 (define_insn "zvdep32"
5163 [(set (match_operand:SI 0 "register_operand" "=r,r")
5164 (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
5165 (minus:SI (const_int 31)
5166 (match_operand:SI 2 "register_operand" "q,q"))))]
5169 {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
5170 {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
5171 [(set_attr "type" "shift,shift")
5172 (set_attr "length" "4,4")])
5174 (define_insn "zvdep_imm32"
5175 [(set (match_operand:SI 0 "register_operand" "=r")
5176 (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
5177 (minus:SI (const_int 31)
5178 (match_operand:SI 2 "register_operand" "q"))))]
5182 int x = INTVAL (operands[1]);
5183 operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
5184 operands[1] = GEN_INT ((x & 0xf) - 0x10);
5185 return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
5187 [(set_attr "type" "shift")
5188 (set_attr "length" "4")])
5190 (define_insn "vdepi_ior"
5191 [(set (match_operand:SI 0 "register_operand" "=r")
5192 (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
5193 (minus:SI (const_int 31)
5194 (match_operand:SI 2 "register_operand" "q")))
5195 (match_operand:SI 3 "register_operand" "0")))]
5196 ; accept ...0001...1, can this be generalized?
5197 "exact_log2 (INTVAL (operands[1]) + 1) >= 0"
5200 int x = INTVAL (operands[1]);
5201 operands[2] = GEN_INT (exact_log2 (x + 1));
5202 return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
5204 [(set_attr "type" "shift")
5205 (set_attr "length" "4")])
5207 (define_insn "vdepi_and"
5208 [(set (match_operand:SI 0 "register_operand" "=r")
5209 (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
5210 (minus:SI (const_int 31)
5211 (match_operand:SI 2 "register_operand" "q")))
5212 (match_operand:SI 3 "register_operand" "0")))]
5213 ; this can be generalized...!
5214 "INTVAL (operands[1]) == -2"
5217 int x = INTVAL (operands[1]);
5218 operands[2] = GEN_INT (exact_log2 ((~x) + 1));
5219 return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
5221 [(set_attr "type" "shift")
5222 (set_attr "length" "4")])
5224 (define_expand "ashldi3"
5225 [(set (match_operand:DI 0 "register_operand" "")
5226 (ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
5227 (match_operand:DI 2 "arith32_operand" "")))]
5231 if (GET_CODE (operands[2]) != CONST_INT)
5233 rtx temp = gen_reg_rtx (DImode);
5234 emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
5235 if (GET_CODE (operands[1]) == CONST_INT)
5236 emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
5238 emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
5241 /* Make sure both inputs are not constants,
5242 there are no patterns for that. */
5243 operands[1] = force_reg (DImode, operands[1]);
5247 [(set (match_operand:DI 0 "register_operand" "=r")
5248 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5249 (match_operand:DI 2 "const_int_operand" "n")))]
5251 "depd,z %1,%p2,%Q2,%0"
5252 [(set_attr "type" "shift")
5253 (set_attr "length" "4")])
5255 ; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
5256 ; Doing it like this makes slightly better code since reload can
5257 ; replace a register with a known value in range -16..15 with a
5258 ; constant. Ideally, we would like to merge zvdep64 and zvdep_imm64,
5259 ; but since we have no more CONST_OK... characters, that is not
5261 (define_insn "zvdep64"
5262 [(set (match_operand:DI 0 "register_operand" "=r,r")
5263 (ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
5264 (minus:DI (const_int 63)
5265 (match_operand:DI 2 "register_operand" "q,q"))))]
5268 depd,z %1,%%sar,64,%0
5269 depdi,z %1,%%sar,64,%0"
5270 [(set_attr "type" "shift,shift")
5271 (set_attr "length" "4,4")])
5273 (define_insn "zvdep_imm64"
5274 [(set (match_operand:DI 0 "register_operand" "=r")
5275 (ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
5276 (minus:DI (const_int 63)
5277 (match_operand:DI 2 "register_operand" "q"))))]
5281 int x = INTVAL (operands[1]);
5282 operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
5283 operands[1] = GEN_INT ((x & 0x1f) - 0x20);
5284 return \"depdi,z %1,%%sar,%2,%0\";
5286 [(set_attr "type" "shift")
5287 (set_attr "length" "4")])
5290 [(set (match_operand:DI 0 "register_operand" "=r")
5291 (ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
5292 (minus:DI (const_int 63)
5293 (match_operand:DI 2 "register_operand" "q")))
5294 (match_operand:DI 3 "register_operand" "0")))]
5295 ; accept ...0001...1, can this be generalized?
5296 "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) >= 0"
5299 int x = INTVAL (operands[1]);
5300 operands[2] = GEN_INT (exact_log2 (x + 1));
5301 return \"depdi -1,%%sar,%2,%0\";
5303 [(set_attr "type" "shift")
5304 (set_attr "length" "4")])
5307 [(set (match_operand:DI 0 "register_operand" "=r")
5308 (and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
5309 (minus:DI (const_int 63)
5310 (match_operand:DI 2 "register_operand" "q")))
5311 (match_operand:DI 3 "register_operand" "0")))]
5312 ; this can be generalized...!
5313 "TARGET_64BIT && INTVAL (operands[1]) == -2"
5316 int x = INTVAL (operands[1]);
5317 operands[2] = GEN_INT (exact_log2 ((~x) + 1));
5318 return \"depdi 0,%%sar,%2,%0\";
5320 [(set_attr "type" "shift")
5321 (set_attr "length" "4")])
5323 (define_expand "ashrsi3"
5324 [(set (match_operand:SI 0 "register_operand" "")
5325 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
5326 (match_operand:SI 2 "arith32_operand" "")))]
5330 if (GET_CODE (operands[2]) != CONST_INT)
5332 rtx temp = gen_reg_rtx (SImode);
5333 emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
5334 emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
5340 [(set (match_operand:SI 0 "register_operand" "=r")
5341 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5342 (match_operand:SI 2 "const_int_operand" "n")))]
5344 "{extrs|extrw,s} %1,%P2,%L2,%0"
5345 [(set_attr "type" "shift")
5346 (set_attr "length" "4")])
5348 (define_insn "vextrs32"
5349 [(set (match_operand:SI 0 "register_operand" "=r")
5350 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5351 (minus:SI (const_int 31)
5352 (match_operand:SI 2 "register_operand" "q"))))]
5354 "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
5355 [(set_attr "type" "shift")
5356 (set_attr "length" "4")])
5358 (define_expand "ashrdi3"
5359 [(set (match_operand:DI 0 "register_operand" "")
5360 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5361 (match_operand:DI 2 "arith32_operand" "")))]
5365 if (GET_CODE (operands[2]) != CONST_INT)
5367 rtx temp = gen_reg_rtx (DImode);
5368 emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
5369 emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
5375 [(set (match_operand:DI 0 "register_operand" "=r")
5376 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5377 (match_operand:DI 2 "const_int_operand" "n")))]
5379 "extrd,s %1,%p2,%Q2,%0"
5380 [(set_attr "type" "shift")
5381 (set_attr "length" "4")])
5383 (define_insn "vextrs64"
5384 [(set (match_operand:DI 0 "register_operand" "=r")
5385 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5386 (minus:DI (const_int 63)
5387 (match_operand:DI 2 "register_operand" "q"))))]
5389 "extrd,s %1,%%sar,64,%0"
5390 [(set_attr "type" "shift")
5391 (set_attr "length" "4")])
5393 (define_insn "lshrsi3"
5394 [(set (match_operand:SI 0 "register_operand" "=r,r")
5395 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
5396 (match_operand:SI 2 "arith32_operand" "q,n")))]
5399 {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
5400 {extru|extrw,u} %1,%P2,%L2,%0"
5401 [(set_attr "type" "shift")
5402 (set_attr "length" "4")])
5404 (define_insn "lshrdi3"
5405 [(set (match_operand:DI 0 "register_operand" "=r,r")
5406 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
5407 (match_operand:DI 2 "arith32_operand" "q,n")))]
5410 shrpd %%r0,%1,%%sar,%0
5411 extrd,u %1,%p2,%Q2,%0"
5412 [(set_attr "type" "shift")
5413 (set_attr "length" "4")])
5415 (define_insn "rotrsi3"
5416 [(set (match_operand:SI 0 "register_operand" "=r,r")
5417 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
5418 (match_operand:SI 2 "arith32_operand" "q,n")))]
5422 if (GET_CODE (operands[2]) == CONST_INT)
5424 operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
5425 return \"{shd|shrpw} %1,%1,%2,%0\";
5428 return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
5430 [(set_attr "type" "shift")
5431 (set_attr "length" "4")])
5433 (define_expand "rotlsi3"
5434 [(set (match_operand:SI 0 "register_operand" "")
5435 (rotate:SI (match_operand:SI 1 "register_operand" "")
5436 (match_operand:SI 2 "arith32_operand" "")))]
5440 if (GET_CODE (operands[2]) != CONST_INT)
5442 rtx temp = gen_reg_rtx (SImode);
5443 emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
5444 emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
5447 /* Else expand normally. */
5451 [(set (match_operand:SI 0 "register_operand" "=r")
5452 (rotate:SI (match_operand:SI 1 "register_operand" "r")
5453 (match_operand:SI 2 "const_int_operand" "n")))]
5457 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
5458 return \"{shd|shrpw} %1,%1,%2,%0\";
5460 [(set_attr "type" "shift")
5461 (set_attr "length" "4")])
5464 [(set (match_operand:SI 0 "register_operand" "=r")
5465 (match_operator:SI 5 "plus_xor_ior_operator"
5466 [(ashift:SI (match_operand:SI 1 "register_operand" "r")
5467 (match_operand:SI 3 "const_int_operand" "n"))
5468 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
5469 (match_operand:SI 4 "const_int_operand" "n"))]))]
5470 "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
5471 "{shd|shrpw} %1,%2,%4,%0"
5472 [(set_attr "type" "shift")
5473 (set_attr "length" "4")])
5476 [(set (match_operand:SI 0 "register_operand" "=r")
5477 (match_operator:SI 5 "plus_xor_ior_operator"
5478 [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
5479 (match_operand:SI 4 "const_int_operand" "n"))
5480 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5481 (match_operand:SI 3 "const_int_operand" "n"))]))]
5482 "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
5483 "{shd|shrpw} %1,%2,%4,%0"
5484 [(set_attr "type" "shift")
5485 (set_attr "length" "4")])
5488 [(set (match_operand:SI 0 "register_operand" "=r")
5489 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
5490 (match_operand:SI 2 "const_int_operand" ""))
5491 (match_operand:SI 3 "const_int_operand" "")))]
5492 "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) >= 0"
5495 int cnt = INTVAL (operands[2]) & 31;
5496 operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
5497 operands[2] = GEN_INT (31 - cnt);
5498 return \"{zdep|depw,z} %1,%2,%3,%0\";
5500 [(set_attr "type" "shift")
5501 (set_attr "length" "4")])
5503 ;; Unconditional and other jump instructions.
5505 ;; This can only be used in a leaf function, so we do
5506 ;; not need to use the PIC register when generating PIC code.
5507 (define_insn "return"
5511 "hppa_can_use_return_insn_p ()"
5515 return \"bve%* (%%r2)\";
5516 return \"bv%* %%r0(%%r2)\";
5518 [(set_attr "type" "branch")
5519 (set_attr "length" "4")])
5521 ;; Emit a different pattern for functions which have non-trivial
5522 ;; epilogues so as not to confuse jump and reorg.
5523 (define_insn "return_internal"
5531 return \"bve%* (%%r2)\";
5532 return \"bv%* %%r0(%%r2)\";
5534 [(set_attr "type" "branch")
5535 (set_attr "length" "4")])
5537 ;; Use the PIC register to ensure it's restored after a
5538 ;; call in PIC mode.
5539 (define_insn "return_internal_pic"
5541 (use (match_operand 0 "register_operand" "r"))
5543 "flag_pic && true_regnum (operands[0]) == PIC_OFFSET_TABLE_REGNUM"
5547 return \"bve%* (%%r2)\";
5548 return \"bv%* %%r0(%%r2)\";
5550 [(set_attr "type" "branch")
5551 (set_attr "length" "4")])
5553 (define_expand "prologue"
5556 "hppa_expand_prologue ();DONE;")
5558 (define_expand "sibcall_epilogue"
5563 hppa_expand_epilogue ();
5567 (define_expand "epilogue"
5572 /* Try to use the trivial return first. Else use the full
5574 if (hppa_can_use_return_insn_p ())
5575 emit_jump_insn (gen_return ());
5580 hppa_expand_epilogue ();
5582 x = gen_return_internal_pic (gen_rtx_REG (word_mode,
5583 PIC_OFFSET_TABLE_REGNUM));
5585 x = gen_return_internal ();
5591 ;; Special because we use the value placed in %r2 by the bl instruction
5592 ;; from within its delay slot to set the value for the 2nd parameter to
5594 (define_insn "call_profiler"
5595 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
5596 (match_operand 1 "" ""))
5597 (use (match_operand 2 "" ""))
5600 (clobber (reg:SI 2))]
5606 output_arg_descriptor (insn);
5608 xoperands[0] = operands[0];
5609 xoperands[1] = operands[2];
5610 xoperands[2] = gen_label_rtx ();
5611 output_asm_insn (\"{bl|b,l} %0,%%r2\;ldo %1-%2(%%r2),%%r25\", xoperands);
5613 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5614 CODE_LABEL_NUMBER (xoperands[2]));
5617 [(set_attr "type" "multi")
5618 (set_attr "length" "8")])
5620 (define_insn "blockage"
5621 [(unspec_volatile [(const_int 2)] 0)]
5624 [(set_attr "length" "0")])
5627 [(set (pc) (label_ref (match_operand 0 "" "")))]
5631 extern int optimize;
5633 if (GET_MODE (insn) == SImode)
5636 /* An unconditional branch which can reach its target. */
5637 if (get_attr_length (insn) != 24
5638 && get_attr_length (insn) != 16)
5641 /* An unconditional branch which can not reach its target.
5643 We need to be able to use %r1 as a scratch register; however,
5644 we can never be sure whether or not it's got a live value in
5645 it. Therefore, we must restore its original value after the
5648 To make matters worse, we don't have a stack slot which we
5649 can always clobber. sp-12/sp-16 shouldn't ever have a live
5650 value during a non-optimizing compilation, so we use those
5651 slots for now. We don't support very long branches when
5652 optimizing -- they should be quite rare when optimizing.
5654 Really the way to go long term is a register scavenger; goto
5655 the target of the jump and find a register which we can use
5656 as a scratch to hold the value in %r1. */
5658 /* We don't know how to register scavenge yet. */
5662 /* First store %r1 into the stack. */
5663 output_asm_insn (\"stw %%r1,-16(%%r30)\", operands);
5665 /* Now load the target address into %r1 and do an indirect jump
5666 to the value specified in %r1. Be careful to generate PIC
5671 xoperands[0] = operands[0];
5672 xoperands[1] = gen_label_rtx ();
5674 output_asm_insn (\"{bl|b,l} .+8,%%r1\\n\\taddil L'%l0-%l1,%%r1\",
5676 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5677 CODE_LABEL_NUMBER (xoperands[1]));
5678 output_asm_insn (\"ldo R'%l0-%l1(%%r1),%%r1\\n\\tbv %%r0(%%r1)\",
5682 output_asm_insn (\"ldil L'%l0,%%r1\\n\\tbe R'%l0(%%sr4,%%r1)\", operands);;
5684 /* And restore the value of %r1 in the delay slot. We're not optimizing,
5685 so we know nothing else can be in the delay slot. */
5686 return \"ldw -16(%%r30),%%r1\";
5688 [(set_attr "type" "uncond_branch")
5689 (set_attr "pa_combine_type" "uncond_branch")
5690 (set (attr "length")
5691 (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 1))
5692 (if_then_else (lt (abs (minus (match_dup 0)
5693 (plus (pc) (const_int 8))))
5697 (ge (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
5699 (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
5704 ;; Subroutines of "casesi".
5705 ;; operand 0 is index
5706 ;; operand 1 is the minimum bound
5707 ;; operand 2 is the maximum bound - minimum bound + 1
5708 ;; operand 3 is CODE_LABEL for the table;
5709 ;; operand 4 is the CODE_LABEL to go to if index out of range.
5711 (define_expand "casesi"
5712 [(match_operand:SI 0 "general_operand" "")
5713 (match_operand:SI 1 "const_int_operand" "")
5714 (match_operand:SI 2 "const_int_operand" "")
5715 (match_operand 3 "" "")
5716 (match_operand 4 "" "")]
5720 if (GET_CODE (operands[0]) != REG)
5721 operands[0] = force_reg (SImode, operands[0]);
5723 if (operands[1] != const0_rtx)
5725 rtx reg = gen_reg_rtx (SImode);
5727 operands[1] = GEN_INT (-INTVAL (operands[1]));
5728 if (!INT_14_BITS (operands[1]))
5729 operands[1] = force_reg (SImode, operands[1]);
5730 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
5735 /* In 64bit mode we must make sure to wipe the upper bits of the register
5736 just in case the addition overflowed or we had random bits in the
5737 high part of the register. */
5740 rtx reg = gen_reg_rtx (DImode);
5741 emit_insn (gen_extendsidi2 (reg, operands[0]));
5742 operands[0] = gen_rtx_SUBREG (SImode, reg, 0);
5745 if (!INT_5_BITS (operands[2]))
5746 operands[2] = force_reg (SImode, operands[2]);
5748 emit_insn (gen_cmpsi (operands[0], operands[2]));
5749 emit_jump_insn (gen_bgtu (operands[4]));
5750 if (TARGET_BIG_SWITCH)
5752 rtx temp = gen_reg_rtx (SImode);
5753 emit_move_insn (temp, gen_rtx_PLUS (SImode, operands[0], operands[0]));
5756 emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
5760 (define_insn "casesi0"
5762 (mem:SI (plus:SI (pc)
5763 (match_operand:SI 0 "register_operand" "r")))
5764 (label_ref (match_operand 1 "" ""))))]
5767 [(set_attr "type" "multi")
5768 (set_attr "length" "8")])
5770 ;; Need nops for the calls because execution is supposed to continue
5771 ;; past; we don't want to nullify an instruction that we need.
5772 ;;- jump to subroutine
5774 (define_expand "call"
5775 [(parallel [(call (match_operand:SI 0 "" "")
5776 (match_operand 1 "" ""))
5777 (clobber (reg:SI 2))])]
5784 if (TARGET_PORTABLE_RUNTIME)
5785 op = force_reg (SImode, XEXP (operands[0], 0));
5787 op = XEXP (operands[0], 0);
5790 emit_move_insn (arg_pointer_rtx,
5791 gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
5794 /* Use two different patterns for calls to explicitly named functions
5795 and calls through function pointers. This is necessary as these two
5796 types of calls use different calling conventions, and CSE might try
5797 to change the named call into an indirect call in some cases (using
5798 two patterns keeps CSE from performing this optimization). */
5799 if (GET_CODE (op) == SYMBOL_REF)
5800 call_insn = emit_call_insn (gen_call_internal_symref (op, operands[1]));
5801 else if (TARGET_64BIT)
5803 rtx tmpreg = force_reg (word_mode, op);
5804 call_insn = emit_call_insn (gen_call_internal_reg_64bit (tmpreg,
5809 rtx tmpreg = gen_rtx_REG (word_mode, 22);
5810 emit_move_insn (tmpreg, force_reg (word_mode, op));
5811 call_insn = emit_call_insn (gen_call_internal_reg (operands[1]));
5816 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
5818 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
5820 /* After each call we must restore the PIC register, even if it
5821 doesn't appear to be used. */
5822 emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
5827 (define_insn "call_internal_symref"
5828 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
5829 (match_operand 1 "" "i"))
5830 (clobber (reg:SI 2))
5831 (use (const_int 0))]
5832 "! TARGET_PORTABLE_RUNTIME"
5835 output_arg_descriptor (insn);
5836 return output_call (insn, operands[0], 0);
5838 [(set_attr "type" "call")
5839 (set (attr "length")
5840 ;; If we're sure that we can either reach the target or that the
5841 ;; linker can use a long-branch stub, then the length is 4 bytes.
5843 ;; For long-calls the length will be either 52 bytes (non-pic)
5844 ;; or 68 bytes (pic). */
5845 ;; Else we have to use a long-call;
5846 (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
5849 (if_then_else (eq (symbol_ref "flag_pic")
5854 (define_insn "call_internal_reg_64bit"
5855 [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
5856 (match_operand 1 "" "i"))
5857 (clobber (reg:SI 2))
5858 (use (const_int 1))]
5864 /* ??? Needs more work. Length computation, split into multiple insns,
5865 do not use %r22 directly, expose delay slot. */
5866 return \"ldd 16(%0),%%r2\;ldd 24(%0),%%r27\;bve,l (%%r2),%%r2\;nop\";
5868 [(set_attr "type" "dyncall")
5869 (set (attr "length") (const_int 16))])
5871 (define_insn "call_internal_reg"
5872 [(call (mem:SI (reg:SI 22))
5873 (match_operand 0 "" "i"))
5874 (clobber (reg:SI 2))
5875 (use (const_int 1))]
5881 /* First the special case for kernels, level 0 systems, etc. */
5882 if (TARGET_FAST_INDIRECT_CALLS)
5883 return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
5885 /* Now the normal case -- we can reach $$dyncall directly or
5886 we're sure that we can get there via a long-branch stub.
5888 No need to check target flags as the length uniquely identifies
5889 the remaining cases. */
5890 if (get_attr_length (insn) == 8)
5891 return \".CALL\\tARGW0=GR\;{bl|b,l} $$dyncall,%%r31\;copy %%r31,%%r2\";
5893 /* Long millicode call, but we are not generating PIC or portable runtime
5895 if (get_attr_length (insn) == 12)
5896 return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
5898 /* Long millicode call for portable runtime. */
5899 if (get_attr_length (insn) == 20)
5900 return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr %%r0,%%r2\;bv,n %%r0(%%r31)\;nop\";
5902 /* If we're generating PIC code. */
5903 xoperands[0] = operands[0];
5904 xoperands[1] = gen_label_rtx ();
5905 output_asm_insn (\"{bl|b,l} .+8,%%r1\", xoperands);
5906 output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
5907 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5908 CODE_LABEL_NUMBER (xoperands[1]));
5909 output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
5910 output_asm_insn (\"blr %%r0,%%r2\", xoperands);
5911 output_asm_insn (\"bv,n %%r0(%%r1)\\n\\tnop\", xoperands);
5914 [(set_attr "type" "dyncall")
5915 (set (attr "length")
5917 ;; First FAST_INDIRECT_CALLS
5918 (ne (symbol_ref "TARGET_FAST_INDIRECT_CALLS")
5922 ;; Target (or stub) within reach
5923 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
5925 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
5930 (ne (symbol_ref "flag_pic")
5934 ;; Out of reach PORTABLE_RUNTIME
5935 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
5939 ;; Out of reach, can use ble
5942 (define_expand "call_value"
5943 [(parallel [(set (match_operand 0 "" "")
5944 (call (match_operand:SI 1 "" "")
5945 (match_operand 2 "" "")))
5946 (clobber (reg:SI 2))])]
5953 if (TARGET_PORTABLE_RUNTIME)
5954 op = force_reg (word_mode, XEXP (operands[1], 0));
5956 op = XEXP (operands[1], 0);
5959 emit_move_insn (arg_pointer_rtx,
5960 gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
5963 /* Use two different patterns for calls to explicitly named functions
5964 and calls through function pointers. This is necessary as these two
5965 types of calls use different calling conventions, and CSE might try
5966 to change the named call into an indirect call in some cases (using
5967 two patterns keeps CSE from performing this optimization). */
5968 if (GET_CODE (op) == SYMBOL_REF)
5969 call_insn = emit_call_insn (gen_call_value_internal_symref (operands[0],
5972 else if (TARGET_64BIT)
5974 rtx tmpreg = force_reg (word_mode, op);
5976 = emit_call_insn (gen_call_value_internal_reg_64bit (operands[0],
5982 rtx tmpreg = gen_rtx_REG (word_mode, 22);
5983 emit_move_insn (tmpreg, force_reg (word_mode, op));
5984 call_insn = emit_call_insn (gen_call_value_internal_reg (operands[0],
5989 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
5991 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
5993 /* After each call we must restore the PIC register, even if it
5994 doesn't appear to be used. */
5995 emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
6000 (define_insn "call_value_internal_symref"
6001 [(set (match_operand 0 "" "=rf")
6002 (call (mem:SI (match_operand 1 "call_operand_address" ""))
6003 (match_operand 2 "" "i")))
6004 (clobber (reg:SI 2))
6005 (use (const_int 0))]
6006 ;;- Don't use operand 1 for most machines.
6007 "! TARGET_PORTABLE_RUNTIME"
6010 output_arg_descriptor (insn);
6011 return output_call (insn, operands[1], 0);
6013 [(set_attr "type" "call")
6014 (set (attr "length")
6015 ;; If we're sure that we can either reach the target or that the
6016 ;; linker can use a long-branch stub, then the length is 4 bytes.
6018 ;; For long-calls the length will be either 52 bytes (non-pic)
6019 ;; or 68 bytes (pic). */
6020 ;; Else we have to use a long-call;
6021 (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
6024 (if_then_else (eq (symbol_ref "flag_pic")
6029 (define_insn "call_value_internal_reg_64bit"
6030 [(set (match_operand 0 "" "=rf")
6031 (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
6032 (match_operand 2 "" "i")))
6033 (clobber (reg:SI 2))
6034 (use (const_int 1))]
6038 /* ??? Needs more work. Length computation, split into multiple insns,
6039 do not use %r22 directly, expose delay slot. */
6040 return \"ldd 16(%1),%%r2\;ldd 24(%1),%%r27\;bve,l (%%r2),%%r2\;nop\";
6042 [(set_attr "type" "dyncall")
6043 (set (attr "length") (const_int 16))])
6045 (define_insn "call_value_internal_reg"
6046 [(set (match_operand 0 "" "=rf")
6047 (call (mem:SI (reg:SI 22))
6048 (match_operand 1 "" "i")))
6049 (clobber (reg:SI 2))
6050 (use (const_int 1))]
6056 /* First the special case for kernels, level 0 systems, etc. */
6057 if (TARGET_FAST_INDIRECT_CALLS)
6058 return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
6060 /* Now the normal case -- we can reach $$dyncall directly or
6061 we're sure that we can get there via a long-branch stub.
6063 No need to check target flags as the length uniquely identifies
6064 the remaining cases. */
6065 if (get_attr_length (insn) == 8)
6066 return \".CALL\\tARGW0=GR\;{bl|b,l} $$dyncall,%%r31\;copy %%r31,%%r2\";
6068 /* Long millicode call, but we are not generating PIC or portable runtime
6070 if (get_attr_length (insn) == 12)
6071 return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
6073 /* Long millicode call for portable runtime. */
6074 if (get_attr_length (insn) == 20)
6075 return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr %%r0,%%r2\;bv,n %%r0(%%r31)\;nop\";
6077 /* If we're generating PIC code. */
6078 xoperands[0] = operands[1];
6079 xoperands[1] = gen_label_rtx ();
6080 output_asm_insn (\"{bl|b,l} .+8,%%r1\", xoperands);
6081 output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
6082 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
6083 CODE_LABEL_NUMBER (xoperands[1]));
6084 output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
6085 output_asm_insn (\"blr %%r0,%%r2\", xoperands);
6086 output_asm_insn (\"bv,n %%r0(%%r1)\\n\\tnop\", xoperands);
6089 [(set_attr "type" "dyncall")
6090 (set (attr "length")
6092 ;; First FAST_INDIRECT_CALLS
6093 (ne (symbol_ref "TARGET_FAST_INDIRECT_CALLS")
6097 ;; Target (or stub) within reach
6098 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
6100 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
6105 (ne (symbol_ref "flag_pic")
6109 ;; Out of reach PORTABLE_RUNTIME
6110 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
6114 ;; Out of reach, can use ble
6117 ;; Call subroutine returning any type.
6119 (define_expand "untyped_call"
6120 [(parallel [(call (match_operand 0 "" "")
6122 (match_operand 1 "" "")
6123 (match_operand 2 "" "")])]
6129 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6131 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6133 rtx set = XVECEXP (operands[2], 0, i);
6134 emit_move_insn (SET_DEST (set), SET_SRC (set));
6137 /* The optimizer does not know that the call sets the function value
6138 registers we stored in the result block. We avoid problems by
6139 claiming that all hard registers are used and clobbered at this
6141 emit_insn (gen_blockage ());
6146 (define_expand "sibcall"
6147 [(parallel [(call (match_operand:SI 0 "" "")
6148 (match_operand 1 "" ""))
6149 (clobber (reg:SI 0))])]
6150 "! TARGET_PORTABLE_RUNTIME"
6156 op = XEXP (operands[0], 0);
6158 /* We do not allow indirect sibling calls. */
6159 call_insn = emit_call_insn (gen_sibcall_internal_symref (op, operands[1]));
6163 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
6165 /* After each call we must restore the PIC register, even if it
6166 doesn't appear to be used. */
6167 emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
6172 (define_insn "sibcall_internal_symref"
6173 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
6174 (match_operand 1 "" "i"))
6175 (clobber (reg:SI 0))
6177 (use (const_int 0))]
6178 "! TARGET_PORTABLE_RUNTIME"
6181 output_arg_descriptor (insn);
6182 return output_call (insn, operands[0], 1);
6184 [(set_attr "type" "call")
6185 (set (attr "length")
6186 ;; If we're sure that we can either reach the target or that the
6187 ;; linker can use a long-branch stub, then the length is 4 bytes.
6189 ;; For long-calls the length will be either 52 bytes (non-pic)
6190 ;; or 68 bytes (pic). */
6191 ;; Else we have to use a long-call;
6192 (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
6195 (if_then_else (eq (symbol_ref "flag_pic")
6200 (define_expand "sibcall_value"
6201 [(parallel [(set (match_operand 0 "" "")
6202 (call (match_operand:SI 1 "" "")
6203 (match_operand 2 "" "")))
6204 (clobber (reg:SI 0))])]
6205 "! TARGET_PORTABLE_RUNTIME"
6211 op = XEXP (operands[1], 0);
6213 /* We do not allow indirect sibling calls. */
6214 call_insn = emit_call_insn (gen_sibcall_value_internal_symref (operands[0],
6219 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
6221 /* After each call we must restore the PIC register, even if it
6222 doesn't appear to be used. */
6223 emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
6228 (define_insn "sibcall_value_internal_symref"
6229 [(set (match_operand 0 "" "=rf")
6230 (call (mem:SI (match_operand 1 "call_operand_address" ""))
6231 (match_operand 2 "" "i")))
6232 (clobber (reg:SI 0))
6234 (use (const_int 0))]
6235 ;;- Don't use operand 1 for most machines.
6236 "! TARGET_PORTABLE_RUNTIME"
6239 output_arg_descriptor (insn);
6240 return output_call (insn, operands[1], 1);
6242 [(set_attr "type" "call")
6243 (set (attr "length")
6244 ;; If we're sure that we can either reach the target or that the
6245 ;; linker can use a long-branch stub, then the length is 4 bytes.
6247 ;; For long-calls the length will be either 52 bytes (non-pic)
6248 ;; or 68 bytes (pic). */
6249 ;; Else we have to use a long-call;
6250 (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
6253 (if_then_else (eq (symbol_ref "flag_pic")
6262 [(set_attr "type" "move")
6263 (set_attr "length" "4")])
6265 ;; These are just placeholders so we know where branch tables
6267 (define_insn "begin_brtab"
6272 /* Only GAS actually supports this pseudo-op. */
6274 return \".begin_brtab\";
6278 [(set_attr "type" "move")
6279 (set_attr "length" "0")])
6281 (define_insn "end_brtab"
6286 /* Only GAS actually supports this pseudo-op. */
6288 return \".end_brtab\";
6292 [(set_attr "type" "move")
6293 (set_attr "length" "0")])
6295 ;;; EH does longjmp's from and within the data section. Thus,
6296 ;;; an interspace branch is required for the longjmp implementation.
6297 ;;; Registers r1 and r2 are used as scratch registers for the jump.
6298 (define_expand "interspace_jump"
6300 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
6301 (clobber (match_dup 1))])]
6305 operands[1] = gen_rtx_REG (word_mode, 2);
6309 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
6310 (clobber (reg:SI 2))]
6312 "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
6313 [(set_attr "type" "branch")
6314 (set_attr "length" "12")])
6317 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
6318 (clobber (reg:DI 2))]
6320 "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
6321 [(set_attr "type" "branch")
6322 (set_attr "length" "12")])
6324 (define_expand "builtin_longjmp"
6325 [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
6329 /* The elements of the buffer are, in order: */
6330 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6331 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0],
6332 POINTER_SIZE / BITS_PER_UNIT));
6333 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0],
6334 (POINTER_SIZE * 2) / BITS_PER_UNIT));
6335 rtx pv = gen_rtx_REG (Pmode, 1);
6337 /* This bit is the same as expand_builtin_longjmp. */
6338 emit_move_insn (hard_frame_pointer_rtx, fp);
6339 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6340 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6341 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6343 /* Load the label we are jumping through into r1 so that we know
6344 where to look for it when we get back to setjmp's function for
6345 restoring the gp. */
6346 emit_move_insn (pv, lab);
6348 /* Prevent the insns above from being scheduled into the delay slot
6349 of the interspace jump because the space register could change. */
6350 emit_insn (gen_blockage ());
6352 emit_jump_insn (gen_interspace_jump (pv));
6357 ;;; Hope this is only within a function...
6358 (define_insn "indirect_jump"
6359 [(set (pc) (match_operand 0 "register_operand" "r"))]
6360 "GET_MODE (operands[0]) == word_mode"
6362 [(set_attr "type" "branch")
6363 (set_attr "length" "4")])
6365 (define_expand "extzv"
6366 [(set (match_operand 0 "register_operand" "")
6367 (zero_extract (match_operand 1 "register_operand" "")
6368 (match_operand 2 "uint32_operand" "")
6369 (match_operand 3 "uint32_operand" "")))]
6374 emit_insn (gen_extzv_64 (operands[0], operands[1],
6375 operands[2], operands[3]));
6377 emit_insn (gen_extzv_32 (operands[0], operands[1],
6378 operands[2], operands[3]));
6382 (define_insn "extzv_32"
6383 [(set (match_operand:SI 0 "register_operand" "=r")
6384 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
6385 (match_operand:SI 2 "uint5_operand" "")
6386 (match_operand:SI 3 "uint5_operand" "")))]
6388 "{extru|extrw,u} %1,%3+%2-1,%2,%0"
6389 [(set_attr "type" "shift")
6390 (set_attr "length" "4")])
6393 [(set (match_operand:SI 0 "register_operand" "=r")
6394 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
6396 (match_operand:SI 2 "register_operand" "q")))]
6398 "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
6399 [(set_attr "type" "shift")
6400 (set_attr "length" "4")])
6402 (define_insn "extzv_64"
6403 [(set (match_operand:DI 0 "register_operand" "=r")
6404 (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
6405 (match_operand:DI 2 "uint32_operand" "")
6406 (match_operand:DI 3 "uint32_operand" "")))]
6408 "extrd,u %1,%3+%2-1,%2,%0"
6409 [(set_attr "type" "shift")
6410 (set_attr "length" "4")])
6413 [(set (match_operand:DI 0 "register_operand" "=r")
6414 (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
6416 (match_operand:DI 2 "register_operand" "q")))]
6418 "extrd,u %1,%%sar,1,%0"
6419 [(set_attr "type" "shift")
6420 (set_attr "length" "4")])
6422 (define_expand "extv"
6423 [(set (match_operand 0 "register_operand" "")
6424 (sign_extract (match_operand 1 "register_operand" "")
6425 (match_operand 2 "uint32_operand" "")
6426 (match_operand 3 "uint32_operand" "")))]
6431 emit_insn (gen_extv_64 (operands[0], operands[1],
6432 operands[2], operands[3]));
6434 emit_insn (gen_extv_32 (operands[0], operands[1],
6435 operands[2], operands[3]));
6439 (define_insn "extv_32"
6440 [(set (match_operand:SI 0 "register_operand" "=r")
6441 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
6442 (match_operand:SI 2 "uint5_operand" "")
6443 (match_operand:SI 3 "uint5_operand" "")))]
6445 "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
6446 [(set_attr "type" "shift")
6447 (set_attr "length" "4")])
6450 [(set (match_operand:SI 0 "register_operand" "=r")
6451 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
6453 (match_operand:SI 2 "register_operand" "q")))]
6455 "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
6456 [(set_attr "type" "shift")
6457 (set_attr "length" "4")])
6459 (define_insn "extv_64"
6460 [(set (match_operand:DI 0 "register_operand" "=r")
6461 (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
6462 (match_operand:DI 2 "uint32_operand" "")
6463 (match_operand:DI 3 "uint32_operand" "")))]
6465 "extrd,s %1,%3+%2-1,%2,%0"
6466 [(set_attr "type" "shift")
6467 (set_attr "length" "4")])
6470 [(set (match_operand:DI 0 "register_operand" "=r")
6471 (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
6473 (match_operand:DI 2 "register_operand" "q")))]
6475 "extrd,s %1,%%sar,1,%0"
6476 [(set_attr "type" "shift")
6477 (set_attr "length" "4")])
6479 ;; Only specify the mode operands 0, the rest are assumed to be word_mode.
6480 (define_expand "insv"
6481 [(set (zero_extract (match_operand 0 "register_operand" "")
6482 (match_operand 1 "uint32_operand" "")
6483 (match_operand 2 "uint32_operand" ""))
6484 (match_operand 3 "arith5_operand" ""))]
6489 emit_insn (gen_insv_64 (operands[0], operands[1],
6490 operands[2], operands[3]));
6492 emit_insn (gen_insv_32 (operands[0], operands[1],
6493 operands[2], operands[3]));
6497 (define_insn "insv_32"
6498 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
6499 (match_operand:SI 1 "uint5_operand" "")
6500 (match_operand:SI 2 "uint5_operand" ""))
6501 (match_operand:SI 3 "arith5_operand" "r,L"))]
6504 {dep|depw} %3,%2+%1-1,%1,%0
6505 {depi|depwi} %3,%2+%1-1,%1,%0"
6506 [(set_attr "type" "shift,shift")
6507 (set_attr "length" "4,4")])
6509 ;; Optimize insertion of const_int values of type 1...1xxxx.
6511 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
6512 (match_operand:SI 1 "uint5_operand" "")
6513 (match_operand:SI 2 "uint5_operand" ""))
6514 (match_operand:SI 3 "const_int_operand" ""))]
6515 "(INTVAL (operands[3]) & 0x10) != 0 &&
6516 (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
6519 operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
6520 return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
6522 [(set_attr "type" "shift")
6523 (set_attr "length" "4")])
6525 (define_insn "insv_64"
6526 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
6527 (match_operand:DI 1 "uint32_operand" "")
6528 (match_operand:DI 2 "uint32_operand" ""))
6529 (match_operand:DI 3 "arith32_operand" "r,L"))]
6532 depd %3,%2+%1-1,%1,%0
6533 depdi %3,%2+%1-1,%1,%0"
6534 [(set_attr "type" "shift,shift")
6535 (set_attr "length" "4,4")])
6537 ;; Optimize insertion of const_int values of type 1...1xxxx.
6539 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
6540 (match_operand:DI 1 "uint32_operand" "")
6541 (match_operand:DI 2 "uint32_operand" ""))
6542 (match_operand:DI 3 "const_int_operand" ""))]
6543 "(INTVAL (operands[3]) & 0x10) != 0
6545 && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
6548 operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
6549 return \"depdi %3,%2+%1-1,%1,%0\";
6551 [(set_attr "type" "shift")
6552 (set_attr "length" "4")])
6555 [(set (match_operand:DI 0 "register_operand" "=r")
6556 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6559 "depd,z %1,31,32,%0"
6560 [(set_attr "type" "shift")
6561 (set_attr "length" "4")])
6563 ;; This insn is used for some loop tests, typically loops reversed when
6564 ;; strength reduction is used. It is actually created when the instruction
6565 ;; combination phase combines the special loop test. Since this insn
6566 ;; is both a jump insn and has an output, it must deal with its own
6567 ;; reloads, hence the `m' constraints. The `!' constraints direct reload
6568 ;; to not choose the register alternatives in the event a reload is needed.
6569 (define_insn "decrement_and_branch_until_zero"
6572 (match_operator 2 "comparison_operator"
6573 [(plus:SI (match_operand:SI 0 "register_operand" "+!r,!*f,!*m")
6574 (match_operand:SI 1 "int5_operand" "L,L,L"))
6576 (label_ref (match_operand 3 "" ""))
6579 (plus:SI (match_dup 0) (match_dup 1)))
6580 (clobber (match_scratch:SI 4 "=X,r,r"))]
6582 "* return output_dbra (operands, insn, which_alternative); "
6583 ;; Do not expect to understand this the first time through.
6584 [(set_attr "type" "cbranch,multi,multi")
6585 (set (attr "length")
6586 (if_then_else (eq_attr "alternative" "0")
6587 ;; Loop counter in register case
6588 ;; Short branch has length of 4
6589 ;; Long branch has length of 8
6590 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6595 ;; Loop counter in FP reg case.
6596 ;; Extra goo to deal with additional reload insns.
6597 (if_then_else (eq_attr "alternative" "1")
6598 (if_then_else (lt (match_dup 3) (pc))
6600 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
6605 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6609 ;; Loop counter in memory case.
6610 ;; Extra goo to deal with additional reload insns.
6611 (if_then_else (lt (match_dup 3) (pc))
6613 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
6618 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6621 (const_int 16))))))])
6626 (match_operator 2 "movb_comparison_operator"
6627 [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
6628 (label_ref (match_operand 3 "" ""))
6630 (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
6633 "* return output_movb (operands, insn, which_alternative, 0); "
6634 ;; Do not expect to understand this the first time through.
6635 [(set_attr "type" "cbranch,multi,multi,multi")
6636 (set (attr "length")
6637 (if_then_else (eq_attr "alternative" "0")
6638 ;; Loop counter in register case
6639 ;; Short branch has length of 4
6640 ;; Long branch has length of 8
6641 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6646 ;; Loop counter in FP reg case.
6647 ;; Extra goo to deal with additional reload insns.
6648 (if_then_else (eq_attr "alternative" "1")
6649 (if_then_else (lt (match_dup 3) (pc))
6651 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
6656 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6660 ;; Loop counter in memory or sar case.
6661 ;; Extra goo to deal with additional reload insns.
6663 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6666 (const_int 12)))))])
6668 ;; Handle negated branch.
6672 (match_operator 2 "movb_comparison_operator"
6673 [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
6675 (label_ref (match_operand 3 "" ""))))
6676 (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
6679 "* return output_movb (operands, insn, which_alternative, 1); "
6680 ;; Do not expect to understand this the first time through.
6681 [(set_attr "type" "cbranch,multi,multi,multi")
6682 (set (attr "length")
6683 (if_then_else (eq_attr "alternative" "0")
6684 ;; Loop counter in register case
6685 ;; Short branch has length of 4
6686 ;; Long branch has length of 8
6687 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6692 ;; Loop counter in FP reg case.
6693 ;; Extra goo to deal with additional reload insns.
6694 (if_then_else (eq_attr "alternative" "1")
6695 (if_then_else (lt (match_dup 3) (pc))
6697 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
6702 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6706 ;; Loop counter in memory or SAR case.
6707 ;; Extra goo to deal with additional reload insns.
6709 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6712 (const_int 12)))))])
6715 [(set (pc) (label_ref (match_operand 3 "" "" )))
6716 (set (match_operand:SI 0 "ireg_operand" "=r")
6717 (plus:SI (match_operand:SI 1 "ireg_operand" "r")
6718 (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
6719 "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
6722 return output_parallel_addb (operands, get_attr_length (insn));
6724 [(set_attr "type" "parallel_branch")
6725 (set (attr "length")
6726 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6732 [(set (pc) (label_ref (match_operand 2 "" "" )))
6733 (set (match_operand:SF 0 "ireg_operand" "=r")
6734 (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
6738 return output_parallel_movb (operands, get_attr_length (insn));
6740 [(set_attr "type" "parallel_branch")
6741 (set (attr "length")
6742 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
6748 [(set (pc) (label_ref (match_operand 2 "" "" )))
6749 (set (match_operand:SI 0 "ireg_operand" "=r")
6750 (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
6754 return output_parallel_movb (operands, get_attr_length (insn));
6756 [(set_attr "type" "parallel_branch")
6757 (set (attr "length")
6758 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
6764 [(set (pc) (label_ref (match_operand 2 "" "" )))
6765 (set (match_operand:HI 0 "ireg_operand" "=r")
6766 (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
6770 return output_parallel_movb (operands, get_attr_length (insn));
6772 [(set_attr "type" "parallel_branch")
6773 (set (attr "length")
6774 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
6780 [(set (pc) (label_ref (match_operand 2 "" "" )))
6781 (set (match_operand:QI 0 "ireg_operand" "=r")
6782 (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
6786 return output_parallel_movb (operands, get_attr_length (insn));
6788 [(set_attr "type" "parallel_branch")
6789 (set (attr "length")
6790 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
6796 [(set (match_operand 0 "register_operand" "=f")
6797 (mult (match_operand 1 "register_operand" "f")
6798 (match_operand 2 "register_operand" "f")))
6799 (set (match_operand 3 "register_operand" "+f")
6800 (plus (match_operand 4 "register_operand" "f")
6801 (match_operand 5 "register_operand" "f")))]
6802 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
6803 && reload_completed && fmpyaddoperands (operands)"
6806 if (GET_MODE (operands[0]) == DFmode)
6808 if (rtx_equal_p (operands[3], operands[5]))
6809 return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
6811 return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
6815 if (rtx_equal_p (operands[3], operands[5]))
6816 return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
6818 return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
6821 [(set_attr "type" "fpalu")
6822 (set_attr "length" "4")])
6825 [(set (match_operand 3 "register_operand" "+f")
6826 (plus (match_operand 4 "register_operand" "f")
6827 (match_operand 5 "register_operand" "f")))
6828 (set (match_operand 0 "register_operand" "=f")
6829 (mult (match_operand 1 "register_operand" "f")
6830 (match_operand 2 "register_operand" "f")))]
6831 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
6832 && reload_completed && fmpyaddoperands (operands)"
6835 if (GET_MODE (operands[0]) == DFmode)
6837 if (rtx_equal_p (operands[3], operands[5]))
6838 return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
6840 return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
6844 if (rtx_equal_p (operands[3], operands[5]))
6845 return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
6847 return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
6850 [(set_attr "type" "fpalu")
6851 (set_attr "length" "4")])
6854 [(set (match_operand 0 "register_operand" "=f")
6855 (mult (match_operand 1 "register_operand" "f")
6856 (match_operand 2 "register_operand" "f")))
6857 (set (match_operand 3 "register_operand" "+f")
6858 (minus (match_operand 4 "register_operand" "f")
6859 (match_operand 5 "register_operand" "f")))]
6860 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
6861 && reload_completed && fmpysuboperands (operands)"
6864 if (GET_MODE (operands[0]) == DFmode)
6865 return \"fmpysub,dbl %1,%2,%0,%5,%3\";
6867 return \"fmpysub,sgl %1,%2,%0,%5,%3\";
6869 [(set_attr "type" "fpalu")
6870 (set_attr "length" "4")])
6873 [(set (match_operand 3 "register_operand" "+f")
6874 (minus (match_operand 4 "register_operand" "f")
6875 (match_operand 5 "register_operand" "f")))
6876 (set (match_operand 0 "register_operand" "=f")
6877 (mult (match_operand 1 "register_operand" "f")
6878 (match_operand 2 "register_operand" "f")))]
6879 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
6880 && reload_completed && fmpysuboperands (operands)"
6883 if (GET_MODE (operands[0]) == DFmode)
6884 return \"fmpysub,dbl %1,%2,%0,%5,%3\";
6886 return \"fmpysub,sgl %1,%2,%0,%5,%3\";
6888 [(set_attr "type" "fpalu")
6889 (set_attr "length" "4")])
6891 ;; Clean up turds left by reload.
6893 [(set (match_operand 0 "reg_or_nonsymb_mem_operand" "")
6894 (match_operand 1 "register_operand" "fr"))
6895 (set (match_operand 2 "register_operand" "fr")
6897 "! TARGET_SOFT_FLOAT
6898 && GET_CODE (operands[0]) == MEM
6899 && ! MEM_VOLATILE_P (operands[0])
6900 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6901 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6902 && GET_MODE (operands[0]) == DFmode
6903 && GET_CODE (operands[1]) == REG
6904 && GET_CODE (operands[2]) == REG
6905 && ! side_effects_p (XEXP (operands[0], 0))
6906 && REGNO_REG_CLASS (REGNO (operands[1]))
6907 == REGNO_REG_CLASS (REGNO (operands[2]))"
6912 if (FP_REG_P (operands[1]))
6913 output_asm_insn (output_fp_move_double (operands), operands);
6915 output_asm_insn (output_move_double (operands), operands);
6917 if (rtx_equal_p (operands[1], operands[2]))
6920 xoperands[0] = operands[2];
6921 xoperands[1] = operands[1];
6923 if (FP_REG_P (xoperands[1]))
6924 output_asm_insn (output_fp_move_double (xoperands), xoperands);
6926 output_asm_insn (output_move_double (xoperands), xoperands);
6932 [(set (match_operand 0 "register_operand" "fr")
6933 (match_operand 1 "reg_or_nonsymb_mem_operand" ""))
6934 (set (match_operand 2 "register_operand" "fr")
6936 "! TARGET_SOFT_FLOAT
6937 && GET_CODE (operands[1]) == MEM
6938 && ! MEM_VOLATILE_P (operands[1])
6939 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6940 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6941 && GET_MODE (operands[0]) == DFmode
6942 && GET_CODE (operands[0]) == REG
6943 && GET_CODE (operands[2]) == REG
6944 && ! side_effects_p (XEXP (operands[1], 0))
6945 && REGNO_REG_CLASS (REGNO (operands[0]))
6946 == REGNO_REG_CLASS (REGNO (operands[2]))"
6951 if (FP_REG_P (operands[0]))
6952 output_asm_insn (output_fp_move_double (operands), operands);
6954 output_asm_insn (output_move_double (operands), operands);
6956 xoperands[0] = operands[2];
6957 xoperands[1] = operands[0];
6959 if (FP_REG_P (xoperands[1]))
6960 output_asm_insn (output_fp_move_double (xoperands), xoperands);
6962 output_asm_insn (output_move_double (xoperands), xoperands);
6967 ;; Flush the I and D cache line found at the address in operand 0.
6968 ;; This is used by the trampoline code for nested functions.
6969 ;; So long as the trampoline itself is less than 32 bytes this
6972 (define_insn "dcacheflush"
6973 [(unspec_volatile [(const_int 1)] 0)
6974 (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
6975 (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))]
6977 "fdc 0(%0)\;fdc 0(%1)\;sync"
6978 [(set_attr "type" "multi")
6979 (set_attr "length" "12")])
6981 (define_insn "icacheflush"
6982 [(unspec_volatile [(const_int 2)] 0)
6983 (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
6984 (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))
6985 (use (match_operand 2 "pmode_register_operand" "r"))
6986 (clobber (match_operand 3 "pmode_register_operand" "=&r"))
6987 (clobber (match_operand 4 "pmode_register_operand" "=&r"))]
6989 "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"
6990 [(set_attr "type" "multi")
6991 (set_attr "length" "52")])
6993 ;; An out-of-line prologue.
6994 (define_insn "outline_prologue_call"
6995 [(unspec_volatile [(const_int 0)] 0)
6996 (clobber (reg:SI 31))
6997 (clobber (reg:SI 22))
6998 (clobber (reg:SI 21))
6999 (clobber (reg:SI 20))
7000 (clobber (reg:SI 19))
7001 (clobber (reg:SI 1))]
7005 extern int frame_pointer_needed;
7007 /* We need two different versions depending on whether or not we
7008 need a frame pointer. Also note that we return to the instruction
7009 immediately after the branch rather than two instructions after the
7010 break as normally is the case. */
7011 if (frame_pointer_needed)
7013 /* Must import the magic millicode routine(s). */
7014 output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
7016 if (TARGET_PORTABLE_RUNTIME)
7018 output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
7019 output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
7023 output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
7027 /* Must import the magic millicode routine(s). */
7028 output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
7030 if (TARGET_PORTABLE_RUNTIME)
7032 output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
7033 output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
7036 output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
7040 [(set_attr "type" "multi")
7041 (set_attr "length" "8")])
7043 ;; An out-of-line epilogue.
7044 (define_insn "outline_epilogue_call"
7045 [(unspec_volatile [(const_int 1)] 0)
7048 (clobber (reg:SI 31))
7049 (clobber (reg:SI 22))
7050 (clobber (reg:SI 21))
7051 (clobber (reg:SI 20))
7052 (clobber (reg:SI 19))
7053 (clobber (reg:SI 2))
7054 (clobber (reg:SI 1))]
7058 extern int frame_pointer_needed;
7060 /* We need two different versions depending on whether or not we
7061 need a frame pointer. Also note that we return to the instruction
7062 immediately after the branch rather than two instructions after the
7063 break as normally is the case. */
7064 if (frame_pointer_needed)
7066 /* Must import the magic millicode routine. */
7067 output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
7069 /* The out-of-line prologue will make sure we return to the right
7071 if (TARGET_PORTABLE_RUNTIME)
7073 output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
7074 output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
7078 output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
7082 /* Must import the magic millicode routine. */
7083 output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
7085 /* The out-of-line prologue will make sure we return to the right
7087 if (TARGET_PORTABLE_RUNTIME)
7089 output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
7090 output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
7093 output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
7097 [(set_attr "type" "multi")
7098 (set_attr "length" "8")])
7100 ;; Given a function pointer, canonicalize it so it can be
7101 ;; reliably compared to another function pointer. */
7102 (define_expand "canonicalize_funcptr_for_compare"
7103 [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
7104 (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
7105 (clobber (match_dup 2))
7106 (clobber (reg:SI 26))
7107 (clobber (reg:SI 22))
7108 (clobber (reg:SI 31))])
7109 (set (match_operand:SI 0 "register_operand" "")
7111 "! TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && !TARGET_ELF32"
7114 operands[2] = gen_reg_rtx (SImode);
7115 if (GET_CODE (operands[1]) != REG)
7117 rtx tmp = gen_reg_rtx (Pmode);
7118 emit_move_insn (tmp, operands[1]);
7124 [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
7125 (clobber (match_operand:SI 0 "register_operand" "=a"))
7126 (clobber (reg:SI 26))
7127 (clobber (reg:SI 22))
7128 (clobber (reg:SI 31))]
7132 /* Must import the magic millicode routine. */
7133 output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
7135 /* This is absolutely amazing.
7137 First, copy our input parameter into %r29 just in case we don't
7138 need to call $$sh_func_adrs. */
7139 output_asm_insn (\"copy %%r26,%%r29\", NULL);
7141 /* Next, examine the low two bits in %r26, if they aren't 0x2, then
7142 we use %r26 unchanged. */
7143 if (get_attr_length (insn) == 32)
7144 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+24\", NULL);
7145 else if (get_attr_length (insn) == 40)
7146 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+32\", NULL);
7147 else if (get_attr_length (insn) == 44)
7148 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+36\", NULL);
7150 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+20\", NULL);
7152 /* Next, compare %r26 with 4096, if %r26 is less than or equal to
7153 4096, then we use %r26 unchanged. */
7154 if (get_attr_length (insn) == 32)
7155 output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+16\",
7157 else if (get_attr_length (insn) == 40)
7158 output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+24\",
7160 else if (get_attr_length (insn) == 44)
7161 output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+28\",
7164 output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+12\",
7167 /* Else call $$sh_func_adrs to extract the function's real add24. */
7168 return output_millicode_call (insn,
7169 gen_rtx_SYMBOL_REF (SImode,
7170 \"$$sh_func_adrs\"));
7172 [(set_attr "type" "multi")
7173 (set (attr "length")
7175 ;; Target (or stub) within reach
7176 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
7178 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
7183 (ne (symbol_ref "flag_pic")
7187 ;; Out of reach PORTABLE_RUNTIME
7188 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
7192 ;; Out of reach, can use ble
7195 ;; On the PA, the PIC register is call clobbered, so it must
7196 ;; be saved & restored around calls by the caller. If the call
7197 ;; doesn't return normally (nonlocal goto, or an exception is
7198 ;; thrown), then the code at the exception handler label must
7199 ;; restore the PIC register.
7200 (define_expand "exception_receiver"
7202 "!TARGET_PORTABLE_RUNTIME && flag_pic"
7205 /* Load the PIC register from the stack slot (in our caller's
7207 emit_move_insn (pic_offset_table_rtx,
7208 gen_rtx_MEM (SImode,
7209 plus_constant (stack_pointer_rtx, -32)));
7210 emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx));
7211 emit_insn (gen_blockage ());
7215 (define_expand "builtin_setjmp_receiver"
7216 [(label_ref (match_operand 0 "" ""))]
7220 /* Restore the PIC register. Hopefully, this will always be from
7221 a stack slot. The only registers that are valid after a
7222 builtin_longjmp are the stack and frame pointers. */
7223 emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());