]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/mep/mep.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / mep / mep.md
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 \f
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 \f
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 \f
346 (include "predicates.md")
347 (include "constraints.md")
348 (include "intrinsics.md")
349 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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