]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/mep/mep.md
Update copyright years in gcc/
[thirdparty/gcc.git] / gcc / config / mep / mep.md
CommitLineData
7acf4da6 1;; Toshiba Media Processor Machine description template
23a5b65a 2;; Copyright (C) 2001-2014 Free Software Foundation, Inc.
7acf4da6
DD
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 REAL_VALUE_TYPE rv;
764 HOST_WIDE_INT value;
765 HOST_WIDE_INT lo, hi;
766 rtx out;
767
768 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
769 REAL_VALUE_TO_TARGET_SINGLE (rv, value);
770
771 lo = value & 0xffff;
772 hi = trunc_int_for_mode (value & 0xffff0000, SImode);
773
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;
779}")
780
781(define_expand "movdf"
782 [(set (match_operand:DF 0 "" "")
783 (match_operand:DF 1 "" ""))]
784 ""
785 "
786{
787 if (mep_expand_mov (operands, DFmode))
788 DONE;
789}")
790
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")])
797
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")])
816
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);")
824
825\f
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")])
836
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")])
847
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")])
858
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")])
869
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")])
880
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")])
891
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")])
902
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")])
913
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)]
920{
921 emit_note (NOTE_INSN_DELETED);
922 DONE;
923})
924\f
925;; ::::::::::::::::::::
926;; ::
927;; :: Reloads
928;; ::
929;; ::::::::::::::::::::
930
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 "
937{
938 mep_expand_reload (operands, SImode);
939 DONE;
940}")
941
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 "
948{
949 mep_expand_reload (operands, SImode);
950 DONE;
951}")
952
953\f
954;; ::::::::::::::::::::
955;; ::
956;; :: Conversions
957;; ::
958;; ::::::::::::::::::::
959
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")])
972
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")])
985
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")])
998
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")])
1011\f
1012;; ::::::::::::::::::::
1013;; ::
1014;; :: 32 bit Integer arithmetic
1015;; ::
1016;; ::::::::::::::::::::
1017
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)))])
1034
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 "")
1053
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")])
1061
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"
1067{
1068 emit_insn (gen_mulsi3_1 (operands[0], operands[1], operands[2]));
1069 DONE;
1070})
1071
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")])
1082
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")])
1097
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")])
1108
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 "
1115{
1116 rtx hi = gen_reg_rtx (SImode);
1117 rtx lo = gen_reg_rtx (SImode);
1118
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;
1123}")
1124
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")])
1141
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")])
1156
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 "
1163{
1164 rtx hi = gen_reg_rtx (SImode);
1165 rtx lo = gen_reg_rtx (SImode);
1166
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;
1171}")
1172
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")])
1189
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")])
1204
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")])
1217
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")])
1229
1230;; A pattern for 'r1 = r2 * r3 + r4'. There are three possible
1231;; implementations:
1232;;
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.
1236;;
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.
1240;;
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.
1244;;
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.
1248;;
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")])
1265
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]);")
1293
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]);")
1316
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))])]
1337{
1338 emit_move_insn (operands[4], operands[3]);
1339 operands[2] = mep_mulr_source (0, operands[0], operands[1], operands[2]);
1340})
1341
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)]
1351{
1352 emit_note (NOTE_INSN_DELETED);
1353 DONE;
1354})
1355
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")])
1366
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")])
1381
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")])
1391
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")])
1404
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")])
1417
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")])
1424
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);")
1435
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")])
1443
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]));")
1456
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")])
1464
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")])
1472
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")])
1480
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")])
1488
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")])
1500
1501;; clip support
1502
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")])
1511
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")])
1520
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")])
1529
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")])
1538\f
1539;; ::::::::::::::::::::
1540;; ::
1541;; :: 32 bit Integer Shifts and Rotates
1542;; ::
1543;; ::::::::::::::::::::
1544
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")])
1555
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")])
1564
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")])
1573\f
1574;; ::::::::::::::::::::
1575;; ::
1576;; :: 32 Bit Integer Logical operations
1577;; ::
1578;; ::::::::::::::::::::
1579
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")])
1589
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")])
1599
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")])
1609
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 ")
1616
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")])
1624\f
1625;; ::::::::::::::::::::
1626;; ::
1627;; :: Bit Manipulation
1628;; ::
1629;; ::::::::::::::::::::
1630
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")])
1642
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")])
1654
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")])
1663
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")])
1674
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 "")
1690
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]);")
1708
1709\f
1710;; ::::::::::::::::::::
1711;; ::
1712;; :: Conditional branches and stores
1713;; ::
1714;; ::::::::::::::::::::
1715
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;")
1743
1744;; ------------------------------------------------------------
1745
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")])
1753
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")])
1761
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")])
1771
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")])
1781
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")])
1791
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")])
1801
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.
1805
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")] )
1815
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")])
1825
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")])
1835
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")])
1845
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")])
1855
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")])
1865\f
1866;; ::::::::::::::::::::
1867;; ::
1868;; :: Call and branch instructions
1869;; ::
1870;; ::::::::::::::::::::
1871
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 "
1880{
1881 mep_expand_call (operands, 0);
1882 DONE;
1883}")
1884
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 ""
1895{
1896 static char const pattern[2][2][8] =
1897 {
1898 { "bsrv\t%0", "jsrv\t%0" },
1899 { "bsr\t%0", "jsr\t%0" }
1900 };
1901
1902 return pattern[mep_vliw_mode_match (operands[2])][which_alternative];
1903}
1904 [(set_attr "length" "4,2")])
1905
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 "")
1915
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)"
1924{
a9d1723f 1925 if (mep_vliw_jmp_match (operands[2]))
7acf4da6 1926 return "jmp\t%0";
54a1e1d0
DD
1927 else if (mep_vliw_mode_match (operands[2]))
1928 return
11af2d7b
DD
1929 "movu $0, %0\n\
1930 jmp $0";
7acf4da6
DD
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";
1939}
1940 [(set_attr "length" "48")
1941 (set_attr "slot" "multi")])
1942
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 "
1952{
1953 mep_expand_call (operands, 1);
1954 DONE;
1955}")
1956
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 ""
1968{
1969 static char const pattern[2][2][8] =
1970 {
1971 { "bsrv\t%1", "jsrv\t%1" },
1972 { "bsr\t%1", "jsr\t%1" }
1973 };
1974
1975 return pattern[mep_vliw_mode_match (operands[3])][which_alternative];
1976}
1977 [(set_attr "length" "4,2")])
1978
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 "")
1989
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)"
1999{
a9d1723f 2000 if (mep_vliw_jmp_match (operands[3]))
7acf4da6 2001 return "jmp\t%1";
54a1e1d0
DD
2002 else if (mep_vliw_mode_match (operands[3]))
2003 return
11af2d7b
DD
2004 "movu $0, %1\n\
2005 jmp $0";
7acf4da6
DD
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";
2014}
2015 [(set_attr "length" "48")
2016 (set_attr "slot" "multi")])
2017
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")])
2025
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")])
2037
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")])
2044
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")])
2050
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")])
2057
2058\f
2059;; ::::::::::::::::::::
2060;; ::
2061;; :: Low Overhead Looping
2062;; ::
2063;; ::::::::::::::::::::
2064
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")])
2076
2077(define_expand "doloop_begin"
2078 [(use (match_operand 0 "register_operand" ""))
1d0216c8 2079 (use (match_operand 1 "" ""))]
7acf4da6 2080 "!profile_arc_flag && TARGET_OPT_REPEAT"
1d0216c8 2081 "mep_emit_doloop (operands, 0);
7acf4da6
DD
2082 DONE;
2083 ")
2084
2085(define_insn "doloop_end_internal"
2086 [(set (pc)
2087 (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+r,cxy,*m")
2088 (const_int 0))
2089 (label_ref (match_operand 1 "" ""))
2090 (pc)))
2091 (set (match_dup 0)
2092 (plus:SI (match_dup 0)
2093 (const_int -1)))
2094 (unspec [(match_operand 2 "const_int_operand" "")] UNS_REPEAT_END)
2095 (clobber (match_scratch:SI 3 "=X,&r,&r"))]
2096 ""
2097 { gcc_unreachable (); }
2098 ;; Worst case length:
2099 ;;
2100 ;; lw <op3>,<op0> 4
2101 ;; add <op3>,-1 2
2102 ;; sw <op3>,<op0> 4
2103 ;; jmp <op1> 4
2104 ;; 1f:
2105 [(set_attr "length" "14")
2106 (set_attr "slot" "multi")])
2107
2108(define_expand "doloop_end"
2109 [(use (match_operand 0 "nonimmediate_operand" ""))
1d0216c8 2110 (use (label_ref (match_operand 1 "" "")))]
7acf4da6 2111 "!profile_arc_flag && TARGET_OPT_REPEAT"
1d0216c8 2112 "if (GET_CODE (operands[0]) == REG && GET_MODE (operands[0]) != SImode)
7acf4da6
DD
2113 FAIL;
2114 mep_emit_doloop (operands, 1);
2115 DONE;
2116 ")
2117
2118(define_insn "repeat"
2119 [(set (reg:SI RPC_REGNO)
2120 (unspec:SI [(match_operand:SI 0 "mep_r0_15_operand" "r")
2121 (match_operand:SI 1 "" "")]
2122 UNS_REPEAT_BEG))]
2123 ""
2124 "repeat\\t%0,%l1"
2125 [(set_attr "length" "4")])
2126
2127(define_insn "repeat_end"
2128 [(unspec [(const_int 0)] UNS_REPEAT_END)]
2129 ""
2130 "# repeat end"
2131 [(set_attr "length" "0")])
2132
2133(define_insn "erepeat"
2134 [(unspec [(match_operand 0 "" "")] UNS_EREPEAT_BEG)]
2135 ""
2136 "erepeat\\t%l0"
2137 [(set_attr "length" "4")])
2138
2139(define_insn "erepeat_end"
2140 [(unspec [(const_int 0)] UNS_EREPEAT_END)]
2141 ""
2142 "# erepeat end"
2143 [(set_attr "length" "0")
2144 (set_attr "slot" "multi")])
2145
2146\f
2147;; ::::::::::::::::::::
2148;; ::
2149;; :: Prologue and Epilogue instructions
2150;; ::
2151;; ::::::::::::::::::::
2152
2153(define_expand "prologue"
2154 [(const_int 1)]
2155 ""
2156 "
2157{
2158 mep_expand_prologue ();
2159 DONE;
2160}")
2161
2162(define_expand "epilogue"
2163 [(return)]
2164 ""
2165 "
2166{
2167 mep_expand_epilogue ();
2168 DONE;
2169}")
2170
2171(define_expand "eh_return"
2172 [(use (match_operand:SI 0 "register_operand" "r"))]
2173 ""
2174 "
2175{
2176 mep_expand_eh_return (operands);
2177 DONE;
2178}")
2179
2180(define_insn_and_split "eh_epilogue"
2181 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNS_EH_EPILOGUE)
2182 (use (reg:SI LP_REGNO))]
2183 ""
2184 "#"
5ba863d7 2185 "epilogue_completed"
7acf4da6
DD
2186 [(const_int 1)]
2187 "mep_emit_eh_epilogue (operands); DONE;"
2188 [(set_attr "slot" "multi")])
2189
2190(define_expand "sibcall_epilogue"
2191 [(const_int 0)]
2192 ""
2193 "
2194{
2195 mep_expand_sibcall_epilogue ();
2196 DONE;
2197}")
2198
2199(define_insn "mep_bb_trace_ret"
2200 [(unspec_volatile [(const_int 0)] UNS_BB_TRACE_RET)]
2201 ""
2202 "* return mep_emit_bb_trace_ret ();"
2203 [(set_attr "slot" "multi")])
2204
2205(define_insn "mep_disable_int"
2206 [(unspec_volatile [(const_int 0)] UNS_DISABLE_INT)]
2207 ""
2208 "di"
2209 [(set_attr "length" "2")])
2210
2211(define_insn "mep_enable_int"
2212 [(unspec_volatile [(const_int 0)] UNS_ENABLE_INT)]
2213 ""
2214 "ei"
2215 [(set_attr "length" "2")])
2216
2217(define_insn "mep_reti"
2218 [(return)
2219 (unspec_volatile [(const_int 0)] UNS_RETI)]
2220 ""
2221 "reti"
2222 [(set_attr "length" "2")])
2223\f
2224;; ::::::::::::::::::::
2225;; ::
2226;; :: Miscellaneous instructions
2227;; ::
2228;; ::::::::::::::::::::
2229
2230(define_insn "nop"
2231 [(const_int 0)]
2232 ""
2233 "nop"
2234 [(set_attr "length" "2")])
2235
2236(define_insn "nop32"
2237 [(const_int 1)]
2238 ""
2239 "or3\\t$0, $0, 0"
2240 [(set_attr "length" "4")])
2241
2242(define_insn "blockage"
2243 [(unspec_volatile [(const_int 0)] UNS_BLOCKAGE)]
2244 ""
2245 ""
2246 [(set_attr "length" "0")
2247 (set_attr "slot" "multi")])
2248
2249
2250(define_insn "djmark"
2251 [(unspec_volatile [(const_int 0)] 999)]
2252 ""
2253 "# dj"
2254 [(set_attr "length" "0")
2255 (set_attr "slot" "multi")])
2256