1 ;; XSTORMY16 Machine description template
2 ;; Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
3 ;; 2010 Free Software Foundation, Inc.
4 ;; Contributed by Red Hat, Inc.
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>.
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
40 ;; Q post-inc mem (push)
41 ;; R pre-dec mem (pop)
44 ;; U -inf..1 or 16..inf
53 ;; ::::::::::::::::::::
57 ;; ::::::::::::::::::::
59 ; Categorize branches for the conditional in the length attribute.
60 (define_attr "branch_class" "notdirectbranch,br12,bcc12,bcc8p2,bcc8p4"
61 (const_string "notdirectbranch"))
63 ; The length of an instruction, used for branch shortening.
64 (define_attr "length" ""
66 [(eq_attr "branch_class" "br12")
67 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2046))
68 (lt (minus (match_dup 0) (pc)) (const_int 2048)))
71 (eq_attr "branch_class" "bcc12")
72 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
73 (lt (minus (match_dup 0) (pc)) (const_int 2048)))
76 (eq_attr "branch_class" "bcc8p2")
77 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -124))
78 (lt (minus (match_dup 0) (pc)) (const_int 128)))
81 (eq_attr "branch_class" "bcc8p4")
82 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -122))
83 (lt (minus (match_dup 0) (pc)) (const_int 128)))
88 ; The operand which determines the setting of Rpsw.
89 ; The numbers indicate the operand number,
90 ; 'clobber' indicates it is changed in some unspecified way
91 ; 'nop' means it is not changed.
92 (define_attr "psw_operand" "clobber,nop,0,1,2,3,4" (const_string "0"))
94 (define_asm_attributes [(set_attr "length" "4")
95 (set_attr "psw_operand" "clobber")])
97 (include "predicates.md")
98 (include "constraints.md")
100 ;; ::::::::::::::::::::
104 ;; ::::::::::::::::::::
105 ;; push/pop qi and hi are here as separate insns rather than part of
106 ;; the movqi/hi patterns because we need to ensure that reload isn't
107 ;; passed anything it can't cope with. Without these patterns, we
110 ;; (set (mem (post_inc (sp))) mem (post_inc (reg)))
112 ;; If, in this example, reg needs reloading, reload will read reg from
113 ;; the stack , adjust sp, and store reg back at what is now the wrong
114 ;; offset. By using separate patterns for push and pop we ensure that
115 ;; insns like this one are never generated.
117 (define_insn "pushqi1"
118 [(set (mem:QI (post_inc (reg:HI 15)))
119 (match_operand:QI 0 "register_operand" "r"))]
122 [(set_attr "psw_operand" "nop")
123 (set_attr "length" "2")])
125 (define_insn "popqi1"
126 [(set (match_operand:QI 0 "register_operand" "=r")
127 (mem:QI (pre_dec (reg:HI 15))))]
130 [(set_attr "psw_operand" "nop")
131 (set_attr "length" "2")])
133 (define_expand "movqi"
134 [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "")
135 (match_operand:QI 1 "general_operand" ""))]
137 { xstormy16_expand_move (QImode, operands[0], operands[1]);
141 (define_insn "movqi_internal"
142 [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,e")
143 (match_operand:QI 1 "general_operand" "r,e,m,i,i,i,i,ie,W"))]
155 [(set_attr_alternative "length"
157 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
160 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
169 (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")])
171 (define_insn "pushhi1"
172 [(set (mem:HI (post_inc (reg:HI 15)))
173 (match_operand:HI 0 "register_operand" "r"))]
176 [(set_attr "psw_operand" "nop")
177 (set_attr "length" "2")])
179 (define_insn "pophi1"
180 [(set (match_operand:HI 0 "register_operand" "=r")
181 (mem:HI (pre_dec (reg:HI 15))))]
184 [(set_attr "psw_operand" "nop")
185 (set_attr "length" "2")])
187 (define_expand "movhi"
188 [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "")
189 (match_operand:HI 1 "xs_hi_general_operand" ""))]
191 { xstormy16_expand_move (HImode, operands[0], operands[1]);
195 (define_insn "movhi_internal"
196 [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,e")
197 (match_operand:HI 1 "xs_hi_general_operand" "r,e,m,L,L,i,i,ie,W"))]
209 [(set_attr_alternative "length"
211 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
214 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
223 (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")])
225 (define_expand "movsi"
226 [(set (match_operand:SI 0 "nonimmediate_operand" "")
227 (match_operand:SI 1 "general_operand" ""))]
229 { xstormy16_expand_move (SImode, operands[0], operands[1]);
233 (define_insn_and_split "*movsi_internal"
234 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Q,r,m,e,&e,e,r,S")
235 (match_operand:SI 1 "general_operand" "r,r,R,e,o, V,L,i,i"))]
240 { xstormy16_split_move (SImode, operands[0], operands[1]);
243 [(set_attr_alternative "length"
247 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
250 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
253 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
260 ;; ::::::::::::::::::::
264 ;; ::::::::::::::::::::
266 (define_insn "extendqihi2"
267 [(set (match_operand:HI 0 "register_operand" "=r")
268 (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
272 (define_insn "zero_extendqihi2"
273 [(set (match_operand:HI 0 "register_operand" "=e,r")
274 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,0")))]
278 shl %0,#8\n\tshr %0,#8"
279 [(set_attr "psw_operand" "nop,0")
280 (set_attr_alternative "length"
284 ;; ::::::::::::::::::::
286 ;; :: Bit field extraction
288 ;; ::::::::::::::::::::
290 ;; Extract an unsigned bit field
291 ;(define_insn "extzv"
292 ; [(set (match_operand:SI 0 "register_operand" "=r")
293 ; (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
294 ; (match_operand:SI 2 "const_int_operand" "n")
295 ; (match_operand:SI 3 "const_int_operand" "n")))]
297 ; "extzv %0,%1,%2,%3"
298 ; [(set_attr "length" "4")])
300 ;; Insert a bit field
302 ; [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
303 ; (match_operand:SI 1 "const_int_operand" "n")
304 ; (match_operand:SI 2 "const_int_operand" "n"))
305 ; (match_operand:SI 3 "nonmemory_operand" "ri"))]
308 ; [(set_attr "length" "4")])
311 ;; ::::::::::::::::::::
313 ;; :: 16-bit Integer arithmetic
315 ;; ::::::::::::::::::::
318 ; Note - the early clobber modifier is no longer needed on operand 3
319 ; and in fact can cause some reload spill failures if it is present.
320 ; Note that the 'Z' constraint matches "add $reg,0", which reload
321 ; will occasionally emit. We avoid the "add $reg,imm" match because
322 ; it clobbers the carry.
323 (define_insn "addhi3"
324 [(set (match_operand:HI 0 "register_operand" "=r,r,r,T,T,r,r,r")
325 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0,0,0")
326 (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,Z,L,M,Ir,N,i")))
327 (clobber (reg:BI CARRY_REG))]
338 [(set_attr "length" "2,2,0,2,2,2,2,4")])
340 (define_insn "addchi4"
341 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
342 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
343 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
344 (set (reg:BI CARRY_REG)
345 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
346 (zero_extend:SI (match_dup 2)))
353 [(set_attr "length" "2,2,4")])
355 (define_insn "addchi5"
356 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
357 (plus:HI (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
358 (zero_extend:HI (reg:BI CARRY_REG)))
359 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
360 (set (reg:BI CARRY_REG)
361 (truncate:BI (lshiftrt:SI (plus:SI (plus:SI
362 (zero_extend:SI (match_dup 1))
363 (zero_extend:SI (reg:BI CARRY_REG)))
364 (zero_extend:SI (match_dup 2)))
371 [(set_attr "length" "2,2,4")])
374 ; Operand 3 is marked earlyclobber because that helps reload
375 ; to generate better code---this pattern will never need the
376 ; carry register as an input, and some output reloads or input
377 ; reloads might need to use it. In fact, without the '&' reload
378 ; will fail in some cases.
379 (define_insn "subhi3"
380 [(set (match_operand:HI 0 "register_operand" "=r,r,T,T,r,r,r")
381 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0,0,0,0,0")
382 (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,L,M,rI,M,i")))
383 (clobber (reg:BI CARRY_REG))]
393 [(set_attr "length" "2,2,2,2,2,2,4")])
395 (define_insn "subchi4"
396 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
397 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
398 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
399 (set (reg:BI CARRY_REG)
400 (truncate:BI (lshiftrt:SI (minus:SI (zero_extend:SI (match_dup 1))
401 (zero_extend:SI (match_dup 2)))
408 [(set_attr "length" "2,2,4")])
410 (define_insn "subchi5"
411 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
412 (minus:HI (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
413 (zero_extend:HI (reg:BI CARRY_REG)))
414 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
415 (set (reg:BI CARRY_REG)
416 (truncate:BI (lshiftrt:SI (minus:SI (minus:SI
417 (zero_extend:SI (match_dup 1))
418 (zero_extend:SI (reg:BI CARRY_REG)))
419 (zero_extend:SI (match_dup 2)))
426 [(set_attr "length" "2,2,4")])
428 ; Basic multiplication
429 (define_insn "mulhi3"
430 [(set (match_operand:HI 0 "register_operand" "=a")
431 (mult:HI (match_operand:HI 1 "register_operand" "%a")
432 (match_operand:HI 2 "register_operand" "c")))
433 (clobber (match_scratch:HI 3 "=b"))
437 [(set_attr "psw_operand" "nop")])
439 ;; Unsigned multiplication producing 64-bit results from 32-bit inputs
440 ; The constraint on operand 0 is 't' because it is actually two regs
441 ; long, and both regs must match the constraint.
442 (define_insn "umulhisi3"
443 [(set (match_operand:SI 0 "register_operand" "=t")
444 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%a"))
445 (zero_extend:SI (match_operand:HI 2 "register_operand" "c"))))
449 [(set_attr "psw_operand" "nop")])
451 ;; Unsigned division giving both quotient and remainder
452 (define_insn "udivmodhi4"
453 [(set (match_operand:HI 0 "register_operand" "=a")
454 (udiv:HI (match_operand:HI 1 "register_operand" "a")
455 (match_operand:HI 2 "register_operand" "c")))
456 (set (match_operand:HI 3 "register_operand" "=b")
457 (umod:HI (match_dup 1)
461 [(set_attr "psw_operand" "nop")])
463 ;; Signed division giving both quotient and remainder
464 (define_insn "divmodhi4"
465 [(set (match_operand:HI 0 "register_operand" "=a")
466 (div:HI (match_operand:HI 1 "register_operand" "a")
467 (match_operand:HI 2 "register_operand" "c")))
468 (set (match_operand:HI 3 "register_operand" "=b")
469 (mod:HI (match_dup 1)
473 [(set_attr "psw_operand" "nop")])
475 ;; Signed 32/16 division
476 (define_insn "sdivlh"
477 [(set (match_operand:HI 0 "register_operand" "=a")
478 (div:HI (match_operand:SI 2 "register_operand" "t")
479 (match_operand:HI 3 "register_operand" "c")))
480 (set (match_operand:HI 1 "register_operand" "=b")
481 (mod:HI (match_dup 2)
485 [(set_attr "psw_operand" "nop")])
487 ;; Unsigned 32/16 division
488 (define_insn "udivlh"
489 [(set (match_operand:HI 0 "register_operand" "=a")
490 (udiv:HI (match_operand:SI 2 "register_operand" "t")
491 (match_operand:HI 3 "register_operand" "c")))
492 (set (match_operand:HI 1 "register_operand" "=b")
493 (umod:HI (match_dup 2)
497 [(set_attr "psw_operand" "nop")])
501 (define_expand "neghi2"
502 [(set (match_operand:HI 0 "register_operand" "")
503 (not:HI (match_operand:HI 1 "register_operand" "")))
504 (parallel [(set (match_dup 0) (plus:HI (match_dup 0) (const_int 1)))
505 (clobber (reg:BI CARRY_REG))])]
509 ;; ::::::::::::::::::::
511 ;; :: 16-bit Integer Shifts and Rotates
513 ;; ::::::::::::::::::::
515 ;; Arithmetic Shift Left
516 (define_insn "ashlhi3"
517 [(set (match_operand:HI 0 "register_operand" "=r")
518 (ashift:HI (match_operand:HI 1 "register_operand" "0")
519 (match_operand:HI 2 "nonmemory_operand" "ri")))
520 (clobber (reg:BI CARRY_REG))]
524 ;; Arithmetic Shift Right
525 (define_insn "ashrhi3"
526 [(set (match_operand:HI 0 "register_operand" "=r")
527 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
528 (match_operand:HI 2 "nonmemory_operand" "ri")))
529 (clobber (reg:BI CARRY_REG))]
533 ;; Logical Shift Right
534 (define_insn "lshrhi3"
535 [(set (match_operand:HI 0 "register_operand" "=r")
536 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
537 (match_operand:HI 2 "nonmemory_operand" "ri")))
538 (clobber (reg:BI CARRY_REG))]
542 ;; ::::::::::::::::::::
544 ;; :: 16-Bit Integer Logical operations
546 ;; ::::::::::::::::::::
548 ;; Logical AND, 16-bit integers
549 (define_insn "andhi3"
550 [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
551 (and:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
552 (match_operand:HI 2 "nonmemory_operand" "L,r,K,i,K")))]
560 [(set_attr "length" "2,2,2,4,2")])
563 [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
564 (and:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
565 (match_operand:HI 2 "xstormy16_onebit_clr_operand" "")))]
568 (and:QI (match_dup 4)
570 { int s = ((INTVAL (operands[2]) & 0xff) == 0xff) ? 1 : 0;
571 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
572 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
573 operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
574 operands[5] = GEN_INT (INTVAL (operands[5]) | ~ (HOST_WIDE_INT) 0xff);
577 ;; Inclusive OR, 16-bit integers
578 (define_insn "iorhi3"
579 [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
580 (ior:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
581 (match_operand:HI 2 "nonmemory_operand" "L,r,J,i,J")))]
589 [(set_attr "length" "2,2,2,4,2")])
592 [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
593 (ior:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
594 (match_operand:HI 2 "xstormy16_onebit_set_operand" "")))]
597 (ior:QI (match_dup 4)
599 { int s = ((INTVAL (operands[2]) & 0xff) == 0x00) ? 1 : 0;
600 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
601 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
602 operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
603 operands[5] = GEN_INT (INTVAL (operands[5]) & 0xff);
606 ;; Exclusive OR, 16-bit integers
607 (define_insn "xorhi3"
608 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
609 (xor:HI (match_operand:HI 1 "register_operand" "%0,0,0")
610 (match_operand:HI 2 "nonmemory_operand" "L,r,i")))]
616 [(set_attr "length" "2,2,4")])
618 ;; One's complement, 16-bit integers
619 (define_insn "one_cmplhi2"
620 [(set (match_operand:HI 0 "register_operand" "=r")
621 (not:HI (match_operand:HI 1 "register_operand" "0")))]
625 ;; ::::::::::::::::::::
627 ;; :: 32-bit Integer arithmetic
629 ;; ::::::::::::::::::::
632 (define_insn_and_split "addsi3"
633 [(set (match_operand:SI 0 "register_operand" "=r")
634 (plus:SI (match_operand:SI 1 "register_operand" "%0")
635 (match_operand:SI 2 "nonmemory_operand" "ri")))
636 (clobber (reg:BI CARRY_REG))]
641 { xstormy16_expand_arith (SImode, PLUS, operands[0], operands[1],
645 [(set_attr "length" "4")])
648 (define_insn_and_split "subsi3"
649 [(set (match_operand:SI 0 "register_operand" "=r")
650 (minus:SI (match_operand:SI 1 "register_operand" "0")
651 (match_operand:SI 2 "nonmemory_operand" "ri")))
652 (clobber (reg:BI CARRY_REG))]
657 { xstormy16_expand_arith (SImode, MINUS, operands[0], operands[1],
661 [(set_attr "length" "4")])
663 (define_expand "negsi2"
664 [(parallel [(set (match_operand:SI 0 "register_operand" "")
665 (neg:SI (match_operand:SI 1 "register_operand" "")))
666 (clobber (reg:BI CARRY_REG))])]
668 { operands[2] = gen_reg_rtx (HImode); })
670 (define_insn_and_split "*negsi2_internal"
671 [(set (match_operand:SI 0 "register_operand" "=&r")
672 (neg:SI (match_operand:SI 1 "register_operand" "r")))
673 (clobber (reg:BI CARRY_REG))]
678 { xstormy16_expand_arith (SImode, NEG, operands[0], operands[0],
683 ;; ::::::::::::::::::::
685 ;; :: 32-bit Integer Shifts and Rotates
687 ;; ::::::::::::::::::::
689 ;; Arithmetic Shift Left
690 (define_expand "ashlsi3"
691 [(parallel [(set (match_operand:SI 0 "register_operand" "")
692 (ashift:SI (match_operand:SI 1 "register_operand" "")
693 (match_operand:SI 2 "const_int_operand" "")))
694 (clobber (reg:BI CARRY_REG))
695 (clobber (match_dup 3))])]
697 { if (! const_int_operand (operands[2], SImode))
699 operands[3] = gen_reg_rtx (HImode);
702 ;; Arithmetic Shift Right
703 (define_expand "ashrsi3"
704 [(parallel [(set (match_operand:SI 0 "register_operand" "")
705 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
706 (match_operand:SI 2 "const_int_operand" "")))
707 (clobber (reg:BI CARRY_REG))
708 (clobber (match_dup 3))])]
710 { if (! const_int_operand (operands[2], SImode))
712 operands[3] = gen_reg_rtx (HImode);
715 ;; Logical Shift Right
716 (define_expand "lshrsi3"
717 [(parallel [(set (match_operand:SI 0 "register_operand" "")
718 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
719 (match_operand:SI 2 "const_int_operand" "")))
720 (clobber (reg:BI CARRY_REG))
721 (clobber (match_dup 3))])]
723 { if (! const_int_operand (operands[2], SImode))
725 operands[3] = gen_reg_rtx (HImode);
728 (define_insn "*shiftsi"
729 [(set (match_operand:SI 0 "register_operand" "=r,r")
730 (match_operator:SI 4 "shift_operator"
731 [(match_operand:SI 1 "register_operand" "0,0")
732 (match_operand:SI 2 "const_int_operand" "U,n")]))
733 (clobber (reg:BI CARRY_REG))
734 (clobber (match_operand:HI 3 "" "=X,r"))]
736 "* return xstormy16_output_shift (SImode, GET_CODE (operands[4]),
737 operands[0], operands[2], operands[3]);"
738 [(set_attr "length" "6,10")
739 (set_attr "psw_operand" "clobber,clobber")])
742 ;; ::::::::::::::::::::
746 ;; ::::::::::::::::::::
748 (define_expand "cbranchhi4"
750 (if_then_else (match_operator 0 "comparison_operator"
751 [(match_operand:HI 1 "register_operand" "")
752 (match_operand:HI 2 "nonmemory_operand" "")])
753 (label_ref (match_operand 3 "" ""))
755 (clobber (reg:BI CARRY_REG))]
758 xstormy16_emit_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
763 (define_insn "cbranchhi"
765 (if_then_else (match_operator:HI 1 "comparison_operator"
766 [(match_operand:HI 2 "nonmemory_operand"
768 (match_operand:HI 3 "nonmemory_operand"
770 (label_ref (match_operand 0 "" ""))
772 (clobber (reg:BI CARRY_REG))]
776 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 0, insn);
778 [(set_attr "branch_class" "bcc12")
779 (set_attr "psw_operand" "0,0,1")])
781 (define_insn "cbranchhi_neg"
783 (if_then_else (match_operator:HI 1 "comparison_operator"
784 [(match_operand:HI 2 "nonmemory_operand"
786 (match_operand:HI 3 "nonmemory_operand"
789 (label_ref (match_operand 0 "" ""))))
790 (clobber (reg:BI CARRY_REG))]
794 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 1, insn);
796 [(set_attr "branch_class" "bcc12")
797 (set_attr "psw_operand" "0,0,1")])
799 (define_insn "*eqbranchsi"
801 (if_then_else (match_operator:SI 1 "equality_operator"
802 [(match_operand:SI 2 "register_operand"
805 (label_ref (match_operand 0 "" ""))
807 (clobber (match_operand:SI 3 "register_operand" "=2"))]
811 return xstormy16_output_cbranch_si (operands[1], \"%l0\", 0, insn);
813 [(set_attr "branch_class" "bcc8p2")
814 (set_attr "psw_operand" "clobber")])
816 (define_insn "*ineqbranch_1"
818 (if_then_else (match_operator:HI 4 "xstormy16_ineqsi_operator"
819 [(minus:HI (match_operand:HI 1 "register_operand" "T,r,r")
820 (zero_extend:HI (reg:BI CARRY_REG)))
821 (match_operand:HI 3 "nonmemory_operand" "L,r,i")])
822 (label_ref (match_operand 0 "" ""))
824 (set (match_operand:HI 2 "register_operand" "=1,1,1")
825 (minus:HI (minus:HI (match_dup 1) (zero_extend:HI (reg:BI CARRY_REG)))
827 (clobber (reg:BI CARRY_REG))]
831 return xstormy16_output_cbranch_si (operands[4], \"%l0\", 0, insn);
833 [(set_attr "branch_class" "bcc8p2,bcc8p2,bcc8p4")
834 (set_attr "psw_operand" "2,2,2")])
836 ;; ::::::::::::::::::::
838 ;; :: Call and branch instructions
840 ;; ::::::::::::::::::::
842 ;; Subroutine call instruction returning no value. Operand 0 is the function
843 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
844 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
845 ;; registers used as operands.
847 ;; On most machines, operand 2 is not actually stored into the RTL pattern. It
848 ;; is supplied for the sake of some RISC machines which need to put this
849 ;; information into the assembler code; they can put it in the RTL instead of
852 (define_expand "call"
853 [(call (match_operand:HI 0 "memory_operand" "m")
854 (match_operand 1 "" ""))
855 (use (match_operand 2 "immediate_operand" ""))]
857 "xstormy16_expand_call (NULL_RTX, operands[0], operands[1]); DONE;")
859 ;; Subroutine call instruction returning a value. Operand 0 is the hard
860 ;; register in which the value is returned. There are three more operands, the
861 ;; same as the three operands of the `call' instruction (but with numbers
862 ;; increased by one).
864 ;; Subroutines that return `BLKmode' objects use the `call' insn.
866 (define_expand "call_value"
867 [(set (match_operand 0 "register_operand" "=r")
868 (call (match_operand:HI 1 "memory_operand" "m")
869 (match_operand:SI 2 "" "")))
870 (use (match_operand 3 "immediate_operand" ""))]
872 "xstormy16_expand_call (operands[0], operands[1], operands[2]); DONE;")
874 (define_insn "*call_internal"
875 [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
876 (match_operand 1 "" ""))
877 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
882 [(set_attr "length" "4,2")
883 (set_attr "psw_operand" "clobber")])
885 (define_insn "*call_value_internal"
886 [(set (match_operand 3 "register_operand" "=r,r")
887 (call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
888 (match_operand 1 "" "")))
889 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
894 [(set_attr "length" "4,2")
895 (set_attr "psw_operand" "clobber")])
898 (define_expand "return"
903 (define_insn "return_internal"
907 [(set_attr "psw_operand" "nop")])
909 (define_insn "return_internal_interrupt"
911 (unspec_volatile [(const_int 0)] 1)]
914 [(set_attr "psw_operand" "clobber")])
916 ;; Normal unconditional jump
918 [(set (pc) (label_ref (match_operand 0 "" "")))]
922 return xstormy16_output_cbranch_hi (NULL_RTX, \"%l0\", 0, insn);
924 [(set_attr "branch_class" "br12")
925 (set_attr "psw_operand" "nop")])
927 ;; Indirect jump through a register
928 (define_expand "indirect_jump"
929 [(set (match_dup 1) (const_int 0))
930 (parallel [(set (pc) (match_operand:HI 0 "register_operand" ""))
931 (use (match_dup 1))])]
933 "operands[1] = gen_reg_rtx (HImode);")
936 [(set (pc) (match_operand:HI 0 "register_operand" "r"))
937 (use (match_operand:HI 1 "register_operand" "z"))]
940 [(set_attr "length" "4")
941 (set_attr "psw_operand" "nop")])
943 ;; Table-based switch statements.
944 (define_expand "casesi"
945 [(use (match_operand:SI 0 "register_operand" ""))
946 (use (match_operand:SI 1 "immediate_operand" ""))
947 (use (match_operand:SI 2 "immediate_operand" ""))
948 (use (label_ref (match_operand 3 "" "")))
949 (use (label_ref (match_operand 4 "" "")))]
953 xstormy16_expand_casesi (operands[0], operands[1], operands[2],
954 operands[3], operands[4]);
958 (define_insn "tablejump_pcrel"
959 [(set (pc) (mem:HI (plus:HI (pc)
960 (match_operand:HI 0 "register_operand" "r"))))
961 (use (label_ref:SI (match_operand 1 "" "")))]
964 [(set_attr "psw_operand" "nop")])
966 ;; ::::::::::::::::::::
968 ;; :: Prologue and Epilogue instructions
970 ;; ::::::::::::::::::::
972 ;; Called after register allocation to add any instructions needed for
973 ;; the prologue. Using a prologue insn is favored compared to putting
974 ;; all of the instructions in the TARGET_ASM_FUNCTION_PROLOGUE macro,
975 ;; since it allows the scheduler to intermix instructions with the
976 ;; saves of the caller saved registers. In some cases, it might be
977 ;; necessary to emit a barrier instruction as the last insn to prevent
979 (define_expand "prologue"
983 xstormy16_expand_prologue ();
987 ;; Called after register allocation to add any instructions needed for
988 ;; the epilogue. Using an epilogue insn is favored compared to putting
989 ;; all of the instructions in the TARGET_ASM_FUNCTION_EPILOGUE macro,
990 ;; since it allows the scheduler to intermix instructions with the
991 ;; restores of the caller saved registers. In some cases, it might be
992 ;; necessary to emit a barrier instruction as the first insn to
993 ;; prevent such scheduling.
994 (define_expand "epilogue"
998 xstormy16_expand_epilogue ();
1002 ;; ::::::::::::::::::::
1004 ;; :: Miscellaneous instructions
1006 ;; ::::::::::::::::::::
1008 ;; No operation, needed in case the user uses -g but not -O.
1013 [(set_attr "psw_operand" "nop")])
1015 ;; Pseudo instruction that prevents the scheduler from moving code above this
1017 (define_insn "blockage"
1018 [(unspec_volatile [(const_int 0)] 0)]
1021 [(set_attr "length" "0")
1022 (set_attr "psw_operand" "nop")])
1024 ;;---------------------------------------------------------------------------
1026 (define_expand "iorqi3"
1027 [(match_operand:QI 0 "xstormy16_below100_or_register" "")
1028 (match_operand:QI 1 "xstormy16_below100_or_register" "")
1029 (match_operand:QI 2 "nonmemory_operand" "")]
1032 xstormy16_expand_iorqi3 (operands);
1036 (define_insn "iorqi3_internal"
1037 [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
1038 (ior:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
1039 (match_operand:QI 2 "xstormy16_onebit_set_operand" "i")))]
1042 [(set_attr "length" "2")
1043 (set_attr "psw_operand" "0")])
1046 [(set (match_operand:QI 0 "register_operand" "")
1047 (match_operand:QI 1 "xstormy16_below100_operand" ""))
1048 (set (match_operand:HI 2 "register_operand" "")
1049 (ior:HI (match_operand:HI 3 "register_operand" "")
1050 (match_operand:QI 4 "xstormy16_onebit_set_operand" "")))
1051 (set (match_operand:QI 5 "xstormy16_below100_operand" "")
1052 (match_operand:QI 6 "register_operand" ""))
1054 "REGNO (operands[0]) == REGNO (operands[2])
1055 && REGNO (operands[0]) == REGNO (operands[3])
1056 && REGNO (operands[0]) == REGNO (operands[6])
1057 && rtx_equal_p (operands[1], operands[5])"
1059 (ior:QI (match_dup 1)
1065 (define_expand "andqi3"
1066 [(match_operand:QI 0 "xstormy16_below100_or_register" "")
1067 (match_operand:QI 1 "xstormy16_below100_or_register" "")
1068 (match_operand:QI 2 "nonmemory_operand" "")]
1071 xstormy16_expand_andqi3 (operands);
1075 (define_insn "andqi3_internal"
1076 [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
1077 (and:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
1078 (match_operand:QI 2 "xstormy16_onebit_clr_operand" "i")))]
1081 [(set_attr "length" "2")
1082 (set_attr "psw_operand" "0")])
1085 [(set (match_operand:HI 0 "register_operand" "")
1086 (and:HI (match_operand:HI 1 "register_operand" "")
1087 (match_operand 2 "immediate_operand" "")))
1088 (set (match_operand:HI 3 "register_operand" "")
1089 (zero_extend:HI (match_operand:QI 4 "register_operand" "")));
1091 "REGNO (operands[0]) == REGNO (operands[1])
1092 && REGNO (operands[0]) == REGNO (operands[3])
1093 && REGNO (operands[0]) == REGNO (operands[4])"
1095 (and:HI (match_dup 1)
1098 "operands[5] = GEN_INT (INTVAL (operands[2]) & 0xff);")
1101 [(set (match_operand:QI 0 "register_operand" "")
1102 (match_operand:QI 1 "xstormy16_below100_operand" ""))
1103 (set (match_operand:HI 2 "register_operand" "")
1104 (and:HI (match_operand:HI 3 "register_operand" "")
1105 (match_operand:QI 4 "xstormy16_onebit_clr_operand" "")))
1106 (set (match_operand:QI 5 "xstormy16_below100_operand" "")
1107 (match_operand:QI 6 "register_operand" ""))
1109 "REGNO (operands[0]) == REGNO (operands[2])
1110 && REGNO (operands[0]) == REGNO (operands[3])
1111 && REGNO (operands[0]) == REGNO (operands[6])
1112 && rtx_equal_p (operands[1], operands[5])"
1114 (and:QI (match_dup 1)
1119 ;; GCC uses different techniques to optimize MSB and LSB accesses, so
1120 ;; we have to code those separately.
1122 (define_insn "*bclrx"
1124 (if_then_else (eq:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1125 (match_operand:HI 2 "immediate_operand" "i"))
1127 (label_ref (match_operand 0 "" ""))
1129 (clobber (reg:BI CARRY_REG))]
1132 [(set_attr "length" "4")
1133 (set_attr "psw_operand" "nop")])
1135 (define_insn "*bclrx2"
1137 (if_then_else (zero_extract:HI
1139 (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1140 (match_operand:HI 2 "xstormy16_onebit_set_operand" "J"))
1142 (match_operand:HI 3 "immediate_operand" "i"))
1143 (label_ref (match_operand 0 "" ""))
1145 (clobber (reg:BI CARRY_REG))]
1148 [(set_attr "length" "4")
1149 (set_attr "psw_operand" "nop")])
1151 (define_insn "*bclrx3"
1153 (if_then_else (eq:HI (and:HI (zero_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1154 (match_operand:HI 2 "immediate_operand" "i"))
1156 (label_ref (match_operand 0 "" ""))
1158 (clobber (reg:BI CARRY_REG))]
1161 [(set_attr "length" "4")
1162 (set_attr "psw_operand" "nop")])
1164 (define_insn "*bclr7"
1166 (if_then_else (xor:HI (lshiftrt:HI (subreg:HI
1167 (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1170 (label_ref (match_operand 0 "" ""))
1172 (clobber (reg:BI CARRY_REG))]
1175 [(set_attr "length" "4")
1176 (set_attr "psw_operand" "nop")])
1178 (define_insn "*bclr15"
1180 (if_then_else (ge:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1182 (label_ref (match_operand 0 "" ""))
1184 (clobber (reg:BI CARRY_REG))]
1187 [(set_attr "length" "4")
1188 (set_attr "psw_operand" "nop")])
1190 (define_insn "*bsetx"
1192 (if_then_else (ne:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1193 (match_operand:HI 2 "immediate_operand" "i"))
1195 (label_ref (match_operand 0 "" ""))
1197 (clobber (reg:BI CARRY_REG))]
1200 [(set_attr "length" "4")
1201 (set_attr "psw_operand" "nop")])
1203 (define_insn "*bsetx2"
1205 (if_then_else (zero_extract:HI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1207 (match_operand:HI 2 "immediate_operand" "i"))
1208 (label_ref (match_operand 0 "" ""))
1210 (clobber (reg:BI CARRY_REG))]
1213 [(set_attr "length" "4")
1214 (set_attr "psw_operand" "nop")])
1216 (define_insn "*bsetx3"
1218 (if_then_else (ne:HI (and:HI (zero_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1219 (match_operand:HI 2 "immediate_operand" "i"))
1221 (label_ref (match_operand 0 "" ""))
1223 (clobber (reg:BI CARRY_REG))]
1226 [(set_attr "length" "4")
1227 (set_attr "psw_operand" "nop")])
1229 (define_insn "*bset7"
1231 (if_then_else (lshiftrt:HI (subreg:HI (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1233 (label_ref (match_operand 0 "" ""))
1235 (clobber (reg:BI CARRY_REG))]
1238 [(set_attr "length" "4")
1239 (set_attr "psw_operand" "nop")])
1241 (define_insn "*bset15"
1243 (if_then_else (lt:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1245 (label_ref (match_operand 0 "" ""))
1247 (clobber (reg:BI CARRY_REG))]
1250 [(set_attr "length" "4")
1251 (set_attr "psw_operand" "nop")])