OSDN Git Service

* ipa-pure-const.c, ipa-reference.c, ipa-reference.h,
[pf3gnuchains/gcc-fork.git] / gcc / config / crx / crx.md
1 ;; GCC machine description for CRX.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC 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 ;; GCC 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 GCC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 ;; Boston, MA 02110-1301, USA.  */
22
23 ;;  Register numbers
24
25 (define_constants
26   [(SP_REGNUM 15)       ; Stack pointer
27    (RA_REGNUM 14)       ; Return address
28    (LO_REGNUM 16)       ; LO register
29    (HI_REGNUM 17)       ; HI register
30    (CC_REGNUM 18)       ; Condition code register
31   ]
32 )
33
34 (define_attr "length" "" ( const_int 6 ) )
35
36 (define_asm_attributes
37   [(set_attr "length" "6")]
38 )
39
40 ;;  Predicates
41
42 (define_predicate "u4bits_operand"
43   (match_code "const_int,const_double")
44   {
45     if (GET_CODE (op) == CONST_DOUBLE)
46       return crx_const_double_ok (op);
47     return (UNSIGNED_INT_FITS_N_BITS(INTVAL(op), 4)) ? 1 : 0;
48   }
49 )
50
51 (define_predicate "cst4_operand"
52   (and (match_code "const_int")
53        (match_test "INT_CST4(INTVAL(op))")))
54
55 (define_predicate "reg_or_u4bits_operand"
56   (ior (match_operand 0 "u4bits_operand")
57        (match_operand 0 "register_operand")))
58
59 (define_predicate "reg_or_cst4_operand"
60   (ior (match_operand 0 "cst4_operand")
61        (match_operand 0 "register_operand")))
62
63 (define_predicate "reg_or_sym_operand"
64   (ior (match_code "symbol_ref")
65        (match_operand 0 "register_operand")))
66
67 (define_predicate "nosp_reg_operand"
68   (and (match_operand 0 "register_operand")
69        (match_test "REGNO (op) != SP_REGNUM")))
70
71 (define_predicate "store_operand"
72   (and (match_operand 0 "memory_operand")
73        (not (match_operand 0 "push_operand"))))
74
75 ;;  Mode Macro Definitions
76
77 (define_mode_macro ALLMT [QI HI SI SF DI DF])
78 (define_mode_macro CRXMM [QI HI SI SF])
79 (define_mode_macro CRXIM [QI HI SI])
80 (define_mode_macro DIDFM [DI DF])
81 (define_mode_macro SISFM [SI SF])
82 (define_mode_macro SHORT [QI HI])
83
84 (define_mode_attr tIsa [(QI "b") (HI "w") (SI "d") (SF "d")])
85 (define_mode_attr lImmArith [(QI "4") (HI "4") (SI "6")])
86 (define_mode_attr lImmRotl [(QI "2") (HI "2") (SI "4")])
87 (define_mode_attr IJK [(QI "I") (HI "J") (SI "K")])
88 (define_mode_attr iF [(QI "i") (HI "i") (SI "i") (DI "i") (SF "F") (DF "F")])
89 (define_mode_attr JG [(QI "J") (HI "J") (SI "J") (DI "J") (SF "G") (DF "G")])
90 ;   In HI or QI mode we push 4 bytes.
91 (define_mode_attr pushCnstr [(QI "X") (HI "X") (SI "<") (SF "<") (DI "<") (DF "<")])
92 (define_mode_attr tpush [(QI "") (HI "") (SI "") (SF "") (DI "sp, ") (DF "sp, ")])
93 (define_mode_attr lpush [(QI "2") (HI "2") (SI "2") (SF "2") (DI "4") (DF "4")])
94
95
96 ;;  Code Macro Definitions
97
98 (define_code_macro sz_xtnd [sign_extend zero_extend])
99 (define_code_attr sIsa [(sign_extend "") (zero_extend "u")])
100 (define_code_attr sPat [(sign_extend "s") (zero_extend "u")])
101 (define_code_attr szPat [(sign_extend "") (zero_extend "zero_")])
102 (define_code_attr szIsa [(sign_extend "s") (zero_extend "z")])
103
104 (define_code_macro sh_oprnd [ashift ashiftrt lshiftrt])
105 (define_code_attr shIsa [(ashift "ll") (ashiftrt "ra") (lshiftrt "rl")])
106 (define_code_attr shPat [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr")])
107
108 (define_code_macro mima_oprnd [smax umax smin umin])
109 (define_code_attr mimaIsa [(smax "maxs") (umax "maxu") (smin "mins") (umin "minu")])
110
111 (define_code_macro any_cond [eq ne gt gtu lt ltu ge geu le leu])
112
113 ;;  Addition Instructions
114
115 (define_insn "adddi3"
116   [(set (match_operand:DI 0 "register_operand" "=r,r")
117         (plus:DI (match_operand:DI 1 "register_operand" "%0,0")
118                  (match_operand:DI 2 "nonmemory_operand" "r,i")))
119    (clobber (reg:CC CC_REGNUM))]
120   ""
121   "addd\\t%L2, %L1\;addcd\\t%H2, %H1"
122   [(set_attr "length" "4,12")]
123 )
124
125 (define_insn "add<mode>3"
126   [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
127         (plus:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0")
128                     (match_operand:CRXIM 2 "nonmemory_operand" "r,i")))
129    (clobber (reg:CC CC_REGNUM))]
130   ""
131   "add<tIsa>\\t%2, %0"
132   [(set_attr "length" "2,<lImmArith>")]
133 )
134
135 ;;  Subtract Instructions
136
137 (define_insn "subdi3"
138   [(set (match_operand:DI 0 "register_operand" "=r,r")
139         (minus:DI (match_operand:DI 1 "register_operand" "0,0")
140                   (match_operand:DI 2 "nonmemory_operand" "r,i")))
141    (clobber (reg:CC CC_REGNUM))]
142   ""
143   "subd\\t%L2, %L1\;subcd\\t%H2, %H1"
144   [(set_attr "length" "4,12")]
145 )
146
147 (define_insn "sub<mode>3"
148   [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
149         (minus:CRXIM (match_operand:CRXIM 1 "register_operand" "0,0")
150                      (match_operand:CRXIM 2 "nonmemory_operand" "r,i")))
151    (clobber (reg:CC CC_REGNUM))]
152   ""
153   "sub<tIsa>\\t%2, %0"
154   [(set_attr "length" "2,<lImmArith>")]
155 )
156
157 ;;  Multiply Instructions
158
159 (define_insn "mul<mode>3"
160   [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
161         (mult:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0")
162                     (match_operand:CRXIM 2 "nonmemory_operand" "r,i")))
163    (clobber (reg:CC CC_REGNUM))]
164   ""
165   "mul<tIsa>\\t%2, %0"
166   [(set_attr "length" "2,<lImmArith>")]
167 )
168
169 ;;  Widening-multiplication Instructions
170
171 (define_insn "<sIsa>mulsidi3"
172   [(set (match_operand:DI 0 "register_operand" "=k")
173         (mult:DI (sz_xtnd:DI (match_operand:SI 1 "register_operand" "%r"))
174                  (sz_xtnd:DI (match_operand:SI 2 "register_operand" "r"))))
175    (clobber (reg:CC CC_REGNUM))]
176   ""
177   "mull<sPat>d\\t%2, %1"
178   [(set_attr "length" "4")]
179 )
180
181 (define_insn "<sIsa>mulhisi3"
182   [(set (match_operand:SI 0 "register_operand" "=r")
183         (mult:SI (sz_xtnd:SI (match_operand:HI 1 "register_operand" "%0"))
184                  (sz_xtnd:SI (match_operand:HI 2 "register_operand" "r"))))
185    (clobber (reg:CC CC_REGNUM))]
186   ""
187   "mul<sPat>wd\\t%2, %0"
188   [(set_attr "length" "4")]
189 )
190
191 (define_insn "<sIsa>mulqihi3"
192   [(set (match_operand:HI 0 "register_operand" "=r")
193         (mult:HI (sz_xtnd:HI (match_operand:QI 1 "register_operand" "%0"))
194                  (sz_xtnd:HI (match_operand:QI 2 "register_operand" "r"))))
195    (clobber (reg:CC CC_REGNUM))]
196   ""
197   "mul<sPat>bw\\t%2, %0"
198   [(set_attr "length" "4")]
199 )
200
201 ;;  Logical Instructions - and
202
203 (define_insn "and<mode>3"
204   [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
205         (and:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0")
206                    (match_operand:CRXIM 2 "nonmemory_operand" "r,i")))
207    (clobber (reg:CC CC_REGNUM))]
208   ""
209   "and<tIsa>\\t%2, %0"
210   [(set_attr "length" "2,<lImmArith>")]
211 )
212
213 ;;  Logical Instructions - or
214
215 (define_insn "ior<mode>3"
216   [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
217         (ior:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0")
218                    (match_operand:CRXIM 2 "nonmemory_operand" "r,i")))
219    (clobber (reg:CC CC_REGNUM))]
220   ""
221   "or<tIsa>\\t%2, %0"
222   [(set_attr "length" "2,<lImmArith>")]
223 )
224
225 ;;  Logical Instructions - xor
226
227 (define_insn "xor<mode>3"
228   [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
229         (xor:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0")
230                    (match_operand:CRXIM 2 "nonmemory_operand" "r,i")))
231    (clobber (reg:CC CC_REGNUM))]
232   ""
233   "xor<tIsa>\\t%2, %0"
234   [(set_attr "length" "2,<lImmArith>")]
235 )
236
237 ;;  Sign and Zero Extend Instructions
238
239 (define_insn "<szPat>extendhisi2"
240   [(set (match_operand:SI 0 "register_operand" "=r")
241         (sz_xtnd:SI (match_operand:HI 1 "register_operand" "r")))
242    (clobber (reg:CC CC_REGNUM))]
243   ""
244   "<szIsa>extwd\\t%1, %0"
245   [(set_attr "length" "4")]
246 )
247
248 (define_insn "<szPat>extendqisi2"
249   [(set (match_operand:SI 0 "register_operand" "=r")
250         (sz_xtnd:SI (match_operand:QI 1 "register_operand" "r")))
251    (clobber (reg:CC CC_REGNUM))]
252   ""
253   "<szIsa>extbd\\t%1, %0"
254   [(set_attr "length" "4")]
255 )
256
257 (define_insn "<szPat>extendqihi2"
258   [(set (match_operand:HI 0 "register_operand" "=r")
259         (sz_xtnd:HI (match_operand:QI 1 "register_operand" "r")))
260    (clobber (reg:CC CC_REGNUM))]
261   ""
262   "<szIsa>extbw\\t%1, %0"
263   [(set_attr "length" "4")]
264 )
265
266 ;;  Negation Instructions
267
268 (define_insn "neg<mode>2"
269   [(set (match_operand:CRXIM 0 "register_operand" "=r")
270         (neg:CRXIM (match_operand:CRXIM 1 "register_operand" "r")))
271    (clobber (reg:CC CC_REGNUM))]
272   ""
273   "neg<tIsa>\\t%1, %0"
274   [(set_attr "length" "4")]
275 )
276
277 ;;  Absolute Instructions
278
279 (define_insn "abs<mode>2"
280   [(set (match_operand:CRXIM 0 "register_operand" "=r")
281         (abs:CRXIM (match_operand:CRXIM 1 "register_operand" "r")))
282    (clobber (reg:CC CC_REGNUM))]
283   ""
284   "abs<tIsa>\\t%1, %0"
285   [(set_attr "length" "4")]
286 )
287
288 ;;  Max and Min Instructions
289
290 (define_insn "<code><mode>3"
291   [(set (match_operand:CRXIM 0 "register_operand" "=r")
292         (mima_oprnd:CRXIM (match_operand:CRXIM 1 "register_operand"  "%0")
293                           (match_operand:CRXIM 2 "register_operand"  "r")))]
294   ""
295   "<mimaIsa><tIsa>\\t%2, %0"
296   [(set_attr "length" "4")]
297 )
298
299 ;;  One's Complement
300
301 (define_insn "one_cmpl<mode>2"
302   [(set (match_operand:CRXIM 0 "register_operand" "=r")
303         (not:CRXIM (match_operand:CRXIM 1 "register_operand" "0")))
304    (clobber (reg:CC CC_REGNUM))]
305   ""
306   "xor<tIsa>\\t$-1, %0"
307   [(set_attr "length" "2")]
308 )
309
310 ;;  Rotate Instructions
311
312 (define_insn "rotl<mode>3"
313   [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
314         (rotate:CRXIM (match_operand:CRXIM 1 "register_operand" "0,0")
315                       (match_operand:CRXIM 2 "nonmemory_operand" "r,<IJK>")))
316    (clobber (reg:CC CC_REGNUM))]
317   ""
318   "@
319   rotl<tIsa>\\t%2, %0
320   rot<tIsa>\\t%2, %0"
321   [(set_attr "length" "4,<lImmRotl>")]
322 )
323
324 (define_insn "rotr<mode>3"
325   [(set (match_operand:CRXIM 0 "register_operand" "=r")
326         (rotatert:CRXIM (match_operand:CRXIM 1 "register_operand" "0")
327                         (match_operand:CRXIM 2 "register_operand" "r")))
328    (clobber (reg:CC CC_REGNUM))]
329   ""
330   "rotr<tIsa>\\t%2, %0"
331   [(set_attr "length" "4")]
332 )
333
334 ;;  Arithmetic Left and Right Shift Instructions
335
336 (define_insn "<shPat><mode>3"
337   [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
338         (sh_oprnd:CRXIM (match_operand:CRXIM 1 "register_operand" "0,0")
339                         (match_operand:QI 2 "nonmemory_operand" "r,<IJK>")))
340    (clobber (reg:CC CC_REGNUM))]
341   ""
342   "s<shIsa><tIsa>\\t%2, %0"
343   [(set_attr "length" "2,2")]
344 )
345
346 ;;  Bit Set Instructions
347
348 (define_insn "extv"
349   [(set (match_operand:SI 0 "register_operand" "=r")
350         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
351                          (match_operand:SI 2 "const_int_operand" "n")
352                          (match_operand:SI 3 "const_int_operand" "n")))]
353   ""
354   {
355     static char buf[100];
356     int strpntr;
357     int size = INTVAL (operands[2]);
358     int pos = INTVAL (operands[3]);
359     strpntr = sprintf (buf, "ram\t$%d, $31, $%d, %%1, %%0\;",
360               BITS_PER_WORD - (size + pos), BITS_PER_WORD - size);
361     sprintf (buf + strpntr, "srad\t$%d, %%0", BITS_PER_WORD - size);
362     return buf;
363   }
364   [(set_attr "length" "6")]
365 )
366
367 (define_insn "extzv"
368   [(set (match_operand:SI 0 "register_operand" "=r")
369         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
370                          (match_operand:SI 2 "const_int_operand" "n")
371                          (match_operand:SI 3 "const_int_operand" "n")))]
372   ""
373   {
374     static char buf[40];
375     int size = INTVAL (operands[2]);
376     int pos = INTVAL (operands[3]);
377     sprintf (buf, "ram\t$%d, $%d, $0, %%1, %%0",
378            (BITS_PER_WORD - pos) % BITS_PER_WORD, size - 1);
379     return buf;
380   }
381   [(set_attr "length" "4")]
382 )
383
384 (define_insn "insv"
385   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
386                          (match_operand:SI 1 "const_int_operand" "n")
387                          (match_operand:SI 2 "const_int_operand" "n"))
388         (match_operand:SI 3 "register_operand" "r"))]
389   ""
390   {
391     static char buf[40];
392     int size = INTVAL (operands[1]);
393     int pos = INTVAL (operands[2]);
394     sprintf (buf, "rim\t$%d, $%d, $%d, %%3, %%0",
395             pos, size + pos - 1, pos);
396     return buf;
397   }
398   [(set_attr "length" "4")]
399 )
400
401 ;;  Move Instructions
402
403 (define_expand "mov<mode>"
404   [(set (match_operand:ALLMT 0 "nonimmediate_operand" "")
405         (match_operand:ALLMT 1 "general_operand" ""))]
406   ""
407   {
408     if (!(reload_in_progress || reload_completed))
409       {
410         if (!register_operand (operands[0], <MODE>mode))
411           {
412             if (push_operand (operands[0], <MODE>mode) ?
413                 !nosp_reg_operand (operands[1], <MODE>mode) :
414                 !reg_or_u4bits_operand (operands[1], <MODE>mode))
415               {
416                 operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]);
417               }
418           }
419       }
420   }
421 )
422
423 (define_insn "push<mode>_internal"
424   [(set (match_operand:ALLMT 0 "push_operand" "=<pushCnstr>")
425         (match_operand:ALLMT 1 "nosp_reg_operand" "b"))]
426   ""
427   "push\t<tpush>%p1"
428   [(set_attr "length" "<lpush>")]
429 )
430
431 (define_insn "mov<mode>_regs"
432   [(set (match_operand:SISFM 0 "register_operand" "=r, r, r, k")
433         (match_operand:SISFM 1 "nonmemory_operand" "r, <iF>, k, r"))]
434   ""
435   "@
436   movd\\t%1, %0
437   movd\\t%1, %0
438   mfpr\\t%1, %0
439   mtpr\\t%1, %0"
440   [(set_attr "length" "2,6,4,4")]
441 )
442
443 (define_insn "mov<mode>_regs"
444   [(set (match_operand:DIDFM 0 "register_operand" "=r, r, r, k")
445         (match_operand:DIDFM 1 "nonmemory_operand" "r, <iF>, k, r"))]
446   ""
447   {
448     switch (which_alternative)
449       {
450       case 0: if (REGNO (operands[0]) > REGNO (operands[1]))
451                 return "movd\t%H1, %H0\;movd\t%L1, %L0";
452               else
453                 return "movd\t%L1, %L0\;movd\t%H1, %H0";
454       case 1: return "movd\t%H1, %H0\;movd\t%L1, %L0";
455       case 2: return "mfpr\t%H1, %H0\;mfpr\t%L1, %L0";
456       case 3: return "mtpr\t%H1, %H0\;mtpr\t%L1, %L0";
457       default: gcc_unreachable ();
458       }
459   }
460   [(set_attr "length" "4,12,8,8")]
461 )
462
463 (define_insn "mov<mode>_regs" ; no HI/QI mode in HILO regs
464   [(set (match_operand:SHORT 0 "register_operand" "=r, r")
465         (match_operand:SHORT 1 "nonmemory_operand" "r, i"))]
466   ""
467   "mov<tIsa>\\t%1, %0"
468   [(set_attr "length" "2,<lImmArith>")]
469 )
470
471 (define_insn "mov<mode>_load"
472   [(set (match_operand:CRXMM 0 "register_operand" "=r")
473         (match_operand:CRXMM 1 "memory_operand" "m"))]
474   ""
475   "load<tIsa>\\t%1, %0"
476   [(set_attr "length" "6")]
477 )
478
479 (define_insn "mov<mode>_load"
480   [(set (match_operand:DIDFM 0 "register_operand" "=r")
481         (match_operand:DIDFM 1 "memory_operand" "m"))]
482   ""
483   {
484     rtx first_dest_reg = gen_rtx_REG (SImode, REGNO (operands[0]));
485     if (reg_overlap_mentioned_p (first_dest_reg, operands[1]))
486       return "loadd\t%H1, %H0\;loadd\t%L1, %L0";
487     return "loadd\t%L1, %L0\;loadd\t%H1, %H0";
488   }
489   [(set_attr "length" "12")]
490 )
491
492 (define_insn "mov<mode>_store"
493   [(set (match_operand:CRXMM 0 "store_operand" "=m, m")
494         (match_operand:CRXMM 1 "reg_or_u4bits_operand" "r, <JG>"))]
495   ""
496   "stor<tIsa>\\t%1, %0"
497   [(set_attr "length" "6")]
498 )
499
500 (define_insn "mov<mode>_store"
501   [(set (match_operand:DIDFM 0 "store_operand" "=m, m")
502         (match_operand:DIDFM 1 "reg_or_u4bits_operand" "r, <JG>"))]
503   ""
504   "stord\t%H1, %H0\;stord\t%L1, %L0"
505   [(set_attr "length" "12")]
506 )
507
508 ;;  Movmem Instruction
509
510 (define_expand "movmemsi"
511   [(use (match_operand:BLK 0 "memory_operand" ""))
512    (use (match_operand:BLK 1 "memory_operand" ""))
513    (use (match_operand:SI 2 "nonmemory_operand" ""))
514    (use (match_operand:SI 3 "const_int_operand" ""))]
515   ""
516   {
517     if (crx_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
518       DONE;
519     else
520       FAIL;
521   }
522 )
523
524 ;;  Compare and Branch Instructions
525
526 (define_insn "cbranch<mode>4"
527   [(set (pc)
528         (if_then_else (match_operator 0 "comparison_operator"
529                         [(match_operand:CRXIM 1 "register_operand" "r")
530                          (match_operand:CRXIM 2 "reg_or_cst4_operand" "rL")])
531                       (label_ref (match_operand 3 "" ""))
532                       (pc)))]
533   ""
534   "cmpb%d0<tIsa>\\t%2, %1, %l3"
535   [(set_attr "length" "6")]
536 )
537
538 ;;  Compare Instructions
539
540 (define_expand "cmp<mode>"
541   [(set (reg:CC CC_REGNUM)
542         (compare:CC (match_operand:CRXIM 0 "register_operand" "")
543                     (match_operand:CRXIM 1 "nonmemory_operand" "")))]
544   ""
545   {
546     crx_compare_op0 = operands[0];
547     crx_compare_op1 = operands[1];
548     DONE;
549   }
550 )
551
552 (define_insn "cmp<mode>_internal"
553   [(set (reg:CC CC_REGNUM)
554         (compare:CC (match_operand:CRXIM 0 "register_operand" "r,r")
555                     (match_operand:CRXIM 1 "nonmemory_operand" "r,i")))]
556   ""
557   "cmp<tIsa>\\t%1, %0"
558   [(set_attr "length" "2,<lImmArith>")]
559 )
560
561 ;;  Conditional Branch Instructions
562
563 (define_expand "b<code>"
564   [(set (pc)
565         (if_then_else (any_cond (reg:CC CC_REGNUM)
566                                 (const_int 0))
567                       (label_ref (match_operand 0 ""))
568                       (pc)))]
569   ""
570   {
571     crx_expand_branch (<CODE>, operands[0]);
572     DONE;
573   }
574 )
575
576 (define_insn "bCOND_internal"
577   [(set (pc)
578         (if_then_else (match_operator 0 "comparison_operator"
579                         [(reg:CC CC_REGNUM)
580                          (const_int 0)])
581                       (label_ref (match_operand 1 ""))
582                       (pc)))]
583   ""
584   "b%d0\\t%l1"
585   [(set_attr "length" "6")]
586 )
587
588 ;;  Scond Instructions
589
590 (define_expand "s<code>"
591   [(set (match_operand:SI 0 "register_operand")
592         (any_cond:SI (reg:CC CC_REGNUM) (const_int 0)))]
593   ""
594   {
595     crx_expand_scond (<CODE>, operands[0]);
596     DONE;
597   }
598 )
599
600 (define_insn "sCOND_internal"
601   [(set (match_operand:SI 0 "register_operand" "=r")
602         (match_operator:SI 1 "comparison_operator"
603           [(reg:CC CC_REGNUM) (const_int 0)]))]
604   ""
605   "s%d1\\t%0"
606   [(set_attr "length" "2")]
607 )
608
609 ;;  Jumps and Branches
610
611 (define_insn "indirect_jump_return"
612   [(parallel
613     [(set (pc)
614           (reg:SI RA_REGNUM))
615      (return)])
616   ]
617   "reload_completed"
618   "jump\\tra"
619   [(set_attr "length" "2")]
620 )
621
622 (define_insn "indirect_jump"
623   [(set (pc)
624         (match_operand:SI 0 "reg_or_sym_operand" "r,i"))]
625   ""
626   "@
627   jump\\t%0
628   br\\t%a0"
629   [(set_attr "length" "2,6")]
630 )
631
632 (define_insn "interrupt_return"
633   [(parallel
634     [(unspec_volatile [(const_int 0)] 0)
635      (return)])]
636   ""
637   {
638     return crx_prepare_push_pop_string (1);
639   }
640   [(set_attr "length" "14")]
641 )
642
643 (define_insn "jump_to_imm"
644   [(set (pc)
645         (match_operand 0 "immediate_operand" "i"))]
646   ""
647   "br\\t%c0"
648   [(set_attr "length" "6")]
649 )
650
651 (define_insn "jump"
652   [(set (pc)
653         (label_ref (match_operand 0 "" "")))]
654   ""
655   "br\\t%l0"
656   [(set_attr "length" "6")]
657 )
658
659 ;;  Function Prologue and Epilogue
660
661 (define_expand "prologue"
662   [(const_int 0)]
663   ""
664   {
665     crx_expand_prologue ();
666     DONE;
667   }
668 )
669
670 (define_insn "push_for_prologue"
671   [(parallel
672     [(set (reg:SI SP_REGNUM)
673           (minus:SI (reg:SI SP_REGNUM)
674                     (match_operand:SI 0 "immediate_operand" "i")))])]
675   "reload_completed"
676   {
677     return crx_prepare_push_pop_string (0);
678   }
679   [(set_attr "length" "4")]
680 )
681
682 (define_expand "epilogue"
683   [(return)]
684   ""
685   {
686     crx_expand_epilogue ();
687     DONE;
688   }
689 )
690
691 (define_insn "pop_and_popret_return"
692   [(parallel
693     [(set (reg:SI SP_REGNUM)
694           (plus:SI (reg:SI SP_REGNUM)
695                    (match_operand:SI 0 "immediate_operand" "i")))
696      (use (reg:SI RA_REGNUM))
697      (return)])
698   ]
699   "reload_completed"
700   {
701     return crx_prepare_push_pop_string (1);
702   }
703   [(set_attr "length" "4")]
704 )
705
706 (define_insn "popret_RA_return"
707   [(parallel
708     [(use (reg:SI RA_REGNUM))
709      (return)])
710   ]
711   "reload_completed"
712   "popret\\tra"
713   [(set_attr "length" "2")]
714 )
715
716 ;;  Table Jump
717
718 (define_insn "tablejump"
719   [(set (pc)
720         (match_operand:SI 0 "register_operand" "r"))
721         (use (label_ref:SI (match_operand 1 "" "" )))]
722   ""
723   "jump\\t%0"
724   [(set_attr "length" "2")]
725 )
726
727 ;;  Call Instructions
728
729 (define_expand "call"
730   [(call (match_operand:QI 0 "memory_operand" "")
731          (match_operand 1 "" ""))]
732   ""
733   {
734     emit_call_insn (gen_crx_call (operands[0], operands[1]));
735     DONE;
736   }
737 )
738
739 (define_expand "crx_call"
740   [(parallel
741     [(call (match_operand:QI 0 "memory_operand" "")
742            (match_operand 1 "" ""))
743      (clobber (reg:SI RA_REGNUM))])]
744   ""
745   ""
746 )
747
748 (define_insn "crx_call_insn_branch"
749   [(call (mem:QI (match_operand:SI 0 "immediate_operand" "i"))
750          (match_operand 1 "" ""))
751    (clobber (match_operand:SI 2 "register_operand" "+r"))]
752   ""
753   "bal\\tra, %a0"
754   [(set_attr "length" "6")]
755 )
756
757 (define_insn "crx_call_insn_jump"
758   [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
759          (match_operand 1 "" ""))
760    (clobber (match_operand:SI 2 "register_operand" "+r"))]
761   ""
762   "jal\\t%0"
763   [(set_attr "length" "2")]
764 )
765
766 (define_insn "crx_call_insn_jalid"
767   [(call (mem:QI (mem:SI (plus:SI
768                            (match_operand:SI 0 "register_operand" "r")
769                            (match_operand:SI 1 "register_operand" "r"))))
770          (match_operand 2 "" ""))
771    (clobber (match_operand:SI 3 "register_operand" "+r"))]
772   ""
773   "jalid\\t%0, %1"
774   [(set_attr "length" "4")]
775 )
776
777 ;;  Call Value Instructions
778
779 (define_expand "call_value"
780   [(set (match_operand 0 "general_operand" "")
781         (call (match_operand:QI 1 "memory_operand" "")
782               (match_operand 2 "" "")))]
783   ""
784   {
785     emit_call_insn (gen_crx_call_value (operands[0], operands[1], operands[2]));
786     DONE;
787   }
788 )
789
790 (define_expand "crx_call_value"
791   [(parallel
792     [(set (match_operand 0 "general_operand" "")
793           (call (match_operand 1 "memory_operand" "")
794                 (match_operand 2 "" "")))
795      (clobber (reg:SI RA_REGNUM))])]
796   ""
797   ""
798 )
799
800 (define_insn "crx_call_value_insn_branch"
801   [(set (match_operand 0 "" "=g")
802         (call (mem:QI (match_operand:SI 1 "immediate_operand" "i"))
803               (match_operand 2 "" "")))
804    (clobber (match_operand:SI 3 "register_operand" "+r"))]
805   ""
806   "bal\\tra, %a1"
807   [(set_attr "length" "6")]
808 )
809
810 (define_insn "crx_call_value_insn_jump"
811   [(set (match_operand 0 "" "=g")
812         (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
813               (match_operand 2 "" "")))
814    (clobber (match_operand:SI 3 "register_operand" "+r"))]
815   ""
816   "jal\\t%1"
817   [(set_attr "length" "2")]
818 )
819
820 (define_insn "crx_call_value_insn_jalid"
821   [(set (match_operand 0 "" "=g")
822         (call (mem:QI (mem:SI (plus:SI
823                                 (match_operand:SI 1 "register_operand" "r")
824                                 (match_operand:SI 2 "register_operand" "r"))))
825               (match_operand 3 "" "")))
826    (clobber (match_operand:SI 4 "register_operand" "+r"))]
827   ""
828   "jalid\\t%0, %1"
829   [(set_attr "length" "4")]
830 )
831
832 ;;  Nop
833
834 (define_insn "nop"
835   [(const_int 0)]
836   ""
837   ""
838 )
839
840 ;;  Multiply and Accumulate Instructions
841
842 (define_insn "<sPat>madsidi3"
843   [(set (match_operand:DI 0 "register_operand" "+k")
844         (plus:DI
845           (mult:DI (sz_xtnd:DI (match_operand:SI 1 "register_operand" "%r"))
846                    (sz_xtnd:DI (match_operand:SI 2 "register_operand" "r")))
847           (match_dup 0)))
848    (clobber (reg:CC CC_REGNUM))]
849   "TARGET_MAC"
850   "mac<sPat>d\\t%2, %1"
851   [(set_attr "length" "4")]
852 )
853
854 (define_insn "<sPat>madhisi3"
855   [(set (match_operand:SI 0 "register_operand" "+l")
856         (plus:SI
857           (mult:SI (sz_xtnd:SI (match_operand:HI 1 "register_operand" "%r"))
858                    (sz_xtnd:SI (match_operand:HI 2 "register_operand" "r")))
859           (match_dup 0)))
860    (clobber (reg:CC CC_REGNUM))]
861   "TARGET_MAC"
862   "mac<sPat>w\\t%2, %1"
863   [(set_attr "length" "4")]
864 )
865
866 (define_insn "<sPat>madqihi3"
867   [(set (match_operand:HI 0 "register_operand" "+l")
868         (plus:HI
869           (mult:HI (sz_xtnd:HI (match_operand:QI 1 "register_operand" "%r"))
870                    (sz_xtnd:HI (match_operand:QI 2 "register_operand" "r")))
871           (match_dup 0)))
872    (clobber (reg:CC CC_REGNUM))]
873   "TARGET_MAC"
874   "mac<sPat>b\\t%2, %1"
875   [(set_attr "length" "4")]
876 )
877
878 ;;  Loop Instructions
879
880 (define_expand "doloop_end"
881   [(use (match_operand 0 "" ""))        ; loop pseudo
882    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
883    (use (match_operand 2 "" ""))        ; max iterations
884    (use (match_operand 3 "" ""))        ; loop level
885    (use (match_operand 4 "" ""))]       ; label
886   ""
887   {
888     switch (GET_MODE (operands[0]))
889       {
890       case SImode:
891         emit_jump_insn (gen_doloop_end_si (operands[4], operands[0], operands[0]));
892         break;
893       case HImode:
894         emit_jump_insn (gen_doloop_end_hi (operands[4], operands[0], operands[0]));
895         break;
896       case QImode:
897         emit_jump_insn (gen_doloop_end_qi (operands[4], operands[0], operands[0]));
898         break;
899       default:
900         FAIL;
901       }
902     DONE;
903   }
904 )
905
906 (define_insn "doloop_end_<mode>"
907   [(set (pc)
908         (if_then_else (ne (match_operand:CRXIM 1 "register_operand" "r,m")
909                           (const_int 1))
910                       (label_ref (match_operand 0 "" ""))
911                       (pc)))
912    (set (match_operand:CRXIM 2 "register_operand" "=r,m") (plus:CRXIM (match_dup 1) (const_int -1)))
913    (clobber (match_scratch:CRXIM 3 "=X,r"))
914    (clobber (reg:CC CC_REGNUM))]
915   ""
916   "@
917   dbnz<tIsa>\\t%1, %l0
918   load<tIsa>\\t%1, %3\;add<tIsa>\\t$-1, %3\;stor<tIsa>\\t%3, %1\;bne\\t%l0"
919   [(set_attr "length" "6, 12")]
920 )