]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/bfin/bfin.md
re PR libstdc++/27404 (Rope iterators are not InputIterators)
[thirdparty/gcc.git] / gcc / config / bfin / bfin.md
CommitLineData
0d4a78eb 1;;- Machine description for Blackfin for GNU compiler
4729dc92 2;; Copyright 2005, 2006 Free Software Foundation, Inc.
0d4a78eb
BS
3;; Contributed by Analog Devices.
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
9;; by the Free Software Foundation; either version 2, or (at your
10;; option) 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 COPYING. If not, write to
39d14dda
KC
19;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20;; Boston, MA 02110-1301, USA.
0d4a78eb
BS
21
22; operand punctuation marks:
23;
24; X -- integer value printed as log2
25; Y -- integer value printed as log2(~value) - for bitclear
26; h -- print half word register, low part
27; d -- print half word register, high part
28; D -- print operand as dregs pairs
29; w -- print operand as accumulator register word (a0w, a1w)
30; H -- high part of double mode operand
31; T -- byte register representation Oct. 02 2001
32
33; constant operand classes
34;
35; J 2**N 5bit imm scaled
36; Ks7 -64 .. 63 signed 7bit imm
37; Ku5 0..31 unsigned 5bit imm
38; Ks4 -8 .. 7 signed 4bit imm
39; Ks3 -4 .. 3 signed 3bit imm
40; Ku3 0 .. 7 unsigned 3bit imm
41; Pn 0, 1, 2 constants 0, 1 or 2, corresponding to n
42;
43; register operands
44; d (r0..r7)
45; a (p0..p5,fp,sp)
46; e (a0, a1)
47; b (i0..i3)
48; f (m0..m3)
49; B
50; c (i0..i3,m0..m3) CIRCREGS
51; C (CC) CCREGS
52;
53
54;; Define constants for hard registers.
55
56(define_constants
57 [(REG_R0 0)
58 (REG_R1 1)
59 (REG_R2 2)
60 (REG_R3 3)
61 (REG_R4 4)
62 (REG_R5 5)
63 (REG_R6 6)
64 (REG_R7 7)
65
66 (REG_P0 8)
67 (REG_P1 9)
68 (REG_P2 10)
69 (REG_P3 11)
70 (REG_P4 12)
71 (REG_P5 13)
72 (REG_P6 14)
73 (REG_P7 15)
74
75 (REG_SP 14)
76 (REG_FP 15)
77
78 (REG_I0 16)
df259245
JZ
79 (REG_I1 17)
80 (REG_I2 18)
81 (REG_I3 19)
82
83 (REG_B0 20)
84 (REG_B1 21)
85 (REG_B2 22)
86 (REG_B3 23)
87
88 (REG_L0 24)
89 (REG_L1 25)
90 (REG_L2 26)
0d4a78eb
BS
91 (REG_L3 27)
92
93 (REG_M0 28)
94 (REG_M1 29)
95 (REG_M2 30)
96 (REG_M3 31)
97
98 (REG_A0 32)
99 (REG_A1 33)
100
101 (REG_CC 34)
102 (REG_RETS 35)
103 (REG_RETI 36)
104 (REG_RETX 37)
105 (REG_RETN 38)
106 (REG_RETE 39)
107
108 (REG_ASTAT 40)
109 (REG_SEQSTAT 41)
110 (REG_USP 42)
111
112 (REG_ARGP 43)])
113
114;; Constants used in UNSPECs and UNSPEC_VOLATILEs.
115
116(define_constants
117 [(UNSPEC_CBRANCH_TAKEN 0)
118 (UNSPEC_CBRANCH_NOPS 1)
119 (UNSPEC_RETURN 2)
120 (UNSPEC_MOVE_PIC 3)
121 (UNSPEC_LIBRARY_OFFSET 4)
75d8b2d0
BS
122 (UNSPEC_PUSH_MULTIPLE 5)
123 ;; Multiply or MAC with extra CONST_INT operand specifying the macflag
124 (UNSPEC_MUL_WITH_FLAG 6)
125 (UNSPEC_MAC_WITH_FLAG 7)])
0d4a78eb
BS
126
127(define_constants
5fcead21
BS
128 [(UNSPEC_VOLATILE_EH_RETURN 0)
129 (UNSPEC_VOLATILE_CSYNC 1)
130 (UNSPEC_VOLATILE_SSYNC 2)])
0d4a78eb 131
75d8b2d0
BS
132(define_constants
133 [(MACFLAG_NONE 0)
134 (MACFLAG_T 1)
135 (MACFLAG_FU 2)
136 (MACFLAG_TFU 3)
137 (MACFLAG_IS 4)
138 (MACFLAG_IU 5)
139 (MACFLAG_W32 6)
140 (MACFLAG_M 7)
141 (MACFLAG_S2RND 8)
142 (MACFLAG_ISS2 9)
143 (MACFLAG_IH 10)])
144
0d4a78eb 145(define_attr "type"
3fb192d2 146 "move,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy"
0d4a78eb
BS
147 (const_string "misc"))
148
149;; Scheduling definitions
150
151(define_automaton "bfin")
152
153(define_cpu_unit "core" "bfin")
154
155(define_insn_reservation "alu" 1
3fb192d2 156 (eq_attr "type" "move,mvi,mcst,dsp32,alu0,shft,brcc,br,call,misc,sync,compare")
0d4a78eb
BS
157 "core")
158
159(define_insn_reservation "imul" 3
160 (eq_attr "type" "mult")
161 "core*3")
162
163(define_insn_reservation "load" 1
164 (eq_attr "type" "mcld")
165 "core")
166
167;; Make sure genautomata knows about the maximum latency that can be produced
168;; by the adjust_cost function.
169(define_insn_reservation "dummy" 5
170 (eq_attr "type" "mcld")
171 "core")
172\f
173;; Operand and operator predicates
174
175(include "predicates.md")
176
177\f
178;;; FRIO branches have been optimized for code density
179;;; this comes at a slight cost of complexity when
180;;; a compiler needs to generate branches in the general
181;;; case. In order to generate the correct branching
182;;; mechanisms the compiler needs keep track of instruction
183;;; lengths. The follow table describes how to count instructions
184;;; for the FRIO architecture.
185;;;
186;;; unconditional br are 12-bit imm pcrelative branches *2
187;;; conditional br are 10-bit imm pcrelative branches *2
188;;; brcc 10-bit:
189;;; 1024 10-bit imm *2 is 2048 (-1024..1022)
190;;; br 12-bit :
191;;; 4096 12-bit imm *2 is 8192 (-4096..4094)
192;;; NOTE : For brcc we generate instructions such as
193;;; if cc jmp; jump.[sl] offset
194;;; offset of jump.[sl] is from the jump instruction but
195;;; gcc calculates length from the if cc jmp instruction
a2391c6a
JZ
196;;; furthermore gcc takes the end address of the branch instruction
197;;; as (pc) for a forward branch
198;;; hence our range is (-4094, 4092) instead of (-4096, 4094) for a br
0d4a78eb
BS
199;;;
200;;; The way the (pc) rtx works in these calculations is somewhat odd;
201;;; for backward branches it's the address of the current instruction,
202;;; for forward branches it's the previously known address of the following
203;;; instruction - we have to take this into account by reducing the range
204;;; for a forward branch.
205
206;; Lengths for type "mvi" insns are always defined by the instructions
207;; themselves.
208(define_attr "length" ""
209 (cond [(eq_attr "type" "mcld")
210 (if_then_else (match_operand 1 "effective_address_32bit_p" "")
211 (const_int 4) (const_int 2))
212
213 (eq_attr "type" "mcst")
214 (if_then_else (match_operand 0 "effective_address_32bit_p" "")
215 (const_int 4) (const_int 2))
216
217 (eq_attr "type" "move") (const_int 2)
218
219 (eq_attr "type" "dsp32") (const_int 4)
220 (eq_attr "type" "call") (const_int 4)
221
222 (eq_attr "type" "br")
223 (if_then_else (and
224 (le (minus (match_dup 0) (pc)) (const_int 4092))
225 (ge (minus (match_dup 0) (pc)) (const_int -4096)))
226 (const_int 2)
227 (const_int 4))
228
229 (eq_attr "type" "brcc")
230 (cond [(and
231 (le (minus (match_dup 3) (pc)) (const_int 1020))
232 (ge (minus (match_dup 3) (pc)) (const_int -1024)))
233 (const_int 2)
234 (and
a2391c6a 235 (le (minus (match_dup 3) (pc)) (const_int 4092))
0d4a78eb
BS
236 (ge (minus (match_dup 3) (pc)) (const_int -4094)))
237 (const_int 4)]
238 (const_int 6))
239 ]
240
241 (const_int 2)))
242
243;; Conditional moves
244
245(define_expand "movsicc"
246 [(set (match_operand:SI 0 "register_operand" "")
247 (if_then_else:SI (match_operand 1 "comparison_operator" "")
248 (match_operand:SI 2 "register_operand" "")
249 (match_operand:SI 3 "register_operand" "")))]
250 ""
251{
252 operands[1] = bfin_gen_compare (operands[1], SImode);
253})
254
255(define_insn "*movsicc_insn1"
256 [(set (match_operand:SI 0 "register_operand" "=da,da,da")
257 (if_then_else:SI
4729dc92 258 (eq:BI (match_operand:BI 3 "register_operand" "C,C,C")
0d4a78eb
BS
259 (const_int 0))
260 (match_operand:SI 1 "register_operand" "da,0,da")
261 (match_operand:SI 2 "register_operand" "0,da,da")))]
262 ""
263 "@
264 if !cc %0 =%1; /* movsicc-1a */
265 if cc %0 =%2; /* movsicc-1b */
266 if !cc %0 =%1; if cc %0=%2; /* movsicc-1 */"
267 [(set_attr "length" "2,2,4")
268 (set_attr "type" "move")])
269
270(define_insn "*movsicc_insn2"
271 [(set (match_operand:SI 0 "register_operand" "=da,da,da")
272 (if_then_else:SI
4729dc92 273 (ne:BI (match_operand:BI 3 "register_operand" "C,C,C")
0d4a78eb
BS
274 (const_int 0))
275 (match_operand:SI 1 "register_operand" "0,da,da")
276 (match_operand:SI 2 "register_operand" "da,0,da")))]
277 ""
278 "@
279 if !cc %0 =%2; /* movsicc-2b */
280 if cc %0 =%1; /* movsicc-2a */
281 if cc %0 =%1; if !cc %0=%2; /* movsicc-1 */"
282 [(set_attr "length" "2,2,4")
283 (set_attr "type" "move")])
284
285;; Insns to load HIGH and LO_SUM
286
287(define_insn "movsi_high"
288 [(set (match_operand:SI 0 "register_operand" "=x")
289 (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
290 "reload_completed"
291 "%d0 = %d1;"
292 [(set_attr "type" "mvi")
293 (set_attr "length" "4")])
294
295(define_insn "movstricthi_high"
296 [(set (match_operand:SI 0 "register_operand" "+x")
297 (ior:SI (and:SI (match_dup 0) (const_int 65535))
298 (match_operand:SI 1 "immediate_operand" "i")))]
299 "reload_completed"
300 "%d0 = %d1;"
301 [(set_attr "type" "mvi")
302 (set_attr "length" "4")])
303
304(define_insn "movsi_low"
305 [(set (match_operand:SI 0 "register_operand" "=x")
306 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
307 (match_operand:SI 2 "immediate_operand" "i")))]
308 "reload_completed"
309 "%h0 = %h2;"
310 [(set_attr "type" "mvi")
311 (set_attr "length" "4")])
312
313(define_insn "movsi_high_pic"
314 [(set (match_operand:SI 0 "register_operand" "=x")
315 (high:SI (unspec:SI [(match_operand:SI 1 "" "")]
316 UNSPEC_MOVE_PIC)))]
317 ""
318 "%d0 = %1@GOT_LOW;"
319 [(set_attr "type" "mvi")
320 (set_attr "length" "4")])
321
322(define_insn "movsi_low_pic"
323 [(set (match_operand:SI 0 "register_operand" "=x")
324 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
325 (unspec:SI [(match_operand:SI 2 "" "")]
326 UNSPEC_MOVE_PIC)))]
327 ""
328 "%h0 = %h2@GOT_HIGH;"
329 [(set_attr "type" "mvi")
330 (set_attr "length" "4")])
331
332;;; Move instructions
333
334(define_insn_and_split "movdi_insn"
335 [(set (match_operand:DI 0 "nonimmediate_operand" "=x,mx,r")
336 (match_operand:DI 1 "general_operand" "iFx,r,mx"))]
337 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
338 "#"
339 "reload_completed"
340 [(set (match_dup 2) (match_dup 3))
341 (set (match_dup 4) (match_dup 5))]
342{
343 rtx lo_half[2], hi_half[2];
344 split_di (operands, 2, lo_half, hi_half);
345
346 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
347 {
348 operands[2] = hi_half[0];
349 operands[3] = hi_half[1];
350 operands[4] = lo_half[0];
351 operands[5] = lo_half[1];
352 }
353 else
354 {
355 operands[2] = lo_half[0];
356 operands[3] = lo_half[1];
357 operands[4] = hi_half[0];
358 operands[5] = hi_half[1];
359 }
360})
361
362(define_insn "movbi"
4729dc92
BS
363 [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,md,C,d,C")
364 (match_operand:BI 1 "general_operand" "x,xKs3,md,d,d,C,P0"))]
0d4a78eb
BS
365
366 ""
367 "@
368 %0 = %1;
369 %0 = %1 (X);
4729dc92
BS
370 %0 = B %1 (Z);
371 B %0 = %1;
0d4a78eb 372 CC = %1;
49373252
BS
373 %0 = CC;
374 R0 = R0 | R0; CC = AC0;"
375 [(set_attr "type" "move,mvi,mcld,mcst,compare,compare,alu0")
376 (set_attr "length" "2,2,*,*,2,2,4")])
0d4a78eb
BS
377
378(define_insn "movpdi"
379 [(set (match_operand:PDI 0 "nonimmediate_operand" "=e,<,e")
380 (match_operand:PDI 1 "general_operand" " e,e,>"))]
381 ""
382 "@
383 %0 = %1;
384 %0 = %x1; %0 = %w1;
385 %w0 = %1; %x0 = %1;"
386 [(set_attr "type" "move,mcst,mcld")])
387
75d8b2d0
BS
388(define_insn "load_accumulator"
389 [(set (match_operand:PDI 0 "register_operand" "=e")
390 (sign_extend:PDI (match_operand:SI 1 "register_operand" "d")))]
391 ""
392 "%0 = %1;"
393 [(set_attr "type" "move")])
394
395(define_insn_and_split "load_accumulator_pair"
396 [(set (match_operand:V2PDI 0 "register_operand" "=e")
397 (sign_extend:V2PDI (vec_concat:V2SI
398 (match_operand:SI 1 "register_operand" "d")
399 (match_operand:SI 2 "register_operand" "d"))))]
400 ""
401 "#"
402 "reload_completed"
403 [(set (match_dup 3) (sign_extend:PDI (match_dup 1)))
404 (set (match_dup 4) (sign_extend:PDI (match_dup 2)))]
405{
406 operands[3] = gen_rtx_REG (PDImode, REGNO (operands[0]));
407 operands[4] = gen_rtx_REG (PDImode, REGNO (operands[0]) + 1);
408})
409
0d4a78eb
BS
410(define_insn "*pushsi_insn"
411 [(set (mem:SI (pre_dec:SI (reg:SI REG_SP)))
412 (match_operand:SI 0 "register_operand" "xy"))]
413 ""
414 "[--SP] = %0;"
415 [(set_attr "type" "mcst")
416 (set_attr "length" "2")])
417
418(define_insn "*popsi_insn"
419 [(set (match_operand:SI 0 "register_operand" "=xy")
420 (mem:SI (post_inc:SI (reg:SI REG_SP))))]
421 ""
422 "%0 = [SP++];"
423 [(set_attr "type" "mcld")
424 (set_attr "length" "2")])
425
426;; The first alternative is used to make reload choose a limited register
427;; class when faced with a movsi_insn that had its input operand replaced
428;; with a PLUS. We generally require fewer secondary reloads this way.
429(define_insn "*movsi_insn"
430 [(set (match_operand:SI 0 "nonimmediate_operand" "=da,x*y,da,x,x,x,da,mr")
431 (match_operand:SI 1 "general_operand" "da,x*y,xKs7,xKsh,xKuh,ix,mr,da"))]
432
433 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
434 "@
435 %0 = %1;
436 %0 = %1;
437 %0 = %1 (X);
438 %0 = %1 (X);
439 %0 = %1 (Z);
440 #
441 %0 = %1;
442 %0 = %1;"
443 [(set_attr "type" "move,move,mvi,mvi,mvi,*,mcld,mcst")
444 (set_attr "length" "2,2,2,4,4,*,*,*")])
445
75d8b2d0
BS
446(define_insn_and_split "*movv2hi_insn"
447 [(set (match_operand:V2HI 0 "nonimmediate_operand" "=da,da,d,dm")
448 (match_operand:V2HI 1 "general_operand" "i,di,md,d"))]
0d4a78eb
BS
449
450 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
75d8b2d0
BS
451 "@
452 #
453 %0 = %1;
454 %0 = %1;
455 %0 = %1;"
456 "reload_completed && GET_CODE (operands[1]) == CONST_VECTOR"
457 [(set (match_dup 0) (high:SI (match_dup 2)))
458 (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 3)))]
459{
460 HOST_WIDE_INT intval = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
461 intval |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
462
463 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
464 operands[2] = operands[3] = GEN_INT (trunc_int_for_mode (intval, SImode));
465}
466 [(set_attr "type" "move,move,mcld,mcst")
467 (set_attr "length" "2,2,*,*")])
0d4a78eb
BS
468
469(define_insn "*movhi_insn"
470 [(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr")
471 (match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
472 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
c4963a0a
BS
473{
474 static const char *templates[] = {
475 "%0 = %1;",
476 "%0 = %1 (X);",
477 "%0 = %1 (X);",
478 "%0 = W %1 (X);",
479 "W %0 = %1;",
480 "%h0 = W %1;",
481 "W %0 = %h1;"
482 };
483 int alt = which_alternative;
484 rtx mem = (MEM_P (operands[0]) ? operands[0]
485 : MEM_P (operands[1]) ? operands[1] : NULL_RTX);
486 if (mem && bfin_dsp_memref_p (mem))
487 alt += 2;
488 return templates[alt];
489}
0d4a78eb
BS
490 [(set_attr "type" "move,mvi,mvi,mcld,mcst")
491 (set_attr "length" "2,2,4,*,*")])
492
493(define_insn "*movqi_insn"
494 [(set (match_operand:QI 0 "nonimmediate_operand" "=x,da,x,d,mr")
495 (match_operand:QI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
496 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
497 "@
498 %0 = %1;
499 %0 = %1 (X);
500 %0 = %1 (X);
501 %0 = B %1 (X);
502 B %0 = %1;"
503 [(set_attr "type" "move,mvi,mvi,mcld,mcst")
504 (set_attr "length" "2,2,4,*,*")])
505
506(define_insn "*movsf_insn"
507 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,da,mr")
508 (match_operand:SF 1 "general_operand" "x,Fx,mr,da"))]
509 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
510 "@
511 %0 = %1;
512 #
513 %0 = %1;
514 %0 = %1;"
515 [(set_attr "type" "move,*,mcld,mcst")])
516
517(define_insn_and_split "movdf_insn"
518 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,mx,r")
519 (match_operand:DF 1 "general_operand" "iFx,r,mx"))]
520 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
521 "#"
522 "reload_completed"
523 [(set (match_dup 2) (match_dup 3))
524 (set (match_dup 4) (match_dup 5))]
525{
526 rtx lo_half[2], hi_half[2];
527 split_di (operands, 2, lo_half, hi_half);
528
529 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
530 {
531 operands[2] = hi_half[0];
532 operands[3] = hi_half[1];
533 operands[4] = lo_half[0];
534 operands[5] = lo_half[1];
535 }
536 else
537 {
538 operands[2] = lo_half[0];
539 operands[3] = lo_half[1];
540 operands[4] = hi_half[0];
541 operands[5] = hi_half[1];
542 }
543})
544
75d8b2d0
BS
545;; Storing halfwords.
546(define_insn "*movsi_insv"
547 [(set (zero_extract:SI (match_operand 0 "register_operand" "+d,x")
548 (const_int 16)
549 (const_int 16))
550 (match_operand:SI 1 "nonmemory_operand" "d,n"))]
551 ""
552 "@
553 %d0 = %h1 << 0;
554 %d0 = %1;"
555 [(set_attr "type" "dsp32,mvi")])
556
557(define_expand "insv"
558 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
559 (match_operand:SI 1 "immediate_operand" "")
560 (match_operand:SI 2 "immediate_operand" ""))
561 (match_operand:SI 3 "nonmemory_operand" ""))]
562 ""
563{
564 if (INTVAL (operands[1]) != 16 || INTVAL (operands[2]) != 16)
565 FAIL;
566
567 /* From mips.md: insert_bit_field doesn't verify that our source
568 matches the predicate, so check it again here. */
569 if (! register_operand (operands[0], VOIDmode))
570 FAIL;
571})
572
0d4a78eb
BS
573;; This is the main "hook" for PIC code. When generating
574;; PIC, movsi is responsible for determining when the source address
575;; needs PIC relocation and appropriately calling legitimize_pic_address
576;; to perform the actual relocation.
577
578(define_expand "movsi"
579 [(set (match_operand:SI 0 "nonimmediate_operand" "")
580 (match_operand:SI 1 "general_operand" ""))]
581 ""
582 "expand_move (operands, SImode);")
583
584(define_expand "movv2hi"
585 [(set (match_operand:V2HI 0 "nonimmediate_operand" "")
586 (match_operand:V2HI 1 "general_operand" ""))]
587 ""
588 "expand_move (operands, V2HImode);")
589
590(define_expand "movdi"
591 [(set (match_operand:DI 0 "nonimmediate_operand" "")
592 (match_operand:DI 1 "general_operand" ""))]
593 ""
594 "expand_move (operands, DImode);")
595
596(define_expand "movsf"
597 [(set (match_operand:SF 0 "nonimmediate_operand" "")
598 (match_operand:SF 1 "general_operand" ""))]
599 ""
600 "expand_move (operands, SFmode);")
601
602(define_expand "movdf"
603 [(set (match_operand:DF 0 "nonimmediate_operand" "")
604 (match_operand:DF 1 "general_operand" ""))]
605 ""
606 "expand_move (operands, DFmode);")
607
608(define_expand "movhi"
609 [(set (match_operand:HI 0 "nonimmediate_operand" "")
610 (match_operand:HI 1 "general_operand" ""))]
611 ""
612 "expand_move (operands, HImode);")
613
614(define_expand "movqi"
615 [(set (match_operand:QI 0 "nonimmediate_operand" "")
616 (match_operand:QI 1 "general_operand" ""))]
617 ""
618 " expand_move (operands, QImode); ")
619
620;; Some define_splits to break up SI/SFmode loads of immediate constants.
621
622(define_split
623 [(set (match_operand:SI 0 "register_operand" "")
624 (match_operand:SI 1 "symbolic_or_const_operand" ""))]
625 "reload_completed
626 /* Always split symbolic operands; split integer constants that are
627 too large for a single instruction. */
628 && (GET_CODE (operands[1]) != CONST_INT
629 || (INTVAL (operands[1]) < -32768
630 || INTVAL (operands[1]) >= 65536
631 || (INTVAL (operands[1]) >= 32768 && PREG_P (operands[0]))))"
632 [(set (match_dup 0) (high:SI (match_dup 1)))
633 (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))]
634{
635 if (GET_CODE (operands[1]) == CONST_INT
636 && split_load_immediate (operands))
637 DONE;
638 /* ??? Do something about TARGET_LOW_64K. */
639})
640
641(define_split
642 [(set (match_operand:SF 0 "register_operand" "")
643 (match_operand:SF 1 "immediate_operand" ""))]
644 "reload_completed"
645 [(set (match_dup 2) (high:SI (match_dup 3)))
646 (set (match_dup 2) (lo_sum:SI (match_dup 2) (match_dup 3)))]
647{
648 long values;
649 REAL_VALUE_TYPE value;
650
3b9dd769 651 gcc_assert (GET_CODE (operands[1]) == CONST_DOUBLE);
0d4a78eb
BS
652
653 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
654 REAL_VALUE_TO_TARGET_SINGLE (value, values);
655
656 operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0]));
657 operands[3] = GEN_INT (trunc_int_for_mode (values, SImode));
658 if (values >= -32768 && values < 65536)
659 {
660 emit_move_insn (operands[2], operands[3]);
661 DONE;
662 }
663 if (split_load_immediate (operands + 2))
664 DONE;
665})
666
667;; Sadly, this can't be a proper named movstrict pattern, since the compiler
668;; expects to be able to use registers for operand 1.
669;; Note that the asm instruction is defined by the manual to take an unsigned
670;; constant, but it doesn't matter to the assembler, and the compiler only
671;; deals with sign-extended constants. Hence "Ksh".
75d8b2d0 672(define_insn "movstricthi_1"
0d4a78eb
BS
673 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+x"))
674 (match_operand:HI 1 "immediate_operand" "Ksh"))]
675 ""
676 "%h0 = %1;"
677 [(set_attr "type" "mvi")
678 (set_attr "length" "4")])
679
680;; Sign and zero extensions
681
c4963a0a 682(define_insn_and_split "extendhisi2"
0d4a78eb
BS
683 [(set (match_operand:SI 0 "register_operand" "=d, d")
684 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
685 ""
686 "@
687 %0 = %h1 (X);
688 %0 = W %h1 (X);"
c4963a0a
BS
689 "reload_completed && bfin_dsp_memref_p (operands[1])"
690 [(set (match_dup 2) (match_dup 1))
691 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
692{
693 operands[2] = gen_lowpart (HImode, operands[0]);
694}
0d4a78eb
BS
695 [(set_attr "type" "alu0,mcld")])
696
c4963a0a 697(define_insn_and_split "zero_extendhisi2"
0d4a78eb
BS
698 [(set (match_operand:SI 0 "register_operand" "=d, d")
699 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
700 ""
701 "@
702 %0 = %h1 (Z);
c4963a0a
BS
703 %0 = W %h1 (Z);"
704 "reload_completed && bfin_dsp_memref_p (operands[1])"
705 [(set (match_dup 2) (match_dup 1))
706 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
707{
708 operands[2] = gen_lowpart (HImode, operands[0]);
709}
0d4a78eb
BS
710 [(set_attr "type" "alu0,mcld")])
711
712(define_insn "zero_extendbisi2"
713 [(set (match_operand:SI 0 "register_operand" "=d")
714 (zero_extend:SI (match_operand:BI 1 "nonimmediate_operand" "C")))]
715 ""
716 "%0 = %1;"
717 [(set_attr "type" "compare")])
718
719(define_insn "extendqihi2"
720 [(set (match_operand:HI 0 "register_operand" "=d, d")
721 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
722 ""
723 "@
724 %0 = B %1 (X);
725 %0 = %T1 (X);"
726 [(set_attr "type" "mcld,alu0")])
727
728(define_insn "extendqisi2"
729 [(set (match_operand:SI 0 "register_operand" "=d, d")
730 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
731 ""
732 "@
733 %0 = B %1 (X);
734 %0 = %T1 (X);"
735 [(set_attr "type" "mcld,alu0")])
736
737
738(define_insn "zero_extendqihi2"
739 [(set (match_operand:HI 0 "register_operand" "=d, d")
740 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
741 ""
742 "@
743 %0 = B %1 (Z);
744 %0 = %T1 (Z);"
745 [(set_attr "type" "mcld,alu0")])
746
747
748(define_insn "zero_extendqisi2"
749 [(set (match_operand:SI 0 "register_operand" "=d, d")
750 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
751 ""
752 "@
753 %0 = B %1 (Z);
754 %0 = %T1 (Z);"
755 [(set_attr "type" "mcld,alu0")])
756
757;; DImode logical operations
758
759(define_code_macro any_logical [and ior xor])
760(define_code_attr optab [(and "and")
761 (ior "ior")
762 (xor "xor")])
763(define_code_attr op [(and "&")
764 (ior "|")
765 (xor "^")])
766(define_code_attr high_result [(and "0")
767 (ior "%H1")
768 (xor "%H1")])
769
770(define_insn "<optab>di3"
771 [(set (match_operand:DI 0 "register_operand" "=d")
772 (any_logical:DI (match_operand:DI 1 "register_operand" "0")
773 (match_operand:DI 2 "register_operand" "d")))]
774 ""
775 "%0 = %1 <op> %2;\\n\\t%H0 = %H1 <op> %H2;"
776 [(set_attr "length" "4")])
777
778(define_insn "*<optab>di_zesidi_di"
779 [(set (match_operand:DI 0 "register_operand" "=d")
780 (any_logical:DI (zero_extend:DI
781 (match_operand:SI 2 "register_operand" "d"))
782 (match_operand:DI 1 "register_operand" "d")))]
783 ""
784 "%0 = %1 <op> %2;\\n\\t%H0 = <high_result>;"
785 [(set_attr "length" "4")])
786
787(define_insn "*<optab>di_sesdi_di"
788 [(set (match_operand:DI 0 "register_operand" "=d")
789 (any_logical:DI (sign_extend:DI
790 (match_operand:SI 2 "register_operand" "d"))
791 (match_operand:DI 1 "register_operand" "0")))
792 (clobber (match_scratch:SI 3 "=&d"))]
793 ""
794 "%0 = %1 <op> %2;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 <op> %3;"
795 [(set_attr "length" "8")])
796
797(define_insn "negdi2"
798 [(set (match_operand:DI 0 "register_operand" "=d")
799 (neg:DI (match_operand:DI 1 "register_operand" "d")))
800 (clobber (match_scratch:SI 2 "=&d"))
801 (clobber (reg:CC REG_CC))]
802 ""
803 "%2 = 0; %2 = %2 - %1; cc = ac0; cc = !cc; %2 = cc;\\n\\t%0 = -%1; %H0 = -%H1; %H0 = %H0 - %2;"
804 [(set_attr "length" "16")])
805
806(define_insn "one_cmpldi2"
807 [(set (match_operand:DI 0 "register_operand" "=d")
808 (not:DI (match_operand:DI 1 "register_operand" "d")))]
809 ""
810 "%0 = ~%1;\\n\\t%H0 = ~%H1;"
811 [(set_attr "length" "4")])
812
813;; DImode zero and sign extend patterns
814
815(define_insn_and_split "zero_extendsidi2"
816 [(set (match_operand:DI 0 "register_operand" "=d")
817 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
818 ""
819 "#"
820 "reload_completed"
821 [(set (match_dup 3) (const_int 0))]
822{
823 split_di (operands, 1, operands + 2, operands + 3);
824 if (REGNO (operands[0]) != REGNO (operands[1]))
825 emit_move_insn (operands[2], operands[1]);
826})
827
828(define_insn "zero_extendqidi2"
829 [(set (match_operand:DI 0 "register_operand" "=d")
830 (zero_extend:DI (match_operand:QI 1 "register_operand" "d")))]
831 ""
832 "%0 = %T1 (Z);\\n\\t%H0 = 0;"
833 [(set_attr "length" "4")])
834
835(define_insn "zero_extendhidi2"
836 [(set (match_operand:DI 0 "register_operand" "=d")
837 (zero_extend:DI (match_operand:HI 1 "register_operand" "d")))]
838 ""
839 "%0 = %h1 (Z);\\n\\t%H0 = 0;"
840 [(set_attr "length" "4")])
841
842(define_insn_and_split "extendsidi2"
843 [(set (match_operand:DI 0 "register_operand" "=d")
844 (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))]
845 ""
846 "#"
847 "reload_completed"
848 [(set (match_dup 3) (match_dup 1))
849 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
850{
851 split_di (operands, 1, operands + 2, operands + 3);
852 if (REGNO (operands[0]) != REGNO (operands[1]))
853 emit_move_insn (operands[2], operands[1]);
854})
855
856(define_insn_and_split "extendqidi2"
857 [(set (match_operand:DI 0 "register_operand" "=d")
858 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
859 ""
860 "#"
861 "reload_completed"
862 [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
863 (set (match_dup 3) (sign_extend:SI (match_dup 1)))
864 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
865{
866 split_di (operands, 1, operands + 2, operands + 3);
867})
868
869(define_insn_and_split "extendhidi2"
870 [(set (match_operand:DI 0 "register_operand" "=d")
871 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
872 ""
873 "#"
874 "reload_completed"
875 [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
876 (set (match_dup 3) (sign_extend:SI (match_dup 1)))
877 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
878{
879 split_di (operands, 1, operands + 2, operands + 3);
880})
881
882;; DImode arithmetic operations
883
884(define_insn "adddi3"
885 [(set (match_operand:DI 0 "register_operand" "=&d,&d,&d")
886 (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
887 (match_operand:DI 2 "nonmemory_operand" "Kn7,Ks7,d")))
888 (clobber (match_scratch:SI 3 "=&d,&d,&d"))
889 (clobber (reg:CC 34))]
890 ""
891 "@
892 %0 += %2; cc = ac0; %3 = cc; %H0 += -1; %H0 = %H0 + %3;
893 %0 += %2; cc = ac0; %3 = cc; %H0 = %H0 + %3;
894 %0 = %0 + %2; cc = ac0; %3 = cc; %H0 = %H0 + %H2; %H0 = %H0 + %3;"
895 [(set_attr "type" "alu0")
896 (set_attr "length" "10,8,10")])
897
898(define_insn "subdi3"
899 [(set (match_operand:DI 0 "register_operand" "=&d")
900 (minus:DI (match_operand:DI 1 "register_operand" "0")
901 (match_operand:DI 2 "register_operand" "d")))
902 (clobber (reg:CC 34))]
903 ""
904 "%0 = %1-%2;\\n\\tcc = ac0;\\n\\t%H0 = %H1-%H2;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
905 [(set_attr "length" "10")])
906
907(define_insn "*subdi_di_zesidi"
908 [(set (match_operand:DI 0 "register_operand" "=d")
909 (minus:DI (match_operand:DI 1 "register_operand" "0")
910 (zero_extend:DI
911 (match_operand:SI 2 "register_operand" "d"))))
912 (clobber (match_scratch:SI 3 "=&d"))
913 (clobber (reg:CC 34))]
914 ""
915 "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%H0 = %H1 - %3;"
916 [(set_attr "length" "10")])
917
918(define_insn "*subdi_zesidi_di"
919 [(set (match_operand:DI 0 "register_operand" "=d")
920 (minus:DI (zero_extend:DI
921 (match_operand:SI 2 "register_operand" "d"))
922 (match_operand:DI 1 "register_operand" "0")))
923 (clobber (match_scratch:SI 3 "=&d"))
924 (clobber (reg:CC 34))]
925 ""
926 "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%3 = -%3;\\n\\t%H0 = %3 - %H1"
927 [(set_attr "length" "12")])
928
929(define_insn "*subdi_di_sesidi"
930 [(set (match_operand:DI 0 "register_operand" "=d")
931 (minus:DI (match_operand:DI 1 "register_operand" "0")
932 (sign_extend:DI
933 (match_operand:SI 2 "register_operand" "d"))))
934 (clobber (match_scratch:SI 3 "=&d"))
935 (clobber (reg:CC 34))]
936 ""
937 "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 - %3;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
938 [(set_attr "length" "14")])
939
940(define_insn "*subdi_sesidi_di"
941 [(set (match_operand:DI 0 "register_operand" "=d")
942 (minus:DI (sign_extend:DI
943 (match_operand:SI 2 "register_operand" "d"))
944 (match_operand:DI 1 "register_operand" "0")))
945 (clobber (match_scratch:SI 3 "=&d"))
946 (clobber (reg:CC 34))]
947 ""
948 "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %3 - %H1;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
949 [(set_attr "length" "14")])
950
951;; Combined shift/add instructions
952
953(define_insn ""
954 [(set (match_operand:SI 0 "register_operand" "=a,d")
955 (ashift:SI (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
956 (match_operand:SI 2 "register_operand" "a,d"))
957 (match_operand:SI 3 "pos_scale_operand" "P1P2,P1P2")))]
958 ""
959 "%0 = (%0 + %2) << %3;" /* "shadd %0,%2,%3;" */
960 [(set_attr "type" "alu0")])
961
962(define_insn ""
963 [(set (match_operand:SI 0 "register_operand" "=a")
964 (plus:SI (match_operand:SI 1 "register_operand" "a")
965 (mult:SI (match_operand:SI 2 "register_operand" "a")
966 (match_operand:SI 3 "scale_by_operand" "i"))))]
967 ""
968 "%0 = %1 + (%2 << %X3);"
969 [(set_attr "type" "alu0")])
970
971(define_insn ""
972 [(set (match_operand:SI 0 "register_operand" "=a")
973 (plus:SI (match_operand:SI 1 "register_operand" "a")
974 (ashift:SI (match_operand:SI 2 "register_operand" "a")
975 (match_operand:SI 3 "pos_scale_operand" "i"))))]
976 ""
977 "%0 = %1 + (%2 << %3);"
978 [(set_attr "type" "alu0")])
979
980(define_insn ""
981 [(set (match_operand:SI 0 "register_operand" "=a")
982 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "a")
983 (match_operand:SI 2 "scale_by_operand" "i"))
984 (match_operand:SI 3 "register_operand" "a")))]
985 ""
986 "%0 = %3 + (%1 << %X2);"
987 [(set_attr "type" "alu0")])
988
989(define_insn ""
990 [(set (match_operand:SI 0 "register_operand" "=a")
991 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "a")
992 (match_operand:SI 2 "pos_scale_operand" "i"))
993 (match_operand:SI 3 "register_operand" "a")))]
994 ""
995 "%0 = %3 + (%1 << %2);"
996 [(set_attr "type" "alu0")])
997
998(define_insn "mulhisi3"
999 [(set (match_operand:SI 0 "register_operand" "=d")
1000 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%d"))
1001 (sign_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
1002 ""
1003 "%0 = %h1 * %h2 (IS);"
1004 [(set_attr "type" "dsp32")])
1005
1006(define_insn "umulhisi3"
1007 [(set (match_operand:SI 0 "register_operand" "=d")
1008 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%d"))
1009 (zero_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
1010 ""
1011 "%0 = %h1 * %h2 (FU);"
1012 [(set_attr "type" "dsp32")])
1013
8b44057d
BS
1014(define_insn "usmulhisi3"
1015 [(set (match_operand:SI 0 "register_operand" "=W")
1016 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "W"))
1017 (sign_extend:SI (match_operand:HI 2 "register_operand" "W"))))]
1018 ""
1019 "%0 = %h2 * %h1 (IS,M);"
1020 [(set_attr "type" "dsp32")])
1021
0d4a78eb
BS
1022;; The processor also supports ireg += mreg or ireg -= mreg, but these
1023;; are unusable if we don't ensure that the corresponding lreg is zero.
1024;; The same applies to the add/subtract constant versions involving
1025;; iregs
1026
1027(define_insn "addsi3"
1028 [(set (match_operand:SI 0 "register_operand" "=ad,a,d")
1029 (plus:SI (match_operand:SI 1 "register_operand" "%0, a,d")
1030 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7, a,d")))]
1031 ""
1032 "@
1033 %0 += %2;
1034 %0 = %1 + %2;
1035 %0 = %1 + %2;"
1036 [(set_attr "type" "alu0")
1037 (set_attr "length" "2,2,2")])
1038
75d8b2d0
BS
1039(define_insn "ssaddsi3"
1040 [(set (match_operand:SI 0 "register_operand" "=d")
1041 (ss_plus:SI (match_operand:SI 1 "register_operand" "d")
1042 (match_operand:SI 2 "register_operand" "d")))]
1043 ""
1044 "%0 = %1 + %2 (S);"
1045 [(set_attr "type" "dsp32")])
1046
0d4a78eb
BS
1047(define_expand "subsi3"
1048 [(set (match_operand:SI 0 "register_operand" "")
1049 (minus:SI (match_operand:SI 1 "register_operand" "")
1050 (match_operand:SI 2 "reg_or_7bit_operand" "")))]
1051 ""
1052 "")
1053
1054(define_insn ""
1055 [(set (match_operand:SI 0 "register_operand" "=da,d,a")
1056 (minus:SI (match_operand:SI 1 "register_operand" "0,d,0")
1057 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7,d,a")))]
1058 "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -64"
1059{
1060 static const char *const strings_subsi3[] = {
1061 "%0 += -%2;",
1062 "%0 = %1 - %2;",
1063 "%0 -= %2;",
1064 };
1065
1066 if (CONSTANT_P (operands[2]) && INTVAL (operands[2]) < 0) {
1067 rtx tmp_op = operands[2];
1068 operands[2] = GEN_INT (-INTVAL (operands[2]));
1069 output_asm_insn ("%0 += %2;", operands);
1070 operands[2] = tmp_op;
1071 return "";
1072 }
1073
1074 return strings_subsi3[which_alternative];
1075}
1076 [(set_attr "type" "alu0")])
1077
75d8b2d0
BS
1078(define_insn "sssubsi3"
1079 [(set (match_operand:SI 0 "register_operand" "=d")
1080 (ss_minus:SI (match_operand:SI 1 "register_operand" "d")
1081 (match_operand:SI 2 "register_operand" "d")))]
1082 ""
1083 "%0 = %1 - %2 (S);"
1084 [(set_attr "type" "dsp32")])
1085
0d4a78eb
BS
1086;; Bit test instructions
1087
1088(define_insn "*not_bittst"
4729dc92 1089 [(set (match_operand:BI 0 "register_operand" "=C")
0d4a78eb
BS
1090 (eq:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1091 (const_int 1)
1092 (match_operand:SI 2 "immediate_operand" "Ku5"))
1093 (const_int 0)))]
1094 ""
1095 "cc = !BITTST (%1,%2);"
1096 [(set_attr "type" "alu0")])
1097
1098(define_insn "*bittst"
4729dc92 1099 [(set (match_operand:BI 0 "register_operand" "=C")
0d4a78eb
BS
1100 (ne:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1101 (const_int 1)
1102 (match_operand:SI 2 "immediate_operand" "Ku5"))
1103 (const_int 0)))]
1104 ""
1105 "cc = BITTST (%1,%2);"
1106 [(set_attr "type" "alu0")])
1107
1108(define_insn_and_split "*bit_extract"
1109 [(set (match_operand:SI 0 "register_operand" "=d")
1110 (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1111 (const_int 1)
1112 (match_operand:SI 2 "immediate_operand" "Ku5")))
1113 (clobber (reg:BI REG_CC))]
1114 ""
1115 "#"
1116 ""
1117 [(set (reg:BI REG_CC)
1118 (ne:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1119 (const_int 0)))
1120 (set (match_dup 0)
1121 (ne:SI (reg:BI REG_CC) (const_int 0)))])
1122
1123(define_insn_and_split "*not_bit_extract"
1124 [(set (match_operand:SI 0 "register_operand" "=d")
1125 (zero_extract:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1126 (const_int 1)
1127 (match_operand:SI 2 "immediate_operand" "Ku5")))
1128 (clobber (reg:BI REG_CC))]
1129 ""
1130 "#"
1131 ""
1132 [(set (reg:BI REG_CC)
1133 (eq:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1134 (const_int 0)))
1135 (set (match_dup 0)
1136 (ne:SI (reg:BI REG_CC) (const_int 0)))])
1137
1138(define_insn "*andsi_insn"
1139 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
1140 (and:SI (match_operand:SI 1 "register_operand" "%0,d,d,d")
1141 (match_operand:SI 2 "rhs_andsi3_operand" "L,M1,M2,d")))]
1142 ""
1143 "@
1144 BITCLR (%0,%Y2);
1145 %0 = %T1 (Z);
1146 %0 = %h1 (Z);
1147 %0 = %1 & %2;"
1148 [(set_attr "type" "alu0")])
1149
1150(define_expand "andsi3"
1151 [(set (match_operand:SI 0 "register_operand" "")
1152 (and:SI (match_operand:SI 1 "register_operand" "")
1153 (match_operand:SI 2 "general_operand" "")))]
1154 ""
1155{
1156 if (highbits_operand (operands[2], SImode))
1157 {
1158 operands[2] = GEN_INT (exact_log2 (-INTVAL (operands[2])));
1159 emit_insn (gen_ashrsi3 (operands[0], operands[1], operands[2]));
1160 emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
1161 DONE;
1162 }
1163 if (! rhs_andsi3_operand (operands[2], SImode))
1164 operands[2] = force_reg (SImode, operands[2]);
1165})
1166
1167(define_insn "iorsi3"
1168 [(set (match_operand:SI 0 "register_operand" "=d,d")
1169 (ior:SI (match_operand:SI 1 "register_operand" "%0,d")
1170 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1171 ""
1172 "@
1173 BITSET (%0, %X2);
1174 %0 = %1 | %2;"
1175 [(set_attr "type" "alu0")])
1176
1177(define_insn "xorsi3"
1178 [(set (match_operand:SI 0 "register_operand" "=d,d")
1179 (xor:SI (match_operand:SI 1 "register_operand" "%0,d")
1180 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1181 ""
1182 "@
1183 BITTGL (%0, %X2);
1184 %0 = %1 ^ %2;"
1185 [(set_attr "type" "alu0")])
1186
1187(define_insn "smaxsi3"
1188 [(set (match_operand:SI 0 "register_operand" "=d")
1189 (smax:SI (match_operand:SI 1 "register_operand" "d")
1190 (match_operand:SI 2 "register_operand" "d")))]
1191 ""
75d8b2d0 1192 "%0 = max(%1,%2);"
0d4a78eb
BS
1193 [(set_attr "type" "dsp32")])
1194
1195(define_insn "sminsi3"
1196 [(set (match_operand:SI 0 "register_operand" "=d")
1197 (smin:SI (match_operand:SI 1 "register_operand" "d")
1198 (match_operand:SI 2 "register_operand" "d")))]
1199 ""
75d8b2d0 1200 "%0 = min(%1,%2);"
0d4a78eb
BS
1201 [(set_attr "type" "dsp32")])
1202
1203(define_insn "abssi2"
1204 [(set (match_operand:SI 0 "register_operand" "=d")
75d8b2d0 1205 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
0d4a78eb 1206 ""
75d8b2d0 1207 "%0 = abs %1;"
0d4a78eb
BS
1208 [(set_attr "type" "dsp32")])
1209
0d4a78eb
BS
1210(define_insn "negsi2"
1211 [(set (match_operand:SI 0 "register_operand" "=d")
75d8b2d0 1212 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
0d4a78eb 1213 ""
75d8b2d0 1214 "%0 = -%1;"
0d4a78eb
BS
1215 [(set_attr "type" "alu0")])
1216
75d8b2d0
BS
1217(define_insn "ssnegsi2"
1218 [(set (match_operand:SI 0 "register_operand" "=d")
1219 (ss_neg:SI (match_operand:SI 1 "register_operand" "d")))]
1220 ""
1221 "%0 = -%1 (S);"
1222 [(set_attr "type" "dsp32")])
1223
0d4a78eb
BS
1224(define_insn "one_cmplsi2"
1225 [(set (match_operand:SI 0 "register_operand" "=d")
75d8b2d0 1226 (not:SI (match_operand:SI 1 "register_operand" "d")))]
0d4a78eb 1227 ""
75d8b2d0 1228 "%0 = ~%1;"
0d4a78eb
BS
1229 [(set_attr "type" "alu0")])
1230
75d8b2d0
BS
1231(define_insn "signbitssi2"
1232 [(set (match_operand:HI 0 "register_operand" "=d")
1233 (if_then_else:HI
1234 (lt (match_operand:SI 1 "register_operand" "d") (const_int 0))
1235 (clz:HI (not:SI (match_dup 1)))
1236 (clz:HI (match_dup 1))))]
1237 ""
1238 "%h0 = signbits %1;"
1239 [(set_attr "type" "dsp32")])
1240
1241(define_insn "smaxhi3"
1242 [(set (match_operand:HI 0 "register_operand" "=d")
1243 (smax:HI (match_operand:HI 1 "register_operand" "d")
1244 (match_operand:HI 2 "register_operand" "d")))]
1245 ""
1246 "%0 = max(%1,%2) (V);"
1247 [(set_attr "type" "dsp32")])
1248
1249(define_insn "sminhi3"
1250 [(set (match_operand:HI 0 "register_operand" "=d")
1251 (smin:HI (match_operand:HI 1 "register_operand" "d")
1252 (match_operand:HI 2 "register_operand" "d")))]
1253 ""
1254 "%0 = min(%1,%2) (V);"
1255 [(set_attr "type" "dsp32")])
1256
1257(define_insn "abshi2"
1258 [(set (match_operand:HI 0 "register_operand" "=d")
1259 (abs:HI (match_operand:HI 1 "register_operand" "d")))]
1260 ""
1261 "%0 = abs %1 (V);"
1262 [(set_attr "type" "dsp32")])
1263
1264(define_insn "neghi2"
1265 [(set (match_operand:HI 0 "register_operand" "=d")
1266 (neg:HI (match_operand:HI 1 "register_operand" "d")))]
1267 ""
1268 "%0 = -%1;"
1269 [(set_attr "type" "dsp32")])
1270
1271(define_insn "ssneghi2"
1272 [(set (match_operand:HI 0 "register_operand" "=d")
1273 (ss_neg:HI (match_operand:HI 1 "register_operand" "d")))]
1274 ""
1275 "%0 = -%1 (V);"
1276 [(set_attr "type" "dsp32")])
1277
1278(define_insn "signbitshi2"
1279 [(set (match_operand:HI 0 "register_operand" "=d")
1280 (if_then_else:HI
1281 (lt (match_operand:HI 1 "register_operand" "d") (const_int 0))
1282 (clz:HI (not:HI (match_dup 1)))
1283 (clz:HI (match_dup 1))))]
1284 ""
1285 "%h0 = signbits %h1;"
1286 [(set_attr "type" "dsp32")])
1287
0d4a78eb
BS
1288(define_insn "mulsi3"
1289 [(set (match_operand:SI 0 "register_operand" "=d")
1290 (mult:SI (match_operand:SI 1 "register_operand" "%0")
1291 (match_operand:SI 2 "register_operand" "d")))]
1292 ""
75d8b2d0 1293 "%0 *= %2;"
0d4a78eb
BS
1294 [(set_attr "type" "mult")])
1295
1296(define_expand "ashlsi3"
1297 [(set (match_operand:SI 0 "register_operand" "")
1298 (ashift:SI (match_operand:SI 1 "register_operand" "")
1299 (match_operand:SI 2 "nonmemory_operand" "")))]
1300 ""
1301{
1302 if (GET_CODE (operands[2]) == CONST_INT
1303 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1304 {
1305 emit_insn (gen_movsi (operands[0], const0_rtx));
1306 DONE;
1307 }
1308})
1309
1310(define_insn_and_split "*ashlsi3_insn"
1311 [(set (match_operand:SI 0 "register_operand" "=d,a,a,a")
1312 (ashift:SI (match_operand:SI 1 "register_operand" "0,a,a,a")
1313 (match_operand:SI 2 "nonmemory_operand" "dKu5,P1,P2,?P3P4")))]
1314 ""
1315 "@
1316 %0 <<= %2;
1317 %0 = %1 + %1;
1318 %0 = %1 << %2;
1319 #"
1320 "PREG_P (operands[0]) && INTVAL (operands[2]) > 2"
1321 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
1322 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
1323 "operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
1324 [(set_attr "type" "shft")])
1325
1326(define_insn "ashrsi3"
1327 [(set (match_operand:SI 0 "register_operand" "=d")
1328 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1329 (match_operand:SI 2 "nonmemory_operand" "dKu5")))]
1330 ""
1331 "%0 >>>= %2;"
1332 [(set_attr "type" "shft")])
1333
49373252
BS
1334(define_insn "ror_one"
1335 [(set (match_operand:SI 0 "register_operand" "=d")
1336 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1337 (ashift:SI (zero_extend:SI (reg:BI REG_CC)) (const_int 31))))
1338 (set (reg:BI REG_CC)
1339 (zero_extract:BI (match_dup 1) (const_int 1) (const_int 0)))]
1340 ""
1341 "%0 = ROT %1 BY -1;"
1342 [(set_attr "type" "shft")
1343 (set_attr "length" "4")])
1344
1345(define_insn "rol_one"
1346 [(set (match_operand:SI 0 "register_operand" "+d")
1347 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1348 (zero_extend:SI (reg:BI REG_CC))))
1349 (set (reg:BI REG_CC)
1350 (zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))]
1351 ""
1352 "%0 = ROT %1 BY 1;"
1353 [(set_attr "type" "shft")
1354 (set_attr "length" "4")])
1355
1356(define_expand "lshrdi3"
1357 [(set (match_operand:DI 0 "register_operand" "")
1358 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1359 (match_operand:DI 2 "general_operand" "")))]
1360 ""
1361{
1362 rtx lo_half[2], hi_half[2];
1363
1364 if (operands[2] != const1_rtx)
1365 FAIL;
1366 if (! rtx_equal_p (operands[0], operands[1]))
1367 emit_move_insn (operands[0], operands[1]);
1368
1369 split_di (operands, 2, lo_half, hi_half);
1370
1371 emit_move_insn (bfin_cc_rtx, const0_rtx);
1372 emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1373 emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1374 DONE;
1375})
1376
1377(define_expand "ashrdi3"
1378 [(set (match_operand:DI 0 "register_operand" "")
1379 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1380 (match_operand:DI 2 "general_operand" "")))]
1381 ""
1382{
1383 rtx lo_half[2], hi_half[2];
1384
1385 if (operands[2] != const1_rtx)
1386 FAIL;
1387 if (! rtx_equal_p (operands[0], operands[1]))
1388 emit_move_insn (operands[0], operands[1]);
1389
1390 split_di (operands, 2, lo_half, hi_half);
1391
1392 emit_insn (gen_compare_lt (gen_rtx_REG (BImode, REG_CC),
1393 hi_half[1], const0_rtx));
1394 emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1395 emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1396 DONE;
1397})
1398
1399(define_expand "ashldi3"
1400 [(set (match_operand:DI 0 "register_operand" "")
1401 (ashift:DI (match_operand:DI 1 "register_operand" "")
1402 (match_operand:DI 2 "general_operand" "")))]
1403 ""
1404{
1405 rtx lo_half[2], hi_half[2];
1406
1407 if (operands[2] != const1_rtx)
1408 FAIL;
1409 if (! rtx_equal_p (operands[0], operands[1]))
1410 emit_move_insn (operands[0], operands[1]);
1411
1412 split_di (operands, 2, lo_half, hi_half);
1413
1414 emit_move_insn (bfin_cc_rtx, const0_rtx);
1415 emit_insn (gen_rol_one (lo_half[0], lo_half[0]));
1416 emit_insn (gen_rol_one (hi_half[0], hi_half[0]));
1417 DONE;
1418})
1419
0d4a78eb
BS
1420(define_insn "lshrsi3"
1421 [(set (match_operand:SI 0 "register_operand" "=d,a")
1422 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0,a")
1423 (match_operand:SI 2 "nonmemory_operand" "dKu5,P1P2")))]
1424 ""
1425 "@
1426 %0 >>= %2;
1427 %0 = %1 >> %2;"
1428 [(set_attr "type" "shft")])
1429
1430;; A pattern to reload the equivalent of
1431;; (set (Dreg) (plus (FP) (large_constant)))
1432;; or
1433;; (set (dagreg) (plus (FP) (arbitrary_constant)))
1434;; using a scratch register
1435(define_expand "reload_insi"
1436 [(parallel [(set (match_operand:SI 0 "register_operand" "=w")
1437 (match_operand:SI 1 "fp_plus_const_operand" ""))
1438 (clobber (match_operand:SI 2 "register_operand" "=&a"))])]
1439 ""
1440{
1441 rtx fp_op = XEXP (operands[1], 0);
1442 rtx const_op = XEXP (operands[1], 1);
1443 rtx primary = operands[0];
1444 rtx scratch = operands[2];
1445
1446 emit_move_insn (scratch, const_op);
1447 emit_insn (gen_addsi3 (scratch, scratch, fp_op));
1448 emit_move_insn (primary, scratch);
1449 DONE;
1450})
1451
1452;; Jump instructions
1453
1454(define_insn "jump"
1455 [(set (pc)
1456 (label_ref (match_operand 0 "" "")))]
1457 ""
1458{
1459 if (get_attr_length (insn) == 2)
1460 return "jump.s %0;";
1461 else
1462 return "jump.l %0;";
1463}
1464 [(set_attr "type" "br")])
1465
1466(define_insn "indirect_jump"
1467 [(set (pc)
1468 (match_operand:SI 0 "register_operand" "a"))]
1469 ""
1470 "jump (%0);"
1471 [(set_attr "type" "misc")])
1472
1473(define_expand "tablejump"
1474 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1475 (use (label_ref (match_operand 1 "" "")))])]
1476 ""
1477{
1478 /* In PIC mode, the table entries are stored PC relative.
1479 Convert the relative address to an absolute address. */
1480 if (flag_pic)
1481 {
1482 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1483
1484 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1485 op1, NULL_RTX, 0, OPTAB_DIRECT);
1486 }
1487})
1488
1489(define_insn "*tablejump_internal"
1490 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1491 (use (label_ref (match_operand 1 "" "")))]
1492 ""
1493 "jump (%0);"
1494 [(set_attr "type" "misc")])
1495
1496;; Call instructions..
1497
1498(define_expand "call"
6d459e2b
BS
1499 [(parallel [(call (match_operand:SI 0 "" "")
1500 (match_operand 1 "" ""))
1501 (use (match_operand 2 "" ""))])]
0d4a78eb 1502 ""
6d459e2b
BS
1503{
1504 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 0);
1505 DONE;
1506})
0d4a78eb
BS
1507
1508(define_expand "sibcall"
1509 [(parallel [(call (match_operand:SI 0 "" "")
1510 (match_operand 1 "" ""))
6d459e2b 1511 (use (match_operand 2 "" ""))
0d4a78eb
BS
1512 (return)])]
1513 ""
6d459e2b
BS
1514{
1515 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 1);
1516 DONE;
1517})
0d4a78eb
BS
1518
1519(define_expand "call_value"
6d459e2b
BS
1520 [(parallel [(set (match_operand 0 "register_operand" "")
1521 (call (match_operand:SI 1 "" "")
1522 (match_operand 2 "" "")))
1523 (use (match_operand 3 "" ""))])]
0d4a78eb 1524 ""
6d459e2b
BS
1525{
1526 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 0);
1527 DONE;
1528})
0d4a78eb
BS
1529
1530(define_expand "sibcall_value"
1531 [(parallel [(set (match_operand 0 "register_operand" "")
1532 (call (match_operand:SI 1 "" "")
1533 (match_operand 2 "" "")))
6d459e2b 1534 (use (match_operand 3 "" ""))
0d4a78eb
BS
1535 (return)])]
1536 ""
6d459e2b
BS
1537{
1538 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 1);
1539 DONE;
1540})
0d4a78eb 1541
6d459e2b
BS
1542(define_insn "*call_symbol"
1543 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1544 (match_operand 1 "general_operand" "g"))
1545 (use (match_operand 2 "" ""))]
0d4a78eb 1546 "! SIBLING_CALL_P (insn)
96c30d2a 1547 && !TARGET_ID_SHARED_LIBRARY
6d459e2b
BS
1548 && GET_CODE (operands[0]) == SYMBOL_REF
1549 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
96c30d2a 1550 "call %0;"
0d4a78eb 1551 [(set_attr "type" "call")
6d459e2b 1552 (set_attr "length" "4")])
0d4a78eb 1553
6d459e2b
BS
1554(define_insn "*sibcall_symbol"
1555 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1556 (match_operand 1 "general_operand" "g"))
1557 (use (match_operand 2 "" ""))
0d4a78eb
BS
1558 (return)]
1559 "SIBLING_CALL_P (insn)
96c30d2a 1560 && !TARGET_ID_SHARED_LIBRARY
6d459e2b
BS
1561 && GET_CODE (operands[0]) == SYMBOL_REF
1562 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
96c30d2a 1563 "jump.l %0;"
0d4a78eb 1564 [(set_attr "type" "br")
6d459e2b 1565 (set_attr "length" "4")])
0d4a78eb 1566
6d459e2b
BS
1567(define_insn "*call_value_symbol"
1568 [(set (match_operand 0 "register_operand" "=d")
1569 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1570 (match_operand 2 "general_operand" "g")))
1571 (use (match_operand 3 "" ""))]
0d4a78eb 1572 "! SIBLING_CALL_P (insn)
96c30d2a 1573 && !TARGET_ID_SHARED_LIBRARY
6d459e2b
BS
1574 && GET_CODE (operands[1]) == SYMBOL_REF
1575 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
96c30d2a 1576 "call %1;"
0d4a78eb 1577 [(set_attr "type" "call")
6d459e2b 1578 (set_attr "length" "4")])
0d4a78eb 1579
6d459e2b
BS
1580(define_insn "*sibcall_value_symbol"
1581 [(set (match_operand 0 "register_operand" "=d")
1582 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1583 (match_operand 2 "general_operand" "g")))
1584 (use (match_operand 3 "" ""))
0d4a78eb
BS
1585 (return)]
1586 "SIBLING_CALL_P (insn)
96c30d2a 1587 && !TARGET_ID_SHARED_LIBRARY
6d459e2b
BS
1588 && GET_CODE (operands[1]) == SYMBOL_REF
1589 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
96c30d2a 1590 "jump.l %1;"
6d459e2b
BS
1591 [(set_attr "type" "br")
1592 (set_attr "length" "4")])
1593
1594(define_insn "*call_insn"
1595 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a"))
1596 (match_operand 1 "general_operand" "g"))
1597 (use (match_operand 2 "" ""))]
1598 "! SIBLING_CALL_P (insn)"
1599 "call (%0);"
1600 [(set_attr "type" "call")
1601 (set_attr "length" "2")])
1602
1603(define_insn "*sibcall_insn"
1604 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "z"))
1605 (match_operand 1 "general_operand" "g"))
1606 (use (match_operand 2 "" ""))
1607 (return)]
1608 "SIBLING_CALL_P (insn)"
1609 "jump (%0);"
1610 [(set_attr "type" "br")
1611 (set_attr "length" "2")])
1612
1613(define_insn "*call_value_insn"
1614 [(set (match_operand 0 "register_operand" "=d")
1615 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a"))
1616 (match_operand 2 "general_operand" "g")))
1617 (use (match_operand 3 "" ""))]
1618 "! SIBLING_CALL_P (insn)"
1619 "call (%1);"
1620 [(set_attr "type" "call")
1621 (set_attr "length" "2")])
1622
1623(define_insn "*sibcall_value_insn"
1624 [(set (match_operand 0 "register_operand" "=d")
1625 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "z"))
1626 (match_operand 2 "general_operand" "g")))
1627 (use (match_operand 3 "" ""))
1628 (return)]
1629 "SIBLING_CALL_P (insn)"
1630 "jump (%1);"
0d4a78eb 1631 [(set_attr "type" "br")
6d459e2b 1632 (set_attr "length" "2")])
0d4a78eb
BS
1633
1634;; Block move patterns
1635
1636;; We cheat. This copies one more word than operand 2 indicates.
1637
1638(define_insn "rep_movsi"
1639 [(set (match_operand:SI 0 "register_operand" "=&a")
1640 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1641 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1642 (const_int 2)))
1643 (const_int 4)))
1644 (set (match_operand:SI 1 "register_operand" "=&b")
1645 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1646 (ashift:SI (match_dup 2) (const_int 2)))
1647 (const_int 4)))
1648 (set (mem:BLK (match_dup 3))
1649 (mem:BLK (match_dup 4)))
1650 (use (match_dup 2))
1651 (clobber (match_scratch:HI 5 "=&d"))]
1652 ""
51a641fd 1653 "%5 = [%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || [%3++] = %5 || %5 = [%4++]; [%3++] = %5;"
0d4a78eb
BS
1654 [(set_attr "type" "misc")
1655 (set_attr "length" "16")])
1656
1657(define_insn "rep_movhi"
1658 [(set (match_operand:SI 0 "register_operand" "=&a")
1659 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1660 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1661 (const_int 1)))
1662 (const_int 2)))
1663 (set (match_operand:SI 1 "register_operand" "=&b")
1664 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1665 (ashift:SI (match_dup 2) (const_int 1)))
1666 (const_int 2)))
1667 (set (mem:BLK (match_dup 3))
1668 (mem:BLK (match_dup 4)))
1669 (use (match_dup 2))
1670 (clobber (match_scratch:HI 5 "=&d"))]
1671 ""
51a641fd 1672 "%h5 = W[%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || W [%3++] = %5 || %h5 = W [%4++]; W [%3++] = %5;"
0d4a78eb
BS
1673 [(set_attr "type" "misc")
1674 (set_attr "length" "16")])
1675
144f8315 1676(define_expand "movmemsi"
0d4a78eb
BS
1677 [(match_operand:BLK 0 "general_operand" "")
1678 (match_operand:BLK 1 "general_operand" "")
1679 (match_operand:SI 2 "const_int_operand" "")
1680 (match_operand:SI 3 "const_int_operand" "")]
1681 ""
1682{
144f8315 1683 if (bfin_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
0d4a78eb
BS
1684 DONE;
1685 FAIL;
1686})
1687
1688;; Conditional branch patterns
1689;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
1690
1691;; The only outcome of this pattern is that global variables
1692;; bfin_compare_op[01] are set for use in bcond patterns.
1693
1694(define_expand "cmpbi"
1695 [(set (cc0) (compare (match_operand:BI 0 "register_operand" "")
1696 (match_operand:BI 1 "immediate_operand" "")))]
1697 ""
1698{
1699 bfin_compare_op0 = operands[0];
1700 bfin_compare_op1 = operands[1];
1701 DONE;
1702})
1703
1704(define_expand "cmpsi"
1705 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
7ddcf3d2 1706 (match_operand:SI 1 "reg_or_const_int_operand" "")))]
0d4a78eb
BS
1707 ""
1708{
1709 bfin_compare_op0 = operands[0];
1710 bfin_compare_op1 = operands[1];
1711 DONE;
1712})
1713
49373252 1714(define_insn "compare_eq"
4729dc92 1715 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 1716 (eq:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 1717 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
0d4a78eb
BS
1718 ""
1719 "cc =%1==%2;"
1720 [(set_attr "type" "compare")])
1721
49373252 1722(define_insn "compare_ne"
4729dc92 1723 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 1724 (ne:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 1725 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
0d4a78eb
BS
1726 "0"
1727 "cc =%1!=%2;"
1728 [(set_attr "type" "compare")])
1729
49373252 1730(define_insn "compare_lt"
4729dc92 1731 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 1732 (lt:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 1733 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
0d4a78eb
BS
1734 ""
1735 "cc =%1<%2;"
1736 [(set_attr "type" "compare")])
1737
49373252 1738(define_insn "compare_le"
4729dc92 1739 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 1740 (le:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 1741 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
0d4a78eb
BS
1742 ""
1743 "cc =%1<=%2;"
1744 [(set_attr "type" "compare")])
1745
49373252 1746(define_insn "compare_leu"
4729dc92 1747 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 1748 (leu:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 1749 (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
0d4a78eb
BS
1750 ""
1751 "cc =%1<=%2 (iu);"
1752 [(set_attr "type" "compare")])
1753
49373252 1754(define_insn "compare_ltu"
4729dc92 1755 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 1756 (ltu:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 1757 (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
0d4a78eb
BS
1758 ""
1759 "cc =%1<%2 (iu);"
1760 [(set_attr "type" "compare")])
1761
1762(define_expand "beq"
1763 [(set (match_dup 1) (match_dup 2))
1764 (set (pc)
1765 (if_then_else (match_dup 3)
1766 (label_ref (match_operand 0 "" ""))
1767 (pc)))]
1768 ""
1769{
1770 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1771 operands[1] = bfin_cc_rtx; /* hard register: CC */
1772 operands[2] = gen_rtx_EQ (BImode, op0, op1);
1773 /* If we have a BImode input, then we already have a compare result, and
1774 do not need to emit another comparison. */
1775 if (GET_MODE (bfin_compare_op0) == BImode)
1776 {
3b9dd769
NS
1777 gcc_assert (bfin_compare_op1 == const0_rtx);
1778 emit_insn (gen_cbranchbi4 (operands[2], op0, op1, operands[0]));
1779 DONE;
0d4a78eb
BS
1780 }
1781
1782 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1783})
1784
1785(define_expand "bne"
1786 [(set (match_dup 1) (match_dup 2))
1787 (set (pc)
1788 (if_then_else (match_dup 3)
1789 (label_ref (match_operand 0 "" ""))
1790 (pc)))]
1791 ""
1792{
1793 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1794 /* If we have a BImode input, then we already have a compare result, and
1795 do not need to emit another comparison. */
1796 if (GET_MODE (bfin_compare_op0) == BImode)
1797 {
3b9dd769
NS
1798 rtx cmp = gen_rtx_NE (BImode, op0, op1);
1799
1800 gcc_assert (bfin_compare_op1 == const0_rtx);
1801 emit_insn (gen_cbranchbi4 (cmp, op0, op1, operands[0]));
1802 DONE;
0d4a78eb
BS
1803 }
1804
1805 operands[1] = bfin_cc_rtx; /* hard register: CC */
1806 operands[2] = gen_rtx_EQ (BImode, op0, op1);
1807 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1808})
1809
1810(define_expand "bgt"
1811 [(set (match_dup 1) (match_dup 2))
1812 (set (pc)
1813 (if_then_else (match_dup 3)
1814 (label_ref (match_operand 0 "" ""))
1815 (pc)))]
1816 ""
1817{
1818 operands[1] = bfin_cc_rtx;
1819 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1820 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1821})
1822
1823(define_expand "bgtu"
1824 [(set (match_dup 1) (match_dup 2))
1825 (set (pc)
1826 (if_then_else (match_dup 3)
1827 (label_ref (match_operand 0 "" ""))
1828 (pc)))]
1829 ""
1830{
1831 operands[1] = bfin_cc_rtx;
1832 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1833 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1834})
1835
1836(define_expand "blt"
1837 [(set (match_dup 1) (match_dup 2))
1838 (set (pc)
1839 (if_then_else (match_dup 3)
1840 (label_ref (match_operand 0 "" ""))
1841 (pc)))]
1842 ""
1843{
1844 operands[1] = bfin_cc_rtx;
1845 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1846 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1847})
1848
1849(define_expand "bltu"
1850 [(set (match_dup 1) (match_dup 2))
1851 (set (pc)
1852 (if_then_else (match_dup 3)
1853 (label_ref (match_operand 0 "" ""))
1854 (pc)))]
1855 ""
1856{
1857 operands[1] = bfin_cc_rtx;
1858 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1859 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1860})
1861
1862
1863(define_expand "bge"
1864 [(set (match_dup 1) (match_dup 2))
1865 (set (pc)
1866 (if_then_else (match_dup 3)
1867 (label_ref (match_operand 0 "" ""))
1868 (pc)))]
1869 ""
1870{
1871 operands[1] = bfin_cc_rtx;
1872 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1873 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1874})
1875
1876(define_expand "bgeu"
1877 [(set (match_dup 1) (match_dup 2))
1878 (set (pc)
1879 (if_then_else (match_dup 3)
1880 (label_ref (match_operand 0 "" ""))
1881 (pc)))]
1882 ""
1883{
1884 operands[1] = bfin_cc_rtx;
1885 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1886 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1887})
1888
1889(define_expand "ble"
1890 [(set (match_dup 1) (match_dup 2))
1891 (set (pc)
1892 (if_then_else (match_dup 3)
1893 (label_ref (match_operand 0 "" ""))
1894 (pc)))]
1895 ""
1896{
1897 operands[1] = bfin_cc_rtx;
1898 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1899 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1900})
1901
1902(define_expand "bleu"
1903 [(set (match_dup 1) (match_dup 2))
1904 (set (pc)
1905 (if_then_else (match_dup 3)
1906 (label_ref (match_operand 0 "" ""))
1907 (pc)))
1908 ]
1909 ""
1910{
1911 operands[1] = bfin_cc_rtx;
1912 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1913 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1914})
1915
1916(define_insn "cbranchbi4"
1917 [(set (pc)
1918 (if_then_else
1919 (match_operator 0 "bfin_cbranch_operator"
4729dc92 1920 [(match_operand:BI 1 "register_operand" "C")
0d4a78eb
BS
1921 (match_operand:BI 2 "immediate_operand" "P0")])
1922 (label_ref (match_operand 3 "" ""))
1923 (pc)))]
1924 ""
1925{
1926 asm_conditional_branch (insn, operands, 0, 0);
1927 return "";
1928}
1929 [(set_attr "type" "brcc")])
1930
1931;; Special cbranch patterns to deal with the speculative load problem - see
1932;; bfin_reorg for details.
1933
1934(define_insn "cbranch_predicted_taken"
1935 [(set (pc)
1936 (if_then_else
1937 (match_operator 0 "bfin_cbranch_operator"
4729dc92 1938 [(match_operand:BI 1 "register_operand" "C")
0d4a78eb
BS
1939 (match_operand:BI 2 "immediate_operand" "P0")])
1940 (label_ref (match_operand 3 "" ""))
1941 (pc)))
1942 (unspec [(const_int 0)] UNSPEC_CBRANCH_TAKEN)]
1943 ""
1944{
1945 asm_conditional_branch (insn, operands, 0, 1);
1946 return "";
1947}
1948 [(set_attr "type" "brcc")])
1949
1950(define_insn "cbranch_with_nops"
1951 [(set (pc)
1952 (if_then_else
1953 (match_operator 0 "bfin_cbranch_operator"
4729dc92 1954 [(match_operand:BI 1 "register_operand" "C")
0d4a78eb
BS
1955 (match_operand:BI 2 "immediate_operand" "P0")])
1956 (label_ref (match_operand 3 "" ""))
1957 (pc)))
1958 (unspec [(match_operand 4 "immediate_operand" "")] UNSPEC_CBRANCH_NOPS)]
1959 "reload_completed"
1960{
1961 asm_conditional_branch (insn, operands, INTVAL (operands[4]), 0);
1962 return "";
1963}
1964 [(set_attr "type" "brcc")
1965 (set_attr "length" "6")])
1966
1967;; setcc insns. */
1968(define_expand "seq"
1969 [(set (match_dup 1) (eq:BI (match_dup 2) (match_dup 3)))
1970 (set (match_operand:SI 0 "register_operand" "")
1971 (ne:SI (match_dup 1) (const_int 0)))]
1972 ""
1973{
1974 operands[2] = bfin_compare_op0;
1975 operands[3] = bfin_compare_op1;
1976 operands[1] = bfin_cc_rtx;
1977})
1978
1979(define_expand "slt"
1980 [(set (match_dup 1) (lt:BI (match_dup 2) (match_dup 3)))
1981 (set (match_operand:SI 0 "register_operand" "")
1982 (ne:SI (match_dup 1) (const_int 0)))]
1983 ""
1984{
1985 operands[2] = bfin_compare_op0;
1986 operands[3] = bfin_compare_op1;
1987 operands[1] = bfin_cc_rtx;
1988})
1989
1990(define_expand "sle"
1991 [(set (match_dup 1) (le:BI (match_dup 2) (match_dup 3)))
1992 (set (match_operand:SI 0 "register_operand" "")
1993 (ne:SI (match_dup 1) (const_int 0)))]
1994 ""
1995{
1996 operands[2] = bfin_compare_op0;
1997 operands[3] = bfin_compare_op1;
1998 operands[1] = bfin_cc_rtx;
1999})
2000
2001(define_expand "sltu"
2002 [(set (match_dup 1) (ltu:BI (match_dup 2) (match_dup 3)))
2003 (set (match_operand:SI 0 "register_operand" "")
2004 (ne:SI (match_dup 1) (const_int 0)))]
2005 ""
2006{
2007 operands[2] = bfin_compare_op0;
2008 operands[3] = bfin_compare_op1;
2009 operands[1] = bfin_cc_rtx;
2010})
2011
2012(define_expand "sleu"
2013 [(set (match_dup 1) (leu:BI (match_dup 2) (match_dup 3)))
2014 (set (match_operand:SI 0 "register_operand" "")
2015 (ne:SI (match_dup 1) (const_int 0)))]
2016 ""
2017{
2018 operands[2] = bfin_compare_op0;
2019 operands[3] = bfin_compare_op1;
2020 operands[1] = bfin_cc_rtx;
2021})
2022
2023(define_insn "nop"
2024 [(const_int 0)]
2025 ""
2026 "nop;")
2027
2028;;;;;;;;;;;;;;;;;;;; CC2dreg ;;;;;;;;;;;;;;;;;;;;;;;;;
2029(define_insn "movsibi"
4729dc92 2030 [(set (match_operand:BI 0 "register_operand" "=C")
0d4a78eb
BS
2031 (ne:BI (match_operand:SI 1 "register_operand" "d")
2032 (const_int 0)))]
2033 ""
2034 "CC = %1;"
2035 [(set_attr "length" "2")])
2036
2037(define_insn "movbisi"
2038 [(set (match_operand:SI 0 "register_operand" "=d")
4729dc92 2039 (ne:SI (match_operand:BI 1 "register_operand" "C")
0d4a78eb
BS
2040 (const_int 0)))]
2041 ""
2042 "%0 = CC;"
2043 [(set_attr "length" "2")])
2044
2045(define_insn ""
4729dc92
BS
2046 [(set (match_operand:BI 0 "register_operand" "=C")
2047 (eq:BI (match_operand:BI 1 "register_operand" " 0")
0d4a78eb
BS
2048 (const_int 0)))]
2049 ""
2050 "%0 = ! %0;" /* NOT CC;" */
2051 [(set_attr "type" "compare")])
2052
2053;; Vector and DSP insns
2054
2055(define_insn ""
2056 [(set (match_operand:SI 0 "register_operand" "=d")
2057 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2058 (const_int 24))
2059 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2060 (const_int 8))))]
2061 ""
2062 "%0 = ALIGN8(%1, %2);"
2063 [(set_attr "type" "dsp32")])
2064
2065(define_insn ""
2066 [(set (match_operand:SI 0 "register_operand" "=d")
2067 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2068 (const_int 16))
2069 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2070 (const_int 16))))]
2071 ""
2072 "%0 = ALIGN16(%1, %2);"
2073 [(set_attr "type" "dsp32")])
2074
2075(define_insn ""
2076 [(set (match_operand:SI 0 "register_operand" "=d")
2077 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2078 (const_int 8))
2079 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2080 (const_int 24))))]
2081 ""
2082 "%0 = ALIGN24(%1, %2);"
2083 [(set_attr "type" "dsp32")])
2084
2085;; Prologue and epilogue.
2086
2087(define_expand "prologue"
2088 [(const_int 1)]
2089 ""
2090 "bfin_expand_prologue (); DONE;")
2091
2092(define_expand "epilogue"
2093 [(const_int 1)]
2094 ""
2095 "bfin_expand_epilogue (1, 0); DONE;")
2096
2097(define_expand "sibcall_epilogue"
2098 [(const_int 1)]
2099 ""
2100 "bfin_expand_epilogue (0, 0); DONE;")
2101
2102(define_expand "eh_return"
2103 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")]
2104 UNSPEC_VOLATILE_EH_RETURN)]
2105 ""
2106{
2107 emit_move_insn (EH_RETURN_HANDLER_RTX, operands[0]);
2108 emit_insn (gen_eh_return_internal ());
2109 emit_barrier ();
4193ce73 2110 DONE;
0d4a78eb
BS
2111})
2112
2113(define_insn_and_split "eh_return_internal"
2114 [(unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN)]
2115 ""
2116 "#"
2117 "reload_completed"
2118 [(const_int 1)]
2119 "bfin_expand_epilogue (1, 1); DONE;")
2120
2121(define_insn "link"
2122 [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS))
2123 (set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:SI REG_FP))
2124 (set (reg:SI REG_FP)
2125 (plus:SI (reg:SI REG_SP) (const_int -8)))
2126 (set (reg:SI REG_SP)
2127 (plus:SI (reg:SI REG_SP) (match_operand:SI 0 "immediate_operand" "i")))]
2128 ""
2129 "LINK %Z0;"
2130 [(set_attr "length" "4")])
2131
2132(define_insn "unlink"
2133 [(set (reg:SI REG_FP) (mem:SI (reg:SI REG_FP)))
2134 (set (reg:SI REG_RETS) (mem:SI (plus:SI (reg:SI REG_FP) (const_int 4))))
2135 (set (reg:SI REG_SP) (plus:SI (reg:SI REG_FP) (const_int 8)))]
2136 ""
2137 "UNLINK;"
2138 [(set_attr "length" "4")])
2139
2140;; This pattern is slightly clumsy. The stack adjust must be the final SET in
2141;; the pattern, otherwise dwarf2out becomes very confused about which reg goes
2142;; where on the stack, since it goes through all elements of the parallel in
2143;; sequence.
2144(define_insn "push_multiple"
2145 [(match_parallel 0 "push_multiple_operation"
2146 [(unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_PUSH_MULTIPLE)])]
2147 ""
2148{
2149 output_push_multiple (insn, operands);
2150 return "";
2151})
2152
2153(define_insn "pop_multiple"
2154 [(match_parallel 0 "pop_multiple_operation"
2155 [(set (reg:SI REG_SP)
2156 (plus:SI (reg:SI REG_SP) (match_operand:SI 1 "immediate_operand" "i")))])]
2157 ""
2158{
2159 output_pop_multiple (insn, operands);
2160 return "";
2161})
2162
2163(define_insn "return_internal"
2164 [(return)
2165 (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)]
2166 "reload_completed"
2167{
2168 switch (INTVAL (operands[0]))
2169 {
2170 case EXCPT_HANDLER:
2171 return "rtx;";
2172 case NMI_HANDLER:
2173 return "rtn;";
2174 case INTERRUPT_HANDLER:
2175 return "rti;";
2176 case SUBROUTINE:
2177 return "rts;";
2178 }
2179 gcc_unreachable ();
2180})
2181
5fcead21
BS
2182(define_insn "csync"
2183 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
2184 ""
2185 "csync;"
3fb192d2 2186 [(set_attr "type" "sync")])
5fcead21
BS
2187
2188(define_insn "ssync"
2189 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_SSYNC)]
2190 ""
2191 "ssync;"
3fb192d2 2192 [(set_attr "type" "sync")])
5fcead21 2193
3d33a056
JZ
2194(define_insn "trap"
2195 [(trap_if (const_int 1) (const_int 3))]
2196 ""
2197 "excpt 3;"
2198 [(set_attr "type" "misc")
2199 (set_attr "length" "2")])
2200
09350e36
BS
2201(define_insn "trapifcc"
2202 [(trap_if (reg:BI REG_CC) (const_int 3))]
2203 ""
2204 "if !cc jump 4 (bp); excpt 3;"
2205 [(set_attr "type" "misc")
2206 (set_attr "length" "4")])
2207
0d4a78eb
BS
2208;;; Vector instructions
2209
75d8b2d0
BS
2210;; First, all sorts of move variants
2211
2212(define_insn "movhi_low2high"
2213 [(set (match_operand:V2HI 0 "register_operand" "=d")
2214 (vec_concat:V2HI
2215 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2216 (parallel [(const_int 0)]))
2217 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2218 (parallel [(const_int 0)]))))]
2219 ""
2220 "%d0 = %h2 << 0;"
2221 [(set_attr "type" "dsp32")])
2222
2223(define_insn "movhi_high2high"
2224 [(set (match_operand:V2HI 0 "register_operand" "=d")
2225 (vec_concat:V2HI
2226 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2227 (parallel [(const_int 0)]))
2228 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2229 (parallel [(const_int 1)]))))]
2230 ""
2231 "%d0 = %d2 << 0;"
2232 [(set_attr "type" "dsp32")])
2233
2234(define_insn "movhi_low2low"
2235 [(set (match_operand:V2HI 0 "register_operand" "=d")
2236 (vec_concat:V2HI
2237 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2238 (parallel [(const_int 0)]))
2239 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2240 (parallel [(const_int 1)]))))]
2241 ""
2242 "%h0 = %h2 << 0;"
2243 [(set_attr "type" "dsp32")])
2244
2245(define_insn "movhi_high2low"
2246 [(set (match_operand:V2HI 0 "register_operand" "=d")
2247 (vec_concat:V2HI
2248 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2249 (parallel [(const_int 1)]))
2250 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2251 (parallel [(const_int 1)]))))]
2252 ""
2253 "%h0 = %d2 << 0;"
2254 [(set_attr "type" "dsp32")])
2255
2256(define_insn "movhiv2hi_low"
2257 [(set (match_operand:V2HI 0 "register_operand" "=d")
2258 (vec_concat:V2HI
2259 (match_operand:HI 2 "register_operand" "d")
2260 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2261 (parallel [(const_int 1)]))))]
2262 ""
2263 "%h0 = %h2 << 0;"
2264 [(set_attr "type" "dsp32")])
2265
2266(define_insn "movhiv2hi_high"
2267 [(set (match_operand:V2HI 0 "register_operand" "=d")
2268 (vec_concat:V2HI
2269 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2270 (parallel [(const_int 0)]))
2271 (match_operand:HI 2 "register_operand" "d")))]
2272 ""
2273 "%d0 = %h2 << 0;"
2274 [(set_attr "type" "dsp32")])
2275
2276;; No earlyclobber on alternative two since our sequence ought to be safe.
2277;; The order of operands is intentional to match the VDSP builtin (high word
2278;; is passed first).
2279(define_insn_and_split "composev2hi"
2280 [(set (match_operand:V2HI 0 "register_operand" "=d,d")
2281 (vec_concat:V2HI (match_operand:HI 2 "register_operand" "0,d")
2282 (match_operand:HI 1 "register_operand" "d,d")))]
2283 ""
2284 "@
2285 %d0 = %h2 << 0;
2286 #"
2287 "reload_completed"
2288 [(set (match_dup 0)
2289 (vec_concat:V2HI
2290 (vec_select:HI (match_dup 0) (parallel [(const_int 0)]))
2291 (match_dup 2)))
2292 (set (match_dup 0)
2293 (vec_concat:V2HI
2294 (match_dup 1)
2295 (vec_select:HI (match_dup 0) (parallel [(const_int 1)]))))]
2296 ""
2297 [(set_attr "type" "dsp32")])
2298
2299; Like composev2hi, but operating on elements of V2HI vectors.
2300; Useful on its own, and as a combiner bridge for the multiply and
2301; mac patterns.
2302(define_insn "packv2hi"
2303 [(set (match_operand:V2HI 0 "register_operand" "=d,d,d,d")
2304 (vec_concat:V2HI (vec_select:HI
2305 (match_operand:V2HI 1 "register_operand" "d,d,d,d")
2306 (parallel [(match_operand 3 "const01_operand" "P0,P1,P0,P1")]))
2307 (vec_select:HI
2308 (match_operand:V2HI 2 "register_operand" "d,d,d,d")
2309 (parallel [(match_operand 4 "const01_operand" "P0,P0,P1,P1")]))))]
2310 ""
2311 "@
2312 %0 = PACK (%h2,%h1);
2313 %0 = PACK (%h2,%d1);
2314 %0 = PACK (%d2,%h1);
2315 %0 = PACK (%d2,%d1);"
2316 [(set_attr "type" "dsp32")])
2317
2318(define_insn "movv2hi_hi"
2319 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
2320 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0,d,d")
2321 (parallel [(match_operand:SI 2 "const01_operand" "P0,P0,P1")])))]
2322 ""
2323 "@
2324 /* optimized out */
2325 %h0 = %h1 << 0;
2326 %h0 = %d1 << 0;"
2327 [(set_attr "type" "dsp32")])
2328
2329(define_expand "movv2hi_hi_low"
2330 [(set (match_operand:HI 0 "register_operand" "")
2331 (vec_select:HI (match_operand:V2HI 1 "register_operand" "")
2332 (parallel [(const_int 0)])))]
2333 ""
2334 "")
2335
2336(define_expand "movv2hi_hi_high"
2337 [(set (match_operand:HI 0 "register_operand" "")
2338 (vec_select:HI (match_operand:V2HI 1 "register_operand" "")
2339 (parallel [(const_int 1)])))]
2340 ""
2341 "")
2342
2343;; Unusual arithmetic operations on 16 bit registers.
2344
2345(define_insn "ssaddhi3"
2346 [(set (match_operand:HI 0 "register_operand" "=d")
2347 (ss_plus:HI (match_operand:HI 1 "register_operand" "d")
2348 (match_operand:HI 2 "register_operand" "d")))]
2349 ""
2350 "%h0 = %h1 + %h2 (S);"
2351 [(set_attr "type" "dsp32")])
2352
2353(define_insn "sssubhi3"
2354 [(set (match_operand:HI 0 "register_operand" "=d")
2355 (ss_minus:HI (match_operand:HI 1 "register_operand" "d")
2356 (match_operand:HI 2 "register_operand" "d")))]
2357 ""
2358 "%h0 = %h1 - %h2 (S);"
2359 [(set_attr "type" "dsp32")])
2360
2361;; V2HI vector insns
2362
c9b3f817 2363(define_insn "addv2hi3"
0d4a78eb
BS
2364 [(set (match_operand:V2HI 0 "register_operand" "=d")
2365 (plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2366 (match_operand:V2HI 2 "register_operand" "d")))]
2367 ""
2368 "%0 = %1 +|+ %2;"
2369 [(set_attr "type" "dsp32")])
2370
75d8b2d0
BS
2371(define_insn "ssaddv2hi3"
2372 [(set (match_operand:V2HI 0 "register_operand" "=d")
2373 (ss_plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2374 (match_operand:V2HI 2 "register_operand" "d")))]
2375 ""
2376 "%0 = %1 +|+ %2 (S);"
2377 [(set_attr "type" "dsp32")])
2378
c9b3f817 2379(define_insn "subv2hi3"
0d4a78eb
BS
2380 [(set (match_operand:V2HI 0 "register_operand" "=d")
2381 (minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2382 (match_operand:V2HI 2 "register_operand" "d")))]
2383 ""
2384 "%0 = %1 -|- %2;"
2385 [(set_attr "type" "dsp32")])
2386
75d8b2d0
BS
2387(define_insn "sssubv2hi3"
2388 [(set (match_operand:V2HI 0 "register_operand" "=d")
2389 (ss_minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2390 (match_operand:V2HI 2 "register_operand" "d")))]
2391 ""
2392 "%0 = %1 -|- %2 (S);"
2393 [(set_attr "type" "dsp32")])
2394
2395(define_insn "addsubv2hi3"
2396 [(set (match_operand:V2HI 0 "register_operand" "=d")
2397 (vec_concat:V2HI
2398 (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2399 (parallel [(const_int 0)]))
2400 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2401 (parallel [(const_int 0)])))
2402 (minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2403 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2404 ""
2405 "%0 = %1 +|- %2;"
2406 [(set_attr "type" "dsp32")])
2407
2408(define_insn "subaddv2hi3"
2409 [(set (match_operand:V2HI 0 "register_operand" "=d")
2410 (vec_concat:V2HI
2411 (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2412 (parallel [(const_int 0)]))
2413 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2414 (parallel [(const_int 0)])))
2415 (plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2416 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2417 ""
2418 "%0 = %1 -|+ %2;"
2419 [(set_attr "type" "dsp32")])
2420
2421(define_insn "ssaddsubv2hi3"
2422 [(set (match_operand:V2HI 0 "register_operand" "=d")
2423 (vec_concat:V2HI
2424 (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2425 (parallel [(const_int 0)]))
2426 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2427 (parallel [(const_int 0)])))
2428 (ss_minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2429 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2430 ""
2431 "%0 = %1 +|- %2 (S);"
2432 [(set_attr "type" "dsp32")])
2433
2434(define_insn "sssubaddv2hi3"
2435 [(set (match_operand:V2HI 0 "register_operand" "=d")
2436 (vec_concat:V2HI
2437 (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2438 (parallel [(const_int 0)]))
2439 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2440 (parallel [(const_int 0)])))
2441 (ss_plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2442 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2443 ""
2444 "%0 = %1 -|+ %2 (S);"
2445 [(set_attr "type" "dsp32")])
2446
2447(define_insn "sublohiv2hi3"
2448 [(set (match_operand:HI 0 "register_operand" "=d")
2449 (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2450 (parallel [(const_int 1)]))
2451 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2452 (parallel [(const_int 0)]))))]
2453 ""
2454 "%h0 = %d1 - %h2;"
2455 [(set_attr "type" "dsp32")])
2456
2457(define_insn "subhilov2hi3"
2458 [(set (match_operand:HI 0 "register_operand" "=d")
2459 (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2460 (parallel [(const_int 0)]))
2461 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2462 (parallel [(const_int 1)]))))]
2463 ""
2464 "%h0 = %h1 - %d2;"
2465 [(set_attr "type" "dsp32")])
2466
2467(define_insn "sssublohiv2hi3"
2468 [(set (match_operand:HI 0 "register_operand" "=d")
2469 (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2470 (parallel [(const_int 1)]))
2471 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2472 (parallel [(const_int 0)]))))]
2473 ""
2474 "%h0 = %d1 - %h2 (S);"
2475 [(set_attr "type" "dsp32")])
2476
2477(define_insn "sssubhilov2hi3"
2478 [(set (match_operand:HI 0 "register_operand" "=d")
2479 (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2480 (parallel [(const_int 0)]))
2481 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2482 (parallel [(const_int 1)]))))]
2483 ""
2484 "%h0 = %h1 - %d2 (S);"
2485 [(set_attr "type" "dsp32")])
2486
2487(define_insn "addlohiv2hi3"
2488 [(set (match_operand:HI 0 "register_operand" "=d")
2489 (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2490 (parallel [(const_int 1)]))
2491 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2492 (parallel [(const_int 0)]))))]
2493 ""
2494 "%h0 = %d1 + %h2;"
2495 [(set_attr "type" "dsp32")])
2496
2497(define_insn "addhilov2hi3"
2498 [(set (match_operand:HI 0 "register_operand" "=d")
2499 (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2500 (parallel [(const_int 0)]))
2501 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2502 (parallel [(const_int 1)]))))]
2503 ""
2504 "%h0 = %h1 + %d2;"
2505 [(set_attr "type" "dsp32")])
2506
2507(define_insn "ssaddlohiv2hi3"
2508 [(set (match_operand:HI 0 "register_operand" "=d")
2509 (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2510 (parallel [(const_int 1)]))
2511 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2512 (parallel [(const_int 0)]))))]
2513 ""
2514 "%h0 = %d1 + %h2 (S);"
2515 [(set_attr "type" "dsp32")])
2516
2517(define_insn "ssaddhilov2hi3"
2518 [(set (match_operand:HI 0 "register_operand" "=d")
2519 (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2520 (parallel [(const_int 0)]))
2521 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2522 (parallel [(const_int 1)]))))]
2523 ""
2524 "%h0 = %h1 + %d2 (S);"
2525 [(set_attr "type" "dsp32")])
2526
c9b3f817 2527(define_insn "sminv2hi3"
0d4a78eb
BS
2528 [(set (match_operand:V2HI 0 "register_operand" "=d")
2529 (smin:V2HI (match_operand:V2HI 1 "register_operand" "d")
2530 (match_operand:V2HI 2 "register_operand" "d")))]
2531 ""
2532 "%0 = MIN (%1, %2) (V);"
2533 [(set_attr "type" "dsp32")])
2534
c9b3f817 2535(define_insn "smaxv2hi3"
0d4a78eb
BS
2536 [(set (match_operand:V2HI 0 "register_operand" "=d")
2537 (smax:V2HI (match_operand:V2HI 1 "register_operand" "d")
2538 (match_operand:V2HI 2 "register_operand" "d")))]
2539 ""
2540 "%0 = MAX (%1, %2) (V);"
2541 [(set_attr "type" "dsp32")])
2542
75d8b2d0
BS
2543;; Multiplications.
2544
2545;; The Blackfin allows a lot of different options, and we need many patterns to
2546;; cover most of the hardware's abilities.
2547;; There are a few simple patterns using MULT rtx codes, but most of them use
2548;; an unspec with a const_int operand that determines which flag to use in the
2549;; instruction.
2550;; There are variants for single and parallel multiplications.
2551;; There are variants which just use 16 bit lowparts as inputs, and variants
2552;; which allow the user to choose just which halves to use as input values.
2553;; There are variants which set D registers, variants which set accumulators,
2554;; variants which set both, some of them optionally using the accumulators as
2555;; inputs for multiply-accumulate operations.
2556
2557(define_insn "flag_mulhi"
2558 [(set (match_operand:HI 0 "register_operand" "=d")
2559 (unspec:HI [(match_operand:HI 1 "register_operand" "d")
2560 (match_operand:HI 2 "register_operand" "d")
2561 (match_operand 3 "const_int_operand" "n")]
2562 UNSPEC_MUL_WITH_FLAG))]
2563 ""
2564 "%h0 = %h1 * %h2 %M3;"
2565 [(set_attr "type" "dsp32")])
2566
2567(define_insn "flag_mulhisi"
2568 [(set (match_operand:SI 0 "register_operand" "=d")
2569 (unspec:SI [(match_operand:HI 1 "register_operand" "d")
2570 (match_operand:HI 2 "register_operand" "d")
2571 (match_operand 3 "const_int_operand" "n")]
2572 UNSPEC_MUL_WITH_FLAG))]
2573 ""
2574 "%0 = %h1 * %h2 %M3;"
2575 [(set_attr "type" "dsp32")])
2576
2577(define_insn "flag_mulhisi_parts"
2578 [(set (match_operand:SI 0 "register_operand" "=d")
2579 (unspec:SI [(vec_select:HI
2580 (match_operand:V2HI 1 "register_operand" "d")
2581 (parallel [(match_operand:SI 3 "const01_operand" "P0P1")]))
2582 (vec_select:HI
2583 (match_operand:V2HI 2 "register_operand" "d")
2584 (parallel [(match_operand:SI 4 "const01_operand" "P0P1")]))
2585 (match_operand 5 "const_int_operand" "n")]
2586 UNSPEC_MUL_WITH_FLAG))]
2587 ""
2588{
2589 const char *templates[] = {
2590 "%0 = %h1 * %h2 %M5;",
2591 "%0 = %d1 * %h2 %M5;",
2592 "%0 = %h1 * %d2 %M5;",
2593 "%0 = %d1 * %d2 %M5;" };
2594 int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
2595 return templates[alt];
2596}
2597 [(set_attr "type" "dsp32")])
2598
2599(define_insn "flag_machi"
2600 [(set (match_operand:HI 0 "register_operand" "=d")
2601 (unspec:HI [(match_operand:HI 1 "register_operand" "d")
2602 (match_operand:HI 2 "register_operand" "d")
2603 (match_operand 3 "register_operand" "A")
2604 (match_operand 4 "const01_operand" "P0P1")
2605 (match_operand 5 "const_int_operand" "n")]
2606 UNSPEC_MAC_WITH_FLAG))
2607 (set (match_operand:PDI 6 "register_operand" "=A")
2608 (unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)
2609 (match_dup 4) (match_dup 5)]
2610 UNSPEC_MAC_WITH_FLAG))]
2611 ""
2612 "%h0 = (A0 %b4 %h1 * %h2) %M6;"
2613 [(set_attr "type" "dsp32")])
2614
2615(define_insn "flag_machi_acconly"
2616 [(set (match_operand:PDI 0 "register_operand" "=e")
2617 (unspec:PDI [(match_operand:HI 1 "register_operand" "d")
2618 (match_operand:HI 2 "register_operand" "d")
2619 (match_operand 3 "register_operand" "A")
2620 (match_operand 4 "const01_operand" "P0P1")
2621 (match_operand 5 "const_int_operand" "n")]
2622 UNSPEC_MAC_WITH_FLAG))]
2623 ""
2624 "%0 %b4 %h1 * %h2 %M6;"
2625 [(set_attr "type" "dsp32")])
2626
2627(define_insn "flag_macinithi"
2628 [(set (match_operand:HI 0 "register_operand" "=d")
2629 (unspec:HI [(match_operand:HI 1 "register_operand" "d")
2630 (match_operand:HI 2 "register_operand" "d")
2631 (match_operand 3 "const_int_operand" "n")]
2632 UNSPEC_MAC_WITH_FLAG))
2633 (set (match_operand:PDI 4 "register_operand" "=A")
2634 (unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)]
2635 UNSPEC_MAC_WITH_FLAG))]
2636 ""
2637 "%h0 = (A0 = %h1 * %h2) %M3;"
2638 [(set_attr "type" "dsp32")])
2639
2640(define_insn "flag_macinit1hi"
2641 [(set (match_operand:PDI 0 "register_operand" "=e")
2642 (unspec:PDI [(match_operand:HI 1 "register_operand" "d")
2643 (match_operand:HI 2 "register_operand" "d")
2644 (match_operand 3 "const_int_operand" "n")]
2645 UNSPEC_MAC_WITH_FLAG))]
2646 ""
2647 "%0 = %h1 * %h2 %M3;"
2648 [(set_attr "type" "dsp32")])
2649
c9b3f817 2650(define_insn "mulv2hi3"
0d4a78eb
BS
2651 [(set (match_operand:V2HI 0 "register_operand" "=d")
2652 (mult:V2HI (match_operand:V2HI 1 "register_operand" "d")
2653 (match_operand:V2HI 2 "register_operand" "d")))]
2654 ""
2655 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 (IS);"
2656 [(set_attr "type" "dsp32")])
2657
75d8b2d0
BS
2658(define_insn "flag_mulv2hi"
2659 [(set (match_operand:V2HI 0 "register_operand" "=d")
2660 (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "d")
2661 (match_operand:V2HI 2 "register_operand" "d")
2662 (match_operand 3 "const_int_operand" "n")]
2663 UNSPEC_MUL_WITH_FLAG))]
2664 ""
2665 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 %M3;"
2666 [(set_attr "type" "dsp32")])
2667
2668(define_insn "flag_mulv2hi_parts"
2669 [(set (match_operand:V2HI 0 "register_operand" "=d")
2670 (unspec:V2HI [(vec_concat:V2HI
2671 (vec_select:HI
2672 (match_operand:V2HI 1 "register_operand" "d")
2673 (parallel [(match_operand:SI 3 "const01_operand" "P0P1")]))
2674 (vec_select:HI
2675 (match_dup 1)
2676 (parallel [(match_operand:SI 4 "const01_operand" "P0P1")])))
2677 (vec_concat:V2HI
2678 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2679 (parallel [(match_operand:SI 5 "const01_operand" "P0P1")]))
2680 (vec_select:HI (match_dup 2)
2681 (parallel [(match_operand:SI 6 "const01_operand" "P0P1")])))
2682 (match_operand 7 "const_int_operand" "n")]
2683 UNSPEC_MUL_WITH_FLAG))]
2684 ""
2685{
2686 const char *templates[] = {
2687 "%h0 = %h1 * %h2, %d0 = %h1 * %h2 %M7;",
2688 "%h0 = %d1 * %h2, %d0 = %h1 * %h2 %M7;",
2689 "%h0 = %h1 * %h2, %d0 = %d1 * %h2 %M7;",
2690 "%h0 = %d1 * %h2, %d0 = %d1 * %h2 %M7;",
2691 "%h0 = %h1 * %d2, %d0 = %h1 * %h2 %M7;",
2692 "%h0 = %d1 * %d2, %d0 = %h1 * %h2 %M7;",
2693 "%h0 = %h1 * %d2, %d0 = %d1 * %h2 %M7;",
2694 "%h0 = %d1 * %d2, %d0 = %d1 * %h2 %M7;",
2695 "%h0 = %h1 * %h2, %d0 = %h1 * %d2 %M7;",
2696 "%h0 = %d1 * %h2, %d0 = %h1 * %d2 %M7;",
2697 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 %M7;",
2698 "%h0 = %d1 * %h2, %d0 = %d1 * %d2 %M7;",
2699 "%h0 = %h1 * %d2, %d0 = %h1 * %d2 %M7;",
2700 "%h0 = %d1 * %d2, %d0 = %h1 * %d2 %M7;",
2701 "%h0 = %h1 * %d2, %d0 = %d1 * %d2 %M7;",
2702 "%h0 = %d1 * %d2, %d0 = %d1 * %d2 %M7;" };
2703 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
2704 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
2705 return templates[alt];
2706}
2707 [(set_attr "type" "dsp32")])
2708
2709;; A slightly complicated pattern.
2710;; Operand 0 is the halfword output; operand 11 is the accumulator output
2711;; Halfword inputs are operands 1 and 2; operands 3, 4, 5 and 6 specify which
2712;; parts of these 2x16 bit registers to use.
2713;; Operand 7 is the accumulator input.
2714;; Operands 8/9 specify whether low/high parts are mac (0) or msu (1)
2715;; Operand 10 is the macflag to be used.
2716(define_insn "flag_macv2hi_parts"
2717 [(set (match_operand:V2HI 0 "register_operand" "=d")
2718 (unspec:V2HI [(vec_concat:V2HI
2719 (vec_select:HI
2720 (match_operand:V2HI 1 "register_operand" "d")
2721 (parallel [(match_operand:SI 3 "const01_operand" "P0P1")]))
2722 (vec_select:HI
2723 (match_dup 1)
2724 (parallel [(match_operand:SI 4 "const01_operand" "P0P1")])))
2725 (vec_concat:V2HI
2726 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2727 (parallel [(match_operand:SI 5 "const01_operand" "P0P1")]))
2728 (vec_select:HI (match_dup 2)
2729 (parallel [(match_operand:SI 6 "const01_operand" "P0P1")])))
2730 (match_operand:V2PDI 7 "register_operand" "e")
2731 (match_operand 8 "const01_operand" "P0P1")
2732 (match_operand 9 "const01_operand" "P0P1")
2733 (match_operand 10 "const_int_operand" "n")]
2734 UNSPEC_MAC_WITH_FLAG))
2735 (set (match_operand:V2PDI 11 "register_operand" "=e")
2736 (unspec:V2PDI [(vec_concat:V2HI
2737 (vec_select:HI (match_dup 1) (parallel [(match_dup 3)]))
2738 (vec_select:HI (match_dup 1) (parallel [(match_dup 4)])))
2739 (vec_concat:V2HI
2740 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)]))
2741 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)])))
2742 (match_dup 7) (match_dup 8) (match_dup 9) (match_dup 10)]
2743 UNSPEC_MAC_WITH_FLAG))]
2744 ""
2745{
2746 const char *templates[] = {
2747 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %h1 * %h2) %M10;",
2748 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %h1 * %h2) %M10;",
2749 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %d1 * %h2) %M10;",
2750 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %d1 * %h2) %M10;",
2751 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %h1 * %h2) %M10;",
2752 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %h1 * %h2) %M10;",
2753 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %d1 * %h2) %M10;",
2754 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %d1 * %h2) %M10;",
2755 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %h1 * %d2) %M10;",
2756 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %h1 * %d2) %M10;",
2757 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %d1 * %d2) %M10;",
2758 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %d1 * %d2) %M10;",
2759 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %h1 * %d2) %M10;",
2760 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %h1 * %d2) %M10;",
2761 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %d1 * %d2) %M10;",
2762 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %d1 * %d2) %M10;" };
2763 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
2764 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
2765 return templates[alt];
2766}
2767 [(set_attr "type" "dsp32")])
2768
2769(define_insn "flag_macv2hi_parts_acconly"
2770 [(set (match_operand:V2PDI 0 "register_operand" "=e")
2771 (unspec:V2PDI [(vec_concat:V2HI
2772 (vec_select:HI
2773 (match_operand:V2HI 1 "register_operand" "d")
2774 (parallel [(match_operand:SI 3 "const01_operand" "P0P1")]))
2775 (vec_select:HI
2776 (match_dup 1)
2777 (parallel [(match_operand:SI 4 "const01_operand" "P0P1")])))
2778 (vec_concat:V2HI
2779 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2780 (parallel [(match_operand:SI 5 "const01_operand" "P0P1")]))
2781 (vec_select:HI (match_dup 2)
2782 (parallel [(match_operand:SI 6 "const01_operand" "P0P1")])))
2783 (match_operand:V2PDI 7 "register_operand" "e")
2784 (match_operand 8 "const01_operand" "P0P1")
2785 (match_operand 9 "const01_operand" "P0P1")
2786 (match_operand 10 "const_int_operand" "n")]
2787 UNSPEC_MAC_WITH_FLAG))]
2788 ""
2789{
2790 const char *templates[] = {
2791 "A0 %b8 %h1 * %h2, A1 %b9 %h1 * %h2 %M10;",
2792 "A0 %b8 %d1 * %h2, A1 %b9 %h1 * %h2 %M10;",
2793 "A0 %b8 %h1 * %h2, A1 %b9 %d1 * %h2 %M10;",
2794 "A0 %b8 %d1 * %h2, A1 %b9 %d1 * %h2 %M10;",
2795 "A0 %b8 %h1 * %d2, A1 %b9 %h1 * %h2 %M10;",
2796 "A0 %b8 %d1 * %d2, A1 %b9 %h1 * %h2 %M10;",
2797 "A0 %b8 %h1 * %d2, A1 %b9 %d1 * %h2 %M10;",
2798 "A0 %b8 %d1 * %d2, A1 %b9 %d1 * %h2 %M10;",
2799 "A0 %b8 %h1 * %h2, A1 %b9 %h1 * %d2 %M10;",
2800 "A0 %b8 %d1 * %h2, A1 %b9 %h1 * %d2 %M10;",
2801 "A0 %b8 %h1 * %h2, A1 %b9 %d1 * %d2 %M10;",
2802 "A0 %b8 %d1 * %h2, A1 %b9 %d1 * %d2 %M10;",
2803 "A0 %b8 %h1 * %d2, A1 %b9 %h1 * %d2 %M10;",
2804 "A0 %b8 %d1 * %d2, A1 %b9 %h1 * %d2 %M10;",
2805 "A0 %b8 %h1 * %d2, A1 %b9 %d1 * %d2 %M10;",
2806 "A0 %b8 %d1 * %d2, A1 %b9 %d1 * %d2 %M10;" };
2807 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
2808 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
2809 return templates[alt];
2810}
2811 [(set_attr "type" "dsp32")])
2812
2813;; Same as above, but initializing the accumulators and therefore a couple fewer
2814;; necessary operands.
2815(define_insn "flag_macinitv2hi_parts"
0d4a78eb 2816 [(set (match_operand:V2HI 0 "register_operand" "=d")
75d8b2d0
BS
2817 (unspec:V2HI [(vec_concat:V2HI
2818 (vec_select:HI
2819 (match_operand:V2HI 1 "register_operand" "d")
2820 (parallel [(match_operand:SI 3 "const01_operand" "P0P1")]))
2821 (vec_select:HI
2822 (match_dup 1)
2823 (parallel [(match_operand:SI 4 "const01_operand" "P0P1")])))
2824 (vec_concat:V2HI
2825 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2826 (parallel [(match_operand:SI 5 "const01_operand" "P0P1")]))
2827 (vec_select:HI (match_dup 2)
2828 (parallel [(match_operand:SI 6 "const01_operand" "P0P1")])))
2829 (match_operand 7 "const_int_operand" "n")]
2830 UNSPEC_MAC_WITH_FLAG))
2831 (set (match_operand:V2PDI 8 "register_operand" "=e")
2832 (unspec:V2PDI [(vec_concat:V2HI
2833 (vec_select:HI (match_dup 1) (parallel [(match_dup 3)]))
2834 (vec_select:HI (match_dup 1) (parallel [(match_dup 4)])))
2835 (vec_concat:V2HI
2836 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)]))
2837 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)])))
2838 (match_dup 7)]
2839 UNSPEC_MAC_WITH_FLAG))]
2840 ""
2841{
2842 const char *templates[] = {
2843 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %h1 * %h2) %M7;",
2844 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %h1 * %h2) %M7;",
2845 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %d1 * %h2) %M7;",
2846 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %d1 * %h2) %M7;",
2847 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %h1 * %h2) %M7;",
2848 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %h1 * %h2) %M7;",
2849 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %d1 * %h2) %M7;",
2850 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %d1 * %h2) %M7;",
2851 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %h1 * %d2) %M7;",
2852 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %h1 * %d2) %M7;",
2853 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %d1 * %d2) %M7;",
2854 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %d1 * %d2) %M7;",
2855 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %h1 * %d2) %M7;",
2856 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %h1 * %d2) %M7;",
2857 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %d1 * %d2) %M7;",
2858 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %d1 * %d2) %M7;" };
2859 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
2860 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
2861 return templates[alt];
2862}
2863 [(set_attr "type" "dsp32")])
2864
2865(define_insn "flag_macinit1v2hi_parts"
2866 [(set (match_operand:V2PDI 0 "register_operand" "=e")
2867 (unspec:V2PDI [(vec_concat:V2HI
2868 (vec_select:HI
2869 (match_operand:V2HI 1 "register_operand" "d")
2870 (parallel [(match_operand:SI 3 "const01_operand" "P0P1")]))
2871 (vec_select:HI
2872 (match_dup 1)
2873 (parallel [(match_operand:SI 4 "const01_operand" "P0P1")])))
2874 (vec_concat:V2HI
2875 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2876 (parallel [(match_operand:SI 5 "const01_operand" "P0P1")]))
2877 (vec_select:HI (match_dup 2)
2878 (parallel [(match_operand:SI 6 "const01_operand" "P0P1")])))
2879 (match_operand 7 "const_int_operand" "n")]
2880 UNSPEC_MAC_WITH_FLAG))]
2881 ""
2882{
2883 const char *templates[] = {
2884 "A0 = %h1 * %h2, A1 = %h1 * %h2 %M7;",
2885 "A0 = %d1 * %h2, A1 = %h1 * %h2 %M7;",
2886 "A0 = %h1 * %h2, A1 = %d1 * %h2 %M7;",
2887 "A0 = %d1 * %h2, A1 = %d1 * %h2 %M7;",
2888 "A0 = %h1 * %d2, A1 = %h1 * %h2 %M7;",
2889 "A0 = %d1 * %d2, A1 = %h1 * %h2 %M7;",
2890 "A0 = %h1 * %d2, A1 = %d1 * %h2 %M7;",
2891 "A0 = %d1 * %d2, A1 = %d1 * %h2 %M7;",
2892 "A0 = %h1 * %h2, A1 = %h1 * %d2 %M7;",
2893 "A0 = %d1 * %h2, A1 = %h1 * %d2 %M7;",
2894 "A0 = %h1 * %h2, A1 = %d1 * %d2 %M7;",
2895 "A0 = %d1 * %h2, A1 = %d1 * %d2 %M7;",
2896 "A0 = %h1 * %d2, A1 = %h1 * %d2 %M7;",
2897 "A0 = %d1 * %d2, A1 = %h1 * %d2 %M7;",
2898 "A0 = %h1 * %d2, A1 = %d1 * %d2 %M7;",
2899 "A0 = %d1 * %d2, A1 = %d1 * %d2 %M7;" };
2900 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
2901 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
2902 return templates[alt];
2903}
2904 [(set_attr "type" "dsp32")])
2905
2906(define_insn "mulhisi_ll"
2907 [(set (match_operand:SI 0 "register_operand" "=d")
2908 (mult:SI (sign_extend:SI
2909 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
2910 (parallel [(const_int 0)])))
2911 (sign_extend:SI
2912 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2913 (parallel [(const_int 0)])))))]
2914 ""
2915 "%0 = %h1 * %h2 (IS);"
2916 [(set_attr "type" "dsp32")])
2917
2918(define_insn "mulhisi_lh"
2919 [(set (match_operand:SI 0 "register_operand" "=d")
2920 (mult:SI (sign_extend:SI
2921 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
2922 (parallel [(const_int 0)])))
2923 (sign_extend:SI
2924 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2925 (parallel [(const_int 1)])))))]
2926 ""
2927 "%0 = %h1 * %d2 (IS);"
2928 [(set_attr "type" "dsp32")])
2929
2930(define_insn "mulhisi_hl"
2931 [(set (match_operand:SI 0 "register_operand" "=d")
2932 (mult:SI (sign_extend:SI
2933 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
2934 (parallel [(const_int 1)])))
2935 (sign_extend:SI
2936 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2937 (parallel [(const_int 0)])))))]
2938 ""
2939 "%0 = %d1 * %h2 (IS);"
2940 [(set_attr "type" "dsp32")])
2941
2942(define_insn "mulhisi_hh"
2943 [(set (match_operand:SI 0 "register_operand" "=d")
2944 (mult:SI (sign_extend:SI
2945 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
2946 (parallel [(const_int 1)])))
2947 (sign_extend:SI
2948 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2949 (parallel [(const_int 1)])))))]
2950 ""
2951 "%0 = %d1 * %d2 (IS);"
2952 [(set_attr "type" "dsp32")])
2953
2954(define_insn "ssnegv2hi2"
2955 [(set (match_operand:V2HI 0 "register_operand" "=d")
2956 (ss_neg:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
0d4a78eb
BS
2957 ""
2958 "%0 = - %1 (V);"
2959 [(set_attr "type" "dsp32")])
2960
c9b3f817 2961(define_insn "absv2hi2"
0d4a78eb
BS
2962 [(set (match_operand:V2HI 0 "register_operand" "=d")
2963 (abs:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
2964 ""
2965 "%0 = ABS %1 (V);"
2966 [(set_attr "type" "dsp32")])
2967
75d8b2d0
BS
2968;; Shifts.
2969
2970(define_insn "ssashiftv2hi3"
2971 [(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
2972 (if_then_else:V2HI
2973 (lt (match_operand:SI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
2974 (ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" "d,d,d")
2975 (match_dup 2))
2976 (ss_ashift:V2HI (match_dup 1) (match_dup 2))))]
2977 ""
2978 "@
2979 %0 = ASHIFT %1 BY %2 (V, S);
2980 %0 = %1 >>> %2 (V,S);
2981 %0 = %1 << %2 (V,S);"
2982 [(set_attr "type" "dsp32")])
2983
2984(define_insn "ssashifthi3"
2985 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
2986 (if_then_else:HI
2987 (lt (match_operand:SI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
2988 (ashiftrt:HI (match_operand:HI 1 "register_operand" "d,d,d")
2989 (match_dup 2))
2990 (ss_ashift:HI (match_dup 1) (match_dup 2))))]
2991 ""
2992 "@
2993 %0 = ASHIFT %1 BY %2 (V, S);
2994 %0 = %1 >>> %2 (V,S);
2995 %0 = %1 << %2 (V,S);"
2996 [(set_attr "type" "dsp32")])
2997
2998(define_insn "lshiftv2hi3"
2999 [(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
3000 (if_then_else:V2HI
3001 (lt (match_operand:SI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
3002 (lshiftrt:V2HI (match_operand:V2HI 1 "register_operand" "d,d,d")
3003 (match_dup 2))
3004 (ashift:V2HI (match_dup 1) (match_dup 2))))]
3005 ""
3006 "@
3007 %0 = LSHIFT %1 BY %2 (V);
3008 %0 = %1 >> %2 (V);
3009 %0 = %1 << %2 (V);"
3010 [(set_attr "type" "dsp32")])
3011
3012(define_insn "lshifthi3"
3013 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3014 (if_then_else:HI
3015 (lt (match_operand:SI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
3016 (lshiftrt:HI (match_operand:HI 1 "register_operand" "d,d,d")
3017 (match_dup 2))
3018 (ashift:HI (match_dup 1) (match_dup 2))))]
3019 ""
3020 "@
3021 %0 = LSHIFT %1 BY %2 (V);
3022 %0 = %1 >> %2 (V);
3023 %0 = %1 << %2 (V);"
3024 [(set_attr "type" "dsp32")])
3025