OSDN Git Service

596aa4707e5d50d1816180fde983d16585ce033b
[pf3gnuchains/gcc-fork.git] / gcc / config / a29k / a29k.md
1 ;;- Machine description for AMD Am29000 for GNU C compiler
2 ;;   Copyright (C) 1991, 1992, 1994, 1998, 1999, 2001
3 ;;   Free Software Foundation, Inc.
4 ;;   Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5
6 ;; This file is part of GNU CC.
7
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 ;; The insns in this file are presented in the same order as the AMD 29000
26 ;; User's Manual (i.e., alphabetical by machine op-code).
27 ;;
28 ;; DEFINE_EXPAND's are located near the first occurrence of the major insn
29 ;; that they generate.
30 \f
31 ;; The only attribute we have is the type.  We only care about calls, branches,
32 ;; loads, stores, floating-point operations, and multi-word insns.
33 ;; Everything else is miscellaneous.
34
35 (define_attr "type"
36   "call,branch,load,store,fadd,fmul,fam,fdiv,fsqrt,dmul,dam,ddiv,dsqrt,multi,misc"
37   (const_string "misc"))
38
39 ;; ASM insns cannot go into a delay slot, so call them "multi".
40 (define_asm_attributes [(set_attr "type" "multi")])
41
42 (define_attr "in_delay_slot" "yes,no"
43   (if_then_else (eq_attr "type" "call,branch,multi")  (const_string "no")
44                 (const_string "yes")))
45
46 ;; Branch and call insns require a single delay slot.  Annulling is not
47 ;; supported.
48 (define_delay (eq_attr "type" "call,branch")
49   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
50
51 ;; Define the function unit usages.  We first define memory as a unit.
52 (define_function_unit "memory" 1 0 (eq_attr "type" "load") 6 5
53   [(eq_attr "type" "load")])
54 (define_function_unit "memory" 1 0 (eq_attr "type" "load") 6 6
55   [(eq_attr "type" "store")])
56 (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
57
58 ;; Now define the function units for the floating-point support.  Most
59 ;; units are pipelined and can accept an input every cycle.
60 ;;
61 ;; Note that we have an inaccuracy here.  If a fmac insn is issued, followed
62 ;; 2 cycles later by a fadd, there will be a conflict for the floating
63 ;; adder that we can't represent.  Also, all insns will conflict for the
64 ;; floating-point rounder.  It isn't clear how to represent this.
65
66 (define_function_unit "multiplier" 1 0 (eq_attr "type" "fmul") 3 0)
67 (define_function_unit "multiplier" 1 0 (eq_attr "type" "dmul") 6 4)
68 (define_function_unit "multiplier" 1 0 (eq_attr "type" "fam") 6 0)
69 (define_function_unit "multiplier" 1 0 (eq_attr "type" "dam") 9 4)
70
71 (define_function_unit "adder" 1 0 (eq_attr "type" "fadd,fam,dam") 3 0)
72
73 (define_function_unit "divider" 1 0 (eq_attr "type" "fdiv") 11 10)
74 (define_function_unit "divider" 1 0 (eq_attr "type" "fsqrt") 28 27)
75 (define_function_unit "divider" 1 0 (eq_attr "type" "ddiv") 18 17)
76 (define_function_unit "divider" 1 0 (eq_attr "type" "dsqrt") 57 56)
77 \f
78 ;; ADD
79 (define_insn "addsi3"
80   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
81         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
82                  (match_operand:SI 2 "add_operand" "rI,N")))]
83   ""
84   "@
85    add %0,%1,%2
86    sub %0,%1,%n2")
87
88 (define_insn "adddi3"
89   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
90         (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
91                  (match_operand:DI 2 "gpc_reg_operand" "r")))]
92   ""
93   "add %L0,%L1,%L2\;addc %0,%1,%2"
94   [(set_attr "type" "multi")])
95
96 ;; AND/ANDN
97 (define_insn "andsi3"
98   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
99         (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
100                 (match_operand:SI 2 "and_operand" "rI,K")))]
101   ""
102   "@
103    and %0,%1,%2
104    andn %0,%1,%C2")
105
106 (define_insn ""
107   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
108         (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
109                 (match_operand:SI 2 "cmplsrcb_operand" "r,K")))]
110   ""
111   "@
112    andn %0,%2,%1
113    nor %0,%1,%C2")
114 \f
115 ;; CALLI
116 ;;
117 ;; Each call pattern is duplicated so that we can add CLOBBERs to the
118 ;; resulting insn.
119 ;;
120 ;; We indicate that LR0 is clobbered in the CALL_INSN itself.  Otherwise,
121 ;; reorg will think it is just clobbered by the called function.
122
123 (define_expand "call"
124   [(use (match_operand:SI 0 "" ""))
125    (use (match_operand 1 "" ""))
126    (use (match_operand 2 "" ""))]
127   ""
128   "
129 { rtx insn = emit_call_insn (gen_call_internal (operands[0], operands[1]));
130   a29k_clobbers_to (insn, operands[2]);
131
132   DONE;
133 }")
134  
135 (define_expand "call_internal"
136   [(parallel [(call (match_operand:SI 0 "" "")
137                     (match_operand 1 "" ""))
138               (clobber (scratch:SI))])]
139   ""
140   "
141 {
142   if (GET_CODE (operands[0]) != MEM)
143     abort ();
144
145   /* We tell here whether this is a recursive call, since this insn may
146      later be inlined into another function.  */
147   if (! TARGET_SMALL_MEMORY
148       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
149     operands[0] = gen_rtx_MEM (SImode,
150                                force_reg (Pmode, XEXP (operands[0], 0)));
151 }")
152  
153 (define_expand "call_value"
154   [(use (match_operand:SI 0 "gpc_reg_operand" ""))
155    (use (match_operand:SI 1 "" ""))
156    (use (match_operand 2 "" ""))
157    (use (match_operand 3 "" ""))]
158   ""
159   "
160 { rtx insn = emit_call_insn (gen_call_value_internal (operands[0], operands[1],
161                                                       operands[2]));
162
163   a29k_clobbers_to (insn, operands[3]);
164   DONE;
165 }")
166  
167 (define_expand "call_value_internal"
168   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
169                    (call (match_operand:SI 1 "" "")
170                          (match_operand 2 "" "")))
171                    (clobber (scratch:SI))])]
172   ""
173   "
174 {
175   if (GET_CODE (operands[1]) != MEM)
176     abort ();
177
178   /* We tell here whether this is a recursive call, since this insn may
179      later be inlined into another function.  */
180   if (! TARGET_SMALL_MEMORY
181       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
182     operands[1] = gen_rtx_MEM (SImode,
183                                force_reg (Pmode, XEXP (operands[1], 0)));
184 }")
185  
186 (define_insn ""
187   [(call (match_operand:SI 0 "memory_operand" "m")
188          (match_operand 1 "" ""))
189    (clobber (match_scratch:SI 2 "=&l"))]
190   "GET_CODE (XEXP (operands[0], 0)) != CONST_INT"
191   "calli lr0,%0%#"
192   [(set_attr "type" "call")])
193
194 (define_insn ""
195   [(call (mem:SI (match_operand:SI 0 "call_operand" "i"))
196          (match_operand:SI 1 "general_operand" "g"))
197    (clobber (match_scratch:SI 2 "=&l"))]
198   ""
199   "call lr0,%F0"
200   [(set_attr "type" "call")])
201
202 (define_insn ""
203   [(set (match_operand 0 "gpc_reg_operand" "=r")
204         (call (match_operand:SI 1 "memory_operand" "m")
205               (match_operand 2 "" "")))
206    (clobber (match_scratch:SI 3 "=&l"))]
207   "GET_CODE (XEXP (operands[1], 0)) != CONST_INT"
208   "calli lr0,%1%#"
209   [(set_attr "type" "call")])
210
211 (define_insn ""
212   [(set (match_operand 0 "gpc_reg_operand" "=r")
213         (call (mem:SI (match_operand:SI 1 "call_operand" "i"))
214               (match_operand:SI 2 "general_operand" "g")))
215    (clobber (match_scratch:SI 3 "=&l"))]
216   ""
217   "call lr0,%F1"
218   [(set_attr "type" "call")])
219
220 (define_expand "probe"
221   [(call (mem:SI (symbol_ref:SI "_msp_check"))
222          (const_int 1))]
223   "TARGET_STACK_CHECK"
224   "")
225
226 ;; This is used for internal routine calls via TPC.  Currently used only
227 ;; in probe, above.
228 (define_insn ""
229   [(call (mem:SI (match_operand:SI 0 "immediate_operand" "s"))
230          (const_int 1))]
231   ""
232   "call %*,%0"
233   [(set_attr "type" "call")])
234 \f
235 ;; CONST, CONSTH, CONSTN
236 ;;
237 ;; Many of these are generated from move insns.
238 (define_insn ""
239   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
240         (and:SI (match_operand:SI 1 "immediate_operand" "i")
241                 (const_int 65535)))]
242   ""
243   "const %0,%1")
244
245 (define_insn ""
246   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
247                          (const_int 16)
248                          (match_operand:SI 1 "const_0_operand" ""))
249         (ashiftrt:SI (match_operand:SI 2 "immediate_operand" "i")
250                      (const_int 16)))]
251   ""
252   "consth %0,%2")
253
254 (define_insn ""
255   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
256                          (const_int 16)
257                          (match_operand:SI 1 "const_0_operand" ""))
258         (match_operand:SI 2 "cint_16_operand" "J"))]
259   ""
260   "consth %0,%m2")
261
262 (define_insn ""
263   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
264         (ior:SI (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "0"))
265                 (match_operand:SI 2 "const_int_operand" "n")))]
266   "(INTVAL (operands[2]) & 0xffff) == 0"
267   "consth %0,%2")
268
269 (define_insn ""
270   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
271         (ior:SI (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "0"))
272                 (and:SI (match_operand:SI 2 "immediate_operand" "i")
273                         (const_int -65536))))]
274   ""
275   "consth %0,%2")
276 \f
277 ;; CONVERT
278 (define_insn "fix_truncsfsi2"
279   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
280         (fix:SI (match_operand:SF 1 "register_operand" "r")))]
281   "! TARGET_SOFT_FLOAT"
282   "convert %0,%1,0,3,0,1")
283
284 (define_insn "fix_truncdfsi2"
285   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
286         (fix:SI (match_operand:DF 1 "register_operand" "r")))]
287   "! TARGET_SOFT_FLOAT"
288   "convert %0,%1,0,3,0,2")
289
290 (define_insn "fixuns_truncsfsi2"
291   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
292         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))]
293   "! TARGET_SOFT_FLOAT"
294   "convert %0,%1,1,3,0,1")
295
296 (define_insn "fixuns_truncdfsi2"
297   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
298         (unsigned_fix:SI (match_operand:DF 1 "register_operand" "r")))]
299   "! TARGET_SOFT_FLOAT"
300   "convert %0,%1,1,3,0,2")
301
302 (define_insn "truncdfsf2"
303   [(set (match_operand:SF 0 "register_operand" "=r")
304         (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
305   "! TARGET_SOFT_FLOAT"
306   "convert %0,%1,0,4,1,2")
307
308 (define_insn "extendsfdf2"
309   [(set (match_operand:DF 0 "register_operand" "=r")
310         (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
311   "! TARGET_SOFT_FLOAT"
312   "convert %0,%1,0,4,2,1")
313
314 (define_insn "floatsisf2"
315   [(set (match_operand:SF 0 "register_operand" "=r")
316         (float:SF (match_operand:SI 1 "gpc_reg_operand" "r")))]
317   "! TARGET_SOFT_FLOAT"
318   "convert %0,%1,0,4,1,0")
319
320 (define_insn "floatsidf2"
321   [(set (match_operand:DF 0 "register_operand" "=r")
322         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))]
323   "! TARGET_SOFT_FLOAT"
324   "convert %0,%1,0,4,2,0")
325
326 (define_insn "floatunssisf2"
327   [(set (match_operand:SF 0 "register_operand" "=r")
328         (unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "r")))]
329   "! TARGET_SOFT_FLOAT"
330   "convert %0,%1,1,4,1,0")
331
332 (define_insn "floatunssidf2"
333   [(set (match_operand:DF 0 "register_operand" "=r")
334         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))]
335   "! TARGET_SOFT_FLOAT"
336   "convert %0,%1,1,4,2,0")
337 \f
338 ;; CPxxx, DEQ, DGT, DGE, FEQ, FGT, FGE
339 (define_insn ""
340   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
341         (match_operator:SI 3 "comparison_operator"
342                         [(match_operand:SI 1 "gpc_reg_operand" "r")
343                          (match_operand:SI 2 "srcb_operand" "rI")]))]
344   ""
345   "cp%J3 %0,%1,%2")
346
347 (define_insn ""
348   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
349         (match_operator:SI 3 "fp_comparison_operator"
350                         [(match_operand:SF 1 "register_operand" "r")
351                          (match_operand:SF 2 "register_operand" "r")]))]
352   "! TARGET_SOFT_FLOAT"
353   "f%J3 %0,%1,%2"
354   [(set_attr "type" "fadd")])
355
356 (define_insn ""
357   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
358         (match_operator:SI 3 "fp_comparison_operator"
359                         [(match_operand:DF 1 "register_operand" "r")
360                          (match_operand:DF 2 "register_operand" "r")]))]
361   "! TARGET_SOFT_FLOAT"
362   "d%J3 %0,%1,%2"
363   [(set_attr "type" "fadd")])
364 \f
365 ;; DADD
366 (define_expand "adddf3"
367   [(set (match_operand:DF 0 "register_operand" "")
368         (plus:DF (match_operand:DF 1 "register_operand" "")
369                  (match_operand:DF 2 "register_operand" "")))]
370   "! TARGET_SOFT_FLOAT"
371   "")
372
373 (define_insn ""
374   [(set (match_operand:DF 0 "register_operand" "=r")
375         (plus:DF (match_operand:DF 1 "register_operand" "%r")
376                  (match_operand:DF 2 "register_operand" "r")))]
377   "! TARGET_29050 "
378   "dadd %0,%1,%2"
379   [(set_attr "type" "fadd")])
380
381 (define_insn ""
382   [(set (match_operand:DF 0 "register_operand" "=r,a")
383         (plus:DF (match_operand:DF 1 "register_operand" "%r,r")
384                  (match_operand:DF 2 "register_operand" "r,0")))]
385   "TARGET_29050"
386   "@
387    dadd %0,%1,%2
388    dmac 8,%0,%1,%1"
389   [(set_attr "type" "fadd,dam")])
390
391 ;; DDIV
392 (define_insn "divdf3"
393   [(set (match_operand:DF 0 "register_operand" "=r")
394         (div:DF (match_operand:DF 1 "register_operand" "=r")
395                 (match_operand:DF 2 "register_operand" "r")))]
396   "! TARGET_SOFT_FLOAT"
397   "ddiv %0,%1,%2"
398   [(set_attr "type" "ddiv")])
399 \f
400 ;; DIVIDE
401 ;;
402 ;; We must set Q to the sign extension of the dividend first.  For MOD, we
403 ;; must get the remainder from Q.
404 ;;
405 ;; For divmod: operand 1 is divided by operand 2; quotient goes to operand
406 ;; 0 and remainder to operand 3.
407 (define_expand "divmodsi4"
408   [(set (match_dup 4)
409         (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
410                      (const_int 31)))
411    (parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
412                    (div:SI (match_dup 1)
413                            (match_operand:SI 2 "gpc_reg_operand" "")))
414               (set (match_operand:SI 3 "gpc_reg_operand" "")
415                    (mod:SI (match_dup 1)
416                            (match_dup 2)))
417               (use (match_dup 4))])]
418   ""
419   "
420 {
421   operands[4] = gen_reg_rtx (SImode);
422 }")
423
424 (define_insn ""
425   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
426         (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
427                 (match_operand:SI 2 "gpc_reg_operand" "r")))
428    (set (match_operand:SI 3 "register_operand" "=q")
429         (mod:SI (match_dup 1)
430                 (match_dup 2)))
431    (use (match_operand:SI 4 "register_operand" "3"))]
432   ""
433   "divide %0,%1,%2")
434 \f
435 ;; DIVIDU
436 ;;
437 ;; Similar to DIVIDE.
438 (define_expand "udivmodsi4"
439   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
440                    (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
441                             (match_operand:SI 2 "gpc_reg_operand" "")))
442               (set (match_operand:SI 3 "gpc_reg_operand" "")
443                    (umod:SI (match_dup 1)
444                             (match_dup 2)))
445               (use (const_int 0))])]
446   ""
447   "")
448
449 (define_insn ""
450   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
451         (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r")
452                  (match_operand:SI 2 "gpc_reg_operand" "r")))
453    (set (match_operand:SI 3 "register_operand" "=q")
454         (umod:SI (match_dup 1)
455                  (match_dup 2)))
456    (use (match_operand:SI 4 "const_int_operand" "3"))]
457   ""
458   "dividu %0,%1,%2")
459 \f
460 ;; DMAC/DMSM
461 (define_insn ""
462   [(set (match_operand:DF 0 "register_operand" "=a,*r")
463         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "%r,A")
464                           (match_operand:DF 2 "register_operand" "r,r"))
465                  (match_operand:DF 3 "register_operand" "0,*r")))]
466   "TARGET_29050"
467   "@
468    dmac 0,%0,%1,%2
469    dmsm %0,%2,%3"
470   [(set_attr "type" "dam")])
471
472 (define_insn ""
473   [(set (match_operand:DF 0 "register_operand" "=a")
474         (plus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "r"))
475                           (match_operand:DF 2 "register_operand" "r"))
476                  (match_operand:DF 3 "register_operand" "0")))]
477   "TARGET_29050"
478   "dmac 1,%0,%2,%1"
479   [(set_attr "type" "dam")])
480
481 (define_insn ""
482   [(set (match_operand:DF 0 "register_operand" "=a")
483         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "%r")
484                            (match_operand:DF 2 "register_operand" "r"))
485                   (match_operand:DF 3 "register_operand" "0")))]
486   "TARGET_29050"
487   "dmac 2,%0,%1,%2"
488   [(set_attr "type" "dam")])
489
490 (define_insn ""
491   [(set (match_operand:DF 0 "register_operand" "=a")
492         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "r")
493                            (neg:DF (match_operand:DF 2 "register_operand" "r")))
494                   (match_operand:DF 3 "register_operand" "0")))]
495   "TARGET_29050"
496   "dmac 3,%0,%1,%2"
497   [(set_attr "type" "dam")])
498
499 (define_insn ""
500   [(set (match_operand:DF 0 "register_operand" "=a")
501         (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "r"))
502                  (match_operand:DF 2 "register_operand" "r")))]
503   "TARGET_29050"
504   "dmac 5,%0,%2,%1"
505   [(set_attr "type" "dam")])
506
507 (define_insn ""
508   [(set (match_operand:DF 0 "register_operand" "=a")
509         (minus:DF (neg:DF (match_operand:DF 1 "register_operand" "r"))
510                   (match_operand:DF 2 "register_operand" "0")))]
511   "TARGET_29050"
512   "dmac 11,%0,%1,%1"
513   [(set_attr "type" "dam")])
514
515 (define_insn ""
516   [(set (match_operand:DF 0 "register_operand" "=a")
517         (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "%r")
518                          (match_operand:DF 2 "register_operand" "0"))))]
519   "TARGET_29050"
520   "dmac 11,%0,%1,%1"
521   [(set_attr "type" "dam")])
522
523 (define_insn ""
524  [(set (match_operand:DF 0 "register_operand" "=r,r,a")
525        (neg:DF (match_operand:DF 1 "register_operand" "0,r,r")))
526   (clobber (match_scratch:SI 2 "=&r,&r,X"))]
527  "TARGET_29050"
528  "@
529   cpeq %2,gr1,gr1\;xor %0,%1,%2
530   cpeq %2,gr1,gr1\;xor %0,%1,%2\;sll %L0,%L1,0
531   dmac 13,%0,%1,%1"
532  [(set_attr "type" "multi,multi,dam")])
533
534 ;; DMUL
535 (define_expand "muldf3"
536   [(set (match_operand:DF 0 "register_operand" "")
537         (mult:DF (match_operand:DF 1 "register_operand" "")
538                  (match_operand:DF 2 "register_operand" "")))]
539   "! TARGET_SOFT_FLOAT"
540   "")
541
542 (define_insn ""
543   [(set (match_operand:DF 0 "register_operand" "=r")
544         (mult:DF (match_operand:DF 1 "register_operand" "%r")
545                  (match_operand:DF 2 "register_operand" "r")))]
546   "! TARGET_29050"
547   "dmul %0,%1,%2"
548   [(set_attr "type" "dmul")])
549
550 (define_insn ""
551   [(set (match_operand:DF 0 "register_operand" "=r,a")
552         (mult:DF (match_operand:DF 1 "register_operand" "%r,r")
553                  (match_operand:DF 2 "register_operand" "r,r")))]
554   "TARGET_29050"
555   "@
556    dmul %0,%1,%2
557    dmac 4,%0,%1,%2"
558   [(set_attr "type" "dmul,dam")])
559
560 ;; DSUB
561 (define_expand "subdf3"
562   [(set (match_operand:DF 0 "register_operand" "=r")
563         (minus:DF (match_operand:DF 1 "register_operand" "r")
564                   (match_operand:DF 2 "register_operand" "r")))]
565   "! TARGET_SOFT_FLOAT"
566   "")
567
568 (define_insn ""
569   [(set (match_operand:DF 0 "register_operand" "=r")
570         (minus:DF (match_operand:DF 1 "register_operand" "r")
571                   (match_operand:DF 2 "register_operand" "r")))]
572   "! TARGET_29050"
573   "dsub %0,%1,%2"
574   [(set_attr "type" "fadd")])
575
576 (define_insn ""
577   [(set (match_operand:DF 0 "register_operand" "=r,a,a")
578         (minus:DF (match_operand:DF 1 "register_operand" "r,0,r")
579                   (match_operand:DF 2 "register_operand" "r,r,0")))]
580   "TARGET_29050"
581   "@
582    dsub %0,%1,%2
583    dmac 9,%0,%2,%2
584    dmac 10,%0,%1,%1"
585   [(set_attr "type" "fadd,dam,dam")])
586 \f
587 ;; EXBYTE
588 (define_insn ""
589   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
590         (ior:SI (and:SI (match_operand:SI 1 "srcb_operand" "rI")
591                         (const_int -256))
592                 (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
593                                  (const_int 8)
594                                  (ashift:PSI
595                                   (match_operand:PSI 3 "register_operand" "b")
596                                   (const_int 3)))))]
597   ""
598   "exbyte %0,%2,%1")
599
600 (define_insn ""
601   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
602         (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
603                          (const_int 8)
604                          (ashift:PSI
605                           (match_operand:PSI 2 "register_operand" "b")
606                           (const_int 3))))]
607   ""
608   "exbyte %0,%1,0")
609
610 (define_insn ""
611   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
612                          (const_int 8)
613                          (match_operand:PSI 1 "const_24_operand" ""))
614         (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
615                          (const_int 8)
616                          (ashift:PSI
617                           (match_operand:PSI 3 "register_operand" "b")
618                           (const_int 3))))]
619   ""
620   "exbyte %0,%2,%0")
621
622 (define_expand "extzv"
623   [(set (match_operand:SI 0 "gpc_reg_operand" "")
624         (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
625                          (match_operand:SI 2 "general_operand" "")
626                          (match_operand:SI 3 "general_operand" "")))]
627   ""
628   "
629 {
630   int size, pos;
631
632   if (GET_CODE (operands[2]) != CONST_INT
633       || GET_CODE (operands[3]) != CONST_INT)
634     FAIL;
635
636   size = INTVAL (operands[2]);
637   pos = INTVAL (operands[3]);
638
639   /* Can't do this unless a byte extraction.  If extracting the high
640      or low byte, don't do this because a shift or AND is shorter.
641      Don't do 16-bit extracts, since the only two are the high and low
642      ends, and it is faster to do them with CONSTH and SRL.  */
643
644   if (size != 8 || (pos != 8 && pos != 16))
645     FAIL;
646
647   operands[3] = gen_rtx_ASHIFT (PSImode,
648                                 force_reg (PSImode, GEN_INT (pos / 8)),
649                                 GEN_INT (3));
650
651 }")
652
653 ;; EXHW
654 (define_insn ""
655   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
656         (ior:SI (and:SI (match_operand:SI 1 "srcb_operand" "rI")
657                 (const_int -65536))
658                 (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
659                                  (const_int 16)
660                                  (ashift:PSI
661                                   (match_operand:PSI 3 "register_operand" "b")
662                                   (const_int 3)))))]
663   ""
664   "exhw %0,%2,%1")
665
666 (define_insn ""
667   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
668         (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
669                          (const_int 16)
670                          (ashift:PSI
671                           (match_operand:PSI 2 "register_operand" "b")
672                           (const_int 3))))]
673   ""
674   "exhw %0,%1,0")
675
676 (define_insn ""
677   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
678                          (const_int 16)
679                          (match_operand:PSI 1 "const_16_operand" ""))
680         (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
681                          (const_int 16)
682                          (ashift:PSI
683                           (match_operand:PSI 3 "register_operand" "b")
684                           (const_int 3))))]
685   ""
686   "exhw %0,%2,%0")
687
688 ;; EXHWS
689 ;;
690 ;; This is probably unused.  The high-order 16-bits are obtained with an SRA
691 ;; insn.  The low-order 16 bits are a sign-extend, which is a pair of
692 ;; shifts.  Setting BP followed by the insn is equivalent, so we don't
693 ;; bother going to any trouble to generate this insn.
694
695 (define_insn ""
696   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
697         (sign_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
698                          (const_int 16)
699                          (ashift:PSI
700                           (match_operand:PSI 2 "register_operand" "b")
701                           (const_int 3))))]
702   ""
703   "exhws %0,%1")
704 \f
705 ;; EXTRACT
706 (define_insn ""
707   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
708         (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
709                    (match_operand:PSI 2 "register_operand" "f")))]
710   ""
711   "extract %0,%1,%1")
712
713 (define_expand "rotlsi3"
714   [(set (match_dup 3)
715         (match_operand:SI 2 "gpc_reg_or_immediate_operand" ""))
716    (set (match_operand:SI 0 "gpc_reg_operand" "")
717         (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
718                    (match_dup 3)))]
719   ""
720   "
721 { operands[2] = gen_lowpart (PSImode, operands[2]);
722   operands[3] = gen_reg_rtx (PSImode);
723 }")
724
725 ;; It would be nice to be able to have a define_split corresponding to the
726 ;; above, but there is no way to tell combine we need a PSImode temporary.
727 ;; If we put a (clobber (scratch:PSI)) there, combine would merge the above
728 ;; two insns.  This is bad because it then thinks only one insn is needed.
729 \f
730 ;; FADD
731 (define_expand "addsf3"
732   [(set (match_operand:SF 0 "register_operand" "")
733         (plus:SF (match_operand:SF 1 "register_operand" "")
734                  (match_operand:SF 2 "register_operand" "")))]
735   "! TARGET_SOFT_FLOAT"
736   "")
737
738 (define_insn ""
739   [(set (match_operand:SF 0 "register_operand" "=r")
740         (plus:SF (match_operand:SF 1 "register_operand" "%r")
741                  (match_operand:SF 2 "register_operand" "r")))]
742   "! TARGET_29050"
743   "fadd %0,%1,%2"
744   [(set_attr "type" "fadd")])
745
746 (define_insn ""
747   [(set (match_operand:SF 0 "register_operand" "=r,a")
748         (plus:SF (match_operand:SF 1 "register_operand" "%r,r")
749                  (match_operand:SF 2 "register_operand" "r,0")))]
750   "TARGET_29050"
751   "@
752    fadd %0,%1,%2
753    fmac 8,%0,%1,%1"
754   [(set_attr "type" "fadd,fam")])
755
756 ;; FDIV
757 (define_insn "divsf3"
758   [(set (match_operand:SF 0 "register_operand" "=r")
759         (div:SF (match_operand:SF 1 "register_operand" "=r")
760                 (match_operand:SF 2 "register_operand" "r")))]
761   "! TARGET_SOFT_FLOAT"
762   "fdiv %0,%1,%2"
763   [(set_attr "type" "fdiv")])
764
765 ;; FDMUL
766 (define_insn ""
767   [(set (match_operand:DF 0 "register_operand" "=r")
768         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "%r"))
769                  (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))]
770   "! TARGET_SOFT_FLOAT"
771   "fdmul %0,%1,%2")
772
773 ;; FMAC/FMSM
774 (define_insn ""
775   [(set (match_operand:SF 0 "register_operand" "=a,*r")
776         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%r,A")
777                           (match_operand:SF 2 "register_operand" "r,r"))
778                  (match_operand:SF 3 "register_operand" "0,*r")))]
779   "TARGET_29050"
780   "@
781    fmac 0,%0,%1,%2
782    fmsm %0,%2,%3"
783   [(set_attr "type" "fam")])
784
785 (define_insn ""
786   [(set (match_operand:SF 0 "register_operand" "=a")
787         (plus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "r"))
788                           (match_operand:SF 2 "register_operand" "r"))
789                  (match_operand:SF 3 "register_operand" "0")))]
790   "TARGET_29050"
791   "fmac 1,%0,%2,%1"
792   [(set_attr "type" "fam")])
793
794 (define_insn ""
795   [(set (match_operand:SF 0 "register_operand" "=a")
796         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%r")
797                            (match_operand:SF 2 "register_operand" "r"))
798                   (match_operand:SF 3 "register_operand" "0")))]
799   "TARGET_29050"
800   "fmac 2,%0,%1,%2"
801   [(set_attr "type" "fam")])
802
803 (define_insn ""
804   [(set (match_operand:SF 0 "register_operand" "=a")
805         (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "r"))
806                            (match_operand:SF 2 "register_operand" "r"))
807                   (match_operand:SF 3 "register_operand" "0")))]
808   "TARGET_29050"
809   "fmac 3,%0,%2,%1"
810   [(set_attr "type" "fam")])
811
812 (define_insn ""
813   [(set (match_operand:SF 0 "register_operand" "=a")
814         (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "r"))
815                  (match_operand:SF 2 "register_operand" "r")))]
816   "TARGET_29050"
817   "fmac 5,%0,%2,%1"
818   [(set_attr "type" "fam")])
819
820 (define_insn ""
821   [(set (match_operand:SF 0 "register_operand" "=a")
822         (minus:SF (neg:SF (match_operand:SF 1 "register_operand" "%r"))
823                   (match_operand:SF 2 "register_operand" "0")))]
824   "TARGET_29050"
825   "fmac 11,%0,%1,%1"
826   [(set_attr "type" "fam")])
827
828 (define_insn ""
829   [(set (match_operand:SF 0 "register_operand" "=a")
830         (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "%r")
831                          (match_operand:SF 2 "register_operand" "0"))))]
832   "TARGET_29050"
833   "fmac 11,%0,%1,%1"
834   [(set_attr "type" "fam")])
835
836 (define_insn ""
837   [(set (match_operand:SF 0 "register_operand" "=r,a")
838         (neg:SF (match_operand:SF 1 "register_operand" "r,r")))
839    (clobber (match_scratch:SI 2 "=&r,X"))]
840   "TARGET_29050"
841   "@
842    cpeq %2,gr1,gr1\;xor %0,%1,%2
843    fmac 13,%0,%1,%1"
844   [(set_attr "type" "multi,fam")])
845
846 ;; FMUL
847 (define_expand "mulsf3"
848   [(set (match_operand:SF 0 "register_operand" "")
849         (mult:SF (match_operand:SF 1 "register_operand" "")
850                  (match_operand:SF 2 "register_operand" "")))]
851   "! TARGET_SOFT_FLOAT"
852   "")
853
854 (define_insn ""
855   [(set (match_operand:SF 0 "register_operand" "=r")
856         (mult:SF (match_operand:SF 1 "register_operand" "%r")
857                  (match_operand:SF 2 "register_operand" "r")))]
858   "! TARGET_29050"
859   "fmul %0,%1,%2"
860   [(set_attr "type" "fmul")])
861
862 (define_insn ""
863   [(set (match_operand:SF 0 "register_operand" "=r,a")
864         (mult:SF (match_operand:SF 1 "register_operand" "%r,r")
865                  (match_operand:SF 2 "register_operand" "r,r")))]
866   "TARGET_29050"
867   "@
868    fmul %0,%1,%2
869    fmac 4,%0,%1,%2"
870   [(set_attr "type" "fmul,fam")])
871
872 ;; FSUB
873 (define_expand "subsf3"
874   [(set (match_operand:SF 0 "register_operand" "")
875         (minus:SF (match_operand:SF 1 "register_operand" "")
876                   (match_operand:SF 2 "register_operand" "")))]
877   "! TARGET_SOFT_FLOAT"
878   "")
879
880 (define_insn ""
881   [(set (match_operand:SF 0 "register_operand" "=r")
882         (minus:SF (match_operand:SF 1 "register_operand" "r")
883                   (match_operand:SF 2 "register_operand" "r")))]
884   "! TARGET_29050"
885   "fsub %0,%1,%2"
886   [(set_attr "type" "fadd")])
887
888 (define_insn ""
889   [(set (match_operand:SF 0 "register_operand" "=r,a,a")
890         (minus:SF (match_operand:SF 1 "register_operand" "r,0,r")
891                   (match_operand:SF 2 "register_operand" "r,r,0")))]
892   "TARGET_29050"
893   "@
894    fsub %0,%1,%2
895    fmac 9,%0,%2,%2
896    fmac 10,%0,%1,%1"
897   [(set_attr "type" "fadd,fam,fam")])
898 \f
899 ;; INBYTE
900 (define_insn ""
901   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
902                          (const_int 8)
903                          (ashift:PSI
904                           (match_operand:PSI 2 "register_operand" "b")
905                           (const_int 3)))
906         (match_operand:SI 1 "srcb_operand" "rI"))]
907   ""
908   "inbyte %0,%0,%1")
909
910 (define_insn ""
911   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
912         (ior:SI (and:SI
913                  (not:SI
914                   (ashift:SI (const_int 255)
915                              (ashift:PSI
916                               (match_operand:PSI 3 "register_operand" "b")
917                               (const_int 3))))
918                  (match_operand:SI 1 "gpc_reg_operand" "r"))
919                 (ashift:SI (zero_extend:SI
920                             (match_operand:QI 2 "srcb_operand" "rI"))
921                            (ashift:PSI (match_dup 3) (const_int 3)))))]
922   ""
923   "inbyte %0,%1,%2")
924
925 ;; INHW
926 (define_insn ""
927   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
928                          (const_int 16)
929                          (ashift:PSI
930                           (match_operand:PSI 2 "register_operand" "b")
931                           (const_int 3)))
932         (match_operand:SI 1 "srcb_operand" "rI"))]
933   ""
934   "inhw %0,%0,%1")
935
936 (define_insn ""
937   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
938         (ior:SI (and:SI
939                  (not:SI
940                   (ashift:SI (const_int 65535)
941                              (ashift:PSI
942                               (match_operand:PSI 3 "register_operand" "b")
943                               (const_int 3))))
944                  (match_operand:SI 1 "gpc_reg_operand" "r"))
945                 (ashift:SI (zero_extend:SI
946                             (match_operand:HI 2 "srcb_operand" "rI"))
947                            (ashift:PSI (match_dup 3) (const_int 3)))))]
948   ""
949   "inhw %0,%1,%2")
950
951 (define_expand "insv"
952   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "")
953                          (match_operand:SI 1 "general_operand" "")
954                          (match_operand:SI 2 "general_operand" ""))
955         (match_operand:SI 3 "srcb_operand" ""))]
956   ""
957   "
958 {
959   int size, pos;
960
961   if (GET_CODE (operands[1]) != CONST_INT
962       || GET_CODE (operands[2]) != CONST_INT)
963     FAIL;
964
965   size = INTVAL (operands[1]);
966   pos = INTVAL (operands[2]);
967   if ((size != 8 && size != 16) || pos % size != 0)
968     FAIL;
969
970   operands[2] = gen_rtx_ASHIFT (PSImode,
971                                 force_reg (PSImode, GEN_INT (pos / 8)),
972                                 GEN_INT (3));
973 }")
974 \f
975 ;; LOAD (also used by move insn).
976 (define_insn ""
977   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
978         (mem:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "r")
979                         (const_int -4))))
980    (set (match_operand:PSI 2 "register_operand" "=b")
981         (truncate:PSI (match_dup 1)))]
982   "! TARGET_DW_ENABLE"
983   "load 0,16,%0,%1"
984   [(set_attr "type" "load")])
985
986 (define_insn ""
987   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
988         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
989   "TARGET_DW_ENABLE"
990   "load 0,1,%0,%1"
991   [(set_attr "type" "load")])
992
993 (define_insn ""
994   [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
995         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
996   "TARGET_DW_ENABLE"
997   "load 0,1,%0,%1"
998   [(set_attr "type" "load")])
999
1000 (define_insn ""
1001   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1002         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1003   "TARGET_DW_ENABLE"
1004   "load 0,2,%0,%1"
1005   [(set_attr "type" "load")])
1006
1007 (define_insn ""
1008   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1009         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))
1010    (clobber (match_scratch:PSI 2 "=&b"))]
1011   "TARGET_DW_ENABLE"
1012   "load 0,17,%0,%1"
1013   [(set_attr "type" "load")])
1014
1015 (define_insn ""
1016   [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
1017         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))
1018    (clobber (match_scratch:PSI 2 "=&b"))]
1019   "TARGET_DW_ENABLE"
1020   "load 0,17,%0,%1"
1021   [(set_attr "type" "load")])
1022
1023 (define_insn ""
1024   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1025         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
1026    (clobber (match_scratch:PSI 2 "=&b"))]
1027   "TARGET_DW_ENABLE"
1028   "load 0,18,%0,%1"
1029   [(set_attr "type" "load")])
1030 \f
1031 ;; LOADM
1032 (define_expand "load_multiple"
1033   [(set (match_dup 4)
1034         (match_operand:PSI 2 "const_int_operand" ""))
1035    (match_par_dup 3 [(set (match_operand:SI 0 "" "")
1036                           (match_operand:SI 1 "" ""))])]
1037   ""
1038   "
1039 {
1040   int regno;
1041   int count;
1042   rtx from;
1043   int i;
1044
1045   /* Support only loading a constant number of hard registers from memory.  */
1046   if (GET_CODE (operands[2]) != CONST_INT
1047       || operands[2] == const1_rtx
1048       || GET_CODE (operands[1]) != MEM
1049       || GET_CODE (operands[0]) != REG
1050       || REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
1051     FAIL;
1052
1053   count = INTVAL (operands[2]);
1054   regno = REGNO (operands[0]);
1055
1056   /* CR gets set to the number of registers minus one.  */
1057   operands[2] = GEN_INT(count - 1);
1058
1059   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
1060   from = memory_address (SImode, XEXP (operands[1], 0));
1061   XVECEXP (operands[3], 0, 0) = gen_rtx_SET (VOIDmode,
1062                                              gen_rtx_REG (SImode, regno),
1063                                              gen_rtx_MEM (SImode, from));
1064   operands[4] = gen_reg_rtx (PSImode);
1065
1066   XVECEXP (operands[3], 0, 1) = gen_rtx_USE (VOIDmode, operands[4]);
1067   XVECEXP (operands[3], 0, 2) = gen_rtx_CLOBBER (VOIDmode, operands[4]);
1068
1069   for (i = 1; i < count; i++)
1070     XVECEXP (operands[3], 0, i + 2)
1071       = gen_rtx_SET (VOIDmode, gen_rtx (REG, SImode, regno + i),
1072                  gen_rtx_MEM (SImode, plus_constant (from, i * 4)));
1073 }")
1074
1075 ;; Indicate that CR is used and is then clobbered.
1076 (define_insn ""
1077   [(set (match_operand 0 "gpc_reg_operand" "=r")
1078         (match_operand 1 "memory_operand" "m"))
1079    (use (match_operand:PSI 2 "register_operand" "+c"))
1080    (clobber (match_dup 2))]
1081   "GET_MODE (operands[0]) == GET_MODE (operands[1])
1082    && GET_MODE_SIZE (GET_MODE (operands[0])) > UNITS_PER_WORD"
1083   "loadm 0,0,%0,%1"
1084   [(set_attr "type" "load")])
1085
1086 (define_insn ""
1087   [(match_parallel 0 "load_multiple_operation"
1088                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
1089                          (match_operand:SI 2 "memory_operand" "m"))
1090                     (use (match_operand:PSI 3 "register_operand" "+c"))
1091                     (clobber (match_dup 3))])]
1092   ""
1093   "loadm 0,0,%1,%2"
1094   [(set_attr "type" "load")])
1095 \f
1096 ;; MTSR (used also by move insn)
1097 (define_insn ""
1098   [(set (match_operand:SI 0 "spec_reg_operand" "=*h,*h")
1099         (and:SI (match_operand:SI 1 "gpc_reg_or_immediate_operand" "r,i")
1100                 (match_operand:SI 2 "const_int_operand" "n,n")))]
1101   "masks_bits_for_special (operands[0], operands[2])"
1102   "@
1103    mtsr %0,%1
1104    mtsrim %0,%1")
1105
1106 (define_insn ""
1107   [(set (match_operand:PSI 0 "register_operand" "=h,h")
1108         (truncate:PSI
1109          (match_operand:SI 1 "gpc_reg_or_immediate_operand" "r,i")))]
1110   ""
1111   "@
1112    mtsr %0,%1
1113    mtsrim %0,%1")
1114 \f
1115 ;; MULTIPLY, MULTM, MULTMU
1116 (define_insn "mulsi3"
1117   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1118         (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1119                  (match_operand:SI 2 "gpc_reg_operand" "r")))
1120    (clobber (match_scratch:SI 3 "=&q"))]
1121   ""
1122   "multiply %0,%1,%2")
1123
1124 (define_insn "mulsidi3"
1125   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
1126         (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
1127                  (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
1128    (clobber (match_scratch:SI 3 "=&q"))]
1129   "TARGET_MULTM"
1130   "multiply %L0,%1,%2\;multm %0,%1,%2"
1131   [(set_attr "type" "multi")])
1132
1133 (define_split
1134   [(set (match_operand:DI 0 "gpc_reg_operand" "")
1135         (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
1136                  (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))
1137    (clobber (reg:SI 180))]
1138   "reload_completed"
1139   [(parallel [(set (match_dup 3)
1140                    (mult:SI (match_dup 1) (match_dup 2)))
1141               (clobber (reg:SI 180))])
1142    (parallel [(set (match_dup 4)
1143                    (truncate:SI
1144                     (lshiftrt:DI
1145                      (mult:DI (sign_extend:DI (match_dup 1))
1146                               (sign_extend:DI (match_dup 2)))
1147                      (const_int 32))))
1148               (clobber (reg:SI 180))])]
1149   "
1150 { operands[3] = operand_subword (operands[0], 1, 1, DImode);
1151   operands[4] = operand_subword (operands[0], 0, 1, DImode); } ")
1152                             
1153 (define_insn "umulsidi3"
1154   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
1155         (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
1156                  (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
1157    (clobber (match_scratch:SI 3 "=&q"))]
1158   "TARGET_MULTM"
1159   "multiplu %L0,%1,%2\;multmu %0,%1,%2"
1160   [(set_attr "type" "multi")])
1161
1162 (define_split
1163   [(set (match_operand:DI 0 "gpc_reg_operand" "")
1164         (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
1165                  (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))
1166    (clobber (reg:SI 180))]
1167   "reload_completed"
1168   [(parallel [(set (match_dup 3)
1169                    (mult:SI (match_dup 1) (match_dup 2)))
1170               (clobber (reg:SI 180))])
1171    (parallel [(set (match_dup 4)
1172                    (truncate:SI
1173                     (lshiftrt:DI
1174                      (mult:DI (zero_extend:DI (match_dup 1))
1175                               (zero_extend:DI (match_dup 2)))
1176                      (const_int 32))))
1177               (clobber (reg:SI 180))])]
1178   "
1179 { operands[3] = operand_subword (operands[0], 1, 1, DImode);
1180   operands[4] = operand_subword (operands[0], 0, 1, DImode); } ")
1181                             
1182 (define_insn "smulsi3_highpart"
1183   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1184         (truncate:SI
1185          (lshiftrt:DI
1186           (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1187                    (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r")))
1188           (const_int 32))))
1189    (clobber (match_scratch:SI 3 "=&q"))]
1190   "TARGET_MULTM"
1191   "multm %0,%1,%2")
1192
1193 (define_insn "umulsi3_highpart"
1194   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1195         (truncate:SI
1196          (lshiftrt:DI
1197           (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1198                    (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r")))
1199           (const_int 32))))
1200    (clobber (match_scratch:SI 3 "=&q"))]
1201   "TARGET_MULTM"
1202   "multmu %0,%1,%2")
1203
1204 ;; NAND
1205 (define_insn ""
1206   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1207         (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1208                 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1209   ""
1210   "nand %0,%1,%2")
1211
1212 (define_insn ""
1213   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1214         (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1215                 (match_operand:SI 2 "const_int_operand" "K")))]
1216   ; Match TARGET_29050 in "orn" pattern for slightly better reload.
1217   "! TARGET_29050 && ((unsigned) ~ INTVAL (operands[2])) < 256"
1218   "nand %0,%1,%C2")
1219
1220 ;; NOR
1221 (define_insn ""
1222   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1223         (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1224                 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1225   ""
1226   "nor %0,%1,%2")
1227
1228 (define_insn "one_cmplsi2"
1229   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1230         (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1231   ""
1232   "nor %0,%1,0")
1233 \f
1234 ;; OR/ORN
1235 (define_expand "iorsi3"
1236   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1237         (ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
1238                 (match_operand:SI 2 "srcb_operand" "")))]
1239   ""
1240   "")
1241
1242 (define_insn ""
1243   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1244         (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1245                 (match_operand:SI 2 "srcb_operand" "rI")))]
1246   "! TARGET_29050"
1247   "or %0,%1,%2")
1248
1249 (define_insn ""
1250   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1251         (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
1252                 (match_operand:SI 2 "and_operand" "rI,K")))]
1253   "TARGET_29050"
1254   "@
1255    or %0,%1,%2
1256    orn %0,%1,%C2")
1257
1258 (define_insn ""
1259   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1260         (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1261                 (match_operand:SI 2 "cmplsrcb_operand" "r,K")))]
1262   "TARGET_29050"
1263   "@
1264    orn %0,%2,%1
1265    nand %0,%1,%C2")
1266
1267 \f
1268 ;; SLL (also used by move insn)
1269 (define_insn "nop"
1270   [(const_int 0)]
1271   ""
1272   "aseq 0x40,gr1,gr1")
1273
1274 (define_insn "ashlsi3"
1275   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1276         (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1277                    (match_operand:QI 2 "srcb_operand" "rn")))]
1278   ""
1279   "sll %0,%1,%Q2")
1280
1281 ;; SQRT
1282 (define_insn "sqrtsf2"
1283   [(set (match_operand:SF 0 "gpc_reg_operand" "=r")
1284         (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "r")))]
1285   "TARGET_29050"
1286   "sqrt %0,%1,1"
1287   [(set_attr "type" "fsqrt")])
1288
1289 (define_insn "sqrtdf2"
1290   [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
1291         (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "r")))]
1292   "TARGET_29050"
1293   "sqrt %0,%1,2"
1294   [(set_attr "type" "dsqrt")])
1295
1296 ;; SRA
1297 (define_insn "ashrsi3"
1298   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1299         (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1300                      (match_operand:QI 2 "srcb_operand" "rn")))]
1301   ""
1302   "sra %0,%1,%Q2")
1303
1304 ;; SRL
1305 (define_insn "lshrsi3"
1306   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1307         (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1308                      (match_operand:QI 2 "srcb_operand" "rn")))]
1309   ""
1310   "srl %0,%1,%Q2")
1311 \f
1312 ;; STORE
1313 ;;
1314 ;; These somewhat bogus patterns exist to set OPT = 001/010 for partial-word
1315 ;; stores on systems with DW not set.
1316 (define_insn ""
1317   [(set (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "r")
1318                         (const_int -4)))
1319         (match_operand:SI 1 "gpc_reg_operand" "r"))]
1320   "! TARGET_DW_ENABLE"
1321   "store 0,1,%1,%0"
1322   [(set_attr "type" "store")])
1323
1324 (define_insn ""
1325   [(set (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "r")
1326                         (const_int -3)))
1327         (match_operand:SI 1 "gpc_reg_operand" "r"))]
1328   "! TARGET_DW_ENABLE"
1329   "store 0,2,%1,%0"
1330   [(set_attr "type" "store")])
1331
1332 ;; STOREM
1333 (define_expand "store_multiple"
1334   [(use (match_operand 0 "" ""))
1335    (use (match_operand 1 "" ""))
1336    (use (match_operand 2 "" ""))]
1337   ""
1338   "
1339 { rtx pat;
1340
1341  if (TARGET_NO_STOREM_BUG)
1342     pat = gen_store_multiple_no_bug (operands[0], operands[1], operands[2]);
1343   else
1344     pat = gen_store_multiple_bug (operands[0], operands[1], operands[2]);
1345
1346   if (pat)
1347     emit_insn (pat);
1348   else
1349     FAIL;
1350
1351   DONE;
1352 }")
1353
1354 (define_expand "store_multiple_no_bug"
1355   [(set (match_dup 4)
1356         (match_operand:PSI 2 "const_int_operand" ""))
1357    (match_par_dup 3 [(set (match_operand:SI 0 "" "")
1358                           (match_operand:SI 1 "" ""))])]
1359   ""
1360   "
1361 {
1362   int regno;
1363   int count;
1364   rtx from;
1365   int i;
1366
1367   /* Support only storing a constant number of hard registers to memory.  */
1368   if (GET_CODE (operands[2]) != CONST_INT
1369       || operands[2] == const1_rtx
1370       || GET_CODE (operands[0]) != MEM
1371       || GET_CODE (operands[1]) != REG
1372       || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
1373     FAIL;
1374
1375   count = INTVAL (operands[2]);
1376   regno = REGNO (operands[1]);
1377
1378   /* CR gets set to the number of registers minus one.  */
1379   operands[2] = GEN_INT(count - 1);
1380
1381   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
1382   from = memory_address (SImode, XEXP (operands[0], 0));
1383   XVECEXP (operands[3], 0, 0) = gen_rtx_SET (VOIDmode,
1384                                              gen_rtx_MEM (SImode, from),
1385                                              gen_rtx_REG (SImode, regno));
1386   operands[4] = gen_reg_rtx (PSImode);
1387   XVECEXP (operands[3], 0, 1) = gen_rtx_USE (VOIDmode, operands[4]);
1388   XVECEXP (operands[3], 0, 2) = gen_rtx_CLOBBER (VOIDmode, operands[4]);
1389
1390   for (i = 1; i < count; i++)
1391     XVECEXP (operands[3], 0, i + 2)
1392       = gen_rtx_SET (VOIDmode,
1393                      gen_rtx_MEM (SImode, plus_constant (from, i * 4)),
1394                      gen_rtx_REG (SImode, regno + i));
1395 }")
1396
1397 (define_expand "store_multiple_bug"
1398   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
1399                           (match_operand:SI 1 "" ""))
1400                      (use (match_operand:SI 2 "" ""))])]
1401   ""
1402   "
1403 {
1404   int regno;
1405   int count;
1406   rtx from;
1407   int i;
1408
1409   /* Support only storing a constant number of hard registers to memory.  */
1410   if (GET_CODE (operands[2]) != CONST_INT
1411       || operands[2] == const1_rtx
1412       || GET_CODE (operands[0]) != MEM
1413       || GET_CODE (operands[1]) != REG
1414       || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
1415     FAIL;
1416
1417   count = INTVAL (operands[2]);
1418   regno = REGNO (operands[1]);
1419
1420   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
1421   from = memory_address (SImode, XEXP (operands[0], 0));
1422   XVECEXP (operands[3], 0, 0) = gen_rtx_SET (VOIDmode,
1423                                              gen_rtx_MEM (SImode, from),
1424                                              gen_rtx_REG (SImode, regno));
1425   XVECEXP (operands[3], 0, 1)
1426     = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (PSImode));
1427
1428   for (i = 1; i < count; i++)
1429     XVECEXP (operands[3], 0, i + 1)
1430       = gen_rtx_SET (VOIDmode,
1431                      gen_rtx_MEM (SImode, plus_constant (from, i * 4)),
1432                      gen_rtx_REG (SImode, regno + i));
1433 }")
1434
1435 (define_insn ""
1436   [(set (match_operand 0 "memory_operand" "=m")
1437         (match_operand 1 "gpc_reg_operand" "r"))
1438    (clobber (match_scratch:PSI 2 "=&c"))]
1439   "!TARGET_NO_STOREM_BUG
1440    && GET_MODE (operands[0]) == GET_MODE (operands[1])
1441    && GET_MODE_SIZE (GET_MODE (operands[0])) > UNITS_PER_WORD"
1442   "mtsrim cr,%S1\;storem 0,0,%1,%0"
1443   [(set_attr "type" "multi")])
1444
1445 (define_insn ""
1446   [(match_parallel 0 "store_multiple_operation"
1447                    [(set (match_operand:SI 1 "memory_operand" "=m")
1448                          (match_operand:SI 2 "gpc_reg_operand" "r"))
1449                     (clobber (match_scratch:PSI 3 "=&c"))])]
1450   "!TARGET_NO_STOREM_BUG"
1451   "mtsrim cr,%V0\;storem 0,0,%2,%1"
1452   [(set_attr "type" "multi")])
1453
1454 (define_insn ""
1455   [(set (match_operand 0 "memory_operand" "=m")
1456         (match_operand 1 "gpc_reg_operand" "r"))
1457    (use (match_operand:PSI 2 "register_operand" "+c"))
1458    (clobber (match_dup 2))]
1459   "TARGET_NO_STOREM_BUG
1460    && GET_MODE (operands[0]) == GET_MODE (operands[1])
1461    && GET_MODE_SIZE (GET_MODE (operands[0])) > UNITS_PER_WORD"
1462   "storem 0,0,%1,%0"
1463   [(set_attr "type" "store")])
1464
1465 (define_insn ""
1466   [(match_parallel 0 "store_multiple_operation"
1467                    [(set (match_operand:SI 1 "memory_operand" "=m")
1468                          (match_operand:SI 2 "gpc_reg_operand" "r"))
1469                     (use (match_operand:PSI 3 "register_operand" "+c"))
1470                     (clobber (match_dup 3))])]
1471   "TARGET_NO_STOREM_BUG"
1472   "storem 0,0,%2,%1"
1473   [(set_attr "type" "store")])
1474 \f
1475 ;; SUB
1476 ;;
1477 ;; Either operand can be a register or an 8-bit constant, but both cannot be
1478 ;; constants (can't usually occur anyway).
1479 (define_expand "subsi3"
1480   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1481         (minus:SI (match_operand:SI 1 "srcb_operand" "")
1482                   (match_operand:SI 2 "srcb_operand" "")))]
1483   ""
1484   "
1485 {
1486   if (GET_CODE (operands[0]) == CONST_INT
1487       && GET_CODE (operands[1]) == CONST_INT)
1488     operands[1] = force_reg (SImode, operands[1]);
1489 }")
1490
1491 (define_insn ""
1492   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1493         (minus:SI (match_operand:SI 1 "srcb_operand" "r,I")
1494                   (match_operand:SI 2 "srcb_operand" "rI,r")))]
1495   "register_operand (operands[1], SImode)
1496    || register_operand (operands[2], SImode)"
1497   "@
1498    sub %0,%1,%2
1499    subr %0,%2,%1")
1500
1501 (define_insn "subdi3"
1502   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
1503         (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
1504                   (match_operand:DI 2 "gpc_reg_operand" "r")))]
1505   ""
1506   "sub %L0,%L1,%L2\;subc %0,%1,%2"
1507   [(set_attr "type" "multi")])
1508
1509 ;; SUBR (also used above in SUB)
1510 (define_insn "negdi2"
1511   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
1512         (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
1513   ""
1514   "subr %L0,%L1,0\;subrc %0,%1,0"
1515   [(set_attr "type" "multi")])
1516
1517 (define_insn "negsi2"
1518   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1519         (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1520   ""
1521   "subr %0,%1,0")
1522 \f
1523 ;; XNOR
1524 (define_insn ""
1525   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1526         (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1527                         (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1528   ""
1529   "xnor %0,%1,%2")
1530
1531 ;; XOR
1532
1533 (define_insn "xorsi3"
1534   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1535         (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
1536                 (match_operand:SI 2 "and_operand" "rI,K")))]
1537   ""
1538   "@
1539    xor %0,%1,%2
1540    xnor %0,%1,%C2")
1541
1542 ;; Can use XOR to negate floating-point values, but we are better off not doing
1543 ;; it that way on the 29050 so it can combine with the fmac insns.
1544 (define_expand "negsf2"
1545   [(parallel [(set (match_operand:SF 0 "register_operand" "")
1546                    (neg:SF (match_operand:SF 1 "register_operand" "")))
1547               (clobber (match_scratch:SI 2 ""))])]
1548   "! TARGET_SOFT_FLOAT"
1549   "
1550 {
1551   rtx result;
1552   rtx target;
1553
1554   if (! TARGET_29050)
1555     {
1556       target = operand_subword_force (operands[0], 0, SFmode);
1557       result = expand_binop (SImode, xor_optab,
1558                              operand_subword_force (operands[1], 0, SFmode),
1559                              GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
1560       if (result == 0)
1561         abort ();
1562
1563       if (result != target)
1564         emit_move_insn (result, target);
1565
1566       /* Make a place for REG_EQUAL.  */
1567       emit_move_insn (operands[0], operands[0]);
1568       DONE;
1569     }
1570 }")
1571
1572 (define_expand "negdf2"
1573   [(parallel [(set (match_operand:DF 0 "register_operand" "")
1574                    (neg:DF (match_operand:DF 1 "register_operand" "")))
1575               (clobber (match_scratch:SI 2 ""))])]
1576   "! TARGET_SOFT_FLOAT"
1577   "
1578 {
1579   rtx result;
1580   rtx target;
1581   rtx insns;
1582
1583   if (! TARGET_29050)
1584     {
1585       start_sequence ();
1586       target = operand_subword (operands[0], 0, 1, DFmode);
1587       result = expand_binop (SImode, xor_optab,
1588                              operand_subword_force (operands[1], 0, DFmode),
1589                              GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
1590       if (result == 0)
1591         abort ();
1592
1593       if (result != target)
1594         emit_move_insn (result, target);
1595   
1596       emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
1597                       operand_subword_force (operands[1], 1, DFmode));
1598
1599       insns = get_insns ();
1600       end_sequence ();
1601
1602       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1603       DONE;
1604     }
1605 }")
1606 \f
1607 ;; Sign extend and truncation operations.
1608 (define_insn "zero_extendqihi2"
1609   [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
1610         (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))]
1611   ""
1612   "and %0,%1,255")
1613
1614 (define_insn "zero_extendqisi2"
1615   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1616         (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))]
1617   ""
1618   "and %0,%1,255")
1619
1620 (define_insn "zero_extendhisi2"
1621   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1622         (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "0")))]
1623   ""
1624   "consth %0,0")
1625
1626 (define_expand "extendqihi2"
1627   [(set (match_dup 2)
1628         (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
1629                    (const_int 24)))
1630    (set (match_operand:HI 0 "gpc_reg_operand" "")
1631         (ashiftrt:SI (match_dup 2)
1632                      (const_int 24)))]
1633   ""
1634   "
1635 { operands[0] = gen_lowpart (SImode, operands[0]);
1636   operands[1] = gen_lowpart (SImode, operands[1]);
1637   operands[2] = gen_reg_rtx (SImode); }")
1638
1639 (define_expand "extendqisi2"
1640   [(set (match_dup 2)
1641         (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
1642                    (const_int 24)))
1643    (set (match_operand:SI 0 "gpc_reg_operand" "")
1644         (ashiftrt:SI (match_dup 2)
1645                      (const_int 24)))]
1646   ""
1647   "
1648 { operands[1] = gen_lowpart (SImode, operands[1]);
1649   operands[2] = gen_reg_rtx (SImode); }")
1650
1651 (define_expand "extendhisi2"
1652   [(set (match_dup 2)
1653         (ashift:SI (match_operand:HI 1 "gpc_reg_operand" "")
1654                    (const_int 16)))
1655    (set (match_operand:SI 0 "gpc_reg_operand" "")
1656         (ashiftrt:SI (match_dup 2)
1657                      (const_int 16)))]
1658   ""
1659   "
1660 { operands[1] = gen_lowpart (SImode, operands[1]);
1661   operands[2] = gen_reg_rtx (SImode); }")
1662 \f
1663 ;; Define the methods used to move data around.
1664 ;;
1665 ;; movsi:
1666 ;;
1667 ;; If storing into memory, force source into register.
1668 (define_expand "movsi"
1669   [(set (match_operand:SI 0 "general_operand" "")
1670         (match_operand:SI 1 "general_operand" ""))]
1671   ""
1672   "
1673 {
1674   if (GET_CODE (operands[0]) == MEM && ! gpc_reg_operand (operands[1], SImode))
1675     operands[1] = copy_to_mode_reg (SImode, operands[1]);
1676   else if (spec_reg_operand (operands[0], SImode)
1677            && ! (register_operand (operands[1], SImode)
1678                  || cint_16_operand (operands[1], SImode)))
1679     operands[1] = force_reg (SImode, operands[1]);
1680 }")
1681
1682 (define_expand "movpsi"
1683   [(set (match_operand:PSI 0 "general_operand" "")
1684         (match_operand:PSI 1 "general_operand" ""))]
1685   ""
1686   "
1687 {
1688   if (GET_CODE (operands[0]) == MEM
1689       && ! gpc_reg_operand (operands[1], PSImode))
1690     operands[1] = copy_to_mode_reg (PSImode, operands[1]);
1691   else if (spec_reg_operand (operands[0], PSImode)
1692            && ! (register_operand (operands[1], PSImode)
1693                  || cint_16_operand (operands[1], PSImode)))
1694     operands[1] = force_reg (PSImode, operands[1]);
1695 }")
1696
1697 (define_split
1698   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1699         (match_operand:SI 1 "long_const_operand" ""))]
1700   ""
1701   [(set (match_dup 0)
1702         (and:SI (match_dup 1)
1703                 (const_int 65535)))
1704    (set (match_dup 0)
1705         (ior:SI (zero_extend:SI (match_dup 2))
1706                 (and:SI (match_dup 1)
1707                         (const_int -65536))))]
1708   " operands[2] = gen_lowpart (HImode, operands[0]); ")
1709 \f
1710 ;; Subroutines to load/store halfwords.  Operands 0 and 1 are the output and
1711 ;; input, respectively, except that the address is passed for a MEM instead 
1712 ;; of the MEM itself and the short item is passed in QImode.
1713 ;;
1714 ;; Operand 2 is a scratch general register and operand 3 is a scratch register
1715 ;; used for BP.  When called before reload, pseudos are passed for both
1716 ;; operands.  During reload, R_TAV is used for the general register, and
1717 ;; a reload register of class BR_REGS (R_VP) for BP.
1718 ;;
1719 ;; We have two versions of the store operations, for when halfword writes are
1720 ;; supported and when they are not.
1721 (define_expand "loadhi"
1722   [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "")
1723                    (mem:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
1724                                    (const_int -4))))
1725               (set (match_operand:PSI 3 "register_operand" "")
1726                    (truncate:PSI (match_dup 1)))])
1727    (set (match_operand:SI 0 "gpc_reg_operand" "")
1728         (zero_extract:SI (match_dup 2)
1729                          (const_int 16)
1730                          (ashift:PSI (match_dup 3) (const_int 3))))]
1731   ""
1732   "")
1733
1734 (define_expand "storehinhww"
1735  [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "")
1736                    (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "")
1737                                    (const_int -4))))
1738               (set (match_operand:PSI 3 "register_operand" "")
1739                    (truncate:PSI (match_dup 0)))])
1740    (set (zero_extract:SI (match_dup 2)
1741                          (const_int 16)
1742                          (ashift:PSI (match_dup 3) (const_int 3)))
1743         (match_operand:SI 1 "gpc_reg_operand" ""))
1744    (set (mem:SI (match_dup 0))
1745         (match_dup 2))]
1746   ""
1747   "")
1748
1749 (define_expand "storehihww"
1750   [(set (match_operand:PSI 3 "register_operand" "")
1751         (truncate:PSI (match_operand:SI 0 "gpc_reg_operand" "")))
1752    (set (match_operand:SI 2 "gpc_reg_operand" "")
1753         (ior:SI (and:SI (not:SI (ashift:SI (const_int 65535)
1754                                            (ashift:PSI (match_dup 3)
1755                                                        (const_int 3))))
1756                         (match_operand:SI 1 "gpc_reg_operand" ""))
1757                 (ashift:SI (zero_extend:SI (match_dup 4))
1758                            (ashift:PSI (match_dup 3) (const_int 3)))))
1759    (set (mem:SI (and:SI (match_dup 0)
1760                         (const_int -3)))
1761         (match_dup 2))]
1762   ""
1763   "
1764 { operands[4] = gen_lowpart (HImode, operands[1]); }")
1765
1766 (define_expand "movhi"
1767   [(set (match_operand:HI 0 "general_operand" "")
1768         (match_operand:HI 1 "general_operand" ""))]
1769   ""
1770   "
1771 { if (GET_CODE (operands[0]) == MEM) 
1772     {
1773       if (! gpc_reg_operand (operands[1], HImode))
1774         operands[1] = copy_to_mode_reg (HImode, operands[1]);
1775       if (! TARGET_DW_ENABLE)
1776         {
1777           rtx general = gen_reg_rtx (SImode);
1778           rtx bp = gen_reg_rtx (PSImode);
1779           rtx (*fcn) PARAMS ((rtx, rtx, rtx, rtx))
1780             = TARGET_BYTE_WRITES ? gen_storehihww : gen_storehinhww;
1781           rtx seq = (*fcn) (XEXP (operands[0], 0),
1782                             gen_lowpart (SImode, operands[1]),
1783                             general, bp);
1784             
1785           a29k_set_memflags (seq, operands[0]);
1786           emit_insn (seq);
1787           DONE;
1788         }
1789     }
1790   else if (GET_CODE (operands[1]) == MEM)
1791     {
1792       if (! TARGET_DW_ENABLE)
1793         {
1794           rtx general = gen_reg_rtx (SImode);
1795           rtx bp = gen_reg_rtx (PSImode);
1796           rtx seq = gen_loadhi (gen_lowpart (SImode, operands[0]),
1797                                 XEXP (operands[1], 0), general, bp);
1798
1799           a29k_set_memflags (seq, operands[1]);
1800           emit_insn (seq);
1801           DONE;
1802         }
1803     }
1804 }")
1805
1806 (define_expand "reload_inhi"
1807   [(parallel [(match_operand:SI 0 "register_operand" "=r")
1808               (match_operand:SI 1 "reload_memory_operand" "m")
1809               (match_operand:PSI 2 "register_operand" "=b")])]
1810   "! TARGET_DW_ENABLE"
1811   "
1812 { rtx seq = gen_loadhi (gen_lowpart (SImode, operands[0]),
1813                         a29k_get_reloaded_address (operands[1]),
1814                         gen_rtx_REG (SImode, R_TAV),
1815                         operands[2]);
1816
1817   a29k_set_memflags (seq, operands[1]);
1818   emit_insn (seq);
1819   DONE;
1820 }")
1821
1822 (define_expand "reload_outhi"
1823   [(parallel [(match_operand:SI 0 "reload_memory_operand" "=m")
1824               (match_operand:SI 1 "register_operand" "m")
1825               (match_operand:PSI 2 "register_operand" "=b")])]
1826   "! TARGET_DW_ENABLE"
1827   "
1828 { rtx (*fcn) PARAMS ((rtx, rtx, rtx, rtx)) =
1829     TARGET_BYTE_WRITES ? gen_storehihww : gen_storehinhww;
1830   rtx seq = (*fcn) (a29k_get_reloaded_address (operands[0]),
1831                     gen_lowpart (SImode, operands[1]),
1832                     gen_rtx_REG (SImode, R_TAV), operands[2]);
1833
1834   a29k_set_memflags (seq, operands[0]);
1835   emit_insn (seq);
1836   DONE;
1837 }")
1838 \f
1839 ;; Subroutines to load/store bytes.  Operands 0 and 1 are the output and
1840 ;; input, respectively, except that the address is passed for a MEM instead 
1841 ;; of the MEM itself and the short item is passed in QImode.
1842 ;;
1843 ;; Operand 2 is a scratch general register and operand 3 is a scratch register
1844 ;; used for BP.  When called before reload, pseudos are passed for both
1845 ;; operands.  During reload, R_TAV is used for the general register, and
1846 ;; a reload register of class BR_REGS (R_VP) for BP.
1847 ;;
1848 ;; We have two versions of the store operations, for when byte writes are
1849 ;; supported and when they are not.
1850 (define_expand "loadqi"
1851   [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "")
1852                    (mem:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
1853                                    (const_int -4))))
1854               (set (match_operand:PSI 3 "register_operand" "")
1855                    (truncate:PSI (match_dup 1)))])
1856    (set (match_operand:SI 0 "gpc_reg_operand" "")
1857         (zero_extract:SI (match_dup 2)
1858                          (const_int 8)
1859                          (ashift:PSI (match_dup 3) (const_int 3))))]
1860   ""
1861   "")
1862
1863 (define_expand "storeqinhww"
1864   [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "")
1865                    (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "")
1866                                    (const_int -4))))
1867               (set (match_operand:PSI 3 "register_operand" "")
1868                    (truncate:PSI (match_dup 0)))])
1869    (set (zero_extract:SI (match_dup 2)
1870                          (const_int 8)
1871                          (ashift:PSI (match_dup 3)
1872                                      (const_int 3)))
1873         (match_operand:SI 1 "gpc_reg_operand" ""))
1874    (set (mem:SI (match_dup 0))
1875         (match_dup 2))]
1876   ""
1877   "")
1878
1879 (define_expand "storeqihww"
1880   [(set (match_operand:PSI 3 "register_operand" "")
1881         (truncate:PSI (match_operand:SI 0 "gpc_reg_operand" "")))
1882    (set (match_operand:SI 2 "gpc_reg_operand" "")
1883         (ior:SI (and:SI (not:SI (ashift:SI (const_int 255)
1884                                            (ashift:PSI (match_dup 3)
1885                                                        (const_int 3))))
1886                         (match_operand:SI 1 "gpc_reg_operand" ""))
1887                 (ashift:SI (zero_extend:SI (match_dup 4))
1888                            (ashift:PSI (match_dup 3)
1889                                        (const_int 3)))))
1890    (set (mem:SI (and:SI (match_dup 0)
1891                         (const_int -4)))
1892         (match_dup 2))]
1893   ""
1894   "
1895 { operands[4] = gen_lowpart (QImode, operands[1]); }")
1896 \f
1897 (define_expand "movqi"
1898   [(set (match_operand:QI 0 "general_operand" "")
1899         (match_operand:QI 1 "general_operand" ""))]
1900   ""
1901   "
1902 { if (GET_CODE (operands[0]) == MEM)
1903     {
1904       if (! gpc_reg_operand (operands[1], QImode))
1905         operands[1] = copy_to_mode_reg (QImode, operands[1]);
1906       if (! TARGET_DW_ENABLE)
1907         {
1908           rtx general = gen_reg_rtx (SImode);
1909           rtx bp = gen_reg_rtx (PSImode);
1910           rtx (*fcn) PARAMS ((rtx, rtx, rtx, rtx))
1911             = TARGET_BYTE_WRITES ? gen_storeqihww : gen_storeqinhww;
1912           rtx seq = (*fcn) (XEXP (operands[0], 0),
1913                             gen_lowpart (SImode, operands[1]),
1914                             general, bp);
1915             
1916           a29k_set_memflags (seq, operands[0]);
1917           emit_insn (seq);
1918           DONE;
1919         }
1920     }
1921   else if (GET_CODE (operands[1]) == MEM)
1922     {
1923       if (! TARGET_DW_ENABLE)
1924         {
1925           rtx general = gen_reg_rtx (SImode);
1926           rtx bp = gen_reg_rtx (PSImode);
1927           rtx seq = gen_loadqi (gen_lowpart (SImode, operands[0]),
1928                                 XEXP (operands[1], 0), general, bp);
1929
1930           a29k_set_memflags (seq, operands[1]);
1931           emit_insn (seq);
1932           DONE;
1933         }
1934     }
1935 }")
1936
1937 (define_expand "reload_inqi"
1938   [(parallel [(match_operand:SI 0 "register_operand" "=r")
1939               (match_operand:SI 1 "reload_memory_operand" "m")
1940               (match_operand:PSI 2 "register_operand" "=b")])]
1941   "! TARGET_DW_ENABLE"
1942   "
1943 { rtx seq = gen_loadqi (gen_lowpart (SImode, operands[0]),
1944                         a29k_get_reloaded_address (operands[1]),
1945                         gen_rtx_REG (SImode, R_TAV),
1946                         operands[2]);
1947
1948   a29k_set_memflags (seq, operands[1]);
1949   emit_insn (seq);
1950   DONE;
1951 }")
1952
1953 (define_expand "reload_outqi"
1954   [(parallel [(match_operand:SI 0 "reload_memory_operand" "=m")
1955               (match_operand:SI 1 "register_operand" "m")
1956               (match_operand:PSI 2 "register_operand" "=b")])]
1957   "! TARGET_DW_ENABLE"
1958   "
1959 { rtx (*fcn) PARAMS ((rtx, rtx, rtx, rtx)) =
1960     TARGET_BYTE_WRITES ? gen_storeqihww : gen_storeqinhww;
1961   rtx seq = (*fcn) (a29k_get_reloaded_address (operands[0]),
1962                     gen_lowpart (SImode, operands[1]),
1963                     gen_rtx_REG (SImode, R_TAV), operands[2]);
1964
1965   a29k_set_memflags (seq, operands[0]);
1966   emit_insn (seq);
1967   DONE;
1968 }")
1969 \f
1970 ;; Now the actual insns used to move data around.  We include here the
1971 ;; DEFINE_SPLITs that may be needed.  In some cases these will be
1972 ;; split again.  For floating-point, if we can look inside the constant,
1973 ;; always split it.  This can eliminate unnecessary insns.
1974 (define_insn ""
1975   [(set (match_operand:SF 0 "out_operand" "=r,r,r,r,m")
1976         (match_operand:SF 1 "in_operand" "r,E,F,m,r"))]
1977   "(gpc_reg_operand (operands[0], SFmode)
1978     || gpc_reg_operand (operands[1], SFmode))
1979    && ! TARGET_29050"
1980   "@
1981    sll %0,%1,0
1982    #
1983    const %0,%1\;consth %0,%1
1984    load 0,0,%0,%1
1985    store 0,0,%1,%0"
1986   [(set_attr "type" "misc,multi,multi,load,store")])
1987
1988 (define_insn ""
1989   [(set (match_operand:SF 0 "out_operand" "=r,r,r,r,m,*a,r")
1990         (match_operand:SF 1 "in_operand" "r,E,F,m,r,r,*a"))]
1991   "(gpc_reg_operand (operands[0], SFmode)
1992     || gpc_reg_operand (operands[1], SFmode))
1993    && TARGET_29050"
1994   "@
1995    sll %0,%1,0
1996    #
1997    const %0,%1\;consth %0,%1
1998    load 0,0,%0,%1
1999    store 0,0,%1,%0
2000    mtacc %1,1,%0
2001    mfacc %0,1,%1"
2002   [(set_attr "type" "misc,multi,multi,load,store,fadd,fadd")])
2003
2004 ;; Turn this into SImode.  It will then be split up that way.
2005 (define_split
2006   [(set (match_operand:SF 0 "register_operand" "")
2007         (match_operand:SF 1 "float_const_operand" ""))]
2008   "HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT"
2009   [(set (match_dup 0)
2010         (match_dup 1))]
2011   "
2012 { operands[0] = operand_subword (operands[0], 0, 0, SFmode);
2013   operands[1] = operand_subword (operands[1], 0, 0, SFmode);
2014
2015   if (operands[0] == 0 || operands[1] == 0)
2016     FAIL;
2017 }")
2018
2019 (define_insn ""
2020   [(set (match_operand:DF 0 "out_operand" "=?r,?r,r,m")
2021         (match_operand:DF 1 "in_operand" "rE,F,m,r"))
2022    (clobber (match_scratch:PSI 2 "=X,X,&c,&c"))]
2023   "(gpc_reg_operand (operands[0], DFmode)
2024     || gpc_reg_operand (operands[1], DFmode))
2025    && ! TARGET_29050"
2026   "@
2027    #
2028    const %0,%1\;consth %0,%1\;const %L0,%L1\;consth %L0,%L1
2029    mtsrim cr,1\;loadm 0,0,%0,%1
2030    mtsrim cr,1\;storem 0,0,%1,%0"
2031   [(set_attr "type" "multi")])
2032
2033 (define_insn ""
2034   [(set (match_operand:DF 0 "out_operand" "=?r,?r,r,m,?*a,?r")
2035         (match_operand:DF 1 "in_operand" "rE,F,m,r,r,*a"))
2036    (clobber (match_scratch:PSI 2 "=X,X,&c,&c,X,X"))]
2037   "(gpc_reg_operand (operands[0], DFmode)
2038     || gpc_reg_operand (operands[1], DFmode))
2039    && TARGET_29050"
2040   "@
2041    #
2042    const %0,%1\;consth %0,%1\;const %L0,%L1\;consth %L0,%L1
2043    mtsrim cr,1\;loadm 0,0,%0,%1
2044    mtsrim cr,1\;storem 0,0,%1,%0
2045    mtacc %1,2,%0
2046    mfacc %0,2,%1"
2047   [(set_attr "type" "multi,multi,multi,multi,fadd,fadd")])
2048
2049 ;; Split register-register copies and constant loads into two SImode loads,
2050 ;; one for each word.  In the constant case, they will get further split.
2051 ;; Don't so this until register allocation, though, since it will
2052 ;; interfere with register allocation.  Normally copy the lowest-addressed
2053 ;; word first; the exception is if we are copying register to register and
2054 ;; the lowest register of the first operand is the highest register of the
2055 ;; second operand.
2056 (define_split
2057   [(set (match_operand:DF 0 "gpc_reg_operand" "")
2058         (match_operand:DF 1 "gpc_reg_or_float_constant_operand" ""))
2059    (clobber (match_scratch:PSI 2 ""))]
2060   "reload_completed"
2061   [(set (match_dup 3) (match_dup 4))
2062    (set (match_dup 5) (match_dup 6))]
2063   "
2064 { if (GET_CODE (operands[1]) == REG
2065       && REGNO (operands[0]) == REGNO (operands[1]) + 1)
2066     {
2067       operands[3] = operand_subword (operands[0], 1, 1, DFmode);
2068       operands[4] = operand_subword (operands[1], 1, 1, DFmode);
2069       operands[5] = operand_subword (operands[0], 0, 1, DFmode);
2070       operands[6] = operand_subword (operands[1], 0, 1, DFmode);
2071     }
2072   else
2073     {
2074       operands[3] = operand_subword (operands[0], 0, 1, DFmode);
2075       operands[4] = operand_subword (operands[1], 0, 1, DFmode);
2076       operands[5] = operand_subword (operands[0], 1, 1, DFmode);
2077       operands[6] = operand_subword (operands[1], 1, 1, DFmode);
2078     }
2079
2080   if (operands[3] == 0 || operands[4] == 0
2081       || operands[5] == 0 || operands[6] == 0)
2082     FAIL;
2083 }")
2084
2085 ;; Split memory loads and stores into the MTSR and LOADM/STOREM.
2086 (define_split
2087   [(set (match_operand:DF 0 "out_operand" "")
2088         (match_operand:DF 1 "in_operand" ""))
2089    (clobber (reg:PSI 179))]
2090   "TARGET_NO_STOREM_BUG
2091    && (memory_operand (operands[0], DFmode)
2092        || memory_operand (operands[1], DFmode))"
2093   [(set (reg:PSI 179) (const_int 1))
2094    (parallel [(set (match_dup 0) (match_dup 1))
2095               (use (reg:PSI 179))
2096               (clobber (reg:PSI 179))])]
2097   "")
2098
2099 ;; DI move is similar to DF move.
2100 (define_insn ""
2101   [(set (match_operand:DI 0 "out_operand" "=?r,r,m")
2102         (match_operand:DI 1 "in_operand" "rn,m,r"))
2103    (clobber (match_scratch:PSI 2 "=X,&c,&c"))]
2104   "(gpc_reg_operand (operands[0], DImode)
2105      || gpc_reg_operand (operands[1], DImode))"
2106   "@
2107    #
2108    mtsrim cr,1\;loadm 0,0,%0,%1
2109    mtsrim cr,1\;storem 0,0,%1,%0"
2110   [(set_attr "type" "multi")])
2111
2112 (define_split
2113   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2114         (match_operand:DI 1 "gpc_reg_or_integer_constant_operand" ""))
2115    (clobber (match_scratch:PSI 2 ""))]
2116   "reload_completed"
2117   [(set (match_dup 3) (match_dup 4))
2118    (set (match_dup 5) (match_dup 6))]
2119   "
2120 { if (GET_CODE (operands[1]) == REG
2121       && REGNO (operands[0]) == REGNO (operands[1]) + 1)
2122     {
2123       operands[3] = operand_subword (operands[0], 1, 1, DImode);
2124       operands[4] = operand_subword (operands[1], 1, 1, DImode);
2125       operands[5] = operand_subword (operands[0], 0, 1, DImode);
2126       operands[6] = operand_subword (operands[1], 0, 1, DImode);
2127     }
2128   else
2129     {
2130       operands[3] = operand_subword (operands[0], 0, 1, DImode);
2131       operands[4] = operand_subword (operands[1], 0, 1, DImode);
2132       operands[5] = operand_subword (operands[0], 1, 1, DImode);
2133       operands[6] = operand_subword (operands[1], 1, 1, DImode);
2134     }
2135 }")
2136
2137 (define_split
2138   [(set (match_operand:DI 0 "out_operand" "")
2139         (match_operand:DI 1 "in_operand" ""))
2140    (clobber (reg:PSI 179))]
2141   "TARGET_NO_STOREM_BUG
2142    && (memory_operand (operands[0], DImode)
2143        || memory_operand (operands[1], DImode))"
2144   [(set (reg:PSI 179) (const_int 1))
2145    (parallel [(set (match_dup 0) (match_dup 1))
2146               (use (reg:PSI 179))
2147               (clobber (reg:PSI 179))])]
2148   "")
2149
2150 ;; TImode moves are very similar to DImode moves, except that we can't
2151 ;; have constants.
2152 (define_insn ""
2153   [(set (match_operand:TI 0 "out_operand" "=?r,r,m")
2154         (match_operand:TI 1 "in_operand" "r,m,r"))
2155    (clobber (match_scratch:PSI 2 "=X,&c,&c"))]
2156   "(gpc_reg_operand (operands[0], TImode)
2157     || gpc_reg_operand (operands[1], TImode))"
2158   "@
2159    #
2160    mtsrim cr,3\;loadm 0,0,%0,%1
2161    mtsrim cr,3\;storem 0,0,%1,%0"
2162   [(set_attr "type" "multi,multi,multi")])
2163
2164 (define_split
2165   [(set (match_operand:TI 0 "gpc_reg_operand" "")
2166         (match_operand:TI 1 "gpc_reg_operand" ""))
2167    (clobber (match_scratch:PSI 2 ""))]
2168   "reload_completed"
2169   [(set (match_dup 3) (match_dup 4))
2170    (set (match_dup 5) (match_dup 6))
2171    (set (match_dup 7) (match_dup 8))
2172    (set (match_dup 9) (match_dup 10))]
2173   "
2174 {
2175   if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
2176       && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
2177     {
2178       operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 3);
2179       operands[4] = gen_rtx_REG (SImode, REGNO (operands[1]) + 3);
2180       operands[5] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
2181       operands[6] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
2182       operands[7] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2183       operands[8] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2184       operands[9] = gen_rtx_REG (SImode, REGNO (operands[0]));
2185       operands[10] = gen_rtx_REG (SImode, REGNO (operands[1]));
2186     }
2187   else
2188     {
2189       operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
2190       operands[4] = gen_rtx_REG (SImode, REGNO (operands[1]));
2191       operands[5] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2192       operands[6] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2193       operands[7] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
2194       operands[8] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
2195       operands[9] = gen_rtx_REG (SImode, REGNO (operands[0]) + 3);
2196       operands[10] = gen_rtx_REG (SImode, REGNO (operands[1]) + 3); 
2197     }
2198 }")
2199
2200 (define_split
2201   [(set (match_operand:TI 0 "out_operand" "")
2202         (match_operand:TI 1 "in_operand" ""))
2203    (clobber (reg:PSI 179))]
2204   "TARGET_NO_STOREM_BUG
2205    && (memory_operand (operands[0], TImode)
2206        || memory_operand (operands[1], TImode))"
2207   [(set (reg:PSI 179) (const_int 3))
2208    (parallel [(set (match_dup 0) (match_dup 1))
2209               (use (reg:PSI 179))
2210               (clobber (reg:PSI 179))])]
2211   "")
2212
2213 (define_insn ""
2214   [(set (match_operand:SI 0 "out_operand" "=r,r,r,r,r,r,r,m,*h,*h")
2215         (match_operand:SI 1 "in_operand" "r,J,M,O,i,m,*h,r,r,J"))]
2216   "(gpc_reg_operand (operands[0], SImode)
2217     || gpc_reg_operand (operands[1], SImode)
2218     || (spec_reg_operand (operands[0], SImode)
2219         && cint_16_operand (operands[1], SImode)))
2220    && ! TARGET_29050"
2221   "@
2222    sll %0,%1,0
2223    const %0,%1
2224    constn %0,%M1
2225    cpeq %0,gr1,gr1
2226    #
2227    load 0,0,%0,%1
2228    mfsr %0,%1
2229    store 0,0,%1,%0
2230    mtsr %0,%1
2231    mtsrim %0,%1"
2232   [(set_attr "type" "misc,misc,misc,misc,multi,load,misc,store,misc,misc")])
2233
2234 (define_insn ""
2235   [(set (match_operand:SI 0 "out_operand" "=r,r,r,r,r,r,r,m,*h,*h")
2236         (match_operand:SI 1 "in_operand" "r,J,M,O,i,m,*h,r,r,J"))]
2237   "(gpc_reg_operand (operands[0], SImode)
2238     || gpc_reg_operand (operands[1], SImode)
2239     || (spec_reg_operand (operands[0], SImode)
2240         && cint_16_operand (operands[1], SImode)))
2241    && TARGET_29050"
2242   "@
2243    sll %0,%1,0
2244    const %0,%1
2245    constn %0,%M1
2246    consthz %0,%1
2247    #
2248    load 0,0,%0,%1
2249    mfsr %0,%1
2250    store 0,0,%1,%0
2251    mtsr %0,%1
2252    mtsrim %0,%1"
2253   [(set_attr "type" "misc,misc,misc,misc,multi,load,misc,store,misc,misc")])
2254
2255 (define_insn ""
2256   [(set (match_operand:PSI 0 "out_operand" "=*r,*r,*r,*r,m,h,h")
2257         (match_operand:PSI 1 "in_operand" "r,i,m,h,r,r,J"))]
2258   "(gpc_reg_operand (operands[0], PSImode)
2259     || gpc_reg_operand (operands[1], PSImode)
2260     || (spec_reg_operand (operands[0], PSImode)
2261         && cint_16_operand (operands[1], PSImode)))"
2262   "@
2263    sll %0,%1,0
2264    const %0,%1
2265    load 0,0,%0,%1
2266    mfsr %0,%1
2267    store 0,0,%1,%0
2268    mtsr %0,%1
2269    mtsrim %0,%1"
2270   [(set_attr "type" "misc,multi,load,misc,store,misc,misc")])
2271
2272 (define_insn ""
2273   [(set (match_operand:HI 0 "out_operand" "=r,r,r,m,r,*h,*h")
2274         (match_operand:HI 1 "in_operand" "r,i,m,r,*h,r,i"))]
2275   "gpc_reg_operand (operands[0], HImode)
2276    || gpc_reg_operand (operands[1], HImode)
2277    || (spec_reg_operand (operands[0], HImode)
2278        && cint_16_operand (operands[1], HImode))"
2279   "@
2280    sll %0,%1,0
2281    const %0,%1
2282    load 0,2,%0,%1
2283    store 0,2,%1,%0
2284    mfsr %0,%1
2285    mtsr %0,%1
2286    mtsrim %0,%1"
2287   [(set_attr "type" "misc,misc,load,store,misc,misc,misc")])
2288
2289 (define_insn ""
2290   [(set (match_operand:QI 0 "out_operand" "=r,r,r,m,r,*h,*h")
2291         (match_operand:QI 1 "in_operand" "r,i,m,r,*h,r,i"))]
2292   "gpc_reg_operand (operands[0], QImode)
2293    || gpc_reg_operand (operands[1], QImode)
2294    || (spec_reg_operand (operands[0], HImode)
2295        && cint_16_operand (operands[1], HImode))"
2296   "@
2297    sll %0,%1,0
2298    const %0,%1
2299    load 0,1,%0,%1
2300    store 0,1,%1,%0
2301    mfsr %0,%1
2302    mtsr %0,%1
2303    mtsrim %0,%1"
2304   [(set_attr "type" "misc,misc,load,store,misc,misc,misc")])
2305 \f
2306 ;; Define move insns for DI, TI, SF, and DF.
2307 ;;
2308 ;; In no case do we support mem->mem directly.
2309 ;;
2310 ;; For DI move of constant to register, split apart at this time since these
2311 ;; can require anywhere from 2 to 4 insns and determining which is complex.
2312 ;;
2313 ;; In other cases, handle similarly to SImode moves.
2314 ;;
2315 ;; However, indicate that DI, TI, and DF moves may clobber CR (reg 179).
2316 (define_expand "movdi"
2317   [(parallel [(set (match_operand:DI 0 "general_operand" "")
2318                    (match_operand:DI 1 "general_operand" ""))
2319               (clobber (scratch:PSI))])]
2320   ""
2321   "
2322 {
2323   if (GET_CODE (operands[0]) == MEM)
2324     operands[1] = force_reg (DImode, operands[1]);
2325 }")
2326
2327 (define_expand "movsf"
2328   [(set (match_operand:SF 0 "general_operand" "")
2329         (match_operand:SF 1 "general_operand" ""))]
2330   ""
2331   "
2332 { if (GET_CODE (operands[0]) == MEM)
2333     operands[1] = force_reg (SFmode, operands[1]);
2334 }")
2335
2336 (define_expand "movdf"
2337   [(parallel [(set (match_operand:DF 0 "general_operand" "")
2338                    (match_operand:DF 1 "general_operand" ""))
2339               (clobber (scratch:PSI))])]
2340   ""
2341   "
2342 { if (GET_CODE (operands[0]) == MEM)
2343     operands[1] = force_reg (DFmode, operands[1]);
2344 }")
2345
2346 (define_expand "movti"
2347   [(parallel [(set (match_operand:TI 0 "general_operand" "")
2348                    (match_operand:TI 1 "general_operand" ""))
2349               (clobber (scratch:PSI))])]
2350   ""
2351   "
2352 {
2353   if (GET_CODE (operands[0]) == MEM)
2354     operands[1] = force_reg (TImode, operands[1]);
2355
2356   /* We can't handle constants in general because there is no rtl to represent
2357      128 bit constants.  Splitting happens to work for CONST_INTs so we split
2358      them for good code.  Other constants will get forced to memory.  */
2359
2360   if (GET_CODE (operands[1]) == CONST_INT)
2361     {
2362      rtx part0, part1, part2, part3;
2363
2364      part0 = operand_subword (operands[0], 0, 1, TImode);
2365      part1 = operand_subword (operands[0], 1, 1, TImode);
2366      part2 = operand_subword (operands[0], 2, 1, TImode);
2367      part3 = operand_subword (operands[0], 3, 1, TImode);
2368
2369      emit_move_insn (part0, const0_rtx);
2370      emit_move_insn (part1, const0_rtx);
2371      emit_move_insn (part2, const0_rtx);
2372      emit_move_insn (part3, const0_rtx);
2373
2374      DONE;
2375     }
2376   else if (CONSTANT_P (operands[1]))
2377     {
2378       operands[1] = force_const_mem (TImode, operands[1]);
2379       if (! memory_address_p (TImode, XEXP (operands[1], 0))
2380           && ! reload_in_progress)
2381         operands[1] = adjust_address (operands[1], TImode, 0);
2382     }
2383 }")
2384 \f
2385 ;; Here are the variants of the above for use during reload.
2386
2387 (define_expand "reload_indf"
2388   [(parallel [(set (match_operand:DF 0 "register_operand" "=r")
2389                    (match_operand:DF 1 "reload_memory_operand" "m"))
2390               (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
2391   ""
2392   "")
2393
2394 (define_expand "reload_outdf"
2395   [(parallel [(set (match_operand:DF 0 "reload_memory_operand" "=m")
2396                    (match_operand:DF 1 "register_operand" "r"))
2397               (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
2398   ""
2399   "")
2400
2401 (define_expand "reload_indi"
2402   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
2403                    (match_operand:DI 1 "reload_memory_operand" "m"))
2404               (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
2405   ""
2406   "")
2407
2408 (define_expand "reload_outdi"
2409   [(parallel [(set (match_operand:DI 0 "reload_memory_operand" "=m")
2410                    (match_operand:DI 1 "register_operand" "r"))
2411               (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
2412   ""
2413   "")
2414
2415 (define_expand "reload_inti"
2416   [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
2417                    (match_operand:TI 1 "reload_memory_operand" "m"))
2418               (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
2419   ""
2420   "")
2421
2422 (define_expand "reload_outti"
2423   [(parallel [(set (match_operand:TI 0 "reload_memory_operand" "=m")
2424                    (match_operand:TI 1 "register_operand" "r"))
2425               (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
2426   ""
2427   "")
2428 \f
2429 ;; For compare operations, we simply store the comparison operands and
2430 ;; do nothing else.  The following branch or scc insn will output whatever
2431 ;; is needed.
2432 (define_expand "cmpsi"
2433   [(set (cc0)
2434         (compare (match_operand:SI 0 "gpc_reg_operand" "")
2435                  (match_operand:SI 1 "srcb_operand" "")))]
2436   ""
2437   "
2438 {
2439   a29k_compare_op0 = operands[0];
2440   a29k_compare_op1 = operands[1];
2441   a29k_compare_fp_p = 0;
2442   DONE;
2443 }")
2444
2445 (define_expand "cmpsf"
2446   [(set (cc0)
2447         (compare (match_operand:SF 0 "gpc_reg_operand" "")
2448                  (match_operand:SF 1 "gpc_reg_operand" "")))]
2449   "! TARGET_SOFT_FLOAT"
2450   "
2451 {
2452   a29k_compare_op0 = operands[0];
2453   a29k_compare_op1 = operands[1];
2454   a29k_compare_fp_p = 1;
2455   DONE;
2456 }")
2457
2458 (define_expand "cmpdf"
2459   [(set (cc0)
2460         (compare (match_operand:DF 0 "gpc_reg_operand" "")
2461                  (match_operand:DF 1 "gpc_reg_operand" "")))]
2462   "! TARGET_SOFT_FLOAT"
2463   "
2464 {
2465   a29k_compare_op0 = operands[0];
2466   a29k_compare_op1 = operands[1];
2467   a29k_compare_fp_p = 1;
2468   DONE;
2469 }")
2470
2471 ;; We can generate bit-tests better if we use NE instead of EQ, but we
2472 ;; don't have an NE for floating-point.  So we have to have two patterns
2473 ;; for EQ and two for NE.
2474
2475 (define_expand "beq"
2476   [(set (match_dup 1) (ne:SI (match_dup 2) (match_dup 3)))
2477    (set (pc)
2478         (if_then_else (ge (match_dup 1) (const_int 0))
2479                       (label_ref (match_operand 0 "" ""))
2480                       (pc)))]
2481   ""
2482   "
2483 {
2484   if (GET_MODE_CLASS (GET_MODE (a29k_compare_op0)) == MODE_FLOAT)
2485     {
2486       emit_insn (gen_beq_fp (operands[0]));
2487       DONE;
2488     }
2489
2490   operands[1] = gen_reg_rtx (SImode);
2491   operands[2] = a29k_compare_op0;
2492   operands[3] = a29k_compare_op1;
2493 }")
2494
2495 (define_expand "beq_fp"
2496   [(set (match_dup 1) (eq:SI (match_dup 2) (match_dup 3)))
2497    (set (pc)
2498         (if_then_else (lt (match_dup 1) (const_int 0))
2499                       (label_ref (match_operand 0 "" ""))
2500                       (pc)))]
2501   ""
2502   "
2503 {
2504   operands[1] = gen_reg_rtx (SImode);
2505   operands[2] = a29k_compare_op0;
2506   operands[3] = a29k_compare_op1;
2507 }")
2508
2509 (define_expand "bne"
2510   [(set (match_dup 1) (ne:SI (match_dup 2) (match_dup 3)))
2511    (set (pc)
2512         (if_then_else (lt (match_dup 1) (const_int 0))
2513                       (label_ref (match_operand 0 "" ""))
2514                       (pc)))]
2515   ""
2516   "
2517 {
2518   if (GET_MODE_CLASS (GET_MODE (a29k_compare_op0)) == MODE_FLOAT)
2519     {
2520       emit_insn (gen_bne_fp (operands[0]));
2521       DONE;
2522     }
2523
2524   operands[1] = gen_reg_rtx (SImode);
2525   operands[2] = a29k_compare_op0;
2526   operands[3] = a29k_compare_op1;
2527 }")
2528
2529 (define_expand "bne_fp"
2530   [(set (match_dup 1) (eq:SI (match_dup 2) (match_dup 3)))
2531    (set (pc)
2532         (if_then_else (ge (match_dup 1) (const_int 0))
2533                       (label_ref (match_operand 0 "" ""))
2534                       (pc)))]
2535   ""
2536   "
2537 {
2538   operands[1] = gen_reg_rtx (SImode);
2539   operands[2] = a29k_compare_op0;
2540   operands[3] = a29k_compare_op1;
2541 }")
2542
2543 ;; We don't have a floating-point "lt" insn, so we have to use "gt" in that
2544 ;; case with the operands swapped.  The operands must both be registers in
2545 ;; the floating-point case, so we know that swapping them is OK.
2546 (define_expand "blt"
2547   [(set (match_dup 1) (match_dup 2))
2548    (set (pc)
2549         (if_then_else (lt (match_dup 1) (const_int 0))
2550                       (label_ref (match_operand 0 "" ""))
2551                       (pc)))]
2552   ""
2553   "
2554 {
2555   operands[1] = gen_reg_rtx (SImode);
2556   if (a29k_compare_fp_p)
2557     operands[2] = gen_rtx_GT (SImode, a29k_compare_op1, a29k_compare_op0);
2558   else
2559     operands[2] = gen_rtx_LT (SImode, a29k_compare_op0, a29k_compare_op1);
2560 }")
2561
2562 ;; Similarly for "le".
2563 (define_expand "ble"
2564   [(set (match_dup 1) (match_dup 2))
2565    (set (pc)
2566         (if_then_else (lt (match_dup 1) (const_int 0))
2567                       (label_ref (match_operand 0 "" ""))
2568                       (pc)))]
2569   ""
2570   "
2571 {
2572   operands[1] = gen_reg_rtx (SImode);
2573   if (a29k_compare_fp_p)
2574     operands[2] = gen_rtx_GE (SImode, a29k_compare_op1, a29k_compare_op0);
2575   else
2576     operands[2] = gen_rtx_LE (SImode, a29k_compare_op0, a29k_compare_op1);
2577 }")
2578
2579 (define_expand "bltu"
2580   [(set (match_dup 1) (ltu:SI (match_dup 2) (match_dup 3)))
2581    (set (pc)
2582         (if_then_else (lt (match_dup 1) (const_int 0))
2583                       (label_ref (match_operand 0 "" ""))
2584                       (pc)))]
2585   ""
2586   "
2587 {
2588   operands[1] = gen_reg_rtx (SImode);
2589   operands[2] = a29k_compare_op0;
2590   operands[3] = a29k_compare_op1;
2591 }")
2592
2593 (define_expand "bleu"
2594   [(set (match_dup 1) (leu:SI (match_dup 2) (match_dup 3)))
2595    (set (pc)
2596         (if_then_else (lt (match_dup 1) (const_int 0))
2597                       (label_ref (match_operand 0 "" ""))
2598                       (pc)))]
2599   ""
2600   "
2601 {
2602   operands[1] = gen_reg_rtx (SImode);
2603   operands[2] = a29k_compare_op0;
2604   operands[3] = a29k_compare_op1;
2605 }")
2606
2607 (define_expand "bgt"
2608   [(set (match_dup 1) (gt:SI (match_dup 2) (match_dup 3)))
2609    (set (pc)
2610         (if_then_else (lt (match_dup 1) (const_int 0))
2611                       (label_ref (match_operand 0 "" ""))
2612                       (pc)))]
2613   ""
2614   "
2615 {
2616   operands[1] = gen_reg_rtx (SImode);
2617   operands[2] = a29k_compare_op0;
2618   operands[3] = a29k_compare_op1;
2619 }")
2620
2621 (define_expand "bge"
2622   [(set (match_dup 1) (ge:SI (match_dup 2) (match_dup 3)))
2623    (set (pc)
2624         (if_then_else (lt (match_dup 1) (const_int 0))
2625                       (label_ref (match_operand 0 "" ""))
2626                       (pc)))]
2627   ""
2628   "
2629 {
2630   operands[1] = gen_reg_rtx (SImode);
2631   operands[2] = a29k_compare_op0;
2632   operands[3] = a29k_compare_op1;
2633 }")
2634
2635 (define_expand "bgtu"
2636   [(set (match_dup 1) (gtu:SI (match_dup 2) (match_dup 3)))
2637    (set (pc)
2638         (if_then_else (lt (match_dup 1) (const_int 0))
2639                       (label_ref (match_operand 0 "" ""))
2640                       (pc)))]
2641   ""
2642   "
2643 {
2644   operands[1] = gen_reg_rtx (SImode);
2645   operands[2] = a29k_compare_op0;
2646   operands[3] = a29k_compare_op1;
2647 }")
2648
2649 (define_expand "bgeu"
2650   [(set (match_dup 1) (geu:SI (match_dup 2) (match_dup 3)))
2651    (set (pc)
2652         (if_then_else (lt (match_dup 1) (const_int 0))
2653                       (label_ref (match_operand 0 "" ""))
2654                       (pc)))]
2655   ""
2656   "
2657 {
2658   operands[1] = gen_reg_rtx (SImode);
2659   operands[2] = a29k_compare_op0;
2660   operands[3] = a29k_compare_op1;
2661 }")
2662 \f
2663 (define_expand "seq"
2664   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2665         (eq:SI (match_dup 1) (match_dup 2)))]
2666   ""
2667   "
2668 {
2669   operands[1] = a29k_compare_op0;
2670   operands[2] = a29k_compare_op1;
2671 }")
2672                  
2673 ;; This is the most complicated case, because we don't have a floating-point
2674 ;; "ne" insn.  If integer, handle normally.  If floating-point, write the
2675 ;; compare and then write an insn to reverse the test.
2676 (define_expand "sne_fp"
2677   [(set (match_dup 3)
2678         (eq:SI (match_operand 1 "gpc_reg_operand" "")
2679                (match_operand 2 "gpc_reg_operand" "")))
2680    (set (match_operand:SI 0 "gpc_reg_operand" "")
2681         (ge:SI (match_dup 3) (const_int 0)))]
2682   "! TARGET_SOFT_FLOAT"
2683   "
2684 { operands[3] = gen_reg_rtx (SImode);
2685 }");
2686
2687 (define_expand "sne"
2688   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2689         (ne:SI (match_dup 1) (match_dup 2)))]
2690   ""
2691   "
2692 {
2693   operands[1] = a29k_compare_op0;
2694   operands[2] = a29k_compare_op1;
2695
2696   if (a29k_compare_fp_p)
2697     {
2698       emit_insn (gen_sne_fp (operands[0], operands[1], operands[2]));
2699       DONE;
2700     }
2701 }")
2702                  
2703 ;; We don't have a floating-point "lt" insn, so use "gt" and swap the
2704 ;; operands, the same as we do "blt".
2705 (define_expand "slt"
2706   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2707         (match_dup 1))]
2708   ""
2709   "
2710 {
2711   if (a29k_compare_fp_p)
2712     operands[1] = gen_rtx_GT (SImode, a29k_compare_op1, a29k_compare_op0);
2713   else
2714     operands[1] = gen_rtx_LT (SImode, a29k_compare_op0, a29k_compare_op1);
2715 }")
2716
2717 ;; Similarly for "le"
2718 (define_expand "sle"
2719   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2720         (match_dup 1))]
2721   ""
2722   "
2723 {
2724   if (a29k_compare_fp_p)
2725     operands[1] = gen_rtx_GE (SImode, a29k_compare_op1, a29k_compare_op0);
2726   else
2727     operands[1] = gen_rtx_LE (SImode, a29k_compare_op0, a29k_compare_op1);
2728 }")
2729
2730 (define_expand "sltu"
2731   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2732         (ltu:SI (match_dup 1) (match_dup 2)))]
2733   ""
2734   "
2735 {
2736   operands[1] = a29k_compare_op0;
2737   operands[2] = a29k_compare_op1;
2738 }")
2739
2740 (define_expand "sleu"
2741   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2742         (leu:SI (match_dup 1) (match_dup 2)))]
2743   ""
2744   "
2745 {
2746   operands[1] = a29k_compare_op0;
2747   operands[2] = a29k_compare_op1;
2748 }")
2749
2750 (define_expand "sgt"
2751   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2752         (gt:SI (match_dup 1) (match_dup 2)))]
2753   ""
2754   "
2755 {
2756   operands[1] = a29k_compare_op0;
2757   operands[2] = a29k_compare_op1;
2758 }")
2759
2760 (define_expand "sge"
2761   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2762         (ge:SI (match_dup 1) (match_dup 2)))]
2763   ""
2764   "
2765 {
2766   operands[1] = a29k_compare_op0;
2767   operands[2] = a29k_compare_op1;
2768 }")
2769                  
2770 (define_expand "sgtu"
2771   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2772         (gtu:SI (match_dup 1) (match_dup 2)))]
2773   ""
2774   "
2775 {
2776   operands[1] = a29k_compare_op0;
2777   operands[2] = a29k_compare_op1;
2778 }")
2779
2780 (define_expand "sgeu"
2781   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2782         (geu:SI (match_dup 1) (match_dup 2)))]
2783   ""
2784   "
2785 {
2786   operands[1] = a29k_compare_op0;
2787   operands[2] = a29k_compare_op1;
2788 }")
2789 \f
2790 ;; Now define the actual jump insns.
2791 (define_insn ""
2792   [(set (pc)
2793         (if_then_else (match_operator 0 "branch_operator"
2794                                       [(match_operand:SI 1 "gpc_reg_operand" "r")
2795                                        (const_int 0)])
2796                       (label_ref (match_operand 2 "" ""))
2797                       (pc)))]
2798   ""
2799   "jmp%b0 %1,%l2%#"
2800   [(set_attr "type" "branch")])
2801
2802 (define_insn ""
2803   [(set (pc)
2804         (if_then_else (match_operator 0 "branch_operator"
2805                                       [(match_operand:SI 1 "gpc_reg_operand" "r")
2806                                        (const_int 0)])
2807                       (return)
2808                       (pc)))]
2809   "null_epilogue ()"
2810   "jmp%b0i %1,lr0%#"
2811   [(set_attr "type" "branch")])
2812
2813 (define_insn ""
2814   [(set (pc)
2815         (if_then_else (match_operator 0 "branch_operator"
2816                                       [(match_operand:SI 1 "gpc_reg_operand" "r")
2817                                        (const_int 0)])
2818                       (pc)
2819                       (label_ref (match_operand 2 "" ""))))]
2820   ""
2821   "jmp%B0 %1,%l2%#"
2822   [(set_attr "type" "branch")])
2823
2824 (define_insn ""
2825   [(set (pc)
2826         (if_then_else (match_operator 0 "branch_operator"
2827                                       [(match_operand:SI 1 "gpc_reg_operand" "r")
2828                                        (const_int 0)])
2829                       (pc)
2830                       (return)))]
2831   "null_epilogue ()"
2832   "jmp%B0i %1,lr0%#"
2833   [(set_attr "type" "branch")])
2834
2835 (define_insn "jump"
2836   [(set (pc)
2837         (label_ref (match_operand 0 "" "")))]
2838   ""
2839   "jmp %e0%E0"
2840   [(set_attr "type" "branch")])
2841
2842 (define_insn "return"
2843   [(return)]
2844   "null_epilogue ()"
2845   "jmpi lr0%#"
2846   [(set_attr "type" "branch")])
2847
2848 (define_insn "indirect_jump"
2849   [(set (pc)
2850         (match_operand:SI 0 "gpc_reg_operand" "r"))]
2851   ""
2852   "jmpi %0%#"
2853   [(set_attr "type" "branch")])
2854
2855 (define_insn "tablejump"
2856   [(set (pc)
2857         (match_operand:SI 0 "gpc_reg_operand" "r"))
2858    (use (label_ref (match_operand 1 "" "")))]
2859   ""
2860   "jmpi %0%#"
2861   [(set_attr "type" "branch")])
2862
2863 ;; JMPFDEC
2864 (define_insn ""
2865   [(set (pc)
2866         (if_then_else (ge (match_operand:SI 0 "gpc_reg_operand" "+r")
2867                           (const_int 0))
2868                       (label_ref (match_operand 1 "" ""))
2869                       (pc)))
2870    (set (match_dup 0)
2871         (plus:SI (match_dup 0)
2872                  (const_int -1)))]
2873   ""
2874   "jmpfdec %0,%l1%#"
2875   [(set_attr "type" "branch")])