OSDN Git Service

(tst?f): Use CONST0_RTX instead of incorrect call to
[pf3gnuchains/gcc-fork.git] / gcc / config / romp / romp.md
1 ;;- Machine description for ROMP chip for GNU C compiler
2 ;;   Copyright (C) 1988, 1991, 1993, 1994 Free Software Foundation, Inc.
3 ;;   Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4
5 ;; This file is part of GNU CC.
6
7 ;; GNU CC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11
12 ;; GNU CC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING.  If not, write to
19 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20
21
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 \f
24 ;; Define the attributes for the ROMP.
25
26 ;; Insn type.  Used to default other attribute values.
27
28 (define_attr "type"
29   "branch,ibranch,return,fp,load,loadz,store,call,address,arith,compare,multi,misc"
30   (const_string "arith"))
31
32 ;; Length in bytes.
33
34 (define_attr "length" ""
35   (cond [(eq_attr "type" "branch")
36          (if_then_else (and (ge (minus (pc) (match_dup 0))
37                                 (const_int -256))
38                             (le (minus (pc) (match_dup 0))
39                                 (const_int 254)))
40                        (const_int 2)
41                        (const_int 4))
42          (eq_attr "type" "return,ibranch") (const_int 2)
43          (eq_attr "type" "fp")          (const_int 10)
44          (eq_attr "type" "call")        (const_int 4)
45          (eq_attr "type" "load")
46            (cond [(match_operand 1 "short_memory_operand" "") (const_int 2)
47                   (match_operand 1 "symbolic_memory_operand" "") (const_int 8)]
48                  (const_int 4))
49          (eq_attr "type" "loadz")
50            (cond [(match_operand 1 "zero_memory_operand" "") (const_int 2)
51                   (match_operand 1 "symbolic_memory_operand" "") (const_int 8)]
52                  (const_string "4"))
53          (eq_attr "type" "store")
54            (cond [(match_operand 0 "short_memory_operand" "") (const_int 2)
55                   (match_operand 0 "symbolic_memory_operand" "") (const_int 8)]
56                  (const_int 4))]
57         (const_int 4)))
58
59 ;; Whether insn can be placed in a delay slot.
60
61 (define_attr "in_delay_slot" "yes,no" 
62   (cond [(eq_attr "length" "8,10,38")                   (const_string "no")
63          (eq_attr "type" "branch,ibranch,return,call,multi")
64          (const_string "no")]
65         (const_string "yes")))
66
67 ;; Whether insn needs a delay slot.  We have to say that two-byte
68 ;; branches do not need a delay slot.  Otherwise, branch shortening will
69 ;; try to do something with delay slot insns (we want it to on the PA).
70 ;; This is a kludge, which should be cleaned up at some point.
71
72 (define_attr "needs_delay_slot" "yes,no"
73   (if_then_else (ior (and (eq_attr "type" "branch")
74                           (eq_attr "length" "4"))
75                      (eq_attr "type" "ibranch,return,call"))
76                 (const_string "yes") (const_string "no")))
77
78 ;; What insn does to the condition code.
79
80 (define_attr "cc"
81   "clobber,none,sets,change0,copy1to0,compare,tbit"
82   (cond [(eq_attr "type" "load,loadz")          (const_string "change0")
83          (eq_attr "type" "store")               (const_string "none")
84          (eq_attr "type" "fp,call")             (const_string "clobber")
85          (eq_attr "type" "branch,ibranch,return") (const_string "none")
86          (eq_attr "type" "address")             (const_string "change0")
87          (eq_attr "type" "compare")             (const_string "compare")
88          (eq_attr "type" "arith")               (const_string "sets")]
89         (const_string "clobber")))
90 \f
91 ;; Define attributes for `asm' insns.
92
93 (define_asm_attributes [(set_attr "type" "misc")
94                         (set_attr "length" "8")
95                         (set_attr "in_delay_slot" "no")
96                         (set_attr "cc" "clobber")])
97
98 ;; Define the delay slot requirements for branches and calls.  We don't have
99 ;; any annulled insns.
100 ;;
101 (define_delay (eq_attr "needs_delay_slot" "yes")
102   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
103
104 ;; We cannot give a floating-point comparison a delay slot, even though it
105 ;; could make use of it.  This is because it would confuse next_cc0_user
106 ;; to do so.  Other fp insns can't get a delay slow because they set their
107 ;; result and use their input after the delay slot insn is executed.  This
108 ;; isn't what reorg.c expects.  
109
110 ;; Define load & store delays.  These were obtained by measurements done by
111 ;; jfc@athena.mit.edu.
112 ;;
113 ;; In general, the memory unit can support at most two simultaneous operations.
114 ;;
115 ;; Loads take 5 cycles to return the data and can be pipelined up to the
116 ;; limit of two simultaneous operations.
117 (define_function_unit "memory" 1 2 (eq_attr "type" "load,loadz") 5 0)
118
119 ;; Stores do not return data, but tie up the memory unit for 2 cycles if the
120 ;; next insn is also a store.
121 (define_function_unit "memory" 1 2 (eq_attr "type" "store") 1 2
122   [(eq_attr "type" "store")])
123 \f
124 ;; Move word instructions.
125 ;;
126 ;; If destination is memory but source is not register, force source to
127 ;; register.
128 ;;
129 ;; If source is a constant that is too large to load in a single insn, build
130 ;; it in two pieces.
131 ;;
132 ;; If destination is memory and source is a register, a temporary register
133 ;; will be needed.  In that case, make a PARALLEL of the SET and a
134 ;; CLOBBER of a SCRATCH to allocate the required temporary.
135 ;;
136 ;; This temporary is ACTUALLY only needed when the destination is a
137 ;; relocatable expression.  For generating RTL, however, we always
138 ;; place the CLOBBER.  In insns where it is not needed, the SCRATCH will
139 ;; not be allocated to a register.
140 ;;
141 ;; Also, avoid creating pseudo-registers or SCRATCH rtx's during reload as
142 ;; they will not be correctly handled.  We never need pseudos for that
143 ;; case anyway.
144 ;;
145 ;; We do not use DEFINE_SPLIT for loading constants because the number
146 ;; of cases in the resulting unsplit insn would be too high to deal
147 ;; with practically.
148 (define_expand "movsi"
149   [(set (match_operand:SI 0 "general_operand" "")
150         (match_operand:SI 1 "general_operand" ""))]
151   ""
152   "
153 { rtx op0 = operands[0];
154   rtx op1 = operands[1];
155
156   if (GET_CODE (op1) == REG && REGNO (op1) == 16)
157     DONE;
158
159   if (GET_CODE (op0) == REG && REGNO (op0) == 16)
160     DONE;
161
162   if (GET_CODE (op0) == MEM && ! reload_in_progress)
163     {
164       emit_insn (gen_storesi (operands[0], force_reg (SImode, operands[1])));
165       DONE;
166     }
167   else if (GET_CODE (op1) == CONST_INT)
168     {
169       int const_val = INTVAL (op1);
170
171       /* Try a number of cases to see how to best load the constant.  */
172       if ((const_val & 0xffff) == 0
173           || (const_val & 0xffff0000) == 0
174           || (unsigned) (const_val + 0x8000) < 0x10000)
175         /* Can do this in one insn, so generate it.  */
176         ;
177       else if (((- const_val) & 0xffff) == 0
178                || ((- const_val) & 0xffff0000) == 0
179                || (unsigned) ((- const_val) + 0x8000) < 0x10000)
180         {
181           /* Can do this by loading the negative constant and then negating. */
182           emit_move_insn (operands[0],
183                           gen_rtx (CONST_INT, VOIDmode, - const_val));
184           emit_insn (gen_negsi2 (operands[0], operands[0]));
185           DONE;
186         }
187       else
188         /* Do this the long way.  */
189         {
190           unsigned int high_part = const_val & 0xffff0000;
191           unsigned int low_part = const_val & 0xffff;
192           int i;
193
194           if (low_part >= 0x10 && exact_log2 (low_part) >= 0)
195             i = high_part, high_part = low_part, low_part = i;
196
197           emit_move_insn (operands[0],
198                           gen_rtx (CONST_INT, VOIDmode, low_part));
199           emit_insn (gen_iorsi3 (operands[0], operands[0],
200                                  gen_rtx (CONST_INT, VOIDmode, high_part)));
201           DONE;
202         }
203     }
204 }")
205
206 ;; Move from a symbolic memory location to a register is special.  In this
207 ;; case, we know in advance that the register cannot be r0, so we can improve
208 ;; register allocation by treating it separately.
209
210 (define_insn ""
211   [(set (match_operand:SI 0 "register_operand" "=b")
212         (match_operand:SI 1 "symbolic_memory_operand" "m"))]
213   ""
214   "load %0,%1"
215   [(set_attr "type" "load")])
216
217 ;; Generic single-word move insn.  We avoid the case where the destination is
218 ;; a symbolic address, as that needs a temporary register.
219
220 (define_insn ""
221   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,r,r,r,b,Q")
222         (match_operand:SI 1 "romp_operand" "rR,I,K,L,M,S,s,Q,m,r"))]
223   "register_operand (operands[0], SImode)
224    || register_operand (operands[1], SImode)"
225   "@
226    cas %0,%1,r0
227    lis %0,%1
228    cal %0,%1(r0)
229    cal16 %0,%1(r0)
230    cau %0,%H1(r0)
231    ail %0,r14,%C1
232    get %0,$%1
233    l%M1 %0,%1
234    load %0,%1
235    st%M0 %1,%0"
236   [(set_attr "type" "address,address,address,address,address,arith,misc,load,load,store")
237    (set_attr "length" "2,2,4,4,4,4,8,*,*,*")])
238
239 (define_insn "storesi"
240   [(set (match_operand:SI 0 "memory_operand" "=Q,m")
241         (match_operand:SI 1 "register_operand" "r,r"))
242    (clobber (match_scratch:SI 2 "=X,&b"))]
243   ""
244   "@
245    st%M0 %1,%0
246    store %1,%0,%2"
247   [(set_attr "type" "store")])
248
249 ;; This pattern is used by reload when we store into a symbolic address.  It
250 ;; provides the temporary register required.  This pattern is only used
251 ;; when SECONDARY_OUTPUT_RELOAD_CLASS returns something other than
252 ;; NO_REGS, so we need not have any predicates here.
253
254 (define_expand "reload_outsi"
255   [(parallel [(set (match_operand:SI 0 "symbolic_memory_operand" "=m")
256                    (match_operand:SI 1 "" "r"))
257               (clobber (match_operand:SI 2 "" "=&b"))])]
258   ""
259   "")
260 \f
261 ;; Now do the same for the QI move instructions.
262 (define_expand "movqi"
263   [(set (match_operand:QI 0 "general_operand" "")
264         (match_operand:QI 1 "general_operand" ""))]
265   ""
266   "
267 { rtx op0 = operands[0];
268
269   if (GET_CODE (op0) == MEM && ! reload_in_progress)
270     {
271       emit_insn (gen_storeqi (operands[0], force_reg (QImode, operands[1])));
272       DONE;
273     }
274 }")
275
276 (define_insn ""
277   [(set (match_operand:QI 0 "register_operand" "=b")
278         (match_operand:QI 1 "symbolic_memory_operand" "m"))]
279   "" 
280   "loadc %0,%1"
281   [(set_attr "type" "load")])
282
283 (define_insn ""
284   [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,b,Q")
285         (match_operand:QI 1 "romp_operand" "r,I,n,s,Q,m,r"))]
286   "register_operand (operands[0], QImode)
287    || register_operand (operands[1], QImode)"
288   "@
289    cas %0,%1,r0
290    lis %0,%1
291    cal %0,%L1(r0)
292    get %0,$%1
293    lc%M1 %0,%1
294    loadc %0,%1
295    stc%M0 %1,%0"
296   [(set_attr "type" "address,address,address,misc,load,load,store")
297    (set_attr "length" "2,2,4,8,*,*,*")])
298
299 (define_insn "storeqi"
300   [(set (match_operand:QI 0 "memory_operand" "=Q,m")
301         (match_operand:QI 1 "register_operand" "r,r"))
302    (clobber (match_scratch:SI 2 "=X,&b"))]
303   ""
304   "@
305    stc%M0 %1,%0
306    storec %1,%0,%2"
307   [(set_attr "type" "store")])
308
309 (define_expand "reload_outqi"
310   [(parallel [(set (match_operand:QI 0 "symbolic_memory_operand" "=m")
311                    (match_operand:QI 1 "" "r"))
312               (clobber (match_operand:SI 2 "" "=&b"))])]
313   ""
314   "")
315 \f
316 ;; Finally, the HI instructions.
317 (define_expand "movhi"
318   [(set (match_operand:HI 0 "general_operand" "")
319         (match_operand:HI 1 "general_operand" ""))]
320   ""
321   "
322 { rtx op0 = operands[0];
323
324   if (GET_CODE (op0) == MEM && ! reload_in_progress)
325     {
326       emit_insn (gen_storehi (operands[0], force_reg (HImode, operands[1])));
327       DONE;
328     }
329 }")
330
331 (define_insn ""
332   [(set (match_operand:HI 0 "register_operand" "=b")
333         (match_operand:HI 1 "symbolic_memory_operand" "m"))]
334   ""
335   "loadha %0,%1"
336   [(set_attr "type" "load")])
337
338
339 ;; use cal16 instead of cal for constant source because combine requires
340 ;; the high bits of the register to be 0 after a HImode load of a constant
341
342 (define_insn ""
343   [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,b,Q")
344         (match_operand:HI 1 "romp_operand" "r,I,n,s,Q,m,r"))]
345   "register_operand (operands[0], HImode)
346    || register_operand (operands[1], HImode)"
347   "@
348    cas %0,%1,r0
349    lis %0,%1
350    cal16 %0,%L1(r0)
351    get %0,$%1
352    lh%N1 %0,%1
353    loadh %0,%1
354    sth%M0 %1,%0"
355   [(set_attr "type" "address,address,address,misc,loadz,loadz,store")
356    (set_attr "length" "2,2,4,8,*,*,*")])
357
358 (define_insn "storehi"
359   [(set (match_operand:HI 0 "memory_operand" "=Q,m")
360         (match_operand:HI 1 "register_operand" "r,r"))
361    (clobber (match_scratch:SI 2 "=X,&b"))]
362   ""
363   "@
364    sth%M0 %1,%0
365    storeh %1,%0,%2"
366   [(set_attr "type" "store")])
367
368 (define_expand "reload_outhi"
369   [(parallel [(set (match_operand:HI 0 "symbolic_memory_operand" "=m")
370                    (match_operand:HI 1 "" "r"))
371               (clobber (match_operand:SI 2 "" "=&b"))])]
372   ""
373   "")
374 \f
375 ;; For DI move, if we have a constant, break the operation apart into
376 ;; two SImode moves because the optimizer may be able to do a better job
377 ;; with the resulting code.
378 ;;
379 ;; For memory stores, make the required pseudo for a temporary in case we
380 ;; are storing into an absolute address.
381 ;;
382 ;; We need to be careful about the cases where the output is a register that is
383 ;; the second register of the input.
384
385 (define_expand "movdi"
386   [(set (match_operand:DI 0 "general_operand" "")
387         (match_operand:DI 1 "general_operand" ""))]
388   ""
389   "
390 { rtx op0 = operands[0];
391   rtx op1 = operands[1];
392  
393   if (CONSTANT_P (op1))
394     {
395       rtx insns;
396
397       start_sequence ();
398       emit_move_insn (operand_subword (op0, 0, 1, DImode),
399                       operand_subword (op1, 0, 1, DImode));
400       emit_move_insn (operand_subword (op0, 1, 1, DImode),
401                       operand_subword (op1, 1, 1, DImode));
402       insns = get_insns ();
403       end_sequence ();
404
405       emit_no_conflict_block (insns, op0, op1, 0, op1);
406       DONE;
407     }
408
409   if (GET_CODE (op0) == MEM && ! reload_in_progress)
410     {
411       emit_insn (gen_storedi (operands[0], force_reg (DImode, operands[1])));
412       DONE;
413     }
414 }")
415
416 (define_insn ""
417  [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
418        (match_operand:DI 1 "reg_or_mem_operand" "r,Q,m,r"))]
419   "register_operand (operands[0], DImode)
420    || register_operand (operands[1], DImode)"
421   "*
422 {
423   switch (which_alternative)
424     {
425     case 0:
426       if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
427         return \"cas %O0,%O1,r0\;cas %0,%1,r0\";
428       else
429         return \"cas %0,%1,r0\;cas %O0,%O1,r0\";
430     case 1:
431       /* Here we must see which word to load first.  We default to the
432          low-order word unless it occurs in the address.  */
433       if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
434                              operands[1], 0))
435         return \"l%M1 %O0,%O1\;l%M1 %0,%1\";
436       else
437         return \"l%M1 %0,%1\;l%M1 %O0,%O1\";
438     case 2:
439       return \"get %O0,$%1\;ls %0,0(%O0)\;ls %O0,4(%O0)\";
440     case 3:
441       return \"st%M0 %1,%0\;st%M0 %O1,%O0\";
442     }
443 }"
444   [(set_attr "type" "multi")
445    (set_attr "cc" "change0,change0,change0,none")
446    (set_attr "length" "4,12,8,8")])
447
448 (define_insn "storedi"
449   [(set (match_operand:DI 0 "memory_operand" "=Q,m")
450         (match_operand:DI 1 "register_operand" "r,r"))
451    (clobber (match_scratch:SI 2 "=X,&b"))]
452   ""
453   "@
454    st%M0 %1,%0\;st%M0 %O1,%O0
455    get %2,$%0\;sts %1,0(%2)\;sts %O1,4(%2)"
456   [(set_attr "type" "multi,multi")
457    (set_attr "cc" "none,none")
458    (set_attr "length" "8,12")])
459
460 (define_expand "reload_outdi"
461   [(parallel [(set (match_operand:DI 0 "symbolic_memory_operand" "=m")
462                    (match_operand:DI 1 "" "r"))
463               (clobber (match_operand:SI 2 "" "=&b"))])]
464   ""
465   "")
466
467 ;; Split symbolic memory operands differently.  We first load the address
468 ;; into a register and then do the two loads or stores.  We can only do
469 ;; this if operand_subword won't produce a SUBREG, which is only when
470 ;; operands[0] is a hard register.  Thus, these won't be used during the
471 ;; first insn scheduling pass.
472 (define_split
473   [(set (match_operand:DI 0 "register_operand" "")
474         (match_operand:DI 1 "symbolic_memory_operand" ""))]
475   "GET_CODE (operands[0]) == REG
476    && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER"
477   [(set (match_dup 2) (match_dup 3))
478    (set (match_dup 4) (match_dup 5))
479    (set (match_dup 6) (match_dup 7))]
480   "
481 { operands[2] = operand_subword (operands[0], 1, 0, DImode);
482   operands[3] = XEXP (operands[1], 0);
483   operands[4] = operand_subword (operands[0], 0, 0, DImode);
484   operands[5] = gen_rtx (MEM, SImode, operands[2]);
485   operands[6] = operands[2];
486   operands[7] = gen_rtx (MEM, SImode,
487                          gen_rtx (PLUS, SImode, operands[2],
488                                   gen_rtx (CONST_INT, VOIDmode, 4)));
489
490   if (operands[2] == 0 || operands[4] == 0)
491     FAIL;
492 }")
493
494 (define_split
495   [(set (match_operand:DI 0 "symbolic_memory_operand" "")
496         (match_operand:DI 1 "register_operand" ""))
497    (clobber (match_operand:SI 2 "register_operand" ""))] 
498   "GET_CODE (operands[0]) == REG
499    && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER"
500   [(set (match_dup 2) (match_dup 3))
501    (set (match_dup 4) (match_dup 5))
502    (set (match_dup 6) (match_dup 7))]
503   "
504 { operands[3] = XEXP (operands[0], 0);
505   operands[4] = gen_rtx (MEM, SImode, operands[2]);
506   operands[5] = operand_subword (operands[1], 0, 0, DImode);
507   operands[6] = gen_rtx (MEM, SImode,
508                          gen_rtx (PLUS, SImode, operands[2],
509                                   gen_rtx (CONST_INT, VOIDmode, 4)));
510   operands[7] = operand_subword (operands[1], 1, 0, DImode);
511
512   if (operands[5] == 0 || operands[7] == 0)
513     FAIL;
514 }")
515
516 ;; If the output is a register and the input is memory, we have to be careful
517 ;; and see which word needs to be loaded first.
518 ;;
519 ;; Note that this case doesn't have a CLOBBER.   Therefore, we must either
520 ;; be after reload or operand[0] must not be a MEM.  So we don't need a
521 ;; CLOBBER on the new insns either.
522 ;;
523 ;; Due to a bug in sched.c, we do not want to split this insn if both
524 ;; operands are registers and they overlap unless reload has completed.
525 (define_split
526   [(set (match_operand:DI 0 "general_operand" "")
527         (match_operand:DI 1 "general_operand" ""))]
528   "! symbolic_memory_operand (operands[0], DImode)
529    && ! symbolic_memory_operand (operands[1], DImode)
530    && ! (GET_CODE (operands[0]) == REG
531          && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
532    && ! (GET_CODE (operands[1]) == REG
533          && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
534    && ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
535          && ! reload_completed
536          && reg_overlap_mentioned_p (operands[0], operands[1]))"
537   [(set (match_dup 2) (match_dup 3))
538    (set (match_dup 4) (match_dup 5))]
539   "
540 { if (GET_CODE (operands[0]) != REG
541       || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
542                               operands[1], 0))
543     {
544       operands[2] = operand_subword (operands[0], 0, 0, DImode);
545       operands[3] = operand_subword (operands[1], 0, 0, DImode);
546       operands[4] = operand_subword (operands[0], 1, 0, DImode);
547       operands[5] = operand_subword (operands[1], 1, 0, DImode);
548     }
549   else
550     {
551       operands[2] = operand_subword (operands[0], 1, 0, DImode);
552       operands[3] = operand_subword (operands[1], 1, 0, DImode);
553       operands[4] = operand_subword (operands[0], 0, 0, DImode);
554       operands[5] = operand_subword (operands[1], 0, 0, DImode);
555     }
556
557   if (operands[2] == 0 || operands[3] == 0
558       || operands[4] == 0 || operands[5] == 0)
559     FAIL;
560 }")
561
562 (define_split
563  [(set (match_operand:DI 0 "general_operand" "")
564        (match_operand:DI 1 "general_operand" ""))
565   (clobber (match_operand:SI 6 "register_operand" ""))]
566   "! symbolic_memory_operand (operands[0], DImode)
567    && ! symbolic_memory_operand (operands[1], DImode)
568    && ! (GET_CODE (operands[0]) == REG
569          && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
570    && ! (GET_CODE (operands[1]) == REG
571          && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
572    && ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
573          && ! reload_completed
574          && reg_overlap_mentioned_p (operands[0], operands[1]))"
575  [(parallel [(set (match_dup 2) (match_dup 3))
576              (clobber (match_dup 7))])
577   (parallel [(set (match_dup 4) (match_dup 5))
578              (clobber (match_dup 8))])]
579  "
580 { if (GET_CODE (operands[0]) != REG
581       || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
582                               operands[1], 0))
583     {
584       operands[2] = operand_subword (operands[0], 0, 0, DImode);
585       operands[3] = operand_subword (operands[1], 0, 0, DImode);
586       operands[4] = operand_subword (operands[0], 1, 0, DImode);
587       operands[5] = operand_subword (operands[1], 1, 0, DImode);
588     }
589   else
590     {
591       operands[2] = operand_subword (operands[0], 1, 0, DImode);
592       operands[3] = operand_subword (operands[1], 1, 0, DImode);
593       operands[4] = operand_subword (operands[0], 0, 0, DImode);
594       operands[5] = operand_subword (operands[1], 0, 0, DImode);
595     }
596
597   if (operands[2] == 0 || operands[3] == 0
598       || operands[4] == 0 || operands[5] == 0)
599     FAIL;
600
601   /* We must be sure to make two different SCRATCH operands, since they
602      are not allowed to be shared.  After reload, however, we only have
603      a SCRATCH if we won't use the operand, so it is allowed to share it
604      then.  */
605   if (reload_completed || GET_CODE (operands[6]) != SCRATCH)
606     operands[7] = operands[8] = operands[6];
607   else
608     {
609       operands[7] = gen_rtx (SCRATCH, SImode);
610       operands[8] = gen_rtx (SCRATCH, SImode);
611     }
612 }")
613
614 ;; Define move insns for SF, and DF.
615 ;;
616 ;; For register-register copies or a copy of something to itself, emit a
617 ;; single SET insn since it will likely be optimized away.
618 ;;
619 ;; Otherwise, emit a floating-point move operation unless both input and
620 ;; output are either constant, memory, or a non-floating-point hard register.
621 (define_expand "movdf"
622   [(parallel [(set (match_operand:DF 0 "general_operand" "")
623                    (match_operand:DF 1 "general_operand" ""))
624               (clobber (reg:SI 0))
625               (clobber (reg:SI 15))])]
626   ""
627   "
628 { rtx op0 = operands[0];
629   rtx op1 = operands[1];
630
631   if (op0 == op1)
632     {
633       emit_insn (gen_rtx (SET, VOIDmode, op0, op1));
634       DONE;
635     }
636
637   if ((GET_CODE (op0) == MEM
638        || (GET_CODE (op0) == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER
639            && ! FP_REGNO_P (REGNO (op0))))
640       && (GET_CODE (op1) == MEM
641           || GET_CODE (op1) == CONST_DOUBLE
642           || (GET_CODE (op1) == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER
643               && ! FP_REGNO_P (REGNO (op1)) && ! rtx_equal_p (op0, op1))))
644     {
645       rtx insns;
646
647       if (GET_CODE (op1) == CONST_DOUBLE)
648         op1 = force_const_mem (DFmode, op1);
649
650       start_sequence ();
651       if (GET_CODE (operands[0]) != REG
652           || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
653                                   operands[1]), 0)
654         {
655           emit_move_insn (operand_subword (op0, 0, 1, DFmode),
656                           operand_subword_force (op1, 0, DFmode));
657           emit_move_insn (operand_subword (op0, 1, 1, DFmode),
658                           operand_subword_force (op1, 1, DFmode));
659         }
660       else
661         {
662           emit_move_insn (operand_subword (op0, 1, 1, DFmode),
663                           operand_subword_force (op1, 1, DFmode));
664           emit_move_insn (operand_subword (op0, 0, 1, DFmode),
665                           operand_subword_force (op1, 0, DFmode));
666         }
667
668       insns = get_insns ();
669       end_sequence ();
670
671       emit_no_conflict_block (insns, op0, op1, 0, op1);
672       DONE;
673     }
674 }")
675
676 (define_expand "movsf"
677   [(parallel [(set (match_operand:SF 0 "general_operand" "")
678                    (match_operand:SF 1 "general_operand" ""))
679               (clobber (reg:SI 0))
680               (clobber (reg:SI 15))])]
681   ""
682   "
683 { rtx op0 = operands[0];
684   rtx op1 = operands[1];
685   
686   if (op0 == op1)
687     {
688       emit_insn (gen_rtx (SET, VOIDmode, op0, op1));
689       DONE;
690     }
691
692   if ((GET_CODE (op0) == MEM
693        || (GET_CODE (op0) == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER
694            && ! FP_REGNO_P (REGNO (op0))))
695        && (GET_CODE (op1) == MEM
696            || GET_CODE (op1) == CONST_DOUBLE
697            || (GET_CODE (op1) == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER
698                && ! FP_REGNO_P (REGNO (op1)))))
699     {
700       rtx last;
701
702       if (GET_CODE (op1) == CONST_DOUBLE)
703         op1 = force_const_mem (SFmode, op1);
704
705       last = emit_move_insn (operand_subword (op0, 0, 1, SFmode),
706                              operand_subword_force (op1, 0, SFmode));
707
708       REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, op1, REG_NOTES (last));
709       DONE;
710     }
711 }")
712
713 ;; Define the move insns for SF and DF.  Check for all general regs
714 ;; in the FP insns and make them non-FP if so.  Do the same if the input and
715 ;; output are the same (the insn will be deleted in this case and we don't
716 ;; want to think there are FP insns when there might not be).
717 (define_insn ""
718   [(set (match_operand:SF 0 "general_operand" "=*frg")
719         (match_dup 0))]
720   ""
721   "nopr r0"
722   [(set_attr "type" "address")
723    (set_attr "length" "2")])
724
725 (define_insn ""
726   [(set (match_operand:SF 0 "general_operand" "=r,*fr,r,r,Q,m,frg")
727         (match_operand:SF 1 "general_operand" "r,0,Q,m,r,r,frg"))
728    (clobber (match_operand:SI 2 "reg_0_operand" "=&z,z,z,z,z,z,z"))
729    (clobber (match_operand:SI 3 "reg_15_operand" "=&t,t,t,t,t,t,t"))]
730   ""
731   "*
732 { switch (which_alternative)
733     {
734     case 0:
735       return \"cas %0,%1,r0\";
736     case 1:
737       return \"nopr r0\";
738     case 2:
739       return \"l%M1 %0,%1\";
740     case 3:
741       return \"load %0,%1\";
742     case 4:
743       return \"st%M0 %1,%0\";
744     case 5:
745       return \"store %1,%0,%3\";
746     default:
747       return output_fpop (SET, operands[0], operands[1], 0, insn);
748     }
749 }"
750   [(set_attr "type" "address,address,load,load,store,store,fp")
751    (set_attr "length" "2,2,*,*,*,*,*")])
752
753 (define_insn ""
754   [(set (match_operand:DF 0 "general_operand" "=*frg")
755         (match_dup 0))]
756   ""
757   "nopr r0"
758   [(set_attr "type" "address")
759    (set_attr "length" "2")])
760
761 (define_insn ""
762   [(set (match_operand:DF 0 "general_operand" "=r,*fr,r,r,Q,m,frg")
763         (match_operand:DF 1 "general_operand" "r,0,Q,m,r,r,*frg"))
764    (clobber (match_operand:SI 2 "reg_0_operand" "=&z,z,z,z,z,z,z"))
765    (clobber (match_operand:SI 3 "reg_15_operand" "=&t,t,t,t,t,t,t"))]
766   ""
767   "*
768 { switch (which_alternative)
769     {
770     case 0:
771       if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
772         return \"cas %O0,%O1,r0\;cas %0,%1,r0\";
773       else
774         return \"cas %0,%1,r0\;cas %O0,%O1,r0\";
775     case 1:
776       return \"nopr r0\";
777     case 2:
778       /* Here we must see which word to load first.  We default to the
779          low-order word unless it occurs in the address.  */
780       if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
781                              operands[1], 0))
782         return \"l%M1 %O0,%O1\;l%M1 %0,%1\";
783       else
784         return \"l%M1 %0,%1\;l%M1 %O0,%O1\";
785     case 3:
786       return \"get %3,$%1\;ls %0,0(%3)\;ls %O0,4(%3)\";
787     case 4:
788       return \"st%M0 %1,%0\;st%M0 %O1,%O0\";
789     case 5:
790       return \"get %3,$%0\;sts %1,0(%3)\;sts %O1,4(%3)\";
791     default:
792       return output_fpop (SET, operands[0], operands[1], 0, insn);
793     }
794 }"
795   [(set_attr "type" "address,multi,multi,multi,multi,multi,fp")
796    (set_attr "length" "2,4,*,*,*,*,*")])
797
798 ;; Split all the above cases that involve multiple insns and no floating-point
799 ;; data block.  If before reload, we can make a SCRATCH.  Otherwise, use
800 ;; register 15.
801
802 (define_split
803   [(set (match_operand:DF 0 "register_operand" "")
804         (match_operand:DF 1 "symbolic_memory_operand" ""))
805    (clobber (reg:SI 0))
806    (clobber (reg:SI 15))]
807   "GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 16"
808   [(set (reg:SI 15) (match_dup 2))
809    (set (match_dup 3) (match_dup 4))
810    (set (match_dup 5) (match_dup 6))]
811   "
812 { operands[2] = XEXP (operands[1], 0);
813   operands[3] = operand_subword (operands[0], 0, 0, DFmode);
814   operands[4] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 15));
815   operands[5] = operand_subword (operands[0], 1, 0, DFmode);
816   operands[6] = gen_rtx (MEM, SImode,
817                          gen_rtx (PLUS, SImode, gen_rtx (REG, SImode, 15),
818                                   gen_rtx (CONST_INT, VOIDmode, 4)));
819
820   if (operands[3] == 0 || operands[5] == 0)
821     FAIL;
822 }")
823
824 (define_split
825   [(set (match_operand:DF 0 "symbolic_memory_operand" "")
826         (match_operand:DF 1 "register_operand" ""))
827    (clobber (reg:SI 0))
828    (clobber (reg:SI 15))]
829   "GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 16"
830   [(set (reg:SI 15) (match_dup 2))
831    (set (match_dup 3) (match_dup 4))
832    (set (match_dup 5) (match_dup 6))]
833   "
834 { operands[2] = XEXP (operands[0], 0);
835   operands[3] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 15));
836   operands[4] = operand_subword (operands[1], 0, 0, DFmode);
837   operands[5] = gen_rtx (MEM, SImode,
838                          gen_rtx (PLUS, SImode, gen_rtx (REG, SImode, 15),
839                                   gen_rtx (CONST_INT, VOIDmode, 4)));
840   operands[6] = operand_subword (operands[1], 1, 0, DFmode);
841
842   if (operands[4] == 0 || operands[6] == 0)
843     FAIL;
844 }")
845
846 ;; If the output is a register and the input is memory, we have to be careful
847 ;; and see which word needs to be loaded first.  We also cannot to the
848 ;; split if the input is a constant because it would result in invalid
849 ;; insns.  When the output is a MEM, we must put a CLOBBER on each of the
850 ;; resulting insn, when it is not a MEM, we must not.
851 (define_split
852   [(set (match_operand:DF 0 "memory_operand" "")
853         (match_operand:DF 1 "register_operand" ""))
854    (clobber (reg:SI 0))
855    (clobber (reg:SI 15))]
856   "GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 15"
857   [(parallel [(set (match_dup 2) (match_dup 3))
858               (clobber (match_dup 6))])
859    (parallel [(set (match_dup 4) (match_dup 5))
860               (clobber (match_dup 7))])]
861   "
862 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
863   operands[3] = operand_subword (operands[1], 0, 0, DFmode);
864   operands[4] = operand_subword (operands[0], 1, 0, DFmode);
865   operands[5] = operand_subword (operands[1], 1, 0, DFmode);
866
867   if (operands[2] == 0 || operands[3] == 0
868       || operands[4] == 0 || operands[5] == 0)
869     FAIL;
870
871   if (reload_completed)
872     operands[6] = operands[7] = gen_rtx (REG, SImode, 15);
873   else
874     {
875       operands[6] = gen_rtx (SCRATCH, SImode);
876       operands[7] = gen_rtx (SCRATCH, SImode);
877     }
878 }")
879
880 (define_split
881   [(set (match_operand:DF 0 "nonmemory_operand" "")
882         (match_operand:DF 1 "general_operand" ""))
883    (clobber (reg:SI 0))
884    (clobber (reg:SI 15))]
885   "! symbolic_memory_operand (operands[1], DFmode)
886    && GET_CODE (operands[1]) != CONST_DOUBLE
887    && (GET_CODE (operands[0]) != REG || REGNO (operands[0]) < 15)
888    && (GET_CODE (operands[1]) != REG || REGNO (operands[1]) < 15)
889    && (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)
890    && ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
891          && ! reload_completed
892          && reg_overlap_mentioned_p (operands[0], operands[1]))"
893   [(set (match_dup 2) (match_dup 3))
894    (set (match_dup 4) (match_dup 5))]
895   "
896 { if (GET_CODE (operands[0]) != REG
897       || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
898                               operands[1], 0))
899     {
900       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
901       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
902       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
903       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
904     }
905   else
906     {
907       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
908       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
909       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
910       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
911     }
912
913   if (operands[2] == 0 || operands[3] == 0
914       || operands[4] == 0 || operands[5] == 0)
915     FAIL;
916 }")
917 \f
918 ;; Conversions from one integer mode to another.
919 ;; It is possible sometimes to sign- or zero-extend while fetching from memory.
920 ;;
921 ;; First, sign-extensions:
922 (define_expand "extendhisi2"
923   [(set (match_operand:SI 0 "register_operand" "")
924         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
925   ""
926   "")
927
928 (define_insn ""
929   [(set (match_operand:SI 0 "register_operand" "=b")
930         (sign_extend:SI (match_operand:HI 1 "symbolic_memory_operand" "m")))]
931   ""
932   "loadha %0,%1"
933   [(set_attr "type" "load")])
934
935 (define_insn ""
936   [(set (match_operand:SI 0 "register_operand" "=r,r,b")
937         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Q,m")))]
938   ""
939   "@
940    exts %0,%1
941    lha%M1 %0,%1
942    loadha %0,%1"
943   [(set_attr "type" "arith,load,load")
944    (set_attr "length" "2,*,*")])
945
946 (define_expand "extendqisi2"
947   [(set (match_dup 2)
948         (ashift:SI (match_operand:QI 1 "register_operand" "")
949                    (const_int 24)))
950    (set (match_operand:SI 0 "register_operand" "")
951         (ashiftrt:SI (match_dup 2)
952                      (const_int 24)))]
953   ""
954   "
955 { operands[1] = gen_lowpart (SImode, operands[1]);
956   operands[2] = gen_reg_rtx (SImode); }")
957
958 (define_expand "extendqihi2"
959   [(set (match_dup 2)
960         (ashift:SI (match_operand:QI 1 "register_operand" "")
961                    (const_int 24)))
962    (set (match_operand:HI 0 "register_operand" "")
963         (ashiftrt:SI (match_dup 2)
964                      (const_int 24)))]
965   ""
966   "
967 { operands[0] = gen_lowpart (SImode, operands[0]);
968   operands[1] = gen_lowpart (SImode, operands[1]);
969   operands[2] = gen_reg_rtx (SImode); }")
970
971 ;; Define peepholes to eliminate an instruction when we are doing a sign
972 ;; extension but cannot clobber the input.
973 ;;
974 ;; In this case we will shift left 24 bits, but need a copy first.  The shift
975 ;; can be replaced by a "mc03" instruction, but this can only be done if
976 ;; followed by the right shift of 24 or more bits.
977 (define_peephole
978   [(set (match_operand:SI 0 "register_operand" "")
979         (subreg:SI (match_operand:QI 1 "register_operand" "") 0))
980    (set (match_dup 0)
981         (ashift:SI (match_dup 0)
982                    (const_int 24)))
983    (set (match_dup 0)
984         (ashiftrt:SI (match_dup 0)
985                      (match_operand:SI 2 "const_int_operand" "")))]
986   "INTVAL (operands[2]) >= 24"
987   "mc03 %0,%1\;sari16 %0,%S2"
988  [(set_attr "type" "multi")
989   (set_attr "length" "4")
990   (set_attr "cc" "sets")])
991
992 ;; Now zero extensions:
993 (define_expand "zero_extendhisi2"
994   [(set (match_operand:SI 0 "register_operand" "")
995         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
996   ""
997   "")
998
999 (define_insn ""
1000   [(set (match_operand:SI 0 "register_operand" "=b")
1001         (zero_extend:SI (match_operand:HI 1 "symbolic_memory_operand" "m")))]
1002   ""
1003   "loadh %0,%1"
1004   [(set_attr "type" "load")])
1005
1006 (define_insn ""
1007   [(set (match_operand:SI 0 "register_operand" "=r,r,b")
1008         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Q,m")))]
1009   ""
1010   "@
1011    nilz %0,%1,65535
1012    lh%N1 %0,%1
1013    loadh %0,%1"
1014   [(set_attr "type" "arith,loadz,load")])
1015
1016 (define_expand "zero_extendqisi2"
1017   [(set (match_operand:SI 0 "register_operand" "")
1018         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1019   ""
1020   "")
1021
1022 (define_insn ""
1023   [(set (match_operand:SI 0 "register_operand" "=b")
1024         (zero_extend:SI (match_operand:QI 1 "symbolic_memory_operand" "m")))]
1025   ""
1026   "loadc %0,%1"
1027   [(set_attr "type" "load")])
1028
1029 (define_insn ""
1030   [(set (match_operand:SI 0 "register_operand" "=r,r,b")
1031         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Q,m")))]
1032   ""
1033   "@
1034    nilz %0,%1,255
1035    lc%M1 %0,%1
1036    loadc %0,%1"
1037   [(set_attr "type" "arith,load,load")])
1038
1039 (define_expand "zero_extendqihi2"
1040   [(set (match_operand:HI 0 "register_operand" "")
1041         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1042   ""
1043   "")
1044
1045 (define_insn ""
1046   [(set (match_operand:HI 0 "register_operand" "=b")
1047         (zero_extend:HI (match_operand:QI 1 "symbolic_memory_operand" "m")))]
1048   ""
1049   "loadc %0,%1"
1050   [(set_attr "type" "load")])
1051
1052 (define_insn ""
1053   [(set (match_operand:HI 0 "register_operand" "=r,r,b")
1054         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,Q,m")))]
1055   ""
1056   "@
1057    nilz %0,%1,255
1058    lc%M1 %0,%1
1059    loadc %0,%1"
1060   [(set_attr "type" "arith,load,load")])
1061 \f
1062 ;; Various extract and insertion operations.
1063 (define_expand "extzv"
1064   [(set (match_operand:SI 0 "register_operand" "")
1065         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
1066                          (match_operand:SI 2 "const_int_operand" "")
1067                          (match_operand:SI 3 "const_int_operand" "")))]
1068   ""
1069   "
1070 {
1071   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
1072     FAIL;
1073
1074   if (GET_CODE (operands[3]) != CONST_INT)
1075     FAIL;
1076
1077   if (INTVAL (operands[3]) != 0 && INTVAL (operands[3]) != 8
1078       && INTVAL (operands[3]) != 16 && INTVAL (operands[3]) != 24)
1079     FAIL;
1080 }")
1081
1082 (define_insn ""
1083   [(set (match_operand:SI 0 "register_operand" "=&r")
1084         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1085                          (const_int 8)
1086                          (match_operand:SI 2 "const_int_operand" "n")))]
1087   "(INTVAL (operands[2]) & 7) == 0"
1088   "lis %0,0\;mc3%B2 %0,%1"
1089   [(set_attr "type" "multi")
1090    (set_attr "cc" "change0")])
1091
1092 (define_split
1093   [(set (match_operand:SI 0 "register_operand" "=&r")
1094         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1095                          (const_int 8)
1096                          (match_operand:SI 2 "const_int_operand" "n")))]
1097   "(INTVAL (operands[2]) & 7) == 0"
1098   [(set (match_dup 0) (const_int 0))
1099    (set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 24))
1100         (zero_extract:SI (match_dup 1) (const_int 8) (match_dup 2)))]
1101   "")
1102
1103 (define_insn ""
1104   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1105                          (const_int 8)
1106                          (const_int 24))
1107         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1108                          (const_int 8)
1109                          (match_operand:SI 2 "const_int_operand" "n")))]
1110   "(INTVAL (operands[2]) & 7) == 0"
1111   "mc3%B2 %0,%1"
1112   [(set_attr "type" "address")
1113    (set_attr "length" "2")])
1114
1115 (define_expand "insv"
1116   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
1117                          (match_operand:SI 1 "const_int_operand" "")
1118                          (match_operand:SI 2 "const_int_operand" ""))
1119         (match_operand:SI 3 "register_operand" ""))]
1120   ""
1121   "
1122 {
1123   if (GET_CODE (operands[2]) != CONST_INT)
1124     FAIL;
1125
1126   if (GET_CODE (operands[1]) != CONST_INT)
1127     FAIL;
1128
1129   if (INTVAL (operands[1]) == 1)
1130     {
1131       emit_insn (gen_bit_insv (operands[0], operands[1], operands[2],
1132                                operands[3]));
1133       DONE;
1134     }
1135   else if (INTVAL (operands[1]) == 8
1136            && (INTVAL (operands[2]) % 8 == 0))
1137     ;                           /* Accept aligned byte-wide field. */
1138   else
1139     FAIL;
1140 }")
1141
1142 ;; For a single-bit insert, it is better to explicitly generate references
1143 ;; to the T bit.  We will call the T bit "CC0" because it can be clobbered
1144 ;; by some CC0 sets (single-bit tests).
1145
1146 (define_expand "bit_insv"
1147   [(set (cc0)
1148         (zero_extract:SI (match_operand:SI 3 "register_operand" "")
1149                          (const_int 1)
1150                          (const_int 31)))
1151    (parallel [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
1152                                     (match_operand:SI 1 "const_int_operand" "")
1153                                     (match_operand:SI 2 "const_int_operand" ""))
1154                    (ne (cc0) (const_int 0)))
1155               (clobber (match_scratch:SI 4 ""))])]
1156   ""
1157   "")
1158         
1159 (define_insn ""
1160   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1161                          (const_int 8)
1162                          (match_operand:SI 1 "const_int_operand" "n"))
1163         (match_operand:SI 2 "register_operand" "r"))]
1164   "(INTVAL (operands[1]) & 7) == 0"
1165   "mc%B1%.3 %0,%2"
1166   [(set_attr "type" "address")
1167    (set_attr "length" "2")])
1168
1169 ;; This pattern cannot have any input reloads since if references CC0.
1170 ;; So we have to add code to support memory, which is the only other
1171 ;; thing that a "register_operand" can become.  There is still a problem
1172 ;; if the address isn't valid and *it* needs a reload, but there is no
1173 ;; way to solve that problem, so let's hope it never happens.
1174
1175 (define_insn ""
1176   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,m")
1177                          (const_int 1)
1178                          (match_operand:SI 1 "const_int_operand" "n,m"))
1179         (ne (cc0) (const_int 0)))
1180    (clobber (match_scratch:SI 2 "=X,b"))]
1181   ""
1182   "@
1183    mftbi%t1 %0,%S1
1184    l%M0 %2,%0\;mftb%t1 %2,%S1\;st%M0 %2,%0"
1185   [(set_attr "type" "*,multi")
1186    (set_attr "cc" "none,none")
1187    (set_attr "length" "2,10")])
1188 \f
1189 ;; Arithmetic instructions.  First, add and subtract.
1190 ;;
1191 ;; It may be that the second input is either large or small enough that
1192 ;; the operation cannot be done in a single insn.  In that case, emit two.
1193 (define_expand "addsi3"
1194   [(set (match_operand:SI 0 "register_operand" "")
1195         (plus:SI (match_operand:SI 1 "register_operand" "")
1196                  (match_operand:SI 2 "nonmemory_operand" "")))]
1197   ""
1198   "
1199 {
1200   if (GET_CODE (operands[2]) == CONST_INT
1201       && (unsigned) (INTVAL (operands[2]) + 0x8000) >= 0x10000
1202       && (INTVAL (operands[2]) & 0xffff) != 0)
1203     {
1204       int low = INTVAL (operands[2]) & 0xffff;
1205       int high = (unsigned) INTVAL (operands[2]) >> 16;
1206
1207       if (low & 0x8000)
1208         high++, low |= 0xffff0000;
1209
1210       emit_insn (gen_addsi3 (operands[0], operands[1],
1211                              gen_rtx (CONST_INT, VOIDmode, high << 16)));
1212       operands[1] = operands[0];
1213       operands[2] = gen_rtx (CONST_INT, VOIDmode, low);
1214     }
1215 }")
1216
1217 ;; Put the insn to add a symbolic constant to a register separately to
1218 ;; improve register allocation since it has different register requirements.
1219 (define_insn ""
1220   [(set (match_operand:SI 0 "register_operand" "=b")
1221         (plus:SI (match_operand:SI 1 "register_operand" "%b")
1222                  (match_operand:SI 2 "romp_symbolic_operand" "s")))]
1223    ""
1224    "get %0,$%2(%1)"
1225    [(set_attr "type" "address")
1226     (set_attr "length" "8")])
1227
1228 (define_insn ""
1229   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,b")
1230         (plus:SI (match_operand:SI 1 "reg_or_add_operand" "%0,0,r,b,0,r,b")
1231                  (match_operand:SI 2 "reg_or_add_operand" "I,J,K,M,r,b,s")))]
1232   "register_operand (operands[1], SImode)
1233    || register_operand (operands[2], SImode)"
1234   "@
1235    ais %0,%2
1236    sis %0,%n2
1237    ail %0,%1,%2
1238    cau %0,%H2(%1)
1239    a %0,%2
1240    cas %0,%1,%2
1241    get %0,$%2(%1)"
1242   [(set_attr "type" "arith,arith,arith,address,arith,address,misc")
1243    (set_attr "length" "2,2,4,4,2,2,8")])
1244
1245 ;; Now subtract.
1246 ;;
1247 ;; 1.   If third operand is constant integer, convert it to add of the negative
1248 ;;      of that integer.
1249 ;; 2.   If the second operand is not a valid constant integer, force it into a
1250 ;;      register.
1251 (define_expand "subsi3"
1252   [(set (match_operand:SI 0 "register_operand" "")
1253         (minus:SI (match_operand:SI 1 "reg_or_any_cint_operand" "")
1254                   (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1255   ""
1256   "
1257 {
1258   if (GET_CODE (operands [2]) == CONST_INT)
1259     {
1260       emit_insn (gen_addsi3 (operands[0], operands[1], 
1261                              gen_rtx (CONST_INT,
1262                                       VOIDmode, - INTVAL (operands[2]))));
1263       DONE;
1264     }
1265   else
1266     operands[2] = force_reg (SImode, operands[2]);
1267
1268   if (GET_CODE (operands[1]) != CONST_INT
1269       || (unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000)
1270     operands[1] = force_reg (SImode, operands[1]);
1271 }")
1272
1273 (define_insn ""
1274   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1275         (minus:SI (match_operand:SI 1 "reg_or_D_operand" "K,0,r")
1276                   (match_operand:SI 2 "register_operand" "r,r,0")))]
1277   ""
1278   "@
1279    sfi %0,%2,%1
1280    s %0,%2
1281    sf %0,%1"
1282   [(set_attr "length" "4,2,2")])
1283 \f
1284 ;; Multiply either calls a special RT routine or is done in-line, depending
1285 ;; on the value of a -m flag.
1286 ;;
1287 ;; First define the way we call the subroutine.
1288 (define_expand "mulsi3_subr"
1289   [(set (reg:SI 2) (match_operand:SI 1 "register_operand" ""))
1290    (set (reg:SI 3) (match_operand:SI 2 "register_operand" ""))
1291    (parallel [(set (reg:SI 2) (mult:SI (reg:SI 2) (reg:SI 3)))
1292               (clobber (reg:SI 0))
1293               (clobber (reg:SI 15))])
1294    (set (match_operand:SI 0 "register_operand" "")
1295         (reg:SI 2))]
1296   ""
1297   "")
1298
1299 (define_expand "mulsi3"
1300   [(set (match_operand:SI 0 "register_operand" "")
1301         (mult:SI (match_operand:SI 1 "register_operand" "")
1302                  (match_operand:SI 2 "register_operand" "")))]
1303   ""
1304   "
1305 {
1306   if (! TARGET_IN_LINE_MUL)
1307     {
1308       emit_insn (gen_mulsi3_subr (operands[0], operands[1], operands[2]));
1309       DONE;
1310     }
1311 }")
1312
1313 ;; Define the patterns to match.
1314 ;; We would like to provide a delay slot for the insns that call internal
1315 ;; routines, but doing so is risky since reorg will think that the use of
1316 ;; r2 and r3 is completed in the insn needing the delay slot.  Also, it
1317 ;; won't know that the cc will be clobbered.  So take the safe approach
1318 ;; and don't give them delay slots.
1319 (define_insn ""
1320   [(set (reg:SI 2)
1321         (mult:SI (reg:SI 2) (reg:SI 3)))
1322    (clobber (reg:SI 0))
1323    (clobber (reg:SI 15))]
1324   "! TARGET_IN_LINE_MUL"
1325   "bali%# r15,lmul$$"
1326   [(set_attr "type" "misc")
1327    (set_attr "in_delay_slot" "no")])
1328
1329 (define_insn ""
1330   [(set (match_operand:SI 0 "register_operand" "=&r")
1331         (mult:SI (match_operand:SI 1 "register_operand" "%r")
1332                  (match_operand:SI 2 "register_operand" "r")))]
1333   "TARGET_IN_LINE_MUL"
1334   "*
1335 { return output_in_line_mul (); }"
1336   [(set_attr "length" "38")
1337    (set_attr "type" "multi")])
1338 \f
1339 ;; Handle divide and modulus.  The same function returns both values,
1340 ;; so use divmodsi4.  This divides arg 1 by arg 2 with quotient to go
1341 ;; into arg 0 and remainder in arg 3.
1342 ;;
1343 ;; We want to put REG_EQUAL notes for the two outputs.  So we need a
1344 ;; function to do everything else.
1345 (define_expand "divmodsi4_doit"
1346   [(set (reg:SI 2)
1347         (match_operand:SI 0 "register_operand" ""))
1348    (set (reg:SI 3)
1349         (match_operand:SI 1 "register_operand" ""))
1350    (parallel [(set (reg:SI 2) (div:SI (reg:SI 2) (reg:SI 3)))
1351               (set (reg:SI 3) (mod:SI (reg:SI 2) (reg:SI 3)))
1352               (clobber (reg:SI 0))
1353               (clobber (reg:SI 15))])]
1354   ""
1355   "")
1356
1357 (define_expand "divmodsi4"
1358   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1359                    (div:SI (match_operand:SI 1 "register_operand" "")
1360                            (match_operand:SI 2 "register_operand" "")))
1361               (set (match_operand:SI 3 "register_operand" "")
1362                    (mod:SI (match_dup 1) (match_dup 2)))])]
1363   ""
1364   "
1365 {
1366   rtx insn;
1367
1368   emit_insn (gen_divmodsi4_doit (operands[1], operands[2]));
1369   insn = emit_move_insn (operands[0], gen_rtx (REG, SImode, 2));
1370   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1371                               gen_rtx (DIV, SImode, operands[1],
1372                                        operands[2]),
1373                               REG_NOTES (insn));
1374   insn = emit_move_insn (operands[3], gen_rtx (REG, SImode, 3));
1375   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1376                               gen_rtx (MOD, SImode, operands[1],
1377                                        operands[2]),
1378                               REG_NOTES (insn));
1379   DONE;
1380 }")
1381
1382 (define_insn ""
1383   [(set (reg:SI 2)
1384         (div:SI (reg:SI 2) (reg:SI 3)))
1385    (set (reg:SI 3)
1386         (mod:SI (reg:SI 2) (reg:SI 3)))
1387    (clobber (reg:SI 0))
1388    (clobber (reg:SI 15))]
1389   ""
1390   "bali%# r15,ldiv$$"
1391   [(set_attr "type" "misc")
1392    (set_attr "in_delay_slot" "no")])
1393
1394 ;; Similarly for unsigned divide.
1395 (define_expand "udivmodsi4_doit"
1396   [(set (reg:SI 2)
1397         (match_operand:SI 0 "register_operand" ""))
1398    (set (reg:SI 3)
1399         (match_operand:SI 1 "register_operand" ""))
1400    (parallel [(set (reg:SI 2) (udiv:SI (reg:SI 2) (reg:SI 3)))
1401               (set (reg:SI 3) (umod:SI (reg:SI 2) (reg:SI 3)))
1402               (clobber (reg:SI 0))
1403               (clobber (reg:SI 15))])]
1404   ""
1405   "")
1406
1407 (define_expand "udivmodsi4"
1408   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1409                    (udiv:SI (match_operand:SI 1 "register_operand" "")
1410                             (match_operand:SI 2 "register_operand" "")))
1411               (set (match_operand:SI 3 "register_operand" "")
1412                    (umod:SI (match_dup 1) (match_dup 2)))])]
1413   ""
1414   "
1415 {
1416   rtx insn;
1417
1418   emit_insn (gen_udivmodsi4_doit (operands[1], operands[2]));
1419   insn = emit_move_insn (operands[0], gen_rtx (REG, SImode, 2));
1420   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1421                               gen_rtx (UDIV, SImode, operands[1],
1422                                        operands[2]),
1423                               REG_NOTES (insn));
1424   insn = emit_move_insn (operands[3], gen_rtx (REG, SImode, 3));
1425   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1426                               gen_rtx (UMOD, SImode, operands[1],
1427                                        operands[2]),
1428                               REG_NOTES (insn));
1429   DONE;
1430 }")
1431
1432 (define_insn ""
1433   [(set (reg:SI 2)
1434         (udiv:SI (reg:SI 2) (reg:SI 3)))
1435    (set (reg:SI 3)
1436         (umod:SI (reg:SI 2) (reg:SI 3)))
1437    (clobber (reg:SI 0))
1438    (clobber (reg:SI 15))]
1439   ""
1440   "bali%# r15,uldiv$$"
1441   [(set_attr "type" "misc")
1442    (set_attr "in_delay_slot" "no")])
1443 \f
1444 ;; Define DImode arithmetic operations.
1445 ;;
1446 ;; It is possible to do certain adds and subtracts with constants in a single
1447 ;; insn, but it doesn't seem worth the trouble.
1448 ;;
1449 ;; Don't use DEFINE_SPLIT on these because the dependency on CC can't be
1450 ;; easily tracked in that case!
1451 (define_insn "adddi3"
1452   [(set (match_operand:DI 0 "register_operand" "=r")
1453         (plus:DI (match_operand:DI 1 "register_operand" "%0")
1454                  (match_operand:DI 2 "register_operand" "r")))]
1455   ""
1456   "a %O0,%O2\;ae %0,%2"
1457   [(set_attr "type" "multi")])
1458
1459 (define_insn "subdi3"
1460   [(set (match_operand:DI 0 "register_operand" "=r")
1461         (minus:DI (match_operand:DI 1 "register_operand" "0")
1462                   (match_operand:DI 2 "register_operand" "r")))]
1463   ""
1464   "s %O0,%O2\;se %0,%2"
1465   [(set_attr "type" "multi")])
1466
1467 (define_insn "negdi2"
1468   [(set (match_operand:DI 0 "register_operand" "=r,&r")
1469         (neg:DI (match_operand:DI 1 "register_operand" "0,r")))]
1470   ""
1471   "twoc %O0,%O1\;onec %0,%1\;aei %0,%0,0"
1472   [(set_attr "type" "multi")
1473    (set_attr "length" "8")])
1474 \f
1475 ;; Unary arithmetic operations.
1476 (define_insn "abssi2"
1477   [(set (match_operand:SI 0 "register_operand" "=r")
1478         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
1479   ""
1480   "abs %0,%1"
1481   [(set_attr "length" "2")])
1482
1483 (define_insn "negsi2"
1484   [(set (match_operand:SI 0 "register_operand" "=r")
1485         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1486   ""
1487   "twoc %0,%1"
1488   [(set_attr "length" "2")])
1489
1490 (define_insn "one_cmplsi2"
1491   [(set (match_operand:SI 0 "register_operand" "=r")
1492         (not:SI (match_operand:SI 1 "register_operand" "r")))]
1493   ""
1494   "onec %0,%1"
1495   [(set_attr "length" "2")])
1496
1497 \f
1498 ;; Logical insns: AND, IOR, and XOR
1499 ;;
1500 ;; If the operation is being performed on a 32-bit constant such that
1501 ;; it cannot be done in one insn, do it in two.  We may lose a bit on
1502 ;; CSE in pathological cases, but it seems better doing it this way.
1503 (define_expand "andsi3"
1504   [(set (match_operand:SI 0 "register_operand" "")
1505         (and:SI (match_operand:SI 1 "register_operand" "")
1506                 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1507   ""
1508   "
1509 {
1510   if (GET_CODE (operands[2]) == CONST_INT)
1511     {
1512       int top = (unsigned) INTVAL (operands[2]) >> 16;
1513       int bottom = INTVAL (operands[2]) & 0xffff;
1514
1515       if (top != 0 && top != 0xffff && bottom != 0 && bottom != 0xffff)
1516         {
1517           emit_insn (gen_andsi3 (operands[0], operands[1],
1518                                  gen_rtx (CONST_INT, VOIDmode,
1519                                           (top << 16) | 0xffff)));
1520           operands[1] = operands[0];
1521           operands[2] = gen_rtx (CONST_INT, VOIDmode, 0xffff0000 | bottom);
1522         }
1523     }
1524 }");
1525
1526 (define_insn ""
1527   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1528         (and:SI (match_operand:SI 1 "reg_or_and_operand" "%0,r,0")
1529                 (match_operand:SI 2 "reg_or_and_operand" "P,LMO,r")))]
1530   "register_operand (operands[1], SImode)
1531    || register_operand (operands[2], SImode)"
1532   "@
1533    clrb%k2 %0,%b2
1534    ni%z2 %0,%1,%Z2
1535    n %0,%2"
1536   [(set_attr "length" "2,4,2")])
1537
1538 ;; logical OR (IOR)
1539 (define_expand "iorsi3"
1540   [(set (match_operand:SI 0 "register_operand" "")
1541         (ior:SI (match_operand:SI 1 "register_operand" "")
1542                 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1543   ""
1544   "
1545 {
1546   if (GET_CODE (operands[2]) == CONST_INT)
1547     {
1548       int top = (unsigned) INTVAL (operands[2]) >> 16;
1549       int bottom = INTVAL (operands[2]) & 0xffff;
1550
1551       if (top != 0 && bottom != 0)
1552         {
1553           emit_insn (gen_iorsi3 (operands[0], operands[1],
1554                                  gen_rtx (CONST_INT, VOIDmode, (top << 16))));
1555           operands[1] = operands[0];
1556           operands[2] = gen_rtx (CONST_INT, VOIDmode, bottom);
1557         }
1558     }
1559 }");
1560
1561 (define_insn ""
1562   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1563         (ior:SI (match_operand:SI 1 "reg_or_cint_operand" "%0,r,0")
1564                 (match_operand:SI 2 "reg_or_cint_operand" "N,LM,r")))]
1565   "register_operand (operands[1], SImode)
1566    || register_operand (operands[2], SImode)"
1567   "@
1568    setb%h2 %0,%b2
1569    oi%h2 %0,%1,%H2
1570    o %0,%2"
1571   [(set_attr "length" "2,4,2")])
1572
1573 ;; exclusive-or (XOR)
1574 (define_expand "xorsi3"
1575   [(set (match_operand:SI 0 "register_operand" "")
1576         (xor:SI (match_operand:SI 1 "register_operand" "")
1577                 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1578   ""
1579   "
1580 {
1581   if (GET_CODE (operands[2]) == CONST_INT)
1582     {
1583       int top = (unsigned) INTVAL (operands[2]) >> 16;
1584       int bottom = INTVAL (operands[2]) & 0xffff;
1585
1586       if (top == 0xffff && bottom == 0xffff)
1587         {
1588           emit_insn (gen_one_cmplsi2 (operands[0], operands[1]));
1589           DONE;
1590         }
1591       else if (top != 0 && bottom != 0)
1592         {
1593           emit_insn (gen_xorsi3 (operands[0], operands[1],
1594                                  gen_rtx (CONST_INT, VOIDmode, (top << 16))));
1595           operands[1] = operands[0];
1596           operands[2] = gen_rtx (CONST_INT, VOIDmode, bottom);
1597         }
1598     }
1599 }");
1600
1601 (define_insn ""
1602   [(set (match_operand:SI 0 "register_operand" "=r,r")
1603         (xor:SI (match_operand:SI 1 "reg_or_cint_operand" "%r,0")
1604                 (match_operand:SI 2 "reg_or_cint_operand" "LM,r")))]
1605   "register_operand (operands[1], SImode)
1606    || register_operand (operands[2], SImode)"
1607   "@
1608    xi%h2 %0,%1,%H2
1609    x %0,%2"
1610   [(set_attr "length" "4,2")])
1611 \f
1612 ;; Various shift insns
1613 (define_insn "ashrsi3"
1614   [(set (match_operand:SI 0 "register_operand" "=r,r")
1615         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1616                      (match_operand:SI 2 "reg_or_cint_operand" "r,n")))]
1617   ""
1618   "@
1619    sar %0,%2
1620    sari%s2 %0,%S2"
1621   [(set_attr "length" "2")])
1622
1623 (define_insn "lshrsi3"
1624   [(set (match_operand:SI 0 "register_operand" "=r,r")
1625         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1626                      (match_operand:SI 2 "reg_or_cint_operand" "r,n")))]
1627   ""
1628   "@
1629    sr %0,%2
1630    sri%s2 %0,%S2"
1631   [(set_attr "length" "2")])
1632
1633 (define_insn ""
1634   [(set (match_operand:SI 0 "register_operand" "=r")
1635         (ashift:SI (match_operand:SI 1 "register_operand" "b")
1636                    (const_int 1)))]
1637   ""
1638   "cas %0,%1,%1"
1639   [(set_attr "length" "2")
1640    (set_attr "type" "address")])
1641
1642 (define_insn "ashlsi3"
1643   [(set (match_operand:SI 0 "register_operand" "=r,r")
1644         (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
1645                    (match_operand:SI 2 "reg_or_cint_operand" "r,n")))]
1646   ""
1647   "@
1648    sl %0,%2
1649    sli%s2 %0,%S2"
1650   [(set_attr "length" "2")])
1651 \f
1652 ;; Function call insns:
1653 ;;
1654 ;; On the ROMP, &fcn is actually a pointer to the data area, which is passed
1655 ;; to the function in r0.  &.fcn is the actual starting address of the
1656 ;; function.  Also, the word at &fcn contains &.fcn.
1657 ;;
1658 ;; For both functions that do and don't return values, there are two cases:
1659 ;; where the function's address is a constant, and where it isn't.
1660 ;;
1661 ;; Operand 1 (2 for `call_value') is the number of arguments and is not used.
1662 (define_expand "call"
1663   [(use (reg:SI 0))
1664    (parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
1665                     (match_operand 1 "" ""))
1666               (clobber (reg:SI 15))])]
1667   ""
1668   "
1669 {
1670   if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
1671     abort();
1672
1673   operands[0] = XEXP (operands[0], 0);
1674   if (GET_CODE (operands[0]) == SYMBOL_REF)
1675     {
1676       extern rtx get_symref ();
1677       char *real_fcnname =
1678                 (char *) alloca (strlen (XSTR (operands[0], 0)) + 2);
1679
1680       /* Copy the data area address to r0.  */
1681       emit_move_insn (gen_rtx (REG, SImode, 0),
1682                       force_reg (SImode, operands[0]));
1683       strcpy (real_fcnname, \".\");
1684       strcat (real_fcnname, XSTR (operands[0], 0));
1685       operands[0] = get_symref (real_fcnname);
1686     }
1687   else
1688     {
1689       rtx data_access;
1690
1691       emit_move_insn (gen_rtx (REG, SImode, 0),
1692                       force_reg (SImode, operands[0]));
1693       data_access = gen_rtx (MEM, SImode, operands[0]);
1694       RTX_UNCHANGING_P (data_access) = 1;
1695       operands[0] = copy_to_reg (data_access);
1696     }
1697 }")
1698
1699 (define_insn ""
1700   [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
1701          (match_operand 1 "" "g"))
1702    (clobber (reg:SI 15))]
1703   ""
1704   "balr%# r15,%0"
1705   [(set_attr "type" "call")
1706    (set_attr "length" "2")])
1707
1708 (define_insn ""
1709   [(call (mem:SI (match_operand:SI 0 "romp_symbolic_operand" "i"))
1710          (match_operand 1 "" "g"))
1711    (clobber (reg:SI 15))]
1712   "GET_CODE (operands[0]) == SYMBOL_REF"
1713   "bali%# r15,%0"
1714   [(set_attr "type" "call")])
1715
1716 ;; Call a function and return a value.
1717 (define_expand "call_value"
1718   [(use (reg:SI 0))
1719    (parallel [(set (match_operand 0 "" "=fg")
1720                    (call (mem:SI (match_operand:SI 1 "address_operand" ""))
1721                          (match_operand 2 "" "")))
1722               (clobber (reg:SI 15))])]
1723   ""
1724   "
1725 {
1726   if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
1727     abort();
1728
1729   operands[1] = XEXP (operands[1], 0);
1730   if (GET_CODE (operands[1]) == SYMBOL_REF)
1731     {
1732       extern rtx get_symref ();
1733       char *real_fcnname =
1734                 (char *) alloca (strlen (XSTR (operands[1], 0)) + 2);
1735
1736       /* Copy the data area address to r0.  */
1737       emit_move_insn (gen_rtx (REG, SImode, 0),
1738                       force_reg (SImode, operands[1]));
1739       strcpy (real_fcnname, \".\");
1740       strcat (real_fcnname, XSTR (operands[1], 0));
1741       operands[1] = get_symref (real_fcnname);
1742     }
1743   else
1744     {
1745       rtx data_access;
1746
1747       emit_move_insn (gen_rtx (REG, SImode, 0),
1748                       force_reg (SImode, operands[1]));
1749       data_access = gen_rtx (MEM, SImode, operands[1]);
1750       RTX_UNCHANGING_P (data_access) = 1;
1751       operands[1] = copy_to_reg (data_access);
1752     }
1753 }")
1754
1755 (define_insn ""
1756   [(set (match_operand 0 "" "=fg")
1757         (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
1758               (match_operand 2 "" "g")))
1759    (clobber (reg:SI 15))]
1760   ""
1761   "balr%# r15,%1"
1762   [(set_attr "length" "2")
1763    (set_attr "type" "call")])
1764
1765 (define_insn ""
1766   [(set (match_operand 0 "" "=fg")
1767         (call (mem:SI (match_operand:SI 1 "romp_symbolic_operand" "i"))
1768               (match_operand 2 "" "g")))
1769    (clobber (reg:SI 15))]
1770   "GET_CODE (operands[1]) == SYMBOL_REF"
1771   "bali%# r15,%1"
1772   [(set_attr "type" "call")])
1773
1774 ;; Call subroutine returning any type.
1775
1776 (define_expand "untyped_call"
1777   [(parallel [(call (match_operand 0 "" "")
1778                     (const_int 0))
1779               (match_operand 1 "" "")
1780               (match_operand 2 "" "")])]
1781   ""
1782   "
1783 {
1784   int i;
1785
1786   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
1787
1788   for (i = 0; i < XVECLEN (operands[2], 0); i++)
1789     {
1790       rtx set = XVECEXP (operands[2], 0, i);
1791       emit_move_insn (SET_DEST (set), SET_SRC (set));
1792     }
1793
1794   /* The optimizer does not know that the call sets the function value
1795      registers we stored in the result block.  We avoid problems by
1796      claiming that all hard registers are used and clobbered at this
1797      point.  */
1798   emit_insn (gen_blockage ());
1799
1800   DONE;
1801 }")
1802
1803 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1804 ;; all of memory.  This blocks insns from being moved across this point.
1805
1806 (define_insn "blockage"
1807   [(unspec_volatile [(const_int 0)] 0)]
1808   ""
1809   "")
1810
1811 ;; No operation insn.
1812 (define_insn "nop"
1813   [(const_int 0)]
1814   ""
1815   "nopr r0"
1816   [(set_attr "type" "address")
1817    (set_attr "length" "2")
1818    (set_attr "cc" "none")])
1819 \f
1820 ;; Here are the floating-point operations.
1821 ;;
1822 ;; Start by providing DEFINE_EXPAND for each operation.
1823 ;; The insns will be handled with MATCH_OPERATOR; the methodology will be
1824 ;; discussed below.
1825
1826 ;; First the conversion operations.
1827
1828 (define_expand "truncdfsf2"
1829   [(parallel [(set (match_operand:SF 0 "general_operand" "")
1830                    (float_truncate:SF (match_operand:DF 1 "general_operand" "")))
1831               (clobber (reg:SI 0))
1832               (clobber (reg:SI 15))])]
1833   ""
1834   "")
1835
1836 (define_expand "extendsfdf2"
1837   [(parallel [(set (match_operand:DF 0 "general_operand" "")
1838                    (float_extend:DF (match_operand:SF 1 "general_operand" "")))
1839               (clobber (reg:SI 0))
1840               (clobber (reg:SI 15))])]
1841   ""
1842   "")
1843
1844 (define_expand "floatsisf2"
1845   [(parallel [(set (match_operand:SF 0 "general_operand" "")
1846                    (float:SF (match_operand:SI 1 "general_operand" "")))
1847               (clobber (reg:SI 0))
1848               (clobber (reg:SI 15))])]
1849   ""
1850   "")
1851
1852 (define_expand "floatsidf2"
1853   [(parallel [(set (match_operand:DF 0 "general_operand" "")
1854                    (float:DF (match_operand:SI 1 "general_operand" "")))
1855               (clobber (reg:SI 0))
1856               (clobber (reg:SI 15))])]
1857   ""
1858   "")
1859
1860 (define_expand "fix_truncsfsi2"
1861   [(parallel [(set (match_operand:SI 0 "general_operand" "")
1862                    (fix:SI (match_operand:SF 1 "general_operand" "")))
1863               (clobber (reg:SI 0))
1864               (clobber (reg:SI 15))])]
1865   ""
1866   "")
1867
1868 (define_expand "fix_truncdfsi2"
1869   [(parallel [(set (match_operand:SI 0 "general_operand" "")
1870                    (fix:SI (match_operand:DF 1 "general_operand" "")))
1871               (clobber (reg:SI 0))
1872               (clobber (reg:SI 15))])]
1873   ""
1874   "")
1875 \f
1876 ;; Now the binary operations.
1877
1878 (define_expand "addsf3"
1879   [(parallel [(set (match_operand:SF 0 "general_operand" "")
1880                    (plus:SF (match_operand:SF 1 "general_operand" "")
1881                             (match_operand:SF 2 "general_operand" "")))
1882               (clobber (reg:SI 0))
1883               (clobber (reg:SI 15))])]
1884   ""
1885   "")
1886
1887 (define_expand "adddf3"
1888   [(parallel [(set (match_operand:DF 0 "general_operand" "")
1889                    (plus:DF (match_operand:DF 1 "general_operand" "")
1890                             (match_operand:DF 2 "general_operand" "")))
1891                (clobber (reg:SI 0))
1892                (clobber (reg:SI 15))])]
1893   ""
1894   "")
1895
1896 (define_expand "subsf3"
1897   [(parallel [(set (match_operand:SF 0 "general_operand" "")
1898                    (minus:SF (match_operand:SF 1 "general_operand" "")
1899                              (match_operand:SF 2 "general_operand" "")))
1900               (clobber (reg:SI 0))
1901               (clobber (reg:SI 15))])]
1902   ""
1903   "")
1904
1905 (define_expand "subdf3"
1906   [(parallel [(set (match_operand:DF 0 "general_operand" "")
1907                    (minus:DF (match_operand:DF 1 "general_operand" "")
1908                              (match_operand:DF 2 "general_operand" "")))
1909               (clobber (reg:SI 0))
1910               (clobber (reg:SI 15))])]
1911   ""
1912   "")
1913
1914 (define_expand "mulsf3"
1915   [(parallel [(set (match_operand:SF 0 "general_operand" "")
1916                    (mult:SF (match_operand:SF 1 "general_operand" "")
1917                             (match_operand:SF 2 "general_operand" "")))
1918               (clobber (reg:SI 0))
1919               (clobber (reg:SI 15))])]
1920   ""
1921   "")
1922
1923 (define_expand "muldf3"
1924   [(parallel [(set (match_operand:DF 0 "general_operand" "")
1925                    (mult:DF (match_operand:DF 1 "general_operand" "")
1926                             (match_operand:DF 2 "general_operand" "")))
1927               (clobber (reg:SI 0))
1928               (clobber (reg:SI 15))])]
1929   ""
1930   "")
1931
1932 (define_expand "divsf3"
1933   [(parallel [(set (match_operand:SF 0 "general_operand" "")
1934                    (div:SF (match_operand:SF 1 "general_operand" "")
1935                            (match_operand:SF 2 "general_operand" "")))
1936               (clobber (reg:SI 0))
1937               (clobber (reg:SI 15))])]
1938   ""
1939   "")
1940
1941 (define_expand "divdf3"
1942   [(parallel [(set (match_operand:DF 0 "general_operand" "")
1943                    (div:DF (match_operand:DF 1 "general_operand" "")
1944                            (match_operand:DF 2 "general_operand" "")))
1945               (clobber (reg:SI 0))
1946               (clobber (reg:SI 15))])]
1947   ""
1948   "")
1949 \f
1950 ;; Unary floating-point operations.
1951 ;;
1952 ;; Negations can be done without floating-point, since this is IEEE.
1953 ;; But we cannot do this if an operand is a hard FP register, since
1954 ;; the SUBREG we create would not be valid.
1955 (define_expand "negsf2"
1956   [(set (match_operand:SF 0 "register_operand" "")
1957         (neg:SF (match_operand:SF 1 "register_operand" "")))]
1958   ""
1959   "
1960 {
1961   if (! (GET_CODE (operands[0]) == REG
1962          && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
1963          && FP_REGNO_P (REGNO (operands[0])))
1964       && ! (GET_CODE (operands[1]) == REG
1965             && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
1966             && FP_REGNO_P (REGNO (operands[1]))))
1967     {
1968       rtx result;
1969       rtx target = operand_subword (operands[0], 0, 1, SFmode);
1970
1971       result = expand_binop (SImode, xor_optab,
1972                              operand_subword_force (operands[1], 0, SFmode),
1973                              gen_rtx (CONST_INT, VOIDmode, 0x80000000),
1974                              target, 0, OPTAB_WIDEN);
1975       if (result == 0)
1976         abort ();
1977
1978       if (result != target)
1979         emit_move_insn (result, target);
1980
1981       /* Make a place for REG_EQUAL.  */
1982       emit_move_insn (operands[0], operands[0]);
1983       DONE;
1984     }
1985 }")
1986
1987 (define_expand "negdf2"
1988   [(set (match_operand:DF 0 "register_operand" "")
1989         (neg:DF (match_operand:DF 1 "register_operand" "")))]
1990   ""
1991   "
1992 {
1993   if (! (GET_CODE (operands[0]) == REG
1994          && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
1995          && FP_REGNO_P (REGNO (operands[0])))
1996       && ! (GET_CODE (operands[1]) == REG
1997             && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
1998             && FP_REGNO_P (REGNO (operands[1]))))
1999     {
2000       rtx result;
2001       rtx target = operand_subword (operands[0], 0, 1, DFmode);
2002       rtx insns;
2003
2004       start_sequence ();
2005       result = expand_binop (SImode, xor_optab,
2006                              operand_subword_force (operands[1], 0, DFmode),
2007                              gen_rtx (CONST_INT, VOIDmode, 0x80000000),
2008                              target, 0, OPTAB_WIDEN);
2009       if (result == 0)
2010         abort ();
2011
2012       if (result != target)
2013         emit_move_insn (result, target);
2014   
2015       emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
2016                       operand_subword_force (operands[1], 1, DFmode));
2017
2018       insns = get_insns ();
2019       end_sequence ();
2020
2021       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2022       DONE;
2023     }
2024 }")
2025
2026 (define_expand "abssf2"
2027   [(parallel [(set (match_operand:SF 0 "general_operand" "")
2028                    (abs:SF (match_operand:SF 1 "general_operand" "")))
2029               (clobber (reg:SI 0))
2030               (clobber (reg:SI 15))])]
2031   ""
2032   "")
2033
2034 (define_expand "absdf2"
2035   [(parallel [(set (match_operand:DF 0 "general_operand" "")
2036                    (abs:DF (match_operand:DF 1 "general_operand" "")))
2037               (clobber (reg:SI 0))
2038               (clobber (reg:SI 15))])]
2039   ""
2040   "")
2041 \f
2042 ;; Any floating-point operation can be either SFmode or DFmode, and each
2043 ;; operand (including the output) can be either a normal operand or a
2044 ;; conversion from a normal operand.
2045 ;;
2046 ;; We use MATCH_OPERATOR to match a floating-point binary or unary operator
2047 ;; and input and output conversions.  So we need 2^N patterns for each type
2048 ;; of operation, where N is the number of operands, including the output.
2049 ;; There are thus a total of 14 patterns, 8 for binary operations, 4 for
2050 ;; unary operations and two for conversion/move operations (only one
2051 ;; operand can have a conversion for move operations).  In addition, we have
2052 ;; to be careful that a floating-point reload register doesn't get allocated
2053 ;; for an integer.  We take care of this for inputs with PREFERRED_RELOAD_CLASS
2054 ;; but need to have two different constraints for outputs.  This means that
2055 ;; we have to duplicate each pattern where the output could be an integer.
2056 ;; This adds another 7 patterns, for a total of 21.
2057
2058 ;; Start with conversion operations (moves are done above).
2059
2060 (define_insn ""
2061   [(set (match_operand:SI 0 "general_operand" "=g")
2062         (match_operator 1 "float_conversion"
2063                 [(match_operand 2 "general_operand" "frg")]))
2064    (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2065    (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2066   ""
2067   "*
2068 { return output_fpop (SET, operands[0], operands[2], 0, insn);
2069 }"
2070   [(set_attr "type" "fp")])
2071
2072 (define_insn ""
2073   [(set (match_operand 0 "general_operand" "=frg")
2074         (match_operator 1 "float_conversion"
2075                 [(match_operand 2 "general_operand" "frg")]))
2076    (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2077    (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2078   ""
2079   "*
2080 { return output_fpop (SET, operands[0], operands[2], 0, insn);
2081 }"
2082   [(set_attr "type" "fp")])
2083 \f
2084 ;; Next, binary floating-point operations.
2085
2086 (define_insn ""
2087   [(set (match_operand 0 "general_operand" "=frg")
2088         (match_operator 1 "float_binary"
2089                 [(match_operand 2 "general_operand" "frg")
2090                  (match_operand 3 "general_operand" "frg")]))
2091    (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2092    (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2093   "check_precision (GET_MODE (operands[1]), operands[2], operands[3])"
2094   "*
2095 { return output_fpop (GET_CODE (operands[1]), operands[0], 
2096                       operands[2], operands[3], insn);
2097 }"
2098   [(set_attr "type" "fp")])
2099
2100 (define_insn ""
2101   [(set (match_operand 0 "general_operand" "=frg")
2102         (match_operator 1 "float_binary"
2103                 [(match_operand 2 "general_operand" "frg")
2104                  (match_operator 3 "float_conversion"
2105                         [(match_operand 4 "general_operand" "frg")])]))
2106    (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2107    (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2108   "check_precision (GET_MODE (operands[1]), operands[2], operands[4])"
2109   "*
2110 { return output_fpop (GET_CODE (operands[1]), operands[0], 
2111                       operands[2], operands[4], insn);
2112 }"
2113   [(set_attr "type" "fp")])
2114
2115 (define_insn ""
2116   [(set (match_operand 0 "general_operand" "=frg")
2117         (match_operator 1 "float_binary"
2118                 [(match_operator 2 "float_conversion"
2119                         [(match_operand 3 "general_operand" "frg")])
2120                  (match_operand 4 "general_operand" "frg")]))
2121    (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2122    (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2123   "check_precision (GET_MODE (operands[1]), operands[3], operands[4])"
2124   "*
2125 { return output_fpop (GET_CODE (operands[1]), operands[0], 
2126                       operands[3], operands[4], insn);
2127 }"
2128   [(set_attr "type" "fp")])
2129
2130 (define_insn ""
2131   [(set (match_operand 0 "general_operand" "=frg")
2132         (match_operator 1 "float_binary"
2133                 [(match_operator 2 "float_conversion"
2134                         [(match_operand 3 "general_operand" "frg")])
2135                  (match_operator 4 "float_conversion"
2136                         [(match_operand 5 "general_operand" "frg")])]))
2137    (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2138    (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2139   "check_precision (GET_MODE (operands[1]), operands[3], operands[5])"
2140   "*
2141 { return output_fpop (GET_CODE (operands[1]), operands[0], 
2142                       operands[3], operands[5], insn);
2143 }"
2144   [(set_attr "type" "fp")])
2145
2146 (define_insn ""
2147   [(set (match_operand:SI 0 "general_operand" "=g")
2148         (match_operator 1 "float_conversion"
2149                 [(match_operator 2 "float_binary"
2150                         [(match_operand 3 "general_operand" "frg")
2151                          (match_operand 4 "general_operand" "frg")])]))
2152    (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2153    (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2154   "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2155   "*
2156 { return output_fpop (GET_CODE (operands[2]), operands[0], 
2157                       operands[3], operands[4], insn);
2158 }"
2159   [(set_attr "type" "fp")])
2160
2161 (define_insn ""
2162   [(set (match_operand 0 "general_operand" "=frg")
2163         (match_operator 1 "float_conversion"
2164                 [(match_operator 2 "float_binary"
2165                         [(match_operand 3 "general_operand" "frg")
2166                          (match_operand 4 "general_operand" "frg")])]))
2167    (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2168    (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2169   "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2170   "*
2171 { return output_fpop (GET_CODE (operands[2]), operands[0], 
2172                       operands[3], operands[4], insn);
2173 }"
2174   [(set_attr "type" "fp")])
2175
2176 (define_insn ""
2177   [(set (match_operand:SI 0 "general_operand" "=g")
2178         (match_operator 1 "float_conversion"
2179                 [(match_operator 2 "float_binary"
2180                         [(match_operand 3 "general_operand" "frg")
2181                          (match_operator 4 "float_conversion"
2182                                 [(match_operand 5 "general_operand" "frg")])])]))
2183    (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2184    (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2185   "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2186   "*
2187 { return output_fpop (GET_CODE (operands[2]), operands[0], 
2188                       operands[3], operands[5], insn);
2189 }"
2190   [(set_attr "type" "fp")])
2191
2192 (define_insn ""
2193   [(set (match_operand 0 "general_operand" "=frg")
2194         (match_operator 1 "float_conversion"
2195                 [(match_operator 2 "float_binary"
2196                         [(match_operand 3 "general_operand" "frg")
2197                          (match_operator 4 "float_conversion"
2198                                 [(match_operand 5 "general_operand" "frg")])])]))
2199    (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2200    (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2201   "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2202   "*
2203 { return output_fpop (GET_CODE (operands[2]), operands[0], 
2204                       operands[3], operands[5], insn);
2205 }"
2206   [(set_attr "type" "fp")])
2207
2208 (define_insn ""
2209   [(set (match_operand:SI 0 "general_operand" "=g")
2210         (match_operator 1 "float_conversion"
2211                 [(match_operator 2 "float_binary"
2212                         [(match_operator 3 "float_conversion"
2213                                 [(match_operand 4 "general_operand" "frg")])
2214                          (match_operand 5 "general_operand" "frg")])]))
2215    (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2216    (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2217   "check_precision (GET_MODE (operands[2]), operands[4], operands[5])"
2218   "*
2219 { return output_fpop (GET_CODE (operands[2]), operands[0], 
2220                       operands[4], operands[5], insn);
2221 }"
2222   [(set_attr "type" "fp")])
2223
2224 (define_insn ""
2225   [(set (match_operand 0 "general_operand" "=frg")
2226         (match_operator 1 "float_conversion"
2227                 [(match_operator 2 "float_binary"
2228                         [(match_operator 3 "float_conversion"
2229                                 [(match_operand 4 "general_operand" "frg")])
2230                          (match_operand 5 "general_operand" "frg")])]))
2231    (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2232    (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2233   "check_precision (GET_MODE (operands[2]), operands[4], operands[5])"
2234   "*
2235 { return output_fpop (GET_CODE (operands[2]), operands[0], 
2236                       operands[4], operands[5], insn);
2237 }"
2238   [(set_attr "type" "fp")])
2239
2240 (define_insn ""
2241   [(set (match_operand:SI 0 "general_operand" "=g")
2242         (match_operator 1 "float_conversion"
2243                 [(match_operator 2 "float_binary"
2244                         [(match_operator 3 "float_conversion"
2245                                 [(match_operand 4 "general_operand" "frg")])
2246                          (match_operator 5 "float_conversion"
2247                                 [(match_operand 6 "general_operand" "frg")])])]))
2248    (clobber (match_operand:SI 7 "reg_0_operand" "=&z"))
2249    (clobber (match_operand:SI 8 "reg_15_operand" "=&t"))]
2250   "check_precision (GET_MODE (operands[2]), operands[4], operands[6])"
2251   "*
2252 { return output_fpop (GET_CODE (operands[2]), operands[0], 
2253                       operands[4], operands[6], insn);
2254 }"
2255   [(set_attr "type" "fp")])
2256
2257 (define_insn ""
2258   [(set (match_operand 0 "general_operand" "=frg")
2259         (match_operator 1 "float_conversion"
2260                 [(match_operator 2 "float_binary"
2261                         [(match_operator 3 "float_conversion"
2262                                 [(match_operand 4 "general_operand" "frg")])
2263                          (match_operator 5 "float_conversion"
2264                                 [(match_operand 6 "general_operand" "frg")])])]))
2265    (clobber (match_operand:SI 7 "reg_0_operand" "=&z"))
2266    (clobber (match_operand:SI 8 "reg_15_operand" "=&t"))]
2267   "check_precision (GET_MODE (operands[2]), operands[4], operands[6])"
2268   "*
2269 { return output_fpop (GET_CODE (operands[2]), operands[0], 
2270                       operands[4], operands[6], insn);
2271 }"
2272   [(set_attr "type" "fp")])
2273 \f
2274 ;; Unary floating-point operations.
2275
2276 (define_insn ""
2277   [(set (match_operand 0 "general_operand" "=frg")
2278         (match_operator 1 "float_unary"
2279                 [(match_operand 2 "general_operand" "frg")]))
2280    (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2281    (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2282   "check_precision (GET_MODE (operands[1]), operands[2], 0)"
2283   "*
2284 { return output_fpop (GET_CODE (operands[1]), operands[0], operands[2],
2285                       0, insn);
2286 }"
2287   [(set_attr "type" "fp")])
2288
2289 (define_insn ""
2290   [(set (match_operand 0 "general_operand" "=frg")
2291         (match_operator 1 "float_unary"
2292                 [(match_operator 2 "float_conversion"
2293                         [(match_operand 3 "general_operand" "frg")])]))
2294    (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2295    (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2296   "check_precision (GET_MODE (operands[1]), operands[3], 0)"
2297   "*
2298 { return output_fpop (GET_CODE (operands[1]), operands[0], operands[3],
2299                       0, insn);
2300 }"
2301   [(set_attr "type" "fp")])
2302
2303 (define_insn ""
2304   [(set (match_operand:SI 0 "general_operand" "=g")
2305         (match_operator 1 "float_conversion"
2306                 [(match_operator 2 "float_unary"
2307                         [(match_operand 3 "general_operand" "frg")])]))
2308    (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2309    (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2310   "check_precision (GET_MODE (operands[2]), operands[3], 0)"
2311   "*
2312 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[3],
2313                       0, insn);
2314 }"
2315   [(set_attr "type" "fp")])
2316
2317 (define_insn ""
2318   [(set (match_operand 0 "general_operand" "=frg")
2319         (match_operator 1 "float_conversion"
2320                 [(match_operator 2 "float_unary"
2321                         [(match_operand 3 "general_operand" "frg")])]))
2322    (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2323    (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2324   "check_precision (GET_MODE (operands[2]), operands[3], 0)"
2325   "*
2326 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[3],
2327                       0, insn);
2328 }"
2329   [(set_attr "type" "fp")])
2330
2331 (define_insn ""
2332   [(set (match_operand:SI 0 "general_operand" "=g")
2333         (match_operator 1 "float_conversion"
2334                 [(match_operator 2 "float_unary"
2335                         [(match_operator 3 "float_conversion"
2336                                 [(match_operand 4 "general_operand" "frg")])])]))
2337    (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2338    (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2339   "check_precision (GET_MODE (operands[2]), operands[4], 0)"
2340   "*
2341 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[4],
2342                       0, insn);
2343 }"
2344   [(set_attr "type" "fp")])
2345
2346 (define_insn ""
2347   [(set (match_operand 0 "general_operand" "=frg")
2348         (match_operator 1 "float_conversion"
2349                 [(match_operator 2 "float_unary"
2350                         [(match_operator 3 "float_conversion"
2351                                 [(match_operand 4 "general_operand" "frg")])])]))
2352    (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2353    (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2354   "check_precision (GET_MODE (operands[2]), operands[4], 0)"
2355   "*
2356 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[4],
2357                       0, insn);
2358 }"
2359   [(set_attr "type" "fp")])
2360 \f
2361 ;; Compare insns are next.  Note that the ROMP has two types of compares,
2362 ;; signed & unsigned, and one type of branch.  Use the routine
2363 ;; `next_insn_tests_no_unsigned' to see which type to use.
2364 (define_expand "tstsi"
2365   [(set (cc0)
2366         (match_operand:SI 0 "register_operand" "r"))]
2367   ""
2368   "")
2369
2370 (define_expand "cmpsi"
2371   [(set (cc0)
2372         (compare (match_operand:SI 0 "register_operand" "")
2373                  (match_operand:SI 1 "reg_or_cint_operand" "")))]
2374   ""
2375   "")
2376
2377 ;; Signed compare, `test' first.
2378
2379 (define_insn ""
2380   [(set (cc0)
2381         (match_operand:SI 0 "register_operand" "r"))]
2382   "next_insn_tests_no_unsigned (insn)"
2383   "cis %0,0"
2384   [(set_attr "length" "2")
2385    (set_attr "type" "compare")])
2386
2387 (define_insn ""
2388   [(set (cc0) (match_operand:SI 0 "register_operand" "r,r,r"))
2389    (set (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "=0,r,Q")
2390         (match_dup 0))]
2391   "next_insn_tests_no_unsigned (insn)"
2392   "@
2393    cis %1,0
2394    nilo %1,%0,65535
2395    st%M1 %0,%1\;cis %0,0"
2396   [(set_attr "type" "compare,compare,store")
2397    (set_attr "length" "2,4,6")
2398    (set_attr "cc" "compare")])
2399
2400 (define_insn ""
2401   [(set (cc0)
2402         (compare (match_operand:SI 0 "register_operand" "r,r,r")
2403                  (match_operand:SI 1 "reg_or_cint_operand" "I,K,r")))]
2404   "next_insn_tests_no_unsigned (insn)"
2405   "@
2406    cis %0,%1
2407    cil %0,%1
2408    c %0,%1"
2409   [(set_attr "length" "2,4,2")
2410    (set_attr "type" "compare")])
2411
2412 ;; Unsigned comparisons, `test' first, again.
2413 (define_insn ""
2414   [(set (cc0)
2415         (match_operand:SI 0 "register_operand" "r"))]
2416   "! next_insn_tests_no_unsigned (insn)"
2417   "clil %0,0"
2418   [(set_attr "type" "compare")])
2419
2420 (define_insn ""
2421   [(set (cc0)
2422         (compare (match_operand:SI 0 "register_operand" "r,r")
2423                  (match_operand:SI 1 "reg_or_cint_operand" "K,r")))]
2424   "! next_insn_tests_no_unsigned (insn)"
2425   "@
2426    clil %0,%1
2427    cl %0,%1"
2428   [(set_attr "length" "4,2")
2429    (set_attr "type" "compare")])
2430
2431 ;; Bit test insn.  Many cases are converted into this by combine.  This
2432 ;; uses the ROMP test bit.
2433
2434 (define_insn ""
2435   [(set (cc0)
2436         (zero_extract (match_operand:SI 0 "register_operand" "r,r")
2437                       (const_int 1)
2438                       (match_operand:SI 1 "reg_or_any_cint_operand" "r,n")))]
2439   "next_insn_tests_no_inequality (insn)"
2440   "@
2441    mttb %0,%1
2442    mttbi%t1 %0,%S1"
2443   [(set_attr "length" "2")
2444    (set_attr "type" "compare")
2445    (set_attr "cc" "tbit")])
2446 \f
2447 ;; Floating-point comparisons.  There are two, equality and order.
2448 ;; The difference will be that a trap for NaN will be given on the orderr
2449 ;; comparisons only.
2450
2451 (define_expand "cmpsf"
2452   [(parallel [(set (cc0) (compare (match_operand:SF 0 "general_operand" "")
2453                                   (match_operand:SF 1 "general_operand" "")))
2454               (clobber (reg:SI 0))
2455               (clobber (reg:SI 15))])]
2456   ""
2457   "")
2458
2459 (define_expand "cmpdf"
2460   [(parallel [(set (cc0) (compare (match_operand:DF 0 "general_operand" "")
2461                                   (match_operand:DF 1 "general_operand" "")))
2462               (clobber (reg:SI 0))
2463               (clobber (reg:SI 15))])]
2464   ""
2465   "")
2466
2467 (define_expand "tstsf"
2468   [(parallel [(set (cc0) (match_operand:SF 0 "general_operand" ""))
2469               (clobber (reg:SI 0))
2470               (clobber (reg:SI 15))])]
2471   ""
2472   "")
2473
2474 (define_expand "tstdf"
2475   [(parallel [(set (cc0) (match_operand:DF 0 "general_operand" ""))
2476               (clobber (reg:SI 0))
2477               (clobber (reg:SI 15))])]
2478   ""
2479   "")
2480 \f
2481 ;; There are four cases for compare and two for test.  These correspond
2482 ;; to each input having a floating-point conversion or not.
2483
2484 (define_insn ""
2485   [(set (cc0) (compare (match_operand 0 "general_operand" "frg")
2486                        (match_operand 1 "general_operand" "frg")))
2487    (clobber (match_operand:SI 2 "reg_0_operand" "=&z"))
2488    (clobber (match_operand:SI 3 "reg_15_operand" "=&t"))]
2489   "GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode"
2490   "*
2491 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2492                       operands[0], operands[1], 0, insn);
2493 }"
2494   [(set_attr "type" "fp")
2495    (set_attr "cc" "compare")])
2496
2497 (define_insn ""
2498   [(set (cc0) (compare (match_operand 0 "general_operand" "frg")
2499                        (match_operator 1 "float_conversion"
2500                               [(match_operand 2 "general_operand" "frg")])))
2501    (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2502    (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2503   ""
2504   "*
2505 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2506                       operands[0], operands[2], 0, insn);
2507 }"
2508   [(set_attr "type" "fp")
2509    (set_attr "cc" "compare")])
2510
2511 (define_insn ""
2512   [(set (cc0) (compare (match_operator 0 "float_conversion"
2513                               [(match_operand 1 "general_operand" "frg")])
2514                        (match_operand 2 "general_operand" "frg")))
2515    (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2516    (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2517   ""
2518   "*
2519 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2520                       operands[1], operands[2], 0, insn);
2521 }"
2522   [(set_attr "type" "fp")
2523    (set_attr "cc" "compare")])
2524
2525 (define_insn ""
2526   [(set (cc0) (compare (match_operator 0 "float_conversion"
2527                               [(match_operand 1 "general_operand" "frg")])
2528                        (match_operator 2 "float_conversion"
2529                               [(match_operand 3 "general_operand" "frg")])))
2530    (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2531    (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2532   ""
2533   "*
2534 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2535                       operands[1], operands[3], 0, insn);
2536 }"
2537   [(set_attr "type" "fp")
2538    (set_attr "cc" "compare")])
2539
2540 (define_insn ""
2541   [(set (cc0) (match_operand 0 "general_operand" "frg"))
2542    (clobber (match_operand:SI 1 "reg_0_operand" "=&z"))
2543    (clobber (match_operand:SI 2 "reg_15_operand" "=&t"))]
2544   "GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode"
2545   "*
2546 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2547                       operands[0], CONST0_RTX (GET_MODE (operands[0])),
2548                       0, insn);
2549 }"
2550   [(set_attr "type" "fp")
2551    (set_attr "cc" "compare")])
2552
2553 (define_insn ""
2554   [(set (cc0) (match_operator 0 "float_conversion"
2555                         [(match_operand 1 "general_operand" "frg")]))
2556    (clobber (match_operand:SI 2 "reg_0_operand" "=&z"))
2557    (clobber (match_operand:SI 3 "reg_15_operand" "=&t"))]
2558   ""
2559   "*
2560 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2561                       operands[1], CONST0_RTX (GET_MODE (operands[1])),
2562                       0, insn);
2563 }"
2564   [(set_attr "type" "fp")
2565    (set_attr "cc" "compare")])
2566 \f
2567 ;; Branch insns.  Unsigned vs. signed have already
2568 ;; been taken care of.  The only insns that need to be concerned about the
2569 ;; test bit are beq and bne because the rest are either always true,
2570 ;; always false, or converted to EQ or NE.
2571
2572 ;; For conditional branches, we use `define_expand' and just have two patterns
2573 ;; that match them.  Operand printing does most of the work.
2574
2575 (define_expand "beq"
2576   [(set (pc)
2577         (if_then_else (eq (cc0)
2578                           (const_int 0))
2579                       (label_ref (match_operand 0 "" ""))
2580                       (pc)))]
2581   ""
2582   "")
2583
2584 (define_expand "bne"
2585   [(set (pc)
2586         (if_then_else (ne (cc0)
2587                           (const_int 0))
2588                       (label_ref (match_operand 0 "" ""))
2589                       (pc)))]
2590   ""
2591   "")
2592
2593 (define_expand "bgt"
2594   [(set (pc)
2595         (if_then_else (gt (cc0)
2596                           (const_int 0))
2597                       (label_ref (match_operand 0 "" ""))
2598                       (pc)))]
2599   ""
2600   "")
2601
2602 (define_expand "bgtu"
2603   [(set (pc)
2604         (if_then_else (gtu (cc0)
2605                            (const_int 0))
2606                       (label_ref (match_operand 0 "" ""))
2607                       (pc)))]
2608   ""
2609   "")
2610
2611 (define_expand "blt"
2612   [(set (pc)
2613         (if_then_else (lt (cc0)
2614                           (const_int 0))
2615                       (label_ref (match_operand 0 "" ""))
2616                       (pc)))]
2617   ""
2618   "")
2619
2620 (define_expand "bltu"
2621   [(set (pc)
2622         (if_then_else (ltu (cc0)
2623                            (const_int 0))
2624                       (label_ref (match_operand 0 "" ""))
2625                       (pc)))]
2626   ""
2627   "")
2628
2629 (define_expand "bge"
2630   [(set (pc)
2631         (if_then_else (ge (cc0)
2632                           (const_int 0))
2633                       (label_ref (match_operand 0 "" ""))
2634                       (pc)))]
2635   ""
2636   "")
2637
2638 (define_expand "bgeu"
2639   [(set (pc)
2640         (if_then_else (geu (cc0)
2641                            (const_int 0))
2642                       (label_ref (match_operand 0 "" ""))
2643                       (pc)))]
2644   ""
2645   "")
2646
2647 (define_expand "ble"
2648   [(set (pc)
2649         (if_then_else (le (cc0)
2650                           (const_int 0))
2651                       (label_ref (match_operand 0 "" ""))
2652                       (pc)))]
2653   ""
2654   "")
2655
2656 (define_expand "bleu"
2657   [(set (pc)
2658         (if_then_else (leu (cc0)
2659                            (const_int 0))
2660                       (label_ref (match_operand 0 "" ""))
2661                       (pc)))]
2662   ""
2663   "")
2664 \f
2665 ;; Define both directions of branch and return.
2666
2667 (define_insn ""
2668   [(set (pc)
2669         (if_then_else (match_operator 1 "comparison_operator"
2670                                       [(cc0) (const_int 0)])
2671                       (label_ref (match_operand 0 "" ""))
2672                       (pc)))]
2673   ""
2674   "*
2675 {
2676   if (restore_compare_p (operands[1]))
2677     return 0;
2678   else if (get_attr_length (insn) == 2)
2679     return \"j%j1 %l0\";
2680   else
2681     return \"b%j1%# %l0\";
2682 }"
2683   [(set_attr "type" "branch")])
2684
2685 (define_insn ""
2686   [(set (pc)
2687         (if_then_else (match_operator 0 "comparison_operator"
2688                                       [(cc0) (const_int 0)])
2689                       (return)
2690                       (pc)))]
2691   "null_epilogue ()"
2692   "*
2693 {
2694   if (restore_compare_p (operands[0]))
2695     return 0;
2696   else
2697     return \"b%j0r%# r15\";
2698 }"
2699   [(set_attr "type" "return")])
2700
2701 (define_insn ""
2702   [(set (pc)
2703         (if_then_else (match_operator 1 "comparison_operator"
2704                                 [(cc0) (const_int 0)])
2705                       (pc)
2706                       (label_ref (match_operand 0 "" ""))))]
2707   ""
2708   "*
2709 {
2710   if (restore_compare_p (operands[1]))
2711     return 0;
2712   else if (get_attr_length (insn) == 2)
2713     return \"j%J1 %l0\";
2714   else
2715     return \"b%J1%# %l0\";
2716 }"
2717   [(set_attr "type" "branch")])
2718
2719 (define_insn ""
2720   [(set (pc)
2721         (if_then_else (match_operator 0 "comparison_operator"
2722                                       [(cc0) (const_int 0)])
2723                       (pc)
2724                       (return)))]
2725   "null_epilogue ()"
2726   "*
2727 {
2728   if (restore_compare_p (operands[0]))
2729     return 0;
2730   else
2731     return \"b%J0r%# r15\";
2732 }"
2733   [(set_attr "type" "return")])
2734
2735 ;; Unconditional branch and return.
2736
2737 (define_insn "jump"
2738   [(set (pc)
2739         (label_ref (match_operand 0 "" "")))]
2740   ""
2741   "*
2742 {
2743   if (get_attr_length (insn) == 2)
2744     return \"j %l0\";
2745   else
2746     return \"b%# %l0\";
2747 }"
2748   [(set_attr "type" "branch")])
2749
2750 (define_insn "return"
2751   [(return)]
2752   "null_epilogue ()"
2753   "br%# r15"
2754   [(set_attr "type" "return")])
2755
2756 (define_insn "indirect_jump"
2757   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2758   ""
2759   "br%# %0"
2760   [(set_attr "type" "ibranch")])
2761
2762 ;; Table jump for switch statements:
2763 (define_insn "tablejump"
2764   [(set (pc)
2765         (match_operand:SI 0 "register_operand" "r"))
2766    (use (label_ref (match_operand 1 "" "")))]
2767   ""
2768   "br%# %0"
2769   [(set_attr "type" "ibranch")])