1;; Toshiba Media Processor Machine description template
2;; Copyright (C) 2001-2016 Free Software Foundation, Inc.
3;; Contributed by Red Hat Inc
4;;
5;; This file is part of GCC.
6;;
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 3, or (at your option)
10;; any later version.
11;;
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15;; License for more details.
16;;
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3.  If not see
19;; <http://www.gnu.org/licenses/>.  */
20
21
22
23;; Constraints:
24;;
25;;  a   $sp
26;;  b   $tp
27;;  c   control regs
28;;  h   $hi ($23)
29;;  l   $lo ($24)
30;;  d   $hi/$lo pair (DImode)
31;;  j   $rpc ($22)
32;;  r   $0..$15
33;;  t   $0..$7
34;;  v   $gp
35;;  x	$c0..$c31
36;;  ex  coprocessor registers that can be moved to other coprocessor registers
37;;  er  coprocessor registers that can be moved to and from core registers
38;;  em  coprocessor registers that can be moves to and from memory
39;;  y	$ccr0..$ccr31
40;;  z   $0
41;;
42;;  I   sign imm16	mov/add
43;;  J   zero imm16	mov/add
44;;  K   zero imm24	mov
45;;  L   sign imm6	add
46;;  M   zero imm5	slt,shifts
47;;  N   zero imm4	bCC
48;;  O   high imm16	mov
49;;
50;;  R   near symbol
51;;  S   sign imm8	mov
52;;  T   tp or gp relative symbol
53;;  U   non-absolute memory
54;;  W   %hi(sym)
55;;  Y   (Rn)
56;;  Z   Control Bus Symbol
57;;
58;; Modifiers:
59;;
60;;  b   print unique bit in mask
61;;  B   print bits required for value (for clip)
62;;  h	print decimal >> 16.
63;;  I   print decimal, with hex comment if more than 8 bits
64;;  J   print unsigned hex
65;;  L   print set, clr or not (for bitops)
66;;  P	print memory as a post-inc with no increment
67;;  U   print bits required for value (for clipu)
68;;  x   print unsigned decimal or hex, depending on where set bits are
69
70(define_constants [
71		   (REGSAVE_CONTROL_TEMP 11)
72		   (FP_REGNO 8)
73		   (TP_REGNO 13)
74		   (GP_REGNO 14)
75		   (SP_REGNO 15)
76		   (PSW_REGNO 16)
77		   (LP_REGNO 17)
78		   (SAR_REGNO 18)
79		   (RPB_REGNO 20)
80		   (RPE_REGNO 21)
81		   (RPC_REGNO 22)
82		   (HI_REGNO 23)
83		   (LO_REGNO 24)
84		   (CBCR_REGNO 81)
85		   ])
86
87(define_constants [
88		   (UNS_BLOCKAGE 0)
89		   (UNS_TPREL 2)
90		   (UNS_GPREL 3)
91		   (UNS_REPEAT_BEG 4)
92		   (UNS_REPEAT_END 5)
93		   (UNS_EH_EPILOGUE 6)
94		   (UNS_EREPEAT_BEG 7)
95		   (UNS_EREPEAT_END 8)
96		   (UNS_BB_TRACE_RET 9)
97		   (UNS_DISABLE_INT 10)
98		   (UNS_ENABLE_INT 11)
99		   (UNS_RETI 12)
100		  ])
101
102;; This attribute determines the VLIW packing mechanism.  The IVC2
103;; coprocessor has two pipelines (P0 and P1), and a MeP+IVC2 can issue
104;; up to three insns at a time.  Most IVC2 insns can run on either
105;; pipeline, however, scheduling some insns on P0 precludes packing a
106;; core insn with it, and only 16-bit core insns can pack with any P0
107;; insn.
108(define_attr "vliw" "basic,ivc2"
109  (const (symbol_ref "TARGET_IVC2")))
110
111;; This attribute describes the kind of memory operand present in the
112;; instruction.  This is used to compute the length of the insn based
113;; on the addressing mode used.
114(define_attr "memop" "none,core0,core1,cop0,cop1"
115  (const_string "none"))
116
117(define_attr "intrinsic" "none,cmov,cmov1,cmov2,cmovc1,cmovc2,cmovh1,cmovh2"
118  (const_string "none"))
119
120;; This attribute describes how the instruction may be bundled in a
121;; VLIW instruction.  Type MULTI is assumed to use both slots.
122(define_attr "slot" "core,cop,multi"
123  (cond [(eq_attr "intrinsic" "!none")
124	   (const_string "cop")]
125	(const_string "core")))
126
127;; This attribute describes the latency of the opcode (ready delay).
128;; The 0 is used to indicate "unspecified".  An instruction that
129;; completes immediately with no potential stalls would have a value
130;; of 1, a one cycle stall would be 2, etc.
131(define_attr "latency" ""
132  (const_int 0))
133
134(define_attr "shiftop" "none,operand2"
135  (const_string "none"))
136
137;; This attribute describes the size of the instruction in bytes.
138;; This *must* be exact unless the pattern is SLOT_MULTI, as this
139;; is used by the VLIW bundling code.
140(define_attr "length" ""
141  (cond [(eq_attr "memop" "core0")
142	   (symbol_ref "mep_core_address_length (insn, 0)")
143	 (eq_attr "memop" "core1")
144	   (symbol_ref "mep_core_address_length (insn, 1)")
145	 (eq_attr "memop" "cop0")
146	   (symbol_ref "mep_cop_address_length (insn, 0)")
147	 (eq_attr "memop" "cop1")
148	   (symbol_ref "mep_cop_address_length (insn, 1)")
149         ]
150	 ; Catch patterns that don't define the length properly.
151         (symbol_ref "(abort (), 0)")))
152
153;; This attribute describes a pipeline hazard seen in the insn.
154(define_attr "stall" "none,int2,ssarb,load,store,ldc,stc,ldcb,stcb,ssrab,fsft,ret,advck,mul,mulr,div"
155  (cond [(and (eq_attr "shiftop" "operand2")
156	      (not (match_operand:SI 2 "mep_single_shift_operand" "")))
157	 (const_string "int2")]
158	(const_string "none")))
159
160(define_attr "may_trap" "no,yes"
161  (const_string "no"))
162
163;; Describe a user's asm statement.
164(define_asm_attributes
165  [(set_attr "length" "4")
166   (set_attr "slot" "multi")])
167
168;; Each IVC2 instruction uses one of these two pipelines.  P0S insns
169;; use P0; C3 insns use P1.
170(define_automaton "mep_ivc2")
171(define_cpu_unit "ivc2_core,ivc2_p0,ivc2_p1" "mep_ivc2")
172
173;; Each core or IVC2 instruction is bundled into one of these slots.
174;; Supported bundlings:
175;;
176;; Core mode:
177;;
178;;  C1	[-----core-----]
179;;  C2	[-------------core-------------]
180;;  C3	[--------------c3--------------]
181;;
182;; VLIW mode:
183;;
184;;  V1	[-----core-----][--------p0s-------][------------p1------------]
185;;  V2  [-------------core-------------]xxxx[------------p1------------]
186;;  V3	1111[--p0--]0111[--------p0--------][------------p1------------]
187
188(define_attr "slots" "core,c3,p0,p0_p0s,p0_p1,p0s,p0s_p1,p1" (const_string "core"))
189
190(define_cpu_unit "ivc2_slot_c16,ivc2_slot_c32,ivc2_slot_c3,ivc2_slot_p0s,ivc2_slot_p0,ivc2_slot_p1" "mep_ivc2")
191
192(define_insn_reservation "ivc2_insn_core16" 1
193  (and (eq_attr "vliw" "ivc2")
194       (and (eq (symbol_ref "get_attr_length(insn)") (const_int 2))
195	    (and (eq_attr "intrinsic" "none")
196		 (eq_attr "slot" "!cop"))))
197  "ivc2_core+ivc2_slot_c16")
198
199(define_insn_reservation "ivc2_insn_core32" 1
200  (and (eq_attr "vliw" "ivc2")
201       (and (eq (symbol_ref "get_attr_length(insn)") (const_int 4))
202	    (and (eq_attr "intrinsic" "none")
203		 (eq_attr "slot" "!cop"))))
204  "ivc2_core+ivc2_slot_c32")
205
206;; These shouldn't happen when in VLIW mode.
207(define_insn_reservation "ivc2_insn_c3" 1
208  (and (eq_attr "vliw" "ivc2")
209       (eq_attr "slots" "c3"))
210  "ivc2_p1+ivc2_slot_c3")
211
212(define_insn_reservation "ivc2_insn_p0" 1
213  (and (eq_attr "vliw" "ivc2")
214       (eq_attr "slots" "p0"))
215  "ivc2_p0+ivc2_slot_p0")
216
217(define_insn_reservation "ivc2_insn_p0_p0s" 1
218  (and (eq_attr "vliw" "ivc2")
219       (eq_attr "slots" "p0_p0s"))
220  "ivc2_p0+ivc2_slot_p0|ivc2_p0+ivc2_slot_p0s")
221
222(define_insn_reservation "ivc2_insn_p0_p1" 1
223  (and (eq_attr "vliw" "ivc2")
224       (eq_attr "slots" "p0_p1"))
225  "ivc2_p0+ivc2_slot_p0|ivc2_p1+ivc2_slot_p1")
226
227(define_insn_reservation "ivc2_insn_p0s" 1
228  (and (eq_attr "vliw" "ivc2")
229       (eq_attr "slots" "p0s"))
230  "ivc2_p0+ivc2_slot_p0s")
231
232(define_insn_reservation "ivc2_insn_p0s_p1" 1
233  (and (eq_attr "vliw" "ivc2")
234       (eq_attr "slots" "p0s_p1"))
235  "ivc2_p0+ivc2_slot_p0s|ivc2_p1+ivc2_slot_p1")
236
237(define_insn_reservation "ivc2_insn_p1" 1
238  (and (eq_attr "vliw" "ivc2")
239       (eq_attr "slots" "p1"))
240  "ivc2_p1+ivc2_slot_p1")
241
242;; these run in C3 also, but when we're doing VLIW scheduling, they
243;; only run in P0.
244(define_insn_reservation "ivc2_insn_cmov" 1
245  (and (eq_attr "vliw" "ivc2")
246       (eq_attr "intrinsic" "!none"))
247  "ivc2_p0+ivc2_slot_p0")
248
249
250(exclusion_set "ivc2_slot_c32"
251	       "ivc2_slot_p0,ivc2_slot_p0s")
252(exclusion_set "ivc2_slot_p0"
253	       "ivc2_slot_p0s")
254(exclusion_set "ivc2_slot_c16"
255	       "ivc2_slot_p0")
256(exclusion_set "ivc2_slot_c16"
257	       "ivc2_slot_c32")
258
259;; Non-IVC2 scheduling.
260(define_automaton "mep")
261(define_cpu_unit "core,cop" "mep")
262
263;; Latencies are the time between one insn entering the second pipeline
264;; stage (E2, LD, A2 or V2) and the next instruction entering the same
265;; stage.  When an instruction assigns to general registers, the default
266;; latencies are for when the next instruction receives the register
267;; through bypass 1.
268
269;; Arithmetic instructions that execute in a single stage.
270(define_insn_reservation "h1_int1" 2
271  (and (eq_attr "slot" "!cop")
272       (eq_attr "stall" "none"))
273  "core")
274(define_bypass 1 "h1_int1" "h1_int1,h1_ssarb")
275(define_bypass 1 "h1_int1" "h1_store" "mep_store_data_bypass_p")
276
277;; $sar can be read by an immediately following fsft or ldc.
278(define_insn_reservation "h1_ssarb" 1
279  (eq_attr "stall" "ssarb")
280  "core")
281
282;; Arithmetic instructions that execute in two stages.
283(define_insn_reservation "h1_int2" 2
284  (eq_attr "stall" "int2,fsft")
285  "core")
286(define_bypass 1 "h1_int2" "h1_int1,h1_ssarb")
287(define_bypass 1 "h1_int2" "h1_store" "mep_store_data_bypass_p")
288
289(define_insn_reservation "h1_load" 4
290  (eq_attr "stall" "load")
291  "core")
292(define_bypass 3 "h1_load" "h1_int1,h1_ssarb")
293(define_bypass 3 "h1_load" "h1_store" "mep_store_data_bypass_p")
294
295(define_insn_reservation "h1_store" 1
296  (eq_attr "stall" "store")
297  "core")
298
299(define_insn_reservation "h1_ipipe_ldc" 2
300  (and (eq_attr "stall" "ldc")
301       (ne (symbol_ref "mep_ipipe_ldc_p(insn)") (const_int 0)))
302  "core")
303(define_bypass 1 "h1_ipipe_ldc" "h1_int1,h1_ssarb")
304(define_bypass 1 "h1_ipipe_ldc" "h1_store" "mep_store_data_bypass_p")
305
306(define_insn_reservation "h1_apipe_ldc" 2
307  (and (eq_attr "stall" "ldc")
308       (eq (symbol_ref "mep_ipipe_ldc_p(insn)") (const_int 0)))
309  "core")
310
311;; 2 is correct for stc->ret and stc->fsft.  The most important remaining
312;; case is stc->madd, which induces no stall.
313(define_insn_reservation "h1_stc" 2
314  (eq_attr "stall" "stc")
315  "core")
316(define_bypass 1 "h1_stc" "h1_mul")
317
318;; ??? Parameterised latency.
319(define_insn_reservation "h1_ldcb" 5
320  (eq_attr "stall" "ldcb")
321  "core")
322
323(define_insn_reservation "h1_stcb" 1
324  (eq_attr "stall" "stcb")
325  "core")
326
327(define_insn_reservation "h1_advck" 6
328  (eq_attr "stall" "advck")
329  "core")
330
331(define_insn_reservation "h1_mul" 5
332  (eq_attr "stall" "mul,mulr")
333  "core")
334(define_bypass 4 "h1_mul" "h1_int1,h1_ssarb")
335(define_bypass 4 "h1_mul" "h1_store" "mep_store_data_bypass_p")
336(define_bypass 1 "h1_mul" "h1_mul" "mep_mul_hilo_bypass_p")
337
338(define_insn_reservation "h1_div" 36
339  (eq_attr "stall" "div")
340  "core")
341
342(define_insn_reservation "h1_cop" 1
343  (eq_attr "slot" "cop")
344  "cop")
345
346(include "predicates.md")
347(include "constraints.md")
348(include "intrinsics.md")
349
350;; ::::::::::::::::::::
351;; ::
352;; :: Moves
353;; ::
354;; ::::::::::::::::::::
355
356(define_expand "movqi"
357  [(set (match_operand:QI 0 "general_operand" "")
358	(match_operand:QI 1 "general_operand" ""))]
359  ""
360  "
361{
362  if (mep_expand_mov (operands, QImode))
363    DONE;
364}")
365
366;; The Idea here is to prefer the 16-bit tp-relative load, but to fall back
367;; to the general 32-bit load rather than do silly things with spill regs.
368(define_insn "*movqi_tprel_load"
369  [(set (match_operand:QI 0 "mep_tprel_operand" "=t,*r")
370	(mem:QI (plus:SI (match_operand:SI 1 "mep_tp_operand" "b,*r")
371			 (const:SI (unspec:SI [(match_operand:SI 2
372						"symbolic_operand" "s,s")]
373					      UNS_TPREL)))))]
374  ""
375  "lb\\t%0, %%tpoff(%2)(%1)"
376  [(set_attr "length" "2,4")
377   (set_attr "stall" "load")])
378
379(define_insn "*movqi_tprel_store"
380  [(set (mem:QI (plus:SI (match_operand:SI 0 "mep_tp_operand" "b,*r")
381			 (const:SI (unspec:SI [(match_operand:SI 1
382						"symbolic_operand" "s,s")]
383					      UNS_TPREL))))
384	(match_operand:QI 2 "mep_tprel_operand" "t,*r"))]
385  ""
386  "sb\\t%2, %%tpoff(%1)(%0)"
387  [(set_attr "length" "2,4")
388   (set_attr "stall" "store")])
389
390(define_insn "*movqi_internal"
391  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r, r,m,r,c,r,y,r,er,ex,em,Y")
392	(match_operand:QI 1 "general_operand" " r,n,rm,r,c,r,y,r,er,r,ex,Y,em"))]
393  "mep_mov_ok (operands, QImode)"
394  "@
395   mov\\t%0, %1
396   mov\\t%0, %1
397   lb\\t%0, %1
398   sb\\t%1, %0
399   ldc\\t%0, %1
400   stc\\t%1, %0
401   cmovc\\t%0, %1
402   cmovc\\t%0, %1
403   cmov\\t%0, %1
404   cmov\\t%0, %1
405   %<\\t%0, %M1
406   lbcpa\\t%0, %P1
407   sbcpa\\t%1, %P0"
408  [(set_attr "length" "2,2,*,*,2,2,4,4,4,4,*,4,4")
409   (set_attr "intrinsic" "*,*,*,*,*,*,cmovc2,cmovc1,cmov2,cmov1,cmov,*,*")
410   (set_attr "stall"  "*,*,load,store,ldc,stc,*,*,*,*,*,load,store")
411   (set_attr "memop"  "*,*,core1,core0,*,*,*,*,*,*,*,*,*")])
412
413(define_expand "movhi"
414  [(set (match_operand:HI 0 "general_operand" "")
415	(match_operand:HI 1 "general_operand" ""))]
416  ""
417  "
418{
419  if (mep_expand_mov (operands, HImode))
420    DONE;
421}")
422
423(define_insn "*movhi_tprel_load"
424  [(set (match_operand:HI 0 "mep_tprel_operand" "=t,*r")
425	(mem:HI (plus:SI (match_operand:SI 1 "mep_tp_operand" "b,*r")
426			 (const:SI (unspec:SI [(match_operand:SI 2
427						"symbolic_operand" "s,s")]
428					      UNS_TPREL)))))]
429  ""
430  "lh\\t%0, %%tpoff(%2)(%1)"
431  [(set_attr "length" "2,4")
432   (set_attr "stall" "load")])
433
434(define_insn "*movhi_tprel_store"
435  [(set (mem:HI (plus:SI (match_operand:SI 0 "mep_tp_operand" "b,*r")
436			 (const:SI (unspec:SI [(match_operand:SI 1
437						"symbolic_operand" "s,s")]
438					      UNS_TPREL))))
439	(match_operand:HI 2 "mep_tprel_operand" "t,*r"))]
440  ""
441  "sh\\t%2, %%tpoff(%1)(%0)"
442  [(set_attr "length" "2,4")
443   (set_attr "stall" "store")])
444
445(define_insn "*movhi_internal"
446  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,m,r,c,r,y,r,er,ex,em,Y")
447	(match_operand:HI 1 "general_operand" " r,S,n,m,r,c,r,y,r,er,r,ex,Y,em"))]
448  "mep_mov_ok (operands, HImode)"
449  "@
450   mov\\t%0, %1
451   mov\\t%0, %I1
452   mov\\t%0, %I1
453   lh\\t%0, %1
454   sh\\t%1, %0
455   ldc\\t%0, %1
456   stc\\t%1, %0
457   cmovc\\t%0, %1
458   cmovc\\t%0, %1
459   cmov\\t%0, %1
460   cmov\\t%0, %1
461   %<\\t%0, %M1
462   lhcpa\\t%0, %P1
463   shcpa\\t%1, %P0"
464  [(set_attr "length" "2,2,4,*,*,2,2,4,4,4,4,*,4,4")
465   (set_attr "intrinsic" "*,*,*,*,*,*,*,cmovc2,cmovc1,cmov2,cmov1,cmov,*,*")
466   (set_attr "stall"  "*,*,*,load,store,ldc,stc,*,*,*,*,*,load,store")
467   (set_attr "memop"  "*,*,*,core1,core0,*,*,*,*,*,*,*,*,*")])
468
469(define_expand "movsi"
470  [(set (match_operand:SI 0 "nonimmediate_operand" "")
471	(match_operand:SI 1 "general_operand" ""))]
472  ""
473  "
474{
475  if (mep_expand_mov (operands, SImode))
476    DONE;
477}")
478
479(define_insn "*movsi_tprel_load"
480  [(set (match_operand:SI 0 "mep_tprel_operand" "=t,*r")
481	(mem:SI (plus:SI (match_operand:SI 1 "mep_tp_operand" "b,*r")
482			 (const:SI (unspec:SI [(match_operand:SI 2
483						"symbolic_operand" "s,s")]
484					      UNS_TPREL)))))]
485  ""
486  "lw\\t%0, %%tpoff(%2)(%1)"
487  [(set_attr "length" "2,4")
488   (set_attr "stall" "load")])
489
490(define_insn "*movsi_tprel_store"
491  [(set (mem:SI (plus:SI (match_operand:SI 0 "mep_tp_operand" "b,*r")
492			 (const:SI (unspec:SI [(match_operand:SI 1
493						"symbolic_operand" "s,s")]
494					      UNS_TPREL))))
495	(match_operand:SI 2 "mep_tprel_operand" "t,*r"))]
496  ""
497  "sw\\t%2, %%tpoff(%1)(%0)"
498  [(set_attr "length" "2,4")
499   (set_attr "stall" "store")])
500
501(define_insn "movsi_topsym_s"
502  [(set (match_operand:SI 0 "register_operand" "=r")
503	(high:SI (match_operand:SI 1 "symbolic_operand" "s")))]
504  ""
505  "movh\\t%0, %%hi(%1)"
506  [(set_attr "length" "4")])
507
508(define_insn "movsi_botsym_s"
509  [(set (match_operand:SI 0 "register_operand" "=r")
510	(lo_sum:SI (match_operand:SI 1 "register_operand" "0")
511		   (match_operand:SI 2 "symbolic_operand" "s")))]
512  ""
513  "add3\\t%0, %1, %%lo(%2)"
514  [(set_attr "length" "4")])
515
516
517
518(define_insn "cmovh_getsub"
519  [(set (match_operand:SI 0 "register_operand" "=r")
520	(subreg:SI (match_operand:DI 1 "register_operand" "er") 4))]
521  "0 && TARGET_64BIT_CR_REGS"
522  "cmovh\\t%0, %1"
523  [(set_attr "intrinsic" "cmovh2")
524   (set_attr "length" "4")])
525
526(define_insn "*movsi_internal"
527  [(set (match_operand:SI 0 "mep_movdest_operand"
528	    "=r,r,r,r,r, t,t,r,r,r,Z,m,r,c,r,y,r, er,ex,em,U ")
529	(match_operand:SI 1 "general_operand"
530	    " r,S,I,J,OW,K,s,i,Z,m,r,r,c,r,y,r,er,r, ex,U, em"))]
531  "mep_mov_ok (operands, SImode)"
532  "@
533   mov\\t%0, %1
534   mov\\t%0, %I1
535   mov\\t%0, %I1
536   movu\\t%0, %J1
537   movh\\t%0, %h1
538   movu\\t%0, %x1
539   movu\\t%0, %1
540   #
541   ldcb\\t%0, %1
542   lw\\t%0, %1
543   stcb\\t%1, %0
544   sw\\t%1, %0
545   ldc\\t%0, %1
546   stc\\t%1, %0
547   cmovc\\t%0, %1
548   cmovc\\t%0, %1
549   cmov\\t%0, %1
550   cmov\\t%0, %1
551   %<\\t%0, %M1
552   lwcp\\t%0, %1
553   swcp\\t%1, %0"
554  [(set_attr "length" "2,2,4,4,4,4,4,*,4,*,4,*,2,2,4,4,4,4,4,*,*")
555   (set_attr "intrinsic" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,cmovc2,cmovc1,cmov2,cmov1,cmov,*,*")
556   (set_attr "stall"  "*,*,*,*,*,*,*,*,ldcb,load,stcb,store,ldc,stc,*,*,*,*,*,load,store")
557   (set_attr "memop"  "*,*,*,*,*,*,*,*,*,core1,*,core0,*,*,*,*,*,*,*,cop1,cop0")
558   (set_attr "slot"   "*,*,*,*,*,*,*,multi,*,*,*,*,*,*,*,*,*,*,*,*,*")])
559
560(define_split
561  [(set (match_operand:SI 0 "register_operand" "")
562        (match_operand:SI 1 "const_int_operand" ""))]
563  "mep_split_mov (operands, 0)"
564  [(set (match_dup 0) (match_dup 2))
565   (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 3)))]
566  "
567{
568  HOST_WIDE_INT value;
569  int lo, hi;
570
571  value = INTVAL (operands[1]);
572
573  lo = value & 0xffff;
574  hi = trunc_int_for_mode (value & 0xffff0000, SImode);
575
576  operands[2] = GEN_INT (hi);
577  operands[3] = GEN_INT (lo);
578}")
579
580(define_split
581  [(set (match_operand:SI 0 "register_operand" "")
582        (match_operand:SI 1 "immediate_operand" ""))]
583  "mep_split_mov (operands, 1)"
584  [(set (match_dup 0) (high:SI (match_dup 1)))
585   (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))]
586  "")
587
588;; ??? What purpose do these two serve that high+lo_sum do not?
589(define_insn "movsi_topsym_u"
590  [(set (match_operand:SI 0 "register_operand" "=r")
591	(and:SI (match_operand:SI 1 "symbolic_operand" "s")
592		(const_int -65536)))]
593  ""
594  "movh\\t%0, %%uhi(%1)"
595  [(set_attr "length" "4")])
596
597(define_insn "movsi_botsym_u"
598  [(set (match_operand:SI 0 "register_operand" "=r")
599	(ior:SI (match_operand:SI 1 "register_operand" "0")
600		(and:SI (match_operand:SI 2 "symbolic_operand" "s")
601			(const_int 65535))))]
602  ""
603  "or3\\t%0, %1, %%lo(%2)"
604  [(set_attr "length" "4")])
605
606(define_expand "movdi"
607  [(set (match_operand:DI 0 "" "")
608	(match_operand:DI 1 "" ""))]
609  ""
610  "
611{
612  if (mep_expand_mov (operands, DImode))
613    DONE;
614}")
615
616(define_insn "*movdi_internal_32"
617  [(set (match_operand:DI 0 "mep_movdest_operand" "= r,m,r,c,r,er,ex,em,U")
618	(match_operand:DI 1 "general_operand"     "rim,r,c,r,er,r,ex,U,em"))]
619  "TARGET_32BIT_CR_REGS && mep_mov_ok (operands, DImode)"
620  "#"
621  [(set_attr "slot" "multi")])
622
623(define_insn "*movdi_internal_64"
624  [(set (match_operand:DI 0 "mep_movdest_operand" "=r,r,m,r,c,r,er,ex,em,U")
625	(match_operand:DI 1 "general_operand"     "r,im,r,c,r,er,r,ex,U,em"))]
626  "TARGET_64BIT_CR_REGS && mep_mov_ok (operands, DImode)"
627  "@
628   #
629   #
630   #
631   #
632   #
633   #
634   #
635   %<\\t%0, %M1
636   lmcp\\t%0, %1
637   smcp\\t%1, %0"
638  [(set_attr "slot"  "multi,multi,multi,multi,multi,multi,multi,*,*,*")
639   (set_attr "intrinsic" "*,*,*,*,*,*,*,cmov,*,*")
640   (set_attr "memop" "*,*,*,*,*,*,*,cop0,cop1,cop0")
641   (set_attr "stall" "*,*,*,*,*,*,*,*,load,store")])
642
643(define_insn "*movdi_cop_postinc"
644  [(parallel [(set (match_operand:DI 0 "register_operand" "=em")
645		   (mem:DI (reg:SI SP_REGNO)))
646	      (set (reg:SI SP_REGNO)
647		   (plus:SI (reg:SI SP_REGNO)
648			    (const_int 8)))
649	      ]
650	     )]
651  "TARGET_COP"
652  "lmcpi\\t%0,($sp+)"
653  [(set_attr "length" "2")])
654
655(define_insn "*movdi_cop_postinc"
656  [(parallel [(set (match_operand:DI 0 "register_operand" "=em")
657		   (mem:DI (match_operand:SI 2 "register_operand" "r")))
658	      (set (match_operand:SI 1 "register_operand" "=0")
659		   (plus:SI (match_operand:SI 3 "register_operand" "0")
660			    (const_int 8)))
661	      ]
662	     )]
663  "TARGET_COP"
664  "lmcpi\\t%0,(%1+)"
665  [(set_attr "length" "2")])
666
667(define_insn "*cmovh_set"
668  [(set (zero_extract:SI (match_operand:DI 0 "register_operand" "+er")
669			 (const_int 32)
670			 (const_int 32))
671	(match_operand:SI 1 "register_operand" "r"))]
672  "TARGET_64BIT_CR_REGS"
673  "cmovh\\t%0, %1"
674  [(set_attr "intrinsic" "cmovh1")
675   (set_attr "length" "4")])
676
677(define_insn "cmovh_get"
678  [(set (match_operand:SI 0 "register_operand" "=r")
679	(zero_extract:SI (match_operand:DI 1 "register_operand" "er")
680			 (const_int 32)
681			 (const_int 32)))]
682  "TARGET_64BIT_CR_REGS"
683  "cmovh\\t%0, %1"
684  [(set_attr "intrinsic" "cmovh2")
685   (set_attr "length" "4")])
686
687(define_split
688  [(set (match_operand:DI 0 "mep_movdest_operand" "")
689        (match_operand:DI 1 "general_operand" ""))]
690  "reload_completed && mep_multi_slot (insn)"
691  [(set (match_dup 2) (match_dup 3))
692   (set (match_dup 4) (match_dup 5))]
693  "mep_split_wide_move (operands, DImode);")
694
695;; Floating Point Moves
696
697(define_expand "movsf"
698  [(set (match_operand:SF 0 "nonimmediate_operand" "")
699	(match_operand:SF 1 "general_operand" ""))]
700  ""
701  "
702{
703  if (mep_expand_mov (operands, SFmode))
704    DONE;
705}")
706
707(define_insn "*movsf_tprel_load"
708  [(set (match_operand:SF 0 "mep_tprel_operand" "=t,*r")
709	(mem:SF (plus:SI (match_operand:SI 1 "mep_tp_operand" "b,*r")
710			 (const:SI (unspec:SI [(match_operand:SI 2
711						"symbolic_operand" "s,s")]
712					      UNS_TPREL)))))]
713  ""
714  "lw\\t%0, %%tpoff(%2)(%1)"
715  [(set_attr "length" "2,4")
716   (set_attr "stall" "load")])
717
718(define_insn "*movsf_tprel_store"
719  [(set (mem:SF (plus:SI (match_operand:SI 0 "mep_tp_operand" "b,*r")
720			 (const:SI (unspec:SI [(match_operand:SI 1
721						"symbolic_operand" "s,s")]
722					      UNS_TPREL))))
723	(match_operand:SF 2 "mep_tprel_operand" "t,*r"))]
724  ""
725  "sw\\t%2, %%tpoff(%1)(%0)"
726  [(set_attr "length" "2,4")
727   (set_attr "stall" "store")])
728
729(define_insn "*movsf_internal"
730  [(set (match_operand:SF 0 "mep_movdest_operand"
731	    "=r,r,r,r,Z,m,r,c,r,y,r,er,ex,em,U")
732	(match_operand:SF 1 "general_operand"
733	    " r,F,Z,m,r,r,c,r,y,r,er,r,ex,U,em"))]
734  "mep_mov_ok (operands, SFmode)"
735  "@
736   mov\\t%0, %1
737   #
738   ldcb\\t%0, %1
739   lw\\t%0, %1
740   stcb\\t%1, %0
741   sw\\t%1, %0
742   ldc\\t%0, %1
743   stc\\t%1, %0
744   cmovc\\t%0, %1
745   cmovc\\t%0, %1
746   cmov\\t%0, %1
747   cmov\\t%0, %1
748   %<\\t%0, %M1
749   lwcp\\t%0, %1
750   swcp\\t%1, %0"
751  [(set_attr "length" "2,*,2,*,2,*,2,2,*,*,4,4,*,*,*")
752   (set_attr "intrinsic" "*,*,*,*,*,*,*,*,cmovc2,cmovc1,cmov2,cmov1,cmov,*,*")
753   (set_attr "stall"  "*,*,ldcb,load,stcb,store,ldc,stc,*,*,*,*,*,load,store")
754   (set_attr "memop"  "*,*,*,core1,*,core0,*,*,*,*,*,*,*,cop1,cop0")])
755
756(define_split
757  [(set (match_operand:SF 0 "register_operand" "")
758        (match_operand:SF 1 "const_double_operand" ""))]
759  "reload_completed"
760  [(const_int 0)]
761  "
762{
763  HOST_WIDE_INT value;
764  HOST_WIDE_INT lo, hi;
765  rtx out;
766
767  REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), value);
768
769  lo = value & 0xffff;
770  hi = trunc_int_for_mode (value & 0xffff0000, SImode);
771
772  out = gen_rtx_REG (SImode, REGNO (operands[0]));
773  emit_move_insn (out, GEN_INT (hi));
774  if (lo != 0)
775    emit_insn (gen_iorsi3 (out, out, GEN_INT (lo)));
776  DONE;
777}")
778
779(define_expand "movdf"
780  [(set (match_operand:DF 0 "" "")
781	(match_operand:DF 1 "" ""))]
782  ""
783  "
784{
785  if (mep_expand_mov (operands, DFmode))
786    DONE;
787}")
788
789(define_insn "*movdf_internal_32"
790  [(set (match_operand:DF 0 "mep_movdest_operand" "= r,m,r,c,r,er,ex,em,U")
791	(match_operand:DF 1 "general_operand"     "rFm,r,c,r,er,r,ex,U,em"))]
792  "TARGET_32BIT_CR_REGS && mep_mov_ok (operands, DFmode)"
793  "#"
794  [(set_attr "slot" "multi")])
795
796(define_insn "*movdf_internal_64"
797  [(set (match_operand:DF 0 "mep_movdest_operand" "= r,m,r,c,r,er,ex,em,U")
798	(match_operand:DF 1 "general_operand"     "rFm,r,c,r,er,r,ex,U,em"))]
799  "TARGET_64BIT_CR_REGS && mep_mov_ok (operands, DFmode)"
800  "@
801   #
802   #
803   #
804   #
805   #
806   #
807   %<\\t%0, %M1
808   lmcp\\t%0, %1
809   smcp\\t%1, %0"
810  [(set_attr "slot"  "multi,multi,multi,multi,multi,multi,*,*,*")
811   (set_attr "intrinsic" "*,*,*,*,*,*,cmov,*,*")
812   (set_attr "memop" "*,*,*,*,*,*,*,cop1,cop0")
813   (set_attr "stall" "*,*,*,*,*,*,*,load,store")])
814
815(define_split
816  [(set (match_operand:DF 0 "mep_movdest_operand" "")
817        (match_operand:DF 1 "general_operand" ""))]
818  "reload_completed && mep_multi_slot (insn)"
819  [(set (match_dup 2) (match_dup 3))
820   (set (match_dup 4) (match_dup 5))]
821  "mep_split_wide_move (operands, DFmode);")
822
823
824(define_insn "*lbcpa"
825  [(set (match_operand:SI 0 "register_operand" "=em")
826	(sign_extend:SI (mem:QI (match_operand:SI 2 "register_operand" "1"))))
827   (set (match_operand:SI 1 "register_operand" "=r")
828	(plus:SI (match_dup 2)
829		 (match_operand:SI 3 "cgen_h_sint_8a1_immediate" "")))]
830  "TARGET_COP && reload_completed"
831  "lbcpa\t%0, (%1+), %3"
832  [(set_attr "length" "4")
833   (set_attr "stall" "load")])
834
835(define_insn "*sbcpa"
836  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
837	(match_operand:QI 2 "register_operand" "em"))
838   (set (match_operand:SI 0 "register_operand" "=r")
839	(plus:SI (match_dup 1)
840		 (match_operand:SI 3 "cgen_h_sint_8a1_immediate" "")))]
841  "TARGET_COP && reload_completed"
842  "sbcpa\t%2, (%0+), %3"
843  [(set_attr "length" "4")
844   (set_attr "stall" "store")])
845
846(define_insn "*lhcpa"
847  [(set (match_operand:SI 0 "register_operand" "=em")
848	(sign_extend:SI (mem:HI (match_operand:SI 2 "register_operand" "1"))))
849   (set (match_operand:SI 1 "register_operand" "=r")
850	(plus:SI (match_dup 2)
851		 (match_operand:SI 3 "cgen_h_sint_7a2_immediate" "")))]
852  "TARGET_COP && reload_completed"
853  "lhcpa\t%0, (%1+), %3"
854  [(set_attr "length" "4")
855   (set_attr "stall" "load")])
856
857(define_insn "*shcpa"
858  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
859	(match_operand:HI 2 "register_operand" "em"))
860   (set (match_operand:SI 0 "register_operand" "=r")
861	(plus:SI (match_dup 1)
862		 (match_operand:SI 3 "cgen_h_sint_7a2_immediate" "")))]
863  "TARGET_COP && reload_completed"
864  "shcpa\t%2, (%0+), %3"
865  [(set_attr "length" "4")
866   (set_attr "stall" "store")])
867
868(define_insn "*lwcpi"
869  [(set (match_operand:SI 0 "register_operand" "=em")
870	(mem:SI (match_operand:SI 2 "register_operand" "1")))
871   (set (match_operand:SI 1 "register_operand" "=r")
872	(plus:SI (match_dup 2)
873		 (const_int 4)))]
874  "TARGET_COP && reload_completed"
875  "lwcpi\t%0, (%1+)"
876  [(set_attr "length" "2")
877   (set_attr "stall" "load")])
878
879(define_insn "*lwcpa"
880  [(set (match_operand:SI 0 "register_operand" "=em")
881	(mem:SI (match_operand:SI 2 "register_operand" "1")))
882   (set (match_operand:SI 1 "register_operand" "=r")
883	(plus:SI (match_dup 2)
884		 (match_operand:SI 3 "cgen_h_sint_6a4_immediate" "")))]
885  "TARGET_COP && reload_completed"
886  "lwcpa\t%0, (%1+), %3"
887  [(set_attr "length" "4")
888   (set_attr "stall" "load")])
889
890(define_insn "*swcpi"
891  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
892	(match_operand:SI 2 "register_operand" "em"))
893   (set (match_operand:SI 0 "register_operand" "=r")
894	(plus:SI (match_dup 1)
895		 (const_int 4)))]
896  "TARGET_COP && reload_completed"
897  "swcpi\t%2, (%0+)"
898  [(set_attr "length" "2")
899   (set_attr "stall" "store")])
900
901(define_insn "*swcpa"
902  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
903	(match_operand:SI 2 "register_operand" "em"))
904   (set (match_operand:SI 0 "register_operand" "=r")
905	(plus:SI (match_dup 1)
906		 (match_operand:SI 3 "cgen_h_sint_6a4_immediate" "")))]
907  "TARGET_COP && reload_completed"
908  "swcpa\t%2, (%0+), %3"
909  [(set_attr "length" "4")
910   (set_attr "stall" "store")])
911
912(define_peephole2
913  [(set (match_operand:SI 0 "register_operand" "")
914	(plus:SI (match_dup 0)
915		 (match_operand:SI 1 "cgen_h_sint_8a1_immediate" "")))]
916  "TARGET_COP && mep_use_post_modify_p (insn, operands[0], operands[1])"
917  [(const_int 0)]
918{
919  emit_note (NOTE_INSN_DELETED);
920  DONE;
921})
922
923;; ::::::::::::::::::::
924;; ::
925;; :: Reloads
926;; ::
927;; ::::::::::::::::::::
928
929(define_expand "reload_insi"
930  [(set (match_operand:SI 0 "mep_reload_operand" "")
931        (match_operand:SI 1 "mep_reload_operand" "r"))
932   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
933  ""
934  "
935{
936  mep_expand_reload (operands, SImode);
937  DONE;
938}")
939
940(define_expand "reload_outsi"
941  [(set (match_operand:SI 0 "mep_reload_operand" "=r")
942        (match_operand:SI 1 "mep_reload_operand" ""))
943   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
944  ""
945  "
946{
947  mep_expand_reload (operands, SImode);
948  DONE;
949}")
950
951
952;; ::::::::::::::::::::
953;; ::
954;; :: Conversions
955;; ::
956;; ::::::::::::::::::::
957
958(define_insn "extendqisi2"
959  [(set (match_operand:SI 0 "register_operand" "=r,r,em")
960	(sign_extend:SI
961	  (match_operand:QI 1 "nonimmediate_operand" "0,m,Y")))]
962  ""
963  "@
964   extb\\t%0
965   lb\\t%0, %1
966   lbcpa\\t%0, %P1"
967  [(set_attr "length" "2,*,*")
968   (set_attr "stall"  "*,load,load")
969   (set_attr "memop"  "*,core1,cop1")])
970
971(define_insn "extendhisi2"
972  [(set (match_operand:SI 0 "register_operand" "=r,r,em")
973	(sign_extend:SI
974	  (match_operand:HI 1 "nonimmediate_operand" "0,m,Y")))]
975  ""
976  "@
977   exth\\t%0
978   lh\\t%0, %1
979   lhcpa\\t%0, %P1"
980  [(set_attr "length" "2,*,*")
981   (set_attr "stall"  "*,load,load")
982   (set_attr "memop"  "*,core1,cop1")])
983
984(define_insn "zero_extendqisi2"
985  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
986	(zero_extend:SI
987	  (match_operand:QI 1 "nonimmediate_operand" "0,r,m")))]
988  ""
989  "@
990   extub\\t%0
991   and3\\t%0, %1, 255
992   lbu\\t%0, %1"
993  [(set_attr "length" "2,4,*")
994   (set_attr "stall" "*,*,load")
995   (set_attr "memop"  "*,*,core1")])
996
997(define_insn "zero_extendhisi2"
998  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
999	(zero_extend:SI
1000	  (match_operand:HI 1 "nonimmediate_operand" "0,r,m")))]
1001  ""
1002  "@
1003   extuh\\t%0
1004   and3\\t%0, %1, 65535
1005   lhu\\t%0, %1"
1006  [(set_attr "length" "2,4,*")
1007   (set_attr "stall" "*,*,load")
1008   (set_attr "memop"  "*,*,core1")])
1009
1010;; ::::::::::::::::::::
1011;; ::
1012;; :: 32 bit Integer arithmetic
1013;; ::
1014;; ::::::::::::::::::::
1015
1016(define_insn "addsi3"
1017  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1018	(plus:SI (match_operand:SI 1 "register_operand" "%r,0,r")
1019		 (match_operand:SI 2 "mep_add_operand" "r,L,IT")))]
1020  ""
1021  "@
1022   add3\\t%0, %1, %2
1023   add\\t%0, %2
1024   add3\\t%0, %1, %I2"
1025  [(set (attr "length")
1026	(if_then_else (eq_attr "alternative" "2")
1027	  (if_then_else (and (match_operand:SI 1 "mep_sp_operand" "")
1028			     (match_operand:SI 2 "mep_imm7a4_operand" ""))
1029	    (const_int 2)
1030	    (const_int 4))
1031	  (const_int 2)))])
1032
1033;; The intention here is to combine the 16-bit add with the 16-bit
1034;; move to create a 32-bit add.  It's the same size, but takes one
1035;; less machine cycle.  It will happen to match a 32-bit add with a
1036;; 16-bit move also, but gcc shouldn't be doing that ;)
1037(define_peephole2
1038  [(set (match_operand:SI 0 "register_operand" "")
1039	(plus:SI (match_operand:SI 1 "register_operand" "")
1040		 (match_operand:SI 2 "immediate_operand" "")))
1041   (set (match_operand:SI 3 "register_operand" "")
1042	(match_operand:SI 4 "register_operand" ""))]
1043  "REGNO (operands[0]) == REGNO (operands[1])
1044   && REGNO (operands[0]) == REGNO (operands[4])
1045   && GR_REGNO_P (REGNO (operands[3]))
1046   && dead_or_set_p (peep2_next_insn (1), operands[4])"
1047  [(set (match_dup 3)
1048	(plus:SI (match_dup 1)
1049		 (match_dup 2)))]
1050  "")
1051
1052(define_insn "subsi3"
1053  [(set (match_operand:SI 0 "register_operand" "=r")
1054	(minus:SI (match_operand:SI 1 "register_operand" "0")
1055		  (match_operand:SI 2 "register_operand" "r")))]
1056  ""
1057  "sub\\t%0, %2"
1058  [(set_attr "length" "2")])
1059
1060(define_expand "mulsi3"
1061  [(set (match_operand:SI 0 "register_operand" "")
1062        (mult:SI (match_operand:SI 1 "register_operand" "")
1063                 (match_operand:SI 2 "register_operand" "")))]
1064  "TARGET_OPT_MULT || TARGET_COPRO_MULT"
1065{
1066  emit_insn (gen_mulsi3_1 (operands[0], operands[1], operands[2]));
1067  DONE;
1068})
1069
1070;; Generated by mep_reuse_lo_p when no GPR destination is needed.
1071(define_insn "mulsi3_lo"
1072  [(set (match_operand:SI 0 "mep_lo_operand" "=l")
1073	(mult:SI (match_operand:SI 1 "register_operand" "r")
1074		 (match_operand:SI 2 "register_operand" "r")))
1075   (clobber (match_scratch:SI 3 "=h"))]
1076  "TARGET_OPT_MULT && reload_completed"
1077  "mul\\t%1, %2"
1078  [(set_attr "length" "2")
1079   (set_attr "stall" "mul")])
1080
1081;; Generated by mep_reuse_lo_p when both destinations of a mulr
1082;; are needed.
1083(define_insn "mulsi3r"
1084  [(set (match_operand:SI 0 "mep_lo_operand" "=l")
1085	(mult:SI (match_operand:SI 2 "register_operand" "1")
1086		 (match_operand:SI 3 "register_operand" "r")))
1087   (set (match_operand:SI 1 "register_operand" "=r")
1088	(mult:SI (match_dup 2)
1089		 (match_dup 3)))
1090   (clobber (match_scratch:SI 4 "=h"))]
1091  "TARGET_OPT_MULT && reload_completed"
1092  "mulr\\t%2, %3"
1093  [(set_attr "length" "2")
1094   (set_attr "stall" "mulr")])
1095
1096(define_insn "mulsi3_1"
1097  [(set (match_operand:SI 0 "register_operand" "=r")
1098	(mult:SI (match_operand:SI 1 "register_operand" "%0")
1099		 (match_operand:SI 2 "register_operand" "r")))
1100   (clobber (match_scratch:SI 3 "=l"))
1101   (clobber (match_scratch:SI 4 "=h"))]
1102  "TARGET_OPT_MULT"
1103  "mulr\\t%1, %2"
1104  [(set_attr "length" "2")
1105   (set_attr "stall" "mulr")])
1106
1107(define_expand "mulsidi3"
1108  [(set (match_operand:DI 0 "register_operand" "")
1109	(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1110		 (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))]
1111  "TARGET_OPT_MULT"
1112  "
1113{
1114  rtx hi = gen_reg_rtx (SImode);
1115  rtx lo = gen_reg_rtx (SImode);
1116
1117  emit_insn (gen_mulsidi3_i (hi, lo, operands[1], operands[2]));
1118  emit_move_insn (gen_lowpart (SImode, operands[0]), lo);
1119  emit_move_insn (gen_highpart (SImode, operands[0]), hi);
1120  DONE;
1121}")
1122
1123(define_insn "mulsidi3_i"
1124  [(set (match_operand:SI 0 "mep_hi_operand" "=h")
1125	(truncate:SI
1126	 (lshiftrt:DI
1127	  (mult:DI (sign_extend:DI
1128		    (match_operand:SI 2 "register_operand" "r"))
1129		   (sign_extend:DI
1130		    (match_operand:SI 3 "register_operand" "r")))
1131	  (const_int 32))))
1132   (set (match_operand:SI 1 "mep_lo_operand" "=l")
1133	(mult:SI (match_dup 2)
1134		 (match_dup 3)))]
1135  "TARGET_OPT_MULT"
1136  "mul\\t%2, %3"
1137  [(set_attr "length" "2")
1138   (set_attr "stall" "mul")])
1139
1140(define_insn "smulsi3_highpart"
1141  [(set (match_operand:SI 0 "mep_hi_operand" "=h")
1142	(truncate:SI
1143	 (lshiftrt:DI
1144	  (mult:DI (sign_extend:DI
1145		    (match_operand:SI 1 "register_operand" "r"))
1146		   (sign_extend:DI
1147		    (match_operand:SI 2 "register_operand" "r")))
1148	  (const_int 32))))
1149   (clobber (reg:SI LO_REGNO))]
1150  "TARGET_OPT_MULT"
1151  "mul\\t%1, %2"
1152  [(set_attr "length" "2")
1153   (set_attr "stall" "mul")])
1154
1155(define_expand "umulsidi3"
1156  [(set (match_operand:DI 0 "mep_hi_operand" "")
1157	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1158		 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))]
1159  "TARGET_OPT_MULT"
1160  "
1161{
1162  rtx hi = gen_reg_rtx (SImode);
1163  rtx lo = gen_reg_rtx (SImode);
1164
1165  emit_insn (gen_umulsidi3_i (hi, lo, operands[1], operands[2]));
1166  emit_move_insn (gen_lowpart (SImode, operands[0]), lo);
1167  emit_move_insn (gen_highpart (SImode, operands[0]), hi);
1168  DONE;
1169}")
1170
1171(define_insn "umulsidi3_i"
1172  [(set (match_operand:SI 0 "mep_hi_operand" "=h")
1173	(truncate:SI
1174	 (lshiftrt:DI
1175	  (mult:DI (zero_extend:DI
1176		    (match_operand:SI 2 "register_operand" "r"))
1177		   (zero_extend:DI
1178		    (match_operand:SI 3 "register_operand" "r")))
1179	  (const_int 32))))
1180   (set (match_operand:SI 1 "mep_lo_operand" "=l")
1181	(mult:SI (match_dup 2)
1182		 (match_dup 3)))]
1183  "TARGET_OPT_MULT"
1184  "mulu\\t%2, %3"
1185  [(set_attr "length" "2")
1186   (set_attr "stall" "mul")])
1187
1188(define_insn "umulsi3_highpart"
1189  [(set (match_operand:SI 0 "mep_hi_operand" "=h")
1190	(truncate:SI
1191	 (lshiftrt:DI
1192	  (mult:DI (zero_extend:DI
1193		    (match_operand:SI 1 "register_operand" "r"))
1194		   (zero_extend:DI
1195		    (match_operand:SI 2 "register_operand" "r")))
1196	  (const_int 32))))
1197   (clobber (reg:SI LO_REGNO))]
1198  "TARGET_OPT_MULT"
1199  "mulu %1, %2"
1200  [(set_attr "length" "2")
1201   (set_attr "stall" "mul")])
1202
1203;; These two don't currently match because we don't have an adddi3 pattern.
1204(define_insn "*smultdi_and_add"
1205  [(set (match_operand:DI 0 "mep_hi_operand" "=d")
1206	(plus:DI (mult:DI (zero_extend:DI
1207			   (match_operand:SI 1 "register_operand" "r"))
1208			  (zero_extend:DI
1209			   (match_operand:SI 2 "register_operand" "r")))
1210		 (match_operand:DI 3 "mep_hi_operand" "0")))]
1211  "TARGET_OPT_MULT && TARGET_BIG_ENDIAN"
1212  "maddu\\t%1, %2"
1213  [(set_attr "length" "4")
1214   (set_attr "stall" "mul")])
1215
1216(define_insn "*umultdi_and_add"
1217  [(set (match_operand:DI 0 "mep_hi_operand" "=d")
1218	(plus:DI (mult:DI (sign_extend:DI
1219			   (match_operand:SI 1 "register_operand" "r"))
1220			  (sign_extend:DI
1221			   (match_operand:SI 2 "register_operand" "r")))
1222		 (match_operand:DI 3 "mep_hi_operand" "0")))]
1223  "TARGET_OPT_MULT && TARGET_BIG_ENDIAN"
1224  "madd\\t%1, %2"
1225  [(set_attr "length" "4")
1226   (set_attr "stall" "mul")])
1227
1228;; A pattern for 'r1 = r2 * r3 + r4'.  There are three possible
1229;; implementations:
1230;;
1231;;    (1) 'mulr;add3'.  This is usually the best choice if the instruction
1232;;	  is not part of a natural multiply-accumulate chain.  It has the
1233;;	  same latency as 'stc;maddr' but doesn't tie up $lo for as long.
1234;;
1235;;    (2) 'madd'.  This is the best choice if the instruction is in the
1236;;	  middle of a natural multiply-accumulate chain.  r4 will already
1237;;	  be in $lo and r1 will also be needed in $lo.
1238;;
1239;;    (3) 'maddr'.  This is the best choice if the instruction is at the
1240;;	  end of a natural multiply-accumulate chain.  r4 will be in $lo
1241;;	  but r1 will be needed in a GPR.
1242;;
1243;; In theory, we could put all the alternatives into a single pattern and
1244;; leave the register allocator to choose between them.  However, this can
1245;; sometimes produce poor results in practice.
1246;;
1247;; This pattern therefore describes a general GPR-to-GPR operation that
1248;; has a slight preference for cases in which operands 0 and 1 are tied.
1249;; After reload, we try to rewrite the patterns using peephole2s (if
1250;; enabled), falling back on define_splits if that fails.  See also
1251;; mep_reuse_lo_p.
1252(define_insn "maddsi3"
1253  [(set (match_operand:SI 0 "register_operand" "=r,r")
1254	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%0,r")
1255			  (match_operand:SI 2 "register_operand" "r,r"))
1256		 (match_operand:SI 3 "register_operand" "r,r")))
1257   (clobber (match_scratch:SI 4 "=l,l"))
1258   (clobber (match_scratch:SI 5 "=h,h"))]
1259  "TARGET_OPT_MULT"
1260  "#"
1261  [(set_attr "length" "8")
1262   (set_attr "stall" "mulr")])
1263
1264;; Implement maddsi3s using maddr if operand 3 is already available in $lo.
1265(define_peephole2
1266  [(parallel
1267	[(set (match_operand:SI 0 "register_operand" "")
1268	      (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1269				(match_operand:SI 2 "register_operand" ""))
1270		       (match_operand:SI 3 "register_operand" "")))
1271	 (clobber (match_scratch:SI 4 ""))
1272	 (clobber (match_scratch:SI 5 ""))])]
1273  "TARGET_OPT_MULT
1274   && reload_completed
1275   && mep_reuse_lo_p (operands[4], operands[3], insn,
1276		      !rtx_equal_p (operands[1], operands[3])
1277		      && !rtx_equal_p (operands[2], operands[3])
1278		      && (rtx_equal_p (operands[0], operands[3])
1279			  || peep2_reg_dead_p (1, operands[3])))"
1280  [(parallel
1281	[(set (match_dup 4)
1282	      (plus:SI (mult:SI (match_dup 0)
1283			        (match_dup 2))
1284		       (match_dup 4)))
1285	 (set (match_dup 0)
1286	      (plus:SI (mult:SI (match_dup 0)
1287				(match_dup 2))
1288		       (match_dup 4)))
1289	 (clobber (match_dup 5))])]
1290  "operands[2] = mep_mulr_source (0, operands[0], operands[1], operands[2]);")
1291
1292;; This splitter implements maddsi3 as "mulr;add3".  It only works if
1293;; operands 0 and 3 are distinct, since operand 0 is clobbered before
1294;; operand 3 is used.
1295(define_split
1296  [(set (match_operand:SI 0 "register_operand" "")
1297	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1298			  (match_operand:SI 2 "register_operand" ""))
1299		 (match_operand:SI 3 "register_operand" "")))
1300   (clobber (match_scratch:SI 4 ""))
1301   (clobber (match_scratch:SI 5 ""))]
1302  "TARGET_OPT_MULT
1303   && reload_completed
1304   && !rtx_equal_p (operands[0], operands[3])"
1305  [(parallel [(set (match_dup 0)
1306		   (mult:SI (match_dup 0)
1307			    (match_dup 2)))
1308	      (clobber (match_dup 4))
1309	      (clobber (match_dup 5))])
1310   (set (match_dup 0)
1311	(plus:SI (match_dup 0)
1312		 (match_dup 3)))]
1313  "operands[2] = mep_mulr_source (0, operands[0], operands[1], operands[2]);")
1314
1315;; This is the fallback splitter for maddsi3.  It moves operand 3 into
1316;; $lo and then uses maddr.
1317(define_split
1318  [(set (match_operand:SI 0 "register_operand" "")
1319	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1320			  (match_operand:SI 2 "register_operand" ""))
1321		 (match_operand:SI 3 "register_operand" "")))
1322   (clobber (match_scratch:SI 4 ""))
1323   (clobber (match_scratch:SI 5 ""))]
1324  "TARGET_OPT_MULT
1325   && reload_completed"
1326  [(parallel [(set (match_dup 4)
1327		   (plus:SI (mult:SI (match_dup 0)
1328				     (match_dup 2))
1329			    (match_dup 4)))
1330	      (set (match_dup 0)
1331		   (plus:SI (mult:SI (match_dup 0)
1332				     (match_dup 2))
1333			    (match_dup 4)))
1334	      (clobber (match_dup 5))])]
1335{
1336  emit_move_insn (operands[4], operands[3]);
1337  operands[2] = mep_mulr_source (0, operands[0], operands[1], operands[2]);
1338})
1339
1340;; Remove unnecessary stcs to $lo.  This cleans up the moves generated
1341;; by earlier calls to mep_reuse_lo_p.
1342(define_peephole2
1343  [(set (match_operand:SI 0 "mep_lo_operand" "")
1344	(match_operand:SI 1 "register_operand" ""))]
1345  "TARGET_OPT_MULT
1346   && mep_reuse_lo_p (operands[0], operands[1], insn,
1347		      peep2_reg_dead_p (1, operands[1]))"
1348  [(const_int 0)]
1349{
1350  emit_note (NOTE_INSN_DELETED);
1351  DONE;
1352})
1353
1354(define_insn "maddsi3_lo"
1355  [(set (match_operand:SI 0 "mep_lo_operand" "=l")
1356	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
1357			  (match_operand:SI 2 "register_operand" "r"))
1358		 (match_operand:SI 3 "mep_lo_operand" "0")))
1359   (clobber (match_scratch:SI 4 "=h"))]
1360  "TARGET_OPT_MULT && reload_completed"
1361  "madd\\t%1, %2"
1362  [(set_attr "length" "4")
1363   (set_attr "stall" "mul")])
1364
1365(define_insn "maddsi3r"
1366  [(set (match_operand:SI 0 "mep_lo_operand" "=l")
1367	(plus:SI (mult:SI (match_operand:SI 2 "register_operand" "1")
1368			  (match_operand:SI 3 "register_operand" "r"))
1369		 (match_operand:SI 4 "register_operand" "0")))
1370   (set (match_operand:SI 1 "register_operand" "=r")
1371	(plus:SI (mult:SI (match_dup 2)
1372			  (match_dup 3))
1373		 (match_dup 4)))
1374   (clobber (match_scratch:SI 5 "=h"))]
1375  "TARGET_OPT_MULT && reload_completed"
1376  "maddr\\t%2, %3"
1377  [(set_attr "length" "4")
1378   (set_attr "stall" "mulr")])
1379
1380(define_insn "*shift_1_or_2_and_add"
1381  [(set (match_operand:SI 0 "mep_r0_operand" "=z")
1382	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
1383			  (match_operand:SI 2 "mep_slad_operand" "n"))
1384		 (match_operand:SI 3 "register_operand" "r")))]
1385  ""
1386  "sl%b2ad3\\t%0, %1, %3"
1387  [(set_attr "length" "2")
1388   (set_attr "stall" "int2")])
1389
1390(define_insn "divmodsi4"
1391  [(set (match_operand:SI 0 "mep_lo_operand" "=l")
1392	(div:SI (match_operand:SI 1 "register_operand" "r")
1393		(match_operand:SI 2 "register_operand" "r")))
1394   (set (match_operand:SI 3 "mep_hi_operand" "=h")
1395	(mod:SI (match_dup 1)
1396		(match_dup 2)))]
1397  "TARGET_OPT_DIV"
1398  "div\\t%1, %2"
1399  [(set_attr "length" "2")
1400   (set_attr "stall" "div")
1401   (set_attr "may_trap" "yes")])
1402
1403(define_insn "udivmodsi4"
1404  [(set (match_operand:SI 0 "mep_lo_operand" "=l")
1405	(udiv:SI (match_operand:SI 1 "register_operand" "r")
1406		 (match_operand:SI 2 "register_operand" "r")))
1407   (set (match_operand:SI 3 "mep_hi_operand" "=h")
1408	(umod:SI (match_dup 1)
1409		(match_dup 2)))]
1410  "TARGET_OPT_DIV"
1411  "divu\\t%1, %2"
1412  [(set_attr "length" "2")
1413   (set_attr "stall" "div")
1414   (set_attr "may_trap" "yes")])
1415
1416(define_insn "negsi2"
1417  [(set (match_operand:SI 0 "register_operand" "=r")
1418	(neg:SI (match_operand:SI 1 "register_operand" "r")))]
1419  ""
1420  "neg\\t%0, %1"
1421  [(set_attr "length" "2")])
1422
1423;; We have "absolute difference between two regs" which isn't quite
1424;; what gcc is expecting.
1425(define_expand "abssi2"
1426  [(set (match_dup 2) (const_int 0))
1427   (set (match_operand:SI 0 "register_operand" "")
1428	(abs:SI (minus:SI (match_operand:SI 1 "register_operand" "")
1429			  (match_dup 2))
1430		))]
1431  "TARGET_OPT_ABSDIFF"
1432  "operands[2] = gen_reg_rtx (SImode);")
1433
1434(define_insn "*absdiff"
1435  [(set (match_operand:SI 0 "register_operand" "=r")
1436	(abs:SI (minus:SI (match_operand:SI 1 "register_operand" "0")
1437			  (match_operand:SI 2 "register_operand" "r"))))]
1438  "TARGET_OPT_ABSDIFF"
1439  "abs\\t%0, %2"
1440  [(set_attr "length" "4")])
1441
1442(define_split
1443  [(set (match_operand:SI 0 "register_operand" "")
1444	(abs:SI (plus:SI (match_operand:SI 1 "register_operand" "")
1445			 (match_operand:SI 2 "immediate_operand" ""))))
1446   (clobber (match_operand:SI 3 "register_operand" ""))]
1447  "!reload_completed"
1448  [(set (match_dup 3)
1449	(match_dup 4))
1450   (set (match_operand:SI 0 "register_operand" "")
1451	(abs:SI (minus:SI (match_operand:SI 1 "register_operand" "")
1452			  (match_dup 3))))]
1453  "operands[4] = GEN_INT (-INTVAL (operands[2]));")
1454
1455(define_insn "sminsi3"
1456  [(set (match_operand:SI 0 "register_operand" "=r")
1457	(smin:SI (match_operand:SI 1 "register_operand" "0")
1458		 (match_operand:SI 2 "nonmemory_operand" "r")))]
1459  "TARGET_OPT_MINMAX"
1460  "min\\t%0, %2"
1461  [(set_attr "length" "4")])
1462
1463(define_insn "smaxsi3"
1464  [(set (match_operand:SI 0 "register_operand" "=r")
1465	(smax:SI (match_operand:SI 1 "register_operand" "0")
1466		 (match_operand:SI 2 "nonmemory_operand" "r")))]
1467  "TARGET_OPT_MINMAX"
1468  "max\\t%0, %2"
1469  [(set_attr "length" "4")])
1470
1471(define_insn "uminsi3"
1472  [(set (match_operand:SI 0 "register_operand" "=r")
1473	(umin:SI (match_operand:SI 1 "register_operand" "0")
1474		 (match_operand:SI 2 "nonmemory_operand" "r")))]
1475  "TARGET_OPT_MINMAX"
1476  "minu\\t%0, %2"
1477  [(set_attr "length" "4")])
1478
1479(define_insn "umaxsi3"
1480  [(set (match_operand:SI 0 "register_operand" "=r")
1481	(umax:SI (match_operand:SI 1 "register_operand" "0")
1482		 (match_operand:SI 2 "nonmemory_operand" "r")))]
1483  "TARGET_OPT_MINMAX"
1484  "maxu\\t%0, %2"
1485  [(set_attr "length" "4")])
1486
1487;; Average:  a = (b+c+1)>>1
1488(define_insn "*averagesi3"
1489  [(set (match_operand:SI 0 "register_operand" "=r")
1490	(ashiftrt:SI (plus:SI (plus:SI
1491				(match_operand:SI 1 "register_operand" "0")
1492				(match_operand:SI 2 "register_operand" "r"))
1493			      (const_int 1))
1494		     (const_int 1)))]
1495  "TARGET_OPT_AVERAGE"
1496  "ave\\t%0, %2"
1497  [(set_attr "length" "4")])
1498
1499;; clip support
1500
1501(define_insn "clip_maxmin"
1502  [(set (match_operand:SI 0 "register_operand" "=r")
1503	(smax:SI (smin:SI (match_operand:SI 1 "register_operand" "0")
1504			  (match_operand:SI 2 "immediate_operand" "n"))
1505		 (match_operand:SI 3 "immediate_operand" "n")))]
1506  "mep_allow_clip (operands[2], operands[3], 1)"
1507  "clip\\t%0, %B2"
1508  [(set_attr "length" "4")])
1509
1510(define_insn "clip_minmax"
1511  [(set (match_operand:SI 0 "register_operand" "=r")
1512	(smin:SI (smax:SI (match_operand:SI 1 "register_operand" "0")
1513			  (match_operand:SI 2 "immediate_operand" "n"))
1514		 (match_operand:SI 3 "immediate_operand" "n")))]
1515  "mep_allow_clip (operands[3], operands[2], 1)"
1516  "clip\\t%0, %B3"
1517  [(set_attr "length" "4")])
1518
1519(define_insn "clipu_maxmin"
1520  [(set (match_operand:SI 0 "register_operand" "=r")
1521	(smax:SI (smin:SI (match_operand:SI 1 "register_operand" "0")
1522			  (match_operand:SI 2 "immediate_operand" "n"))
1523		 (match_operand:SI 3 "immediate_operand" "n")))]
1524  "mep_allow_clip (operands[2], operands[3], 0)"
1525  "clipu\\t%0, %U2"
1526  [(set_attr "length" "4")])
1527
1528(define_insn "clipu_minmax"
1529  [(set (match_operand:SI 0 "register_operand" "=r")
1530	(smin:SI (smax:SI (match_operand:SI 1 "register_operand" "0")
1531			  (match_operand:SI 2 "immediate_operand" "n"))
1532		 (match_operand:SI 3 "immediate_operand" "n")))]
1533  "mep_allow_clip (operands[3], operands[2], 0)"
1534  "clipu\\t%0, %U3"
1535  [(set_attr "length" "4")])
1536
1537;; ::::::::::::::::::::
1538;; ::
1539;; :: 32 bit Integer Shifts and Rotates
1540;; ::
1541;; ::::::::::::::::::::
1542
1543(define_insn "ashlsi3"
1544  [(set (match_operand:SI 0 "register_operand" "=r,z")
1545	(ashift:SI (match_operand:SI 1 "register_operand" "0,r")
1546		   (match_operand:SI 2 "nonmemory_operand" "rM,M")))]
1547  ""
1548  "@
1549   sll\\t%0, %2
1550   sll3\\t%0, %1, %2"
1551  [(set_attr "length" "2,2")
1552   (set_attr "shiftop" "operand2")])
1553
1554(define_insn "ashrsi3"
1555  [(set (match_operand:SI 0 "register_operand" "=r")
1556	(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1557		     (match_operand:SI 2 "nonmemory_operand" "rM")))]
1558  ""
1559  "sra\\t%0, %2"
1560  [(set_attr "length" "2")
1561   (set_attr "shiftop" "operand2")])
1562
1563(define_insn "lshrsi3"
1564  [(set (match_operand:SI 0 "register_operand" "=r")
1565	(lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
1566		     (match_operand:SI 2 "nonmemory_operand" "rM")))]
1567  ""
1568  "srl\\t%0, %2"
1569  [(set_attr "length" "2")
1570   (set_attr "shiftop" "operand2")])
1571
1572;; ::::::::::::::::::::
1573;; ::
1574;; :: 32 Bit Integer Logical operations
1575;; ::
1576;; ::::::::::::::::::::
1577
1578(define_insn "andsi3"
1579  [(set (match_operand:SI 0 "register_operand" "=r,r")
1580	(and:SI (match_operand:SI 1 "register_operand" "%0,r")
1581		(match_operand:SI 2 "nonmemory_operand" "r,J")))]
1582  ""
1583  "@
1584   and\\t%0, %2
1585   and3\\t%0, %1, %J2"
1586  [(set_attr "length" "2,4")])
1587
1588(define_insn "iorsi3"
1589  [(set (match_operand:SI 0 "register_operand" "=r,r")
1590	(ior:SI (match_operand:SI 1 "register_operand" "%0,r")
1591		(match_operand:SI 2 "nonmemory_operand" "r,J")))]
1592  ""
1593  "@
1594   or\\t%0, %2
1595   or3\\t%0, %1, %J2"
1596  [(set_attr "length" "2,4")])
1597
1598(define_insn "xorsi3"
1599  [(set (match_operand:SI 0 "register_operand" "=r,r")
1600	(xor:SI (match_operand:SI 1 "register_operand" "%0,r")
1601		(match_operand:SI 2 "nonmemory_operand" "r,J")))]
1602  ""
1603  "@
1604   xor\\t%0, %2
1605   xor3\\t%0, %1, %J2"
1606  [(set_attr "length" "2,4")])
1607
1608(define_expand "one_cmplsi2"
1609  [(set (match_operand:SI 0 "register_operand" "")
1610	(not:SI (match_operand:SI 1 "register_operand" "")))]
1611  ""
1612  "operands[2] = operands[1];
1613   ")
1614
1615;; No separate insn for this; use NOR
1616(define_insn "*one_cmplsi3_internal"
1617  [(set (match_operand:SI 0 "register_operand" "=r")
1618	(not:SI (match_operand:SI 1 "register_operand" "0")))]
1619  ""
1620  "nor\\t%0, %0"
1621  [(set_attr "length" "2")])
1622
1623;; ::::::::::::::::::::
1624;; ::
1625;; :: Bit Manipulation
1626;; ::
1627;; ::::::::::::::::::::
1628
1629(define_insn "*bitop_be"
1630  [(set (match_operand:QI 0 "mep_Y_operand" "=Y")
1631	(subreg:QI (match_operator:SI 3 "mep_bit_operator"
1632			[(subreg:SI (match_operand:QI 1 "mep_Y_operand" "0") 0)
1633			 (match_operand 2 "immediate_operand" "n")])
1634		   3)
1635	)]
1636  "TARGET_BIG_ENDIAN && TARGET_OPT_BITOPS
1637   && rtx_equal_p (operands[0], operands[1])"
1638  "b%L3m\\t%0, %b2"
1639  [(set_attr "length" "2")])
1640
1641(define_insn "*bitop_le"
1642  [(set (match_operand:QI 0 "mep_Y_operand" "=Y")
1643	(subreg:QI (match_operator:SI 3 "mep_bit_operator"
1644			[(subreg:SI (match_operand:QI 1 "mep_Y_operand" "0") 0)
1645			 (match_operand 2 "immediate_operand" "n")])
1646		   0)
1647	)]
1648  "!TARGET_BIG_ENDIAN && TARGET_OPT_BITOPS
1649   && rtx_equal_p (operands[0], operands[1])"
1650  "b%L3m\\t%0, %b2"
1651  [(set_attr "length" "2")])
1652
1653(define_insn "btstm"
1654  [(set (match_operand:SI 0 "mep_r0_operand" "=z")
1655	(and:SI (subreg:SI (match_operand:QI 1 "mep_Y_operand" "Y") 0)
1656		(match_operand 2 "immediate_operand" "n"))
1657	)]
1658  "TARGET_OPT_BITOPS && mep_bit_position_p (operands[2], 1)"
1659  "btstm\\t%0, %1, %b2"
1660  [(set_attr "length" "2")])
1661
1662(define_insn "tas"
1663  [(parallel [(set (match_operand:SI 0 "mep_r0_operand" "=z")
1664		   (zero_extend:SI (match_operand:QI 1 "mep_Y_operand" "+Y")))
1665	      (set (match_dup 1)
1666		   (const_int 1))
1667	      ]
1668	     )]
1669  "TARGET_OPT_BITOPS"
1670  "tas\\t%0, %1"
1671  [(set_attr "length" "2")])
1672
1673(define_peephole2
1674  [(set (match_operand:SI 0 "mep_r0_operand" "")
1675	(zero_extend:SI (match_operand:QI 1 "mep_Y_operand" "")))
1676   (set (match_operand:QI 2 "register_operand" "")
1677	(const_int 1))
1678   (set (match_dup 1)
1679	(match_dup 2))
1680   ]
1681  "TARGET_OPT_BITOPS"
1682  [(parallel [(set (match_dup 0)
1683		   (zero_extend:SI (match_dup 1)))
1684	      (set (match_dup 1)
1685		   (const_int 1))
1686	      ])]
1687  "")
1688
1689(define_peephole2
1690  [(set (match_operand:SI 0 "mep_r0_operand" "")
1691	(sign_extend:SI (match_operand:QI 1 "mep_Y_operand" "")))
1692   (set (match_operand:QI 2 "register_operand" "")
1693	(const_int 1))
1694   (set (match_dup 1)
1695	(match_dup 2))
1696   ]
1697  "TARGET_OPT_BITOPS"
1698  [(parallel [(set (match_dup 0)
1699		   (zero_extend:SI (match_dup 1)))
1700	      (set (match_dup 1)
1701		   (const_int 1))
1702	      ])
1703   (set (match_dup 0)
1704	(sign_extend:SI (match_dup 3)))]
1705  "operands[3] = gen_lowpart (QImode, operands[0]);")
1706
1707
1708;; ::::::::::::::::::::
1709;; ::
1710;; :: Conditional branches and stores
1711;; ::
1712;; ::::::::::::::::::::
1713
1714(define_expand "cbranchsi4"
1715  [(set (pc)
1716	(if_then_else (match_operator 0 "ordered_comparison_operator"
1717				      [(match_operand:SI 1 "register_operand" "")
1718				       (match_operand:SI 2 "nonmemory_operand" "")])
1719		      (label_ref (match_operand 3 "" ""))
1720		      (pc)))]
1721  ""
1722  "emit_jump_insn (gen_branch_true (operands[3],
1723			       mep_expand_cbranch (operands)));
1724   DONE;")
1725
1726(define_expand "branch_true"
1727  [(set (pc)
1728	(if_then_else (match_operand 1 "" "")
1729		      (label_ref (match_operand 0 "" ""))
1730		      (pc)))]
1731  ""
1732  "")
1733
1734(define_expand "cstoresi4"
1735  [(set (match_operand:SI 0 "register_operand" "")
1736	(match_operator:SI 1 "ordered_comparison_operator"
1737			   [(match_operand:SI 2 "register_operand" "")
1738			    (match_operand:SI 3 "nonmemory_operand" "")]))]
1739  ""
1740  "if (mep_expand_setcc (operands)) DONE; else FAIL;")
1741
1742;; ------------------------------------------------------------
1743
1744(define_insn "*slt"
1745  [(set (match_operand:SI 0 "register_operand" "=z,z,r")
1746	(lt:SI (match_operand:SI 1 "register_operand" "r,r,r")
1747	    (match_operand:SI 2 "nonmemory_operand" "r,M,I")))]
1748  ""
1749  "slt3\\t%0, %1, %2"
1750  [(set_attr "length" "2,2,4")])
1751
1752(define_insn "*sltu"
1753  [(set (match_operand:SI 0 "register_operand" "=z,z,r")
1754	(ltu:SI (match_operand:SI 1 "register_operand" "r,r,r")
1755	     (match_operand:SI 2 "nonmemory_operand" "r,M,J")))]
1756  ""
1757  "sltu3\\t%0, %1, %2"
1758  [(set_attr "length" "2,2,4")])
1759
1760(define_insn "*bcpeq_true"
1761  [(set (pc)
1762	(if_then_else (eq:SI (reg:SI CBCR_REGNO)
1763			     (const_int 0))
1764		      (label_ref (match_operand 0 "" ""))
1765		      (pc)))]
1766  ""
1767  "bcpeq\t0, %l0"
1768  [(set_attr "length" "4")])
1769
1770(define_insn "*bcpeq_false"
1771  [(set (pc)
1772	(if_then_else (eq:SI (reg:SI CBCR_REGNO)
1773			     (const_int 0))
1774		      (pc)
1775		      (label_ref (match_operand 0 "" ""))))]
1776  ""
1777  "bcpne\t0, %l0"
1778  [(set_attr "length" "4")])
1779
1780(define_insn "*bcpne_true"
1781  [(set (pc)
1782	(if_then_else (ne:SI (reg:SI CBCR_REGNO)
1783			     (const_int 0))
1784		      (label_ref (match_operand 0 "" ""))
1785		      (pc)))]
1786  ""
1787  "bcpne\t0, %l0"
1788  [(set_attr "length" "4")])
1789
1790(define_insn "*bcpne_false"
1791  [(set (pc)
1792	(if_then_else (ne:SI (reg:SI CBCR_REGNO)
1793			     (const_int 0))
1794		      (pc)
1795		      (label_ref (match_operand 0 "" ""))))]
1796  ""
1797  "bcpeq\t0, %l0"
1798  [(set_attr "length" "4")])
1799
1800;; ??? The lengths here aren't correct, since no attempt it made to
1801;; find "beqz" in the 256-byte range.  However, this should not affect
1802;; bundling, since we never run core branches in parallel.
1803
1804(define_insn "mep_beq_true"
1805  [(set (pc)
1806	(if_then_else (eq (match_operand:SI 0 "register_operand" "r")
1807			  (match_operand:SI 1 "mep_reg_or_imm4_operand" "rN"))
1808		      (label_ref (match_operand 2 "" ""))
1809		      (pc)))]
1810  ""
1811  "* return mep_emit_cbranch (operands, 0);"
1812  [(set_attr "length" "4")]  )
1813
1814(define_insn "*beq_false"
1815  [(set (pc)
1816	(if_then_else (eq (match_operand:SI 0 "register_operand" "r")
1817			  (match_operand:SI 1 "mep_reg_or_imm4_operand" "rN"))
1818		      (pc)
1819		      (label_ref (match_operand 2 "" ""))))]
1820  ""
1821  "* return mep_emit_cbranch (operands, 1);"
1822  [(set_attr "length" "4")])
1823
1824(define_insn "mep_bne_true"
1825  [(set (pc)
1826	(if_then_else (ne (match_operand:SI 0 "register_operand" "r")
1827			  (match_operand:SI 1 "mep_reg_or_imm4_operand" "rN"))
1828		      (label_ref (match_operand 2 "" ""))
1829		      (pc)))]
1830  ""
1831  "* return mep_emit_cbranch (operands, 1); "
1832  [(set_attr "length" "4")])
1833
1834(define_insn "*bne_false"
1835  [(set (pc)
1836	(if_then_else (ne (match_operand:SI 0 "register_operand" "r")
1837			  (match_operand:SI 1 "mep_reg_or_imm4_operand" "rN"))
1838		      (pc)
1839		      (label_ref (match_operand 2 "" ""))))]
1840  ""
1841  "* return mep_emit_cbranch (operands, 0); "
1842  [(set_attr "length" "4")])
1843
1844(define_insn "mep_blti"
1845  [(set (pc)
1846	(if_then_else (lt (match_operand:SI 0 "register_operand" "r")
1847			  (match_operand:SI 1 "mep_imm4_operand" "N"))
1848		      (label_ref (match_operand 2 "" ""))
1849		      (pc)))]
1850  ""
1851  "blti\\t%0, %1, %l2"
1852  [(set_attr "length" "4")])
1853
1854(define_insn "*bgei"
1855  [(set (pc)
1856	(if_then_else (ge (match_operand:SI 0 "register_operand" "r")
1857			  (match_operand:SI 1 "mep_imm4_operand" "N"))
1858		      (label_ref (match_operand 2 "" ""))
1859		      (pc)))]
1860  ""
1861  "bgei\\t%0, %1, %l2"
1862  [(set_attr "length" "4")])
1863
1864;; ::::::::::::::::::::
1865;; ::
1866;; :: Call and branch instructions
1867;; ::
1868;; ::::::::::::::::::::
1869
1870(define_expand "call"
1871  [(parallel [(call (match_operand:QI 0 "" "")
1872		    (match_operand:SI 1 "" ""))
1873	      (use (match_operand:SI 2 "" ""))
1874	      (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1875	      ])]
1876  ""
1877  "
1878{
1879  mep_expand_call (operands, 0);
1880  DONE;
1881}")
1882
1883(define_insn "call_internal"
1884  [(call (mem (match_operand:SI 0 "mep_call_address_operand" "R,r"))
1885	 (match_operand:SI 1 "" ""))
1886   (use (match_operand:SI 2 "const_int_operand" ""))
1887   (use (match_operand:SI 3 "mep_tp_operand" "b,b"))
1888   (use (match_operand:SI 4 "mep_gp_operand" "v,v"))
1889   (clobber (reg:SI LP_REGNO))
1890   (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1891  ]
1892  ""
1893{
1894  static char const pattern[2][2][8] =
1895  {
1896    { "bsrv\t%0", "jsrv\t%0" },
1897    { "bsr\t%0", "jsr\t%0" }
1898  };
1899
1900  return pattern[mep_vliw_mode_match (operands[2])][which_alternative];
1901}
1902  [(set_attr "length" "4,2")])
1903
1904(define_expand "sibcall"
1905  [(parallel [(call (match_operand:QI 0 "" "")
1906		    (match_operand:SI 1 "" ""))
1907	      (use (match_operand:SI 2 "" ""))
1908	      (use (reg:SI LP_REGNO))
1909	      (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1910	      ])]
1911  ""
1912  "")
1913
1914(define_insn "*sibcall_internal"
1915  [(call (mem (match_operand:SI 0 "mep_nearsym_operand" "s"))
1916	 (match_operand:SI 1 "" ""))
1917   (use (match_operand:SI 2 "const_int_operand" ""))
1918   (use (reg:SI LP_REGNO))
1919   (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1920  ]
1921  "SIBLING_CALL_P (insn)"
1922{
1923  if (mep_vliw_jmp_match (operands[2]))
1924    return "jmp\t%0";
1925  else if (mep_vliw_mode_match (operands[2]))
1926    return
1927        "movu	$0, %0\n\
1928	jmp	$0";
1929  else
1930    return
1931	"ldc	$12, $lp\n\
1932	movh	$11, %%hi(%0)\n\
1933	xor3	$12, $12, 1\n\
1934	add3	$11, $11, %%lo(%0+1)\n\
1935	stc	$12, $lp\n\
1936	jmp	$11";
1937}
1938  [(set_attr "length" "48")
1939   (set_attr "slot" "multi")])
1940
1941(define_expand "call_value"
1942  [(parallel [(set (match_operand 0 "" "")
1943		   (call (match_operand:QI 1 "" "")
1944		         (match_operand:SI 2 "" "")))
1945	      (use (match_operand:SI 3 "" ""))
1946	      (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1947	      ])]
1948  ""
1949  "
1950{
1951  mep_expand_call (operands, 1);
1952  DONE;
1953}")
1954
1955(define_insn "call_value_internal"
1956  [(set (match_operand 0 "register_operand" "=rx,rx")
1957	(call (mem:SI (match_operand:SI 1 "mep_call_address_operand" "R,r"))
1958	      (match_operand:SI 2 "" "")))
1959   (use (match_operand:SI 3 "const_int_operand" ""))
1960   (use (match_operand:SI 4 "mep_tp_operand" "b,b"))
1961   (use (match_operand:SI 5 "mep_gp_operand" "v,v"))
1962   (clobber (reg:SI LP_REGNO))
1963   (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1964  ]
1965  ""
1966{
1967  static char const pattern[2][2][8] =
1968  {
1969    { "bsrv\t%1", "jsrv\t%1" },
1970    { "bsr\t%1", "jsr\t%1" }
1971  };
1972
1973  return pattern[mep_vliw_mode_match (operands[3])][which_alternative];
1974}
1975  [(set_attr "length" "4,2")])
1976
1977(define_expand "sibcall_value"
1978  [(parallel [(set (match_operand 0 "" "")
1979		   (call (match_operand:QI 1 "" "")
1980		         (match_operand:SI 2 "" "")))
1981	      (use (match_operand:SI 3 "" ""))
1982	      (use (reg:SI LP_REGNO))
1983	      (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1984	      ])]
1985  ""
1986  "")
1987
1988(define_insn "*sibcall_value_internal"
1989  [(set (match_operand 0 "register_operand" "=rx")
1990	(call (mem (match_operand:SI 1 "mep_nearsym_operand" "s"))
1991	      (match_operand:SI 2 "" "")))
1992   (use (match_operand:SI 3 "const_int_operand" ""))
1993   (use (reg:SI LP_REGNO))
1994   (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1995  ]
1996  "SIBLING_CALL_P (insn)"
1997{
1998  if (mep_vliw_jmp_match (operands[3]))
1999    return "jmp\t%1";
2000  else if (mep_vliw_mode_match (operands[3]))
2001    return
2002        "movu	$0, %1\n\
2003	jmp	$0";
2004  else
2005    return
2006	"ldc	$12, $lp\n\
2007	movh	$11, %%hi(%1)\n\
2008	xor3	$12, $12, 1\n\
2009	add3	$11, $11, %%lo(%1+1)\n\
2010	stc	$12, $lp\n\
2011	jmp	$11";
2012}
2013  [(set_attr "length" "48")
2014   (set_attr "slot" "multi")])
2015
2016(define_insn "return_internal"
2017  [(return)
2018   (use (match_operand:SI 0 "register_operand" ""))]
2019  ""
2020  "* return (REGNO (operands[0]) == LP_REGNO) ? \"ret\" : \"jmp\\t%0\";"
2021  [(set_attr "length" "2")
2022   (set_attr "stall" "ret")])
2023
2024(define_insn "eh_return_internal"
2025  [(return)
2026   (use (reg:SI 10))
2027   (use (reg:SI 11))
2028   (use (reg:SI LP_REGNO))
2029   (clobber (reg:SI REGSAVE_CONTROL_TEMP))
2030  ]
2031  ""
2032  "ret"
2033  [(set_attr "length" "2")
2034   (set_attr "stall" "ret")])
2035
2036;; The assembler replaces short jumps with long jumps as needed.
2037(define_insn "jump"
2038  [(set (pc) (label_ref (match_operand 0 "" "")))]
2039  ""
2040  "bra\\t%l0"
2041  [(set_attr "length" "4")])
2042
2043(define_insn "indirect_jump"
2044  [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2045  ""
2046  "jmp\\t%0"
2047  [(set_attr "length" "2")])
2048
2049(define_insn "tablejump"
2050  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2051   (use (label_ref (match_operand 1 "" "")))]
2052  ""
2053  "jmp\\t%0"
2054  [(set_attr "length" "2")])
2055
2056
2057;; ::::::::::::::::::::
2058;; ::
2059;; :: Low Overhead Looping
2060;; ::
2061;; ::::::::::::::::::::
2062
2063;; This insn is volatile because we'd like it to stay in its original
2064;; position, just before the loop header.  If it stays there, we might
2065;; be able to convert it into a "repeat" insn.
2066(define_insn "doloop_begin_internal"
2067  [(set (match_operand:SI 0 "register_operand" "=r")
2068	(unspec_volatile:SI
2069	 [(match_operand:SI 1 "register_operand" "0")
2070	  (match_operand 2 "const_int_operand" "")] UNS_REPEAT_BEG))]
2071  ""
2072  { gcc_unreachable (); }
2073  [(set_attr "length" "4")])
2074
2075(define_expand "doloop_begin"
2076  [(use (match_operand 0 "register_operand" ""))
2077   (use (match_operand 1 "" ""))]
2078  "!profile_arc_flag && TARGET_OPT_REPEAT"
2079  "mep_emit_doloop (operands, 0);
2080   DONE;
2081  ")
2082
2083(define_insn "doloop_end_internal"
2084  [(set (pc)
2085	(if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+r,cxy,*m")
2086			  (const_int 0))
2087		      (label_ref (match_operand 1 "" ""))
2088		      (pc)))
2089   (set (match_dup 0)
2090	(plus:SI (match_dup 0)
2091		 (const_int -1)))
2092   (unspec [(match_operand 2 "const_int_operand" "")] UNS_REPEAT_END)
2093   (clobber (match_scratch:SI 3 "=X,&r,&r"))]
2094  ""
2095  { gcc_unreachable (); }
2096  ;; Worst case length:
2097  ;;
2098  ;;      lw <op3>,<op0>	4
2099  ;;      add <op3>,-1		2
2100  ;;      sw <op3>,<op0>	4
2101  ;;      jmp <op1>		4
2102  ;; 1f:
2103  [(set_attr "length" "14")
2104   (set_attr "slot" "multi")])
2105
2106(define_expand "doloop_end"
2107  [(use (match_operand 0 "nonimmediate_operand" ""))
2108   (use (label_ref (match_operand 1 "" "")))]
2109  "!profile_arc_flag && TARGET_OPT_REPEAT"
2110  "if (GET_CODE (operands[0]) == REG && GET_MODE (operands[0]) != SImode)
2111     FAIL;
2112   mep_emit_doloop (operands, 1);
2113   DONE;
2114  ")
2115
2116(define_insn "repeat"
2117  [(set (reg:SI RPC_REGNO)
2118	(unspec:SI [(match_operand:SI 0 "mep_r0_15_operand" "r")
2119		    (match_operand:SI 1 "" "")]
2120		   UNS_REPEAT_BEG))]
2121  ""
2122  "repeat\\t%0,%l1"
2123  [(set_attr "length" "4")])
2124
2125(define_insn "repeat_end"
2126  [(unspec [(const_int 0)] UNS_REPEAT_END)]
2127  ""
2128  "# repeat end"
2129  [(set_attr "length" "0")])
2130
2131(define_insn "erepeat"
2132  [(unspec [(match_operand 0 "" "")] UNS_EREPEAT_BEG)]
2133  ""
2134  "erepeat\\t%l0"
2135  [(set_attr "length" "4")])
2136
2137(define_insn "erepeat_end"
2138  [(unspec [(const_int 0)] UNS_EREPEAT_END)]
2139  ""
2140  "# erepeat end"
2141  [(set_attr "length" "0")
2142   (set_attr "slot" "multi")])
2143
2144
2145;; ::::::::::::::::::::
2146;; ::
2147;; :: Prologue and Epilogue instructions
2148;; ::
2149;; ::::::::::::::::::::
2150
2151(define_expand "prologue"
2152  [(const_int 1)]
2153  ""
2154  "
2155{
2156  mep_expand_prologue ();
2157  DONE;
2158}")
2159
2160(define_expand "epilogue"
2161  [(return)]
2162  ""
2163  "
2164{
2165  mep_expand_epilogue ();
2166  DONE;
2167}")
2168
2169(define_expand "eh_return"
2170  [(use (match_operand:SI 0 "register_operand" "r"))]
2171  ""
2172  "
2173{
2174  mep_expand_eh_return (operands);
2175  DONE;
2176}")
2177
2178(define_insn_and_split "eh_epilogue"
2179  [(unspec [(match_operand:SI 0 "register_operand" "r")] UNS_EH_EPILOGUE)
2180   (use (reg:SI LP_REGNO))]
2181  ""
2182  "#"
2183  "epilogue_completed"
2184  [(const_int 1)]
2185  "mep_emit_eh_epilogue (operands); DONE;"
2186  [(set_attr "slot" "multi")])
2187
2188(define_expand "sibcall_epilogue"
2189  [(const_int 0)]
2190  ""
2191  "
2192{
2193  mep_expand_sibcall_epilogue ();
2194  DONE;
2195}")
2196
2197(define_insn "mep_bb_trace_ret"
2198  [(unspec_volatile [(const_int 0)] UNS_BB_TRACE_RET)]
2199  ""
2200  "* return mep_emit_bb_trace_ret ();"
2201  [(set_attr "slot" "multi")])
2202
2203(define_insn "mep_disable_int"
2204  [(unspec_volatile [(const_int 0)] UNS_DISABLE_INT)]
2205  ""
2206  "di"
2207  [(set_attr "length" "2")])
2208
2209(define_insn "mep_enable_int"
2210  [(unspec_volatile [(const_int 0)] UNS_ENABLE_INT)]
2211  ""
2212  "ei"
2213  [(set_attr "length" "2")])
2214
2215(define_insn "mep_reti"
2216  [(return)
2217   (unspec_volatile [(const_int 0)] UNS_RETI)]
2218  ""
2219  "reti"
2220  [(set_attr "length" "2")])
2221
2222;; ::::::::::::::::::::
2223;; ::
2224;; :: Miscellaneous instructions
2225;; ::
2226;; ::::::::::::::::::::
2227
2228(define_insn "nop"
2229  [(const_int 0)]
2230  ""
2231  "nop"
2232  [(set_attr "length" "2")])
2233
2234(define_insn "nop32"
2235  [(const_int 1)]
2236  ""
2237  "or3\\t$0, $0, 0"
2238  [(set_attr "length" "4")])
2239
2240(define_insn "blockage"
2241  [(unspec_volatile [(const_int 0)] UNS_BLOCKAGE)]
2242  ""
2243  ""
2244  [(set_attr "length" "0")
2245   (set_attr "slot" "multi")])
2246
2247
2248(define_insn "djmark"
2249  [(unspec_volatile [(const_int 0)] 999)]
2250  ""
2251  "# dj"
2252  [(set_attr "length" "0")
2253   (set_attr "slot" "multi")])
2254
2255