1 ;; XSTORMY16 Machine description template
2 ;; Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
3 ;; Contributed by Red Hat, Inc.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
41 ;; Q post-inc mem (push)
42 ;; R pre-dec mem (pop)
45 ;; U -inf..1 or 16..inf
49 ;; ::::::::::::::::::::
53 ;; ::::::::::::::::::::
55 ; Categorize branches for the conditional in the length attribute.
56 (define_attr "branch_class" "notdirectbranch,br12,bcc12,bcc8p2,bcc8p4"
57 (const_string "notdirectbranch"))
59 ; The length of an instruction, used for branch shortening.
60 (define_attr "length" ""
62 [(eq_attr "branch_class" "br12")
63 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2046))
64 (lt (minus (match_dup 0) (pc)) (const_int 2048)))
67 (eq_attr "branch_class" "bcc12")
68 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
69 (lt (minus (match_dup 0) (pc)) (const_int 2048)))
72 (eq_attr "branch_class" "bcc8p2")
73 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -124))
74 (lt (minus (match_dup 0) (pc)) (const_int 128)))
77 (eq_attr "branch_class" "bcc8p4")
78 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -122))
79 (lt (minus (match_dup 0) (pc)) (const_int 128)))
84 ; The operand which determines the setting of Rpsw.
85 ; The numbers indicate the operand number,
86 ; 'clobber' indicates it is changed in some unspecified way
87 ; 'nop' means it is not changed.
88 (define_attr "psw_operand" "clobber,nop,0,1,2,3,4" (const_string "0"))
90 (define_asm_attributes [(set_attr "length" "4")
91 (set_attr "psw_operand" "clobber")])
94 ;; ::::::::::::::::::::
98 ;; ::::::::::::::::::::
99 ;; push/pop qi and hi are here as separate insns rather than part of
100 ;; the movqi/hi patterns because we need to ensure that reload isn't
101 ;; passed anything it can't cope with. Without these patterns, we
104 ;; (set (mem (post_inc (sp))) mem (post_inc (reg)))
106 ;; If, in this example, reg needs reloading, reload will read reg from
107 ;; the stack , adjust sp, and store reg back at what is now the wrong
108 ;; offset. By using separate patterns for push and pop we ensure that
109 ;; insns like this one are never generated.
111 (define_insn "pushqi"
112 [(set (mem:QI (post_inc (reg:HI 15)))
113 (match_operand:QI 0 "register_operand" "r"))]
116 [(set_attr "psw_operand" "nop")
117 (set_attr "length" "2")])
120 [(set (match_operand:QI 0 "register_operand" "=r")
121 (mem:QI (pre_dec (reg:HI 15))))]
124 [(set_attr "psw_operand" "nop")
125 (set_attr "length" "2")])
127 (define_expand "movqi"
128 [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "")
129 (match_operand:QI 1 "general_operand" ""))]
131 "{ xstormy16_expand_move (QImode, operands[0], operands[1]); DONE; }")
133 (define_insn "movqi_internal"
134 [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,r")
135 (match_operand:QI 1 "general_operand" "r,e,m,i,i,i,i,ir,W"))]
147 [(set_attr_alternative "length"
149 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
152 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
161 (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")])
163 (define_insn "pushhi"
164 [(set (mem:HI (post_inc (reg:HI 15)))
165 (match_operand:HI 0 "register_operand" "r"))]
168 [(set_attr "psw_operand" "nop")
169 (set_attr "length" "2")])
172 [(set (match_operand:HI 0 "register_operand" "=r")
173 (mem:HI (pre_dec (reg:HI 15))))]
176 [(set_attr "psw_operand" "nop")
177 (set_attr "length" "2")])
179 (define_expand "movhi"
180 [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "")
181 (match_operand:HI 1 "xs_hi_general_operand" ""))]
183 "{ xstormy16_expand_move (HImode, operands[0], operands[1]); DONE; }")
185 (define_insn "movhi_internal"
186 [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,r")
187 (match_operand:HI 1 "xs_hi_general_operand" "r,e,m,L,L,i,i,ir,W"))]
199 [(set_attr_alternative "length"
201 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
204 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
213 (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")])
215 (define_expand "movsi"
216 [(set (match_operand:SI 0 "nonimmediate_operand" "")
217 (match_operand:SI 1 "general_operand" ""))]
219 "{ xstormy16_expand_move (SImode, operands[0], operands[1]); DONE; }")
221 (define_insn_and_split "*movsi_internal"
222 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Q,r,m,e,&e,e,r,S")
223 (match_operand:SI 1 "general_operand" "r,r,R,e,o, V,L,i,i"))]
228 "{ xstormy16_split_move (SImode, operands[0], operands[1]); DONE; }"
229 [(set_attr_alternative "length"
233 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
236 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
239 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
247 ;; ::::::::::::::::::::
251 ;; ::::::::::::::::::::
253 (define_insn "extendqihi2"
254 [(set (match_operand:HI 0 "register_operand" "=r")
255 (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
259 (define_insn "zero_extendqihi2"
260 [(set (match_operand:HI 0 "register_operand" "=e,r")
261 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,0")))]
265 shl %0,#8\n\tshr %0,#8"
266 [(set_attr "psw_operand" "nop,0")
267 (set_attr_alternative "length"
272 ;; ::::::::::::::::::::
274 ;; :: Bit field extraction
276 ;; ::::::::::::::::::::
278 ;; Extract an unsigned bit field
279 ;(define_insn "extzv"
280 ; [(set (match_operand:SI 0 "register_operand" "=r")
281 ; (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
282 ; (match_operand:SI 2 "const_int_operand" "n")
283 ; (match_operand:SI 3 "const_int_operand" "n")))]
285 ; "extzv %0,%1,%2,%3"
286 ; [(set_attr "length" "4")])
288 ;; Insert a bit field
290 ; [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
291 ; (match_operand:SI 1 "const_int_operand" "n")
292 ; (match_operand:SI 2 "const_int_operand" "n"))
293 ; (match_operand:SI 3 "nonmemory_operand" "ri"))]
296 ; [(set_attr "length" "4")])
299 ;; ::::::::::::::::::::
301 ;; :: 16 bit Integer arithmetic
303 ;; ::::::::::::::::::::
306 ; Operand 3 is marked earlyclobber because that helps reload
307 ; to generate better code---this pattern will never need the
308 ; carry register as an input, and some output reloads or input
309 ; reloads might need to use it. In fact, without the '&' reload
310 ; will fail in some cases.
311 ; Note that the 'Z' constraint matches "add $reg,0", which reload
312 ; will occasionally emit. We avoid the "add $reg,imm" match because
313 ; it clobbers the carry.
314 (define_insn "addhi3"
315 [(set (match_operand:HI 0 "register_operand" "=r,r,r,T,T,r,r,r")
316 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0,0,0")
317 (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,Z,L,M,Ir,N,i")))
318 (clobber (match_scratch:BI 3 "=X,X,X,&y,&y,&y,&y,&y"))]
329 [(set_attr "length" "2,2,0,2,2,2,2,4")])
331 ; Reload can generate addition operations. The SECONDARY_RELOAD_CLASS
332 ; macro causes it to allocate the carry register; this pattern
333 ; shows it how to place the register in RTL to make the addition work.
334 (define_expand "reload_inhi"
335 [(parallel [(set (match_operand:HI 0 "register_operand" "=r")
336 (match_operand:HI 1 "xstormy16_carry_plus_operand" ""))
337 (clobber (match_operand:BI 2 "" "=&y"))])]
339 "if (! rtx_equal_p (operands[0], XEXP (operands[1], 0)))
341 emit_insn (gen_rtx_SET (VOIDmode, operands[0], XEXP (operands[1], 0)));
342 operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]), operands[0],
343 XEXP (operands[1], 1));
347 (define_insn "addchi4"
348 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
349 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
350 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
351 (set (match_operand:BI 3 "register_operand" "=y,y,y")
352 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
353 (zero_extend:SI (match_dup 2)))
360 [(set_attr "length" "2,2,4")])
362 (define_insn "addchi5"
363 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
364 (plus:HI (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
365 (zero_extend:HI (match_operand:BI 3
368 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
369 (set (match_operand:BI 4 "register_operand" "=y,y,y")
370 (truncate:BI (lshiftrt:SI (plus:SI (plus:SI
371 (zero_extend:SI (match_dup 1))
372 (zero_extend:SI (match_dup 3)))
373 (zero_extend:SI (match_dup 2)))
380 [(set_attr "length" "2,2,4")])
383 ; Operand 3 is marked earlyclobber because that helps reload
384 ; to generate better code---this pattern will never need the
385 ; carry register as an input, and some output reloads or input
386 ; reloads might need to use it. In fact, without the '&' reload
387 ; will fail in some cases.
388 (define_insn "subhi3"
389 [(set (match_operand:HI 0 "register_operand" "=r,r,T,T,r,r,r")
390 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0,0,0,0,0")
391 (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,L,M,rI,M,i")))
392 (clobber (match_scratch:BI 3 "=X,X,&y,&y,&y,&y,&y"))]
402 [(set_attr "length" "2,2,2,2,2,2,4")])
404 (define_insn "subchi4"
405 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
406 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
407 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
408 (set (match_operand:BI 3 "register_operand" "=y,y,y")
409 (truncate:BI (lshiftrt:SI (minus:SI (zero_extend:SI (match_dup 1))
410 (zero_extend:SI (match_dup 2)))
417 [(set_attr "length" "2,2,4")])
419 (define_insn "subchi5"
420 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
421 (minus:HI (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
422 (zero_extend:HI (match_operand:BI 3
425 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
426 (set (match_operand:BI 4 "register_operand" "=y,y,y")
427 (truncate:BI (lshiftrt:SI (minus:SI (minus:SI
428 (zero_extend:SI (match_dup 1))
429 (zero_extend:SI (match_dup 3)))
430 (zero_extend:SI (match_dup 2)))
437 [(set_attr "length" "2,2,4")])
439 ; Basic multiplication
440 (define_insn "mulhi3"
441 [(set (match_operand:HI 0 "register_operand" "=a")
442 (mult:HI (match_operand:HI 1 "register_operand" "%a")
443 (match_operand:HI 2 "register_operand" "c")))
444 (clobber (match_scratch:HI 3 "=b"))
448 [(set_attr "psw_operand" "nop")])
450 ;; Unsigned multiplication producing 64 bit results from 32 bit inputs
451 ; The constraint on operand 0 is 't' because it is actually two regs
452 ; long, and both regs must match the constraint.
453 (define_insn "umulhisi3"
454 [(set (match_operand:SI 0 "register_operand" "=t")
455 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%a"))
456 (zero_extend:SI (match_operand:HI 2 "register_operand" "c"))))
460 [(set_attr "psw_operand" "nop")])
462 ;; Unsigned division giving both quotient and remainder
463 (define_insn "udivmodhi4"
464 [(set (match_operand:HI 0 "register_operand" "=a")
465 (udiv: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 (umod:HI (match_dup 1)
472 [(set_attr "psw_operand" "nop")])
474 ;; Signed division giving both quotient and remainder
475 (define_insn "divmodhi4"
476 [(set (match_operand:HI 0 "register_operand" "=a")
477 (div:HI (match_operand:HI 1 "register_operand" "a")
478 (match_operand:HI 2 "register_operand" "c")))
479 (set (match_operand:HI 3 "register_operand" "=b")
480 (mod:HI (match_dup 1)
484 [(set_attr "psw_operand" "nop")])
486 ;; Signed 32/16 division
487 (define_insn "sdivlh"
488 [(set (match_operand:HI 0 "register_operand" "=a")
489 (div: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 (mod:HI (match_dup 2)
496 [(set_attr "psw_operand" "nop")])
498 ;; Unsigned 32/16 division
499 (define_insn "udivlh"
500 [(set (match_operand:HI 0 "register_operand" "=a")
501 (udiv:HI (match_operand:SI 2 "register_operand" "t")
502 (match_operand:HI 3 "register_operand" "c")))
503 (set (match_operand:HI 1 "register_operand" "=b")
504 (umod:HI (match_dup 2)
508 [(set_attr "psw_operand" "nop")])
512 (define_expand "neghi2"
513 [(set (match_operand:HI 0 "register_operand" "")
514 (not:HI (match_operand:HI 1 "register_operand" "")))
515 (parallel [(set (match_dup 0) (plus:HI (match_dup 0) (const_int 1)))
516 (clobber (match_scratch:BI 3 ""))])]
521 ;; ::::::::::::::::::::
523 ;; :: 16 bit Integer Shifts and Rotates
525 ;; ::::::::::::::::::::
527 ;; Arithmetic Shift Left
528 (define_insn "ashlhi3"
529 [(set (match_operand:HI 0 "register_operand" "=r")
530 (ashift:HI (match_operand:HI 1 "register_operand" "0")
531 (match_operand:HI 2 "nonmemory_operand" "ri")))
532 (clobber (match_scratch:BI 3 "=y"))]
536 ;; Arithmetic Shift Right
537 (define_insn "ashrhi3"
538 [(set (match_operand:HI 0 "register_operand" "=r")
539 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
540 (match_operand:HI 2 "nonmemory_operand" "ri")))
541 (clobber (match_scratch:BI 3 "=y"))]
545 ;; Logical Shift Right
546 (define_insn "lshrhi3"
547 [(set (match_operand:HI 0 "register_operand" "=r")
548 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
549 (match_operand:HI 2 "nonmemory_operand" "ri")))
550 (clobber (match_scratch:BI 3 "=y"))]
555 ;; ::::::::::::::::::::
557 ;; :: 16 Bit Integer Logical operations
559 ;; ::::::::::::::::::::
561 ;; Logical AND, 16 bit integers
562 (define_insn "andhi3"
563 [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
564 (and:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
565 (match_operand:HI 2 "nonmemory_operand" "L,r,K,i,K")))]
573 [(set_attr "length" "2,2,2,4,2")])
576 [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
577 (and:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
578 (match_operand:HI 2 "xstormy16_onebit_clr_operand" "")))]
581 (and:QI (match_dup 4)
583 "{ int s = ((INTVAL (operands[2]) & 0xff) == 0xff) ? 1 : 0;
584 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
585 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
586 operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
587 operands[5] = GEN_INT (INTVAL (operands[5]) | ~(HOST_WIDE_INT)0xff);
591 ;; Inclusive OR, 16 bit integers
592 (define_insn "iorhi3"
593 [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
594 (ior:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
595 (match_operand:HI 2 "nonmemory_operand" "L,r,J,i,J")))]
603 [(set_attr "length" "2,2,2,4,2")])
606 [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
607 (ior:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
608 (match_operand:HI 2 "xstormy16_onebit_set_operand" "")))]
611 (ior:QI (match_dup 4)
613 "{ int s = ((INTVAL (operands[2]) & 0xff) == 0x00) ? 1 : 0;
614 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
615 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
616 operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
617 operands[5] = GEN_INT (INTVAL (operands[5]) & 0xff);
621 ;; Exclusive OR, 16 bit integers
622 (define_insn "xorhi3"
623 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
624 (xor:HI (match_operand:HI 1 "register_operand" "%0,0,0")
625 (match_operand:HI 2 "nonmemory_operand" "L,r,i")))]
631 [(set_attr "length" "2,2,4")])
633 ;; One's complement, 16 bit integers
634 (define_insn "one_cmplhi2"
635 [(set (match_operand:HI 0 "register_operand" "=r")
636 (not:HI (match_operand:HI 1 "register_operand" "0")))]
641 ;; ::::::::::::::::::::
643 ;; :: 32 bit Integer arithmetic
645 ;; ::::::::::::::::::::
648 (define_insn_and_split "addsi3"
649 [(set (match_operand:SI 0 "register_operand" "=r")
650 (plus:SI (match_operand:SI 1 "register_operand" "%0")
651 (match_operand:SI 2 "nonmemory_operand" "ri")))
652 (clobber (match_scratch:BI 3 "=y"))]
657 "{ xstormy16_expand_arith (SImode, PLUS, operands[0], operands[1],
658 operands[2], operands[3]); DONE; } "
659 [(set_attr "length" "4")])
662 (define_insn_and_split "subsi3"
663 [(set (match_operand:SI 0 "register_operand" "=r")
664 (minus:SI (match_operand:SI 1 "register_operand" "0")
665 (match_operand:SI 2 "nonmemory_operand" "ri")))
666 (clobber (match_scratch:BI 3 "=y"))]
671 "{ xstormy16_expand_arith (SImode, MINUS, operands[0], operands[1],
672 operands[2], operands[3]); DONE; } "
673 [(set_attr "length" "4")])
675 (define_expand "negsi2"
676 [(parallel [(set (match_operand:SI 0 "register_operand" "")
677 (neg:SI (match_operand:SI 1 "register_operand" "")))
678 (clobber (match_scratch:BI 2 ""))])]
680 "{ operands[2] = gen_reg_rtx (HImode);
681 operands[3] = gen_reg_rtx (BImode); }")
683 (define_insn_and_split "*negsi2_internal"
684 [(set (match_operand:SI 0 "register_operand" "=&r")
685 (neg:SI (match_operand:SI 1 "register_operand" "r")))
686 (clobber (match_scratch:BI 2 "=y"))]
691 "{ xstormy16_expand_arith (SImode, NEG, operands[0], operands[0],
692 operands[1], operands[2]); DONE; }")
694 ;; ::::::::::::::::::::
696 ;; :: 32 bit Integer Shifts and Rotates
698 ;; ::::::::::::::::::::
700 ;; Arithmetic Shift Left
701 (define_expand "ashlsi3"
702 [(parallel [(set (match_operand:SI 0 "register_operand" "")
703 (ashift:SI (match_operand:SI 1 "register_operand" "")
704 (match_operand:SI 2 "const_int_operand" "")))
705 (clobber (match_dup 3))
706 (clobber (match_dup 4))])]
708 " if (! const_int_operand (operands[2], SImode)) FAIL;
709 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
711 ;; Arithmetic Shift Right
712 (define_expand "ashrsi3"
713 [(parallel [(set (match_operand:SI 0 "register_operand" "")
714 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
715 (match_operand:SI 2 "const_int_operand" "")))
716 (clobber (match_dup 3))
717 (clobber (match_dup 4))])]
719 " if (! const_int_operand (operands[2], SImode)) FAIL;
720 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
722 ;; Logical Shift Right
723 (define_expand "lshrsi3"
724 [(parallel [(set (match_operand:SI 0 "register_operand" "")
725 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
726 (match_operand:SI 2 "const_int_operand" "")))
727 (clobber (match_dup 3))
728 (clobber (match_dup 4))])]
730 " if (! const_int_operand (operands[2], SImode)) FAIL;
731 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
733 (define_insn "*shiftsi"
734 [(set (match_operand:SI 0 "register_operand" "=r,r")
735 (match_operator:SI 5 "shift_operator"
736 [(match_operand:SI 1 "register_operand" "0,0")
737 (match_operand:SI 2 "const_int_operand" "U,n")]))
738 (clobber (match_operand:BI 3 "register_operand" "=y,y"))
739 (clobber (match_operand:HI 4 "" "=X,r"))]
741 "* return xstormy16_output_shift (SImode, GET_CODE (operands[5]),
742 operands[0], operands[2], operands[4]);"
743 [(set_attr "length" "6,10")
744 (set_attr "psw_operand" "clobber,clobber")])
747 ;; ::::::::::::::::::::
751 ;; ::::::::::::::::::::
753 ;; Note, we store the operands in the comparison insns, and use them later
754 ;; when generating the branch or scc operation.
756 ;; First the routines called by the machine independent part of the compiler
757 (define_expand "cmphi"
759 (compare (match_operand:HI 0 "register_operand" "")
760 (match_operand:HI 1 "nonmemory_operand" "")))]
764 xstormy16_compare_op0 = operands[0];
765 xstormy16_compare_op1 = operands[1];
769 ; There are no real SImode comparisons, but some can be emulated
770 ; by performing a SImode subtract and looking at the condition flags.
771 (define_expand "cmpsi"
773 (compare (match_operand:SI 0 "register_operand" "")
774 (match_operand:SI 1 "nonmemory_operand" "")))]
778 xstormy16_compare_op0 = operands[0];
779 xstormy16_compare_op1 = operands[1];
784 ;; ::::::::::::::::::::
788 ;; ::::::::::::::::::::
791 [(use (match_operand 0 "" ""))]
793 "{ xstormy16_emit_cbranch (EQ, operands[0]); DONE; }")
796 [(use (match_operand 0 "" ""))]
798 "{ xstormy16_emit_cbranch (NE, operands[0]); DONE; }")
801 [(use (match_operand 0 "" ""))]
803 "{ xstormy16_emit_cbranch (GE, operands[0]); DONE; }")
806 [(use (match_operand 0 "" ""))]
808 "{ xstormy16_emit_cbranch (GT, operands[0]); DONE; }")
811 [(use (match_operand 0 "" ""))]
813 "{ xstormy16_emit_cbranch (LE, operands[0]); DONE; }")
816 [(use (match_operand 0 "" ""))]
818 "{ xstormy16_emit_cbranch (LT, operands[0]); DONE; }")
820 (define_expand "bgeu"
821 [(use (match_operand 0 "" ""))]
823 "{ xstormy16_emit_cbranch (GEU, operands[0]); DONE; }")
825 (define_expand "bgtu"
826 [(use (match_operand 0 "" ""))]
828 "{ xstormy16_emit_cbranch (GTU, operands[0]); DONE; }")
830 (define_expand "bleu"
831 [(use (match_operand 0 "" ""))]
833 "{ xstormy16_emit_cbranch (LEU, operands[0]); DONE; }")
835 (define_expand "bltu"
836 [(use (match_operand 0 "" ""))]
838 "{ xstormy16_emit_cbranch (LTU, operands[0]); DONE; }")
841 (define_insn "cbranchhi"
843 (if_then_else (match_operator:HI 1 "comparison_operator"
844 [(match_operand:HI 2 "nonmemory_operand"
846 (match_operand:HI 3 "nonmemory_operand"
848 (label_ref (match_operand 0 "" ""))
850 (clobber (match_operand:BI 4 "" "=&y,&y,&y"))]
854 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 0, insn);
856 [(set_attr "branch_class" "bcc12")
857 (set_attr "psw_operand" "0,0,1")])
859 (define_insn "cbranchhi_neg"
861 (if_then_else (match_operator:HI 1 "comparison_operator"
862 [(match_operand:HI 2 "nonmemory_operand"
864 (match_operand:HI 3 "nonmemory_operand"
867 (label_ref (match_operand 0 "" ""))))
868 (clobber (match_operand:BI 4 "" "=&y,&y,&y"))]
872 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 1, insn);
874 [(set_attr "branch_class" "bcc12")
875 (set_attr "psw_operand" "0,0,1")])
877 (define_insn "*eqbranchsi"
879 (if_then_else (match_operator:SI 1 "equality_operator"
880 [(match_operand:SI 2 "register_operand"
883 (label_ref (match_operand 0 "" ""))
885 ;; Although I would greatly like the 'match_dup' in the following line
886 ;; to actually be a register constraint, there is (at the time of writing) no
887 ;; way for reload to insert an output reload on the edges out of a branch.
888 ;; If reload is fixed to use insert_insn_on_edge, this can be changed.
889 (clobber (match_dup 2))]
893 return xstormy16_output_cbranch_si (operands[1], \"%l0\", 0, insn);
895 [(set_attr "branch_class" "bcc8p2")
896 (set_attr "psw_operand" "clobber")])
898 (define_insn_and_split "*ineqbranchsi"
900 (if_then_else (match_operator:SI 1 "xstormy16_ineqsi_operator"
901 [(match_operand:SI 2 "register_operand"
903 (match_operand:SI 3 "nonmemory_operand"
905 (label_ref (match_operand 0 "" ""))
907 ;; Although I would greatly like the 'match_dup' in the following line
908 ;; to actually be a register constraint, there is (at the time of writing) no
909 ;; way for reload to insert an output reload on the edges out of a branch.
910 ;; If reload is fixed to use insert_insn_on_edge, this can be changed,
911 ;; preferably to a 'minus' operand that explains the actual operation, like:
912 ; (set (match_operand 5 "register_operand" "=2")
913 ; (minus:SI (match_operand 6 "register_operand" "2")
914 ; (match_operand 7 "register_operand" "3")))
915 (clobber (match_dup 2))
916 (clobber (match_operand:BI 4 "" "=&y"))]
921 "{ xstormy16_split_cbranch (SImode, operands[0], operands[1], operands[2],
922 operands[4]); DONE; }"
923 [(set_attr "length" "8")])
925 (define_insn "*ineqbranch_1"
927 (if_then_else (match_operator:HI 5 "xstormy16_ineqsi_operator"
928 [(minus:HI (match_operand:HI 1 "register_operand"
930 (zero_extend:HI (match_operand:BI 4
933 (match_operand:HI 3 "nonmemory_operand" "L,Ir,i")])
934 (label_ref (match_operand 0 "" ""))
936 (set (match_operand:HI 2 "register_operand" "=1,1,1")
937 (minus:HI (minus:HI (match_dup 1) (zero_extend:HI (match_dup 4)))
939 (clobber (match_operand:BI 6 "" "=y,y,y"))]
943 return xstormy16_output_cbranch_si (operands[5], \"%l0\", 0, insn);
945 [(set_attr "branch_class" "bcc8p2,bcc8p2,bcc8p4")
946 (set_attr "psw_operand" "2,2,2")])
949 ;; ::::::::::::::::::::
951 ;; :: Call and branch instructions
953 ;; ::::::::::::::::::::
955 ;; Subroutine call instruction returning no value. Operand 0 is the function
956 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
957 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
958 ;; registers used as operands.
960 ;; On most machines, operand 2 is not actually stored into the RTL pattern. It
961 ;; is supplied for the sake of some RISC machines which need to put this
962 ;; information into the assembler code; they can put it in the RTL instead of
965 (define_expand "call"
966 [(call (match_operand:HI 0 "memory_operand" "m")
967 (match_operand 1 "" ""))
968 (use (match_operand 2 "immediate_operand" ""))]
970 "xstormy16_expand_call (NULL_RTX, operands[0], operands[1]); DONE;")
972 ;; Subroutine call instruction returning a value. Operand 0 is the hard
973 ;; register in which the value is returned. There are three more operands, the
974 ;; same as the three operands of the `call' instruction (but with numbers
975 ;; increased by one).
977 ;; Subroutines that return `BLKmode' objects use the `call' insn.
979 (define_expand "call_value"
980 [(set (match_operand 0 "register_operand" "=r")
981 (call (match_operand:HI 1 "memory_operand" "m")
982 (match_operand:SI 2 "" "")))
983 (use (match_operand 3 "immediate_operand" ""))]
985 "xstormy16_expand_call (operands[0], operands[1], operands[2]); DONE;")
987 (define_insn "*call_internal"
988 [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
989 (match_operand 1 "" ""))
990 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
995 [(set_attr "length" "4,2")
996 (set_attr "psw_operand" "clobber")])
998 (define_insn "*call_value_internal"
999 [(set (match_operand 3 "register_operand" "=r,r")
1000 (call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
1001 (match_operand 1 "" "")))
1002 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
1007 [(set_attr "length" "4,2")
1008 (set_attr "psw_operand" "clobber")])
1010 ;; Subroutine return
1011 (define_expand "return"
1016 (define_insn "return_internal"
1020 [(set_attr "psw_operand" "nop")])
1022 (define_insn "return_internal_interrupt"
1024 (unspec_volatile [(const_int 0)] 1)]
1027 [(set_attr "psw_operand" "clobber")])
1029 ;; Normal unconditional jump
1031 [(set (pc) (label_ref (match_operand 0 "" "")))]
1035 return xstormy16_output_cbranch_hi (NULL_RTX, \"%l0\", 0, insn);
1037 [(set_attr "branch_class" "br12")
1038 (set_attr "psw_operand" "nop")])
1040 ;; Indirect jump through a register
1041 (define_expand "indirect_jump"
1042 [(set (match_dup 1) (const_int 0))
1043 (parallel [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1044 (use (match_dup 1))])]
1046 "operands[1] = gen_reg_rtx (HImode);")
1049 [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1050 (use (match_operand:HI 1 "register_operand" "z"))]
1053 [(set_attr "length" "4")
1054 (set_attr "psw_operand" "nop")])
1056 ;; Table-based switch statements.
1057 (define_expand "casesi"
1058 [(use (match_operand:SI 0 "register_operand" ""))
1059 (use (match_operand:SI 1 "immediate_operand" ""))
1060 (use (match_operand:SI 2 "immediate_operand" ""))
1061 (use (label_ref (match_operand 3 "" "")))
1062 (use (label_ref (match_operand 4 "" "")))]
1066 xstormy16_expand_casesi (operands[0], operands[1], operands[2],
1067 operands[3], operands[4]);
1071 (define_insn "tablejump_pcrel"
1072 [(set (pc) (mem:HI (plus:HI (pc)
1073 (match_operand:HI 0 "register_operand" "r"))))
1074 (use (label_ref:SI (match_operand 1 "" "")))]
1077 [(set_attr "psw_operand" "nop")])
1080 ;; ::::::::::::::::::::
1082 ;; :: Prologue and Epilogue instructions
1084 ;; ::::::::::::::::::::
1086 ;; Called after register allocation to add any instructions needed for
1087 ;; the prologue. Using a prologue insn is favored compared to putting
1088 ;; all of the instructions in the TARGET_ASM_FUNCTION_PROLOGUE macro,
1089 ;; since it allows the scheduler to intermix instructions with the
1090 ;; saves of the caller saved registers. In some cases, it might be
1091 ;; necessary to emit a barrier instruction as the last insn to prevent
1093 (define_expand "prologue"
1098 xstormy16_expand_prologue ();
1102 ;; Called after register allocation to add any instructions needed for
1103 ;; the epilogue. Using an epilogue insn is favored compared to putting
1104 ;; all of the instructions in the TARGET_ASM_FUNCTION_EPILOGUE macro,
1105 ;; since it allows the scheduler to intermix instructions with the
1106 ;; restires of the caller saved registers. In some cases, it might be
1107 ;; necessary to emit a barrier instruction as the first insn to
1108 ;; prevent such scheduling.
1109 (define_expand "epilogue"
1114 xstormy16_expand_epilogue ();
1119 ;; ::::::::::::::::::::
1121 ;; :: Miscellaneous instructions
1123 ;; ::::::::::::::::::::
1125 ;; No operation, needed in case the user uses -g but not -O.
1130 [(set_attr "psw_operand" "nop")])
1132 ;; Pseudo instruction that prevents the scheduler from moving code above this
1134 (define_insn "blockage"
1135 [(unspec_volatile [(const_int 0)] 0)]
1138 [(set_attr "length" "0")
1139 (set_attr "psw_operand" "nop")])
1141 ;;---------------------------------------------------------------------------
1143 (define_expand "iorqi3"
1144 [(match_operand:QI 0 "xstormy16_below100_or_register" "")
1145 (match_operand:QI 1 "xstormy16_below100_or_register" "")
1146 (match_operand:QI 2 "nonmemory_operand" "")]
1150 xstormy16_expand_iorqi3 (operands);
1154 (define_insn "iorqi3_internal"
1155 [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
1156 (ior:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
1157 (match_operand:QI 2 "xstormy16_onebit_set_operand" "i")))]
1160 [(set_attr "length" "2")
1161 (set_attr "psw_operand" "0")])
1164 [(set (match_operand:QI 0 "register_operand" "")
1165 (match_operand:QI 1 "xstormy16_below100_operand" ""))
1166 (set (match_operand:HI 2 "register_operand" "")
1167 (ior:HI (match_operand:HI 3 "register_operand" "")
1168 (match_operand:QI 4 "xstormy16_onebit_set_operand" "")))
1169 (set (match_operand:QI 5 "xstormy16_below100_operand" "")
1170 (match_operand:QI 6 "register_operand" ""))
1172 "REGNO (operands[0]) == REGNO (operands[2])
1173 && REGNO (operands[0]) == REGNO (operands[3])
1174 && REGNO (operands[0]) == REGNO (operands[6])
1175 && rtx_equal_p (operands[1], operands[5])"
1177 (ior:QI (match_dup 1)
1183 (define_expand "andqi3"
1184 [(match_operand:QI 0 "xstormy16_below100_or_register" "")
1185 (match_operand:QI 1 "xstormy16_below100_or_register" "")
1186 (match_operand:QI 2 "nonmemory_operand" "")]
1190 xstormy16_expand_andqi3 (operands);
1194 (define_insn "andqi3_internal"
1195 [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
1196 (and:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
1197 (match_operand:QI 2 "xstormy16_onebit_clr_operand" "i")))]
1200 [(set_attr "length" "2")
1201 (set_attr "psw_operand" "0")])
1204 [(set (match_operand:HI 0 "register_operand" "")
1205 (and:HI (match_operand:HI 1 "register_operand" "")
1206 (match_operand 2 "immediate_operand" "")))
1207 (set (match_operand:HI 3 "register_operand" "")
1208 (zero_extend:HI (match_operand:QI 4 "register_operand" "")));
1210 "REGNO (operands[0]) == REGNO (operands[1])
1211 && REGNO (operands[0]) == REGNO (operands[3])
1212 && REGNO (operands[0]) == REGNO (operands[4])"
1214 (and:HI (match_dup 1)
1217 "operands[5] = GEN_INT (INTVAL (operands[2]) & 0xff);")
1220 [(set (match_operand:QI 0 "register_operand" "")
1221 (match_operand:QI 1 "xstormy16_below100_operand" ""))
1222 (set (match_operand:HI 2 "register_operand" "")
1223 (and:HI (match_operand:HI 3 "register_operand" "")
1224 (match_operand:QI 4 "xstormy16_onebit_clr_operand" "")))
1225 (set (match_operand:QI 5 "xstormy16_below100_operand" "")
1226 (match_operand:QI 6 "register_operand" ""))
1228 "REGNO (operands[0]) == REGNO (operands[2])
1229 && REGNO (operands[0]) == REGNO (operands[3])
1230 && REGNO (operands[0]) == REGNO (operands[6])
1231 && rtx_equal_p (operands[1], operands[5])"
1233 (and:QI (match_dup 1)
1238 ;; GCC uses different techniques to optimize MSB and LSB accesses, so
1239 ;; we have to code those separately.
1241 (define_insn "*bclrx"
1243 (if_then_else (eq:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1244 (match_operand:HI 2 "immediate_operand" "i"))
1246 (label_ref (match_operand 0 "" ""))
1248 (clobber (match_operand:BI 3 "" "=y"))]
1251 [(set_attr "length" "4")
1252 (set_attr "psw_operand" "nop")])
1254 (define_insn "*bclrx2"
1256 (if_then_else (zero_extract:HI
1258 (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1259 (match_operand:HI 2 "xstormy16_onebit_set_operand" "J"))
1261 (match_operand:HI 3 "immediate_operand" "i"))
1262 (label_ref (match_operand 0 "" ""))
1264 (clobber (match_operand:BI 4 "" "=y"))]
1267 [(set_attr "length" "4")
1268 (set_attr "psw_operand" "nop")])
1270 (define_insn "*bclr7"
1272 (if_then_else (xor:HI (lshiftrt:HI (subreg:HI
1273 (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1276 (label_ref (match_operand 0 "" ""))
1278 (clobber (match_operand:BI 2 "" "=y"))]
1281 [(set_attr "length" "4")
1282 (set_attr "psw_operand" "nop")])
1284 (define_insn "*bclr15"
1286 (if_then_else (ge:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1288 (label_ref (match_operand 0 "" ""))
1290 (clobber (match_operand:BI 2 "" "=y"))]
1293 [(set_attr "length" "4")
1294 (set_attr "psw_operand" "nop")])
1296 (define_insn "*bsetx"
1298 (if_then_else (ne:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1299 (match_operand:HI 2 "immediate_operand" "i"))
1301 (label_ref (match_operand 0 "" ""))
1303 (clobber (match_operand:BI 3 "" "=y"))]
1306 [(set_attr "length" "4")
1307 (set_attr "psw_operand" "nop")])
1309 (define_insn "*bsetx2"
1311 (if_then_else (zero_extract:HI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1313 (match_operand:HI 2 "immediate_operand" "i"))
1314 (label_ref (match_operand 0 "" ""))
1316 (clobber (match_operand:BI 3 "" "=y"))]
1319 [(set_attr "length" "4")
1320 (set_attr "psw_operand" "nop")])
1322 (define_insn "*bset7"
1324 (if_then_else (lshiftrt:HI (subreg:HI (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1326 (label_ref (match_operand 0 "" ""))
1328 (clobber (match_operand:BI 2 "" "=y"))]
1331 [(set_attr "length" "4")
1332 (set_attr "psw_operand" "nop")])
1334 (define_insn "*bset15"
1336 (if_then_else (lt:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1338 (label_ref (match_operand 0 "" ""))
1340 (clobber (match_operand:BI 2 "" "=y"))]
1343 [(set_attr "length" "4")
1344 (set_attr "psw_operand" "nop")])