]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/ft32/ft32.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / ft32 / ft32.md
CommitLineData
fef939d6 1;; Machine description for FT32
8d9254fc 2;; Copyright (C) 2015-2020 Free Software Foundation, Inc.
fef939d6
JB
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")))]
dc2e8995 104 "!TARGET_NODIV"
fef939d6
JB
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")))]
dc2e8995 112 "!TARGET_NODIV"
fef939d6
JB
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")))]
dc2e8995 120 "!TARGET_NODIV"
fef939d6
JB
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")))]
dc2e8995 128 "!TARGET_NODIV"
fef939d6
JB
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
6d82151f
JB
258(define_insn "*sne"
259 [(set (match_operand:SI 0 "register_operand" "=r")
260 (reg:SI CC_REG))]
261 ""
262 "bextu.l %0,$cc,32|0\;xor.l %0,%0,-1"
263)
264
fef939d6
JB
265;; Push a register onto the stack
266(define_insn "movsi_push"
267 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
268 (match_operand:SI 0 "register_operand" "r"))]
269 ""
270 "push.l %0")
271
272;; Pop a register from the stack
273(define_insn "movsi_pop"
274 [(set (match_operand:SI 0 "register_operand" "=r")
275 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
276 ""
277 "pop.l %0")
278
279(define_expand "movsi"
280 [(set (match_operand:SI 0 "general_operand" "")
281 (match_operand:SI 1 "general_operand" ""))]
282 ""
283{
284 /* If this is a store, force the value into a register. */
285 if (!(reload_in_progress || reload_completed))
286 {
287 if (MEM_P (operands[0]))
288 {
289 operands[1] = force_reg (SImode, operands[1]);
290 if (MEM_P (XEXP (operands[0], 0)))
291 operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0)));
292 }
293 else
294 {
295 if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0)))
296 operands[1] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[1], 0)));
297 }
298 /*
299 if (MEM_P (operands[0])) {
300 rtx o = XEXP (operands[0], 0);
301 if (!REG_P(o) &&
302 !CONST_INT_P(o) &&
303 GET_CODE(o) != SYMBOL_REF &&
304 GET_CODE(o) != LABEL_REF) {
305 operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0)));
306 }
307 }
308 */
309 }
310})
311
312(define_insn "*rtestsi"
313 [(set (reg:SI CC_REG)
314 (match_operand:SI 0 "register_operand" "r"))]
315 ""
316 "cmp.l %0,0"
317)
318
319(define_insn "*rtestqi"
320 [(set (reg:QI CC_REG)
321 (match_operand:QI 0 "register_operand" "r"))]
322 ""
323 "cmp.b %0,0"
324)
325
326(define_insn "*movsi"
327 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,BW,r,r,r,r,A,r,r")
328 (match_operand:SI 1 "ft32_general_movsrc_operand" "r,r,BW,A,S,i,r,e,f"))]
329 "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)"
330 "@
331 move.l %0,%1
332 sti.l %0,%1
333 ldi.l %0,%1
334 lda.l %0,%1
335 ldk.l %0,%1
336 *return ft32_load_immediate(operands[0], INTVAL(operands[1]));
337 sta.l %0,%1
338 lpm.l %0,%1
339 lpmi.l %0,%1"
340)
341
342(define_expand "movqi"
343 [(set (match_operand:QI 0 "general_operand" "")
344 (match_operand:QI 1 "general_operand" ""))]
345 ""
346{
347 /* If this is a store, force the value into a register. */
348 if (!(reload_in_progress || reload_completed))
349 {
350 if (MEM_P (operands[0]))
351 {
352 operands[1] = force_reg (QImode, operands[1]);
353 if (MEM_P (XEXP (operands[0], 0)))
354 operands[0] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[0], 0)));
355 }
356 else
357 {
358 if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0)))
359 operands[1] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[1], 0)));
360 }
361 if (MEM_P (operands[0]) && !REG_P(XEXP (operands[0], 0)))
362 {
363 operands[0] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[0], 0)));
364 }
365 }
366})
367
368(define_insn "zero_extendqisi2"
369 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r")
370 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "BW,r,f")))]
371 ""
372 "@
373 ldi.b %0,%1
374 and.l %0,%1,255
375 lpmi.b %0,%1"
376)
377
378(define_insn "extendqisi2"
379 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
380 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r")))]
381 ""
382 "bexts.l %0,%1,(8<<5)|0"
383)
384
385(define_insn "zero_extendhisi2"
386 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r")
387 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "BW,r,f")))]
388 ""
389 "@
390 ldi.s %0,%1
391 bextu.l %0,%1,(0<<5)|0
392 lpmi.s %0,%1"
393)
394
395(define_insn "extendhisi2"
396 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
397 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
398 ""
399 "bexts.l %0,%1,(0<<5)|0"
400)
401
402(define_insn "*movqi"
403 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r,r")
404 (match_operand:QI 1 "ft32_general_movsrc_operand" "r,r,BW,A,r,I,e,f"))]
405 "register_operand (operands[0], QImode)
406 || register_operand (operands[1], QImode)"
407 "@
408 move.b %0,%1
409 sti.b %0,%1
410 ldi.b %0,%1
411 lda.b %0,%1
412 sta.b %0,%1
413 ldk.b %0,%1
414 lpm.b %0,%1
415 lpmi.b %0,%1"
416)
417
418(define_expand "movhi"
419 [(set (match_operand:HI 0 "general_operand" "")
420 (match_operand:HI 1 "general_operand" ""))]
421 ""
422{
423 /* If this is a store, force the value into a register. */
424 if (!(reload_in_progress || reload_completed))
425 {
426 if (MEM_P (operands[0]))
427 {
428 operands[1] = force_reg (HImode, operands[1]);
429 if (MEM_P (XEXP (operands[0], 0)))
430 operands[0] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[0], 0)));
431 }
432 else
433 {
434 if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0)))
435 operands[1] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[1], 0)));
436 }
437 if (MEM_P (operands[0]))
438 {
439 rtx o = XEXP (operands[0], 0);
440 if (!REG_P(o) &&
441 !CONST_INT_P(o) &&
442 GET_CODE(o) != SYMBOL_REF &&
443 GET_CODE(o) != LABEL_REF) {
444 operands[0] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[0], 0)));
445 }
446 }
447 }
448})
449
450(define_insn "*movhi"
451 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r,r")
452 (match_operand:HI 1 "ft32_general_movsrc_operand" "r,r,BW,A,r,I,e,f"))]
453 "(register_operand (operands[0], HImode)
454 || register_operand (operands[1], HImode))"
455 "@
456 move.s %0,%1
457 sti.s %0,%1
458 ldi.s %0,%1
459 lda.s %0,%1
460 sta.s %0,%1
461 ldk.s %0,%1
462 lpm.s %0,%1
463 lpmi.s %0,%1"
464)
465
466(define_expand "movsf"
467 [(set (match_operand:SF 0 "general_operand" "")
468 (match_operand:SF 1 "general_operand" ""))]
469 ""
470{
471 /* If this is a store, force the value into a register. */
472 if (MEM_P (operands[0]))
473 operands[1] = force_reg (SFmode, operands[1]);
474 if (CONST_DOUBLE_P(operands[1]))
475 operands[1] = force_const_mem(SFmode, operands[1]);
476})
477
478(define_insn "*movsf"
479 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r")
480 (match_operand:SF 1 "ft32_general_movsrc_operand" "r,r,BW,A,r,I,f"))]
481 "(register_operand (operands[0], SFmode)
482 || register_operand (operands[1], SFmode))"
483 "@
484 move.l %0,%1
485 sti.l %0,%1
486 ldi.l %0,%1
487 lda.l %0,%1
488 sta.l %0,%1
489 ldk.l %0,%1
490 lpmi.l %0,%1"
491)
492
493;; -------------------------------------------------------------------------
494;; Compare instructions
495;; -------------------------------------------------------------------------
496
497(define_expand "cbranchsi4"
498 [(set (reg:CC CC_REG)
499 (compare:CC
500 (match_operand:SI 1 "register_operand" "")
501 (match_operand:SI 2 "ft32_rimm_operand" "")))
502 (set (pc)
503 (if_then_else (match_operator 0 "comparison_operator"
504 [(reg:CC CC_REG) (const_int 0)])
505 (label_ref (match_operand 3 "" ""))
506 (pc)))]
507 ""
508 "")
509
510(define_insn "cmpsi"
511 [(set (reg:CC CC_REG)
512 (compare:CC
513 (match_operand:SI 0 "register_operand" "r,r")
514 (match_operand:SI 1 "ft32_rimm_operand" "r,KA")))]
515 ""
516 "cmp.l %0,%1")
517
518(define_insn ""
519 [(set (pc)
520 (if_then_else
521 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
522 (const_int 1)
523 (match_operand:SI 1 "const_int_operand" "i"))
524 (const_int 0))
525 (label_ref (match_operand 2 "" ""))
526 (pc)))
527 (clobber (reg:CC CC_REG))]
528 ""
529 "btst.l %0,(1<<5)|%1\;jmpc nz,%l2")
530
531(define_insn ""
532 [(set (pc)
533 (if_then_else
534 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
535 (const_int 1)
536 (match_operand:SI 1 "const_int_operand" "i"))
537 (const_int 0))
538 (label_ref (match_operand 2 "" ""))
539 (pc)))
540 (clobber (reg:CC CC_REG))]
541 ""
542 "btst.l %0,(1<<5)|%1\;jmpc z,%l2")
543
544(define_expand "cbranchqi4"
545 [(set (reg:CC CC_REG)
546 (compare:CC
547 (match_operand:QI 1 "register_operand" "")
548 (match_operand:QI 2 "ft32_rimm_operand" "")))
549 (set (pc)
550 (if_then_else (match_operator 0 "comparison_operator"
551 [(reg:CC CC_REG) (const_int 0)])
552 (label_ref (match_operand 3 "" ""))
553 (pc)))]
554 ""
555 "")
556
557(define_insn "*cmpqi"
558 [(set (reg:CC CC_REG)
559 (compare:CC
560 (match_operand:QI 0 "register_operand" "r,r")
561 (match_operand:QI 1 "ft32_rimm_operand" "r,KA")))]
562 ""
563 "cmp.b %0,%1")
564
565;; -------------------------------------------------------------------------
566;; Branch instructions
567;; -------------------------------------------------------------------------
568
569(define_code_iterator cond [ne eq lt ltu gt gtu ge le geu leu])
570(define_code_attr CC [(ne "nz") (eq "z") (lt "lt") (ltu "b")
571 (gt "gt") (gtu "a") (ge "gte") (le "lte")
572 (geu "ae") (leu "be") ])
573(define_code_attr rCC [(ne "z") (eq "nz") (lt "gte") (ltu "ae")
574 (gt "lte") (gtu "be") (ge "lt") (le "gt")
575 (geu "b") (leu "a") ])
576
577(define_insn "*b<cond:code>"
578 [(set (pc)
579 (if_then_else (cond (reg:CC CC_REG)
580 (const_int 0))
581 (label_ref (match_operand 0 "" ""))
582 (pc)))]
583 ""
584{
585 return "jmpc <CC>,%l0";
586}
587)
588
589(define_expand "cstoresi4"
590 [(set (reg:CC CC_REG)
591 (compare:CC (match_operand:SI 2 "register_operand" "r,r")
592 (match_operand:SI 3 "ft32_rimm_operand" "r,KA")))
593 (set (match_operand:SI 0 "register_operand")
594 (match_operator:SI 1 "ordered_comparison_operator"
595 [(reg:CC CC_REG) (const_int 0)]))]
596 ""
597{
598 rtx test;
599
600 switch (GET_CODE (operands[1])) {
601 case NE:
602 case GEU:
603 case LT:
604 case LE:
605 case LEU:
606 test = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
607 SImode, operands[2], operands[3]);
608 emit_insn(gen_cstoresi4(operands[0], test, operands[2], operands[3]));
609 emit_insn(gen_xorsi3(operands[0], operands[0], gen_int_mode(1, SImode)));
610 DONE;
611 default:
612 ;
613 }
614})
615
616(define_insn "*seq"
617 [(set (match_operand:SI 0 "register_operand" "=r")
618 (eq:SI (reg CC_REG) (const_int 0)))]
619 ""
620 "bextu.l %0,$cc,32|0"
621)
622
623(define_insn "*sltu"
624 [(set (match_operand:SI 0 "register_operand" "=r")
625 (ltu:SI (reg CC_REG) (const_int 0)))]
626 ""
627 "bextu.l %0,$cc,32|1"
628)
629
630(define_insn "*sge"
631 [(set (match_operand:SI 0 "register_operand" "=r")
632 (ge:SI (reg CC_REG) (const_int 0)))]
633 ""
634 "bextu.l %0,$cc,32|4"
635)
636
637(define_insn "*sgt"
638 [(set (match_operand:SI 0 "register_operand" "=r")
639 (gt:SI (reg CC_REG) (const_int 0)))]
640 ""
641 "bextu.l %0,$cc,32|5"
642)
643
644(define_insn "*sgtu"
645 [(set (match_operand:SI 0 "register_operand" "=r")
646 (gtu:SI (reg CC_REG) (const_int 0)))]
647 ""
648 "bextu.l %0,$cc,32|6"
649)
650
651;; -------------------------------------------------------------------------
652;; Call and Jump instructions
653;; -------------------------------------------------------------------------
654
655(define_expand "call"
656 [(call (match_operand:QI 0 "memory_operand" "")
657 (match_operand 1 "general_operand" ""))]
658 ""
659{
660 gcc_assert (MEM_P (operands[0]));
661})
662
663(define_insn "*call"
664 [(call (mem:QI (match_operand:SI
665 0 "nonmemory_operand" "i,r"))
666 (match_operand 1 "" ""))]
667 ""
668 "@
669 call %0
670 calli %0"
671)
672
673(define_expand "call_value"
674 [(set (match_operand 0 "" "")
675 (call (match_operand:QI 1 "memory_operand" "")
676 (match_operand 2 "" "")))]
677 ""
678{
679 gcc_assert (MEM_P (operands[1]));
680})
681
682(define_insn "*call_value"
683 [(set (match_operand 0 "register_operand" "=r")
684 (call (mem:QI (match_operand:SI
685 1 "immediate_operand" "i"))
686 (match_operand 2 "" "")))]
687 ""
688 "call %1"
689)
690
691(define_insn "*call_value_indirect"
692 [(set (match_operand 0 "register_operand" "=r")
693 (call (mem:QI (match_operand:SI
694 1 "register_operand" "r"))
695 (match_operand 2 "" "")))]
696 ""
697 "calli %1"
698)
699
700(define_insn "indirect_jump"
701 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
702 ""
703 "jmpi %0")
704
705(define_insn "jump"
706 [(set (pc)
707 (label_ref (match_operand 0 "" "")))]
708 ""
709 "jmp %l0"
710)
711
712(define_insn "call_prolog"
713 [(unspec:SI [(match_operand 0 "" "")]
714 UNSPEC_JMP_PROLOG)]
715 ""
716 "call __prolog_%0"
717)
718
719(define_insn "jump_epilog"
720 [(unspec:SI [(match_operand 0 "" "")]
721 UNSPEC_JMP_EPILOG)]
722 ""
723 "jmp __epilog_%0"
724)
725
726(define_insn "jump_epilog24"
727 [(unspec:SI [(match_operand 0 "" "")]
728 UNSPEC_JMP_EPILOG24)]
729 ""
730 "jmp __epilog24_%0"
731)
732
733
734;; Subroutines of "casesi".
735;; operand 0 is index
736;; operand 1 is the minimum bound
737;; operand 2 is the maximum bound - minimum bound + 1
738;; operand 3 is CODE_LABEL for the table;
739;; operand 4 is the CODE_LABEL to go to if index out of range.
740
741(define_expand "casesi"
742 [(match_operand:SI 0 "general_operand" "")
743 (match_operand:SI 1 "const_int_operand" "")
744 (match_operand:SI 2 "const_int_operand" "")
745 (match_operand 3 "" "")
746 (match_operand 4 "" "")]
747 ""
748 "
749{
750 if (GET_CODE (operands[0]) != REG)
751 operands[0] = force_reg (SImode, operands[0]);
752
753 if (operands[1] != const0_rtx)
754 {
755 rtx index = gen_reg_rtx (SImode);
756 rtx offset = gen_reg_rtx (SImode);
757
758 emit_insn (gen_movsi (offset, operands[1]));
759 emit_insn (gen_subsi3 (index, operands[0], offset));
760 operands[0] = index;
761 }
762
763 {
764 rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
765 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
766 }
767
768 emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
769 DONE;
770}")
771
772(define_insn "casesi0"
773 [(set (pc) (mem:SI (plus:SI
774 (mult:SI (match_operand:SI 0 "register_operand" "r")
775 (const_int 4))
776 (label_ref (match_operand 1 "" "")))))
777 (clobber (match_scratch:SI 2 "=&r"))
778 ]
779 ""
7c42a367
JB
780 {
781 if (TARGET_NOPM)
782 return \"ldk.l\t$cc,%l1\;ashl.l\t%2,%0,2\;add.l\t%2,%2,$cc\;ldi.l\t%2,%2,0\;jmpi\t%2\";
783 else
784 return \"ldk.l\t$cc,%l1\;ashl.l\t%2,%0,2\;add.l\t%2,%2,$cc\;lpmi.l\t%2,%2,0\;jmpi\t%2\";
785 })
fef939d6
JB
786
787;; -------------------------------------------------------------------------
788;; Atomic exchange instruction
789;; -------------------------------------------------------------------------
790
791(define_insn "atomic_exchangesi"
792 [(set (match_operand:SI 0 "register_operand" "=&r,r") ;; output
793 (match_operand:SI 1 "memory_operand" "+BW,A")) ;; memory
794 (set (match_dup 1)
795 (unspec:SI
796 [(match_operand:SI 2 "register_operand" "0,0") ;; input
797 (match_operand:SI 3 "const_int_operand")] ;; model
798 UNSPEC_XCHG))]
799 ""
800 "@
801 exi.l %0,%1
802 exa.l %0,%1")
803
804(define_insn "atomic_exchangehi"
805 [(set (match_operand:HI 0 "register_operand" "=&r,r") ;; output
806 (match_operand:HI 1 "memory_operand" "+BW,A")) ;; memory
807 (set (match_dup 1)
808 (unspec:HI
809 [(match_operand:HI 2 "register_operand" "0,0") ;; input
810 (match_operand:HI 3 "const_int_operand")] ;; model
811 UNSPEC_XCHG))]
812 ""
813 "@
814 exi.s %0,%1
815 exa.s %0,%1")
816
817(define_insn "atomic_exchangeqi"
818 [(set (match_operand:QI 0 "register_operand" "=&r,r") ;; output
819 (match_operand:QI 1 "memory_operand" "+BW,A")) ;; memory
820 (set (match_dup 1)
821 (unspec:QI
822 [(match_operand:QI 2 "register_operand" "0,0") ;; input
823 (match_operand:QI 3 "const_int_operand")] ;; model
824 UNSPEC_XCHG))]
825 ""
826 "@
827 exi.b %0,%1
828 exa.b %0,%1")
829
830;; -------------------------------------------------------------------------
831;; String instructions
832;; -------------------------------------------------------------------------
833
834(define_insn "cmpstrsi"
835 [(set (match_operand:SI 0 "register_operand" "=r,r")
836 (compare:SI (match_operand:BLK 1 "memory_operand" "W,BW")
837 (match_operand:BLK 2 "memory_operand" "W,BW")))
838 (clobber (match_operand:SI 3))
839 ]
840 ""
841 "strcmp.%d3 %0,%b1,%b2"
842)
843
844(define_insn "movstr"
845[(set (match_operand:BLK 1 "memory_operand" "=W")
846 (match_operand:BLK 2 "memory_operand" "W"))
847 (use (match_operand:SI 0))
848 (clobber (match_dup 0))
849 ]
850"0"
851"stpcpy %b1,%b2 # %0 %b1 %b2"
852)
853
76715c32 854(define_insn "cpymemsi"
d3adfe5d
JB
855 [(set (match_operand:BLK 0 "memory_operand" "=W,BW")
856 (match_operand:BLK 1 "memory_operand" "W,BW"))
857 (use (match_operand:SI 2 "ft32_imm_operand" "KA,KA"))
fef939d6
JB
858 (use (match_operand:SI 3))
859 ]
860 ""
d3adfe5d 861 "memcpy.%d3 %b0,%b1,%2 "
fef939d6
JB
862)
863
864(define_insn "setmemsi"
d3adfe5d
JB
865 [(set (match_operand:BLK 0 "memory_operand" "=BW") (unspec:BLK [
866 (use (match_operand:QI 2 "register_operand" "r"))
867 (use (match_operand:SI 1 "ft32_imm_operand" "KA"))
fef939d6
JB
868 ] UNSPEC_SETMEM))
869 (use (match_operand:SI 3))
870 ]
871 ""
872 "memset.%d3 %b0,%2,%1"
873)
874
875(define_insn "strlensi"
876 [(set (match_operand:SI 0 "register_operand" "=r")
877 (unspec:SI [(match_operand:BLK 1 "memory_operand" "W")
878 (match_operand:QI 2 "const_int_operand" "")
879 (match_operand:SI 3 "ft32_rimm_operand" "")]
880 UNSPEC_STRLEN))]
881 ""
882 "strlen.%d3 %0,%b1 # %2 %3"
883)
884
885;; -------------------------------------------------------------------------
886;; Prologue & Epilogue
887;; -------------------------------------------------------------------------
888
889(define_expand "prologue"
890 [(clobber (const_int 0))]
891 ""
892{
893 extern void ft32_expand_prologue();
894 ft32_expand_prologue ();
895 DONE;
896})
897
6d82151f 898
fef939d6
JB
899(define_expand "epilogue"
900 [(return)]
901 ""
902{
903 extern void ft32_expand_epilogue();
904 ft32_expand_epilogue ();
905 DONE;
906})
907
908(define_insn "link"
909 [
910;; (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
911;; (reg:SI FP_REG))
912 (set (match_operand:SI 0)
913 (reg:SI SP_REG))
914 (set (reg:SI SP_REG)
915 (plus:SI (reg:SI SP_REG)
916 (match_operand:SI 1 "general_operand" "L")))]
917 ""
918 "link %0,%m1"
919)
920
921(define_insn "unlink"
922 [(set (reg:SI FP_REG)
923 (mem:SI (reg:SI FP_REG)))
924 (set (reg:SI SP_REG)
925 (plus:SI (reg:SI FP_REG)
926 (const_int 4)))]
927 ""
928 "unlink $r29"
929)
930
931(define_insn "returner"
932 [(return)]
933 "reload_completed"
934 "return")
935
d48ab010
JB
936(define_insn "pretend_returner"
937 [(set (reg:SI SP_REG)
938 (plus:SI (reg:SI SP_REG)
939 (match_operand:SI 0)))
940 (return)]
941 "reload_completed"
942 "pop.l $cc\;add.l $sp,$sp,%0\;jmpi $cc")
943
fef939d6
JB
944(define_insn "returner24"
945 [
946 (set (reg:SI SP_REG)
947 (plus:SI
948 (reg:SI SP_REG)
949 (const_int 24)))
950 (return)]
951 ""
952 "jmp __epilog24")