xref: /openbsd/gnu/usr.bin/gcc/gcc/config/arc/arc.md (revision c87b03e5)
1*c87b03e5Sespie;; Machine description of the Argonaut ARC cpu for GNU C compiler
2*c87b03e5Sespie;; Copyright (C) 1994, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
3*c87b03e5Sespie
4*c87b03e5Sespie;; This file is part of GNU CC.
5*c87b03e5Sespie
6*c87b03e5Sespie;; GNU CC is free software; you can redistribute it and/or modify
7*c87b03e5Sespie;; it under the terms of the GNU General Public License as published by
8*c87b03e5Sespie;; the Free Software Foundation; either version 2, or (at your option)
9*c87b03e5Sespie;; any later version.
10*c87b03e5Sespie
11*c87b03e5Sespie;; GNU CC is distributed in the hope that it will be useful,
12*c87b03e5Sespie;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13*c87b03e5Sespie;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*c87b03e5Sespie;; GNU General Public License for more details.
15*c87b03e5Sespie
16*c87b03e5Sespie;; You should have received a copy of the GNU General Public License
17*c87b03e5Sespie;; along with GNU CC; see the file COPYING.  If not, write to
18*c87b03e5Sespie;; the Free Software Foundation, 59 Temple Place - Suite 330,
19*c87b03e5Sespie;; Boston, MA 02111-1307, USA.
20*c87b03e5Sespie
21*c87b03e5Sespie;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
22*c87b03e5Sespie
23*c87b03e5Sespie;; ??? This is an old port, and is undoubtedly suffering from bit rot.
24*c87b03e5Sespie
25*c87b03e5Sespie;; Insn type.  Used to default other attribute values.
26*c87b03e5Sespie
27*c87b03e5Sespie(define_attr "type"
28*c87b03e5Sespie  "move,load,store,cmove,unary,binary,compare,shift,mul,uncond_branch,branch,call,call_no_delay_slot,multi,misc"
29*c87b03e5Sespie  (const_string "binary"))
30*c87b03e5Sespie
31*c87b03e5Sespie;; Length (in # of insns, long immediate constants counted too).
32*c87b03e5Sespie;; ??? There's a nasty interaction between the conditional execution fsm
33*c87b03e5Sespie;; and insn lengths: insns with shimm values cannot be conditionally executed.
34*c87b03e5Sespie(define_attr "length" ""
35*c87b03e5Sespie  (cond [(eq_attr "type" "load")
36*c87b03e5Sespie	 (if_then_else (match_operand 1 "long_immediate_loadstore_operand" "")
37*c87b03e5Sespie		       (const_int 2) (const_int 1))
38*c87b03e5Sespie
39*c87b03e5Sespie	 (eq_attr "type" "store")
40*c87b03e5Sespie	 (if_then_else (match_operand 0 "long_immediate_loadstore_operand" "")
41*c87b03e5Sespie		       (const_int 2) (const_int 1))
42*c87b03e5Sespie
43*c87b03e5Sespie	 (eq_attr "type" "move,unary,compare")
44*c87b03e5Sespie	 (if_then_else (match_operand 1 "long_immediate_operand" "")
45*c87b03e5Sespie		       (const_int 2) (const_int 1))
46*c87b03e5Sespie
47*c87b03e5Sespie	 (eq_attr "type" "binary,mul")
48*c87b03e5Sespie	 (if_then_else (match_operand 2 "long_immediate_operand" "")
49*c87b03e5Sespie		       (const_int 2) (const_int 1))
50*c87b03e5Sespie
51*c87b03e5Sespie	 (eq_attr "type" "cmove")
52*c87b03e5Sespie	 (if_then_else (match_operand 2 "register_operand" "")
53*c87b03e5Sespie		       (const_int 1) (const_int 2))
54*c87b03e5Sespie
55*c87b03e5Sespie	 (eq_attr "type" "multi") (const_int 2)
56*c87b03e5Sespie	]
57*c87b03e5Sespie
58*c87b03e5Sespie	(const_int 1)))
59*c87b03e5Sespie
60*c87b03e5Sespie;; The length here is the length of a single asm.  Unfortunately it might be
61*c87b03e5Sespie;; 1 or 2 so we must allow for 2.  That's ok though.  How often will users
62*c87b03e5Sespie;; lament asm's not being put in delay slots?
63*c87b03e5Sespie(define_asm_attributes
64*c87b03e5Sespie  [(set_attr "length" "2")
65*c87b03e5Sespie   (set_attr "type" "multi")])
66*c87b03e5Sespie
67*c87b03e5Sespie;; Condition codes: this one is used by final_prescan_insn to speed up
68*c87b03e5Sespie;; conditionalizing instructions.  It saves having to scan the rtl to see if
69*c87b03e5Sespie;; it uses or alters the condition codes.
70*c87b03e5Sespie
71*c87b03e5Sespie;; USE: This insn uses the condition codes (eg: a conditional branch).
72*c87b03e5Sespie;; CANUSE: This insn can use the condition codes (for conditional execution).
73*c87b03e5Sespie;; SET: All condition codes are set by this insn.
74*c87b03e5Sespie;; SET_ZN: the Z and N flags are set by this insn.
75*c87b03e5Sespie;; SET_ZNC: the Z, N, and C flags are set by this insn.
76*c87b03e5Sespie;; CLOB: The condition codes are set to unknown values by this insn.
77*c87b03e5Sespie;; NOCOND: This insn can't use and doesn't affect the condition codes.
78*c87b03e5Sespie
79*c87b03e5Sespie(define_attr "cond" "use,canuse,set,set_zn,set_znc,clob,nocond"
80*c87b03e5Sespie  (cond [(and (eq_attr "type" "unary,binary,move")
81*c87b03e5Sespie	      (eq_attr "length" "1"))
82*c87b03e5Sespie	 (const_string "canuse")
83*c87b03e5Sespie
84*c87b03e5Sespie	 (eq_attr "type" "compare")
85*c87b03e5Sespie	 (const_string "set")
86*c87b03e5Sespie
87*c87b03e5Sespie	 (eq_attr "type" "cmove,branch")
88*c87b03e5Sespie	 (const_string "use")
89*c87b03e5Sespie
90*c87b03e5Sespie	 (eq_attr "type" "multi,misc")
91*c87b03e5Sespie	 (const_string "clob")
92*c87b03e5Sespie	 ]
93*c87b03e5Sespie
94*c87b03e5Sespie	 (const_string "nocond")))
95*c87b03e5Sespie
96*c87b03e5Sespie;; Delay slots.
97*c87b03e5Sespie
98*c87b03e5Sespie(define_attr "in_delay_slot" "false,true"
99*c87b03e5Sespie  (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
100*c87b03e5Sespie	 (const_string "false")
101*c87b03e5Sespie	 ]
102*c87b03e5Sespie
103*c87b03e5Sespie	 (if_then_else (eq_attr "length" "1")
104*c87b03e5Sespie		       (const_string "true")
105*c87b03e5Sespie		       (const_string "false"))))
106*c87b03e5Sespie
107*c87b03e5Sespie(define_delay (eq_attr "type" "call")
108*c87b03e5Sespie  [(eq_attr "in_delay_slot" "true")
109*c87b03e5Sespie   (eq_attr "in_delay_slot" "true")
110*c87b03e5Sespie   (eq_attr "in_delay_slot" "true")])
111*c87b03e5Sespie
112*c87b03e5Sespie(define_delay (eq_attr "type" "branch,uncond_branch")
113*c87b03e5Sespie  [(eq_attr "in_delay_slot" "true")
114*c87b03e5Sespie   (eq_attr "in_delay_slot" "true")
115*c87b03e5Sespie   (eq_attr "in_delay_slot" "true")])
116*c87b03e5Sespie
117*c87b03e5Sespie;; Function units of the ARC
118*c87b03e5Sespie
119*c87b03e5Sespie;; (define_function_unit {name} {num-units} {n-users} {test}
120*c87b03e5Sespie;;                       {ready-delay} {issue-delay} [{conflict-list}])
121*c87b03e5Sespie
122*c87b03e5Sespie;; 1) A conditional jump cannot immediately follow the insn setting the flags.
123*c87b03e5Sespie;; This isn't a complete solution as it doesn't come with guarantees.  That
124*c87b03e5Sespie;; is done in the branch patterns and in arc_print_operand.  This exists to
125*c87b03e5Sespie;; avoid inserting a nop when we can.
126*c87b03e5Sespie(define_function_unit "compare" 1 0 (eq_attr "type" "compare") 2 2 [(eq_attr "type" "branch")])
127*c87b03e5Sespie
128*c87b03e5Sespie;; 2) References to loaded registers should wait a cycle.
129*c87b03e5Sespie
130*c87b03e5Sespie;; Memory with load-delay of 1 (i.e., 2 cycle load).
131*c87b03e5Sespie(define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0)
132*c87b03e5Sespie
133*c87b03e5Sespie;; Units that take one cycle do not need to be specified.
134*c87b03e5Sespie
135*c87b03e5Sespie;; Move instructions.
136*c87b03e5Sespie
137*c87b03e5Sespie(define_expand "movqi"
138*c87b03e5Sespie  [(set (match_operand:QI 0 "general_operand" "")
139*c87b03e5Sespie	(match_operand:QI 1 "general_operand" ""))]
140*c87b03e5Sespie  ""
141*c87b03e5Sespie  "
142*c87b03e5Sespie{
143*c87b03e5Sespie  /* Everything except mem = const or mem = mem can be done easily.  */
144*c87b03e5Sespie
145*c87b03e5Sespie  if (GET_CODE (operands[0]) == MEM)
146*c87b03e5Sespie    operands[1] = force_reg (QImode, operands[1]);
147*c87b03e5Sespie}")
148*c87b03e5Sespie
149*c87b03e5Sespie(define_insn "*movqi_insn"
150*c87b03e5Sespie  [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,m")
151*c87b03e5Sespie	(match_operand:QI 1 "move_src_operand" "rI,Ji,m,r"))]
152*c87b03e5Sespie;; ??? Needed?
153*c87b03e5Sespie  "register_operand (operands[0], QImode)
154*c87b03e5Sespie   || register_operand (operands[1], QImode)"
155*c87b03e5Sespie  "@
156*c87b03e5Sespie   mov%? %0,%1
157*c87b03e5Sespie   mov%? %0,%1
158*c87b03e5Sespie   ldb%U1%V1 %0,%1
159*c87b03e5Sespie   stb%U0%V0 %1,%0"
160*c87b03e5Sespie  [(set_attr "type" "move,move,load,store")])
161*c87b03e5Sespie
162*c87b03e5Sespie;; ??? This may never match since there's no cmpqi insn.
163*c87b03e5Sespie
164*c87b03e5Sespie(define_insn "*movqi_set_cc_insn"
165*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
166*c87b03e5Sespie		       (sign_extend:SI (match_operand:QI 1 "move_src_operand" "rIJi"))
167*c87b03e5Sespie		       (const_int 0)))
168*c87b03e5Sespie   (set (match_operand:QI 0 "move_dest_operand" "=r")
169*c87b03e5Sespie	(match_dup 1))]
170*c87b03e5Sespie  ""
171*c87b03e5Sespie  "mov%?.f %0,%1"
172*c87b03e5Sespie  [(set_attr "type" "move")
173*c87b03e5Sespie   (set_attr "cond" "set_zn")])
174*c87b03e5Sespie
175*c87b03e5Sespie(define_expand "movhi"
176*c87b03e5Sespie  [(set (match_operand:HI 0 "general_operand" "")
177*c87b03e5Sespie	(match_operand:HI 1 "general_operand" ""))]
178*c87b03e5Sespie  ""
179*c87b03e5Sespie  "
180*c87b03e5Sespie{
181*c87b03e5Sespie  /* Everything except mem = const or mem = mem can be done easily.  */
182*c87b03e5Sespie
183*c87b03e5Sespie  if (GET_CODE (operands[0]) == MEM)
184*c87b03e5Sespie    operands[1] = force_reg (HImode, operands[1]);
185*c87b03e5Sespie}")
186*c87b03e5Sespie
187*c87b03e5Sespie(define_insn "*movhi_insn"
188*c87b03e5Sespie  [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,m")
189*c87b03e5Sespie	(match_operand:HI 1 "move_src_operand" "rI,Ji,m,r"))]
190*c87b03e5Sespie  "register_operand (operands[0], HImode)
191*c87b03e5Sespie   || register_operand (operands[1], HImode)"
192*c87b03e5Sespie  "@
193*c87b03e5Sespie   mov%? %0,%1
194*c87b03e5Sespie   mov%? %0,%1
195*c87b03e5Sespie   ldw%U1%V1 %0,%1
196*c87b03e5Sespie   stw%U0%V0 %1,%0"
197*c87b03e5Sespie  [(set_attr "type" "move,move,load,store")])
198*c87b03e5Sespie
199*c87b03e5Sespie;; ??? Will this ever match?
200*c87b03e5Sespie
201*c87b03e5Sespie(define_insn "*movhi_set_cc_insn"
202*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
203*c87b03e5Sespie		       (sign_extend:SI (match_operand:HI 1 "move_src_operand" "rIJi"))
204*c87b03e5Sespie		       (const_int 0)))
205*c87b03e5Sespie   (set (match_operand:HI 0 "move_dest_operand" "=r")
206*c87b03e5Sespie	(match_dup 1))]
207*c87b03e5Sespie;; ??? Needed?
208*c87b03e5Sespie  "register_operand (operands[0], HImode)
209*c87b03e5Sespie   || register_operand (operands[1], HImode)"
210*c87b03e5Sespie  "mov%?.f %0,%1"
211*c87b03e5Sespie  [(set_attr "type" "move")
212*c87b03e5Sespie   (set_attr "cond" "set_zn")])
213*c87b03e5Sespie
214*c87b03e5Sespie(define_expand "movsi"
215*c87b03e5Sespie  [(set (match_operand:SI 0 "general_operand" "")
216*c87b03e5Sespie	(match_operand:SI 1 "general_operand" ""))]
217*c87b03e5Sespie  ""
218*c87b03e5Sespie  "
219*c87b03e5Sespie{
220*c87b03e5Sespie  /* Everything except mem = const or mem = mem can be done easily.  */
221*c87b03e5Sespie
222*c87b03e5Sespie  if (GET_CODE (operands[0]) == MEM)
223*c87b03e5Sespie    operands[1] = force_reg (SImode, operands[1]);
224*c87b03e5Sespie}")
225*c87b03e5Sespie
226*c87b03e5Sespie(define_insn "*movsi_insn"
227*c87b03e5Sespie  [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,m")
228*c87b03e5Sespie	(match_operand:SI 1 "move_src_operand" "rI,GJi,m,r"))]
229*c87b03e5Sespie  "register_operand (operands[0], SImode)
230*c87b03e5Sespie   || register_operand (operands[1], SImode)"
231*c87b03e5Sespie  "@
232*c87b03e5Sespie   mov%? %0,%1
233*c87b03e5Sespie   mov%? %0,%S1
234*c87b03e5Sespie   ld%U1%V1 %0,%1
235*c87b03e5Sespie   st%U0%V0 %1,%0"
236*c87b03e5Sespie  [(set_attr "type" "move,move,load,store")])
237*c87b03e5Sespie
238*c87b03e5Sespie(define_insn "*movsi_set_cc_insn"
239*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
240*c87b03e5Sespie		       (match_operand:SI 1 "move_src_operand" "rIJi")
241*c87b03e5Sespie		       (const_int 0)))
242*c87b03e5Sespie   (set (match_operand:SI 0 "move_dest_operand" "=r")
243*c87b03e5Sespie	(match_dup 1))]
244*c87b03e5Sespie  "register_operand (operands[0], SImode)
245*c87b03e5Sespie   || register_operand (operands[1], SImode)"
246*c87b03e5Sespie  "mov%?.f %0,%S1"
247*c87b03e5Sespie  [(set_attr "type" "move")
248*c87b03e5Sespie   (set_attr "cond" "set_zn")])
249*c87b03e5Sespie
250*c87b03e5Sespie(define_expand "movdi"
251*c87b03e5Sespie  [(set (match_operand:DI 0 "general_operand" "")
252*c87b03e5Sespie	(match_operand:DI 1 "general_operand" ""))]
253*c87b03e5Sespie  ""
254*c87b03e5Sespie  "
255*c87b03e5Sespie{
256*c87b03e5Sespie  /* Everything except mem = const or mem = mem can be done easily.  */
257*c87b03e5Sespie
258*c87b03e5Sespie  if (GET_CODE (operands[0]) == MEM)
259*c87b03e5Sespie    operands[1] = force_reg (DImode, operands[1]);
260*c87b03e5Sespie}")
261*c87b03e5Sespie
262*c87b03e5Sespie(define_insn "*movdi_insn"
263*c87b03e5Sespie  [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,m")
264*c87b03e5Sespie	(match_operand:DI 1 "move_double_src_operand" "r,HK,m,r"))]
265*c87b03e5Sespie  "register_operand (operands[0], DImode)
266*c87b03e5Sespie   || register_operand (operands[1], DImode)"
267*c87b03e5Sespie  "*
268*c87b03e5Sespie{
269*c87b03e5Sespie  switch (which_alternative)
270*c87b03e5Sespie    {
271*c87b03e5Sespie    case 0 :
272*c87b03e5Sespie      /* We normally copy the low-numbered register first.  However, if
273*c87b03e5Sespie	 the first register operand 0 is the same as the second register of
274*c87b03e5Sespie	 operand 1, we must copy in the opposite order.  */
275*c87b03e5Sespie      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
276*c87b03e5Sespie	return \"mov %R0,%R1\;mov %0,%1\";
277*c87b03e5Sespie      else
278*c87b03e5Sespie	return \"mov %0,%1\;mov %R0,%R1\";
279*c87b03e5Sespie    case 1 :
280*c87b03e5Sespie      return \"mov %0,%L1\;mov %R0,%H1\";
281*c87b03e5Sespie    case 2 :
282*c87b03e5Sespie      /* If the low-address word is used in the address, we must load it
283*c87b03e5Sespie	 last.  Otherwise, load it first.  Note that we cannot have
284*c87b03e5Sespie	 auto-increment in that case since the address register is known to be
285*c87b03e5Sespie	 dead.  */
286*c87b03e5Sespie      if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
287*c87b03e5Sespie			     operands [1], 0))
288*c87b03e5Sespie	  return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
289*c87b03e5Sespie      else
290*c87b03e5Sespie	  return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
291*c87b03e5Sespie    case 3 :
292*c87b03e5Sespie      return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
293*c87b03e5Sespie    default:
294*c87b03e5Sespie      abort();
295*c87b03e5Sespie    }
296*c87b03e5Sespie}"
297*c87b03e5Sespie  [(set_attr "type" "move,move,load,store")
298*c87b03e5Sespie   ;; ??? The ld/st values could be 4 if it's [reg,bignum].
299*c87b03e5Sespie   (set_attr "length" "2,4,2,2")])
300*c87b03e5Sespie
301*c87b03e5Sespie;(define_expand "movdi"
302*c87b03e5Sespie;  [(set (match_operand:DI 0 "general_operand" "")
303*c87b03e5Sespie;	(match_operand:DI 1 "general_operand" ""))]
304*c87b03e5Sespie;  ""
305*c87b03e5Sespie;  "
306*c87b03e5Sespie;{
307*c87b03e5Sespie;  /* Flow doesn't understand that this is effectively a DFmode move.
308*c87b03e5Sespie;     It doesn't know that all of `operands[0]' is set.  */
309*c87b03e5Sespie;  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
310*c87b03e5Sespie;
311*c87b03e5Sespie;  /* Emit insns that movsi_insn can handle.  */
312*c87b03e5Sespie;  emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DImode),
313*c87b03e5Sespie;			operand_subword (operands[1], 0, 0, DImode)));
314*c87b03e5Sespie;  emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DImode),
315*c87b03e5Sespie;			operand_subword (operands[1], 1, 0, DImode)));
316*c87b03e5Sespie;  DONE;
317*c87b03e5Sespie;}")
318*c87b03e5Sespie
319*c87b03e5Sespie;; Floating point move insns.
320*c87b03e5Sespie
321*c87b03e5Sespie(define_expand "movsf"
322*c87b03e5Sespie  [(set (match_operand:SF 0 "general_operand" "")
323*c87b03e5Sespie	(match_operand:SF 1 "general_operand" ""))]
324*c87b03e5Sespie  ""
325*c87b03e5Sespie  "
326*c87b03e5Sespie{
327*c87b03e5Sespie  /* Everything except mem = const or mem = mem can be done easily.  */
328*c87b03e5Sespie  if (GET_CODE (operands[0]) == MEM)
329*c87b03e5Sespie    operands[1] = force_reg (SFmode, operands[1]);
330*c87b03e5Sespie}")
331*c87b03e5Sespie
332*c87b03e5Sespie(define_insn "*movsf_insn"
333*c87b03e5Sespie  [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
334*c87b03e5Sespie	(match_operand:SF 1 "move_src_operand" "r,E,m,r"))]
335*c87b03e5Sespie  "register_operand (operands[0], SFmode)
336*c87b03e5Sespie   || register_operand (operands[1], SFmode)"
337*c87b03e5Sespie  "@
338*c87b03e5Sespie   mov%? %0,%1
339*c87b03e5Sespie   mov%? %0,%1 ; %A1
340*c87b03e5Sespie   ld%U1%V1 %0,%1
341*c87b03e5Sespie   st%U0%V0 %1,%0"
342*c87b03e5Sespie  [(set_attr "type" "move,move,load,store")])
343*c87b03e5Sespie
344*c87b03e5Sespie(define_expand "movdf"
345*c87b03e5Sespie  [(set (match_operand:DF 0 "general_operand" "")
346*c87b03e5Sespie	(match_operand:DF 1 "general_operand" ""))]
347*c87b03e5Sespie  ""
348*c87b03e5Sespie  "
349*c87b03e5Sespie{
350*c87b03e5Sespie  /* Everything except mem = const or mem = mem can be done easily.  */
351*c87b03e5Sespie  if (GET_CODE (operands[0]) == MEM)
352*c87b03e5Sespie    operands[1] = force_reg (DFmode, operands[1]);
353*c87b03e5Sespie}")
354*c87b03e5Sespie
355*c87b03e5Sespie(define_insn "*movdf_insn"
356*c87b03e5Sespie  [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
357*c87b03e5Sespie	(match_operand:DF 1 "move_double_src_operand" "r,E,m,r"))]
358*c87b03e5Sespie  "register_operand (operands[0], DFmode)
359*c87b03e5Sespie   || register_operand (operands[1], DFmode)"
360*c87b03e5Sespie  "*
361*c87b03e5Sespie{
362*c87b03e5Sespie  switch (which_alternative)
363*c87b03e5Sespie    {
364*c87b03e5Sespie    case 0 :
365*c87b03e5Sespie      /* We normally copy the low-numbered register first.  However, if
366*c87b03e5Sespie	 the first register operand 0 is the same as the second register of
367*c87b03e5Sespie	 operand 1, we must copy in the opposite order.  */
368*c87b03e5Sespie      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
369*c87b03e5Sespie	return \"mov %R0,%R1\;mov %0,%1\";
370*c87b03e5Sespie      else
371*c87b03e5Sespie	return \"mov %0,%1\;mov %R0,%R1\";
372*c87b03e5Sespie    case 1 :
373*c87b03e5Sespie      return \"mov %0,%L1\;mov %R0,%H1 ; %A1\";
374*c87b03e5Sespie    case 2 :
375*c87b03e5Sespie      /* If the low-address word is used in the address, we must load it
376*c87b03e5Sespie	 last.  Otherwise, load it first.  Note that we cannot have
377*c87b03e5Sespie	 auto-increment in that case since the address register is known to be
378*c87b03e5Sespie	 dead.  */
379*c87b03e5Sespie      if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
380*c87b03e5Sespie			     operands [1], 0))
381*c87b03e5Sespie	return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
382*c87b03e5Sespie      else
383*c87b03e5Sespie	return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
384*c87b03e5Sespie    case 3 :
385*c87b03e5Sespie      return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
386*c87b03e5Sespie    default:
387*c87b03e5Sespie      abort();
388*c87b03e5Sespie    }
389*c87b03e5Sespie}"
390*c87b03e5Sespie  [(set_attr "type" "move,move,load,store")
391*c87b03e5Sespie   ;; ??? The ld/st values could be 4 if it's [reg,bignum].
392*c87b03e5Sespie   (set_attr "length" "2,4,2,2")])
393*c87b03e5Sespie
394*c87b03e5Sespie;(define_expand "movdf"
395*c87b03e5Sespie;  [(set (match_operand:DF 0 "general_operand" "")
396*c87b03e5Sespie;	(match_operand:DF 1 "general_operand" ""))]
397*c87b03e5Sespie;  ""
398*c87b03e5Sespie;  "
399*c87b03e5Sespie;{
400*c87b03e5Sespie;  /* Flow doesn't understand that this is effectively a DFmode move.
401*c87b03e5Sespie;     It doesn't know that all of `operands[0]' is set.  */
402*c87b03e5Sespie;  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
403*c87b03e5Sespie;
404*c87b03e5Sespie;  /* Emit insns that movsi_insn can handle.  */
405*c87b03e5Sespie;  emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DFmode),
406*c87b03e5Sespie;			operand_subword (operands[1], 0, 0, DFmode)));
407*c87b03e5Sespie;  emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DFmode),
408*c87b03e5Sespie;			operand_subword (operands[1], 1, 0, DFmode)));
409*c87b03e5Sespie;  DONE;
410*c87b03e5Sespie;}")
411*c87b03e5Sespie
412*c87b03e5Sespie;; Load/Store with update instructions.
413*c87b03e5Sespie;;
414*c87b03e5Sespie;; Some of these we can get by using pre-decrement or pre-increment, but the
415*c87b03e5Sespie;; hardware can also do cases where the increment is not the size of the
416*c87b03e5Sespie;; object.
417*c87b03e5Sespie;;
418*c87b03e5Sespie;; In all these cases, we use operands 0 and 1 for the register being
419*c87b03e5Sespie;; incremented because those are the operands that local-alloc will
420*c87b03e5Sespie;; tie and these are the pair most likely to be tieable (and the ones
421*c87b03e5Sespie;; that will benefit the most).
422*c87b03e5Sespie;;
423*c87b03e5Sespie;; We use match_operator here because we need to know whether the memory
424*c87b03e5Sespie;; object is volatile or not.
425*c87b03e5Sespie
426*c87b03e5Sespie(define_insn "*loadqi_update"
427*c87b03e5Sespie  [(set (match_operand:QI 3 "register_operand" "=r,r")
428*c87b03e5Sespie	(match_operator:QI 4 "load_update_operand"
429*c87b03e5Sespie	 [(match_operand:SI 1 "register_operand" "0,0")
430*c87b03e5Sespie	  (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
431*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r,r")
432*c87b03e5Sespie	(plus:SI (match_dup 1) (match_dup 2)))]
433*c87b03e5Sespie  ""
434*c87b03e5Sespie  "ldb.a%V4 %3,[%0,%2]"
435*c87b03e5Sespie  [(set_attr "type" "load,load")
436*c87b03e5Sespie   (set_attr "length" "1,2")])
437*c87b03e5Sespie
438*c87b03e5Sespie(define_insn "*load_zeroextendqisi_update"
439*c87b03e5Sespie  [(set (match_operand:SI 3 "register_operand" "=r,r")
440*c87b03e5Sespie	(zero_extend:SI (match_operator:QI 4 "load_update_operand"
441*c87b03e5Sespie			 [(match_operand:SI 1 "register_operand" "0,0")
442*c87b03e5Sespie			  (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
443*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r,r")
444*c87b03e5Sespie	(plus:SI (match_dup 1) (match_dup 2)))]
445*c87b03e5Sespie  ""
446*c87b03e5Sespie  "ldb.a%V4 %3,[%0,%2]"
447*c87b03e5Sespie  [(set_attr "type" "load,load")
448*c87b03e5Sespie   (set_attr "length" "1,2")])
449*c87b03e5Sespie
450*c87b03e5Sespie(define_insn "*load_signextendqisi_update"
451*c87b03e5Sespie  [(set (match_operand:SI 3 "register_operand" "=r,r")
452*c87b03e5Sespie	(sign_extend:SI (match_operator:QI 4 "load_update_operand"
453*c87b03e5Sespie			 [(match_operand:SI 1 "register_operand" "0,0")
454*c87b03e5Sespie			  (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
455*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r,r")
456*c87b03e5Sespie	(plus:SI (match_dup 1) (match_dup 2)))]
457*c87b03e5Sespie  ""
458*c87b03e5Sespie  "ldb.x.a%V4 %3,[%0,%2]"
459*c87b03e5Sespie  [(set_attr "type" "load,load")
460*c87b03e5Sespie   (set_attr "length" "1,2")])
461*c87b03e5Sespie
462*c87b03e5Sespie(define_insn "*storeqi_update"
463*c87b03e5Sespie  [(set (match_operator:QI 4 "store_update_operand"
464*c87b03e5Sespie	 [(match_operand:SI 1 "register_operand" "0")
465*c87b03e5Sespie	  (match_operand:SI 2 "short_immediate_operand" "I")])
466*c87b03e5Sespie	(match_operand:QI 3 "register_operand" "r"))
467*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
468*c87b03e5Sespie	(plus:SI (match_dup 1) (match_dup 2)))]
469*c87b03e5Sespie  ""
470*c87b03e5Sespie  "stb.a%V4 %3,[%0,%2]"
471*c87b03e5Sespie  [(set_attr "type" "store")
472*c87b03e5Sespie   (set_attr "length" "1")])
473*c87b03e5Sespie
474*c87b03e5Sespie(define_insn "*loadhi_update"
475*c87b03e5Sespie  [(set (match_operand:HI 3 "register_operand" "=r,r")
476*c87b03e5Sespie	(match_operator:HI 4 "load_update_operand"
477*c87b03e5Sespie	 [(match_operand:SI 1 "register_operand" "0,0")
478*c87b03e5Sespie	  (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
479*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r,r")
480*c87b03e5Sespie	(plus:SI (match_dup 1) (match_dup 2)))]
481*c87b03e5Sespie  ""
482*c87b03e5Sespie  "ldw.a%V4 %3,[%0,%2]"
483*c87b03e5Sespie  [(set_attr "type" "load,load")
484*c87b03e5Sespie   (set_attr "length" "1,2")])
485*c87b03e5Sespie
486*c87b03e5Sespie(define_insn "*load_zeroextendhisi_update"
487*c87b03e5Sespie  [(set (match_operand:SI 3 "register_operand" "=r,r")
488*c87b03e5Sespie	(zero_extend:SI (match_operator:HI 4 "load_update_operand"
489*c87b03e5Sespie			 [(match_operand:SI 1 "register_operand" "0,0")
490*c87b03e5Sespie			  (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
491*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r,r")
492*c87b03e5Sespie	(plus:SI (match_dup 1) (match_dup 2)))]
493*c87b03e5Sespie  ""
494*c87b03e5Sespie  "ldw.a%V4 %3,[%0,%2]"
495*c87b03e5Sespie  [(set_attr "type" "load,load")
496*c87b03e5Sespie   (set_attr "length" "1,2")])
497*c87b03e5Sespie
498*c87b03e5Sespie(define_insn "*load_signextendhisi_update"
499*c87b03e5Sespie  [(set (match_operand:SI 3 "register_operand" "=r,r")
500*c87b03e5Sespie	(sign_extend:SI (match_operator:HI 4 "load_update_operand"
501*c87b03e5Sespie			 [(match_operand:SI 1 "register_operand" "0,0")
502*c87b03e5Sespie			  (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
503*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r,r")
504*c87b03e5Sespie	(plus:SI (match_dup 1) (match_dup 2)))]
505*c87b03e5Sespie  ""
506*c87b03e5Sespie  "ldw.x.a%V4 %3,[%0,%2]"
507*c87b03e5Sespie  [(set_attr "type" "load,load")
508*c87b03e5Sespie   (set_attr "length" "1,2")])
509*c87b03e5Sespie
510*c87b03e5Sespie(define_insn "*storehi_update"
511*c87b03e5Sespie  [(set (match_operator:HI 4 "store_update_operand"
512*c87b03e5Sespie	 [(match_operand:SI 1 "register_operand" "0")
513*c87b03e5Sespie	  (match_operand:SI 2 "short_immediate_operand" "I")])
514*c87b03e5Sespie	(match_operand:HI 3 "register_operand" "r"))
515*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
516*c87b03e5Sespie	(plus:SI (match_dup 1) (match_dup 2)))]
517*c87b03e5Sespie  ""
518*c87b03e5Sespie  "stw.a%V4 %3,[%0,%2]"
519*c87b03e5Sespie  [(set_attr "type" "store")
520*c87b03e5Sespie   (set_attr "length" "1")])
521*c87b03e5Sespie
522*c87b03e5Sespie(define_insn "*loadsi_update"
523*c87b03e5Sespie  [(set (match_operand:SI 3 "register_operand" "=r,r")
524*c87b03e5Sespie	(match_operator:SI 4 "load_update_operand"
525*c87b03e5Sespie	 [(match_operand:SI 1 "register_operand" "0,0")
526*c87b03e5Sespie	  (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
527*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r,r")
528*c87b03e5Sespie	(plus:SI (match_dup 1) (match_dup 2)))]
529*c87b03e5Sespie  ""
530*c87b03e5Sespie  "ld.a%V4 %3,[%0,%2]"
531*c87b03e5Sespie  [(set_attr "type" "load,load")
532*c87b03e5Sespie   (set_attr "length" "1,2")])
533*c87b03e5Sespie
534*c87b03e5Sespie(define_insn "*storesi_update"
535*c87b03e5Sespie  [(set (match_operator:SI 4 "store_update_operand"
536*c87b03e5Sespie	 [(match_operand:SI 1 "register_operand" "0")
537*c87b03e5Sespie	  (match_operand:SI 2 "short_immediate_operand" "I")])
538*c87b03e5Sespie	(match_operand:SI 3 "register_operand" "r"))
539*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
540*c87b03e5Sespie	(plus:SI (match_dup 1) (match_dup 2)))]
541*c87b03e5Sespie  ""
542*c87b03e5Sespie  "st.a%V4 %3,[%0,%2]"
543*c87b03e5Sespie  [(set_attr "type" "store")
544*c87b03e5Sespie   (set_attr "length" "1")])
545*c87b03e5Sespie
546*c87b03e5Sespie(define_insn "*loadsf_update"
547*c87b03e5Sespie  [(set (match_operand:SF 3 "register_operand" "=r,r")
548*c87b03e5Sespie	(match_operator:SF 4 "load_update_operand"
549*c87b03e5Sespie	 [(match_operand:SI 1 "register_operand" "0,0")
550*c87b03e5Sespie	  (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
551*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r,r")
552*c87b03e5Sespie	(plus:SI (match_dup 1) (match_dup 2)))]
553*c87b03e5Sespie  ""
554*c87b03e5Sespie  "ld.a%V4 %3,[%0,%2]"
555*c87b03e5Sespie  [(set_attr "type" "load,load")
556*c87b03e5Sespie   (set_attr "length" "1,2")])
557*c87b03e5Sespie
558*c87b03e5Sespie(define_insn "*storesf_update"
559*c87b03e5Sespie  [(set (match_operator:SF 4 "store_update_operand"
560*c87b03e5Sespie	 [(match_operand:SI 1 "register_operand" "0")
561*c87b03e5Sespie	  (match_operand:SI 2 "short_immediate_operand" "I")])
562*c87b03e5Sespie	(match_operand:SF 3 "register_operand" "r"))
563*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
564*c87b03e5Sespie	(plus:SI (match_dup 1) (match_dup 2)))]
565*c87b03e5Sespie  ""
566*c87b03e5Sespie  "st.a%V4 %3,[%0,%2]"
567*c87b03e5Sespie  [(set_attr "type" "store")
568*c87b03e5Sespie   (set_attr "length" "1")])
569*c87b03e5Sespie
570*c87b03e5Sespie;; Conditional move instructions.
571*c87b03e5Sespie
572*c87b03e5Sespie(define_expand "movsicc"
573*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "")
574*c87b03e5Sespie	(if_then_else:SI (match_operand 1 "comparison_operator" "")
575*c87b03e5Sespie			 (match_operand:SI 2 "nonmemory_operand" "")
576*c87b03e5Sespie			 (match_operand:SI 3 "register_operand" "")))]
577*c87b03e5Sespie  ""
578*c87b03e5Sespie  "
579*c87b03e5Sespie{
580*c87b03e5Sespie  enum rtx_code code = GET_CODE (operands[1]);
581*c87b03e5Sespie  rtx ccreg
582*c87b03e5Sespie    = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
583*c87b03e5Sespie		   61);
584*c87b03e5Sespie
585*c87b03e5Sespie  operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
586*c87b03e5Sespie}")
587*c87b03e5Sespie
588*c87b03e5Sespie;(define_expand "movdicc"
589*c87b03e5Sespie;  [(set (match_operand:DI 0 "register_operand" "")
590*c87b03e5Sespie;	(if_then_else:DI (match_operand 1 "comparison_operator" "")
591*c87b03e5Sespie;			 (match_operand:DI 2 "nonmemory_operand" "")
592*c87b03e5Sespie;			 (match_operand:DI 3 "register_operand" "")))]
593*c87b03e5Sespie;  "0 /* ??? this would work better if we had cmpdi */"
594*c87b03e5Sespie;  "
595*c87b03e5Sespie;{
596*c87b03e5Sespie;  enum rtx_code code = GET_CODE (operands[1]);
597*c87b03e5Sespie;  rtx ccreg
598*c87b03e5Sespie;   = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
599*c87b03e5Sespie;		   61);
600*c87b03e5Sespie;
601*c87b03e5Sespie;  operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
602*c87b03e5Sespie;}")
603*c87b03e5Sespie
604*c87b03e5Sespie(define_expand "movsfcc"
605*c87b03e5Sespie  [(set (match_operand:SF 0 "register_operand" "")
606*c87b03e5Sespie	(if_then_else:SF (match_operand 1 "comparison_operator" "")
607*c87b03e5Sespie			 (match_operand:SF 2 "nonmemory_operand" "")
608*c87b03e5Sespie			 (match_operand:SF 3 "register_operand" "")))]
609*c87b03e5Sespie  ""
610*c87b03e5Sespie  "
611*c87b03e5Sespie{
612*c87b03e5Sespie  enum rtx_code code = GET_CODE (operands[1]);
613*c87b03e5Sespie  rtx ccreg
614*c87b03e5Sespie    = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
615*c87b03e5Sespie		   61);
616*c87b03e5Sespie
617*c87b03e5Sespie  operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
618*c87b03e5Sespie}")
619*c87b03e5Sespie
620*c87b03e5Sespie;(define_expand "movdfcc"
621*c87b03e5Sespie;  [(set (match_operand:DF 0 "register_operand" "")
622*c87b03e5Sespie;	(if_then_else:DF (match_operand 1 "comparison_operator" "")
623*c87b03e5Sespie;			 (match_operand:DF 2 "nonmemory_operand" "")
624*c87b03e5Sespie;			 (match_operand:DF 3 "register_operand" "")))]
625*c87b03e5Sespie;  "0 /* ??? can generate less efficient code if constants involved */"
626*c87b03e5Sespie;  "
627*c87b03e5Sespie;{
628*c87b03e5Sespie; enum rtx_code code = GET_CODE (operands[1]);
629*c87b03e5Sespie; rtx ccreg
630*c87b03e5Sespie;   = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
631*c87b03e5Sespie;		   61);
632*c87b03e5Sespie;
633*c87b03e5Sespie;  operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
634*c87b03e5Sespie;}")
635*c87b03e5Sespie
636*c87b03e5Sespie(define_insn "*movsicc_insn"
637*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
638*c87b03e5Sespie	(if_then_else:SI (match_operand 1 "comparison_operator" "")
639*c87b03e5Sespie			 (match_operand:SI 2 "nonmemory_operand" "rJi")
640*c87b03e5Sespie			 (match_operand:SI 3 "register_operand" "0")))]
641*c87b03e5Sespie  ""
642*c87b03e5Sespie  "mov.%d1 %0,%S2"
643*c87b03e5Sespie  [(set_attr "type" "cmove")])
644*c87b03e5Sespie
645*c87b03e5Sespie; ??? This doesn't properly handle constants.
646*c87b03e5Sespie;(define_insn "*movdicc_insn"
647*c87b03e5Sespie;  [(set (match_operand:DI 0 "register_operand" "=r,r")
648*c87b03e5Sespie;	(if_then_else:DI (match_operand 1 "comparison_operator" "")
649*c87b03e5Sespie;			 (match_operand:DI 2 "nonmemory_operand" "r,Ji")
650*c87b03e5Sespie;			 (match_operand:DI 3 "register_operand" "0,0")))]
651*c87b03e5Sespie;  "0"
652*c87b03e5Sespie;  "*
653*c87b03e5Sespie;{
654*c87b03e5Sespie;  switch (which_alternative)
655*c87b03e5Sespie;    {
656*c87b03e5Sespie;    case 0 :
657*c87b03e5Sespie;      /* We normally copy the low-numbered register first.  However, if
658*c87b03e5Sespie;	 the first register operand 0 is the same as the second register of
659*c87b03e5Sespie;	 operand 1, we must copy in the opposite order.  */
660*c87b03e5Sespie;      if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
661*c87b03e5Sespie;	return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
662*c87b03e5Sespie;      else
663*c87b03e5Sespie;	return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
664*c87b03e5Sespie;    case 1 :
665*c87b03e5Sespie;      return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
666*c87b03e5Sespie;    }
667*c87b03e5Sespie;}"
668*c87b03e5Sespie;  [(set_attr "type" "cmove,cmove")
669*c87b03e5Sespie;   (set_attr "length" "2,4")])
670*c87b03e5Sespie
671*c87b03e5Sespie(define_insn "*movsfcc_insn"
672*c87b03e5Sespie  [(set (match_operand:SF 0 "register_operand" "=r,r")
673*c87b03e5Sespie	(if_then_else:SF (match_operand 1 "comparison_operator" "")
674*c87b03e5Sespie			 (match_operand:SF 2 "nonmemory_operand" "r,E")
675*c87b03e5Sespie			 (match_operand:SF 3 "register_operand" "0,0")))]
676*c87b03e5Sespie  ""
677*c87b03e5Sespie  "@
678*c87b03e5Sespie   mov.%d1 %0,%2
679*c87b03e5Sespie   mov.%d1 %0,%2 ; %A2"
680*c87b03e5Sespie  [(set_attr "type" "cmove,cmove")])
681*c87b03e5Sespie
682*c87b03e5Sespie;(define_insn "*movdfcc_insn"
683*c87b03e5Sespie;  [(set (match_operand:DF 0 "register_operand" "=r,r")
684*c87b03e5Sespie;	(if_then_else:DF (match_operand 1 "comparison_operator" "")
685*c87b03e5Sespie;			 (match_operand:DF 2 "nonmemory_operand" "r,E")
686*c87b03e5Sespie;			 (match_operand:DF 3 "register_operand" "0,0")))]
687*c87b03e5Sespie;  "0"
688*c87b03e5Sespie;  "*
689*c87b03e5Sespie;{
690*c87b03e5Sespie;  switch (which_alternative)
691*c87b03e5Sespie;    {
692*c87b03e5Sespie;    case 0 :
693*c87b03e5Sespie;      /* We normally copy the low-numbered register first.  However, if
694*c87b03e5Sespie;	 the first register operand 0 is the same as the second register of
695*c87b03e5Sespie;	 operand 1, we must copy in the opposite order.  */
696*c87b03e5Sespie;      if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
697*c87b03e5Sespie;	return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
698*c87b03e5Sespie;      else
699*c87b03e5Sespie;	return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
700*c87b03e5Sespie;    case 1 :
701*c87b03e5Sespie;      return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\";
702*c87b03e5Sespie;    }
703*c87b03e5Sespie;}"
704*c87b03e5Sespie;  [(set_attr "type" "cmove,cmove")
705*c87b03e5Sespie;   (set_attr "length" "2,4")])
706*c87b03e5Sespie
707*c87b03e5Sespie;; Zero extension instructions.
708*c87b03e5Sespie;; ??? We don't support volatile memrefs here, but I'm not sure why.
709*c87b03e5Sespie
710*c87b03e5Sespie(define_insn "zero_extendqihi2"
711*c87b03e5Sespie  [(set (match_operand:HI 0 "register_operand" "=r,r")
712*c87b03e5Sespie	(zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
713*c87b03e5Sespie  ""
714*c87b03e5Sespie  "@
715*c87b03e5Sespie   extb%? %0,%1
716*c87b03e5Sespie   ldb%U1 %0,%1"
717*c87b03e5Sespie  [(set_attr "type" "unary,load")])
718*c87b03e5Sespie
719*c87b03e5Sespie(define_insn "*zero_extendqihi2_set_cc_insn"
720*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
721*c87b03e5Sespie		       (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
722*c87b03e5Sespie		       (const_int 0)))
723*c87b03e5Sespie   (set (match_operand:HI 0 "register_operand" "=r")
724*c87b03e5Sespie	(zero_extend:HI (match_dup 1)))]
725*c87b03e5Sespie  ""
726*c87b03e5Sespie  "extb%?.f %0,%1"
727*c87b03e5Sespie  [(set_attr "type" "unary")
728*c87b03e5Sespie   (set_attr "cond" "set_zn")])
729*c87b03e5Sespie
730*c87b03e5Sespie(define_insn "zero_extendqisi2"
731*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r,r")
732*c87b03e5Sespie	(zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
733*c87b03e5Sespie  ""
734*c87b03e5Sespie  "@
735*c87b03e5Sespie   extb%? %0,%1
736*c87b03e5Sespie   ldb%U1 %0,%1"
737*c87b03e5Sespie  [(set_attr "type" "unary,load")])
738*c87b03e5Sespie
739*c87b03e5Sespie(define_insn "*zero_extendqisi2_set_cc_insn"
740*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
741*c87b03e5Sespie		       (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
742*c87b03e5Sespie		       (const_int 0)))
743*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
744*c87b03e5Sespie	(zero_extend:SI (match_dup 1)))]
745*c87b03e5Sespie  ""
746*c87b03e5Sespie  "extb%?.f %0,%1"
747*c87b03e5Sespie  [(set_attr "type" "unary")
748*c87b03e5Sespie   (set_attr "cond" "set_zn")])
749*c87b03e5Sespie
750*c87b03e5Sespie(define_insn "zero_extendhisi2"
751*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r,r")
752*c87b03e5Sespie	(zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
753*c87b03e5Sespie  ""
754*c87b03e5Sespie  "@
755*c87b03e5Sespie   extw%? %0,%1
756*c87b03e5Sespie   ldw%U1 %0,%1"
757*c87b03e5Sespie  [(set_attr "type" "unary,load")])
758*c87b03e5Sespie
759*c87b03e5Sespie(define_insn "*zero_extendhisi2_set_cc_insn"
760*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
761*c87b03e5Sespie		       (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
762*c87b03e5Sespie		       (const_int 0)))
763*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
764*c87b03e5Sespie	(zero_extend:SI (match_dup 1)))]
765*c87b03e5Sespie  ""
766*c87b03e5Sespie  "extw%?.f %0,%1"
767*c87b03e5Sespie  [(set_attr "type" "unary")
768*c87b03e5Sespie   (set_attr "cond" "set_zn")])
769*c87b03e5Sespie
770*c87b03e5Sespie;; Sign extension instructions.
771*c87b03e5Sespie
772*c87b03e5Sespie(define_insn "extendqihi2"
773*c87b03e5Sespie  [(set (match_operand:HI 0 "register_operand" "=r,r")
774*c87b03e5Sespie	(sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
775*c87b03e5Sespie  ""
776*c87b03e5Sespie  "@
777*c87b03e5Sespie   sexb%? %0,%1
778*c87b03e5Sespie   ldb.x%U1 %0,%1"
779*c87b03e5Sespie  [(set_attr "type" "unary,load")])
780*c87b03e5Sespie
781*c87b03e5Sespie(define_insn "*extendqihi2_set_cc_insn"
782*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
783*c87b03e5Sespie		       (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
784*c87b03e5Sespie		       (const_int 0)))
785*c87b03e5Sespie   (set (match_operand:HI 0 "register_operand" "=r")
786*c87b03e5Sespie	(sign_extend:HI (match_dup 1)))]
787*c87b03e5Sespie  ""
788*c87b03e5Sespie  "sexb%?.f %0,%1"
789*c87b03e5Sespie  [(set_attr "type" "unary")
790*c87b03e5Sespie   (set_attr "cond" "set_zn")])
791*c87b03e5Sespie
792*c87b03e5Sespie(define_insn "extendqisi2"
793*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r,r")
794*c87b03e5Sespie	(sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
795*c87b03e5Sespie  ""
796*c87b03e5Sespie  "@
797*c87b03e5Sespie   sexb%? %0,%1
798*c87b03e5Sespie   ldb.x%U1 %0,%1"
799*c87b03e5Sespie  [(set_attr "type" "unary,load")])
800*c87b03e5Sespie
801*c87b03e5Sespie(define_insn "*extendqisi2_set_cc_insn"
802*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
803*c87b03e5Sespie		       (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
804*c87b03e5Sespie		       (const_int 0)))
805*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
806*c87b03e5Sespie	(sign_extend:SI (match_dup 1)))]
807*c87b03e5Sespie  ""
808*c87b03e5Sespie  "sexb%?.f %0,%1"
809*c87b03e5Sespie  [(set_attr "type" "unary")
810*c87b03e5Sespie   (set_attr "cond" "set_zn")])
811*c87b03e5Sespie
812*c87b03e5Sespie(define_insn "extendhisi2"
813*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r,r")
814*c87b03e5Sespie	(sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
815*c87b03e5Sespie  ""
816*c87b03e5Sespie  "@
817*c87b03e5Sespie   sexw%? %0,%1
818*c87b03e5Sespie   ldw.x%U1 %0,%1"
819*c87b03e5Sespie  [(set_attr "type" "unary,load")])
820*c87b03e5Sespie
821*c87b03e5Sespie(define_insn "*extendhisi2_set_cc_insn"
822*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
823*c87b03e5Sespie		       (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
824*c87b03e5Sespie		       (const_int 0)))
825*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
826*c87b03e5Sespie	(sign_extend:SI (match_dup 1)))]
827*c87b03e5Sespie  ""
828*c87b03e5Sespie  "sexw%?.f %0,%1"
829*c87b03e5Sespie  [(set_attr "type" "unary")
830*c87b03e5Sespie   (set_attr "cond" "set_zn")])
831*c87b03e5Sespie
832*c87b03e5Sespie;; Arithmetic instructions.
833*c87b03e5Sespie
834*c87b03e5Sespie(define_insn "addsi3"
835*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
836*c87b03e5Sespie	(plus:SI (match_operand:SI 1 "register_operand" "%r")
837*c87b03e5Sespie		 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
838*c87b03e5Sespie  ""
839*c87b03e5Sespie  "add%? %0,%1,%2")
840*c87b03e5Sespie
841*c87b03e5Sespie(define_insn "*addsi3_set_cc_insn"
842*c87b03e5Sespie  [(set (reg:CC 61) (compare:CC
843*c87b03e5Sespie		     (plus:SI (match_operand:SI 1 "register_operand" "%r")
844*c87b03e5Sespie			      (match_operand:SI 2 "nonmemory_operand" "rIJ"))
845*c87b03e5Sespie		     (const_int 0)))
846*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
847*c87b03e5Sespie	(plus:SI (match_dup 1)
848*c87b03e5Sespie		 (match_dup 2)))]
849*c87b03e5Sespie  ""
850*c87b03e5Sespie  "add%?.f %0,%1,%2"
851*c87b03e5Sespie  [(set_attr "cond" "set")])
852*c87b03e5Sespie
853*c87b03e5Sespie(define_insn "adddi3"
854*c87b03e5Sespie  [(set (match_operand:DI 0 "register_operand" "=r")
855*c87b03e5Sespie	(plus:DI (match_operand:DI 1 "nonmemory_operand" "%r")
856*c87b03e5Sespie		 (match_operand:DI 2 "nonmemory_operand" "ri")))
857*c87b03e5Sespie   (clobber (reg:CC 61))]
858*c87b03e5Sespie  ""
859*c87b03e5Sespie  "*
860*c87b03e5Sespie{
861*c87b03e5Sespie  rtx op2 = operands[2];
862*c87b03e5Sespie
863*c87b03e5Sespie  if (GET_CODE (op2) == CONST_INT)
864*c87b03e5Sespie    {
865*c87b03e5Sespie      int sign = INTVAL (op2);
866*c87b03e5Sespie      if (sign < 0)
867*c87b03e5Sespie	return \"add.f %L0,%L1,%2\;adc %H0,%H1,-1\";
868*c87b03e5Sespie      else
869*c87b03e5Sespie	return \"add.f %L0,%L1,%2\;adc %H0,%H1,0\";
870*c87b03e5Sespie    }
871*c87b03e5Sespie  else
872*c87b03e5Sespie    return \"add.f %L0,%L1,%L2\;adc %H0,%H1,%H2\";
873*c87b03e5Sespie}"
874*c87b03e5Sespie  [(set_attr "length" "2")])
875*c87b03e5Sespie
876*c87b03e5Sespie(define_insn "subsi3"
877*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
878*c87b03e5Sespie	(minus:SI (match_operand:SI 1 "register_operand" "r")
879*c87b03e5Sespie		  (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
880*c87b03e5Sespie  ""
881*c87b03e5Sespie  "sub%? %0,%1,%2")
882*c87b03e5Sespie
883*c87b03e5Sespie(define_insn "*subsi3_set_cc_insn"
884*c87b03e5Sespie  [(set (reg:CC 61) (compare:CC
885*c87b03e5Sespie		     (minus:SI (match_operand:SI 1 "register_operand" "%r")
886*c87b03e5Sespie			       (match_operand:SI 2 "nonmemory_operand" "rIJ"))
887*c87b03e5Sespie		     (const_int 0)))
888*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
889*c87b03e5Sespie	(minus:SI (match_dup 1)
890*c87b03e5Sespie		  (match_dup 2)))]
891*c87b03e5Sespie  ""
892*c87b03e5Sespie  "sub%?.f %0,%1,%2"
893*c87b03e5Sespie  [(set_attr "cond" "set")])
894*c87b03e5Sespie
895*c87b03e5Sespie(define_insn "subdi3"
896*c87b03e5Sespie  [(set (match_operand:DI 0 "register_operand" "=r")
897*c87b03e5Sespie	(minus:DI (match_operand:DI 1 "nonmemory_operand" "r")
898*c87b03e5Sespie		  (match_operand:DI 2 "nonmemory_operand" "ri")))
899*c87b03e5Sespie   (clobber (reg:CC 61))]
900*c87b03e5Sespie  ""
901*c87b03e5Sespie  "*
902*c87b03e5Sespie{
903*c87b03e5Sespie  rtx op2 = operands[2];
904*c87b03e5Sespie
905*c87b03e5Sespie  if (GET_CODE (op2) == CONST_INT)
906*c87b03e5Sespie    {
907*c87b03e5Sespie      int sign = INTVAL (op2);
908*c87b03e5Sespie      if (sign < 0)
909*c87b03e5Sespie	return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,-1\";
910*c87b03e5Sespie      else
911*c87b03e5Sespie	return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,0\";
912*c87b03e5Sespie    }
913*c87b03e5Sespie  else
914*c87b03e5Sespie    return \"sub.f %L0,%L1,%L2\;sbc %H0,%H1,%H2\";
915*c87b03e5Sespie}"
916*c87b03e5Sespie  [(set_attr "length" "2")])
917*c87b03e5Sespie
918*c87b03e5Sespie;; Boolean instructions.
919*c87b03e5Sespie;;
920*c87b03e5Sespie;; We don't define the DImode versions as expand_binop does a good enough job.
921*c87b03e5Sespie
922*c87b03e5Sespie(define_insn "andsi3"
923*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
924*c87b03e5Sespie	(and:SI (match_operand:SI 1 "register_operand" "%r")
925*c87b03e5Sespie		(match_operand:SI 2 "nonmemory_operand" "rIJ")))]
926*c87b03e5Sespie  ""
927*c87b03e5Sespie  "and%? %0,%1,%2")
928*c87b03e5Sespie
929*c87b03e5Sespie(define_insn "*andsi3_set_cc_insn"
930*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
931*c87b03e5Sespie		       (and:SI (match_operand:SI 1 "register_operand" "%r")
932*c87b03e5Sespie			       (match_operand:SI 2 "nonmemory_operand" "rIJ"))
933*c87b03e5Sespie		       (const_int 0)))
934*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
935*c87b03e5Sespie	(and:SI (match_dup 1)
936*c87b03e5Sespie		(match_dup 2)))]
937*c87b03e5Sespie  ""
938*c87b03e5Sespie  "and%?.f %0,%1,%2"
939*c87b03e5Sespie  [(set_attr "cond" "set_zn")])
940*c87b03e5Sespie
941*c87b03e5Sespie(define_insn "*bicsi3_insn"
942*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
943*c87b03e5Sespie	(and:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
944*c87b03e5Sespie		(not:SI (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r"))))]
945*c87b03e5Sespie  ""
946*c87b03e5Sespie  "bic%? %0,%1,%2"
947*c87b03e5Sespie  [(set_attr "length" "1,2,1,2")])
948*c87b03e5Sespie
949*c87b03e5Sespie(define_insn "*bicsi3_set_cc_insn"
950*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
951*c87b03e5Sespie		       (and:SI (match_operand:SI 1 "register_operand" "%r")
952*c87b03e5Sespie			       (not:SI (match_operand:SI 2 "nonmemory_operand" "rIJ")))
953*c87b03e5Sespie		       (const_int 0)))
954*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
955*c87b03e5Sespie	(and:SI (match_dup 1)
956*c87b03e5Sespie		(not:SI (match_dup 2))))]
957*c87b03e5Sespie  ""
958*c87b03e5Sespie  "bic%?.f %0,%1,%2"
959*c87b03e5Sespie  [(set_attr "cond" "set_zn")])
960*c87b03e5Sespie
961*c87b03e5Sespie(define_insn "iorsi3"
962*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
963*c87b03e5Sespie	(ior:SI (match_operand:SI 1 "register_operand" "%r")
964*c87b03e5Sespie		(match_operand:SI 2 "nonmemory_operand" "rIJ")))]
965*c87b03e5Sespie  ""
966*c87b03e5Sespie  "or%? %0,%1,%2")
967*c87b03e5Sespie
968*c87b03e5Sespie(define_insn "*iorsi3_set_cc_insn"
969*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
970*c87b03e5Sespie		       (ior:SI (match_operand:SI 1 "register_operand" "%r")
971*c87b03e5Sespie			       (match_operand:SI 2 "nonmemory_operand" "rIJ"))
972*c87b03e5Sespie		       (const_int 0)))
973*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
974*c87b03e5Sespie	(ior:SI (match_dup 1)
975*c87b03e5Sespie		(match_dup 2)))]
976*c87b03e5Sespie  ""
977*c87b03e5Sespie  "or%?.f %0,%1,%2"
978*c87b03e5Sespie  [(set_attr "cond" "set_zn")])
979*c87b03e5Sespie
980*c87b03e5Sespie(define_insn "xorsi3"
981*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
982*c87b03e5Sespie	(xor:SI (match_operand:SI 1 "register_operand" "%r")
983*c87b03e5Sespie		(match_operand:SI 2 "nonmemory_operand" "rIJ")))]
984*c87b03e5Sespie  ""
985*c87b03e5Sespie  "xor%? %0,%1,%2")
986*c87b03e5Sespie
987*c87b03e5Sespie(define_insn "*xorsi3_set_cc_insn"
988*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
989*c87b03e5Sespie		       (xor:SI (match_operand:SI 1 "register_operand" "%r")
990*c87b03e5Sespie			       (match_operand:SI 2 "nonmemory_operand" "rIJ"))
991*c87b03e5Sespie		       (const_int 0)))
992*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
993*c87b03e5Sespie	(xor:SI (match_dup 1)
994*c87b03e5Sespie		(match_dup 2)))]
995*c87b03e5Sespie  ""
996*c87b03e5Sespie  "xor%?.f %0,%1,%2"
997*c87b03e5Sespie  [(set_attr "cond" "set_zn")])
998*c87b03e5Sespie
999*c87b03e5Sespie(define_insn "negsi2"
1000*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1001*c87b03e5Sespie	(neg:SI (match_operand:SI 1 "register_operand" "r")))]
1002*c87b03e5Sespie  ""
1003*c87b03e5Sespie  "sub%? %0,0,%1"
1004*c87b03e5Sespie  [(set_attr "type" "unary")])
1005*c87b03e5Sespie
1006*c87b03e5Sespie(define_insn "*negsi2_set_cc_insn"
1007*c87b03e5Sespie  [(set (reg:CC 61) (compare:CC
1008*c87b03e5Sespie		     (neg:SI (match_operand:SI 1 "register_operand" "r"))
1009*c87b03e5Sespie		     (const_int 0)))
1010*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
1011*c87b03e5Sespie	(neg:SI (match_dup 1)))]
1012*c87b03e5Sespie  ""
1013*c87b03e5Sespie  "sub%?.f %0,0,%1"
1014*c87b03e5Sespie  [(set_attr "type" "unary")
1015*c87b03e5Sespie   (set_attr "cond" "set")])
1016*c87b03e5Sespie
1017*c87b03e5Sespie(define_insn "negdi2"
1018*c87b03e5Sespie  [(set (match_operand:DI 0 "register_operand" "=r")
1019*c87b03e5Sespie	(neg:DI (match_operand:DI 1 "register_operand" "r")))
1020*c87b03e5Sespie   (clobber (reg:SI 61))]
1021*c87b03e5Sespie  ""
1022*c87b03e5Sespie  "sub.f %L0,0,%L1\;sbc %H0,0,%H1"
1023*c87b03e5Sespie  [(set_attr "type" "unary")
1024*c87b03e5Sespie   (set_attr "length" "2")])
1025*c87b03e5Sespie
1026*c87b03e5Sespie(define_insn "one_cmplsi2"
1027*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1028*c87b03e5Sespie	(not:SI (match_operand:SI 1 "register_operand" "r")))]
1029*c87b03e5Sespie  ""
1030*c87b03e5Sespie  "xor%? %0,%1,-1"
1031*c87b03e5Sespie  [(set_attr "type" "unary")])
1032*c87b03e5Sespie
1033*c87b03e5Sespie(define_insn "*one_cmplsi2_set_cc_insn"
1034*c87b03e5Sespie  [(set (reg:CCZN 61) (compare:CCZN
1035*c87b03e5Sespie		       (not:SI (match_operand:SI 1 "register_operand" "r"))
1036*c87b03e5Sespie		       (const_int 0)))
1037*c87b03e5Sespie   (set (match_operand:SI 0 "register_operand" "=r")
1038*c87b03e5Sespie	(not:SI (match_dup 1)))]
1039*c87b03e5Sespie  ""
1040*c87b03e5Sespie  "xor%?.f %0,%1,-1"
1041*c87b03e5Sespie  [(set_attr "type" "unary")
1042*c87b03e5Sespie   (set_attr "cond" "set_zn")])
1043*c87b03e5Sespie
1044*c87b03e5Sespie;; Shift instructions.
1045*c87b03e5Sespie
1046*c87b03e5Sespie(define_expand "ashlsi3"
1047*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "")
1048*c87b03e5Sespie	(ashift:SI (match_operand:SI 1 "register_operand" "")
1049*c87b03e5Sespie		   (match_operand:SI 2 "nonmemory_operand" "")))]
1050*c87b03e5Sespie  ""
1051*c87b03e5Sespie  "
1052*c87b03e5Sespie{
1053*c87b03e5Sespie  if (! TARGET_SHIFTER)
1054*c87b03e5Sespie    {
1055*c87b03e5Sespie      emit_insn (gen_rtx_PARALLEL
1056*c87b03e5Sespie		 (VOIDmode,
1057*c87b03e5Sespie		  gen_rtvec (2,
1058*c87b03e5Sespie			     gen_rtx_SET (VOIDmode, operands[0],
1059*c87b03e5Sespie					  gen_rtx_ASHIFT (SImode, operands[1],
1060*c87b03e5Sespie							  operands[2])),
1061*c87b03e5Sespie			     gen_rtx_CLOBBER (VOIDmode,
1062*c87b03e5Sespie					      gen_rtx_SCRATCH (SImode)))));
1063*c87b03e5Sespie      DONE;
1064*c87b03e5Sespie    }
1065*c87b03e5Sespie}")
1066*c87b03e5Sespie
1067*c87b03e5Sespie(define_expand "ashrsi3"
1068*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "")
1069*c87b03e5Sespie	(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1070*c87b03e5Sespie		     (match_operand:SI 2 "nonmemory_operand" "")))]
1071*c87b03e5Sespie  ""
1072*c87b03e5Sespie  "
1073*c87b03e5Sespie{
1074*c87b03e5Sespie  if (! TARGET_SHIFTER)
1075*c87b03e5Sespie    {
1076*c87b03e5Sespie      emit_insn (gen_rtx_PARALLEL
1077*c87b03e5Sespie		 (VOIDmode,
1078*c87b03e5Sespie		  gen_rtvec (2,
1079*c87b03e5Sespie			     gen_rtx_SET (VOIDmode, operands[0],
1080*c87b03e5Sespie					  gen_rtx_ASHIFTRT (SImode,
1081*c87b03e5Sespie							    operands[1],
1082*c87b03e5Sespie							    operands[2])),
1083*c87b03e5Sespie			     gen_rtx_CLOBBER (VOIDmode,
1084*c87b03e5Sespie					      gen_rtx_SCRATCH (SImode)))));
1085*c87b03e5Sespie      DONE;
1086*c87b03e5Sespie    }
1087*c87b03e5Sespie}")
1088*c87b03e5Sespie
1089*c87b03e5Sespie(define_expand "lshrsi3"
1090*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "")
1091*c87b03e5Sespie	(lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1092*c87b03e5Sespie		     (match_operand:SI 2 "nonmemory_operand" "")))]
1093*c87b03e5Sespie  ""
1094*c87b03e5Sespie  "
1095*c87b03e5Sespie{
1096*c87b03e5Sespie  if (! TARGET_SHIFTER)
1097*c87b03e5Sespie    {
1098*c87b03e5Sespie      emit_insn (gen_rtx_PARALLEL
1099*c87b03e5Sespie		 (VOIDmode,
1100*c87b03e5Sespie		  gen_rtvec (2,
1101*c87b03e5Sespie			     gen_rtx_SET (VOIDmode, operands[0],
1102*c87b03e5Sespie					  gen_rtx_LSHIFTRT (SImode,
1103*c87b03e5Sespie							    operands[1],
1104*c87b03e5Sespie							    operands[2])),
1105*c87b03e5Sespie			     gen_rtx_CLOBBER (VOIDmode,
1106*c87b03e5Sespie					      gen_rtx_SCRATCH (SImode)))));
1107*c87b03e5Sespie      DONE;
1108*c87b03e5Sespie    }
1109*c87b03e5Sespie}")
1110*c87b03e5Sespie
1111*c87b03e5Sespie(define_insn "*ashlsi3_insn"
1112*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1113*c87b03e5Sespie	(ashift:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1114*c87b03e5Sespie		   (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1115*c87b03e5Sespie  "TARGET_SHIFTER"
1116*c87b03e5Sespie  "asl%? %0,%1,%2"
1117*c87b03e5Sespie  [(set_attr "type" "shift")
1118*c87b03e5Sespie   (set_attr "length" "1,2,1,2")])
1119*c87b03e5Sespie
1120*c87b03e5Sespie(define_insn "*ashrsi3_insn"
1121*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1122*c87b03e5Sespie	(ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1123*c87b03e5Sespie		     (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1124*c87b03e5Sespie  "TARGET_SHIFTER"
1125*c87b03e5Sespie  "asr%? %0,%1,%2"
1126*c87b03e5Sespie  [(set_attr "type" "shift")
1127*c87b03e5Sespie   (set_attr "length" "1,2,1,2")])
1128*c87b03e5Sespie
1129*c87b03e5Sespie(define_insn "*lshrsi3_insn"
1130*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1131*c87b03e5Sespie	(lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1132*c87b03e5Sespie		     (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1133*c87b03e5Sespie  "TARGET_SHIFTER"
1134*c87b03e5Sespie  "lsr%? %0,%1,%2"
1135*c87b03e5Sespie  [(set_attr "type" "shift")
1136*c87b03e5Sespie   (set_attr "length" "1,2,1,2")])
1137*c87b03e5Sespie
1138*c87b03e5Sespie(define_insn "*shift_si3"
1139*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1140*c87b03e5Sespie	(match_operator:SI 3 "shift_operator"
1141*c87b03e5Sespie			   [(match_operand:SI 1 "register_operand" "0")
1142*c87b03e5Sespie			    (match_operand:SI 2 "nonmemory_operand" "rIJ")]))
1143*c87b03e5Sespie   (clobber (match_scratch:SI 4 "=&r"))]
1144*c87b03e5Sespie  "! TARGET_SHIFTER"
1145*c87b03e5Sespie  "* return output_shift (operands);"
1146*c87b03e5Sespie  [(set_attr "type" "shift")
1147*c87b03e5Sespie   (set_attr "length" "8")])
1148*c87b03e5Sespie
1149*c87b03e5Sespie;; Compare instructions.
1150*c87b03e5Sespie;; This controls RTL generation and register allocation.
1151*c87b03e5Sespie
1152*c87b03e5Sespie;; We generate RTL for comparisons and branches by having the cmpxx
1153*c87b03e5Sespie;; patterns store away the operands.  Then, the scc and bcc patterns
1154*c87b03e5Sespie;; emit RTL for both the compare and the branch.
1155*c87b03e5Sespie
1156*c87b03e5Sespie(define_expand "cmpsi"
1157*c87b03e5Sespie  [(set (reg:CC 61)
1158*c87b03e5Sespie	(compare:CC (match_operand:SI 0 "register_operand" "")
1159*c87b03e5Sespie		    (match_operand:SI 1 "nonmemory_operand" "")))]
1160*c87b03e5Sespie  ""
1161*c87b03e5Sespie  "
1162*c87b03e5Sespie{
1163*c87b03e5Sespie  arc_compare_op0 = operands[0];
1164*c87b03e5Sespie  arc_compare_op1 = operands[1];
1165*c87b03e5Sespie  DONE;
1166*c87b03e5Sespie}")
1167*c87b03e5Sespie
1168*c87b03e5Sespie;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
1169*c87b03e5Sespie;; This assumes sub.f 0,symbol,0 is a valid insn.
1170*c87b03e5Sespie;; Note that "sub.f 0,r0,1" is an 8 byte insn.  To avoid unnecessarily
1171*c87b03e5Sespie;; creating 8 byte insns we duplicate %1 in the destination reg of the insn
1172*c87b03e5Sespie;; if it's a small constant.
1173*c87b03e5Sespie
1174*c87b03e5Sespie(define_insn "*cmpsi_cc_insn"
1175*c87b03e5Sespie  [(set (reg:CC 61)
1176*c87b03e5Sespie	(compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
1177*c87b03e5Sespie		    (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1178*c87b03e5Sespie  ""
1179*c87b03e5Sespie  "@
1180*c87b03e5Sespie   sub.f 0,%0,%1
1181*c87b03e5Sespie   sub.f %1,%0,%1
1182*c87b03e5Sespie   sub.f 0,%0,%1"
1183*c87b03e5Sespie  [(set_attr "type" "compare,compare,compare")])
1184*c87b03e5Sespie
1185*c87b03e5Sespie(define_insn "*cmpsi_cczn_insn"
1186*c87b03e5Sespie  [(set (reg:CCZN 61)
1187*c87b03e5Sespie	(compare:CCZN (match_operand:SI 0 "register_operand" "r,r,r")
1188*c87b03e5Sespie		      (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1189*c87b03e5Sespie  ""
1190*c87b03e5Sespie  "@
1191*c87b03e5Sespie   sub.f 0,%0,%1
1192*c87b03e5Sespie   sub.f %1,%0,%1
1193*c87b03e5Sespie   sub.f 0,%0,%1"
1194*c87b03e5Sespie  [(set_attr "type" "compare,compare,compare")])
1195*c87b03e5Sespie
1196*c87b03e5Sespie(define_insn "*cmpsi_ccznc_insn"
1197*c87b03e5Sespie  [(set (reg:CCZNC 61)
1198*c87b03e5Sespie	(compare:CCZNC (match_operand:SI 0 "register_operand" "r,r,r")
1199*c87b03e5Sespie		       (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1200*c87b03e5Sespie  ""
1201*c87b03e5Sespie  "@
1202*c87b03e5Sespie   sub.f 0,%0,%1
1203*c87b03e5Sespie   sub.f %1,%0,%1
1204*c87b03e5Sespie   sub.f 0,%0,%1"
1205*c87b03e5Sespie  [(set_attr "type" "compare,compare,compare")])
1206*c87b03e5Sespie
1207*c87b03e5Sespie;; Next come the scc insns.
1208*c87b03e5Sespie
1209*c87b03e5Sespie(define_expand "seq"
1210*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1211*c87b03e5Sespie	(eq:SI (match_dup 1) (const_int 0)))]
1212*c87b03e5Sespie  ""
1213*c87b03e5Sespie  "
1214*c87b03e5Sespie{
1215*c87b03e5Sespie  operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
1216*c87b03e5Sespie}")
1217*c87b03e5Sespie
1218*c87b03e5Sespie(define_expand "sne"
1219*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1220*c87b03e5Sespie	(ne:SI (match_dup 1) (const_int 0)))]
1221*c87b03e5Sespie  ""
1222*c87b03e5Sespie  "
1223*c87b03e5Sespie{
1224*c87b03e5Sespie  operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
1225*c87b03e5Sespie}")
1226*c87b03e5Sespie
1227*c87b03e5Sespie(define_expand "sgt"
1228*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1229*c87b03e5Sespie	(gt:SI (match_dup 1) (const_int 0)))]
1230*c87b03e5Sespie  ""
1231*c87b03e5Sespie  "
1232*c87b03e5Sespie{
1233*c87b03e5Sespie  operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
1234*c87b03e5Sespie}")
1235*c87b03e5Sespie
1236*c87b03e5Sespie(define_expand "sle"
1237*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1238*c87b03e5Sespie	(le:SI (match_dup 1) (const_int 0)))]
1239*c87b03e5Sespie  ""
1240*c87b03e5Sespie  "
1241*c87b03e5Sespie{
1242*c87b03e5Sespie  operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
1243*c87b03e5Sespie}")
1244*c87b03e5Sespie
1245*c87b03e5Sespie(define_expand "sge"
1246*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1247*c87b03e5Sespie	(ge:SI (match_dup 1) (const_int 0)))]
1248*c87b03e5Sespie  ""
1249*c87b03e5Sespie  "
1250*c87b03e5Sespie{
1251*c87b03e5Sespie  operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
1252*c87b03e5Sespie}")
1253*c87b03e5Sespie
1254*c87b03e5Sespie(define_expand "slt"
1255*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1256*c87b03e5Sespie	(lt:SI (match_dup 1) (const_int 0)))]
1257*c87b03e5Sespie  ""
1258*c87b03e5Sespie  "
1259*c87b03e5Sespie{
1260*c87b03e5Sespie  operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
1261*c87b03e5Sespie}")
1262*c87b03e5Sespie
1263*c87b03e5Sespie(define_expand "sgtu"
1264*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1265*c87b03e5Sespie	(gtu:SI (match_dup 1) (const_int 0)))]
1266*c87b03e5Sespie  ""
1267*c87b03e5Sespie  "
1268*c87b03e5Sespie{
1269*c87b03e5Sespie  operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
1270*c87b03e5Sespie}")
1271*c87b03e5Sespie
1272*c87b03e5Sespie(define_expand "sleu"
1273*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1274*c87b03e5Sespie	(leu:SI (match_dup 1) (const_int 0)))]
1275*c87b03e5Sespie  ""
1276*c87b03e5Sespie  "
1277*c87b03e5Sespie{
1278*c87b03e5Sespie  operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
1279*c87b03e5Sespie}")
1280*c87b03e5Sespie
1281*c87b03e5Sespie(define_expand "sgeu"
1282*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1283*c87b03e5Sespie	(geu:SI (match_dup 1) (const_int 0)))]
1284*c87b03e5Sespie  ""
1285*c87b03e5Sespie  "
1286*c87b03e5Sespie{
1287*c87b03e5Sespie  operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
1288*c87b03e5Sespie}")
1289*c87b03e5Sespie
1290*c87b03e5Sespie(define_expand "sltu"
1291*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1292*c87b03e5Sespie	(ltu:SI (match_dup 1) (const_int 0)))]
1293*c87b03e5Sespie  ""
1294*c87b03e5Sespie  "
1295*c87b03e5Sespie{
1296*c87b03e5Sespie  operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
1297*c87b03e5Sespie}")
1298*c87b03e5Sespie
1299*c87b03e5Sespie(define_insn "*scc_insn"
1300*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1301*c87b03e5Sespie	(match_operator:SI 1 "comparison_operator" [(reg 61) (const_int 0)]))]
1302*c87b03e5Sespie  ""
1303*c87b03e5Sespie  "mov %0,1\;sub.%D1 %0,%0,%0"
1304*c87b03e5Sespie  [(set_attr "type" "unary")
1305*c87b03e5Sespie   (set_attr "length" "2")])
1306*c87b03e5Sespie
1307*c87b03e5Sespie;; ??? Look up negscc insn.  See pa.md for example.
1308*c87b03e5Sespie(define_insn "*neg_scc_insn"
1309*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1310*c87b03e5Sespie	(neg:SI (match_operator:SI 1 "comparison_operator"
1311*c87b03e5Sespie		 [(reg 61) (const_int 0)])))]
1312*c87b03e5Sespie  ""
1313*c87b03e5Sespie  "mov %0,-1\;sub.%D1 %0,%0,%0"
1314*c87b03e5Sespie  [(set_attr "type" "unary")
1315*c87b03e5Sespie   (set_attr "length" "2")])
1316*c87b03e5Sespie
1317*c87b03e5Sespie(define_insn "*not_scc_insn"
1318*c87b03e5Sespie  [(set (match_operand:SI 0 "register_operand" "=r")
1319*c87b03e5Sespie	(not:SI (match_operator:SI 1 "comparison_operator"
1320*c87b03e5Sespie		 [(reg 61) (const_int 0)])))]
1321*c87b03e5Sespie  ""
1322*c87b03e5Sespie  "mov %0,1\;sub.%d1 %0,%0,%0"
1323*c87b03e5Sespie  [(set_attr "type" "unary")
1324*c87b03e5Sespie   (set_attr "length" "2")])
1325*c87b03e5Sespie
1326*c87b03e5Sespie;; These control RTL generation for conditional jump insns
1327*c87b03e5Sespie
1328*c87b03e5Sespie(define_expand "beq"
1329*c87b03e5Sespie  [(set (pc)
1330*c87b03e5Sespie	(if_then_else (eq (match_dup 1) (const_int 0))
1331*c87b03e5Sespie		      (label_ref (match_operand 0 "" ""))
1332*c87b03e5Sespie		      (pc)))]
1333*c87b03e5Sespie  ""
1334*c87b03e5Sespie  "
1335*c87b03e5Sespie{
1336*c87b03e5Sespie  operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
1337*c87b03e5Sespie}")
1338*c87b03e5Sespie
1339*c87b03e5Sespie(define_expand "bne"
1340*c87b03e5Sespie  [(set (pc)
1341*c87b03e5Sespie	(if_then_else (ne (match_dup 1) (const_int 0))
1342*c87b03e5Sespie		      (label_ref (match_operand 0 "" ""))
1343*c87b03e5Sespie		      (pc)))]
1344*c87b03e5Sespie  ""
1345*c87b03e5Sespie  "
1346*c87b03e5Sespie{
1347*c87b03e5Sespie  operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
1348*c87b03e5Sespie}")
1349*c87b03e5Sespie
1350*c87b03e5Sespie(define_expand "bgt"
1351*c87b03e5Sespie  [(set (pc)
1352*c87b03e5Sespie	(if_then_else (gt (match_dup 1) (const_int 0))
1353*c87b03e5Sespie		      (label_ref (match_operand 0 "" ""))
1354*c87b03e5Sespie		      (pc)))]
1355*c87b03e5Sespie  ""
1356*c87b03e5Sespie  "
1357*c87b03e5Sespie{
1358*c87b03e5Sespie  operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
1359*c87b03e5Sespie}")
1360*c87b03e5Sespie
1361*c87b03e5Sespie(define_expand "ble"
1362*c87b03e5Sespie  [(set (pc)
1363*c87b03e5Sespie	(if_then_else (le (match_dup 1) (const_int 0))
1364*c87b03e5Sespie		      (label_ref (match_operand 0 "" ""))
1365*c87b03e5Sespie		      (pc)))]
1366*c87b03e5Sespie  ""
1367*c87b03e5Sespie  "
1368*c87b03e5Sespie{
1369*c87b03e5Sespie  operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
1370*c87b03e5Sespie}")
1371*c87b03e5Sespie
1372*c87b03e5Sespie(define_expand "bge"
1373*c87b03e5Sespie  [(set (pc)
1374*c87b03e5Sespie	(if_then_else (ge (match_dup 1) (const_int 0))
1375*c87b03e5Sespie		      (label_ref (match_operand 0 "" ""))
1376*c87b03e5Sespie		      (pc)))]
1377*c87b03e5Sespie  ""
1378*c87b03e5Sespie  "
1379*c87b03e5Sespie{
1380*c87b03e5Sespie  operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
1381*c87b03e5Sespie}")
1382*c87b03e5Sespie
1383*c87b03e5Sespie(define_expand "blt"
1384*c87b03e5Sespie  [(set (pc)
1385*c87b03e5Sespie	(if_then_else (lt (match_dup 1) (const_int 0))
1386*c87b03e5Sespie		      (label_ref (match_operand 0 "" ""))
1387*c87b03e5Sespie		      (pc)))]
1388*c87b03e5Sespie  ""
1389*c87b03e5Sespie  "
1390*c87b03e5Sespie{
1391*c87b03e5Sespie  operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
1392*c87b03e5Sespie}")
1393*c87b03e5Sespie
1394*c87b03e5Sespie(define_expand "bgtu"
1395*c87b03e5Sespie  [(set (pc)
1396*c87b03e5Sespie	(if_then_else (gtu (match_dup 1) (const_int 0))
1397*c87b03e5Sespie		      (label_ref (match_operand 0 "" ""))
1398*c87b03e5Sespie		      (pc)))]
1399*c87b03e5Sespie  ""
1400*c87b03e5Sespie  "
1401*c87b03e5Sespie{
1402*c87b03e5Sespie  operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
1403*c87b03e5Sespie}")
1404*c87b03e5Sespie
1405*c87b03e5Sespie(define_expand "bleu"
1406*c87b03e5Sespie  [(set (pc)
1407*c87b03e5Sespie	(if_then_else (leu (match_dup 1) (const_int 0))
1408*c87b03e5Sespie		      (label_ref (match_operand 0 "" ""))
1409*c87b03e5Sespie		      (pc)))]
1410*c87b03e5Sespie  ""
1411*c87b03e5Sespie  "
1412*c87b03e5Sespie{
1413*c87b03e5Sespie  operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
1414*c87b03e5Sespie}")
1415*c87b03e5Sespie
1416*c87b03e5Sespie(define_expand "bgeu"
1417*c87b03e5Sespie  [(set (pc)
1418*c87b03e5Sespie	(if_then_else (geu (match_dup 1) (const_int 0))
1419*c87b03e5Sespie		      (label_ref (match_operand 0 "" ""))
1420*c87b03e5Sespie		      (pc)))]
1421*c87b03e5Sespie  ""
1422*c87b03e5Sespie  "
1423*c87b03e5Sespie{
1424*c87b03e5Sespie  operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
1425*c87b03e5Sespie}")
1426*c87b03e5Sespie
1427*c87b03e5Sespie(define_expand "bltu"
1428*c87b03e5Sespie  [(set (pc)
1429*c87b03e5Sespie	(if_then_else (ltu (match_dup 1) (const_int 0))
1430*c87b03e5Sespie		      (label_ref (match_operand 0 "" ""))
1431*c87b03e5Sespie		      (pc)))]
1432*c87b03e5Sespie  ""
1433*c87b03e5Sespie  "
1434*c87b03e5Sespie{
1435*c87b03e5Sespie  operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
1436*c87b03e5Sespie}")
1437*c87b03e5Sespie
1438*c87b03e5Sespie;; Now match both normal and inverted jump.
1439*c87b03e5Sespie
1440*c87b03e5Sespie(define_insn "*branch_insn"
1441*c87b03e5Sespie  [(set (pc)
1442*c87b03e5Sespie	(if_then_else (match_operator 1 "proper_comparison_operator"
1443*c87b03e5Sespie				      [(reg 61) (const_int 0)])
1444*c87b03e5Sespie		      (label_ref (match_operand 0 "" ""))
1445*c87b03e5Sespie		      (pc)))]
1446*c87b03e5Sespie  ""
1447*c87b03e5Sespie  "*
1448*c87b03e5Sespie{
1449*c87b03e5Sespie  if (arc_ccfsm_branch_deleted_p ())
1450*c87b03e5Sespie    {
1451*c87b03e5Sespie      arc_ccfsm_record_branch_deleted ();
1452*c87b03e5Sespie      return \"; branch deleted, next insns conditionalized\";
1453*c87b03e5Sespie    }
1454*c87b03e5Sespie  else
1455*c87b03e5Sespie    return \"%~b%d1%# %l0\";
1456*c87b03e5Sespie}"
1457*c87b03e5Sespie  [(set_attr "type" "branch")])
1458*c87b03e5Sespie
1459*c87b03e5Sespie(define_insn "*rev_branch_insn"
1460*c87b03e5Sespie  [(set (pc)
1461*c87b03e5Sespie	(if_then_else (match_operator 1 "proper_comparison_operator"
1462*c87b03e5Sespie				      [(reg 61) (const_int 0)])
1463*c87b03e5Sespie		      (pc)
1464*c87b03e5Sespie		      (label_ref (match_operand 0 "" ""))))]
1465*c87b03e5Sespie  "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
1466*c87b03e5Sespie  "*
1467*c87b03e5Sespie{
1468*c87b03e5Sespie  if (arc_ccfsm_branch_deleted_p ())
1469*c87b03e5Sespie    {
1470*c87b03e5Sespie      arc_ccfsm_record_branch_deleted ();
1471*c87b03e5Sespie      return \"; branch deleted, next insns conditionalized\";
1472*c87b03e5Sespie    }
1473*c87b03e5Sespie  else
1474*c87b03e5Sespie    return \"%~b%D1%# %l0\";
1475*c87b03e5Sespie}"
1476*c87b03e5Sespie  [(set_attr "type" "branch")])
1477*c87b03e5Sespie
1478*c87b03e5Sespie;; Unconditional and other jump instructions.
1479*c87b03e5Sespie
1480*c87b03e5Sespie(define_insn "jump"
1481*c87b03e5Sespie  [(set (pc) (label_ref (match_operand 0 "" "")))]
1482*c87b03e5Sespie  ""
1483*c87b03e5Sespie  "b%* %l0"
1484*c87b03e5Sespie  [(set_attr "type" "uncond_branch")])
1485*c87b03e5Sespie
1486*c87b03e5Sespie(define_insn "indirect_jump"
1487*c87b03e5Sespie  [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
1488*c87b03e5Sespie  ""
1489*c87b03e5Sespie  "j%* %a0"
1490*c87b03e5Sespie  [(set_attr "type" "uncond_branch")])
1491*c87b03e5Sespie
1492*c87b03e5Sespie;; Implement a switch statement.
1493*c87b03e5Sespie;; This wouldn't be necessary in the non-pic case if we could distinguish
1494*c87b03e5Sespie;; label refs of the jump table from other label refs.  The problem is that
1495*c87b03e5Sespie;; label refs are output as "%st(.LL42)" but we don't want the %st - we want
1496*c87b03e5Sespie;; the real address since it's the address of the table.
1497*c87b03e5Sespie
1498*c87b03e5Sespie(define_expand "casesi"
1499*c87b03e5Sespie  [(set (match_dup 5)
1500*c87b03e5Sespie	(minus:SI (match_operand:SI 0 "register_operand" "")
1501*c87b03e5Sespie		  (match_operand:SI 1 "nonmemory_operand" "")))
1502*c87b03e5Sespie   (set (reg:CC 61)
1503*c87b03e5Sespie	(compare:CC (match_dup 5)
1504*c87b03e5Sespie		    (match_operand:SI 2 "nonmemory_operand" "")))
1505*c87b03e5Sespie   (set (pc)
1506*c87b03e5Sespie	(if_then_else (gtu (reg:CC 61)
1507*c87b03e5Sespie			   (const_int 0))
1508*c87b03e5Sespie		      (label_ref (match_operand 4 "" ""))
1509*c87b03e5Sespie		      (pc)))
1510*c87b03e5Sespie   (parallel
1511*c87b03e5Sespie    [(set (pc)
1512*c87b03e5Sespie	  (mem:SI (plus:SI (mult:SI (match_dup 5)
1513*c87b03e5Sespie				    (const_int 4))
1514*c87b03e5Sespie			   (label_ref (match_operand 3 "" "")))))
1515*c87b03e5Sespie     (clobber (match_scratch:SI 6 ""))
1516*c87b03e5Sespie     (clobber (match_scratch:SI 7 ""))])]
1517*c87b03e5Sespie  ""
1518*c87b03e5Sespie  "
1519*c87b03e5Sespie{
1520*c87b03e5Sespie  operands[5] = gen_reg_rtx (SImode);
1521*c87b03e5Sespie}")
1522*c87b03e5Sespie
1523*c87b03e5Sespie(define_insn "*casesi_insn"
1524*c87b03e5Sespie  [(set (pc)
1525*c87b03e5Sespie	(mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
1526*c87b03e5Sespie				  (const_int 4))
1527*c87b03e5Sespie			 (label_ref (match_operand 1 "" "")))))
1528*c87b03e5Sespie   (clobber (match_scratch:SI 2 "=r"))
1529*c87b03e5Sespie   (clobber (match_scratch:SI 3 "=r"))]
1530*c87b03e5Sespie  ""
1531*c87b03e5Sespie  "*
1532*c87b03e5Sespie{
1533*c87b03e5Sespie  output_asm_insn (\"mov %2,%1\", operands);
1534*c87b03e5Sespie  if (TARGET_SHIFTER)
1535*c87b03e5Sespie    output_asm_insn (\"asl %3,%0,2\", operands);
1536*c87b03e5Sespie  else
1537*c87b03e5Sespie    output_asm_insn (\"asl %3,%0\;asl %3,%3\", operands);
1538*c87b03e5Sespie  output_asm_insn (\"ld %2,[%2,%3]\", operands);
1539*c87b03e5Sespie  output_asm_insn (\"j.nd %a2\", operands);
1540*c87b03e5Sespie  return \"\";
1541*c87b03e5Sespie}"
1542*c87b03e5Sespie  [(set_attr "type" "uncond_branch")
1543*c87b03e5Sespie   (set_attr "length" "6")])
1544*c87b03e5Sespie
1545*c87b03e5Sespie(define_insn "tablejump"
1546*c87b03e5Sespie  [(set (pc) (match_operand:SI 0 "address_operand" "p"))
1547*c87b03e5Sespie   (use (label_ref (match_operand 1 "" "")))]
1548*c87b03e5Sespie  "0 /* disabled -> using casesi now */"
1549*c87b03e5Sespie  "j%* %a0"
1550*c87b03e5Sespie  [(set_attr "type" "uncond_branch")])
1551*c87b03e5Sespie
1552*c87b03e5Sespie(define_expand "call"
1553*c87b03e5Sespie  ;; operands[1] is stack_size_rtx
1554*c87b03e5Sespie  ;; operands[2] is next_arg_register
1555*c87b03e5Sespie  [(parallel [(call (match_operand:SI 0 "call_operand" "")
1556*c87b03e5Sespie		    (match_operand 1 "" ""))
1557*c87b03e5Sespie	     (clobber (reg:SI 31))])]
1558*c87b03e5Sespie  ""
1559*c87b03e5Sespie  "")
1560*c87b03e5Sespie
1561*c87b03e5Sespie(define_insn "*call_via_reg"
1562*c87b03e5Sespie  [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
1563*c87b03e5Sespie	 (match_operand 1 "" ""))
1564*c87b03e5Sespie   (clobber (reg:SI 31))]
1565*c87b03e5Sespie  ""
1566*c87b03e5Sespie  "lr blink,[status]\;j.d %0\;add blink,blink,2"
1567*c87b03e5Sespie  [(set_attr "type" "call_no_delay_slot")
1568*c87b03e5Sespie   (set_attr "length" "3")])
1569*c87b03e5Sespie
1570*c87b03e5Sespie(define_insn "*call_via_label"
1571*c87b03e5Sespie  [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
1572*c87b03e5Sespie	 (match_operand 1 "" ""))
1573*c87b03e5Sespie   (clobber (reg:SI 31))]
1574*c87b03e5Sespie  ""
1575*c87b03e5Sespie  ; The %~ is necessary in case this insn gets conditionalized and the previous
1576*c87b03e5Sespie  ; insn is the cc setter.
1577*c87b03e5Sespie  "%~bl%!%* %0"
1578*c87b03e5Sespie  [(set_attr "type" "call")
1579*c87b03e5Sespie   (set_attr "cond" "canuse")])
1580*c87b03e5Sespie
1581*c87b03e5Sespie(define_expand "call_value"
1582*c87b03e5Sespie  ;; operand 2 is stack_size_rtx
1583*c87b03e5Sespie  ;; operand 3 is next_arg_register
1584*c87b03e5Sespie  [(parallel [(set (match_operand 0 "register_operand" "=r")
1585*c87b03e5Sespie		   (call (match_operand:SI 1 "call_operand" "")
1586*c87b03e5Sespie			 (match_operand 2 "" "")))
1587*c87b03e5Sespie	     (clobber (reg:SI 31))])]
1588*c87b03e5Sespie  ""
1589*c87b03e5Sespie  "")
1590*c87b03e5Sespie
1591*c87b03e5Sespie(define_insn "*call_value_via_reg"
1592*c87b03e5Sespie  [(set (match_operand 0 "register_operand" "=r")
1593*c87b03e5Sespie	(call (mem:SI (match_operand:SI 1 "register_operand" "r"))
1594*c87b03e5Sespie	      (match_operand 2 "" "")))
1595*c87b03e5Sespie   (clobber (reg:SI 31))]
1596*c87b03e5Sespie  ""
1597*c87b03e5Sespie  "lr blink,[status]\;j.d %1\;add blink,blink,2"
1598*c87b03e5Sespie  [(set_attr "type" "call_no_delay_slot")
1599*c87b03e5Sespie   (set_attr "length" "3")])
1600*c87b03e5Sespie
1601*c87b03e5Sespie(define_insn "*call_value_via_label"
1602*c87b03e5Sespie  [(set (match_operand 0 "register_operand" "=r")
1603*c87b03e5Sespie	(call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
1604*c87b03e5Sespie	      (match_operand 2 "" "")))
1605*c87b03e5Sespie   (clobber (reg:SI 31))]
1606*c87b03e5Sespie  ""
1607*c87b03e5Sespie  ; The %~ is necessary in case this insn gets conditionalized and the previous
1608*c87b03e5Sespie  ; insn is the cc setter.
1609*c87b03e5Sespie  "%~bl%!%* %1"
1610*c87b03e5Sespie  [(set_attr "type" "call")
1611*c87b03e5Sespie   (set_attr "cond" "canuse")])
1612*c87b03e5Sespie
1613*c87b03e5Sespie(define_insn "nop"
1614*c87b03e5Sespie  [(const_int 0)]
1615*c87b03e5Sespie  ""
1616*c87b03e5Sespie  "nop"
1617*c87b03e5Sespie  [(set_attr "type" "misc")])
1618*c87b03e5Sespie
1619*c87b03e5Sespie;; Special pattern to flush the icache.
1620*c87b03e5Sespie;; ??? Not sure what to do here.  Some ARC's are known to support this.
1621*c87b03e5Sespie
1622*c87b03e5Sespie(define_insn "flush_icache"
1623*c87b03e5Sespie  [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
1624*c87b03e5Sespie  ""
1625*c87b03e5Sespie  "* return \"\";"
1626*c87b03e5Sespie  [(set_attr "type" "misc")])
1627*c87b03e5Sespie
1628*c87b03e5Sespie;; Split up troublesome insns for better scheduling.
1629*c87b03e5Sespie
1630*c87b03e5Sespie;; Peepholes go at the end.
1631