1 ;;- Machine description for HP PA-RISC architecture for GNU C compiler
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by the Center for Software Science at the University
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
24 ;; This gcc Version 2 machine description is inspired by sparc.md and
27 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; Insn type. Used to default other attribute values.
31 ;; type "unary" insns have one input operand (1) and one output operand (0)
32 ;; type "binary" insns have two input operands (1,2) and one output (0)
35 "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,parallel_branch"
36 (const_string "binary"))
38 (define_attr "pa_combine_type"
39 "fmpy,faddsub,uncond_branch,addmove,none"
40 (const_string "none"))
42 ;; Processor type (for scheduling, not code generation) -- this attribute
43 ;; must exactly match the processor_type enumeration in pa.h.
45 ;; FIXME: Add 800 scheduling for completeness?
47 (define_attr "cpu" "700,7100,7100LC" (const (symbol_ref "pa_cpu_attr")))
49 ;; Length (in # of insns).
50 (define_attr "length" ""
51 (cond [(eq_attr "type" "load,fpload")
52 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
53 (const_int 8) (const_int 4))
55 (eq_attr "type" "store,fpstore")
56 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
57 (const_int 8) (const_int 4))
59 (eq_attr "type" "binary,shift,nullshift")
60 (if_then_else (match_operand 2 "arith_operand" "")
61 (const_int 4) (const_int 12))
63 (eq_attr "type" "move,unary,shift,nullshift")
64 (if_then_else (match_operand 1 "arith_operand" "")
65 (const_int 4) (const_int 8))]
69 (define_asm_attributes
70 [(set_attr "length" "4")
71 (set_attr "type" "multi")])
73 ;; Attributes for instruction and branch scheduling
75 ;; For conditional branches.
76 (define_attr "in_branch_delay" "false,true"
77 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
78 (eq_attr "length" "4"))
80 (const_string "false")))
82 ;; Disallow instructions which use the FPU since they will tie up the FPU
83 ;; even if the instruction is nullified.
84 (define_attr "in_nullified_branch_delay" "false,true"
85 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch")
86 (eq_attr "length" "4"))
88 (const_string "false")))
90 ;; For calls and millicode calls. Allow unconditional branches in the
92 (define_attr "in_call_delay" "false,true"
93 (cond [(and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
94 (eq_attr "length" "4"))
96 (eq_attr "type" "uncond_branch")
97 (if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY")
100 (const_string "false"))]
101 (const_string "false")))
104 ;; Call delay slot description.
105 (define_delay (eq_attr "type" "call")
106 [(eq_attr "in_call_delay" "true") (nil) (nil)])
108 ;; millicode call delay slot description. Note it disallows delay slot
109 ;; when TARGET_PORTABLE_RUNTIME is true.
110 (define_delay (eq_attr "type" "milli")
111 [(and (eq_attr "in_call_delay" "true")
112 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0)))
115 ;; Return and other similar instructions.
116 (define_delay (eq_attr "type" "branch,parallel_branch")
117 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
119 ;; Floating point conditional branch delay slot description and
120 (define_delay (eq_attr "type" "fbranch")
121 [(eq_attr "in_branch_delay" "true")
122 (eq_attr "in_nullified_branch_delay" "true")
125 ;; Integer conditional branch delay slot description.
126 ;; Nullification of conditional branches on the PA is dependent on the
127 ;; direction of the branch. Forward branches nullify true and
128 ;; backward branches nullify false. If the direction is unknown
129 ;; then nullification is not allowed.
130 (define_delay (eq_attr "type" "cbranch")
131 [(eq_attr "in_branch_delay" "true")
132 (and (eq_attr "in_nullified_branch_delay" "true")
133 (attr_flag "forward"))
134 (and (eq_attr "in_nullified_branch_delay" "true")
135 (attr_flag "backward"))])
137 (define_delay (and (eq_attr "type" "uncond_branch")
138 (eq (symbol_ref "following_call (insn)")
140 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
142 ;; Function units of the HPPA. The following data is for the 700 CPUs
143 ;; (Mustang CPU + Timex FPU aka PA-89) because that's what I have the docs for.
144 ;; Scheduling instructions for PA-83 machines according to the Snake
145 ;; constraints shouldn't hurt.
147 ;; (define_function_unit {name} {num-units} {n-users} {test}
148 ;; {ready-delay} {issue-delay} [{conflict-list}])
151 ;; (Noted only for documentation; units that take one cycle do not need to
154 ;; (define_function_unit "alu" 1 0
155 ;; (and (eq_attr "type" "unary,shift,nullshift,binary,move,address")
156 ;; (eq_attr "cpu" "700"))
160 ;; Memory. Disregarding Cache misses, the Mustang memory times are:
161 ;; load: 2, fpload: 3
162 ;; store, fpstore: 3, no D-cache operations should be scheduled.
164 (define_function_unit "pa700memory" 1 0
165 (and (eq_attr "type" "load,fpload")
166 (eq_attr "cpu" "700")) 2 0)
167 (define_function_unit "pa700memory" 1 0
168 (and (eq_attr "type" "store,fpstore")
169 (eq_attr "cpu" "700")) 3 3)
171 ;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
173 ;; Instruction Time Unit Minimum Distance (unit contention)
180 ;; fmpyadd 3 ALU,MPY 2
181 ;; fmpysub 3 ALU,MPY 2
182 ;; fmpycfxt 3 ALU,MPY 2
185 ;; fdiv,sgl 10 MPY 10
186 ;; fdiv,dbl 12 MPY 12
187 ;; fsqrt,sgl 14 MPY 14
188 ;; fsqrt,dbl 18 MPY 18
190 (define_function_unit "pa700fp_alu" 1 0
191 (and (eq_attr "type" "fpcc")
192 (eq_attr "cpu" "700")) 4 2)
193 (define_function_unit "pa700fp_alu" 1 0
194 (and (eq_attr "type" "fpalu")
195 (eq_attr "cpu" "700")) 3 2)
196 (define_function_unit "pa700fp_mpy" 1 0
197 (and (eq_attr "type" "fpmulsgl,fpmuldbl")
198 (eq_attr "cpu" "700")) 3 2)
199 (define_function_unit "pa700fp_mpy" 1 0
200 (and (eq_attr "type" "fpdivsgl")
201 (eq_attr "cpu" "700")) 10 10)
202 (define_function_unit "pa700fp_mpy" 1 0
203 (and (eq_attr "type" "fpdivdbl")
204 (eq_attr "cpu" "700")) 12 12)
205 (define_function_unit "pa700fp_mpy" 1 0
206 (and (eq_attr "type" "fpsqrtsgl")
207 (eq_attr "cpu" "700")) 14 14)
208 (define_function_unit "pa700fp_mpy" 1 0
209 (and (eq_attr "type" "fpsqrtdbl")
210 (eq_attr "cpu" "700")) 18 18)
212 ;; Function units for the 7100 and 7150. The 7100/7150 can dual-issue
213 ;; floating point computations with non-floating point computations (fp loads
214 ;; and stores are not fp computations).
216 ;; As with the alpha we multiply the ready delay by two to encourage
217 ;; schedules which will allow the 7100/7150 to dual issue as many instructions
220 ;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
221 ;; take two cycles, during which no Dcache operations should be scheduled.
222 ;; Any special cases are handled in pa_adjust_cost. The 7100, 7150 and 7100LC
223 ;; all have the same memory characteristics if one disregards cache misses.
224 (define_function_unit "pa7100memory" 1 0
225 (and (eq_attr "type" "load,fpload")
226 (eq_attr "cpu" "7100,7100LC")) 4 0)
227 (define_function_unit "pa7100memory" 1 0
228 (and (eq_attr "type" "store,fpstore")
229 (eq_attr "cpu" "7100,7100LC")) 4 4)
231 ;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
233 ;; Instruction Time Unit Minimum Distance (unit contention)
240 ;; fmpyadd 2 ALU,MPY 1
241 ;; fmpysub 2 ALU,MPY 1
242 ;; fmpycfxt 2 ALU,MPY 1
246 ;; fdiv,dbl 15 DIV 15
248 ;; fsqrt,dbl 15 DIV 15
250 (define_function_unit "pa7100fp_alu" 1 0
251 (and (eq_attr "type" "fpcc,fpalu")
252 (eq_attr "cpu" "7100")) 4 2)
253 (define_function_unit "pa7100fp_mpy" 1 0
254 (and (eq_attr "type" "fpmulsgl,fpmuldbl")
255 (eq_attr "cpu" "7100")) 4 2)
256 (define_function_unit "pa7100fp_div" 1 0
257 (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
258 (eq_attr "cpu" "7100")) 16 16)
259 (define_function_unit "pa7100fp_div" 1 0
260 (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
261 (eq_attr "cpu" "7100")) 30 30)
263 ;; To encourage dual issue we define function units corresponding to
264 ;; the instructions which can be dual issued. This is a rather crude
265 ;; approximation, the "pa7100nonflop" test in particular could be refined.
266 (define_function_unit "pa7100flop" 1 1
268 (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
269 (eq_attr "cpu" "7100,7100LC")) 2 2)
271 (define_function_unit "pa7100nonflop" 1 1
273 (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
274 (eq_attr "cpu" "7100")) 2 2)
277 ;; Memory subsystem works just like 7100/7150 (except for cache miss times which
278 ;; we don't model here).
280 ;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
281 ;; Note divides and sqrt flops lock the cpu until the flop is
282 ;; finished. fmpy and xmpyu (fmpyi) lock the cpu for one cycle.
283 ;; There's no way to avoid the penalty.
285 ;; Instruction Time Unit Minimum Distance (unit contention)
292 ;; fmpyadd,sgl 2 ALU,MPY 1
293 ;; fmpyadd,dbl 3 ALU,MPY 2
294 ;; fmpysub,sgl 2 ALU,MPY 1
295 ;; fmpysub,dbl 3 ALU,MPY 2
296 ;; fmpycfxt,sgl 2 ALU,MPY 1
297 ;; fmpycfxt,dbl 3 ALU,MPY 2
302 ;; fdiv,dbl 15 DIV 15
304 ;; fsqrt,dbl 15 DIV 15
306 (define_function_unit "pa7100LCfp_alu" 1 0
307 (and (eq_attr "type" "fpcc,fpalu")
308 (eq_attr "cpu" "7100LC")) 4 2)
309 (define_function_unit "pa7100LCfp_mpy" 1 0
310 (and (eq_attr "type" "fpmulsgl")
311 (eq_attr "cpu" "7100LC")) 4 2)
312 (define_function_unit "pa7100LCfp_mpy" 1 0
313 (and (eq_attr "type" "fpmuldbl")
314 (eq_attr "cpu" "7100LC")) 6 4)
315 (define_function_unit "pa7100LCfp_div" 1 0
316 (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
317 (eq_attr "cpu" "7100LC")) 16 16)
318 (define_function_unit "pa7100LCfp_div" 1 0
319 (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
320 (eq_attr "cpu" "7100LC")) 30 30)
322 ;; Define the various functional units for dual-issue.
323 ;; The 7100LC shares the generic "flop" unit specification with the 7100/7150.
325 ;; The 7100LC has two basic integer which allow dual issue of most integer
326 ;; instructions. This needs further refinement to deal with the nullify,
327 ;; carry/borrow possible the ldw/ldw stw/stw special dual issue cases, and
328 ;; of course it needs to know about hte 2nd alu.
329 (define_function_unit "pa7100LCnonflop" 1 1
331 (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
332 (eq_attr "cpu" "7100LC")) 2 2)
334 (define_function_unit "pa7100LCshifter" 1 1
336 (eq_attr "type" "shift,nullshift")
337 (eq_attr "cpu" "7100LC")) 2 2)
339 (define_function_unit "pa7100LCmem" 1 1
341 (eq_attr "type" "load,fpload,store,fpstore")
342 (eq_attr "cpu" "7100LC")) 2 2)
345 ;; Compare instructions.
346 ;; This controls RTL generation and register allocation.
348 ;; We generate RTL for comparisons and branches by having the cmpxx
349 ;; patterns store away the operands. Then, the scc and bcc patterns
350 ;; emit RTL for both the compare and the branch.
353 (define_expand "cmpsi"
355 (compare:CC (match_operand:SI 0 "reg_or_0_operand" "")
356 (match_operand:SI 1 "arith5_operand" "")))]
360 hppa_compare_op0 = operands[0];
361 hppa_compare_op1 = operands[1];
362 hppa_branch_type = CMP_SI;
366 (define_expand "cmpsf"
368 (compare:CCFP (match_operand:SF 0 "reg_or_0_operand" "")
369 (match_operand:SF 1 "reg_or_0_operand" "")))]
370 "! TARGET_SOFT_FLOAT"
373 hppa_compare_op0 = operands[0];
374 hppa_compare_op1 = operands[1];
375 hppa_branch_type = CMP_SF;
379 (define_expand "cmpdf"
381 (compare:CCFP (match_operand:DF 0 "reg_or_0_operand" "")
382 (match_operand:DF 1 "reg_or_0_operand" "")))]
383 "! TARGET_SOFT_FLOAT"
386 hppa_compare_op0 = operands[0];
387 hppa_compare_op1 = operands[1];
388 hppa_branch_type = CMP_DF;
394 (match_operator:CCFP 2 "comparison_operator"
395 [(match_operand:SF 0 "reg_or_0_operand" "fG")
396 (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
397 "! TARGET_SOFT_FLOAT"
398 "fcmp,sgl,%Y2 %r0,%r1"
399 [(set_attr "length" "4")
400 (set_attr "type" "fpcc")])
404 (match_operator:CCFP 2 "comparison_operator"
405 [(match_operand:DF 0 "reg_or_0_operand" "fG")
406 (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
407 "! TARGET_SOFT_FLOAT"
408 "fcmp,dbl,%Y2 %r0,%r1"
409 [(set_attr "length" "4")
410 (set_attr "type" "fpcc")])
415 [(set (match_operand:SI 0 "register_operand" "")
421 /* fp scc patterns rarely match, and are not a win on the PA. */
422 if (hppa_branch_type != CMP_SI)
424 /* set up operands from compare. */
425 operands[1] = hppa_compare_op0;
426 operands[2] = hppa_compare_op1;
427 /* fall through and generate default code */
431 [(set (match_operand:SI 0 "register_operand" "")
437 /* fp scc patterns rarely match, and are not a win on the PA. */
438 if (hppa_branch_type != CMP_SI)
440 operands[1] = hppa_compare_op0;
441 operands[2] = hppa_compare_op1;
445 [(set (match_operand:SI 0 "register_operand" "")
451 /* fp scc patterns rarely match, and are not a win on the PA. */
452 if (hppa_branch_type != CMP_SI)
454 operands[1] = hppa_compare_op0;
455 operands[2] = hppa_compare_op1;
459 [(set (match_operand:SI 0 "register_operand" "")
465 /* fp scc patterns rarely match, and are not a win on the PA. */
466 if (hppa_branch_type != CMP_SI)
468 operands[1] = hppa_compare_op0;
469 operands[2] = hppa_compare_op1;
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 operands[1] = hppa_compare_op0;
483 operands[2] = hppa_compare_op1;
487 [(set (match_operand:SI 0 "register_operand" "")
493 /* fp scc patterns rarely match, and are not a win on the PA. */
494 if (hppa_branch_type != CMP_SI)
496 operands[1] = hppa_compare_op0;
497 operands[2] = hppa_compare_op1;
500 (define_expand "sltu"
501 [(set (match_operand:SI 0 "register_operand" "")
502 (ltu:SI (match_dup 1)
507 if (hppa_branch_type != CMP_SI)
509 operands[1] = hppa_compare_op0;
510 operands[2] = hppa_compare_op1;
513 (define_expand "sgtu"
514 [(set (match_operand:SI 0 "register_operand" "")
515 (gtu:SI (match_dup 1)
520 if (hppa_branch_type != CMP_SI)
522 operands[1] = hppa_compare_op0;
523 operands[2] = hppa_compare_op1;
526 (define_expand "sleu"
527 [(set (match_operand:SI 0 "register_operand" "")
528 (leu:SI (match_dup 1)
533 if (hppa_branch_type != CMP_SI)
535 operands[1] = hppa_compare_op0;
536 operands[2] = hppa_compare_op1;
539 (define_expand "sgeu"
540 [(set (match_operand:SI 0 "register_operand" "")
541 (geu:SI (match_dup 1)
546 if (hppa_branch_type != CMP_SI)
548 operands[1] = hppa_compare_op0;
549 operands[2] = hppa_compare_op1;
552 ;; Instruction canonicalization puts immediate operands second, which
553 ;; is the reverse of what we want.
556 [(set (match_operand:SI 0 "register_operand" "=r")
557 (match_operator:SI 3 "comparison_operator"
558 [(match_operand:SI 1 "register_operand" "r")
559 (match_operand:SI 2 "arith11_operand" "rI")]))]
561 "com%I2clr,%B3 %2,%1,%0\;ldi 1,%0"
562 [(set_attr "type" "binary")
563 (set_attr "length" "8")])
565 (define_insn "iorscc"
566 [(set (match_operand:SI 0 "register_operand" "=r")
567 (ior:SI (match_operator:SI 3 "comparison_operator"
568 [(match_operand:SI 1 "register_operand" "r")
569 (match_operand:SI 2 "arith11_operand" "rI")])
570 (match_operator:SI 6 "comparison_operator"
571 [(match_operand:SI 4 "register_operand" "r")
572 (match_operand:SI 5 "arith11_operand" "rI")])))]
574 "com%I2clr,%S3 %2,%1,0\;com%I5clr,%B6 %5,%4,%0\;ldi 1,%0"
575 [(set_attr "type" "binary")
576 (set_attr "length" "12")])
578 ;; Combiner patterns for common operations performed with the output
579 ;; from an scc insn (negscc and incscc).
580 (define_insn "negscc"
581 [(set (match_operand:SI 0 "register_operand" "=r")
582 (neg:SI (match_operator:SI 3 "comparison_operator"
583 [(match_operand:SI 1 "register_operand" "r")
584 (match_operand:SI 2 "arith11_operand" "rI")])))]
586 "com%I2clr,%B3 %2,%1,%0\;ldi -1,%0"
587 [(set_attr "type" "binary")
588 (set_attr "length" "8")])
590 ;; Patterns for adding/subtracting the result of a boolean expression from
591 ;; a register. First we have special patterns that make use of the carry
592 ;; bit, and output only two instructions. For the cases we can't in
593 ;; general do in two instructions, the incscc pattern at the end outputs
594 ;; two or three instructions.
597 [(set (match_operand:SI 0 "register_operand" "=r")
598 (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
599 (match_operand:SI 3 "arith11_operand" "rI"))
600 (match_operand:SI 1 "register_operand" "r")))]
602 "sub%I3 %3,%2,0\;addc 0,%1,%0"
603 [(set_attr "type" "binary")
604 (set_attr "length" "8")])
606 ; This need only accept registers for op3, since canonicalization
607 ; replaces geu with gtu when op3 is an integer.
609 [(set (match_operand:SI 0 "register_operand" "=r")
610 (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
611 (match_operand:SI 3 "register_operand" "r"))
612 (match_operand:SI 1 "register_operand" "r")))]
614 "sub %2,%3,0\;addc 0,%1,%0"
615 [(set_attr "type" "binary")
616 (set_attr "length" "8")])
618 ; Match only integers for op3 here. This is used as canonical form of the
619 ; geu pattern when op3 is an integer. Don't match registers since we can't
620 ; make better code than the general incscc pattern.
622 [(set (match_operand:SI 0 "register_operand" "=r")
623 (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
624 (match_operand:SI 3 "int11_operand" "I"))
625 (match_operand:SI 1 "register_operand" "r")))]
627 "addi %k3,%2,0\;addc 0,%1,%0"
628 [(set_attr "type" "binary")
629 (set_attr "length" "8")])
631 (define_insn "incscc"
632 [(set (match_operand:SI 0 "register_operand" "=r,r")
633 (plus:SI (match_operator:SI 4 "comparison_operator"
634 [(match_operand:SI 2 "register_operand" "r,r")
635 (match_operand:SI 3 "arith11_operand" "rI,rI")])
636 (match_operand:SI 1 "register_operand" "0,?r")))]
639 com%I3clr,%B4 %3,%2,0\;addi 1,%0,%0
640 com%I3clr,%B4 %3,%2,0\;addi,tr 1,%1,%0\;copy %1,%0"
641 [(set_attr "type" "binary,binary")
642 (set_attr "length" "8,12")])
645 [(set (match_operand:SI 0 "register_operand" "=r")
646 (minus:SI (match_operand:SI 1 "register_operand" "r")
647 (gtu:SI (match_operand:SI 2 "register_operand" "r")
648 (match_operand:SI 3 "arith11_operand" "rI"))))]
650 "sub%I3 %3,%2,0\;subb %1,0,%0"
651 [(set_attr "type" "binary")
652 (set_attr "length" "8")])
655 [(set (match_operand:SI 0 "register_operand" "=r")
656 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
657 (gtu:SI (match_operand:SI 2 "register_operand" "r")
658 (match_operand:SI 3 "arith11_operand" "rI")))
659 (match_operand:SI 4 "register_operand" "r")))]
661 "sub%I3 %3,%2,0\;subb %1,%4,%0"
662 [(set_attr "type" "binary")
663 (set_attr "length" "8")])
665 ; This need only accept registers for op3, since canonicalization
666 ; replaces ltu with leu when op3 is an integer.
668 [(set (match_operand:SI 0 "register_operand" "=r")
669 (minus:SI (match_operand:SI 1 "register_operand" "r")
670 (ltu:SI (match_operand:SI 2 "register_operand" "r")
671 (match_operand:SI 3 "register_operand" "r"))))]
673 "sub %2,%3,0\;subb %1,0,%0"
674 [(set_attr "type" "binary")
675 (set_attr "length" "8")])
678 [(set (match_operand:SI 0 "register_operand" "=r")
679 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
680 (ltu:SI (match_operand:SI 2 "register_operand" "r")
681 (match_operand:SI 3 "register_operand" "r")))
682 (match_operand:SI 4 "register_operand" "r")))]
684 "sub %2,%3,0\;subb %1,%4,%0"
685 [(set_attr "type" "binary")
686 (set_attr "length" "8")])
688 ; Match only integers for op3 here. This is used as canonical form of the
689 ; ltu pattern when op3 is an integer. Don't match registers since we can't
690 ; make better code than the general incscc pattern.
692 [(set (match_operand:SI 0 "register_operand" "=r")
693 (minus:SI (match_operand:SI 1 "register_operand" "r")
694 (leu:SI (match_operand:SI 2 "register_operand" "r")
695 (match_operand:SI 3 "int11_operand" "I"))))]
697 "addi %k3,%2,0\;subb %1,0,%0"
698 [(set_attr "type" "binary")
699 (set_attr "length" "8")])
702 [(set (match_operand:SI 0 "register_operand" "=r")
703 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
704 (leu:SI (match_operand:SI 2 "register_operand" "r")
705 (match_operand:SI 3 "int11_operand" "I")))
706 (match_operand:SI 4 "register_operand" "r")))]
708 "addi %k3,%2,0\;subb %1,%4,%0"
709 [(set_attr "type" "binary")
710 (set_attr "length" "8")])
712 (define_insn "decscc"
713 [(set (match_operand:SI 0 "register_operand" "=r,r")
714 (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
715 (match_operator:SI 4 "comparison_operator"
716 [(match_operand:SI 2 "register_operand" "r,r")
717 (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
720 com%I3clr,%B4 %3,%2,0\;addi -1,%0,%0
721 com%I3clr,%B4 %3,%2,0\;addi,tr -1,%1,%0\;copy %1,%0"
722 [(set_attr "type" "binary,binary")
723 (set_attr "length" "8,12")])
725 ; Patterns for max and min. (There is no need for an earlyclobber in the
726 ; last alternative since the middle alternative will match if op0 == op1.)
728 (define_insn "sminsi3"
729 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
730 (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
731 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
734 comclr,> %2,%0,0\;copy %2,%0
735 comiclr,> %2,%0,0\;ldi %2,%0
736 comclr,> %1,%2,%0\;copy %1,%0"
737 [(set_attr "type" "multi,multi,multi")
738 (set_attr "length" "8,8,8")])
740 (define_insn "uminsi3"
741 [(set (match_operand:SI 0 "register_operand" "=r,r")
742 (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
743 (match_operand:SI 2 "arith11_operand" "r,I")))]
746 comclr,>> %2,%0,0\;copy %2,%0
747 comiclr,>> %2,%0,0\;ldi %2,%0"
748 [(set_attr "type" "multi,multi")
749 (set_attr "length" "8,8")])
751 (define_insn "smaxsi3"
752 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
753 (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
754 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
757 comclr,< %2,%0,0\;copy %2,%0
758 comiclr,< %2,%0,0\;ldi %2,%0
759 comclr,< %1,%2,%0\;copy %1,%0"
760 [(set_attr "type" "multi,multi,multi")
761 (set_attr "length" "8,8,8")])
763 (define_insn "umaxsi3"
764 [(set (match_operand:SI 0 "register_operand" "=r,r")
765 (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
766 (match_operand:SI 2 "arith11_operand" "r,I")))]
769 comclr,<< %2,%0,0\;copy %2,%0
770 comiclr,<< %2,%0,0\;ldi %2,%0"
771 [(set_attr "type" "multi,multi")
772 (set_attr "length" "8,8")])
774 (define_insn "abssi2"
775 [(set (match_operand:SI 0 "register_operand" "=r")
776 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
778 "or,>= %%r0,%1,%0\;subi 0,%0,%0"
779 [(set_attr "type" "multi")
780 (set_attr "length" "8")])
782 ;;; Experimental conditional move patterns
784 (define_expand "movsicc"
785 [(set (match_operand:SI 0 "register_operand" "")
787 (match_operator 1 "comparison_operator"
790 (match_operand:SI 2 "reg_or_cint_move_operand" "")
791 (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
795 enum rtx_code code = GET_CODE (operands[1]);
797 if (hppa_branch_type != CMP_SI)
800 /* operands[1] is currently the result of compare_from_rtx. We want to
801 emit a compare of the original operands. */
802 operands[1] = gen_rtx (code, SImode, hppa_compare_op0, hppa_compare_op1);
803 operands[4] = hppa_compare_op0;
804 operands[5] = hppa_compare_op1;
807 ; We need the first constraint alternative in order to avoid
808 ; earlyclobbers on all other alternatives.
810 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
812 (match_operator 5 "comparison_operator"
813 [(match_operand:SI 3 "register_operand" "r,r,r,r,r")
814 (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
815 (match_operand:SI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
819 com%I4clr,%S5 %4,%3,0\;ldi 0,%0
820 com%I4clr,%B5 %4,%3,%0\;copy %1,%0
821 com%I4clr,%B5 %4,%3,%0\;ldi %1,%0
822 com%I4clr,%B5 %4,%3,%0\;ldil L'%1,%0
823 com%I4clr,%B5 %4,%3,%0\;zdepi %Z1,%0"
824 [(set_attr "type" "multi,multi,multi,multi,nullshift")
825 (set_attr "length" "8,8,8,8,8")])
828 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
830 (match_operator 5 "comparison_operator"
831 [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
832 (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
833 (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
834 (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
837 com%I4clr,%S5 %4,%3,0\;copy %2,%0
838 com%I4clr,%S5 %4,%3,0\;ldi %2,%0
839 com%I4clr,%S5 %4,%3,0\;ldil L'%2,%0
840 com%I4clr,%S5 %4,%3,0\;zdepi %Z2,%0
841 com%I4clr,%B5 %4,%3,0\;copy %1,%0
842 com%I4clr,%B5 %4,%3,0\;ldi %1,%0
843 com%I4clr,%B5 %4,%3,0\;ldil L'%1,%0
844 com%I4clr,%B5 %4,%3,0\;zdepi %Z1,%0"
845 [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
846 (set_attr "length" "8,8,8,8,8,8,8,8")])
848 ;; Conditional Branches
852 (if_then_else (eq (match_dup 1) (match_dup 2))
853 (label_ref (match_operand 0 "" ""))
858 if (hppa_branch_type != CMP_SI)
860 emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1));
861 emit_bcond_fp (NE, operands[0]);
864 /* set up operands from compare. */
865 operands[1] = hppa_compare_op0;
866 operands[2] = hppa_compare_op1;
867 /* fall through and generate default code */
872 (if_then_else (ne (match_dup 1) (match_dup 2))
873 (label_ref (match_operand 0 "" ""))
878 if (hppa_branch_type != CMP_SI)
880 emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1));
881 emit_bcond_fp (NE, operands[0]);
884 operands[1] = hppa_compare_op0;
885 operands[2] = hppa_compare_op1;
890 (if_then_else (gt (match_dup 1) (match_dup 2))
891 (label_ref (match_operand 0 "" ""))
896 if (hppa_branch_type != CMP_SI)
898 emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1));
899 emit_bcond_fp (NE, operands[0]);
902 operands[1] = hppa_compare_op0;
903 operands[2] = hppa_compare_op1;
908 (if_then_else (lt (match_dup 1) (match_dup 2))
909 (label_ref (match_operand 0 "" ""))
914 if (hppa_branch_type != CMP_SI)
916 emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1));
917 emit_bcond_fp (NE, operands[0]);
920 operands[1] = hppa_compare_op0;
921 operands[2] = hppa_compare_op1;
926 (if_then_else (ge (match_dup 1) (match_dup 2))
927 (label_ref (match_operand 0 "" ""))
932 if (hppa_branch_type != CMP_SI)
934 emit_insn (gen_cmp_fp (GE, hppa_compare_op0, hppa_compare_op1));
935 emit_bcond_fp (NE, operands[0]);
938 operands[1] = hppa_compare_op0;
939 operands[2] = hppa_compare_op1;
944 (if_then_else (le (match_dup 1) (match_dup 2))
945 (label_ref (match_operand 0 "" ""))
950 if (hppa_branch_type != CMP_SI)
952 emit_insn (gen_cmp_fp (LE, hppa_compare_op0, hppa_compare_op1));
953 emit_bcond_fp (NE, operands[0]);
956 operands[1] = hppa_compare_op0;
957 operands[2] = hppa_compare_op1;
960 (define_expand "bgtu"
962 (if_then_else (gtu (match_dup 1) (match_dup 2))
963 (label_ref (match_operand 0 "" ""))
968 if (hppa_branch_type != CMP_SI)
970 operands[1] = hppa_compare_op0;
971 operands[2] = hppa_compare_op1;
974 (define_expand "bltu"
976 (if_then_else (ltu (match_dup 1) (match_dup 2))
977 (label_ref (match_operand 0 "" ""))
982 if (hppa_branch_type != CMP_SI)
984 operands[1] = hppa_compare_op0;
985 operands[2] = hppa_compare_op1;
988 (define_expand "bgeu"
990 (if_then_else (geu (match_dup 1) (match_dup 2))
991 (label_ref (match_operand 0 "" ""))
996 if (hppa_branch_type != CMP_SI)
998 operands[1] = hppa_compare_op0;
999 operands[2] = hppa_compare_op1;
1002 (define_expand "bleu"
1004 (if_then_else (leu (match_dup 1) (match_dup 2))
1005 (label_ref (match_operand 0 "" ""))
1010 if (hppa_branch_type != CMP_SI)
1012 operands[1] = hppa_compare_op0;
1013 operands[2] = hppa_compare_op1;
1016 ;; Match the branch patterns.
1019 ;; Note a long backward conditional branch with an annulled delay slot
1020 ;; has a length of 12.
1024 (match_operator 3 "comparison_operator"
1025 [(match_operand:SI 1 "register_operand" "r")
1026 (match_operand:SI 2 "arith5_operand" "rL")])
1027 (label_ref (match_operand 0 "" ""))
1032 return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1033 get_attr_length (insn), 0, insn);
1035 [(set_attr "type" "cbranch")
1036 (set (attr "length")
1037 (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1042 ;; Match the negated branch.
1047 (match_operator 3 "comparison_operator"
1048 [(match_operand:SI 1 "register_operand" "r")
1049 (match_operand:SI 2 "arith5_operand" "rL")])
1051 (label_ref (match_operand 0 "" ""))))]
1055 return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1056 get_attr_length (insn), 1, insn);
1058 [(set_attr "type" "cbranch")
1059 (set (attr "length")
1060 (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1065 ;; Branch on Bit patterns.
1069 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1071 (match_operand:SI 1 "uint5_operand" ""))
1073 (label_ref (match_operand 2 "" ""))
1078 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1079 get_attr_length (insn), 0, insn, 0);
1081 [(set_attr "type" "cbranch")
1082 (set (attr "length")
1083 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1091 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1093 (match_operand:SI 1 "uint5_operand" ""))
1096 (label_ref (match_operand 2 "" ""))))]
1100 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1101 get_attr_length (insn), 1, insn, 0);
1103 [(set_attr "type" "cbranch")
1104 (set (attr "length")
1105 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1113 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1115 (match_operand:SI 1 "uint5_operand" ""))
1117 (label_ref (match_operand 2 "" ""))
1122 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1123 get_attr_length (insn), 0, insn, 1);
1125 [(set_attr "type" "cbranch")
1126 (set (attr "length")
1127 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1135 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1137 (match_operand:SI 1 "uint5_operand" ""))
1140 (label_ref (match_operand 2 "" ""))))]
1144 return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1145 get_attr_length (insn), 1, insn, 1);
1147 [(set_attr "type" "cbranch")
1148 (set (attr "length")
1149 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1154 ;; Branch on Variable Bit patterns.
1158 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1160 (match_operand:SI 1 "register_operand" "q"))
1162 (label_ref (match_operand 2 "" ""))
1167 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1168 get_attr_length (insn), 0, insn, 0);
1170 [(set_attr "type" "cbranch")
1171 (set (attr "length")
1172 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1180 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1182 (match_operand:SI 1 "register_operand" "q"))
1185 (label_ref (match_operand 2 "" ""))))]
1189 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1190 get_attr_length (insn), 1, insn, 0);
1192 [(set_attr "type" "cbranch")
1193 (set (attr "length")
1194 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1202 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1204 (match_operand:SI 1 "register_operand" "q"))
1206 (label_ref (match_operand 2 "" ""))
1211 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1212 get_attr_length (insn), 0, insn, 1);
1214 [(set_attr "type" "cbranch")
1215 (set (attr "length")
1216 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1224 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1226 (match_operand:SI 1 "register_operand" "q"))
1229 (label_ref (match_operand 2 "" ""))))]
1233 return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1234 get_attr_length (insn), 1, insn, 1);
1236 [(set_attr "type" "cbranch")
1237 (set (attr "length")
1238 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1243 ;; Floating point branches
1245 [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
1246 (label_ref (match_operand 0 "" ""))
1248 "! TARGET_SOFT_FLOAT"
1251 if (INSN_ANNULLED_BRANCH_P (insn))
1252 return \"ftest\;bl,n %0,0\";
1254 return \"ftest\;bl%* %0,0\";
1256 [(set_attr "type" "fbranch")
1257 (set_attr "length" "8")])
1260 [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
1262 (label_ref (match_operand 0 "" ""))))]
1263 "! TARGET_SOFT_FLOAT"
1266 if (INSN_ANNULLED_BRANCH_P (insn))
1267 return \"ftest\;add,tr 0,0,0\;bl,n %0,0\";
1269 return \"ftest\;add,tr 0,0,0\;bl%* %0,0\";
1271 [(set_attr "type" "fbranch")
1272 (set_attr "length" "12")])
1274 ;; Move instructions
1276 (define_expand "movsi"
1277 [(set (match_operand:SI 0 "general_operand" "")
1278 (match_operand:SI 1 "general_operand" ""))]
1282 if (emit_move_sequence (operands, SImode, 0))
1286 ;; Reloading an SImode or DImode value requires a scratch register if
1287 ;; going in to or out of float point registers.
1289 (define_expand "reload_insi"
1290 [(set (match_operand:SI 0 "register_operand" "=Z")
1291 (match_operand:SI 1 "non_hard_reg_operand" ""))
1292 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1296 if (emit_move_sequence (operands, SImode, operands[2]))
1299 /* We don't want the clobber emitted, so handle this ourselves. */
1300 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
1304 (define_expand "reload_outsi"
1305 [(set (match_operand:SI 0 "non_hard_reg_operand" "")
1306 (match_operand:SI 1 "register_operand" "Z"))
1307 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1311 if (emit_move_sequence (operands, SImode, operands[2]))
1314 /* We don't want the clobber emitted, so handle this ourselves. */
1315 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
1319 ;;; pic symbol references
1322 [(set (match_operand:SI 0 "register_operand" "=r")
1323 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
1324 (match_operand:SI 2 "symbolic_operand" ""))))]
1325 "flag_pic && operands[1] == pic_offset_table_rtx"
1327 [(set_attr "type" "load")
1328 (set_attr "length" "4")])
1331 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
1332 "=r,r,r,r,r,Q,*q,!f,f,*TR")
1333 (match_operand:SI 1 "move_operand"
1334 "r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
1335 "(register_operand (operands[0], SImode)
1336 || reg_or_0_operand (operands[1], SImode))
1337 && ! TARGET_SOFT_FLOAT"
1349 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
1350 (set_attr "pa_combine_type" "addmove")
1351 (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
1354 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
1356 (match_operand:SI 1 "move_operand"
1357 "r,J,N,K,RQ,rM,rM"))]
1358 "(register_operand (operands[0], SImode)
1359 || reg_or_0_operand (operands[1], SImode))
1360 && TARGET_SOFT_FLOAT"
1369 [(set_attr "type" "move,move,move,move,load,store,move")
1370 (set_attr "pa_combine_type" "addmove")
1371 (set_attr "length" "4,4,4,4,4,4,4")])
1374 [(set (match_operand:SI 0 "register_operand" "=r")
1375 (mem:SI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
1376 (match_operand:SI 2 "register_operand" "r"))))]
1377 "! TARGET_DISABLE_INDEXING"
1380 /* Reload can create backwards (relative to cse) unscaled index
1381 address modes when eliminating registers and possibly for
1382 pseudos that don't get hard registers. Deal with it. */
1383 if (operands[2] == hard_frame_pointer_rtx
1384 || operands[2] == stack_pointer_rtx)
1385 return \"ldwx %1(0,%2),%0\";
1387 return \"ldwx %2(0,%1),%0\";
1389 [(set_attr "type" "load")
1390 (set_attr "length" "4")])
1393 [(set (match_operand:SI 0 "register_operand" "=r")
1394 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
1395 (match_operand:SI 2 "basereg_operand" "r"))))]
1396 "! TARGET_DISABLE_INDEXING"
1399 /* Reload can create backwards (relative to cse) unscaled index
1400 address modes when eliminating registers and possibly for
1401 pseudos that don't get hard registers. Deal with it. */
1402 if (operands[1] == hard_frame_pointer_rtx
1403 || operands[1] == stack_pointer_rtx)
1404 return \"ldwx %2(0,%1),%0\";
1406 return \"ldwx %1(0,%2),%0\";
1408 [(set_attr "type" "load")
1409 (set_attr "length" "4")])
1411 ;; Load or store with base-register modification.
1413 (define_insn "pre_ldwm"
1414 [(set (match_operand:SI 0 "register_operand" "=r")
1415 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "=r")
1416 (match_operand:SI 2 "pre_cint_operand" ""))))
1418 (plus:SI (match_dup 1) (match_dup 2)))]
1422 if (INTVAL (operands[2]) < 0)
1423 return \"ldwm %2(0,%1),%0\";
1424 return \"ldws,mb %2(0,%1),%0\";
1426 [(set_attr "type" "load")
1427 (set_attr "length" "4")])
1429 (define_insn "pre_stwm"
1430 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "=r")
1431 (match_operand:SI 1 "pre_cint_operand" "")))
1432 (match_operand:SI 2 "reg_or_0_operand" "rM"))
1434 (plus:SI (match_dup 0) (match_dup 1)))]
1438 if (INTVAL (operands[1]) < 0)
1439 return \"stwm %r2,%1(0,%0)\";
1440 return \"stws,mb %r2,%1(0,%0)\";
1442 [(set_attr "type" "store")
1443 (set_attr "length" "4")])
1445 (define_insn "post_ldwm"
1446 [(set (match_operand:SI 0 "register_operand" "=r")
1447 (mem:SI (match_operand:SI 1 "register_operand" "=r")))
1449 (plus:SI (match_dup 1)
1450 (match_operand:SI 2 "post_cint_operand" "")))]
1454 if (INTVAL (operands[2]) > 0)
1455 return \"ldwm %2(0,%1),%0\";
1456 return \"ldws,ma %2(0,%1),%0\";
1458 [(set_attr "type" "load")
1459 (set_attr "length" "4")])
1461 (define_insn "post_stwm"
1462 [(set (mem:SI (match_operand:SI 0 "register_operand" "=r"))
1463 (match_operand:SI 1 "reg_or_0_operand" "rM"))
1465 (plus:SI (match_dup 0)
1466 (match_operand:SI 2 "post_cint_operand" "")))]
1470 if (INTVAL (operands[2]) > 0)
1471 return \"stwm %r1,%2(0,%0)\";
1472 return \"stws,ma %r1,%2(0,%0)\";
1474 [(set_attr "type" "store")
1475 (set_attr "length" "4")])
1478 ;; Note since this pattern can be created at reload time (via movsi), all
1479 ;; the same rules for movsi apply here. (no new pseudos, no temporaries).
1480 (define_insn "pic_load_label"
1481 [(set (match_operand:SI 0 "register_operand" "=a")
1482 (match_operand:SI 1 "pic_label_operand" ""))]
1486 rtx label_rtx = gen_label_rtx ();
1488 extern FILE *asm_out_file;
1490 xoperands[0] = operands[0];
1491 xoperands[1] = operands[1];
1492 xoperands[2] = label_rtx;
1493 output_asm_insn (\"bl .+8,%0\", xoperands);
1494 output_asm_insn (\"depi 0,31,2,%0\", xoperands);
1495 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
1496 CODE_LABEL_NUMBER (label_rtx));
1498 /* If we're trying to load the address of a label that happens to be
1499 close, then we can use a shorter sequence. */
1500 if (GET_CODE (operands[1]) == LABEL_REF
1502 && abs (insn_addresses[INSN_UID (XEXP (operands[1], 0))]
1503 - insn_addresses[INSN_UID (insn)]) < 8100)
1505 /* Prefixing with R% here is wrong, it extracts just 11 bits and is
1506 always non-negative. */
1507 output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
1511 output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
1512 output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
1516 [(set_attr "type" "multi")
1517 (set_attr "length" "16")]) ; 12 or 16
1519 (define_insn "pic2_highpart"
1520 [(set (match_operand:SI 0 "register_operand" "=a")
1521 (plus:SI (match_operand:SI 1 "register_operand" "r")
1522 (high:SI (match_operand 2 "" ""))))]
1523 "symbolic_operand (operands[2], Pmode)
1524 && ! function_label_operand (operands[2])
1527 [(set_attr "type" "binary")
1528 (set_attr "length" "4")])
1530 ; We need this to make sure CSE doesn't simplify a memory load with a
1531 ; symbolic address, whose content it think it knows. For PIC, what CSE
1532 ; think is the real value will be the address of that value.
1533 (define_insn "pic2_lo_sum"
1534 [(set (match_operand:SI 0 "register_operand" "=r")
1535 (mem:SI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1536 (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")] 0))))]
1542 return \"ldw RT'%G2(%1),%0\";
1544 [(set_attr "type" "load")
1545 (set_attr "length" "4")])
1548 ;; Always use addil rather than ldil;add sequences. This allows the
1549 ;; HP linker to eliminate the dp relocation if the symbolic operand
1550 ;; lives in the TEXT space.
1552 [(set (match_operand:SI 0 "register_operand" "=a")
1553 (high:SI (match_operand 1 "" "")))]
1554 "symbolic_operand (operands[1], Pmode)
1555 && ! function_label_operand (operands[1])
1556 && ! read_only_operand (operands[1])
1560 if (TARGET_LONG_LOAD_STORE)
1561 return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
1563 return \"addil LR'%H1,%%r27\";
1565 [(set_attr "type" "binary")
1566 (set (attr "length")
1567 (if_then_else (eq (symbol_ref "TARGET_LONG_LOAD_STORE") (const_int 0))
1572 ;; This is for use in the prologue/epilogue code. We need it
1573 ;; to add large constants to a stack pointer or frame pointer.
1574 ;; Because of the additional %r1 pressure, we probably do not
1575 ;; want to use this in general code, so make it available
1576 ;; only after reload.
1577 (define_insn "add_high_const"
1578 [(set (match_operand:SI 0 "register_operand" "=!a,*r")
1579 (plus:SI (match_operand:SI 1 "register_operand" "r,r")
1580 (high:SI (match_operand 2 "const_int_operand" ""))))]
1584 ldil L'%G2,%0\;addl %0,%1,%0"
1585 [(set_attr "type" "binary,binary")
1586 (set_attr "length" "4,8")])
1588 ;; For function addresses.
1590 [(set (match_operand:SI 0 "register_operand" "=r")
1591 (high:SI (match_operand:SI 1 "function_label_operand" "")))]
1592 "!TARGET_PORTABLE_RUNTIME"
1594 [(set_attr "type" "move")
1595 (set_attr "length" "4")])
1597 ;; This version is used only for the portable runtime conventions model
1598 ;; (it does not use/support plabels)
1600 [(set (match_operand:SI 0 "register_operand" "=r")
1601 (high:SI (match_operand:SI 1 "function_label_operand" "")))]
1602 "TARGET_PORTABLE_RUNTIME"
1604 [(set_attr "type" "move")
1605 (set_attr "length" "4")])
1608 [(set (match_operand:SI 0 "register_operand" "=r")
1609 (high:SI (match_operand 1 "" "")))]
1610 "(!flag_pic || !symbolic_operand (operands[1]), Pmode)
1611 && !is_function_label_plus_const (operands[1])"
1614 if (symbolic_operand (operands[1], Pmode))
1615 return \"ldil LR'%H1,%0\";
1617 return \"ldil L'%G1,%0\";
1619 [(set_attr "type" "move")
1620 (set_attr "length" "4")])
1622 ;; lo_sum of a function address.
1624 ;; Note since we are not supporting MPE style external calls we can
1625 ;; use the short ldil;ldo sequence. If one wanted to support
1626 ;; MPE external calls you would want to generate something like
1627 ;; ldil;ldo;extru;ldw;add. See the HP compiler's output for details.
1629 [(set (match_operand:SI 0 "register_operand" "=r")
1630 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1631 (match_operand:SI 2 "function_label_operand" "")))]
1632 "!TARGET_PORTABLE_RUNTIME"
1634 [(set_attr "type" "move")
1635 (set_attr "length" "4")])
1637 ;; This version is used only for the portable runtime conventions model
1638 ;; (it does not use/support plabels)
1640 [(set (match_operand:SI 0 "register_operand" "=r")
1641 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1642 (match_operand:SI 2 "function_label_operand" "")))]
1643 "TARGET_PORTABLE_RUNTIME"
1645 [(set_attr "type" "move")
1646 (set_attr "length" "4")])
1649 [(set (match_operand:SI 0 "register_operand" "=r")
1650 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1651 (match_operand:SI 2 "immediate_operand" "i")))]
1652 "!is_function_label_plus_const (operands[2])"
1655 if (flag_pic && symbolic_operand (operands[2], Pmode))
1657 else if (symbolic_operand (operands[2], Pmode))
1658 return \"ldo RR'%G2(%1),%0\";
1660 return \"ldo R'%G2(%1),%0\";
1662 [(set_attr "type" "move")
1663 (set_attr "length" "4")])
1665 ;; Now that a symbolic_address plus a constant is broken up early
1666 ;; in the compilation phase (for better CSE) we need a special
1667 ;; combiner pattern to load the symbolic address plus the constant
1668 ;; in only 2 instructions. (For cases where the symbolic address
1669 ;; was not a common subexpression.)
1671 [(set (match_operand:SI 0 "register_operand" "")
1672 (match_operand:SI 1 "symbolic_operand" ""))
1673 (clobber (match_operand:SI 2 "register_operand" ""))]
1674 "! (flag_pic && pic_label_operand (operands[1], SImode))"
1675 [(set (match_dup 2) (high:SI (match_dup 1)))
1676 (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
1679 ;; hppa_legitimize_address goes to a great deal of trouble to
1680 ;; create addresses which use indexing. In some cases, this
1681 ;; is a lose because there isn't any store instructions which
1682 ;; allow indexed addresses (with integer register source).
1684 ;; These define_splits try to turn a 3 insn store into
1685 ;; a 2 insn store with some creative RTL rewriting.
1687 [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
1688 (match_operand:SI 1 "shadd_operand" ""))
1689 (plus:SI (match_operand:SI 2 "register_operand" "")
1690 (match_operand:SI 3 "const_int_operand" ""))))
1691 (match_operand:SI 4 "register_operand" ""))
1692 (clobber (match_operand:SI 5 "register_operand" ""))]
1694 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
1696 (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
1700 [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
1701 (match_operand:SI 1 "shadd_operand" ""))
1702 (plus:SI (match_operand:SI 2 "register_operand" "")
1703 (match_operand:SI 3 "const_int_operand" ""))))
1704 (match_operand:HI 4 "register_operand" ""))
1705 (clobber (match_operand:SI 5 "register_operand" ""))]
1707 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
1709 (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
1713 [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
1714 (match_operand:SI 1 "shadd_operand" ""))
1715 (plus:SI (match_operand:SI 2 "register_operand" "")
1716 (match_operand:SI 3 "const_int_operand" ""))))
1717 (match_operand:QI 4 "register_operand" ""))
1718 (clobber (match_operand:SI 5 "register_operand" ""))]
1720 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
1722 (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
1725 (define_expand "movhi"
1726 [(set (match_operand:HI 0 "general_operand" "")
1727 (match_operand:HI 1 "general_operand" ""))]
1731 if (emit_move_sequence (operands, HImode, 0))
1736 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!f")
1737 (match_operand:HI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!fM"))]
1738 "register_operand (operands[0], HImode)
1739 || reg_or_0_operand (operands[1], HImode)"
1749 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
1750 (set_attr "pa_combine_type" "addmove")
1751 (set_attr "length" "4,4,4,4,4,4,4,4")])
1754 [(set (match_operand:HI 0 "register_operand" "=r")
1755 (mem:HI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
1756 (match_operand:SI 2 "register_operand" "r"))))]
1757 "! TARGET_DISABLE_INDEXING"
1760 /* Reload can create backwards (relative to cse) unscaled index
1761 address modes when eliminating registers and possibly for
1762 pseudos that don't get hard registers. Deal with it. */
1763 if (operands[2] == hard_frame_pointer_rtx
1764 || operands[2] == stack_pointer_rtx)
1765 return \"ldhx %1(0,%2),%0\";
1767 return \"ldhx %2(0,%1),%0\";
1769 [(set_attr "type" "load")
1770 (set_attr "length" "4")])
1773 [(set (match_operand:HI 0 "register_operand" "=r")
1774 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
1775 (match_operand:SI 2 "basereg_operand" "r"))))]
1776 "! TARGET_DISABLE_INDEXING"
1779 /* Reload can create backwards (relative to cse) unscaled index
1780 address modes when eliminating registers and possibly for
1781 pseudos that don't get hard registers. Deal with it. */
1782 if (operands[1] == hard_frame_pointer_rtx
1783 || operands[1] == stack_pointer_rtx)
1784 return \"ldhx %2(0,%1),%0\";
1786 return \"ldhx %1(0,%2),%0\";
1788 [(set_attr "type" "load")
1789 (set_attr "length" "4")])
1791 ; Now zero extended variants.
1793 [(set (match_operand:SI 0 "register_operand" "=r")
1794 (zero_extend:SI (mem:HI
1796 (match_operand:SI 1 "basereg_operand" "r")
1797 (match_operand:SI 2 "register_operand" "r")))))]
1798 "! TARGET_DISABLE_INDEXING"
1801 /* Reload can create backwards (relative to cse) unscaled index
1802 address modes when eliminating registers and possibly for
1803 pseudos that don't get hard registers. Deal with it. */
1804 if (operands[2] == hard_frame_pointer_rtx
1805 || operands[2] == stack_pointer_rtx)
1806 return \"ldhx %1(0,%2),%0\";
1808 return \"ldhx %2(0,%1),%0\";
1810 [(set_attr "type" "load")
1811 (set_attr "length" "4")])
1814 [(set (match_operand:SI 0 "register_operand" "=r")
1815 (zero_extend:SI (mem:HI
1817 (match_operand:SI 1 "register_operand" "r")
1818 (match_operand:SI 2 "basereg_operand" "r")))))]
1819 "! TARGET_DISABLE_INDEXING"
1822 /* Reload can create backwards (relative to cse) unscaled index
1823 address modes when eliminating registers and possibly for
1824 pseudos that don't get hard registers. Deal with it. */
1825 if (operands[1] == hard_frame_pointer_rtx
1826 || operands[1] == stack_pointer_rtx)
1827 return \"ldhx %2(0,%1),%0\";
1829 return \"ldhx %1(0,%2),%0\";
1831 [(set_attr "type" "load")
1832 (set_attr "length" "4")])
1835 [(set (match_operand:HI 0 "register_operand" "=r")
1836 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "=r")
1837 (match_operand:SI 2 "int5_operand" "L"))))
1839 (plus:SI (match_dup 1) (match_dup 2)))]
1841 "ldhs,mb %2(0,%1),%0"
1842 [(set_attr "type" "load")
1843 (set_attr "length" "4")])
1845 ; And a zero extended variant.
1847 [(set (match_operand:SI 0 "register_operand" "=r")
1848 (zero_extend:SI (mem:HI
1850 (match_operand:SI 1 "register_operand" "=r")
1851 (match_operand:SI 2 "int5_operand" "L")))))
1853 (plus:SI (match_dup 1) (match_dup 2)))]
1855 "ldhs,mb %2(0,%1),%0"
1856 [(set_attr "type" "load")
1857 (set_attr "length" "4")])
1860 [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "=r")
1861 (match_operand:SI 1 "int5_operand" "L")))
1862 (match_operand:HI 2 "reg_or_0_operand" "rM"))
1864 (plus:SI (match_dup 0) (match_dup 1)))]
1866 "sths,mb %r2,%1(0,%0)"
1867 [(set_attr "type" "store")
1868 (set_attr "length" "4")])
1871 [(set (match_operand:HI 0 "register_operand" "=r")
1872 (high:HI (match_operand 1 "const_int_operand" "")))]
1875 [(set_attr "type" "move")
1876 (set_attr "length" "4")])
1879 [(set (match_operand:HI 0 "register_operand" "=r")
1880 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
1881 (match_operand 2 "const_int_operand" "")))]
1884 [(set_attr "type" "move")
1885 (set_attr "length" "4")])
1887 (define_expand "movqi"
1888 [(set (match_operand:QI 0 "general_operand" "")
1889 (match_operand:QI 1 "general_operand" ""))]
1893 if (emit_move_sequence (operands, QImode, 0))
1898 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!f")
1899 (match_operand:QI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!fM"))]
1900 "register_operand (operands[0], QImode)
1901 || reg_or_0_operand (operands[1], QImode)"
1911 [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
1912 (set_attr "pa_combine_type" "addmove")
1913 (set_attr "length" "4,4,4,4,4,4,4,4")])
1916 [(set (match_operand:QI 0 "register_operand" "=r")
1917 (mem:QI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
1918 (match_operand:SI 2 "register_operand" "r"))))]
1919 "! TARGET_DISABLE_INDEXING"
1922 /* Reload can create backwards (relative to cse) unscaled index
1923 address modes when eliminating registers and possibly for
1924 pseudos that don't get hard registers. Deal with it. */
1925 if (operands[2] == hard_frame_pointer_rtx
1926 || operands[2] == stack_pointer_rtx)
1927 return \"ldbx %1(0,%2),%0\";
1929 return \"ldbx %2(0,%1),%0\";
1931 [(set_attr "type" "load")
1932 (set_attr "length" "4")])
1935 [(set (match_operand:QI 0 "register_operand" "=r")
1936 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
1937 (match_operand:SI 2 "basereg_operand" "r"))))]
1938 "! TARGET_DISABLE_INDEXING"
1941 /* Reload can create backwards (relative to cse) unscaled index
1942 address modes when eliminating registers and possibly for
1943 pseudos that don't get hard registers. Deal with it. */
1944 if (operands[1] == hard_frame_pointer_rtx
1945 || operands[1] == stack_pointer_rtx)
1946 return \"ldbx %2(0,%1),%0\";
1948 return \"ldbx %1(0,%2),%0\";
1950 [(set_attr "type" "load")
1951 (set_attr "length" "4")])
1953 ; Indexed byte load with zero extension to SImode or HImode.
1955 [(set (match_operand:SI 0 "register_operand" "=r")
1956 (zero_extend:SI (mem:QI
1958 (match_operand:SI 1 "basereg_operand" "r")
1959 (match_operand:SI 2 "register_operand" "r")))))]
1960 "! TARGET_DISABLE_INDEXING"
1963 /* Reload can create backwards (relative to cse) unscaled index
1964 address modes when eliminating registers and possibly for
1965 pseudos that don't get hard registers. Deal with it. */
1966 if (operands[2] == hard_frame_pointer_rtx
1967 || operands[2] == stack_pointer_rtx)
1968 return \"ldbx %1(0,%2),%0\";
1970 return \"ldbx %2(0,%1),%0\";
1972 [(set_attr "type" "load")
1973 (set_attr "length" "4")])
1976 [(set (match_operand:SI 0 "register_operand" "=r")
1977 (zero_extend:SI (mem:QI
1979 (match_operand:SI 1 "register_operand" "r")
1980 (match_operand:SI 2 "basereg_operand" "r")))))]
1981 "! TARGET_DISABLE_INDEXING"
1984 /* Reload can create backwards (relative to cse) unscaled index
1985 address modes when eliminating registers and possibly for
1986 pseudos that don't get hard registers. Deal with it. */
1987 if (operands[1] == hard_frame_pointer_rtx
1988 || operands[1] == stack_pointer_rtx)
1989 return \"ldbx %2(0,%1),%0\";
1991 return \"ldbx %1(0,%2),%0\";
1993 [(set_attr "type" "load")
1994 (set_attr "length" "4")])
1997 [(set (match_operand:HI 0 "register_operand" "=r")
1998 (zero_extend:HI (mem:QI
2000 (match_operand:SI 1 "basereg_operand" "r")
2001 (match_operand:SI 2 "register_operand" "r")))))]
2002 "! TARGET_DISABLE_INDEXING"
2005 /* Reload can create backwards (relative to cse) unscaled index
2006 address modes when eliminating registers and possibly for
2007 pseudos that don't get hard registers. Deal with it. */
2008 if (operands[2] == hard_frame_pointer_rtx
2009 || operands[2] == stack_pointer_rtx)
2010 return \"ldbx %1(0,%2),%0\";
2012 return \"ldbx %2(0,%1),%0\";
2014 [(set_attr "type" "load")
2015 (set_attr "length" "4")])
2018 [(set (match_operand:HI 0 "register_operand" "=r")
2019 (zero_extend:HI (mem:QI
2021 (match_operand:SI 1 "register_operand" "r")
2022 (match_operand:SI 2 "basereg_operand" "r")))))]
2023 "! TARGET_DISABLE_INDEXING"
2026 /* Reload can create backwards (relative to cse) unscaled index
2027 address modes when eliminating registers and possibly for
2028 pseudos that don't get hard registers. Deal with it. */
2029 if (operands[1] == hard_frame_pointer_rtx
2030 || operands[1] == stack_pointer_rtx)
2031 return \"ldbx %2(0,%1),%0\";
2033 return \"ldbx %1(0,%2),%0\";
2035 [(set_attr "type" "load")
2036 (set_attr "length" "4")])
2039 [(set (match_operand:QI 0 "register_operand" "=r")
2040 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "=r")
2041 (match_operand:SI 2 "int5_operand" "L"))))
2042 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2044 "ldbs,mb %2(0,%1),%0"
2045 [(set_attr "type" "load")
2046 (set_attr "length" "4")])
2048 ; Now the same thing with zero extensions.
2050 [(set (match_operand:SI 0 "register_operand" "=r")
2051 (zero_extend:SI (mem:QI (plus:SI
2052 (match_operand:SI 1 "register_operand" "=r")
2053 (match_operand:SI 2 "int5_operand" "L")))))
2054 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2056 "ldbs,mb %2(0,%1),%0"
2057 [(set_attr "type" "load")
2058 (set_attr "length" "4")])
2061 [(set (match_operand:HI 0 "register_operand" "=r")
2062 (zero_extend:HI (mem:QI (plus:SI
2063 (match_operand:SI 1 "register_operand" "=r")
2064 (match_operand:SI 2 "int5_operand" "L")))))
2065 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2067 "ldbs,mb %2(0,%1),%0"
2068 [(set_attr "type" "load")
2069 (set_attr "length" "4")])
2072 [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "=r")
2073 (match_operand:SI 1 "int5_operand" "L")))
2074 (match_operand:QI 2 "reg_or_0_operand" "rM"))
2076 (plus:SI (match_dup 0) (match_dup 1)))]
2078 "stbs,mb %r2,%1(0,%0)"
2079 [(set_attr "type" "store")
2080 (set_attr "length" "4")])
2082 ;; The definition of this insn does not really explain what it does,
2083 ;; but it should suffice
2084 ;; that anything generated as this insn will be recognized as one
2085 ;; and that it will not successfully combine with anything.
2086 (define_expand "movstrsi"
2087 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
2088 (mem:BLK (match_operand:BLK 1 "" "")))
2089 (clobber (match_dup 0))
2090 (clobber (match_dup 1))
2091 (clobber (match_dup 4))
2092 (clobber (match_dup 5))
2093 (use (match_operand:SI 2 "arith_operand" ""))
2094 (use (match_operand:SI 3 "const_int_operand" ""))])]
2099 /* HP provides very fast block move library routine for the PA;
2100 this routine includes:
2102 4x4 byte at a time block moves,
2103 1x4 byte at a time with alignment checked at runtime with
2104 attempts to align the source and destination as needed
2107 With that in mind, here's the heuristics to try and guess when
2108 the inlined block move will be better than the library block
2111 If the size isn't constant, then always use the library routines.
2113 If the size is large in respect to the known alignment, then use
2114 the library routines.
2116 If the size is small in repsect to the known alignment, then open
2117 code the copy (since that will lead to better scheduling).
2119 Else use the block move pattern. */
2121 /* Undetermined size, use the library routine. */
2122 if (GET_CODE (operands[2]) != CONST_INT)
2125 size = INTVAL (operands[2]);
2126 align = INTVAL (operands[3]);
2127 align = align > 4 ? 4 : align;
2129 /* If size/alignment > 8 (eg size is large in respect to alignment),
2130 then use the library routines. */
2131 if (size/align > 16)
2134 /* This does happen, but not often enough to worry much about. */
2135 if (size/align < MOVE_RATIO)
2138 /* Fall through means we're going to use our block move pattern. */
2139 operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
2140 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2141 operands[4] = gen_reg_rtx (SImode);
2142 operands[5] = gen_reg_rtx (SImode);
2143 emit_insn (gen_movstrsi_internal (operands[0], operands[1], operands[4],
2144 operands[5], operands[2], operands[3],
2145 gen_reg_rtx (SImode)));
2149 ;; The operand constraints are written like this to support both compile-time
2150 ;; and run-time determined byte count. If the count is run-time determined,
2151 ;; the register with the byte count is clobbered by the copying code, and
2152 ;; therefore it is forced to operand 2. If the count is compile-time
2153 ;; determined, we need two scratch registers for the unrolled code.
2154 (define_insn "movstrsi_internal"
2155 [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
2156 (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
2157 (clobber (match_dup 0))
2158 (clobber (match_dup 1))
2159 (clobber (match_operand:SI 2 "register_operand" "=r,r")) ;loop cnt/tmp
2160 (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp
2161 (clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
2162 (use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count
2163 (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
2165 "* return output_block_move (operands, !which_alternative);"
2166 [(set_attr "type" "multi,multi")])
2168 ;; Floating point move insns
2170 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2171 ;; to be reloaded by putting the constant into memory when
2172 ;; reg is a floating point register.
2174 ;; For integer registers we use ldil;ldo to set the appropriate
2177 ;; This must come before the movdf pattern, and it must be present
2178 ;; to handle obscure reloading cases.
2180 [(set (match_operand:DF 0 "register_operand" "=?r,f")
2181 (match_operand:DF 1 "" "?F,m"))]
2182 "GET_CODE (operands[1]) == CONST_DOUBLE
2183 && operands[1] != CONST0_RTX (DFmode)
2184 && ! TARGET_SOFT_FLOAT"
2185 "* return (which_alternative == 0 ? output_move_double (operands)
2186 : \"fldd%F1 %1,%0\");"
2187 [(set_attr "type" "move,fpload")
2188 (set_attr "length" "16,4")])
2190 (define_expand "movdf"
2191 [(set (match_operand:DF 0 "general_operand" "")
2192 (match_operand:DF 1 "general_operand" ""))]
2196 if (emit_move_sequence (operands, DFmode, 0))
2200 ;; Reloading an SImode or DImode value requires a scratch register if
2201 ;; going in to or out of float point registers.
2203 (define_expand "reload_indf"
2204 [(set (match_operand:DF 0 "register_operand" "=Z")
2205 (match_operand:DF 1 "non_hard_reg_operand" ""))
2206 (clobber (match_operand:DF 2 "register_operand" "=&r"))]
2210 if (emit_move_sequence (operands, DFmode, operands[2]))
2213 /* We don't want the clobber emitted, so handle this ourselves. */
2214 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
2218 (define_expand "reload_outdf"
2219 [(set (match_operand:DF 0 "non_hard_reg_operand" "")
2220 (match_operand:DF 1 "register_operand" "Z"))
2221 (clobber (match_operand:DF 2 "register_operand" "=&r"))]
2225 if (emit_move_sequence (operands, DFmode, operands[2]))
2228 /* We don't want the clobber emitted, so handle this ourselves. */
2229 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
2234 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
2235 "=f,*r,RQ,?o,?Q,f,*r,*r")
2236 (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
2237 "fG,*rG,f,*r,*r,RQ,o,Q"))]
2238 "(register_operand (operands[0], DFmode)
2239 || reg_or_0_operand (operands[1], DFmode))
2240 && ! (GET_CODE (operands[1]) == CONST_DOUBLE
2241 && GET_CODE (operands[0]) == MEM)
2242 && ! TARGET_SOFT_FLOAT"
2245 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
2246 || operands[1] == CONST0_RTX (DFmode))
2247 return output_fp_move_double (operands);
2248 return output_move_double (operands);
2250 [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load")
2251 (set_attr "length" "4,8,4,8,16,4,8,16")])
2254 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
2256 (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
2258 "(register_operand (operands[0], DFmode)
2259 || reg_or_0_operand (operands[1], DFmode))
2260 && TARGET_SOFT_FLOAT"
2263 return output_move_double (operands);
2265 [(set_attr "type" "move,store,store,load,load")
2266 (set_attr "length" "8,8,16,8,16")])
2269 [(set (match_operand:DF 0 "register_operand" "=fx")
2270 (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2271 (match_operand:SI 2 "register_operand" "r"))))]
2272 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2275 /* Reload can create backwards (relative to cse) unscaled index
2276 address modes when eliminating registers and possibly for
2277 pseudos that don't get hard registers. Deal with it. */
2278 if (operands[2] == hard_frame_pointer_rtx
2279 || operands[2] == stack_pointer_rtx)
2280 return \"flddx %1(0,%2),%0\";
2282 return \"flddx %2(0,%1),%0\";
2284 [(set_attr "type" "fpload")
2285 (set_attr "length" "4")])
2288 [(set (match_operand:DF 0 "register_operand" "=fx")
2289 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
2290 (match_operand:SI 2 "basereg_operand" "r"))))]
2291 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2294 /* Reload can create backwards (relative to cse) unscaled index
2295 address modes when eliminating registers and possibly for
2296 pseudos that don't get hard registers. Deal with it. */
2297 if (operands[1] == hard_frame_pointer_rtx
2298 || operands[1] == stack_pointer_rtx)
2299 return \"flddx %2(0,%1),%0\";
2301 return \"flddx %1(0,%2),%0\";
2303 [(set_attr "type" "fpload")
2304 (set_attr "length" "4")])
2307 [(set (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2308 (match_operand:SI 2 "register_operand" "r")))
2309 (match_operand:DF 0 "register_operand" "fx"))]
2310 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2313 /* Reload can create backwards (relative to cse) unscaled index
2314 address modes when eliminating registers and possibly for
2315 pseudos that don't get hard registers. Deal with it. */
2316 if (operands[2] == hard_frame_pointer_rtx
2317 || operands[2] == stack_pointer_rtx)
2318 return \"fstdx %0,%1(0,%2)\";
2320 return \"fstdx %0,%2(0,%1)\";
2322 [(set_attr "type" "fpstore")
2323 (set_attr "length" "4")])
2326 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
2327 (match_operand:SI 2 "basereg_operand" "r")))
2328 (match_operand:DF 0 "register_operand" "fx"))]
2329 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2332 /* Reload can create backwards (relative to cse) unscaled index
2333 address modes when eliminating registers and possibly for
2334 pseudos that don't get hard registers. Deal with it. */
2335 if (operands[1] == hard_frame_pointer_rtx
2336 || operands[1] == stack_pointer_rtx)
2337 return \"fstdx %0,%2(0,%1)\";
2339 return \"fstdx %0,%1(0,%2)\";
2341 [(set_attr "type" "fpstore")
2342 (set_attr "length" "4")])
2344 (define_expand "movdi"
2345 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2346 (match_operand:DI 1 "general_operand" ""))]
2350 if (emit_move_sequence (operands, DImode, 0))
2354 (define_expand "reload_indi"
2355 [(set (match_operand:DI 0 "register_operand" "=f")
2356 (match_operand:DI 1 "non_hard_reg_operand" ""))
2357 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2361 if (emit_move_sequence (operands, DImode, operands[2]))
2364 /* We don't want the clobber emitted, so handle this ourselves. */
2365 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
2369 (define_expand "reload_outdi"
2370 [(set (match_operand:DI 0 "general_operand" "")
2371 (match_operand:DI 1 "register_operand" "f"))
2372 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2376 if (emit_move_sequence (operands, DImode, operands[2]))
2379 /* We don't want the clobber emitted, so handle this ourselves. */
2380 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
2385 [(set (match_operand:DI 0 "register_operand" "=r")
2386 (high:DI (match_operand 1 "" "")))]
2390 rtx op0 = operands[0];
2391 rtx op1 = operands[1];
2393 if (GET_CODE (op1) == CONST_INT)
2395 operands[0] = operand_subword (op0, 1, 0, DImode);
2396 output_asm_insn (\"ldil L'%1,%0\", operands);
2398 operands[0] = operand_subword (op0, 0, 0, DImode);
2399 if (INTVAL (op1) < 0)
2400 output_asm_insn (\"ldi -1,%0\", operands);
2402 output_asm_insn (\"ldi 0,%0\", operands);
2405 else if (GET_CODE (op1) == CONST_DOUBLE)
2407 operands[0] = operand_subword (op0, 1, 0, DImode);
2408 operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
2409 output_asm_insn (\"ldil L'%1,%0\", operands);
2411 operands[0] = operand_subword (op0, 0, 0, DImode);
2412 operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
2413 output_asm_insn (singlemove_string (operands), operands);
2419 [(set_attr "type" "move")
2420 (set_attr "length" "8")])
2425 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
2426 "=r,o,Q,r,r,r,f,f,*TR")
2427 (match_operand:DI 1 "general_operand"
2428 "rM,r,r,o,Q,i,fM,*TR,f"))]
2429 "(register_operand (operands[0], DImode)
2430 || reg_or_0_operand (operands[1], DImode))
2431 && ! TARGET_SOFT_FLOAT"
2434 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
2435 || (operands[1] == CONST0_RTX (DImode)))
2436 return output_fp_move_double (operands);
2437 return output_move_double (operands);
2439 [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore")
2440 (set_attr "length" "8,8,16,8,16,16,4,4,4")])
2443 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
2445 (match_operand:DI 1 "general_operand"
2447 "(register_operand (operands[0], DImode)
2448 || reg_or_0_operand (operands[1], DImode))
2449 && TARGET_SOFT_FLOAT"
2452 return output_move_double (operands);
2454 [(set_attr "type" "move,store,store,load,load,multi")
2455 (set_attr "length" "8,8,16,8,16,16")])
2458 [(set (match_operand:DI 0 "register_operand" "=r,&r")
2459 (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
2460 (match_operand:DI 2 "immediate_operand" "i,i")))]
2464 /* Don't output a 64 bit constant, since we can't trust the assembler to
2465 handle it correctly. */
2466 if (GET_CODE (operands[2]) == CONST_DOUBLE)
2467 operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
2468 if (which_alternative == 1)
2469 output_asm_insn (\"copy %1,%0\", operands);
2470 return \"ldo R'%G2(%R1),%R0\";
2472 [(set_attr "type" "move,move")
2473 (set_attr "length" "4,8")])
2475 ;; This pattern forces (set (reg:SF ...) (const_double ...))
2476 ;; to be reloaded by putting the constant into memory when
2477 ;; reg is a floating point register.
2479 ;; For integer registers we use ldil;ldo to set the appropriate
2482 ;; This must come before the movsf pattern, and it must be present
2483 ;; to handle obscure reloading cases.
2485 [(set (match_operand:SF 0 "register_operand" "=?r,f")
2486 (match_operand:SF 1 "" "?F,m"))]
2487 "GET_CODE (operands[1]) == CONST_DOUBLE
2488 && operands[1] != CONST0_RTX (SFmode)
2489 && ! TARGET_SOFT_FLOAT"
2490 "* return (which_alternative == 0 ? singlemove_string (operands)
2491 : \" fldw%F1 %1,%0\");"
2492 [(set_attr "type" "move,fpload")
2493 (set_attr "length" "8,4")])
2495 (define_expand "movsf"
2496 [(set (match_operand:SF 0 "general_operand" "")
2497 (match_operand:SF 1 "general_operand" ""))]
2501 if (emit_move_sequence (operands, SFmode, 0))
2505 ;; Reloading an SImode or DImode value requires a scratch register if
2506 ;; going in to or out of float point registers.
2508 (define_expand "reload_insf"
2509 [(set (match_operand:SF 0 "register_operand" "=Z")
2510 (match_operand:SF 1 "non_hard_reg_operand" ""))
2511 (clobber (match_operand:SF 2 "register_operand" "=&r"))]
2515 if (emit_move_sequence (operands, SFmode, operands[2]))
2518 /* We don't want the clobber emitted, so handle this ourselves. */
2519 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
2523 (define_expand "reload_outsf"
2524 [(set (match_operand:SF 0 "non_hard_reg_operand" "")
2525 (match_operand:SF 1 "register_operand" "Z"))
2526 (clobber (match_operand:SF 2 "register_operand" "=&r"))]
2530 if (emit_move_sequence (operands, SFmode, operands[2]))
2533 /* We don't want the clobber emitted, so handle this ourselves. */
2534 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
2539 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
2541 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
2542 "fG,rG,RQ,RQ,f,rG"))]
2543 "(register_operand (operands[0], SFmode)
2544 || reg_or_0_operand (operands[1], SFmode))
2545 && ! TARGET_SOFT_FLOAT"
2553 [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
2554 (set_attr "pa_combine_type" "addmove")
2555 (set_attr "length" "4,4,4,4,4,4")])
2558 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
2560 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
2562 "(register_operand (operands[0], SFmode)
2563 || reg_or_0_operand (operands[1], SFmode))
2564 && TARGET_SOFT_FLOAT"
2569 [(set_attr "type" "move,load,store")
2570 (set_attr "pa_combine_type" "addmove")
2571 (set_attr "length" "4,4,4")])
2574 [(set (match_operand:SF 0 "register_operand" "=fx")
2575 (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2576 (match_operand:SI 2 "register_operand" "r"))))]
2577 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2580 /* Reload can create backwards (relative to cse) unscaled index
2581 address modes when eliminating registers and possibly for
2582 pseudos that don't get hard registers. Deal with it. */
2583 if (operands[2] == hard_frame_pointer_rtx
2584 || operands[2] == stack_pointer_rtx)
2585 return \"fldwx %1(0,%2),%0\";
2587 return \"fldwx %2(0,%1),%0\";
2589 [(set_attr "type" "fpload")
2590 (set_attr "length" "4")])
2593 [(set (match_operand:SF 0 "register_operand" "=fx")
2594 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
2595 (match_operand:SI 2 "basereg_operand" "r"))))]
2596 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2599 /* Reload can create backwards (relative to cse) unscaled index
2600 address modes when eliminating registers and possibly for
2601 pseudos that don't get hard registers. Deal with it. */
2602 if (operands[1] == hard_frame_pointer_rtx
2603 || operands[1] == stack_pointer_rtx)
2604 return \"fldwx %2(0,%1),%0\";
2606 return \"fldwx %1(0,%2),%0\";
2608 [(set_attr "type" "fpload")
2609 (set_attr "length" "4")])
2612 [(set (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2613 (match_operand:SI 2 "register_operand" "r")))
2614 (match_operand:SF 0 "register_operand" "fx"))]
2615 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2618 /* Reload can create backwards (relative to cse) unscaled index
2619 address modes when eliminating registers and possibly for
2620 pseudos that don't get hard registers. Deal with it. */
2621 if (operands[2] == hard_frame_pointer_rtx
2622 || operands[2] == stack_pointer_rtx)
2623 return \"fstwx %0,%1(0,%2)\";
2625 return \"fstwx %0,%2(0,%1)\";
2627 [(set_attr "type" "fpstore")
2628 (set_attr "length" "4")])
2631 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
2632 (match_operand:SI 2 "basereg_operand" "r")))
2633 (match_operand:SF 0 "register_operand" "fx"))]
2634 "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2637 /* Reload can create backwards (relative to cse) unscaled index
2638 address modes when eliminating registers and possibly for
2639 pseudos that don't get hard registers. Deal with it. */
2640 if (operands[1] == hard_frame_pointer_rtx
2641 || operands[1] == stack_pointer_rtx)
2642 return \"fstwx %0,%2(0,%1)\";
2644 return \"fstwx %0,%1(0,%2)\";
2646 [(set_attr "type" "fpstore")
2647 (set_attr "length" "4")])
2650 ;;- zero extension instructions
2651 ;; We have define_expand for zero extension patterns to make sure the
2652 ;; operands get loaded into registers. The define_insns accept
2653 ;; memory operands. This gives us better overall code than just
2654 ;; having a pattern that does or does not accept memory operands.
2656 (define_expand "zero_extendhisi2"
2657 [(set (match_operand:SI 0 "register_operand" "")
2659 (match_operand:HI 1 "register_operand" "")))]
2664 [(set (match_operand:SI 0 "register_operand" "=r,r")
2666 (match_operand:HI 1 "move_operand" "r,RQ")))]
2667 "GET_CODE (operands[1]) != CONST_INT"
2671 [(set_attr "type" "shift,load")
2672 (set_attr "length" "4,4")])
2674 (define_expand "zero_extendqihi2"
2675 [(set (match_operand:HI 0 "register_operand" "")
2677 (match_operand:QI 1 "register_operand" "")))]
2682 [(set (match_operand:HI 0 "register_operand" "=r,r")
2684 (match_operand:QI 1 "move_operand" "r,RQ")))]
2685 "GET_CODE (operands[1]) != CONST_INT"
2689 [(set_attr "type" "shift,load")
2690 (set_attr "length" "4,4")])
2692 (define_expand "zero_extendqisi2"
2693 [(set (match_operand:SI 0 "register_operand" "")
2695 (match_operand:QI 1 "register_operand" "")))]
2700 [(set (match_operand:SI 0 "register_operand" "=r,r")
2702 (match_operand:QI 1 "move_operand" "r,RQ")))]
2703 "GET_CODE (operands[1]) != CONST_INT"
2707 [(set_attr "type" "shift,load")
2708 (set_attr "length" "4,4")])
2710 ;;- sign extension instructions
2712 (define_insn "extendhisi2"
2713 [(set (match_operand:SI 0 "register_operand" "=r")
2714 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2717 [(set_attr "type" "shift")
2718 (set_attr "length" "4")])
2720 (define_insn "extendqihi2"
2721 [(set (match_operand:HI 0 "register_operand" "=r")
2722 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
2725 [(set_attr "type" "shift")
2726 (set_attr "length" "4")])
2728 (define_insn "extendqisi2"
2729 [(set (match_operand:SI 0 "register_operand" "=r")
2730 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2733 [(set_attr "type" "shift")
2734 (set_attr "length" "4")])
2736 ;; Conversions between float and double.
2738 (define_insn "extendsfdf2"
2739 [(set (match_operand:DF 0 "register_operand" "=f")
2741 (match_operand:SF 1 "register_operand" "f")))]
2742 "! TARGET_SOFT_FLOAT"
2743 "fcnvff,sgl,dbl %1,%0"
2744 [(set_attr "type" "fpalu")
2745 (set_attr "length" "4")])
2747 (define_insn "truncdfsf2"
2748 [(set (match_operand:SF 0 "register_operand" "=f")
2750 (match_operand:DF 1 "register_operand" "f")))]
2751 "! TARGET_SOFT_FLOAT"
2752 "fcnvff,dbl,sgl %1,%0"
2753 [(set_attr "type" "fpalu")
2754 (set_attr "length" "4")])
2756 ;; Conversion between fixed point and floating point.
2757 ;; Note that among the fix-to-float insns
2758 ;; the ones that start with SImode come first.
2759 ;; That is so that an operand that is a CONST_INT
2760 ;; (and therefore lacks a specific machine mode).
2761 ;; will be recognized as SImode (which is always valid)
2762 ;; rather than as QImode or HImode.
2764 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
2765 ;; to be reloaded by putting the constant into memory.
2766 ;; It must come before the more general floatsisf2 pattern.
2768 [(set (match_operand:SF 0 "register_operand" "=f")
2769 (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
2770 "! TARGET_SOFT_FLOAT"
2771 "fldw%F1 %1,%0\;fcnvxf,sgl,sgl %0,%0"
2772 [(set_attr "type" "fpalu")
2773 (set_attr "length" "8")])
2775 (define_insn "floatsisf2"
2776 [(set (match_operand:SF 0 "register_operand" "=f")
2777 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2778 "! TARGET_SOFT_FLOAT"
2779 "fcnvxf,sgl,sgl %1,%0"
2780 [(set_attr "type" "fpalu")
2781 (set_attr "length" "4")])
2783 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
2784 ;; to be reloaded by putting the constant into memory.
2785 ;; It must come before the more general floatsidf2 pattern.
2787 [(set (match_operand:DF 0 "register_operand" "=f")
2788 (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
2789 "! TARGET_SOFT_FLOAT"
2790 "fldw%F1 %1,%0\;fcnvxf,sgl,dbl %0,%0"
2791 [(set_attr "type" "fpalu")
2792 (set_attr "length" "8")])
2794 (define_insn "floatsidf2"
2795 [(set (match_operand:DF 0 "register_operand" "=f")
2796 (float:DF (match_operand:SI 1 "register_operand" "f")))]
2797 "! TARGET_SOFT_FLOAT"
2798 "fcnvxf,sgl,dbl %1,%0"
2799 [(set_attr "type" "fpalu")
2800 (set_attr "length" "4")])
2802 (define_expand "floatunssisf2"
2803 [(set (subreg:SI (match_dup 2) 1)
2804 (match_operand:SI 1 "register_operand" ""))
2805 (set (subreg:SI (match_dup 2) 0)
2807 (set (match_operand:SF 0 "register_operand" "")
2808 (float:SF (match_dup 2)))]
2809 "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
2810 "operands[2] = gen_reg_rtx (DImode);")
2812 (define_expand "floatunssidf2"
2813 [(set (subreg:SI (match_dup 2) 1)
2814 (match_operand:SI 1 "register_operand" ""))
2815 (set (subreg:SI (match_dup 2) 0)
2817 (set (match_operand:DF 0 "register_operand" "")
2818 (float:DF (match_dup 2)))]
2819 "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
2820 "operands[2] = gen_reg_rtx (DImode);")
2822 (define_insn "floatdisf2"
2823 [(set (match_operand:SF 0 "register_operand" "=f")
2824 (float:SF (match_operand:DI 1 "register_operand" "f")))]
2825 "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
2826 "fcnvxf,dbl,sgl %1,%0"
2827 [(set_attr "type" "fpalu")
2828 (set_attr "length" "4")])
2830 (define_insn "floatdidf2"
2831 [(set (match_operand:DF 0 "register_operand" "=f")
2832 (float:DF (match_operand:DI 1 "register_operand" "f")))]
2833 "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
2834 "fcnvxf,dbl,dbl %1,%0"
2835 [(set_attr "type" "fpalu")
2836 (set_attr "length" "4")])
2838 ;; Convert a float to an actual integer.
2839 ;; Truncation is performed as part of the conversion.
2841 (define_insn "fix_truncsfsi2"
2842 [(set (match_operand:SI 0 "register_operand" "=f")
2843 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
2844 "! TARGET_SOFT_FLOAT"
2845 "fcnvfxt,sgl,sgl %1,%0"
2846 [(set_attr "type" "fpalu")
2847 (set_attr "length" "4")])
2849 (define_insn "fix_truncdfsi2"
2850 [(set (match_operand:SI 0 "register_operand" "=f")
2851 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
2852 "! TARGET_SOFT_FLOAT"
2853 "fcnvfxt,dbl,sgl %1,%0"
2854 [(set_attr "type" "fpalu")
2855 (set_attr "length" "4")])
2857 (define_insn "fix_truncsfdi2"
2858 [(set (match_operand:DI 0 "register_operand" "=f")
2859 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
2860 "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
2861 "fcnvfxt,sgl,dbl %1,%0"
2862 [(set_attr "type" "fpalu")
2863 (set_attr "length" "4")])
2865 (define_insn "fix_truncdfdi2"
2866 [(set (match_operand:DI 0 "register_operand" "=f")
2867 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
2868 "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
2869 "fcnvfxt,dbl,dbl %1,%0"
2870 [(set_attr "type" "fpalu")
2871 (set_attr "length" "4")])
2873 ;;- arithmetic instructions
2875 (define_insn "adddi3"
2876 [(set (match_operand:DI 0 "register_operand" "=r")
2877 (plus:DI (match_operand:DI 1 "register_operand" "%r")
2878 (match_operand:DI 2 "arith11_operand" "rI")))]
2882 if (GET_CODE (operands[2]) == CONST_INT)
2884 if (INTVAL (operands[2]) >= 0)
2885 return \"addi %2,%R1,%R0\;addc %1,0,%0\";
2887 return \"addi %2,%R1,%R0\;subb %1,0,%0\";
2890 return \"add %R2,%R1,%R0\;addc %2,%1,%0\";
2892 [(set_attr "type" "binary")
2893 (set_attr "length" "8")])
2896 [(set (match_operand:SI 0 "register_operand" "=r")
2897 (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2898 (match_operand:SI 2 "register_operand" "r")))]
2901 [(set_attr "type" "binary")
2902 (set_attr "length" "4")])
2904 ;; define_splits to optimize cases of adding a constant integer
2905 ;; to a register when the constant does not fit in 14 bits. */
2907 [(set (match_operand:SI 0 "register_operand" "")
2908 (plus:SI (match_operand:SI 1 "register_operand" "")
2909 (match_operand:SI 2 "const_int_operand" "")))
2910 (clobber (match_operand:SI 4 "register_operand" ""))]
2911 "! cint_ok_for_move (INTVAL (operands[2]))
2912 && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
2913 [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
2914 (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
2917 int val = INTVAL (operands[2]);
2918 int low = (val < 0) ? -0x2000 : 0x1fff;
2919 int rest = val - low;
2921 operands[2] = GEN_INT (rest);
2922 operands[3] = GEN_INT (low);
2926 [(set (match_operand:SI 0 "register_operand" "")
2927 (plus:SI (match_operand:SI 1 "register_operand" "")
2928 (match_operand:SI 2 "const_int_operand" "")))
2929 (clobber (match_operand:SI 4 "register_operand" ""))]
2930 "! cint_ok_for_move (INTVAL (operands[2]))"
2931 [(set (match_dup 4) (match_dup 2))
2932 (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
2936 HOST_WIDE_INT intval = INTVAL (operands[2]);
2938 /* Try dividing the constant by 2, then 4, and finally 8 to see
2939 if we can get a constant which can be loaded into a register
2940 in a single instruction (cint_ok_for_move).
2942 If that fails, try to negate the constant and subtract it
2943 from our input operand. */
2944 if (intval % 2 == 0 && cint_ok_for_move (intval / 2))
2946 operands[2] = GEN_INT (intval / 2);
2947 operands[3] = GEN_INT (2);
2949 else if (intval % 4 == 0 && cint_ok_for_move (intval / 4))
2951 operands[2] = GEN_INT (intval / 4);
2952 operands[3] = GEN_INT (4);
2954 else if (intval % 8 == 0 && cint_ok_for_move (intval / 8))
2956 operands[2] = GEN_INT (intval / 8);
2957 operands[3] = GEN_INT (8);
2959 else if (cint_ok_for_move (-intval))
2961 emit_insn (gen_rtx (SET, VOIDmode, operands[4], GEN_INT (-intval)));
2962 emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
2969 (define_insn "addsi3"
2970 [(set (match_operand:SI 0 "register_operand" "=r,r")
2971 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
2972 (match_operand:SI 2 "arith_operand" "r,J")))]
2977 [(set_attr "type" "binary,binary")
2978 (set_attr "pa_combine_type" "addmove")
2979 (set_attr "length" "4,4")])
2981 ;; Disgusting kludge to work around reload bugs with frame pointer
2982 ;; elimination. Similar to other magic reload patterns in the
2983 ;; indexed memory operations.
2985 [(set (match_operand:SI 0 "register_operand" "=&r")
2986 (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "%r")
2987 (match_operand:SI 2 "register_operand" "r"))
2988 (match_operand:SI 3 "const_int_operand" "rL")))]
2989 "reload_in_progress"
2992 if (GET_CODE (operands[3]) == CONST_INT)
2993 return \"ldo %3(%2),%0\;addl %1,%0,%0\";
2995 return \"addl %3,%2,%0\;addl %1,%0,%0\";
2997 [(set_attr "type" "binary")
2998 (set_attr "length" "8")])
3000 (define_insn "subdi3"
3001 [(set (match_operand:DI 0 "register_operand" "=r")
3002 (minus:DI (match_operand:DI 1 "register_operand" "r")
3003 (match_operand:DI 2 "register_operand" "r")))]
3005 "sub %R1,%R2,%R0\;subb %1,%2,%0"
3006 [(set_attr "type" "binary")
3007 (set_attr "length" "8")])
3009 (define_insn "subsi3"
3010 [(set (match_operand:SI 0 "register_operand" "=r,r")
3011 (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
3012 (match_operand:SI 2 "register_operand" "r,r")))]
3017 [(set_attr "type" "binary,binary")
3018 (set_attr "length" "4,4")])
3020 ;; Clobbering a "register_operand" instead of a match_scratch
3021 ;; in operand3 of millicode calls avoids spilling %r1 and
3022 ;; produces better code.
3024 ;; The mulsi3 insns set up registers for the millicode call.
3025 (define_expand "mulsi3"
3026 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3027 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3028 (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
3029 (clobber (match_dup 3))
3030 (clobber (reg:SI 26))
3031 (clobber (reg:SI 25))
3032 (clobber (reg:SI 31))])
3033 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3037 if (TARGET_SNAKE && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT)
3039 rtx scratch = gen_reg_rtx (DImode);
3040 operands[1] = force_reg (SImode, operands[1]);
3041 operands[2] = force_reg (SImode, operands[2]);
3042 emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
3043 emit_insn (gen_rtx (SET, VOIDmode,
3045 gen_rtx (SUBREG, SImode, scratch, 1)));
3048 operands[3] = gen_reg_rtx (SImode);
3051 (define_insn "umulsidi3"
3052 [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3053 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3054 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
3055 "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
3057 [(set_attr "type" "fpmuldbl")
3058 (set_attr "length" "4")])
3061 [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3062 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3063 (match_operand:DI 2 "uint32_operand" "f")))]
3064 "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
3066 [(set_attr "type" "fpmuldbl")
3067 (set_attr "length" "4")])
3070 [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
3071 (clobber (match_operand:SI 0 "register_operand" "=a"))
3072 (clobber (reg:SI 26))
3073 (clobber (reg:SI 25))
3074 (clobber (reg:SI 31))]
3076 "* return output_mul_insn (0, insn);"
3077 [(set_attr "type" "milli")
3078 (set (attr "length")
3080 ;; Target (or stub) within reach
3081 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3083 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3088 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3092 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3093 ;; same as NO_SPACE_REGS code
3094 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3096 (eq (symbol_ref "flag_pic")
3100 ;; Out of range and either PIC or PORTABLE_RUNTIME
3103 ;;; Division and mod.
3104 (define_expand "divsi3"
3105 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3106 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3107 (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
3108 (clobber (match_dup 3))
3109 (clobber (reg:SI 26))
3110 (clobber (reg:SI 25))
3111 (clobber (reg:SI 31))])
3112 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3116 operands[3] = gen_reg_rtx (SImode);
3117 if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
3123 (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
3124 (clobber (match_operand:SI 1 "register_operand" "=a"))
3125 (clobber (reg:SI 26))
3126 (clobber (reg:SI 25))
3127 (clobber (reg:SI 31))]
3130 return output_div_insn (operands, 0, insn);"
3131 [(set_attr "type" "milli")
3132 (set (attr "length")
3134 ;; Target (or stub) within reach
3135 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3137 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3142 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3146 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3147 ;; same as NO_SPACE_REGS code
3148 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3150 (eq (symbol_ref "flag_pic")
3154 ;; Out of range and either PIC or PORTABLE_RUNTIME
3157 (define_expand "udivsi3"
3158 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3159 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3160 (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
3161 (clobber (match_dup 3))
3162 (clobber (reg:SI 26))
3163 (clobber (reg:SI 25))
3164 (clobber (reg:SI 31))])
3165 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3169 operands[3] = gen_reg_rtx (SImode);
3170 if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
3176 (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
3177 (clobber (match_operand:SI 1 "register_operand" "=a"))
3178 (clobber (reg:SI 26))
3179 (clobber (reg:SI 25))
3180 (clobber (reg:SI 31))]
3183 return output_div_insn (operands, 1, insn);"
3184 [(set_attr "type" "milli")
3185 (set (attr "length")
3187 ;; Target (or stub) within reach
3188 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3190 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3195 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3199 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3200 ;; same as NO_SPACE_REGS code
3201 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3203 (eq (symbol_ref "flag_pic")
3207 ;; Out of range and either PIC or PORTABLE_RUNTIME
3210 (define_expand "modsi3"
3211 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3212 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3213 (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
3214 (clobber (match_dup 3))
3215 (clobber (reg:SI 26))
3216 (clobber (reg:SI 25))
3217 (clobber (reg:SI 31))])
3218 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3222 operands[3] = gen_reg_rtx (SImode);
3226 [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
3227 (clobber (match_operand:SI 0 "register_operand" "=a"))
3228 (clobber (reg:SI 26))
3229 (clobber (reg:SI 25))
3230 (clobber (reg:SI 31))]
3233 return output_mod_insn (0, insn);"
3234 [(set_attr "type" "milli")
3235 (set (attr "length")
3237 ;; Target (or stub) within reach
3238 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3240 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3245 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3249 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3250 ;; same as NO_SPACE_REGS code
3251 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3253 (eq (symbol_ref "flag_pic")
3257 ;; Out of range and either PIC or PORTABLE_RUNTIME
3260 (define_expand "umodsi3"
3261 [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3262 (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3263 (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
3264 (clobber (match_dup 3))
3265 (clobber (reg:SI 26))
3266 (clobber (reg:SI 25))
3267 (clobber (reg:SI 31))])
3268 (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3272 operands[3] = gen_reg_rtx (SImode);
3276 [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
3277 (clobber (match_operand:SI 0 "register_operand" "=a"))
3278 (clobber (reg:SI 26))
3279 (clobber (reg:SI 25))
3280 (clobber (reg:SI 31))]
3283 return output_mod_insn (1, insn);"
3284 [(set_attr "type" "milli")
3285 (set (attr "length")
3287 ;; Target (or stub) within reach
3288 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3290 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3295 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3299 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3300 ;; same as NO_SPACE_REGS code
3301 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3303 (eq (symbol_ref "flag_pic")
3307 ;; Out of range and either PIC or PORTABLE_RUNTIME
3310 ;;- and instructions
3311 ;; We define DImode `and` so with DImode `not` we can get
3312 ;; DImode `andn`. Other combinations are possible.
3314 (define_expand "anddi3"
3315 [(set (match_operand:DI 0 "register_operand" "")
3316 (and:DI (match_operand:DI 1 "arith_double_operand" "")
3317 (match_operand:DI 2 "arith_double_operand" "")))]
3321 if (! register_operand (operands[1], DImode)
3322 || ! register_operand (operands[2], DImode))
3323 /* Let GCC break this into word-at-a-time operations. */
3328 [(set (match_operand:DI 0 "register_operand" "=r")
3329 (and:DI (match_operand:DI 1 "register_operand" "%r")
3330 (match_operand:DI 2 "register_operand" "r")))]
3332 "and %1,%2,%0\;and %R1,%R2,%R0"
3333 [(set_attr "type" "binary")
3334 (set_attr "length" "8")])
3336 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
3337 ; constant with ldil;ldo.
3338 (define_insn "andsi3"
3339 [(set (match_operand:SI 0 "register_operand" "=r,r")
3340 (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
3341 (match_operand:SI 2 "and_operand" "rO,P")))]
3343 "* return output_and (operands); "
3344 [(set_attr "type" "binary,shift")
3345 (set_attr "length" "4,4")])
3348 [(set (match_operand:DI 0 "register_operand" "=r")
3349 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3350 (match_operand:DI 2 "register_operand" "r")))]
3352 "andcm %2,%1,%0\;andcm %R2,%R1,%R0"
3353 [(set_attr "type" "binary")
3354 (set_attr "length" "8")])
3357 [(set (match_operand:SI 0 "register_operand" "=r")
3358 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3359 (match_operand:SI 2 "register_operand" "r")))]
3362 [(set_attr "type" "binary")
3363 (set_attr "length" "4")])
3365 (define_expand "iordi3"
3366 [(set (match_operand:DI 0 "register_operand" "")
3367 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
3368 (match_operand:DI 2 "arith_double_operand" "")))]
3372 if (! register_operand (operands[1], DImode)
3373 || ! register_operand (operands[2], DImode))
3374 /* Let GCC break this into word-at-a-time operations. */
3379 [(set (match_operand:DI 0 "register_operand" "=r")
3380 (ior:DI (match_operand:DI 1 "register_operand" "%r")
3381 (match_operand:DI 2 "register_operand" "r")))]
3383 "or %1,%2,%0\;or %R1,%R2,%R0"
3384 [(set_attr "type" "binary")
3385 (set_attr "length" "8")])
3387 ;; Need a define_expand because we've run out of CONST_OK... characters.
3388 (define_expand "iorsi3"
3389 [(set (match_operand:SI 0 "register_operand" "")
3390 (ior:SI (match_operand:SI 1 "register_operand" "")
3391 (match_operand:SI 2 "arith32_operand" "")))]
3395 if (! (ior_operand (operands[2]) || register_operand (operands[2])))
3396 operands[2] = force_reg (SImode, operands[2]);
3400 [(set (match_operand:SI 0 "register_operand" "=r,r")
3401 (ior:SI (match_operand:SI 1 "register_operand" "0,0")
3402 (match_operand:SI 2 "ior_operand" "M,i")))]
3404 "* return output_ior (operands); "
3405 [(set_attr "type" "binary,shift")
3406 (set_attr "length" "4,4")])
3409 [(set (match_operand:SI 0 "register_operand" "=r")
3410 (ior:SI (match_operand:SI 1 "register_operand" "%r")
3411 (match_operand:SI 2 "register_operand" "r")))]
3414 [(set_attr "type" "binary")
3415 (set_attr "length" "4")])
3417 (define_expand "xordi3"
3418 [(set (match_operand:DI 0 "register_operand" "")
3419 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
3420 (match_operand:DI 2 "arith_double_operand" "")))]
3424 if (! register_operand (operands[1], DImode)
3425 || ! register_operand (operands[2], DImode))
3426 /* Let GCC break this into word-at-a-time operations. */
3431 [(set (match_operand:DI 0 "register_operand" "=r")
3432 (xor:DI (match_operand:DI 1 "register_operand" "%r")
3433 (match_operand:DI 2 "register_operand" "r")))]
3435 "xor %1,%2,%0\;xor %R1,%R2,%R0"
3436 [(set_attr "type" "binary")
3437 (set_attr "length" "8")])
3439 (define_insn "xorsi3"
3440 [(set (match_operand:SI 0 "register_operand" "=r")
3441 (xor:SI (match_operand:SI 1 "register_operand" "%r")
3442 (match_operand:SI 2 "register_operand" "r")))]
3445 [(set_attr "type" "binary")
3446 (set_attr "length" "4")])
3448 (define_insn "negdi2"
3449 [(set (match_operand:DI 0 "register_operand" "=r")
3450 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
3452 "sub 0,%R1,%R0\;subb 0,%1,%0"
3453 [(set_attr "type" "unary")
3454 (set_attr "length" "8")])
3456 (define_insn "negsi2"
3457 [(set (match_operand:SI 0 "register_operand" "=r")
3458 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
3461 [(set_attr "type" "unary")
3462 (set_attr "length" "4")])
3464 (define_expand "one_cmpldi2"
3465 [(set (match_operand:DI 0 "register_operand" "")
3466 (not:DI (match_operand:DI 1 "arith_double_operand" "")))]
3470 if (! register_operand (operands[1], DImode))
3475 [(set (match_operand:DI 0 "register_operand" "=r")
3476 (not:DI (match_operand:DI 1 "register_operand" "r")))]
3478 "uaddcm 0,%1,%0\;uaddcm 0,%R1,%R0"
3479 [(set_attr "type" "unary")
3480 (set_attr "length" "8")])
3482 (define_insn "one_cmplsi2"
3483 [(set (match_operand:SI 0 "register_operand" "=r")
3484 (not:SI (match_operand:SI 1 "register_operand" "r")))]
3487 [(set_attr "type" "unary")
3488 (set_attr "length" "4")])
3490 ;; Floating point arithmetic instructions.
3492 (define_insn "adddf3"
3493 [(set (match_operand:DF 0 "register_operand" "=f")
3494 (plus:DF (match_operand:DF 1 "register_operand" "f")
3495 (match_operand:DF 2 "register_operand" "f")))]
3496 "! TARGET_SOFT_FLOAT"
3498 [(set_attr "type" "fpalu")
3499 (set_attr "pa_combine_type" "faddsub")
3500 (set_attr "length" "4")])
3502 (define_insn "addsf3"
3503 [(set (match_operand:SF 0 "register_operand" "=f")
3504 (plus:SF (match_operand:SF 1 "register_operand" "f")
3505 (match_operand:SF 2 "register_operand" "f")))]
3506 "! TARGET_SOFT_FLOAT"
3508 [(set_attr "type" "fpalu")
3509 (set_attr "pa_combine_type" "faddsub")
3510 (set_attr "length" "4")])
3512 (define_insn "subdf3"
3513 [(set (match_operand:DF 0 "register_operand" "=f")
3514 (minus:DF (match_operand:DF 1 "register_operand" "f")
3515 (match_operand:DF 2 "register_operand" "f")))]
3516 "! TARGET_SOFT_FLOAT"
3518 [(set_attr "type" "fpalu")
3519 (set_attr "pa_combine_type" "faddsub")
3520 (set_attr "length" "4")])
3522 (define_insn "subsf3"
3523 [(set (match_operand:SF 0 "register_operand" "=f")
3524 (minus:SF (match_operand:SF 1 "register_operand" "f")
3525 (match_operand:SF 2 "register_operand" "f")))]
3526 "! TARGET_SOFT_FLOAT"
3528 [(set_attr "type" "fpalu")
3529 (set_attr "pa_combine_type" "faddsub")
3530 (set_attr "length" "4")])
3532 (define_insn "muldf3"
3533 [(set (match_operand:DF 0 "register_operand" "=f")
3534 (mult:DF (match_operand:DF 1 "register_operand" "f")
3535 (match_operand:DF 2 "register_operand" "f")))]
3536 "! TARGET_SOFT_FLOAT"
3538 [(set_attr "type" "fpmuldbl")
3539 (set_attr "pa_combine_type" "fmpy")
3540 (set_attr "length" "4")])
3542 (define_insn "mulsf3"
3543 [(set (match_operand:SF 0 "register_operand" "=f")
3544 (mult:SF (match_operand:SF 1 "register_operand" "f")
3545 (match_operand:SF 2 "register_operand" "f")))]
3546 "! TARGET_SOFT_FLOAT"
3548 [(set_attr "type" "fpmulsgl")
3549 (set_attr "pa_combine_type" "fmpy")
3550 (set_attr "length" "4")])
3552 (define_insn "divdf3"
3553 [(set (match_operand:DF 0 "register_operand" "=f")
3554 (div:DF (match_operand:DF 1 "register_operand" "f")
3555 (match_operand:DF 2 "register_operand" "f")))]
3556 "! TARGET_SOFT_FLOAT"
3558 [(set_attr "type" "fpdivdbl")
3559 (set_attr "length" "4")])
3561 (define_insn "divsf3"
3562 [(set (match_operand:SF 0 "register_operand" "=f")
3563 (div:SF (match_operand:SF 1 "register_operand" "f")
3564 (match_operand:SF 2 "register_operand" "f")))]
3565 "! TARGET_SOFT_FLOAT"
3567 [(set_attr "type" "fpdivsgl")
3568 (set_attr "length" "4")])
3570 (define_insn "negdf2"
3571 [(set (match_operand:DF 0 "register_operand" "=f")
3572 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3573 "! TARGET_SOFT_FLOAT"
3575 [(set_attr "type" "fpalu")
3576 (set_attr "length" "4")])
3578 (define_insn "negsf2"
3579 [(set (match_operand:SF 0 "register_operand" "=f")
3580 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3581 "! TARGET_SOFT_FLOAT"
3583 [(set_attr "type" "fpalu")
3584 (set_attr "length" "4")])
3586 (define_insn "absdf2"
3587 [(set (match_operand:DF 0 "register_operand" "=f")
3588 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
3589 "! TARGET_SOFT_FLOAT"
3591 [(set_attr "type" "fpalu")
3592 (set_attr "length" "4")])
3594 (define_insn "abssf2"
3595 [(set (match_operand:SF 0 "register_operand" "=f")
3596 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
3597 "! TARGET_SOFT_FLOAT"
3599 [(set_attr "type" "fpalu")
3600 (set_attr "length" "4")])
3602 (define_insn "sqrtdf2"
3603 [(set (match_operand:DF 0 "register_operand" "=f")
3604 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
3605 "! TARGET_SOFT_FLOAT"
3607 [(set_attr "type" "fpsqrtdbl")
3608 (set_attr "length" "4")])
3610 (define_insn "sqrtsf2"
3611 [(set (match_operand:SF 0 "register_operand" "=f")
3612 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
3613 "! TARGET_SOFT_FLOAT"
3615 [(set_attr "type" "fpsqrtsgl")
3616 (set_attr "length" "4")])
3618 ;;- Shift instructions
3620 ;; Optimized special case of shifting.
3623 [(set (match_operand:SI 0 "register_operand" "=r")
3624 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3628 [(set_attr "type" "load")
3629 (set_attr "length" "4")])
3632 [(set (match_operand:SI 0 "register_operand" "=r")
3633 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3637 [(set_attr "type" "load")
3638 (set_attr "length" "4")])
3641 [(set (match_operand:SI 0 "register_operand" "=r")
3642 (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
3643 (match_operand:SI 3 "shadd_operand" ""))
3644 (match_operand:SI 1 "register_operand" "r")))]
3646 "sh%O3addl %2,%1,%0"
3647 [(set_attr "type" "binary")
3648 (set_attr "length" "4")])
3650 ;; This variant of the above insn can occur if the first operand
3651 ;; is the frame pointer. This is a kludge, but there doesn't
3652 ;; seem to be a way around it. Only recognize it while reloading.
3653 ;; Note how operand 3 uses a predicate of "const_int_operand", but
3654 ;; has constraints allowing a register. I don't know how this works,
3655 ;; but it somehow makes sure that out-of-range constants are placed
3656 ;; in a register which somehow magically is a "const_int_operand".
3657 ;; (this was stolen from alpha.md, I'm not going to try and change it.
3660 [(set (match_operand:SI 0 "register_operand" "=&r,r")
3661 (plus:SI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r,r")
3662 (match_operand:SI 4 "shadd_operand" ""))
3663 (match_operand:SI 1 "register_operand" "r,r"))
3664 (match_operand:SI 3 "const_int_operand" "r,J")))]
3665 "reload_in_progress"
3667 sh%O4addl %2,%1,%0\;addl %3,%0,%0
3668 sh%O4addl %2,%1,%0\;ldo %3(%0),%0"
3669 [(set_attr "type" "multi")
3670 (set_attr "length" "8")])
3672 (define_expand "ashlsi3"
3673 [(set (match_operand:SI 0 "register_operand" "")
3674 (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
3675 (match_operand:SI 2 "arith32_operand" "")))]
3679 if (GET_CODE (operands[2]) != CONST_INT)
3681 rtx temp = gen_reg_rtx (SImode);
3682 emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
3683 if (GET_CODE (operands[1]) == CONST_INT)
3684 emit_insn (gen_zvdep_imm (operands[0], operands[1], temp));
3686 emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
3689 /* Make sure both inputs are not constants,
3690 there are no patterns for that. */
3691 operands[1] = force_reg (SImode, operands[1]);
3695 [(set (match_operand:SI 0 "register_operand" "=r")
3696 (ashift:SI (match_operand:SI 1 "register_operand" "r")
3697 (match_operand:SI 2 "const_int_operand" "n")))]
3699 "zdep %1,%P2,%L2,%0"
3700 [(set_attr "type" "shift")
3701 (set_attr "length" "4")])
3703 ; Match cases of op1 a CONST_INT here that zvdep_imm doesn't handle.
3704 ; Doing it like this makes slightly better code since reload can
3705 ; replace a register with a known value in range -16..15 with a
3706 ; constant. Ideally, we would like to merge zvdep32 and zvdep_imm,
3707 ; but since we have no more CONST_OK... characters, that is not
3709 (define_insn "zvdep32"
3710 [(set (match_operand:SI 0 "register_operand" "=r,r")
3711 (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
3712 (minus:SI (const_int 31)
3713 (match_operand:SI 2 "register_operand" "q,q"))))]
3718 [(set_attr "type" "shift,shift")
3719 (set_attr "length" "4,4")])
3721 (define_insn "zvdep_imm"
3722 [(set (match_operand:SI 0 "register_operand" "=r")
3723 (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
3724 (minus:SI (const_int 31)
3725 (match_operand:SI 2 "register_operand" "q"))))]
3729 int x = INTVAL (operands[1]);
3730 operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
3731 operands[1] = GEN_INT ((x & 0xf) - 0x10);
3732 return \"zvdepi %1,%2,%0\";
3734 [(set_attr "type" "shift")
3735 (set_attr "length" "4")])
3737 (define_insn "vdepi_ior"
3738 [(set (match_operand:SI 0 "register_operand" "=r")
3739 (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
3740 (minus:SI (const_int 31)
3741 (match_operand:SI 2 "register_operand" "q")))
3742 (match_operand:SI 3 "register_operand" "0")))]
3743 ; accept ...0001...1, can this be generalized?
3744 "exact_log2 (INTVAL (operands[1]) + 1) >= 0"
3747 int x = INTVAL (operands[1]);
3748 operands[2] = GEN_INT (exact_log2 (x + 1));
3749 return \"vdepi -1,%2,%0\";
3751 [(set_attr "type" "shift")
3752 (set_attr "length" "4")])
3754 (define_insn "vdepi_and"
3755 [(set (match_operand:SI 0 "register_operand" "=r")
3756 (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
3757 (minus:SI (const_int 31)
3758 (match_operand:SI 2 "register_operand" "q")))
3759 (match_operand:SI 3 "register_operand" "0")))]
3760 ; this can be generalized...!
3761 "INTVAL (operands[1]) == -2"
3764 int x = INTVAL (operands[1]);
3765 operands[2] = GEN_INT (exact_log2 ((~x) + 1));
3766 return \"vdepi 0,%2,%0\";
3768 [(set_attr "type" "shift")
3769 (set_attr "length" "4")])
3771 (define_expand "ashrsi3"
3772 [(set (match_operand:SI 0 "register_operand" "")
3773 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3774 (match_operand:SI 2 "arith32_operand" "")))]
3778 if (GET_CODE (operands[2]) != CONST_INT)
3780 rtx temp = gen_reg_rtx (SImode);
3781 emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
3782 emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
3788 [(set (match_operand:SI 0 "register_operand" "=r")
3789 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
3790 (match_operand:SI 2 "const_int_operand" "n")))]
3792 "extrs %1,%P2,%L2,%0"
3793 [(set_attr "type" "shift")
3794 (set_attr "length" "4")])
3796 (define_insn "vextrs32"
3797 [(set (match_operand:SI 0 "register_operand" "=r")
3798 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
3799 (minus:SI (const_int 31)
3800 (match_operand:SI 2 "register_operand" "q"))))]
3803 [(set_attr "type" "shift")
3804 (set_attr "length" "4")])
3806 (define_insn "lshrsi3"
3807 [(set (match_operand:SI 0 "register_operand" "=r,r")
3808 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3809 (match_operand:SI 2 "arith32_operand" "q,n")))]
3813 extru %1,%P2,%L2,%0"
3814 [(set_attr "type" "shift")
3815 (set_attr "length" "4")])
3817 (define_insn "rotrsi3"
3818 [(set (match_operand:SI 0 "register_operand" "=r,r")
3819 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
3820 (match_operand:SI 2 "arith32_operand" "q,n")))]
3824 if (GET_CODE (operands[2]) == CONST_INT)
3826 operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
3827 return \"shd %1,%1,%2,%0\";
3830 return \"vshd %1,%1,%0\";
3832 [(set_attr "type" "shift")
3833 (set_attr "length" "4")])
3836 [(set (match_operand:SI 0 "register_operand" "=r")
3837 (match_operator:SI 5 "plus_xor_ior_operator"
3838 [(ashift:SI (match_operand:SI 1 "register_operand" "r")
3839 (match_operand:SI 3 "const_int_operand" "n"))
3840 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3841 (match_operand:SI 4 "const_int_operand" "n"))]))]
3842 "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
3844 [(set_attr "type" "shift")
3845 (set_attr "length" "4")])
3848 [(set (match_operand:SI 0 "register_operand" "=r")
3849 (match_operator:SI 5 "plus_xor_ior_operator"
3850 [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3851 (match_operand:SI 4 "const_int_operand" "n"))
3852 (ashift:SI (match_operand:SI 1 "register_operand" "r")
3853 (match_operand:SI 3 "const_int_operand" "n"))]))]
3854 "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
3856 [(set_attr "type" "shift")
3857 (set_attr "length" "4")])
3860 [(set (match_operand:SI 0 "register_operand" "=r")
3861 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3862 (match_operand:SI 2 "const_int_operand" ""))
3863 (match_operand:SI 3 "const_int_operand" "")))]
3864 "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) >= 0"
3867 int cnt = INTVAL (operands[2]) & 31;
3868 operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
3869 operands[2] = GEN_INT (31 - cnt);
3870 return \"zdep %1,%2,%3,%0\";
3872 [(set_attr "type" "shift")
3873 (set_attr "length" "4")])
3875 ;; Unconditional and other jump instructions.
3877 (define_insn "return"
3879 "hppa_can_use_return_insn_p ()"
3881 [(set_attr "type" "branch")
3882 (set_attr "length" "4")])
3884 ;; Use a different pattern for functions which have non-trivial
3885 ;; epilogues so as not to confuse jump and reorg.
3886 (define_insn "return_internal"
3891 [(set_attr "type" "branch")
3892 (set_attr "length" "4")])
3894 (define_expand "prologue"
3897 "hppa_expand_prologue ();DONE;")
3899 (define_expand "epilogue"
3904 /* Try to use the trivial return first. Else use the full
3906 if (hppa_can_use_return_insn_p ())
3907 emit_jump_insn (gen_return ());
3910 hppa_expand_epilogue ();
3911 emit_jump_insn (gen_return_internal ());
3916 ;; Special because we use the value placed in %r2 by the bl instruction
3917 ;; from within its delay slot to set the value for the 2nd parameter to
3919 (define_insn "call_profiler"
3920 [(unspec_volatile [(const_int 0)] 0)
3921 (use (match_operand:SI 0 "const_int_operand" ""))]
3923 "bl _mcount,%%r2\;ldo %0(%%r2),%%r25"
3924 [(set_attr "type" "multi")
3925 (set_attr "length" "8")])
3927 (define_insn "blockage"
3928 [(unspec_volatile [(const_int 2)] 0)]
3931 [(set_attr "length" "0")])
3933 (define_insn "switch_jump"
3934 [(set:DI (pc) (label_ref (match_operand 0 "" "")))]
3937 [(set_attr "type" "uncond_branch")
3938 (set_attr "length" "4")])
3941 [(set (pc) (label_ref (match_operand 0 "" "")))]
3944 [(set_attr "type" "uncond_branch")
3945 (set_attr "pa_combine_type" "uncond_branch")
3946 (set (attr "length")
3947 (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 0))
3949 ;; If the jump is in the delay slot of a call, then its length depends
3950 ;; on whether or not we can add the proper offset to %r2 with an ldo
3952 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
3957 ;; Subroutines of "casesi".
3958 ;; operand 0 is index
3959 ;; operand 1 is the minimum bound
3960 ;; operand 2 is the maximum bound - minimum bound + 1
3961 ;; operand 3 is CODE_LABEL for the table;
3962 ;; operand 4 is the CODE_LABEL to go to if index out of range.
3964 (define_expand "casesi"
3965 [(match_operand:SI 0 "general_operand" "")
3966 (match_operand:SI 1 "const_int_operand" "")
3967 (match_operand:SI 2 "const_int_operand" "")
3968 (match_operand 3 "" "")
3969 (match_operand 4 "" "")]
3973 if (GET_CODE (operands[0]) != REG)
3974 operands[0] = force_reg (SImode, operands[0]);
3976 if (operands[1] != const0_rtx)
3978 rtx reg = gen_reg_rtx (SImode);
3980 operands[1] = GEN_INT (-INTVAL (operands[1]));
3981 if (!INT_14_BITS (operands[1]))
3982 operands[1] = force_reg (SImode, operands[1]);
3983 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
3988 if (!INT_11_BITS (operands[2]))
3989 operands[2] = force_reg (SImode, operands[2]);
3991 emit_jump_insn (gen_casesi0 (operands[0], operands[2],
3992 operands[3], operands[4]));
3996 (define_insn "casesi0"
3998 (if_then_else (leu (match_operand:SI 0 "register_operand" "r")
3999 (match_operand:SI 1 "arith11_operand" "rI"))
4000 (plus:SI (mem:SI (plus:SI (pc) (match_dup 0)))
4001 (label_ref (match_operand 2 "" "")))
4003 (use (label_ref (match_operand 3 "" "")))]
4007 if (GET_CODE (operands[1]) == CONST_INT)
4009 operands[1] = GEN_INT (~INTVAL (operands[1]));
4010 return \"addi,uv %1,%0,0\;blr,n %0,0\;b,n %l3\";
4014 return \"sub,>> %0,%1,0\;blr,n %0,0\;b,n %l3\";
4017 [(set_attr "type" "multi")
4018 (set_attr "length" "12")])
4020 ;; Need nops for the calls because execution is supposed to continue
4021 ;; past; we don't want to nullify an instruction that we need.
4022 ;;- jump to subroutine
4024 (define_expand "call"
4025 [(parallel [(call (match_operand:SI 0 "" "")
4026 (match_operand 1 "" ""))
4027 (clobber (reg:SI 2))])]
4034 if (TARGET_PORTABLE_RUNTIME)
4035 op = force_reg (SImode, XEXP (operands[0], 0));
4037 op = XEXP (operands[0], 0);
4039 /* Use two different patterns for calls to explicitly named functions
4040 and calls through function pointers. This is necessary as these two
4041 types of calls use different calling conventions, and CSE might try
4042 to change the named call into an indirect call in some cases (using
4043 two patterns keeps CSE from performing this optimization). */
4044 if (GET_CODE (op) == SYMBOL_REF)
4045 call_insn = emit_call_insn (gen_call_internal_symref (op, operands[1]));
4048 rtx tmpreg = gen_rtx (REG, SImode, 22);
4049 emit_move_insn (tmpreg, force_reg (SImode, op));
4050 call_insn = emit_call_insn (gen_call_internal_reg (operands[1]));
4055 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
4057 /* After each call we must restore the PIC register, even if it
4058 doesn't appear to be used.
4060 This will set regs_ever_live for the callee saved register we
4061 stored the PIC register in. */
4062 emit_move_insn (pic_offset_table_rtx,
4063 gen_rtx (REG, SImode, PIC_OFFSET_TABLE_REGNUM_SAVED));
4064 emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx));
4066 /* Gross. We have to keep the scheduler from moving the restore
4067 of the PIC register away from the call. SCHED_GROUP_P is
4068 supposed to do this, but for some reason the compiler will
4069 go into an infinite loop when we use that.
4071 This method (blockage insn) may make worse code (then again
4072 it may not since calls are nearly blockages anyway), but at
4073 least it should work. */
4074 emit_insn (gen_blockage ());
4079 (define_insn "call_internal_symref"
4080 [(call (mem:SI (match_operand:SI 0 "call_operand_address" ""))
4081 (match_operand 1 "" "i"))
4082 (clobber (reg:SI 2))
4083 (use (const_int 0))]
4084 "! TARGET_PORTABLE_RUNTIME"
4087 output_arg_descriptor (insn);
4088 return output_call (insn, operands[0], gen_rtx (REG, SImode, 2));
4090 [(set_attr "type" "call")
4091 (set (attr "length")
4092 ;; If we're sure that we can either reach the target or that the
4093 ;; linker can use a long-branch stub, then the length is 4 bytes.
4095 ;; For long-calls the length will be either 52 bytes (non-pic)
4096 ;; or 68 bytes (pic). */
4097 ;; Else we have to use a long-call;
4098 (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
4101 (if_then_else (eq (symbol_ref "flag_pic")
4106 (define_insn "call_internal_reg"
4107 [(call (mem:SI (reg:SI 22))
4108 (match_operand 0 "" "i"))
4109 (clobber (reg:SI 2))
4110 (use (const_int 1))]
4116 /* First the special case for kernels, level 0 systems, etc. */
4117 if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
4118 return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
4120 /* Now the normal case -- we can reach $$dyncall directly or
4121 we're sure that we can get there via a long-branch stub.
4123 No need to check target flags as the length uniquely identifies
4124 the remaining cases. */
4125 if (get_attr_length (insn) == 8)
4126 return \".CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\";
4128 /* Long millicode call, but we are not generating PIC or portable runtime
4130 if (get_attr_length (insn) == 12)
4131 return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
4133 /* Long millicode call for portable runtime. */
4134 if (get_attr_length (insn) == 20)
4135 return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr 0,%%r2\;bv,n 0(%%r31)\;nop\";
4137 /* If we're generating PIC code. */
4138 xoperands[0] = operands[0];
4139 xoperands[1] = gen_label_rtx ();
4140 output_asm_insn (\"bl .+8,%%r1\", xoperands);
4141 output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
4142 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
4143 CODE_LABEL_NUMBER (xoperands[1]));
4144 output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
4145 output_asm_insn (\"blr 0,%%r2\", xoperands);
4146 output_asm_insn (\"bv,n 0(%%r1)\\n\\tnop\", xoperands);
4149 [(set_attr "type" "dyncall")
4150 (set (attr "length")
4152 ;; First NO_SPACE_REGS
4153 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
4157 ;; Target (or stub) within reach
4158 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4160 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4164 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
4165 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4167 (eq (symbol_ref "flag_pic")
4171 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4175 ;; Out of range PIC case
4178 (define_expand "call_value"
4179 [(parallel [(set (match_operand 0 "" "")
4180 (call (match_operand:SI 1 "" "")
4181 (match_operand 2 "" "")))
4182 (clobber (reg:SI 2))])]
4189 if (TARGET_PORTABLE_RUNTIME)
4190 op = force_reg (SImode, XEXP (operands[1], 0));
4192 op = XEXP (operands[1], 0);
4194 /* Use two different patterns for calls to explicitly named functions
4195 and calls through function pointers. This is necessary as these two
4196 types of calls use different calling conventions, and CSE might try
4197 to change the named call into an indirect call in some cases (using
4198 two patterns keeps CSE from performing this optimization). */
4199 if (GET_CODE (op) == SYMBOL_REF)
4200 call_insn = emit_call_insn (gen_call_value_internal_symref (operands[0],
4205 rtx tmpreg = gen_rtx (REG, SImode, 22);
4206 emit_move_insn (tmpreg, force_reg (SImode, op));
4207 call_insn = emit_call_insn (gen_call_value_internal_reg (operands[0],
4212 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
4214 /* After each call we must restore the PIC register, even if it
4215 doesn't appear to be used.
4217 This will set regs_ever_live for the callee saved register we
4218 stored the PIC register in. */
4219 emit_move_insn (pic_offset_table_rtx,
4220 gen_rtx (REG, SImode, PIC_OFFSET_TABLE_REGNUM_SAVED));
4221 emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx));
4223 /* Gross. We have to keep the scheduler from moving the restore
4224 of the PIC register away from the call. SCHED_GROUP_P is
4225 supposed to do this, but for some reason the compiler will
4226 go into an infinite loop when we use that.
4228 This method (blockage insn) may make worse code (then again
4229 it may not since calls are nearly blockages anyway), but at
4230 least it should work. */
4231 emit_insn (gen_blockage ());
4236 (define_insn "call_value_internal_symref"
4237 [(set (match_operand 0 "" "=rf")
4238 (call (mem:SI (match_operand:SI 1 "call_operand_address" ""))
4239 (match_operand 2 "" "i")))
4240 (clobber (reg:SI 2))
4241 (use (const_int 0))]
4242 ;;- Don't use operand 1 for most machines.
4243 "! TARGET_PORTABLE_RUNTIME"
4246 output_arg_descriptor (insn);
4247 return output_call (insn, operands[1], gen_rtx (REG, SImode, 2));
4249 [(set_attr "type" "call")
4250 (set (attr "length")
4251 ;; If we're sure that we can either reach the target or that the
4252 ;; linker can use a long-branch stub, then the length is 4 bytes.
4254 ;; For long-calls the length will be either 52 bytes (non-pic)
4255 ;; or 68 bytes (pic). */
4256 ;; Else we have to use a long-call;
4257 (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
4260 (if_then_else (eq (symbol_ref "flag_pic")
4265 (define_insn "call_value_internal_reg"
4266 [(set (match_operand 0 "" "=rf")
4267 (call (mem:SI (reg:SI 22))
4268 (match_operand 1 "" "i")))
4269 (clobber (reg:SI 2))
4270 (use (const_int 1))]
4276 /* First the special case for kernels, level 0 systems, etc. */
4277 if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
4278 return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
4280 /* Now the normal case -- we can reach $$dyncall directly or
4281 we're sure that we can get there via a long-branch stub.
4283 No need to check target flags as the length uniquely identifies
4284 the remaining cases. */
4285 if (get_attr_length (insn) == 8)
4286 return \".CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\";
4288 /* Long millicode call, but we are not generating PIC or portable runtime
4290 if (get_attr_length (insn) == 12)
4291 return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
4293 /* Long millicode call for portable runtime. */
4294 if (get_attr_length (insn) == 20)
4295 return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr 0,%%r2\;bv,n 0(%%r31)\;nop\";
4297 /* If we're generating PIC code. */
4298 xoperands[0] = operands[1];
4299 xoperands[1] = gen_label_rtx ();
4300 output_asm_insn (\"bl .+8,%%r1\", xoperands);
4301 output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
4302 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
4303 CODE_LABEL_NUMBER (xoperands[1]));
4304 output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
4305 output_asm_insn (\"blr 0,%%r2\", xoperands);
4306 output_asm_insn (\"bv,n 0(%%r1)\\n\\tnop\", xoperands);
4309 [(set_attr "type" "dyncall")
4310 (set (attr "length")
4312 ;; First NO_SPACE_REGS
4313 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
4317 ;; Target (or stub) within reach
4318 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4320 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4324 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
4325 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4327 (eq (symbol_ref "flag_pic")
4331 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4335 ;; Out of range PIC case
4338 ;; Call subroutine returning any type.
4340 (define_expand "untyped_call"
4341 [(parallel [(call (match_operand 0 "" "")
4343 (match_operand 1 "" "")
4344 (match_operand 2 "" "")])]
4350 emit_call_insn (gen_call (operands[0], const0_rtx));
4352 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4354 rtx set = XVECEXP (operands[2], 0, i);
4355 emit_move_insn (SET_DEST (set), SET_SRC (set));
4358 /* The optimizer does not know that the call sets the function value
4359 registers we stored in the result block. We avoid problems by
4360 claiming that all hard registers are used and clobbered at this
4362 emit_insn (gen_blockage ());
4370 [(set_attr "type" "move")
4371 (set_attr "length" "4")])
4373 ;; These are just placeholders so we know where branch tables
4375 (define_insn "begin_brtab"
4379 [(set_attr "type" "move")
4380 (set_attr "length" "0")])
4382 (define_insn "end_brtab"
4386 [(set_attr "type" "move")
4387 (set_attr "length" "0")])
4389 ;;; Hope this is only within a function...
4390 (define_insn "indirect_jump"
4391 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
4394 [(set_attr "type" "branch")
4395 (set_attr "length" "4")])
4397 (define_insn "extzv"
4398 [(set (match_operand:SI 0 "register_operand" "=r")
4399 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
4400 (match_operand:SI 2 "uint5_operand" "")
4401 (match_operand:SI 3 "uint5_operand" "")))]
4403 "extru %1,%3+%2-1,%2,%0"
4404 [(set_attr "type" "shift")
4405 (set_attr "length" "4")])
4408 [(set (match_operand:SI 0 "register_operand" "=r")
4409 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
4411 (match_operand:SI 3 "register_operand" "q")))]
4414 [(set_attr "type" "shift")
4415 (set_attr "length" "4")])
4418 [(set (match_operand:SI 0 "register_operand" "=r")
4419 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
4420 (match_operand:SI 2 "uint5_operand" "")
4421 (match_operand:SI 3 "uint5_operand" "")))]
4423 "extrs %1,%3+%2-1,%2,%0"
4424 [(set_attr "type" "shift")
4425 (set_attr "length" "4")])
4428 [(set (match_operand:SI 0 "register_operand" "=r")
4429 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
4431 (match_operand:SI 3 "register_operand" "q")))]
4434 [(set_attr "type" "shift")
4435 (set_attr "length" "4")])
4438 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
4439 (match_operand:SI 1 "uint5_operand" "")
4440 (match_operand:SI 2 "uint5_operand" ""))
4441 (match_operand:SI 3 "arith5_operand" "r,L"))]
4444 dep %3,%2+%1-1,%1,%0
4445 depi %3,%2+%1-1,%1,%0"
4446 [(set_attr "type" "shift,shift")
4447 (set_attr "length" "4,4")])
4449 ;; Optimize insertion of const_int values of type 1...1xxxx.
4451 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
4452 (match_operand:SI 1 "uint5_operand" "")
4453 (match_operand:SI 2 "uint5_operand" ""))
4454 (match_operand:SI 3 "const_int_operand" ""))]
4455 "(INTVAL (operands[3]) & 0x10) != 0 &&
4456 (~INTVAL (operands[3]) & (1L << INTVAL (operands[1])) - 1 & ~0xf) == 0"
4459 operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
4460 return \"depi %3,%2+%1-1,%1,%0\";
4462 [(set_attr "type" "shift")
4463 (set_attr "length" "4")])
4465 ;; This insn is used for some loop tests, typically loops reversed when
4466 ;; strength reduction is used. It is actually created when the instruction
4467 ;; combination phase combines the special loop test. Since this insn
4468 ;; is both a jump insn and has an output, it must deal with it's own
4469 ;; reloads, hence the `m' constraints. The `!' constraints direct reload
4470 ;; to not choose the register alternatives in the event a reload is needed.
4471 (define_insn "decrement_and_branch_until_zero"
4474 (match_operator 2 "comparison_operator"
4475 [(plus:SI (match_operand:SI 0 "register_operand" "+!r,!*f,!*m")
4476 (match_operand:SI 1 "int5_operand" "L,L,L"))
4478 (label_ref (match_operand 3 "" ""))
4481 (plus:SI (match_dup 0) (match_dup 1)))
4482 (clobber (match_scratch:SI 4 "=X,r,r"))]
4484 "* return output_dbra (operands, insn, which_alternative); "
4485 ;; Do not expect to understand this the first time through.
4486 [(set_attr "type" "cbranch,multi,multi")
4487 (set (attr "length")
4488 (if_then_else (eq_attr "alternative" "0")
4489 ;; Loop counter in register case
4490 ;; Short branch has length of 4
4491 ;; Long branch has length of 8
4492 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4497 ;; Loop counter in FP reg case.
4498 ;; Extra goo to deal with additional reload insns.
4499 (if_then_else (eq_attr "alternative" "1")
4500 (if_then_else (lt (match_dup 3) (pc))
4502 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
4507 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4511 ;; Loop counter in memory case.
4512 ;; Extra goo to deal with additional reload insns.
4513 (if_then_else (lt (match_dup 3) (pc))
4515 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
4520 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4523 (const_int 16))))))])
4525 ;; Simply another variant of the dbra pattern. More restrictive
4526 ;; in testing the comparison operator as it must worry about overflow
4531 (match_operator 2 "eq_neq_comparison_operator"
4532 [(match_operand:SI 0 "register_operand" "+!r,!*f,!*m")
4533 (match_operand:SI 5 "const_int_operand" "")])
4534 (label_ref (match_operand 3 "" ""))
4537 (plus:SI (match_dup 0) (match_operand:SI 1 "int5_operand" "L,L,L")))
4538 (clobber (match_scratch:SI 4 "=X,r,r"))]
4539 "INTVAL (operands[5]) == - INTVAL (operands[1])"
4540 "* return output_dbra (operands, insn, which_alternative);"
4541 ;; Do not expect to understand this the first time through.
4542 [(set_attr "type" "cbranch,multi,multi")
4543 (set (attr "length")
4544 (if_then_else (eq_attr "alternative" "0")
4545 ;; Loop counter in register case
4546 ;; Short branch has length of 4
4547 ;; Long branch has length of 8
4548 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4553 ;; Loop counter in FP reg case.
4554 ;; Extra goo to deal with additional reload insns.
4555 (if_then_else (eq_attr "alternative" "1")
4556 (if_then_else (lt (match_dup 3) (pc))
4558 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
4563 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4567 ;; Loop counter in memory case.
4568 ;; Extra goo to deal with additional reload insns.
4569 (if_then_else (lt (match_dup 3) (pc))
4571 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
4576 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4579 (const_int 16))))))])
4584 (match_operator 2 "movb_comparison_operator"
4585 [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
4586 (label_ref (match_operand 3 "" ""))
4588 (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
4591 "* return output_movb (operands, insn, which_alternative, 0); "
4592 ;; Do not expect to understand this the first time through.
4593 [(set_attr "type" "cbranch,multi,multi,multi")
4594 (set (attr "length")
4595 (if_then_else (eq_attr "alternative" "0")
4596 ;; Loop counter in register case
4597 ;; Short branch has length of 4
4598 ;; Long branch has length of 8
4599 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4604 ;; Loop counter in FP reg case.
4605 ;; Extra goo to deal with additional reload insns.
4606 (if_then_else (eq_attr "alternative" "1")
4607 (if_then_else (lt (match_dup 3) (pc))
4609 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
4614 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4618 ;; Loop counter in memory or sar case.
4619 ;; Extra goo to deal with additional reload insns.
4621 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4624 (const_int 12)))))])
4626 ;; Handle negated branch.
4630 (match_operator 2 "movb_comparison_operator"
4631 [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
4633 (label_ref (match_operand 3 "" ""))))
4634 (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
4637 "* return output_movb (operands, insn, which_alternative, 1); "
4638 ;; Do not expect to understand this the first time through.
4639 [(set_attr "type" "cbranch,multi,multi,multi")
4640 (set (attr "length")
4641 (if_then_else (eq_attr "alternative" "0")
4642 ;; Loop counter in register case
4643 ;; Short branch has length of 4
4644 ;; Long branch has length of 8
4645 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4650 ;; Loop counter in FP reg case.
4651 ;; Extra goo to deal with additional reload insns.
4652 (if_then_else (eq_attr "alternative" "1")
4653 (if_then_else (lt (match_dup 3) (pc))
4655 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
4660 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4664 ;; Loop counter in memory or SAR case.
4665 ;; Extra goo to deal with additional reload insns.
4667 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4670 (const_int 12)))))])
4672 ;; The next several patterns (parallel_addb, parallel_movb, fmpyadd and
4673 ;; fmpysub aren't currently used by the FSF sources, but will be soon.
4675 ;; They're in the FSF tree for documentation and to make Cygnus<->FSF
4678 [(set (pc) (label_ref (match_operand 3 "" "" )))
4679 (set (match_operand:SI 0 "register_operand" "=r")
4680 (plus:SI (match_operand:SI 1 "register_operand" "r")
4681 (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
4682 "reload_completed && operands[0] == operands[1] || operands[0] == operands[2]"
4685 return output_parallel_addb (operands, get_attr_length (insn));
4687 [(set_attr "type" "parallel_branch")
4688 (set (attr "length")
4689 (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4695 [(set (pc) (label_ref (match_operand 2 "" "" )))
4696 (set (match_operand:SF 0 "register_operand" "=r")
4697 (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
4701 return output_parallel_movb (operands, get_attr_length (insn));
4703 [(set_attr "type" "parallel_branch")
4704 (set (attr "length")
4705 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
4711 [(set (pc) (label_ref (match_operand 2 "" "" )))
4712 (set (match_operand:SI 0 "register_operand" "=r")
4713 (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
4717 return output_parallel_movb (operands, get_attr_length (insn));
4719 [(set_attr "type" "parallel_branch")
4720 (set (attr "length")
4721 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
4727 [(set (pc) (label_ref (match_operand 2 "" "" )))
4728 (set (match_operand:HI 0 "register_operand" "=r")
4729 (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
4733 return output_parallel_movb (operands, get_attr_length (insn));
4735 [(set_attr "type" "parallel_branch")
4736 (set (attr "length")
4737 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
4743 [(set (pc) (label_ref (match_operand 2 "" "" )))
4744 (set (match_operand:QI 0 "register_operand" "=r")
4745 (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
4749 return output_parallel_movb (operands, get_attr_length (insn));
4751 [(set_attr "type" "parallel_branch")
4752 (set (attr "length")
4753 (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
4759 [(set (match_operand 0 "register_operand" "=f")
4760 (mult (match_operand 1 "register_operand" "f")
4761 (match_operand 2 "register_operand" "f")))
4762 (set (match_operand 3 "register_operand" "+f")
4763 (plus (match_operand 4 "register_operand" "f")
4764 (match_operand 5 "register_operand" "f")))]
4765 "TARGET_SNAKE && ! TARGET_SOFT_FLOAT
4766 && reload_completed && fmpyaddoperands (operands)"
4769 if (GET_MODE (operands[0]) == DFmode)
4771 if (rtx_equal_p (operands[3], operands[5]))
4772 return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
4774 return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
4778 if (rtx_equal_p (operands[3], operands[5]))
4779 return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
4781 return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
4784 [(set_attr "type" "fpalu")
4785 (set_attr "length" "4")])
4788 [(set (match_operand 3 "register_operand" "+f")
4789 (plus (match_operand 4 "register_operand" "f")
4790 (match_operand 5 "register_operand" "f")))
4791 (set (match_operand 0 "register_operand" "=f")
4792 (mult (match_operand 1 "register_operand" "f")
4793 (match_operand 2 "register_operand" "f")))]
4794 "TARGET_SNAKE && ! TARGET_SOFT_FLOAT
4795 && reload_completed && fmpyaddoperands (operands)"
4798 if (GET_MODE (operands[0]) == DFmode)
4800 if (rtx_equal_p (operands[3], operands[5]))
4801 return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
4803 return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
4807 if (rtx_equal_p (operands[3], operands[5]))
4808 return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
4810 return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
4813 [(set_attr "type" "fpalu")
4814 (set_attr "length" "4")])
4817 [(set (match_operand 0 "register_operand" "=f")
4818 (mult (match_operand 1 "register_operand" "f")
4819 (match_operand 2 "register_operand" "f")))
4820 (set (match_operand 3 "register_operand" "+f")
4821 (minus (match_operand 4 "register_operand" "f")
4822 (match_operand 5 "register_operand" "f")))]
4823 "TARGET_SNAKE && ! TARGET_SOFT_FLOAT
4824 && reload_completed && fmpysuboperands (operands)"
4827 if (GET_MODE (operands[0]) == DFmode)
4828 return \"fmpysub,dbl %1,%2,%0,%5,%3\";
4830 return \"fmpysub,sgl %1,%2,%0,%5,%3\";
4832 [(set_attr "type" "fpalu")
4833 (set_attr "length" "4")])
4836 [(set (match_operand 3 "register_operand" "+f")
4837 (minus (match_operand 4 "register_operand" "f")
4838 (match_operand 5 "register_operand" "f")))
4839 (set (match_operand 0 "register_operand" "=f")
4840 (mult (match_operand 1 "register_operand" "f")
4841 (match_operand 2 "register_operand" "f")))]
4842 "TARGET_SNAKE && ! TARGET_SOFT_FLOAT
4843 && reload_completed && fmpysuboperands (operands)"
4846 if (GET_MODE (operands[0]) == DFmode)
4847 return \"fmpysub,dbl %1,%2,%0,%5,%3\";
4849 return \"fmpysub,sgl %1,%2,%0,%5,%3\";
4851 [(set_attr "type" "fpalu")
4852 (set_attr "length" "4")])
4854 ;; Clean up turds left by reload.
4856 [(set (match_operand 0 "reg_or_nonsymb_mem_operand" "")
4857 (match_operand 1 "register_operand" "f"))
4858 (set (match_operand 2 "register_operand" "f")
4860 "! TARGET_SOFT_FLOAT
4861 && GET_CODE (operands[0]) == MEM
4862 && ! MEM_VOLATILE_P (operands[0])
4863 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4864 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4865 && GET_MODE (operands[0]) == DFmode
4866 && REGNO_REG_CLASS (REGNO (operands[1]))
4867 == REGNO_REG_CLASS (REGNO (operands[2]))"
4870 enum machine_mode mode = GET_MODE (operands[0]);
4873 if (FP_REG_P (operands[1]))
4874 output_asm_insn (output_fp_move_double (operands), operands);
4876 output_asm_insn (output_move_double (operands), operands);
4878 if (rtx_equal_p (operands[1], operands[2]))
4881 xoperands[0] = operands[2];
4882 xoperands[1] = operands[1];
4884 if (FP_REG_P (xoperands[1]))
4885 output_asm_insn (output_fp_move_double (xoperands), xoperands);
4887 output_asm_insn (output_move_double (xoperands), xoperands);
4893 [(set (match_operand 0 "register_operand" "f")
4894 (match_operand 1 "reg_or_nonsymb_mem_operand" ""))
4895 (set (match_operand 2 "register_operand" "f")
4897 "! TARGET_SOFT_FLOAT
4898 && GET_CODE (operands[1]) == MEM
4899 && ! MEM_VOLATILE_P (operands[1])
4900 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4901 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4902 && GET_MODE (operands[0]) == DFmode
4903 && REGNO_REG_CLASS (REGNO (operands[1]))
4904 == REGNO_REG_CLASS (REGNO (operands[2]))"
4907 enum machine_mode mode = GET_MODE (operands[0]);
4910 if (FP_REG_P (operands[0]))
4911 output_asm_insn (output_fp_move_double (operands), operands);
4913 output_asm_insn (output_move_double (operands), operands);
4915 xoperands[0] = operands[2];
4916 xoperands[1] = operands[0];
4918 if (FP_REG_P (xoperands[1]))
4919 output_asm_insn (output_fp_move_double (xoperands), xoperands);
4921 output_asm_insn (output_move_double (xoperands), xoperands);
4926 ;; Flush the I and D cache line found at the address in operand 0.
4927 ;; This is used by the trampoline code for nested functions.
4928 ;; So long as the trampoline itself is less than 32 bytes this
4931 (define_insn "dcacheflush"
4932 [(unspec_volatile [(const_int 1)] 0)
4933 (use (mem:SI (match_operand:SI 0 "register_operand" "r")))
4934 (use (mem:SI (match_operand:SI 1 "register_operand" "r")))]
4936 "fdc 0(0,%0)\;fdc 0(0,%1)\;sync"
4937 [(set_attr "type" "multi")
4938 (set_attr "length" "12")])
4940 (define_insn "icacheflush"
4941 [(unspec_volatile [(const_int 2)] 0)
4942 (use (mem:SI (match_operand:SI 0 "register_operand" "r")))
4943 (use (mem:SI (match_operand:SI 1 "register_operand" "r")))
4944 (use (match_operand:SI 2 "register_operand" "r"))
4945 (clobber (match_operand:SI 3 "register_operand" "=&r"))
4946 (clobber (match_operand:SI 4 "register_operand" "=&r"))]
4948 "mfsp %%sr0,%4\;ldsid (0,%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
4949 [(set_attr "type" "multi")
4950 (set_attr "length" "52")])
4952 ;; An out-of-line prologue.
4953 (define_insn "outline_prologue_call"
4954 [(unspec_volatile [(const_int 0)] 0)
4955 (clobber (reg:SI 31))
4956 (clobber (reg:SI 22))
4957 (clobber (reg:SI 21))
4958 (clobber (reg:SI 20))
4959 (clobber (reg:SI 19))
4960 (clobber (reg:SI 1))]
4964 extern int frame_pointer_needed;
4966 /* We need two different versions depending on whether or not we
4967 need a frame pointer. Also note that we return to the instruction
4968 immediately after the branch rather than two instructions after the
4969 break as normally is the case. */
4970 if (frame_pointer_needed)
4972 /* Must import the magic millicode routine(s). */
4973 output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
4975 if (TARGET_PORTABLE_RUNTIME)
4977 output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
4978 output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
4982 output_asm_insn (\"bl,n __outline_prologue_fp,%%r31\", NULL);
4986 /* Must import the magic millicode routine(s). */
4987 output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
4989 if (TARGET_PORTABLE_RUNTIME)
4991 output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
4992 output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
4995 output_asm_insn (\"bl,n __outline_prologue,%%r31\", NULL);
4999 [(set_attr "type" "multi")
5000 (set_attr "length" "8")])
5002 ;; An out-of-line epilogue.
5003 (define_insn "outline_epilogue_call"
5004 [(unspec_volatile [(const_int 1)] 0)
5007 (clobber (reg:SI 31))
5008 (clobber (reg:SI 22))
5009 (clobber (reg:SI 21))
5010 (clobber (reg:SI 20))
5011 (clobber (reg:SI 19))
5012 (clobber (reg:SI 2))
5013 (clobber (reg:SI 1))]
5017 extern int frame_pointer_needed;
5019 /* We need two different versions depending on whether or not we
5020 need a frame pointer. Also note that we return to the instruction
5021 immediately after the branch rather than two instructions after the
5022 break as normally is the case. */
5023 if (frame_pointer_needed)
5025 /* Must import the magic millicode routine. */
5026 output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
5028 /* The out-of-line prologue will make sure we return to the right
5030 if (TARGET_PORTABLE_RUNTIME)
5032 output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
5033 output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
5037 output_asm_insn (\"bl,n __outline_epilogue_fp,%%r31\", NULL);
5041 /* Must import the magic millicode routine. */
5042 output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
5044 /* The out-of-line prologue will make sure we return to the right
5046 if (TARGET_PORTABLE_RUNTIME)
5048 output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
5049 output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
5052 output_asm_insn (\"bl,n __outline_epilogue,%%r31\", NULL);
5056 [(set_attr "type" "multi")
5057 (set_attr "length" "8")])
5059 ;; Given a function pointer, canonicalize it so it can be
5060 ;; reliably compared to another function pointer. */
5061 (define_expand "canonicalize_funcptr_for_compare"
5062 [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
5063 (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
5064 (clobber (match_dup 2))
5065 (clobber (reg:SI 26))
5066 (clobber (reg:SI 22))
5067 (clobber (reg:SI 31))])
5068 (set (match_operand:SI 0 "register_operand" "")
5070 "! TARGET_PORTABLE_RUNTIME"
5073 operands[2] = gen_reg_rtx (SImode);
5074 if (GET_CODE (operands[1]) != REG)
5076 rtx tmp = gen_reg_rtx (Pmode);
5077 emit_move_insn (tmp, operands[1]);
5083 [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
5084 (clobber (match_operand:SI 0 "register_operand" "=a"))
5085 (clobber (reg:SI 26))
5086 (clobber (reg:SI 22))
5087 (clobber (reg:SI 31))]
5091 /* Must import the magic millicode routine. */
5092 output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
5094 /* This is absolutely fucking amazing.
5096 First, copy our input parameter into %r29 just in case we don't
5097 need to call $$sh_func_adrs. */
5098 output_asm_insn (\"copy %%r26,%%r29\", NULL);
5100 /* Next, examine the low two bits in %r26, if they aren't 0x2, then
5101 we use %r26 unchanged. */
5102 if (get_attr_length (insn) == 32)
5103 output_asm_insn (\"extru %%r26,31,2,%%r31\;comib,<>,n 2,%%r31,.+24\", NULL);
5104 else if (get_attr_length (insn) == 40)
5105 output_asm_insn (\"extru %%r26,31,2,%%r31\;comib,<>,n 2,%%r31,.+32\", NULL);
5106 else if (get_attr_length (insn) == 44)
5107 output_asm_insn (\"extru %%r26,31,2,%%r31\;comib,<>,n 2,%%r31,.+36\", NULL);
5109 output_asm_insn (\"extru %%r26,31,2,%%r31\;comib,<>,n 2,%%r31,.+20\", NULL);
5111 /* Next, compare %r26 with 4096, if %r26 is less than or equal to
5112 4096, then we use %r26 unchanged. */
5113 if (get_attr_length (insn) == 32)
5114 output_asm_insn (\"ldi 4096,%%r31\;comb,<<,n %%r26,%%r31,.+16\", NULL);
5115 else if (get_attr_length (insn) == 40)
5116 output_asm_insn (\"ldi 4096,%%r31\;comb,<<,n %%r26,%%r31,.+24\", NULL);
5117 else if (get_attr_length (insn) == 44)
5118 output_asm_insn (\"ldi 4096,%%r31\;comb,<<,n %%r26,%%r31,.+28\", NULL);
5120 output_asm_insn (\"ldi 4096,%%r31\;comb,<<,n %%r26,%%r31,.+12\", NULL);
5122 /* Else call $$sh_func_adrs to extract the function's real add24. */
5123 return output_millicode_call (insn,
5124 gen_rtx (SYMBOL_REF, SImode,
5125 \"$$sh_func_adrs\"));
5127 [(set_attr "type" "multi")
5128 (set (attr "length")
5130 ;; Target (or stub) within reach
5131 (and (lt (plus (symbol_ref "total_code_bytes") (pc))
5133 (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
5138 (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
5142 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
5143 ;; same as NO_SPACE_REGS code
5144 (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
5146 (eq (symbol_ref "flag_pic")
5151 (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
5155 ;; Out of range and PIC