1 ;; XSTORMY16 Machine description template
2 ;; Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2007, 2008
3 ;; 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")
99 ;; ::::::::::::::::::::
103 ;; ::::::::::::::::::::
104 ;; push/pop qi and hi are here as separate insns rather than part of
105 ;; the movqi/hi patterns because we need to ensure that reload isn't
106 ;; passed anything it can't cope with. Without these patterns, we
109 ;; (set (mem (post_inc (sp))) mem (post_inc (reg)))
111 ;; If, in this example, reg needs reloading, reload will read reg from
112 ;; the stack , adjust sp, and store reg back at what is now the wrong
113 ;; offset. By using separate patterns for push and pop we ensure that
114 ;; insns like this one are never generated.
116 (define_insn "pushqi1"
117 [(set (mem:QI (post_inc (reg:HI 15)))
118 (match_operand:QI 0 "register_operand" "r"))]
121 [(set_attr "psw_operand" "nop")
122 (set_attr "length" "2")])
124 (define_insn "popqi1"
125 [(set (match_operand:QI 0 "register_operand" "=r")
126 (mem:QI (pre_dec (reg:HI 15))))]
129 [(set_attr "psw_operand" "nop")
130 (set_attr "length" "2")])
132 (define_expand "movqi"
133 [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "")
134 (match_operand:QI 1 "general_operand" ""))]
136 { xstormy16_expand_move (QImode, operands[0], operands[1]);
140 (define_insn "movqi_internal"
141 [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,e")
142 (match_operand:QI 1 "general_operand" "r,e,m,i,i,i,i,ie,W"))]
154 [(set_attr_alternative "length"
156 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
159 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
168 (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")])
170 (define_insn "pushhi1"
171 [(set (mem:HI (post_inc (reg:HI 15)))
172 (match_operand:HI 0 "register_operand" "r"))]
175 [(set_attr "psw_operand" "nop")
176 (set_attr "length" "2")])
178 (define_insn "pophi1"
179 [(set (match_operand:HI 0 "register_operand" "=r")
180 (mem:HI (pre_dec (reg:HI 15))))]
183 [(set_attr "psw_operand" "nop")
184 (set_attr "length" "2")])
186 (define_expand "movhi"
187 [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "")
188 (match_operand:HI 1 "xs_hi_general_operand" ""))]
190 { xstormy16_expand_move (HImode, operands[0], operands[1]);
194 (define_insn "movhi_internal"
195 [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,e")
196 (match_operand:HI 1 "xs_hi_general_operand" "r,e,m,L,L,i,i,ie,W"))]
208 [(set_attr_alternative "length"
210 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
213 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
222 (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")])
224 (define_expand "movsi"
225 [(set (match_operand:SI 0 "nonimmediate_operand" "")
226 (match_operand:SI 1 "general_operand" ""))]
228 { xstormy16_expand_move (SImode, operands[0], operands[1]);
232 (define_insn_and_split "*movsi_internal"
233 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Q,r,m,e,&e,e,r,S")
234 (match_operand:SI 1 "general_operand" "r,r,R,e,o, V,L,i,i"))]
239 { xstormy16_split_move (SImode, operands[0], operands[1]);
242 [(set_attr_alternative "length"
246 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
249 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
252 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
259 ;; ::::::::::::::::::::
263 ;; ::::::::::::::::::::
265 (define_insn "extendqihi2"
266 [(set (match_operand:HI 0 "register_operand" "=r")
267 (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
271 (define_insn "zero_extendqihi2"
272 [(set (match_operand:HI 0 "register_operand" "=e,r")
273 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,0")))]
277 shl %0,#8\n\tshr %0,#8"
278 [(set_attr "psw_operand" "nop,0")
279 (set_attr_alternative "length"
283 ;; ::::::::::::::::::::
285 ;; :: Bit field extraction
287 ;; ::::::::::::::::::::
289 ;; Extract an unsigned bit field
290 ;(define_insn "extzv"
291 ; [(set (match_operand:SI 0 "register_operand" "=r")
292 ; (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
293 ; (match_operand:SI 2 "const_int_operand" "n")
294 ; (match_operand:SI 3 "const_int_operand" "n")))]
296 ; "extzv %0,%1,%2,%3"
297 ; [(set_attr "length" "4")])
299 ;; Insert a bit field
301 ; [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
302 ; (match_operand:SI 1 "const_int_operand" "n")
303 ; (match_operand:SI 2 "const_int_operand" "n"))
304 ; (match_operand:SI 3 "nonmemory_operand" "ri"))]
307 ; [(set_attr "length" "4")])
310 ;; ::::::::::::::::::::
312 ;; :: 16-bit Integer arithmetic
314 ;; ::::::::::::::::::::
317 ; Note - the early clobber modifier is no longer needed on operand 3
318 ; and in fact can cause some reload spill failures if it is present.
319 ; Note that the 'Z' constraint matches "add $reg,0", which reload
320 ; will occasionally emit. We avoid the "add $reg,imm" match because
321 ; it clobbers the carry.
322 (define_insn "addhi3"
323 [(set (match_operand:HI 0 "register_operand" "=r,r,r,T,T,r,r,r")
324 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0,0,0")
325 (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,Z,L,M,Ir,N,i")))
326 (clobber (reg:BI CARRY_REG))]
337 [(set_attr "length" "2,2,0,2,2,2,2,4")])
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 (reg:BI CARRY_REG)
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 (reg:BI CARRY_REG)))
358 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
359 (set (reg:BI CARRY_REG)
360 (truncate:BI (lshiftrt:SI (plus:SI (plus:SI
361 (zero_extend:SI (match_dup 1))
362 (zero_extend:SI (reg:BI CARRY_REG)))
363 (zero_extend:SI (match_dup 2)))
370 [(set_attr "length" "2,2,4")])
373 ; Operand 3 is marked earlyclobber because that helps reload
374 ; to generate better code---this pattern will never need the
375 ; carry register as an input, and some output reloads or input
376 ; reloads might need to use it. In fact, without the '&' reload
377 ; will fail in some cases.
378 (define_insn "subhi3"
379 [(set (match_operand:HI 0 "register_operand" "=r,r,T,T,r,r,r")
380 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0,0,0,0,0")
381 (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,L,M,rI,M,i")))
382 (clobber (reg:BI CARRY_REG))]
392 [(set_attr "length" "2,2,2,2,2,2,4")])
394 (define_insn "subchi4"
395 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
396 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
397 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
398 (set (reg:BI CARRY_REG)
399 (truncate:BI (lshiftrt:SI (minus:SI (zero_extend:SI (match_dup 1))
400 (zero_extend:SI (match_dup 2)))
407 [(set_attr "length" "2,2,4")])
409 (define_insn "subchi5"
410 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
411 (minus:HI (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
412 (zero_extend:HI (reg:BI CARRY_REG)))
413 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
414 (set (reg:BI CARRY_REG)
415 (truncate:BI (lshiftrt:SI (minus:SI (minus:SI
416 (zero_extend:SI (match_dup 1))
417 (zero_extend:SI (reg:BI CARRY_REG)))
418 (zero_extend:SI (match_dup 2)))
425 [(set_attr "length" "2,2,4")])
427 ; Basic multiplication
428 (define_insn "mulhi3"
429 [(set (match_operand:HI 0 "register_operand" "=a")
430 (mult:HI (match_operand:HI 1 "register_operand" "%a")
431 (match_operand:HI 2 "register_operand" "c")))
432 (clobber (match_scratch:HI 3 "=b"))
436 [(set_attr "psw_operand" "nop")])
438 ;; Unsigned multiplication producing 64-bit results from 32-bit inputs
439 ; The constraint on operand 0 is 't' because it is actually two regs
440 ; long, and both regs must match the constraint.
441 (define_insn "umulhisi3"
442 [(set (match_operand:SI 0 "register_operand" "=t")
443 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%a"))
444 (zero_extend:SI (match_operand:HI 2 "register_operand" "c"))))
448 [(set_attr "psw_operand" "nop")])
450 ;; Unsigned division giving both quotient and remainder
451 (define_insn "udivmodhi4"
452 [(set (match_operand:HI 0 "register_operand" "=a")
453 (udiv:HI (match_operand:HI 1 "register_operand" "a")
454 (match_operand:HI 2 "register_operand" "c")))
455 (set (match_operand:HI 3 "register_operand" "=b")
456 (umod:HI (match_dup 1)
460 [(set_attr "psw_operand" "nop")])
462 ;; Signed division giving both quotient and remainder
463 (define_insn "divmodhi4"
464 [(set (match_operand:HI 0 "register_operand" "=a")
465 (div:HI (match_operand:HI 1 "register_operand" "a")
466 (match_operand:HI 2 "register_operand" "c")))
467 (set (match_operand:HI 3 "register_operand" "=b")
468 (mod:HI (match_dup 1)
472 [(set_attr "psw_operand" "nop")])
474 ;; Signed 32/16 division
475 (define_insn "sdivlh"
476 [(set (match_operand:HI 0 "register_operand" "=a")
477 (div:HI (match_operand:SI 2 "register_operand" "t")
478 (match_operand:HI 3 "register_operand" "c")))
479 (set (match_operand:HI 1 "register_operand" "=b")
480 (mod:HI (match_dup 2)
484 [(set_attr "psw_operand" "nop")])
486 ;; Unsigned 32/16 division
487 (define_insn "udivlh"
488 [(set (match_operand:HI 0 "register_operand" "=a")
489 (udiv:HI (match_operand:SI 2 "register_operand" "t")
490 (match_operand:HI 3 "register_operand" "c")))
491 (set (match_operand:HI 1 "register_operand" "=b")
492 (umod:HI (match_dup 2)
496 [(set_attr "psw_operand" "nop")])
500 (define_expand "neghi2"
501 [(set (match_operand:HI 0 "register_operand" "")
502 (not:HI (match_operand:HI 1 "register_operand" "")))
503 (parallel [(set (match_dup 0) (plus:HI (match_dup 0) (const_int 1)))
504 (clobber (reg:BI CARRY_REG))])]
508 ;; ::::::::::::::::::::
510 ;; :: 16-bit Integer Shifts and Rotates
512 ;; ::::::::::::::::::::
514 ;; Arithmetic Shift Left
515 (define_insn "ashlhi3"
516 [(set (match_operand:HI 0 "register_operand" "=r")
517 (ashift:HI (match_operand:HI 1 "register_operand" "0")
518 (match_operand:HI 2 "nonmemory_operand" "ri")))
519 (clobber (reg:BI CARRY_REG))]
523 ;; Arithmetic Shift Right
524 (define_insn "ashrhi3"
525 [(set (match_operand:HI 0 "register_operand" "=r")
526 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
527 (match_operand:HI 2 "nonmemory_operand" "ri")))
528 (clobber (reg:BI CARRY_REG))]
532 ;; Logical Shift Right
533 (define_insn "lshrhi3"
534 [(set (match_operand:HI 0 "register_operand" "=r")
535 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
536 (match_operand:HI 2 "nonmemory_operand" "ri")))
537 (clobber (reg:BI CARRY_REG))]
541 ;; ::::::::::::::::::::
543 ;; :: 16-Bit Integer Logical operations
545 ;; ::::::::::::::::::::
547 ;; Logical AND, 16-bit integers
548 (define_insn "andhi3"
549 [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
550 (and:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
551 (match_operand:HI 2 "nonmemory_operand" "L,r,K,i,K")))]
559 [(set_attr "length" "2,2,2,4,2")])
562 [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
563 (and:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
564 (match_operand:HI 2 "xstormy16_onebit_clr_operand" "")))]
567 (and:QI (match_dup 4)
569 { int s = ((INTVAL (operands[2]) & 0xff) == 0xff) ? 1 : 0;
570 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
571 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
572 operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
573 operands[5] = GEN_INT (INTVAL (operands[5]) | ~ (HOST_WIDE_INT) 0xff);
576 ;; Inclusive OR, 16-bit integers
577 (define_insn "iorhi3"
578 [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
579 (ior:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
580 (match_operand:HI 2 "nonmemory_operand" "L,r,J,i,J")))]
588 [(set_attr "length" "2,2,2,4,2")])
591 [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
592 (ior:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
593 (match_operand:HI 2 "xstormy16_onebit_set_operand" "")))]
596 (ior:QI (match_dup 4)
598 { int s = ((INTVAL (operands[2]) & 0xff) == 0x00) ? 1 : 0;
599 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
600 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
601 operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
602 operands[5] = GEN_INT (INTVAL (operands[5]) & 0xff);
605 ;; Exclusive OR, 16-bit integers
606 (define_insn "xorhi3"
607 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
608 (xor:HI (match_operand:HI 1 "register_operand" "%0,0,0")
609 (match_operand:HI 2 "nonmemory_operand" "L,r,i")))]
615 [(set_attr "length" "2,2,4")])
617 ;; One's complement, 16-bit integers
618 (define_insn "one_cmplhi2"
619 [(set (match_operand:HI 0 "register_operand" "=r")
620 (not:HI (match_operand:HI 1 "register_operand" "0")))]
624 ;; ::::::::::::::::::::
626 ;; :: 32-bit Integer arithmetic
628 ;; ::::::::::::::::::::
631 (define_insn_and_split "addsi3"
632 [(set (match_operand:SI 0 "register_operand" "=r")
633 (plus:SI (match_operand:SI 1 "register_operand" "%0")
634 (match_operand:SI 2 "nonmemory_operand" "ri")))
635 (clobber (reg:BI CARRY_REG))]
640 { xstormy16_expand_arith (SImode, PLUS, operands[0], operands[1],
644 [(set_attr "length" "4")])
647 (define_insn_and_split "subsi3"
648 [(set (match_operand:SI 0 "register_operand" "=r")
649 (minus:SI (match_operand:SI 1 "register_operand" "0")
650 (match_operand:SI 2 "nonmemory_operand" "ri")))
651 (clobber (reg:BI CARRY_REG))]
656 { xstormy16_expand_arith (SImode, MINUS, operands[0], operands[1],
660 [(set_attr "length" "4")])
662 (define_expand "negsi2"
663 [(parallel [(set (match_operand:SI 0 "register_operand" "")
664 (neg:SI (match_operand:SI 1 "register_operand" "")))
665 (clobber (reg:BI CARRY_REG))])]
667 { operands[2] = gen_reg_rtx (HImode); })
669 (define_insn_and_split "*negsi2_internal"
670 [(set (match_operand:SI 0 "register_operand" "=&r")
671 (neg:SI (match_operand:SI 1 "register_operand" "r")))
672 (clobber (reg:BI CARRY_REG))]
677 { xstormy16_expand_arith (SImode, NEG, operands[0], operands[0],
682 ;; ::::::::::::::::::::
684 ;; :: 32-bit Integer Shifts and Rotates
686 ;; ::::::::::::::::::::
688 ;; Arithmetic Shift Left
689 (define_expand "ashlsi3"
690 [(parallel [(set (match_operand:SI 0 "register_operand" "")
691 (ashift:SI (match_operand:SI 1 "register_operand" "")
692 (match_operand:SI 2 "const_int_operand" "")))
693 (clobber (reg:BI CARRY_REG))
694 (clobber (match_dup 3))])]
696 { if (! const_int_operand (operands[2], SImode))
698 operands[3] = gen_reg_rtx (HImode);
701 ;; Arithmetic Shift Right
702 (define_expand "ashrsi3"
703 [(parallel [(set (match_operand:SI 0 "register_operand" "")
704 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
705 (match_operand:SI 2 "const_int_operand" "")))
706 (clobber (reg:BI CARRY_REG))
707 (clobber (match_dup 3))])]
709 { if (! const_int_operand (operands[2], SImode))
711 operands[3] = gen_reg_rtx (HImode);
714 ;; Logical Shift Right
715 (define_expand "lshrsi3"
716 [(parallel [(set (match_operand:SI 0 "register_operand" "")
717 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
718 (match_operand:SI 2 "const_int_operand" "")))
719 (clobber (reg:BI CARRY_REG))
720 (clobber (match_dup 3))])]
722 { if (! const_int_operand (operands[2], SImode))
724 operands[3] = gen_reg_rtx (HImode);
727 (define_insn "*shiftsi"
728 [(set (match_operand:SI 0 "register_operand" "=r,r")
729 (match_operator:SI 4 "shift_operator"
730 [(match_operand:SI 1 "register_operand" "0,0")
731 (match_operand:SI 2 "const_int_operand" "U,n")]))
732 (clobber (reg:BI CARRY_REG))
733 (clobber (match_operand:HI 3 "" "=X,r"))]
735 "* return xstormy16_output_shift (SImode, GET_CODE (operands[4]),
736 operands[0], operands[2], operands[3]);"
737 [(set_attr "length" "6,10")
738 (set_attr "psw_operand" "clobber,clobber")])
740 ;; ::::::::::::::::::::
744 ;; ::::::::::::::::::::
746 ;; Note, we store the operands in the comparison insns, and use them later
747 ;; when generating the branch or scc operation.
749 ;; First the routines called by the machine independent part of the compiler
750 (define_expand "cmphi"
752 (compare (match_operand:HI 0 "register_operand" "")
753 (match_operand:HI 1 "nonmemory_operand" "")))]
756 xstormy16_compare_op0 = operands[0];
757 xstormy16_compare_op1 = operands[1];
761 ; There are no real SImode comparisons, but some can be emulated
762 ; by performing a SImode subtract and looking at the condition flags.
763 (define_expand "cmpsi"
765 (compare (match_operand:SI 0 "register_operand" "")
766 (match_operand:SI 1 "nonmemory_operand" "")))]
769 xstormy16_compare_op0 = operands[0];
770 xstormy16_compare_op1 = operands[1];
774 ;; ::::::::::::::::::::
778 ;; ::::::::::::::::::::
781 [(use (match_operand 0 "" ""))]
783 { xstormy16_emit_cbranch (EQ, operands[0]); DONE; })
786 [(use (match_operand 0 "" ""))]
788 { xstormy16_emit_cbranch (NE, operands[0]); DONE; })
791 [(use (match_operand 0 "" ""))]
793 { xstormy16_emit_cbranch (GE, operands[0]); DONE; })
796 [(use (match_operand 0 "" ""))]
798 { xstormy16_emit_cbranch (GT, operands[0]); DONE; })
801 [(use (match_operand 0 "" ""))]
803 { xstormy16_emit_cbranch (LE, operands[0]); DONE; })
806 [(use (match_operand 0 "" ""))]
808 { xstormy16_emit_cbranch (LT, operands[0]); DONE; })
810 (define_expand "bgeu"
811 [(use (match_operand 0 "" ""))]
813 { xstormy16_emit_cbranch (GEU, operands[0]); DONE; })
815 (define_expand "bgtu"
816 [(use (match_operand 0 "" ""))]
818 { xstormy16_emit_cbranch (GTU, operands[0]); DONE; })
820 (define_expand "bleu"
821 [(use (match_operand 0 "" ""))]
823 { xstormy16_emit_cbranch (LEU, operands[0]); DONE; })
825 (define_expand "bltu"
826 [(use (match_operand 0 "" ""))]
828 { xstormy16_emit_cbranch (LTU, operands[0]); DONE; })
830 (define_insn "cbranchhi"
832 (if_then_else (match_operator:HI 1 "comparison_operator"
833 [(match_operand:HI 2 "nonmemory_operand"
835 (match_operand:HI 3 "nonmemory_operand"
837 (label_ref (match_operand 0 "" ""))
839 (clobber (reg:BI CARRY_REG))]
843 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 0, insn);
845 [(set_attr "branch_class" "bcc12")
846 (set_attr "psw_operand" "0,0,1")])
848 (define_insn "cbranchhi_neg"
850 (if_then_else (match_operator:HI 1 "comparison_operator"
851 [(match_operand:HI 2 "nonmemory_operand"
853 (match_operand:HI 3 "nonmemory_operand"
856 (label_ref (match_operand 0 "" ""))))
857 (clobber (reg:BI CARRY_REG))]
861 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 1, insn);
863 [(set_attr "branch_class" "bcc12")
864 (set_attr "psw_operand" "0,0,1")])
866 (define_insn "*eqbranchsi"
868 (if_then_else (match_operator:SI 1 "equality_operator"
869 [(match_operand:SI 2 "register_operand"
872 (label_ref (match_operand 0 "" ""))
874 (clobber (match_operand:SI 3 "register_operand" "=2"))]
878 return xstormy16_output_cbranch_si (operands[1], \"%l0\", 0, insn);
880 [(set_attr "branch_class" "bcc8p2")
881 (set_attr "psw_operand" "clobber")])
883 (define_insn_and_split "*ineqbranchsi"
885 (if_then_else (match_operator:SI 1 "xstormy16_ineqsi_operator"
886 [(match_operand:SI 2 "register_operand"
888 (match_operand:SI 3 "nonmemory_operand"
890 (label_ref (match_operand 0 "" ""))
892 (clobber (match_operand:SI 4 "register_operand" "=2"))
893 (clobber (reg:BI CARRY_REG))]
898 { xstormy16_split_cbranch (SImode, operands[0], operands[1], operands[2]); DONE; }
899 [(set_attr "length" "8")])
901 (define_insn "*ineqbranch_1"
903 (if_then_else (match_operator:HI 4 "xstormy16_ineqsi_operator"
904 [(minus:HI (match_operand:HI 1 "register_operand" "T,r,r")
905 (zero_extend:HI (reg:BI CARRY_REG)))
906 (match_operand:HI 3 "nonmemory_operand" "L,Ir,i")])
907 (label_ref (match_operand 0 "" ""))
909 (set (match_operand:HI 2 "register_operand" "=1,1,1")
910 (minus:HI (minus:HI (match_dup 1) (zero_extend:HI (reg:BI CARRY_REG)))
912 (clobber (reg:BI CARRY_REG))]
916 return xstormy16_output_cbranch_si (operands[4], \"%l0\", 0, insn);
918 [(set_attr "branch_class" "bcc8p2,bcc8p2,bcc8p4")
919 (set_attr "psw_operand" "2,2,2")])
921 ;; ::::::::::::::::::::
923 ;; :: Call and branch instructions
925 ;; ::::::::::::::::::::
927 ;; Subroutine call instruction returning no value. Operand 0 is the function
928 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
929 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
930 ;; registers used as operands.
932 ;; On most machines, operand 2 is not actually stored into the RTL pattern. It
933 ;; is supplied for the sake of some RISC machines which need to put this
934 ;; information into the assembler code; they can put it in the RTL instead of
937 (define_expand "call"
938 [(call (match_operand:HI 0 "memory_operand" "m")
939 (match_operand 1 "" ""))
940 (use (match_operand 2 "immediate_operand" ""))]
942 "xstormy16_expand_call (NULL_RTX, operands[0], operands[1]); DONE;")
944 ;; Subroutine call instruction returning a value. Operand 0 is the hard
945 ;; register in which the value is returned. There are three more operands, the
946 ;; same as the three operands of the `call' instruction (but with numbers
947 ;; increased by one).
949 ;; Subroutines that return `BLKmode' objects use the `call' insn.
951 (define_expand "call_value"
952 [(set (match_operand 0 "register_operand" "=r")
953 (call (match_operand:HI 1 "memory_operand" "m")
954 (match_operand:SI 2 "" "")))
955 (use (match_operand 3 "immediate_operand" ""))]
957 "xstormy16_expand_call (operands[0], operands[1], operands[2]); DONE;")
959 (define_insn "*call_internal"
960 [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
961 (match_operand 1 "" ""))
962 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
967 [(set_attr "length" "4,2")
968 (set_attr "psw_operand" "clobber")])
970 (define_insn "*call_value_internal"
971 [(set (match_operand 3 "register_operand" "=r,r")
972 (call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
973 (match_operand 1 "" "")))
974 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
979 [(set_attr "length" "4,2")
980 (set_attr "psw_operand" "clobber")])
983 (define_expand "return"
988 (define_insn "return_internal"
992 [(set_attr "psw_operand" "nop")])
994 (define_insn "return_internal_interrupt"
996 (unspec_volatile [(const_int 0)] 1)]
999 [(set_attr "psw_operand" "clobber")])
1001 ;; Normal unconditional jump
1003 [(set (pc) (label_ref (match_operand 0 "" "")))]
1007 return xstormy16_output_cbranch_hi (NULL_RTX, \"%l0\", 0, insn);
1009 [(set_attr "branch_class" "br12")
1010 (set_attr "psw_operand" "nop")])
1012 ;; Indirect jump through a register
1013 (define_expand "indirect_jump"
1014 [(set (match_dup 1) (const_int 0))
1015 (parallel [(set (pc) (match_operand:HI 0 "register_operand" ""))
1016 (use (match_dup 1))])]
1018 "operands[1] = gen_reg_rtx (HImode);")
1021 [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1022 (use (match_operand:HI 1 "register_operand" "z"))]
1025 [(set_attr "length" "4")
1026 (set_attr "psw_operand" "nop")])
1028 ;; Table-based switch statements.
1029 (define_expand "casesi"
1030 [(use (match_operand:SI 0 "register_operand" ""))
1031 (use (match_operand:SI 1 "immediate_operand" ""))
1032 (use (match_operand:SI 2 "immediate_operand" ""))
1033 (use (label_ref (match_operand 3 "" "")))
1034 (use (label_ref (match_operand 4 "" "")))]
1038 xstormy16_expand_casesi (operands[0], operands[1], operands[2],
1039 operands[3], operands[4]);
1043 (define_insn "tablejump_pcrel"
1044 [(set (pc) (mem:HI (plus:HI (pc)
1045 (match_operand:HI 0 "register_operand" "r"))))
1046 (use (label_ref:SI (match_operand 1 "" "")))]
1049 [(set_attr "psw_operand" "nop")])
1051 ;; ::::::::::::::::::::
1053 ;; :: Prologue and Epilogue instructions
1055 ;; ::::::::::::::::::::
1057 ;; Called after register allocation to add any instructions needed for
1058 ;; the prologue. Using a prologue insn is favored compared to putting
1059 ;; all of the instructions in the TARGET_ASM_FUNCTION_PROLOGUE macro,
1060 ;; since it allows the scheduler to intermix instructions with the
1061 ;; saves of the caller saved registers. In some cases, it might be
1062 ;; necessary to emit a barrier instruction as the last insn to prevent
1064 (define_expand "prologue"
1068 xstormy16_expand_prologue ();
1072 ;; Called after register allocation to add any instructions needed for
1073 ;; the epilogue. Using an epilogue insn is favored compared to putting
1074 ;; all of the instructions in the TARGET_ASM_FUNCTION_EPILOGUE macro,
1075 ;; since it allows the scheduler to intermix instructions with the
1076 ;; restores of the caller saved registers. In some cases, it might be
1077 ;; necessary to emit a barrier instruction as the first insn to
1078 ;; prevent such scheduling.
1079 (define_expand "epilogue"
1083 xstormy16_expand_epilogue ();
1087 ;; ::::::::::::::::::::
1089 ;; :: Miscellaneous instructions
1091 ;; ::::::::::::::::::::
1093 ;; No operation, needed in case the user uses -g but not -O.
1098 [(set_attr "psw_operand" "nop")])
1100 ;; Pseudo instruction that prevents the scheduler from moving code above this
1102 (define_insn "blockage"
1103 [(unspec_volatile [(const_int 0)] 0)]
1106 [(set_attr "length" "0")
1107 (set_attr "psw_operand" "nop")])
1109 ;;---------------------------------------------------------------------------
1111 (define_expand "iorqi3"
1112 [(match_operand:QI 0 "xstormy16_below100_or_register" "")
1113 (match_operand:QI 1 "xstormy16_below100_or_register" "")
1114 (match_operand:QI 2 "nonmemory_operand" "")]
1117 xstormy16_expand_iorqi3 (operands);
1121 (define_insn "iorqi3_internal"
1122 [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
1123 (ior:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
1124 (match_operand:QI 2 "xstormy16_onebit_set_operand" "i")))]
1127 [(set_attr "length" "2")
1128 (set_attr "psw_operand" "0")])
1131 [(set (match_operand:QI 0 "register_operand" "")
1132 (match_operand:QI 1 "xstormy16_below100_operand" ""))
1133 (set (match_operand:HI 2 "register_operand" "")
1134 (ior:HI (match_operand:HI 3 "register_operand" "")
1135 (match_operand:QI 4 "xstormy16_onebit_set_operand" "")))
1136 (set (match_operand:QI 5 "xstormy16_below100_operand" "")
1137 (match_operand:QI 6 "register_operand" ""))
1139 "REGNO (operands[0]) == REGNO (operands[2])
1140 && REGNO (operands[0]) == REGNO (operands[3])
1141 && REGNO (operands[0]) == REGNO (operands[6])
1142 && rtx_equal_p (operands[1], operands[5])"
1144 (ior:QI (match_dup 1)
1150 (define_expand "andqi3"
1151 [(match_operand:QI 0 "xstormy16_below100_or_register" "")
1152 (match_operand:QI 1 "xstormy16_below100_or_register" "")
1153 (match_operand:QI 2 "nonmemory_operand" "")]
1156 xstormy16_expand_andqi3 (operands);
1160 (define_insn "andqi3_internal"
1161 [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
1162 (and:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
1163 (match_operand:QI 2 "xstormy16_onebit_clr_operand" "i")))]
1166 [(set_attr "length" "2")
1167 (set_attr "psw_operand" "0")])
1170 [(set (match_operand:HI 0 "register_operand" "")
1171 (and:HI (match_operand:HI 1 "register_operand" "")
1172 (match_operand 2 "immediate_operand" "")))
1173 (set (match_operand:HI 3 "register_operand" "")
1174 (zero_extend:HI (match_operand:QI 4 "register_operand" "")));
1176 "REGNO (operands[0]) == REGNO (operands[1])
1177 && REGNO (operands[0]) == REGNO (operands[3])
1178 && REGNO (operands[0]) == REGNO (operands[4])"
1180 (and:HI (match_dup 1)
1183 "operands[5] = GEN_INT (INTVAL (operands[2]) & 0xff);")
1186 [(set (match_operand:QI 0 "register_operand" "")
1187 (match_operand:QI 1 "xstormy16_below100_operand" ""))
1188 (set (match_operand:HI 2 "register_operand" "")
1189 (and:HI (match_operand:HI 3 "register_operand" "")
1190 (match_operand:QI 4 "xstormy16_onebit_clr_operand" "")))
1191 (set (match_operand:QI 5 "xstormy16_below100_operand" "")
1192 (match_operand:QI 6 "register_operand" ""))
1194 "REGNO (operands[0]) == REGNO (operands[2])
1195 && REGNO (operands[0]) == REGNO (operands[3])
1196 && REGNO (operands[0]) == REGNO (operands[6])
1197 && rtx_equal_p (operands[1], operands[5])"
1199 (and:QI (match_dup 1)
1204 ;; GCC uses different techniques to optimize MSB and LSB accesses, so
1205 ;; we have to code those separately.
1207 (define_insn "*bclrx"
1209 (if_then_else (eq:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1210 (match_operand:HI 2 "immediate_operand" "i"))
1212 (label_ref (match_operand 0 "" ""))
1214 (clobber (reg:BI CARRY_REG))]
1217 [(set_attr "length" "4")
1218 (set_attr "psw_operand" "nop")])
1220 (define_insn "*bclrx2"
1222 (if_then_else (zero_extract:HI
1224 (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1225 (match_operand:HI 2 "xstormy16_onebit_set_operand" "J"))
1227 (match_operand:HI 3 "immediate_operand" "i"))
1228 (label_ref (match_operand 0 "" ""))
1230 (clobber (reg:BI CARRY_REG))]
1233 [(set_attr "length" "4")
1234 (set_attr "psw_operand" "nop")])
1236 (define_insn "*bclrx3"
1238 (if_then_else (eq:HI (and:HI (zero_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1239 (match_operand:HI 2 "immediate_operand" "i"))
1241 (label_ref (match_operand 0 "" ""))
1243 (clobber (reg:BI CARRY_REG))]
1246 [(set_attr "length" "4")
1247 (set_attr "psw_operand" "nop")])
1249 (define_insn "*bclr7"
1251 (if_then_else (xor:HI (lshiftrt:HI (subreg:HI
1252 (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1255 (label_ref (match_operand 0 "" ""))
1257 (clobber (reg:BI CARRY_REG))]
1260 [(set_attr "length" "4")
1261 (set_attr "psw_operand" "nop")])
1263 (define_insn "*bclr15"
1265 (if_then_else (ge:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1267 (label_ref (match_operand 0 "" ""))
1269 (clobber (reg:BI CARRY_REG))]
1272 [(set_attr "length" "4")
1273 (set_attr "psw_operand" "nop")])
1275 (define_insn "*bsetx"
1277 (if_then_else (ne:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1278 (match_operand:HI 2 "immediate_operand" "i"))
1280 (label_ref (match_operand 0 "" ""))
1282 (clobber (reg:BI CARRY_REG))]
1285 [(set_attr "length" "4")
1286 (set_attr "psw_operand" "nop")])
1288 (define_insn "*bsetx2"
1290 (if_then_else (zero_extract:HI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1292 (match_operand:HI 2 "immediate_operand" "i"))
1293 (label_ref (match_operand 0 "" ""))
1295 (clobber (reg:BI CARRY_REG))]
1298 [(set_attr "length" "4")
1299 (set_attr "psw_operand" "nop")])
1301 (define_insn "*bsetx3"
1303 (if_then_else (ne:HI (and:HI (zero_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1304 (match_operand:HI 2 "immediate_operand" "i"))
1306 (label_ref (match_operand 0 "" ""))
1308 (clobber (reg:BI CARRY_REG))]
1311 [(set_attr "length" "4")
1312 (set_attr "psw_operand" "nop")])
1314 (define_insn "*bset7"
1316 (if_then_else (lshiftrt:HI (subreg:HI (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1318 (label_ref (match_operand 0 "" ""))
1320 (clobber (reg:BI CARRY_REG))]
1323 [(set_attr "length" "4")
1324 (set_attr "psw_operand" "nop")])
1326 (define_insn "*bset15"
1328 (if_then_else (lt:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1330 (label_ref (match_operand 0 "" ""))
1332 (clobber (reg:BI CARRY_REG))]
1335 [(set_attr "length" "4")
1336 (set_attr "psw_operand" "nop")])