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