OSDN Git Service

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