]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/ft32/ft32.md
FT32 target added. Approved by Jeff Law [law@redhat.com]
[thirdparty/gcc.git] / gcc / config / ft32 / ft32.md
CommitLineData
fef939d6
JB
1;; Machine description for FT32
2;; Copyright (C) 2015 Free Software Foundation, Inc.
3;; Contributed by FTDI <support@ftdi.com>
4
5;; This file is part of GCC.
6
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published
9;; by the Free Software Foundation; either version 3, or (at your
10;; option) any later version.
11
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15;; License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3. If not see
19;; <http://www.gnu.org/licenses/>.
20
21;; -------------------------------------------------------------------------
22;; FT32 specific constraints, predicates and attributes
23;; -------------------------------------------------------------------------
24
25(include "constraints.md")
26(include "predicates.md")
27
28(define_constants [
29 (FP_REG 0)
30 (SP_REG 1)
31 (CC_REG 35)
32])
33
34(define_c_enum "unspec"
35 [UNSPEC_STRLEN
36 UNSPEC_MOVMEM
37 UNSPEC_SETMEM
38 UNSPEC_STPCPY
39 UNSPEC_INDEX_JMP
40 UNSPEC_LPM
41 UNSPEC_FMUL
42 UNSPEC_FMULS
43 UNSPEC_FMULSU
44 UNSPEC_COPYSIGN
45 UNSPEC_IDENTITY
46 UNSPEC_INSERT_BITS
47 UNSPEC_JMP_EPILOG
48 UNSPEC_JMP_EPILOG24
49 UNSPEC_JMP_PROLOG
50 UNSPEC_XCHG
51 ])
52
53;; -------------------------------------------------------------------------
54;; nop instruction
55;; -------------------------------------------------------------------------
56
57(define_insn "nop"
58 [(const_int 0)]
59 ""
60 "nop")
61
62;; -------------------------------------------------------------------------
63;; Arithmetic instructions
64;; -------------------------------------------------------------------------
65
66(define_insn "addsi3"
67 [(set (match_operand:SI 0 "register_operand" "=r,r")
68 (plus:SI
69 (match_operand:SI 1 "register_operand" "r,r")
70 (match_operand:SI 2 "ft32_rimm_operand" "KA,r")))
71 ]
72 ""
73 "add.l %0,%1,%2")
74
75(define_insn "subsi3"
76 [(set (match_operand:SI 0 "register_operand" "=r,r")
77 (minus:SI
78 (match_operand:SI 1 "register_operand" "r,r")
79 (match_operand:SI 2 "ft32_rimm_operand" "KA,r")))]
80 ""
81 "sub.l %0,%1,%2")
82
83(define_insn "mulsi3"
84 [(set (match_operand:SI 0 "register_operand" "=r,r")
85 (mult:SI
86 (match_operand:SI 1 "register_operand" "r,r")
87 (match_operand:SI 2 "ft32_rimm_operand" "KA,r")))]
88 ""
89 "mul.l %0,%1,%2")
90
91(define_insn "umulsidi3"
92 [(set (match_operand:DI 0 "register_operand" "=r,r")
93 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
94 (zero_extend:DI (match_operand:SI 2 "ft32_rimm_operand" "r,KA"))))
95 (clobber (reg:CC CC_REG))]
96 ""
97 "mul.l $cc,%1,%2\;muluh.l %h0,%1,%2\;move.l %0,$cc")
98
99(define_insn "divsi3"
100 [(set (match_operand:SI 0 "register_operand" "=r,r")
101 (div:SI
102 (match_operand:SI 1 "register_operand" "r,r")
103 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
104 ""
105 "div.l %0,%1,%2")
106
107(define_insn "modsi3"
108 [(set (match_operand:SI 0 "register_operand" "=r,r")
109 (mod:SI
110 (match_operand:SI 1 "register_operand" "r,r")
111 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
112 ""
113 "mod.l %0,%1,%2")
114
115(define_insn "udivsi3"
116 [(set (match_operand:SI 0 "register_operand" "=r,r")
117 (udiv:SI
118 (match_operand:SI 1 "register_operand" "r,r")
119 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
120 ""
121 "udiv.l %0,%1,%2")
122
123(define_insn "umodsi3"
124 [(set (match_operand:SI 0 "register_operand" "=r,r")
125 (umod:SI
126 (match_operand:SI 1 "register_operand" "r,r")
127 (match_operand:SI 2 "register_operand" "r,KA")))]
128 ""
129 "umod.l %0,%1,%2")
130
131(define_insn "extvsi"
132 [(set (match_operand:SI 0 "register_operand" "=r")
133 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
134 (match_operand:SI 2 "ft32_bwidth_operand" "b")
135 (match_operand:SI 3 "const_int_operand" "i")))]
136 ""
137 "bexts.l %0,%1,((15 & %2) << 5) | (%3)")
138
139(define_insn "extzvsi"
140 [(set (match_operand:SI 0 "register_operand" "=r")
141 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
142 (match_operand:SI 2 "ft32_bwidth_operand" "b")
143 (match_operand:SI 3 "const_int_operand" "i")))]
144 ""
145 "bextu.l %0,%1,((15 & %2) << 5) | (%3)")
146
147(define_insn "insvsi"
148 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
149 (match_operand:SI 1 "ft32_bwidth_operand" "b,b")
150 (match_operand:SI 2 "const_int_operand" "i,i"))
151 (match_operand:SI 3 "general_operand" "r,O"))
152 (clobber (match_scratch:SI 4 "=&r,r"))]
153 ""
154 {
155 if (which_alternative == 0)
156 {
157 return \"ldl.l %4,%3,((%1&15)<<5)|(%2)\;bins.l %0,%0,%4\";
158 }
159 else
160 {
161 if ((INTVAL(operands[3]) == 0) || (INTVAL(operands[1]) == 1))
162 return \"bins.l %0,%0,(%3<<9)|((%1&15)<<5)|(%2)\";
163 else
164 return \"ldk.l %4,(%3<<10)|((%1&15)<<5)|(%2)\;bins.l %0,%0,%4\";
165 }
166 })
167
168;; -------------------------------------------------------------------------
169;; Unary arithmetic instructions
170;; -------------------------------------------------------------------------
171
172(define_insn "one_cmplsi2"
173 [(set (match_operand:SI 0 "register_operand" "=r")
174 (not:SI (match_operand:SI 1 "register_operand" "r")))]
175 ""
176 "xor.l %0,%1,-1")
177
178;; -------------------------------------------------------------------------
179;; Logical operators
180;; -------------------------------------------------------------------------
181
182(define_insn "andsi3"
183 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
184 (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
185 (match_operand:SI 2 "general_operand" "r,x,KA")))]
186 ""
187 "@
188 and.l %0,%1,%2
189 bins.l %0,%1,%g2
190 and.l %0,%1,%2")
191
192(define_insn "andqi3"
193 [(set (match_operand:QI 0 "register_operand" "=r,r,r")
194 (and:QI (match_operand:QI 1 "register_operand" "r,r,r")
195 (match_operand:QI 2 "general_operand" "r,x,KA")))]
196 ""
197 "@
198 and.b %0,%1,%2
199 bins.b %0,%1,%g2
200 and.b %0,%1,%2")
201
202(define_insn "xorsi3"
203 [(set (match_operand:SI 0 "register_operand" "=r,r")
204 (xor:SI (match_operand:SI 1 "register_operand" "r,r")
205 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
206 ""
207{
208 return "xor.l %0,%1,%2";
209})
210
211(define_insn "iorsi3"
212 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
213 (ior:SI (match_operand:SI 1 "register_operand" "r,r,r")
214 (match_operand:SI 2 "general_operand" "r,w,KA")))]
215 ""
216 "@
217 or.l %0,%1,%2
218 bins.l %0,%1,%f2
219 or.l %0,%1,%2")
220
221;; -------------------------------------------------------------------------
222;; Shifters
223;; -------------------------------------------------------------------------
224
225(define_insn "ashlsi3"
226 [(set (match_operand:SI 0 "register_operand" "=r,r")
227 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
228 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
229 ""
230{
231 return "ashl.l %0,%1,%2";
232})
233
234(define_insn "ashrsi3"
235 [(set (match_operand:SI 0 "register_operand" "=r,r")
236 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
237 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
238 ""
239{
240 return "ashr.l %0,%1,%2";
241})
242
243(define_insn "lshrsi3"
244 [(set (match_operand:SI 0 "register_operand" "=r,r")
245 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
246 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
247 ""
248{
249 return "lshr.l %0,%1,%2";
250})
251
252;; -------------------------------------------------------------------------
253;; Move instructions
254;; -------------------------------------------------------------------------
255
256;; SImode
257
258;; Push a register onto the stack
259(define_insn "movsi_push"
260 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
261 (match_operand:SI 0 "register_operand" "r"))]
262 ""
263 "push.l %0")
264
265;; Pop a register from the stack
266(define_insn "movsi_pop"
267 [(set (match_operand:SI 0 "register_operand" "=r")
268 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
269 ""
270 "pop.l %0")
271
272(define_expand "movsi"
273 [(set (match_operand:SI 0 "general_operand" "")
274 (match_operand:SI 1 "general_operand" ""))]
275 ""
276{
277 /* If this is a store, force the value into a register. */
278 if (!(reload_in_progress || reload_completed))
279 {
280 if (MEM_P (operands[0]))
281 {
282 operands[1] = force_reg (SImode, operands[1]);
283 if (MEM_P (XEXP (operands[0], 0)))
284 operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0)));
285 }
286 else
287 {
288 if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0)))
289 operands[1] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[1], 0)));
290 }
291 /*
292 if (MEM_P (operands[0])) {
293 rtx o = XEXP (operands[0], 0);
294 if (!REG_P(o) &&
295 !CONST_INT_P(o) &&
296 GET_CODE(o) != SYMBOL_REF &&
297 GET_CODE(o) != LABEL_REF) {
298 operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0)));
299 }
300 }
301 */
302 }
303})
304
305(define_insn "*rtestsi"
306 [(set (reg:SI CC_REG)
307 (match_operand:SI 0 "register_operand" "r"))]
308 ""
309 "cmp.l %0,0"
310)
311
312(define_insn "*rtestqi"
313 [(set (reg:QI CC_REG)
314 (match_operand:QI 0 "register_operand" "r"))]
315 ""
316 "cmp.b %0,0"
317)
318
319(define_insn "*movsi"
320 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,BW,r,r,r,r,A,r,r")
321 (match_operand:SI 1 "ft32_general_movsrc_operand" "r,r,BW,A,S,i,r,e,f"))]
322 "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)"
323 "@
324 move.l %0,%1
325 sti.l %0,%1
326 ldi.l %0,%1
327 lda.l %0,%1
328 ldk.l %0,%1
329 *return ft32_load_immediate(operands[0], INTVAL(operands[1]));
330 sta.l %0,%1
331 lpm.l %0,%1
332 lpmi.l %0,%1"
333)
334
335(define_expand "movqi"
336 [(set (match_operand:QI 0 "general_operand" "")
337 (match_operand:QI 1 "general_operand" ""))]
338 ""
339{
340 /* If this is a store, force the value into a register. */
341 if (!(reload_in_progress || reload_completed))
342 {
343 if (MEM_P (operands[0]))
344 {
345 operands[1] = force_reg (QImode, operands[1]);
346 if (MEM_P (XEXP (operands[0], 0)))
347 operands[0] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[0], 0)));
348 }
349 else
350 {
351 if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0)))
352 operands[1] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[1], 0)));
353 }
354 if (MEM_P (operands[0]) && !REG_P(XEXP (operands[0], 0)))
355 {
356 operands[0] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[0], 0)));
357 }
358 }
359})
360
361(define_insn "zero_extendqisi2"
362 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r")
363 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "BW,r,f")))]
364 ""
365 "@
366 ldi.b %0,%1
367 and.l %0,%1,255
368 lpmi.b %0,%1"
369)
370
371(define_insn "extendqisi2"
372 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
373 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r")))]
374 ""
375 "bexts.l %0,%1,(8<<5)|0"
376)
377
378(define_insn "zero_extendhisi2"
379 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r")
380 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "BW,r,f")))]
381 ""
382 "@
383 ldi.s %0,%1
384 bextu.l %0,%1,(0<<5)|0
385 lpmi.s %0,%1"
386)
387
388(define_insn "extendhisi2"
389 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
390 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
391 ""
392 "bexts.l %0,%1,(0<<5)|0"
393)
394
395(define_insn "*movqi"
396 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r,r")
397 (match_operand:QI 1 "ft32_general_movsrc_operand" "r,r,BW,A,r,I,e,f"))]
398 "register_operand (operands[0], QImode)
399 || register_operand (operands[1], QImode)"
400 "@
401 move.b %0,%1
402 sti.b %0,%1
403 ldi.b %0,%1
404 lda.b %0,%1
405 sta.b %0,%1
406 ldk.b %0,%1
407 lpm.b %0,%1
408 lpmi.b %0,%1"
409)
410
411(define_expand "movhi"
412 [(set (match_operand:HI 0 "general_operand" "")
413 (match_operand:HI 1 "general_operand" ""))]
414 ""
415{
416 /* If this is a store, force the value into a register. */
417 if (!(reload_in_progress || reload_completed))
418 {
419 if (MEM_P (operands[0]))
420 {
421 operands[1] = force_reg (HImode, operands[1]);
422 if (MEM_P (XEXP (operands[0], 0)))
423 operands[0] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[0], 0)));
424 }
425 else
426 {
427 if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0)))
428 operands[1] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[1], 0)));
429 }
430 if (MEM_P (operands[0]))
431 {
432 rtx o = XEXP (operands[0], 0);
433 if (!REG_P(o) &&
434 !CONST_INT_P(o) &&
435 GET_CODE(o) != SYMBOL_REF &&
436 GET_CODE(o) != LABEL_REF) {
437 operands[0] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[0], 0)));
438 }
439 }
440 }
441})
442
443(define_insn "*movhi"
444 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r,r")
445 (match_operand:HI 1 "ft32_general_movsrc_operand" "r,r,BW,A,r,I,e,f"))]
446 "(register_operand (operands[0], HImode)
447 || register_operand (operands[1], HImode))"
448 "@
449 move.s %0,%1
450 sti.s %0,%1
451 ldi.s %0,%1
452 lda.s %0,%1
453 sta.s %0,%1
454 ldk.s %0,%1
455 lpm.s %0,%1
456 lpmi.s %0,%1"
457)
458
459(define_expand "movsf"
460 [(set (match_operand:SF 0 "general_operand" "")
461 (match_operand:SF 1 "general_operand" ""))]
462 ""
463{
464 /* If this is a store, force the value into a register. */
465 if (MEM_P (operands[0]))
466 operands[1] = force_reg (SFmode, operands[1]);
467 if (CONST_DOUBLE_P(operands[1]))
468 operands[1] = force_const_mem(SFmode, operands[1]);
469})
470
471(define_insn "*movsf"
472 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r")
473 (match_operand:SF 1 "ft32_general_movsrc_operand" "r,r,BW,A,r,I,f"))]
474 "(register_operand (operands[0], SFmode)
475 || register_operand (operands[1], SFmode))"
476 "@
477 move.l %0,%1
478 sti.l %0,%1
479 ldi.l %0,%1
480 lda.l %0,%1
481 sta.l %0,%1
482 ldk.l %0,%1
483 lpmi.l %0,%1"
484)
485
486;; -------------------------------------------------------------------------
487;; Compare instructions
488;; -------------------------------------------------------------------------
489
490(define_expand "cbranchsi4"
491 [(set (reg:CC CC_REG)
492 (compare:CC
493 (match_operand:SI 1 "register_operand" "")
494 (match_operand:SI 2 "ft32_rimm_operand" "")))
495 (set (pc)
496 (if_then_else (match_operator 0 "comparison_operator"
497 [(reg:CC CC_REG) (const_int 0)])
498 (label_ref (match_operand 3 "" ""))
499 (pc)))]
500 ""
501 "")
502
503(define_insn "cmpsi"
504 [(set (reg:CC CC_REG)
505 (compare:CC
506 (match_operand:SI 0 "register_operand" "r,r")
507 (match_operand:SI 1 "ft32_rimm_operand" "r,KA")))]
508 ""
509 "cmp.l %0,%1")
510
511(define_insn ""
512 [(set (pc)
513 (if_then_else
514 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
515 (const_int 1)
516 (match_operand:SI 1 "const_int_operand" "i"))
517 (const_int 0))
518 (label_ref (match_operand 2 "" ""))
519 (pc)))
520 (clobber (reg:CC CC_REG))]
521 ""
522 "btst.l %0,(1<<5)|%1\;jmpc nz,%l2")
523
524(define_insn ""
525 [(set (pc)
526 (if_then_else
527 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
528 (const_int 1)
529 (match_operand:SI 1 "const_int_operand" "i"))
530 (const_int 0))
531 (label_ref (match_operand 2 "" ""))
532 (pc)))
533 (clobber (reg:CC CC_REG))]
534 ""
535 "btst.l %0,(1<<5)|%1\;jmpc z,%l2")
536
537(define_expand "cbranchqi4"
538 [(set (reg:CC CC_REG)
539 (compare:CC
540 (match_operand:QI 1 "register_operand" "")
541 (match_operand:QI 2 "ft32_rimm_operand" "")))
542 (set (pc)
543 (if_then_else (match_operator 0 "comparison_operator"
544 [(reg:CC CC_REG) (const_int 0)])
545 (label_ref (match_operand 3 "" ""))
546 (pc)))]
547 ""
548 "")
549
550(define_insn "*cmpqi"
551 [(set (reg:CC CC_REG)
552 (compare:CC
553 (match_operand:QI 0 "register_operand" "r,r")
554 (match_operand:QI 1 "ft32_rimm_operand" "r,KA")))]
555 ""
556 "cmp.b %0,%1")
557
558;; -------------------------------------------------------------------------
559;; Branch instructions
560;; -------------------------------------------------------------------------
561
562(define_code_iterator cond [ne eq lt ltu gt gtu ge le geu leu])
563(define_code_attr CC [(ne "nz") (eq "z") (lt "lt") (ltu "b")
564 (gt "gt") (gtu "a") (ge "gte") (le "lte")
565 (geu "ae") (leu "be") ])
566(define_code_attr rCC [(ne "z") (eq "nz") (lt "gte") (ltu "ae")
567 (gt "lte") (gtu "be") (ge "lt") (le "gt")
568 (geu "b") (leu "a") ])
569
570(define_insn "*b<cond:code>"
571 [(set (pc)
572 (if_then_else (cond (reg:CC CC_REG)
573 (const_int 0))
574 (label_ref (match_operand 0 "" ""))
575 (pc)))]
576 ""
577{
578 return "jmpc <CC>,%l0";
579}
580)
581
582(define_expand "cstoresi4"
583 [(set (reg:CC CC_REG)
584 (compare:CC (match_operand:SI 2 "register_operand" "r,r")
585 (match_operand:SI 3 "ft32_rimm_operand" "r,KA")))
586 (set (match_operand:SI 0 "register_operand")
587 (match_operator:SI 1 "ordered_comparison_operator"
588 [(reg:CC CC_REG) (const_int 0)]))]
589 ""
590{
591 rtx test;
592
593 switch (GET_CODE (operands[1])) {
594 case NE:
595 case GEU:
596 case LT:
597 case LE:
598 case LEU:
599 test = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
600 SImode, operands[2], operands[3]);
601 emit_insn(gen_cstoresi4(operands[0], test, operands[2], operands[3]));
602 emit_insn(gen_xorsi3(operands[0], operands[0], gen_int_mode(1, SImode)));
603 DONE;
604 default:
605 ;
606 }
607})
608
609(define_insn "*seq"
610 [(set (match_operand:SI 0 "register_operand" "=r")
611 (eq:SI (reg CC_REG) (const_int 0)))]
612 ""
613 "bextu.l %0,$cc,32|0"
614)
615
616(define_insn "*sltu"
617 [(set (match_operand:SI 0 "register_operand" "=r")
618 (ltu:SI (reg CC_REG) (const_int 0)))]
619 ""
620 "bextu.l %0,$cc,32|1"
621)
622
623(define_insn "*sge"
624 [(set (match_operand:SI 0 "register_operand" "=r")
625 (ge:SI (reg CC_REG) (const_int 0)))]
626 ""
627 "bextu.l %0,$cc,32|4"
628)
629
630(define_insn "*sgt"
631 [(set (match_operand:SI 0 "register_operand" "=r")
632 (gt:SI (reg CC_REG) (const_int 0)))]
633 ""
634 "bextu.l %0,$cc,32|5"
635)
636
637(define_insn "*sgtu"
638 [(set (match_operand:SI 0 "register_operand" "=r")
639 (gtu:SI (reg CC_REG) (const_int 0)))]
640 ""
641 "bextu.l %0,$cc,32|6"
642)
643
644;; -------------------------------------------------------------------------
645;; Call and Jump instructions
646;; -------------------------------------------------------------------------
647
648(define_expand "call"
649 [(call (match_operand:QI 0 "memory_operand" "")
650 (match_operand 1 "general_operand" ""))]
651 ""
652{
653 gcc_assert (MEM_P (operands[0]));
654})
655
656(define_insn "*call"
657 [(call (mem:QI (match_operand:SI
658 0 "nonmemory_operand" "i,r"))
659 (match_operand 1 "" ""))]
660 ""
661 "@
662 call %0
663 calli %0"
664)
665
666(define_expand "call_value"
667 [(set (match_operand 0 "" "")
668 (call (match_operand:QI 1 "memory_operand" "")
669 (match_operand 2 "" "")))]
670 ""
671{
672 gcc_assert (MEM_P (operands[1]));
673})
674
675(define_insn "*call_value"
676 [(set (match_operand 0 "register_operand" "=r")
677 (call (mem:QI (match_operand:SI
678 1 "immediate_operand" "i"))
679 (match_operand 2 "" "")))]
680 ""
681 "call %1"
682)
683
684(define_insn "*call_value_indirect"
685 [(set (match_operand 0 "register_operand" "=r")
686 (call (mem:QI (match_operand:SI
687 1 "register_operand" "r"))
688 (match_operand 2 "" "")))]
689 ""
690 "calli %1"
691)
692
693(define_insn "indirect_jump"
694 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
695 ""
696 "jmpi %0")
697
698(define_insn "jump"
699 [(set (pc)
700 (label_ref (match_operand 0 "" "")))]
701 ""
702 "jmp %l0"
703)
704
705(define_insn "call_prolog"
706 [(unspec:SI [(match_operand 0 "" "")]
707 UNSPEC_JMP_PROLOG)]
708 ""
709 "call __prolog_%0"
710)
711
712(define_insn "jump_epilog"
713 [(unspec:SI [(match_operand 0 "" "")]
714 UNSPEC_JMP_EPILOG)]
715 ""
716 "jmp __epilog_%0"
717)
718
719(define_insn "jump_epilog24"
720 [(unspec:SI [(match_operand 0 "" "")]
721 UNSPEC_JMP_EPILOG24)]
722 ""
723 "jmp __epilog24_%0"
724)
725
726
727;; Subroutines of "casesi".
728;; operand 0 is index
729;; operand 1 is the minimum bound
730;; operand 2 is the maximum bound - minimum bound + 1
731;; operand 3 is CODE_LABEL for the table;
732;; operand 4 is the CODE_LABEL to go to if index out of range.
733
734(define_expand "casesi"
735 [(match_operand:SI 0 "general_operand" "")
736 (match_operand:SI 1 "const_int_operand" "")
737 (match_operand:SI 2 "const_int_operand" "")
738 (match_operand 3 "" "")
739 (match_operand 4 "" "")]
740 ""
741 "
742{
743 if (GET_CODE (operands[0]) != REG)
744 operands[0] = force_reg (SImode, operands[0]);
745
746 if (operands[1] != const0_rtx)
747 {
748 rtx index = gen_reg_rtx (SImode);
749 rtx offset = gen_reg_rtx (SImode);
750
751 emit_insn (gen_movsi (offset, operands[1]));
752 emit_insn (gen_subsi3 (index, operands[0], offset));
753 operands[0] = index;
754 }
755
756 {
757 rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
758 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
759 }
760
761 emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
762 DONE;
763}")
764
765(define_insn "casesi0"
766 [(set (pc) (mem:SI (plus:SI
767 (mult:SI (match_operand:SI 0 "register_operand" "r")
768 (const_int 4))
769 (label_ref (match_operand 1 "" "")))))
770 (clobber (match_scratch:SI 2 "=&r"))
771 ]
772 ""
773 "ldk.l\t$cc,%l1\;ashl.l\t%2,%0,2\;add.l\t%2,%2,$cc\;jmpi\t%2"
774 )
775
776;; -------------------------------------------------------------------------
777;; Atomic exchange instruction
778;; -------------------------------------------------------------------------
779
780(define_insn "atomic_exchangesi"
781 [(set (match_operand:SI 0 "register_operand" "=&r,r") ;; output
782 (match_operand:SI 1 "memory_operand" "+BW,A")) ;; memory
783 (set (match_dup 1)
784 (unspec:SI
785 [(match_operand:SI 2 "register_operand" "0,0") ;; input
786 (match_operand:SI 3 "const_int_operand")] ;; model
787 UNSPEC_XCHG))]
788 ""
789 "@
790 exi.l %0,%1
791 exa.l %0,%1")
792
793(define_insn "atomic_exchangehi"
794 [(set (match_operand:HI 0 "register_operand" "=&r,r") ;; output
795 (match_operand:HI 1 "memory_operand" "+BW,A")) ;; memory
796 (set (match_dup 1)
797 (unspec:HI
798 [(match_operand:HI 2 "register_operand" "0,0") ;; input
799 (match_operand:HI 3 "const_int_operand")] ;; model
800 UNSPEC_XCHG))]
801 ""
802 "@
803 exi.s %0,%1
804 exa.s %0,%1")
805
806(define_insn "atomic_exchangeqi"
807 [(set (match_operand:QI 0 "register_operand" "=&r,r") ;; output
808 (match_operand:QI 1 "memory_operand" "+BW,A")) ;; memory
809 (set (match_dup 1)
810 (unspec:QI
811 [(match_operand:QI 2 "register_operand" "0,0") ;; input
812 (match_operand:QI 3 "const_int_operand")] ;; model
813 UNSPEC_XCHG))]
814 ""
815 "@
816 exi.b %0,%1
817 exa.b %0,%1")
818
819;; -------------------------------------------------------------------------
820;; String instructions
821;; -------------------------------------------------------------------------
822
823(define_insn "cmpstrsi"
824 [(set (match_operand:SI 0 "register_operand" "=r,r")
825 (compare:SI (match_operand:BLK 1 "memory_operand" "W,BW")
826 (match_operand:BLK 2 "memory_operand" "W,BW")))
827 (clobber (match_operand:SI 3))
828 ]
829 ""
830 "strcmp.%d3 %0,%b1,%b2"
831)
832
833(define_insn "movstr"
834[(set (match_operand:BLK 1 "memory_operand" "=W")
835 (match_operand:BLK 2 "memory_operand" "W"))
836 (use (match_operand:SI 0))
837 (clobber (match_dup 0))
838 ]
839"0"
840"stpcpy %b1,%b2 # %0 %b1 %b2"
841)
842
843(define_insn "movmemsi"
844 [(set (match_operand:BLK 0 "memory_operand" "=W,W,BW")
845 (match_operand:BLK 1 "memory_operand" "W,W,BW"))
846 (use (match_operand:SI 2 "ft32_rimm_operand" "r,KA,rKA"))
847 (use (match_operand:SI 3))
848 ]
849 ""
850 "memcpy.%d3 %b0,%b1,%2 # %3!"
851)
852
853(define_insn "setmemsi"
854 [(set (match_operand:BLK 0 "memory_operand" "=BW,BW") (unspec:BLK [
855 (use (match_operand:QI 2 "register_operand" "r,r"))
856 (use (match_operand:SI 1 "ft32_rimm_operand" "r,KA"))
857 ] UNSPEC_SETMEM))
858 (use (match_operand:SI 3))
859 ]
860 ""
861 "memset.%d3 %b0,%2,%1"
862)
863
864(define_insn "strlensi"
865 [(set (match_operand:SI 0 "register_operand" "=r")
866 (unspec:SI [(match_operand:BLK 1 "memory_operand" "W")
867 (match_operand:QI 2 "const_int_operand" "")
868 (match_operand:SI 3 "ft32_rimm_operand" "")]
869 UNSPEC_STRLEN))]
870 ""
871 "strlen.%d3 %0,%b1 # %2 %3"
872)
873
874;; -------------------------------------------------------------------------
875;; Prologue & Epilogue
876;; -------------------------------------------------------------------------
877
878(define_expand "prologue"
879 [(clobber (const_int 0))]
880 ""
881{
882 extern void ft32_expand_prologue();
883 ft32_expand_prologue ();
884 DONE;
885})
886
887(define_expand "epilogue"
888 [(return)]
889 ""
890{
891 extern void ft32_expand_epilogue();
892 ft32_expand_epilogue ();
893 DONE;
894})
895
896(define_insn "link"
897 [
898;; (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
899;; (reg:SI FP_REG))
900 (set (match_operand:SI 0)
901 (reg:SI SP_REG))
902 (set (reg:SI SP_REG)
903 (plus:SI (reg:SI SP_REG)
904 (match_operand:SI 1 "general_operand" "L")))]
905 ""
906 "link %0,%m1"
907)
908
909(define_insn "unlink"
910 [(set (reg:SI FP_REG)
911 (mem:SI (reg:SI FP_REG)))
912 (set (reg:SI SP_REG)
913 (plus:SI (reg:SI FP_REG)
914 (const_int 4)))]
915 ""
916 "unlink $r29"
917)
918
919(define_insn "returner"
920 [(return)]
921 "reload_completed"
922 "return")
923
924(define_insn "returner24"
925 [
926 (set (reg:SI SP_REG)
927 (plus:SI
928 (reg:SI SP_REG)
929 (const_int 24)))
930 (return)]
931 ""
932 "jmp __epilog24")