]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/ft32/ft32.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / ft32 / ft32.md
1 ;; Machine description for FT32
2 ;; Copyright (C) 2015-2020 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 "!TARGET_NODIV"
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 "!TARGET_NODIV"
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 "!TARGET_NODIV"
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 "!TARGET_NODIV"
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 (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
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 ""
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 })
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
854 (define_insn "cpymemsi"
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"))
858 (use (match_operand:SI 3))
859 ]
860 ""
861 "memcpy.%d3 %b0,%b1,%2 "
862 )
863
864 (define_insn "setmemsi"
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"))
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
898
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
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
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")