1 ;; XSTORMY16 Machine description template
2 ;; Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
3 ;; Contributed by Red Hat, Inc.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
41 ;; Q post-inc mem (push)
42 ;; R pre-dec mem (pop)
45 ;; U -inf..1 or 16..inf
49 ;; ::::::::::::::::::::
53 ;; ::::::::::::::::::::
55 ; Categorize branches for the conditional in the length attribute.
56 (define_attr "branch_class" "notdirectbranch,br12,bcc12,bcc8p2,bcc8p4"
57 (const_string "notdirectbranch"))
59 ; The length of an instruction, used for branch shortening.
60 (define_attr "length" ""
62 [(eq_attr "branch_class" "br12")
63 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2046))
64 (lt (minus (match_dup 0) (pc)) (const_int 2048)))
67 (eq_attr "branch_class" "bcc12")
68 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
69 (lt (minus (match_dup 0) (pc)) (const_int 2048)))
72 (eq_attr "branch_class" "bcc8p2")
73 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -124))
74 (lt (minus (match_dup 0) (pc)) (const_int 128)))
77 (eq_attr "branch_class" "bcc8p4")
78 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -122))
79 (lt (minus (match_dup 0) (pc)) (const_int 128)))
84 ; The operand which determines the setting of Rpsw.
85 ; The numbers indicate the operand number,
86 ; 'clobber' indicates it is changed in some unspecified way
87 ; 'nop' means it is not changed.
88 (define_attr "psw_operand" "clobber,nop,0,1,2,3,4" (const_string "0"))
90 (define_asm_attributes [(set_attr "length" "4")
91 (set_attr "psw_operand" "clobber")])
94 ;; ::::::::::::::::::::
98 ;; ::::::::::::::::::::
99 ;; push/pop qi and hi are here as separate insns rather than part of
100 ;; the movqi/hi patterns because we need to ensure that reload isn't
101 ;; passed anything it can't cope with. Without these patterns, we
104 ;; (set (mem (post_inc (sp))) mem (post_inc (reg)))
106 ;; If, in this example, reg needs reloading, reload will read reg from
107 ;; the stack , adjust sp, and store reg back at what is now the wrong
108 ;; offset. By using separate patterns for push and pop we ensure that
109 ;; insns like this one are never generated.
111 (define_insn "pushqi"
112 [(set (mem:QI (post_inc (reg:HI 15)))
113 (match_operand:QI 0 "register_operand" "r"))]
116 [(set_attr "psw_operand" "nop")
117 (set_attr "length" "2")])
120 [(set (match_operand:QI 0 "register_operand" "=r")
121 (mem:QI (pre_dec (reg:HI 15))))]
124 [(set_attr "psw_operand" "nop")
125 (set_attr "length" "2")])
127 (define_expand "movqi"
128 [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "")
129 (match_operand:QI 1 "general_operand" ""))]
131 "{ xstormy16_expand_move (QImode, operands[0], operands[1]); DONE; }")
133 (define_insn "*movqi_internal"
134 [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S")
135 (match_operand:QI 1 "general_operand" "r,e,m,i,i,i,i"))]
145 [(set_attr_alternative "length"
147 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
150 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
157 (set_attr "psw_operand" "0,0,0,0,nop,0,nop")])
159 (define_insn "pushhi"
160 [(set (mem:HI (post_inc (reg:HI 15)))
161 (match_operand:HI 0 "register_operand" "r"))]
164 [(set_attr "psw_operand" "nop")
165 (set_attr "length" "2")])
168 [(set (match_operand:HI 0 "register_operand" "=r")
169 (mem:HI (pre_dec (reg:HI 15))))]
172 [(set_attr "psw_operand" "nop")
173 (set_attr "length" "2")])
175 (define_expand "movhi"
176 [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "")
177 (match_operand:HI 1 "xs_hi_general_operand" ""))]
179 "{ xstormy16_expand_move (HImode, operands[0], operands[1]); DONE; }")
181 (define_insn "*movhi_internal"
182 [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S")
183 (match_operand:HI 1 "xs_hi_general_operand" "r,e,m,L,L,i,i"))]
193 [(set_attr_alternative "length"
195 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
198 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
205 (set_attr "psw_operand" "0,0,0,0,nop,0,nop")])
207 (define_expand "movsi"
208 [(set (match_operand:SI 0 "nonimmediate_operand" "")
209 (match_operand:SI 1 "general_operand" ""))]
211 "{ xstormy16_expand_move (SImode, operands[0], operands[1]); DONE; }")
213 (define_insn_and_split "*movsi_internal"
214 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Q,r,m,e,&e,e,r,S")
215 (match_operand:SI 1 "general_operand" "r,r,R,e,o, V,L,i,i"))]
220 "{ xstormy16_split_move (SImode, operands[0], operands[1]); DONE; }"
221 [(set_attr_alternative "length"
225 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
228 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
231 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
239 ;; ::::::::::::::::::::
243 ;; ::::::::::::::::::::
245 (define_insn "extendqihi2"
246 [(set (match_operand:HI 0 "register_operand" "=r")
247 (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
251 (define_insn "zero_extendqihi2"
252 [(set (match_operand:HI 0 "register_operand" "=e,r")
253 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,0")))]
257 shl %0,#8\n\tshr %0,#8"
258 [(set_attr "psw_operand" "nop,0")
259 (set_attr_alternative "length"
264 ;; ::::::::::::::::::::
266 ;; :: Bit field extraction
268 ;; ::::::::::::::::::::
270 ;; Extract an unsigned bit field
271 ;(define_insn "extzv"
272 ; [(set (match_operand:SI 0 "register_operand" "=r")
273 ; (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
274 ; (match_operand:SI 2 "const_int_operand" "n")
275 ; (match_operand:SI 3 "const_int_operand" "n")))]
277 ; "extzv %0,%1,%2,%3"
278 ; [(set_attr "length" "4")])
280 ;; Insert a bit field
282 ; [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
283 ; (match_operand:SI 1 "const_int_operand" "n")
284 ; (match_operand:SI 2 "const_int_operand" "n"))
285 ; (match_operand:SI 3 "nonmemory_operand" "ri"))]
288 ; [(set_attr "length" "4")])
291 ;; ::::::::::::::::::::
293 ;; :: 16 bit Integer arithmetic
295 ;; ::::::::::::::::::::
298 ; Operand 3 is marked earlyclobber because that helps reload
299 ; to generate better code---this pattern will never need the
300 ; carry register as an input, and some output reloads or input
301 ; reloads might need to use it. In fact, without the '&' reload
302 ; will fail in some cases.
303 ; Note that the 'Z' constraint matches "add $reg,0", which reload
304 ; will occasionally emit. We avoid the "add $reg,imm" match because
305 ; it clobbers the carry.
306 (define_insn "addhi3"
307 [(set (match_operand:HI 0 "register_operand" "=r,r,r,T,T,r,r,r")
308 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0,0,0")
309 (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,Z,L,M,Ir,N,i")))
310 (clobber (match_scratch:BI 3 "=X,X,X,&y,&y,&y,&y,&y"))]
321 [(set_attr "length" "2,2,0,2,2,2,2,4")])
323 ; Reload can generate addition operations. The SECONDARY_RELOAD_CLASS
324 ; macro causes it to allocate the carry register; this pattern
325 ; shows it how to place the register in RTL to make the addition work.
326 (define_expand "reload_inhi"
327 [(parallel [(set (match_operand:HI 0 "register_operand" "=r")
328 (match_operand:HI 1 "xstormy16_carry_plus_operand" ""))
329 (clobber (match_operand:BI 2 "" "=&y"))])]
331 "if (! rtx_equal_p (operands[0], XEXP (operands[1], 0)))
333 emit_insn (gen_rtx_SET (VOIDmode, operands[0], XEXP (operands[1], 0)));
334 operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]), operands[0],
335 XEXP (operands[1], 1));
339 (define_insn "addchi4"
340 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
341 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
342 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
343 (set (match_operand:BI 3 "register_operand" "=y,y,y")
344 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
345 (zero_extend:SI (match_dup 2)))
352 [(set_attr "length" "2,2,4")])
354 (define_insn "addchi5"
355 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
356 (plus:HI (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
357 (zero_extend:HI (match_operand:BI 3
360 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
361 (set (match_operand:BI 4 "register_operand" "=y,y,y")
362 (truncate:BI (lshiftrt:SI (plus:SI (plus:SI
363 (zero_extend:SI (match_dup 1))
364 (zero_extend:SI (match_dup 3)))
365 (zero_extend:SI (match_dup 2)))
372 [(set_attr "length" "2,2,4")])
375 ; Operand 3 is marked earlyclobber because that helps reload
376 ; to generate better code---this pattern will never need the
377 ; carry register as an input, and some output reloads or input
378 ; reloads might need to use it. In fact, without the '&' reload
379 ; will fail in some cases.
380 (define_insn "subhi3"
381 [(set (match_operand:HI 0 "register_operand" "=r,r,T,T,r,r,r")
382 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0,0,0,0,0")
383 (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,L,M,rI,M,i")))
384 (clobber (match_scratch:BI 3 "=X,X,&y,&y,&y,&y,&y"))]
394 [(set_attr "length" "2,2,2,2,2,2,4")])
396 (define_insn "subchi4"
397 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
398 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
399 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
400 (set (match_operand:BI 3 "register_operand" "=y,y,y")
401 (truncate:BI (lshiftrt:SI (minus:SI (zero_extend:SI (match_dup 1))
402 (zero_extend:SI (match_dup 2)))
409 [(set_attr "length" "2,2,4")])
411 (define_insn "subchi5"
412 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
413 (minus:HI (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
414 (zero_extend:HI (match_operand:BI 3
417 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
418 (set (match_operand:BI 4 "register_operand" "=y,y,y")
419 (truncate:BI (lshiftrt:SI (minus:SI (minus:SI
420 (zero_extend:SI (match_dup 1))
421 (zero_extend:SI (match_dup 3)))
422 (zero_extend:SI (match_dup 2)))
429 [(set_attr "length" "2,2,4")])
431 ; Basic multiplication
432 (define_insn "mulhi3"
433 [(set (match_operand:HI 0 "register_operand" "=a")
434 (mult:HI (match_operand:HI 1 "register_operand" "%a")
435 (match_operand:HI 2 "register_operand" "c")))
436 (clobber (match_scratch:HI 3 "=b"))
440 [(set_attr "psw_operand" "nop")])
442 ;; Unsigned multiplication producing 64 bit results from 32 bit inputs
443 ; The constraint on operand 0 is 't' because it is actually two regs
444 ; long, and both regs must match the constraint.
445 (define_insn "umulhisi3"
446 [(set (match_operand:SI 0 "register_operand" "=t")
447 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%a"))
448 (zero_extend:SI (match_operand:HI 2 "register_operand" "c"))))
452 [(set_attr "psw_operand" "nop")])
454 ;; Unsigned division giving both quotient and remainder
455 (define_insn "udivmodhi4"
456 [(set (match_operand:HI 0 "register_operand" "=a")
457 (udiv:HI (match_operand:HI 1 "register_operand" "a")
458 (match_operand:HI 2 "register_operand" "c")))
459 (set (match_operand:HI 3 "register_operand" "=b")
460 (umod:HI (match_dup 1)
464 [(set_attr "psw_operand" "nop")])
466 ;; Signed division giving both quotient and remainder
467 (define_insn "divmodhi4"
468 [(set (match_operand:HI 0 "register_operand" "=a")
469 (div:HI (match_operand:HI 1 "register_operand" "a")
470 (match_operand:HI 2 "register_operand" "c")))
471 (set (match_operand:HI 3 "register_operand" "=b")
472 (mod:HI (match_dup 1)
476 [(set_attr "psw_operand" "nop")])
478 ;; Signed 32/16 division
479 (define_insn "sdivlh"
480 [(set (match_operand:HI 0 "register_operand" "=a")
481 (div:HI (match_operand:SI 2 "register_operand" "t")
482 (match_operand:HI 3 "register_operand" "c")))
483 (set (match_operand:HI 1 "register_operand" "=b")
484 (mod:HI (match_dup 2)
488 [(set_attr "psw_operand" "nop")])
490 ;; Unsigned 32/16 division
491 (define_insn "udivlh"
492 [(set (match_operand:HI 0 "register_operand" "=a")
493 (udiv:HI (match_operand:SI 2 "register_operand" "t")
494 (match_operand:HI 3 "register_operand" "c")))
495 (set (match_operand:HI 1 "register_operand" "=b")
496 (umod:HI (match_dup 2)
500 [(set_attr "psw_operand" "nop")])
504 (define_expand "neghi2"
505 [(set (match_operand:HI 0 "register_operand" "")
506 (not:HI (match_operand:HI 1 "register_operand" "")))
507 (parallel [(set (match_dup 0) (plus:HI (match_dup 0) (const_int 1)))
508 (clobber (match_scratch:BI 3 ""))])]
513 ;; ::::::::::::::::::::
515 ;; :: 16 bit Integer Shifts and Rotates
517 ;; ::::::::::::::::::::
519 ;; Arithmetic Shift Left
520 (define_insn "ashlhi3"
521 [(set (match_operand:HI 0 "register_operand" "=r")
522 (ashift:HI (match_operand:HI 1 "register_operand" "0")
523 (match_operand:HI 2 "nonmemory_operand" "ri")))
524 (clobber (match_scratch:BI 3 "=y"))]
528 ;; Arithmetic Shift Right
529 (define_insn "ashrhi3"
530 [(set (match_operand:HI 0 "register_operand" "=r")
531 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
532 (match_operand:HI 2 "nonmemory_operand" "ri")))
533 (clobber (match_scratch:BI 3 "=y"))]
537 ;; Logical Shift Right
538 (define_insn "lshrhi3"
539 [(set (match_operand:HI 0 "register_operand" "=r")
540 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
541 (match_operand:HI 2 "nonmemory_operand" "ri")))
542 (clobber (match_scratch:BI 3 "=y"))]
547 ;; ::::::::::::::::::::
549 ;; :: 16 Bit Integer Logical operations
551 ;; ::::::::::::::::::::
553 ;; Logical AND, 16 bit integers
554 (define_insn "andhi3"
555 [(set (match_operand:HI 0 "register_operand" "=T,r,r,r")
556 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0")
557 (match_operand:HI 2 "nonmemory_operand" "L,r,K,i")))]
564 [(set_attr "length" "2,2,2,4")])
566 ;; Inclusive OR, 16 bit integers
567 (define_insn "iorhi3"
568 [(set (match_operand:HI 0 "register_operand" "=T,r,r,r")
569 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0")
570 (match_operand:HI 2 "nonmemory_operand" "L,r,J,i")))]
577 [(set_attr "length" "2,2,2,4")])
579 ;; Exclusive OR, 16 bit integers
580 (define_insn "xorhi3"
581 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
582 (xor:HI (match_operand:HI 1 "register_operand" "%0,0,0")
583 (match_operand:HI 2 "nonmemory_operand" "L,r,i")))]
589 [(set_attr "length" "2,2,4")])
591 ;; One's complement, 16 bit integers
592 (define_insn "one_cmplhi2"
593 [(set (match_operand:HI 0 "register_operand" "=r")
594 (not:HI (match_operand:HI 1 "register_operand" "0")))]
599 ;; ::::::::::::::::::::
601 ;; :: 32 bit Integer arithmetic
603 ;; ::::::::::::::::::::
606 (define_insn_and_split "addsi3"
607 [(set (match_operand:SI 0 "register_operand" "=r")
608 (plus:SI (match_operand:SI 1 "register_operand" "%0")
609 (match_operand:SI 2 "nonmemory_operand" "ri")))
610 (clobber (match_scratch:BI 3 "=y"))]
615 "{ xstormy16_expand_arith (SImode, PLUS, operands[0], operands[1],
616 operands[2], operands[3]); DONE; } "
617 [(set_attr "length" "4")])
620 (define_insn_and_split "subsi3"
621 [(set (match_operand:SI 0 "register_operand" "=r")
622 (minus:SI (match_operand:SI 1 "register_operand" "0")
623 (match_operand:SI 2 "nonmemory_operand" "ri")))
624 (clobber (match_scratch:BI 3 "=y"))]
629 "{ xstormy16_expand_arith (SImode, MINUS, operands[0], operands[1],
630 operands[2], operands[3]); DONE; } "
631 [(set_attr "length" "4")])
633 (define_expand "negsi2"
634 [(parallel [(set (match_operand:SI 0 "register_operand" "")
635 (neg:SI (match_operand:SI 1 "register_operand" "")))
636 (clobber (match_scratch:BI 2 ""))])]
638 "{ operands[2] = gen_reg_rtx (HImode);
639 operands[3] = gen_reg_rtx (BImode); }")
641 (define_insn_and_split "*negsi2_internal"
642 [(set (match_operand:SI 0 "register_operand" "=&r")
643 (neg:SI (match_operand:SI 1 "register_operand" "r")))
644 (clobber (match_scratch:BI 2 "=y"))]
649 "{ xstormy16_expand_arith (SImode, NEG, operands[0], operands[0],
650 operands[1], operands[2]); DONE; }")
652 ;; ::::::::::::::::::::
654 ;; :: 32 bit Integer Shifts and Rotates
656 ;; ::::::::::::::::::::
658 ;; Arithmetic Shift Left
659 (define_expand "ashlsi3"
660 [(parallel [(set (match_operand:SI 0 "register_operand" "")
661 (ashift:SI (match_operand:SI 1 "register_operand" "")
662 (match_operand:SI 2 "const_int_operand" "")))
663 (clobber (match_dup 3))
664 (clobber (match_dup 4))])]
666 " if (! const_int_operand (operands[2], SImode)) FAIL;
667 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
669 ;; Arithmetic Shift Right
670 (define_expand "ashrsi3"
671 [(parallel [(set (match_operand:SI 0 "register_operand" "")
672 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
673 (match_operand:SI 2 "const_int_operand" "")))
674 (clobber (match_dup 3))
675 (clobber (match_dup 4))])]
677 " if (! const_int_operand (operands[2], SImode)) FAIL;
678 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
680 ;; Logical Shift Right
681 (define_expand "lshrsi3"
682 [(parallel [(set (match_operand:SI 0 "register_operand" "")
683 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
684 (match_operand:SI 2 "const_int_operand" "")))
685 (clobber (match_dup 3))
686 (clobber (match_dup 4))])]
688 " if (! const_int_operand (operands[2], SImode)) FAIL;
689 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
691 (define_insn "*shiftsi"
692 [(set (match_operand:SI 0 "register_operand" "=r,r")
693 (match_operator:SI 5 "shift_operator"
694 [(match_operand:SI 1 "register_operand" "0,0")
695 (match_operand:SI 2 "const_int_operand" "U,n")]))
696 (clobber (match_operand:BI 3 "register_operand" "=y,y"))
697 (clobber (match_operand:HI 4 "" "=X,r"))]
699 "* return xstormy16_output_shift (SImode, GET_CODE (operands[5]),
700 operands[0], operands[2], operands[4]);"
701 [(set_attr "length" "6,10")
702 (set_attr "psw_operand" "clobber,clobber")])
705 ;; ::::::::::::::::::::
709 ;; ::::::::::::::::::::
711 ;; Note, we store the operands in the comparison insns, and use them later
712 ;; when generating the branch or scc operation.
714 ;; First the routines called by the machine independent part of the compiler
715 (define_expand "cmphi"
717 (compare (match_operand:HI 0 "register_operand" "")
718 (match_operand:HI 1 "nonmemory_operand" "")))]
722 xstormy16_compare_op0 = operands[0];
723 xstormy16_compare_op1 = operands[1];
727 ; There are no real SImode comparisons, but some can be emulated
728 ; by performing a SImode subtract and looking at the condition flags.
729 (define_expand "cmpsi"
731 (compare (match_operand:SI 0 "register_operand" "")
732 (match_operand:SI 1 "nonmemory_operand" "")))]
736 xstormy16_compare_op0 = operands[0];
737 xstormy16_compare_op1 = operands[1];
742 ;; ::::::::::::::::::::
746 ;; ::::::::::::::::::::
749 [(use (match_operand 0 "" ""))]
751 "{ xstormy16_emit_cbranch (EQ, operands[0]); DONE; }")
754 [(use (match_operand 0 "" ""))]
756 "{ xstormy16_emit_cbranch (NE, operands[0]); DONE; }")
759 [(use (match_operand 0 "" ""))]
761 "{ xstormy16_emit_cbranch (GE, operands[0]); DONE; }")
764 [(use (match_operand 0 "" ""))]
766 "{ xstormy16_emit_cbranch (GT, operands[0]); DONE; }")
769 [(use (match_operand 0 "" ""))]
771 "{ xstormy16_emit_cbranch (LE, operands[0]); DONE; }")
774 [(use (match_operand 0 "" ""))]
776 "{ xstormy16_emit_cbranch (LT, operands[0]); DONE; }")
778 (define_expand "bgeu"
779 [(use (match_operand 0 "" ""))]
781 "{ xstormy16_emit_cbranch (GEU, operands[0]); DONE; }")
783 (define_expand "bgtu"
784 [(use (match_operand 0 "" ""))]
786 "{ xstormy16_emit_cbranch (GTU, operands[0]); DONE; }")
788 (define_expand "bleu"
789 [(use (match_operand 0 "" ""))]
791 "{ xstormy16_emit_cbranch (LEU, operands[0]); DONE; }")
793 (define_expand "bltu"
794 [(use (match_operand 0 "" ""))]
796 "{ xstormy16_emit_cbranch (LTU, operands[0]); DONE; }")
799 (define_insn "*cbranchhi"
801 (if_then_else (match_operator:HI 1 "comparison_operator"
802 [(match_operand:HI 2 "nonmemory_operand"
804 (match_operand:HI 3 "nonmemory_operand"
806 (label_ref (match_operand 0 "" ""))
808 (clobber (match_operand:BI 4 "" "=&y,&y,&y"))]
812 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 0, insn);
814 [(set_attr "branch_class" "bcc12")
815 (set_attr "psw_operand" "0,0,1")])
817 (define_insn "*cbranchhi_neg"
819 (if_then_else (match_operator:HI 1 "comparison_operator"
820 [(match_operand:HI 2 "nonmemory_operand"
822 (match_operand:HI 3 "nonmemory_operand"
825 (label_ref (match_operand 0 "" ""))))
826 (clobber (match_operand:BI 4 "" "=&y,&y,&y"))]
830 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 1, insn);
832 [(set_attr "branch_class" "bcc12")
833 (set_attr "psw_operand" "0,0,1")])
835 (define_insn "*eqbranchsi"
837 (if_then_else (match_operator:SI 1 "equality_operator"
838 [(match_operand:SI 2 "register_operand"
841 (label_ref (match_operand 0 "" ""))
843 ;; Although I would greatly like the 'match_dup' in the following line
844 ;; to actually be a register constraint, there is (at the time of writing) no
845 ;; way for reload to insert an output reload on the edges out of a branch.
846 ;; If reload is fixed to use insert_insn_on_edge, this can be changed.
847 (clobber (match_dup 2))]
851 return xstormy16_output_cbranch_si (operands[1], \"%l0\", 0, insn);
853 [(set_attr "branch_class" "bcc8p2")
854 (set_attr "psw_operand" "clobber")])
856 (define_insn_and_split "*ineqbranchsi"
858 (if_then_else (match_operator:SI 1 "xstormy16_ineqsi_operator"
859 [(match_operand:SI 2 "register_operand"
861 (match_operand:SI 3 "nonmemory_operand"
863 (label_ref (match_operand 0 "" ""))
865 ;; Although I would greatly like the 'match_dup' in the following line
866 ;; to actually be a register constraint, there is (at the time of writing) no
867 ;; way for reload to insert an output reload on the edges out of a branch.
868 ;; If reload is fixed to use insert_insn_on_edge, this can be changed,
869 ;; preferably to a 'minus' operand that explains the actual operation, like:
870 ; (set (match_operand 5 "register_operand" "=2")
871 ; (minus:SI (match_operand 6 "register_operand" "2")
872 ; (match_operand 7 "register_operand" "3")))
873 (clobber (match_dup 2))
874 (clobber (match_operand:BI 4 "" "=&y"))]
879 "{ xstormy16_split_cbranch (SImode, operands[0], operands[1], operands[2],
880 operands[4]); DONE; }"
881 [(set_attr "length" "8")])
883 (define_insn "*ineqbranch_1"
885 (if_then_else (match_operator:HI 5 "xstormy16_ineqsi_operator"
886 [(minus:HI (match_operand:HI 1 "register_operand"
888 (zero_extend:HI (match_operand:BI 4
891 (match_operand:HI 3 "nonmemory_operand" "L,Ir,i")])
892 (label_ref (match_operand 0 "" ""))
894 (set (match_operand:HI 2 "register_operand" "=1,1,1")
895 (minus:HI (minus:HI (match_dup 1) (zero_extend:HI (match_dup 4)))
897 (clobber (match_operand:BI 6 "" "=y,y,y"))]
901 return xstormy16_output_cbranch_si (operands[5], \"%l0\", 0, insn);
903 [(set_attr "branch_class" "bcc8p2,bcc8p2,bcc8p4")
904 (set_attr "psw_operand" "2,2,2")])
907 ;; ::::::::::::::::::::
909 ;; :: Call and branch instructions
911 ;; ::::::::::::::::::::
913 ;; Subroutine call instruction returning no value. Operand 0 is the function
914 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
915 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
916 ;; registers used as operands.
918 ;; On most machines, operand 2 is not actually stored into the RTL pattern. It
919 ;; is supplied for the sake of some RISC machines which need to put this
920 ;; information into the assembler code; they can put it in the RTL instead of
923 (define_expand "call"
924 [(call (match_operand:HI 0 "memory_operand" "m")
925 (match_operand 1 "" ""))
926 (use (match_operand 2 "immediate_operand" ""))]
928 "xstormy16_expand_call (NULL_RTX, operands[0], operands[1]); DONE;")
930 ;; Subroutine call instruction returning a value. Operand 0 is the hard
931 ;; register in which the value is returned. There are three more operands, the
932 ;; same as the three operands of the `call' instruction (but with numbers
933 ;; increased by one).
935 ;; Subroutines that return `BLKmode' objects use the `call' insn.
937 (define_expand "call_value"
938 [(set (match_operand 0 "register_operand" "=r")
939 (call (match_operand:HI 1 "memory_operand" "m")
940 (match_operand:SI 2 "" "")))
941 (use (match_operand 3 "immediate_operand" ""))]
943 "xstormy16_expand_call (operands[0], operands[1], operands[2]); DONE;")
945 (define_insn "*call_internal"
946 [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
947 (match_operand 1 "" ""))
948 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
953 [(set_attr "length" "4,2")
954 (set_attr "psw_operand" "clobber")])
956 (define_insn "*call_value_internal"
957 [(set (match_operand 3 "register_operand" "=r,r")
958 (call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
959 (match_operand 1 "" "")))
960 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
965 [(set_attr "length" "4,2")
966 (set_attr "psw_operand" "clobber")])
969 (define_expand "return"
974 (define_insn "return_internal"
978 [(set_attr "psw_operand" "nop")])
980 (define_insn "return_internal_interrupt"
982 (unspec_volatile [(const_int 0)] 1)]
985 [(set_attr "psw_operand" "clobber")])
987 ;; Normal unconditional jump
989 [(set (pc) (label_ref (match_operand 0 "" "")))]
993 return xstormy16_output_cbranch_hi (NULL_RTX, \"%l0\", 0, insn);
995 [(set_attr "branch_class" "br12")
996 (set_attr "psw_operand" "nop")])
998 ;; Indirect jump through a register
999 (define_expand "indirect_jump"
1000 [(set (match_dup 1) (const_int 0))
1001 (parallel [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1002 (use (match_dup 1))])]
1004 "operands[1] = gen_reg_rtx (HImode);")
1007 [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1008 (use (match_operand:HI 1 "register_operand" "z"))]
1011 [(set_attr "length" "4")
1012 (set_attr "psw_operand" "nop")])
1014 ;; Table-based switch statements.
1015 (define_expand "casesi"
1016 [(use (match_operand:SI 0 "register_operand" ""))
1017 (use (match_operand:SI 1 "immediate_operand" ""))
1018 (use (match_operand:SI 2 "immediate_operand" ""))
1019 (use (label_ref (match_operand 3 "" "")))
1020 (use (label_ref (match_operand 4 "" "")))]
1024 xstormy16_expand_casesi (operands[0], operands[1], operands[2],
1025 operands[3], operands[4]);
1029 (define_insn "tablejump_pcrel"
1030 [(set (pc) (mem:HI (plus:HI (pc)
1031 (match_operand:HI 0 "register_operand" "r"))))
1032 (use (label_ref:SI (match_operand 1 "" "")))]
1035 [(set_attr "psw_operand" "nop")])
1038 ;; ::::::::::::::::::::
1040 ;; :: Prologue and Epilogue instructions
1042 ;; ::::::::::::::::::::
1044 ;; Called after register allocation to add any instructions needed for
1045 ;; the prologue. Using a prologue insn is favored compared to putting
1046 ;; all of the instructions in the TARGET_ASM_FUNCTION_PROLOGUE macro,
1047 ;; since it allows the scheduler to intermix instructions with the
1048 ;; saves of the caller saved registers. In some cases, it might be
1049 ;; necessary to emit a barrier instruction as the last insn to prevent
1051 (define_expand "prologue"
1056 xstormy16_expand_prologue ();
1060 ;; Called after register allocation to add any instructions needed for
1061 ;; the epilogue. Using an epilogue insn is favored compared to putting
1062 ;; all of the instructions in the TARGET_ASM_FUNCTION_EPILOGUE macro,
1063 ;; since it allows the scheduler to intermix instructions with the
1064 ;; restires of the caller saved registers. In some cases, it might be
1065 ;; necessary to emit a barrier instruction as the first insn to
1066 ;; prevent such scheduling.
1067 (define_expand "epilogue"
1072 xstormy16_expand_epilogue ();
1077 ;; ::::::::::::::::::::
1079 ;; :: Miscellaneous instructions
1081 ;; ::::::::::::::::::::
1083 ;; No operation, needed in case the user uses -g but not -O.
1088 [(set_attr "psw_operand" "nop")])
1090 ;; Pseudo instruction that prevents the scheduler from moving code above this
1092 (define_insn "blockage"
1093 [(unspec_volatile [(const_int 0)] 0)]
1096 [(set_attr "length" "0")
1097 (set_attr "psw_operand" "nop")])