1 ;;- Machine description for HP PA-RISC architecture for GNU C compiler
2 ;; Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
3 ;; Contributed by the Center for Software Science at the University
6 ;; This file is part of GNU CC.
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
23 ;; This gcc Version 2 machine description is inspired by sparc.md and
26 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;; Insn type. Used to default other attribute values.
30 ;; type "unary" insns have one input operand (1) and one output operand (0)
31 ;; type "binary" insns have two input operands (1,2) and one output (0)
34 "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"
35 (const_string "binary"))
37 (define_attr "pa_combine_type"
38 "fmpy,faddsub,uncond_branch,addmove,none"
39 (const_string "none"))
41 ;; Processor type (for scheduling, not code generation) -- this attribute
42 ;; must exactly match the processor_type enumeration in pa.h.
44 ;; FIXME: Add 800 scheduling for completeness?
46 (define_attr "cpu" "700,7100,7100LC,7200,8000" (const (symbol_ref "pa_cpu_attr")))
48 ;; Length (in # of bytes).
49 (define_attr "length" ""
50 (cond [(eq_attr "type" "load,fpload")
51 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
52 (const_int 8) (const_int 4))
54 (eq_attr "type" "store,fpstore")
55 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
56 (const_int 8) (const_int 4))
58 (eq_attr "type" "binary,shift,nullshift")
59 (if_then_else (match_operand 2 "arith_operand" "")
60 (const_int 4) (const_int 12))
62 (eq_attr "type" "move,unary,shift,nullshift")
63 (if_then_else (match_operand 1 "arith_operand" "")
64 (const_int 4) (const_int 8))]
68 (define_asm_attributes
69 [(set_attr "length" "4")
70 (set_attr "type" "multi")])
72 ;; Attributes for instruction and branch scheduling
74 ;; For conditional branches.
75 (define_attr "in_branch_delay" "false,true"
76 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
77 (eq_attr "length" "4"))
79 (const_string "false")))
81 ;; Disallow instructions which use the FPU since they will tie up the FPU
82 ;; even if the instruction is nullified.
83 (define_attr "in_nullified_branch_delay" "false,true"
84 (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")
85 (eq_attr "length" "4"))
87 (const_string "false")))
89 ;; For calls and millicode calls. Allow unconditional branches in the
91 (define_attr "in_call_delay" "false,true"
92 (cond [(and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
93 (eq_attr "length" "4"))
95 (eq_attr "type" "uncond_branch")
96 (if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY")
99 (const_string "false"))]
100 (const_string "false")))
103 ;; Call delay slot description.
104 (define_delay (eq_attr "type" "call")
105 [(eq_attr "in_call_delay" "true") (nil) (nil)])
107 ;; millicode call delay slot description. Note it disallows delay slot
108 ;; when TARGET_PORTABLE_RUNTIME is true.
109 (define_delay (eq_attr "type" "milli")
110 [(and (eq_attr "in_call_delay" "true")
111 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0)))
114 ;; Return and other similar instructions.
115 (define_delay (eq_attr "type" "branch,parallel_branch")
116 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
118 ;; Floating point conditional branch delay slot description and
119 (define_delay (eq_attr "type" "fbranch")
120 [(eq_attr "in_branch_delay" "true")
121 (eq_attr "in_nullified_branch_delay" "true")
124 ;; Integer conditional branch delay slot description.
125 ;; Nullification of conditional branches on the PA is dependent on the
126 ;; direction of the branch. Forward branches nullify true and
127 ;; backward branches nullify false. If the direction is unknown
128 ;; then nullification is not allowed.
129 (define_delay (eq_attr "type" "cbranch")
130 [(eq_attr "in_branch_delay" "true")
131 (and (eq_attr "in_nullified_branch_delay" "true")
132 (attr_flag "forward"))
133 (and (eq_attr "in_nullified_branch_delay" "true")
134 (attr_flag "backward"))])
136 (define_delay (and (eq_attr "type" "uncond_branch")
137 (eq (symbol_ref "following_call (insn)")
139 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
141 ;; Function units of the HPPA. The following data is for the 700 CPUs
142 ;; (Mustang CPU + Timex FPU aka PA-89) because that's what I have the docs for.
143 ;; Scheduling instructions for PA-83 machines according to the Snake
144 ;; constraints shouldn't hurt.
146 ;; (define_function_unit {name} {num-units} {n-users} {test}
147 ;; {ready-delay} {issue-delay} [{conflict-list}])
150 ;; (Noted only for documentation; units that take one cycle do not need to
153 ;; (define_function_unit "alu" 1 0
154 ;; (and (eq_attr "type" "unary,shift,nullshift,binary,move,address")
155 ;; (eq_attr "cpu" "700"))
159 ;; Memory. Disregarding Cache misses, the Mustang memory times are:
160 ;; load: 2, fpload: 3
161 ;; store, fpstore: 3, no D-cache operations should be scheduled.
163 (define_function_unit "pa700memory" 1 0
164 (and (eq_attr "type" "load,fpload")
165 (eq_attr "cpu" "700")) 2 0)
166 (define_function_unit "pa700memory" 1 0
167 (and (eq_attr "type" "store,fpstore")
168 (eq_attr "cpu" "700")) 3 3)
170 ;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
172 ;; Instruction Time Unit Minimum Distance (unit contention)
179 ;; fmpyadd 3 ALU,MPY 2
180 ;; fmpysub 3 ALU,MPY 2
181 ;; fmpycfxt 3 ALU,MPY 2
184 ;; fdiv,sgl 10 MPY 10
185 ;; fdiv,dbl 12 MPY 12
186 ;; fsqrt,sgl 14 MPY 14
187 ;; fsqrt,dbl 18 MPY 18
189 (define_function_unit "pa700fp_alu" 1 0
190 (and (eq_attr "type" "fpcc")
191 (eq_attr "cpu" "700")) 4 2)
192 (define_function_unit "pa700fp_alu" 1 0
193 (and (eq_attr "type" "fpalu")
194 (eq_attr "cpu" "700")) 3 2)
195 (define_function_unit "pa700fp_mpy" 1 0
196 (and (eq_attr "type" "fpmulsgl,fpmuldbl")
197 (eq_attr "cpu" "700")) 3 2)
198 (define_function_unit "pa700fp_mpy" 1 0
199 (and (eq_attr "type" "fpdivsgl")
200 (eq_attr "cpu" "700")) 10 10)
201 (define_function_unit "pa700fp_mpy" 1 0
202 (and (eq_attr "type" "fpdivdbl")
203 (eq_attr "cpu" "700")) 12 12)
204 (define_function_unit "pa700fp_mpy" 1 0
205 (and (eq_attr "type" "fpsqrtsgl")
206 (eq_attr "cpu" "700")) 14 14)
207 (define_function_unit "pa700fp_mpy" 1 0
208 (and (eq_attr "type" "fpsqrtdbl")
209 (eq_attr "cpu" "700")) 18 18)
211 ;; Function units for the 7100 and 7150. The 7100/7150 can dual-issue
212 ;; floating point computations with non-floating point computations (fp loads
213 ;; and stores are not fp computations).
216 ;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
217 ;; take two cycles, during which no Dcache operations should be scheduled.
218 ;; Any special cases are handled in pa_adjust_cost. The 7100, 7150 and 7100LC
219 ;; all have the same memory characteristics if one disregards cache misses.
220 (define_function_unit "pa7100memory" 1 0
221 (and (eq_attr "type" "load,fpload")
222 (eq_attr "cpu" "7100,7100LC")) 2 0)
223 (define_function_unit "pa7100memory" 1 0
224 (and (eq_attr "type" "store,fpstore")
225 (eq_attr "cpu" "7100,7100LC")) 2 2)
227 ;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
229 ;; Instruction Time Unit Minimum Distance (unit contention)
236 ;; fmpyadd 2 ALU,MPY 1
237 ;; fmpysub 2 ALU,MPY 1
238 ;; fmpycfxt 2 ALU,MPY 1
242 ;; fdiv,dbl 15 DIV 15
244 ;; fsqrt,dbl 15 DIV 15
246 (define_function_unit "pa7100fp_alu" 1 0
247 (and (eq_attr "type" "fpcc,fpalu")
248 (eq_attr "cpu" "7100")) 2 1)
249 (define_function_unit "pa7100fp_mpy" 1 0
250 (and (eq_attr "type" "fpmulsgl,fpmuldbl")
251 (eq_attr "cpu" "7100")) 2 1)
252 (define_function_unit "pa7100fp_div" 1 0
253 (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
254 (eq_attr "cpu" "7100")) 8 8)
255 (define_function_unit "pa7100fp_div" 1 0
256 (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
257 (eq_attr "cpu" "7100")) 15 15)
259 ;; To encourage dual issue we define function units corresponding to
260 ;; the instructions which can be dual issued. This is a rather crude
261 ;; approximation, the "pa7100nonflop" test in particular could be refined.
262 (define_function_unit "pa7100flop" 1 1
264 (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
265 (eq_attr "cpu" "7100")) 1 1)
267 (define_function_unit "pa7100nonflop" 1 1
269 (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
270 (eq_attr "cpu" "7100")) 1 1)
273 ;; Memory subsystem works just like 7100/7150 (except for cache miss times which
274 ;; we don't model here).
276 ;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
277 ;; Note divides and sqrt flops lock the cpu until the flop is
278 ;; finished. fmpy and xmpyu (fmpyi) lock the cpu for one cycle.
279 ;; There's no way to avoid the penalty.
281 ;; Instruction Time Unit Minimum Distance (unit contention)
288 ;; fmpyadd,sgl 2 ALU,MPY 1
289 ;; fmpyadd,dbl 3 ALU,MPY 2
290 ;; fmpysub,sgl 2 ALU,MPY 1
291 ;; fmpysub,dbl 3 ALU,MPY 2
292 ;; fmpycfxt,sgl 2 ALU,MPY 1
293 ;; fmpycfxt,dbl 3 ALU,MPY 2
298 ;; fdiv,dbl 15 DIV 15
300 ;; fsqrt,dbl 15 DIV 15
302 (define_function_unit "pa7100LCfp_alu" 1 0
303 (and (eq_attr "type" "fpcc,fpalu")
304 (eq_attr "cpu" "7100LC,7200")) 2 1)
305 (define_function_unit "pa7100LCfp_mpy" 1 0
306 (and (eq_attr "type" "fpmulsgl")
307 (eq_attr "cpu" "7100LC,7200")) 2 1)
308 (define_function_unit "pa7100LCfp_mpy" 1 0
309 (and (eq_attr "type" "fpmuldbl")
310 (eq_attr "cpu" "7100LC,7200")) 3 2)
311 (define_function_unit "pa7100LCfp_div" 1 0
312 (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
313 (eq_attr "cpu" "7100LC,7200")) 8 8)
314 (define_function_unit "pa7100LCfp_div" 1 0
315 (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
316 (eq_attr "cpu" "7100LC,7200")) 15 15)
318 ;; Define the various functional units for dual-issue.
320 ;; There's only one floating point unit.
321 (define_function_unit "pa7100LCflop" 1 1
323 (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
324 (eq_attr "cpu" "7100LC,7200")) 1 1)
326 ;; Shifts and memory ops execute in only one of the integer ALUs
327 (define_function_unit "pa7100LCshiftmem" 1 1
329 (eq_attr "type" "shift,nullshift,load,fpload,store,fpstore")
330 (eq_attr "cpu" "7100LC,7200")) 1 1)
332 ;; We have two basic ALUs.
333 (define_function_unit "pa7100LCalu" 2 1
335 (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
336 (eq_attr "cpu" "7100LC,7200")) 1 1)
338 ;; I don't have complete information on the PA7200; however, most of
339 ;; what I've heard makes it look like a 7100LC without the store-store
340 ;; penalty. So that's how we'll model it.
342 ;; Memory. Disregarding Cache misses, memory loads and stores take
343 ;; two cycles. Any special cases are handled in pa_adjust_cost.
344 (define_function_unit "pa7200memory" 1 0
345 (and (eq_attr "type" "load,fpload,store,fpstore")
346 (eq_attr "cpu" "7200")) 2 0)
348 ;; I don't have detailed information on the PA7200 FP pipeline, so I
349 ;; treat it just like the 7100LC pipeline.
350 ;; Similarly for the multi-issue fake units.
353 ;; Scheduling for the PA8000 is somewhat different than scheduling for a
354 ;; traditional architecture.
356 ;; The PA8000 has a large (56) entry reorder buffer that is split between
357 ;; memory and non-memory operations.
359 ;; The PA800 can issue two memory and two non-memory operations per cycle to
360 ;; the function units. Similarly, the PA8000 can retire two memory and two
361 ;; non-memory operations per cycle.
363 ;; Given the large reorder buffer, the processor can hide most latencies.
364 ;; According to HP, they've got the best results by scheduling for retirement
365 ;; bandwidth with limited latency scheduling for floating point operations.
366 ;; Latency for integer operations and memory references is ignored.
368 ;; We claim floating point operations have a 2 cycle latency and are
369 ;; fully pipelined, except for div and sqrt which are not pipelined.
371 ;; It is not necessary to define the shifter and integer alu units.
373 ;; These first two define_unit_unit descriptions model retirement from
374 ;; the reorder buffer.
375 (define_function_unit "pa8000lsu" 2 1
377 (eq_attr "type" "load,fpload,store,fpstore")
378 (eq_attr "cpu" "8000")) 1 1)
380 (define_function_unit "pa8000alu" 2 1
382 (eq_attr "type" "!load,fpload,store,fpstore")
383 (eq_attr "cpu" "8000")) 1 1)
385 ;; Claim floating point ops have a 2 cycle latency, excluding div and
386 ;; sqrt, which are not pipelined and issue to different units.
387 (define_function_unit "pa8000fmac" 2 0
389 (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
390 (eq_attr "cpu" "8000")) 2 1)
392 (define_function_unit "pa8000fdiv" 2 1
394 (eq_attr "type" "fpdivsgl,fpsqrtsgl")
395 (eq_attr "cpu" "8000")) 17 17)
397 (define_function_unit "pa8000fdiv" 2 1
399 (eq_attr "type" "fpdivdbl,fpsqrtdbl")
400 (eq_attr "cpu" "8000")) 31 31)
403 ;; Compare instructions.
404 ;; This controls RTL generation and register allocation.
406 ;; We generate RTL for comparisons and branches by having the cmpxx
407 ;; patterns store away the operands. Then, the scc and bcc patterns
408 ;; emit RTL for both the compare and the branch.
411 (define_expand "cmpsi"
413 (compare:CC (match_operand:SI 0 "reg_or_0_operand" "")
414 (match_operand:SI 1 "arith5_operand" "")))]
418 hppa_compare_op0 = operands[0];
419 hppa_compare_op1 = operands[1];
420 hppa_branch_type = CMP_SI;
424 (define_expand "cmpsf"
426 (compare:CCFP (match_operand:SF 0 "reg_or_0_operand" "")
427 (match_operand:SF 1 "reg_or_0_operand" "")))]
428 "! TARGET_SOFT_FLOAT"
431 hppa_compare_op0 = operands[0];
432 hppa_compare_op1 = operands[1];
433 hppa_branch_type = CMP_SF;
437 (define_expand "cmpdf"
439 (compare:CCFP (match_operand:DF 0 "reg_or_0_operand" "")
440 (match_operand:DF 1 "reg_or_0_operand" "")))]
441 "! TARGET_SOFT_FLOAT"
444 hppa_compare_op0 = operands[0];
445 hppa_compare_op1 = operands[1];
446 hppa_branch_type = CMP_DF;
452 (match_operator:CCFP 2 "comparison_operator"
453 [(match_operand:SF 0 "reg_or_0_operand" "fG")
454 (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
455 "! TARGET_SOFT_FLOAT"
456 "fcmp,sgl,%Y2 %f0,%f1"
457 [(set_attr "length" "4")
458 (set_attr "type" "fpcc")])
462 (match_operator:CCFP 2 "comparison_operator"
463 [(match_operand:DF 0 "reg_or_0_operand" "fG")
464 (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
465 "! TARGET_SOFT_FLOAT"
466 "fcmp,dbl,%Y2 %f0,%f1"
467 [(set_attr "length" "4")
468 (set_attr "type" "fpcc")])
473 [(set (match_operand:SI 0 "register_operand" "")
479 /* fp scc patterns rarely match, and are not a win on the PA. */
480 if (hppa_branch_type != CMP_SI)
482 /* set up operands from compare. */
483 operands[1] = hppa_compare_op0;
484 operands[2] = hppa_compare_op1;
485 /* fall through and generate default code */
489 [(set (match_operand:SI 0 "register_operand" "")
495 /* fp scc patterns rarely match, and are not a win on the PA. */
496 if (hppa_branch_type != CMP_SI)
498 operands[1] = hppa_compare_op0;
499 operands[2] = hppa_compare_op1;
503 [(set (match_operand:SI 0 "register_operand" "")
509 /* fp scc patterns rarely match, and are not a win on the PA. */
510 if (hppa_branch_type != CMP_SI)
512 operands[1] = hppa_compare_op0;
513 operands[2] = hppa_compare_op1;
517 [(set (match_operand:SI 0 "register_operand" "")
523 /* fp scc patterns rarely match, and are not a win on the PA. */
524 if (hppa_branch_type != CMP_SI)
526 operands[1] = hppa_compare_op0;
527 operands[2] = hppa_compare_op1;
531 [(set (match_operand:SI 0 "register_operand" "")
537 /* fp scc patterns rarely match, and are not a win on the PA. */
538 if (hppa_branch_type != CMP_SI)
540 operands[1] = hppa_compare_op0;
541 operands[2] = hppa_compare_op1;
545 [(set (match_operand:SI 0 "register_operand" "")
551 /* fp scc patterns rarely match, and are not a win on the PA. */
552 if (hppa_branch_type != CMP_SI)
554 operands[1] = hppa_compare_op0;
555 operands[2] = hppa_compare_op1;
558 (define_expand "sltu"
559 [(set (match_operand:SI 0 "register_operand" "")
560 (ltu:SI (match_dup 1)
565 if (hppa_branch_type != CMP_SI)
567 operands[1] = hppa_compare_op0;
568 operands[2] = hppa_compare_op1;
571 (define_expand "sgtu"
572 [(set (match_operand:SI 0 "register_operand" "")
573 (gtu:SI (match_dup 1)
578 if (hppa_branch_type != CMP_SI)
580 operands[1] = hppa_compare_op0;
581 operands[2] = hppa_compare_op1;
584 (define_expand "sleu"
585 [(set (match_operand:SI 0 "register_operand" "")
586 (leu:SI (match_dup 1)
591 if (hppa_branch_type != CMP_SI)
593 operands[1] = hppa_compare_op0;
594 operands[2] = hppa_compare_op1;
597 (define_expand "sgeu"
598 [(set (match_operand:SI 0 "register_operand" "")
599 (geu:SI (match_dup 1)
604 if (hppa_branch_type != CMP_SI)
606 operands[1] = hppa_compare_op0;
607 operands[2] = hppa_compare_op1;
610 ;; Instruction canonicalization puts immediate operands second, which
611 ;; is the reverse of what we want.
614 [(set (match_operand:SI 0 "register_operand" "=r")
615 (match_operator:SI 3 "comparison_operator"
616 [(match_operand:SI 1 "register_operand" "r")
617 (match_operand:SI 2 "arith11_operand" "rI")]))]
619 "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi 1,%0"
620 [(set_attr "type" "binary")
621 (set_attr "length" "8")])
623 (define_insn "iorscc"
624 [(set (match_operand:SI 0 "register_operand" "=r")
625 (ior:SI (match_operator:SI 3 "comparison_operator"
626 [(match_operand:SI 1 "register_operand" "r")
627 (match_operand:SI 2 "arith11_operand" "rI")])
628 (match_operator:SI 6 "comparison_operator"
629 [(match_operand:SI 4 "register_operand" "r")
630 (match_operand:SI 5 "arith11_operand" "rI")])))]
632 "{com%I2clr|cmp%I2clr},%S3 %2,%1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%4,%0\;ldi 1,%0"
633 [(set_attr "type" "binary")
634 (set_attr "length" "12")])
636 ;; Combiner patterns for common operations performed with the output
637 ;; from an scc insn (negscc and incscc).
638 (define_insn "negscc"
639 [(set (match_operand:SI 0 "register_operand" "=r")
640 (neg:SI (match_operator:SI 3 "comparison_operator"
641 [(match_operand:SI 1 "register_operand" "r")
642 (match_operand:SI 2 "arith11_operand" "rI")])))]
644 "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi -1,%0"
645 [(set_attr "type" "binary")
646 (set_attr "length" "8")])
648 ;; Patterns for adding/subtracting the result of a boolean expression from
649 ;; a register. First we have special patterns that make use of the carry
650 ;; bit, and output only two instructions. For the cases we can't in
651 ;; general do in two instructions, the incscc pattern at the end outputs
652 ;; two or three instructions.
655 [(set (match_operand:SI 0 "register_operand" "=r")
656 (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
657 (match_operand:SI 3 "arith11_operand" "rI"))
658 (match_operand:SI 1 "register_operand" "r")))]
660 "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
661 [(set_attr "type" "binary")
662 (set_attr "length" "8")])
664 ; This need only accept registers for op3, since canonicalization
665 ; replaces geu with gtu when op3 is an integer.
667 [(set (match_operand:SI 0 "register_operand" "=r")
668 (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
669 (match_operand:SI 3 "register_operand" "r"))
670 (match_operand:SI 1 "register_operand" "r")))]
672 "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
673 [(set_attr "type" "binary")
674 (set_attr "length" "8")])
676 ; Match only integers for op3 here. This is used as canonical form of the
677 ; geu pattern when op3 is an integer. Don't match registers since we can't
678 ; make better code than the general incscc pattern.
680 [(set (match_operand:SI 0 "register_operand" "=r")
681 (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
682 (match_operand:SI 3 "int11_operand" "I"))
683 (match_operand:SI 1 "register_operand" "r")))]
685 "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
686 [(set_attr "type" "binary")
687 (set_attr "length" "8")])
689 (define_insn "incscc"
690 [(set (match_operand:SI 0 "register_operand" "=r,r")
691 (plus:SI (match_operator:SI 4 "comparison_operator"
692 [(match_operand:SI 2 "register_operand" "r,r")
693 (match_operand:SI 3 "arith11_operand" "rI,rI")])
694 (match_operand:SI 1 "register_operand" "0,?r")))]
697 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
698 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
699 [(set_attr "type" "binary,binary")
700 (set_attr "length" "8,12")])
703 [(set (match_operand:SI 0 "register_operand" "=r")
704 (minus:SI (match_operand:SI 1 "register_operand" "r")
705 (gtu:SI (match_operand:SI 2 "register_operand" "r")
706 (match_operand:SI 3 "arith11_operand" "rI"))))]
708 "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
709 [(set_attr "type" "binary")
710 (set_attr "length" "8")])
713 [(set (match_operand:SI 0 "register_operand" "=r")
714 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
715 (gtu:SI (match_operand:SI 2 "register_operand" "r")
716 (match_operand:SI 3 "arith11_operand" "rI")))
717 (match_operand:SI 4 "register_operand" "r")))]
719 "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
720 [(set_attr "type" "binary")
721 (set_attr "length" "8")])
723 ; This need only accept registers for op3, since canonicalization
724 ; replaces ltu with leu when op3 is an integer.
726 [(set (match_operand:SI 0 "register_operand" "=r")
727 (minus:SI (match_operand:SI 1 "register_operand" "r")
728 (ltu:SI (match_operand:SI 2 "register_operand" "r")
729 (match_operand:SI 3 "register_operand" "r"))))]
731 "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
732 [(set_attr "type" "binary")
733 (set_attr "length" "8")])
736 [(set (match_operand:SI 0 "register_operand" "=r")
737 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
738 (ltu:SI (match_operand:SI 2 "register_operand" "r")
739 (match_operand:SI 3 "register_operand" "r")))
740 (match_operand:SI 4 "register_operand" "r")))]
742 "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
743 [(set_attr "type" "binary")
744 (set_attr "length" "8")])
746 ; Match only integers for op3 here. This is used as canonical form of the
747 ; ltu pattern when op3 is an integer. Don't match registers since we can't
748 ; make better code than the general incscc pattern.
750 [(set (match_operand:SI 0 "register_operand" "=r")
751 (minus:SI (match_operand:SI 1 "register_operand" "r")
752 (leu:SI (match_operand:SI 2 "register_operand" "r")
753 (match_operand:SI 3 "int11_operand" "I"))))]
755 "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
756 [(set_attr "type" "binary")
757 (set_attr "length" "8")])
760 [(set (match_operand:SI 0 "register_operand" "=r")
761 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
762 (leu:SI (match_operand:SI 2 "register_operand" "r")
763 (match_operand:SI 3 "int11_operand" "I")))
764 (match_operand:SI 4 "register_operand" "r")))]
766 "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
767 [(set_attr "type" "binary")
768 (set_attr "length" "8")])
770 (define_insn "decscc"
771 [(set (match_operand:SI 0 "register_operand" "=r,r")
772 (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
773 (match_operator:SI 4 "comparison_operator"
774 [(match_operand:SI 2 "register_operand" "r,r")
775 (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
778 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
779 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
780 [(set_attr "type" "binary,binary")
781 (set_attr "length" "8,12")])
783 ; Patterns for max and min. (There is no need for an earlyclobber in the
784 ; last alternative since the middle alternative will match if op0 == op1.)
786 (define_insn "sminsi3"
787 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
788 (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
789 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
792 {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
793 {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
794 {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
795 [(set_attr "type" "multi,multi,multi")
796 (set_attr "length" "8,8,8")])
798 (define_insn "uminsi3"
799 [(set (match_operand:SI 0 "register_operand" "=r,r")
800 (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
801 (match_operand:SI 2 "arith11_operand" "r,I")))]
804 {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
805 {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
806 [(set_attr "type" "multi,multi")
807 (set_attr "length" "8,8")])
809 (define_insn "smaxsi3"
810 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
811 (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
812 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
815 {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
816 {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
817 {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
818 [(set_attr "type" "multi,multi,multi")
819 (set_attr "length" "8,8,8")])
821 (define_insn "umaxsi3"
822 [(set (match_operand:SI 0 "register_operand" "=r,r")
823 (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
824 (match_operand:SI 2 "arith11_operand" "r,I")))]
827 {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
828 {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
829 [(set_attr "type" "multi,multi")
830 (set_attr "length" "8,8")])
832 (define_insn "abssi2"
833 [(set (match_operand:SI 0 "register_operand" "=r")
834 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
836 "or,>= %%r0,%1,%0\;subi 0,%0,%0"
837 [(set_attr "type" "multi")
838 (set_attr "length" "8")])
840 ;;; Experimental conditional move patterns
842 (define_expand "movsicc"
843 [(set (match_operand:SI 0 "register_operand" "")
845 (match_operator 1 "comparison_operator"
848 (match_operand:SI 2 "reg_or_cint_move_operand" "")
849 (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
853 enum rtx_code code = GET_CODE (operands[1]);
855 if (hppa_branch_type != CMP_SI)
858 /* operands[1] is currently the result of compare_from_rtx. We want to
859 emit a compare of the original operands. */
860 operands[1] = gen_rtx_fmt_ee (code, SImode, hppa_compare_op0, hppa_compare_op1);
861 operands[4] = hppa_compare_op0;
862 operands[5] = hppa_compare_op1;
865 ;; We used to accept any register for op1.
867 ;; However, it loses sometimes because the compiler will end up using
868 ;; different registers for op0 and op1 in some critical cases. local-alloc
869 ;; will not tie op0 and op1 because op0 is used in multiple basic blocks.
871 ;; If/when global register allocation supports tying we should allow any
872 ;; register for op1 again.
874 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
876 (match_operator 5 "comparison_operator"
877 [(match_operand:SI 3 "register_operand" "r,r,r,r")
878 (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
879 (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
883 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi 0,%0
884 {com%I4clr|cmp%I4clr},%B5 %4,%3,%0\;ldi %1,%0
885 {com%I4clr|cmp%I4clr},%B5 %4,%3,%0\;ldil L'%1,%0
886 {com%I4clr|cmp%I4clr},%B5 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
887 [(set_attr "type" "multi,multi,multi,nullshift")
888 (set_attr "length" "8,8,8,8")])
891 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
893 (match_operator 5 "comparison_operator"
894 [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
895 (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
896 (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
897 (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
900 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
901 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
902 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
903 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
904 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
905 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
906 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
907 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
908 [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
909 (set_attr "length" "8,8,8,8,8,8,8,8")])
911 ;; Conditional Branches
915 (if_then_else (eq (match_dup 1) (match_dup 2))
916 (label_ref (match_operand 0 "" ""))
921 if (hppa_branch_type != CMP_SI)
923 emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1));
924 emit_bcond_fp (NE, operands[0]);
927 /* set up operands from compare. */
928 operands[1] = hppa_compare_op0;
929 operands[2] = hppa_compare_op1;
930 /* fall through and generate default code */
935 (if_then_else (ne (match_dup 1) (match_dup 2))
936 (label_ref (match_operand 0 "" ""))
941 if (hppa_branch_type != CMP_SI)
943 emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1));
944 emit_bcond_fp (NE, operands[0]);
947 operands[1] = hppa_compare_op0;
948 operands[2] = hppa_compare_op1;
953 (if_then_else (gt (match_dup 1) (match_dup 2))
954 (label_ref (match_operand 0 "" ""))
959 if (hppa_branch_type != CMP_SI)
961 emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1));
962 emit_bcond_fp (NE, operands[0]);
965 operands[1] = hppa_compare_op0;
966 operands[2] = hppa_compare_op1;
971 (if_then_else (lt (match_dup 1) (match_dup 2))
972 (label_ref (match_operand 0 "" ""))
977 if (hppa_branch_type != CMP_SI)
979 emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1));
980 emit_bcond_fp (NE, operands[0]);
983 operands[1] = hppa_compare_op0;
984 operands[2] = hppa_compare_op1;
989 (if_then_else (ge (match_dup 1) (match_dup 2))
990 (label_ref (match_operand 0 "" ""))
995 if (hppa_branch_type != CMP_SI)
997 emit_insn (gen_cmp_fp (GE, hppa_compare_op0, hppa_compare_op1));
998 emit_bcond_fp (NE, operands[0]);
1001 operands[1] = hppa_compare_op0;
1002 operands[2] = hppa_compare_op1;
1005 (define_expand "ble"
1007 (if_then_else (le (match_dup 1) (match_dup 2))
1008 (label_ref (match_operand 0 "" ""))
1013 if (hppa_branch_type != CMP_SI)
1015 emit_insn (gen_cmp_fp (LE, hppa_compare_op0, hppa_compare_op1));
1016 emit_bcond_fp (NE, operands[0]);
1019 operands[1] = hppa_compare_op0;
1020 operands[2] = hppa_compare_op1;
1023 (define_expand "bgtu"
1025 (if_then_else (gtu (match_dup 1) (match_dup 2))
1026 (label_ref (match_operand 0 "" ""))
1031 if (hppa_branch_type != CMP_SI)
1033 operands[1] = hppa_compare_op0;
1034 operands[2] = hppa_compare_op1;
1037 (define_expand "bltu"
1039 (if_then_else (ltu (match_dup 1) (match_dup 2))
1040 (label_ref (match_operand 0 "" ""))
1045 if (hppa_branch_type != CMP_SI)
1047 operands[1] = hppa_compare_op0;
1048 operands[2] = hppa_compare_op1;
1051 (define_expand "bgeu"
1053 (if_then_else (geu (match_dup 1) (match_dup 2))
1054 (label_ref (match_operand 0 "" ""))
1059 if (hppa_branch_type != CMP_SI)
1061 operands[1] = hppa_compare_op0;
1062 operands[2] = hppa_compare_op1;
1065 (define_expand "bleu"
1067 (if_then_else (leu (match_dup 1) (match_dup 2))
1068 (label_ref (match_operand 0 "" ""))
1073 if (hppa_branch_type != CMP_SI)
1075 operands[1] = hppa_compare_op0;
1076 operands[2] = hppa_compare_op1;
1079 ;; Match the branch patterns.
1082 ;; Note a long backward conditional branch with an annulled delay slot
1083 ;; has a length of 12.
1087 (match_operator 3 "comparison_operator"
1088 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1089 (match_operand:SI 2 "arith5_operand" "rL")])
1090 (label_ref (match_operand 0 "" ""))
1095 return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1096 get_attr_length (insn), 0, insn);
1098 [(set_attr "type" "cbranch")
1099 (set (attr "length")
1100 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1103 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1106 (eq (symbol_ref "flag_pic") (const_int 0))
1110 ;; Match the negated branch.
1115 (match_operator 3 "comparison_operator"
1116 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1117 (match_operand:SI 2 "arith5_operand" "rL")])
1119 (label_ref (match_operand 0 "" ""))))]
1123 return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1124 get_attr_length (insn), 1, insn);
1126 [(set_attr "type" "cbranch")
1127 (set (attr "length")
1128 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1131 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1134 (eq (symbol_ref "flag_pic") (const_int 0))
1138 ;; Branch on Bit patterns.
1142 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1144 (match_operand:SI 1 "uint5_operand" ""))
1146 (label_ref (match_operand 2 "" ""))
1151 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1152 get_attr_length (insn), 0, insn, 0);
1154 [(set_attr "type" "cbranch")
1155 (set (attr "length")
1156 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1164 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1166 (match_operand:SI 1 "uint5_operand" ""))
1169 (label_ref (match_operand 2 "" ""))))]
1173 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1174 get_attr_length (insn), 1, insn, 0);
1176 [(set_attr "type" "cbranch")
1177 (set (attr "length")
1178 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1186 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1188 (match_operand:SI 1 "uint5_operand" ""))
1190 (label_ref (match_operand 2 "" ""))
1195 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1196 get_attr_length (insn), 0, insn, 1);
1198 [(set_attr "type" "cbranch")
1199 (set (attr "length")
1200 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1208 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1210 (match_operand:SI 1 "uint5_operand" ""))
1213 (label_ref (match_operand 2 "" ""))))]
1217 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1218 get_attr_length (insn), 1, insn, 1);
1220 [(set_attr "type" "cbranch")
1221 (set (attr "length")
1222 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1227 ;; Branch on Variable Bit patterns.
1231 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1233 (match_operand:SI 1 "register_operand" "q"))
1235 (label_ref (match_operand 2 "" ""))
1240 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1241 get_attr_length (insn), 0, insn, 0);
1243 [(set_attr "type" "cbranch")
1244 (set (attr "length")
1245 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1253 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1255 (match_operand:SI 1 "register_operand" "q"))
1258 (label_ref (match_operand 2 "" ""))))]
1262 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1263 get_attr_length (insn), 1, insn, 0);
1265 [(set_attr "type" "cbranch")
1266 (set (attr "length")
1267 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1275 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1277 (match_operand:SI 1 "register_operand" "q"))
1279 (label_ref (match_operand 2 "" ""))
1284 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1285 get_attr_length (insn), 0, insn, 1);
1287 [(set_attr "type" "cbranch")
1288 (set (attr "length")
1289 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1297 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1299 (match_operand:SI 1 "register_operand" "q"))
1302 (label_ref (match_operand 2 "" ""))))]
1306 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1307 get_attr_length (insn), 1, insn, 1);
1309 [(set_attr "type" "cbranch")
1310 (set (attr "length")
1311 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1316 ;; Floating point branches
1318 [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
1319 (label_ref (match_operand 0 "" ""))
1321 "! TARGET_SOFT_FLOAT"
1324 if (INSN_ANNULLED_BRANCH_P (insn))
1325 return \"ftest\;b,n %0\";
1327 return \"ftest\;b%* %0\";
1329 [(set_attr "type" "fbranch")
1330 (set_attr "length" "8")])
1333 [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
1335 (label_ref (match_operand 0 "" ""))))]
1336 "! TARGET_SOFT_FLOAT"
1339 if (INSN_ANNULLED_BRANCH_P (insn))
1340 return \"ftest\;add,tr %%r0,%%r0,%%r0\;b,n %0\";
1342 return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
1344 [(set_attr "type" "fbranch")
1345 (set_attr "length" "12")])
1347 ;; Move instructions
1349 (define_expand "movsi"
1350 [(set (match_operand:SI 0 "general_operand" "")
1351 (match_operand:SI 1 "general_operand" ""))]
1355 if (emit_move_sequence (operands, SImode, 0))
1359 ;; Reloading an SImode or DImode value requires a scratch register if
1360 ;; going in to or out of float point registers.
1362 (define_expand "reload_insi"
1363 [(set (match_operand:SI 0 "register_operand" "=Z")
1364 (match_operand:SI 1 "non_hard_reg_operand" ""))
1365 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1369 if (emit_move_sequence (operands, SImode, operands[2]))
1372 /* We don't want the clobber emitted, so handle this ourselves. */
1373 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
1377 (define_expand "reload_outsi"
1378 [(set (match_operand:SI 0 "non_hard_reg_operand" "")
1379 (match_operand:SI 1 "register_operand" "Z"))
1380 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1384 if (emit_move_sequence (operands, SImode, operands[2]))
1387 /* We don't want the clobber emitted, so handle this ourselves. */
1388 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
1392 ;;; pic symbol references
1395 [(set (match_operand:SI 0 "register_operand" "=r")
1396 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
1397 (match_operand:SI 2 "symbolic_operand" ""))))]
1398 "flag_pic && operands[1] == pic_offset_table_rtx"
1400 [(set_attr "type" "load")
1401 (set_attr "length" "4")])
1404 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
1405 "=r,r,r,r,r,Q,*q,!f,f,*TR")
1406 (match_operand:SI 1 "move_operand"
1407 "r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
1408 "(register_operand (operands[0], SImode)
1409 || reg_or_0_operand (operands[1], SImode))
1410 && ! TARGET_SOFT_FLOAT"
1415 {zdepi|depwi,z} %Z1,%0
1422 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
1423 (set_attr "pa_combine_type" "addmove")
1424 (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
1427 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
1429 (match_operand:SI 1 "move_operand"
1430 "r,J,N,K,RQ,rM,rM"))]
1431 "(register_operand (operands[0], SImode)
1432 || reg_or_0_operand (operands[1], SImode))
1433 && TARGET_SOFT_FLOAT"
1438 {zdepi|depwi,z} %Z1,%0
1442 [(set_attr "type" "move,move,move,move,load,store,move")
1443 (set_attr "pa_combine_type" "addmove")
1444 (set_attr "length" "4,4,4,4,4,4,4")])
1447 [(set (match_operand:SI 0 "register_operand" "=r")
1448 (mem:SI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
1449 (match_operand:SI 2 "register_operand" "r"))))]
1450 "! TARGET_DISABLE_INDEXING"
1453 /* Reload can create backwards (relative to cse) unscaled index
1454 address modes when eliminating registers and possibly for
1455 pseudos that don't get hard registers. Deal with it. */
1456 if (operands[2] == hard_frame_pointer_rtx
1457 || operands[2] == stack_pointer_rtx)
1458 return \"{ldwx|ldw} %1(%2),%0\";
1460 return \"{ldwx|ldw} %2(%1),%0\";
1462 [(set_attr "type" "load")
1463 (set_attr "length" "4")])
1466 [(set (match_operand:SI 0 "register_operand" "=r")
1467 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
1468 (match_operand:SI 2 "basereg_operand" "r"))))]
1469 "! TARGET_DISABLE_INDEXING"
1472 /* Reload can create backwards (relative to cse) unscaled index
1473 address modes when eliminating registers and possibly for
1474 pseudos that don't get hard registers. Deal with it. */
1475 if (operands[1] == hard_frame_pointer_rtx
1476 || operands[1] == stack_pointer_rtx)
1477 return \"{ldwx|ldw} %2(%1),%0\";
1479 return \"{ldwx|ldw} %1(%2),%0\";
1481 [(set_attr "type" "load")
1482 (set_attr "length" "4")])
1484 ;; Load or store with base-register modification.
1486 (define_expand "pre_load"
1487 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1488 (mem (plus (match_operand 1 "register_operand" "")
1489 (match_operand 2 "pre_cint_operand" ""))))
1491 (plus (match_dup 1) (match_dup 2)))])]
1495 emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
1499 (define_insn "pre_ldw"
1500 [(set (match_operand:SI 0 "register_operand" "=r")
1501 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
1502 (match_operand:SI 2 "pre_cint_operand" ""))))
1504 (plus:SI (match_dup 1) (match_dup 2)))]
1508 if (INTVAL (operands[2]) < 0)
1509 return \"{ldwm|ldw,mb} %2(%1),%0\";
1510 return \"{ldws|ldw},mb %2(%1),%0\";
1512 [(set_attr "type" "load")
1513 (set_attr "length" "4")])
1516 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
1517 (match_operand:SI 1 "pre_cint_operand" "")))
1518 (match_operand:SI 2 "reg_or_0_operand" "rM"))
1520 (plus:SI (match_dup 0) (match_dup 1)))]
1524 if (INTVAL (operands[1]) < 0)
1525 return \"{stwm|stw,mb} %r2,%1(%0)\";
1526 return \"{stws|stw},mb %r2,%1(%0)\";
1528 [(set_attr "type" "store")
1529 (set_attr "length" "4")])
1532 [(set (match_operand:SI 0 "register_operand" "=r")
1533 (mem:SI (match_operand:SI 1 "register_operand" "+r")))
1535 (plus:SI (match_dup 1)
1536 (match_operand:SI 2 "post_cint_operand" "")))]
1540 if (INTVAL (operands[2]) > 0)
1541 return \"{ldwm|ldw,ma} %2(%1),%0\";
1542 return \"{ldws|ldw},ma %2(%1),%0\";
1544 [(set_attr "type" "load")
1545 (set_attr "length" "4")])
1547 (define_expand "post_store"
1548 [(parallel [(set (mem (match_operand 0 "register_operand" ""))
1549 (match_operand 1 "reg_or_0_operand" ""))
1552 (match_operand 2 "post_cint_operand" "")))])]
1556 emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
1560 (define_insn "post_stw"
1561 [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
1562 (match_operand:SI 1 "reg_or_0_operand" "rM"))
1564 (plus:SI (match_dup 0)
1565 (match_operand:SI 2 "post_cint_operand" "")))]
1569 if (INTVAL (operands[2]) > 0)
1570 return \"{stwm|stw,ma} %r1,%2(%0)\";
1571 return \"{stws|stw},ma %r1,%2(%0)\";
1573 [(set_attr "type" "store")
1574 (set_attr "length" "4")])
1576 ;; For loading the address of a label while generating PIC code.
1577 ;; Note since this pattern can be created at reload time (via movsi), all
1578 ;; the same rules for movsi apply here. (no new pseudos, no temporaries).
1580 [(set (match_operand 0 "pmode_register_operand" "=a")
1581 (match_operand 1 "pic_label_operand" ""))]
1585 rtx label_rtx = gen_label_rtx ();
1587 extern FILE *asm_out_file;
1589 xoperands[0] = operands[0];
1590 xoperands[1] = operands[1];
1591 xoperands[2] = label_rtx;
1592 output_asm_insn (\"{bl|b,l} .+8,%0\", xoperands);
1593 output_asm_insn (\"{depi|depwi} 0,31,2,%0\", xoperands);
1594 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
1595 CODE_LABEL_NUMBER (label_rtx));
1597 /* If we're trying to load the address of a label that happens to be
1598 close, then we can use a shorter sequence. */
1599 if (GET_CODE (operands[1]) == LABEL_REF
1601 && abs (insn_addresses[INSN_UID (XEXP (operands[1], 0))]
1602 - insn_addresses[INSN_UID (insn)]) < 8100)
1604 /* Prefixing with R% here is wrong, it extracts just 11 bits and is
1605 always non-negative. */
1606 output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
1610 output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
1611 output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
1615 [(set_attr "type" "multi")
1616 (set_attr "length" "16")]) ; 12 or 16
1619 [(set (match_operand:SI 0 "register_operand" "=a")
1620 (plus:SI (match_operand:SI 1 "register_operand" "r")
1621 (high:SI (match_operand 2 "" ""))))]
1622 "symbolic_operand (operands[2], Pmode)
1623 && ! function_label_operand (operands[2])
1626 [(set_attr "type" "binary")
1627 (set_attr "length" "4")])
1629 ; We need this to make sure CSE doesn't simplify a memory load with a
1630 ; symbolic address, whose content it think it knows. For PIC, what CSE
1631 ; think is the real value will be the address of that value.
1633 [(set (match_operand:SI 0 "register_operand" "=r")
1635 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1637 [(match_operand:SI 2 "symbolic_operand" "")] 0))))]
1643 return \"ldw RT'%G2(%1),%0\";
1645 [(set_attr "type" "load")
1646 (set_attr "length" "4")])
1648 ;; Always use addil rather than ldil;add sequences. This allows the
1649 ;; HP linker to eliminate the dp relocation if the symbolic operand
1650 ;; lives in the TEXT space.
1652 [(set (match_operand:SI 0 "register_operand" "=a")
1653 (high:SI (match_operand 1 "" "")))]
1654 "symbolic_operand (operands[1], Pmode)
1655 && ! function_label_operand (operands[1])
1656 && ! read_only_operand (operands[1])
1660 if (TARGET_LONG_LOAD_STORE)
1661 return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
1663 return \"addil LR'%H1,%%r27\";
1665 [(set_attr "type" "binary")
1666 (set (attr "length")
1667 (if_then_else (eq (symbol_ref "TARGET_LONG_LOAD_STORE") (const_int 0))
1672 ;; This is for use in the prologue/epilogue code. We need it
1673 ;; to add large constants to a stack pointer or frame pointer.
1674 ;; Because of the additional %r1 pressure, we probably do not
1675 ;; want to use this in general code, so make it available
1676 ;; only after reload.
1678 [(set (match_operand:SI 0 "register_operand" "=!a,*r")
1679 (plus:SI (match_operand:SI 1 "register_operand" "r,r")
1680 (high:SI (match_operand 2 "const_int_operand" ""))))]
1684 ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
1685 [(set_attr "type" "binary,binary")
1686 (set_attr "length" "4,8")])
1689 [(set (match_operand:SI 0 "register_operand" "=r")
1690 (high:SI (match_operand 1 "" "")))]
1691 "(!flag_pic || !symbolic_operand (operands[1]), Pmode)
1692 && !is_function_label_plus_const (operands[1])"
1695 if (symbolic_operand (operands[1], Pmode))
1696 return \"ldil LR'%H1,%0\";
1698 return \"ldil L'%G1,%0\";
1700 [(set_attr "type" "move")
1701 (set_attr "length" "4")])
1704 [(set (match_operand:SI 0 "register_operand" "=r")
1705 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1706 (match_operand:SI 2 "immediate_operand" "i")))]
1707 "!is_function_label_plus_const (operands[2])"
1710 if (flag_pic && symbolic_operand (operands[2], Pmode))
1712 else if (symbolic_operand (operands[2], Pmode))
1713 return \"ldo RR'%G2(%1),%0\";
1715 return \"ldo R'%G2(%1),%0\";
1717 [(set_attr "type" "move")
1718 (set_attr "length" "4")])
1720 ;; Now that a symbolic_address plus a constant is broken up early
1721 ;; in the compilation phase (for better CSE) we need a special
1722 ;; combiner pattern to load the symbolic address plus the constant
1723 ;; in only 2 instructions. (For cases where the symbolic address
1724 ;; was not a common subexpression.)
1726 [(set (match_operand:SI 0 "register_operand" "")
1727 (match_operand:SI 1 "symbolic_operand" ""))
1728 (clobber (match_operand:SI 2 "register_operand" ""))]
1729 "! (flag_pic && pic_label_operand (operands[1], SImode))"
1730 [(set (match_dup 2) (high:SI (match_dup 1)))
1731 (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
1734 ;; hppa_legitimize_address goes to a great deal of trouble to
1735 ;; create addresses which use indexing. In some cases, this
1736 ;; is a lose because there isn't any store instructions which
1737 ;; allow indexed addresses (with integer register source).
1739 ;; These define_splits try to turn a 3 insn store into
1740 ;; a 2 insn store with some creative RTL rewriting.
1742 [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
1743 (match_operand:SI 1 "shadd_operand" ""))
1744 (plus:SI (match_operand:SI 2 "register_operand" "")
1745 (match_operand:SI 3 "const_int_operand" ""))))
1746 (match_operand:SI 4 "register_operand" ""))
1747 (clobber (match_operand:SI 5 "register_operand" ""))]
1749 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
1751 (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
1755 [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
1756 (match_operand:SI 1 "shadd_operand" ""))
1757 (plus:SI (match_operand:SI 2 "register_operand" "")
1758 (match_operand:SI 3 "const_int_operand" ""))))
1759 (match_operand:HI 4 "register_operand" ""))
1760 (clobber (match_operand:SI 5 "register_operand" ""))]
1762 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
1764 (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
1768 [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
1769 (match_operand:SI 1 "shadd_operand" ""))
1770 (plus:SI (match_operand:SI 2 "register_operand" "")
1771 (match_operand:SI 3 "const_int_operand" ""))))
1772 (match_operand:QI 4 "register_operand" ""))
1773 (clobber (match_operand:SI 5 "register_operand" ""))]
1775 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
1777 (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
1780 (define_expand "movhi"
1781 [(set (match_operand:HI 0 "general_operand" "")
1782 (match_operand:HI 1 "general_operand" ""))]
1786 if (emit_move_sequence (operands, HImode, 0))
1791 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!*f")
1792 (match_operand:HI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!*fM"))]
1793 "register_operand (operands[0], HImode)
1794 || reg_or_0_operand (operands[1], HImode)"
1799 {zdepi|depwi,z} %Z1,%0
1804 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
1805 (set_attr "pa_combine_type" "addmove")
1806 (set_attr "length" "4,4,4,4,4,4,4,4")])
1809 [(set (match_operand:HI 0 "register_operand" "=r")
1810 (mem:HI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
1811 (match_operand:SI 2 "register_operand" "r"))))]
1812 "! TARGET_DISABLE_INDEXING"
1815 /* Reload can create backwards (relative to cse) unscaled index
1816 address modes when eliminating registers and possibly for
1817 pseudos that don't get hard registers. Deal with it. */
1818 if (operands[2] == hard_frame_pointer_rtx
1819 || operands[2] == stack_pointer_rtx)
1820 return \"{ldhx|ldh} %1(%2),%0\";
1822 return \"{ldhx|ldh} %2(%1),%0\";
1824 [(set_attr "type" "load")
1825 (set_attr "length" "4")])
1828 [(set (match_operand:HI 0 "register_operand" "=r")
1829 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
1830 (match_operand:SI 2 "basereg_operand" "r"))))]
1831 "! TARGET_DISABLE_INDEXING"
1834 /* Reload can create backwards (relative to cse) unscaled index
1835 address modes when eliminating registers and possibly for
1836 pseudos that don't get hard registers. Deal with it. */
1837 if (operands[1] == hard_frame_pointer_rtx
1838 || operands[1] == stack_pointer_rtx)
1839 return \"{ldhx|ldh} %2(%1),%0\";
1841 return \"{ldhx|ldh} %1(%2),%0\";
1843 [(set_attr "type" "load")
1844 (set_attr "length" "4")])
1846 ; Now zero extended variants.
1848 [(set (match_operand:SI 0 "register_operand" "=r")
1849 (zero_extend:SI (mem:HI
1851 (match_operand:SI 1 "basereg_operand" "r")
1852 (match_operand:SI 2 "register_operand" "r")))))]
1853 "! TARGET_DISABLE_INDEXING"
1856 /* Reload can create backwards (relative to cse) unscaled index
1857 address modes when eliminating registers and possibly for
1858 pseudos that don't get hard registers. Deal with it. */
1859 if (operands[2] == hard_frame_pointer_rtx
1860 || operands[2] == stack_pointer_rtx)
1861 return \"{ldhx|ldh} %1(%2),%0\";
1863 return \"{ldhx|ldh} %2(%1),%0\";
1865 [(set_attr "type" "load")
1866 (set_attr "length" "4")])
1869 [(set (match_operand:SI 0 "register_operand" "=r")
1870 (zero_extend:SI (mem:HI
1872 (match_operand:SI 1 "register_operand" "r")
1873 (match_operand:SI 2 "basereg_operand" "r")))))]
1874 "! TARGET_DISABLE_INDEXING"
1877 /* Reload can create backwards (relative to cse) unscaled index
1878 address modes when eliminating registers and possibly for
1879 pseudos that don't get hard registers. Deal with it. */
1880 if (operands[1] == hard_frame_pointer_rtx
1881 || operands[1] == stack_pointer_rtx)
1882 return \"{ldhx|ldh} %2(%1),%0\";
1884 return \"{ldhx|ldh} %1(%2),%0\";
1886 [(set_attr "type" "load")
1887 (set_attr "length" "4")])
1890 [(set (match_operand:HI 0 "register_operand" "=r")
1891 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
1892 (match_operand:SI 2 "int5_operand" "L"))))
1894 (plus:SI (match_dup 1) (match_dup 2)))]
1896 "{ldhs|ldh},mb %2(%1),%0"
1897 [(set_attr "type" "load")
1898 (set_attr "length" "4")])
1900 ; And a zero extended variant.
1902 [(set (match_operand:SI 0 "register_operand" "=r")
1903 (zero_extend:SI (mem:HI
1905 (match_operand:SI 1 "register_operand" "+r")
1906 (match_operand:SI 2 "int5_operand" "L")))))
1908 (plus:SI (match_dup 1) (match_dup 2)))]
1910 "{ldhs|ldh},mb %2(%1),%0"
1911 [(set_attr "type" "load")
1912 (set_attr "length" "4")])
1915 [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
1916 (match_operand:SI 1 "int5_operand" "L")))
1917 (match_operand:HI 2 "reg_or_0_operand" "rM"))
1919 (plus:SI (match_dup 0) (match_dup 1)))]
1921 "{sths|sth},mb %r2,%1(%0)"
1922 [(set_attr "type" "store")
1923 (set_attr "length" "4")])
1926 [(set (match_operand:HI 0 "register_operand" "=r")
1927 (high:HI (match_operand 1 "const_int_operand" "")))]
1930 [(set_attr "type" "move")
1931 (set_attr "length" "4")])
1934 [(set (match_operand:HI 0 "register_operand" "=r")
1935 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
1936 (match_operand 2 "const_int_operand" "")))]
1939 [(set_attr "type" "move")
1940 (set_attr "length" "4")])
1942 (define_expand "movqi"
1943 [(set (match_operand:QI 0 "general_operand" "")
1944 (match_operand:QI 1 "general_operand" ""))]
1948 if (emit_move_sequence (operands, QImode, 0))
1953 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!*f")
1954 (match_operand:QI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!*fM"))]
1955 "register_operand (operands[0], QImode)
1956 || reg_or_0_operand (operands[1], QImode)"
1961 {zdepi|depwi,z} %Z1,%0
1966 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
1967 (set_attr "pa_combine_type" "addmove")
1968 (set_attr "length" "4,4,4,4,4,4,4,4")])
1971 [(set (match_operand:QI 0 "register_operand" "=r")
1972 (mem:QI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
1973 (match_operand:SI 2 "register_operand" "r"))))]
1974 "! TARGET_DISABLE_INDEXING"
1977 /* Reload can create backwards (relative to cse) unscaled index
1978 address modes when eliminating registers and possibly for
1979 pseudos that don't get hard registers. Deal with it. */
1980 if (operands[2] == hard_frame_pointer_rtx
1981 || operands[2] == stack_pointer_rtx)
1982 return \"{ldbx|ldb} %1(%2),%0\";
1984 return \"{ldbx|ldb} %2(%1),%0\";
1986 [(set_attr "type" "load")
1987 (set_attr "length" "4")])
1990 [(set (match_operand:QI 0 "register_operand" "=r")
1991 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
1992 (match_operand:SI 2 "basereg_operand" "r"))))]
1993 "! TARGET_DISABLE_INDEXING"
1996 /* Reload can create backwards (relative to cse) unscaled index
1997 address modes when eliminating registers and possibly for
1998 pseudos that don't get hard registers. Deal with it. */
1999 if (operands[1] == hard_frame_pointer_rtx
2000 || operands[1] == stack_pointer_rtx)
2001 return \"{ldbx|ldb} %2(%1),%0\";
2003 return \"{ldbx|ldb} %1(%2),%0\";
2005 [(set_attr "type" "load")
2006 (set_attr "length" "4")])
2008 ; Indexed byte load with zero extension to SImode or HImode.
2010 [(set (match_operand:SI 0 "register_operand" "=r")
2011 (zero_extend:SI (mem:QI
2013 (match_operand:SI 1 "basereg_operand" "r")
2014 (match_operand:SI 2 "register_operand" "r")))))]
2015 "! TARGET_DISABLE_INDEXING"
2018 /* Reload can create backwards (relative to cse) unscaled index
2019 address modes when eliminating registers and possibly for
2020 pseudos that don't get hard registers. Deal with it. */
2021 if (operands[2] == hard_frame_pointer_rtx
2022 || operands[2] == stack_pointer_rtx)
2023 return \"{ldbx|ldb} %1(%2),%0\";
2025 return \"{ldbx|ldb} %2(%1),%0\";
2027 [(set_attr "type" "load")
2028 (set_attr "length" "4")])
2031 [(set (match_operand:SI 0 "register_operand" "=r")
2032 (zero_extend:SI (mem:QI
2034 (match_operand:SI 1 "register_operand" "r")
2035 (match_operand:SI 2 "basereg_operand" "r")))))]
2036 "! TARGET_DISABLE_INDEXING"
2039 /* Reload can create backwards (relative to cse) unscaled index
2040 address modes when eliminating registers and possibly for
2041 pseudos that don't get hard registers. Deal with it. */
2042 if (operands[1] == hard_frame_pointer_rtx
2043 || operands[1] == stack_pointer_rtx)
2044 return \"{ldbx|ldb} %2(%1),%0\";
2046 return \"{ldbx|ldb} %1(%2),%0\";
2048 [(set_attr "type" "load")
2049 (set_attr "length" "4")])
2052 [(set (match_operand:HI 0 "register_operand" "=r")
2053 (zero_extend:HI (mem:QI
2055 (match_operand:SI 1 "basereg_operand" "r")
2056 (match_operand:SI 2 "register_operand" "r")))))]
2057 "! TARGET_DISABLE_INDEXING"
2060 /* Reload can create backwards (relative to cse) unscaled index
2061 address modes when eliminating registers and possibly for
2062 pseudos that don't get hard registers. Deal with it. */
2063 if (operands[2] == hard_frame_pointer_rtx
2064 || operands[2] == stack_pointer_rtx)
2065 return \"{ldbx|ldb} %1(%2),%0\";
2067 return \"{ldbx|ldb} %2(%1),%0\";
2069 [(set_attr "type" "load")
2070 (set_attr "length" "4")])
2073 [(set (match_operand:HI 0 "register_operand" "=r")
2074 (zero_extend:HI (mem:QI
2076 (match_operand:SI 1 "register_operand" "r")
2077 (match_operand:SI 2 "basereg_operand" "r")))))]
2078 "! TARGET_DISABLE_INDEXING"
2081 /* Reload can create backwards (relative to cse) unscaled index
2082 address modes when eliminating registers and possibly for
2083 pseudos that don't get hard registers. Deal with it. */
2084 if (operands[1] == hard_frame_pointer_rtx
2085 || operands[1] == stack_pointer_rtx)
2086 return \"{ldbx|ldb} %2(%1),%0\";
2088 return \"{ldbx|ldb} %1(%2),%0\";
2090 [(set_attr "type" "load")
2091 (set_attr "length" "4")])
2094 [(set (match_operand:QI 0 "register_operand" "=r")
2095 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2096 (match_operand:SI 2 "int5_operand" "L"))))
2097 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2099 "{ldbs|ldb},mb %2(%1),%0"
2100 [(set_attr "type" "load")
2101 (set_attr "length" "4")])
2103 ; Now the same thing with zero extensions.
2105 [(set (match_operand:SI 0 "register_operand" "=r")
2106 (zero_extend:SI (mem:QI (plus:SI
2107 (match_operand:SI 1 "register_operand" "+r")
2108 (match_operand:SI 2 "int5_operand" "L")))))
2109 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2111 "{ldbs|ldb},mb %2(%1),%0"
2112 [(set_attr "type" "load")
2113 (set_attr "length" "4")])
2116 [(set (match_operand:HI 0 "register_operand" "=r")
2117 (zero_extend:HI (mem:QI (plus:SI
2118 (match_operand:SI 1 "register_operand" "+r")
2119 (match_operand:SI 2 "int5_operand" "L")))))
2120 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2122 "{ldbs|ldb},mb %2(%1),%0"
2123 [(set_attr "type" "load")
2124 (set_attr "length" "4")])
2127 [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2128 (match_operand:SI 1 "int5_operand" "L")))
2129 (match_operand:QI 2 "reg_or_0_operand" "rM"))
2131 (plus:SI (match_dup 0) (match_dup 1)))]
2133 "{stbs|stb},mb %r2,%1(%0)"
2134 [(set_attr "type" "store")
2135 (set_attr "length" "4")])
2137 ;; The definition of this insn does not really explain what it does,
2138 ;; but it should suffice
2139 ;; that anything generated as this insn will be recognized as one
2140 ;; and that it will not successfully combine with anything.
2141 (define_expand "movstrsi"
2142 [(parallel [(set (match_operand:BLK 0 "" "")
2143 (match_operand:BLK 1 "" ""))
2144 (clobber (match_dup 7))
2145 (clobber (match_dup 8))
2146 (clobber (match_dup 4))
2147 (clobber (match_dup 5))
2148 (clobber (match_dup 6))
2149 (use (match_operand:SI 2 "arith_operand" ""))
2150 (use (match_operand:SI 3 "const_int_operand" ""))])]
2156 /* HP provides very fast block move library routine for the PA;
2157 this routine includes:
2159 4x4 byte at a time block moves,
2160 1x4 byte at a time with alignment checked at runtime with
2161 attempts to align the source and destination as needed
2164 With that in mind, here's the heuristics to try and guess when
2165 the inlined block move will be better than the library block
2168 If the size isn't constant, then always use the library routines.
2170 If the size is large in respect to the known alignment, then use
2171 the library routines.
2173 If the size is small in repsect to the known alignment, then open
2174 code the copy (since that will lead to better scheduling).
2176 Else use the block move pattern. */
2178 /* Undetermined size, use the library routine. */
2179 if (GET_CODE (operands[2]) != CONST_INT)
2182 size = INTVAL (operands[2]);
2183 align = INTVAL (operands[3]);
2184 align = align > 4 ? 4 : align;
2186 /* If size/alignment > 8 (eg size is large in respect to alignment),
2187 then use the library routines. */
2188 if (size / align > 16)
2191 /* This does happen, but not often enough to worry much about. */
2192 if (size / align < MOVE_RATIO)
2195 /* Fall through means we're going to use our block move pattern. */
2197 = change_address (operands[0], VOIDmode,
2198 copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
2200 = change_address (operands[1], VOIDmode,
2201 copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
2202 operands[4] = gen_reg_rtx (SImode);
2203 operands[5] = gen_reg_rtx (SImode);
2204 operands[6] = gen_reg_rtx (SImode);
2205 operands[7] = XEXP (operands[0], 0);
2206 operands[8] = XEXP (operands[1], 0);
2209 ;; The operand constraints are written like this to support both compile-time
2210 ;; and run-time determined byte count. If the count is run-time determined,
2211 ;; the register with the byte count is clobbered by the copying code, and
2212 ;; therefore it is forced to operand 2. If the count is compile-time
2213 ;; determined, we need two scratch registers for the unrolled code.
2214 (define_insn "movstrsi_internal"
2215 [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
2216 (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
2217 (clobber (match_dup 0))
2218 (clobber (match_dup 1))
2219 (clobber (match_operand:SI 2 "register_operand" "=r,r")) ;loop cnt/tmp
2220 (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp
2221 (clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
2222 (use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count
2223 (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
2225 "* return output_block_move (operands, !which_alternative);"
2226 [(set_attr "type" "multi,multi")])
2228 ;; Floating point move insns
2230 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2231 ;; to be reloaded by putting the constant into memory when
2232 ;; reg is a floating point register.
2234 ;; For integer registers we use ldil;ldo to set the appropriate
2237 ;; This must come before the movdf pattern, and it must be present
2238 ;; to handle obscure reloading cases.
2240 [(set (match_operand:DF 0 "register_operand" "=?r,f")
2241 (match_operand:DF 1 "" "?F,m"))]
2242 "GET_CODE (operands[1]) == CONST_DOUBLE
2243 && operands[1] != CONST0_RTX (DFmode)
2244 && ! TARGET_SOFT_FLOAT"
2245 "* return (which_alternative == 0 ? output_move_double (operands)
2246 : \"fldd%F1 %1,%0\");"
2247 [(set_attr "type" "move,fpload")
2248 (set_attr "length" "16,4")])
2250 (define_expand "movdf"
2251 [(set (match_operand:DF 0 "general_operand" "")
2252 (match_operand:DF 1 "general_operand" ""))]
2256 if (emit_move_sequence (operands, DFmode, 0))
2260 ;; Reloading an SImode or DImode value requires a scratch register if
2261 ;; going in to or out of float point registers.
2263 (define_expand "reload_indf"
2264 [(set (match_operand:DF 0 "register_operand" "=Z")
2265 (match_operand:DF 1 "non_hard_reg_operand" ""))
2266 (clobber (match_operand:DF 2 "register_operand" "=&r"))]
2270 if (emit_move_sequence (operands, DFmode, operands[2]))
2273 /* We don't want the clobber emitted, so handle this ourselves. */
2274 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2278 (define_expand "reload_outdf"
2279 [(set (match_operand:DF 0 "non_hard_reg_operand" "")
2280 (match_operand:DF 1 "register_operand" "Z"))
2281 (clobber (match_operand:DF 2 "register_operand" "=&r"))]
2285 if (emit_move_sequence (operands, DFmode, operands[2]))
2288 /* We don't want the clobber emitted, so handle this ourselves. */
2289 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2294 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
2295 "=f,*r,RQ,?o,?Q,f,*r,*r")
2296 (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
2297 "fG,*rG,f,*r,*r,RQ,o,RQ"))]
2298 "(register_operand (operands[0], DFmode)
2299 || reg_or_0_operand (operands[1], DFmode))
2300 && ! (GET_CODE (operands[1]) == CONST_DOUBLE
2301 && GET_CODE (operands[0]) == MEM)
2302 && ! TARGET_SOFT_FLOAT"
2305 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
2306 || operands[1] == CONST0_RTX (DFmode))
2307 return output_fp_move_double (operands);
2308 return output_move_double (operands);
2310 [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load")
2311 (set_attr "length" "4,8,4,8,16,4,8,16")])
2314 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
2316 (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
2318 "(register_operand (operands[0], DFmode)
2319 || reg_or_0_operand (operands[1], DFmode))
2320 && TARGET_SOFT_FLOAT"
2323 return output_move_double (operands);
2325 [(set_attr "type" "move,store,store,load,load")
2326 (set_attr "length" "8,8,16,8,16")])
2329 [(set (match_operand:DF 0 "register_operand" "=fx")
2330 (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2331 (match_operand:SI 2 "register_operand" "r"))))]
2332 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2335 /* Reload can create backwards (relative to cse) unscaled index
2336 address modes when eliminating registers and possibly for
2337 pseudos that don't get hard registers. Deal with it. */
2338 if (operands[2] == hard_frame_pointer_rtx
2339 || operands[2] == stack_pointer_rtx)
2340 return \"{flddx|fldd} %1(%2),%0\";
2342 return \"{flddx|fldd} %2(%1),%0\";
2344 [(set_attr "type" "fpload")
2345 (set_attr "length" "4")])
2348 [(set (match_operand:DF 0 "register_operand" "=fx")
2349 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
2350 (match_operand:SI 2 "basereg_operand" "r"))))]
2351 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2354 /* Reload can create backwards (relative to cse) unscaled index
2355 address modes when eliminating registers and possibly for
2356 pseudos that don't get hard registers. Deal with it. */
2357 if (operands[1] == hard_frame_pointer_rtx
2358 || operands[1] == stack_pointer_rtx)
2359 return \"{flddx|fldd} %2(%1),%0\";
2361 return \"{flddx|fldd} %1(%2),%0\";
2363 [(set_attr "type" "fpload")
2364 (set_attr "length" "4")])
2367 [(set (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2368 (match_operand:SI 2 "register_operand" "r")))
2369 (match_operand:DF 0 "register_operand" "fx"))]
2370 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2373 /* Reload can create backwards (relative to cse) unscaled index
2374 address modes when eliminating registers and possibly for
2375 pseudos that don't get hard registers. Deal with it. */
2376 if (operands[2] == hard_frame_pointer_rtx
2377 || operands[2] == stack_pointer_rtx)
2378 return \"{fstdx|fstd} %0,%1(%2)\";
2380 return \"{fstdx|fstd} %0,%2(%1)\";
2382 [(set_attr "type" "fpstore")
2383 (set_attr "length" "4")])
2386 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
2387 (match_operand:SI 2 "basereg_operand" "r")))
2388 (match_operand:DF 0 "register_operand" "fx"))]
2389 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2392 /* Reload can create backwards (relative to cse) unscaled index
2393 address modes when eliminating registers and possibly for
2394 pseudos that don't get hard registers. Deal with it. */
2395 if (operands[1] == hard_frame_pointer_rtx
2396 || operands[1] == stack_pointer_rtx)
2397 return \"{fstdx|fstd} %0,%2(%1)\";
2399 return \"{fstdx|fstd} %0,%1(%2)\";
2401 [(set_attr "type" "fpstore")
2402 (set_attr "length" "4")])
2404 (define_expand "movdi"
2405 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2406 (match_operand:DI 1 "general_operand" ""))]
2410 if (emit_move_sequence (operands, DImode, 0))
2414 (define_expand "reload_indi"
2415 [(set (match_operand:DI 0 "register_operand" "=Z")
2416 (match_operand:DI 1 "non_hard_reg_operand" ""))
2417 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2421 if (emit_move_sequence (operands, DImode, operands[2]))
2424 /* We don't want the clobber emitted, so handle this ourselves. */
2425 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2429 (define_expand "reload_outdi"
2430 [(set (match_operand:DI 0 "general_operand" "")
2431 (match_operand:DI 1 "register_operand" "Z"))
2432 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2436 if (emit_move_sequence (operands, DImode, operands[2]))
2439 /* We don't want the clobber emitted, so handle this ourselves. */
2440 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2445 [(set (match_operand:DI 0 "register_operand" "=r")
2446 (high:DI (match_operand 1 "" "")))]
2450 rtx op0 = operands[0];
2451 rtx op1 = operands[1];
2453 if (GET_CODE (op1) == CONST_INT)
2455 operands[0] = operand_subword (op0, 1, 0, DImode);
2456 output_asm_insn (\"ldil L'%1,%0\", operands);
2458 operands[0] = operand_subword (op0, 0, 0, DImode);
2459 if (INTVAL (op1) < 0)
2460 output_asm_insn (\"ldi -1,%0\", operands);
2462 output_asm_insn (\"ldi 0,%0\", operands);
2465 else if (GET_CODE (op1) == CONST_DOUBLE)
2467 operands[0] = operand_subword (op0, 1, 0, DImode);
2468 operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
2469 output_asm_insn (\"ldil L'%1,%0\", operands);
2471 operands[0] = operand_subword (op0, 0, 0, DImode);
2472 operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
2473 output_asm_insn (singlemove_string (operands), operands);
2479 [(set_attr "type" "move")
2480 (set_attr "length" "8")])
2483 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
2484 "=r,o,Q,r,r,r,f,f,*TR")
2485 (match_operand:DI 1 "general_operand"
2486 "rM,r,r,o*R,Q,i,fM,*TR,f"))]
2487 "(register_operand (operands[0], DImode)
2488 || reg_or_0_operand (operands[1], DImode))
2489 && ! TARGET_SOFT_FLOAT"
2492 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
2493 || (operands[1] == CONST0_RTX (DImode)))
2494 return output_fp_move_double (operands);
2495 return output_move_double (operands);
2497 [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore")
2498 (set_attr "length" "8,8,16,8,16,16,4,4,4")])
2501 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
2503 (match_operand:DI 1 "general_operand"
2505 "(register_operand (operands[0], DImode)
2506 || reg_or_0_operand (operands[1], DImode))
2507 && TARGET_SOFT_FLOAT"
2510 return output_move_double (operands);
2512 [(set_attr "type" "move,store,store,load,load,multi")
2513 (set_attr "length" "8,8,16,8,16,16")])
2516 [(set (match_operand:DI 0 "register_operand" "=r,&r")
2517 (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
2518 (match_operand:DI 2 "immediate_operand" "i,i")))]
2522 /* Don't output a 64 bit constant, since we can't trust the assembler to
2523 handle it correctly. */
2524 if (GET_CODE (operands[2]) == CONST_DOUBLE)
2525 operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
2526 if (which_alternative == 1)
2527 output_asm_insn (\"copy %1,%0\", operands);
2528 return \"ldo R'%G2(%R1),%R0\";
2530 [(set_attr "type" "move,move")
2531 (set_attr "length" "4,8")])
2533 ;; This pattern forces (set (reg:SF ...) (const_double ...))
2534 ;; to be reloaded by putting the constant into memory when
2535 ;; reg is a floating point register.
2537 ;; For integer registers we use ldil;ldo to set the appropriate
2540 ;; This must come before the movsf pattern, and it must be present
2541 ;; to handle obscure reloading cases.
2543 [(set (match_operand:SF 0 "register_operand" "=?r,f")
2544 (match_operand:SF 1 "" "?F,m"))]
2545 "GET_CODE (operands[1]) == CONST_DOUBLE
2546 && operands[1] != CONST0_RTX (SFmode)
2547 && ! TARGET_SOFT_FLOAT"
2548 "* return (which_alternative == 0 ? singlemove_string (operands)
2549 : \" fldw%F1 %1,%0\");"
2550 [(set_attr "type" "move,fpload")
2551 (set_attr "length" "8,4")])
2553 (define_expand "movsf"
2554 [(set (match_operand:SF 0 "general_operand" "")
2555 (match_operand:SF 1 "general_operand" ""))]
2559 if (emit_move_sequence (operands, SFmode, 0))
2563 ;; Reloading an SImode or DImode value requires a scratch register if
2564 ;; going in to or out of float point registers.
2566 (define_expand "reload_insf"
2567 [(set (match_operand:SF 0 "register_operand" "=Z")
2568 (match_operand:SF 1 "non_hard_reg_operand" ""))
2569 (clobber (match_operand:SF 2 "register_operand" "=&r"))]
2573 if (emit_move_sequence (operands, SFmode, operands[2]))
2576 /* We don't want the clobber emitted, so handle this ourselves. */
2577 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2581 (define_expand "reload_outsf"
2582 [(set (match_operand:SF 0 "non_hard_reg_operand" "")
2583 (match_operand:SF 1 "register_operand" "Z"))
2584 (clobber (match_operand:SF 2 "register_operand" "=&r"))]
2588 if (emit_move_sequence (operands, SFmode, operands[2]))
2591 /* We don't want the clobber emitted, so handle this ourselves. */
2592 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2597 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
2599 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
2600 "fG,rG,RQ,RQ,f,rG"))]
2601 "(register_operand (operands[0], SFmode)
2602 || reg_or_0_operand (operands[1], SFmode))
2603 && ! TARGET_SOFT_FLOAT"
2611 [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
2612 (set_attr "pa_combine_type" "addmove")
2613 (set_attr "length" "4,4,4,4,4,4")])
2616 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
2618 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
2620 "(register_operand (operands[0], SFmode)
2621 || reg_or_0_operand (operands[1], SFmode))
2622 && TARGET_SOFT_FLOAT"
2627 [(set_attr "type" "move,load,store")
2628 (set_attr "pa_combine_type" "addmove")
2629 (set_attr "length" "4,4,4")])
2632 [(set (match_operand:SF 0 "register_operand" "=fx")
2633 (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2634 (match_operand:SI 2 "register_operand" "r"))))]
2635 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2638 /* Reload can create backwards (relative to cse) unscaled index
2639 address modes when eliminating registers and possibly for
2640 pseudos that don't get hard registers. Deal with it. */
2641 if (operands[2] == hard_frame_pointer_rtx
2642 || operands[2] == stack_pointer_rtx)
2643 return \"{fldwx|fldw} %1(%2),%0\";
2645 return \"{fldwx|fldw} %2(%1),%0\";
2647 [(set_attr "type" "fpload")
2648 (set_attr "length" "4")])
2651 [(set (match_operand:SF 0 "register_operand" "=fx")
2652 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
2653 (match_operand:SI 2 "basereg_operand" "r"))))]
2654 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2657 /* Reload can create backwards (relative to cse) unscaled index
2658 address modes when eliminating registers and possibly for
2659 pseudos that don't get hard registers. Deal with it. */
2660 if (operands[1] == hard_frame_pointer_rtx
2661 || operands[1] == stack_pointer_rtx)
2662 return \"{fldwx|fldw} %2(%1),%0\";
2664 return \"{fldwx|fldw} %1(%2),%0\";
2666 [(set_attr "type" "fpload")
2667 (set_attr "length" "4")])
2670 [(set (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2671 (match_operand:SI 2 "register_operand" "r")))
2672 (match_operand:SF 0 "register_operand" "fx"))]
2673 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2676 /* Reload can create backwards (relative to cse) unscaled index
2677 address modes when eliminating registers and possibly for
2678 pseudos that don't get hard registers. Deal with it. */
2679 if (operands[2] == hard_frame_pointer_rtx
2680 || operands[2] == stack_pointer_rtx)
2681 return \"{fstwx|fstw} %0,%1(%2)\";
2683 return \"{fstwx|fstw} %0,%2(%1)\";
2685 [(set_attr "type" "fpstore")
2686 (set_attr "length" "4")])
2689 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
2690 (match_operand:SI 2 "basereg_operand" "r")))
2691 (match_operand:SF 0 "register_operand" "fx"))]
2692 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2695 /* Reload can create backwards (relative to cse) unscaled index
2696 address modes when eliminating registers and possibly for
2697 pseudos that don't get hard registers. Deal with it. */
2698 if (operands[1] == hard_frame_pointer_rtx
2699 || operands[1] == stack_pointer_rtx)
2700 return \"{fstwx|fstw} %0,%2(%1)\";
2702 return \"{fstwx|fstw} %0,%1(%2)\";
2704 [(set_attr "type" "fpstore")
2705 (set_attr "length" "4")])
2708 ;;- zero extension instructions
2709 ;; We have define_expand for zero extension patterns to make sure the
2710 ;; operands get loaded into registers. The define_insns accept
2711 ;; memory operands. This gives us better overall code than just
2712 ;; having a pattern that does or does not accept memory operands.
2714 (define_expand "zero_extendhisi2"
2715 [(set (match_operand:SI 0 "register_operand" "")
2717 (match_operand:HI 1 "register_operand" "")))]
2722 [(set (match_operand:SI 0 "register_operand" "=r,r")
2724 (match_operand:HI 1 "move_operand" "r,RQ")))]
2725 "GET_CODE (operands[1]) != CONST_INT"
2727 {extru|extrw,u} %1,31,16,%0
2729 [(set_attr "type" "shift,load")
2730 (set_attr "length" "4,4")])
2732 (define_expand "zero_extendqihi2"
2733 [(set (match_operand:HI 0 "register_operand" "")
2735 (match_operand:QI 1 "register_operand" "")))]
2740 [(set (match_operand:HI 0 "register_operand" "=r,r")
2742 (match_operand:QI 1 "move_operand" "r,RQ")))]
2743 "GET_CODE (operands[1]) != CONST_INT"
2745 {extru|extrw,u} %1,31,8,%0
2747 [(set_attr "type" "shift,load")
2748 (set_attr "length" "4,4")])
2750 (define_expand "zero_extendqisi2"
2751 [(set (match_operand:SI 0 "register_operand" "")
2753 (match_operand:QI 1 "register_operand" "")))]
2758 [(set (match_operand:SI 0 "register_operand" "=r,r")
2760 (match_operand:QI 1 "move_operand" "r,RQ")))]
2761 "GET_CODE (operands[1]) != CONST_INT"
2763 {extru|extrw,u} %1,31,8,%0
2765 [(set_attr "type" "shift,load")
2766 (set_attr "length" "4,4")])
2768 ;;- sign extension instructions
2770 (define_insn "extendhisi2"
2771 [(set (match_operand:SI 0 "register_operand" "=r")
2772 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2774 "{extrs|extrw,s} %1,31,16,%0"
2775 [(set_attr "type" "shift")
2776 (set_attr "length" "4")])
2778 (define_insn "extendqihi2"
2779 [(set (match_operand:HI 0 "register_operand" "=r")
2780 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
2782 "{extrs|extrw,s} %1,31,8,%0"
2783 [(set_attr "type" "shift")
2784 (set_attr "length" "4")])
2786 (define_insn "extendqisi2"
2787 [(set (match_operand:SI 0 "register_operand" "=r")
2788 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2790 "{extrs|extrw,s} %1,31,8,%0"
2791 [(set_attr "type" "shift")
2792 (set_attr "length" "4")])
2794 ;; Conversions between float and double.
2796 (define_insn "extendsfdf2"
2797 [(set (match_operand:DF 0 "register_operand" "=f")
2799 (match_operand:SF 1 "register_operand" "f")))]
2800 "! TARGET_SOFT_FLOAT"
2801 "{fcnvff|fcnv},sgl,dbl %1,%0"
2802 [(set_attr "type" "fpalu")
2803 (set_attr "length" "4")])
2805 (define_insn "truncdfsf2"
2806 [(set (match_operand:SF 0 "register_operand" "=f")
2808 (match_operand:DF 1 "register_operand" "f")))]
2809 "! TARGET_SOFT_FLOAT"
2810 "{fcnvff|fcnv},dbl,sgl %1,%0"
2811 [(set_attr "type" "fpalu")
2812 (set_attr "length" "4")])
2814 ;; Conversion between fixed point and floating point.
2815 ;; Note that among the fix-to-float insns
2816 ;; the ones that start with SImode come first.
2817 ;; That is so that an operand that is a CONST_INT
2818 ;; (and therefore lacks a specific machine mode).
2819 ;; will be recognized as SImode (which is always valid)
2820 ;; rather than as QImode or HImode.
2822 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
2823 ;; to be reloaded by putting the constant into memory.
2824 ;; It must come before the more general floatsisf2 pattern.
2826 [(set (match_operand:SF 0 "register_operand" "=f")
2827 (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
2828 "! TARGET_SOFT_FLOAT"
2829 "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
2830 [(set_attr "type" "fpalu")
2831 (set_attr "length" "8")])
2833 (define_insn "floatsisf2"
2834 [(set (match_operand:SF 0 "register_operand" "=f")
2835 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2836 "! TARGET_SOFT_FLOAT"
2837 "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
2838 [(set_attr "type" "fpalu")
2839 (set_attr "length" "4")])
2841 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
2842 ;; to be reloaded by putting the constant into memory.
2843 ;; It must come before the more general floatsidf2 pattern.
2845 [(set (match_operand:DF 0 "register_operand" "=f")
2846 (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
2847 "! TARGET_SOFT_FLOAT"
2848 "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
2849 [(set_attr "type" "fpalu")
2850 (set_attr "length" "8")])
2852 (define_insn "floatsidf2"
2853 [(set (match_operand:DF 0 "register_operand" "=f")
2854 (float:DF (match_operand:SI 1 "register_operand" "f")))]
2855 "! TARGET_SOFT_FLOAT"
2856 "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
2857 [(set_attr "type" "fpalu")
2858 (set_attr "length" "4")])
2860 (define_expand "floatunssisf2"
2861 [(set (subreg:SI (match_dup 2) 1)
2862 (match_operand:SI 1 "register_operand" ""))
2863 (set (subreg:SI (match_dup 2) 0)
2865 (set (match_operand:SF 0 "register_operand" "")
2866 (float:SF (match_dup 2)))]
2867 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
2872 emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
2875 operands[2] = gen_reg_rtx (DImode);
2878 (define_expand "floatunssidf2"
2879 [(set (subreg:SI (match_dup 2) 1)
2880 (match_operand:SI 1 "register_operand" ""))
2881 (set (subreg:SI (match_dup 2) 0)
2883 (set (match_operand:DF 0 "register_operand" "")
2884 (float:DF (match_dup 2)))]
2885 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
2890 emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
2893 operands[2] = gen_reg_rtx (DImode);
2896 (define_insn "floatdisf2"
2897 [(set (match_operand:SF 0 "register_operand" "=f")
2898 (float:SF (match_operand:DI 1 "register_operand" "f")))]
2899 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
2900 "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
2901 [(set_attr "type" "fpalu")
2902 (set_attr "length" "4")])
2904 (define_insn "floatdidf2"
2905 [(set (match_operand:DF 0 "register_operand" "=f")
2906 (float:DF (match_operand:DI 1 "register_operand" "f")))]
2907 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
2908 "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
2909 [(set_attr "type" "fpalu")
2910 (set_attr "length" "4")])
2912 ;; Convert a float to an actual integer.
2913 ;; Truncation is performed as part of the conversion.
2915 (define_insn "fix_truncsfsi2"
2916 [(set (match_operand:SI 0 "register_operand" "=f")
2917 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
2918 "! TARGET_SOFT_FLOAT"
2919 "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
2920 [(set_attr "type" "fpalu")
2921 (set_attr "length" "4")])
2923 (define_insn "fix_truncdfsi2"
2924 [(set (match_operand:SI 0 "register_operand" "=f")
2925 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
2926 "! TARGET_SOFT_FLOAT"
2927 "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
2928 [(set_attr "type" "fpalu")
2929 (set_attr "length" "4")])
2931 (define_insn "fix_truncsfdi2"
2932 [(set (match_operand:DI 0 "register_operand" "=f")
2933 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
2934 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
2935 "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
2936 [(set_attr "type" "fpalu")
2937 (set_attr "length" "4")])
2939 (define_insn "fix_truncdfdi2"
2940 [(set (match_operand:DI 0 "register_operand" "=f")
2941 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
2942 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
2943 "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
2944 [(set_attr "type" "fpalu")
2945 (set_attr "length" "4")])
2947 (define_insn "floatunssidf2_pa20"
2948 [(set (match_operand:DF 0 "register_operand" "=f")
2949 (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
2950 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2952 [(set_attr "type" "fpalu")
2953 (set_attr "length" "4")])
2955 (define_insn "floatunssisf2_pa20"
2956 [(set (match_operand:SF 0 "register_operand" "=f")
2957 (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
2958 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2960 [(set_attr "type" "fpalu")
2961 (set_attr "length" "4")])
2963 (define_insn "floatunsdisf2"
2964 [(set (match_operand:SF 0 "register_operand" "=f")
2965 (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
2966 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2967 "fcnv,udw,sgl %1,%0"
2968 [(set_attr "type" "fpalu")
2969 (set_attr "length" "4")])
2971 (define_insn "floatunsdidf2"
2972 [(set (match_operand:DF 0 "register_operand" "=f")
2973 (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
2974 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2975 "fcnv,udw,dbl %1,%0"
2976 [(set_attr "type" "fpalu")
2977 (set_attr "length" "4")])
2979 (define_insn "fixuns_truncsfsi2"
2980 [(set (match_operand:SI 0 "register_operand" "=f")
2981 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
2982 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2983 "fcnv,t,sgl,uw %1,%0"
2984 [(set_attr "type" "fpalu")
2985 (set_attr "length" "4")])
2987 (define_insn "fixuns_truncdfsi2"
2988 [(set (match_operand:SI 0 "register_operand" "=f")
2989 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
2990 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2991 "fcnv,t,dbl,uw %1,%0"
2992 [(set_attr "type" "fpalu")
2993 (set_attr "length" "4")])
2995 (define_insn "fixuns_truncsfdi2"
2996 [(set (match_operand:DI 0 "register_operand" "=f")
2997 (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
2998 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2999 "fcnv,t,sgl,udw %1,%0"
3000 [(set_attr "type" "fpalu")
3001 (set_attr "length" "4")])
3003 (define_insn "fixuns_truncdfdi2"
3004 [(set (match_operand:DI 0 "register_operand" "=f")
3005 (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3006 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3007 "fcnv,t,dbl,udw %1,%0"
3008 [(set_attr "type" "fpalu")
3009 (set_attr "length" "4")])
3011 ;;- arithmetic instructions
3013 (define_expand "adddi3"
3014 [(set (match_operand:DI 0 "register_operand" "")
3015 (plus:DI (match_operand:DI 1 "register_operand" "")
3016 (match_operand:DI 2 "arith11_operand" "")))]
3021 [(set (match_operand:DI 0 "register_operand" "=r")
3022 (plus:DI (match_operand:DI 1 "register_operand" "%r")
3023 (match_operand:DI 2 "arith11_operand" "rI")))]
3027 if (GET_CODE (operands[2]) == CONST_INT)
3029 if (INTVAL (operands[2]) >= 0)
3030 return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
3032 return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
3035 return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
3037 [(set_attr "type" "binary")
3038 (set_attr "length" "8")])
3041 [(set (match_operand:SI 0 "register_operand" "=r")
3042 (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3043 (match_operand:SI 2 "register_operand" "r")))]
3046 [(set_attr "type" "binary")
3047 (set_attr "length" "4")])
3049 ;; define_splits to optimize cases of adding a constant integer
3050 ;; to a register when the constant does not fit in 14 bits. */
3052 [(set (match_operand:SI 0 "register_operand" "")
3053 (plus:SI (match_operand:SI 1 "register_operand" "")
3054 (match_operand:SI 2 "const_int_operand" "")))
3055 (clobber (match_operand:SI 4 "register_operand" ""))]
3056 "! cint_ok_for_move (INTVAL (operands[2]))
3057 && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
3058 [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
3059 (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
3062 int val = INTVAL (operands[2]);
3063 int low = (val < 0) ? -0x2000 : 0x1fff;
3064 int rest = val - low;
3066 operands[2] = GEN_INT (rest);
3067 operands[3] = GEN_INT (low);
3071 [(set (match_operand:SI 0 "register_operand" "")
3072 (plus:SI (match_operand:SI 1 "register_operand" "")
3073 (match_operand:SI 2 "const_int_operand" "")))
3074 (clobber (match_operand:SI 4 "register_operand" ""))]
3075 "! cint_ok_for_move (INTVAL (operands[2]))"
3076 [(set (match_dup 4) (match_dup 2))
3077 (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
3081 HOST_WIDE_INT intval = INTVAL (operands[2]);
3083 /* Try dividing the constant by 2, then 4, and finally 8 to see
3084 if we can get a constant which can be loaded into a register
3085 in a single instruction (cint_ok_for_move).
3087 If that fails, try to negate the constant and subtract it
3088 from our input operand. */
3089 if (intval % 2 == 0 && cint_ok_for_move (intval / 2))
3091 operands[2] = GEN_INT (intval / 2);
3092 operands[3] = GEN_INT (2);
3094 else if (intval % 4 == 0 && cint_ok_for_move (intval / 4))
3096 operands[2] = GEN_INT (intval / 4);
3097 operands[3] = GEN_INT (4);
3099 else if (intval % 8 == 0 && cint_ok_for_move (intval / 8))
3101 operands[2] = GEN_INT (intval / 8);
3102 operands[3] = GEN_INT (8);
3104 else if (cint_ok_for_move (-intval))
3106 emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval)));
3107 emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
3114 (define_insn "addsi3"
3115 [(set (match_operand:SI 0 "register_operand" "=r,r")
3116 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3117 (match_operand:SI 2 "arith_operand" "r,J")))]
3120 {addl|add,l} %1,%2,%0
3122 [(set_attr "type" "binary,binary")
3123 (set_attr "pa_combine_type" "addmove")
3124 (set_attr "length" "4,4")])
3126 (define_expand "subdi3"
3127 [(set (match_operand:DI 0 "register_operand" "")
3128 (minus:DI (match_operand:DI 1 "register_operand" "")
3129 (match_operand:DI 2 "register_operand" "")))]
3134 [(set (match_operand:DI 0 "register_operand" "=r")
3135 (minus:DI (match_operand:DI 1 "register_operand" "r")
3136 (match_operand:DI 2 "register_operand" "r")))]
3138 "sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0"
3139 [(set_attr "type" "binary")
3140 (set_attr "length" "8")])
3142 (define_expand "subsi3"
3143 [(set (match_operand:SI 0 "register_operand" "")
3144 (minus:SI (match_operand:SI 1 "arith11_operand" "")
3145 (match_operand:SI 2 "register_operand" "")))]
3150 [(set (match_operand:SI 0 "register_operand" "=r,r")
3151 (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
3152 (match_operand:SI 2 "register_operand" "r,r")))]
3157 [(set_attr "type" "binary,binary")
3158 (set_attr "length" "4,4")])
3161 [(set (match_operand:SI 0 "register_operand" "=r,r,q")
3162 (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,S")
3163 (match_operand:SI 2 "register_operand" "r,r,r")))]
3169 [(set_attr "type" "binary,binary,move")
3170 (set_attr "length" "4,4,4")])
3172 ;; Clobbering a "register_operand" instead of a match_scratch
3173 ;; in operand3 of millicode calls avoids spilling %r1 and
3174 ;; produces better code.
3176 ;; The mulsi3 insns set up registers for the millicode call.
3177 (define_expand "mulsi3"
3178 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3179 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3180 (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
3181 (clobber (match_dup 3))
3182 (clobber (reg:SI 26))
3183 (clobber (reg:SI 25))
3184 (clobber (reg:SI 31))])
3185 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3189 if (TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT)
3191 rtx scratch = gen_reg_rtx (DImode);
3192 operands[1] = force_reg (SImode, operands[1]);
3193 operands[2] = force_reg (SImode, operands[2]);
3194 emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
3195 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3196 gen_rtx_SUBREG (SImode, scratch, 1)));
3199 operands[3] = gen_reg_rtx (SImode);
3202 (define_insn "umulsidi3"
3203 [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3204 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3205 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
3206 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
3208 [(set_attr "type" "fpmuldbl")
3209 (set_attr "length" "4")])
3212 [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3213 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3214 (match_operand:DI 2 "uint32_operand" "f")))]
3215 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
3217 [(set_attr "type" "fpmuldbl")
3218 (set_attr "length" "4")])
3221 [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
3222 (clobber (match_operand:SI 0 "register_operand" "=a"))
3223 (clobber (reg:SI 26))
3224 (clobber (reg:SI 25))
3225 (clobber (reg:SI 31))]
3227 "* return output_mul_insn (0, insn);"
3228 [(set_attr "type" "milli")
3229 (set (attr "length")
3231 ;; Target (or stub) within reach
3232 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3234 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3239 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3243 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3244 ;; same as NO_SPACE_REGS code
3245 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3247 (eq (symbol_ref "flag_pic")
3251 ;; Out of range and either PIC or PORTABLE_RUNTIME
3254 ;;; Division and mod.
3255 (define_expand "divsi3"
3256 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3257 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3258 (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
3259 (clobber (match_dup 3))
3260 (clobber (match_dup 4))
3261 (clobber (reg:SI 26))
3262 (clobber (reg:SI 25))
3263 (clobber (reg:SI 31))])
3264 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3268 operands[3] = gen_reg_rtx (SImode);
3269 operands[4] = gen_reg_rtx (SImode);
3270 if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
3276 (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
3277 (clobber (match_operand:SI 1 "register_operand" "=a"))
3278 (clobber (match_operand:SI 2 "register_operand" "=&r"))
3279 (clobber (reg:SI 26))
3280 (clobber (reg:SI 25))
3281 (clobber (reg:SI 31))]
3284 return output_div_insn (operands, 0, insn);"
3285 [(set_attr "type" "milli")
3286 (set (attr "length")
3288 ;; Target (or stub) within reach
3289 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3291 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3296 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3300 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3301 ;; same as NO_SPACE_REGS code
3302 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3304 (eq (symbol_ref "flag_pic")
3308 ;; Out of range and either PIC or PORTABLE_RUNTIME
3311 (define_expand "udivsi3"
3312 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3313 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3314 (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
3315 (clobber (match_dup 3))
3316 (clobber (match_dup 4))
3317 (clobber (reg:SI 26))
3318 (clobber (reg:SI 25))
3319 (clobber (reg:SI 31))])
3320 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3324 operands[3] = gen_reg_rtx (SImode);
3325 operands[4] = gen_reg_rtx (SImode);
3326 if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
3332 (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
3333 (clobber (match_operand:SI 1 "register_operand" "=a"))
3334 (clobber (match_operand:SI 2 "register_operand" "=&r"))
3335 (clobber (reg:SI 26))
3336 (clobber (reg:SI 25))
3337 (clobber (reg:SI 31))]
3340 return output_div_insn (operands, 1, insn);"
3341 [(set_attr "type" "milli")
3342 (set (attr "length")
3344 ;; Target (or stub) within reach
3345 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3347 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3352 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3356 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3357 ;; same as NO_SPACE_REGS code
3358 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3360 (eq (symbol_ref "flag_pic")
3364 ;; Out of range and either PIC or PORTABLE_RUNTIME
3367 (define_expand "modsi3"
3368 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3369 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3370 (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
3371 (clobber (match_dup 3))
3372 (clobber (match_dup 4))
3373 (clobber (reg:SI 26))
3374 (clobber (reg:SI 25))
3375 (clobber (reg:SI 31))])
3376 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3380 operands[4] = gen_reg_rtx (SImode);
3381 operands[3] = gen_reg_rtx (SImode);
3385 [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
3386 (clobber (match_operand:SI 0 "register_operand" "=a"))
3387 (clobber (match_operand:SI 2 "register_operand" "=&r"))
3388 (clobber (reg:SI 26))
3389 (clobber (reg:SI 25))
3390 (clobber (reg:SI 31))]
3393 return output_mod_insn (0, insn);"
3394 [(set_attr "type" "milli")
3395 (set (attr "length")
3397 ;; Target (or stub) within reach
3398 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3400 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3405 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3409 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3410 ;; same as NO_SPACE_REGS code
3411 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3413 (eq (symbol_ref "flag_pic")
3417 ;; Out of range and either PIC or PORTABLE_RUNTIME
3420 (define_expand "umodsi3"
3421 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3422 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3423 (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
3424 (clobber (match_dup 3))
3425 (clobber (match_dup 4))
3426 (clobber (reg:SI 26))
3427 (clobber (reg:SI 25))
3428 (clobber (reg:SI 31))])
3429 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3433 operands[4] = gen_reg_rtx (SImode);
3434 operands[3] = gen_reg_rtx (SImode);
3438 [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
3439 (clobber (match_operand:SI 0 "register_operand" "=a"))
3440 (clobber (match_operand:SI 2 "register_operand" "=&r"))
3441 (clobber (reg:SI 26))
3442 (clobber (reg:SI 25))
3443 (clobber (reg:SI 31))]
3446 return output_mod_insn (1, insn);"
3447 [(set_attr "type" "milli")
3448 (set (attr "length")
3450 ;; Target (or stub) within reach
3451 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3453 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3458 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3462 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3463 ;; same as NO_SPACE_REGS code
3464 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3466 (eq (symbol_ref "flag_pic")
3470 ;; Out of range and either PIC or PORTABLE_RUNTIME
3473 ;;- and instructions
3474 ;; We define DImode `and` so with DImode `not` we can get
3475 ;; DImode `andn`. Other combinations are possible.
3477 (define_expand "anddi3"
3478 [(set (match_operand:DI 0 "register_operand" "")
3479 (and:DI (match_operand:DI 1 "arith_double_operand" "")
3480 (match_operand:DI 2 "arith_double_operand" "")))]
3484 if (! register_operand (operands[1], DImode)
3485 || ! register_operand (operands[2], DImode))
3486 /* Let GCC break this into word-at-a-time operations. */
3491 [(set (match_operand:DI 0 "register_operand" "=r")
3492 (and:DI (match_operand:DI 1 "register_operand" "%r")
3493 (match_operand:DI 2 "register_operand" "r")))]
3495 "and %1,%2,%0\;and %R1,%R2,%R0"
3496 [(set_attr "type" "binary")
3497 (set_attr "length" "8")])
3499 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
3500 ; constant with ldil;ldo.
3501 (define_insn "andsi3"
3502 [(set (match_operand:SI 0 "register_operand" "=r,r")
3503 (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
3504 (match_operand:SI 2 "and_operand" "rO,P")))]
3506 "* return output_and (operands); "
3507 [(set_attr "type" "binary,shift")
3508 (set_attr "length" "4,4")])
3511 [(set (match_operand:DI 0 "register_operand" "=r")
3512 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3513 (match_operand:DI 2 "register_operand" "r")))]
3515 "andcm %2,%1,%0\;andcm %R2,%R1,%R0"
3516 [(set_attr "type" "binary")
3517 (set_attr "length" "8")])
3520 [(set (match_operand:SI 0 "register_operand" "=r")
3521 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3522 (match_operand:SI 2 "register_operand" "r")))]
3525 [(set_attr "type" "binary")
3526 (set_attr "length" "4")])
3528 (define_expand "iordi3"
3529 [(set (match_operand:DI 0 "register_operand" "")
3530 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
3531 (match_operand:DI 2 "arith_double_operand" "")))]
3535 if (! register_operand (operands[1], DImode)
3536 || ! register_operand (operands[2], DImode))
3537 /* Let GCC break this into word-at-a-time operations. */
3542 [(set (match_operand:DI 0 "register_operand" "=r")
3543 (ior:DI (match_operand:DI 1 "register_operand" "%r")
3544 (match_operand:DI 2 "register_operand" "r")))]
3546 "or %1,%2,%0\;or %R1,%R2,%R0"
3547 [(set_attr "type" "binary")
3548 (set_attr "length" "8")])
3550 ;; Need a define_expand because we've run out of CONST_OK... characters.
3551 (define_expand "iorsi3"
3552 [(set (match_operand:SI 0 "register_operand" "")
3553 (ior:SI (match_operand:SI 1 "register_operand" "")
3554 (match_operand:SI 2 "arith32_operand" "")))]
3558 if (! (ior_operand (operands[2], SImode)
3559 || register_operand (operands[2], SImode)))
3560 operands[2] = force_reg (SImode, operands[2]);
3564 [(set (match_operand:SI 0 "register_operand" "=r,r")
3565 (ior:SI (match_operand:SI 1 "register_operand" "0,0")
3566 (match_operand:SI 2 "ior_operand" "M,i")))]
3568 "* return output_ior (operands); "
3569 [(set_attr "type" "binary,shift")
3570 (set_attr "length" "4,4")])
3573 [(set (match_operand:SI 0 "register_operand" "=r")
3574 (ior:SI (match_operand:SI 1 "register_operand" "%r")
3575 (match_operand:SI 2 "register_operand" "r")))]
3578 [(set_attr "type" "binary")
3579 (set_attr "length" "4")])
3581 (define_expand "xordi3"
3582 [(set (match_operand:DI 0 "register_operand" "")
3583 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
3584 (match_operand:DI 2 "arith_double_operand" "")))]
3588 if (! register_operand (operands[1], DImode)
3589 || ! register_operand (operands[2], DImode))
3590 /* Let GCC break this into word-at-a-time operations. */
3595 [(set (match_operand:DI 0 "register_operand" "=r")
3596 (xor:DI (match_operand:DI 1 "register_operand" "%r")
3597 (match_operand:DI 2 "register_operand" "r")))]
3599 "xor %1,%2,%0\;xor %R1,%R2,%R0"
3600 [(set_attr "type" "binary")
3601 (set_attr "length" "8")])
3603 (define_insn "xorsi3"
3604 [(set (match_operand:SI 0 "register_operand" "=r")
3605 (xor:SI (match_operand:SI 1 "register_operand" "%r")
3606 (match_operand:SI 2 "register_operand" "r")))]
3609 [(set_attr "type" "binary")
3610 (set_attr "length" "4")])
3612 (define_expand "negdi2"
3613 [(set (match_operand:DI 0 "register_operand" "")
3614 (neg:DI (match_operand:DI 1 "register_operand" "")))]
3619 [(set (match_operand:DI 0 "register_operand" "=r")
3620 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
3622 "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
3623 [(set_attr "type" "unary")
3624 (set_attr "length" "8")])
3626 (define_insn "negsi2"
3627 [(set (match_operand:SI 0 "register_operand" "=r")
3628 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
3631 [(set_attr "type" "unary")
3632 (set_attr "length" "4")])
3634 (define_expand "one_cmpldi2"
3635 [(set (match_operand:DI 0 "register_operand" "")
3636 (not:DI (match_operand:DI 1 "arith_double_operand" "")))]
3640 if (! register_operand (operands[1], DImode))
3645 [(set (match_operand:DI 0 "register_operand" "=r")
3646 (not:DI (match_operand:DI 1 "register_operand" "r")))]
3648 "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
3649 [(set_attr "type" "unary")
3650 (set_attr "length" "8")])
3652 (define_insn "one_cmplsi2"
3653 [(set (match_operand:SI 0 "register_operand" "=r")
3654 (not:SI (match_operand:SI 1 "register_operand" "r")))]
3657 [(set_attr "type" "unary")
3658 (set_attr "length" "4")])
3660 ;; Floating point arithmetic instructions.
3662 (define_insn "adddf3"
3663 [(set (match_operand:DF 0 "register_operand" "=f")
3664 (plus:DF (match_operand:DF 1 "register_operand" "f")
3665 (match_operand:DF 2 "register_operand" "f")))]
3666 "! TARGET_SOFT_FLOAT"
3668 [(set_attr "type" "fpalu")
3669 (set_attr "pa_combine_type" "faddsub")
3670 (set_attr "length" "4")])
3672 (define_insn "addsf3"
3673 [(set (match_operand:SF 0 "register_operand" "=f")
3674 (plus:SF (match_operand:SF 1 "register_operand" "f")
3675 (match_operand:SF 2 "register_operand" "f")))]
3676 "! TARGET_SOFT_FLOAT"
3678 [(set_attr "type" "fpalu")
3679 (set_attr "pa_combine_type" "faddsub")
3680 (set_attr "length" "4")])
3682 (define_insn "subdf3"
3683 [(set (match_operand:DF 0 "register_operand" "=f")
3684 (minus:DF (match_operand:DF 1 "register_operand" "f")
3685 (match_operand:DF 2 "register_operand" "f")))]
3686 "! TARGET_SOFT_FLOAT"
3688 [(set_attr "type" "fpalu")
3689 (set_attr "pa_combine_type" "faddsub")
3690 (set_attr "length" "4")])
3692 (define_insn "subsf3"
3693 [(set (match_operand:SF 0 "register_operand" "=f")
3694 (minus:SF (match_operand:SF 1 "register_operand" "f")
3695 (match_operand:SF 2 "register_operand" "f")))]
3696 "! TARGET_SOFT_FLOAT"
3698 [(set_attr "type" "fpalu")
3699 (set_attr "pa_combine_type" "faddsub")
3700 (set_attr "length" "4")])
3702 (define_insn "muldf3"
3703 [(set (match_operand:DF 0 "register_operand" "=f")
3704 (mult:DF (match_operand:DF 1 "register_operand" "f")
3705 (match_operand:DF 2 "register_operand" "f")))]
3706 "! TARGET_SOFT_FLOAT"
3708 [(set_attr "type" "fpmuldbl")
3709 (set_attr "pa_combine_type" "fmpy")
3710 (set_attr "length" "4")])
3712 (define_insn "mulsf3"
3713 [(set (match_operand:SF 0 "register_operand" "=f")
3714 (mult:SF (match_operand:SF 1 "register_operand" "f")
3715 (match_operand:SF 2 "register_operand" "f")))]
3716 "! TARGET_SOFT_FLOAT"
3718 [(set_attr "type" "fpmulsgl")
3719 (set_attr "pa_combine_type" "fmpy")
3720 (set_attr "length" "4")])
3722 (define_insn "divdf3"
3723 [(set (match_operand:DF 0 "register_operand" "=f")
3724 (div:DF (match_operand:DF 1 "register_operand" "f")
3725 (match_operand:DF 2 "register_operand" "f")))]
3726 "! TARGET_SOFT_FLOAT"
3728 [(set_attr "type" "fpdivdbl")
3729 (set_attr "length" "4")])
3731 (define_insn "divsf3"
3732 [(set (match_operand:SF 0 "register_operand" "=f")
3733 (div:SF (match_operand:SF 1 "register_operand" "f")
3734 (match_operand:SF 2 "register_operand" "f")))]
3735 "! TARGET_SOFT_FLOAT"
3737 [(set_attr "type" "fpdivsgl")
3738 (set_attr "length" "4")])
3740 (define_insn "negdf2"
3741 [(set (match_operand:DF 0 "register_operand" "=f")
3742 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3743 "! TARGET_SOFT_FLOAT"
3747 return \"fneg,dbl %1,%0\";
3749 return \"fsub,dbl %%fr0,%1,%0\";
3751 [(set_attr "type" "fpalu")
3752 (set_attr "length" "4")])
3754 (define_insn "negsf2"
3755 [(set (match_operand:SF 0 "register_operand" "=f")
3756 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3757 "! TARGET_SOFT_FLOAT"
3761 return \"fneg,sgl %1,%0\";
3763 return \"fsub,sgl %%fr0,%1,%0\";
3765 [(set_attr "type" "fpalu")
3766 (set_attr "length" "4")])
3768 (define_insn "absdf2"
3769 [(set (match_operand:DF 0 "register_operand" "=f")
3770 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
3771 "! TARGET_SOFT_FLOAT"
3773 [(set_attr "type" "fpalu")
3774 (set_attr "length" "4")])
3776 (define_insn "abssf2"
3777 [(set (match_operand:SF 0 "register_operand" "=f")
3778 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
3779 "! TARGET_SOFT_FLOAT"
3781 [(set_attr "type" "fpalu")
3782 (set_attr "length" "4")])
3784 (define_insn "sqrtdf2"
3785 [(set (match_operand:DF 0 "register_operand" "=f")
3786 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
3787 "! TARGET_SOFT_FLOAT"
3789 [(set_attr "type" "fpsqrtdbl")
3790 (set_attr "length" "4")])
3792 (define_insn "sqrtsf2"
3793 [(set (match_operand:SF 0 "register_operand" "=f")
3794 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
3795 "! TARGET_SOFT_FLOAT"
3797 [(set_attr "type" "fpsqrtsgl")
3798 (set_attr "length" "4")])
3800 ;; PA 2.0 floating point instructions
3804 [(set (match_operand:DF 0 "register_operand" "=f")
3805 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
3806 (match_operand:DF 2 "register_operand" "f"))
3807 (match_operand:DF 3 "register_operand" "f")))]
3808 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3809 "fmpyfadd,dbl %1,%2,%3,%0"
3810 [(set_attr "type" "fpmuldbl")
3811 (set_attr "length" "4")])
3814 [(set (match_operand:DF 0 "register_operand" "=f")
3815 (plus:DF (match_operand:DF 1 "register_operand" "f")
3816 (mult:DF (match_operand:DF 2 "register_operand" "f")
3817 (match_operand:DF 3 "register_operand" "f"))))]
3818 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3819 "fmpyfadd,dbl %2,%3,%1,%0"
3820 [(set_attr "type" "fpmuldbl")
3821 (set_attr "length" "4")])
3824 [(set (match_operand:SF 0 "register_operand" "=f")
3825 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
3826 (match_operand:SF 2 "register_operand" "f"))
3827 (match_operand:SF 3 "register_operand" "f")))]
3828 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3829 "fmpyfadd,sgl %1,%2,%3,%0"
3830 [(set_attr "type" "fpmulsgl")
3831 (set_attr "length" "4")])
3834 [(set (match_operand:SF 0 "register_operand" "=f")
3835 (plus:SF (match_operand:SF 1 "register_operand" "f")
3836 (mult:SF (match_operand:SF 2 "register_operand" "f")
3837 (match_operand:SF 3 "register_operand" "f"))))]
3838 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3839 "fmpyfadd,sgl %2,%3,%1,%0"
3840 [(set_attr "type" "fpmulsgl")
3841 (set_attr "length" "4")])
3843 ; fmpynfadd patterns
3845 [(set (match_operand:DF 0 "register_operand" "=f")
3846 (minus:DF (match_operand:DF 1 "register_operand" "f")
3847 (mult:DF (match_operand:DF 2 "register_operand" "f")
3848 (match_operand:DF 3 "register_operand" "f"))))]
3849 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3850 "fmpynfadd,dbl %2,%3,%1,%0"
3851 [(set_attr "type" "fpmuldbl")
3852 (set_attr "length" "4")])
3855 [(set (match_operand:SF 0 "register_operand" "=f")
3856 (minus:SF (match_operand:SF 1 "register_operand" "f")
3857 (mult:SF (match_operand:SF 2 "register_operand" "f")
3858 (match_operand:SF 3 "register_operand" "f"))))]
3859 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3860 "fmpynfadd,sgl %2,%3,%1,%0"
3861 [(set_attr "type" "fpmulsgl")
3862 (set_attr "length" "4")])
3866 [(set (match_operand:DF 0 "register_operand" "=f")
3867 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
3868 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3870 [(set_attr "type" "fpalu")
3871 (set_attr "length" "4")])
3874 [(set (match_operand:SF 0 "register_operand" "=f")
3875 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
3876 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3878 [(set_attr "type" "fpalu")
3879 (set_attr "length" "4")])
3881 ;; Generating a fused multiply sequence is a win for this case as it will
3882 ;; reduce the latency for the fused case without impacting the plain
3885 ;; Similar possibilities exist for fnegabs, shadd and other insns which
3886 ;; perform two operations with the result of the first feeding the second.
3888 [(set (match_operand:DF 0 "register_operand" "=f")
3889 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
3890 (match_operand:DF 2 "register_operand" "f"))
3891 (match_operand:DF 3 "register_operand" "f")))
3892 (set (match_operand:DF 4 "register_operand" "=&f")
3893 (mult:DF (match_dup 1) (match_dup 2)))]
3894 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
3895 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
3896 || reg_overlap_mentioned_p (operands[4], operands[2])))"
3898 [(set_attr "type" "fpmuldbl")
3899 (set_attr "length" "8")])
3901 ;; We want to split this up during scheduling since we want both insns
3902 ;; to schedule independently.
3904 [(set (match_operand:DF 0 "register_operand" "=f")
3905 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
3906 (match_operand:DF 2 "register_operand" "f"))
3907 (match_operand:DF 3 "register_operand" "f")))
3908 (set (match_operand:DF 4 "register_operand" "=&f")
3909 (mult:DF (match_dup 1) (match_dup 2)))]
3910 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3911 [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
3912 (set (match_dup 0) (plus:DF (mult:DF (match_dup 1) (match_dup 2))
3917 [(set (match_operand:SF 0 "register_operand" "=f")
3918 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
3919 (match_operand:SF 2 "register_operand" "f"))
3920 (match_operand:SF 3 "register_operand" "f")))
3921 (set (match_operand:SF 4 "register_operand" "=&f")
3922 (mult:SF (match_dup 1) (match_dup 2)))]
3923 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
3924 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
3925 || reg_overlap_mentioned_p (operands[4], operands[2])))"
3927 [(set_attr "type" "fpmuldbl")
3928 (set_attr "length" "8")])
3930 ;; We want to split this up during scheduling since we want both insns
3931 ;; to schedule independently.
3933 [(set (match_operand:SF 0 "register_operand" "=f")
3934 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
3935 (match_operand:SF 2 "register_operand" "f"))
3936 (match_operand:SF 3 "register_operand" "f")))
3937 (set (match_operand:SF 4 "register_operand" "=&f")
3938 (mult:SF (match_dup 1) (match_dup 2)))]
3939 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3940 [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
3941 (set (match_dup 0) (plus:SF (mult:SF (match_dup 1) (match_dup 2))
3945 ;; Negating a multiply can be faked by adding zero in a fused multiply-add
3948 [(set (match_operand:DF 0 "register_operand" "=f")
3949 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
3950 (match_operand:DF 2 "register_operand" "f"))))]
3951 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3952 "fmpynfadd,dbl %1,%2,%%fr0,%0"
3953 [(set_attr "type" "fpmuldbl")
3954 (set_attr "length" "4")])
3957 [(set (match_operand:SF 0 "register_operand" "=f")
3958 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
3959 (match_operand:SF 2 "register_operand" "f"))))]
3960 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3961 "fmpynfadd,sgl %1,%2,%%fr0,%0"
3962 [(set_attr "type" "fpmuldbl")
3963 (set_attr "length" "4")])
3966 [(set (match_operand:DF 0 "register_operand" "=f")
3967 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
3968 (match_operand:DF 2 "register_operand" "f"))))
3969 (set (match_operand:DF 3 "register_operand" "=&f")
3970 (mult:DF (match_dup 1) (match_dup 2)))]
3971 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
3972 && ! (reg_overlap_mentioned_p (operands[3], operands[1])
3973 || reg_overlap_mentioned_p (operands[3], operands[2])))"
3975 [(set_attr "type" "fpmuldbl")
3976 (set_attr "length" "8")])
3979 [(set (match_operand:DF 0 "register_operand" "=f")
3980 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
3981 (match_operand:DF 2 "register_operand" "f"))))
3982 (set (match_operand:DF 3 "register_operand" "=&f")
3983 (mult:DF (match_dup 1) (match_dup 2)))]
3984 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3985 [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
3986 (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
3990 [(set (match_operand:SF 0 "register_operand" "=f")
3991 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
3992 (match_operand:SF 2 "register_operand" "f"))))
3993 (set (match_operand:SF 3 "register_operand" "=&f")
3994 (mult:SF (match_dup 1) (match_dup 2)))]
3995 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
3996 && ! (reg_overlap_mentioned_p (operands[3], operands[1])
3997 || reg_overlap_mentioned_p (operands[3], operands[2])))"
3999 [(set_attr "type" "fpmuldbl")
4000 (set_attr "length" "8")])
4003 [(set (match_operand:SF 0 "register_operand" "=f")
4004 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4005 (match_operand:SF 2 "register_operand" "f"))))
4006 (set (match_operand:SF 3 "register_operand" "=&f")
4007 (mult:SF (match_dup 1) (match_dup 2)))]
4008 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4009 [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
4010 (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
4013 ;; Now fused multiplies with the result of the multiply negated.
4015 [(set (match_operand:DF 0 "register_operand" "=f")
4016 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4017 (match_operand:DF 2 "register_operand" "f")))
4018 (match_operand:DF 3 "register_operand" "f")))]
4019 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4020 "fmpynfadd,dbl %1,%2,%3,%0"
4021 [(set_attr "type" "fpmuldbl")
4022 (set_attr "length" "4")])
4025 [(set (match_operand:SF 0 "register_operand" "=f")
4026 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4027 (match_operand:SF 2 "register_operand" "f")))
4028 (match_operand:SF 3 "register_operand" "f")))]
4029 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4030 "fmpynfadd,sgl %1,%2,%3,%0"
4031 [(set_attr "type" "fpmuldbl")
4032 (set_attr "length" "4")])
4035 [(set (match_operand:DF 0 "register_operand" "=f")
4036 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4037 (match_operand:DF 2 "register_operand" "f")))
4038 (match_operand:DF 3 "register_operand" "f")))
4039 (set (match_operand:DF 4 "register_operand" "=&f")
4040 (mult:DF (match_dup 1) (match_dup 2)))]
4041 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4042 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4043 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4045 [(set_attr "type" "fpmuldbl")
4046 (set_attr "length" "8")])
4049 [(set (match_operand:DF 0 "register_operand" "=f")
4050 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4051 (match_operand:DF 2 "register_operand" "f")))
4052 (match_operand:DF 3 "register_operand" "f")))
4053 (set (match_operand:DF 4 "register_operand" "=&f")
4054 (mult:DF (match_dup 1) (match_dup 2)))]
4055 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4056 [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
4057 (set (match_dup 0) (plus:DF (neg:DF (mult:DF (match_dup 1) (match_dup 2)))
4062 [(set (match_operand:SF 0 "register_operand" "=f")
4063 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4064 (match_operand:SF 2 "register_operand" "f")))
4065 (match_operand:SF 3 "register_operand" "f")))
4066 (set (match_operand:SF 4 "register_operand" "=&f")
4067 (mult:SF (match_dup 1) (match_dup 2)))]
4068 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4069 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4070 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4072 [(set_attr "type" "fpmuldbl")
4073 (set_attr "length" "8")])
4076 [(set (match_operand:SF 0 "register_operand" "=f")
4077 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4078 (match_operand:SF 2 "register_operand" "f")))
4079 (match_operand:SF 3 "register_operand" "f")))
4080 (set (match_operand:SF 4 "register_operand" "=&f")
4081 (mult:SF (match_dup 1) (match_dup 2)))]
4082 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4083 [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
4084 (set (match_dup 0) (plus:SF (neg:SF (mult:SF (match_dup 1) (match_dup 2)))
4089 [(set (match_operand:DF 0 "register_operand" "=f")
4090 (minus:DF (match_operand:DF 3 "register_operand" "f")
4091 (mult:DF (match_operand:DF 1 "register_operand" "f")
4092 (match_operand:DF 2 "register_operand" "f"))))
4093 (set (match_operand:DF 4 "register_operand" "=&f")
4094 (mult:DF (match_dup 1) (match_dup 2)))]
4095 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4096 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4097 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4099 [(set_attr "type" "fpmuldbl")
4100 (set_attr "length" "8")])
4103 [(set (match_operand:DF 0 "register_operand" "=f")
4104 (minus:DF (match_operand:DF 3 "register_operand" "f")
4105 (mult:DF (match_operand:DF 1 "register_operand" "f")
4106 (match_operand:DF 2 "register_operand" "f"))))
4107 (set (match_operand:DF 4 "register_operand" "=&f")
4108 (mult:DF (match_dup 1) (match_dup 2)))]
4109 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4110 [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
4111 (set (match_dup 0) (minus:DF (match_dup 3)
4112 (mult:DF (match_dup 1) (match_dup 2))))]
4116 [(set (match_operand:SF 0 "register_operand" "=f")
4117 (minus:SF (match_operand:SF 3 "register_operand" "f")
4118 (mult:SF (match_operand:SF 1 "register_operand" "f")
4119 (match_operand:SF 2 "register_operand" "f"))))
4120 (set (match_operand:SF 4 "register_operand" "=&f")
4121 (mult:SF (match_dup 1) (match_dup 2)))]
4122 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4123 && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4124 || reg_overlap_mentioned_p (operands[4], operands[2])))"
4126 [(set_attr "type" "fpmuldbl")
4127 (set_attr "length" "8")])
4130 [(set (match_operand:SF 0 "register_operand" "=f")
4131 (minus:SF (match_operand:SF 3 "register_operand" "f")
4132 (mult:SF (match_operand:SF 1 "register_operand" "f")
4133 (match_operand:SF 2 "register_operand" "f"))))
4134 (set (match_operand:SF 4 "register_operand" "=&f")
4135 (mult:SF (match_dup 1) (match_dup 2)))]
4136 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4137 [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
4138 (set (match_dup 0) (minus:SF (match_dup 3)
4139 (mult:SF (match_dup 1) (match_dup 2))))]
4143 [(set (match_operand:DF 0 "register_operand" "=f")
4144 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
4145 (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
4146 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4147 && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
4149 [(set_attr "type" "fpalu")
4150 (set_attr "length" "8")])
4153 [(set (match_operand:DF 0 "register_operand" "=f")
4154 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
4155 (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
4156 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4157 [(set (match_dup 2) (abs:DF (match_dup 1)))
4158 (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
4162 [(set (match_operand:SF 0 "register_operand" "=f")
4163 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
4164 (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
4165 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4166 && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
4168 [(set_attr "type" "fpalu")
4169 (set_attr "length" "8")])
4172 [(set (match_operand:SF 0 "register_operand" "=f")
4173 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
4174 (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
4175 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4176 [(set (match_dup 2) (abs:SF (match_dup 1)))
4177 (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
4180 ;;- Shift instructions
4182 ;; Optimized special case of shifting.
4185 [(set (match_operand:SI 0 "register_operand" "=r")
4186 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4190 [(set_attr "type" "load")
4191 (set_attr "length" "4")])
4194 [(set (match_operand:SI 0 "register_operand" "=r")
4195 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4199 [(set_attr "type" "load")
4200 (set_attr "length" "4")])
4203 [(set (match_operand:SI 0 "register_operand" "=r")
4204 (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
4205 (match_operand:SI 3 "shadd_operand" ""))
4206 (match_operand:SI 1 "register_operand" "r")))]
4208 "{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0} "
4209 [(set_attr "type" "binary")
4210 (set_attr "length" "4")])
4212 ;; This anonymous pattern and splitter wins because it reduces the latency
4213 ;; of the shadd sequence without increasing the latency of the shift.
4215 ;; We want to make sure and split up the operations for the scheduler since
4216 ;; these instructions can (and should) schedule independently.
4218 ;; It would be clearer if combine used the same operator for both expressions,
4219 ;; it's somewhat confusing to have a mult in ine operation and an ashift
4222 ;; If this pattern is not split before register allocation, then we must expose
4223 ;; the fact that operand 4 is set before operands 1, 2 and 3 have been read.
4225 [(set (match_operand:SI 0 "register_operand" "=r")
4226 (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
4227 (match_operand:SI 3 "shadd_operand" ""))
4228 (match_operand:SI 1 "register_operand" "r")))
4229 (set (match_operand:SI 4 "register_operand" "=&r")
4230 (ashift:SI (match_dup 2)
4231 (match_operand:SI 5 "const_int_operand" "i")))]
4232 "(INTVAL (operands[5]) == exact_log2 (INTVAL (operands[3]))
4233 && ! (reg_overlap_mentioned_p (operands[4], operands[2])))"
4235 [(set_attr "type" "binary")
4236 (set_attr "length" "8")])
4239 [(set (match_operand:SI 0 "register_operand" "=r")
4240 (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
4241 (match_operand:SI 3 "shadd_operand" ""))
4242 (match_operand:SI 1 "register_operand" "r")))
4243 (set (match_operand:SI 4 "register_operand" "=&r")
4244 (ashift:SI (match_dup 2)
4245 (match_operand:SI 5 "const_int_operand" "i")))]
4246 "INTVAL (operands[5]) == exact_log2 (INTVAL (operands[3]))"
4247 [(set (match_dup 4) (ashift:SI (match_dup 2) (match_dup 5)))
4248 (set (match_dup 0) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
4252 (define_expand "ashlsi3"
4253 [(set (match_operand:SI 0 "register_operand" "")
4254 (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
4255 (match_operand:SI 2 "arith32_operand" "")))]
4259 if (GET_CODE (operands[2]) != CONST_INT)
4261 rtx temp = gen_reg_rtx (SImode);
4262 emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
4263 if (GET_CODE (operands[1]) == CONST_INT)
4264 emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
4266 emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
4269 /* Make sure both inputs are not constants,
4270 there are no patterns for that. */
4271 operands[1] = force_reg (SImode, operands[1]);
4275 [(set (match_operand:SI 0 "register_operand" "=r")
4276 (ashift:SI (match_operand:SI 1 "register_operand" "r")
4277 (match_operand:SI 2 "const_int_operand" "n")))]
4279 "{zdep|depw,z} %1,%P2,%L2,%0"
4280 [(set_attr "type" "shift")
4281 (set_attr "length" "4")])
4283 ; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
4284 ; Doing it like this makes slightly better code since reload can
4285 ; replace a register with a known value in range -16..15 with a
4286 ; constant. Ideally, we would like to merge zvdep32 and zvdep_imm32,
4287 ; but since we have no more CONST_OK... characters, that is not
4289 (define_insn "zvdep32"
4290 [(set (match_operand:SI 0 "register_operand" "=r,r")
4291 (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
4292 (minus:SI (const_int 31)
4293 (match_operand:SI 2 "register_operand" "q,q"))))]
4296 {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
4297 {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
4298 [(set_attr "type" "shift,shift")
4299 (set_attr "length" "4,4")])
4301 (define_insn "zvdep_imm32"
4302 [(set (match_operand:SI 0 "register_operand" "=r")
4303 (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
4304 (minus:SI (const_int 31)
4305 (match_operand:SI 2 "register_operand" "q"))))]
4309 int x = INTVAL (operands[1]);
4310 operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
4311 operands[1] = GEN_INT ((x & 0xf) - 0x10);
4312 return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
4314 [(set_attr "type" "shift")
4315 (set_attr "length" "4")])
4317 (define_insn "vdepi_ior"
4318 [(set (match_operand:SI 0 "register_operand" "=r")
4319 (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
4320 (minus:SI (const_int 31)
4321 (match_operand:SI 2 "register_operand" "q")))
4322 (match_operand:SI 3 "register_operand" "0")))]
4323 ; accept ...0001...1, can this be generalized?
4324 "exact_log2 (INTVAL (operands[1]) + 1) >= 0"
4327 int x = INTVAL (operands[1]);
4328 operands[2] = GEN_INT (exact_log2 (x + 1));
4329 return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
4331 [(set_attr "type" "shift")
4332 (set_attr "length" "4")])
4334 (define_insn "vdepi_and"
4335 [(set (match_operand:SI 0 "register_operand" "=r")
4336 (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
4337 (minus:SI (const_int 31)
4338 (match_operand:SI 2 "register_operand" "q")))
4339 (match_operand:SI 3 "register_operand" "0")))]
4340 ; this can be generalized...!
4341 "INTVAL (operands[1]) == -2"
4344 int x = INTVAL (operands[1]);
4345 operands[2] = GEN_INT (exact_log2 ((~x) + 1));
4346 return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
4348 [(set_attr "type" "shift")
4349 (set_attr "length" "4")])
4351 (define_expand "ashrsi3"
4352 [(set (match_operand:SI 0 "register_operand" "")
4353 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
4354 (match_operand:SI 2 "arith32_operand" "")))]
4358 if (GET_CODE (operands[2]) != CONST_INT)
4360 rtx temp = gen_reg_rtx (SImode);
4361 emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
4362 emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
4368 [(set (match_operand:SI 0 "register_operand" "=r")
4369 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
4370 (match_operand:SI 2 "const_int_operand" "n")))]
4372 "{extrs|extrw,s} %1,%P2,%L2,%0"
4373 [(set_attr "type" "shift")
4374 (set_attr "length" "4")])
4376 (define_insn "vextrs32"
4377 [(set (match_operand:SI 0 "register_operand" "=r")
4378 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
4379 (minus:SI (const_int 31)
4380 (match_operand:SI 2 "register_operand" "q"))))]
4382 "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
4383 [(set_attr "type" "shift")
4384 (set_attr "length" "4")])
4386 (define_insn "lshrsi3"
4387 [(set (match_operand:SI 0 "register_operand" "=r,r")
4388 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
4389 (match_operand:SI 2 "arith32_operand" "q,n")))]
4392 {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
4393 {extru|extrw,u} %1,%P2,%L2,%0"
4394 [(set_attr "type" "shift")
4395 (set_attr "length" "4")])
4397 (define_insn "rotrsi3"
4398 [(set (match_operand:SI 0 "register_operand" "=r,r")
4399 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
4400 (match_operand:SI 2 "arith32_operand" "q,n")))]
4404 if (GET_CODE (operands[2]) == CONST_INT)
4406 operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
4407 return \"{shd|shrpw} %1,%1,%2,%0\";
4410 return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
4412 [(set_attr "type" "shift")
4413 (set_attr "length" "4")])
4415 (define_expand "rotlsi3"
4416 [(set (match_operand:SI 0 "register_operand" "")
4417 (rotate:SI (match_operand:SI 1 "register_operand" "")
4418 (match_operand:SI 2 "arith32_operand" "")))]
4422 if (GET_CODE (operands[2]) != CONST_INT)
4424 rtx temp = gen_reg_rtx (SImode);
4425 emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
4426 emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
4429 /* Else expand normally. */
4433 [(set (match_operand:SI 0 "register_operand" "=r")
4434 (rotate:SI (match_operand:SI 1 "register_operand" "r")
4435 (match_operand:SI 2 "const_int_operand" "n")))]
4439 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
4440 return \"{shd|shrpw} %1,%1,%2,%0\";
4442 [(set_attr "type" "shift")
4443 (set_attr "length" "4")])
4446 [(set (match_operand:SI 0 "register_operand" "=r")
4447 (match_operator:SI 5 "plus_xor_ior_operator"
4448 [(ashift:SI (match_operand:SI 1 "register_operand" "r")
4449 (match_operand:SI 3 "const_int_operand" "n"))
4450 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
4451 (match_operand:SI 4 "const_int_operand" "n"))]))]
4452 "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
4453 "{shd|shrpw} %1,%2,%4,%0"
4454 [(set_attr "type" "shift")
4455 (set_attr "length" "4")])
4458 [(set (match_operand:SI 0 "register_operand" "=r")
4459 (match_operator:SI 5 "plus_xor_ior_operator"
4460 [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
4461 (match_operand:SI 4 "const_int_operand" "n"))
4462 (ashift:SI (match_operand:SI 1 "register_operand" "r")
4463 (match_operand:SI 3 "const_int_operand" "n"))]))]
4464 "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
4465 "{shd|shrpw} %1,%2,%4,%0"
4466 [(set_attr "type" "shift")
4467 (set_attr "length" "4")])
4470 [(set (match_operand:SI 0 "register_operand" "=r")
4471 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
4472 (match_operand:SI 2 "const_int_operand" ""))
4473 (match_operand:SI 3 "const_int_operand" "")))]
4474 "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) >= 0"
4477 int cnt = INTVAL (operands[2]) & 31;
4478 operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
4479 operands[2] = GEN_INT (31 - cnt);
4480 return \"{zdep|depw,z} %1,%2,%3,%0\";
4482 [(set_attr "type" "shift")
4483 (set_attr "length" "4")])
4485 ;; Unconditional and other jump instructions.
4487 (define_insn "return"
4489 "hppa_can_use_return_insn_p ()"
4493 return \"bve%* (%%r2)\";
4494 return \"bv%* %%r0(%%r2)\";
4496 [(set_attr "type" "branch")
4497 (set_attr "length" "4")])
4499 ;; Use a different pattern for functions which have non-trivial
4500 ;; epilogues so as not to confuse jump and reorg.
4501 (define_insn "return_internal"
4508 return \"bve%* (%%r2)\";
4509 return \"bv%* %%r0(%%r2)\";
4511 [(set_attr "type" "branch")
4512 (set_attr "length" "4")])
4514 (define_expand "prologue"
4517 "hppa_expand_prologue ();DONE;")
4519 (define_expand "epilogue"
4524 /* Try to use the trivial return first. Else use the full
4526 if (hppa_can_use_return_insn_p ())
4527 emit_jump_insn (gen_return ());
4530 hppa_expand_epilogue ();
4531 emit_jump_insn (gen_return_internal ());
4536 ;; Special because we use the value placed in %r2 by the bl instruction
4537 ;; from within its delay slot to set the value for the 2nd parameter to
4539 (define_insn "call_profiler"
4540 [(unspec_volatile [(const_int 0)] 0)
4541 (use (match_operand:SI 0 "const_int_operand" ""))]
4543 "{bl|b,l} _mcount,%%r2\;ldo %0(%%r2),%%r25"
4544 [(set_attr "type" "multi")
4545 (set_attr "length" "8")])
4547 (define_insn "blockage"
4548 [(unspec_volatile [(const_int 2)] 0)]
4551 [(set_attr "length" "0")])
4554 [(set (pc) (label_ref (match_operand 0 "" "")))]
4558 extern int optimize;
4560 if (GET_MODE (insn) == SImode)
4563 /* An unconditional branch which can reach its target. */
4564 if (get_attr_length (insn) != 24
4565 && get_attr_length (insn) != 16)
4568 /* An unconditional branch which can not reach its target.
4570 We need to be able to use %r1 as a scratch register; however,
4571 we can never be sure whether or not it's got a live value in
4572 it. Therefore, we must restore its original value after the
4575 To make matters worse, we don't have a stack slot which we
4576 can always clobber. sp-12/sp-16 shouldn't ever have a live
4577 value during a non-optimizing compilation, so we use those
4578 slots for now. We don't support very long branches when
4579 optimizing -- they should be quite rare when optimizing.
4581 Really the way to go long term is a register scavenger; goto
4582 the target of the jump and find a register which we can use
4583 as a scratch to hold the value in %r1. */
4585 /* We don't know how to register scavenge yet. */
4589 /* First store %r1 into the stack. */
4590 output_asm_insn (\"stw %%r1,-16(%%r30)\", operands);
4592 /* Now load the target address into %r1 and do an indirect jump
4593 to the value specified in %r1. Be careful to generate PIC
4598 xoperands[0] = operands[0];
4599 xoperands[1] = gen_label_rtx ();
4601 output_asm_insn (\"{bl|b,l} .+8,%%r1\\n\\taddil L'%l0-%l1,%%r1\",
4603 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
4604 CODE_LABEL_NUMBER (xoperands[1]));
4605 output_asm_insn (\"ldo R'%l0-%l1(%%r1),%%r1\\n\\tbv %%r0(%%r1)\",
4609 output_asm_insn (\"ldil L'%l0,%%r1\\n\\tbe R'%l0(%%sr4,%%r1)\", operands);;
4611 /* And restore the value of %r1 in the delay slot. We're not optimizing,
4612 so we know nothing else can be in the delay slot. */
4613 return \"ldw -16(%%r30),%%r1\";
4615 [(set_attr "type" "uncond_branch")
4616 (set_attr "pa_combine_type" "uncond_branch")
4617 (set (attr "length")
4618 (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 1))
4619 (if_then_else (lt (abs (minus (match_dup 0)
4620 (plus (pc) (const_int 8))))
4624 (ge (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
4626 (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
4631 ;; Subroutines of "casesi".
4632 ;; operand 0 is index
4633 ;; operand 1 is the minimum bound
4634 ;; operand 2 is the maximum bound - minimum bound + 1
4635 ;; operand 3 is CODE_LABEL for the table;
4636 ;; operand 4 is the CODE_LABEL to go to if index out of range.
4638 (define_expand "casesi"
4639 [(match_operand:SI 0 "general_operand" "")
4640 (match_operand:SI 1 "const_int_operand" "")
4641 (match_operand:SI 2 "const_int_operand" "")
4642 (match_operand 3 "" "")
4643 (match_operand 4 "" "")]
4647 if (GET_CODE (operands[0]) != REG)
4648 operands[0] = force_reg (SImode, operands[0]);
4650 if (operands[1] != const0_rtx)
4652 rtx reg = gen_reg_rtx (SImode);
4654 operands[1] = GEN_INT (-INTVAL (operands[1]));
4655 if (!INT_14_BITS (operands[1]))
4656 operands[1] = force_reg (SImode, operands[1]);
4657 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
4662 if (!INT_5_BITS (operands[2]))
4663 operands[2] = force_reg (SImode, operands[2]);
4665 emit_insn (gen_cmpsi (operands[0], operands[2]));
4666 emit_jump_insn (gen_bgtu (operands[4]));
4667 if (TARGET_BIG_SWITCH)
4669 rtx temp = gen_reg_rtx (SImode);
4670 emit_move_insn (temp, gen_rtx_PLUS (SImode, operands[0], operands[0]));
4673 emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
4677 (define_insn "casesi0"
4679 (mem:SI (plus:SI (pc)
4680 (match_operand:SI 0 "register_operand" "r")))
4681 (label_ref (match_operand 1 "" ""))))]
4684 [(set_attr "type" "multi")
4685 (set_attr "length" "8")])
4687 ;; Need nops for the calls because execution is supposed to continue
4688 ;; past; we don't want to nullify an instruction that we need.
4689 ;;- jump to subroutine
4691 (define_expand "call"
4692 [(parallel [(call (match_operand:SI 0 "" "")
4693 (match_operand 1 "" ""))
4694 (clobber (reg:SI 2))])]
4701 if (TARGET_PORTABLE_RUNTIME)
4702 op = force_reg (SImode, XEXP (operands[0], 0));
4704 op = XEXP (operands[0], 0);
4706 /* Use two different patterns for calls to explicitly named functions
4707 and calls through function pointers. This is necessary as these two
4708 types of calls use different calling conventions, and CSE might try
4709 to change the named call into an indirect call in some cases (using
4710 two patterns keeps CSE from performing this optimization). */
4711 if (GET_CODE (op) == SYMBOL_REF)
4712 call_insn = emit_call_insn (gen_call_internal_symref (op, operands[1]));
4715 rtx tmpreg = gen_rtx_REG (word_mode, 22);
4716 emit_move_insn (tmpreg, force_reg (word_mode, op));
4717 call_insn = emit_call_insn (gen_call_internal_reg (operands[1]));
4722 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
4723 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
4724 gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
4726 /* After each call we must restore the PIC register, even if it
4727 doesn't appear to be used.
4729 This will set regs_ever_live for the callee saved register we
4730 stored the PIC register in. */
4731 emit_move_insn (pic_offset_table_rtx,
4732 gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
4737 (define_insn "call_internal_symref"
4738 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
4739 (match_operand 1 "" "i"))
4740 (clobber (reg:SI 2))
4741 (use (const_int 0))]
4742 "! TARGET_PORTABLE_RUNTIME"
4745 output_arg_descriptor (insn);
4746 return output_call (insn, operands[0]);
4748 [(set_attr "type" "call")
4749 (set (attr "length")
4750 ;; If we're sure that we can either reach the target or that the
4751 ;; linker can use a long-branch stub, then the length is 4 bytes.
4753 ;; For long-calls the length will be either 52 bytes (non-pic)
4754 ;; or 68 bytes (pic). */
4755 ;; Else we have to use a long-call;
4756 (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
4759 (if_then_else (eq (symbol_ref "flag_pic")
4764 (define_insn "call_internal_reg"
4765 [(call (mem:SI (reg:SI 22))
4766 (match_operand 0 "" "i"))
4767 (clobber (reg:SI 2))
4768 (use (const_int 1))]
4774 /* First the special case for kernels, level 0 systems, etc. */
4775 if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
4776 return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
4778 /* Now the normal case -- we can reach $$dyncall directly or
4779 we're sure that we can get there via a long-branch stub.
4781 No need to check target flags as the length uniquely identifies
4782 the remaining cases. */
4783 if (get_attr_length (insn) == 8)
4784 return \".CALL\\tARGW0=GR\;{bl|b,l} $$dyncall,%%r31\;copy %%r31,%%r2\";
4786 /* Long millicode call, but we are not generating PIC or portable runtime
4788 if (get_attr_length (insn) == 12)
4789 return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
4791 /* Long millicode call for portable runtime. */
4792 if (get_attr_length (insn) == 20)
4793 return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr %%r0,%%r2\;bv,n %%r0(%%r31)\;nop\";
4795 /* If we're generating PIC code. */
4796 xoperands[0] = operands[0];
4797 xoperands[1] = gen_label_rtx ();
4798 output_asm_insn (\"{bl|b,l} .+8,%%r1\", xoperands);
4799 output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
4800 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
4801 CODE_LABEL_NUMBER (xoperands[1]));
4802 output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
4803 output_asm_insn (\"blr %%r0,%%r2\", xoperands);
4804 output_asm_insn (\"bv,n %%r0(%%r1)\\n\\tnop\", xoperands);
4807 [(set_attr "type" "dyncall")
4808 (set (attr "length")
4810 ;; First NO_SPACE_REGS
4811 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
4815 ;; Target (or stub) within reach
4816 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4818 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4822 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
4823 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4825 (eq (symbol_ref "flag_pic")
4829 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4833 ;; Out of range PIC case
4836 (define_expand "call_value"
4837 [(parallel [(set (match_operand 0 "" "")
4838 (call (match_operand:SI 1 "" "")
4839 (match_operand 2 "" "")))
4840 (clobber (reg:SI 2))])]
4847 if (TARGET_PORTABLE_RUNTIME)
4848 op = force_reg (word_mode, XEXP (operands[1], 0));
4850 op = XEXP (operands[1], 0);
4852 /* Use two different patterns for calls to explicitly named functions
4853 and calls through function pointers. This is necessary as these two
4854 types of calls use different calling conventions, and CSE might try
4855 to change the named call into an indirect call in some cases (using
4856 two patterns keeps CSE from performing this optimization). */
4857 if (GET_CODE (op) == SYMBOL_REF)
4858 call_insn = emit_call_insn (gen_call_value_internal_symref (operands[0],
4863 rtx tmpreg = gen_rtx_REG (word_mode, 22);
4864 emit_move_insn (tmpreg, force_reg (word_mode, op));
4865 call_insn = emit_call_insn (gen_call_value_internal_reg (operands[0],
4870 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
4871 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
4872 gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
4874 /* After each call we must restore the PIC register, even if it
4875 doesn't appear to be used.
4877 This will set regs_ever_live for the callee saved register we
4878 stored the PIC register in. */
4879 emit_move_insn (pic_offset_table_rtx,
4880 gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
4885 (define_insn "call_value_internal_symref"
4886 [(set (match_operand 0 "" "=rf")
4887 (call (mem:SI (match_operand 1 "call_operand_address" ""))
4888 (match_operand 2 "" "i")))
4889 (clobber (reg:SI 2))
4890 (use (const_int 0))]
4891 ;;- Don't use operand 1 for most machines.
4892 "! TARGET_PORTABLE_RUNTIME"
4895 output_arg_descriptor (insn);
4896 return output_call (insn, operands[1]);
4898 [(set_attr "type" "call")
4899 (set (attr "length")
4900 ;; If we're sure that we can either reach the target or that the
4901 ;; linker can use a long-branch stub, then the length is 4 bytes.
4903 ;; For long-calls the length will be either 52 bytes (non-pic)
4904 ;; or 68 bytes (pic). */
4905 ;; Else we have to use a long-call;
4906 (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
4909 (if_then_else (eq (symbol_ref "flag_pic")
4914 (define_insn "call_value_internal_reg"
4915 [(set (match_operand 0 "" "=rf")
4916 (call (mem:SI (reg:SI 22))
4917 (match_operand 1 "" "i")))
4918 (clobber (reg:SI 2))
4919 (use (const_int 1))]
4925 /* First the special case for kernels, level 0 systems, etc. */
4926 if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
4927 return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
4929 /* Now the normal case -- we can reach $$dyncall directly or
4930 we're sure that we can get there via a long-branch stub.
4932 No need to check target flags as the length uniquely identifies
4933 the remaining cases. */
4934 if (get_attr_length (insn) == 8)
4935 return \".CALL\\tARGW0=GR\;{bl|b,l} $$dyncall,%%r31\;copy %%r31,%%r2\";
4937 /* Long millicode call, but we are not generating PIC or portable runtime
4939 if (get_attr_length (insn) == 12)
4940 return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
4942 /* Long millicode call for portable runtime. */
4943 if (get_attr_length (insn) == 20)
4944 return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr %%r0,%%r2\;bv,n %%r0(%%r31)\;nop\";
4946 /* If we're generating PIC code. */
4947 xoperands[0] = operands[1];
4948 xoperands[1] = gen_label_rtx ();
4949 output_asm_insn (\"{bl|b,l} .+8,%%r1\", xoperands);
4950 output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
4951 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
4952 CODE_LABEL_NUMBER (xoperands[1]));
4953 output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
4954 output_asm_insn (\"blr %%r0,%%r2\", xoperands);
4955 output_asm_insn (\"bv,n %%r0(%%r1)\\n\\tnop\", xoperands);
4958 [(set_attr "type" "dyncall")
4959 (set (attr "length")
4961 ;; First NO_SPACE_REGS
4962 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
4966 ;; Target (or stub) within reach
4967 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4969 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4973 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
4974 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4976 (eq (symbol_ref "flag_pic")
4980 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4984 ;; Out of range PIC case
4987 ;; Call subroutine returning any type.
4989 (define_expand "untyped_call"
4990 [(parallel [(call (match_operand 0 "" "")
4992 (match_operand 1 "" "")
4993 (match_operand 2 "" "")])]
4999 emit_call_insn (gen_call (operands[0], const0_rtx));
5001 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5003 rtx set = XVECEXP (operands[2], 0, i);
5004 emit_move_insn (SET_DEST (set), SET_SRC (set));
5007 /* The optimizer does not know that the call sets the function value
5008 registers we stored in the result block. We avoid problems by
5009 claiming that all hard registers are used and clobbered at this
5011 emit_insn (gen_blockage ());
5019 [(set_attr "type" "move")
5020 (set_attr "length" "4")])
5022 ;; These are just placeholders so we know where branch tables
5024 (define_insn "begin_brtab"
5029 /* Only GAS actually supports this pseudo-op. */
5031 return \".begin_brtab\";
5035 [(set_attr "type" "move")
5036 (set_attr "length" "0")])
5038 (define_insn "end_brtab"
5043 /* Only GAS actually supports this pseudo-op. */
5045 return \".end_brtab\";
5049 [(set_attr "type" "move")
5050 (set_attr "length" "0")])
5052 ;;; Hope this is only within a function...
5053 (define_insn "indirect_jump"
5054 [(set (pc) (match_operand 0 "register_operand" "r"))]
5055 "GET_MODE (operands[0]) == word_mode"
5057 [(set_attr "type" "branch")
5058 (set_attr "length" "4")])
5060 ;;; EH does longjmp's from and within the data section. Thus,
5061 ;;; an interspace branch is required for the longjmp implementation.
5062 ;;; Registers r1 and r2 are not saved in the jmpbuf environment.
5063 ;;; Thus, they can be used as scratch registers for the jump.
5064 (define_insn "interspace_jump"
5065 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
5066 (clobber (reg:SI 2))]
5068 "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
5069 [(set_attr "type" "branch")
5070 (set_attr "length" "12")])
5072 (define_expand "builtin_longjmp"
5073 [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
5077 /* The elements of the buffer are, in order: */
5078 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5079 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4));
5080 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
5081 rtx pv = gen_rtx_REG (Pmode, 1);
5083 /* This bit is the same as expand_builtin_longjmp. */
5084 emit_move_insn (hard_frame_pointer_rtx, fp);
5085 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5086 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5087 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5089 /* Load the label we are jumping through into r1 so that we know
5090 where to look for it when we get back to setjmp's function for
5091 restoring the gp. */
5092 emit_move_insn (pv, lab);
5093 emit_jump_insn (gen_interspace_jump (pv));
5098 (define_expand "extzv"
5099 [(set (match_operand:SI 0 "register_operand" "")
5100 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
5101 (match_operand:SI 2 "uint5_operand" "")
5102 (match_operand:SI 3 "uint5_operand" "")))]
5106 if (! uint5_operand (operands[2], SImode)
5107 || ! uint5_operand (operands[3], SImode))
5112 [(set (match_operand:SI 0 "register_operand" "=r")
5113 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
5114 (match_operand:SI 2 "uint5_operand" "")
5115 (match_operand:SI 3 "uint5_operand" "")))]
5117 "{extru|extrw,u} %1,%3+%2-1,%2,%0"
5118 [(set_attr "type" "shift")
5119 (set_attr "length" "4")])
5122 [(set (match_operand:SI 0 "register_operand" "=r")
5123 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
5125 (match_operand:SI 3 "register_operand" "q")))]
5127 "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
5128 [(set_attr "type" "shift")
5129 (set_attr "length" "4")])
5131 (define_expand "extv"
5132 [(set (match_operand:SI 0 "register_operand" "")
5133 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
5134 (match_operand:SI 2 "uint5_operand" "")
5135 (match_operand:SI 3 "uint5_operand" "")))]
5139 if (! uint5_operand (operands[2], SImode)
5140 || ! uint5_operand (operands[3], SImode))
5145 [(set (match_operand:SI 0 "register_operand" "=r")
5146 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
5147 (match_operand:SI 2 "uint5_operand" "")
5148 (match_operand:SI 3 "uint5_operand" "")))]
5150 "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
5151 [(set_attr "type" "shift")
5152 (set_attr "length" "4")])
5155 [(set (match_operand:SI 0 "register_operand" "=r")
5156 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
5158 (match_operand:SI 3 "register_operand" "q")))]
5160 "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
5161 [(set_attr "type" "shift")
5162 (set_attr "length" "4")])
5164 (define_expand "insv"
5165 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
5166 (match_operand:SI 1 "uint5_operand" "")
5167 (match_operand:SI 2 "uint5_operand" ""))
5168 (match_operand:SI 3 "arith5_operand" "r,L"))]
5172 if (! uint5_operand (operands[1], SImode)
5173 || ! uint5_operand (operands[2], SImode))
5178 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
5179 (match_operand:SI 1 "uint5_operand" "")
5180 (match_operand:SI 2 "uint5_operand" ""))
5181 (match_operand:SI 3 "arith5_operand" "r,L"))]
5184 {dep|depw} %3,%2+%1-1,%1,%0
5185 {depi|depwi} %3,%2+%1-1,%1,%0"
5186 [(set_attr "type" "shift,shift")
5187 (set_attr "length" "4,4")])
5189 ;; Optimize insertion of const_int values of type 1...1xxxx.
5191 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
5192 (match_operand:SI 1 "uint5_operand" "")
5193 (match_operand:SI 2 "uint5_operand" ""))
5194 (match_operand:SI 3 "const_int_operand" ""))]
5195 "(INTVAL (operands[3]) & 0x10) != 0 &&
5196 (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
5199 operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
5200 return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
5202 [(set_attr "type" "shift")
5203 (set_attr "length" "4")])
5205 ;; This insn is used for some loop tests, typically loops reversed when
5206 ;; strength reduction is used. It is actually created when the instruction
5207 ;; combination phase combines the special loop test. Since this insn
5208 ;; is both a jump insn and has an output, it must deal with its own
5209 ;; reloads, hence the `m' constraints. The `!' constraints direct reload
5210 ;; to not choose the register alternatives in the event a reload is needed.
5211 (define_insn "decrement_and_branch_until_zero"
5214 (match_operator 2 "comparison_operator"
5215 [(plus:SI (match_operand:SI 0 "register_operand" "+!r,!*f,!*m")
5216 (match_operand:SI 1 "int5_operand" "L,L,L"))
5218 (label_ref (match_operand 3 "" ""))
5221 (plus:SI (match_dup 0) (match_dup 1)))
5222 (clobber (match_scratch:SI 4 "=X,r,r"))]
5224 "* return output_dbra (operands, insn, which_alternative); "
5225 ;; Do not expect to understand this the first time through.
5226 [(set_attr "type" "cbranch,multi,multi")
5227 (set (attr "length")
5228 (if_then_else (eq_attr "alternative" "0")
5229 ;; Loop counter in register case
5230 ;; Short branch has length of 4
5231 ;; Long branch has length of 8
5232 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5237 ;; Loop counter in FP reg case.
5238 ;; Extra goo to deal with additional reload insns.
5239 (if_then_else (eq_attr "alternative" "1")
5240 (if_then_else (lt (match_dup 3) (pc))
5242 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
5247 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5251 ;; Loop counter in memory case.
5252 ;; Extra goo to deal with additional reload insns.
5253 (if_then_else (lt (match_dup 3) (pc))
5255 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
5260 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5263 (const_int 16))))))])
5268 (match_operator 2 "movb_comparison_operator"
5269 [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
5270 (label_ref (match_operand 3 "" ""))
5272 (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
5275 "* return output_movb (operands, insn, which_alternative, 0); "
5276 ;; Do not expect to understand this the first time through.
5277 [(set_attr "type" "cbranch,multi,multi,multi")
5278 (set (attr "length")
5279 (if_then_else (eq_attr "alternative" "0")
5280 ;; Loop counter in register case
5281 ;; Short branch has length of 4
5282 ;; Long branch has length of 8
5283 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5288 ;; Loop counter in FP reg case.
5289 ;; Extra goo to deal with additional reload insns.
5290 (if_then_else (eq_attr "alternative" "1")
5291 (if_then_else (lt (match_dup 3) (pc))
5293 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
5298 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5302 ;; Loop counter in memory or sar case.
5303 ;; Extra goo to deal with additional reload insns.
5305 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5308 (const_int 12)))))])
5310 ;; Handle negated branch.
5314 (match_operator 2 "movb_comparison_operator"
5315 [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
5317 (label_ref (match_operand 3 "" ""))))
5318 (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
5321 "* return output_movb (operands, insn, which_alternative, 1); "
5322 ;; Do not expect to understand this the first time through.
5323 [(set_attr "type" "cbranch,multi,multi,multi")
5324 (set (attr "length")
5325 (if_then_else (eq_attr "alternative" "0")
5326 ;; Loop counter in register case
5327 ;; Short branch has length of 4
5328 ;; Long branch has length of 8
5329 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5334 ;; Loop counter in FP reg case.
5335 ;; Extra goo to deal with additional reload insns.
5336 (if_then_else (eq_attr "alternative" "1")
5337 (if_then_else (lt (match_dup 3) (pc))
5339 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
5344 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5348 ;; Loop counter in memory or SAR case.
5349 ;; Extra goo to deal with additional reload insns.
5351 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5354 (const_int 12)))))])
5357 [(set (pc) (label_ref (match_operand 3 "" "" )))
5358 (set (match_operand:SI 0 "ireg_operand" "=r")
5359 (plus:SI (match_operand:SI 1 "ireg_operand" "r")
5360 (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
5361 "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
5364 return output_parallel_addb (operands, get_attr_length (insn));
5366 [(set_attr "type" "parallel_branch")
5367 (set (attr "length")
5368 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5374 [(set (pc) (label_ref (match_operand 2 "" "" )))
5375 (set (match_operand:SF 0 "ireg_operand" "=r")
5376 (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
5380 return output_parallel_movb (operands, get_attr_length (insn));
5382 [(set_attr "type" "parallel_branch")
5383 (set (attr "length")
5384 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
5390 [(set (pc) (label_ref (match_operand 2 "" "" )))
5391 (set (match_operand:SI 0 "ireg_operand" "=r")
5392 (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
5396 return output_parallel_movb (operands, get_attr_length (insn));
5398 [(set_attr "type" "parallel_branch")
5399 (set (attr "length")
5400 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
5406 [(set (pc) (label_ref (match_operand 2 "" "" )))
5407 (set (match_operand:HI 0 "ireg_operand" "=r")
5408 (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
5412 return output_parallel_movb (operands, get_attr_length (insn));
5414 [(set_attr "type" "parallel_branch")
5415 (set (attr "length")
5416 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
5422 [(set (pc) (label_ref (match_operand 2 "" "" )))
5423 (set (match_operand:QI 0 "ireg_operand" "=r")
5424 (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
5428 return output_parallel_movb (operands, get_attr_length (insn));
5430 [(set_attr "type" "parallel_branch")
5431 (set (attr "length")
5432 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
5438 [(set (match_operand 0 "register_operand" "=f")
5439 (mult (match_operand 1 "register_operand" "f")
5440 (match_operand 2 "register_operand" "f")))
5441 (set (match_operand 3 "register_operand" "+f")
5442 (plus (match_operand 4 "register_operand" "f")
5443 (match_operand 5 "register_operand" "f")))]
5444 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
5445 && reload_completed && fmpyaddoperands (operands)"
5448 if (GET_MODE (operands[0]) == DFmode)
5450 if (rtx_equal_p (operands[3], operands[5]))
5451 return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
5453 return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
5457 if (rtx_equal_p (operands[3], operands[5]))
5458 return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
5460 return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
5463 [(set_attr "type" "fpalu")
5464 (set_attr "length" "4")])
5467 [(set (match_operand 3 "register_operand" "+f")
5468 (plus (match_operand 4 "register_operand" "f")
5469 (match_operand 5 "register_operand" "f")))
5470 (set (match_operand 0 "register_operand" "=f")
5471 (mult (match_operand 1 "register_operand" "f")
5472 (match_operand 2 "register_operand" "f")))]
5473 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
5474 && reload_completed && fmpyaddoperands (operands)"
5477 if (GET_MODE (operands[0]) == DFmode)
5479 if (rtx_equal_p (operands[3], operands[5]))
5480 return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
5482 return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
5486 if (rtx_equal_p (operands[3], operands[5]))
5487 return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
5489 return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
5492 [(set_attr "type" "fpalu")
5493 (set_attr "length" "4")])
5496 [(set (match_operand 0 "register_operand" "=f")
5497 (mult (match_operand 1 "register_operand" "f")
5498 (match_operand 2 "register_operand" "f")))
5499 (set (match_operand 3 "register_operand" "+f")
5500 (minus (match_operand 4 "register_operand" "f")
5501 (match_operand 5 "register_operand" "f")))]
5502 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
5503 && reload_completed && fmpysuboperands (operands)"
5506 if (GET_MODE (operands[0]) == DFmode)
5507 return \"fmpysub,dbl %1,%2,%0,%5,%3\";
5509 return \"fmpysub,sgl %1,%2,%0,%5,%3\";
5511 [(set_attr "type" "fpalu")
5512 (set_attr "length" "4")])
5515 [(set (match_operand 3 "register_operand" "+f")
5516 (minus (match_operand 4 "register_operand" "f")
5517 (match_operand 5 "register_operand" "f")))
5518 (set (match_operand 0 "register_operand" "=f")
5519 (mult (match_operand 1 "register_operand" "f")
5520 (match_operand 2 "register_operand" "f")))]
5521 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
5522 && reload_completed && fmpysuboperands (operands)"
5525 if (GET_MODE (operands[0]) == DFmode)
5526 return \"fmpysub,dbl %1,%2,%0,%5,%3\";
5528 return \"fmpysub,sgl %1,%2,%0,%5,%3\";
5530 [(set_attr "type" "fpalu")
5531 (set_attr "length" "4")])
5533 ;; Clean up turds left by reload.
5535 [(set (match_operand 0 "reg_or_nonsymb_mem_operand" "")
5536 (match_operand 1 "register_operand" "fr"))
5537 (set (match_operand 2 "register_operand" "fr")
5539 "! TARGET_SOFT_FLOAT
5540 && GET_CODE (operands[0]) == MEM
5541 && ! MEM_VOLATILE_P (operands[0])
5542 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5543 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5544 && GET_MODE (operands[0]) == DFmode
5545 && GET_CODE (operands[1]) == REG
5546 && GET_CODE (operands[2]) == REG
5547 && ! side_effects_p (XEXP (operands[0], 0))
5548 && REGNO_REG_CLASS (REGNO (operands[1]))
5549 == REGNO_REG_CLASS (REGNO (operands[2]))"
5554 if (FP_REG_P (operands[1]))
5555 output_asm_insn (output_fp_move_double (operands), operands);
5557 output_asm_insn (output_move_double (operands), operands);
5559 if (rtx_equal_p (operands[1], operands[2]))
5562 xoperands[0] = operands[2];
5563 xoperands[1] = operands[1];
5565 if (FP_REG_P (xoperands[1]))
5566 output_asm_insn (output_fp_move_double (xoperands), xoperands);
5568 output_asm_insn (output_move_double (xoperands), xoperands);
5574 [(set (match_operand 0 "register_operand" "fr")
5575 (match_operand 1 "reg_or_nonsymb_mem_operand" ""))
5576 (set (match_operand 2 "register_operand" "fr")
5578 "! TARGET_SOFT_FLOAT
5579 && GET_CODE (operands[1]) == MEM
5580 && ! MEM_VOLATILE_P (operands[1])
5581 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5582 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5583 && GET_MODE (operands[0]) == DFmode
5584 && GET_CODE (operands[0]) == REG
5585 && GET_CODE (operands[2]) == REG
5586 && ! side_effects_p (XEXP (operands[1], 0))
5587 && REGNO_REG_CLASS (REGNO (operands[0]))
5588 == REGNO_REG_CLASS (REGNO (operands[2]))"
5593 if (FP_REG_P (operands[0]))
5594 output_asm_insn (output_fp_move_double (operands), operands);
5596 output_asm_insn (output_move_double (operands), operands);
5598 xoperands[0] = operands[2];
5599 xoperands[1] = operands[0];
5601 if (FP_REG_P (xoperands[1]))
5602 output_asm_insn (output_fp_move_double (xoperands), xoperands);
5604 output_asm_insn (output_move_double (xoperands), xoperands);
5609 ;; Flush the I and D cache line found at the address in operand 0.
5610 ;; This is used by the trampoline code for nested functions.
5611 ;; So long as the trampoline itself is less than 32 bytes this
5614 (define_insn "dcacheflush"
5615 [(unspec_volatile [(const_int 1)] 0)
5616 (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
5617 (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))]
5619 "fdc 0(%0)\;fdc 0(%1)\;sync"
5620 [(set_attr "type" "multi")
5621 (set_attr "length" "12")])
5623 (define_insn "icacheflush"
5624 [(unspec_volatile [(const_int 2)] 0)
5625 (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
5626 (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))
5627 (use (match_operand 2 "pmode_register_operand" "r"))
5628 (clobber (match_operand 3 "pmode_register_operand" "=&r"))
5629 (clobber (match_operand 4 "pmode_register_operand" "=&r"))]
5631 "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"
5632 [(set_attr "type" "multi")
5633 (set_attr "length" "52")])
5635 ;; An out-of-line prologue.
5636 (define_insn "outline_prologue_call"
5637 [(unspec_volatile [(const_int 0)] 0)
5638 (clobber (reg:SI 31))
5639 (clobber (reg:SI 22))
5640 (clobber (reg:SI 21))
5641 (clobber (reg:SI 20))
5642 (clobber (reg:SI 19))
5643 (clobber (reg:SI 1))]
5647 extern int frame_pointer_needed;
5649 /* We need two different versions depending on whether or not we
5650 need a frame pointer. Also note that we return to the instruction
5651 immediately after the branch rather than two instructions after the
5652 break as normally is the case. */
5653 if (frame_pointer_needed)
5655 /* Must import the magic millicode routine(s). */
5656 output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
5658 if (TARGET_PORTABLE_RUNTIME)
5660 output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
5661 output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
5665 output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
5669 /* Must import the magic millicode routine(s). */
5670 output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
5672 if (TARGET_PORTABLE_RUNTIME)
5674 output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
5675 output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
5678 output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
5682 [(set_attr "type" "multi")
5683 (set_attr "length" "8")])
5685 ;; An out-of-line epilogue.
5686 (define_insn "outline_epilogue_call"
5687 [(unspec_volatile [(const_int 1)] 0)
5690 (clobber (reg:SI 31))
5691 (clobber (reg:SI 22))
5692 (clobber (reg:SI 21))
5693 (clobber (reg:SI 20))
5694 (clobber (reg:SI 19))
5695 (clobber (reg:SI 2))
5696 (clobber (reg:SI 1))]
5700 extern int frame_pointer_needed;
5702 /* We need two different versions depending on whether or not we
5703 need a frame pointer. Also note that we return to the instruction
5704 immediately after the branch rather than two instructions after the
5705 break as normally is the case. */
5706 if (frame_pointer_needed)
5708 /* Must import the magic millicode routine. */
5709 output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
5711 /* The out-of-line prologue will make sure we return to the right
5713 if (TARGET_PORTABLE_RUNTIME)
5715 output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
5716 output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
5720 output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
5724 /* Must import the magic millicode routine. */
5725 output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
5727 /* The out-of-line prologue will make sure we return to the right
5729 if (TARGET_PORTABLE_RUNTIME)
5731 output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
5732 output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
5735 output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
5739 [(set_attr "type" "multi")
5740 (set_attr "length" "8")])
5742 ;; Given a function pointer, canonicalize it so it can be
5743 ;; reliably compared to another function pointer. */
5744 (define_expand "canonicalize_funcptr_for_compare"
5745 [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
5746 (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
5747 (clobber (match_dup 2))
5748 (clobber (reg:SI 26))
5749 (clobber (reg:SI 22))
5750 (clobber (reg:SI 31))])
5751 (set (match_operand:SI 0 "register_operand" "")
5753 "! TARGET_PORTABLE_RUNTIME"
5756 operands[2] = gen_reg_rtx (SImode);
5757 if (GET_CODE (operands[1]) != REG)
5759 rtx tmp = gen_reg_rtx (Pmode);
5760 emit_move_insn (tmp, operands[1]);
5766 [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
5767 (clobber (match_operand:SI 0 "register_operand" "=a"))
5768 (clobber (reg:SI 26))
5769 (clobber (reg:SI 22))
5770 (clobber (reg:SI 31))]
5774 /* Must import the magic millicode routine. */
5775 output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
5777 /* This is absolutely amazing.
5779 First, copy our input parameter into %r29 just in case we don't
5780 need to call $$sh_func_adrs. */
5781 output_asm_insn (\"copy %%r26,%%r29\", NULL);
5783 /* Next, examine the low two bits in %r26, if they aren't 0x2, then
5784 we use %r26 unchanged. */
5785 if (get_attr_length (insn) == 32)
5786 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+24\", NULL);
5787 else if (get_attr_length (insn) == 40)
5788 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+32\", NULL);
5789 else if (get_attr_length (insn) == 44)
5790 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+36\", NULL);
5792 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+20\", NULL);
5794 /* Next, compare %r26 with 4096, if %r26 is less than or equal to
5795 4096, then we use %r26 unchanged. */
5796 if (get_attr_length (insn) == 32)
5797 output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+16\",
5799 else if (get_attr_length (insn) == 40)
5800 output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+24\",
5802 else if (get_attr_length (insn) == 44)
5803 output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+28\",
5806 output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+12\",
5809 /* Else call $$sh_func_adrs to extract the function's real add24. */
5810 return output_millicode_call (insn,
5811 gen_rtx_SYMBOL_REF (SImode,
5812 \"$$sh_func_adrs\"));
5814 [(set_attr "type" "multi")
5815 (set (attr "length")
5817 ;; Target (or stub) within reach
5818 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
5820 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
5825 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
5829 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
5830 ;; same as NO_SPACE_REGS code
5831 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
5833 (eq (symbol_ref "flag_pic")
5838 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
5842 ;; Out of range and PIC
5845 ;; On the PA, the PIC register is call clobbered, so it must
5846 ;; be saved & restored around calls by the caller. If the call
5847 ;; doesn't return normally (nonlocal goto, or an exception is
5848 ;; thrown), then the code at the exception handler label must
5849 ;; restore the PIC register.
5850 (define_expand "exception_receiver"
5852 "!TARGET_PORTABLE_RUNTIME && flag_pic"
5855 /* Load the PIC register from the stack slot (in our caller's
5857 emit_move_insn (pic_offset_table_rtx,
5858 gen_rtx_MEM (SImode,
5859 plus_constant (stack_pointer_rtx, -32)));
5860 emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx));
5861 emit_insn (gen_blockage ());