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.
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")])
93 (include "predicates.md")
95 ;; ::::::::::::::::::::
99 ;; ::::::::::::::::::::
100 ;; push/pop qi and hi are here as separate insns rather than part of
101 ;; the movqi/hi patterns because we need to ensure that reload isn't
102 ;; passed anything it can't cope with. Without these patterns, we
105 ;; (set (mem (post_inc (sp))) mem (post_inc (reg)))
107 ;; If, in this example, reg needs reloading, reload will read reg from
108 ;; the stack , adjust sp, and store reg back at what is now the wrong
109 ;; offset. By using separate patterns for push and pop we ensure that
110 ;; insns like this one are never generated.
112 (define_insn "pushqi1"
113 [(set (mem:QI (post_inc (reg:HI 15)))
114 (match_operand:QI 0 "register_operand" "r"))]
117 [(set_attr "psw_operand" "nop")
118 (set_attr "length" "2")])
120 (define_insn "popqi1"
121 [(set (match_operand:QI 0 "register_operand" "=r")
122 (mem:QI (pre_dec (reg:HI 15))))]
125 [(set_attr "psw_operand" "nop")
126 (set_attr "length" "2")])
128 (define_expand "movqi"
129 [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "")
130 (match_operand:QI 1 "general_operand" ""))]
132 "{ xstormy16_expand_move (QImode, operands[0], operands[1]); DONE; }")
134 (define_insn "movqi_internal"
135 [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,r")
136 (match_operand:QI 1 "general_operand" "r,e,m,i,i,i,i,ir,W"))]
148 [(set_attr_alternative "length"
150 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
153 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
162 (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")])
164 (define_insn "pushhi1"
165 [(set (mem:HI (post_inc (reg:HI 15)))
166 (match_operand:HI 0 "register_operand" "r"))]
169 [(set_attr "psw_operand" "nop")
170 (set_attr "length" "2")])
172 (define_insn "pophi1"
173 [(set (match_operand:HI 0 "register_operand" "=r")
174 (mem:HI (pre_dec (reg:HI 15))))]
177 [(set_attr "psw_operand" "nop")
178 (set_attr "length" "2")])
180 (define_expand "movhi"
181 [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "")
182 (match_operand:HI 1 "xs_hi_general_operand" ""))]
184 "{ xstormy16_expand_move (HImode, operands[0], operands[1]); DONE; }")
186 (define_insn "movhi_internal"
187 [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,r")
188 (match_operand:HI 1 "xs_hi_general_operand" "r,e,m,L,L,i,i,ie,W"))]
200 [(set_attr_alternative "length"
202 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
205 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
214 (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")])
216 (define_expand "movsi"
217 [(set (match_operand:SI 0 "nonimmediate_operand" "")
218 (match_operand:SI 1 "general_operand" ""))]
220 "{ xstormy16_expand_move (SImode, operands[0], operands[1]); DONE; }")
222 (define_insn_and_split "*movsi_internal"
223 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Q,r,m,e,&e,e,r,S")
224 (match_operand:SI 1 "general_operand" "r,r,R,e,o, V,L,i,i"))]
229 "{ xstormy16_split_move (SImode, operands[0], operands[1]); DONE; }"
230 [(set_attr_alternative "length"
234 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
237 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
240 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
248 ;; ::::::::::::::::::::
252 ;; ::::::::::::::::::::
254 (define_insn "extendqihi2"
255 [(set (match_operand:HI 0 "register_operand" "=r")
256 (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
260 (define_insn "zero_extendqihi2"
261 [(set (match_operand:HI 0 "register_operand" "=e,r")
262 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,0")))]
266 shl %0,#8\n\tshr %0,#8"
267 [(set_attr "psw_operand" "nop,0")
268 (set_attr_alternative "length"
273 ;; ::::::::::::::::::::
275 ;; :: Bit field extraction
277 ;; ::::::::::::::::::::
279 ;; Extract an unsigned bit field
280 ;(define_insn "extzv"
281 ; [(set (match_operand:SI 0 "register_operand" "=r")
282 ; (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
283 ; (match_operand:SI 2 "const_int_operand" "n")
284 ; (match_operand:SI 3 "const_int_operand" "n")))]
286 ; "extzv %0,%1,%2,%3"
287 ; [(set_attr "length" "4")])
289 ;; Insert a bit field
291 ; [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
292 ; (match_operand:SI 1 "const_int_operand" "n")
293 ; (match_operand:SI 2 "const_int_operand" "n"))
294 ; (match_operand:SI 3 "nonmemory_operand" "ri"))]
297 ; [(set_attr "length" "4")])
300 ;; ::::::::::::::::::::
302 ;; :: 16-bit Integer arithmetic
304 ;; ::::::::::::::::::::
307 ; Note - the early clobber modifier is no longer needed on operand 3
308 ; and in fact can cause some reload spill failures if it is present.
309 ; Note that the 'Z' constraint matches "add $reg,0", which reload
310 ; will occasionally emit. We avoid the "add $reg,imm" match because
311 ; it clobbers the carry.
312 (define_insn "addhi3"
313 [(set (match_operand:HI 0 "register_operand" "=r,r,r,T,T,r,r,r")
314 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0,0,0")
315 (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,Z,L,M,Ir,N,i")))
316 (clobber (match_scratch:BI 3 "=X,X,X,y,y,y,y,y"))]
327 [(set_attr "length" "2,2,0,2,2,2,2,4")])
329 ; Reload can generate addition operations. The SECONDARY_RELOAD_CLASS
330 ; macro causes it to allocate the carry register; this pattern
331 ; shows it how to place the register in RTL to make the addition work.
332 (define_expand "reload_inhi"
333 [(parallel [(set (match_operand:HI 0 "register_operand" "=r")
334 (match_operand:HI 1 "xstormy16_carry_plus_operand" ""))
335 (clobber (match_operand:BI 2 "" "=&y"))])]
337 "if (! rtx_equal_p (operands[0], XEXP (operands[1], 0)))
339 emit_insn (gen_rtx_SET (VOIDmode, operands[0], XEXP (operands[1], 0)));
340 operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]), operands[0],
341 XEXP (operands[1], 1));
345 (define_insn "addchi4"
346 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
347 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
348 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
349 (set (match_operand:BI 3 "register_operand" "=y,y,y")
350 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
351 (zero_extend:SI (match_dup 2)))
358 [(set_attr "length" "2,2,4")])
360 (define_insn "addchi5"
361 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
362 (plus:HI (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
363 (zero_extend:HI (match_operand:BI 3
366 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
367 (set (match_operand:BI 4 "register_operand" "=y,y,y")
368 (truncate:BI (lshiftrt:SI (plus:SI (plus:SI
369 (zero_extend:SI (match_dup 1))
370 (zero_extend:SI (match_dup 3)))
371 (zero_extend:SI (match_dup 2)))
378 [(set_attr "length" "2,2,4")])
381 ; Operand 3 is marked earlyclobber because that helps reload
382 ; to generate better code---this pattern will never need the
383 ; carry register as an input, and some output reloads or input
384 ; reloads might need to use it. In fact, without the '&' reload
385 ; will fail in some cases.
386 (define_insn "subhi3"
387 [(set (match_operand:HI 0 "register_operand" "=r,r,T,T,r,r,r")
388 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0,0,0,0,0")
389 (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,L,M,rI,M,i")))
390 (clobber (match_scratch:BI 3 "=X,X,&y,&y,&y,&y,&y"))]
400 [(set_attr "length" "2,2,2,2,2,2,4")])
402 (define_insn "subchi4"
403 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
404 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
405 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
406 (set (match_operand:BI 3 "register_operand" "=y,y,y")
407 (truncate:BI (lshiftrt:SI (minus:SI (zero_extend:SI (match_dup 1))
408 (zero_extend:SI (match_dup 2)))
415 [(set_attr "length" "2,2,4")])
417 (define_insn "subchi5"
418 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
419 (minus:HI (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
420 (zero_extend:HI (match_operand:BI 3
423 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
424 (set (match_operand:BI 4 "register_operand" "=y,y,y")
425 (truncate:BI (lshiftrt:SI (minus:SI (minus:SI
426 (zero_extend:SI (match_dup 1))
427 (zero_extend:SI (match_dup 3)))
428 (zero_extend:SI (match_dup 2)))
435 [(set_attr "length" "2,2,4")])
437 ; Basic multiplication
438 (define_insn "mulhi3"
439 [(set (match_operand:HI 0 "register_operand" "=a")
440 (mult:HI (match_operand:HI 1 "register_operand" "%a")
441 (match_operand:HI 2 "register_operand" "c")))
442 (clobber (match_scratch:HI 3 "=b"))
446 [(set_attr "psw_operand" "nop")])
448 ;; Unsigned multiplication producing 64-bit results from 32-bit inputs
449 ; The constraint on operand 0 is 't' because it is actually two regs
450 ; long, and both regs must match the constraint.
451 (define_insn "umulhisi3"
452 [(set (match_operand:SI 0 "register_operand" "=t")
453 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%a"))
454 (zero_extend:SI (match_operand:HI 2 "register_operand" "c"))))
458 [(set_attr "psw_operand" "nop")])
460 ;; Unsigned division giving both quotient and remainder
461 (define_insn "udivmodhi4"
462 [(set (match_operand:HI 0 "register_operand" "=a")
463 (udiv:HI (match_operand:HI 1 "register_operand" "a")
464 (match_operand:HI 2 "register_operand" "c")))
465 (set (match_operand:HI 3 "register_operand" "=b")
466 (umod:HI (match_dup 1)
470 [(set_attr "psw_operand" "nop")])
472 ;; Signed division giving both quotient and remainder
473 (define_insn "divmodhi4"
474 [(set (match_operand:HI 0 "register_operand" "=a")
475 (div:HI (match_operand:HI 1 "register_operand" "a")
476 (match_operand:HI 2 "register_operand" "c")))
477 (set (match_operand:HI 3 "register_operand" "=b")
478 (mod:HI (match_dup 1)
482 [(set_attr "psw_operand" "nop")])
484 ;; Signed 32/16 division
485 (define_insn "sdivlh"
486 [(set (match_operand:HI 0 "register_operand" "=a")
487 (div:HI (match_operand:SI 2 "register_operand" "t")
488 (match_operand:HI 3 "register_operand" "c")))
489 (set (match_operand:HI 1 "register_operand" "=b")
490 (mod:HI (match_dup 2)
494 [(set_attr "psw_operand" "nop")])
496 ;; Unsigned 32/16 division
497 (define_insn "udivlh"
498 [(set (match_operand:HI 0 "register_operand" "=a")
499 (udiv:HI (match_operand:SI 2 "register_operand" "t")
500 (match_operand:HI 3 "register_operand" "c")))
501 (set (match_operand:HI 1 "register_operand" "=b")
502 (umod:HI (match_dup 2)
506 [(set_attr "psw_operand" "nop")])
510 (define_expand "neghi2"
511 [(set (match_operand:HI 0 "register_operand" "")
512 (not:HI (match_operand:HI 1 "register_operand" "")))
513 (parallel [(set (match_dup 0) (plus:HI (match_dup 0) (const_int 1)))
514 (clobber (match_scratch:BI 3 ""))])]
519 ;; ::::::::::::::::::::
521 ;; :: 16-bit Integer Shifts and Rotates
523 ;; ::::::::::::::::::::
525 ;; Arithmetic Shift Left
526 (define_insn "ashlhi3"
527 [(set (match_operand:HI 0 "register_operand" "=r")
528 (ashift:HI (match_operand:HI 1 "register_operand" "0")
529 (match_operand:HI 2 "nonmemory_operand" "ri")))
530 (clobber (match_scratch:BI 3 "=y"))]
534 ;; Arithmetic Shift Right
535 (define_insn "ashrhi3"
536 [(set (match_operand:HI 0 "register_operand" "=r")
537 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
538 (match_operand:HI 2 "nonmemory_operand" "ri")))
539 (clobber (match_scratch:BI 3 "=y"))]
543 ;; Logical Shift Right
544 (define_insn "lshrhi3"
545 [(set (match_operand:HI 0 "register_operand" "=r")
546 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
547 (match_operand:HI 2 "nonmemory_operand" "ri")))
548 (clobber (match_scratch:BI 3 "=y"))]
553 ;; ::::::::::::::::::::
555 ;; :: 16-Bit Integer Logical operations
557 ;; ::::::::::::::::::::
559 ;; Logical AND, 16-bit integers
560 (define_insn "andhi3"
561 [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
562 (and:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
563 (match_operand:HI 2 "nonmemory_operand" "L,r,K,i,K")))]
571 [(set_attr "length" "2,2,2,4,2")])
574 [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
575 (and:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
576 (match_operand:HI 2 "xstormy16_onebit_clr_operand" "")))]
579 (and:QI (match_dup 4)
581 "{ int s = ((INTVAL (operands[2]) & 0xff) == 0xff) ? 1 : 0;
582 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
583 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
584 operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
585 operands[5] = GEN_INT (INTVAL (operands[5]) | ~(HOST_WIDE_INT)0xff);
589 ;; Inclusive OR, 16-bit integers
590 (define_insn "iorhi3"
591 [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
592 (ior:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
593 (match_operand:HI 2 "nonmemory_operand" "L,r,J,i,J")))]
601 [(set_attr "length" "2,2,2,4,2")])
604 [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
605 (ior:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
606 (match_operand:HI 2 "xstormy16_onebit_set_operand" "")))]
609 (ior:QI (match_dup 4)
611 "{ int s = ((INTVAL (operands[2]) & 0xff) == 0x00) ? 1 : 0;
612 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
613 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
614 operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
615 operands[5] = GEN_INT (INTVAL (operands[5]) & 0xff);
619 ;; Exclusive OR, 16-bit integers
620 (define_insn "xorhi3"
621 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
622 (xor:HI (match_operand:HI 1 "register_operand" "%0,0,0")
623 (match_operand:HI 2 "nonmemory_operand" "L,r,i")))]
629 [(set_attr "length" "2,2,4")])
631 ;; One's complement, 16-bit integers
632 (define_insn "one_cmplhi2"
633 [(set (match_operand:HI 0 "register_operand" "=r")
634 (not:HI (match_operand:HI 1 "register_operand" "0")))]
639 ;; ::::::::::::::::::::
641 ;; :: 32-bit Integer arithmetic
643 ;; ::::::::::::::::::::
646 (define_insn_and_split "addsi3"
647 [(set (match_operand:SI 0 "register_operand" "=r")
648 (plus:SI (match_operand:SI 1 "register_operand" "%0")
649 (match_operand:SI 2 "nonmemory_operand" "ri")))
650 (clobber (match_scratch:BI 3 "=y"))]
655 "{ xstormy16_expand_arith (SImode, PLUS, operands[0], operands[1],
656 operands[2], operands[3]); DONE; } "
657 [(set_attr "length" "4")])
660 (define_insn_and_split "subsi3"
661 [(set (match_operand:SI 0 "register_operand" "=r")
662 (minus:SI (match_operand:SI 1 "register_operand" "0")
663 (match_operand:SI 2 "nonmemory_operand" "ri")))
664 (clobber (match_scratch:BI 3 "=y"))]
669 "{ xstormy16_expand_arith (SImode, MINUS, operands[0], operands[1],
670 operands[2], operands[3]); DONE; } "
671 [(set_attr "length" "4")])
673 (define_expand "negsi2"
674 [(parallel [(set (match_operand:SI 0 "register_operand" "")
675 (neg:SI (match_operand:SI 1 "register_operand" "")))
676 (clobber (match_scratch:BI 2 ""))])]
678 "{ operands[2] = gen_reg_rtx (HImode);
679 operands[3] = gen_reg_rtx (BImode); }")
681 (define_insn_and_split "*negsi2_internal"
682 [(set (match_operand:SI 0 "register_operand" "=&r")
683 (neg:SI (match_operand:SI 1 "register_operand" "r")))
684 (clobber (match_scratch:BI 2 "=y"))]
689 "{ xstormy16_expand_arith (SImode, NEG, operands[0], operands[0],
690 operands[1], operands[2]); DONE; }")
692 ;; ::::::::::::::::::::
694 ;; :: 32-bit Integer Shifts and Rotates
696 ;; ::::::::::::::::::::
698 ;; Arithmetic Shift Left
699 (define_expand "ashlsi3"
700 [(parallel [(set (match_operand:SI 0 "register_operand" "")
701 (ashift:SI (match_operand:SI 1 "register_operand" "")
702 (match_operand:SI 2 "const_int_operand" "")))
703 (clobber (match_dup 3))
704 (clobber (match_dup 4))])]
706 " if (! const_int_operand (operands[2], SImode)) FAIL;
707 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
709 ;; Arithmetic Shift Right
710 (define_expand "ashrsi3"
711 [(parallel [(set (match_operand:SI 0 "register_operand" "")
712 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
713 (match_operand:SI 2 "const_int_operand" "")))
714 (clobber (match_dup 3))
715 (clobber (match_dup 4))])]
717 " if (! const_int_operand (operands[2], SImode)) FAIL;
718 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
720 ;; Logical Shift Right
721 (define_expand "lshrsi3"
722 [(parallel [(set (match_operand:SI 0 "register_operand" "")
723 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
724 (match_operand:SI 2 "const_int_operand" "")))
725 (clobber (match_dup 3))
726 (clobber (match_dup 4))])]
728 " if (! const_int_operand (operands[2], SImode)) FAIL;
729 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
731 (define_insn "*shiftsi"
732 [(set (match_operand:SI 0 "register_operand" "=r,r")
733 (match_operator:SI 5 "shift_operator"
734 [(match_operand:SI 1 "register_operand" "0,0")
735 (match_operand:SI 2 "const_int_operand" "U,n")]))
736 (clobber (match_operand:BI 3 "register_operand" "=y,y"))
737 (clobber (match_operand:HI 4 "" "=X,r"))]
739 "* return xstormy16_output_shift (SImode, GET_CODE (operands[5]),
740 operands[0], operands[2], operands[4]);"
741 [(set_attr "length" "6,10")
742 (set_attr "psw_operand" "clobber,clobber")])
745 ;; ::::::::::::::::::::
749 ;; ::::::::::::::::::::
751 ;; Note, we store the operands in the comparison insns, and use them later
752 ;; when generating the branch or scc operation.
754 ;; First the routines called by the machine independent part of the compiler
755 (define_expand "cmphi"
757 (compare (match_operand:HI 0 "register_operand" "")
758 (match_operand:HI 1 "nonmemory_operand" "")))]
762 xstormy16_compare_op0 = operands[0];
763 xstormy16_compare_op1 = operands[1];
767 ; There are no real SImode comparisons, but some can be emulated
768 ; by performing a SImode subtract and looking at the condition flags.
769 (define_expand "cmpsi"
771 (compare (match_operand:SI 0 "register_operand" "")
772 (match_operand:SI 1 "nonmemory_operand" "")))]
776 xstormy16_compare_op0 = operands[0];
777 xstormy16_compare_op1 = operands[1];
782 ;; ::::::::::::::::::::
786 ;; ::::::::::::::::::::
789 [(use (match_operand 0 "" ""))]
791 "{ xstormy16_emit_cbranch (EQ, operands[0]); DONE; }")
794 [(use (match_operand 0 "" ""))]
796 "{ xstormy16_emit_cbranch (NE, operands[0]); DONE; }")
799 [(use (match_operand 0 "" ""))]
801 "{ xstormy16_emit_cbranch (GE, operands[0]); DONE; }")
804 [(use (match_operand 0 "" ""))]
806 "{ xstormy16_emit_cbranch (GT, operands[0]); DONE; }")
809 [(use (match_operand 0 "" ""))]
811 "{ xstormy16_emit_cbranch (LE, operands[0]); DONE; }")
814 [(use (match_operand 0 "" ""))]
816 "{ xstormy16_emit_cbranch (LT, operands[0]); DONE; }")
818 (define_expand "bgeu"
819 [(use (match_operand 0 "" ""))]
821 "{ xstormy16_emit_cbranch (GEU, operands[0]); DONE; }")
823 (define_expand "bgtu"
824 [(use (match_operand 0 "" ""))]
826 "{ xstormy16_emit_cbranch (GTU, operands[0]); DONE; }")
828 (define_expand "bleu"
829 [(use (match_operand 0 "" ""))]
831 "{ xstormy16_emit_cbranch (LEU, operands[0]); DONE; }")
833 (define_expand "bltu"
834 [(use (match_operand 0 "" ""))]
836 "{ xstormy16_emit_cbranch (LTU, operands[0]); DONE; }")
839 (define_insn "cbranchhi"
841 (if_then_else (match_operator:HI 1 "comparison_operator"
842 [(match_operand:HI 2 "nonmemory_operand"
844 (match_operand:HI 3 "nonmemory_operand"
846 (label_ref (match_operand 0 "" ""))
848 (clobber (match_operand:BI 4 "" "=&y,&y,&y"))]
852 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 0, insn);
854 [(set_attr "branch_class" "bcc12")
855 (set_attr "psw_operand" "0,0,1")])
857 (define_insn "cbranchhi_neg"
859 (if_then_else (match_operator:HI 1 "comparison_operator"
860 [(match_operand:HI 2 "nonmemory_operand"
862 (match_operand:HI 3 "nonmemory_operand"
865 (label_ref (match_operand 0 "" ""))))
866 (clobber (match_operand:BI 4 "" "=&y,&y,&y"))]
870 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 1, insn);
872 [(set_attr "branch_class" "bcc12")
873 (set_attr "psw_operand" "0,0,1")])
875 (define_insn "*eqbranchsi"
877 (if_then_else (match_operator:SI 1 "equality_operator"
878 [(match_operand:SI 2 "register_operand"
881 (label_ref (match_operand 0 "" ""))
883 (clobber (match_operand:SI 3 "register_operand" "=2"))]
887 return xstormy16_output_cbranch_si (operands[1], \"%l0\", 0, insn);
889 [(set_attr "branch_class" "bcc8p2")
890 (set_attr "psw_operand" "clobber")])
892 (define_insn_and_split "*ineqbranchsi"
894 (if_then_else (match_operator:SI 1 "xstormy16_ineqsi_operator"
895 [(match_operand:SI 2 "register_operand"
897 (match_operand:SI 3 "nonmemory_operand"
899 (label_ref (match_operand 0 "" ""))
901 (clobber (match_operand:SI 5 "register_operand" "=2"))
902 (clobber (match_operand:BI 4 "" "=&y"))]
907 "{ xstormy16_split_cbranch (SImode, operands[0], operands[1], operands[2],
908 operands[4]); DONE; }"
909 [(set_attr "length" "8")])
911 (define_insn "*ineqbranch_1"
913 (if_then_else (match_operator:HI 5 "xstormy16_ineqsi_operator"
914 [(minus:HI (match_operand:HI 1 "register_operand"
916 (zero_extend:HI (match_operand:BI 4
919 (match_operand:HI 3 "nonmemory_operand" "L,Ir,i")])
920 (label_ref (match_operand 0 "" ""))
922 (set (match_operand:HI 2 "register_operand" "=1,1,1")
923 (minus:HI (minus:HI (match_dup 1) (zero_extend:HI (match_dup 4)))
925 (clobber (match_operand:BI 6 "" "=y,y,y"))]
929 return xstormy16_output_cbranch_si (operands[5], \"%l0\", 0, insn);
931 [(set_attr "branch_class" "bcc8p2,bcc8p2,bcc8p4")
932 (set_attr "psw_operand" "2,2,2")])
935 ;; ::::::::::::::::::::
937 ;; :: Call and branch instructions
939 ;; ::::::::::::::::::::
941 ;; Subroutine call instruction returning no value. Operand 0 is the function
942 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
943 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
944 ;; registers used as operands.
946 ;; On most machines, operand 2 is not actually stored into the RTL pattern. It
947 ;; is supplied for the sake of some RISC machines which need to put this
948 ;; information into the assembler code; they can put it in the RTL instead of
951 (define_expand "call"
952 [(call (match_operand:HI 0 "memory_operand" "m")
953 (match_operand 1 "" ""))
954 (use (match_operand 2 "immediate_operand" ""))]
956 "xstormy16_expand_call (NULL_RTX, operands[0], operands[1]); DONE;")
958 ;; Subroutine call instruction returning a value. Operand 0 is the hard
959 ;; register in which the value is returned. There are three more operands, the
960 ;; same as the three operands of the `call' instruction (but with numbers
961 ;; increased by one).
963 ;; Subroutines that return `BLKmode' objects use the `call' insn.
965 (define_expand "call_value"
966 [(set (match_operand 0 "register_operand" "=r")
967 (call (match_operand:HI 1 "memory_operand" "m")
968 (match_operand:SI 2 "" "")))
969 (use (match_operand 3 "immediate_operand" ""))]
971 "xstormy16_expand_call (operands[0], operands[1], operands[2]); DONE;")
973 (define_insn "*call_internal"
974 [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
975 (match_operand 1 "" ""))
976 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
981 [(set_attr "length" "4,2")
982 (set_attr "psw_operand" "clobber")])
984 (define_insn "*call_value_internal"
985 [(set (match_operand 3 "register_operand" "=r,r")
986 (call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
987 (match_operand 1 "" "")))
988 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
993 [(set_attr "length" "4,2")
994 (set_attr "psw_operand" "clobber")])
997 (define_expand "return"
1002 (define_insn "return_internal"
1006 [(set_attr "psw_operand" "nop")])
1008 (define_insn "return_internal_interrupt"
1010 (unspec_volatile [(const_int 0)] 1)]
1013 [(set_attr "psw_operand" "clobber")])
1015 ;; Normal unconditional jump
1017 [(set (pc) (label_ref (match_operand 0 "" "")))]
1021 return xstormy16_output_cbranch_hi (NULL_RTX, \"%l0\", 0, insn);
1023 [(set_attr "branch_class" "br12")
1024 (set_attr "psw_operand" "nop")])
1026 ;; Indirect jump through a register
1027 (define_expand "indirect_jump"
1028 [(set (match_dup 1) (const_int 0))
1029 (parallel [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1030 (use (match_dup 1))])]
1032 "operands[1] = gen_reg_rtx (HImode);")
1035 [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1036 (use (match_operand:HI 1 "register_operand" "z"))]
1039 [(set_attr "length" "4")
1040 (set_attr "psw_operand" "nop")])
1042 ;; Table-based switch statements.
1043 (define_expand "casesi"
1044 [(use (match_operand:SI 0 "register_operand" ""))
1045 (use (match_operand:SI 1 "immediate_operand" ""))
1046 (use (match_operand:SI 2 "immediate_operand" ""))
1047 (use (label_ref (match_operand 3 "" "")))
1048 (use (label_ref (match_operand 4 "" "")))]
1052 xstormy16_expand_casesi (operands[0], operands[1], operands[2],
1053 operands[3], operands[4]);
1057 (define_insn "tablejump_pcrel"
1058 [(set (pc) (mem:HI (plus:HI (pc)
1059 (match_operand:HI 0 "register_operand" "r"))))
1060 (use (label_ref:SI (match_operand 1 "" "")))]
1063 [(set_attr "psw_operand" "nop")])
1066 ;; ::::::::::::::::::::
1068 ;; :: Prologue and Epilogue instructions
1070 ;; ::::::::::::::::::::
1072 ;; Called after register allocation to add any instructions needed for
1073 ;; the prologue. Using a prologue insn is favored compared to putting
1074 ;; all of the instructions in the TARGET_ASM_FUNCTION_PROLOGUE macro,
1075 ;; since it allows the scheduler to intermix instructions with the
1076 ;; saves of the caller saved registers. In some cases, it might be
1077 ;; necessary to emit a barrier instruction as the last insn to prevent
1079 (define_expand "prologue"
1084 xstormy16_expand_prologue ();
1088 ;; Called after register allocation to add any instructions needed for
1089 ;; the epilogue. Using an epilogue insn is favored compared to putting
1090 ;; all of the instructions in the TARGET_ASM_FUNCTION_EPILOGUE macro,
1091 ;; since it allows the scheduler to intermix instructions with the
1092 ;; restores of the caller saved registers. In some cases, it might be
1093 ;; necessary to emit a barrier instruction as the first insn to
1094 ;; prevent such scheduling.
1095 (define_expand "epilogue"
1100 xstormy16_expand_epilogue ();
1105 ;; ::::::::::::::::::::
1107 ;; :: Miscellaneous instructions
1109 ;; ::::::::::::::::::::
1111 ;; No operation, needed in case the user uses -g but not -O.
1116 [(set_attr "psw_operand" "nop")])
1118 ;; Pseudo instruction that prevents the scheduler from moving code above this
1120 (define_insn "blockage"
1121 [(unspec_volatile [(const_int 0)] 0)]
1124 [(set_attr "length" "0")
1125 (set_attr "psw_operand" "nop")])
1127 ;;---------------------------------------------------------------------------
1129 (define_expand "iorqi3"
1130 [(match_operand:QI 0 "xstormy16_below100_or_register" "")
1131 (match_operand:QI 1 "xstormy16_below100_or_register" "")
1132 (match_operand:QI 2 "nonmemory_operand" "")]
1136 xstormy16_expand_iorqi3 (operands);
1140 (define_insn "iorqi3_internal"
1141 [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
1142 (ior:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
1143 (match_operand:QI 2 "xstormy16_onebit_set_operand" "i")))]
1146 [(set_attr "length" "2")
1147 (set_attr "psw_operand" "0")])
1150 [(set (match_operand:QI 0 "register_operand" "")
1151 (match_operand:QI 1 "xstormy16_below100_operand" ""))
1152 (set (match_operand:HI 2 "register_operand" "")
1153 (ior:HI (match_operand:HI 3 "register_operand" "")
1154 (match_operand:QI 4 "xstormy16_onebit_set_operand" "")))
1155 (set (match_operand:QI 5 "xstormy16_below100_operand" "")
1156 (match_operand:QI 6 "register_operand" ""))
1158 "REGNO (operands[0]) == REGNO (operands[2])
1159 && REGNO (operands[0]) == REGNO (operands[3])
1160 && REGNO (operands[0]) == REGNO (operands[6])
1161 && rtx_equal_p (operands[1], operands[5])"
1163 (ior:QI (match_dup 1)
1169 (define_expand "andqi3"
1170 [(match_operand:QI 0 "xstormy16_below100_or_register" "")
1171 (match_operand:QI 1 "xstormy16_below100_or_register" "")
1172 (match_operand:QI 2 "nonmemory_operand" "")]
1176 xstormy16_expand_andqi3 (operands);
1180 (define_insn "andqi3_internal"
1181 [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
1182 (and:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
1183 (match_operand:QI 2 "xstormy16_onebit_clr_operand" "i")))]
1186 [(set_attr "length" "2")
1187 (set_attr "psw_operand" "0")])
1190 [(set (match_operand:HI 0 "register_operand" "")
1191 (and:HI (match_operand:HI 1 "register_operand" "")
1192 (match_operand 2 "immediate_operand" "")))
1193 (set (match_operand:HI 3 "register_operand" "")
1194 (zero_extend:HI (match_operand:QI 4 "register_operand" "")));
1196 "REGNO (operands[0]) == REGNO (operands[1])
1197 && REGNO (operands[0]) == REGNO (operands[3])
1198 && REGNO (operands[0]) == REGNO (operands[4])"
1200 (and:HI (match_dup 1)
1203 "operands[5] = GEN_INT (INTVAL (operands[2]) & 0xff);")
1206 [(set (match_operand:QI 0 "register_operand" "")
1207 (match_operand:QI 1 "xstormy16_below100_operand" ""))
1208 (set (match_operand:HI 2 "register_operand" "")
1209 (and:HI (match_operand:HI 3 "register_operand" "")
1210 (match_operand:QI 4 "xstormy16_onebit_clr_operand" "")))
1211 (set (match_operand:QI 5 "xstormy16_below100_operand" "")
1212 (match_operand:QI 6 "register_operand" ""))
1214 "REGNO (operands[0]) == REGNO (operands[2])
1215 && REGNO (operands[0]) == REGNO (operands[3])
1216 && REGNO (operands[0]) == REGNO (operands[6])
1217 && rtx_equal_p (operands[1], operands[5])"
1219 (and:QI (match_dup 1)
1224 ;; GCC uses different techniques to optimize MSB and LSB accesses, so
1225 ;; we have to code those separately.
1227 (define_insn "*bclrx"
1229 (if_then_else (eq:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1230 (match_operand:HI 2 "immediate_operand" "i"))
1232 (label_ref (match_operand 0 "" ""))
1234 (clobber (match_operand:BI 3 "" "=y"))]
1237 [(set_attr "length" "4")
1238 (set_attr "psw_operand" "nop")])
1240 (define_insn "*bclrx2"
1242 (if_then_else (zero_extract:HI
1244 (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1245 (match_operand:HI 2 "xstormy16_onebit_set_operand" "J"))
1247 (match_operand:HI 3 "immediate_operand" "i"))
1248 (label_ref (match_operand 0 "" ""))
1250 (clobber (match_operand:BI 4 "" "=y"))]
1253 [(set_attr "length" "4")
1254 (set_attr "psw_operand" "nop")])
1256 (define_insn "*bclrx3"
1258 (if_then_else (eq:HI (and:HI (zero_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1259 (match_operand:HI 2 "immediate_operand" "i"))
1261 (label_ref (match_operand 0 "" ""))
1263 (clobber (match_operand:BI 3 "" "=y"))]
1266 [(set_attr "length" "4")
1267 (set_attr "psw_operand" "nop")])
1269 (define_insn "*bclr7"
1271 (if_then_else (xor:HI (lshiftrt:HI (subreg:HI
1272 (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1275 (label_ref (match_operand 0 "" ""))
1277 (clobber (match_operand:BI 2 "" "=y"))]
1280 [(set_attr "length" "4")
1281 (set_attr "psw_operand" "nop")])
1283 (define_insn "*bclr15"
1285 (if_then_else (ge:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1287 (label_ref (match_operand 0 "" ""))
1289 (clobber (match_operand:BI 2 "" "=y"))]
1292 [(set_attr "length" "4")
1293 (set_attr "psw_operand" "nop")])
1295 (define_insn "*bsetx"
1297 (if_then_else (ne:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1298 (match_operand:HI 2 "immediate_operand" "i"))
1300 (label_ref (match_operand 0 "" ""))
1302 (clobber (match_operand:BI 3 "" "=y"))]
1305 [(set_attr "length" "4")
1306 (set_attr "psw_operand" "nop")])
1308 (define_insn "*bsetx2"
1310 (if_then_else (zero_extract:HI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1312 (match_operand:HI 2 "immediate_operand" "i"))
1313 (label_ref (match_operand 0 "" ""))
1315 (clobber (match_operand:BI 3 "" "=y"))]
1318 [(set_attr "length" "4")
1319 (set_attr "psw_operand" "nop")])
1321 (define_insn "*bsetx3"
1323 (if_then_else (ne:HI (and:HI (zero_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1324 (match_operand:HI 2 "immediate_operand" "i"))
1326 (label_ref (match_operand 0 "" ""))
1328 (clobber (match_operand:BI 3 "" "=y"))]
1331 [(set_attr "length" "4")
1332 (set_attr "psw_operand" "nop")])
1334 (define_insn "*bset7"
1336 (if_then_else (lshiftrt:HI (subreg:HI (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1338 (label_ref (match_operand 0 "" ""))
1340 (clobber (match_operand:BI 2 "" "=y"))]
1343 [(set_attr "length" "4")
1344 (set_attr "psw_operand" "nop")])
1346 (define_insn "*bset15"
1348 (if_then_else (lt:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1350 (label_ref (match_operand 0 "" ""))
1352 (clobber (match_operand:BI 2 "" "=y"))]
1355 [(set_attr "length" "4")
1356 (set_attr "psw_operand" "nop")])