1 ;; XSTORMY16 Machine description template
2 ;; Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005
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 2, 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 COPYING. If not, write to
20 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 ;; Boston, MA 02110-1301, USA.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
42 ;; Q post-inc mem (push)
43 ;; R pre-dec mem (pop)
46 ;; U -inf..1 or 16..inf
50 ;; ::::::::::::::::::::
54 ;; ::::::::::::::::::::
56 ; Categorize branches for the conditional in the length attribute.
57 (define_attr "branch_class" "notdirectbranch,br12,bcc12,bcc8p2,bcc8p4"
58 (const_string "notdirectbranch"))
60 ; The length of an instruction, used for branch shortening.
61 (define_attr "length" ""
63 [(eq_attr "branch_class" "br12")
64 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2046))
65 (lt (minus (match_dup 0) (pc)) (const_int 2048)))
68 (eq_attr "branch_class" "bcc12")
69 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
70 (lt (minus (match_dup 0) (pc)) (const_int 2048)))
73 (eq_attr "branch_class" "bcc8p2")
74 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -124))
75 (lt (minus (match_dup 0) (pc)) (const_int 128)))
78 (eq_attr "branch_class" "bcc8p4")
79 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -122))
80 (lt (minus (match_dup 0) (pc)) (const_int 128)))
85 ; The operand which determines the setting of Rpsw.
86 ; The numbers indicate the operand number,
87 ; 'clobber' indicates it is changed in some unspecified way
88 ; 'nop' means it is not changed.
89 (define_attr "psw_operand" "clobber,nop,0,1,2,3,4" (const_string "0"))
91 (define_asm_attributes [(set_attr "length" "4")
92 (set_attr "psw_operand" "clobber")])
94 (include "predicates.md")
96 ;; ::::::::::::::::::::
100 ;; ::::::::::::::::::::
101 ;; push/pop qi and hi are here as separate insns rather than part of
102 ;; the movqi/hi patterns because we need to ensure that reload isn't
103 ;; passed anything it can't cope with. Without these patterns, we
106 ;; (set (mem (post_inc (sp))) mem (post_inc (reg)))
108 ;; If, in this example, reg needs reloading, reload will read reg from
109 ;; the stack , adjust sp, and store reg back at what is now the wrong
110 ;; offset. By using separate patterns for push and pop we ensure that
111 ;; insns like this one are never generated.
113 (define_insn "pushqi1"
114 [(set (mem:QI (post_inc (reg:HI 15)))
115 (match_operand:QI 0 "register_operand" "r"))]
118 [(set_attr "psw_operand" "nop")
119 (set_attr "length" "2")])
121 (define_insn "popqi1"
122 [(set (match_operand:QI 0 "register_operand" "=r")
123 (mem:QI (pre_dec (reg:HI 15))))]
126 [(set_attr "psw_operand" "nop")
127 (set_attr "length" "2")])
129 (define_expand "movqi"
130 [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "")
131 (match_operand:QI 1 "general_operand" ""))]
133 "{ xstormy16_expand_move (QImode, operands[0], operands[1]); DONE; }")
135 (define_insn "movqi_internal"
136 [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,r")
137 (match_operand:QI 1 "general_operand" "r,e,m,i,i,i,i,ir,W"))]
149 [(set_attr_alternative "length"
151 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
154 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
163 (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")])
165 (define_insn "pushhi1"
166 [(set (mem:HI (post_inc (reg:HI 15)))
167 (match_operand:HI 0 "register_operand" "r"))]
170 [(set_attr "psw_operand" "nop")
171 (set_attr "length" "2")])
173 (define_insn "pophi1"
174 [(set (match_operand:HI 0 "register_operand" "=r")
175 (mem:HI (pre_dec (reg:HI 15))))]
178 [(set_attr "psw_operand" "nop")
179 (set_attr "length" "2")])
181 (define_expand "movhi"
182 [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "")
183 (match_operand:HI 1 "xs_hi_general_operand" ""))]
185 "{ xstormy16_expand_move (HImode, operands[0], operands[1]); DONE; }")
187 (define_insn "movhi_internal"
188 [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,r")
189 (match_operand:HI 1 "xs_hi_general_operand" "r,e,m,L,L,i,i,ir,W"))]
201 [(set_attr_alternative "length"
203 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
206 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
215 (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")])
217 (define_expand "movsi"
218 [(set (match_operand:SI 0 "nonimmediate_operand" "")
219 (match_operand:SI 1 "general_operand" ""))]
221 "{ xstormy16_expand_move (SImode, operands[0], operands[1]); DONE; }")
223 (define_insn_and_split "*movsi_internal"
224 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Q,r,m,e,&e,e,r,S")
225 (match_operand:SI 1 "general_operand" "r,r,R,e,o, V,L,i,i"))]
230 "{ xstormy16_split_move (SImode, operands[0], operands[1]); DONE; }"
231 [(set_attr_alternative "length"
235 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
238 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
241 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
249 ;; ::::::::::::::::::::
253 ;; ::::::::::::::::::::
255 (define_insn "extendqihi2"
256 [(set (match_operand:HI 0 "register_operand" "=r")
257 (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
261 (define_insn "zero_extendqihi2"
262 [(set (match_operand:HI 0 "register_operand" "=e,r")
263 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,0")))]
267 shl %0,#8\n\tshr %0,#8"
268 [(set_attr "psw_operand" "nop,0")
269 (set_attr_alternative "length"
274 ;; ::::::::::::::::::::
276 ;; :: Bit field extraction
278 ;; ::::::::::::::::::::
280 ;; Extract an unsigned bit field
281 ;(define_insn "extzv"
282 ; [(set (match_operand:SI 0 "register_operand" "=r")
283 ; (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
284 ; (match_operand:SI 2 "const_int_operand" "n")
285 ; (match_operand:SI 3 "const_int_operand" "n")))]
287 ; "extzv %0,%1,%2,%3"
288 ; [(set_attr "length" "4")])
290 ;; Insert a bit field
292 ; [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
293 ; (match_operand:SI 1 "const_int_operand" "n")
294 ; (match_operand:SI 2 "const_int_operand" "n"))
295 ; (match_operand:SI 3 "nonmemory_operand" "ri"))]
298 ; [(set_attr "length" "4")])
301 ;; ::::::::::::::::::::
303 ;; :: 16 bit Integer arithmetic
305 ;; ::::::::::::::::::::
308 ; Operand 3 is marked earlyclobber because that helps reload
309 ; to generate better code---this pattern will never need the
310 ; carry register as an input, and some output reloads or input
311 ; reloads might need to use it. In fact, without the '&' reload
312 ; will fail in some cases.
313 ; Note that the 'Z' constraint matches "add $reg,0", which reload
314 ; will occasionally emit. We avoid the "add $reg,imm" match because
315 ; it clobbers the carry.
316 (define_insn "addhi3"
317 [(set (match_operand:HI 0 "register_operand" "=r,r,r,T,T,r,r,r")
318 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0,0,0")
319 (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,Z,L,M,Ir,N,i")))
320 (clobber (match_scratch:BI 3 "=X,X,X,&y,&y,&y,&y,&y"))]
331 [(set_attr "length" "2,2,0,2,2,2,2,4")])
333 ; Reload can generate addition operations. The SECONDARY_RELOAD_CLASS
334 ; macro causes it to allocate the carry register; this pattern
335 ; shows it how to place the register in RTL to make the addition work.
336 (define_expand "reload_inhi"
337 [(parallel [(set (match_operand:HI 0 "register_operand" "=r")
338 (match_operand:HI 1 "xstormy16_carry_plus_operand" ""))
339 (clobber (match_operand:BI 2 "" "=&y"))])]
341 "if (! rtx_equal_p (operands[0], XEXP (operands[1], 0)))
343 emit_insn (gen_rtx_SET (VOIDmode, operands[0], XEXP (operands[1], 0)));
344 operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]), operands[0],
345 XEXP (operands[1], 1));
349 (define_insn "addchi4"
350 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
351 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
352 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
353 (set (match_operand:BI 3 "register_operand" "=y,y,y")
354 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
355 (zero_extend:SI (match_dup 2)))
362 [(set_attr "length" "2,2,4")])
364 (define_insn "addchi5"
365 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
366 (plus:HI (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
367 (zero_extend:HI (match_operand:BI 3
370 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
371 (set (match_operand:BI 4 "register_operand" "=y,y,y")
372 (truncate:BI (lshiftrt:SI (plus:SI (plus:SI
373 (zero_extend:SI (match_dup 1))
374 (zero_extend:SI (match_dup 3)))
375 (zero_extend:SI (match_dup 2)))
382 [(set_attr "length" "2,2,4")])
385 ; Operand 3 is marked earlyclobber because that helps reload
386 ; to generate better code---this pattern will never need the
387 ; carry register as an input, and some output reloads or input
388 ; reloads might need to use it. In fact, without the '&' reload
389 ; will fail in some cases.
390 (define_insn "subhi3"
391 [(set (match_operand:HI 0 "register_operand" "=r,r,T,T,r,r,r")
392 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0,0,0,0,0")
393 (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,L,M,rI,M,i")))
394 (clobber (match_scratch:BI 3 "=X,X,&y,&y,&y,&y,&y"))]
404 [(set_attr "length" "2,2,2,2,2,2,4")])
406 (define_insn "subchi4"
407 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
408 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
409 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
410 (set (match_operand:BI 3 "register_operand" "=y,y,y")
411 (truncate:BI (lshiftrt:SI (minus:SI (zero_extend:SI (match_dup 1))
412 (zero_extend:SI (match_dup 2)))
419 [(set_attr "length" "2,2,4")])
421 (define_insn "subchi5"
422 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
423 (minus:HI (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
424 (zero_extend:HI (match_operand:BI 3
427 (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
428 (set (match_operand:BI 4 "register_operand" "=y,y,y")
429 (truncate:BI (lshiftrt:SI (minus:SI (minus:SI
430 (zero_extend:SI (match_dup 1))
431 (zero_extend:SI (match_dup 3)))
432 (zero_extend:SI (match_dup 2)))
439 [(set_attr "length" "2,2,4")])
441 ; Basic multiplication
442 (define_insn "mulhi3"
443 [(set (match_operand:HI 0 "register_operand" "=a")
444 (mult:HI (match_operand:HI 1 "register_operand" "%a")
445 (match_operand:HI 2 "register_operand" "c")))
446 (clobber (match_scratch:HI 3 "=b"))
450 [(set_attr "psw_operand" "nop")])
452 ;; Unsigned multiplication producing 64 bit results from 32 bit inputs
453 ; The constraint on operand 0 is 't' because it is actually two regs
454 ; long, and both regs must match the constraint.
455 (define_insn "umulhisi3"
456 [(set (match_operand:SI 0 "register_operand" "=t")
457 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%a"))
458 (zero_extend:SI (match_operand:HI 2 "register_operand" "c"))))
462 [(set_attr "psw_operand" "nop")])
464 ;; Unsigned division giving both quotient and remainder
465 (define_insn "udivmodhi4"
466 [(set (match_operand:HI 0 "register_operand" "=a")
467 (udiv:HI (match_operand:HI 1 "register_operand" "a")
468 (match_operand:HI 2 "register_operand" "c")))
469 (set (match_operand:HI 3 "register_operand" "=b")
470 (umod:HI (match_dup 1)
474 [(set_attr "psw_operand" "nop")])
476 ;; Signed division giving both quotient and remainder
477 (define_insn "divmodhi4"
478 [(set (match_operand:HI 0 "register_operand" "=a")
479 (div:HI (match_operand:HI 1 "register_operand" "a")
480 (match_operand:HI 2 "register_operand" "c")))
481 (set (match_operand:HI 3 "register_operand" "=b")
482 (mod:HI (match_dup 1)
486 [(set_attr "psw_operand" "nop")])
488 ;; Signed 32/16 division
489 (define_insn "sdivlh"
490 [(set (match_operand:HI 0 "register_operand" "=a")
491 (div:HI (match_operand:SI 2 "register_operand" "t")
492 (match_operand:HI 3 "register_operand" "c")))
493 (set (match_operand:HI 1 "register_operand" "=b")
494 (mod:HI (match_dup 2)
498 [(set_attr "psw_operand" "nop")])
500 ;; Unsigned 32/16 division
501 (define_insn "udivlh"
502 [(set (match_operand:HI 0 "register_operand" "=a")
503 (udiv:HI (match_operand:SI 2 "register_operand" "t")
504 (match_operand:HI 3 "register_operand" "c")))
505 (set (match_operand:HI 1 "register_operand" "=b")
506 (umod:HI (match_dup 2)
510 [(set_attr "psw_operand" "nop")])
514 (define_expand "neghi2"
515 [(set (match_operand:HI 0 "register_operand" "")
516 (not:HI (match_operand:HI 1 "register_operand" "")))
517 (parallel [(set (match_dup 0) (plus:HI (match_dup 0) (const_int 1)))
518 (clobber (match_scratch:BI 3 ""))])]
523 ;; ::::::::::::::::::::
525 ;; :: 16 bit Integer Shifts and Rotates
527 ;; ::::::::::::::::::::
529 ;; Arithmetic Shift Left
530 (define_insn "ashlhi3"
531 [(set (match_operand:HI 0 "register_operand" "=r")
532 (ashift:HI (match_operand:HI 1 "register_operand" "0")
533 (match_operand:HI 2 "nonmemory_operand" "ri")))
534 (clobber (match_scratch:BI 3 "=y"))]
538 ;; Arithmetic Shift Right
539 (define_insn "ashrhi3"
540 [(set (match_operand:HI 0 "register_operand" "=r")
541 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
542 (match_operand:HI 2 "nonmemory_operand" "ri")))
543 (clobber (match_scratch:BI 3 "=y"))]
547 ;; Logical Shift Right
548 (define_insn "lshrhi3"
549 [(set (match_operand:HI 0 "register_operand" "=r")
550 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
551 (match_operand:HI 2 "nonmemory_operand" "ri")))
552 (clobber (match_scratch:BI 3 "=y"))]
557 ;; ::::::::::::::::::::
559 ;; :: 16 Bit Integer Logical operations
561 ;; ::::::::::::::::::::
563 ;; Logical AND, 16 bit integers
564 (define_insn "andhi3"
565 [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
566 (and:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
567 (match_operand:HI 2 "nonmemory_operand" "L,r,K,i,K")))]
575 [(set_attr "length" "2,2,2,4,2")])
578 [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
579 (and:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
580 (match_operand:HI 2 "xstormy16_onebit_clr_operand" "")))]
583 (and:QI (match_dup 4)
585 "{ int s = ((INTVAL (operands[2]) & 0xff) == 0xff) ? 1 : 0;
586 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
587 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
588 operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
589 operands[5] = GEN_INT (INTVAL (operands[5]) | ~(HOST_WIDE_INT)0xff);
593 ;; Inclusive OR, 16 bit integers
594 (define_insn "iorhi3"
595 [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
596 (ior:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
597 (match_operand:HI 2 "nonmemory_operand" "L,r,J,i,J")))]
605 [(set_attr "length" "2,2,2,4,2")])
608 [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
609 (ior:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
610 (match_operand:HI 2 "xstormy16_onebit_set_operand" "")))]
613 (ior:QI (match_dup 4)
615 "{ int s = ((INTVAL (operands[2]) & 0xff) == 0x00) ? 1 : 0;
616 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
617 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
618 operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
619 operands[5] = GEN_INT (INTVAL (operands[5]) & 0xff);
623 ;; Exclusive OR, 16 bit integers
624 (define_insn "xorhi3"
625 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
626 (xor:HI (match_operand:HI 1 "register_operand" "%0,0,0")
627 (match_operand:HI 2 "nonmemory_operand" "L,r,i")))]
633 [(set_attr "length" "2,2,4")])
635 ;; One's complement, 16 bit integers
636 (define_insn "one_cmplhi2"
637 [(set (match_operand:HI 0 "register_operand" "=r")
638 (not:HI (match_operand:HI 1 "register_operand" "0")))]
643 ;; ::::::::::::::::::::
645 ;; :: 32 bit Integer arithmetic
647 ;; ::::::::::::::::::::
650 (define_insn_and_split "addsi3"
651 [(set (match_operand:SI 0 "register_operand" "=r")
652 (plus:SI (match_operand:SI 1 "register_operand" "%0")
653 (match_operand:SI 2 "nonmemory_operand" "ri")))
654 (clobber (match_scratch:BI 3 "=y"))]
659 "{ xstormy16_expand_arith (SImode, PLUS, operands[0], operands[1],
660 operands[2], operands[3]); DONE; } "
661 [(set_attr "length" "4")])
664 (define_insn_and_split "subsi3"
665 [(set (match_operand:SI 0 "register_operand" "=r")
666 (minus:SI (match_operand:SI 1 "register_operand" "0")
667 (match_operand:SI 2 "nonmemory_operand" "ri")))
668 (clobber (match_scratch:BI 3 "=y"))]
673 "{ xstormy16_expand_arith (SImode, MINUS, operands[0], operands[1],
674 operands[2], operands[3]); DONE; } "
675 [(set_attr "length" "4")])
677 (define_expand "negsi2"
678 [(parallel [(set (match_operand:SI 0 "register_operand" "")
679 (neg:SI (match_operand:SI 1 "register_operand" "")))
680 (clobber (match_scratch:BI 2 ""))])]
682 "{ operands[2] = gen_reg_rtx (HImode);
683 operands[3] = gen_reg_rtx (BImode); }")
685 (define_insn_and_split "*negsi2_internal"
686 [(set (match_operand:SI 0 "register_operand" "=&r")
687 (neg:SI (match_operand:SI 1 "register_operand" "r")))
688 (clobber (match_scratch:BI 2 "=y"))]
693 "{ xstormy16_expand_arith (SImode, NEG, operands[0], operands[0],
694 operands[1], operands[2]); DONE; }")
696 ;; ::::::::::::::::::::
698 ;; :: 32 bit Integer Shifts and Rotates
700 ;; ::::::::::::::::::::
702 ;; Arithmetic Shift Left
703 (define_expand "ashlsi3"
704 [(parallel [(set (match_operand:SI 0 "register_operand" "")
705 (ashift:SI (match_operand:SI 1 "register_operand" "")
706 (match_operand:SI 2 "const_int_operand" "")))
707 (clobber (match_dup 3))
708 (clobber (match_dup 4))])]
710 " if (! const_int_operand (operands[2], SImode)) FAIL;
711 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
713 ;; Arithmetic Shift Right
714 (define_expand "ashrsi3"
715 [(parallel [(set (match_operand:SI 0 "register_operand" "")
716 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
717 (match_operand:SI 2 "const_int_operand" "")))
718 (clobber (match_dup 3))
719 (clobber (match_dup 4))])]
721 " if (! const_int_operand (operands[2], SImode)) FAIL;
722 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
724 ;; Logical Shift Right
725 (define_expand "lshrsi3"
726 [(parallel [(set (match_operand:SI 0 "register_operand" "")
727 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
728 (match_operand:SI 2 "const_int_operand" "")))
729 (clobber (match_dup 3))
730 (clobber (match_dup 4))])]
732 " if (! const_int_operand (operands[2], SImode)) FAIL;
733 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
735 (define_insn "*shiftsi"
736 [(set (match_operand:SI 0 "register_operand" "=r,r")
737 (match_operator:SI 5 "shift_operator"
738 [(match_operand:SI 1 "register_operand" "0,0")
739 (match_operand:SI 2 "const_int_operand" "U,n")]))
740 (clobber (match_operand:BI 3 "register_operand" "=y,y"))
741 (clobber (match_operand:HI 4 "" "=X,r"))]
743 "* return xstormy16_output_shift (SImode, GET_CODE (operands[5]),
744 operands[0], operands[2], operands[4]);"
745 [(set_attr "length" "6,10")
746 (set_attr "psw_operand" "clobber,clobber")])
749 ;; ::::::::::::::::::::
753 ;; ::::::::::::::::::::
755 ;; Note, we store the operands in the comparison insns, and use them later
756 ;; when generating the branch or scc operation.
758 ;; First the routines called by the machine independent part of the compiler
759 (define_expand "cmphi"
761 (compare (match_operand:HI 0 "register_operand" "")
762 (match_operand:HI 1 "nonmemory_operand" "")))]
766 xstormy16_compare_op0 = operands[0];
767 xstormy16_compare_op1 = operands[1];
771 ; There are no real SImode comparisons, but some can be emulated
772 ; by performing a SImode subtract and looking at the condition flags.
773 (define_expand "cmpsi"
775 (compare (match_operand:SI 0 "register_operand" "")
776 (match_operand:SI 1 "nonmemory_operand" "")))]
780 xstormy16_compare_op0 = operands[0];
781 xstormy16_compare_op1 = operands[1];
786 ;; ::::::::::::::::::::
790 ;; ::::::::::::::::::::
793 [(use (match_operand 0 "" ""))]
795 "{ xstormy16_emit_cbranch (EQ, operands[0]); DONE; }")
798 [(use (match_operand 0 "" ""))]
800 "{ xstormy16_emit_cbranch (NE, operands[0]); DONE; }")
803 [(use (match_operand 0 "" ""))]
805 "{ xstormy16_emit_cbranch (GE, operands[0]); DONE; }")
808 [(use (match_operand 0 "" ""))]
810 "{ xstormy16_emit_cbranch (GT, operands[0]); DONE; }")
813 [(use (match_operand 0 "" ""))]
815 "{ xstormy16_emit_cbranch (LE, operands[0]); DONE; }")
818 [(use (match_operand 0 "" ""))]
820 "{ xstormy16_emit_cbranch (LT, operands[0]); DONE; }")
822 (define_expand "bgeu"
823 [(use (match_operand 0 "" ""))]
825 "{ xstormy16_emit_cbranch (GEU, operands[0]); DONE; }")
827 (define_expand "bgtu"
828 [(use (match_operand 0 "" ""))]
830 "{ xstormy16_emit_cbranch (GTU, operands[0]); DONE; }")
832 (define_expand "bleu"
833 [(use (match_operand 0 "" ""))]
835 "{ xstormy16_emit_cbranch (LEU, operands[0]); DONE; }")
837 (define_expand "bltu"
838 [(use (match_operand 0 "" ""))]
840 "{ xstormy16_emit_cbranch (LTU, operands[0]); DONE; }")
843 (define_insn "cbranchhi"
845 (if_then_else (match_operator:HI 1 "comparison_operator"
846 [(match_operand:HI 2 "nonmemory_operand"
848 (match_operand:HI 3 "nonmemory_operand"
850 (label_ref (match_operand 0 "" ""))
852 (clobber (match_operand:BI 4 "" "=&y,&y,&y"))]
856 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 0, insn);
858 [(set_attr "branch_class" "bcc12")
859 (set_attr "psw_operand" "0,0,1")])
861 (define_insn "cbranchhi_neg"
863 (if_then_else (match_operator:HI 1 "comparison_operator"
864 [(match_operand:HI 2 "nonmemory_operand"
866 (match_operand:HI 3 "nonmemory_operand"
869 (label_ref (match_operand 0 "" ""))))
870 (clobber (match_operand:BI 4 "" "=&y,&y,&y"))]
874 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 1, insn);
876 [(set_attr "branch_class" "bcc12")
877 (set_attr "psw_operand" "0,0,1")])
879 (define_insn "*eqbranchsi"
881 (if_then_else (match_operator:SI 1 "equality_operator"
882 [(match_operand:SI 2 "register_operand"
885 (label_ref (match_operand 0 "" ""))
887 ;; Although I would greatly like the 'match_dup' in the following line
888 ;; to actually be a register constraint, there is (at the time of writing) no
889 ;; way for reload to insert an output reload on the edges out of a branch.
890 ;; If reload is fixed to use insert_insn_on_edge, this can be changed.
891 (clobber (match_dup 2))]
895 return xstormy16_output_cbranch_si (operands[1], \"%l0\", 0, insn);
897 [(set_attr "branch_class" "bcc8p2")
898 (set_attr "psw_operand" "clobber")])
900 (define_insn_and_split "*ineqbranchsi"
902 (if_then_else (match_operator:SI 1 "xstormy16_ineqsi_operator"
903 [(match_operand:SI 2 "register_operand"
905 (match_operand:SI 3 "nonmemory_operand"
907 (label_ref (match_operand 0 "" ""))
909 ;; Although I would greatly like the 'match_dup' in the following line
910 ;; to actually be a register constraint, there is (at the time of writing) no
911 ;; way for reload to insert an output reload on the edges out of a branch.
912 ;; If reload is fixed to use insert_insn_on_edge, this can be changed,
913 ;; preferably to a 'minus' operand that explains the actual operation, like:
914 ; (set (match_operand 5 "register_operand" "=2")
915 ; (minus:SI (match_operand 6 "register_operand" "2")
916 ; (match_operand 7 "register_operand" "3")))
917 (clobber (match_dup 2))
918 (clobber (match_operand:BI 4 "" "=&y"))]
923 "{ xstormy16_split_cbranch (SImode, operands[0], operands[1], operands[2],
924 operands[4]); DONE; }"
925 [(set_attr "length" "8")])
927 (define_insn "*ineqbranch_1"
929 (if_then_else (match_operator:HI 5 "xstormy16_ineqsi_operator"
930 [(minus:HI (match_operand:HI 1 "register_operand"
932 (zero_extend:HI (match_operand:BI 4
935 (match_operand:HI 3 "nonmemory_operand" "L,Ir,i")])
936 (label_ref (match_operand 0 "" ""))
938 (set (match_operand:HI 2 "register_operand" "=1,1,1")
939 (minus:HI (minus:HI (match_dup 1) (zero_extend:HI (match_dup 4)))
941 (clobber (match_operand:BI 6 "" "=y,y,y"))]
945 return xstormy16_output_cbranch_si (operands[5], \"%l0\", 0, insn);
947 [(set_attr "branch_class" "bcc8p2,bcc8p2,bcc8p4")
948 (set_attr "psw_operand" "2,2,2")])
951 ;; ::::::::::::::::::::
953 ;; :: Call and branch instructions
955 ;; ::::::::::::::::::::
957 ;; Subroutine call instruction returning no value. Operand 0 is the function
958 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
959 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
960 ;; registers used as operands.
962 ;; On most machines, operand 2 is not actually stored into the RTL pattern. It
963 ;; is supplied for the sake of some RISC machines which need to put this
964 ;; information into the assembler code; they can put it in the RTL instead of
967 (define_expand "call"
968 [(call (match_operand:HI 0 "memory_operand" "m")
969 (match_operand 1 "" ""))
970 (use (match_operand 2 "immediate_operand" ""))]
972 "xstormy16_expand_call (NULL_RTX, operands[0], operands[1]); DONE;")
974 ;; Subroutine call instruction returning a value. Operand 0 is the hard
975 ;; register in which the value is returned. There are three more operands, the
976 ;; same as the three operands of the `call' instruction (but with numbers
977 ;; increased by one).
979 ;; Subroutines that return `BLKmode' objects use the `call' insn.
981 (define_expand "call_value"
982 [(set (match_operand 0 "register_operand" "=r")
983 (call (match_operand:HI 1 "memory_operand" "m")
984 (match_operand:SI 2 "" "")))
985 (use (match_operand 3 "immediate_operand" ""))]
987 "xstormy16_expand_call (operands[0], operands[1], operands[2]); DONE;")
989 (define_insn "*call_internal"
990 [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
991 (match_operand 1 "" ""))
992 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
997 [(set_attr "length" "4,2")
998 (set_attr "psw_operand" "clobber")])
1000 (define_insn "*call_value_internal"
1001 [(set (match_operand 3 "register_operand" "=r,r")
1002 (call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
1003 (match_operand 1 "" "")))
1004 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
1009 [(set_attr "length" "4,2")
1010 (set_attr "psw_operand" "clobber")])
1012 ;; Subroutine return
1013 (define_expand "return"
1018 (define_insn "return_internal"
1022 [(set_attr "psw_operand" "nop")])
1024 (define_insn "return_internal_interrupt"
1026 (unspec_volatile [(const_int 0)] 1)]
1029 [(set_attr "psw_operand" "clobber")])
1031 ;; Normal unconditional jump
1033 [(set (pc) (label_ref (match_operand 0 "" "")))]
1037 return xstormy16_output_cbranch_hi (NULL_RTX, \"%l0\", 0, insn);
1039 [(set_attr "branch_class" "br12")
1040 (set_attr "psw_operand" "nop")])
1042 ;; Indirect jump through a register
1043 (define_expand "indirect_jump"
1044 [(set (match_dup 1) (const_int 0))
1045 (parallel [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1046 (use (match_dup 1))])]
1048 "operands[1] = gen_reg_rtx (HImode);")
1051 [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1052 (use (match_operand:HI 1 "register_operand" "z"))]
1055 [(set_attr "length" "4")
1056 (set_attr "psw_operand" "nop")])
1058 ;; Table-based switch statements.
1059 (define_expand "casesi"
1060 [(use (match_operand:SI 0 "register_operand" ""))
1061 (use (match_operand:SI 1 "immediate_operand" ""))
1062 (use (match_operand:SI 2 "immediate_operand" ""))
1063 (use (label_ref (match_operand 3 "" "")))
1064 (use (label_ref (match_operand 4 "" "")))]
1068 xstormy16_expand_casesi (operands[0], operands[1], operands[2],
1069 operands[3], operands[4]);
1073 (define_insn "tablejump_pcrel"
1074 [(set (pc) (mem:HI (plus:HI (pc)
1075 (match_operand:HI 0 "register_operand" "r"))))
1076 (use (label_ref:SI (match_operand 1 "" "")))]
1079 [(set_attr "psw_operand" "nop")])
1082 ;; ::::::::::::::::::::
1084 ;; :: Prologue and Epilogue instructions
1086 ;; ::::::::::::::::::::
1088 ;; Called after register allocation to add any instructions needed for
1089 ;; the prologue. Using a prologue insn is favored compared to putting
1090 ;; all of the instructions in the TARGET_ASM_FUNCTION_PROLOGUE macro,
1091 ;; since it allows the scheduler to intermix instructions with the
1092 ;; saves of the caller saved registers. In some cases, it might be
1093 ;; necessary to emit a barrier instruction as the last insn to prevent
1095 (define_expand "prologue"
1100 xstormy16_expand_prologue ();
1104 ;; Called after register allocation to add any instructions needed for
1105 ;; the epilogue. Using an epilogue insn is favored compared to putting
1106 ;; all of the instructions in the TARGET_ASM_FUNCTION_EPILOGUE macro,
1107 ;; since it allows the scheduler to intermix instructions with the
1108 ;; restores of the caller saved registers. In some cases, it might be
1109 ;; necessary to emit a barrier instruction as the first insn to
1110 ;; prevent such scheduling.
1111 (define_expand "epilogue"
1116 xstormy16_expand_epilogue ();
1121 ;; ::::::::::::::::::::
1123 ;; :: Miscellaneous instructions
1125 ;; ::::::::::::::::::::
1127 ;; No operation, needed in case the user uses -g but not -O.
1132 [(set_attr "psw_operand" "nop")])
1134 ;; Pseudo instruction that prevents the scheduler from moving code above this
1136 (define_insn "blockage"
1137 [(unspec_volatile [(const_int 0)] 0)]
1140 [(set_attr "length" "0")
1141 (set_attr "psw_operand" "nop")])
1143 ;;---------------------------------------------------------------------------
1145 (define_expand "iorqi3"
1146 [(match_operand:QI 0 "xstormy16_below100_or_register" "")
1147 (match_operand:QI 1 "xstormy16_below100_or_register" "")
1148 (match_operand:QI 2 "nonmemory_operand" "")]
1152 xstormy16_expand_iorqi3 (operands);
1156 (define_insn "iorqi3_internal"
1157 [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
1158 (ior:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
1159 (match_operand:QI 2 "xstormy16_onebit_set_operand" "i")))]
1162 [(set_attr "length" "2")
1163 (set_attr "psw_operand" "0")])
1166 [(set (match_operand:QI 0 "register_operand" "")
1167 (match_operand:QI 1 "xstormy16_below100_operand" ""))
1168 (set (match_operand:HI 2 "register_operand" "")
1169 (ior:HI (match_operand:HI 3 "register_operand" "")
1170 (match_operand:QI 4 "xstormy16_onebit_set_operand" "")))
1171 (set (match_operand:QI 5 "xstormy16_below100_operand" "")
1172 (match_operand:QI 6 "register_operand" ""))
1174 "REGNO (operands[0]) == REGNO (operands[2])
1175 && REGNO (operands[0]) == REGNO (operands[3])
1176 && REGNO (operands[0]) == REGNO (operands[6])
1177 && rtx_equal_p (operands[1], operands[5])"
1179 (ior:QI (match_dup 1)
1185 (define_expand "andqi3"
1186 [(match_operand:QI 0 "xstormy16_below100_or_register" "")
1187 (match_operand:QI 1 "xstormy16_below100_or_register" "")
1188 (match_operand:QI 2 "nonmemory_operand" "")]
1192 xstormy16_expand_andqi3 (operands);
1196 (define_insn "andqi3_internal"
1197 [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
1198 (and:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
1199 (match_operand:QI 2 "xstormy16_onebit_clr_operand" "i")))]
1202 [(set_attr "length" "2")
1203 (set_attr "psw_operand" "0")])
1206 [(set (match_operand:HI 0 "register_operand" "")
1207 (and:HI (match_operand:HI 1 "register_operand" "")
1208 (match_operand 2 "immediate_operand" "")))
1209 (set (match_operand:HI 3 "register_operand" "")
1210 (zero_extend:HI (match_operand:QI 4 "register_operand" "")));
1212 "REGNO (operands[0]) == REGNO (operands[1])
1213 && REGNO (operands[0]) == REGNO (operands[3])
1214 && REGNO (operands[0]) == REGNO (operands[4])"
1216 (and:HI (match_dup 1)
1219 "operands[5] = GEN_INT (INTVAL (operands[2]) & 0xff);")
1222 [(set (match_operand:QI 0 "register_operand" "")
1223 (match_operand:QI 1 "xstormy16_below100_operand" ""))
1224 (set (match_operand:HI 2 "register_operand" "")
1225 (and:HI (match_operand:HI 3 "register_operand" "")
1226 (match_operand:QI 4 "xstormy16_onebit_clr_operand" "")))
1227 (set (match_operand:QI 5 "xstormy16_below100_operand" "")
1228 (match_operand:QI 6 "register_operand" ""))
1230 "REGNO (operands[0]) == REGNO (operands[2])
1231 && REGNO (operands[0]) == REGNO (operands[3])
1232 && REGNO (operands[0]) == REGNO (operands[6])
1233 && rtx_equal_p (operands[1], operands[5])"
1235 (and:QI (match_dup 1)
1240 ;; GCC uses different techniques to optimize MSB and LSB accesses, so
1241 ;; we have to code those separately.
1243 (define_insn "*bclrx"
1245 (if_then_else (eq:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1246 (match_operand:HI 2 "immediate_operand" "i"))
1248 (label_ref (match_operand 0 "" ""))
1250 (clobber (match_operand:BI 3 "" "=y"))]
1253 [(set_attr "length" "4")
1254 (set_attr "psw_operand" "nop")])
1256 (define_insn "*bclrx2"
1258 (if_then_else (zero_extract:HI
1260 (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1261 (match_operand:HI 2 "xstormy16_onebit_set_operand" "J"))
1263 (match_operand:HI 3 "immediate_operand" "i"))
1264 (label_ref (match_operand 0 "" ""))
1266 (clobber (match_operand:BI 4 "" "=y"))]
1269 [(set_attr "length" "4")
1270 (set_attr "psw_operand" "nop")])
1272 (define_insn "*bclrx3"
1274 (if_then_else (eq:HI (and:HI (zero_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1275 (match_operand:HI 2 "immediate_operand" "i"))
1277 (label_ref (match_operand 0 "" ""))
1279 (clobber (match_operand:BI 3 "" "=y"))]
1282 [(set_attr "length" "4")
1283 (set_attr "psw_operand" "nop")])
1285 (define_insn "*bclr7"
1287 (if_then_else (xor:HI (lshiftrt:HI (subreg:HI
1288 (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1291 (label_ref (match_operand 0 "" ""))
1293 (clobber (match_operand:BI 2 "" "=y"))]
1296 [(set_attr "length" "4")
1297 (set_attr "psw_operand" "nop")])
1299 (define_insn "*bclr15"
1301 (if_then_else (ge:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1303 (label_ref (match_operand 0 "" ""))
1305 (clobber (match_operand:BI 2 "" "=y"))]
1308 [(set_attr "length" "4")
1309 (set_attr "psw_operand" "nop")])
1311 (define_insn "*bsetx"
1313 (if_then_else (ne:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1314 (match_operand:HI 2 "immediate_operand" "i"))
1316 (label_ref (match_operand 0 "" ""))
1318 (clobber (match_operand:BI 3 "" "=y"))]
1321 [(set_attr "length" "4")
1322 (set_attr "psw_operand" "nop")])
1324 (define_insn "*bsetx2"
1326 (if_then_else (zero_extract:HI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1328 (match_operand:HI 2 "immediate_operand" "i"))
1329 (label_ref (match_operand 0 "" ""))
1331 (clobber (match_operand:BI 3 "" "=y"))]
1334 [(set_attr "length" "4")
1335 (set_attr "psw_operand" "nop")])
1337 (define_insn "*bsetx3"
1339 (if_then_else (ne:HI (and:HI (zero_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1340 (match_operand:HI 2 "immediate_operand" "i"))
1342 (label_ref (match_operand 0 "" ""))
1344 (clobber (match_operand:BI 3 "" "=y"))]
1347 [(set_attr "length" "4")
1348 (set_attr "psw_operand" "nop")])
1350 (define_insn "*bset7"
1352 (if_then_else (lshiftrt:HI (subreg:HI (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1354 (label_ref (match_operand 0 "" ""))
1356 (clobber (match_operand:BI 2 "" "=y"))]
1359 [(set_attr "length" "4")
1360 (set_attr "psw_operand" "nop")])
1362 (define_insn "*bset15"
1364 (if_then_else (lt:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1366 (label_ref (match_operand 0 "" ""))
1368 (clobber (match_operand:BI 2 "" "=y"))]
1371 [(set_attr "length" "4")
1372 (set_attr "psw_operand" "nop")])