OSDN Git Service

* emit-rtl.c (adjust_address): New function.
[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) ()
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) () = TARGET_BYTE_WRITES ? gen_storehihww : gen_storehinhww;
1829   rtx seq = (*fcn) (a29k_get_reloaded_address (operands[0]),
1830                     gen_lowpart (SImode, operands[1]),
1831                     gen_rtx_REG (SImode, R_TAV), operands[2]);
1832
1833   a29k_set_memflags (seq, operands[0]);
1834   emit_insn (seq);
1835   DONE;
1836 }")
1837 \f
1838 ;; Subroutines to load/store bytes.  Operands 0 and 1 are the output and
1839 ;; input, respectively, except that the address is passed for a MEM instead 
1840 ;; of the MEM itself and the short item is passed in QImode.
1841 ;;
1842 ;; Operand 2 is a scratch general register and operand 3 is a scratch register
1843 ;; used for BP.  When called before reload, pseudos are passed for both
1844 ;; operands.  During reload, R_TAV is used for the general register, and
1845 ;; a reload register of class BR_REGS (R_VP) for BP.
1846 ;;
1847 ;; We have two versions of the store operations, for when byte writes are
1848 ;; supported and when they are not.
1849 (define_expand "loadqi"
1850   [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "")
1851                    (mem:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
1852                                    (const_int -4))))
1853               (set (match_operand:PSI 3 "register_operand" "")
1854                    (truncate:PSI (match_dup 1)))])
1855    (set (match_operand:SI 0 "gpc_reg_operand" "")
1856         (zero_extract:SI (match_dup 2)
1857                          (const_int 8)
1858                          (ashift:PSI (match_dup 3) (const_int 3))))]
1859   ""
1860   "")
1861
1862 (define_expand "storeqinhww"
1863   [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "")
1864                    (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "")
1865                                    (const_int -4))))
1866               (set (match_operand:PSI 3 "register_operand" "")
1867                    (truncate:PSI (match_dup 0)))])
1868    (set (zero_extract:SI (match_dup 2)
1869                          (const_int 8)
1870                          (ashift:PSI (match_dup 3)
1871                                      (const_int 3)))
1872         (match_operand:SI 1 "gpc_reg_operand" ""))
1873    (set (mem:SI (match_dup 0))
1874         (match_dup 2))]
1875   ""
1876   "")
1877
1878 (define_expand "storeqihww"
1879   [(set (match_operand:PSI 3 "register_operand" "")
1880         (truncate:PSI (match_operand:SI 0 "gpc_reg_operand" "")))
1881    (set (match_operand:SI 2 "gpc_reg_operand" "")
1882         (ior:SI (and:SI (not:SI (ashift:SI (const_int 255)
1883                                            (ashift:PSI (match_dup 3)
1884                                                        (const_int 3))))
1885                         (match_operand:SI 1 "gpc_reg_operand" ""))
1886                 (ashift:SI (zero_extend:SI (match_dup 4))
1887                            (ashift:PSI (match_dup 3)
1888                                        (const_int 3)))))
1889    (set (mem:SI (and:SI (match_dup 0)
1890                         (const_int -4)))
1891         (match_dup 2))]
1892   ""
1893   "
1894 { operands[4] = gen_lowpart (QImode, operands[1]); }")
1895 \f
1896 (define_expand "movqi"
1897   [(set (match_operand:QI 0 "general_operand" "")
1898         (match_operand:QI 1 "general_operand" ""))]
1899   ""
1900   "
1901 { if (GET_CODE (operands[0]) == MEM)
1902     {
1903       if (! gpc_reg_operand (operands[1], QImode))
1904         operands[1] = copy_to_mode_reg (QImode, operands[1]);
1905       if (! TARGET_DW_ENABLE)
1906         {
1907           rtx general = gen_reg_rtx (SImode);
1908           rtx bp = gen_reg_rtx (PSImode);
1909           rtx (*fcn) ()
1910             = TARGET_BYTE_WRITES ? gen_storeqihww : gen_storeqinhww;
1911           rtx seq = (*fcn) (XEXP (operands[0], 0),
1912                             gen_lowpart (SImode, operands[1]),
1913                             general, bp);
1914             
1915           a29k_set_memflags (seq, operands[0]);
1916           emit_insn (seq);
1917           DONE;
1918         }
1919     }
1920   else if (GET_CODE (operands[1]) == MEM)
1921     {
1922       if (! TARGET_DW_ENABLE)
1923         {
1924           rtx general = gen_reg_rtx (SImode);
1925           rtx bp = gen_reg_rtx (PSImode);
1926           rtx seq = gen_loadqi (gen_lowpart (SImode, operands[0]),
1927                                 XEXP (operands[1], 0), general, bp);
1928
1929           a29k_set_memflags (seq, operands[1]);
1930           emit_insn (seq);
1931           DONE;
1932         }
1933     }
1934 }")
1935
1936 (define_expand "reload_inqi"
1937   [(parallel [(match_operand:SI 0 "register_operand" "=r")
1938               (match_operand:SI 1 "reload_memory_operand" "m")
1939               (match_operand:PSI 2 "register_operand" "=b")])]
1940   "! TARGET_DW_ENABLE"
1941   "
1942 { rtx seq = gen_loadqi (gen_lowpart (SImode, operands[0]),
1943                         a29k_get_reloaded_address (operands[1]),
1944                         gen_rtx_REG (SImode, R_TAV),
1945                         operands[2]);
1946
1947   a29k_set_memflags (seq, operands[1]);
1948   emit_insn (seq);
1949   DONE;
1950 }")
1951
1952 (define_expand "reload_outqi"
1953   [(parallel [(match_operand:SI 0 "reload_memory_operand" "=m")
1954               (match_operand:SI 1 "register_operand" "m")
1955               (match_operand:PSI 2 "register_operand" "=b")])]
1956   "! TARGET_DW_ENABLE"
1957   "
1958 { rtx (*fcn) () = TARGET_BYTE_WRITES ? gen_storeqihww : gen_storeqinhww;
1959   rtx seq = (*fcn) (a29k_get_reloaded_address (operands[0]),
1960                     gen_lowpart (SImode, operands[1]),
1961                     gen_rtx_REG (SImode, R_TAV), operands[2]);
1962
1963   a29k_set_memflags (seq, operands[0]);
1964   emit_insn (seq);
1965   DONE;
1966 }")
1967 \f
1968 ;; Now the actual insns used to move data around.  We include here the
1969 ;; DEFINE_SPLITs that may be needed.  In some cases these will be
1970 ;; split again.  For floating-point, if we can look inside the constant,
1971 ;; always split it.  This can eliminate unnecessary insns.
1972 (define_insn ""
1973   [(set (match_operand:SF 0 "out_operand" "=r,r,r,r,m")
1974         (match_operand:SF 1 "in_operand" "r,E,F,m,r"))]
1975   "(gpc_reg_operand (operands[0], SFmode)
1976     || gpc_reg_operand (operands[1], SFmode))
1977    && ! TARGET_29050"
1978   "@
1979    sll %0,%1,0
1980    #
1981    const %0,%1\;consth %0,%1
1982    load 0,0,%0,%1
1983    store 0,0,%1,%0"
1984   [(set_attr "type" "misc,multi,multi,load,store")])
1985
1986 (define_insn ""
1987   [(set (match_operand:SF 0 "out_operand" "=r,r,r,r,m,*a,r")
1988         (match_operand:SF 1 "in_operand" "r,E,F,m,r,r,*a"))]
1989   "(gpc_reg_operand (operands[0], SFmode)
1990     || gpc_reg_operand (operands[1], SFmode))
1991    && TARGET_29050"
1992   "@
1993    sll %0,%1,0
1994    #
1995    const %0,%1\;consth %0,%1
1996    load 0,0,%0,%1
1997    store 0,0,%1,%0
1998    mtacc %1,1,%0
1999    mfacc %0,1,%1"
2000   [(set_attr "type" "misc,multi,multi,load,store,fadd,fadd")])
2001
2002 ;; Turn this into SImode.  It will then be split up that way.
2003 (define_split
2004   [(set (match_operand:SF 0 "register_operand" "")
2005         (match_operand:SF 1 "float_const_operand" ""))]
2006   "HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT"
2007   [(set (match_dup 0)
2008         (match_dup 1))]
2009   "
2010 { operands[0] = operand_subword (operands[0], 0, 0, SFmode);
2011   operands[1] = operand_subword (operands[1], 0, 0, SFmode);
2012
2013   if (operands[0] == 0 || operands[1] == 0)
2014     FAIL;
2015 }")
2016
2017 (define_insn ""
2018   [(set (match_operand:DF 0 "out_operand" "=?r,?r,r,m")
2019         (match_operand:DF 1 "in_operand" "rE,F,m,r"))
2020    (clobber (match_scratch:PSI 2 "=X,X,&c,&c"))]
2021   "(gpc_reg_operand (operands[0], DFmode)
2022     || gpc_reg_operand (operands[1], DFmode))
2023    && ! TARGET_29050"
2024   "@
2025    #
2026    const %0,%1\;consth %0,%1\;const %L0,%L1\;consth %L0,%L1
2027    mtsrim cr,1\;loadm 0,0,%0,%1
2028    mtsrim cr,1\;storem 0,0,%1,%0"
2029   [(set_attr "type" "multi")])
2030
2031 (define_insn ""
2032   [(set (match_operand:DF 0 "out_operand" "=?r,?r,r,m,?*a,?r")
2033         (match_operand:DF 1 "in_operand" "rE,F,m,r,r,*a"))
2034    (clobber (match_scratch:PSI 2 "=X,X,&c,&c,X,X"))]
2035   "(gpc_reg_operand (operands[0], DFmode)
2036     || gpc_reg_operand (operands[1], DFmode))
2037    && TARGET_29050"
2038   "@
2039    #
2040    const %0,%1\;consth %0,%1\;const %L0,%L1\;consth %L0,%L1
2041    mtsrim cr,1\;loadm 0,0,%0,%1
2042    mtsrim cr,1\;storem 0,0,%1,%0
2043    mtacc %1,2,%0
2044    mfacc %0,2,%1"
2045   [(set_attr "type" "multi,multi,multi,multi,fadd,fadd")])
2046
2047 ;; Split register-register copies and constant loads into two SImode loads,
2048 ;; one for each word.  In the constant case, they will get further split.
2049 ;; Don't so this until register allocation, though, since it will
2050 ;; interfere with register allocation.  Normally copy the lowest-addressed
2051 ;; word first; the exception is if we are copying register to register and
2052 ;; the lowest register of the first operand is the highest register of the
2053 ;; second operand.
2054 (define_split
2055   [(set (match_operand:DF 0 "gpc_reg_operand" "")
2056         (match_operand:DF 1 "gpc_reg_or_float_constant_operand" ""))
2057    (clobber (match_scratch:PSI 2 ""))]
2058   "reload_completed"
2059   [(set (match_dup 3) (match_dup 4))
2060    (set (match_dup 5) (match_dup 6))]
2061   "
2062 { if (GET_CODE (operands[1]) == REG
2063       && REGNO (operands[0]) == REGNO (operands[1]) + 1)
2064     {
2065       operands[3] = operand_subword (operands[0], 1, 1, DFmode);
2066       operands[4] = operand_subword (operands[1], 1, 1, DFmode);
2067       operands[5] = operand_subword (operands[0], 0, 1, DFmode);
2068       operands[6] = operand_subword (operands[1], 0, 1, DFmode);
2069     }
2070   else
2071     {
2072       operands[3] = operand_subword (operands[0], 0, 1, DFmode);
2073       operands[4] = operand_subword (operands[1], 0, 1, DFmode);
2074       operands[5] = operand_subword (operands[0], 1, 1, DFmode);
2075       operands[6] = operand_subword (operands[1], 1, 1, DFmode);
2076     }
2077
2078   if (operands[3] == 0 || operands[4] == 0
2079       || operands[5] == 0 || operands[6] == 0)
2080     FAIL;
2081 }")
2082
2083 ;; Split memory loads and stores into the MTSR and LOADM/STOREM.
2084 (define_split
2085   [(set (match_operand:DF 0 "out_operand" "")
2086         (match_operand:DF 1 "in_operand" ""))
2087    (clobber (reg:PSI 179))]
2088   "TARGET_NO_STOREM_BUG
2089    && (memory_operand (operands[0], DFmode)
2090        || memory_operand (operands[1], DFmode))"
2091   [(set (reg:PSI 179) (const_int 1))
2092    (parallel [(set (match_dup 0) (match_dup 1))
2093               (use (reg:PSI 179))
2094               (clobber (reg:PSI 179))])]
2095   "")
2096
2097 ;; DI move is similar to DF move.
2098 (define_insn ""
2099   [(set (match_operand:DI 0 "out_operand" "=?r,r,m")
2100         (match_operand:DI 1 "in_operand" "rn,m,r"))
2101    (clobber (match_scratch:PSI 2 "=X,&c,&c"))]
2102   "(gpc_reg_operand (operands[0], DImode)
2103      || gpc_reg_operand (operands[1], DImode))"
2104   "@
2105    #
2106    mtsrim cr,1\;loadm 0,0,%0,%1
2107    mtsrim cr,1\;storem 0,0,%1,%0"
2108   [(set_attr "type" "multi")])
2109
2110 (define_split
2111   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2112         (match_operand:DI 1 "gpc_reg_or_integer_constant_operand" ""))
2113    (clobber (match_scratch:PSI 2 ""))]
2114   "reload_completed"
2115   [(set (match_dup 3) (match_dup 4))
2116    (set (match_dup 5) (match_dup 6))]
2117   "
2118 { if (GET_CODE (operands[1]) == REG
2119       && REGNO (operands[0]) == REGNO (operands[1]) + 1)
2120     {
2121       operands[3] = operand_subword (operands[0], 1, 1, DImode);
2122       operands[4] = operand_subword (operands[1], 1, 1, DImode);
2123       operands[5] = operand_subword (operands[0], 0, 1, DImode);
2124       operands[6] = operand_subword (operands[1], 0, 1, DImode);
2125     }
2126   else
2127     {
2128       operands[3] = operand_subword (operands[0], 0, 1, DImode);
2129       operands[4] = operand_subword (operands[1], 0, 1, DImode);
2130       operands[5] = operand_subword (operands[0], 1, 1, DImode);
2131       operands[6] = operand_subword (operands[1], 1, 1, DImode);
2132     }
2133 }")
2134
2135 (define_split
2136   [(set (match_operand:DI 0 "out_operand" "")
2137         (match_operand:DI 1 "in_operand" ""))
2138    (clobber (reg:PSI 179))]
2139   "TARGET_NO_STOREM_BUG
2140    && (memory_operand (operands[0], DImode)
2141        || memory_operand (operands[1], DImode))"
2142   [(set (reg:PSI 179) (const_int 1))
2143    (parallel [(set (match_dup 0) (match_dup 1))
2144               (use (reg:PSI 179))
2145               (clobber (reg:PSI 179))])]
2146   "")
2147
2148 ;; TImode moves are very similar to DImode moves, except that we can't
2149 ;; have constants.
2150 (define_insn ""
2151   [(set (match_operand:TI 0 "out_operand" "=?r,r,m")
2152         (match_operand:TI 1 "in_operand" "r,m,r"))
2153    (clobber (match_scratch:PSI 2 "=X,&c,&c"))]
2154   "(gpc_reg_operand (operands[0], TImode)
2155     || gpc_reg_operand (operands[1], TImode))"
2156   "@
2157    #
2158    mtsrim cr,3\;loadm 0,0,%0,%1
2159    mtsrim cr,3\;storem 0,0,%1,%0"
2160   [(set_attr "type" "multi,multi,multi")])
2161
2162 (define_split
2163   [(set (match_operand:TI 0 "gpc_reg_operand" "")
2164         (match_operand:TI 1 "gpc_reg_operand" ""))
2165    (clobber (match_scratch:PSI 2 ""))]
2166   "reload_completed"
2167   [(set (match_dup 3) (match_dup 4))
2168    (set (match_dup 5) (match_dup 6))
2169    (set (match_dup 7) (match_dup 8))
2170    (set (match_dup 9) (match_dup 10))]
2171   "
2172 {
2173   if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
2174       && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
2175     {
2176       operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 3);
2177       operands[4] = gen_rtx_REG (SImode, REGNO (operands[1]) + 3);
2178       operands[5] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
2179       operands[6] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
2180       operands[7] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2181       operands[8] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2182       operands[9] = gen_rtx_REG (SImode, REGNO (operands[0]));
2183       operands[10] = gen_rtx_REG (SImode, REGNO (operands[1]));
2184     }
2185   else
2186     {
2187       operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
2188       operands[4] = gen_rtx_REG (SImode, REGNO (operands[1]));
2189       operands[5] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2190       operands[6] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2191       operands[7] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
2192       operands[8] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
2193       operands[9] = gen_rtx_REG (SImode, REGNO (operands[0]) + 3);
2194       operands[10] = gen_rtx_REG (SImode, REGNO (operands[1]) + 3); 
2195     }
2196 }")
2197
2198 (define_split
2199   [(set (match_operand:TI 0 "out_operand" "")
2200         (match_operand:TI 1 "in_operand" ""))
2201    (clobber (reg:PSI 179))]
2202   "TARGET_NO_STOREM_BUG
2203    && (memory_operand (operands[0], TImode)
2204        || memory_operand (operands[1], TImode))"
2205   [(set (reg:PSI 179) (const_int 3))
2206    (parallel [(set (match_dup 0) (match_dup 1))
2207               (use (reg:PSI 179))
2208               (clobber (reg:PSI 179))])]
2209   "")
2210
2211 (define_insn ""
2212   [(set (match_operand:SI 0 "out_operand" "=r,r,r,r,r,r,r,m,*h,*h")
2213         (match_operand:SI 1 "in_operand" "r,J,M,O,i,m,*h,r,r,J"))]
2214   "(gpc_reg_operand (operands[0], SImode)
2215     || gpc_reg_operand (operands[1], SImode)
2216     || (spec_reg_operand (operands[0], SImode)
2217         && cint_16_operand (operands[1], SImode)))
2218    && ! TARGET_29050"
2219   "@
2220    sll %0,%1,0
2221    const %0,%1
2222    constn %0,%M1
2223    cpeq %0,gr1,gr1
2224    #
2225    load 0,0,%0,%1
2226    mfsr %0,%1
2227    store 0,0,%1,%0
2228    mtsr %0,%1
2229    mtsrim %0,%1"
2230   [(set_attr "type" "misc,misc,misc,misc,multi,load,misc,store,misc,misc")])
2231
2232 (define_insn ""
2233   [(set (match_operand:SI 0 "out_operand" "=r,r,r,r,r,r,r,m,*h,*h")
2234         (match_operand:SI 1 "in_operand" "r,J,M,O,i,m,*h,r,r,J"))]
2235   "(gpc_reg_operand (operands[0], SImode)
2236     || gpc_reg_operand (operands[1], SImode)
2237     || (spec_reg_operand (operands[0], SImode)
2238         && cint_16_operand (operands[1], SImode)))
2239    && TARGET_29050"
2240   "@
2241    sll %0,%1,0
2242    const %0,%1
2243    constn %0,%M1
2244    consthz %0,%1
2245    #
2246    load 0,0,%0,%1
2247    mfsr %0,%1
2248    store 0,0,%1,%0
2249    mtsr %0,%1
2250    mtsrim %0,%1"
2251   [(set_attr "type" "misc,misc,misc,misc,multi,load,misc,store,misc,misc")])
2252
2253 (define_insn ""
2254   [(set (match_operand:PSI 0 "out_operand" "=*r,*r,*r,*r,m,h,h")
2255         (match_operand:PSI 1 "in_operand" "r,i,m,h,r,r,J"))]
2256   "(gpc_reg_operand (operands[0], PSImode)
2257     || gpc_reg_operand (operands[1], PSImode)
2258     || (spec_reg_operand (operands[0], PSImode)
2259         && cint_16_operand (operands[1], PSImode)))"
2260   "@
2261    sll %0,%1,0
2262    const %0,%1
2263    load 0,0,%0,%1
2264    mfsr %0,%1
2265    store 0,0,%1,%0
2266    mtsr %0,%1
2267    mtsrim %0,%1"
2268   [(set_attr "type" "misc,multi,load,misc,store,misc,misc")])
2269
2270 (define_insn ""
2271   [(set (match_operand:HI 0 "out_operand" "=r,r,r,m,r,*h,*h")
2272         (match_operand:HI 1 "in_operand" "r,i,m,r,*h,r,i"))]
2273   "gpc_reg_operand (operands[0], HImode)
2274    || gpc_reg_operand (operands[1], HImode)
2275    || (spec_reg_operand (operands[0], HImode)
2276        && cint_16_operand (operands[1], HImode))"
2277   "@
2278    sll %0,%1,0
2279    const %0,%1
2280    load 0,2,%0,%1
2281    store 0,2,%1,%0
2282    mfsr %0,%1
2283    mtsr %0,%1
2284    mtsrim %0,%1"
2285   [(set_attr "type" "misc,misc,load,store,misc,misc,misc")])
2286
2287 (define_insn ""
2288   [(set (match_operand:QI 0 "out_operand" "=r,r,r,m,r,*h,*h")
2289         (match_operand:QI 1 "in_operand" "r,i,m,r,*h,r,i"))]
2290   "gpc_reg_operand (operands[0], QImode)
2291    || gpc_reg_operand (operands[1], QImode)
2292    || (spec_reg_operand (operands[0], HImode)
2293        && cint_16_operand (operands[1], HImode))"
2294   "@
2295    sll %0,%1,0
2296    const %0,%1
2297    load 0,1,%0,%1
2298    store 0,1,%1,%0
2299    mfsr %0,%1
2300    mtsr %0,%1
2301    mtsrim %0,%1"
2302   [(set_attr "type" "misc,misc,load,store,misc,misc,misc")])
2303 \f
2304 ;; Define move insns for DI, TI, SF, and DF.
2305 ;;
2306 ;; In no case do we support mem->mem directly.
2307 ;;
2308 ;; For DI move of constant to register, split apart at this time since these
2309 ;; can require anywhere from 2 to 4 insns and determining which is complex.
2310 ;;
2311 ;; In other cases, handle similarly to SImode moves.
2312 ;;
2313 ;; However, indicate that DI, TI, and DF moves may clobber CR (reg 179).
2314 (define_expand "movdi"
2315   [(parallel [(set (match_operand:DI 0 "general_operand" "")
2316                    (match_operand:DI 1 "general_operand" ""))
2317               (clobber (scratch:PSI))])]
2318   ""
2319   "
2320 {
2321   if (GET_CODE (operands[0]) == MEM)
2322     operands[1] = force_reg (DImode, operands[1]);
2323 }")
2324
2325 (define_expand "movsf"
2326   [(set (match_operand:SF 0 "general_operand" "")
2327         (match_operand:SF 1 "general_operand" ""))]
2328   ""
2329   "
2330 { if (GET_CODE (operands[0]) == MEM)
2331     operands[1] = force_reg (SFmode, operands[1]);
2332 }")
2333
2334 (define_expand "movdf"
2335   [(parallel [(set (match_operand:DF 0 "general_operand" "")
2336                    (match_operand:DF 1 "general_operand" ""))
2337               (clobber (scratch:PSI))])]
2338   ""
2339   "
2340 { if (GET_CODE (operands[0]) == MEM)
2341     operands[1] = force_reg (DFmode, operands[1]);
2342 }")
2343
2344 (define_expand "movti"
2345   [(parallel [(set (match_operand:TI 0 "general_operand" "")
2346                    (match_operand:TI 1 "general_operand" ""))
2347               (clobber (scratch:PSI))])]
2348   ""
2349   "
2350 {
2351   if (GET_CODE (operands[0]) == MEM)
2352     operands[1] = force_reg (TImode, operands[1]);
2353
2354   /* We can't handle constants in general because there is no rtl to represent
2355      128 bit constants.  Splitting happens to work for CONST_INTs so we split
2356      them for good code.  Other constants will get forced to memory.  */
2357
2358   if (GET_CODE (operands[1]) == CONST_INT)
2359     {
2360      rtx part0, part1, part2, part3;
2361
2362      part0 = operand_subword (operands[0], 0, 1, TImode);
2363      part1 = operand_subword (operands[0], 1, 1, TImode);
2364      part2 = operand_subword (operands[0], 2, 1, TImode);
2365      part3 = operand_subword (operands[0], 3, 1, TImode);
2366
2367      emit_move_insn (part0, const0_rtx);
2368      emit_move_insn (part1, const0_rtx);
2369      emit_move_insn (part2, const0_rtx);
2370      emit_move_insn (part3, const0_rtx);
2371
2372      DONE;
2373     }
2374   else if (CONSTANT_P (operands[1]))
2375     {
2376       operands[1] = force_const_mem (TImode, operands[1]);
2377       if (! memory_address_p (TImode, XEXP (operands[1], 0))
2378           && ! reload_in_progress)
2379         operands[1] = adjust_address (operands[1], TImode, 0);
2380     }
2381 }")
2382 \f
2383 ;; Here are the variants of the above for use during reload.
2384
2385 (define_expand "reload_indf"
2386   [(parallel [(set (match_operand:DF 0 "register_operand" "=r")
2387                    (match_operand:DF 1 "reload_memory_operand" "m"))
2388               (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
2389   ""
2390   "")
2391
2392 (define_expand "reload_outdf"
2393   [(parallel [(set (match_operand:DF 0 "reload_memory_operand" "=m")
2394                    (match_operand:DF 1 "register_operand" "r"))
2395               (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
2396   ""
2397   "")
2398
2399 (define_expand "reload_indi"
2400   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
2401                    (match_operand:DI 1 "reload_memory_operand" "m"))
2402               (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
2403   ""
2404   "")
2405
2406 (define_expand "reload_outdi"
2407   [(parallel [(set (match_operand:DI 0 "reload_memory_operand" "=m")
2408                    (match_operand:DI 1 "register_operand" "r"))
2409               (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
2410   ""
2411   "")
2412
2413 (define_expand "reload_inti"
2414   [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
2415                    (match_operand:TI 1 "reload_memory_operand" "m"))
2416               (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
2417   ""
2418   "")
2419
2420 (define_expand "reload_outti"
2421   [(parallel [(set (match_operand:TI 0 "reload_memory_operand" "=m")
2422                    (match_operand:TI 1 "register_operand" "r"))
2423               (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
2424   ""
2425   "")
2426 \f
2427 ;; For compare operations, we simply store the comparison operands and
2428 ;; do nothing else.  The following branch or scc insn will output whatever
2429 ;; is needed.
2430 (define_expand "cmpsi"
2431   [(set (cc0)
2432         (compare (match_operand:SI 0 "gpc_reg_operand" "")
2433                  (match_operand:SI 1 "srcb_operand" "")))]
2434   ""
2435   "
2436 {
2437   a29k_compare_op0 = operands[0];
2438   a29k_compare_op1 = operands[1];
2439   a29k_compare_fp_p = 0;
2440   DONE;
2441 }")
2442
2443 (define_expand "cmpsf"
2444   [(set (cc0)
2445         (compare (match_operand:SF 0 "gpc_reg_operand" "")
2446                  (match_operand:SF 1 "gpc_reg_operand" "")))]
2447   "! TARGET_SOFT_FLOAT"
2448   "
2449 {
2450   a29k_compare_op0 = operands[0];
2451   a29k_compare_op1 = operands[1];
2452   a29k_compare_fp_p = 1;
2453   DONE;
2454 }")
2455
2456 (define_expand "cmpdf"
2457   [(set (cc0)
2458         (compare (match_operand:DF 0 "gpc_reg_operand" "")
2459                  (match_operand:DF 1 "gpc_reg_operand" "")))]
2460   "! TARGET_SOFT_FLOAT"
2461   "
2462 {
2463   a29k_compare_op0 = operands[0];
2464   a29k_compare_op1 = operands[1];
2465   a29k_compare_fp_p = 1;
2466   DONE;
2467 }")
2468
2469 ;; We can generate bit-tests better if we use NE instead of EQ, but we
2470 ;; don't have an NE for floating-point.  So we have to have two patterns
2471 ;; for EQ and two for NE.
2472
2473 (define_expand "beq"
2474   [(set (match_dup 1) (ne:SI (match_dup 2) (match_dup 3)))
2475    (set (pc)
2476         (if_then_else (ge (match_dup 1) (const_int 0))
2477                       (label_ref (match_operand 0 "" ""))
2478                       (pc)))]
2479   ""
2480   "
2481 {
2482   if (GET_MODE_CLASS (GET_MODE (a29k_compare_op0)) == MODE_FLOAT)
2483     {
2484       emit_insn (gen_beq_fp (operands[0]));
2485       DONE;
2486     }
2487
2488   operands[1] = gen_reg_rtx (SImode);
2489   operands[2] = a29k_compare_op0;
2490   operands[3] = a29k_compare_op1;
2491 }")
2492
2493 (define_expand "beq_fp"
2494   [(set (match_dup 1) (eq:SI (match_dup 2) (match_dup 3)))
2495    (set (pc)
2496         (if_then_else (lt (match_dup 1) (const_int 0))
2497                       (label_ref (match_operand 0 "" ""))
2498                       (pc)))]
2499   ""
2500   "
2501 {
2502   operands[1] = gen_reg_rtx (SImode);
2503   operands[2] = a29k_compare_op0;
2504   operands[3] = a29k_compare_op1;
2505 }")
2506
2507 (define_expand "bne"
2508   [(set (match_dup 1) (ne:SI (match_dup 2) (match_dup 3)))
2509    (set (pc)
2510         (if_then_else (lt (match_dup 1) (const_int 0))
2511                       (label_ref (match_operand 0 "" ""))
2512                       (pc)))]
2513   ""
2514   "
2515 {
2516   if (GET_MODE_CLASS (GET_MODE (a29k_compare_op0)) == MODE_FLOAT)
2517     {
2518       emit_insn (gen_bne_fp (operands[0]));
2519       DONE;
2520     }
2521
2522   operands[1] = gen_reg_rtx (SImode);
2523   operands[2] = a29k_compare_op0;
2524   operands[3] = a29k_compare_op1;
2525 }")
2526
2527 (define_expand "bne_fp"
2528   [(set (match_dup 1) (eq:SI (match_dup 2) (match_dup 3)))
2529    (set (pc)
2530         (if_then_else (ge (match_dup 1) (const_int 0))
2531                       (label_ref (match_operand 0 "" ""))
2532                       (pc)))]
2533   ""
2534   "
2535 {
2536   operands[1] = gen_reg_rtx (SImode);
2537   operands[2] = a29k_compare_op0;
2538   operands[3] = a29k_compare_op1;
2539 }")
2540
2541 ;; We don't have a floating-point "lt" insn, so we have to use "gt" in that
2542 ;; case with the operands swapped.  The operands must both be registers in
2543 ;; the floating-point case, so we know that swapping them is OK.
2544 (define_expand "blt"
2545   [(set (match_dup 1) (match_dup 2))
2546    (set (pc)
2547         (if_then_else (lt (match_dup 1) (const_int 0))
2548                       (label_ref (match_operand 0 "" ""))
2549                       (pc)))]
2550   ""
2551   "
2552 {
2553   operands[1] = gen_reg_rtx (SImode);
2554   if (a29k_compare_fp_p)
2555     operands[2] = gen_rtx_GT (SImode, a29k_compare_op1, a29k_compare_op0);
2556   else
2557     operands[2] = gen_rtx_LT (SImode, a29k_compare_op0, a29k_compare_op1);
2558 }")
2559
2560 ;; Similarly for "le".
2561 (define_expand "ble"
2562   [(set (match_dup 1) (match_dup 2))
2563    (set (pc)
2564         (if_then_else (lt (match_dup 1) (const_int 0))
2565                       (label_ref (match_operand 0 "" ""))
2566                       (pc)))]
2567   ""
2568   "
2569 {
2570   operands[1] = gen_reg_rtx (SImode);
2571   if (a29k_compare_fp_p)
2572     operands[2] = gen_rtx_GE (SImode, a29k_compare_op1, a29k_compare_op0);
2573   else
2574     operands[2] = gen_rtx_LE (SImode, a29k_compare_op0, a29k_compare_op1);
2575 }")
2576
2577 (define_expand "bltu"
2578   [(set (match_dup 1) (ltu:SI (match_dup 2) (match_dup 3)))
2579    (set (pc)
2580         (if_then_else (lt (match_dup 1) (const_int 0))
2581                       (label_ref (match_operand 0 "" ""))
2582                       (pc)))]
2583   ""
2584   "
2585 {
2586   operands[1] = gen_reg_rtx (SImode);
2587   operands[2] = a29k_compare_op0;
2588   operands[3] = a29k_compare_op1;
2589 }")
2590
2591 (define_expand "bleu"
2592   [(set (match_dup 1) (leu:SI (match_dup 2) (match_dup 3)))
2593    (set (pc)
2594         (if_then_else (lt (match_dup 1) (const_int 0))
2595                       (label_ref (match_operand 0 "" ""))
2596                       (pc)))]
2597   ""
2598   "
2599 {
2600   operands[1] = gen_reg_rtx (SImode);
2601   operands[2] = a29k_compare_op0;
2602   operands[3] = a29k_compare_op1;
2603 }")
2604
2605 (define_expand "bgt"
2606   [(set (match_dup 1) (gt:SI (match_dup 2) (match_dup 3)))
2607    (set (pc)
2608         (if_then_else (lt (match_dup 1) (const_int 0))
2609                       (label_ref (match_operand 0 "" ""))
2610                       (pc)))]
2611   ""
2612   "
2613 {
2614   operands[1] = gen_reg_rtx (SImode);
2615   operands[2] = a29k_compare_op0;
2616   operands[3] = a29k_compare_op1;
2617 }")
2618
2619 (define_expand "bge"
2620   [(set (match_dup 1) (ge:SI (match_dup 2) (match_dup 3)))
2621    (set (pc)
2622         (if_then_else (lt (match_dup 1) (const_int 0))
2623                       (label_ref (match_operand 0 "" ""))
2624                       (pc)))]
2625   ""
2626   "
2627 {
2628   operands[1] = gen_reg_rtx (SImode);
2629   operands[2] = a29k_compare_op0;
2630   operands[3] = a29k_compare_op1;
2631 }")
2632
2633 (define_expand "bgtu"
2634   [(set (match_dup 1) (gtu:SI (match_dup 2) (match_dup 3)))
2635    (set (pc)
2636         (if_then_else (lt (match_dup 1) (const_int 0))
2637                       (label_ref (match_operand 0 "" ""))
2638                       (pc)))]
2639   ""
2640   "
2641 {
2642   operands[1] = gen_reg_rtx (SImode);
2643   operands[2] = a29k_compare_op0;
2644   operands[3] = a29k_compare_op1;
2645 }")
2646
2647 (define_expand "bgeu"
2648   [(set (match_dup 1) (geu:SI (match_dup 2) (match_dup 3)))
2649    (set (pc)
2650         (if_then_else (lt (match_dup 1) (const_int 0))
2651                       (label_ref (match_operand 0 "" ""))
2652                       (pc)))]
2653   ""
2654   "
2655 {
2656   operands[1] = gen_reg_rtx (SImode);
2657   operands[2] = a29k_compare_op0;
2658   operands[3] = a29k_compare_op1;
2659 }")
2660 \f
2661 (define_expand "seq"
2662   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2663         (eq:SI (match_dup 1) (match_dup 2)))]
2664   ""
2665   "
2666 {
2667   operands[1] = a29k_compare_op0;
2668   operands[2] = a29k_compare_op1;
2669 }")
2670                  
2671 ;; This is the most complicated case, because we don't have a floating-point
2672 ;; "ne" insn.  If integer, handle normally.  If floating-point, write the
2673 ;; compare and then write an insn to reverse the test.
2674 (define_expand "sne_fp"
2675   [(set (match_dup 3)
2676         (eq:SI (match_operand 1 "gpc_reg_operand" "")
2677                (match_operand 2 "gpc_reg_operand" "")))
2678    (set (match_operand:SI 0 "gpc_reg_operand" "")
2679         (ge:SI (match_dup 3) (const_int 0)))]
2680   "! TARGET_SOFT_FLOAT"
2681   "
2682 { operands[3] = gen_reg_rtx (SImode);
2683 }");
2684
2685 (define_expand "sne"
2686   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2687         (ne:SI (match_dup 1) (match_dup 2)))]
2688   ""
2689   "
2690 {
2691   operands[1] = a29k_compare_op0;
2692   operands[2] = a29k_compare_op1;
2693
2694   if (a29k_compare_fp_p)
2695     {
2696       emit_insn (gen_sne_fp (operands[0], operands[1], operands[2]));
2697       DONE;
2698     }
2699 }")
2700                  
2701 ;; We don't have a floating-point "lt" insn, so use "gt" and swap the
2702 ;; operands, the same as we do "blt".
2703 (define_expand "slt"
2704   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2705         (match_dup 1))]
2706   ""
2707   "
2708 {
2709   if (a29k_compare_fp_p)
2710     operands[1] = gen_rtx_GT (SImode, a29k_compare_op1, a29k_compare_op0);
2711   else
2712     operands[1] = gen_rtx_LT (SImode, a29k_compare_op0, a29k_compare_op1);
2713 }")
2714
2715 ;; Similarly for "le"
2716 (define_expand "sle"
2717   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2718         (match_dup 1))]
2719   ""
2720   "
2721 {
2722   if (a29k_compare_fp_p)
2723     operands[1] = gen_rtx_GE (SImode, a29k_compare_op1, a29k_compare_op0);
2724   else
2725     operands[1] = gen_rtx_LE (SImode, a29k_compare_op0, a29k_compare_op1);
2726 }")
2727
2728 (define_expand "sltu"
2729   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2730         (ltu:SI (match_dup 1) (match_dup 2)))]
2731   ""
2732   "
2733 {
2734   operands[1] = a29k_compare_op0;
2735   operands[2] = a29k_compare_op1;
2736 }")
2737
2738 (define_expand "sleu"
2739   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2740         (leu:SI (match_dup 1) (match_dup 2)))]
2741   ""
2742   "
2743 {
2744   operands[1] = a29k_compare_op0;
2745   operands[2] = a29k_compare_op1;
2746 }")
2747
2748 (define_expand "sgt"
2749   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2750         (gt:SI (match_dup 1) (match_dup 2)))]
2751   ""
2752   "
2753 {
2754   operands[1] = a29k_compare_op0;
2755   operands[2] = a29k_compare_op1;
2756 }")
2757
2758 (define_expand "sge"
2759   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2760         (ge:SI (match_dup 1) (match_dup 2)))]
2761   ""
2762   "
2763 {
2764   operands[1] = a29k_compare_op0;
2765   operands[2] = a29k_compare_op1;
2766 }")
2767                  
2768 (define_expand "sgtu"
2769   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2770         (gtu:SI (match_dup 1) (match_dup 2)))]
2771   ""
2772   "
2773 {
2774   operands[1] = a29k_compare_op0;
2775   operands[2] = a29k_compare_op1;
2776 }")
2777
2778 (define_expand "sgeu"
2779   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2780         (geu:SI (match_dup 1) (match_dup 2)))]
2781   ""
2782   "
2783 {
2784   operands[1] = a29k_compare_op0;
2785   operands[2] = a29k_compare_op1;
2786 }")
2787 \f
2788 ;; Now define the actual jump insns.
2789 (define_insn ""
2790   [(set (pc)
2791         (if_then_else (match_operator 0 "branch_operator"
2792                                       [(match_operand:SI 1 "gpc_reg_operand" "r")
2793                                        (const_int 0)])
2794                       (label_ref (match_operand 2 "" ""))
2795                       (pc)))]
2796   ""
2797   "jmp%b0 %1,%l2%#"
2798   [(set_attr "type" "branch")])
2799
2800 (define_insn ""
2801   [(set (pc)
2802         (if_then_else (match_operator 0 "branch_operator"
2803                                       [(match_operand:SI 1 "gpc_reg_operand" "r")
2804                                        (const_int 0)])
2805                       (return)
2806                       (pc)))]
2807   "null_epilogue ()"
2808   "jmp%b0i %1,lr0%#"
2809   [(set_attr "type" "branch")])
2810
2811 (define_insn ""
2812   [(set (pc)
2813         (if_then_else (match_operator 0 "branch_operator"
2814                                       [(match_operand:SI 1 "gpc_reg_operand" "r")
2815                                        (const_int 0)])
2816                       (pc)
2817                       (label_ref (match_operand 2 "" ""))))]
2818   ""
2819   "jmp%B0 %1,%l2%#"
2820   [(set_attr "type" "branch")])
2821
2822 (define_insn ""
2823   [(set (pc)
2824         (if_then_else (match_operator 0 "branch_operator"
2825                                       [(match_operand:SI 1 "gpc_reg_operand" "r")
2826                                        (const_int 0)])
2827                       (pc)
2828                       (return)))]
2829   "null_epilogue ()"
2830   "jmp%B0i %1,lr0%#"
2831   [(set_attr "type" "branch")])
2832
2833 (define_insn "jump"
2834   [(set (pc)
2835         (label_ref (match_operand 0 "" "")))]
2836   ""
2837   "jmp %e0%E0"
2838   [(set_attr "type" "branch")])
2839
2840 (define_insn "return"
2841   [(return)]
2842   "null_epilogue ()"
2843   "jmpi lr0%#"
2844   [(set_attr "type" "branch")])
2845
2846 (define_insn "indirect_jump"
2847   [(set (pc)
2848         (match_operand:SI 0 "gpc_reg_operand" "r"))]
2849   ""
2850   "jmpi %0%#"
2851   [(set_attr "type" "branch")])
2852
2853 (define_insn "tablejump"
2854   [(set (pc)
2855         (match_operand:SI 0 "gpc_reg_operand" "r"))
2856    (use (label_ref (match_operand 1 "" "")))]
2857   ""
2858   "jmpi %0%#"
2859   [(set_attr "type" "branch")])
2860
2861 ;; JMPFDEC
2862 (define_insn ""
2863   [(set (pc)
2864         (if_then_else (ge (match_operand:SI 0 "gpc_reg_operand" "+r")
2865                           (const_int 0))
2866                       (label_ref (match_operand 1 "" ""))
2867                       (pc)))
2868    (set (match_dup 0)
2869         (plus:SI (match_dup 0)
2870                  (const_int -1)))]
2871   ""
2872   "jmpfdec %0,%l1%#"
2873   [(set_attr "type" "branch")])