PR/56490
[official-gcc.git] / gcc / config / mep / mep.md
blob3f09a235241476d1d9b3d2f67f188b6910110fe7
1 ;; Toshiba Media Processor Machine description template
2 ;; Copyright (C) 2001-2013 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.
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.
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/>.  */
23 ;; Constraints:
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
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
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
58 ;; Modifiers:
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
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                    ])
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                   ])
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")))
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"))
117 (define_attr "intrinsic" "none,cmov,cmov1,cmov2,cmovc1,cmovc2,cmovh1,cmovh2"
118   (const_string "none"))
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")))
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))
134 (define_attr "shiftop" "none,operand2"
135   (const_string "none"))
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)")))
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")))
160 (define_attr "may_trap" "no,yes"
161   (const_string "no"))
163 ;; Describe a user's asm statement.
164 (define_asm_attributes
165   [(set_attr "length" "4")
166    (set_attr "slot" "multi")])
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")
173 ;; Each core or IVC2 instruction is bundled into one of these slots.
174 ;; Supported bundlings:
175 ;; 
176 ;; Core mode:
178 ;;  C1  [-----core-----]
179 ;;  C2  [-------------core-------------]
180 ;;  C3  [--------------c3--------------]
182 ;; VLIW mode:
184 ;;  V1  [-----core-----][--------p0s-------][------------p1------------]
185 ;;  V2  [-------------core-------------]xxxx[------------p1------------]
186 ;;  V3  1111[--p0--]0111[--------p0--------][------------p1------------]
188 (define_attr "slots" "core,c3,p0,p0_p0s,p0_p1,p0s,p0s_p1,p1" (const_string "core"))
190 (define_cpu_unit "ivc2_slot_c16,ivc2_slot_c32,ivc2_slot_c3,ivc2_slot_p0s,ivc2_slot_p0,ivc2_slot_p1" "mep_ivc2")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
259 ;; Non-IVC2 scheduling.
260 (define_automaton "mep")
261 (define_cpu_unit "core,cop" "mep")
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.
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")
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")
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")
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")
295 (define_insn_reservation "h1_store" 1
296   (eq_attr "stall" "store")
297   "core")
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")
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")
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")
318 ;; ??? Parameterised latency.
319 (define_insn_reservation "h1_ldcb" 5
320   (eq_attr "stall" "ldcb")
321   "core")
323 (define_insn_reservation "h1_stcb" 1
324   (eq_attr "stall" "stcb")
325   "core")
327 (define_insn_reservation "h1_advck" 6
328   (eq_attr "stall" "advck")
329   "core")
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")
338 (define_insn_reservation "h1_div" 36
339   (eq_attr "stall" "div")
340   "core")
342 (define_insn_reservation "h1_cop" 1
343   (eq_attr "slot" "cop")
344   "cop")
346 (include "predicates.md")
347 (include "constraints.md")
348 (include "intrinsics.md")
350 ;; ::::::::::::::::::::
351 ;; ::
352 ;; :: Moves
353 ;; ::
354 ;; ::::::::::::::::::::
356 (define_expand "movqi"
357   [(set (match_operand:QI 0 "general_operand" "")
358         (match_operand:QI 1 "general_operand" ""))]
359   ""
360   "
362   if (mep_expand_mov (operands, QImode))
363     DONE;
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")])
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")])
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,*,*,*,*,*,*,*,*,*")])
413 (define_expand "movhi"
414   [(set (match_operand:HI 0 "general_operand" "")
415         (match_operand:HI 1 "general_operand" ""))]
416   ""
417   "
419   if (mep_expand_mov (operands, HImode))
420     DONE;
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")])
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")])
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,*,*,*,*,*,*,*,*,*")])
469 (define_expand "movsi"
470   [(set (match_operand:SI 0 "nonimmediate_operand" "")
471         (match_operand:SI 1 "general_operand" ""))]
472   ""
473   "
475   if (mep_expand_mov (operands, SImode))
476     DONE;
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")])
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")])
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")])
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")])
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")])
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,*,*,*,*,*,*,*,*,*,*,*,*,*")])
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   "
568   HOST_WIDE_INT value;
569   int lo, hi;
571   value = INTVAL (operands[1]);
573   lo = value & 0xffff;
574   hi = trunc_int_for_mode (value & 0xffff0000, SImode);
576   operands[2] = GEN_INT (hi);
577   operands[3] = GEN_INT (lo);
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   "")
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")])
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")])
606 (define_expand "movdi"
607   [(set (match_operand:DI 0 "" "")
608         (match_operand:DI 1 "" ""))]
609   ""
610   "
612   if (mep_expand_mov (operands, DImode))
613     DONE;
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")])
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")])
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")])
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")])
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")])
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")])
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);")
695 ;; Floating Point Moves
697 (define_expand "movsf"
698   [(set (match_operand:SF 0 "nonimmediate_operand" "")
699         (match_operand:SF 1 "general_operand" ""))]
700   ""
701   "
703   if (mep_expand_mov (operands, SFmode))
704     DONE;
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")])
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")])
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")])
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   "
763   REAL_VALUE_TYPE rv;
764   HOST_WIDE_INT value;
765   HOST_WIDE_INT lo, hi;
766   rtx out;
768   REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
769   REAL_VALUE_TO_TARGET_SINGLE (rv, value);
771   lo = value & 0xffff;
772   hi = trunc_int_for_mode (value & 0xffff0000, SImode);
774   out = gen_rtx_REG (SImode, REGNO (operands[0]));
775   emit_move_insn (out, GEN_INT (hi));
776   if (lo != 0)
777     emit_insn (gen_iorsi3 (out, out, GEN_INT (lo)));
778   DONE;
781 (define_expand "movdf"
782   [(set (match_operand:DF 0 "" "")
783         (match_operand:DF 1 "" ""))]
784   ""
785   "
787   if (mep_expand_mov (operands, DFmode))
788     DONE;
791 (define_insn "*movdf_internal_32"
792   [(set (match_operand:DF 0 "mep_movdest_operand" "= r,m,r,c,r,er,ex,em,U")
793         (match_operand:DF 1 "general_operand"     "rFm,r,c,r,er,r,ex,U,em"))]
794   "TARGET_32BIT_CR_REGS && mep_mov_ok (operands, DFmode)"
795   "#"
796   [(set_attr "slot" "multi")])
798 (define_insn "*movdf_internal_64"
799   [(set (match_operand:DF 0 "mep_movdest_operand" "= r,m,r,c,r,er,ex,em,U")
800         (match_operand:DF 1 "general_operand"     "rFm,r,c,r,er,r,ex,U,em"))]
801   "TARGET_64BIT_CR_REGS && mep_mov_ok (operands, DFmode)"
802   "@
803    #
804    #
805    #
806    #
807    #
808    #
809    %<\\t%0, %M1
810    lmcp\\t%0, %1
811    smcp\\t%1, %0"
812   [(set_attr "slot"  "multi,multi,multi,multi,multi,multi,*,*,*")
813    (set_attr "intrinsic" "*,*,*,*,*,*,cmov,*,*")
814    (set_attr "memop" "*,*,*,*,*,*,*,cop1,cop0")
815    (set_attr "stall" "*,*,*,*,*,*,*,load,store")])
817 (define_split
818   [(set (match_operand:DF 0 "mep_movdest_operand" "")
819         (match_operand:DF 1 "general_operand" ""))]
820   "reload_completed && mep_multi_slot (insn)"
821   [(set (match_dup 2) (match_dup 3))
822    (set (match_dup 4) (match_dup 5))]
823   "mep_split_wide_move (operands, DFmode);")
826 (define_insn "*lbcpa"
827   [(set (match_operand:SI 0 "register_operand" "=em")
828         (sign_extend:SI (mem:QI (match_operand:SI 2 "register_operand" "1"))))
829    (set (match_operand:SI 1 "register_operand" "=r")
830         (plus:SI (match_dup 2)
831                  (match_operand:SI 3 "cgen_h_sint_8a1_immediate" "")))]
832   "TARGET_COP && reload_completed"
833   "lbcpa\t%0, (%1+), %3"
834   [(set_attr "length" "4")
835    (set_attr "stall" "load")])
837 (define_insn "*sbcpa"
838   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
839         (match_operand:QI 2 "register_operand" "em"))
840    (set (match_operand:SI 0 "register_operand" "=r")
841         (plus:SI (match_dup 1)
842                  (match_operand:SI 3 "cgen_h_sint_8a1_immediate" "")))]
843   "TARGET_COP && reload_completed"
844   "sbcpa\t%2, (%0+), %3"
845   [(set_attr "length" "4")
846    (set_attr "stall" "store")])
848 (define_insn "*lhcpa"
849   [(set (match_operand:SI 0 "register_operand" "=em")
850         (sign_extend:SI (mem:HI (match_operand:SI 2 "register_operand" "1"))))
851    (set (match_operand:SI 1 "register_operand" "=r")
852         (plus:SI (match_dup 2)
853                  (match_operand:SI 3 "cgen_h_sint_7a2_immediate" "")))]
854   "TARGET_COP && reload_completed"
855   "lhcpa\t%0, (%1+), %3"
856   [(set_attr "length" "4")
857    (set_attr "stall" "load")])
859 (define_insn "*shcpa"
860   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
861         (match_operand:HI 2 "register_operand" "em"))
862    (set (match_operand:SI 0 "register_operand" "=r")
863         (plus:SI (match_dup 1)
864                  (match_operand:SI 3 "cgen_h_sint_7a2_immediate" "")))]
865   "TARGET_COP && reload_completed"
866   "shcpa\t%2, (%0+), %3"
867   [(set_attr "length" "4")
868    (set_attr "stall" "store")])
870 (define_insn "*lwcpi"
871   [(set (match_operand:SI 0 "register_operand" "=em")
872         (mem:SI (match_operand:SI 2 "register_operand" "1")))
873    (set (match_operand:SI 1 "register_operand" "=r")
874         (plus:SI (match_dup 2)
875                  (const_int 4)))]
876   "TARGET_COP && reload_completed"
877   "lwcpi\t%0, (%1+)"
878   [(set_attr "length" "2")
879    (set_attr "stall" "load")])
881 (define_insn "*lwcpa"
882   [(set (match_operand:SI 0 "register_operand" "=em")
883         (mem:SI (match_operand:SI 2 "register_operand" "1")))
884    (set (match_operand:SI 1 "register_operand" "=r")
885         (plus:SI (match_dup 2)
886                  (match_operand:SI 3 "cgen_h_sint_6a4_immediate" "")))]
887   "TARGET_COP && reload_completed"
888   "lwcpa\t%0, (%1+), %3"
889   [(set_attr "length" "4")
890    (set_attr "stall" "load")])
892 (define_insn "*swcpi"
893   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
894         (match_operand:SI 2 "register_operand" "em"))
895    (set (match_operand:SI 0 "register_operand" "=r")
896         (plus:SI (match_dup 1)
897                  (const_int 4)))]
898   "TARGET_COP && reload_completed"
899   "swcpi\t%2, (%0+)"
900   [(set_attr "length" "2")
901    (set_attr "stall" "store")])
903 (define_insn "*swcpa"
904   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
905         (match_operand:SI 2 "register_operand" "em"))
906    (set (match_operand:SI 0 "register_operand" "=r")
907         (plus:SI (match_dup 1)
908                  (match_operand:SI 3 "cgen_h_sint_6a4_immediate" "")))]
909   "TARGET_COP && reload_completed"
910   "swcpa\t%2, (%0+), %3"
911   [(set_attr "length" "4")
912    (set_attr "stall" "store")])
914 (define_peephole2
915   [(set (match_operand:SI 0 "register_operand" "")
916         (plus:SI (match_dup 0)
917                  (match_operand:SI 1 "cgen_h_sint_8a1_immediate" "")))]
918   "TARGET_COP && mep_use_post_modify_p (insn, operands[0], operands[1])"
919   [(const_int 0)]
921   emit_note (NOTE_INSN_DELETED);
922   DONE;
925 ;; ::::::::::::::::::::
926 ;; ::
927 ;; :: Reloads
928 ;; ::
929 ;; ::::::::::::::::::::
931 (define_expand "reload_insi"
932   [(set (match_operand:SI 0 "mep_reload_operand" "")
933         (match_operand:SI 1 "mep_reload_operand" "r"))
934    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
935   ""
936   "
938   mep_expand_reload (operands, SImode);
939   DONE;
942 (define_expand "reload_outsi"
943   [(set (match_operand:SI 0 "mep_reload_operand" "=r")
944         (match_operand:SI 1 "mep_reload_operand" ""))
945    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
946   ""
947   "
949   mep_expand_reload (operands, SImode);
950   DONE;
954 ;; ::::::::::::::::::::
955 ;; ::
956 ;; :: Conversions
957 ;; ::
958 ;; ::::::::::::::::::::
960 (define_insn "extendqisi2"
961   [(set (match_operand:SI 0 "register_operand" "=r,r,em")
962         (sign_extend:SI
963           (match_operand:QI 1 "nonimmediate_operand" "0,m,Y")))]
964   ""
965   "@
966    extb\\t%0
967    lb\\t%0, %1
968    lbcpa\\t%0, %P1"
969   [(set_attr "length" "2,*,*")
970    (set_attr "stall"  "*,load,load")
971    (set_attr "memop"  "*,core1,cop1")])
973 (define_insn "extendhisi2"
974   [(set (match_operand:SI 0 "register_operand" "=r,r,em")
975         (sign_extend:SI
976           (match_operand:HI 1 "nonimmediate_operand" "0,m,Y")))]
977   ""
978   "@
979    exth\\t%0
980    lh\\t%0, %1
981    lhcpa\\t%0, %P1"
982   [(set_attr "length" "2,*,*")
983    (set_attr "stall"  "*,load,load")
984    (set_attr "memop"  "*,core1,cop1")])
986 (define_insn "zero_extendqisi2"
987   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
988         (zero_extend:SI
989           (match_operand:QI 1 "nonimmediate_operand" "0,r,m")))]
990   ""
991   "@
992    extub\\t%0
993    and3\\t%0, %1, 255
994    lbu\\t%0, %1"
995   [(set_attr "length" "2,4,*")
996    (set_attr "stall" "*,*,load")
997    (set_attr "memop"  "*,*,core1")])
999 (define_insn "zero_extendhisi2"
1000   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1001         (zero_extend:SI
1002           (match_operand:HI 1 "nonimmediate_operand" "0,r,m")))]
1003   ""
1004   "@
1005    extuh\\t%0
1006    and3\\t%0, %1, 65535
1007    lhu\\t%0, %1"
1008   [(set_attr "length" "2,4,*")
1009    (set_attr "stall" "*,*,load")
1010    (set_attr "memop"  "*,*,core1")])
1012 ;; ::::::::::::::::::::
1013 ;; ::
1014 ;; :: 32 bit Integer arithmetic
1015 ;; ::
1016 ;; ::::::::::::::::::::
1018 (define_insn "addsi3"
1019   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1020         (plus:SI (match_operand:SI 1 "register_operand" "%r,0,r")
1021                  (match_operand:SI 2 "mep_add_operand" "r,L,IT")))]
1022   ""
1023   "@
1024    add3\\t%0, %1, %2
1025    add\\t%0, %2
1026    add3\\t%0, %1, %I2"
1027   [(set (attr "length")
1028         (if_then_else (eq_attr "alternative" "2")
1029           (if_then_else (and (match_operand:SI 1 "mep_sp_operand" "")
1030                              (match_operand:SI 2 "mep_imm7a4_operand" ""))
1031             (const_int 2)
1032             (const_int 4))
1033           (const_int 2)))])
1035 ;; The intention here is to combine the 16-bit add with the 16-bit
1036 ;; move to create a 32-bit add.  It's the same size, but takes one
1037 ;; less machine cycle.  It will happen to match a 32-bit add with a
1038 ;; 16-bit move also, but gcc shouldn't be doing that ;)
1039 (define_peephole2
1040   [(set (match_operand:SI 0 "register_operand" "")
1041         (plus:SI (match_operand:SI 1 "register_operand" "")
1042                  (match_operand:SI 2 "immediate_operand" "")))
1043    (set (match_operand:SI 3 "register_operand" "")
1044         (match_operand:SI 4 "register_operand" ""))]
1045   "REGNO (operands[0]) == REGNO (operands[1])
1046    && REGNO (operands[0]) == REGNO (operands[4])
1047    && GR_REGNO_P (REGNO (operands[3]))
1048    && dead_or_set_p (peep2_next_insn (1), operands[4])"
1049   [(set (match_dup 3)
1050         (plus:SI (match_dup 1)
1051                  (match_dup 2)))]
1052   "")
1054 (define_insn "subsi3"
1055   [(set (match_operand:SI 0 "register_operand" "=r")
1056         (minus:SI (match_operand:SI 1 "register_operand" "0")
1057                   (match_operand:SI 2 "register_operand" "r")))]
1058   ""
1059   "sub\\t%0, %2"
1060   [(set_attr "length" "2")])
1062 (define_expand "mulsi3"
1063   [(set (match_operand:SI 0 "register_operand" "")
1064         (mult:SI (match_operand:SI 1 "register_operand" "")
1065                  (match_operand:SI 2 "register_operand" "")))]
1066   "TARGET_OPT_MULT || TARGET_COPRO_MULT"
1068   emit_insn (gen_mulsi3_1 (operands[0], operands[1], operands[2]));
1069   DONE;
1072 ;; Generated by mep_reuse_lo_p when no GPR destination is needed.
1073 (define_insn "mulsi3_lo"
1074   [(set (match_operand:SI 0 "mep_lo_operand" "=l")
1075         (mult:SI (match_operand:SI 1 "register_operand" "r")
1076                  (match_operand:SI 2 "register_operand" "r")))
1077    (clobber (match_scratch:SI 3 "=h"))]
1078   "TARGET_OPT_MULT && reload_completed"
1079   "mul\\t%1, %2"
1080   [(set_attr "length" "2")
1081    (set_attr "stall" "mul")])
1083 ;; Generated by mep_reuse_lo_p when both destinations of a mulr
1084 ;; are needed.
1085 (define_insn "mulsi3r"
1086   [(set (match_operand:SI 0 "mep_lo_operand" "=l")
1087         (mult:SI (match_operand:SI 2 "register_operand" "1")
1088                  (match_operand:SI 3 "register_operand" "r")))
1089    (set (match_operand:SI 1 "register_operand" "=r")
1090         (mult:SI (match_dup 2)
1091                  (match_dup 3)))
1092    (clobber (match_scratch:SI 4 "=h"))]
1093   "TARGET_OPT_MULT && reload_completed"
1094   "mulr\\t%2, %3"
1095   [(set_attr "length" "2")
1096    (set_attr "stall" "mulr")])
1098 (define_insn "mulsi3_1"
1099   [(set (match_operand:SI 0 "register_operand" "=r")
1100         (mult:SI (match_operand:SI 1 "register_operand" "%0")
1101                  (match_operand:SI 2 "register_operand" "r")))
1102    (clobber (match_scratch:SI 3 "=l"))
1103    (clobber (match_scratch:SI 4 "=h"))]
1104   "TARGET_OPT_MULT"
1105   "mulr\\t%1, %2"
1106   [(set_attr "length" "2")
1107    (set_attr "stall" "mulr")])
1109 (define_expand "mulsidi3"
1110   [(set (match_operand:DI 0 "register_operand" "")
1111         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1112                  (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))]
1113   "TARGET_OPT_MULT"
1114   "
1116   rtx hi = gen_reg_rtx (SImode);
1117   rtx lo = gen_reg_rtx (SImode);
1119   emit_insn (gen_mulsidi3_i (hi, lo, operands[1], operands[2]));
1120   emit_move_insn (gen_lowpart (SImode, operands[0]), lo);
1121   emit_move_insn (gen_highpart (SImode, operands[0]), hi);
1122   DONE;
1125 (define_insn "mulsidi3_i"
1126   [(set (match_operand:SI 0 "mep_hi_operand" "=h")
1127         (truncate:SI
1128          (lshiftrt:DI
1129           (mult:DI (sign_extend:DI
1130                     (match_operand:SI 2 "register_operand" "r"))
1131                    (sign_extend:DI
1132                     (match_operand:SI 3 "register_operand" "r")))
1133           (const_int 32))))
1134    (set (match_operand:SI 1 "mep_lo_operand" "=l")
1135         (mult:SI (match_dup 2)
1136                  (match_dup 3)))]
1137   "TARGET_OPT_MULT"
1138   "mul\\t%2, %3"
1139   [(set_attr "length" "2")
1140    (set_attr "stall" "mul")])
1142 (define_insn "smulsi3_highpart"
1143   [(set (match_operand:SI 0 "mep_hi_operand" "=h")
1144         (truncate:SI
1145          (lshiftrt:DI
1146           (mult:DI (sign_extend:DI
1147                     (match_operand:SI 1 "register_operand" "r"))
1148                    (sign_extend:DI
1149                     (match_operand:SI 2 "register_operand" "r")))
1150           (const_int 32))))
1151    (clobber (reg:SI LO_REGNO))]
1152   "TARGET_OPT_MULT"
1153   "mul\\t%1, %2"
1154   [(set_attr "length" "2")
1155    (set_attr "stall" "mul")])
1157 (define_expand "umulsidi3"
1158   [(set (match_operand:DI 0 "mep_hi_operand" "")
1159         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1160                  (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))]
1161   "TARGET_OPT_MULT"
1162   "
1164   rtx hi = gen_reg_rtx (SImode);
1165   rtx lo = gen_reg_rtx (SImode);
1167   emit_insn (gen_umulsidi3_i (hi, lo, operands[1], operands[2]));
1168   emit_move_insn (gen_lowpart (SImode, operands[0]), lo);
1169   emit_move_insn (gen_highpart (SImode, operands[0]), hi);
1170   DONE;
1173 (define_insn "umulsidi3_i"
1174   [(set (match_operand:SI 0 "mep_hi_operand" "=h")
1175         (truncate:SI
1176          (lshiftrt:DI
1177           (mult:DI (zero_extend:DI
1178                     (match_operand:SI 2 "register_operand" "r"))
1179                    (zero_extend:DI
1180                     (match_operand:SI 3 "register_operand" "r")))
1181           (const_int 32))))
1182    (set (match_operand:SI 1 "mep_lo_operand" "=l")
1183         (mult:SI (match_dup 2)
1184                  (match_dup 3)))]
1185   "TARGET_OPT_MULT"
1186   "mulu\\t%2, %3"
1187   [(set_attr "length" "2")
1188    (set_attr "stall" "mul")])
1190 (define_insn "umulsi3_highpart"
1191   [(set (match_operand:SI 0 "mep_hi_operand" "=h")
1192         (truncate:SI
1193          (lshiftrt:DI
1194           (mult:DI (zero_extend:DI
1195                     (match_operand:SI 1 "register_operand" "r"))
1196                    (zero_extend:DI
1197                     (match_operand:SI 2 "register_operand" "r")))
1198           (const_int 32))))
1199    (clobber (reg:SI LO_REGNO))]
1200   "TARGET_OPT_MULT"
1201   "mulu %1, %2"
1202   [(set_attr "length" "2")
1203    (set_attr "stall" "mul")])
1205 ;; These two don't currently match because we don't have an adddi3 pattern.
1206 (define_insn "*smultdi_and_add"
1207   [(set (match_operand:DI 0 "mep_hi_operand" "=d")
1208         (plus:DI (mult:DI (zero_extend:DI
1209                            (match_operand:SI 1 "register_operand" "r"))
1210                           (zero_extend:DI
1211                            (match_operand:SI 2 "register_operand" "r")))
1212                  (match_operand:DI 3 "mep_hi_operand" "0")))]
1213   "TARGET_OPT_MULT && TARGET_BIG_ENDIAN"
1214   "maddu\\t%1, %2"
1215   [(set_attr "length" "4")
1216    (set_attr "stall" "mul")])
1218 (define_insn "*umultdi_and_add"
1219   [(set (match_operand:DI 0 "mep_hi_operand" "=d")
1220         (plus:DI (mult:DI (sign_extend:DI
1221                            (match_operand:SI 1 "register_operand" "r"))
1222                           (sign_extend:DI
1223                            (match_operand:SI 2 "register_operand" "r")))
1224                  (match_operand:DI 3 "mep_hi_operand" "0")))]
1225   "TARGET_OPT_MULT && TARGET_BIG_ENDIAN"
1226   "madd\\t%1, %2"
1227   [(set_attr "length" "4")
1228    (set_attr "stall" "mul")])
1230 ;; A pattern for 'r1 = r2 * r3 + r4'.  There are three possible
1231 ;; implementations:
1233 ;;    (1) 'mulr;add3'.  This is usually the best choice if the instruction
1234 ;;        is not part of a natural multiply-accumulate chain.  It has the
1235 ;;        same latency as 'stc;maddr' but doesn't tie up $lo for as long.
1237 ;;    (2) 'madd'.  This is the best choice if the instruction is in the
1238 ;;        middle of a natural multiply-accumulate chain.  r4 will already
1239 ;;        be in $lo and r1 will also be needed in $lo.
1241 ;;    (3) 'maddr'.  This is the best choice if the instruction is at the
1242 ;;        end of a natural multiply-accumulate chain.  r4 will be in $lo
1243 ;;        but r1 will be needed in a GPR.
1245 ;; In theory, we could put all the alternatives into a single pattern and
1246 ;; leave the register allocator to choose between them.  However, this can
1247 ;; sometimes produce poor results in practice.
1249 ;; This pattern therefore describes a general GPR-to-GPR operation that
1250 ;; has a slight preference for cases in which operands 0 and 1 are tied.
1251 ;; After reload, we try to rewrite the patterns using peephole2s (if
1252 ;; enabled), falling back on define_splits if that fails.  See also
1253 ;; mep_reuse_lo_p.
1254 (define_insn "maddsi3"
1255   [(set (match_operand:SI 0 "register_operand" "=r,r")
1256         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%0,r")
1257                           (match_operand:SI 2 "register_operand" "r,r"))
1258                  (match_operand:SI 3 "register_operand" "r,r")))
1259    (clobber (match_scratch:SI 4 "=l,l"))
1260    (clobber (match_scratch:SI 5 "=h,h"))]
1261   "TARGET_OPT_MULT"
1262   "#"
1263   [(set_attr "length" "8")
1264    (set_attr "stall" "mulr")])
1266 ;; Implement maddsi3s using maddr if operand 3 is already available in $lo.
1267 (define_peephole2
1268   [(parallel
1269         [(set (match_operand:SI 0 "register_operand" "")
1270               (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1271                                 (match_operand:SI 2 "register_operand" ""))
1272                        (match_operand:SI 3 "register_operand" "")))
1273          (clobber (match_scratch:SI 4 ""))
1274          (clobber (match_scratch:SI 5 ""))])]
1275   "TARGET_OPT_MULT
1276    && reload_completed
1277    && mep_reuse_lo_p (operands[4], operands[3], insn,
1278                       !rtx_equal_p (operands[1], operands[3])
1279                       && !rtx_equal_p (operands[2], operands[3])
1280                       && (rtx_equal_p (operands[0], operands[3])
1281                           || peep2_reg_dead_p (1, operands[3])))"
1282   [(parallel
1283         [(set (match_dup 4)
1284               (plus:SI (mult:SI (match_dup 0)
1285                                 (match_dup 2))
1286                        (match_dup 4)))
1287          (set (match_dup 0)
1288               (plus:SI (mult:SI (match_dup 0)
1289                                 (match_dup 2))
1290                        (match_dup 4)))
1291          (clobber (match_dup 5))])]
1292   "operands[2] = mep_mulr_source (0, operands[0], operands[1], operands[2]);")
1294 ;; This splitter implements maddsi3 as "mulr;add3".  It only works if
1295 ;; operands 0 and 3 are distinct, since operand 0 is clobbered before
1296 ;; operand 3 is used.
1297 (define_split
1298   [(set (match_operand:SI 0 "register_operand" "")
1299         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1300                           (match_operand:SI 2 "register_operand" ""))
1301                  (match_operand:SI 3 "register_operand" "")))
1302    (clobber (match_scratch:SI 4 ""))
1303    (clobber (match_scratch:SI 5 ""))]
1304   "TARGET_OPT_MULT
1305    && reload_completed
1306    && !rtx_equal_p (operands[0], operands[3])"
1307   [(parallel [(set (match_dup 0)
1308                    (mult:SI (match_dup 0)
1309                             (match_dup 2)))
1310               (clobber (match_dup 4))
1311               (clobber (match_dup 5))])
1312    (set (match_dup 0)
1313         (plus:SI (match_dup 0)
1314                  (match_dup 3)))]
1315   "operands[2] = mep_mulr_source (0, operands[0], operands[1], operands[2]);")
1317 ;; This is the fallback splitter for maddsi3.  It moves operand 3 into
1318 ;; $lo and then uses maddr.
1319 (define_split
1320   [(set (match_operand:SI 0 "register_operand" "")
1321         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1322                           (match_operand:SI 2 "register_operand" ""))
1323                  (match_operand:SI 3 "register_operand" "")))
1324    (clobber (match_scratch:SI 4 ""))
1325    (clobber (match_scratch:SI 5 ""))]
1326   "TARGET_OPT_MULT
1327    && reload_completed"
1328   [(parallel [(set (match_dup 4)
1329                    (plus:SI (mult:SI (match_dup 0)
1330                                      (match_dup 2))
1331                             (match_dup 4)))
1332               (set (match_dup 0)
1333                    (plus:SI (mult:SI (match_dup 0)
1334                                      (match_dup 2))
1335                             (match_dup 4)))
1336               (clobber (match_dup 5))])]
1338   emit_move_insn (operands[4], operands[3]);
1339   operands[2] = mep_mulr_source (0, operands[0], operands[1], operands[2]);
1342 ;; Remove unnecessary stcs to $lo.  This cleans up the moves generated
1343 ;; by earlier calls to mep_reuse_lo_p.
1344 (define_peephole2
1345   [(set (match_operand:SI 0 "mep_lo_operand" "")
1346         (match_operand:SI 1 "register_operand" ""))]
1347   "TARGET_OPT_MULT
1348    && mep_reuse_lo_p (operands[0], operands[1], insn,
1349                       peep2_reg_dead_p (1, operands[1]))"
1350   [(const_int 0)]
1352   emit_note (NOTE_INSN_DELETED);
1353   DONE;
1356 (define_insn "maddsi3_lo"
1357   [(set (match_operand:SI 0 "mep_lo_operand" "=l")
1358         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
1359                           (match_operand:SI 2 "register_operand" "r"))
1360                  (match_operand:SI 3 "mep_lo_operand" "0")))
1361    (clobber (match_scratch:SI 4 "=h"))]
1362   "TARGET_OPT_MULT && reload_completed"
1363   "madd\\t%1, %2"
1364   [(set_attr "length" "4")
1365    (set_attr "stall" "mul")])
1367 (define_insn "maddsi3r"
1368   [(set (match_operand:SI 0 "mep_lo_operand" "=l")
1369         (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "1")
1370                           (match_operand:SI 3 "register_operand" "r"))
1371                  (match_operand:SI 4 "register_operand" "0")))
1372    (set (match_operand:SI 1 "register_operand" "=r")
1373         (plus:SI (mult:SI (match_dup 2)
1374                           (match_dup 3))
1375                  (match_dup 4)))
1376    (clobber (match_scratch:SI 5 "=h"))]
1377   "TARGET_OPT_MULT && reload_completed"
1378   "maddr\\t%2, %3"
1379   [(set_attr "length" "4")
1380    (set_attr "stall" "mulr")])
1382 (define_insn "*shift_1_or_2_and_add"
1383   [(set (match_operand:SI 0 "mep_r0_operand" "=z")
1384         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
1385                           (match_operand:SI 2 "mep_slad_operand" "n"))
1386                  (match_operand:SI 3 "register_operand" "r")))]
1387   ""
1388   "sl%b2ad3\\t%0, %1, %3"
1389   [(set_attr "length" "2")
1390    (set_attr "stall" "int2")])
1392 (define_insn "divmodsi4"
1393   [(set (match_operand:SI 0 "mep_lo_operand" "=l")
1394         (div:SI (match_operand:SI 1 "register_operand" "r")
1395                 (match_operand:SI 2 "register_operand" "r")))
1396    (set (match_operand:SI 3 "mep_hi_operand" "=h")
1397         (mod:SI (match_dup 1)
1398                 (match_dup 2)))]
1399   "TARGET_OPT_DIV"
1400   "div\\t%1, %2"
1401   [(set_attr "length" "2")
1402    (set_attr "stall" "div")
1403    (set_attr "may_trap" "yes")])
1405 (define_insn "udivmodsi4"
1406   [(set (match_operand:SI 0 "mep_lo_operand" "=l")
1407         (udiv:SI (match_operand:SI 1 "register_operand" "r")
1408                  (match_operand:SI 2 "register_operand" "r")))
1409    (set (match_operand:SI 3 "mep_hi_operand" "=h")
1410         (umod:SI (match_dup 1)
1411                 (match_dup 2)))]
1412   "TARGET_OPT_DIV"
1413   "divu\\t%1, %2"
1414   [(set_attr "length" "2")
1415    (set_attr "stall" "div")
1416    (set_attr "may_trap" "yes")])
1418 (define_insn "negsi2"
1419   [(set (match_operand:SI 0 "register_operand" "=r")
1420         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1421   ""
1422   "neg\\t%0, %1"
1423   [(set_attr "length" "2")])
1425 ;; We have "absolute difference between two regs" which isn't quite
1426 ;; what gcc is expecting.
1427 (define_expand "abssi2"
1428   [(set (match_dup 2) (const_int 0))
1429    (set (match_operand:SI 0 "register_operand" "")
1430         (abs:SI (minus:SI (match_operand:SI 1 "register_operand" "")
1431                           (match_dup 2))
1432                 ))]
1433   "TARGET_OPT_ABSDIFF"
1434   "operands[2] = gen_reg_rtx (SImode);")
1436 (define_insn "*absdiff"
1437   [(set (match_operand:SI 0 "register_operand" "=r")
1438         (abs:SI (minus:SI (match_operand:SI 1 "register_operand" "0")
1439                           (match_operand:SI 2 "register_operand" "r"))))]
1440   "TARGET_OPT_ABSDIFF"
1441   "abs\\t%0, %2"
1442   [(set_attr "length" "4")])
1444 (define_split
1445   [(set (match_operand:SI 0 "register_operand" "")
1446         (abs:SI (plus:SI (match_operand:SI 1 "register_operand" "")
1447                          (match_operand:SI 2 "immediate_operand" ""))))
1448    (clobber (match_operand:SI 3 "register_operand" ""))]
1449   "!reload_completed"
1450   [(set (match_dup 3)
1451         (match_dup 4))
1452    (set (match_operand:SI 0 "register_operand" "")
1453         (abs:SI (minus:SI (match_operand:SI 1 "register_operand" "")
1454                           (match_dup 3))))]
1455   "operands[4] = GEN_INT (-INTVAL (operands[2]));")
1457 (define_insn "sminsi3"
1458   [(set (match_operand:SI 0 "register_operand" "=r")
1459         (smin:SI (match_operand:SI 1 "register_operand" "0")
1460                  (match_operand:SI 2 "nonmemory_operand" "r")))]
1461   "TARGET_OPT_MINMAX"
1462   "min\\t%0, %2"
1463   [(set_attr "length" "4")])
1465 (define_insn "smaxsi3"
1466   [(set (match_operand:SI 0 "register_operand" "=r")
1467         (smax:SI (match_operand:SI 1 "register_operand" "0")
1468                  (match_operand:SI 2 "nonmemory_operand" "r")))]
1469   "TARGET_OPT_MINMAX"
1470   "max\\t%0, %2"
1471   [(set_attr "length" "4")])
1473 (define_insn "uminsi3"
1474   [(set (match_operand:SI 0 "register_operand" "=r")
1475         (umin:SI (match_operand:SI 1 "register_operand" "0")
1476                  (match_operand:SI 2 "nonmemory_operand" "r")))]
1477   "TARGET_OPT_MINMAX"
1478   "minu\\t%0, %2"
1479   [(set_attr "length" "4")])
1481 (define_insn "umaxsi3"
1482   [(set (match_operand:SI 0 "register_operand" "=r")
1483         (umax:SI (match_operand:SI 1 "register_operand" "0")
1484                  (match_operand:SI 2 "nonmemory_operand" "r")))]
1485   "TARGET_OPT_MINMAX"
1486   "maxu\\t%0, %2"
1487   [(set_attr "length" "4")])
1489 ;; Average:  a = (b+c+1)>>1
1490 (define_insn "*averagesi3"
1491   [(set (match_operand:SI 0 "register_operand" "=r")
1492         (ashiftrt:SI (plus:SI (plus:SI
1493                                 (match_operand:SI 1 "register_operand" "0")
1494                                 (match_operand:SI 2 "register_operand" "r"))
1495                               (const_int 1))
1496                      (const_int 1)))]
1497   "TARGET_OPT_AVERAGE"
1498   "ave\\t%0, %2"
1499   [(set_attr "length" "4")])
1501 ;; clip support
1503 (define_insn "clip_maxmin"
1504   [(set (match_operand:SI 0 "register_operand" "=r")
1505         (smax:SI (smin:SI (match_operand:SI 1 "register_operand" "0")
1506                           (match_operand:SI 2 "immediate_operand" "n"))
1507                  (match_operand:SI 3 "immediate_operand" "n")))]
1508   "mep_allow_clip (operands[2], operands[3], 1)"
1509   "clip\\t%0, %B2"
1510   [(set_attr "length" "4")])
1512 (define_insn "clip_minmax"
1513   [(set (match_operand:SI 0 "register_operand" "=r")
1514         (smin:SI (smax:SI (match_operand:SI 1 "register_operand" "0")
1515                           (match_operand:SI 2 "immediate_operand" "n"))
1516                  (match_operand:SI 3 "immediate_operand" "n")))]
1517   "mep_allow_clip (operands[3], operands[2], 1)"
1518   "clip\\t%0, %B3"
1519   [(set_attr "length" "4")])
1521 (define_insn "clipu_maxmin"
1522   [(set (match_operand:SI 0 "register_operand" "=r")
1523         (smax:SI (smin:SI (match_operand:SI 1 "register_operand" "0")
1524                           (match_operand:SI 2 "immediate_operand" "n"))
1525                  (match_operand:SI 3 "immediate_operand" "n")))]
1526   "mep_allow_clip (operands[2], operands[3], 0)"
1527   "clipu\\t%0, %U2"
1528   [(set_attr "length" "4")])
1530 (define_insn "clipu_minmax"
1531   [(set (match_operand:SI 0 "register_operand" "=r")
1532         (smin:SI (smax:SI (match_operand:SI 1 "register_operand" "0")
1533                           (match_operand:SI 2 "immediate_operand" "n"))
1534                  (match_operand:SI 3 "immediate_operand" "n")))]
1535   "mep_allow_clip (operands[3], operands[2], 0)"
1536   "clipu\\t%0, %U3"
1537   [(set_attr "length" "4")])
1539 ;; ::::::::::::::::::::
1540 ;; ::
1541 ;; :: 32 bit Integer Shifts and Rotates
1542 ;; ::
1543 ;; ::::::::::::::::::::
1545 (define_insn "ashlsi3"
1546   [(set (match_operand:SI 0 "register_operand" "=r,z")
1547         (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
1548                    (match_operand:SI 2 "nonmemory_operand" "rM,M")))]
1549   ""
1550   "@
1551    sll\\t%0, %2
1552    sll3\\t%0, %1, %2"
1553   [(set_attr "length" "2,2")
1554    (set_attr "shiftop" "operand2")])
1556 (define_insn "ashrsi3"
1557   [(set (match_operand:SI 0 "register_operand" "=r")
1558         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1559                      (match_operand:SI 2 "nonmemory_operand" "rM")))]
1560   ""
1561   "sra\\t%0, %2"
1562   [(set_attr "length" "2")
1563    (set_attr "shiftop" "operand2")])
1565 (define_insn "lshrsi3"
1566   [(set (match_operand:SI 0 "register_operand" "=r")
1567         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
1568                      (match_operand:SI 2 "nonmemory_operand" "rM")))]
1569   ""
1570   "srl\\t%0, %2"
1571   [(set_attr "length" "2")
1572    (set_attr "shiftop" "operand2")])
1574 ;; ::::::::::::::::::::
1575 ;; ::
1576 ;; :: 32 Bit Integer Logical operations
1577 ;; ::
1578 ;; ::::::::::::::::::::
1580 (define_insn "andsi3"
1581   [(set (match_operand:SI 0 "register_operand" "=r,r")
1582         (and:SI (match_operand:SI 1 "register_operand" "%0,r")
1583                 (match_operand:SI 2 "nonmemory_operand" "r,J")))]
1584   ""
1585   "@
1586    and\\t%0, %2
1587    and3\\t%0, %1, %J2"
1588   [(set_attr "length" "2,4")])
1590 (define_insn "iorsi3"
1591   [(set (match_operand:SI 0 "register_operand" "=r,r")
1592         (ior:SI (match_operand:SI 1 "register_operand" "%0,r")
1593                 (match_operand:SI 2 "nonmemory_operand" "r,J")))]
1594   ""
1595   "@
1596    or\\t%0, %2
1597    or3\\t%0, %1, %J2"
1598   [(set_attr "length" "2,4")])
1600 (define_insn "xorsi3"
1601   [(set (match_operand:SI 0 "register_operand" "=r,r")
1602         (xor:SI (match_operand:SI 1 "register_operand" "%0,r")
1603                 (match_operand:SI 2 "nonmemory_operand" "r,J")))]
1604   ""
1605   "@
1606    xor\\t%0, %2
1607    xor3\\t%0, %1, %J2"
1608   [(set_attr "length" "2,4")])
1610 (define_expand "one_cmplsi2"
1611   [(set (match_operand:SI 0 "register_operand" "")
1612         (not:SI (match_operand:SI 1 "register_operand" "")))]
1613   ""
1614   "operands[2] = operands[1];
1615    ")
1617 ;; No separate insn for this; use NOR
1618 (define_insn "*one_cmplsi3_internal"
1619   [(set (match_operand:SI 0 "register_operand" "=r")
1620         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1621   ""
1622   "nor\\t%0, %0"
1623   [(set_attr "length" "2")])
1625 ;; ::::::::::::::::::::
1626 ;; ::
1627 ;; :: Bit Manipulation
1628 ;; ::
1629 ;; ::::::::::::::::::::
1631 (define_insn "*bitop_be"
1632   [(set (match_operand:QI 0 "mep_Y_operand" "=Y")
1633         (subreg:QI (match_operator:SI 3 "mep_bit_operator"
1634                         [(subreg:SI (match_operand:QI 1 "mep_Y_operand" "0") 0)
1635                          (match_operand 2 "immediate_operand" "n")])
1636                    3)
1637         )]
1638   "TARGET_BIG_ENDIAN && TARGET_OPT_BITOPS
1639    && rtx_equal_p (operands[0], operands[1])"
1640   "b%L3m\\t%0, %b2"
1641   [(set_attr "length" "2")])
1643 (define_insn "*bitop_le"
1644   [(set (match_operand:QI 0 "mep_Y_operand" "=Y")
1645         (subreg:QI (match_operator:SI 3 "mep_bit_operator"
1646                         [(subreg:SI (match_operand:QI 1 "mep_Y_operand" "0") 0)
1647                          (match_operand 2 "immediate_operand" "n")])
1648                    0)
1649         )]
1650   "!TARGET_BIG_ENDIAN && TARGET_OPT_BITOPS
1651    && rtx_equal_p (operands[0], operands[1])"
1652   "b%L3m\\t%0, %b2"
1653   [(set_attr "length" "2")])
1655 (define_insn "btstm"
1656   [(set (match_operand:SI 0 "mep_r0_operand" "=z")
1657         (and:SI (subreg:SI (match_operand:QI 1 "mep_Y_operand" "Y") 0)
1658                 (match_operand 2 "immediate_operand" "n"))
1659         )]
1660   "TARGET_OPT_BITOPS && mep_bit_position_p (operands[2], 1)"
1661   "btstm\\t%0, %1, %b2"
1662   [(set_attr "length" "2")])
1664 (define_insn "tas"
1665   [(parallel [(set (match_operand:SI 0 "mep_r0_operand" "=z")
1666                    (zero_extend:SI (match_operand:QI 1 "mep_Y_operand" "+Y")))
1667               (set (match_dup 1)
1668                    (const_int 1))
1669               ]
1670              )]
1671   "TARGET_OPT_BITOPS"
1672   "tas\\t%0, %1"
1673   [(set_attr "length" "2")])
1675 (define_peephole2
1676   [(set (match_operand:SI 0 "mep_r0_operand" "")
1677         (zero_extend:SI (match_operand:QI 1 "mep_Y_operand" "")))
1678    (set (match_operand:QI 2 "register_operand" "")
1679         (const_int 1))
1680    (set (match_dup 1)
1681         (match_dup 2))
1682    ]
1683   "TARGET_OPT_BITOPS"
1684   [(parallel [(set (match_dup 0)
1685                    (zero_extend:SI (match_dup 1)))
1686               (set (match_dup 1)
1687                    (const_int 1))
1688               ])]
1689   "")
1691 (define_peephole2
1692   [(set (match_operand:SI 0 "mep_r0_operand" "")
1693         (sign_extend:SI (match_operand:QI 1 "mep_Y_operand" "")))
1694    (set (match_operand:QI 2 "register_operand" "")
1695         (const_int 1))
1696    (set (match_dup 1)
1697         (match_dup 2))
1698    ]
1699   "TARGET_OPT_BITOPS"
1700   [(parallel [(set (match_dup 0)
1701                    (zero_extend:SI (match_dup 1)))
1702               (set (match_dup 1)
1703                    (const_int 1))
1704               ])
1705    (set (match_dup 0)
1706         (sign_extend:SI (match_dup 3)))]
1707   "operands[3] = gen_lowpart (QImode, operands[0]);")
1710 ;; ::::::::::::::::::::
1711 ;; ::
1712 ;; :: Conditional branches and stores
1713 ;; ::
1714 ;; ::::::::::::::::::::
1716 (define_expand "cbranchsi4"
1717   [(set (pc)
1718         (if_then_else (match_operator 0 "ordered_comparison_operator"
1719                                       [(match_operand:SI 1 "register_operand" "")
1720                                        (match_operand:SI 2 "nonmemory_operand" "")])
1721                       (label_ref (match_operand 3 "" ""))
1722                       (pc)))]
1723   ""
1724   "emit_jump_insn (gen_branch_true (operands[3],
1725                                mep_expand_cbranch (operands)));
1726    DONE;")
1727   
1728 (define_expand "branch_true"
1729   [(set (pc)
1730         (if_then_else (match_operand 1 "" "")
1731                       (label_ref (match_operand 0 "" ""))
1732                       (pc)))]
1733   ""
1734   "")
1735   
1736 (define_expand "cstoresi4"
1737   [(set (match_operand:SI 0 "register_operand" "")
1738         (match_operator:SI 1 "ordered_comparison_operator"
1739                            [(match_operand:SI 2 "register_operand" "")
1740                             (match_operand:SI 3 "nonmemory_operand" "")]))]
1741   ""
1742   "if (mep_expand_setcc (operands)) DONE; else FAIL;")
1744 ;; ------------------------------------------------------------
1746 (define_insn "*slt"
1747   [(set (match_operand:SI 0 "register_operand" "=z,z,r")
1748         (lt:SI (match_operand:SI 1 "register_operand" "r,r,r")
1749             (match_operand:SI 2 "nonmemory_operand" "r,M,I")))]
1750   ""
1751   "slt3\\t%0, %1, %2"
1752   [(set_attr "length" "2,2,4")])
1754 (define_insn "*sltu"
1755   [(set (match_operand:SI 0 "register_operand" "=z,z,r")
1756         (ltu:SI (match_operand:SI 1 "register_operand" "r,r,r")
1757              (match_operand:SI 2 "nonmemory_operand" "r,M,J")))]
1758   ""
1759   "sltu3\\t%0, %1, %2"
1760   [(set_attr "length" "2,2,4")])
1762 (define_insn "*bcpeq_true"
1763   [(set (pc)
1764         (if_then_else (eq:SI (reg:SI CBCR_REGNO)
1765                              (const_int 0))
1766                       (label_ref (match_operand 0 "" ""))
1767                       (pc)))]
1768   ""
1769   "bcpeq\t0, %l0"
1770   [(set_attr "length" "4")])
1772 (define_insn "*bcpeq_false"
1773   [(set (pc)
1774         (if_then_else (eq:SI (reg:SI CBCR_REGNO)
1775                              (const_int 0))
1776                       (pc)
1777                       (label_ref (match_operand 0 "" ""))))]
1778   ""
1779   "bcpne\t0, %l0"
1780   [(set_attr "length" "4")])
1782 (define_insn "*bcpne_true"
1783   [(set (pc)
1784         (if_then_else (ne:SI (reg:SI CBCR_REGNO)
1785                              (const_int 0))
1786                       (label_ref (match_operand 0 "" ""))
1787                       (pc)))]
1788   ""
1789   "bcpne\t0, %l0"
1790   [(set_attr "length" "4")])
1792 (define_insn "*bcpne_false"
1793   [(set (pc)
1794         (if_then_else (ne:SI (reg:SI CBCR_REGNO)
1795                              (const_int 0))
1796                       (pc)
1797                       (label_ref (match_operand 0 "" ""))))]
1798   ""
1799   "bcpeq\t0, %l0"
1800   [(set_attr "length" "4")])
1802 ;; ??? The lengths here aren't correct, since no attempt it made to
1803 ;; find "beqz" in the 256-byte range.  However, this should not affect
1804 ;; bundling, since we never run core branches in parallel.
1806 (define_insn "mep_beq_true"
1807   [(set (pc)
1808         (if_then_else (eq (match_operand:SI 0 "register_operand" "r")
1809                           (match_operand:SI 1 "mep_reg_or_imm4_operand" "rN"))
1810                       (label_ref (match_operand 2 "" ""))
1811                       (pc)))]
1812   ""
1813   "* return mep_emit_cbranch (operands, 0);"
1814   [(set_attr "length" "4")]  )
1816 (define_insn "*beq_false"
1817   [(set (pc)
1818         (if_then_else (eq (match_operand:SI 0 "register_operand" "r")
1819                           (match_operand:SI 1 "mep_reg_or_imm4_operand" "rN"))
1820                       (pc)
1821                       (label_ref (match_operand 2 "" ""))))]
1822   ""
1823   "* return mep_emit_cbranch (operands, 1);"
1824   [(set_attr "length" "4")])
1826 (define_insn "mep_bne_true"
1827   [(set (pc)
1828         (if_then_else (ne (match_operand:SI 0 "register_operand" "r")
1829                           (match_operand:SI 1 "mep_reg_or_imm4_operand" "rN"))
1830                       (label_ref (match_operand 2 "" ""))
1831                       (pc)))]
1832   ""
1833   "* return mep_emit_cbranch (operands, 1); "
1834   [(set_attr "length" "4")])
1836 (define_insn "*bne_false"
1837   [(set (pc)
1838         (if_then_else (ne (match_operand:SI 0 "register_operand" "r")
1839                           (match_operand:SI 1 "mep_reg_or_imm4_operand" "rN"))
1840                       (pc)
1841                       (label_ref (match_operand 2 "" ""))))]
1842   ""
1843   "* return mep_emit_cbranch (operands, 0); "
1844   [(set_attr "length" "4")])
1846 (define_insn "mep_blti"
1847   [(set (pc)
1848         (if_then_else (lt (match_operand:SI 0 "register_operand" "r")
1849                           (match_operand:SI 1 "mep_imm4_operand" "N"))
1850                       (label_ref (match_operand 2 "" ""))
1851                       (pc)))]
1852   ""
1853   "blti\\t%0, %1, %l2"
1854   [(set_attr "length" "4")])
1856 (define_insn "*bgei"
1857   [(set (pc)
1858         (if_then_else (ge (match_operand:SI 0 "register_operand" "r")
1859                           (match_operand:SI 1 "mep_imm4_operand" "N"))
1860                       (label_ref (match_operand 2 "" ""))
1861                       (pc)))]
1862   ""
1863   "bgei\\t%0, %1, %l2"
1864   [(set_attr "length" "4")])
1866 ;; ::::::::::::::::::::
1867 ;; ::
1868 ;; :: Call and branch instructions
1869 ;; ::
1870 ;; ::::::::::::::::::::
1872 (define_expand "call"
1873   [(parallel [(call (match_operand:QI 0 "" "")
1874                     (match_operand:SI 1 "" ""))
1875               (use (match_operand:SI 2 "" ""))
1876               (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1877               ])]
1878   ""
1879   "
1881   mep_expand_call (operands, 0);
1882   DONE;
1885 (define_insn "call_internal"
1886   [(call (mem (match_operand:SI 0 "mep_call_address_operand" "R,r"))
1887          (match_operand:SI 1 "" ""))
1888    (use (match_operand:SI 2 "const_int_operand" ""))
1889    (use (match_operand:SI 3 "mep_tp_operand" "b,b"))
1890    (use (match_operand:SI 4 "mep_gp_operand" "v,v"))
1891    (clobber (reg:SI LP_REGNO))
1892    (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1893   ]
1894   ""
1896   static char const pattern[2][2][8] = 
1897   {
1898     { "bsrv\t%0", "jsrv\t%0" },
1899     { "bsr\t%0", "jsr\t%0" }
1900   };
1902   return pattern[mep_vliw_mode_match (operands[2])][which_alternative];
1904   [(set_attr "length" "4,2")])
1906 (define_expand "sibcall"
1907   [(parallel [(call (match_operand:QI 0 "" "")
1908                     (match_operand:SI 1 "" ""))
1909               (use (match_operand:SI 2 "" ""))
1910               (use (reg:SI LP_REGNO))
1911               (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1912               ])]
1913   ""
1914   "")
1916 (define_insn "*sibcall_internal"
1917   [(call (mem (match_operand:SI 0 "mep_nearsym_operand" "s"))
1918          (match_operand:SI 1 "" ""))
1919    (use (match_operand:SI 2 "const_int_operand" ""))
1920    (use (reg:SI LP_REGNO))
1921    (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1922   ]
1923   "SIBLING_CALL_P (insn)"
1925   if (mep_vliw_jmp_match (operands[2]))
1926     return "jmp\t%0";
1927   else if (mep_vliw_mode_match (operands[2]))
1928     return
1929         "movu   $0, %0\n\
1930         jmp     $0";
1931   else
1932     return
1933         "ldc    $12, $lp\n\
1934         movh    $11, %%hi(%0)\n\
1935         xor3    $12, $12, 1\n\
1936         add3    $11, $11, %%lo(%0+1)\n\
1937         stc     $12, $lp\n\
1938         jmp     $11";
1940   [(set_attr "length" "48")
1941    (set_attr "slot" "multi")])
1943 (define_expand "call_value"
1944   [(parallel [(set (match_operand 0 "" "")
1945                    (call (match_operand:QI 1 "" "")
1946                          (match_operand:SI 2 "" "")))
1947               (use (match_operand:SI 3 "" ""))
1948               (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1949               ])]
1950   ""
1951   "
1953   mep_expand_call (operands, 1);
1954   DONE;
1957 (define_insn "call_value_internal"
1958   [(set (match_operand 0 "register_operand" "=rx,rx")
1959         (call (mem:SI (match_operand:SI 1 "mep_call_address_operand" "R,r"))
1960               (match_operand:SI 2 "" "")))
1961    (use (match_operand:SI 3 "const_int_operand" ""))
1962    (use (match_operand:SI 4 "mep_tp_operand" "b,b"))
1963    (use (match_operand:SI 5 "mep_gp_operand" "v,v"))
1964    (clobber (reg:SI LP_REGNO))
1965    (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1966   ]
1967   ""
1969   static char const pattern[2][2][8] = 
1970   {
1971     { "bsrv\t%1", "jsrv\t%1" },
1972     { "bsr\t%1", "jsr\t%1" }
1973   };
1975   return pattern[mep_vliw_mode_match (operands[3])][which_alternative];
1977   [(set_attr "length" "4,2")])
1979 (define_expand "sibcall_value"
1980   [(parallel [(set (match_operand 0 "" "")
1981                    (call (match_operand:QI 1 "" "")
1982                          (match_operand:SI 2 "" "")))
1983               (use (match_operand:SI 3 "" ""))
1984               (use (reg:SI LP_REGNO))
1985               (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1986               ])]
1987   ""
1988   "")
1990 (define_insn "*sibcall_value_internal"
1991   [(set (match_operand 0 "register_operand" "=rx")
1992         (call (mem (match_operand:SI 1 "mep_nearsym_operand" "s"))
1993               (match_operand:SI 2 "" "")))
1994    (use (match_operand:SI 3 "const_int_operand" ""))
1995    (use (reg:SI LP_REGNO))
1996    (clobber (reg:SI REGSAVE_CONTROL_TEMP))
1997   ]
1998   "SIBLING_CALL_P (insn)"
2000   if (mep_vliw_jmp_match (operands[3]))
2001     return "jmp\t%1";
2002   else if (mep_vliw_mode_match (operands[3]))
2003     return
2004         "movu   $0, %1\n\
2005         jmp     $0";
2006   else
2007     return
2008         "ldc    $12, $lp\n\
2009         movh    $11, %%hi(%1)\n\
2010         xor3    $12, $12, 1\n\
2011         add3    $11, $11, %%lo(%1+1)\n\
2012         stc     $12, $lp\n\
2013         jmp     $11";
2015   [(set_attr "length" "48")
2016    (set_attr "slot" "multi")])
2018 (define_insn "return_internal"
2019   [(return)
2020    (use (match_operand:SI 0 "register_operand" ""))]
2021   ""
2022   "* return (REGNO (operands[0]) == LP_REGNO) ? \"ret\" : \"jmp\\t%0\";"
2023   [(set_attr "length" "2")
2024    (set_attr "stall" "ret")])
2026 (define_insn "eh_return_internal"
2027   [(return)
2028    (use (reg:SI 10))
2029    (use (reg:SI 11))
2030    (use (reg:SI LP_REGNO))
2031    (clobber (reg:SI REGSAVE_CONTROL_TEMP))
2032   ]
2033   ""
2034   "ret"
2035   [(set_attr "length" "2")
2036    (set_attr "stall" "ret")])
2038 ;; The assembler replaces short jumps with long jumps as needed.
2039 (define_insn "jump"
2040   [(set (pc) (label_ref (match_operand 0 "" "")))]
2041   ""
2042   "bra\\t%l0"
2043   [(set_attr "length" "4")])
2045 (define_insn "indirect_jump"
2046   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2047   ""
2048   "jmp\\t%0"
2049   [(set_attr "length" "2")])
2051 (define_insn "tablejump"
2052   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2053    (use (label_ref (match_operand 1 "" "")))]
2054   ""
2055   "jmp\\t%0"
2056   [(set_attr "length" "2")])
2059 ;; ::::::::::::::::::::
2060 ;; ::
2061 ;; :: Low Overhead Looping
2062 ;; ::
2063 ;; ::::::::::::::::::::
2065 ;; This insn is volatile because we'd like it to stay in its original
2066 ;; position, just before the loop header.  If it stays there, we might
2067 ;; be able to convert it into a "repeat" insn.
2068 (define_insn "doloop_begin_internal"
2069   [(set (match_operand:SI 0 "register_operand" "=r")
2070         (unspec_volatile:SI
2071          [(match_operand:SI 1 "register_operand" "0")
2072           (match_operand 2 "const_int_operand" "")] UNS_REPEAT_BEG))]
2073   ""
2074   { gcc_unreachable (); }
2075   [(set_attr "length" "4")])
2077 (define_expand "doloop_begin"
2078   [(use (match_operand 0 "register_operand" ""))
2079    (use (match_operand:QI 1 "const_int_operand" ""))
2080    (use (match_operand:QI 2 "const_int_operand" ""))
2081    (use (match_operand:QI 3 "const_int_operand" ""))
2082    (use (match_operand 4 "" ""))]
2083   "!profile_arc_flag && TARGET_OPT_REPEAT"
2084   "if (INTVAL (operands[3]) > 1)
2085      FAIL;
2086    mep_emit_doloop (operands, 0);
2087    DONE;
2088   ")
2090 (define_insn "doloop_end_internal"
2091   [(set (pc)
2092         (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+r,cxy,*m")
2093                           (const_int 0))
2094                       (label_ref (match_operand 1 "" ""))
2095                       (pc)))
2096    (set (match_dup 0)
2097         (plus:SI (match_dup 0)
2098                  (const_int -1)))
2099    (unspec [(match_operand 2 "const_int_operand" "")] UNS_REPEAT_END)
2100    (clobber (match_scratch:SI 3 "=X,&r,&r"))]
2101   ""
2102   { gcc_unreachable (); }
2103   ;; Worst case length:
2104   ;;
2105   ;;      lw <op3>,<op0>        4
2106   ;;      add <op3>,-1          2
2107   ;;      sw <op3>,<op0>        4
2108   ;;      jmp <op1>             4
2109   ;; 1f:
2110   [(set_attr "length" "14")
2111    (set_attr "slot" "multi")])
2113 (define_expand "doloop_end"
2114   [(use (match_operand 0 "nonimmediate_operand" ""))
2115    (use (match_operand:QI 1 "const_int_operand" ""))
2116    (use (match_operand:QI 2 "const_int_operand" ""))
2117    (use (match_operand:QI 3 "const_int_operand" ""))
2118    (use (label_ref (match_operand 4 "" "")))
2119    (use (match_operand 5 "" ""))]
2120   "!profile_arc_flag && TARGET_OPT_REPEAT"
2121   "if (INTVAL (operands[3]) > 1)
2122      FAIL;
2123    if (GET_CODE (operands[0]) == REG && GET_MODE (operands[0]) != SImode)
2124      FAIL;
2125    mep_emit_doloop (operands, 1);
2126    DONE;
2127   ")
2129 (define_insn "repeat"
2130   [(set (reg:SI RPC_REGNO)
2131         (unspec:SI [(match_operand:SI 0 "mep_r0_15_operand" "r")
2132                     (match_operand:SI 1 "" "")]
2133                    UNS_REPEAT_BEG))]
2134   ""
2135   "repeat\\t%0,%l1"
2136   [(set_attr "length" "4")])
2138 (define_insn "repeat_end"
2139   [(unspec [(const_int 0)] UNS_REPEAT_END)]
2140   ""
2141   "# repeat end"
2142   [(set_attr "length" "0")])
2144 (define_insn "erepeat"
2145   [(unspec [(match_operand 0 "" "")] UNS_EREPEAT_BEG)]
2146   ""
2147   "erepeat\\t%l0"
2148   [(set_attr "length" "4")])
2150 (define_insn "erepeat_end"
2151   [(unspec [(const_int 0)] UNS_EREPEAT_END)]
2152   ""
2153   "# erepeat end"
2154   [(set_attr "length" "0")
2155    (set_attr "slot" "multi")])
2158 ;; ::::::::::::::::::::
2159 ;; ::
2160 ;; :: Prologue and Epilogue instructions
2161 ;; ::
2162 ;; ::::::::::::::::::::
2164 (define_expand "prologue"
2165   [(const_int 1)]
2166   ""
2167   "
2169   mep_expand_prologue ();
2170   DONE;
2173 (define_expand "epilogue"
2174   [(return)]
2175   ""
2176   "
2178   mep_expand_epilogue ();
2179   DONE;
2182 (define_expand "eh_return"
2183   [(use (match_operand:SI 0 "register_operand" "r"))]
2184   ""
2185   "
2187   mep_expand_eh_return (operands);
2188   DONE;
2191 (define_insn_and_split "eh_epilogue"
2192   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNS_EH_EPILOGUE)
2193    (use (reg:SI LP_REGNO))]
2194   ""
2195   "#"
2196   "epilogue_completed"
2197   [(const_int 1)]
2198   "mep_emit_eh_epilogue (operands); DONE;"
2199   [(set_attr "slot" "multi")])
2201 (define_expand "sibcall_epilogue"
2202   [(const_int 0)]
2203   ""
2204   "
2206   mep_expand_sibcall_epilogue ();
2207   DONE;
2210 (define_insn "mep_bb_trace_ret"
2211   [(unspec_volatile [(const_int 0)] UNS_BB_TRACE_RET)]
2212   ""
2213   "* return mep_emit_bb_trace_ret ();"
2214   [(set_attr "slot" "multi")])
2216 (define_insn "mep_disable_int"
2217   [(unspec_volatile [(const_int 0)] UNS_DISABLE_INT)]
2218   ""
2219   "di"
2220   [(set_attr "length" "2")])
2222 (define_insn "mep_enable_int"
2223   [(unspec_volatile [(const_int 0)] UNS_ENABLE_INT)]
2224   ""
2225   "ei"
2226   [(set_attr "length" "2")])
2228 (define_insn "mep_reti"
2229   [(return)
2230    (unspec_volatile [(const_int 0)] UNS_RETI)]
2231   ""
2232   "reti"
2233   [(set_attr "length" "2")])
2235 ;; ::::::::::::::::::::
2236 ;; ::
2237 ;; :: Miscellaneous instructions
2238 ;; ::
2239 ;; ::::::::::::::::::::
2241 (define_insn "nop"
2242   [(const_int 0)]
2243   ""
2244   "nop"
2245   [(set_attr "length" "2")])
2247 (define_insn "nop32"
2248   [(const_int 1)]
2249   ""
2250   "or3\\t$0, $0, 0"
2251   [(set_attr "length" "4")])
2253 (define_insn "blockage"
2254   [(unspec_volatile [(const_int 0)] UNS_BLOCKAGE)]
2255   ""
2256   ""
2257   [(set_attr "length" "0")
2258    (set_attr "slot" "multi")])
2261 (define_insn "djmark"
2262   [(unspec_volatile [(const_int 0)] 999)]
2263   ""
2264   "# dj"
2265   [(set_attr "length" "0")
2266    (set_attr "slot" "multi")])