OSDN Git Service

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