2006-03-15 Paul Brook <paul@codesourcery.com>
[official-gcc.git] / gcc / config / crx / crx.md
blob71acdd6680388a4a84a13ca0138659be51153363
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.
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.
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.  */
23 ;;  Register numbers
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   ]
34 (define_attr "length" "" ( const_int 6 ))
36 (define_asm_attributes
37   [(set_attr "length" "6")]
40 ;;  Predicates
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   }
51 (define_predicate "cst4_operand"
52   (and (match_code "const_int")
53        (match_test "INT_CST4(INTVAL(op))")))
55 (define_predicate "reg_or_u4bits_operand"
56   (ior (match_operand 0 "u4bits_operand")
57        (match_operand 0 "register_operand")))
59 (define_predicate "reg_or_cst4_operand"
60   (ior (match_operand 0 "cst4_operand")
61        (match_operand 0 "register_operand")))
63 (define_predicate "reg_or_sym_operand"
64   (ior (match_code "symbol_ref")
65        (match_operand 0 "register_operand")))
67 (define_predicate "nosp_reg_operand"
68   (and (match_operand 0 "register_operand")
69        (match_test "REGNO (op) != SP_REGNUM")))
71 (define_predicate "store_operand"
72   (and (match_operand 0 "memory_operand")
73        (not (match_operand 0 "push_operand"))))
75 ;;  Mode Macro Definitions
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])
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")])
96 ;;  Code Macro Definitions
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")])
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")])
108 (define_code_macro mima_oprnd [smax umax smin umin])
109 (define_code_attr mimaIsa [(smax "maxs") (umax "maxu") (smin "mins") (umin "minu")])
111 (define_code_macro any_cond [eq ne gt gtu lt ltu ge geu le leu])
113 ;;  Addition Instructions
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")]
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>")]
135 ;;  Subtract Instructions
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")]
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>")]
157 ;;  Multiply Instructions
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>")]
169 ;;  Widening-multiplication Instructions
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")]
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")]
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")]
201 ;;  Logical Instructions - and
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>")]
213 ;;  Logical Instructions - or
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>")]
225 ;;  Logical Instructions - xor
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>")]
237 ;;  Sign and Zero Extend Instructions
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")]
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")]
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")]
266 ;;  Negation Instructions
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")]
277 ;;  Absolute Instructions
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")]
288 ;;  Max and Min Instructions
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")]
299 ;;  One's Complement
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")]
310 ;;  Rotate Instructions
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>")]
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")]
334 ;;  Arithmetic Left and Right Shift Instructions
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")]
346 ;;  Bit Set Instructions
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")]
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")]
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")]
401 ;;  Move Instructions
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   }
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>")]
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")]
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")]
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>")]
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")]
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")]
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")]
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")]
508 ;;  Movmem Instruction
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   }
524 ;;  Compare and Branch Instructions
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    (clobber (reg:CC CC_REGNUM))]
534   ""
535   "cmpb%d0<tIsa>\t%2, %1, %l3"
536   [(set_attr "length" "6")]
539 ;;  Compare Instructions
541 (define_expand "cmp<mode>"
542   [(set (reg:CC CC_REGNUM)
543         (compare:CC (match_operand:CRXIM 0 "register_operand" "")
544                     (match_operand:CRXIM 1 "nonmemory_operand" "")))]
545   ""
546   {
547     crx_compare_op0 = operands[0];
548     crx_compare_op1 = operands[1];
549     DONE;
550   }
553 (define_insn "cmp<mode>_internal"
554   [(set (reg:CC CC_REGNUM)
555         (compare:CC (match_operand:CRXIM 0 "register_operand" "r,r")
556                     (match_operand:CRXIM 1 "nonmemory_operand" "r,i")))]
557   ""
558   "cmp<tIsa>\t%1, %0"
559   [(set_attr "length" "2,<lImmArith>")]
562 ;;  Conditional Branch Instructions
564 (define_expand "b<code>"
565   [(set (pc)
566         (if_then_else (any_cond (reg:CC CC_REGNUM)
567                                 (const_int 0))
568                       (label_ref (match_operand 0 ""))
569                       (pc)))]
570   ""
571   {
572     crx_expand_branch (<CODE>, operands[0]);
573     DONE;
574   }
577 (define_insn "bCOND_internal"
578   [(set (pc)
579         (if_then_else (match_operator 0 "comparison_operator"
580                         [(reg:CC CC_REGNUM)
581                          (const_int 0)])
582                       (label_ref (match_operand 1 ""))
583                       (pc)))]
584   ""
585   "b%d0\t%l1"
586   [(set_attr "length" "6")]
589 ;;  Scond Instructions
591 (define_expand "s<code>"
592   [(set (match_operand:SI 0 "register_operand")
593         (any_cond:SI (reg:CC CC_REGNUM) (const_int 0)))]
594   ""
595   {
596     crx_expand_scond (<CODE>, operands[0]);
597     DONE;
598   }
601 (define_insn "sCOND_internal"
602   [(set (match_operand:SI 0 "register_operand" "=r")
603         (match_operator:SI 1 "comparison_operator"
604           [(reg:CC CC_REGNUM) (const_int 0)]))]
605   ""
606   "s%d1\t%0"
607   [(set_attr "length" "2")]
610 ;;  Jumps and Branches
612 (define_insn "indirect_jump_return"
613   [(parallel
614     [(set (pc)
615           (reg:SI RA_REGNUM))
616      (return)])
617   ]
618   "reload_completed"
619   "jump\tra"
620   [(set_attr "length" "2")]
623 (define_insn "indirect_jump"
624   [(set (pc)
625         (match_operand:SI 0 "reg_or_sym_operand" "r,i"))]
626   ""
627   "@
628   jump\t%0
629   br\t%a0"
630   [(set_attr "length" "2,6")]
633 (define_insn "interrupt_return"
634   [(parallel
635     [(unspec_volatile [(const_int 0)] 0)
636      (return)])]
637   ""
638   {
639     return crx_prepare_push_pop_string (1);
640   }
641   [(set_attr "length" "14")]
644 (define_insn "jump_to_imm"
645   [(set (pc)
646         (match_operand 0 "immediate_operand" "i"))]
647   ""
648   "br\t%c0"
649   [(set_attr "length" "6")]
652 (define_insn "jump"
653   [(set (pc)
654         (label_ref (match_operand 0 "" "")))]
655   ""
656   "br\t%l0"
657   [(set_attr "length" "6")]
660 ;;  Function Prologue and Epilogue
662 (define_expand "prologue"
663   [(const_int 0)]
664   ""
665   {
666     crx_expand_prologue ();
667     DONE;
668   }
671 (define_insn "push_for_prologue"
672   [(parallel
673     [(set (reg:SI SP_REGNUM)
674           (minus:SI (reg:SI SP_REGNUM)
675                     (match_operand:SI 0 "immediate_operand" "i")))])]
676   "reload_completed"
677   {
678     return crx_prepare_push_pop_string (0);
679   }
680   [(set_attr "length" "4")]
683 (define_expand "epilogue"
684   [(return)]
685   ""
686   {
687     crx_expand_epilogue ();
688     DONE;
689   }
692 (define_insn "pop_and_popret_return"
693   [(parallel
694     [(set (reg:SI SP_REGNUM)
695           (plus:SI (reg:SI SP_REGNUM)
696                    (match_operand:SI 0 "immediate_operand" "i")))
697      (use (reg:SI RA_REGNUM))
698      (return)])
699   ]
700   "reload_completed"
701   {
702     return crx_prepare_push_pop_string (1);
703   }
704   [(set_attr "length" "4")]
707 (define_insn "popret_RA_return"
708   [(parallel
709     [(use (reg:SI RA_REGNUM))
710      (return)])
711   ]
712   "reload_completed"
713   "popret\tra"
714   [(set_attr "length" "2")]
717 ;;  Table Jump
719 (define_insn "tablejump"
720   [(set (pc)
721         (match_operand:SI 0 "register_operand" "r"))
722         (use (label_ref:SI (match_operand 1 "" "" )))]
723   ""
724   "jump\t%0"
725   [(set_attr "length" "2")]
728 ;;  Call Instructions
730 (define_expand "call"
731   [(call (match_operand:QI 0 "memory_operand" "")
732          (match_operand 1 "" ""))]
733   ""
734   {
735     emit_call_insn (gen_crx_call (operands[0], operands[1]));
736     DONE;
737   }
740 (define_expand "crx_call"
741   [(parallel
742     [(call (match_operand:QI 0 "memory_operand" "")
743            (match_operand 1 "" ""))
744      (clobber (reg:SI RA_REGNUM))])]
745   ""
746   ""
749 (define_insn "crx_call_insn_branch"
750   [(call (mem:QI (match_operand:SI 0 "immediate_operand" "i"))
751          (match_operand 1 "" ""))
752    (clobber (match_operand:SI 2 "register_operand" "+r"))]
753   ""
754   "bal\tra, %a0"
755   [(set_attr "length" "6")]
758 (define_insn "crx_call_insn_jump"
759   [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
760          (match_operand 1 "" ""))
761    (clobber (match_operand:SI 2 "register_operand" "+r"))]
762   ""
763   "jal\t%0"
764   [(set_attr "length" "2")]
767 (define_insn "crx_call_insn_jalid"
768   [(call (mem:QI (mem:SI (plus:SI
769                            (match_operand:SI 0 "register_operand" "r")
770                            (match_operand:SI 1 "register_operand" "r"))))
771          (match_operand 2 "" ""))
772    (clobber (match_operand:SI 3 "register_operand" "+r"))]
773   ""
774   "jalid\t%0, %1"
775   [(set_attr "length" "4")]
778 ;;  Call Value Instructions
780 (define_expand "call_value"
781   [(set (match_operand 0 "general_operand" "")
782         (call (match_operand:QI 1 "memory_operand" "")
783               (match_operand 2 "" "")))]
784   ""
785   {
786     emit_call_insn (gen_crx_call_value (operands[0], operands[1], operands[2]));
787     DONE;
788   }
791 (define_expand "crx_call_value"
792   [(parallel
793     [(set (match_operand 0 "general_operand" "")
794           (call (match_operand 1 "memory_operand" "")
795                 (match_operand 2 "" "")))
796      (clobber (reg:SI RA_REGNUM))])]
797   ""
798   ""
801 (define_insn "crx_call_value_insn_branch"
802   [(set (match_operand 0 "" "=g")
803         (call (mem:QI (match_operand:SI 1 "immediate_operand" "i"))
804               (match_operand 2 "" "")))
805    (clobber (match_operand:SI 3 "register_operand" "+r"))]
806   ""
807   "bal\tra, %a1"
808   [(set_attr "length" "6")]
811 (define_insn "crx_call_value_insn_jump"
812   [(set (match_operand 0 "" "=g")
813         (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
814               (match_operand 2 "" "")))
815    (clobber (match_operand:SI 3 "register_operand" "+r"))]
816   ""
817   "jal\t%1"
818   [(set_attr "length" "2")]
821 (define_insn "crx_call_value_insn_jalid"
822   [(set (match_operand 0 "" "=g")
823         (call (mem:QI (mem:SI (plus:SI
824                                 (match_operand:SI 1 "register_operand" "r")
825                                 (match_operand:SI 2 "register_operand" "r"))))
826               (match_operand 3 "" "")))
827    (clobber (match_operand:SI 4 "register_operand" "+r"))]
828   ""
829   "jalid\t%0, %1"
830   [(set_attr "length" "4")]
833 ;;  Nop
835 (define_insn "nop"
836   [(const_int 0)]
837   ""
838   ""
841 ;;  Multiply and Accumulate Instructions
843 (define_insn "<sPat>madsidi3"
844   [(set (match_operand:DI 0 "register_operand" "+k")
845         (plus:DI
846           (mult:DI (sz_xtnd:DI (match_operand:SI 1 "register_operand" "%r"))
847                    (sz_xtnd:DI (match_operand:SI 2 "register_operand" "r")))
848           (match_dup 0)))
849    (clobber (reg:CC CC_REGNUM))]
850   "TARGET_MAC"
851   "mac<sPat>d\t%2, %1"
852   [(set_attr "length" "4")]
855 (define_insn "<sPat>madhisi3"
856   [(set (match_operand:SI 0 "register_operand" "+l")
857         (plus:SI
858           (mult:SI (sz_xtnd:SI (match_operand:HI 1 "register_operand" "%r"))
859                    (sz_xtnd:SI (match_operand:HI 2 "register_operand" "r")))
860           (match_dup 0)))
861    (clobber (reg:CC CC_REGNUM))]
862   "TARGET_MAC"
863   "mac<sPat>w\t%2, %1"
864   [(set_attr "length" "4")]
867 (define_insn "<sPat>madqihi3"
868   [(set (match_operand:HI 0 "register_operand" "+l")
869         (plus:HI
870           (mult:HI (sz_xtnd:HI (match_operand:QI 1 "register_operand" "%r"))
871                    (sz_xtnd:HI (match_operand:QI 2 "register_operand" "r")))
872           (match_dup 0)))
873    (clobber (reg:CC CC_REGNUM))]
874   "TARGET_MAC"
875   "mac<sPat>b\t%2, %1"
876   [(set_attr "length" "4")]
879 ;;  Loop Instructions
881 (define_expand "doloop_end"
882   [(use (match_operand 0 "" ""))        ; loop pseudo
883    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
884    (use (match_operand 2 "" ""))        ; max iterations
885    (use (match_operand 3 "" ""))        ; loop level
886    (use (match_operand 4 "" ""))]       ; label
887   ""
888   {
889     if (INTVAL (operands[3]) > crx_loop_nesting)
890       FAIL;
891     switch (GET_MODE (operands[0]))
892       {
893       case SImode:
894         emit_jump_insn (gen_doloop_end_si (operands[4], operands[0]));
895         break;
896       case HImode:
897         emit_jump_insn (gen_doloop_end_hi (operands[4], operands[0]));
898         break;
899       case QImode:
900         emit_jump_insn (gen_doloop_end_qi (operands[4], operands[0]));
901         break;
902       default:
903         FAIL;
904       }
905     DONE;
906   }
909 ;   CRX dbnz[bwd] used explicitly (see above) but also by the combiner.
911 (define_insn "doloop_end_<mode>"
912   [(set (pc)
913         (if_then_else (ne (match_operand:CRXIM 1 "register_operand" "+r,!m")
914                           (const_int 1))
915                       (label_ref (match_operand 0 "" ""))
916                       (pc)))
917    (set (match_dup 1) (plus:CRXIM (match_dup 1) (const_int -1)))
918    (clobber (match_scratch:CRXIM 2 "=X,r"))
919    (clobber (reg:CC CC_REGNUM))]
920   ""
921   "@
922   dbnz<tIsa>\t%1, %l0
923   load<tIsa>\t%1, %2\;add<tIsa>\t$-1, %2\;stor<tIsa>\t%2, %1\;bne\t%l0"
924   [(set_attr "length" "6, 12")]