163d1a8abSmrg;; GCC machine description for Matsushita MN10300
2*ec02198aSmrg;; Copyright (C) 1996-2020 Free Software Foundation, Inc.
363d1a8abSmrg;; Contributed by Jeff Law (law@cygnus.com).
463d1a8abSmrg
563d1a8abSmrg;; This file is part of GCC.
663d1a8abSmrg
763d1a8abSmrg;; GCC is free software; you can redistribute it and/or modify
863d1a8abSmrg;; it under the terms of the GNU General Public License as published by
963d1a8abSmrg;; the Free Software Foundation; either version 3, or (at your option)
1063d1a8abSmrg;; any later version.
1163d1a8abSmrg
1263d1a8abSmrg;; GCC is distributed in the hope that it will be useful,
1363d1a8abSmrg;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1463d1a8abSmrg;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1563d1a8abSmrg;; GNU General Public License for more details.
1663d1a8abSmrg
1763d1a8abSmrg;; You should have received a copy of the GNU General Public License
1863d1a8abSmrg;; along with GCC; see the file COPYING3.  If not see
1963d1a8abSmrg;; <http://www.gnu.org/licenses/>.
2063d1a8abSmrg
2163d1a8abSmrg;; The original PO technology requires these to be ordered by speed,
2263d1a8abSmrg;; so that assigner will pick the fastest.
2363d1a8abSmrg
2463d1a8abSmrg;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
2563d1a8abSmrg
2663d1a8abSmrg(define_constants [
2763d1a8abSmrg  (PIC_REG   6)
2863d1a8abSmrg  (SP_REG    9)
2963d1a8abSmrg  (MDR_REG  50)
3063d1a8abSmrg  (CC_REG   51)
3163d1a8abSmrg
3263d1a8abSmrg  (UNSPEC_PIC		1)
3363d1a8abSmrg  (UNSPEC_GOT		2)
3463d1a8abSmrg  (UNSPEC_GOTOFF	3)
3563d1a8abSmrg  (UNSPEC_PLT		4)
3663d1a8abSmrg  (UNSPEC_GOTSYM_OFF	5)
3763d1a8abSmrg
3863d1a8abSmrg  (UNSPEC_EXT		6)
3963d1a8abSmrg  (UNSPEC_BSCH		7)
4063d1a8abSmrg
4163d1a8abSmrg  ;; This is used to encode LIW patterns.
4263d1a8abSmrg  (UNSPEC_LIW		8)
4363d1a8abSmrg  ;; This is for the low overhead loop instructions.
4463d1a8abSmrg  (UNSPEC_SETLB         9)
4563d1a8abSmrg])
4663d1a8abSmrg
4763d1a8abSmrg(include "predicates.md")
4863d1a8abSmrg(include "constraints.md")
4963d1a8abSmrg
5063d1a8abSmrg;; Processor type.  This attribute must exactly match the processor_type
5163d1a8abSmrg;; enumeration in mn10300.h.
5263d1a8abSmrg(define_attr "cpu" "mn10300,am33,am33_2,am34"
5363d1a8abSmrg  (const (symbol_ref "(enum attr_cpu) mn10300_tune_cpu")))
5463d1a8abSmrg
5563d1a8abSmrg;; Used to control the "enabled" attribute on a per-instruction basis.
5663d1a8abSmrg(define_attr "isa" "base,am33,am33_2,am34"
5763d1a8abSmrg  (const_string "base"))
5863d1a8abSmrg
5963d1a8abSmrg(define_attr "enabled" ""
6063d1a8abSmrg  (cond [(eq_attr "isa" "base")
6163d1a8abSmrg         (const_int 1)
6263d1a8abSmrg
6363d1a8abSmrg         (and (eq_attr "isa" "am33")
6463d1a8abSmrg	      (match_test "TARGET_AM33"))
6563d1a8abSmrg         (const_int 1)
6663d1a8abSmrg
6763d1a8abSmrg         (and (eq_attr "isa" "am33_2")
6863d1a8abSmrg	      (match_test "TARGET_AM33_2"))
6963d1a8abSmrg         (const_int 1)
7063d1a8abSmrg
7163d1a8abSmrg         (and (eq_attr "isa" "am34")
7263d1a8abSmrg	      (match_test "TARGET_AM34"))
7363d1a8abSmrg         (const_int 1)
7463d1a8abSmrg	]
7563d1a8abSmrg	(const_int 0))
7663d1a8abSmrg)
7763d1a8abSmrg
7863d1a8abSmrg(define_mode_iterator INT [QI HI SI])
7963d1a8abSmrg
8063d1a8abSmrg
8163d1a8abSmrg;; Bundling of smaller insns into a long instruction word (LIW)
8263d1a8abSmrg(define_automaton "liw_bundling")
8363d1a8abSmrg(automata_option "ndfa")
8463d1a8abSmrg
8563d1a8abSmrg(define_cpu_unit "liw_op1_u,liw_op2_u" "liw_bundling")
8663d1a8abSmrg
8763d1a8abSmrg(define_attr "liw" "op1,op2,both,either"
8863d1a8abSmrg  (const_string "both"))
8963d1a8abSmrg;; Note: this list must match the one defined for liw_op_names[].
9063d1a8abSmrg(define_attr "liw_op" "add,cmp,sub,mov,and,or,xor,asr,lsr,asl,none,max"
9163d1a8abSmrg  (const_string "none"))
9263d1a8abSmrg
9363d1a8abSmrg(define_insn_reservation "liw_op1" 1
9463d1a8abSmrg  (and (ior (eq_attr "cpu" "am33")
9563d1a8abSmrg            (eq_attr "cpu" "am33_2")
9663d1a8abSmrg	    (eq_attr "cpu" "am34"))
9763d1a8abSmrg       (eq_attr "liw" "op1"))
9863d1a8abSmrg  "liw_op1_u");
9963d1a8abSmrg(define_insn_reservation "liw_op2" 1
10063d1a8abSmrg  (and (ior (eq_attr "cpu" "am33")
10163d1a8abSmrg            (eq_attr "cpu" "am33_2")
10263d1a8abSmrg	    (eq_attr "cpu" "am34"))
10363d1a8abSmrg       (eq_attr "liw" "op2"))
10463d1a8abSmrg  "liw_op2_u");
10563d1a8abSmrg(define_insn_reservation "liw_both" 1
10663d1a8abSmrg  (and (ior (eq_attr "cpu" "am33")
10763d1a8abSmrg            (eq_attr "cpu" "am33_2")
10863d1a8abSmrg	    (eq_attr "cpu" "am34"))
10963d1a8abSmrg       (eq_attr "liw" "both"))
11063d1a8abSmrg  "liw_op1_u + liw_op2_u");
11163d1a8abSmrg(define_insn_reservation "liw_either" 1
11263d1a8abSmrg  (and (ior (eq_attr "cpu" "am33")
11363d1a8abSmrg            (eq_attr "cpu" "am33_2")
11463d1a8abSmrg	    (eq_attr "cpu" "am34"))
11563d1a8abSmrg       (eq_attr "liw" "either"))
11663d1a8abSmrg  "liw_op1_u | liw_op2_u");
11763d1a8abSmrg
11863d1a8abSmrg;; ----------------------------------------------------------------------
11963d1a8abSmrg;; Pipeline description.
12063d1a8abSmrg;; ----------------------------------------------------------------------
12163d1a8abSmrg
12263d1a8abSmrg;; The AM33 only has a single pipeline.  It has five stages (fetch,
12363d1a8abSmrg;; decode, execute, memory access, writeback) each of which normally
12463d1a8abSmrg;; takes a single CPU clock cycle.
12563d1a8abSmrg
12663d1a8abSmrg;; The timings attribute consists of two numbers, the first is the
12763d1a8abSmrg;; throughput, which is the number of cycles the instruction takes
12863d1a8abSmrg;; to execute and generate a result.  The second is the latency
12963d1a8abSmrg;; which is the effective number of cycles the instruction takes to
13063d1a8abSmrg;; execute if its result is used by the following instruction.  The
13163d1a8abSmrg;; latency is always greater than or equal to the throughput.
13263d1a8abSmrg;; These values were taken from the Appendix of the "MN103E Series
13363d1a8abSmrg;; Instruction Manual" and the timings for the AM34.
13463d1a8abSmrg
13563d1a8abSmrg;; Note - it would be nice to use strings rather than integers for
13663d1a8abSmrg;; the possible values of this attribute, so that we can have the
13763d1a8abSmrg;; gcc build mechanism check for values that are not supported by
13863d1a8abSmrg;; the reservations below.  But this will not work because the code
13963d1a8abSmrg;; in mn10300_adjust_sched_cost() needs integers not strings.
14063d1a8abSmrg
14163d1a8abSmrg(define_attr "timings" "" (const_int 11))
14263d1a8abSmrg
14363d1a8abSmrg(define_automaton "pipelining")
14463d1a8abSmrg(define_cpu_unit "throughput" "pipelining")
14563d1a8abSmrg
14663d1a8abSmrg(define_insn_reservation "throughput__1_latency__1"  1
14763d1a8abSmrg  (eq_attr "timings" "11") "throughput")
14863d1a8abSmrg(define_insn_reservation "throughput__1_latency__2"  2
14963d1a8abSmrg  (eq_attr "timings" "12") "throughput,nothing")
15063d1a8abSmrg(define_insn_reservation "throughput__1_latency__3"  3
15163d1a8abSmrg  (eq_attr "timings" "13") "throughput,nothing*2")
15263d1a8abSmrg(define_insn_reservation "throughput__1_latency__4"  4
15363d1a8abSmrg  (eq_attr "timings" "14") "throughput,nothing*3")
15463d1a8abSmrg(define_insn_reservation "throughput__2_latency__2"  2
15563d1a8abSmrg  (eq_attr "timings" "22") "throughput*2")
15663d1a8abSmrg(define_insn_reservation "throughput__2_latency__3"  3
15763d1a8abSmrg  (eq_attr "timings" "23") "throughput*2,nothing")
15863d1a8abSmrg(define_insn_reservation "throughput__2_latency__4"  4
15963d1a8abSmrg  (eq_attr "timings" "24") "throughput*2,nothing*2")
16063d1a8abSmrg(define_insn_reservation "throughput__2_latency__5"  5
16163d1a8abSmrg  (eq_attr "timings" "25") "throughput*2,nothing*3")
16263d1a8abSmrg(define_insn_reservation "throughput__3_latency__3"  3
16363d1a8abSmrg  (eq_attr "timings" "33") "throughput*3")
16463d1a8abSmrg(define_insn_reservation "throughput__3_latency__7"  7
16563d1a8abSmrg  (eq_attr "timings" "37") "throughput*3,nothing*4")
16663d1a8abSmrg(define_insn_reservation "throughput__4_latency__4"  4
16763d1a8abSmrg  (eq_attr "timings" "44") "throughput*4")
16863d1a8abSmrg(define_insn_reservation "throughput__4_latency__7"  7
16963d1a8abSmrg  (eq_attr "timings" "47") "throughput*4,nothing*3")
17063d1a8abSmrg(define_insn_reservation "throughput__4_latency__8"  8
17163d1a8abSmrg  (eq_attr "timings" "48") "throughput*4,nothing*4")
17263d1a8abSmrg(define_insn_reservation "throughput__5_latency__5"  5
17363d1a8abSmrg  (eq_attr "timings" "55") "throughput*5")
17463d1a8abSmrg(define_insn_reservation "throughput__6_latency__6"  6
17563d1a8abSmrg  (eq_attr "timings" "66") "throughput*6")
17663d1a8abSmrg(define_insn_reservation "throughput__7_latency__7"  7
17763d1a8abSmrg  (eq_attr "timings" "77") "throughput*7")
17863d1a8abSmrg(define_insn_reservation "throughput__7_latency__8"  8
17963d1a8abSmrg  (eq_attr "timings" "78") "throughput*7,nothing")
18063d1a8abSmrg(define_insn_reservation "throughput__8_latency__8"  8
18163d1a8abSmrg  (eq_attr "timings" "88") "throughput*8")
18263d1a8abSmrg(define_insn_reservation "throughput__9_latency__9"  9
18363d1a8abSmrg  (eq_attr "timings" "99") "throughput*9")
18463d1a8abSmrg(define_insn_reservation "throughput__8_latency_14" 14
18563d1a8abSmrg  (eq_attr "timings" "814") "throughput*8,nothing*6")
18663d1a8abSmrg(define_insn_reservation "throughput__9_latency_10" 10
18763d1a8abSmrg  (eq_attr "timings" "910") "throughput*9,nothing")
18863d1a8abSmrg(define_insn_reservation "throughput_10_latency_10" 10
18963d1a8abSmrg  (eq_attr "timings" "1010") "throughput*10")
19063d1a8abSmrg(define_insn_reservation "throughput_12_latency_16" 16
19163d1a8abSmrg  (eq_attr "timings" "1216") "throughput*12,nothing*4")
19263d1a8abSmrg(define_insn_reservation "throughput_13_latency_13" 13
19363d1a8abSmrg  (eq_attr "timings" "1313") "throughput*13")
19463d1a8abSmrg(define_insn_reservation "throughput_14_latency_14" 14
19563d1a8abSmrg  (eq_attr "timings" "1414") "throughput*14")
19663d1a8abSmrg(define_insn_reservation "throughput_13_latency_17" 17
19763d1a8abSmrg  (eq_attr "timings" "1317") "throughput*13,nothing*4")
19863d1a8abSmrg(define_insn_reservation "throughput_23_latency_27" 27
19963d1a8abSmrg  (eq_attr "timings" "2327") "throughput*23,nothing*4")
20063d1a8abSmrg(define_insn_reservation "throughput_25_latency_31" 31
20163d1a8abSmrg  (eq_attr "timings" "2531") "throughput*25,nothing*6")
20263d1a8abSmrg(define_insn_reservation "throughput_38_latency_39" 39
20363d1a8abSmrg  (eq_attr "timings" "3839") "throughput*38,nothing")
20463d1a8abSmrg(define_insn_reservation "throughput_39_latency_40" 40
20563d1a8abSmrg  (eq_attr "timings" "3940") "throughput*39,nothing")
20663d1a8abSmrg(define_insn_reservation "throughput_40_latency_40" 40
20763d1a8abSmrg  (eq_attr "timings" "4040") "throughput*40")
20863d1a8abSmrg(define_insn_reservation "throughput_41_latency_42" 42
20963d1a8abSmrg  (eq_attr "timings" "4142") "throughput*41,nothing")
21063d1a8abSmrg(define_insn_reservation "throughput_42_latency_43" 44
21163d1a8abSmrg  (eq_attr "timings" "4243") "throughput*42,nothing")
21263d1a8abSmrg(define_insn_reservation "throughput_43_latency_44" 44
21363d1a8abSmrg  (eq_attr "timings" "4344") "throughput*43,nothing")
21463d1a8abSmrg(define_insn_reservation "throughput_45_latency_46" 46
21563d1a8abSmrg  (eq_attr "timings" "4546") "throughput*45,nothing")
21663d1a8abSmrg(define_insn_reservation "throughput_47_latency_53" 53
21763d1a8abSmrg  (eq_attr "timings" "4753") "throughput*47,nothing*6")
21863d1a8abSmrg
21963d1a8abSmrg;; Note - the conflict between memory load/store instructions
22063d1a8abSmrg;; and floating point instructions described in section 1-7-4
22163d1a8abSmrg;; of Chapter 3 of the MN103E Series Instruction Manual is
22263d1a8abSmrg;; handled by the mn10300_adjust_sched_cost function.
22363d1a8abSmrg
22463d1a8abSmrg;; ----------------------------------------------------------------------
22563d1a8abSmrg;; MOVE INSTRUCTIONS
22663d1a8abSmrg;; ----------------------------------------------------------------------
22763d1a8abSmrg
22863d1a8abSmrg;; movqi
22963d1a8abSmrg
23063d1a8abSmrg(define_expand "movqi"
23163d1a8abSmrg  [(set (match_operand:QI 0 "nonimmediate_operand")
23263d1a8abSmrg	(match_operand:QI 1 "general_operand"))]
23363d1a8abSmrg  ""
23463d1a8abSmrg{
23563d1a8abSmrg  /* One of the ops has to be in a register.  */
23663d1a8abSmrg  if (!register_operand (operand0, QImode)
23763d1a8abSmrg      && !register_operand (operand1, QImode))
23863d1a8abSmrg    operands[1] = force_reg (QImode, operand1);
23963d1a8abSmrg})
24063d1a8abSmrg
24163d1a8abSmrg(define_insn "*movqi_internal"
24263d1a8abSmrg  [(set (match_operand:QI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m,*z,d")
24363d1a8abSmrg	(match_operand:QI 1 "general_operand"      "  0,D*r,  i,m,D,d,*z"))]
24463d1a8abSmrg  "(register_operand (operands[0], QImode)
24563d1a8abSmrg    || register_operand (operands[1], QImode))"
24663d1a8abSmrg{
24763d1a8abSmrg  switch (which_alternative)
24863d1a8abSmrg    {
24963d1a8abSmrg    case 0:
25063d1a8abSmrg      return "";
25163d1a8abSmrg    case 1:
25263d1a8abSmrg    case 2:
25363d1a8abSmrg    case 5:
25463d1a8abSmrg    case 6:
25563d1a8abSmrg      return "mov %1,%0";
25663d1a8abSmrg    case 3:
25763d1a8abSmrg    case 4:
25863d1a8abSmrg      return "movbu %1,%0";
25963d1a8abSmrg    default:
26063d1a8abSmrg      gcc_unreachable ();
26163d1a8abSmrg    }
26263d1a8abSmrg}
26363d1a8abSmrg  [(set_attr_alternative "timings"
26463d1a8abSmrg	 [(const_int 11)
26563d1a8abSmrg	  (const_int 11)
26663d1a8abSmrg	  (const_int 11)
26763d1a8abSmrg	  (if_then_else (eq_attr "cpu" "am34")
26863d1a8abSmrg			(const_int 13) (const_int 24))
26963d1a8abSmrg	  (if_then_else (eq_attr "cpu" "am34")
27063d1a8abSmrg			(const_int 11) (const_int 22))
27163d1a8abSmrg	  (const_int 11)
27263d1a8abSmrg	  (const_int 11)
27363d1a8abSmrg	 ])]
27463d1a8abSmrg)
27563d1a8abSmrg
27663d1a8abSmrg;; movhi
27763d1a8abSmrg
27863d1a8abSmrg(define_expand "movhi"
27963d1a8abSmrg  [(set (match_operand:HI 0 "nonimmediate_operand")
28063d1a8abSmrg	(match_operand:HI 1 "general_operand"))]
28163d1a8abSmrg  ""
28263d1a8abSmrg{
28363d1a8abSmrg  /* One of the ops has to be in a register.  */
28463d1a8abSmrg  if (!register_operand (operand1, HImode)
28563d1a8abSmrg      && !register_operand (operand0, HImode))
28663d1a8abSmrg    operands[1] = force_reg (HImode, operand1);
28763d1a8abSmrg})
28863d1a8abSmrg
28963d1a8abSmrg(define_insn "*movhi_internal"
29063d1a8abSmrg  [(set (match_operand:HI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m,*z,d")
29163d1a8abSmrg	(match_operand:HI 1 "general_operand"      "  0,  i,D*r,m,D,d,*z"))]
29263d1a8abSmrg  "(register_operand (operands[0], HImode)
29363d1a8abSmrg    || register_operand (operands[1], HImode))"
29463d1a8abSmrg{
29563d1a8abSmrg  switch (which_alternative)
29663d1a8abSmrg    {
29763d1a8abSmrg    case 0:
29863d1a8abSmrg      return "";
29963d1a8abSmrg    case 1:
30063d1a8abSmrg      /* Note that "MOV imm8,An" is already zero-extending, and is 2 bytes.
30163d1a8abSmrg	 We have "MOV imm16,Dn" at 3 bytes.  The only win for the 4 byte
30263d1a8abSmrg	 movu is for an 8-bit unsigned move into Rn.  */
30363d1a8abSmrg      if (TARGET_AM33
30463d1a8abSmrg	  && CONST_INT_P (operands[1])
30563d1a8abSmrg	  && IN_RANGE (INTVAL (operands[1]), 0x80, 0xff)
30663d1a8abSmrg	  && REGNO_EXTENDED_P (REGNO (operands[0]), 1))
30763d1a8abSmrg	return "movu %1,%0";
30863d1a8abSmrg      /* FALLTHRU */
30963d1a8abSmrg    case 5:
31063d1a8abSmrg    case 6:
31163d1a8abSmrg    case 2:
31263d1a8abSmrg      return "mov %1,%0";
31363d1a8abSmrg    case 3:
31463d1a8abSmrg    case 4:
31563d1a8abSmrg      return "movhu %1,%0";
31663d1a8abSmrg    default:
31763d1a8abSmrg      gcc_unreachable ();
31863d1a8abSmrg    }
31963d1a8abSmrg}
32063d1a8abSmrg  [(set_attr_alternative "timings"
32163d1a8abSmrg	 [(const_int 11)
32263d1a8abSmrg	  (const_int 11)
32363d1a8abSmrg	  (if_then_else (eq_attr "cpu" "am34")
32463d1a8abSmrg	  		(const_int 11) (const_int 22))
32563d1a8abSmrg	  (if_then_else (eq_attr "cpu" "am34")
32663d1a8abSmrg	  		(const_int 13) (const_int 24))
32763d1a8abSmrg	  (if_then_else (eq_attr "cpu" "am34")
32863d1a8abSmrg	  		(const_int 11) (const_int 22))
32963d1a8abSmrg	  (if_then_else (eq_attr "cpu" "am34")
33063d1a8abSmrg	  		(const_int 11) (const_int 22))
33163d1a8abSmrg	  (if_then_else (eq_attr "cpu" "am34")
33263d1a8abSmrg	  		(const_int 11) (const_int 22))
33363d1a8abSmrg	 ])]
33463d1a8abSmrg)
33563d1a8abSmrg
33663d1a8abSmrg;; movsi and helpers
33763d1a8abSmrg
33863d1a8abSmrg;; We use this to handle addition of two values when one operand is the
33963d1a8abSmrg;; stack pointer and the other is a memory reference of some kind.  Reload
34063d1a8abSmrg;; does not handle them correctly without this expander.
34163d1a8abSmrg(define_expand "reload_plus_sp_const"
34263d1a8abSmrg  [(set (match_operand:SI     0 "register_operand" "=r")
34363d1a8abSmrg	(match_operand:SI     1 "impossible_plus_operand" ""))
34463d1a8abSmrg   (clobber (match_operand:SI 2 "register_operand" "=&A"))]
34563d1a8abSmrg  ""
34663d1a8abSmrg{
34763d1a8abSmrg  rtx dest, scratch, other;
34863d1a8abSmrg
34963d1a8abSmrg  dest = operands[0];
35063d1a8abSmrg  scratch = operands[2];
35163d1a8abSmrg
35263d1a8abSmrg  other = XEXP (operands[1], 1);
35363d1a8abSmrg  if (other == stack_pointer_rtx)
35463d1a8abSmrg    other = XEXP (operands[1], 0);
35563d1a8abSmrg
35663d1a8abSmrg  if (true_regnum (other) == true_regnum (dest))
35763d1a8abSmrg    {
35863d1a8abSmrg      gcc_assert (true_regnum (scratch) != true_regnum (dest));
35963d1a8abSmrg      emit_move_insn (scratch, stack_pointer_rtx);
36063d1a8abSmrg      emit_insn (gen_addsi3 (dest, dest, scratch));
36163d1a8abSmrg    }
36263d1a8abSmrg  else if (TARGET_AM33 || REGNO_REG_CLASS (true_regnum (dest)) == ADDRESS_REGS)
36363d1a8abSmrg    {
36463d1a8abSmrg      emit_move_insn (dest, stack_pointer_rtx);
36563d1a8abSmrg      if (other == stack_pointer_rtx)
36663d1a8abSmrg        emit_insn (gen_addsi3 (dest, dest, dest));
36763d1a8abSmrg      else if (other != const0_rtx)
36863d1a8abSmrg        emit_insn (gen_addsi3 (dest, dest, other));
36963d1a8abSmrg    }
37063d1a8abSmrg  else
37163d1a8abSmrg    {
37263d1a8abSmrg      emit_move_insn (scratch, stack_pointer_rtx);
37363d1a8abSmrg      if (other == stack_pointer_rtx)
37463d1a8abSmrg	{
37563d1a8abSmrg	  emit_move_insn (dest, scratch);
37663d1a8abSmrg          emit_insn (gen_addsi3 (dest, dest, dest));
37763d1a8abSmrg	}
37863d1a8abSmrg      else if (other != const0_rtx)
37963d1a8abSmrg	{
38063d1a8abSmrg	  emit_move_insn (dest, other);
38163d1a8abSmrg          emit_insn (gen_addsi3 (dest, dest, scratch));
38263d1a8abSmrg	}
38363d1a8abSmrg      else
38463d1a8abSmrg	emit_move_insn (dest, scratch);
38563d1a8abSmrg    }
38663d1a8abSmrg  DONE;
38763d1a8abSmrg})
38863d1a8abSmrg
38963d1a8abSmrg(define_expand "movsi"
39063d1a8abSmrg  [(set (match_operand:SI 0 "nonimmediate_operand")
39163d1a8abSmrg	(match_operand:SI 1 "general_operand"))]
39263d1a8abSmrg  ""
39363d1a8abSmrg{
39463d1a8abSmrg  /* One of the ops has to be in a register.  */
39563d1a8abSmrg  if (!register_operand (operand1, SImode)
39663d1a8abSmrg      && !register_operand (operand0, SImode))
39763d1a8abSmrg    operands[1] = force_reg (SImode, operand1);
39863d1a8abSmrg  if (flag_pic)
39963d1a8abSmrg    {
40063d1a8abSmrg      rtx temp;
40163d1a8abSmrg      if (SYMBOLIC_CONST_P (operands[1]))
40263d1a8abSmrg	{
40363d1a8abSmrg	  if (MEM_P (operands[0]))
40463d1a8abSmrg	    operands[1] = force_reg (Pmode, operands[1]);
40563d1a8abSmrg	  else
40663d1a8abSmrg	    {
40763d1a8abSmrg	      temp = (!can_create_pseudo_p ()
40863d1a8abSmrg		      ? operands[0]
40963d1a8abSmrg		      : gen_reg_rtx (Pmode));
41063d1a8abSmrg	      operands[1] = mn10300_legitimize_pic_address (operands[1], temp);
41163d1a8abSmrg	    }
41263d1a8abSmrg	}
41363d1a8abSmrg      else if (GET_CODE (operands[1]) == CONST
41463d1a8abSmrg	       && GET_CODE (XEXP (operands[1], 0)) == PLUS
41563d1a8abSmrg	       && SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0)))
41663d1a8abSmrg	{
41763d1a8abSmrg	  temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
41863d1a8abSmrg	  temp = mn10300_legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0),
41963d1a8abSmrg						 temp);
42063d1a8abSmrg	  operands[1] = expand_binop (SImode, add_optab, temp,
42163d1a8abSmrg				      XEXP (XEXP (operands[1], 0), 1),
42263d1a8abSmrg				      (!can_create_pseudo_p ()
42363d1a8abSmrg				       ? temp
42463d1a8abSmrg				       : gen_reg_rtx (Pmode)),
42563d1a8abSmrg				      0, OPTAB_LIB_WIDEN);
42663d1a8abSmrg	}
42763d1a8abSmrg    }
42863d1a8abSmrg})
42963d1a8abSmrg
43063d1a8abSmrg(define_insn "*movsi_internal"
43163d1a8abSmrg  [(set (match_operand:SI 0 "nonimmediate_operand"
43263d1a8abSmrg			  "=r,r,r,r,m,r, A,*y,*y,*z,*d")
43363d1a8abSmrg	(match_operand:SI 1 "general_operand"
43463d1a8abSmrg			  " 0,O,i,r,r,m,*y, A, i,*d,*z"))]
43563d1a8abSmrg  "register_operand (operands[0], SImode)
43663d1a8abSmrg   || register_operand (operands[1], SImode)"
43763d1a8abSmrg{
43863d1a8abSmrg  switch (which_alternative)
43963d1a8abSmrg    {
44063d1a8abSmrg    case 0:
44163d1a8abSmrg      return "";
44263d1a8abSmrg    case 1: /* imm-reg.  */
44363d1a8abSmrg    case 2:
44463d1a8abSmrg      /* See movhi for a discussion of sizes for 8-bit movu.  Note that the
44563d1a8abSmrg	 24-bit movu is 6 bytes, which is the same size as the full 32-bit
44663d1a8abSmrg	 mov form for An and Dn.  So again movu is only a win for Rn.  */
44763d1a8abSmrg      if (TARGET_AM33
44863d1a8abSmrg	  && CONST_INT_P (operands[1])
44963d1a8abSmrg	  && REGNO_EXTENDED_P (REGNO (operands[0]), 1))
45063d1a8abSmrg	{
45163d1a8abSmrg	  HOST_WIDE_INT val = INTVAL (operands[1]);
45263d1a8abSmrg	  if (IN_RANGE (val, 0x80, 0xff)
45363d1a8abSmrg	      || IN_RANGE (val, 0x800000, 0xffffff))
45463d1a8abSmrg	    return "movu %1,%0";
45563d1a8abSmrg	}
45663d1a8abSmrg      /* FALLTHRU */
45763d1a8abSmrg    case 3:  /* reg-reg */
45863d1a8abSmrg    case 4:  /* reg-mem */
45963d1a8abSmrg    case 5:  /* mem-reg */
46063d1a8abSmrg    case 6:  /* sp-reg */
46163d1a8abSmrg    case 7:  /* reg-sp */
46263d1a8abSmrg    case 8:  /* imm-sp */
46363d1a8abSmrg    case 9:  /* reg-mdr */
46463d1a8abSmrg    case 10:  /* mdr-reg */
46563d1a8abSmrg      return "mov %1,%0";
46663d1a8abSmrg    default:
46763d1a8abSmrg      gcc_unreachable ();
46863d1a8abSmrg    }
46963d1a8abSmrg}
47063d1a8abSmrg  [(set_attr "isa" "*,*,*,*,*,*,*,*,am33,*,*")
47163d1a8abSmrg   (set_attr "liw" "*,either,*,either,*,*,*,*,*,*,*")
47263d1a8abSmrg   (set_attr "liw_op" "mov")
47363d1a8abSmrg   (set_attr_alternative "timings"
47463d1a8abSmrg	 [(const_int 11)
47563d1a8abSmrg	  (const_int 22)
47663d1a8abSmrg	  (const_int 22)
47763d1a8abSmrg	  (const_int 11)
47863d1a8abSmrg	  (if_then_else (eq_attr "cpu" "am34")
47963d1a8abSmrg			(const_int 11) (const_int 22))
48063d1a8abSmrg	  (if_then_else (eq_attr "cpu" "am34")
48163d1a8abSmrg			(const_int 13) (const_int 24))
48263d1a8abSmrg	  (if_then_else (eq_attr "cpu" "am34")
48363d1a8abSmrg			(const_int 11) (const_int 22))
48463d1a8abSmrg	  (if_then_else (eq_attr "cpu" "am34")
48563d1a8abSmrg			(const_int 13) (const_int 24))
48663d1a8abSmrg	  (const_int 11)
48763d1a8abSmrg	  (const_int 11)
48863d1a8abSmrg	  (const_int 11)
48963d1a8abSmrg	 ])]
49063d1a8abSmrg)
49163d1a8abSmrg
49263d1a8abSmrg(define_expand "movsf"
49363d1a8abSmrg  [(set (match_operand:SF 0 "nonimmediate_operand")
49463d1a8abSmrg	(match_operand:SF 1 "general_operand"))]
49563d1a8abSmrg  "TARGET_AM33_2"
49663d1a8abSmrg{
49763d1a8abSmrg  /* One of the ops has to be in a register.  */
49863d1a8abSmrg  if (!register_operand (operand1, SFmode)
49963d1a8abSmrg      && !register_operand (operand0, SFmode))
50063d1a8abSmrg    operands[1] = force_reg (SFmode, operand1);
50163d1a8abSmrg})
50263d1a8abSmrg
50363d1a8abSmrg(define_insn "*movsf_internal"
50463d1a8abSmrg  [(set (match_operand:SF 0 "nonimmediate_operand" "=rf,r,f,r,f,r,f,r,m,f,Q,z,d")
50563d1a8abSmrg	(match_operand:SF 1 "general_operand"	   "  0,F,F,r,f,f,r,m,r,Q,f,d,z"))]
50663d1a8abSmrg  "TARGET_AM33_2
50763d1a8abSmrg   && (register_operand (operands[0], SFmode)
50863d1a8abSmrg       || register_operand (operands[1], SFmode))"
50963d1a8abSmrg{
51063d1a8abSmrg  switch (which_alternative)
51163d1a8abSmrg    {
51263d1a8abSmrg    case 0:
51363d1a8abSmrg      return "";
51463d1a8abSmrg    case 1:
51563d1a8abSmrg    case 3:
51663d1a8abSmrg    case 7:
51763d1a8abSmrg    case 8:
51863d1a8abSmrg    case 11:
51963d1a8abSmrg    case 12:
52063d1a8abSmrg      return "mov %1,%0";
52163d1a8abSmrg    case 2:
52263d1a8abSmrg    case 4:
52363d1a8abSmrg    case 5:
52463d1a8abSmrg    case 6:
52563d1a8abSmrg    case 9:
52663d1a8abSmrg    case 10:
52763d1a8abSmrg      return "fmov %1,%0";
52863d1a8abSmrg    default:
52963d1a8abSmrg      gcc_unreachable ();
53063d1a8abSmrg    }
53163d1a8abSmrg}
53263d1a8abSmrg  [(set_attr_alternative "timings"
53363d1a8abSmrg		 [(const_int 11)
53463d1a8abSmrg		  (const_int 22)
53563d1a8abSmrg		  (if_then_else (eq_attr "cpu" "am34")
53663d1a8abSmrg				(const_int 47) (const_int 25))
53763d1a8abSmrg		  (const_int 11)
53863d1a8abSmrg		  (if_then_else (eq_attr "cpu" "am34")
53963d1a8abSmrg				(const_int 13) (const_int 14))
54063d1a8abSmrg		  (if_then_else (eq_attr "cpu" "am34")
54163d1a8abSmrg				(const_int 13) (const_int 12))
54263d1a8abSmrg		  (if_then_else (eq_attr "cpu" "am34")
54363d1a8abSmrg				(const_int 13) (const_int 14))
54463d1a8abSmrg		  (if_then_else (eq_attr "cpu" "am34")
54563d1a8abSmrg				(const_int 13) (const_int 24))
54663d1a8abSmrg		  (if_then_else (eq_attr "cpu" "am34")
54763d1a8abSmrg				(const_int 13) (const_int 24))
54863d1a8abSmrg		  (if_then_else (eq_attr "cpu" "am34")
54963d1a8abSmrg				(const_int 13) (const_int 24))
55063d1a8abSmrg		  (if_then_else (eq_attr "cpu" "am34")
55163d1a8abSmrg				(const_int 13) (const_int 24))
55263d1a8abSmrg		  (const_int 22)
55363d1a8abSmrg		  (const_int 22)
55463d1a8abSmrg		 ])]
55563d1a8abSmrg)
55663d1a8abSmrg
55763d1a8abSmrg;; If the flags register is not live, generate CLR instead of MOV 0.
55863d1a8abSmrg;; For MN103, this is only legal for DATA_REGS; for AM33 this is legal
55963d1a8abSmrg;; but not a win for ADDRESS_REGS.
56063d1a8abSmrg(define_peephole2
56163d1a8abSmrg  [(set (match_operand:INT 0 "register_operand" "") (const_int 0))]
56263d1a8abSmrg  "peep2_regno_dead_p (0, CC_REG)
56363d1a8abSmrg   && (REGNO_DATA_P (REGNO (operands[0]), 1)
56463d1a8abSmrg       || REGNO_EXTENDED_P (REGNO (operands[0]), 1))"
56563d1a8abSmrg  [(parallel [(set (match_dup 0) (const_int 0))
56663d1a8abSmrg	      (clobber (reg:CC CC_REG))])]
56763d1a8abSmrg)
56863d1a8abSmrg
56963d1a8abSmrg(define_insn "*mov<mode>_clr"
57063d1a8abSmrg  [(set (match_operand:INT 0 "register_operand" "=D")
57163d1a8abSmrg	(const_int 0))
57263d1a8abSmrg   (clobber (reg:CC CC_REG))]
57363d1a8abSmrg  ""
57463d1a8abSmrg  "clr %0"
57563d1a8abSmrg)
57663d1a8abSmrg
57763d1a8abSmrg;; ----------------------------------------------------------------------
57863d1a8abSmrg;; ADD INSTRUCTIONS
57963d1a8abSmrg;; ----------------------------------------------------------------------
58063d1a8abSmrg
58163d1a8abSmrg(define_insn "addsi3"
58263d1a8abSmrg  [(set (match_operand:SI          0 "register_operand"  "=r,r,r,!*y,!r")
58363d1a8abSmrg	(plus:SI (match_operand:SI 1 "register_operand"  "%0,0,0,  0, r")
58463d1a8abSmrg		 (match_operand:SI 2 "nonmemory_operand"  "r,O,i,  i, r")))
58563d1a8abSmrg   (clobber (reg:CC CC_REG))]
58663d1a8abSmrg  ""
58763d1a8abSmrg  { return mn10300_output_add (operands, false); }
58863d1a8abSmrg  [(set_attr "timings" "11,11,11,11,22")
58963d1a8abSmrg   (set_attr "liw" "either,either,*,*,*")
59063d1a8abSmrg   (set_attr "liw_op" "add")]
59163d1a8abSmrg)
59263d1a8abSmrg
59363d1a8abSmrg;; Note that ADD IMM,SP does not set the flags, so omit that here.
59463d1a8abSmrg(define_insn "*addsi3_flags"
595c7a68eb7Smrg  [(set (reg CC_REG)
596c7a68eb7Smrg   	(compare (plus:SI (match_operand:SI 1 "register_operand"  "%0, r")
597c7a68eb7Smrg			  (match_operand:SI 2 "nonmemory_operand" "ri, r"))
598c7a68eb7Smrg		 (const_int 0)))
599c7a68eb7Smrg   (set (match_operand:SI          0 "register_operand"  "=r,!r")
600c7a68eb7Smrg  	(plus:SI (match_dup 1) (match_dup 2)))]
60163d1a8abSmrg  "reload_completed && mn10300_match_ccmode (insn, CCZNCmode)"
60263d1a8abSmrg  { return mn10300_output_add (operands, true); }
60363d1a8abSmrg  [(set_attr "timings" "11,22")]
60463d1a8abSmrg)
60563d1a8abSmrg
60663d1a8abSmrg;; A helper to expand the above, with the CC_MODE filled in.
60763d1a8abSmrg(define_expand "addsi3_flags"
608c7a68eb7Smrg  [(parallel [(set (reg:CCZNC CC_REG)
60963d1a8abSmrg		   (compare:CCZNC (plus:SI (match_dup 1) (match_dup 2))
610c7a68eb7Smrg				  (const_int 0)))
611c7a68eb7Smrg	      (set (match_operand:SI 0 "register_operand")
612c7a68eb7Smrg		   (plus:SI (match_operand:SI 1 "register_operand")
613c7a68eb7Smrg			    (match_operand:SI 2 "nonmemory_operand")))])]
61463d1a8abSmrg  ""
61563d1a8abSmrg)
61663d1a8abSmrg
61763d1a8abSmrg(define_insn "addc_internal"
61863d1a8abSmrg  [(set (match_operand:SI 0 "register_operand"            "=D,r,r")
61963d1a8abSmrg	(plus:SI
62063d1a8abSmrg	  (plus:SI
62163d1a8abSmrg	    (ltu:SI (reg:CC CC_REG) (const_int 0))
62263d1a8abSmrg	    (match_operand:SI 1 "register_operand"        "%0,0,r"))
62363d1a8abSmrg	  (match_operand:SI 2 "reg_or_am33_const_operand" " D,i,r")))
62463d1a8abSmrg    (clobber (reg:CC CC_REG))]
62563d1a8abSmrg  "reload_completed"
62663d1a8abSmrg  "@
62763d1a8abSmrg   addc %2,%0
62863d1a8abSmrg   addc %2,%0
62963d1a8abSmrg   addc %2,%1,%0"
63063d1a8abSmrg  [(set_attr "isa" "*,am33,am33")]
63163d1a8abSmrg)
63263d1a8abSmrg
63363d1a8abSmrg(define_expand "adddi3"
63463d1a8abSmrg  [(set (match_operand:DI 0 "register_operand" "")
63563d1a8abSmrg	(plus:DI (match_operand:DI 1 "register_operand" "")
63663d1a8abSmrg		 (match_operand:DI 2 "nonmemory_operand" "")))]
63763d1a8abSmrg  ""
63863d1a8abSmrg{
63963d1a8abSmrg  rtx op0l, op0h, op1l, op1h, op2l, op2h;
64063d1a8abSmrg
64163d1a8abSmrg  op0l = gen_lowpart (SImode, operands[0]);
64263d1a8abSmrg  op1l = gen_lowpart (SImode, operands[1]);
64363d1a8abSmrg  op2l = gen_lowpart (SImode, operands[2]);
64463d1a8abSmrg  op0h = gen_highpart (SImode, operands[0]);
64563d1a8abSmrg  op1h = gen_highpart (SImode, operands[1]);
64663d1a8abSmrg  op2h = gen_highpart_mode (SImode, DImode, operands[2]);
64763d1a8abSmrg
64863d1a8abSmrg  if (!reg_or_am33_const_operand (op2h, SImode))
64963d1a8abSmrg    op2h = force_reg (SImode, op2h);
65063d1a8abSmrg
65163d1a8abSmrg  emit_insn (gen_adddi3_internal (op0l, op0h, op1l, op2l, op1h, op2h));
65263d1a8abSmrg  DONE;
65363d1a8abSmrg})
65463d1a8abSmrg
65563d1a8abSmrg;; Note that reload only supports one commutative operand.  Thus we cannot
65663d1a8abSmrg;; auto-swap both the high and low outputs with their matching constraints.
65763d1a8abSmrg;; For MN103, we're strapped for registers but thankfully the alternatives
65863d1a8abSmrg;; are few.  For AM33, it becomes much easier to not represent the early
65963d1a8abSmrg;; clobber and 6 permutations of immediate and three-operand adds, but
66063d1a8abSmrg;; instead allocate a scratch register and do the expansion by hand.
66163d1a8abSmrg
66263d1a8abSmrg(define_insn_and_split "adddi3_internal"
66363d1a8abSmrg  [(set (match_operand:SI          0 "register_operand"   "=r, r, r")
66463d1a8abSmrg	(plus:SI (match_operand:SI 2 "register_operand"   "%0, 0, r")
66563d1a8abSmrg		 (match_operand:SI 3 "nonmemory_operand"  "ri,ri,ri")))
66663d1a8abSmrg   (set (match_operand:SI          1 "register_operand"   "=D, D, r")
66763d1a8abSmrg	(plus:SI
66863d1a8abSmrg	  (plus:SI
66963d1a8abSmrg	    (ltu:SI (plus:SI (match_dup 2) (match_dup 3)) (match_dup 2))
67063d1a8abSmrg	    (match_operand:SI      4 "register_operand"   " 1, D, r"))
67163d1a8abSmrg	  (match_operand:SI 5 "reg_or_am33_const_operand" " D, 1,ri")))
67263d1a8abSmrg   (clobber (match_scratch:SI      6                      "=X, X,&r"))
67363d1a8abSmrg   (clobber (reg:CC CC_REG))]
67463d1a8abSmrg  ""
67563d1a8abSmrg  "#"
67663d1a8abSmrg  "reload_completed"
67763d1a8abSmrg  [(const_int 0)]
67863d1a8abSmrg{
67963d1a8abSmrg  rtx op0l = operands[0];
68063d1a8abSmrg  rtx op0h = operands[1];
68163d1a8abSmrg  rtx op1l = operands[2];
68263d1a8abSmrg  rtx op2l = operands[3];
68363d1a8abSmrg  rtx op1h = operands[4];
68463d1a8abSmrg  rtx op2h = operands[5];
68563d1a8abSmrg  rtx scratch = operands[6];
68663d1a8abSmrg  rtx x;
68763d1a8abSmrg
68863d1a8abSmrg  if (reg_overlap_mentioned_p (op0l, op1h))
68963d1a8abSmrg    {
69063d1a8abSmrg      emit_move_insn (scratch, op0l);
69163d1a8abSmrg      op1h = scratch;
69263d1a8abSmrg      if (reg_overlap_mentioned_p (op0l, op2h))
69363d1a8abSmrg	op2h = scratch;
69463d1a8abSmrg    }
69563d1a8abSmrg  else if (reg_overlap_mentioned_p (op0l, op2h))
69663d1a8abSmrg    {
69763d1a8abSmrg      emit_move_insn (scratch, op0l);
69863d1a8abSmrg      op2h = scratch;
69963d1a8abSmrg    }
70063d1a8abSmrg
70163d1a8abSmrg  if (rtx_equal_p (op0l, op1l))
70263d1a8abSmrg    ;
70363d1a8abSmrg  else if (rtx_equal_p (op0l, op2l))
70463d1a8abSmrg    x = op1l, op1l = op2l, op2l = x;
70563d1a8abSmrg  else
70663d1a8abSmrg    {
70763d1a8abSmrg      gcc_assert (TARGET_AM33);
70863d1a8abSmrg      if (!REG_P (op2l))
70963d1a8abSmrg	{
71063d1a8abSmrg	  emit_move_insn (op0l, op2l);
71163d1a8abSmrg	  op2l = op1l;
71263d1a8abSmrg	  op1l = op0l;
71363d1a8abSmrg	}
71463d1a8abSmrg    }
71563d1a8abSmrg  emit_insn (gen_addsi3_flags (op0l, op1l, op2l));
71663d1a8abSmrg
71763d1a8abSmrg  if (rtx_equal_p (op0h, op1h))
71863d1a8abSmrg    ;
71963d1a8abSmrg  else if (rtx_equal_p (op0h, op2h))
72063d1a8abSmrg    x = op1h, op1h = op2h, op2h = x;
72163d1a8abSmrg  else
72263d1a8abSmrg    {
72363d1a8abSmrg      gcc_assert (TARGET_AM33);
72463d1a8abSmrg      if (!REG_P (op2h))
72563d1a8abSmrg	{
72663d1a8abSmrg	  emit_move_insn (op0h, op2h);
72763d1a8abSmrg	  op2h = op1h;
72863d1a8abSmrg	  op1h = op0h;
72963d1a8abSmrg	}
73063d1a8abSmrg    }
73163d1a8abSmrg  emit_insn (gen_addc_internal (op0h, op1h, op2h));
73263d1a8abSmrg  DONE;
73363d1a8abSmrg}
73463d1a8abSmrg  [(set_attr "isa" "*,*,am33")]
73563d1a8abSmrg)
73663d1a8abSmrg
73763d1a8abSmrg;; The following pattern is generated by combine when it proves that one
73863d1a8abSmrg;; of the inputs to the low-part of the double-word add is zero, and thus
73963d1a8abSmrg;; no carry is generated into the high-part.
74063d1a8abSmrg
74163d1a8abSmrg(define_insn_and_split "*adddi3_degenerate"
74263d1a8abSmrg  [(set (match_operand:SI          0 "register_operand"  "=&r,&r")
74363d1a8abSmrg	(match_operand:SI          2 "nonmemory_operand" "  0, 0"))
74463d1a8abSmrg   (set (match_operand:SI          1 "register_operand"  "=r , r")
74563d1a8abSmrg	(plus:SI (match_operand:SI 3 "register_operand"  "%1 , r")
74663d1a8abSmrg		 (match_operand:SI 4 "nonmemory_operand" "ri, r")))
74763d1a8abSmrg   (clobber (reg:CC CC_REG))]
74863d1a8abSmrg  ""
74963d1a8abSmrg  "#"
75063d1a8abSmrg  ""
75163d1a8abSmrg  [(const_int 0)]
75263d1a8abSmrg{
75363d1a8abSmrg  rtx scratch = NULL_RTX;
75463d1a8abSmrg  if (!rtx_equal_p (operands[0], operands[2]))
75563d1a8abSmrg    {
75663d1a8abSmrg      if (reg_overlap_mentioned_p (operands[0], operands[3])
75763d1a8abSmrg	  || reg_overlap_mentioned_p (operands[0], operands[4]))
75863d1a8abSmrg	{
75963d1a8abSmrg	  scratch = gen_reg_rtx (SImode);
76063d1a8abSmrg	  emit_move_insn (scratch, operands[2]);
76163d1a8abSmrg	}
76263d1a8abSmrg      else
76363d1a8abSmrg	emit_move_insn (operands[0], operands[2]);
76463d1a8abSmrg    }
76563d1a8abSmrg  emit_insn (gen_addsi3 (operands[1], operands[3], operands[4]));
76663d1a8abSmrg  if (scratch)
76763d1a8abSmrg    emit_move_insn (operands[0], scratch);
76863d1a8abSmrg  DONE;
76963d1a8abSmrg})
77063d1a8abSmrg
77163d1a8abSmrg;; ----------------------------------------------------------------------
77263d1a8abSmrg;; SUBTRACT INSTRUCTIONS
77363d1a8abSmrg;; ----------------------------------------------------------------------
77463d1a8abSmrg
77563d1a8abSmrg(define_insn "subsi3"
77663d1a8abSmrg  [(set (match_operand:SI           0 "register_operand"  "=r,r,r,r")
77763d1a8abSmrg	(minus:SI (match_operand:SI 1 "register_operand"   "0,0,0,r")
77863d1a8abSmrg		  (match_operand:SI 2 "nonmemory_operand"  "r,O,i,r")))
77963d1a8abSmrg   (clobber (reg:CC CC_REG))]
78063d1a8abSmrg  ""
78163d1a8abSmrg  "@
78263d1a8abSmrg   sub %2,%0
78363d1a8abSmrg   sub %2,%0
78463d1a8abSmrg   sub %2,%0
78563d1a8abSmrg   sub %2,%1,%0"
78663d1a8abSmrg  [(set_attr "isa" "*,*,*,am33")
78763d1a8abSmrg   (set_attr "liw" "either,either,*,*")
78863d1a8abSmrg   (set_attr "liw_op" "sub")
78963d1a8abSmrg   (set_attr "timings" "11,11,11,22")]
79063d1a8abSmrg)
79163d1a8abSmrg
79263d1a8abSmrg(define_insn "*subsi3_flags"
793c7a68eb7Smrg  [(set (reg CC_REG)
794c7a68eb7Smrg   	(compare (minus:SI (match_operand:SI 1 "register_operand"  "0, r")
795c7a68eb7Smrg			   (match_operand:SI 2 "nonmemory_operand" "ri,r"))
796c7a68eb7Smrg		 (const_int 0)))
797c7a68eb7Smrg   (set (match_operand:SI           0 "register_operand"  "=r, r")
798c7a68eb7Smrg	(minus:SI (match_dup 1) (match_dup 2)))]
79963d1a8abSmrg  "reload_completed && mn10300_match_ccmode (insn, CCZNCmode)"
80063d1a8abSmrg  "@
80163d1a8abSmrg   sub %2,%0
80263d1a8abSmrg   sub %2,%1,%0"
80363d1a8abSmrg  [(set_attr "isa" "*,am33")
80463d1a8abSmrg   (set_attr "timings" "11,22")]
80563d1a8abSmrg)
80663d1a8abSmrg
80763d1a8abSmrg;; A helper to expand the above, with the CC_MODE filled in.
80863d1a8abSmrg(define_expand "subsi3_flags"
809c7a68eb7Smrg  [(parallel [(set (reg:CCZNC CC_REG)
81063d1a8abSmrg		   (compare:CCZNC (minus:SI (match_dup 1) (match_dup 2))
811c7a68eb7Smrg				  (const_int 0)))
812c7a68eb7Smrg	      (set (match_operand:SI 0 "register_operand")
813c7a68eb7Smrg		   (minus:SI (match_operand:SI 1 "register_operand")
814c7a68eb7Smrg			     (match_operand:SI 2 "nonmemory_operand")))])]
81563d1a8abSmrg  ""
81663d1a8abSmrg)
81763d1a8abSmrg
81863d1a8abSmrg(define_insn "subc_internal"
81963d1a8abSmrg  [(set (match_operand:SI 0 "register_operand"                      "=D,r,r")
82063d1a8abSmrg	(minus:SI
82163d1a8abSmrg	  (minus:SI (match_operand:SI 1 "register_operand"          " 0,0,r")
82263d1a8abSmrg		    (match_operand:SI 2 "reg_or_am33_const_operand" " D,i,r"))
82363d1a8abSmrg	  (geu:SI (reg:CC CC_REG) (const_int 0))))
82463d1a8abSmrg   (clobber (reg:CC CC_REG))]
82563d1a8abSmrg  "reload_completed"
82663d1a8abSmrg  "@
82763d1a8abSmrg   subc %2,%0
82863d1a8abSmrg   subc %2,%0
82963d1a8abSmrg   subc %2,%1,%0"
83063d1a8abSmrg  [(set_attr "isa" "*,am33,am33")]
83163d1a8abSmrg)
83263d1a8abSmrg
83363d1a8abSmrg(define_expand "subdi3"
83463d1a8abSmrg  [(set (match_operand:DI 0 "register_operand" "")
83563d1a8abSmrg        (minus:DI (match_operand:DI 1 "register_operand" "")
83663d1a8abSmrg                  (match_operand:DI 2 "nonmemory_operand" "")))]
83763d1a8abSmrg  ""
83863d1a8abSmrg{
83963d1a8abSmrg  rtx op0l, op0h, op1l, op1h, op2l, op2h;
84063d1a8abSmrg
84163d1a8abSmrg  op0l = gen_lowpart (SImode, operands[0]);
84263d1a8abSmrg  op1l = gen_lowpart (SImode, operands[1]);
84363d1a8abSmrg  op2l = gen_lowpart (SImode, operands[2]);
84463d1a8abSmrg  op0h = gen_highpart (SImode, operands[0]);
84563d1a8abSmrg  op1h = gen_highpart (SImode, operands[1]);
84663d1a8abSmrg  op2h = gen_highpart_mode (SImode, DImode, operands[2]);
84763d1a8abSmrg
84863d1a8abSmrg  if (!reg_or_am33_const_operand (op2h, SImode))
84963d1a8abSmrg    op2h = force_reg (SImode, op2h);
85063d1a8abSmrg
85163d1a8abSmrg  emit_insn (gen_subdi3_internal (op0l, op0h, op1l, op1h, op2l, op2h));
85263d1a8abSmrg  DONE;
85363d1a8abSmrg})
85463d1a8abSmrg
85563d1a8abSmrg;; As with adddi3, the use of the scratch register helps reduce the
85663d1a8abSmrg;; number of permutations for AM33.
85763d1a8abSmrg;; ??? The early clobber on op0 avoids a reload bug wherein both output
85863d1a8abSmrg;; registers are set the same.  Consider negate, where both op2 and op3
85963d1a8abSmrg;; are 0, are csed to the same input register, and reload fails to undo
86063d1a8abSmrg;; the cse when satisfying the matching constraints.
86163d1a8abSmrg
86263d1a8abSmrg(define_insn_and_split "subdi3_internal"
86363d1a8abSmrg  [(set (match_operand:SI     0 "register_operand"         "=&r, r")
86463d1a8abSmrg	(minus:SI
86563d1a8abSmrg	  (match_operand:SI   2 "register_operand"         "  0, r")
86663d1a8abSmrg	  (match_operand:SI   4 "nonmemory_operand"        " ri,ri")))
86763d1a8abSmrg   (set (match_operand:SI     1 "register_operand"         "=D , r")
86863d1a8abSmrg	(minus:SI
86963d1a8abSmrg	  (minus:SI
87063d1a8abSmrg	    (match_operand:SI 3 "register_operand"         "  1, r")
87163d1a8abSmrg	    (match_operand:SI 5 "reg_or_am33_const_operand" " D,ri"))
87263d1a8abSmrg	  (ltu:SI (match_dup 2) (match_dup 4))))
87363d1a8abSmrg   (clobber (match_scratch:SI 6                            "=X ,&r"))
87463d1a8abSmrg   (clobber (reg:CC CC_REG))]
87563d1a8abSmrg  ""
87663d1a8abSmrg  "#"
87763d1a8abSmrg  "reload_completed"
87863d1a8abSmrg  [(const_int 0)]
87963d1a8abSmrg{
88063d1a8abSmrg  rtx op0l = operands[0];
88163d1a8abSmrg  rtx op0h = operands[1];
88263d1a8abSmrg  rtx op1l = operands[2];
88363d1a8abSmrg  rtx op1h = operands[3];
88463d1a8abSmrg  rtx op2l = operands[4];
88563d1a8abSmrg  rtx op2h = operands[5];
88663d1a8abSmrg  rtx scratch = operands[6];
88763d1a8abSmrg
88863d1a8abSmrg  if (reg_overlap_mentioned_p (op0l, op1h))
88963d1a8abSmrg    {
89063d1a8abSmrg      emit_move_insn (scratch, op0l);
89163d1a8abSmrg      op1h = scratch;
89263d1a8abSmrg      if (reg_overlap_mentioned_p (op0l, op2h))
89363d1a8abSmrg	op2h = scratch;
89463d1a8abSmrg    }
89563d1a8abSmrg  else if (reg_overlap_mentioned_p (op0l, op2h))
89663d1a8abSmrg    {
89763d1a8abSmrg      emit_move_insn (scratch, op0l);
89863d1a8abSmrg      op2h = scratch;
89963d1a8abSmrg    }
90063d1a8abSmrg
90163d1a8abSmrg  if (!rtx_equal_p (op0l, op1l))
90263d1a8abSmrg    {
90363d1a8abSmrg      gcc_assert (TARGET_AM33);
90463d1a8abSmrg      if (!REG_P (op2l))
90563d1a8abSmrg	{
90663d1a8abSmrg	  emit_move_insn (op0l, op1l);
90763d1a8abSmrg	  op1l = op0l;
90863d1a8abSmrg	}
90963d1a8abSmrg    }
91063d1a8abSmrg  emit_insn (gen_subsi3_flags (op0l, op1l, op2l));
91163d1a8abSmrg
91263d1a8abSmrg  if (!rtx_equal_p (op0h, op1h))
91363d1a8abSmrg    {
91463d1a8abSmrg      gcc_assert (TARGET_AM33);
91563d1a8abSmrg      if (!REG_P (op2h))
91663d1a8abSmrg	{
91763d1a8abSmrg	  emit_move_insn (op0h, op1h);
91863d1a8abSmrg	  op1h = op0h;
91963d1a8abSmrg	}
92063d1a8abSmrg    }
92163d1a8abSmrg  emit_insn (gen_subc_internal (op0h, op1h, op2h));
92263d1a8abSmrg  DONE;
92363d1a8abSmrg}
92463d1a8abSmrg  [(set_attr "isa" "*,am33")]
92563d1a8abSmrg)
92663d1a8abSmrg
92763d1a8abSmrg;; The following pattern is generated by combine when it proves that one
92863d1a8abSmrg;; of the inputs to the low-part of the double-word sub is zero, and thus
92963d1a8abSmrg;; no carry is generated into the high-part.
93063d1a8abSmrg
93163d1a8abSmrg(define_insn_and_split "*subdi3_degenerate"
93263d1a8abSmrg  [(set (match_operand:SI          0 "register_operand"   "=&r,&r")
93363d1a8abSmrg	(match_operand:SI          2 "nonmemory_operand"  "  0, 0"))
93463d1a8abSmrg   (set (match_operand:SI          1 "register_operand"   "=r , r")
93563d1a8abSmrg	(minus:SI (match_operand:SI 3 "register_operand"  "  1, r")
93663d1a8abSmrg		  (match_operand:SI 4 "nonmemory_operand" " ri, r")))
93763d1a8abSmrg   (clobber (reg:CC CC_REG))]
93863d1a8abSmrg  ""
93963d1a8abSmrg  "#"
94063d1a8abSmrg  ""
94163d1a8abSmrg  [(const_int 0)]
94263d1a8abSmrg{
94363d1a8abSmrg  rtx scratch = NULL_RTX;
94463d1a8abSmrg  if (!rtx_equal_p (operands[0], operands[2]))
94563d1a8abSmrg    {
94663d1a8abSmrg      gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[1]));
94763d1a8abSmrg      if (reg_overlap_mentioned_p (operands[0], operands[3])
94863d1a8abSmrg	  || reg_overlap_mentioned_p (operands[0], operands[4]))
94963d1a8abSmrg	{
95063d1a8abSmrg	  scratch = gen_reg_rtx (SImode);
95163d1a8abSmrg	  emit_move_insn (scratch, operands[2]);
95263d1a8abSmrg	}
95363d1a8abSmrg      else
95463d1a8abSmrg	emit_move_insn (operands[0], operands[2]);
95563d1a8abSmrg    }
95663d1a8abSmrg  emit_insn (gen_subsi3 (operands[1], operands[3], operands[4]));
95763d1a8abSmrg  if (scratch)
95863d1a8abSmrg    emit_move_insn (operands[0], scratch);
95963d1a8abSmrg  DONE;
96063d1a8abSmrg})
96163d1a8abSmrg
96263d1a8abSmrg(define_insn_and_split "negsi2"
96363d1a8abSmrg  [(set (match_operand:SI         0 "register_operand"  "=D,&r")
96463d1a8abSmrg	(neg:SI (match_operand:SI 1 "register_operand"  " 0, r")))
96563d1a8abSmrg   (clobber (reg:CC CC_REG))]
96663d1a8abSmrg  ""
96763d1a8abSmrg  "#"
96863d1a8abSmrg  "&& reload_completed"
96963d1a8abSmrg  [(const_int 0)]
97063d1a8abSmrg{
97163d1a8abSmrg  /* Recall that twos-compliment is ones-compliment plus one.  When
97263d1a8abSmrg     allocated in DATA_REGS this is 2+1 bytes; otherwise (for am33)
97363d1a8abSmrg     this is 3+3 bytes.
97463d1a8abSmrg
97563d1a8abSmrg     For AM33, it would have been possible to load zero and use the
97663d1a8abSmrg     three-address subtract to have a total size of 3+4*N bytes for
97763d1a8abSmrg     multiple negations, plus increased throughput.  Not attempted here.  */
97863d1a8abSmrg
97963d1a8abSmrg  if (true_regnum (operands[0]) == true_regnum (operands[1]))
98063d1a8abSmrg    {
98163d1a8abSmrg      emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
98263d1a8abSmrg      emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx));
98363d1a8abSmrg    }
98463d1a8abSmrg  else
98563d1a8abSmrg    {
98663d1a8abSmrg      emit_move_insn (operands[0], const0_rtx);
98763d1a8abSmrg      emit_insn (gen_subsi3 (operands[0], operands[0], operands[1]));
98863d1a8abSmrg    }
98963d1a8abSmrg  DONE;
99063d1a8abSmrg})
99163d1a8abSmrg
99263d1a8abSmrg;; ----------------------------------------------------------------------
99363d1a8abSmrg;; MULTIPLY INSTRUCTIONS
99463d1a8abSmrg;; ----------------------------------------------------------------------
99563d1a8abSmrg
99663d1a8abSmrg;; ??? Note that AM33 has a third multiply variant that puts the high part
99763d1a8abSmrg;; into the MDRQ register, however this variant also constrains the inputs
99863d1a8abSmrg;; to be in DATA_REGS and thus isn't as helpful as it might be considering
99963d1a8abSmrg;; the existence of the 4-operand multiply.  Nor is there a set of divide
100063d1a8abSmrg;; insns that use MDRQ.  Given that there is an IMM->MDRQ insn, this would
100163d1a8abSmrg;; have been very handy for starting udivmodsi4...
100263d1a8abSmrg
100363d1a8abSmrg(define_expand "mulsidi3"
100463d1a8abSmrg  [(set (match_operand:DI 0 "register_operand" "")
100563d1a8abSmrg        (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
100663d1a8abSmrg                 (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))]
100763d1a8abSmrg  ""
100863d1a8abSmrg{
100963d1a8abSmrg  emit_insn (gen_mulsidi3_internal (gen_lowpart (SImode, operands[0]),
101063d1a8abSmrg				    gen_highpart (SImode, operands[0]),
101163d1a8abSmrg				    operands[1], operands[2]));
101263d1a8abSmrg  DONE;
101363d1a8abSmrg})
101463d1a8abSmrg
101563d1a8abSmrg(define_insn "mulsidi3_internal"
101663d1a8abSmrg  [(set (match_operand:SI          0 "register_operand" "=D,r")
101763d1a8abSmrg	(mult:SI (match_operand:SI 2 "register_operand" "%0,r")
101863d1a8abSmrg		 (match_operand:SI 3 "register_operand" " D,r")))
101963d1a8abSmrg   (set (match_operand:SI          1 "register_operand" "=z,r")
102063d1a8abSmrg	(truncate:SI
102163d1a8abSmrg	  (ashiftrt:DI
102263d1a8abSmrg	    (mult:DI (sign_extend:DI (match_dup 2))
102363d1a8abSmrg		     (sign_extend:DI (match_dup 3)))
102463d1a8abSmrg	    (const_int 32))))
102563d1a8abSmrg   (clobber (reg:CC CC_REG))]
102663d1a8abSmrg  ""
102763d1a8abSmrg{
102863d1a8abSmrg  if (which_alternative == 1)
102963d1a8abSmrg    return "mul %2,%3,%1,%0";
103063d1a8abSmrg  else if (TARGET_MULT_BUG)
103163d1a8abSmrg    return "nop\;nop\;mul %3,%0";
103263d1a8abSmrg  else
103363d1a8abSmrg    return "mul %3,%0";
103463d1a8abSmrg}
103563d1a8abSmrg  [(set_attr "isa" "*,am33")
103663d1a8abSmrg   (set (attr "timings")
103763d1a8abSmrg        (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))]
103863d1a8abSmrg)
103963d1a8abSmrg
104063d1a8abSmrg(define_expand "umulsidi3"
104163d1a8abSmrg  [(set (match_operand:DI 0 "register_operand" "")
104263d1a8abSmrg        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
104363d1a8abSmrg                 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
104463d1a8abSmrg   (clobber (reg:CC CC_REG))]
104563d1a8abSmrg  ""
104663d1a8abSmrg{
104763d1a8abSmrg  emit_insn (gen_umulsidi3_internal (gen_lowpart (SImode, operands[0]),
104863d1a8abSmrg				     gen_highpart (SImode, operands[0]),
104963d1a8abSmrg				     operands[1], operands[2]));
105063d1a8abSmrg  DONE;
105163d1a8abSmrg})
105263d1a8abSmrg
105363d1a8abSmrg(define_insn "umulsidi3_internal"
105463d1a8abSmrg  [(set (match_operand:SI          0 "register_operand" "=D,r")
105563d1a8abSmrg	(mult:SI (match_operand:SI 2 "register_operand" "%0,r")
105663d1a8abSmrg		 (match_operand:SI 3 "register_operand" " D,r")))
105763d1a8abSmrg   (set (match_operand:SI          1 "register_operand" "=z,r")
105863d1a8abSmrg	(truncate:SI
105963d1a8abSmrg	  (lshiftrt:DI
106063d1a8abSmrg	    (mult:DI (zero_extend:DI (match_dup 2))
106163d1a8abSmrg		     (zero_extend:DI (match_dup 3)))
106263d1a8abSmrg	    (const_int 32))))
106363d1a8abSmrg   (clobber (reg:CC CC_REG))]
106463d1a8abSmrg  ""
106563d1a8abSmrg{
106663d1a8abSmrg  if (which_alternative == 1)
106763d1a8abSmrg    return "mulu %2,%3,%1,%0";
106863d1a8abSmrg  else if (TARGET_MULT_BUG)
106963d1a8abSmrg    return "nop\;nop\;mulu %3,%0";
107063d1a8abSmrg  else
107163d1a8abSmrg    return "mulu %3,%0";
107263d1a8abSmrg}
107363d1a8abSmrg  [(set_attr "isa" "*,am33")
107463d1a8abSmrg   (set (attr "timings")
107563d1a8abSmrg        (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))]
107663d1a8abSmrg)
107763d1a8abSmrg
107863d1a8abSmrg(define_expand "mulsi3"
107963d1a8abSmrg  [(parallel [(set (match_operand:SI          0 "register_operand")
108063d1a8abSmrg		   (mult:SI (match_operand:SI 1 "register_operand")
108163d1a8abSmrg			    (match_operand:SI 2 "reg_or_am33_const_operand")))
108263d1a8abSmrg	      (clobber (match_scratch:SI      3))
108363d1a8abSmrg	      (clobber (reg:CC CC_REG))])]
108463d1a8abSmrg  ""
108563d1a8abSmrg)
108663d1a8abSmrg
108763d1a8abSmrg(define_insn "*mulsi3"
108863d1a8abSmrg  [(set (match_operand:SI          0 "register_operand"          "=D, r,r")
108963d1a8abSmrg	(mult:SI (match_operand:SI 2 "register_operand"          "%0, 0,r")
109063d1a8abSmrg		 (match_operand:SI 3 "reg_or_am33_const_operand" " D,ri,r")))
109163d1a8abSmrg   (clobber (match_scratch:SI      1                             "=z, z,r"))
109263d1a8abSmrg   (clobber (reg:CC CC_REG))]
109363d1a8abSmrg  ""
109463d1a8abSmrg{
109563d1a8abSmrg  if (which_alternative == 2)
109663d1a8abSmrg    return "mul %2,%3,%1,%0";
109763d1a8abSmrg  else if (TARGET_MULT_BUG)
109863d1a8abSmrg    return "nop\;nop\;mul %3,%0";
109963d1a8abSmrg  else
110063d1a8abSmrg    return "mul %3,%0";
110163d1a8abSmrg}
110263d1a8abSmrg  [(set_attr "isa" "*,am33,am33")
110363d1a8abSmrg   (set (attr "timings")
110463d1a8abSmrg	(if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))]
110563d1a8abSmrg)
110663d1a8abSmrg
110763d1a8abSmrg(define_expand "udivmodsi4"
110863d1a8abSmrg  [(parallel [(set (match_operand:SI          0 "register_operand")
110963d1a8abSmrg		   (udiv:SI (match_operand:SI 1 "register_operand")
111063d1a8abSmrg			    (match_operand:SI 2 "register_operand")))
111163d1a8abSmrg	      (set (match_operand:SI          3 "register_operand")
111263d1a8abSmrg		   (umod:SI (match_dup 1) (match_dup 2)))
111363d1a8abSmrg	      (use (const_int 0))
111463d1a8abSmrg	      (clobber (reg:CC CC_REG))])]
111563d1a8abSmrg  ""
111663d1a8abSmrg)
111763d1a8abSmrg
111863d1a8abSmrg;; Note the trick to get reload to put the zero into the MDR register,
111963d1a8abSmrg;; rather than exposing the load early and letting CSE or someone try
112063d1a8abSmrg;; to share the zeros between division insns.  Which tends to result
112163d1a8abSmrg;; in sequences like 0->r0->d0->mdr.
112263d1a8abSmrg
112363d1a8abSmrg(define_insn "*udivmodsi4"
112463d1a8abSmrg  [(set (match_operand:SI          0 "register_operand" "=D")
112563d1a8abSmrg	(udiv:SI (match_operand:SI 2 "register_operand" " 0")
112663d1a8abSmrg		 (match_operand:SI 3 "register_operand" " D")))
112763d1a8abSmrg   (set (match_operand:SI          1 "register_operand" "=z")
112863d1a8abSmrg	(umod:SI (match_dup 2) (match_dup 3)))
112963d1a8abSmrg   (use (match_operand:SI          4 "nonmemory_operand" " 1"))
113063d1a8abSmrg   (clobber (reg:CC CC_REG))]
113163d1a8abSmrg  ""
113263d1a8abSmrg  "divu %3,%0"
113363d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
113463d1a8abSmrg  	      		 	       (const_int 3839) (const_int 4243)))]
113563d1a8abSmrg)
113663d1a8abSmrg
113763d1a8abSmrg(define_expand "divmodsi4"
113863d1a8abSmrg  [(parallel [(set (match_operand:SI          0 "register_operand" "")
113963d1a8abSmrg		   (div:SI (match_operand:SI  1 "register_operand" "")
114063d1a8abSmrg			   (match_operand:SI  2 "register_operand" "")))
114163d1a8abSmrg	      (set (match_operand:SI          3 "register_operand" "")
114263d1a8abSmrg		   (mod:SI (match_dup 1) (match_dup 2)))
114363d1a8abSmrg	      (use (match_dup 4))
114463d1a8abSmrg	      (clobber (reg:CC CC_REG))])]
114563d1a8abSmrg  ""
114663d1a8abSmrg{
114763d1a8abSmrg  operands[4] = gen_reg_rtx (SImode);
114863d1a8abSmrg  emit_insn (gen_ext_internal (operands[4], operands[1]));
114963d1a8abSmrg})
115063d1a8abSmrg
115163d1a8abSmrg;; ??? Ideally we'd represent this via shift, but it seems like adding a
115263d1a8abSmrg;; special-case pattern for (ashiftrt x 31) is just as likely to result
115363d1a8abSmrg;; in poor register allocation choices.
115463d1a8abSmrg(define_insn "ext_internal"
115563d1a8abSmrg  [(set (match_operand:SI 0 "register_operand" "=z")
115663d1a8abSmrg	(unspec:SI [(match_operand:SI 1 "register_operand" "D")] UNSPEC_EXT))]
115763d1a8abSmrg  ""
115863d1a8abSmrg  "ext %1"
115963d1a8abSmrg)
116063d1a8abSmrg
116163d1a8abSmrg(define_insn "*divmodsi4"
116263d1a8abSmrg  [(set (match_operand:SI          0 "register_operand" "=D")
116363d1a8abSmrg	(div:SI (match_operand:SI  2 "register_operand" " 0")
116463d1a8abSmrg		(match_operand:SI  3 "register_operand" " D")))
116563d1a8abSmrg   (set (match_operand:SI          1 "register_operand" "=z")
116663d1a8abSmrg	(mod:SI (match_dup 2) (match_dup 3)))
116763d1a8abSmrg   (use (match_operand:SI          4 "register_operand" " 1"))
116863d1a8abSmrg   (clobber (reg:CC CC_REG))]
116963d1a8abSmrg  ""
117063d1a8abSmrg  "div %3,%0";
117163d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
117263d1a8abSmrg  	      		 	       (const_int 3839) (const_int 4243)))]
117363d1a8abSmrg)
117463d1a8abSmrg
117563d1a8abSmrg
117663d1a8abSmrg;; ----------------------------------------------------------------------
117763d1a8abSmrg;; AND INSTRUCTIONS
117863d1a8abSmrg;; ----------------------------------------------------------------------
117963d1a8abSmrg
118063d1a8abSmrg(define_insn "andsi3"
118163d1a8abSmrg  [(set (match_operand:SI         0 "register_operand"  "=D,D,r")
118263d1a8abSmrg	(and:SI (match_operand:SI 1 "register_operand"  "%0,0,r")
118363d1a8abSmrg		(match_operand:SI 2 "nonmemory_operand" " i,D,r")))
118463d1a8abSmrg   (clobber (reg:CC CC_REG))]
118563d1a8abSmrg  ""
118663d1a8abSmrg  "@
118763d1a8abSmrg   and %2,%0
118863d1a8abSmrg   and %2,%0
118963d1a8abSmrg   and %2,%1,%0"
119063d1a8abSmrg  [(set_attr "isa" "*,*,am33")
119163d1a8abSmrg   (set_attr "liw" "*,op1,*")
119263d1a8abSmrg   (set_attr "liw_op" "and")
119363d1a8abSmrg   (set_attr "timings" "22,11,11")]
119463d1a8abSmrg)
119563d1a8abSmrg
119663d1a8abSmrg(define_insn "*andsi3_flags"
1197c7a68eb7Smrg  [(set (reg CC_REG)
1198c7a68eb7Smrg   	(compare (and:SI (match_operand:SI 1 "register_operand"  "%0,0,r")
1199c7a68eb7Smrg			 (match_operand:SI 2 "nonmemory_operand" " i,D,r"))
1200c7a68eb7Smrg		 (const_int 0)))
1201c7a68eb7Smrg   (set (match_operand:SI         0 "register_operand"  "=D,D,r")
1202c7a68eb7Smrg	(and:SI (match_dup 1) (match_dup 2)))]
120363d1a8abSmrg  "reload_completed && mn10300_match_ccmode (insn, CCZNmode)"
120463d1a8abSmrg  "@
120563d1a8abSmrg   and %2,%0
120663d1a8abSmrg   and %2,%0
120763d1a8abSmrg   and %2,%1,%0"
120863d1a8abSmrg  [(set_attr "isa" "*,*,am33")
120963d1a8abSmrg   (set_attr "timings" "22,11,11")]
121063d1a8abSmrg)
121163d1a8abSmrg
121263d1a8abSmrg;; Make sure we generate extensions instead of ANDs.
121363d1a8abSmrg
121463d1a8abSmrg(define_split
121563d1a8abSmrg  [(parallel [(set (match_operand:SI 0 "register_operand" "")
121663d1a8abSmrg		   (and:SI (match_operand:SI 1 "register_operand" "")
121763d1a8abSmrg			   (const_int 255)))
121863d1a8abSmrg	      (clobber (reg:CC CC_REG))])]
121963d1a8abSmrg  ""
122063d1a8abSmrg  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
122163d1a8abSmrg  { operands[1] = gen_lowpart (QImode, operands[1]); }
122263d1a8abSmrg)
122363d1a8abSmrg
122463d1a8abSmrg(define_split
122563d1a8abSmrg  [(parallel [(set (match_operand:SI 0 "register_operand" "")
122663d1a8abSmrg		   (and:SI (match_operand:SI 1 "register_operand" "")
122763d1a8abSmrg			   (const_int 65535)))
122863d1a8abSmrg	      (clobber (reg:CC CC_REG))])]
122963d1a8abSmrg  ""
123063d1a8abSmrg  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
123163d1a8abSmrg  { operands[1] = gen_lowpart (HImode, operands[1]); }
123263d1a8abSmrg)
123363d1a8abSmrg
123463d1a8abSmrg;; Split AND by an appropriate constant into two shifts.  Recall that
123563d1a8abSmrg;; operations with a full 32-bit immediate require an extra cycle, so
123663d1a8abSmrg;; this is a size optimization with no speed penalty.  This only applies
123763d1a8abSmrg;; do DATA_REGS; the shift insns that AM33 adds are too large for a win.
123863d1a8abSmrg
123963d1a8abSmrg(define_split
124063d1a8abSmrg  [(parallel [(set (match_operand:SI 0 "register_operand" "")
124163d1a8abSmrg		   (and:SI (match_dup 0)
124263d1a8abSmrg			   (match_operand:SI 1 "const_int_operand" "")))
124363d1a8abSmrg	      (clobber (reg:CC CC_REG))])]
124463d1a8abSmrg  "reload_completed
124563d1a8abSmrg   && REGNO_DATA_P (true_regnum (operands[0]), 1)
124663d1a8abSmrg   && mn10300_split_and_operand_count (operands[1]) != 0"
124763d1a8abSmrg  [(const_int 0)]
124863d1a8abSmrg{
124963d1a8abSmrg  int count = mn10300_split_and_operand_count (operands[1]);
125063d1a8abSmrg  if (count > 0)
125163d1a8abSmrg    {
125263d1a8abSmrg      emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (count)));
125363d1a8abSmrg      emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (count)));
125463d1a8abSmrg    }
125563d1a8abSmrg  else
125663d1a8abSmrg    {
125763d1a8abSmrg      emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (-count)));
125863d1a8abSmrg      emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (-count)));
125963d1a8abSmrg    }
126063d1a8abSmrg  DONE;
126163d1a8abSmrg})
126263d1a8abSmrg
126363d1a8abSmrg;; ----------------------------------------------------------------------
126463d1a8abSmrg;; OR INSTRUCTIONS
126563d1a8abSmrg;; ----------------------------------------------------------------------
126663d1a8abSmrg
126763d1a8abSmrg(define_insn "iorsi3"
126863d1a8abSmrg  [(set (match_operand:SI         0 "register_operand"  "=D,D,r")
126963d1a8abSmrg	(ior:SI (match_operand:SI 1 "register_operand"  "%0,0,r")
127063d1a8abSmrg		(match_operand:SI 2 "nonmemory_operand" " i,D,r")))
127163d1a8abSmrg   (clobber (reg:CC CC_REG))]
127263d1a8abSmrg  ""
127363d1a8abSmrg  "@
127463d1a8abSmrg   or %2,%0
127563d1a8abSmrg   or %2,%0
127663d1a8abSmrg   or %2,%1,%0"
127763d1a8abSmrg  [(set_attr "isa" "*,*,am33")
127863d1a8abSmrg   (set_attr "liw" "*,op1,*")
127963d1a8abSmrg   (set_attr "liw_op" "or")
128063d1a8abSmrg   (set_attr "timings" "22,11,11")]
128163d1a8abSmrg)
128263d1a8abSmrg
128363d1a8abSmrg(define_insn "*iorsi3_flags"
1284c7a68eb7Smrg  [(set (reg CC_REG)
1285c7a68eb7Smrg   	(compare (ior:SI (match_operand:SI 1 "register_operand"  "%0,0,r")
1286c7a68eb7Smrg			 (match_operand:SI 2 "nonmemory_operand" " i,D,r"))
1287c7a68eb7Smrg		 (const_int 0)))
1288c7a68eb7Smrg   (set (match_operand:SI         0 "register_operand"  "=D,D,r")
1289c7a68eb7Smrg	(ior:SI (match_dup 1) (match_dup 2)))]
129063d1a8abSmrg  "reload_completed && mn10300_match_ccmode (insn, CCZNmode)"
129163d1a8abSmrg  "@
129263d1a8abSmrg   or %2,%0
129363d1a8abSmrg   or %2,%0
129463d1a8abSmrg   or %2,%1,%0"
129563d1a8abSmrg  [(set_attr "isa" "*,*,am33")
129663d1a8abSmrg   (set_attr "timings" "22,11,11")]
129763d1a8abSmrg)
129863d1a8abSmrg
129963d1a8abSmrg;; ----------------------------------------------------------------------
130063d1a8abSmrg;; XOR INSTRUCTIONS
130163d1a8abSmrg;; ----------------------------------------------------------------------
130263d1a8abSmrg
130363d1a8abSmrg(define_insn "xorsi3"
130463d1a8abSmrg  [(set (match_operand:SI         0 "register_operand"  "=D,D,r")
130563d1a8abSmrg	(xor:SI (match_operand:SI 1 "register_operand"  "%0,0,r")
130663d1a8abSmrg		(match_operand:SI 2 "nonmemory_operand" " i,D,r")))
130763d1a8abSmrg   (clobber (reg:CC CC_REG))]
130863d1a8abSmrg  ""
130963d1a8abSmrg  "@
131063d1a8abSmrg   xor %2,%0
131163d1a8abSmrg   xor %2,%0
131263d1a8abSmrg   xor %2,%1,%0"
131363d1a8abSmrg  [(set_attr "isa" "*,*,am33")
131463d1a8abSmrg   (set_attr "liw" "*,op1,*")
131563d1a8abSmrg   (set_attr "liw_op" "xor")
131663d1a8abSmrg   (set_attr "timings" "22,11,11")]
131763d1a8abSmrg)
131863d1a8abSmrg
131963d1a8abSmrg(define_insn "*xorsi3_flags"
1320c7a68eb7Smrg  [(set (reg CC_REG)
1321c7a68eb7Smrg   	(compare (xor:SI (match_operand:SI 1 "register_operand"  "%0,0,r")
1322c7a68eb7Smrg			 (match_operand:SI 2 "nonmemory_operand" " i,D,r"))
1323c7a68eb7Smrg		 (const_int 0)))
1324c7a68eb7Smrg   (set (match_operand:SI         0 "register_operand"  "=D,D,r")
1325c7a68eb7Smrg	(xor:SI (match_dup 1) (match_dup 2)))]
132663d1a8abSmrg  "reload_completed && mn10300_match_ccmode (insn, CCZNmode)"
132763d1a8abSmrg  "@
132863d1a8abSmrg   xor %2,%0
132963d1a8abSmrg   xor %2,%0
133063d1a8abSmrg   xor %2,%1,%0"
133163d1a8abSmrg  [(set_attr "isa" "*,*,am33")
133263d1a8abSmrg   (set_attr "timings" "22,11,11")]
133363d1a8abSmrg)
133463d1a8abSmrg
133563d1a8abSmrg;; ----------------------------------------------------------------------
133663d1a8abSmrg;; NOT INSTRUCTIONS
133763d1a8abSmrg;; ----------------------------------------------------------------------
133863d1a8abSmrg
133963d1a8abSmrg(define_insn "one_cmplsi2"
134063d1a8abSmrg  [(set (match_operand:SI         0 "register_operand" "=D")
134163d1a8abSmrg	(not:SI (match_operand:SI 1 "register_operand" " 0")))
134263d1a8abSmrg   (clobber (reg:CC CC_REG))]
134363d1a8abSmrg  ""
134463d1a8abSmrg  "not %0"
134563d1a8abSmrg)
134663d1a8abSmrg
134763d1a8abSmrg(define_insn "*one_cmplsi2_flags"
1348c7a68eb7Smrg  [(set (reg CC_REG)
1349c7a68eb7Smrg   	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
1350c7a68eb7Smrg		 (const_int 0)))
1351c7a68eb7Smrg   (set (match_operand:SI         0 "register_operand" "=D")
1352c7a68eb7Smrg	(not:SI (match_dup 1)))]
135363d1a8abSmrg  "reload_completed && mn10300_match_ccmode (insn, CCZNmode)"
135463d1a8abSmrg  "not %0"
135563d1a8abSmrg)
135663d1a8abSmrg
135763d1a8abSmrg;; ----------------------------------------------------------------------
135863d1a8abSmrg;; COMPARE AND BRANCH INSTRUCTIONS
135963d1a8abSmrg;; ----------------------------------------------------------------------
136063d1a8abSmrg
136163d1a8abSmrg;; We expand the comparison into a single insn so that it will not be split
136263d1a8abSmrg;; up by reload.
136363d1a8abSmrg(define_expand "cbranchsi4"
136463d1a8abSmrg  [(set (pc)
136563d1a8abSmrg	(if_then_else
136663d1a8abSmrg	      (match_operator                    0 "ordered_comparison_operator"
136763d1a8abSmrg			      [(match_operand:SI 1 "register_operand")
136863d1a8abSmrg			       (match_operand:SI 2 "nonmemory_operand")])
136963d1a8abSmrg              (label_ref (match_operand 3 ""))
137063d1a8abSmrg              (pc)))]
137163d1a8abSmrg  ""
137263d1a8abSmrg  ""
137363d1a8abSmrg)
137463d1a8abSmrg
137563d1a8abSmrg(define_insn_and_split "*cbranchsi4_cmp"
137663d1a8abSmrg  [(set (pc)
137763d1a8abSmrg	(if_then_else (match_operator           3 "ordered_comparison_operator"
137863d1a8abSmrg                       [(match_operand:SI       0 "register_operand"  "r")
137963d1a8abSmrg		        (match_operand:SI       1 "nonmemory_operand" "ri")])
138063d1a8abSmrg		      (match_operand            2 "label_ref_operand" "")
138163d1a8abSmrg		      (pc)))]
138263d1a8abSmrg  ""
138363d1a8abSmrg  "#"
138463d1a8abSmrg  "reload_completed"
138563d1a8abSmrg  [(const_int 0)]
138663d1a8abSmrg{
138763d1a8abSmrg  mn10300_split_cbranch (CCmode, operands[3], operands[2]);
138863d1a8abSmrg  DONE;
138963d1a8abSmrg})
139063d1a8abSmrg
139163d1a8abSmrg(define_insn "cmpsi"
139263d1a8abSmrg  [(set (reg CC_REG)
139363d1a8abSmrg	(compare (match_operand:SI 0 "register_operand"  "r,r,r")
139463d1a8abSmrg		 (match_operand:SI 1 "nonmemory_operand" "r,O,i")))]
139563d1a8abSmrg  "reload_completed"
139663d1a8abSmrg{
139763d1a8abSmrg  /* The operands of CMP must be distinct registers.  In the case where
139863d1a8abSmrg     we've failed to optimize the comparison of a register to itself, we
139963d1a8abSmrg     must use another method to set the Z flag.  We can achieve this
140063d1a8abSmrg     effect with a BTST 0,D0.  This will not alter the contents of D0;
140163d1a8abSmrg     the use of d0 is arbitrary; any data register would work.  */
140263d1a8abSmrg  if (rtx_equal_p (operands[0], operands[1]))
140363d1a8abSmrg    return "btst 0,d0";
140463d1a8abSmrg  else
140563d1a8abSmrg    return "cmp %1,%0";
140663d1a8abSmrg}
140763d1a8abSmrg  [(set_attr_alternative "timings"
140863d1a8abSmrg     [(if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))
140963d1a8abSmrg      (if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))
141063d1a8abSmrg      (if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))])
141163d1a8abSmrg   (set_attr "liw" "either,either,*")
141263d1a8abSmrg   (set_attr "liw_op" "cmp")]
141363d1a8abSmrg)
141463d1a8abSmrg
141563d1a8abSmrg(define_insn "*integer_conditional_branch"
141663d1a8abSmrg  [(set (pc)
141763d1a8abSmrg	(if_then_else (match_operator 0 "comparison_operator"
141863d1a8abSmrg			[(match_operand 2 "int_mode_flags" "")
141963d1a8abSmrg			 (const_int 0)])
142063d1a8abSmrg		      (label_ref (match_operand 1 "" ""))
142163d1a8abSmrg		      (pc)))]
142263d1a8abSmrg  "reload_completed"
142363d1a8abSmrg  "b%b0 %1"
142463d1a8abSmrg)
142563d1a8abSmrg
142663d1a8abSmrg(define_insn_and_split "*cbranchsi4_btst"
142763d1a8abSmrg  [(set (pc)
142863d1a8abSmrg	(if_then_else
142963d1a8abSmrg	  (match_operator 3 "CCZN_comparison_operator"
143063d1a8abSmrg	    [(and:SI (match_operand:SI 0 "register_operand" "D")
143163d1a8abSmrg		     (match_operand:SI 1 "immediate_operand" "i"))
143263d1a8abSmrg	     (const_int 0)])
143363d1a8abSmrg	  (match_operand 2 "label_ref_operand" "")
143463d1a8abSmrg	  (pc)))]
143563d1a8abSmrg  ""
143663d1a8abSmrg  "#"
143763d1a8abSmrg  "reload_completed"
143863d1a8abSmrg  [(const_int 0)]
143963d1a8abSmrg{
144063d1a8abSmrg  mn10300_split_cbranch (CCZNmode, operands[3], operands[2]);
144163d1a8abSmrg  DONE;
144263d1a8abSmrg})
144363d1a8abSmrg
144463d1a8abSmrg(define_insn "*btstsi"
144563d1a8abSmrg  [(set (reg:CCZN CC_REG)
144663d1a8abSmrg	(compare:CCZN
144763d1a8abSmrg	  (and:SI (match_operand:SI 0 "register_operand" "D")
144863d1a8abSmrg		  (match_operand:SI 1 "immediate_operand" "i"))
144963d1a8abSmrg	  (const_int 0)))]
145063d1a8abSmrg  "reload_completed"
145163d1a8abSmrg  "btst %1,%0"
145263d1a8abSmrg)
145363d1a8abSmrg
145463d1a8abSmrg(define_expand "cbranchsf4"
145563d1a8abSmrg  [(set (pc)
145663d1a8abSmrg      (if_then_else
145763d1a8abSmrg            (match_operator                    0 "ordered_comparison_operator"
145863d1a8abSmrg			    [(match_operand:SF 1 "register_operand")
145963d1a8abSmrg			     (match_operand:SF 2 "nonmemory_operand")])
146063d1a8abSmrg	    (label_ref (match_operand 3 ""))
146163d1a8abSmrg	    (pc)))]
146263d1a8abSmrg  "TARGET_AM33_2"
146363d1a8abSmrg  ""
146463d1a8abSmrg)
146563d1a8abSmrg
146663d1a8abSmrg(define_insn_and_split "*cbranchsf4_cmp"
146763d1a8abSmrg  [(set (pc)
146863d1a8abSmrg	(if_then_else (match_operator            3 "ordered_comparison_operator"
146963d1a8abSmrg			[(match_operand:SF       0 "register_operand"  "f")
147063d1a8abSmrg			 (match_operand:SF       1 "nonmemory_operand" "fF")])
147163d1a8abSmrg		      (match_operand             2 "label_ref_operand" "")
147263d1a8abSmrg		      (pc)))
147363d1a8abSmrg   ]
147463d1a8abSmrg  "TARGET_AM33_2"
147563d1a8abSmrg  "#"
147663d1a8abSmrg  "&& reload_completed"
147763d1a8abSmrg  [(const_int 0)]
147863d1a8abSmrg{
147963d1a8abSmrg  mn10300_split_cbranch (CC_FLOATmode, operands[3], operands[2]);
148063d1a8abSmrg  DONE;
148163d1a8abSmrg})
148263d1a8abSmrg
148363d1a8abSmrg(define_insn "*am33_cmpsf"
148463d1a8abSmrg  [(set (reg:CC_FLOAT CC_REG)
148563d1a8abSmrg	(compare:CC_FLOAT (match_operand:SF 0 "register_operand"  "f")
148663d1a8abSmrg			  (match_operand:SF 1 "nonmemory_operand" "fF")))]
148763d1a8abSmrg  "TARGET_AM33_2 && reload_completed"
148863d1a8abSmrg  "fcmp %1, %0"
148963d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
149063d1a8abSmrg				       (const_int 17) (const_int 25)))]
149163d1a8abSmrg)
149263d1a8abSmrg
149363d1a8abSmrg(define_insn "*float_conditional_branch"
149463d1a8abSmrg  [(set (pc)
149563d1a8abSmrg	(if_then_else (match_operator 0 "comparison_operator"
149663d1a8abSmrg				      [(reg:CC_FLOAT CC_REG) (const_int 0)])
149763d1a8abSmrg		      (label_ref (match_operand 1 "" ""))
149863d1a8abSmrg		      (pc)))]
149963d1a8abSmrg  "TARGET_AM33_2 && reload_completed"
150063d1a8abSmrg  "fb%b0 %1"
150163d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
150263d1a8abSmrg				       (const_int 44) (const_int 33)))]
150363d1a8abSmrg)
150463d1a8abSmrg
150563d1a8abSmrg;; Unconditional and other jump instructions.
150663d1a8abSmrg
150763d1a8abSmrg(define_insn "jump"
150863d1a8abSmrg  [(set (pc)
150963d1a8abSmrg	(label_ref (match_operand 0 "" "")))]
151063d1a8abSmrg  ""
151163d1a8abSmrg  "jmp %l0"
151263d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
151363d1a8abSmrg				       (const_int 11) (const_int 44)))]
151463d1a8abSmrg)
151563d1a8abSmrg
151663d1a8abSmrg(define_insn "indirect_jump"
151763d1a8abSmrg  [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
151863d1a8abSmrg  ""
151963d1a8abSmrg  "jmp (%0)"
152063d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
152163d1a8abSmrg				       (const_int 11) (const_int 33)))]
152263d1a8abSmrg)
152363d1a8abSmrg
152463d1a8abSmrg(define_expand "builtin_setjmp_receiver"
152563d1a8abSmrg  [(match_operand 0 "" "")]
152663d1a8abSmrg  "flag_pic"
152763d1a8abSmrg{
152863d1a8abSmrg  emit_insn (gen_load_pic ());
152963d1a8abSmrg  DONE;
153063d1a8abSmrg})
153163d1a8abSmrg
153263d1a8abSmrg(define_expand "casesi"
153363d1a8abSmrg  [(match_operand:SI 0 "register_operand")
153463d1a8abSmrg   (match_operand:SI 1 "immediate_operand")
153563d1a8abSmrg   (match_operand:SI 2 "immediate_operand")
153663d1a8abSmrg   (match_operand 3 "" "") (match_operand 4 "")]
153763d1a8abSmrg  ""
153863d1a8abSmrg{
153963d1a8abSmrg  rtx table = gen_reg_rtx (SImode);
154063d1a8abSmrg  rtx index = gen_reg_rtx (SImode);
154163d1a8abSmrg  rtx addr = gen_reg_rtx (Pmode);
154263d1a8abSmrg  rtx test;
154363d1a8abSmrg
154463d1a8abSmrg  emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
154563d1a8abSmrg  emit_insn (gen_addsi3 (index, operands[0], GEN_INT (- INTVAL (operands[1]))));
154663d1a8abSmrg  test = gen_rtx_fmt_ee (GTU, VOIDmode, index, operands[2]);
154763d1a8abSmrg  emit_jump_insn (gen_cbranchsi4 (test, index, operands[2], operands[4]));
154863d1a8abSmrg
154963d1a8abSmrg  emit_insn (gen_ashlsi3 (index, index, const2_rtx));
155063d1a8abSmrg  emit_move_insn (addr, gen_rtx_MEM (SImode,
155163d1a8abSmrg				     gen_rtx_PLUS (SImode, table, index)));
155263d1a8abSmrg  if (flag_pic)
155363d1a8abSmrg    emit_insn (gen_addsi3 (addr, addr, table));
155463d1a8abSmrg
155563d1a8abSmrg  emit_jump_insn (gen_tablejump (addr, operands[3]));
155663d1a8abSmrg  DONE;
155763d1a8abSmrg})
155863d1a8abSmrg
155963d1a8abSmrg(define_insn "tablejump"
156063d1a8abSmrg  [(set (pc) (match_operand:SI 0 "register_operand" "a"))
156163d1a8abSmrg   (use (label_ref (match_operand 1 "" "")))]
156263d1a8abSmrg  ""
156363d1a8abSmrg  "jmp (%0)"
156463d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
156563d1a8abSmrg				       (const_int 11) (const_int 33)))]
156663d1a8abSmrg)
156763d1a8abSmrg
156863d1a8abSmrg;; Call subroutine with no return value.
156963d1a8abSmrg
157063d1a8abSmrg(define_expand "call"
157163d1a8abSmrg  [(call (match_operand:QI 0 "general_operand")
157263d1a8abSmrg	 (match_operand:SI 1 "general_operand"))]
157363d1a8abSmrg  ""
157463d1a8abSmrg{
157563d1a8abSmrg  rtx fn = XEXP (operands[0], 0);
157663d1a8abSmrg
157763d1a8abSmrg  if (flag_pic && GET_CODE (fn) == SYMBOL_REF)
157863d1a8abSmrg    {
157963d1a8abSmrg      if (MN10300_GLOBAL_P (fn))
158063d1a8abSmrg	{
158163d1a8abSmrg	  /* The PLT code won't run on AM30, but then, there's no
158263d1a8abSmrg	     shared library support for AM30 either, so we just assume
158363d1a8abSmrg	     the linker is going to adjust all @PLT relocs to the
158463d1a8abSmrg	     actual symbols.  */
158563d1a8abSmrg	  emit_use (pic_offset_table_rtx);
158663d1a8abSmrg	  fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT);
158763d1a8abSmrg	}
158863d1a8abSmrg      else
158963d1a8abSmrg	fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC);
159063d1a8abSmrg    }
159163d1a8abSmrg  if (! call_address_operand (fn, VOIDmode))
159263d1a8abSmrg    fn = force_reg (SImode, fn);
159363d1a8abSmrg
159463d1a8abSmrg  XEXP (operands[0], 0) = fn;
159563d1a8abSmrg})
159663d1a8abSmrg
159763d1a8abSmrg(define_insn "*call_internal"
159863d1a8abSmrg  [(call (mem:QI (match_operand:SI 0 "call_address_operand" "a,S"))
159963d1a8abSmrg	 (match_operand:SI 1 "" ""))]
160063d1a8abSmrg  ""
160163d1a8abSmrg  "@
160263d1a8abSmrg   calls %C0
160363d1a8abSmrg   call %C0,[],0"
160463d1a8abSmrg  [(set_attr_alternative "timings"
160563d1a8abSmrg			 [(if_then_else (eq_attr "cpu" "am34")
160663d1a8abSmrg					(const_int 33) (const_int 44))
160763d1a8abSmrg			  (if_then_else (eq_attr "cpu" "am34")
160863d1a8abSmrg					(const_int 55) (const_int 33))
160963d1a8abSmrg			 ])
161063d1a8abSmrg  ]
161163d1a8abSmrg)
161263d1a8abSmrg
161363d1a8abSmrg;; Call subroutine, returning value in operand 0
161463d1a8abSmrg;; (which must be a hard register).
161563d1a8abSmrg
161663d1a8abSmrg(define_expand "call_value"
161763d1a8abSmrg  [(set (match_operand 0 "")
161863d1a8abSmrg	(call (match_operand:QI 1 "general_operand")
161963d1a8abSmrg	      (match_operand:SI 2 "general_operand")))]
162063d1a8abSmrg  ""
162163d1a8abSmrg{
162263d1a8abSmrg  rtx fn = XEXP (operands[1], 0);
162363d1a8abSmrg
162463d1a8abSmrg  if (flag_pic && GET_CODE (fn) == SYMBOL_REF)
162563d1a8abSmrg    {
162663d1a8abSmrg      if (MN10300_GLOBAL_P (fn))
162763d1a8abSmrg	{
162863d1a8abSmrg	  /* The PLT code won't run on AM30, but then, there's no
162963d1a8abSmrg	     shared library support for AM30 either, so we just assume
163063d1a8abSmrg	     the linker is going to adjust all @PLT relocs to the
163163d1a8abSmrg	     actual symbols.  */
163263d1a8abSmrg	  emit_use (pic_offset_table_rtx);
163363d1a8abSmrg	  fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT);
163463d1a8abSmrg	}
163563d1a8abSmrg      else
163663d1a8abSmrg	fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC);
163763d1a8abSmrg    }
163863d1a8abSmrg  if (! call_address_operand (fn, VOIDmode))
163963d1a8abSmrg    fn = force_reg (SImode, fn);
164063d1a8abSmrg
164163d1a8abSmrg  XEXP (operands[1], 0) = fn;
164263d1a8abSmrg})
164363d1a8abSmrg
164463d1a8abSmrg(define_insn "call_value_internal"
164563d1a8abSmrg  [(set (match_operand 0 "" "")
164663d1a8abSmrg	(call (mem:QI (match_operand:SI 1 "call_address_operand" "a,S"))
164763d1a8abSmrg	      (match_operand:SI 2 "" "")))]
164863d1a8abSmrg  ""
164963d1a8abSmrg  "@
165063d1a8abSmrg   calls %C1
165163d1a8abSmrg   call %C1,[],0"
165263d1a8abSmrg  [(set_attr_alternative "timings"
165363d1a8abSmrg			 [(if_then_else (eq_attr "cpu" "am34")
165463d1a8abSmrg					(const_int 33) (const_int 44))
165563d1a8abSmrg			  (if_then_else (eq_attr "cpu" "am34")
165663d1a8abSmrg					(const_int 55) (const_int 33))
165763d1a8abSmrg			 ])
165863d1a8abSmrg  ]
165963d1a8abSmrg)
166063d1a8abSmrg
166163d1a8abSmrg(define_expand "untyped_call"
166263d1a8abSmrg  [(parallel [(call (match_operand 0 "")
166363d1a8abSmrg                    (const_int 0))
166463d1a8abSmrg              (match_operand 1 "")
166563d1a8abSmrg              (match_operand 2 "")])]
166663d1a8abSmrg  ""
166763d1a8abSmrg{
166863d1a8abSmrg  int i;
166963d1a8abSmrg
167063d1a8abSmrg  emit_call_insn (gen_call (operands[0], const0_rtx));
167163d1a8abSmrg
167263d1a8abSmrg  for (i = 0; i < XVECLEN (operands[2], 0); i++)
167363d1a8abSmrg    {
167463d1a8abSmrg      rtx set = XVECEXP (operands[2], 0, i);
167563d1a8abSmrg      emit_move_insn (SET_DEST (set), SET_SRC (set));
167663d1a8abSmrg    }
167763d1a8abSmrg  DONE;
167863d1a8abSmrg})
167963d1a8abSmrg
168063d1a8abSmrg(define_insn "nop"
168163d1a8abSmrg  [(const_int 0)]
168263d1a8abSmrg  ""
168363d1a8abSmrg  "nop"
168463d1a8abSmrg)
168563d1a8abSmrg
168663d1a8abSmrg;; ----------------------------------------------------------------------
168763d1a8abSmrg;; EXTEND INSTRUCTIONS
168863d1a8abSmrg;; ----------------------------------------------------------------------
168963d1a8abSmrg
169063d1a8abSmrg(define_insn "zero_extendqisi2"
169163d1a8abSmrg  [(set (match_operand:SI 0 "register_operand"      "=D,D,r")
169263d1a8abSmrg	(zero_extend:SI
169363d1a8abSmrg	 (match_operand:QI 1 "nonimmediate_operand" " 0,m,r")))]
169463d1a8abSmrg  ""
169563d1a8abSmrg  "@
169663d1a8abSmrg   extbu %0
169763d1a8abSmrg   movbu %1,%0
169863d1a8abSmrg   extbu %1,%0"
169963d1a8abSmrg  [(set_attr "isa" "*,*,am33")
170063d1a8abSmrg   (set_attr_alternative "timings"
170163d1a8abSmrg		 [(const_int 11)
170263d1a8abSmrg		  (if_then_else (eq_attr "cpu" "am34")
170363d1a8abSmrg				(const_int 13) (const_int 24))
170463d1a8abSmrg		  (const_int 11)
170563d1a8abSmrg		 ])]
170663d1a8abSmrg)
170763d1a8abSmrg
170863d1a8abSmrg(define_insn "zero_extendhisi2"
170963d1a8abSmrg  [(set (match_operand:SI 0 "register_operand"      "=D,D,r")
171063d1a8abSmrg	(zero_extend:SI
171163d1a8abSmrg	 (match_operand:HI 1 "nonimmediate_operand" " 0,m,r")))]
171263d1a8abSmrg  ""
171363d1a8abSmrg  "@
171463d1a8abSmrg   exthu %0
171563d1a8abSmrg   movhu %1,%0
171663d1a8abSmrg   exthu %1,%0"
171763d1a8abSmrg  [(set_attr "isa" "*,*,am33")
171863d1a8abSmrg   (set_attr_alternative "timings"
171963d1a8abSmrg		 [(const_int 11)
172063d1a8abSmrg		  (if_then_else (eq_attr "cpu" "am34")
172163d1a8abSmrg				(const_int 13) (const_int 24))
172263d1a8abSmrg		  (const_int 11)])]
172363d1a8abSmrg)
172463d1a8abSmrg
172563d1a8abSmrg(define_insn "extendqisi2"
172663d1a8abSmrg  [(set (match_operand:SI 0 "register_operand" "=D,r")
172763d1a8abSmrg	(sign_extend:SI
172863d1a8abSmrg	 (match_operand:QI 1 "register_operand" "0,r")))]
172963d1a8abSmrg  ""
173063d1a8abSmrg  "@
173163d1a8abSmrg   extb %0
173263d1a8abSmrg   extb %1,%0"
173363d1a8abSmrg  [(set_attr "isa" "*,am33")]
173463d1a8abSmrg)
173563d1a8abSmrg
173663d1a8abSmrg(define_insn "extendhisi2"
173763d1a8abSmrg  [(set (match_operand:SI 0 "register_operand" "=D,r")
173863d1a8abSmrg	(sign_extend:SI
173963d1a8abSmrg	 (match_operand:HI 1 "register_operand" "0,r")))]
174063d1a8abSmrg  ""
174163d1a8abSmrg  "@
174263d1a8abSmrg   exth %0
174363d1a8abSmrg   exth %1,%0"
174463d1a8abSmrg  [(set_attr "isa" "*,am33")]
174563d1a8abSmrg)
174663d1a8abSmrg
174763d1a8abSmrg;; ----------------------------------------------------------------------
174863d1a8abSmrg;; SHIFTS
174963d1a8abSmrg;; ----------------------------------------------------------------------
175063d1a8abSmrg
175163d1a8abSmrg(define_insn "ashlsi3"
175263d1a8abSmrg  [(set (match_operand:SI  0 "register_operand"   "=r,D,d,d,D,D,D,r")
175363d1a8abSmrg	(ashift:SI
175463d1a8abSmrg	  (match_operand:SI 1 "register_operand"  " 0,0,0,0,0,0,0,r")
175563d1a8abSmrg	  (match_operand:QI 2 "nonmemory_operand" " J,K,M,L,D,O,i,r")))
175663d1a8abSmrg   (clobber (reg:CC CC_REG))]
175763d1a8abSmrg  ""
175863d1a8abSmrg  "@
175963d1a8abSmrg   add %0,%0
176063d1a8abSmrg   asl2 %0
176163d1a8abSmrg   asl2 %0\;add %0,%0
176263d1a8abSmrg   asl2 %0\;asl2 %0
176363d1a8abSmrg   asl %S2,%0
176463d1a8abSmrg   asl %S2,%0
176563d1a8abSmrg   asl %S2,%0
176663d1a8abSmrg   asl %2,%1,%0"
176763d1a8abSmrg  [(set_attr "isa" "*,*,*,*,*,*,*,am33")
176863d1a8abSmrg   (set_attr "liw" "op2,op2,op2,op2,op2,op2,*,*")
176963d1a8abSmrg   (set_attr "liw_op" "asl")
177063d1a8abSmrg   (set_attr "timings" "11,11,22,22,11,11,11,11")]
177163d1a8abSmrg)
177263d1a8abSmrg
177363d1a8abSmrg(define_insn "lshrsi3"
177463d1a8abSmrg  [(set (match_operand:SI  0 "register_operand"  "=D,D,D,r")
177563d1a8abSmrg	(lshiftrt:SI
177663d1a8abSmrg	  (match_operand:SI 1 "register_operand"  "0,0,0,r")
177763d1a8abSmrg	  (match_operand:QI 2 "nonmemory_operand" "D,O,i,r")))
177863d1a8abSmrg   (clobber (reg:CC CC_REG))]
177963d1a8abSmrg  ""
178063d1a8abSmrg  "@
178163d1a8abSmrg   lsr %S2,%0
178263d1a8abSmrg   lsr %S2,%0
178363d1a8abSmrg   lsr %S2,%0
178463d1a8abSmrg   lsr %2,%1,%0"
178563d1a8abSmrg  [(set_attr "isa" "*,*,*,am33")
178663d1a8abSmrg   (set_attr "liw" "op2,op2,*,*")
178763d1a8abSmrg   (set_attr "liw_op" "lsr")]
178863d1a8abSmrg)
178963d1a8abSmrg
179063d1a8abSmrg(define_insn "ashrsi3"
179163d1a8abSmrg  [(set (match_operand:SI  0 "register_operand"  "=D,D,D,r")
179263d1a8abSmrg	(ashiftrt:SI
179363d1a8abSmrg	  (match_operand:SI 1 "register_operand"  "0,0,0,r")
179463d1a8abSmrg	  (match_operand:QI 2 "nonmemory_operand" "D,O,i,r")))
179563d1a8abSmrg   (clobber (reg:CC CC_REG))]
179663d1a8abSmrg  ""
179763d1a8abSmrg  "@
179863d1a8abSmrg   asr %S2,%0
179963d1a8abSmrg   asr %S2,%0
180063d1a8abSmrg   asr %S2,%0
180163d1a8abSmrg   asr %2,%1,%0"
180263d1a8abSmrg  [(set_attr "isa" "*,*,*,am33")
180363d1a8abSmrg   (set_attr "liw" "op2,op2,*,*")
180463d1a8abSmrg   (set_attr "liw_op" "asr")]
180563d1a8abSmrg)
180663d1a8abSmrg
180763d1a8abSmrg;; ----------------------------------------------------------------------
180863d1a8abSmrg;; MISCELLANEOUS
180963d1a8abSmrg;; ----------------------------------------------------------------------
181063d1a8abSmrg
181163d1a8abSmrg;; Note the use of the (const_int 0) when generating the insn that matches
181263d1a8abSmrg;; the bsch pattern.  This ensures that the destination register is
181363d1a8abSmrg;; initialised with 0 which will make the BSCH instruction set searching
181463d1a8abSmrg;; at bit 31.
181563d1a8abSmrg;;
181663d1a8abSmrg;; The XOR in the instruction sequence below is there because the BSCH
181763d1a8abSmrg;; instruction returns the bit number of the highest set bit and we want
181863d1a8abSmrg;; the number of zero bits above that bit.  The AM33 does not have a
181963d1a8abSmrg;; reverse subtraction instruction, but we can use a simple xor instead
182063d1a8abSmrg;; since we know that the top 27 bits are clear.
182163d1a8abSmrg(define_expand "clzsi2"
182263d1a8abSmrg  [(parallel [(set (match_operand:SI 0 "register_operand")
182363d1a8abSmrg		   (unspec:SI [(match_operand:SI 1 "register_operand")
182463d1a8abSmrg			       (const_int 0)] UNSPEC_BSCH))
182563d1a8abSmrg	      (clobber (reg:CC CC_REG))])
182663d1a8abSmrg   (parallel [(set (match_dup 0)
182763d1a8abSmrg		   (xor:SI (match_dup 0)
182863d1a8abSmrg			   (const_int 31)))
182963d1a8abSmrg	      (clobber (reg:CC CC_REG))])]
183063d1a8abSmrg  "TARGET_AM33"
183163d1a8abSmrg)
183263d1a8abSmrg
183363d1a8abSmrg(define_insn "*bsch"
183463d1a8abSmrg  [(set (match_operand:SI 0 "register_operand" "=r")
183563d1a8abSmrg	(unspec:SI [(match_operand:SI 1 "register_operand" "r")
183663d1a8abSmrg		    (match_operand:SI 2 "nonmemory_operand" "0")]
183763d1a8abSmrg		   UNSPEC_BSCH))
183863d1a8abSmrg   (clobber (reg:CC CC_REG))]
183963d1a8abSmrg  "TARGET_AM33"
184063d1a8abSmrg  "bsch %1, %0"
184163d1a8abSmrg)
184263d1a8abSmrg
184363d1a8abSmrg;; ----------------------------------------------------------------------
184463d1a8abSmrg;; FP INSTRUCTIONS
184563d1a8abSmrg;; ----------------------------------------------------------------------
184663d1a8abSmrg
184763d1a8abSmrg(define_insn "abssf2"
184863d1a8abSmrg  [(set (match_operand:SF         0 "register_operand" "=f,f")
184963d1a8abSmrg	(abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
185063d1a8abSmrg  "TARGET_AM33_2"
185163d1a8abSmrg  "@
185263d1a8abSmrg   fabs %0
185363d1a8abSmrg   fabs %1, %0"
185463d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
185563d1a8abSmrg				       (const_int 17) (const_int 14)))]
185663d1a8abSmrg)
185763d1a8abSmrg
185863d1a8abSmrg(define_insn "negsf2"
185963d1a8abSmrg  [(set (match_operand:SF         0 "register_operand" "=f,f")
186063d1a8abSmrg	(neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
186163d1a8abSmrg  "TARGET_AM33_2"
186263d1a8abSmrg  "@
186363d1a8abSmrg   fneg %0
186463d1a8abSmrg   fneg %1, %0"
186563d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
186663d1a8abSmrg				       (const_int 17) (const_int 14)))]
186763d1a8abSmrg)
186863d1a8abSmrg
186963d1a8abSmrg(define_expand "sqrtsf2"
187063d1a8abSmrg  [(set (match_operand:SF 0 "register_operand" "")
187163d1a8abSmrg	(sqrt:SF (match_operand:SF 1 "register_operand" "")))]
187263d1a8abSmrg  "TARGET_AM33_2 && flag_unsafe_math_optimizations"
187363d1a8abSmrg{
187463d1a8abSmrg  rtx scratch = gen_reg_rtx (SFmode);
187563d1a8abSmrg  emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
187663d1a8abSmrg  emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
187763d1a8abSmrg			 scratch));
187863d1a8abSmrg  DONE;
187963d1a8abSmrg})
188063d1a8abSmrg
188163d1a8abSmrg(define_insn "rsqrtsf2"
188263d1a8abSmrg  [(set (match_operand:SF                  0 "register_operand" "=f,f")
188363d1a8abSmrg	(div:SF (match_operand:SF          2 "const_1f_operand" "F,F")
188463d1a8abSmrg		(sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))
188563d1a8abSmrg   (clobber (reg:CC_FLOAT CC_REG))]
188663d1a8abSmrg  "TARGET_AM33_2"
188763d1a8abSmrg  "@
188863d1a8abSmrg   frsqrt %0
188963d1a8abSmrg   frsqrt %1, %0"
189063d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
189163d1a8abSmrg				       (const_int 4753) (const_int 2327)))]
189263d1a8abSmrg)
189363d1a8abSmrg
189463d1a8abSmrg(define_insn "addsf3"
189563d1a8abSmrg  [(set (match_operand:SF          0 "register_operand" "=f,f")
189663d1a8abSmrg	(plus:SF (match_operand:SF 1 "register_operand" "%0,f")
189763d1a8abSmrg		 (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
189863d1a8abSmrg   (clobber (reg:CC_FLOAT CC_REG))]
189963d1a8abSmrg  "TARGET_AM33_2"
190063d1a8abSmrg  "@
190163d1a8abSmrg   fadd %2, %0
190263d1a8abSmrg   fadd %2, %1, %0"
190363d1a8abSmrg  [(set_attr_alternative "timings"
190463d1a8abSmrg			 [(if_then_else (eq_attr "cpu" "am34")
190563d1a8abSmrg					(const_int 17) (const_int 14))
190663d1a8abSmrg			  (if_then_else (eq_attr "cpu" "am34")
190763d1a8abSmrg					(const_int 17) (const_int 25))
190863d1a8abSmrg			 ])]
190963d1a8abSmrg)
191063d1a8abSmrg
191163d1a8abSmrg(define_insn "subsf3"
191263d1a8abSmrg  [(set (match_operand:SF           0 "register_operand" "=f,f")
191363d1a8abSmrg	(minus:SF (match_operand:SF 1 "register_operand" "0,f")
191463d1a8abSmrg		  (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
191563d1a8abSmrg   (clobber (reg:CC_FLOAT CC_REG))]
191663d1a8abSmrg  "TARGET_AM33_2"
191763d1a8abSmrg  "@
191863d1a8abSmrg   fsub %2, %0
191963d1a8abSmrg   fsub %2, %1, %0"
192063d1a8abSmrg  [(set_attr_alternative "timings"
192163d1a8abSmrg			 [(if_then_else (eq_attr "cpu" "am34")
192263d1a8abSmrg					(const_int 17) (const_int 14))
192363d1a8abSmrg			  (if_then_else (eq_attr "cpu" "am34")
192463d1a8abSmrg					(const_int 17) (const_int 25))
192563d1a8abSmrg			 ])]
192663d1a8abSmrg)
192763d1a8abSmrg
192863d1a8abSmrg(define_insn "mulsf3"
192963d1a8abSmrg  [(set (match_operand:SF          0 "register_operand" "=f,f")
193063d1a8abSmrg	(mult:SF (match_operand:SF 1 "register_operand" "%0,f")
193163d1a8abSmrg		 (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
193263d1a8abSmrg  (clobber (reg:CC_FLOAT CC_REG))
193363d1a8abSmrg  ]
193463d1a8abSmrg  "TARGET_AM33_2"
193563d1a8abSmrg  "@
193663d1a8abSmrg   fmul %2, %0
193763d1a8abSmrg   fmul %2, %1, %0"
193863d1a8abSmrg  [(set_attr_alternative "timings"
193963d1a8abSmrg			 [(if_then_else (eq_attr "cpu" "am34")
194063d1a8abSmrg					(const_int 17) (const_int 14))
194163d1a8abSmrg			  (if_then_else (eq_attr "cpu" "am34")
194263d1a8abSmrg					(const_int 17) (const_int 25))
194363d1a8abSmrg			 ])]
194463d1a8abSmrg)
194563d1a8abSmrg
194663d1a8abSmrg(define_insn "divsf3"
194763d1a8abSmrg  [(set (match_operand:SF         0 "register_operand" "=f,f")
194863d1a8abSmrg	(div:SF (match_operand:SF 1 "register_operand"  "0,f")
194963d1a8abSmrg		(match_operand:SF 2 "nonmemory_operand" "f,?fF")))
195063d1a8abSmrg   (clobber (reg:CC_FLOAT CC_REG))]
195163d1a8abSmrg  "TARGET_AM33_2"
195263d1a8abSmrg  "@
195363d1a8abSmrg   fdiv %2, %0
195463d1a8abSmrg   fdiv %2, %1, %0"
195563d1a8abSmrg  [(set_attr_alternative "timings"
195663d1a8abSmrg			 [(if_then_else (eq_attr "cpu" "am34")
195763d1a8abSmrg					(const_int 2531) (const_int 1216))
195863d1a8abSmrg			  (if_then_else (eq_attr "cpu" "am34")
195963d1a8abSmrg					(const_int 2531) (const_int 1317))
196063d1a8abSmrg			 ])]
196163d1a8abSmrg)
196263d1a8abSmrg
196363d1a8abSmrg(define_insn "fmasf4"
196463d1a8abSmrg  [(set (match_operand:SF         0 "register_operand" "=c")
196563d1a8abSmrg	(fma:SF (match_operand:SF 1 "register_operand" "f")
196663d1a8abSmrg		(match_operand:SF 2 "register_operand" "f")
196763d1a8abSmrg		(match_operand:SF 3 "register_operand" "f")))
196863d1a8abSmrg   (clobber (reg:CC_FLOAT CC_REG))
196963d1a8abSmrg  ]
197063d1a8abSmrg  "TARGET_AM33_2"
197163d1a8abSmrg  "fmadd %1, %2, %3, %0"
197263d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
197363d1a8abSmrg				       (const_int 17) (const_int 24)))]
197463d1a8abSmrg)
197563d1a8abSmrg
197663d1a8abSmrg(define_insn "fmssf4"
197763d1a8abSmrg  [(set (match_operand:SF                 0 "register_operand" "=c")
197863d1a8abSmrg	(fma:SF (match_operand:SF         1 "register_operand" "f")
197963d1a8abSmrg		(match_operand:SF         2 "register_operand" "f")
198063d1a8abSmrg		(neg:SF (match_operand:SF 3 "register_operand" "f"))))
198163d1a8abSmrg   (clobber (reg:CC_FLOAT CC_REG))
198263d1a8abSmrg  ]
198363d1a8abSmrg  "TARGET_AM33_2"
198463d1a8abSmrg  "fmsub %1, %2, %3, %0"
198563d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
198663d1a8abSmrg				       (const_int 17) (const_int 24)))]
198763d1a8abSmrg)
198863d1a8abSmrg
198963d1a8abSmrg(define_insn "fnmasf4"
199063d1a8abSmrg  [(set (match_operand:SF                 0 "register_operand" "=c")
199163d1a8abSmrg	(fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
199263d1a8abSmrg		(match_operand:SF         2 "register_operand" "f")
199363d1a8abSmrg		(match_operand:SF         3 "register_operand" "f")))
199463d1a8abSmrg   (clobber (reg:CC_FLOAT CC_REG))
199563d1a8abSmrg  ]
199663d1a8abSmrg  "TARGET_AM33_2"
199763d1a8abSmrg  "fnmadd %1, %2, %3, %0"
199863d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
199963d1a8abSmrg				       (const_int 17) (const_int 24)))]
200063d1a8abSmrg)
200163d1a8abSmrg
200263d1a8abSmrg(define_insn "fnmssf4"
200363d1a8abSmrg  [(set (match_operand:SF                 0 "register_operand" "=c")
200463d1a8abSmrg	(fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
200563d1a8abSmrg		(match_operand:SF         2 "register_operand" "f")
200663d1a8abSmrg		(neg:SF (match_operand:SF 3 "register_operand" "f"))))
200763d1a8abSmrg   (clobber (reg:CC_FLOAT CC_REG))
200863d1a8abSmrg  ]
200963d1a8abSmrg  "TARGET_AM33_2"
201063d1a8abSmrg  "fnmsub %1, %2, %3, %0"
201163d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
201263d1a8abSmrg				       (const_int 17) (const_int 24)))]
201363d1a8abSmrg)
201463d1a8abSmrg
201563d1a8abSmrg;; ----------------------------------------------------------------------
201663d1a8abSmrg;; PROLOGUE/EPILOGUE
201763d1a8abSmrg;; ----------------------------------------------------------------------
201863d1a8abSmrg(define_expand "prologue"
201963d1a8abSmrg  [(const_int 0)]
202063d1a8abSmrg  ""
202163d1a8abSmrg  { mn10300_expand_prologue (); DONE; }
202263d1a8abSmrg)
202363d1a8abSmrg
202463d1a8abSmrg(define_expand "epilogue"
202563d1a8abSmrg  [(return)]
202663d1a8abSmrg  ""
202763d1a8abSmrg  { mn10300_expand_epilogue (); DONE; }
202863d1a8abSmrg)
202963d1a8abSmrg
203063d1a8abSmrg(define_insn "return"
203163d1a8abSmrg  [(return)]
203263d1a8abSmrg  "mn10300_can_use_rets_insn ()"
203363d1a8abSmrg{
203463d1a8abSmrg  /* The RETF insn is 4 cycles faster than RETS, though 1 byte larger.  */
203563d1a8abSmrg  if (optimize_insn_for_speed_p () && mn10300_can_use_retf_insn ())
203663d1a8abSmrg    return "retf [],0";
203763d1a8abSmrg  else
203863d1a8abSmrg    return "rets";
203963d1a8abSmrg})
204063d1a8abSmrg
204163d1a8abSmrg(define_insn "return_ret"
204263d1a8abSmrg  [(return)
204363d1a8abSmrg   (use (match_operand:SI 0 "const_int_operand" ""))]
204463d1a8abSmrg  ""
204563d1a8abSmrg{
204663d1a8abSmrg  /* The RETF insn is up to 3 cycles faster than RET.  */
204763d1a8abSmrg  fputs ((mn10300_can_use_retf_insn () ? "\tretf " : "\tret "), asm_out_file);
204863d1a8abSmrg  mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs (NULL));
204963d1a8abSmrg  fprintf (asm_out_file, ",%d\n", (int) INTVAL (operands[0]));
205063d1a8abSmrg  return "";
205163d1a8abSmrg})
205263d1a8abSmrg
205363d1a8abSmrg;; This instruction matches one generated by mn10300_gen_multiple_store()
205463d1a8abSmrg(define_insn "store_movm"
205563d1a8abSmrg  [(match_parallel 0 "mn10300_store_multiple_operation"
205663d1a8abSmrg    [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand 1 "" "")))])]
205763d1a8abSmrg  ""
205863d1a8abSmrg{
205963d1a8abSmrg  fputs ("\tmovm ", asm_out_file);
206063d1a8abSmrg  mn10300_print_reg_list (asm_out_file,
206163d1a8abSmrg                          mn10300_store_multiple_regs (operands[0]));
206263d1a8abSmrg  fprintf (asm_out_file, ",(sp)\n");
206363d1a8abSmrg  return "";
206463d1a8abSmrg}
206563d1a8abSmrg  ;; Assume that no more than 8 registers will be pushed.
206663d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
206763d1a8abSmrg				       (const_int 99) (const_int 88)))]
206863d1a8abSmrg)
206963d1a8abSmrg
207063d1a8abSmrg(define_expand "load_pic"
207163d1a8abSmrg  [(const_int 0)]
207263d1a8abSmrg  "flag_pic"
207363d1a8abSmrg{
207463d1a8abSmrg  if (TARGET_AM33)
207563d1a8abSmrg    emit_insn (gen_am33_load_pic (pic_offset_table_rtx));
207663d1a8abSmrg  else if (mn10300_frame_size () == 0)
207763d1a8abSmrg    emit_insn (gen_mn10300_load_pic0 (pic_offset_table_rtx));
207863d1a8abSmrg  else
207963d1a8abSmrg    emit_insn (gen_mn10300_load_pic1 (pic_offset_table_rtx));
208063d1a8abSmrg  DONE;
208163d1a8abSmrg})
208263d1a8abSmrg
208363d1a8abSmrg(define_insn "am33_load_pic"
208463d1a8abSmrg  [(set (match_operand:SI 0 "register_operand" "=a")
208563d1a8abSmrg	(unspec:SI [(const_int 0)] UNSPEC_GOT))
208663d1a8abSmrg   (clobber (reg:CC CC_REG))]
208763d1a8abSmrg  "TARGET_AM33"
208863d1a8abSmrg{
208963d1a8abSmrg  operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
209063d1a8abSmrg  return ".LPIC%=:\;mov pc,%0\;add %1-(.LPIC%=-.),%0";
209163d1a8abSmrg}
209263d1a8abSmrg  [(set_attr "timings" "33")]
209363d1a8abSmrg)
209463d1a8abSmrg
209563d1a8abSmrg;; Load pic register with push/pop of stack.
209663d1a8abSmrg(define_insn "mn10300_load_pic0"
209763d1a8abSmrg  [(set (match_operand:SI 0 "register_operand" "=a")
209863d1a8abSmrg	(unspec:SI [(const_int 0)] UNSPEC_GOT))
209963d1a8abSmrg   (clobber (reg:SI MDR_REG))
210063d1a8abSmrg   (clobber (reg:CC CC_REG))]
210163d1a8abSmrg  ""
210263d1a8abSmrg{
210363d1a8abSmrg  operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
210463d1a8abSmrg  return ("add -4,sp\;"
210563d1a8abSmrg	  "calls .LPIC%=\n"
210663d1a8abSmrg          ".LPIC%=:\;"
210763d1a8abSmrg	  "movm (sp),[%0]\;"
210863d1a8abSmrg	  "add %1-(.LPIC%=-.),%0");
210963d1a8abSmrg}
211063d1a8abSmrg  [(set_attr "timings" "88")]
211163d1a8abSmrg)
211263d1a8abSmrg
211363d1a8abSmrg;; Load pic register re-using existing stack space.
211463d1a8abSmrg(define_insn "mn10300_load_pic1"
211563d1a8abSmrg  [(set (match_operand:SI 0 "register_operand" "=a")
211663d1a8abSmrg	(unspec:SI [(const_int 0)] UNSPEC_GOT))
211763d1a8abSmrg   (clobber (mem:SI (reg:SI SP_REG)))
211863d1a8abSmrg   (clobber (reg:SI MDR_REG))
211963d1a8abSmrg   (clobber (reg:CC CC_REG))]
212063d1a8abSmrg  ""
212163d1a8abSmrg{
212263d1a8abSmrg  operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
212363d1a8abSmrg  return ("calls .LPIC%=\n"
212463d1a8abSmrg	  ".LPIC%=:\;"
212563d1a8abSmrg          "mov (sp),%0\;"
212663d1a8abSmrg          "add %1-(.LPIC%=-.),%0");
212763d1a8abSmrg}
212863d1a8abSmrg  [(set_attr "timings" "66")]
212963d1a8abSmrg)
213063d1a8abSmrg
213163d1a8abSmrg;; The mode on operand 3 has been deliberately omitted because it
213263d1a8abSmrg;; can be either SI (for arithmetic operations) or QI (for shifts).
213363d1a8abSmrg(define_insn "liw"
213463d1a8abSmrg  [(set (match_operand:SI             0 "register_operand" "=r")
213563d1a8abSmrg	(unspec:SI [(match_dup 0)
213663d1a8abSmrg                    (match_operand    2 "liw_operand"       "rO")
213763d1a8abSmrg                    (match_operand:SI 4 "const_int_operand" "")]
213863d1a8abSmrg                   UNSPEC_LIW))
213963d1a8abSmrg   (set (match_operand:SI             1 "register_operand" "=r")
214063d1a8abSmrg        (unspec:SI [(match_dup 1)
214163d1a8abSmrg                    (match_operand    3 "liw_operand"       "rO")
214263d1a8abSmrg                    (match_operand:SI 5 "const_int_operand" "")]
214363d1a8abSmrg                   UNSPEC_LIW))]
214463d1a8abSmrg  "TARGET_ALLOW_LIW"
214563d1a8abSmrg  "%W4_%W5 %2, %0, %3, %1"
214663d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
214763d1a8abSmrg				       (const_int 13) (const_int 12)))]
214863d1a8abSmrg)
214963d1a8abSmrg
215063d1a8abSmrg;; The mode on operand 1 has been deliberately omitted because it
215163d1a8abSmrg;; can be either SI (for arithmetic operations) or QI (for shifts).
215263d1a8abSmrg(define_insn "cmp_liw"
215363d1a8abSmrg  [(set (reg:CC CC_REG)
215463d1a8abSmrg	(compare:CC (match_operand:SI 2 "register_operand" "r")
215563d1a8abSmrg		    (match_operand    3 "liw_operand"      "rO")))
215663d1a8abSmrg   (set (match_operand:SI             0 "register_operand" "=r")
215763d1a8abSmrg        (unspec:SI [(match_dup 0)
215863d1a8abSmrg                    (match_operand    1 "liw_operand"       "rO")
215963d1a8abSmrg                    (match_operand:SI 4 "const_int_operand" "")]
216063d1a8abSmrg                   UNSPEC_LIW))]
216163d1a8abSmrg  "TARGET_ALLOW_LIW"
216263d1a8abSmrg  "cmp_%W4 %3, %2, %1, %0"
216363d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
216463d1a8abSmrg				       (const_int 13) (const_int 12)))]
216563d1a8abSmrg)
216663d1a8abSmrg
216763d1a8abSmrg(define_insn "liw_cmp"
216863d1a8abSmrg  [(set (match_operand:SI             0 "register_operand" "=r")
216963d1a8abSmrg        (unspec:SI [(match_dup 0)
217063d1a8abSmrg                    (match_operand    1 "liw_operand"      "rO")
217163d1a8abSmrg                    (match_operand:SI 4 "const_int_operand" "")]
217263d1a8abSmrg                   UNSPEC_LIW))
217363d1a8abSmrg   (set (reg:CC CC_REG)
217463d1a8abSmrg	(compare:CC (match_operand:SI 2 "register_operand" "r")
217563d1a8abSmrg		    (match_operand    3 "liw_operand"      "rO")))]
217663d1a8abSmrg  "TARGET_ALLOW_LIW"
217763d1a8abSmrg  "%W4_cmp %1, %0, %3, %2"
217863d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
217963d1a8abSmrg				       (const_int 13) (const_int 12)))]
218063d1a8abSmrg)
218163d1a8abSmrg
218263d1a8abSmrg;; Note - in theory the doloop patterns could be used here to express
218363d1a8abSmrg;; the SETLB and Lcc instructions.  In practice this does not work because
218463d1a8abSmrg;; the acceptable forms of the doloop patterns do not include UNSPECs
218563d1a8abSmrg;; and without them gcc's basic block reordering code can duplicate the
218663d1a8abSmrg;; doloop_end pattern, leading to bogus multiple decrements of the loop
218763d1a8abSmrg;; counter.
218863d1a8abSmrg
218963d1a8abSmrg(define_insn "setlb"
219063d1a8abSmrg  [(unspec [(const_int 0)] UNSPEC_SETLB)]
219163d1a8abSmrg  "TARGET_AM33 && TARGET_ALLOW_SETLB"
219263d1a8abSmrg  "setlb"
219363d1a8abSmrg)
219463d1a8abSmrg
219563d1a8abSmrg(define_insn "Lcc"
219663d1a8abSmrg  [(set (pc)
219763d1a8abSmrg	(if_then_else (match_operator 0 "comparison_operator"
219863d1a8abSmrg		      [(reg:CC CC_REG) (const_int 0)])
219963d1a8abSmrg		      (label_ref (match_operand 1 "" ""))
220063d1a8abSmrg		      (pc)))
220163d1a8abSmrg   (unspec [(const_int 1)] UNSPEC_SETLB)]
220263d1a8abSmrg  "TARGET_AM33 && TARGET_ALLOW_SETLB"
220363d1a8abSmrg  "L%b0 # loop back to: %1"
220463d1a8abSmrg)
220563d1a8abSmrg
220663d1a8abSmrg(define_insn "FLcc"
220763d1a8abSmrg  [(set (pc)
220863d1a8abSmrg	(if_then_else (match_operator 0 "comparison_operator"
220963d1a8abSmrg		      [(reg:CC_FLOAT CC_REG) (const_int 0)])
221063d1a8abSmrg		      (label_ref (match_operand 1 "" ""))
221163d1a8abSmrg		      (pc)))
221263d1a8abSmrg   (unspec [(const_int 2)] UNSPEC_SETLB)]
221363d1a8abSmrg  "TARGET_AM33_2 && TARGET_ALLOW_SETLB"
221463d1a8abSmrg  "FL%b0 # loop back to: %1"
221563d1a8abSmrg  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") (const_int 44) (const_int 11)))]
221663d1a8abSmrg)
2217