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   (clobber (reg:CC CC_REGNUM))]
534  ""
535  "cmpb%d0<tIsa>\t%2, %1, %l3"
536  [(set_attr "length" "6")]
537)
538
539;;  Compare Instructions
540
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  }
551)
552
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>")]
560)
561
562;;  Conditional Branch Instructions
563
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  }
575)
576
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")]
587)
588
589;;  Scond Instructions
590
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  }
599)
600
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")]
608)
609
610;;  Jumps and Branches
611
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")]
621)
622
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")]
631)
632
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")]
642)
643
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")]
650)
651
652(define_insn "jump"
653  [(set (pc)
654	(label_ref (match_operand 0 "" "")))]
655  ""
656  "br\t%l0"
657  [(set_attr "length" "6")]
658)
659
660;;  Function Prologue and Epilogue
661
662(define_expand "prologue"
663  [(const_int 0)]
664  ""
665  {
666    crx_expand_prologue ();
667    DONE;
668  }
669)
670
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")]
681)
682
683(define_expand "epilogue"
684  [(return)]
685  ""
686  {
687    crx_expand_epilogue ();
688    DONE;
689  }
690)
691
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")]
705)
706
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")]
715)
716
717;;  Table Jump
718
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")]
726)
727
728;;  Call Instructions
729
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  }
738)
739
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  ""
747)
748
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")]
756)
757
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")]
765)
766
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")]
776)
777
778;;  Call Value Instructions
779
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  }
789)
790
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  ""
799)
800
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")]
809)
810
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")]
819)
820
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")]
831)
832
833;;  Nop
834
835(define_insn "nop"
836  [(const_int 0)]
837  ""
838  ""
839)
840
841;;  Multiply and Accumulate Instructions
842
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")]
853)
854
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")]
865)
866
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")]
877)
878
879;;  Loop Instructions
880
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  }
907)
908
909;   CRX dbnz[bwd] used explicitly (see above) but also by the combiner.
910
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")]
925)
926