1 ;; GCC machine description for Matsushita MN10300
2 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
4 ;; Contributed by Jeff Law (law@cygnus.com).
6 ;; This file is part of GNU CC.
8 ;; GNU CC 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 ;; GNU CC 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 GNU CC; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;; Condition code settings.
29 ;; none - insn does not affect cc
30 ;; none_0hit - insn does not affect cc but it does modify operand 0
31 ;; This attribute is used to keep track of when operand 0 changes.
32 ;; See the description of NOTICE_UPDATE_CC for more info.
33 ;; set - insn sets flags z,n. v is unusable c is set to 0.
34 ;; (c may not really be set to 0 but that's ok, we don't need it anyway).
35 ;; set_zn_c0 - insn sets z,n to usable values. v is unknown. c may or may not
36 ;; be known (if it isn't that's ok, we don't need it anyway).
37 ;; compare - compare instruction
38 ;; invert -- like compare, but flags are inverted.
39 ;; clobber - value of cc is unknown
40 (define_attr "cc" "none,none_0hit,tst,set_zn_c0,compare,clobber,invert"
41 (const_string "clobber"))
43 ;; ----------------------------------------------------------------------
45 ;; ----------------------------------------------------------------------
49 (define_expand "movqi"
50 [(set (match_operand:QI 0 "general_operand" "")
51 (match_operand:QI 1 "general_operand" ""))]
55 /* One of the ops has to be in a register */
56 if (!register_operand (operand0, QImode)
57 && !register_operand (operand1, QImode))
58 operands[1] = copy_to_mode_reg (QImode, operand1);
62 [(set (match_operand:QI 0 "general_operand" "=d,a,d,d,a,d,a,d,m")
63 (match_operand:QI 1 "general_operand" "0,0,I,a,d,di,ia,m,d"))]
64 "register_operand (operands[0], QImode)
65 || register_operand (operands[1], QImode)"
76 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
80 (define_expand "movhi"
81 [(set (match_operand:HI 0 "general_operand" "")
82 (match_operand:HI 1 "general_operand" ""))]
86 /* One of the ops has to be in a register */
87 if (!register_operand (operand1, HImode)
88 && !register_operand (operand0, HImode))
89 operands[1] = copy_to_mode_reg (HImode, operand1);
93 [(set (match_operand:HI 0 "general_operand" "=d,a,d,d,a,d,a,d,m")
94 (match_operand:HI 1 "general_operand" "0,0,I,a,d,di,ia,m,d"))]
95 "register_operand (operands[0], HImode)
96 || register_operand (operands[1], HImode)"
107 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
111 (define_expand "movsi"
112 [(set (match_operand:SI 0 "general_operand" "")
113 (match_operand:SI 1 "general_operand" ""))]
117 /* One of the ops has to be in a register */
118 if (!register_operand (operand1, SImode)
119 && !register_operand (operand0, SImode))
120 operands[1] = copy_to_mode_reg (SImode, operand1);
124 [(set (match_operand:SI 0 "general_operand" "=d,a,d,dm,dm,am,am,d,d,a,a,aR,x")
125 (match_operand:SI 1 "general_operand" "0,0,I,d,a,d,a,dim,aim,dim,aim,x,aR"))]
126 "register_operand (operands[0], SImode)
127 || register_operand (operands[1], SImode)"
142 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
144 (define_expand "movsf"
145 [(set (match_operand:SF 0 "general_operand" "")
146 (match_operand:SF 1 "general_operand" ""))]
150 /* One of the ops has to be in a register */
151 if (!register_operand (operand1, SFmode)
152 && !register_operand (operand0, SFmode))
153 operands[1] = copy_to_mode_reg (SFmode, operand1);
157 [(set (match_operand:SF 0 "general_operand" "=d,a,d,dam,da")
158 (match_operand:SF 1 "general_operand" "0,0,G,da,daim"))]
159 "register_operand (operands[0], SFmode)
160 || register_operand (operands[1], SFmode)"
167 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit")])
169 (define_expand "movdi"
170 [(set (match_operand:DI 0 "general_operand" "")
171 (match_operand:DI 1 "general_operand" ""))]
175 /* One of the ops has to be in a register */
176 if (!register_operand (operand1, DImode)
177 && !register_operand (operand0, DImode))
178 operands[1] = copy_to_mode_reg (DImode, operand1);
182 [(set (match_operand:DI 0 "general_operand" "=d,a,d,dm,dm,am,am,d,d,a,a")
183 (match_operand:DI 1 "general_operand" "0,0,I,d,a,d,a,dim,aim,dim,aim"))]
184 "register_operand (operands[0], DImode)
185 || register_operand (operands[1], DImode)"
191 switch (which_alternative)
198 return \"clr %L0\;clr %H0\";
208 if (GET_CODE (operands[1]) == CONST_INT)
210 val[0] = INTVAL (operands[1]);
211 val[1] = val[0] < 0 ? -1 : 0;
213 if (GET_CODE (operands[1]) == CONST_DOUBLE)
215 if (GET_MODE (operands[1]) == DFmode)
217 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
218 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
220 else if (GET_MODE (operands[1]) == VOIDmode
221 || GET_MODE (operands[1]) == DImode)
223 val[0] = CONST_DOUBLE_LOW (operands[1]);
224 val[1] = CONST_DOUBLE_HIGH (operands[1]);
228 if (GET_CODE (operands[1]) == MEM
229 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
231 rtx temp = operands[0];
233 while (GET_CODE (temp) == SUBREG)
234 temp = SUBREG_REG (temp);
236 if (GET_CODE (temp) != REG)
239 if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
240 XEXP (operands[1], 0)))
241 return \"mov %H1,%H0\;mov %L1,%L0\";
243 return \"mov %L1,%L0\;mov %H1,%H0\";
248 if ((GET_CODE (operands[1]) == CONST_INT
249 || GET_CODE (operands[1]) == CONST_DOUBLE)
251 && REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
252 output_asm_insn (\"clr %L0\", operands);
254 output_asm_insn (\"mov %L1,%L0\", operands);
256 if ((GET_CODE (operands[1]) == CONST_INT
257 || GET_CODE (operands[1]) == CONST_DOUBLE)
259 && REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
260 output_asm_insn (\"clr %H0\", operands);
262 output_asm_insn (\"mov %H1,%H0\", operands);
267 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
269 (define_expand "movdf"
270 [(set (match_operand:DF 0 "general_operand" "")
271 (match_operand:DF 1 "general_operand" ""))]
275 /* One of the ops has to be in a register */
276 if (!register_operand (operand1, DFmode)
277 && !register_operand (operand0, DFmode))
278 operands[1] = copy_to_mode_reg (DFmode, operand1);
282 [(set (match_operand:DF 0 "general_operand" "=d,a,d,dm,dm,am,am,d,d,a,a")
283 (match_operand:DF 1 "general_operand" "0,0,G,d,a,d,a,dim,aim,dim,aim"))]
284 "register_operand (operands[0], DFmode)
285 || register_operand (operands[1], DFmode)"
291 switch (which_alternative)
298 return \"clr %L0\;clr %H0\";
308 if (GET_CODE (operands[1]) == CONST_INT)
310 val[0] = INTVAL (operands[1]);
311 val[1] = val[0] < 0 ? -1 : 0;
313 if (GET_CODE (operands[1]) == CONST_DOUBLE)
315 if (GET_MODE (operands[1]) == DFmode)
317 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
318 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
320 else if (GET_MODE (operands[1]) == VOIDmode
321 || GET_MODE (operands[1]) == DImode)
323 val[0] = CONST_DOUBLE_LOW (operands[1]);
324 val[1] = CONST_DOUBLE_HIGH (operands[1]);
328 if (GET_CODE (operands[1]) == MEM
329 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
331 rtx temp = operands[0];
333 while (GET_CODE (temp) == SUBREG)
334 temp = SUBREG_REG (temp);
336 if (GET_CODE (temp) != REG)
339 if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
340 XEXP (operands[1], 0)))
341 return \"mov %H1,%H0\;mov %L1,%L0\";
343 return \"mov %L1,%L0\;mov %H1,%H0\";
348 if ((GET_CODE (operands[1]) == CONST_INT
349 || GET_CODE (operands[1]) == CONST_DOUBLE)
351 && REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
352 output_asm_insn (\"clr %L0\", operands);
354 output_asm_insn (\"mov %L1,%L0\", operands);
356 if ((GET_CODE (operands[1]) == CONST_INT
357 || GET_CODE (operands[1]) == CONST_DOUBLE)
359 && REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
360 output_asm_insn (\"clr %H0\", operands);
362 output_asm_insn (\"mov %H1,%H0\", operands);
367 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
371 ;; ----------------------------------------------------------------------
373 ;; ----------------------------------------------------------------------
375 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
376 ;; when we start trying to optimize this port.
378 [(set (cc0) (match_operand:SI 0 "register_operand" "da"))]
380 "* return output_tst (operands[0], insn);"
381 [(set_attr "cc" "tst")])
384 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "d")))]
386 "* return output_tst (operands[0], insn);"
387 [(set_attr "cc" "tst")])
390 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "d")))]
392 "* return output_tst (operands[0], insn);"
393 [(set_attr "cc" "tst")])
398 (compare (match_operand:SI 0 "register_operand" "!*d*a,da")
399 (match_operand:SI 1 "nonmemory_operand" "!*0,dai")))]
404 [(set_attr "cc" "invert,compare")])
406 ;; ----------------------------------------------------------------------
408 ;; ----------------------------------------------------------------------
410 (define_expand "addsi3"
411 [(set (match_operand:SI 0 "register_operand" "")
412 (plus:SI (match_operand:SI 1 "register_operand" "")
413 (match_operand:SI 2 "nonmemory_operand" "")))]
417 /* We can't add a variable amount directly to the stack pointer;
418 so do so via a temporary register. */
419 if (operands[0] == stack_pointer_rtx
420 && GET_CODE (operands[1]) != CONST_INT
421 && GET_CODE (operands[2]) != CONST_INT)
423 rtx temp = gen_reg_rtx (SImode);
424 emit_move_insn (temp, gen_rtx (PLUS, SImode, operands[1], operands[2]));
425 emit_move_insn (operands[0], temp);
431 [(set (match_operand:SI 0 "register_operand" "=d,a,a,da,x")
432 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0")
433 (match_operand:SI 2 "nonmemory_operand" "J,J,L,dai,i")))]
441 [(set_attr "cc" "set_zn_c0,none_0hit,none_0hit,set_zn_c0,none_0hit")])
443 (define_expand "adddi3"
444 [(set (reg:DI 0) (match_operand:DI 1 "register_operand" ""))
445 (set (reg:DI 2) (match_operand:DI 2 "nonmemory_operand" ""))
446 (set (reg:DI 0) (plus:DI (reg:DI 0) (reg:DI 2)))
447 (set (match_operand:DI 0 "register_operand" "") (reg:DI 0))]
451 if (GET_CODE (operands[2]) == CONST_INT)
453 rtx reg0 = gen_rtx (REG, DImode, 0);
455 emit_move_insn (reg0, operands[1]);
456 emit_insn (gen_adddi3_const (operands[2]));
457 emit_move_insn (operands[0], reg0);
462 ;; The general adddi3 pattern.
464 [(set (reg:DI 0) (plus:DI (reg:DI 0) (reg:DI 2)))]
466 "add d2,d0\;addc d3,d1"
467 [(set_attr "cc" "clobber")])
469 ;; adddi3 with on operand being a constant.
470 (define_insn "adddi3_const"
472 (plus:DI (reg:DI 0) (match_operand:DI 0 "const_int_operand" "i")))
473 (clobber (reg:DI 2))]
477 long value = INTVAL (operands[0]);
480 return \"mov -1,d2\;add %0,d0\;addc d2,d1\";
482 return \"clr d2\;add %0,d0\;addc d2,d1\";
484 [(set_attr "cc" "clobber")])
485 ;; ----------------------------------------------------------------------
486 ;; SUBTRACT INSTRUCTIONS
487 ;; ----------------------------------------------------------------------
489 (define_insn "subsi3"
490 [(set (match_operand:SI 0 "register_operand" "=da")
491 (minus:SI (match_operand:SI 1 "register_operand" "0")
492 (match_operand:SI 2 "nonmemory_operand" "dai")))]
495 [(set_attr "cc" "set_zn_c0")])
497 (define_expand "negsi2"
498 [(set (match_operand:SI 0 "register_operand" "")
499 (neg:SI (match_operand:SI 1 "register_operand" "")))]
503 rtx target = gen_reg_rtx (SImode);
505 emit_move_insn (target, GEN_INT (0));
506 emit_insn (gen_subsi3 (target, target, operands[1]));
507 emit_move_insn (operands[0], target);
511 (define_expand "subdi3"
512 [(set (reg:DI 0) (match_operand:DI 1 "register_operand" ""))
513 (set (reg:DI 2) (match_operand:DI 2 "nonmemory_operand" ""))
514 (set (reg:DI 0) (minus:DI (reg:DI 0) (reg:DI 2)))
515 (set (match_operand:DI 0 "register_operand" "") (reg:DI 0))]
520 [(set (reg:DI 0) (minus:DI (reg:DI 0) (reg:DI 2)))]
522 "sub d2,d0\;subc d3,d1"
523 [(set_attr "cc" "clobber")])
525 ;; ----------------------------------------------------------------------
526 ;; MULTIPLY INSTRUCTIONS
527 ;; ----------------------------------------------------------------------
529 (define_insn "mulsi3"
530 [(set (match_operand:SI 0 "register_operand" "=d")
531 (mult:SI (match_operand:SI 1 "register_operand" "%0")
532 (match_operand:SI 2 "register_operand" "d")))]
535 [(set_attr "cc" "set_zn_c0")])
537 (define_expand "udivmodsi4"
538 [(parallel [(set (match_operand:SI 0 "register_operand" "")
539 (udiv:SI (match_operand:SI 1 "register_operand" "")
540 (match_operand:SI 2 "register_operand" "")))
541 (set (match_operand:SI 3 "register_operand" "")
542 (umod:SI (match_dup 1) (match_dup 2)))])]
546 rtx reg = gen_reg_rtx (SImode);
547 emit_move_insn (reg, GEN_INT (0));
548 emit_insn (gen_clear_mdr (reg));
552 [(set (match_operand:SI 0 "general_operand" "=d")
553 (udiv:SI (match_operand:SI 1 "general_operand" "0")
554 (match_operand:SI 2 "general_operand" "d")))
555 (set (match_operand:SI 3 "general_operand" "=d")
556 (umod:SI (match_dup 1) (match_dup 2)))]
560 if (find_reg_note (insn, REG_UNUSED, operands[3]))
561 return \"divu %2,%0\";
563 return \"divu %2,%0\;mov mdr,%3\";
565 [(set_attr "cc" "set_zn_c0")])
567 (define_expand "divmodsi4"
568 [(parallel [(set (match_operand:SI 0 "register_operand" "")
569 (div:SI (match_operand:SI 1 "register_operand" "")
570 (match_operand:SI 2 "register_operand" "")))
571 (set (match_operand:SI 3 "register_operand" "")
572 (mod:SI (match_dup 1) (match_dup 2)))])]
577 [(set (match_operand:SI 0 "general_operand" "=d")
578 (div:SI (match_operand:SI 1 "general_operand" "0")
579 (match_operand:SI 2 "general_operand" "d")))
580 (set (match_operand:SI 3 "general_operand" "=d")
581 (mod:SI (match_dup 1) (match_dup 2)))]
585 if (find_reg_note (insn, REG_UNUSED, operands[3]))
586 return \"ext %0\;div %2,%0\";
588 return \"ext %0\;div %2,%0\;mov mdr,%3\";
590 [(set_attr "cc" "set_zn_c0")])
592 (define_insn "clear_mdr"
593 [(unspec_volatile [(const_int 2)] 0)
594 (use (match_operand:SI 0 "register_operand" "d"))]
597 [(set_attr "cc" "none")])
599 ;; ----------------------------------------------------------------------
601 ;; ----------------------------------------------------------------------
603 (define_insn "andsi3"
604 [(set (match_operand:SI 0 "register_operand" "=d,d")
605 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
606 (match_operand:SI 2 "nonmemory_operand" "N,di")))]
610 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
612 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
614 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
615 return \"add %0,%0\;lsr 1,%0\";
616 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
617 return \"asl2 %0\;lsr 2,%0\";
618 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
619 return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
620 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
621 return \"asl2 %0,%0\;asl2 %0\;lsr 4,%0\";
622 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
623 return \"lsr 1,%0\;add %0,%0\";
624 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
625 return \"lsr 2,%0\;asl2 %0\";
626 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
627 return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
628 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
629 return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
630 return \"and %2,%0\";
632 [(set_attr "cc" "none_0hit,set_zn_c0")])
634 ;; ----------------------------------------------------------------------
636 ;; ----------------------------------------------------------------------
638 (define_insn "iorsi3"
639 [(set (match_operand:SI 0 "register_operand" "=d")
640 (ior:SI (match_operand:SI 1 "register_operand" "%0")
641 (match_operand:SI 2 "nonmemory_operand" "di")))]
644 [(set_attr "cc" "set_zn_c0")])
646 ;; ----------------------------------------------------------------------
648 ;; ----------------------------------------------------------------------
650 (define_insn "xorsi3"
651 [(set (match_operand:SI 0 "register_operand" "=d")
652 (xor:SI (match_operand:SI 1 "register_operand" "%0")
653 (match_operand:SI 2 "nonmemory_operand" "di")))]
656 [(set_attr "cc" "set_zn_c0")])
658 ;; ----------------------------------------------------------------------
660 ;; ----------------------------------------------------------------------
662 (define_insn "one_cmplsi2"
663 [(set (match_operand:SI 0 "register_operand" "=d")
664 (not:SI (match_operand:SI 1 "register_operand" "0")))]
667 [(set_attr "cc" "set_zn_c0")])
669 ;; -----------------------------------------------------------------
671 ;; -----------------------------------------------------------------
674 ;; These set/clear memory in byte sized chunks.
676 ;; They are no smaller/faster than loading the value into a register
677 ;; and storing the register, but they don't need a scratch register
678 ;; which may allow for better code generation.
680 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int 0))]
685 [(set_attr "cc" "clobber")])
688 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int -1))]
693 [(set_attr "cc" "clobber,none_0hit")])
696 [(set (match_operand:QI 0 "general_operand" "=R,d")
698 (and:SI (subreg:SI (match_dup 0) 0)
699 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
704 [(set_attr "cc" "clobber,set_zn_c0")])
707 [(set (match_operand:QI 0 "general_operand" "=R,d")
709 (ior:SI (subreg:SI (match_dup 0) 0)
710 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
715 [(set_attr "cc" "clobber")])
719 (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
720 (match_operand 1 "const_int_operand" "")
721 (match_operand 2 "const_int_operand" "")))]
725 int len = INTVAL (operands[1]);
726 int bit = INTVAL (operands[2]);
737 xoperands[0] = operands[0];
738 xoperands[1] = GEN_INT (mask);
739 output_asm_insn (\"btst %1,%0\", xoperands);
742 [(set_attr "cc" "set_zn_c0")])
746 (zero_extract:SI (match_operand:QI 0 "general_operand" "R,d")
747 (match_operand 1 "const_int_operand" "")
748 (match_operand 2 "const_int_operand" "")))]
749 "INTVAL (operands[1]) <= 8 && INTVAL (operands[2]) <= 7"
752 int len = INTVAL (operands[1]);
753 int bit = INTVAL (operands[2]);
764 xoperands[0] = operands[0];
765 xoperands[1] = GEN_INT (mask);
766 if (GET_CODE (operands[0]) == REG)
767 output_asm_insn (\"btst %1,%0\", xoperands);
769 output_asm_insn (\"btst %1,%A0\", xoperands);
772 [(set_attr "cc" "set_zn_c0")])
775 [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "d")
776 (match_operand:SI 1 "const_int_operand" "")))]
779 [(set_attr "cc" "set_zn_c0")])
784 (subreg:SI (match_operand:QI 0 "general_operand" "R,d") 0)
785 (match_operand:SI 1 "const_int_operand" "")))]
790 [(set_attr "cc" "set_zn_c0")])
792 ;; -----------------------------------------------------------------
793 ;; -----------------------------------------------------------------
795 ;; -----------------------------------------------------------------
796 ;; It's probably worth the time to define setcc type insns too
799 ;; ----------------------------------------------------------------------
801 ;; ----------------------------------------------------------------------
803 ;; Conditional jump instructions
807 (if_then_else (le (cc0)
809 (label_ref (match_operand 0 "" ""))
814 (define_expand "bleu"
816 (if_then_else (leu (cc0)
818 (label_ref (match_operand 0 "" ""))
825 (if_then_else (ge (cc0)
827 (label_ref (match_operand 0 "" ""))
832 (define_expand "bgeu"
834 (if_then_else (geu (cc0)
836 (label_ref (match_operand 0 "" ""))
843 (if_then_else (lt (cc0)
845 (label_ref (match_operand 0 "" ""))
850 (define_expand "bltu"
852 (if_then_else (ltu (cc0)
854 (label_ref (match_operand 0 "" ""))
861 (if_then_else (gt (cc0)
863 (label_ref (match_operand 0 "" ""))
868 (define_expand "bgtu"
870 (if_then_else (gtu (cc0)
872 (label_ref (match_operand 0 "" ""))
879 (if_then_else (eq (cc0)
881 (label_ref (match_operand 0 "" ""))
888 (if_then_else (ne (cc0)
890 (label_ref (match_operand 0 "" ""))
897 (if_then_else (match_operator 1 "comparison_operator"
898 [(cc0) (const_int 0)])
899 (label_ref (match_operand 0 "" ""))
904 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
905 && (GET_CODE (operands[1]) == GT
906 || GET_CODE (operands[1]) == GE
907 || GET_CODE (operands[1]) == LE
908 || GET_CODE (operands[1]) == LT))
912 [(set_attr "cc" "none")])
916 (if_then_else (match_operator 1 "comparison_operator"
917 [(cc0) (const_int 0)])
919 (label_ref (match_operand 0 "" ""))))]
923 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
924 && (GET_CODE (operands[1]) == GT
925 || GET_CODE (operands[1]) == GE
926 || GET_CODE (operands[1]) == LE
927 || GET_CODE (operands[1]) == LT))
931 [(set_attr "cc" "none")])
933 ;; Unconditional and other jump instructions.
937 (label_ref (match_operand 0 "" "")))]
940 [(set_attr "cc" "none")])
942 (define_insn "indirect_jump"
943 [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
946 [(set_attr "cc" "none")])
948 (define_insn "tablejump"
949 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
950 (use (label_ref (match_operand 1 "" "")))]
953 [(set_attr "cc" "none")])
955 ;; Call subroutine with no return value.
957 (define_expand "call"
958 [(call (match_operand:QI 0 "general_operand" "")
959 (match_operand:SI 1 "general_operand" ""))]
963 if (! call_address_operand (XEXP (operands[0], 0)))
964 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
965 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-4)));
966 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
967 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (4)));
971 (define_insn "call_internal"
972 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
973 (match_operand:SI 1 "general_operand" "g"))]
976 [(set_attr "cc" "clobber")])
978 ;; Call subroutine, returning value in operand 0
979 ;; (which must be a hard register).
981 (define_expand "call_value"
982 [(set (match_operand 0 "" "")
983 (call (match_operand:QI 1 "general_operand" "")
984 (match_operand:SI 2 "general_operand" "")))]
988 if (! call_address_operand (XEXP (operands[1], 0)))
989 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
990 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-4)));
991 emit_call_insn (gen_call_value_internal (operands[0],
992 XEXP (operands[1], 0),
994 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (4)));
998 (define_insn "call_value_internal"
999 [(set (match_operand 0 "" "=d")
1000 (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1001 (match_operand:SI 2 "general_operand" "g")))]
1004 [(set_attr "cc" "clobber")])
1010 [(set_attr "cc" "none")])
1012 ;; ----------------------------------------------------------------------
1013 ;; EXTEND INSTRUCTIONS
1014 ;; ----------------------------------------------------------------------
1016 (define_insn "zero_extendqisi2"
1017 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1019 (match_operand:QI 1 "general_operand" "0,d,m")))]
1025 [(set_attr "cc" "none_0hit")])
1027 (define_insn "zero_extendhisi2"
1028 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1030 (match_operand:HI 1 "general_operand" "0,d,m")))]
1036 [(set_attr "cc" "none_0hit")])
1038 ;;- sign extension instructions
1040 (define_insn "extendqisi2"
1041 [(set (match_operand:SI 0 "general_operand" "=d,d")
1043 (match_operand:QI 1 "general_operand" "0,d")))]
1048 [(set_attr "cc" "none_0hit")])
1050 (define_insn "extendhisi2"
1051 [(set (match_operand:SI 0 "general_operand" "=d,d")
1053 (match_operand:HI 1 "general_operand" "0,d")))]
1058 [(set_attr "cc" "none_0hit")])
1060 ;; ----------------------------------------------------------------------
1062 ;; ----------------------------------------------------------------------
1064 (define_insn "ashlsi3"
1065 [(set (match_operand:SI 0 "register_operand" "=da,d,a,d,a,d,a,d")
1067 (match_operand:SI 1 "register_operand" "0,0,0,0,0,0,0,0")
1068 (match_operand:QI 2 "nonmemory_operand" "J,K,K,M,M,L,L,di")))]
1073 add %0,%0\;add %0,%0
1075 add %0,%0\;add %0,%0\;add %0,%0
1077 add %0,%0\;add %0,%0\;add %0,%0\;add %0,%0
1079 [(set_attr "cc" "set_zn_c0")])
1081 (define_insn "lshrsi3"
1082 [(set (match_operand:SI 0 "register_operand" "=d")
1084 (match_operand:SI 1 "register_operand" "0")
1085 (match_operand:QI 2 "nonmemory_operand" "di")))]
1088 [(set_attr "cc" "set_zn_c0")])
1090 (define_insn "ashrsi3"
1091 [(set (match_operand:SI 0 "register_operand" "=d")
1093 (match_operand:SI 1 "register_operand" "0")
1094 (match_operand:QI 2 "nonmemory_operand" "di")))]
1097 [(set_attr "cc" "set_zn_c0")])
1099 ;; ----------------------------------------------------------------------
1100 ;; PROLOGUE/EPILOGUE
1101 ;; ----------------------------------------------------------------------
1102 (define_expand "prologue"
1105 "expand_prologue (); DONE;")
1107 (define_expand "epilogue"
1116 (define_insn "return_internal"
1120 [(set_attr "cc" "clobber")])
1122 ;; This insn restores the callee saved registers and does a return, it
1123 ;; can also deallocate stack space.
1124 (define_insn "return_internal_regs"
1126 (match_operand:SI 0 "const_int_operand" "i")
1129 "ret [d2,d3,a2,a3],%0"
1130 [(set_attr "cc" "clobber")])
1132 (define_insn "store_movm"
1135 "movm [d2,d3,a2,a3],(sp)"
1136 [(set_attr "cc" "clobber")])
1138 (define_insn "return"
1140 "can_use_return_insn ()"
1142 [(set_attr "cc" "clobber")])
1144 ;; Try to combine consecutive updates of the stack pointer (or any
1145 ;; other register for that matter).
1147 [(set (match_operand:SI 0 "register_operand" "=dax")
1148 (plus:SI (match_dup 0)
1149 (match_operand 1 "const_int_operand" "")))
1151 (plus:SI (match_dup 0)
1152 (match_operand 2 "const_int_operand" "")))]
1156 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
1157 return \"add %1,%0\";
1159 [(set_attr "cc" "clobber")])
1162 ;; We had patterns to check eq/ne, but the they don't work because
1163 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
1165 ;; The Z flag and C flag would be set, and we have no way to
1166 ;; check for the Z flag set and C flag clear.
1168 ;; This will work on the mn10200 because we can check the ZX flag
1169 ;; if the comparison is in HImode.
1171 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1172 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1173 (match_operand 1 "" "")
1175 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1177 [(set_attr "cc" "clobber")])
1180 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1181 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1182 (match_operand 1 "" "")
1184 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1186 [(set_attr "cc" "clobber")])
1189 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1190 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1192 (match_operand 1 "" "")))]
1193 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1195 [(set_attr "cc" "clobber")])
1198 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1199 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1201 (match_operand 1 "" "")))]
1202 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1204 [(set_attr "cc" "clobber")])