OSDN Git Service

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