OSDN Git Service

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