]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/bfin/bfin.md
re PR middle-end/31699 (-march=opteron -ftree-vectorize generates wrong code)
[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)
a9c46998
JZ
49; v (b0..b3)
50; c (i0..i3,m0..m3) CIRCREGS
51; C (CC) CCREGS
b03149e1
JZ
52; t (lt0,lt1)
53; k (lc0,lc1)
a9c46998 54; u (lb0,lb1)
0d4a78eb
BS
55;
56
57;; Define constants for hard registers.
58
59(define_constants
60 [(REG_R0 0)
61 (REG_R1 1)
62 (REG_R2 2)
63 (REG_R3 3)
64 (REG_R4 4)
65 (REG_R5 5)
66 (REG_R6 6)
67 (REG_R7 7)
68
69 (REG_P0 8)
70 (REG_P1 9)
71 (REG_P2 10)
72 (REG_P3 11)
73 (REG_P4 12)
74 (REG_P5 13)
75 (REG_P6 14)
76 (REG_P7 15)
77
78 (REG_SP 14)
79 (REG_FP 15)
80
81 (REG_I0 16)
df259245
JZ
82 (REG_I1 17)
83 (REG_I2 18)
84 (REG_I3 19)
85
86 (REG_B0 20)
87 (REG_B1 21)
88 (REG_B2 22)
89 (REG_B3 23)
90
91 (REG_L0 24)
92 (REG_L1 25)
93 (REG_L2 26)
0d4a78eb
BS
94 (REG_L3 27)
95
96 (REG_M0 28)
97 (REG_M1 29)
98 (REG_M2 30)
99 (REG_M3 31)
100
101 (REG_A0 32)
102 (REG_A1 33)
103
104 (REG_CC 34)
105 (REG_RETS 35)
106 (REG_RETI 36)
107 (REG_RETX 37)
108 (REG_RETN 38)
109 (REG_RETE 39)
110
111 (REG_ASTAT 40)
112 (REG_SEQSTAT 41)
113 (REG_USP 42)
114
b03149e1
JZ
115 (REG_ARGP 43)
116
117 (REG_LT0 44)
118 (REG_LT1 45)
119 (REG_LC0 46)
120 (REG_LC1 47)
121 (REG_LB0 48)
122 (REG_LB1 49)])
0d4a78eb
BS
123
124;; Constants used in UNSPECs and UNSPEC_VOLATILEs.
125
126(define_constants
127 [(UNSPEC_CBRANCH_TAKEN 0)
128 (UNSPEC_CBRANCH_NOPS 1)
129 (UNSPEC_RETURN 2)
130 (UNSPEC_MOVE_PIC 3)
131 (UNSPEC_LIBRARY_OFFSET 4)
75d8b2d0
BS
132 (UNSPEC_PUSH_MULTIPLE 5)
133 ;; Multiply or MAC with extra CONST_INT operand specifying the macflag
134 (UNSPEC_MUL_WITH_FLAG 6)
6614f9f5
BS
135 (UNSPEC_MAC_WITH_FLAG 7)
136 (UNSPEC_MOVE_FDPIC 8)
b03149e1 137 (UNSPEC_FUNCDESC_GOT17M4 9)
bbbc206e 138 (UNSPEC_LSETUP_END 10)
942fd98f 139 ;; Distinguish a 32-bit version of an insn from a 16-bit version.
bbbc206e 140 (UNSPEC_32BIT 11)])
0d4a78eb
BS
141
142(define_constants
5fcead21
BS
143 [(UNSPEC_VOLATILE_EH_RETURN 0)
144 (UNSPEC_VOLATILE_CSYNC 1)
6614f9f5
BS
145 (UNSPEC_VOLATILE_SSYNC 2)
146 (UNSPEC_VOLATILE_LOAD_FUNCDESC 3)])
0d4a78eb 147
75d8b2d0
BS
148(define_constants
149 [(MACFLAG_NONE 0)
150 (MACFLAG_T 1)
151 (MACFLAG_FU 2)
152 (MACFLAG_TFU 3)
153 (MACFLAG_IS 4)
154 (MACFLAG_IU 5)
155 (MACFLAG_W32 6)
156 (MACFLAG_M 7)
3efd5670
BS
157 (MACFLAG_IS_M 8)
158 (MACFLAG_S2RND 9)
159 (MACFLAG_ISS2 10)
160 (MACFLAG_IH 11)])
75d8b2d0 161
0d4a78eb 162(define_attr "type"
96f46444 163 "move,movcc,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy"
0d4a78eb
BS
164 (const_string "misc"))
165
36662eb1
BS
166(define_attr "addrtype" "32bit,preg,ireg"
167 (cond [(and (eq_attr "type" "mcld")
168 (and (match_operand 0 "d_register_operand" "")
169 (match_operand 1 "mem_p_address_operand" "")))
170 (const_string "preg")
171 (and (eq_attr "type" "mcld")
172 (and (match_operand 0 "d_register_operand" "")
173 (match_operand 1 "mem_i_address_operand" "")))
174 (const_string "ireg")
175 (and (eq_attr "type" "mcst")
176 (and (match_operand 1 "d_register_operand" "")
177 (match_operand 0 "mem_p_address_operand" "")))
178 (const_string "preg")
179 (and (eq_attr "type" "mcst")
180 (and (match_operand 1 "d_register_operand" "")
181 (match_operand 0 "mem_i_address_operand" "")))
182 (const_string "ireg")]
183 (const_string "32bit")))
184
0d4a78eb
BS
185;; Scheduling definitions
186
187(define_automaton "bfin")
188
36662eb1
BS
189(define_cpu_unit "slot0" "bfin")
190(define_cpu_unit "slot1" "bfin")
191(define_cpu_unit "slot2" "bfin")
192
193;; Three units used to enforce parallel issue restrictions:
942fd98f 194;; only one of the 16-bit slots can use a P register in an address,
36662eb1
BS
195;; and only one them can be a store.
196(define_cpu_unit "store" "bfin")
197(define_cpu_unit "pregs" "bfin")
198
199(define_reservation "core" "slot0+slot1+slot2")
0d4a78eb
BS
200
201(define_insn_reservation "alu" 1
96f46444 202 (eq_attr "type" "move,movcc,mvi,alu0,shft,brcc,br,call,misc,sync,compare")
0d4a78eb
BS
203 "core")
204
205(define_insn_reservation "imul" 3
206 (eq_attr "type" "mult")
207 "core*3")
208
36662eb1
BS
209(define_insn_reservation "dsp32" 1
210 (eq_attr "type" "dsp32")
211 "slot0")
212
213(define_insn_reservation "load32" 1
214 (and (not (eq_attr "seq_insns" "multi"))
215 (and (eq_attr "type" "mcld") (eq_attr "addrtype" "32bit")))
216 "core")
217
218(define_insn_reservation "loadp" 1
219 (and (not (eq_attr "seq_insns" "multi"))
220 (and (eq_attr "type" "mcld") (eq_attr "addrtype" "preg")))
221 "(slot1|slot2)+pregs")
222
223(define_insn_reservation "loadi" 1
224 (and (not (eq_attr "seq_insns" "multi"))
225 (and (eq_attr "type" "mcld") (eq_attr "addrtype" "ireg")))
226 "(slot1|slot2)")
227
228(define_insn_reservation "store32" 1
229 (and (not (eq_attr "seq_insns" "multi"))
230 (and (eq_attr "type" "mcst") (eq_attr "addrtype" "32bit")))
0d4a78eb
BS
231 "core")
232
36662eb1
BS
233(define_insn_reservation "storep" 1
234 (and (not (eq_attr "seq_insns" "multi"))
235 (and (eq_attr "type" "mcst") (eq_attr "addrtype" "preg")))
236 "(slot1|slot2)+pregs+store")
237
238(define_insn_reservation "storei" 1
239 (and (not (eq_attr "seq_insns" "multi"))
240 (and (eq_attr "type" "mcst") (eq_attr "addrtype" "ireg")))
241 "(slot1|slot2)+store")
242
243(define_insn_reservation "multi" 2
244 (eq_attr "seq_insns" "multi")
245 "core")
246
247(absence_set "slot0" "slot1,slot2")
248(absence_set "slot1" "slot2")
249
0d4a78eb
BS
250;; Make sure genautomata knows about the maximum latency that can be produced
251;; by the adjust_cost function.
252(define_insn_reservation "dummy" 5
36662eb1 253 (eq_attr "type" "dummy")
0d4a78eb
BS
254 "core")
255\f
256;; Operand and operator predicates
257
258(include "predicates.md")
259
260\f
261;;; FRIO branches have been optimized for code density
262;;; this comes at a slight cost of complexity when
263;;; a compiler needs to generate branches in the general
264;;; case. In order to generate the correct branching
265;;; mechanisms the compiler needs keep track of instruction
266;;; lengths. The follow table describes how to count instructions
267;;; for the FRIO architecture.
268;;;
269;;; unconditional br are 12-bit imm pcrelative branches *2
270;;; conditional br are 10-bit imm pcrelative branches *2
271;;; brcc 10-bit:
272;;; 1024 10-bit imm *2 is 2048 (-1024..1022)
273;;; br 12-bit :
274;;; 4096 12-bit imm *2 is 8192 (-4096..4094)
275;;; NOTE : For brcc we generate instructions such as
276;;; if cc jmp; jump.[sl] offset
277;;; offset of jump.[sl] is from the jump instruction but
278;;; gcc calculates length from the if cc jmp instruction
a2391c6a
JZ
279;;; furthermore gcc takes the end address of the branch instruction
280;;; as (pc) for a forward branch
281;;; hence our range is (-4094, 4092) instead of (-4096, 4094) for a br
0d4a78eb
BS
282;;;
283;;; The way the (pc) rtx works in these calculations is somewhat odd;
284;;; for backward branches it's the address of the current instruction,
285;;; for forward branches it's the previously known address of the following
286;;; instruction - we have to take this into account by reducing the range
287;;; for a forward branch.
288
289;; Lengths for type "mvi" insns are always defined by the instructions
290;; themselves.
291(define_attr "length" ""
292 (cond [(eq_attr "type" "mcld")
293 (if_then_else (match_operand 1 "effective_address_32bit_p" "")
294 (const_int 4) (const_int 2))
295
296 (eq_attr "type" "mcst")
297 (if_then_else (match_operand 0 "effective_address_32bit_p" "")
298 (const_int 4) (const_int 2))
299
300 (eq_attr "type" "move") (const_int 2)
301
302 (eq_attr "type" "dsp32") (const_int 4)
303 (eq_attr "type" "call") (const_int 4)
304
305 (eq_attr "type" "br")
306 (if_then_else (and
307 (le (minus (match_dup 0) (pc)) (const_int 4092))
308 (ge (minus (match_dup 0) (pc)) (const_int -4096)))
309 (const_int 2)
310 (const_int 4))
311
312 (eq_attr "type" "brcc")
313 (cond [(and
314 (le (minus (match_dup 3) (pc)) (const_int 1020))
315 (ge (minus (match_dup 3) (pc)) (const_int -1024)))
316 (const_int 2)
317 (and
a2391c6a 318 (le (minus (match_dup 3) (pc)) (const_int 4092))
0d4a78eb
BS
319 (ge (minus (match_dup 3) (pc)) (const_int -4094)))
320 (const_int 4)]
321 (const_int 6))
322 ]
323
324 (const_int 2)))
325
b03149e1
JZ
326;; Classify the insns into those that are one instruction and those that
327;; are more than one in sequence.
328(define_attr "seq_insns" "single,multi"
329 (const_string "single"))
330
0d4a78eb
BS
331;; Conditional moves
332
333(define_expand "movsicc"
334 [(set (match_operand:SI 0 "register_operand" "")
335 (if_then_else:SI (match_operand 1 "comparison_operator" "")
336 (match_operand:SI 2 "register_operand" "")
337 (match_operand:SI 3 "register_operand" "")))]
338 ""
339{
340 operands[1] = bfin_gen_compare (operands[1], SImode);
341})
342
343(define_insn "*movsicc_insn1"
344 [(set (match_operand:SI 0 "register_operand" "=da,da,da")
345 (if_then_else:SI
4729dc92 346 (eq:BI (match_operand:BI 3 "register_operand" "C,C,C")
0d4a78eb
BS
347 (const_int 0))
348 (match_operand:SI 1 "register_operand" "da,0,da")
349 (match_operand:SI 2 "register_operand" "0,da,da")))]
350 ""
351 "@
352 if !cc %0 =%1; /* movsicc-1a */
353 if cc %0 =%2; /* movsicc-1b */
354 if !cc %0 =%1; if cc %0=%2; /* movsicc-1 */"
355 [(set_attr "length" "2,2,4")
96f46444 356 (set_attr "type" "movcc")
b03149e1 357 (set_attr "seq_insns" "*,*,multi")])
0d4a78eb
BS
358
359(define_insn "*movsicc_insn2"
360 [(set (match_operand:SI 0 "register_operand" "=da,da,da")
361 (if_then_else:SI
4729dc92 362 (ne:BI (match_operand:BI 3 "register_operand" "C,C,C")
0d4a78eb
BS
363 (const_int 0))
364 (match_operand:SI 1 "register_operand" "0,da,da")
365 (match_operand:SI 2 "register_operand" "da,0,da")))]
366 ""
367 "@
368 if !cc %0 =%2; /* movsicc-2b */
369 if cc %0 =%1; /* movsicc-2a */
370 if cc %0 =%1; if !cc %0=%2; /* movsicc-1 */"
371 [(set_attr "length" "2,2,4")
96f46444 372 (set_attr "type" "movcc")
b03149e1 373 (set_attr "seq_insns" "*,*,multi")])
0d4a78eb
BS
374
375;; Insns to load HIGH and LO_SUM
376
377(define_insn "movsi_high"
378 [(set (match_operand:SI 0 "register_operand" "=x")
379 (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
380 "reload_completed"
381 "%d0 = %d1;"
382 [(set_attr "type" "mvi")
383 (set_attr "length" "4")])
384
385(define_insn "movstricthi_high"
386 [(set (match_operand:SI 0 "register_operand" "+x")
387 (ior:SI (and:SI (match_dup 0) (const_int 65535))
388 (match_operand:SI 1 "immediate_operand" "i")))]
389 "reload_completed"
390 "%d0 = %d1;"
391 [(set_attr "type" "mvi")
392 (set_attr "length" "4")])
393
394(define_insn "movsi_low"
395 [(set (match_operand:SI 0 "register_operand" "=x")
396 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
397 (match_operand:SI 2 "immediate_operand" "i")))]
398 "reload_completed"
399 "%h0 = %h2;"
400 [(set_attr "type" "mvi")
401 (set_attr "length" "4")])
402
403(define_insn "movsi_high_pic"
404 [(set (match_operand:SI 0 "register_operand" "=x")
405 (high:SI (unspec:SI [(match_operand:SI 1 "" "")]
406 UNSPEC_MOVE_PIC)))]
407 ""
408 "%d0 = %1@GOT_LOW;"
409 [(set_attr "type" "mvi")
410 (set_attr "length" "4")])
411
412(define_insn "movsi_low_pic"
413 [(set (match_operand:SI 0 "register_operand" "=x")
414 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
415 (unspec:SI [(match_operand:SI 2 "" "")]
416 UNSPEC_MOVE_PIC)))]
417 ""
418 "%h0 = %h2@GOT_HIGH;"
419 [(set_attr "type" "mvi")
420 (set_attr "length" "4")])
421
422;;; Move instructions
423
424(define_insn_and_split "movdi_insn"
425 [(set (match_operand:DI 0 "nonimmediate_operand" "=x,mx,r")
426 (match_operand:DI 1 "general_operand" "iFx,r,mx"))]
427 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
428 "#"
429 "reload_completed"
430 [(set (match_dup 2) (match_dup 3))
431 (set (match_dup 4) (match_dup 5))]
432{
433 rtx lo_half[2], hi_half[2];
434 split_di (operands, 2, lo_half, hi_half);
435
436 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
437 {
438 operands[2] = hi_half[0];
439 operands[3] = hi_half[1];
440 operands[4] = lo_half[0];
441 operands[5] = lo_half[1];
442 }
443 else
444 {
445 operands[2] = lo_half[0];
446 operands[3] = lo_half[1];
447 operands[4] = hi_half[0];
448 operands[5] = hi_half[1];
449 }
450})
451
452(define_insn "movbi"
4729dc92
BS
453 [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,md,C,d,C")
454 (match_operand:BI 1 "general_operand" "x,xKs3,md,d,d,C,P0"))]
0d4a78eb
BS
455
456 ""
457 "@
458 %0 = %1;
459 %0 = %1 (X);
bbbc206e 460 %0 = B %1 (Z)%!
4729dc92 461 B %0 = %1;
0d4a78eb 462 CC = %1;
49373252
BS
463 %0 = CC;
464 R0 = R0 | R0; CC = AC0;"
465 [(set_attr "type" "move,mvi,mcld,mcst,compare,compare,alu0")
b03149e1
JZ
466 (set_attr "length" "2,2,*,*,2,2,4")
467 (set_attr "seq_insns" "*,*,*,*,*,*,multi")])
0d4a78eb
BS
468
469(define_insn "movpdi"
470 [(set (match_operand:PDI 0 "nonimmediate_operand" "=e,<,e")
471 (match_operand:PDI 1 "general_operand" " e,e,>"))]
472 ""
473 "@
474 %0 = %1;
475 %0 = %x1; %0 = %w1;
476 %w0 = %1; %x0 = %1;"
b03149e1
JZ
477 [(set_attr "type" "move,mcst,mcld")
478 (set_attr "seq_insns" "*,multi,multi")])
0d4a78eb 479
75d8b2d0
BS
480(define_insn "load_accumulator"
481 [(set (match_operand:PDI 0 "register_operand" "=e")
482 (sign_extend:PDI (match_operand:SI 1 "register_operand" "d")))]
483 ""
484 "%0 = %1;"
485 [(set_attr "type" "move")])
486
487(define_insn_and_split "load_accumulator_pair"
488 [(set (match_operand:V2PDI 0 "register_operand" "=e")
489 (sign_extend:V2PDI (vec_concat:V2SI
490 (match_operand:SI 1 "register_operand" "d")
491 (match_operand:SI 2 "register_operand" "d"))))]
492 ""
493 "#"
494 "reload_completed"
495 [(set (match_dup 3) (sign_extend:PDI (match_dup 1)))
496 (set (match_dup 4) (sign_extend:PDI (match_dup 2)))]
497{
498 operands[3] = gen_rtx_REG (PDImode, REGNO (operands[0]));
499 operands[4] = gen_rtx_REG (PDImode, REGNO (operands[0]) + 1);
500})
501
0d4a78eb
BS
502(define_insn "*pushsi_insn"
503 [(set (mem:SI (pre_dec:SI (reg:SI REG_SP)))
504 (match_operand:SI 0 "register_operand" "xy"))]
505 ""
506 "[--SP] = %0;"
507 [(set_attr "type" "mcst")
35e3ced9 508 (set_attr "addrtype" "32bit")
0d4a78eb
BS
509 (set_attr "length" "2")])
510
511(define_insn "*popsi_insn"
35e3ced9 512 [(set (match_operand:SI 0 "register_operand" "=d,xy")
0d4a78eb
BS
513 (mem:SI (post_inc:SI (reg:SI REG_SP))))]
514 ""
bbbc206e 515 "%0 = [SP++]%!"
0d4a78eb 516 [(set_attr "type" "mcld")
35e3ced9 517 (set_attr "addrtype" "preg,32bit")
0d4a78eb
BS
518 (set_attr "length" "2")])
519
520;; The first alternative is used to make reload choose a limited register
521;; class when faced with a movsi_insn that had its input operand replaced
522;; with a PLUS. We generally require fewer secondary reloads this way.
0d4a78eb 523
b03149e1 524(define_insn "*movsi_insn"
4d4f2837
BS
525 [(set (match_operand:SI 0 "nonimmediate_operand" "=da,x*y,da,x,x,x,da,mr")
526 (match_operand:SI 1 "general_operand" "da,x*y,xKs7,xKsh,xKuh,ix,mr,da"))]
0d4a78eb 527 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
b03149e1 528 "@
0d4a78eb
BS
529 %0 = %1;
530 %0 = %1;
531 %0 = %1 (X);
532 %0 = %1 (X);
533 %0 = %1 (Z);
534 #
bbbc206e
BS
535 %0 = %1%!
536 %0 = %1%!"
4d4f2837
BS
537 [(set_attr "type" "move,move,mvi,mvi,mvi,*,mcld,mcst")
538 (set_attr "length" "2,2,2,4,4,*,*,*")])
0d4a78eb 539
bbbc206e
BS
540(define_insn "*movsi_insn32"
541 [(set (match_operand:SI 0 "register_operand" "=d,d")
542 (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "d,P0")] UNSPEC_32BIT))]
543 ""
544 "@
545 %0 = ROT %1 BY 0%!
546 %0 = %0 -|- %0%!"
547 [(set_attr "type" "dsp32")])
548
549(define_split
550 [(set (match_operand:SI 0 "d_register_operand" "")
551 (const_int 0))]
552 "splitting_for_sched && !optimize_size"
553 [(set (match_dup 0) (unspec:SI [(const_int 0)] UNSPEC_32BIT))])
554
555(define_split
556 [(set (match_operand:SI 0 "d_register_operand" "")
557 (match_operand:SI 1 "d_register_operand" ""))]
558 "splitting_for_sched && !optimize_size"
559 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_32BIT))])
560
75d8b2d0
BS
561(define_insn_and_split "*movv2hi_insn"
562 [(set (match_operand:V2HI 0 "nonimmediate_operand" "=da,da,d,dm")
563 (match_operand:V2HI 1 "general_operand" "i,di,md,d"))]
0d4a78eb
BS
564
565 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
75d8b2d0
BS
566 "@
567 #
568 %0 = %1;
bbbc206e
BS
569 %0 = %1%!
570 %0 = %1%!"
75d8b2d0
BS
571 "reload_completed && GET_CODE (operands[1]) == CONST_VECTOR"
572 [(set (match_dup 0) (high:SI (match_dup 2)))
573 (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 3)))]
574{
575 HOST_WIDE_INT intval = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
576 intval |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
554006bd 577
75d8b2d0
BS
578 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
579 operands[2] = operands[3] = GEN_INT (trunc_int_for_mode (intval, SImode));
580}
581 [(set_attr "type" "move,move,mcld,mcst")
582 (set_attr "length" "2,2,*,*")])
0d4a78eb
BS
583
584(define_insn "*movhi_insn"
585 [(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr")
586 (match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
587 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
c4963a0a
BS
588{
589 static const char *templates[] = {
590 "%0 = %1;",
591 "%0 = %1 (X);",
592 "%0 = %1 (X);",
bbbc206e
BS
593 "%0 = W %1 (X)%!",
594 "W %0 = %1%!",
595 "%h0 = W %1%!",
596 "W %0 = %h1%!"
c4963a0a
BS
597 };
598 int alt = which_alternative;
599 rtx mem = (MEM_P (operands[0]) ? operands[0]
600 : MEM_P (operands[1]) ? operands[1] : NULL_RTX);
601 if (mem && bfin_dsp_memref_p (mem))
602 alt += 2;
603 return templates[alt];
604}
0d4a78eb
BS
605 [(set_attr "type" "move,mvi,mvi,mcld,mcst")
606 (set_attr "length" "2,2,4,*,*")])
607
608(define_insn "*movqi_insn"
609 [(set (match_operand:QI 0 "nonimmediate_operand" "=x,da,x,d,mr")
610 (match_operand:QI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
611 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
612 "@
613 %0 = %1;
614 %0 = %1 (X);
615 %0 = %1 (X);
bbbc206e
BS
616 %0 = B %1 (X)%!
617 B %0 = %1%!"
0d4a78eb
BS
618 [(set_attr "type" "move,mvi,mvi,mcld,mcst")
619 (set_attr "length" "2,2,4,*,*")])
620
621(define_insn "*movsf_insn"
622 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,da,mr")
623 (match_operand:SF 1 "general_operand" "x,Fx,mr,da"))]
624 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
625 "@
626 %0 = %1;
627 #
bbbc206e
BS
628 %0 = %1%!
629 %0 = %1%!"
0d4a78eb
BS
630 [(set_attr "type" "move,*,mcld,mcst")])
631
632(define_insn_and_split "movdf_insn"
633 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,mx,r")
634 (match_operand:DF 1 "general_operand" "iFx,r,mx"))]
635 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
636 "#"
637 "reload_completed"
638 [(set (match_dup 2) (match_dup 3))
639 (set (match_dup 4) (match_dup 5))]
640{
641 rtx lo_half[2], hi_half[2];
642 split_di (operands, 2, lo_half, hi_half);
643
644 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
645 {
646 operands[2] = hi_half[0];
647 operands[3] = hi_half[1];
648 operands[4] = lo_half[0];
649 operands[5] = lo_half[1];
650 }
651 else
652 {
653 operands[2] = lo_half[0];
654 operands[3] = lo_half[1];
655 operands[4] = hi_half[0];
656 operands[5] = hi_half[1];
657 }
658})
659
75d8b2d0
BS
660;; Storing halfwords.
661(define_insn "*movsi_insv"
662 [(set (zero_extract:SI (match_operand 0 "register_operand" "+d,x")
663 (const_int 16)
664 (const_int 16))
665 (match_operand:SI 1 "nonmemory_operand" "d,n"))]
666 ""
667 "@
bbbc206e 668 %d0 = %h1 << 0%!
75d8b2d0
BS
669 %d0 = %1;"
670 [(set_attr "type" "dsp32,mvi")])
671
672(define_expand "insv"
673 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
674 (match_operand:SI 1 "immediate_operand" "")
675 (match_operand:SI 2 "immediate_operand" ""))
676 (match_operand:SI 3 "nonmemory_operand" ""))]
677 ""
678{
679 if (INTVAL (operands[1]) != 16 || INTVAL (operands[2]) != 16)
680 FAIL;
681
682 /* From mips.md: insert_bit_field doesn't verify that our source
683 matches the predicate, so check it again here. */
684 if (! register_operand (operands[0], VOIDmode))
685 FAIL;
686})
687
0d4a78eb
BS
688;; This is the main "hook" for PIC code. When generating
689;; PIC, movsi is responsible for determining when the source address
690;; needs PIC relocation and appropriately calling legitimize_pic_address
691;; to perform the actual relocation.
692
693(define_expand "movsi"
694 [(set (match_operand:SI 0 "nonimmediate_operand" "")
695 (match_operand:SI 1 "general_operand" ""))]
696 ""
d6f6753e
BS
697{
698 if (expand_move (operands, SImode))
699 DONE;
700})
0d4a78eb
BS
701
702(define_expand "movv2hi"
703 [(set (match_operand:V2HI 0 "nonimmediate_operand" "")
704 (match_operand:V2HI 1 "general_operand" ""))]
705 ""
706 "expand_move (operands, V2HImode);")
707
708(define_expand "movdi"
709 [(set (match_operand:DI 0 "nonimmediate_operand" "")
710 (match_operand:DI 1 "general_operand" ""))]
711 ""
712 "expand_move (operands, DImode);")
713
714(define_expand "movsf"
715 [(set (match_operand:SF 0 "nonimmediate_operand" "")
716 (match_operand:SF 1 "general_operand" ""))]
717 ""
718 "expand_move (operands, SFmode);")
719
720(define_expand "movdf"
721 [(set (match_operand:DF 0 "nonimmediate_operand" "")
722 (match_operand:DF 1 "general_operand" ""))]
723 ""
724 "expand_move (operands, DFmode);")
725
726(define_expand "movhi"
727 [(set (match_operand:HI 0 "nonimmediate_operand" "")
728 (match_operand:HI 1 "general_operand" ""))]
729 ""
730 "expand_move (operands, HImode);")
731
732(define_expand "movqi"
733 [(set (match_operand:QI 0 "nonimmediate_operand" "")
734 (match_operand:QI 1 "general_operand" ""))]
735 ""
736 " expand_move (operands, QImode); ")
737
738;; Some define_splits to break up SI/SFmode loads of immediate constants.
739
740(define_split
741 [(set (match_operand:SI 0 "register_operand" "")
742 (match_operand:SI 1 "symbolic_or_const_operand" ""))]
743 "reload_completed
744 /* Always split symbolic operands; split integer constants that are
745 too large for a single instruction. */
746 && (GET_CODE (operands[1]) != CONST_INT
747 || (INTVAL (operands[1]) < -32768
748 || INTVAL (operands[1]) >= 65536
749 || (INTVAL (operands[1]) >= 32768 && PREG_P (operands[0]))))"
750 [(set (match_dup 0) (high:SI (match_dup 1)))
751 (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))]
752{
753 if (GET_CODE (operands[1]) == CONST_INT
754 && split_load_immediate (operands))
755 DONE;
756 /* ??? Do something about TARGET_LOW_64K. */
757})
758
759(define_split
760 [(set (match_operand:SF 0 "register_operand" "")
761 (match_operand:SF 1 "immediate_operand" ""))]
762 "reload_completed"
763 [(set (match_dup 2) (high:SI (match_dup 3)))
764 (set (match_dup 2) (lo_sum:SI (match_dup 2) (match_dup 3)))]
765{
766 long values;
767 REAL_VALUE_TYPE value;
768
3b9dd769 769 gcc_assert (GET_CODE (operands[1]) == CONST_DOUBLE);
0d4a78eb
BS
770
771 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
772 REAL_VALUE_TO_TARGET_SINGLE (value, values);
773
774 operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0]));
775 operands[3] = GEN_INT (trunc_int_for_mode (values, SImode));
776 if (values >= -32768 && values < 65536)
777 {
778 emit_move_insn (operands[2], operands[3]);
779 DONE;
780 }
781 if (split_load_immediate (operands + 2))
782 DONE;
783})
784
785;; Sadly, this can't be a proper named movstrict pattern, since the compiler
786;; expects to be able to use registers for operand 1.
787;; Note that the asm instruction is defined by the manual to take an unsigned
788;; constant, but it doesn't matter to the assembler, and the compiler only
789;; deals with sign-extended constants. Hence "Ksh".
75d8b2d0 790(define_insn "movstricthi_1"
0d4a78eb
BS
791 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+x"))
792 (match_operand:HI 1 "immediate_operand" "Ksh"))]
793 ""
794 "%h0 = %1;"
795 [(set_attr "type" "mvi")
796 (set_attr "length" "4")])
797
798;; Sign and zero extensions
799
c4963a0a 800(define_insn_and_split "extendhisi2"
0d4a78eb
BS
801 [(set (match_operand:SI 0 "register_operand" "=d, d")
802 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
803 ""
804 "@
805 %0 = %h1 (X);
bbbc206e 806 %0 = W %h1 (X)%!"
c4963a0a
BS
807 "reload_completed && bfin_dsp_memref_p (operands[1])"
808 [(set (match_dup 2) (match_dup 1))
809 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
810{
811 operands[2] = gen_lowpart (HImode, operands[0]);
812}
0d4a78eb
BS
813 [(set_attr "type" "alu0,mcld")])
814
c4963a0a 815(define_insn_and_split "zero_extendhisi2"
0d4a78eb
BS
816 [(set (match_operand:SI 0 "register_operand" "=d, d")
817 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
818 ""
819 "@
820 %0 = %h1 (Z);
bbbc206e 821 %0 = W %h1 (Z)%!"
c4963a0a
BS
822 "reload_completed && bfin_dsp_memref_p (operands[1])"
823 [(set (match_dup 2) (match_dup 1))
824 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
825{
826 operands[2] = gen_lowpart (HImode, operands[0]);
827}
0d4a78eb
BS
828 [(set_attr "type" "alu0,mcld")])
829
830(define_insn "zero_extendbisi2"
831 [(set (match_operand:SI 0 "register_operand" "=d")
832 (zero_extend:SI (match_operand:BI 1 "nonimmediate_operand" "C")))]
833 ""
834 "%0 = %1;"
835 [(set_attr "type" "compare")])
836
837(define_insn "extendqihi2"
838 [(set (match_operand:HI 0 "register_operand" "=d, d")
839 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
840 ""
841 "@
bbbc206e 842 %0 = B %1 (X)%!
0d4a78eb
BS
843 %0 = %T1 (X);"
844 [(set_attr "type" "mcld,alu0")])
845
846(define_insn "extendqisi2"
847 [(set (match_operand:SI 0 "register_operand" "=d, d")
848 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
849 ""
850 "@
bbbc206e 851 %0 = B %1 (X)%!
0d4a78eb
BS
852 %0 = %T1 (X);"
853 [(set_attr "type" "mcld,alu0")])
854
855
856(define_insn "zero_extendqihi2"
857 [(set (match_operand:HI 0 "register_operand" "=d, d")
858 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
859 ""
860 "@
bbbc206e 861 %0 = B %1 (Z)%!
0d4a78eb
BS
862 %0 = %T1 (Z);"
863 [(set_attr "type" "mcld,alu0")])
864
865
866(define_insn "zero_extendqisi2"
867 [(set (match_operand:SI 0 "register_operand" "=d, d")
868 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
869 ""
870 "@
bbbc206e 871 %0 = B %1 (Z)%!
0d4a78eb
BS
872 %0 = %T1 (Z);"
873 [(set_attr "type" "mcld,alu0")])
874
875;; DImode logical operations
876
877(define_code_macro any_logical [and ior xor])
878(define_code_attr optab [(and "and")
879 (ior "ior")
880 (xor "xor")])
881(define_code_attr op [(and "&")
882 (ior "|")
883 (xor "^")])
884(define_code_attr high_result [(and "0")
885 (ior "%H1")
886 (xor "%H1")])
887
888(define_insn "<optab>di3"
889 [(set (match_operand:DI 0 "register_operand" "=d")
890 (any_logical:DI (match_operand:DI 1 "register_operand" "0")
891 (match_operand:DI 2 "register_operand" "d")))]
892 ""
893 "%0 = %1 <op> %2;\\n\\t%H0 = %H1 <op> %H2;"
b03149e1
JZ
894 [(set_attr "length" "4")
895 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
896
897(define_insn "*<optab>di_zesidi_di"
898 [(set (match_operand:DI 0 "register_operand" "=d")
899 (any_logical:DI (zero_extend:DI
900 (match_operand:SI 2 "register_operand" "d"))
901 (match_operand:DI 1 "register_operand" "d")))]
902 ""
903 "%0 = %1 <op> %2;\\n\\t%H0 = <high_result>;"
b03149e1
JZ
904 [(set_attr "length" "4")
905 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
906
907(define_insn "*<optab>di_sesdi_di"
908 [(set (match_operand:DI 0 "register_operand" "=d")
909 (any_logical:DI (sign_extend:DI
910 (match_operand:SI 2 "register_operand" "d"))
911 (match_operand:DI 1 "register_operand" "0")))
912 (clobber (match_scratch:SI 3 "=&d"))]
913 ""
914 "%0 = %1 <op> %2;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 <op> %3;"
b03149e1
JZ
915 [(set_attr "length" "8")
916 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
917
918(define_insn "negdi2"
919 [(set (match_operand:DI 0 "register_operand" "=d")
920 (neg:DI (match_operand:DI 1 "register_operand" "d")))
921 (clobber (match_scratch:SI 2 "=&d"))
922 (clobber (reg:CC REG_CC))]
923 ""
924 "%2 = 0; %2 = %2 - %1; cc = ac0; cc = !cc; %2 = cc;\\n\\t%0 = -%1; %H0 = -%H1; %H0 = %H0 - %2;"
b03149e1
JZ
925 [(set_attr "length" "16")
926 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
927
928(define_insn "one_cmpldi2"
929 [(set (match_operand:DI 0 "register_operand" "=d")
930 (not:DI (match_operand:DI 1 "register_operand" "d")))]
931 ""
932 "%0 = ~%1;\\n\\t%H0 = ~%H1;"
b03149e1
JZ
933 [(set_attr "length" "4")
934 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
935
936;; DImode zero and sign extend patterns
937
938(define_insn_and_split "zero_extendsidi2"
939 [(set (match_operand:DI 0 "register_operand" "=d")
940 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
941 ""
942 "#"
943 "reload_completed"
944 [(set (match_dup 3) (const_int 0))]
945{
946 split_di (operands, 1, operands + 2, operands + 3);
947 if (REGNO (operands[0]) != REGNO (operands[1]))
948 emit_move_insn (operands[2], operands[1]);
949})
950
951(define_insn "zero_extendqidi2"
952 [(set (match_operand:DI 0 "register_operand" "=d")
953 (zero_extend:DI (match_operand:QI 1 "register_operand" "d")))]
954 ""
955 "%0 = %T1 (Z);\\n\\t%H0 = 0;"
b03149e1
JZ
956 [(set_attr "length" "4")
957 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
958
959(define_insn "zero_extendhidi2"
960 [(set (match_operand:DI 0 "register_operand" "=d")
961 (zero_extend:DI (match_operand:HI 1 "register_operand" "d")))]
962 ""
963 "%0 = %h1 (Z);\\n\\t%H0 = 0;"
b03149e1
JZ
964 [(set_attr "length" "4")
965 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
966
967(define_insn_and_split "extendsidi2"
968 [(set (match_operand:DI 0 "register_operand" "=d")
969 (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))]
970 ""
971 "#"
972 "reload_completed"
973 [(set (match_dup 3) (match_dup 1))
974 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
975{
976 split_di (operands, 1, operands + 2, operands + 3);
977 if (REGNO (operands[0]) != REGNO (operands[1]))
978 emit_move_insn (operands[2], operands[1]);
979})
980
981(define_insn_and_split "extendqidi2"
982 [(set (match_operand:DI 0 "register_operand" "=d")
983 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
984 ""
985 "#"
986 "reload_completed"
987 [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
988 (set (match_dup 3) (sign_extend:SI (match_dup 1)))
989 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
990{
991 split_di (operands, 1, operands + 2, operands + 3);
992})
993
994(define_insn_and_split "extendhidi2"
995 [(set (match_operand:DI 0 "register_operand" "=d")
996 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
997 ""
998 "#"
999 "reload_completed"
1000 [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
1001 (set (match_dup 3) (sign_extend:SI (match_dup 1)))
1002 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
1003{
1004 split_di (operands, 1, operands + 2, operands + 3);
1005})
1006
1007;; DImode arithmetic operations
1008
2889abed
BS
1009(define_insn "add_with_carry"
1010 [(set (match_operand:SI 0 "register_operand" "=d,d")
1011 (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
1012 (match_operand:SI 2 "nonmemory_operand" "Ks7,d")))
1013 (set (match_operand:SI 3 "register_operand" "=d,d")
1014 (truncate:SI
1015 (lshiftrt:DI (plus:DI (zero_extend:DI (match_dup 1))
1016 (zero_extend:DI (match_dup 2)))
1017 (const_int 32))))
1018 (clobber (reg:CC 34))]
1019 ""
1020 "@
1021 %0 += %2; cc = ac0; %3 = cc;
1022 %0 = %0 + %2; cc = ac0; %3 = cc;"
1023 [(set_attr "type" "alu0")
1024 (set_attr "length" "6")
1025 (set_attr "seq_insns" "multi")])
1026
0d4a78eb
BS
1027(define_insn "adddi3"
1028 [(set (match_operand:DI 0 "register_operand" "=&d,&d,&d")
1029 (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
1030 (match_operand:DI 2 "nonmemory_operand" "Kn7,Ks7,d")))
1031 (clobber (match_scratch:SI 3 "=&d,&d,&d"))
1032 (clobber (reg:CC 34))]
1033 ""
1034 "@
1035 %0 += %2; cc = ac0; %3 = cc; %H0 += -1; %H0 = %H0 + %3;
1036 %0 += %2; cc = ac0; %3 = cc; %H0 = %H0 + %3;
1037 %0 = %0 + %2; cc = ac0; %3 = cc; %H0 = %H0 + %H2; %H0 = %H0 + %3;"
1038 [(set_attr "type" "alu0")
b03149e1
JZ
1039 (set_attr "length" "10,8,10")
1040 (set_attr "seq_insns" "multi,multi,multi")])
0d4a78eb
BS
1041
1042(define_insn "subdi3"
1043 [(set (match_operand:DI 0 "register_operand" "=&d")
1044 (minus:DI (match_operand:DI 1 "register_operand" "0")
1045 (match_operand:DI 2 "register_operand" "d")))
1046 (clobber (reg:CC 34))]
1047 ""
1048 "%0 = %1-%2;\\n\\tcc = ac0;\\n\\t%H0 = %H1-%H2;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
b03149e1
JZ
1049 [(set_attr "length" "10")
1050 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
1051
1052(define_insn "*subdi_di_zesidi"
1053 [(set (match_operand:DI 0 "register_operand" "=d")
1054 (minus:DI (match_operand:DI 1 "register_operand" "0")
1055 (zero_extend:DI
1056 (match_operand:SI 2 "register_operand" "d"))))
1057 (clobber (match_scratch:SI 3 "=&d"))
1058 (clobber (reg:CC 34))]
1059 ""
1060 "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%H0 = %H1 - %3;"
b03149e1
JZ
1061 [(set_attr "length" "10")
1062 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
1063
1064(define_insn "*subdi_zesidi_di"
1065 [(set (match_operand:DI 0 "register_operand" "=d")
1066 (minus:DI (zero_extend:DI
1067 (match_operand:SI 2 "register_operand" "d"))
1068 (match_operand:DI 1 "register_operand" "0")))
1069 (clobber (match_scratch:SI 3 "=&d"))
1070 (clobber (reg:CC 34))]
1071 ""
1072 "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%3 = -%3;\\n\\t%H0 = %3 - %H1"
b03149e1
JZ
1073 [(set_attr "length" "12")
1074 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
1075
1076(define_insn "*subdi_di_sesidi"
1077 [(set (match_operand:DI 0 "register_operand" "=d")
1078 (minus:DI (match_operand:DI 1 "register_operand" "0")
1079 (sign_extend:DI
1080 (match_operand:SI 2 "register_operand" "d"))))
1081 (clobber (match_scratch:SI 3 "=&d"))
1082 (clobber (reg:CC 34))]
1083 ""
1084 "%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:"
b03149e1
JZ
1085 [(set_attr "length" "14")
1086 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
1087
1088(define_insn "*subdi_sesidi_di"
1089 [(set (match_operand:DI 0 "register_operand" "=d")
1090 (minus:DI (sign_extend:DI
1091 (match_operand:SI 2 "register_operand" "d"))
1092 (match_operand:DI 1 "register_operand" "0")))
1093 (clobber (match_scratch:SI 3 "=&d"))
1094 (clobber (reg:CC 34))]
1095 ""
1096 "%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:"
b03149e1
JZ
1097 [(set_attr "length" "14")
1098 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
1099
1100;; Combined shift/add instructions
1101
1102(define_insn ""
1103 [(set (match_operand:SI 0 "register_operand" "=a,d")
1104 (ashift:SI (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
1105 (match_operand:SI 2 "register_operand" "a,d"))
1106 (match_operand:SI 3 "pos_scale_operand" "P1P2,P1P2")))]
1107 ""
1108 "%0 = (%0 + %2) << %3;" /* "shadd %0,%2,%3;" */
1109 [(set_attr "type" "alu0")])
1110
1111(define_insn ""
1112 [(set (match_operand:SI 0 "register_operand" "=a")
1113 (plus:SI (match_operand:SI 1 "register_operand" "a")
1114 (mult:SI (match_operand:SI 2 "register_operand" "a")
1115 (match_operand:SI 3 "scale_by_operand" "i"))))]
1116 ""
1117 "%0 = %1 + (%2 << %X3);"
1118 [(set_attr "type" "alu0")])
1119
1120(define_insn ""
1121 [(set (match_operand:SI 0 "register_operand" "=a")
1122 (plus:SI (match_operand:SI 1 "register_operand" "a")
1123 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1124 (match_operand:SI 3 "pos_scale_operand" "i"))))]
1125 ""
1126 "%0 = %1 + (%2 << %3);"
1127 [(set_attr "type" "alu0")])
1128
1129(define_insn ""
1130 [(set (match_operand:SI 0 "register_operand" "=a")
1131 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "a")
1132 (match_operand:SI 2 "scale_by_operand" "i"))
1133 (match_operand:SI 3 "register_operand" "a")))]
1134 ""
1135 "%0 = %3 + (%1 << %X2);"
1136 [(set_attr "type" "alu0")])
1137
1138(define_insn ""
1139 [(set (match_operand:SI 0 "register_operand" "=a")
1140 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "a")
1141 (match_operand:SI 2 "pos_scale_operand" "i"))
1142 (match_operand:SI 3 "register_operand" "a")))]
1143 ""
1144 "%0 = %3 + (%1 << %2);"
1145 [(set_attr "type" "alu0")])
1146
1147(define_insn "mulhisi3"
1148 [(set (match_operand:SI 0 "register_operand" "=d")
1149 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%d"))
1150 (sign_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
1151 ""
bbbc206e 1152 "%0 = %h1 * %h2 (IS)%!"
0d4a78eb
BS
1153 [(set_attr "type" "dsp32")])
1154
1155(define_insn "umulhisi3"
1156 [(set (match_operand:SI 0 "register_operand" "=d")
1157 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%d"))
1158 (zero_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
1159 ""
bbbc206e 1160 "%0 = %h1 * %h2 (FU)%!"
0d4a78eb
BS
1161 [(set_attr "type" "dsp32")])
1162
8b44057d
BS
1163(define_insn "usmulhisi3"
1164 [(set (match_operand:SI 0 "register_operand" "=W")
1165 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "W"))
1166 (sign_extend:SI (match_operand:HI 2 "register_operand" "W"))))]
1167 ""
bbbc206e 1168 "%0 = %h2 * %h1 (IS,M)%!"
8b44057d
BS
1169 [(set_attr "type" "dsp32")])
1170
0d4a78eb
BS
1171;; The processor also supports ireg += mreg or ireg -= mreg, but these
1172;; are unusable if we don't ensure that the corresponding lreg is zero.
1173;; The same applies to the add/subtract constant versions involving
1174;; iregs
1175
1176(define_insn "addsi3"
1177 [(set (match_operand:SI 0 "register_operand" "=ad,a,d")
1178 (plus:SI (match_operand:SI 1 "register_operand" "%0, a,d")
1179 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7, a,d")))]
1180 ""
1181 "@
1182 %0 += %2;
1183 %0 = %1 + %2;
1184 %0 = %1 + %2;"
1185 [(set_attr "type" "alu0")
1186 (set_attr "length" "2,2,2")])
1187
75d8b2d0
BS
1188(define_insn "ssaddsi3"
1189 [(set (match_operand:SI 0 "register_operand" "=d")
1190 (ss_plus:SI (match_operand:SI 1 "register_operand" "d")
1191 (match_operand:SI 2 "register_operand" "d")))]
1192 ""
bbbc206e 1193 "%0 = %1 + %2 (S)%!"
75d8b2d0
BS
1194 [(set_attr "type" "dsp32")])
1195
d4e85050 1196(define_insn "subsi3"
0d4a78eb
BS
1197 [(set (match_operand:SI 0 "register_operand" "=da,d,a")
1198 (minus:SI (match_operand:SI 1 "register_operand" "0,d,0")
d4e85050
BS
1199 (match_operand:SI 2 "reg_or_neg7bit_operand" "KN7,d,a")))]
1200 ""
0d4a78eb
BS
1201{
1202 static const char *const strings_subsi3[] = {
1203 "%0 += -%2;",
1204 "%0 = %1 - %2;",
1205 "%0 -= %2;",
1206 };
1207
1208 if (CONSTANT_P (operands[2]) && INTVAL (operands[2]) < 0) {
1209 rtx tmp_op = operands[2];
1210 operands[2] = GEN_INT (-INTVAL (operands[2]));
1211 output_asm_insn ("%0 += %2;", operands);
1212 operands[2] = tmp_op;
1213 return "";
1214 }
1215
1216 return strings_subsi3[which_alternative];
1217}
1218 [(set_attr "type" "alu0")])
1219
75d8b2d0
BS
1220(define_insn "sssubsi3"
1221 [(set (match_operand:SI 0 "register_operand" "=d")
1222 (ss_minus:SI (match_operand:SI 1 "register_operand" "d")
1223 (match_operand:SI 2 "register_operand" "d")))]
1224 ""
bbbc206e 1225 "%0 = %1 - %2 (S)%!"
75d8b2d0
BS
1226 [(set_attr "type" "dsp32")])
1227
3efd5670
BS
1228;; Accumulator addition
1229
1230(define_insn "sum_of_accumulators"
1231 [(set (match_operand:SI 0 "register_operand" "=d")
1232 (ss_truncate:SI
1233 (ss_plus:PDI (match_operand:PDI 2 "register_operand" "1")
1234 (match_operand:PDI 3 "register_operand" "B"))))
1235 (set (match_operand:PDI 1 "register_operand" "=A")
1236 (ss_plus:PDI (match_dup 2) (match_dup 3)))]
1237 ""
1238 "%0 = (A0 += A1)%!"
1239 [(set_attr "type" "dsp32")])
1240
0d4a78eb
BS
1241;; Bit test instructions
1242
1243(define_insn "*not_bittst"
4729dc92 1244 [(set (match_operand:BI 0 "register_operand" "=C")
0d4a78eb
BS
1245 (eq:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1246 (const_int 1)
1247 (match_operand:SI 2 "immediate_operand" "Ku5"))
1248 (const_int 0)))]
1249 ""
1250 "cc = !BITTST (%1,%2);"
1251 [(set_attr "type" "alu0")])
1252
1253(define_insn "*bittst"
4729dc92 1254 [(set (match_operand:BI 0 "register_operand" "=C")
0d4a78eb
BS
1255 (ne:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1256 (const_int 1)
1257 (match_operand:SI 2 "immediate_operand" "Ku5"))
1258 (const_int 0)))]
1259 ""
1260 "cc = BITTST (%1,%2);"
1261 [(set_attr "type" "alu0")])
1262
1263(define_insn_and_split "*bit_extract"
1264 [(set (match_operand:SI 0 "register_operand" "=d")
1265 (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1266 (const_int 1)
1267 (match_operand:SI 2 "immediate_operand" "Ku5")))
1268 (clobber (reg:BI REG_CC))]
1269 ""
1270 "#"
1271 ""
1272 [(set (reg:BI REG_CC)
1273 (ne:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1274 (const_int 0)))
1275 (set (match_dup 0)
1276 (ne:SI (reg:BI REG_CC) (const_int 0)))])
1277
1278(define_insn_and_split "*not_bit_extract"
1279 [(set (match_operand:SI 0 "register_operand" "=d")
1280 (zero_extract:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1281 (const_int 1)
1282 (match_operand:SI 2 "immediate_operand" "Ku5")))
1283 (clobber (reg:BI REG_CC))]
1284 ""
1285 "#"
1286 ""
1287 [(set (reg:BI REG_CC)
1288 (eq:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1289 (const_int 0)))
1290 (set (match_dup 0)
1291 (ne:SI (reg:BI REG_CC) (const_int 0)))])
1292
1293(define_insn "*andsi_insn"
1294 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
1295 (and:SI (match_operand:SI 1 "register_operand" "%0,d,d,d")
1296 (match_operand:SI 2 "rhs_andsi3_operand" "L,M1,M2,d")))]
1297 ""
1298 "@
1299 BITCLR (%0,%Y2);
1300 %0 = %T1 (Z);
1301 %0 = %h1 (Z);
1302 %0 = %1 & %2;"
1303 [(set_attr "type" "alu0")])
1304
1305(define_expand "andsi3"
1306 [(set (match_operand:SI 0 "register_operand" "")
1307 (and:SI (match_operand:SI 1 "register_operand" "")
1308 (match_operand:SI 2 "general_operand" "")))]
1309 ""
1310{
1311 if (highbits_operand (operands[2], SImode))
1312 {
1313 operands[2] = GEN_INT (exact_log2 (-INTVAL (operands[2])));
1314 emit_insn (gen_ashrsi3 (operands[0], operands[1], operands[2]));
1315 emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
1316 DONE;
1317 }
1318 if (! rhs_andsi3_operand (operands[2], SImode))
1319 operands[2] = force_reg (SImode, operands[2]);
1320})
1321
1322(define_insn "iorsi3"
1323 [(set (match_operand:SI 0 "register_operand" "=d,d")
1324 (ior:SI (match_operand:SI 1 "register_operand" "%0,d")
1325 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1326 ""
1327 "@
1328 BITSET (%0, %X2);
1329 %0 = %1 | %2;"
1330 [(set_attr "type" "alu0")])
1331
1332(define_insn "xorsi3"
1333 [(set (match_operand:SI 0 "register_operand" "=d,d")
1334 (xor:SI (match_operand:SI 1 "register_operand" "%0,d")
1335 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1336 ""
1337 "@
1338 BITTGL (%0, %X2);
1339 %0 = %1 ^ %2;"
1340 [(set_attr "type" "alu0")])
1341
1342(define_insn "smaxsi3"
1343 [(set (match_operand:SI 0 "register_operand" "=d")
1344 (smax:SI (match_operand:SI 1 "register_operand" "d")
1345 (match_operand:SI 2 "register_operand" "d")))]
1346 ""
bbbc206e 1347 "%0 = max(%1,%2)%!"
0d4a78eb
BS
1348 [(set_attr "type" "dsp32")])
1349
1350(define_insn "sminsi3"
1351 [(set (match_operand:SI 0 "register_operand" "=d")
1352 (smin:SI (match_operand:SI 1 "register_operand" "d")
1353 (match_operand:SI 2 "register_operand" "d")))]
1354 ""
bbbc206e 1355 "%0 = min(%1,%2)%!"
0d4a78eb
BS
1356 [(set_attr "type" "dsp32")])
1357
1358(define_insn "abssi2"
1359 [(set (match_operand:SI 0 "register_operand" "=d")
75d8b2d0 1360 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
0d4a78eb 1361 ""
bbbc206e 1362 "%0 = abs %1%!"
0d4a78eb
BS
1363 [(set_attr "type" "dsp32")])
1364
26c5953d
BS
1365(define_insn "ssabssi2"
1366 [(set (match_operand:SI 0 "register_operand" "=d")
1367 (ss_abs:SI (match_operand:SI 1 "register_operand" "d")))]
1368 ""
1369 "%0 = abs %1%!"
1370 [(set_attr "type" "dsp32")])
1371
0d4a78eb
BS
1372(define_insn "negsi2"
1373 [(set (match_operand:SI 0 "register_operand" "=d")
75d8b2d0 1374 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
0d4a78eb 1375 ""
75d8b2d0 1376 "%0 = -%1;"
0d4a78eb
BS
1377 [(set_attr "type" "alu0")])
1378
75d8b2d0
BS
1379(define_insn "ssnegsi2"
1380 [(set (match_operand:SI 0 "register_operand" "=d")
1381 (ss_neg:SI (match_operand:SI 1 "register_operand" "d")))]
1382 ""
bbbc206e 1383 "%0 = -%1 (S)%!"
75d8b2d0
BS
1384 [(set_attr "type" "dsp32")])
1385
0d4a78eb
BS
1386(define_insn "one_cmplsi2"
1387 [(set (match_operand:SI 0 "register_operand" "=d")
75d8b2d0 1388 (not:SI (match_operand:SI 1 "register_operand" "d")))]
0d4a78eb 1389 ""
75d8b2d0 1390 "%0 = ~%1;"
0d4a78eb
BS
1391 [(set_attr "type" "alu0")])
1392
75d8b2d0
BS
1393(define_insn "signbitssi2"
1394 [(set (match_operand:HI 0 "register_operand" "=d")
1395 (if_then_else:HI
1396 (lt (match_operand:SI 1 "register_operand" "d") (const_int 0))
1397 (clz:HI (not:SI (match_dup 1)))
1398 (clz:HI (match_dup 1))))]
1399 ""
bbbc206e 1400 "%h0 = signbits %1%!"
75d8b2d0
BS
1401 [(set_attr "type" "dsp32")])
1402
26c5953d
BS
1403(define_insn "ssroundsi2"
1404 [(set (match_operand:HI 0 "register_operand" "=d")
1405 (truncate:HI
1406 (lshiftrt:SI (ss_plus:SI (match_operand:SI 1 "register_operand" "d")
1407 (const_int 32768))
1408 (const_int 16))))]
1409 ""
1410 "%h0 = %1 (RND)%!"
1411 [(set_attr "type" "dsp32")])
1412
75d8b2d0
BS
1413(define_insn "smaxhi3"
1414 [(set (match_operand:HI 0 "register_operand" "=d")
1415 (smax:HI (match_operand:HI 1 "register_operand" "d")
1416 (match_operand:HI 2 "register_operand" "d")))]
1417 ""
bbbc206e 1418 "%0 = max(%1,%2) (V)%!"
75d8b2d0
BS
1419 [(set_attr "type" "dsp32")])
1420
1421(define_insn "sminhi3"
1422 [(set (match_operand:HI 0 "register_operand" "=d")
1423 (smin:HI (match_operand:HI 1 "register_operand" "d")
1424 (match_operand:HI 2 "register_operand" "d")))]
1425 ""
bbbc206e 1426 "%0 = min(%1,%2) (V)%!"
75d8b2d0
BS
1427 [(set_attr "type" "dsp32")])
1428
1429(define_insn "abshi2"
1430 [(set (match_operand:HI 0 "register_operand" "=d")
1431 (abs:HI (match_operand:HI 1 "register_operand" "d")))]
1432 ""
bbbc206e 1433 "%0 = abs %1 (V)%!"
75d8b2d0
BS
1434 [(set_attr "type" "dsp32")])
1435
1436(define_insn "neghi2"
1437 [(set (match_operand:HI 0 "register_operand" "=d")
1438 (neg:HI (match_operand:HI 1 "register_operand" "d")))]
1439 ""
1440 "%0 = -%1;"
bbbc206e 1441 [(set_attr "type" "alu0")])
75d8b2d0
BS
1442
1443(define_insn "ssneghi2"
1444 [(set (match_operand:HI 0 "register_operand" "=d")
1445 (ss_neg:HI (match_operand:HI 1 "register_operand" "d")))]
1446 ""
bbbc206e 1447 "%0 = -%1 (V)%!"
75d8b2d0
BS
1448 [(set_attr "type" "dsp32")])
1449
1450(define_insn "signbitshi2"
1451 [(set (match_operand:HI 0 "register_operand" "=d")
1452 (if_then_else:HI
1453 (lt (match_operand:HI 1 "register_operand" "d") (const_int 0))
1454 (clz:HI (not:HI (match_dup 1)))
1455 (clz:HI (match_dup 1))))]
1456 ""
bbbc206e 1457 "%h0 = signbits %h1%!"
75d8b2d0
BS
1458 [(set_attr "type" "dsp32")])
1459
0d4a78eb
BS
1460(define_insn "mulsi3"
1461 [(set (match_operand:SI 0 "register_operand" "=d")
1462 (mult:SI (match_operand:SI 1 "register_operand" "%0")
1463 (match_operand:SI 2 "register_operand" "d")))]
1464 ""
75d8b2d0 1465 "%0 *= %2;"
0d4a78eb
BS
1466 [(set_attr "type" "mult")])
1467
01e7cd6e 1468(define_expand "umulsi3_highpart"
3fbee523
BS
1469 [(parallel
1470 [(set (match_operand:SI 0 "register_operand" "")
1471 (truncate:SI
1472 (lshiftrt:DI
1473 (mult:DI (zero_extend:DI
1474 (match_operand:SI 1 "nonimmediate_operand" ""))
1475 (zero_extend:DI
1476 (match_operand:SI 2 "register_operand" "")))
1477 (const_int 32))))
1478 (clobber (reg:PDI REG_A0))
1479 (clobber (reg:PDI REG_A1))])]
01e7cd6e
BS
1480 ""
1481{
3fbee523
BS
1482 if (!optimize_size)
1483 {
1484 rtx a1reg = gen_rtx_REG (PDImode, REG_A1);
1485 rtx a0reg = gen_rtx_REG (PDImode, REG_A0);
1486 emit_insn (gen_flag_macinit1hi (a1reg,
1487 gen_lowpart (HImode, operands[1]),
1488 gen_lowpart (HImode, operands[2]),
1489 GEN_INT (MACFLAG_FU)));
1490 emit_insn (gen_lshrpdi3 (a1reg, a1reg, GEN_INT (16)));
1491 emit_insn (gen_flag_mul_macv2hi_parts_acconly (a0reg, a1reg,
1492 gen_lowpart (V2HImode, operands[1]),
1493 gen_lowpart (V2HImode, operands[2]),
1494 const1_rtx, const1_rtx,
1495 const1_rtx, const0_rtx, a1reg,
1496 const0_rtx, GEN_INT (MACFLAG_FU),
1497 GEN_INT (MACFLAG_FU)));
1498 emit_insn (gen_flag_machi_parts_acconly (a1reg,
1499 gen_lowpart (V2HImode, operands[2]),
1500 gen_lowpart (V2HImode, operands[1]),
1501 const1_rtx, const0_rtx,
1502 a1reg, const0_rtx, GEN_INT (MACFLAG_FU)));
1503 emit_insn (gen_lshrpdi3 (a1reg, a1reg, GEN_INT (16)));
1504 emit_insn (gen_sum_of_accumulators (operands[0], a0reg, a0reg, a1reg));
1505 }
1506 else
1507 {
1508 rtx umulsi3_highpart_libfunc
1509 = init_one_libfunc ("__umulsi3_highpart");
01e7cd6e 1510
3fbee523
BS
1511 emit_library_call_value (umulsi3_highpart_libfunc,
1512 operands[0], LCT_NORMAL, SImode,
1513 2, operands[1], SImode, operands[2], SImode);
1514 }
01e7cd6e
BS
1515 DONE;
1516})
1517
1518(define_expand "smulsi3_highpart"
3fbee523
BS
1519 [(parallel
1520 [(set (match_operand:SI 0 "register_operand" "")
1521 (truncate:SI
1522 (lshiftrt:DI
1523 (mult:DI (sign_extend:DI
1524 (match_operand:SI 1 "nonimmediate_operand" ""))
1525 (sign_extend:DI
1526 (match_operand:SI 2 "register_operand" "")))
1527 (const_int 32))))
1528 (clobber (reg:PDI REG_A0))
1529 (clobber (reg:PDI REG_A1))])]
01e7cd6e
BS
1530 ""
1531{
3fbee523
BS
1532 if (!optimize_size)
1533 {
1534 rtx a1reg = gen_rtx_REG (PDImode, REG_A1);
1535 rtx a0reg = gen_rtx_REG (PDImode, REG_A0);
1536 emit_insn (gen_flag_macinit1hi (a1reg,
1537 gen_lowpart (HImode, operands[1]),
1538 gen_lowpart (HImode, operands[2]),
1539 GEN_INT (MACFLAG_FU)));
1540 emit_insn (gen_lshrpdi3 (a1reg, a1reg, GEN_INT (16)));
1541 emit_insn (gen_flag_mul_macv2hi_parts_acconly (a0reg, a1reg,
1542 gen_lowpart (V2HImode, operands[1]),
1543 gen_lowpart (V2HImode, operands[2]),
1544 const1_rtx, const1_rtx,
1545 const1_rtx, const0_rtx, a1reg,
1546 const0_rtx, GEN_INT (MACFLAG_IS),
1547 GEN_INT (MACFLAG_IS_M)));
1548 emit_insn (gen_flag_machi_parts_acconly (a1reg,
1549 gen_lowpart (V2HImode, operands[2]),
1550 gen_lowpart (V2HImode, operands[1]),
1551 const1_rtx, const0_rtx,
1552 a1reg, const0_rtx, GEN_INT (MACFLAG_IS_M)));
1553 emit_insn (gen_ashrpdi3 (a1reg, a1reg, GEN_INT (16)));
1554 emit_insn (gen_sum_of_accumulators (operands[0], a0reg, a0reg, a1reg));
1555 }
1556 else
1557 {
1558 rtx smulsi3_highpart_libfunc
1559 = init_one_libfunc ("__smulsi3_highpart");
01e7cd6e 1560
3fbee523
BS
1561 emit_library_call_value (smulsi3_highpart_libfunc,
1562 operands[0], LCT_NORMAL, SImode,
1563 2, operands[1], SImode, operands[2], SImode);
1564 }
01e7cd6e
BS
1565 DONE;
1566})
1567
0d4a78eb
BS
1568(define_expand "ashlsi3"
1569 [(set (match_operand:SI 0 "register_operand" "")
1570 (ashift:SI (match_operand:SI 1 "register_operand" "")
1571 (match_operand:SI 2 "nonmemory_operand" "")))]
1572 ""
1573{
1574 if (GET_CODE (operands[2]) == CONST_INT
1575 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1576 {
1577 emit_insn (gen_movsi (operands[0], const0_rtx));
1578 DONE;
1579 }
1580})
1581
1582(define_insn_and_split "*ashlsi3_insn"
bbbc206e
BS
1583 [(set (match_operand:SI 0 "register_operand" "=d,d,a,a,a")
1584 (ashift:SI (match_operand:SI 1 "register_operand" "0,d,a,a,a")
1585 (match_operand:SI 2 "nonmemory_operand" "dKu5,Ku5,P1,P2,?P3P4")))]
0d4a78eb
BS
1586 ""
1587 "@
1588 %0 <<= %2;
bbbc206e 1589 %0 = %1 << %2%!
0d4a78eb
BS
1590 %0 = %1 + %1;
1591 %0 = %1 << %2;
1592 #"
1593 "PREG_P (operands[0]) && INTVAL (operands[2]) > 2"
1594 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
1595 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
1596 "operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
bbbc206e 1597 [(set_attr "type" "shft,dsp32,shft,shft,*")])
0d4a78eb
BS
1598
1599(define_insn "ashrsi3"
bbbc206e
BS
1600 [(set (match_operand:SI 0 "register_operand" "=d,d")
1601 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
1602 (match_operand:SI 2 "nonmemory_operand" "dKu5,Ku5")))]
0d4a78eb 1603 ""
bbbc206e
BS
1604 "@
1605 %0 >>>= %2;
1606 %0 = %1 >>> %2%!"
1607 [(set_attr "type" "shft,dsp32")])
0d4a78eb 1608
97130915
BS
1609(define_insn "rotl16"
1610 [(set (match_operand:SI 0 "register_operand" "=d")
1611 (rotate:SI (match_operand:SI 1 "register_operand" "d")
1612 (const_int 16)))]
1613 ""
1614 "%0 = PACK (%h1, %d1)%!"
1615 [(set_attr "type" "dsp32")])
1616
1617(define_expand "rotlsi3"
1618 [(set (match_operand:SI 0 "register_operand" "")
1619 (rotate:SI (match_operand:SI 1 "register_operand" "")
1620 (match_operand:SI 2 "immediate_operand" "")))]
1621 ""
1622{
1623 if (INTVAL (operands[2]) != 16)
1624 FAIL;
1625})
1626
1627(define_expand "rotrsi3"
1628 [(set (match_operand:SI 0 "register_operand" "")
1629 (rotatert:SI (match_operand:SI 1 "register_operand" "")
1630 (match_operand:SI 2 "immediate_operand" "")))]
1631 ""
1632{
1633 if (INTVAL (operands[2]) != 16)
1634 FAIL;
1635 emit_insn (gen_rotl16 (operands[0], operands[1]));
1636 DONE;
1637})
1638
1639
49373252
BS
1640(define_insn "ror_one"
1641 [(set (match_operand:SI 0 "register_operand" "=d")
1642 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1643 (ashift:SI (zero_extend:SI (reg:BI REG_CC)) (const_int 31))))
1644 (set (reg:BI REG_CC)
1645 (zero_extract:BI (match_dup 1) (const_int 1) (const_int 0)))]
1646 ""
bbbc206e
BS
1647 "%0 = ROT %1 BY -1%!"
1648 [(set_attr "type" "dsp32")])
49373252
BS
1649
1650(define_insn "rol_one"
1651 [(set (match_operand:SI 0 "register_operand" "+d")
1652 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1653 (zero_extend:SI (reg:BI REG_CC))))
1654 (set (reg:BI REG_CC)
1655 (zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))]
1656 ""
bbbc206e
BS
1657 "%0 = ROT %1 BY 1%!"
1658 [(set_attr "type" "dsp32")])
49373252
BS
1659
1660(define_expand "lshrdi3"
1661 [(set (match_operand:DI 0 "register_operand" "")
1662 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1663 (match_operand:DI 2 "general_operand" "")))]
1664 ""
1665{
1666 rtx lo_half[2], hi_half[2];
1667
1668 if (operands[2] != const1_rtx)
1669 FAIL;
1670 if (! rtx_equal_p (operands[0], operands[1]))
1671 emit_move_insn (operands[0], operands[1]);
1672
1673 split_di (operands, 2, lo_half, hi_half);
1674
1675 emit_move_insn (bfin_cc_rtx, const0_rtx);
1676 emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1677 emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1678 DONE;
1679})
1680
1681(define_expand "ashrdi3"
1682 [(set (match_operand:DI 0 "register_operand" "")
1683 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1684 (match_operand:DI 2 "general_operand" "")))]
1685 ""
1686{
1687 rtx lo_half[2], hi_half[2];
1688
1689 if (operands[2] != const1_rtx)
1690 FAIL;
1691 if (! rtx_equal_p (operands[0], operands[1]))
1692 emit_move_insn (operands[0], operands[1]);
1693
1694 split_di (operands, 2, lo_half, hi_half);
1695
1696 emit_insn (gen_compare_lt (gen_rtx_REG (BImode, REG_CC),
1697 hi_half[1], const0_rtx));
1698 emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1699 emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1700 DONE;
1701})
1702
1703(define_expand "ashldi3"
1704 [(set (match_operand:DI 0 "register_operand" "")
1705 (ashift:DI (match_operand:DI 1 "register_operand" "")
1706 (match_operand:DI 2 "general_operand" "")))]
1707 ""
1708{
1709 rtx lo_half[2], hi_half[2];
1710
1711 if (operands[2] != const1_rtx)
1712 FAIL;
1713 if (! rtx_equal_p (operands[0], operands[1]))
1714 emit_move_insn (operands[0], operands[1]);
1715
1716 split_di (operands, 2, lo_half, hi_half);
1717
1718 emit_move_insn (bfin_cc_rtx, const0_rtx);
1719 emit_insn (gen_rol_one (lo_half[0], lo_half[0]));
1720 emit_insn (gen_rol_one (hi_half[0], hi_half[0]));
1721 DONE;
1722})
1723
0d4a78eb 1724(define_insn "lshrsi3"
bbbc206e
BS
1725 [(set (match_operand:SI 0 "register_operand" "=d,d,a")
1726 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d,a")
1727 (match_operand:SI 2 "nonmemory_operand" "dKu5,Ku5,P1P2")))]
0d4a78eb
BS
1728 ""
1729 "@
1730 %0 >>= %2;
bbbc206e 1731 %0 = %1 >> %2%!
0d4a78eb 1732 %0 = %1 >> %2;"
bbbc206e 1733 [(set_attr "type" "shft,dsp32,shft")])
0d4a78eb 1734
3efd5670
BS
1735(define_insn "lshrpdi3"
1736 [(set (match_operand:PDI 0 "register_operand" "=e")
1737 (lshiftrt:PDI (match_operand:PDI 1 "register_operand" "0")
1738 (match_operand:SI 2 "nonmemory_operand" "Ku5")))]
1739 ""
1740 "%0 = %1 >> %2%!"
1741 [(set_attr "type" "dsp32")])
1742
1743(define_insn "ashrpdi3"
1744 [(set (match_operand:PDI 0 "register_operand" "=e")
1745 (ashiftrt:PDI (match_operand:PDI 1 "register_operand" "0")
1746 (match_operand:SI 2 "nonmemory_operand" "Ku5")))]
1747 ""
1748 "%0 = %1 >>> %2%!"
1749 [(set_attr "type" "dsp32")])
1750
0d4a78eb
BS
1751;; A pattern to reload the equivalent of
1752;; (set (Dreg) (plus (FP) (large_constant)))
1753;; or
1754;; (set (dagreg) (plus (FP) (arbitrary_constant)))
1755;; using a scratch register
1756(define_expand "reload_insi"
1757 [(parallel [(set (match_operand:SI 0 "register_operand" "=w")
1758 (match_operand:SI 1 "fp_plus_const_operand" ""))
1759 (clobber (match_operand:SI 2 "register_operand" "=&a"))])]
1760 ""
1761{
1762 rtx fp_op = XEXP (operands[1], 0);
1763 rtx const_op = XEXP (operands[1], 1);
1764 rtx primary = operands[0];
1765 rtx scratch = operands[2];
1766
1767 emit_move_insn (scratch, const_op);
1768 emit_insn (gen_addsi3 (scratch, scratch, fp_op));
1769 emit_move_insn (primary, scratch);
1770 DONE;
1771})
1772
1773;; Jump instructions
1774
1775(define_insn "jump"
1776 [(set (pc)
1777 (label_ref (match_operand 0 "" "")))]
1778 ""
1779{
1780 if (get_attr_length (insn) == 2)
1781 return "jump.s %0;";
1782 else
1783 return "jump.l %0;";
1784}
1785 [(set_attr "type" "br")])
1786
1787(define_insn "indirect_jump"
1788 [(set (pc)
1789 (match_operand:SI 0 "register_operand" "a"))]
1790 ""
1791 "jump (%0);"
1792 [(set_attr "type" "misc")])
1793
1794(define_expand "tablejump"
1795 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1796 (use (label_ref (match_operand 1 "" "")))])]
1797 ""
1798{
1799 /* In PIC mode, the table entries are stored PC relative.
1800 Convert the relative address to an absolute address. */
1801 if (flag_pic)
1802 {
1803 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1804
1805 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1806 op1, NULL_RTX, 0, OPTAB_DIRECT);
1807 }
1808})
1809
1810(define_insn "*tablejump_internal"
1811 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1812 (use (label_ref (match_operand 1 "" "")))]
1813 ""
1814 "jump (%0);"
1815 [(set_attr "type" "misc")])
1816
b03149e1
JZ
1817;; Hardware loop
1818
1819; operand 0 is the loop count pseudo register
1820; operand 1 is the number of loop iterations or 0 if it is unknown
1821; operand 2 is the maximum number of loop iterations
1822; operand 3 is the number of levels of enclosed loops
1823; operand 4 is the label to jump to at the top of the loop
1824(define_expand "doloop_end"
1825 [(parallel [(set (pc) (if_then_else
1826 (ne (match_operand:SI 0 "" "")
1827 (const_int 1))
1828 (label_ref (match_operand 4 "" ""))
1829 (pc)))
1830 (set (match_dup 0)
1831 (plus:SI (match_dup 0)
1832 (const_int -1)))
1833 (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1834 (clobber (match_scratch:SI 5 ""))])]
1835 ""
0a8f8c45 1836{
9b02a95e
BS
1837 /* The loop optimizer doesn't check the predicates... */
1838 if (GET_MODE (operands[0]) != SImode)
1839 FAIL;
0a8f8c45
BS
1840 /* Due to limitations in the hardware (an initial loop count of 0
1841 does not loop 2^32 times) we must avoid to generate a hardware
1842 loops when we cannot rule out this case. */
0a8f8c45
BS
1843 if (!flag_unsafe_loop_optimizations
1844 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 0xFFFFFFFF)
1845 FAIL;
1846 bfin_hardware_loop ();
1847})
b03149e1
JZ
1848
1849(define_insn "loop_end"
1850 [(set (pc)
a9c46998 1851 (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+a*d,*b*v*f,m")
b03149e1
JZ
1852 (const_int 1))
1853 (label_ref (match_operand 1 "" ""))
1854 (pc)))
1855 (set (match_dup 0)
1856 (plus (match_dup 0)
1857 (const_int -1)))
1858 (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1859 (clobber (match_scratch:SI 2 "=X,&r,&r"))]
1860 ""
1861 "@
1862 /* loop end %0 %l1 */
1863 #
1864 #"
1865 [(set_attr "length" "6,10,14")])
1866
1867(define_split
1868 [(set (pc)
1869 (if_then_else (ne (match_operand:SI 0 "nondp_reg_or_memory_operand" "")
1870 (const_int 1))
1871 (label_ref (match_operand 1 "" ""))
1872 (pc)))
1873 (set (match_dup 0)
1874 (plus (match_dup 0)
1875 (const_int -1)))
1876 (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1877 (clobber (match_scratch:SI 2 "=&r"))]
1878 "reload_completed"
1879 [(set (match_dup 2) (match_dup 0))
1880 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
1881 (set (match_dup 0) (match_dup 2))
1882 (set (reg:BI REG_CC) (eq:BI (match_dup 2) (const_int 0)))
1883 (set (pc)
1884 (if_then_else (eq (reg:BI REG_CC)
1885 (const_int 0))
1886 (label_ref (match_dup 1))
1887 (pc)))]
1888 "")
1889
1890(define_insn "lsetup_with_autoinit"
1891 [(set (match_operand:SI 0 "lt_register_operand" "=t")
1892 (label_ref (match_operand 1 "" "")))
a9c46998 1893 (set (match_operand:SI 2 "lb_register_operand" "=u")
b03149e1
JZ
1894 (label_ref (match_operand 3 "" "")))
1895 (set (match_operand:SI 4 "lc_register_operand" "=k")
1896 (match_operand:SI 5 "register_operand" "a"))]
1897 ""
1898 "LSETUP (%1, %3) %4 = %5;"
1899 [(set_attr "length" "4")])
1900
1901(define_insn "lsetup_without_autoinit"
1902 [(set (match_operand:SI 0 "lt_register_operand" "=t")
1903 (label_ref (match_operand 1 "" "")))
a9c46998 1904 (set (match_operand:SI 2 "lb_register_operand" "=u")
b03149e1
JZ
1905 (label_ref (match_operand 3 "" "")))
1906 (use (match_operand:SI 4 "lc_register_operand" "k"))]
1907 ""
1908 "LSETUP (%1, %3) %4;"
1909 [(set_attr "length" "4")])
1910
0d4a78eb
BS
1911;; Call instructions..
1912
6614f9f5
BS
1913;; The explicit MEM inside the UNSPEC prevents the compiler from moving
1914;; the load before a branch after a NULL test, or before a store that
1915;; initializes a function descriptor.
1916
1917(define_insn_and_split "load_funcdescsi"
1918 [(set (match_operand:SI 0 "register_operand" "=a")
1919 (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
1920 UNSPEC_VOLATILE_LOAD_FUNCDESC))]
1921 ""
1922 "#"
1923 "reload_completed"
1924 [(set (match_dup 0) (mem:SI (match_dup 1)))])
1925
0d4a78eb 1926(define_expand "call"
6d459e2b
BS
1927 [(parallel [(call (match_operand:SI 0 "" "")
1928 (match_operand 1 "" ""))
1929 (use (match_operand 2 "" ""))])]
0d4a78eb 1930 ""
6d459e2b
BS
1931{
1932 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 0);
1933 DONE;
1934})
0d4a78eb
BS
1935
1936(define_expand "sibcall"
1937 [(parallel [(call (match_operand:SI 0 "" "")
1938 (match_operand 1 "" ""))
6d459e2b 1939 (use (match_operand 2 "" ""))
0d4a78eb
BS
1940 (return)])]
1941 ""
6d459e2b
BS
1942{
1943 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 1);
1944 DONE;
1945})
0d4a78eb
BS
1946
1947(define_expand "call_value"
6d459e2b
BS
1948 [(parallel [(set (match_operand 0 "register_operand" "")
1949 (call (match_operand:SI 1 "" "")
1950 (match_operand 2 "" "")))
1951 (use (match_operand 3 "" ""))])]
0d4a78eb 1952 ""
6d459e2b
BS
1953{
1954 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 0);
1955 DONE;
1956})
0d4a78eb
BS
1957
1958(define_expand "sibcall_value"
1959 [(parallel [(set (match_operand 0 "register_operand" "")
1960 (call (match_operand:SI 1 "" "")
1961 (match_operand 2 "" "")))
6d459e2b 1962 (use (match_operand 3 "" ""))
0d4a78eb
BS
1963 (return)])]
1964 ""
6d459e2b
BS
1965{
1966 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 1);
1967 DONE;
1968})
0d4a78eb 1969
6614f9f5
BS
1970(define_insn "*call_symbol_fdpic"
1971 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1972 (match_operand 1 "general_operand" "g"))
1973 (use (match_operand:SI 2 "register_operand" "Z"))
1974 (use (match_operand 3 "" ""))]
1975 "! SIBLING_CALL_P (insn)
1976 && GET_CODE (operands[0]) == SYMBOL_REF
1977 && !bfin_longcall_p (operands[0], INTVAL (operands[3]))"
1978 "call %0;"
1979 [(set_attr "type" "call")
1980 (set_attr "length" "4")])
1981
1982(define_insn "*sibcall_symbol_fdpic"
1983 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1984 (match_operand 1 "general_operand" "g"))
1985 (use (match_operand:SI 2 "register_operand" "Z"))
1986 (use (match_operand 3 "" ""))
1987 (return)]
1988 "SIBLING_CALL_P (insn)
1989 && GET_CODE (operands[0]) == SYMBOL_REF
1990 && !bfin_longcall_p (operands[0], INTVAL (operands[3]))"
1991 "jump.l %0;"
1992 [(set_attr "type" "br")
1993 (set_attr "length" "4")])
1994
1995(define_insn "*call_value_symbol_fdpic"
1996 [(set (match_operand 0 "register_operand" "=d")
1997 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1998 (match_operand 2 "general_operand" "g")))
1999 (use (match_operand:SI 3 "register_operand" "Z"))
2000 (use (match_operand 4 "" ""))]
2001 "! SIBLING_CALL_P (insn)
2002 && GET_CODE (operands[1]) == SYMBOL_REF
2003 && !bfin_longcall_p (operands[1], INTVAL (operands[4]))"
2004 "call %1;"
2005 [(set_attr "type" "call")
2006 (set_attr "length" "4")])
2007
2008(define_insn "*sibcall_value_symbol_fdpic"
2009 [(set (match_operand 0 "register_operand" "=d")
2010 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
2011 (match_operand 2 "general_operand" "g")))
2012 (use (match_operand:SI 3 "register_operand" "Z"))
2013 (use (match_operand 4 "" ""))
2014 (return)]
2015 "SIBLING_CALL_P (insn)
2016 && GET_CODE (operands[1]) == SYMBOL_REF
2017 && !bfin_longcall_p (operands[1], INTVAL (operands[4]))"
2018 "jump.l %1;"
2019 [(set_attr "type" "br")
2020 (set_attr "length" "4")])
2021
2022(define_insn "*call_insn_fdpic"
2023 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y"))
2024 (match_operand 1 "general_operand" "g"))
2025 (use (match_operand:SI 2 "register_operand" "Z"))
2026 (use (match_operand 3 "" ""))]
2027 "! SIBLING_CALL_P (insn)"
2028 "call (%0);"
2029 [(set_attr "type" "call")
2030 (set_attr "length" "2")])
2031
2032(define_insn "*sibcall_insn_fdpic"
2033 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y"))
2034 (match_operand 1 "general_operand" "g"))
2035 (use (match_operand:SI 2 "register_operand" "Z"))
2036 (use (match_operand 3 "" ""))
2037 (return)]
2038 "SIBLING_CALL_P (insn)"
2039 "jump (%0);"
2040 [(set_attr "type" "br")
2041 (set_attr "length" "2")])
2042
2043(define_insn "*call_value_insn_fdpic"
2044 [(set (match_operand 0 "register_operand" "=d")
2045 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y"))
2046 (match_operand 2 "general_operand" "g")))
2047 (use (match_operand:SI 3 "register_operand" "Z"))
2048 (use (match_operand 4 "" ""))]
2049 "! SIBLING_CALL_P (insn)"
2050 "call (%1);"
2051 [(set_attr "type" "call")
2052 (set_attr "length" "2")])
2053
2054(define_insn "*sibcall_value_insn_fdpic"
2055 [(set (match_operand 0 "register_operand" "=d")
2056 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y"))
2057 (match_operand 2 "general_operand" "g")))
2058 (use (match_operand:SI 3 "register_operand" "Z"))
2059 (use (match_operand 4 "" ""))
2060 (return)]
2061 "SIBLING_CALL_P (insn)"
2062 "jump (%1);"
2063 [(set_attr "type" "br")
2064 (set_attr "length" "2")])
2065
6d459e2b
BS
2066(define_insn "*call_symbol"
2067 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
2068 (match_operand 1 "general_operand" "g"))
2069 (use (match_operand 2 "" ""))]
0d4a78eb 2070 "! SIBLING_CALL_P (insn)
93147119 2071 && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
6d459e2b
BS
2072 && GET_CODE (operands[0]) == SYMBOL_REF
2073 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
96c30d2a 2074 "call %0;"
0d4a78eb 2075 [(set_attr "type" "call")
6d459e2b 2076 (set_attr "length" "4")])
0d4a78eb 2077
6d459e2b
BS
2078(define_insn "*sibcall_symbol"
2079 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
2080 (match_operand 1 "general_operand" "g"))
2081 (use (match_operand 2 "" ""))
0d4a78eb
BS
2082 (return)]
2083 "SIBLING_CALL_P (insn)
93147119 2084 && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
6d459e2b
BS
2085 && GET_CODE (operands[0]) == SYMBOL_REF
2086 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
96c30d2a 2087 "jump.l %0;"
0d4a78eb 2088 [(set_attr "type" "br")
6d459e2b 2089 (set_attr "length" "4")])
0d4a78eb 2090
6d459e2b
BS
2091(define_insn "*call_value_symbol"
2092 [(set (match_operand 0 "register_operand" "=d")
2093 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
2094 (match_operand 2 "general_operand" "g")))
2095 (use (match_operand 3 "" ""))]
0d4a78eb 2096 "! SIBLING_CALL_P (insn)
93147119 2097 && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
6d459e2b
BS
2098 && GET_CODE (operands[1]) == SYMBOL_REF
2099 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
96c30d2a 2100 "call %1;"
0d4a78eb 2101 [(set_attr "type" "call")
6d459e2b 2102 (set_attr "length" "4")])
0d4a78eb 2103
6d459e2b
BS
2104(define_insn "*sibcall_value_symbol"
2105 [(set (match_operand 0 "register_operand" "=d")
2106 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
2107 (match_operand 2 "general_operand" "g")))
2108 (use (match_operand 3 "" ""))
0d4a78eb
BS
2109 (return)]
2110 "SIBLING_CALL_P (insn)
93147119 2111 && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
6d459e2b
BS
2112 && GET_CODE (operands[1]) == SYMBOL_REF
2113 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
96c30d2a 2114 "jump.l %1;"
6d459e2b
BS
2115 [(set_attr "type" "br")
2116 (set_attr "length" "4")])
2117
2118(define_insn "*call_insn"
2119 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a"))
2120 (match_operand 1 "general_operand" "g"))
2121 (use (match_operand 2 "" ""))]
2122 "! SIBLING_CALL_P (insn)"
2123 "call (%0);"
2124 [(set_attr "type" "call")
2125 (set_attr "length" "2")])
2126
2127(define_insn "*sibcall_insn"
2128 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "z"))
2129 (match_operand 1 "general_operand" "g"))
2130 (use (match_operand 2 "" ""))
2131 (return)]
2132 "SIBLING_CALL_P (insn)"
2133 "jump (%0);"
2134 [(set_attr "type" "br")
2135 (set_attr "length" "2")])
2136
2137(define_insn "*call_value_insn"
2138 [(set (match_operand 0 "register_operand" "=d")
2139 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a"))
2140 (match_operand 2 "general_operand" "g")))
2141 (use (match_operand 3 "" ""))]
2142 "! SIBLING_CALL_P (insn)"
2143 "call (%1);"
2144 [(set_attr "type" "call")
2145 (set_attr "length" "2")])
2146
2147(define_insn "*sibcall_value_insn"
2148 [(set (match_operand 0 "register_operand" "=d")
2149 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "z"))
2150 (match_operand 2 "general_operand" "g")))
2151 (use (match_operand 3 "" ""))
2152 (return)]
2153 "SIBLING_CALL_P (insn)"
2154 "jump (%1);"
0d4a78eb 2155 [(set_attr "type" "br")
6d459e2b 2156 (set_attr "length" "2")])
0d4a78eb
BS
2157
2158;; Block move patterns
2159
2160;; We cheat. This copies one more word than operand 2 indicates.
2161
2162(define_insn "rep_movsi"
2163 [(set (match_operand:SI 0 "register_operand" "=&a")
2164 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
2165 (ashift:SI (match_operand:SI 2 "register_operand" "a")
2166 (const_int 2)))
2167 (const_int 4)))
2168 (set (match_operand:SI 1 "register_operand" "=&b")
2169 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
2170 (ashift:SI (match_dup 2) (const_int 2)))
2171 (const_int 4)))
2172 (set (mem:BLK (match_dup 3))
2173 (mem:BLK (match_dup 4)))
2174 (use (match_dup 2))
b03149e1
JZ
2175 (clobber (match_scratch:HI 5 "=&d"))
2176 (clobber (reg:SI REG_LT1))
2177 (clobber (reg:SI REG_LC1))
2178 (clobber (reg:SI REG_LB1))]
0d4a78eb 2179 ""
51a641fd 2180 "%5 = [%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || [%3++] = %5 || %5 = [%4++]; [%3++] = %5;"
0d4a78eb 2181 [(set_attr "type" "misc")
b03149e1
JZ
2182 (set_attr "length" "16")
2183 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
2184
2185(define_insn "rep_movhi"
2186 [(set (match_operand:SI 0 "register_operand" "=&a")
2187 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
2188 (ashift:SI (match_operand:SI 2 "register_operand" "a")
2189 (const_int 1)))
2190 (const_int 2)))
2191 (set (match_operand:SI 1 "register_operand" "=&b")
2192 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
2193 (ashift:SI (match_dup 2) (const_int 1)))
2194 (const_int 2)))
2195 (set (mem:BLK (match_dup 3))
2196 (mem:BLK (match_dup 4)))
2197 (use (match_dup 2))
b03149e1
JZ
2198 (clobber (match_scratch:HI 5 "=&d"))
2199 (clobber (reg:SI REG_LT1))
2200 (clobber (reg:SI REG_LC1))
2201 (clobber (reg:SI REG_LB1))]
0d4a78eb 2202 ""
51a641fd 2203 "%h5 = W[%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || W [%3++] = %5 || %h5 = W [%4++]; W [%3++] = %5;"
0d4a78eb 2204 [(set_attr "type" "misc")
b03149e1
JZ
2205 (set_attr "length" "16")
2206 (set_attr "seq_insns" "multi")])
0d4a78eb 2207
144f8315 2208(define_expand "movmemsi"
0d4a78eb
BS
2209 [(match_operand:BLK 0 "general_operand" "")
2210 (match_operand:BLK 1 "general_operand" "")
2211 (match_operand:SI 2 "const_int_operand" "")
2212 (match_operand:SI 3 "const_int_operand" "")]
2213 ""
2214{
144f8315 2215 if (bfin_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
0d4a78eb
BS
2216 DONE;
2217 FAIL;
2218})
2219
2220;; Conditional branch patterns
2221;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
2222
2223;; The only outcome of this pattern is that global variables
2224;; bfin_compare_op[01] are set for use in bcond patterns.
2225
2226(define_expand "cmpbi"
2227 [(set (cc0) (compare (match_operand:BI 0 "register_operand" "")
2228 (match_operand:BI 1 "immediate_operand" "")))]
2229 ""
2230{
2231 bfin_compare_op0 = operands[0];
2232 bfin_compare_op1 = operands[1];
2233 DONE;
2234})
2235
2236(define_expand "cmpsi"
2237 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
7ddcf3d2 2238 (match_operand:SI 1 "reg_or_const_int_operand" "")))]
0d4a78eb
BS
2239 ""
2240{
2241 bfin_compare_op0 = operands[0];
2242 bfin_compare_op1 = operands[1];
2243 DONE;
2244})
2245
49373252 2246(define_insn "compare_eq"
4729dc92 2247 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 2248 (eq:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 2249 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
0d4a78eb
BS
2250 ""
2251 "cc =%1==%2;"
2252 [(set_attr "type" "compare")])
2253
49373252 2254(define_insn "compare_ne"
4729dc92 2255 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 2256 (ne:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 2257 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
0d4a78eb
BS
2258 "0"
2259 "cc =%1!=%2;"
2260 [(set_attr "type" "compare")])
2261
49373252 2262(define_insn "compare_lt"
4729dc92 2263 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 2264 (lt:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 2265 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
0d4a78eb
BS
2266 ""
2267 "cc =%1<%2;"
2268 [(set_attr "type" "compare")])
2269
49373252 2270(define_insn "compare_le"
4729dc92 2271 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 2272 (le:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 2273 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
0d4a78eb
BS
2274 ""
2275 "cc =%1<=%2;"
2276 [(set_attr "type" "compare")])
2277
49373252 2278(define_insn "compare_leu"
4729dc92 2279 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 2280 (leu:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 2281 (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
0d4a78eb
BS
2282 ""
2283 "cc =%1<=%2 (iu);"
2284 [(set_attr "type" "compare")])
2285
49373252 2286(define_insn "compare_ltu"
4729dc92 2287 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 2288 (ltu:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 2289 (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
0d4a78eb
BS
2290 ""
2291 "cc =%1<%2 (iu);"
2292 [(set_attr "type" "compare")])
2293
2294(define_expand "beq"
2295 [(set (match_dup 1) (match_dup 2))
2296 (set (pc)
2297 (if_then_else (match_dup 3)
2298 (label_ref (match_operand 0 "" ""))
2299 (pc)))]
2300 ""
2301{
2302 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
2303 operands[1] = bfin_cc_rtx; /* hard register: CC */
2304 operands[2] = gen_rtx_EQ (BImode, op0, op1);
2305 /* If we have a BImode input, then we already have a compare result, and
2306 do not need to emit another comparison. */
2307 if (GET_MODE (bfin_compare_op0) == BImode)
2308 {
3b9dd769
NS
2309 gcc_assert (bfin_compare_op1 == const0_rtx);
2310 emit_insn (gen_cbranchbi4 (operands[2], op0, op1, operands[0]));
2311 DONE;
0d4a78eb
BS
2312 }
2313
2314 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2315})
2316
2317(define_expand "bne"
2318 [(set (match_dup 1) (match_dup 2))
2319 (set (pc)
2320 (if_then_else (match_dup 3)
2321 (label_ref (match_operand 0 "" ""))
2322 (pc)))]
2323 ""
2324{
2325 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
2326 /* If we have a BImode input, then we already have a compare result, and
2327 do not need to emit another comparison. */
2328 if (GET_MODE (bfin_compare_op0) == BImode)
2329 {
3b9dd769
NS
2330 rtx cmp = gen_rtx_NE (BImode, op0, op1);
2331
2332 gcc_assert (bfin_compare_op1 == const0_rtx);
2333 emit_insn (gen_cbranchbi4 (cmp, op0, op1, operands[0]));
2334 DONE;
0d4a78eb
BS
2335 }
2336
2337 operands[1] = bfin_cc_rtx; /* hard register: CC */
2338 operands[2] = gen_rtx_EQ (BImode, op0, op1);
2339 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2340})
2341
2342(define_expand "bgt"
2343 [(set (match_dup 1) (match_dup 2))
2344 (set (pc)
2345 (if_then_else (match_dup 3)
2346 (label_ref (match_operand 0 "" ""))
2347 (pc)))]
2348 ""
2349{
2350 operands[1] = bfin_cc_rtx;
2351 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
2352 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2353})
2354
2355(define_expand "bgtu"
2356 [(set (match_dup 1) (match_dup 2))
2357 (set (pc)
2358 (if_then_else (match_dup 3)
2359 (label_ref (match_operand 0 "" ""))
2360 (pc)))]
2361 ""
2362{
2363 operands[1] = bfin_cc_rtx;
2364 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
2365 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2366})
2367
2368(define_expand "blt"
2369 [(set (match_dup 1) (match_dup 2))
2370 (set (pc)
2371 (if_then_else (match_dup 3)
2372 (label_ref (match_operand 0 "" ""))
2373 (pc)))]
2374 ""
2375{
2376 operands[1] = bfin_cc_rtx;
2377 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
2378 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2379})
2380
2381(define_expand "bltu"
2382 [(set (match_dup 1) (match_dup 2))
2383 (set (pc)
2384 (if_then_else (match_dup 3)
2385 (label_ref (match_operand 0 "" ""))
2386 (pc)))]
2387 ""
2388{
2389 operands[1] = bfin_cc_rtx;
2390 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
2391 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2392})
2393
26c5953d
BS
2394;; Same as above, but and CC with the overflow bit generated by the first
2395;; multiplication.
2396(define_insn "flag_mul_macv2hi_parts_acconly_andcc0"
2397 [(set (match_operand:PDI 0 "register_operand" "=B,e,e")
2398 (unspec:PDI [(vec_select:HI
2399 (match_operand:V2HI 2 "register_operand" "d,d,d")
2400 (parallel [(match_operand 4 "const01_operand" "P0P1,P0P1,P0P1")]))
2401 (vec_select:HI
2402 (match_operand:V2HI 3 "register_operand" "d,d,d")
2403 (parallel [(match_operand 6 "const01_operand" "P0P1,P0P1,P0P1")]))
2404 (match_operand 10 "const_int_operand" "PB,PA,PA")]
2405 UNSPEC_MUL_WITH_FLAG))
2406 (set (match_operand:PDI 1 "register_operand" "=B,e,e")
2407 (unspec:PDI [(vec_select:HI
2408 (match_dup 2)
2409 (parallel [(match_operand 5 "const01_operand" "P0P1,P0P1,P0P1")]))
2410 (vec_select:HI
2411 (match_dup 3)
2412 (parallel [(match_operand 7 "const01_operand" "P0P1,P0P1,P0P1")]))
2413 (match_operand:PDI 8 "register_operand" "1,1,1")
2414 (match_operand 9 "const01_operand" "P0P1,P0P1,P0P1")
2415 (match_operand 11 "const_int_operand" "PA,PB,PA")]
2416 UNSPEC_MAC_WITH_FLAG))
2417 (set (reg:BI REG_CC)
2418 (and:BI (reg:BI REG_CC)
2419 (unspec:BI [(vec_select:HI (match_dup 2) (parallel [(match_dup 4)]))
2420 (vec_select:HI (match_dup 3) (parallel [(match_dup 6)]))
2421 (match_dup 10)]
2422 UNSPEC_MUL_WITH_FLAG)))]
2423 "MACFLAGS_MATCH_P (INTVAL (operands[10]), INTVAL (operands[11]))"
2424{
2425 rtx xops[6];
2426 const char *templates[] = {
2427 "%0 = %h2 * %h3, %1 %b4 %h2 * %h3 %M5;\n\tCC &= %v0;",
2428 "%0 = %d2 * %h3, %1 %b4 %h2 * %h3 %M5;\n\tCC &= %v0;",
2429 "%0 = %h2 * %h3, %1 %b4 %d2 * %h3 %M5;\n\tCC &= %v0;",
2430 "%0 = %d2 * %h3, %1 %b4 %d2 * %h3 %M5;\n\tCC &= %v0;",
2431 "%0 = %h2 * %d3, %1 %b4 %h2 * %h3 %M5;\n\tCC &= %v0;",
2432 "%0 = %d2 * %d3, %1 %b4 %h2 * %h3 %M5;\n\tCC &= %v0;",
2433 "%0 = %h2 * %d3, %1 %b4 %d2 * %h3 %M5;\n\tCC &= %v0;",
2434 "%0 = %d2 * %d3, %1 %b4 %d2 * %h3 %M5;\n\tCC &= %v0;",
2435 "%0 = %h2 * %h3, %1 %b4 %h2 * %d3 %M5;\n\tCC &= %v0;",
2436 "%0 = %d2 * %h3, %1 %b4 %h2 * %d3 %M5;\n\tCC &= %v0;",
2437 "%0 = %h2 * %h3, %1 %b4 %d2 * %d3 %M5;\n\tCC &= %v0;",
2438 "%0 = %d2 * %h3, %1 %b4 %d2 * %d3 %M5;\n\tCC &= %v0;",
2439 "%0 = %h2 * %d3, %1 %b4 %h2 * %d3 %M5;\n\tCC &= %v0;",
2440 "%0 = %d2 * %d3, %1 %b4 %h2 * %d3 %M5;\n\tCC &= %v0;",
2441 "%0 = %h2 * %d3, %1 %b4 %d2 * %d3 %M5;\n\tCC &= %v0;",
2442 "%0 = %d2 * %d3, %1 %b4 %d2 * %d3 %M5;\n\tCC &= %v0;" };
2443 int alt = (INTVAL (operands[4]) + (INTVAL (operands[5]) << 1)
2444 + (INTVAL (operands[6]) << 2) + (INTVAL (operands[7]) << 3));
2445 xops[0] = operands[0];
2446 xops[1] = operands[1];
2447 xops[2] = operands[2];
2448 xops[3] = operands[3];
2449 xops[4] = operands[9];
2450 xops[5] = which_alternative == 0 ? operands[10] : operands[11];
2451 output_asm_insn (templates[alt], xops);
2452 return "";
2453}
2454 [(set_attr "type" "misc")
2455 (set_attr "length" "6")
2456 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
2457
2458(define_expand "bge"
2459 [(set (match_dup 1) (match_dup 2))
2460 (set (pc)
2461 (if_then_else (match_dup 3)
2462 (label_ref (match_operand 0 "" ""))
2463 (pc)))]
2464 ""
2465{
2466 operands[1] = bfin_cc_rtx;
2467 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
2468 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2469})
2470
2471(define_expand "bgeu"
2472 [(set (match_dup 1) (match_dup 2))
2473 (set (pc)
2474 (if_then_else (match_dup 3)
2475 (label_ref (match_operand 0 "" ""))
2476 (pc)))]
2477 ""
2478{
2479 operands[1] = bfin_cc_rtx;
2480 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
2481 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2482})
2483
2484(define_expand "ble"
2485 [(set (match_dup 1) (match_dup 2))
2486 (set (pc)
2487 (if_then_else (match_dup 3)
2488 (label_ref (match_operand 0 "" ""))
2489 (pc)))]
2490 ""
2491{
2492 operands[1] = bfin_cc_rtx;
2493 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
2494 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2495})
2496
2497(define_expand "bleu"
2498 [(set (match_dup 1) (match_dup 2))
2499 (set (pc)
2500 (if_then_else (match_dup 3)
2501 (label_ref (match_operand 0 "" ""))
2502 (pc)))
2503 ]
2504 ""
2505{
2506 operands[1] = bfin_cc_rtx;
2507 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
2508 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2509})
2510
2511(define_insn "cbranchbi4"
2512 [(set (pc)
2513 (if_then_else
2514 (match_operator 0 "bfin_cbranch_operator"
4729dc92 2515 [(match_operand:BI 1 "register_operand" "C")
0d4a78eb
BS
2516 (match_operand:BI 2 "immediate_operand" "P0")])
2517 (label_ref (match_operand 3 "" ""))
2518 (pc)))]
2519 ""
2520{
2521 asm_conditional_branch (insn, operands, 0, 0);
2522 return "";
2523}
2524 [(set_attr "type" "brcc")])
2525
2526;; Special cbranch patterns to deal with the speculative load problem - see
2527;; bfin_reorg for details.
2528
2529(define_insn "cbranch_predicted_taken"
2530 [(set (pc)
2531 (if_then_else
2532 (match_operator 0 "bfin_cbranch_operator"
4729dc92 2533 [(match_operand:BI 1 "register_operand" "C")
0d4a78eb
BS
2534 (match_operand:BI 2 "immediate_operand" "P0")])
2535 (label_ref (match_operand 3 "" ""))
2536 (pc)))
2537 (unspec [(const_int 0)] UNSPEC_CBRANCH_TAKEN)]
2538 ""
2539{
2540 asm_conditional_branch (insn, operands, 0, 1);
2541 return "";
2542}
2543 [(set_attr "type" "brcc")])
2544
2545(define_insn "cbranch_with_nops"
2546 [(set (pc)
2547 (if_then_else
2548 (match_operator 0 "bfin_cbranch_operator"
4729dc92 2549 [(match_operand:BI 1 "register_operand" "C")
0d4a78eb
BS
2550 (match_operand:BI 2 "immediate_operand" "P0")])
2551 (label_ref (match_operand 3 "" ""))
2552 (pc)))
2553 (unspec [(match_operand 4 "immediate_operand" "")] UNSPEC_CBRANCH_NOPS)]
2554 "reload_completed"
2555{
2556 asm_conditional_branch (insn, operands, INTVAL (operands[4]), 0);
2557 return "";
2558}
2559 [(set_attr "type" "brcc")
2560 (set_attr "length" "6")])
2561
2562;; setcc insns. */
2563(define_expand "seq"
2564 [(set (match_dup 1) (eq:BI (match_dup 2) (match_dup 3)))
2565 (set (match_operand:SI 0 "register_operand" "")
2566 (ne:SI (match_dup 1) (const_int 0)))]
2567 ""
2568{
2569 operands[2] = bfin_compare_op0;
2570 operands[3] = bfin_compare_op1;
2571 operands[1] = bfin_cc_rtx;
2572})
2573
2574(define_expand "slt"
2575 [(set (match_dup 1) (lt:BI (match_dup 2) (match_dup 3)))
2576 (set (match_operand:SI 0 "register_operand" "")
2577 (ne:SI (match_dup 1) (const_int 0)))]
2578 ""
2579{
2580 operands[2] = bfin_compare_op0;
2581 operands[3] = bfin_compare_op1;
2582 operands[1] = bfin_cc_rtx;
2583})
2584
2585(define_expand "sle"
2586 [(set (match_dup 1) (le:BI (match_dup 2) (match_dup 3)))
2587 (set (match_operand:SI 0 "register_operand" "")
2588 (ne:SI (match_dup 1) (const_int 0)))]
2589 ""
2590{
2591 operands[2] = bfin_compare_op0;
2592 operands[3] = bfin_compare_op1;
2593 operands[1] = bfin_cc_rtx;
2594})
2595
2596(define_expand "sltu"
2597 [(set (match_dup 1) (ltu:BI (match_dup 2) (match_dup 3)))
2598 (set (match_operand:SI 0 "register_operand" "")
2599 (ne:SI (match_dup 1) (const_int 0)))]
2600 ""
2601{
2602 operands[2] = bfin_compare_op0;
2603 operands[3] = bfin_compare_op1;
2604 operands[1] = bfin_cc_rtx;
2605})
2606
2607(define_expand "sleu"
2608 [(set (match_dup 1) (leu:BI (match_dup 2) (match_dup 3)))
2609 (set (match_operand:SI 0 "register_operand" "")
2610 (ne:SI (match_dup 1) (const_int 0)))]
2611 ""
2612{
2613 operands[2] = bfin_compare_op0;
2614 operands[3] = bfin_compare_op1;
2615 operands[1] = bfin_cc_rtx;
2616})
2617
2618(define_insn "nop"
2619 [(const_int 0)]
2620 ""
2621 "nop;")
2622
bbbc206e
BS
2623(define_insn "mnop"
2624 [(unspec [(const_int 0)] UNSPEC_32BIT)]
2625 ""
2626 "mnop%!"
2627 [(set_attr "type" "dsp32")])
2628
0d4a78eb
BS
2629;;;;;;;;;;;;;;;;;;;; CC2dreg ;;;;;;;;;;;;;;;;;;;;;;;;;
2630(define_insn "movsibi"
4729dc92 2631 [(set (match_operand:BI 0 "register_operand" "=C")
0d4a78eb
BS
2632 (ne:BI (match_operand:SI 1 "register_operand" "d")
2633 (const_int 0)))]
2634 ""
2635 "CC = %1;"
2636 [(set_attr "length" "2")])
2637
2638(define_insn "movbisi"
2639 [(set (match_operand:SI 0 "register_operand" "=d")
4729dc92 2640 (ne:SI (match_operand:BI 1 "register_operand" "C")
0d4a78eb
BS
2641 (const_int 0)))]
2642 ""
2643 "%0 = CC;"
2644 [(set_attr "length" "2")])
2645
2646(define_insn ""
4729dc92
BS
2647 [(set (match_operand:BI 0 "register_operand" "=C")
2648 (eq:BI (match_operand:BI 1 "register_operand" " 0")
0d4a78eb
BS
2649 (const_int 0)))]
2650 ""
2651 "%0 = ! %0;" /* NOT CC;" */
2652 [(set_attr "type" "compare")])
2653
2654;; Vector and DSP insns
2655
2656(define_insn ""
2657 [(set (match_operand:SI 0 "register_operand" "=d")
2658 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2659 (const_int 24))
2660 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2661 (const_int 8))))]
2662 ""
bbbc206e 2663 "%0 = ALIGN8(%1, %2)%!"
0d4a78eb
BS
2664 [(set_attr "type" "dsp32")])
2665
2666(define_insn ""
2667 [(set (match_operand:SI 0 "register_operand" "=d")
2668 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2669 (const_int 16))
2670 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2671 (const_int 16))))]
2672 ""
bbbc206e 2673 "%0 = ALIGN16(%1, %2)%!"
0d4a78eb
BS
2674 [(set_attr "type" "dsp32")])
2675
2676(define_insn ""
2677 [(set (match_operand:SI 0 "register_operand" "=d")
2678 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2679 (const_int 8))
2680 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2681 (const_int 24))))]
2682 ""
bbbc206e 2683 "%0 = ALIGN24(%1, %2)%!"
0d4a78eb
BS
2684 [(set_attr "type" "dsp32")])
2685
2686;; Prologue and epilogue.
2687
2688(define_expand "prologue"
2689 [(const_int 1)]
2690 ""
2691 "bfin_expand_prologue (); DONE;")
2692
2693(define_expand "epilogue"
2694 [(const_int 1)]
2695 ""
2696 "bfin_expand_epilogue (1, 0); DONE;")
2697
2698(define_expand "sibcall_epilogue"
2699 [(const_int 1)]
2700 ""
2701 "bfin_expand_epilogue (0, 0); DONE;")
2702
2703(define_expand "eh_return"
2704 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")]
2705 UNSPEC_VOLATILE_EH_RETURN)]
2706 ""
2707{
2708 emit_move_insn (EH_RETURN_HANDLER_RTX, operands[0]);
1e96b1c3 2709 emit_jump_insn (gen_eh_return_internal ());
0d4a78eb 2710 emit_barrier ();
4193ce73 2711 DONE;
0d4a78eb
BS
2712})
2713
2714(define_insn_and_split "eh_return_internal"
1e96b1c3
JZ
2715 [(set (pc)
2716 (unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN))]
0d4a78eb
BS
2717 ""
2718 "#"
2719 "reload_completed"
2720 [(const_int 1)]
2721 "bfin_expand_epilogue (1, 1); DONE;")
2722
2723(define_insn "link"
2724 [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS))
2725 (set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:SI REG_FP))
2726 (set (reg:SI REG_FP)
2727 (plus:SI (reg:SI REG_SP) (const_int -8)))
2728 (set (reg:SI REG_SP)
2729 (plus:SI (reg:SI REG_SP) (match_operand:SI 0 "immediate_operand" "i")))]
2730 ""
2731 "LINK %Z0;"
2732 [(set_attr "length" "4")])
2733
2734(define_insn "unlink"
2735 [(set (reg:SI REG_FP) (mem:SI (reg:SI REG_FP)))
2736 (set (reg:SI REG_RETS) (mem:SI (plus:SI (reg:SI REG_FP) (const_int 4))))
2737 (set (reg:SI REG_SP) (plus:SI (reg:SI REG_FP) (const_int 8)))]
2738 ""
2739 "UNLINK;"
2740 [(set_attr "length" "4")])
2741
2742;; This pattern is slightly clumsy. The stack adjust must be the final SET in
2743;; the pattern, otherwise dwarf2out becomes very confused about which reg goes
2744;; where on the stack, since it goes through all elements of the parallel in
2745;; sequence.
2746(define_insn "push_multiple"
2747 [(match_parallel 0 "push_multiple_operation"
2748 [(unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_PUSH_MULTIPLE)])]
2749 ""
2750{
2751 output_push_multiple (insn, operands);
2752 return "";
2753})
2754
2755(define_insn "pop_multiple"
2756 [(match_parallel 0 "pop_multiple_operation"
2757 [(set (reg:SI REG_SP)
2758 (plus:SI (reg:SI REG_SP) (match_operand:SI 1 "immediate_operand" "i")))])]
2759 ""
2760{
2761 output_pop_multiple (insn, operands);
2762 return "";
2763})
2764
2765(define_insn "return_internal"
2766 [(return)
2767 (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)]
2768 "reload_completed"
2769{
2770 switch (INTVAL (operands[0]))
2771 {
2772 case EXCPT_HANDLER:
2773 return "rtx;";
2774 case NMI_HANDLER:
2775 return "rtn;";
2776 case INTERRUPT_HANDLER:
2777 return "rti;";
2778 case SUBROUTINE:
2779 return "rts;";
2780 }
2781 gcc_unreachable ();
2782})
2783
5fcead21
BS
2784(define_insn "csync"
2785 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
2786 ""
2787 "csync;"
3fb192d2 2788 [(set_attr "type" "sync")])
5fcead21
BS
2789
2790(define_insn "ssync"
2791 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_SSYNC)]
2792 ""
2793 "ssync;"
3fb192d2 2794 [(set_attr "type" "sync")])
5fcead21 2795
3d33a056
JZ
2796(define_insn "trap"
2797 [(trap_if (const_int 1) (const_int 3))]
2798 ""
2799 "excpt 3;"
2800 [(set_attr "type" "misc")
2801 (set_attr "length" "2")])
2802
09350e36
BS
2803(define_insn "trapifcc"
2804 [(trap_if (reg:BI REG_CC) (const_int 3))]
2805 ""
2806 "if !cc jump 4 (bp); excpt 3;"
2807 [(set_attr "type" "misc")
b03149e1
JZ
2808 (set_attr "length" "4")
2809 (set_attr "seq_insns" "multi")])
09350e36 2810
0d4a78eb
BS
2811;;; Vector instructions
2812
75d8b2d0
BS
2813;; First, all sorts of move variants
2814
75d8b2d0
BS
2815(define_insn "movhiv2hi_low"
2816 [(set (match_operand:V2HI 0 "register_operand" "=d")
2817 (vec_concat:V2HI
2818 (match_operand:HI 2 "register_operand" "d")
2819 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2820 (parallel [(const_int 1)]))))]
2821 ""
bbbc206e 2822 "%h0 = %h2 << 0%!"
75d8b2d0
BS
2823 [(set_attr "type" "dsp32")])
2824
2825(define_insn "movhiv2hi_high"
2826 [(set (match_operand:V2HI 0 "register_operand" "=d")
2827 (vec_concat:V2HI
2828 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2829 (parallel [(const_int 0)]))
2830 (match_operand:HI 2 "register_operand" "d")))]
2831 ""
bbbc206e 2832 "%d0 = %h2 << 0%!"
75d8b2d0
BS
2833 [(set_attr "type" "dsp32")])
2834
2835;; No earlyclobber on alternative two since our sequence ought to be safe.
2836;; The order of operands is intentional to match the VDSP builtin (high word
2837;; is passed first).
2838(define_insn_and_split "composev2hi"
2839 [(set (match_operand:V2HI 0 "register_operand" "=d,d")
2840 (vec_concat:V2HI (match_operand:HI 2 "register_operand" "0,d")
2841 (match_operand:HI 1 "register_operand" "d,d")))]
2842 ""
2843 "@
bbbc206e 2844 %d0 = %h2 << 0%!
75d8b2d0
BS
2845 #"
2846 "reload_completed"
2847 [(set (match_dup 0)
2848 (vec_concat:V2HI
2849 (vec_select:HI (match_dup 0) (parallel [(const_int 0)]))
2850 (match_dup 2)))
2851 (set (match_dup 0)
2852 (vec_concat:V2HI
2853 (match_dup 1)
2854 (vec_select:HI (match_dup 0) (parallel [(const_int 1)]))))]
2855 ""
2856 [(set_attr "type" "dsp32")])
2857
2858; Like composev2hi, but operating on elements of V2HI vectors.
2859; Useful on its own, and as a combiner bridge for the multiply and
2860; mac patterns.
2861(define_insn "packv2hi"
2d3649b2 2862 [(set (match_operand:V2HI 0 "register_operand" "=d,d,d,d,d,d,d,d")
75d8b2d0 2863 (vec_concat:V2HI (vec_select:HI
2d3649b2
BS
2864 (match_operand:V2HI 1 "register_operand" "0,0,d,d,d,d,d,d")
2865 (parallel [(match_operand 3 "const01_operand" "P0,P0,P0,P1,P0,P1,P0,P1")]))
75d8b2d0 2866 (vec_select:HI
2d3649b2
BS
2867 (match_operand:V2HI 2 "register_operand" "d,d,0,0,d,d,d,d")
2868 (parallel [(match_operand 4 "const01_operand" "P0,P1,P1,P1,P0,P0,P1,P1")]))))]
75d8b2d0
BS
2869 ""
2870 "@
2d3649b2
BS
2871 %d0 = %h2 << 0%!
2872 %d0 = %d2 << 0%!
2873 %h0 = %h1 << 0%!
2874 %h0 = %d1 << 0%!
bbbc206e
BS
2875 %0 = PACK (%h2,%h1)%!
2876 %0 = PACK (%h2,%d1)%!
2877 %0 = PACK (%d2,%h1)%!
2878 %0 = PACK (%d2,%d1)%!"
75d8b2d0
BS
2879 [(set_attr "type" "dsp32")])
2880
2881(define_insn "movv2hi_hi"
2882 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
2883 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0,d,d")
554006bd 2884 (parallel [(match_operand 2 "const01_operand" "P0,P0,P1")])))]
75d8b2d0
BS
2885 ""
2886 "@
2887 /* optimized out */
bbbc206e
BS
2888 %h0 = %h1 << 0%!
2889 %h0 = %d1 << 0%!"
75d8b2d0
BS
2890 [(set_attr "type" "dsp32")])
2891
2892(define_expand "movv2hi_hi_low"
2893 [(set (match_operand:HI 0 "register_operand" "")
2894 (vec_select:HI (match_operand:V2HI 1 "register_operand" "")
2895 (parallel [(const_int 0)])))]
2896 ""
2897 "")
2898
2899(define_expand "movv2hi_hi_high"
2900 [(set (match_operand:HI 0 "register_operand" "")
2901 (vec_select:HI (match_operand:V2HI 1 "register_operand" "")
2902 (parallel [(const_int 1)])))]
2903 ""
2904 "")
2905
942fd98f 2906;; Unusual arithmetic operations on 16-bit registers.
75d8b2d0
BS
2907
2908(define_insn "ssaddhi3"
2909 [(set (match_operand:HI 0 "register_operand" "=d")
2910 (ss_plus:HI (match_operand:HI 1 "register_operand" "d")
2911 (match_operand:HI 2 "register_operand" "d")))]
2912 ""
bbbc206e 2913 "%h0 = %h1 + %h2 (S)%!"
75d8b2d0
BS
2914 [(set_attr "type" "dsp32")])
2915
2916(define_insn "sssubhi3"
2917 [(set (match_operand:HI 0 "register_operand" "=d")
2918 (ss_minus:HI (match_operand:HI 1 "register_operand" "d")
2919 (match_operand:HI 2 "register_operand" "d")))]
2920 ""
bbbc206e 2921 "%h0 = %h1 - %h2 (S)%!"
75d8b2d0
BS
2922 [(set_attr "type" "dsp32")])
2923
2924;; V2HI vector insns
2925
c9b3f817 2926(define_insn "addv2hi3"
0d4a78eb
BS
2927 [(set (match_operand:V2HI 0 "register_operand" "=d")
2928 (plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2929 (match_operand:V2HI 2 "register_operand" "d")))]
2930 ""
bbbc206e 2931 "%0 = %1 +|+ %2%!"
0d4a78eb
BS
2932 [(set_attr "type" "dsp32")])
2933
75d8b2d0
BS
2934(define_insn "ssaddv2hi3"
2935 [(set (match_operand:V2HI 0 "register_operand" "=d")
2936 (ss_plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2937 (match_operand:V2HI 2 "register_operand" "d")))]
2938 ""
bbbc206e 2939 "%0 = %1 +|+ %2 (S)%!"
75d8b2d0
BS
2940 [(set_attr "type" "dsp32")])
2941
c9b3f817 2942(define_insn "subv2hi3"
0d4a78eb
BS
2943 [(set (match_operand:V2HI 0 "register_operand" "=d")
2944 (minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2945 (match_operand:V2HI 2 "register_operand" "d")))]
2946 ""
bbbc206e 2947 "%0 = %1 -|- %2%!"
0d4a78eb
BS
2948 [(set_attr "type" "dsp32")])
2949
75d8b2d0
BS
2950(define_insn "sssubv2hi3"
2951 [(set (match_operand:V2HI 0 "register_operand" "=d")
2952 (ss_minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2953 (match_operand:V2HI 2 "register_operand" "d")))]
2954 ""
bbbc206e 2955 "%0 = %1 -|- %2 (S)%!"
75d8b2d0
BS
2956 [(set_attr "type" "dsp32")])
2957
2958(define_insn "addsubv2hi3"
2959 [(set (match_operand:V2HI 0 "register_operand" "=d")
2960 (vec_concat:V2HI
2961 (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2962 (parallel [(const_int 0)]))
2963 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2964 (parallel [(const_int 0)])))
2965 (minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2966 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2967 ""
bbbc206e 2968 "%0 = %1 +|- %2%!"
75d8b2d0
BS
2969 [(set_attr "type" "dsp32")])
2970
2971(define_insn "subaddv2hi3"
2972 [(set (match_operand:V2HI 0 "register_operand" "=d")
2973 (vec_concat:V2HI
2974 (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2975 (parallel [(const_int 0)]))
2976 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2977 (parallel [(const_int 0)])))
2978 (plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2979 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2980 ""
bbbc206e 2981 "%0 = %1 -|+ %2%!"
75d8b2d0
BS
2982 [(set_attr "type" "dsp32")])
2983
2984(define_insn "ssaddsubv2hi3"
2985 [(set (match_operand:V2HI 0 "register_operand" "=d")
2986 (vec_concat:V2HI
2987 (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2988 (parallel [(const_int 0)]))
2989 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2990 (parallel [(const_int 0)])))
2991 (ss_minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2992 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2993 ""
bbbc206e 2994 "%0 = %1 +|- %2 (S)%!"
75d8b2d0
BS
2995 [(set_attr "type" "dsp32")])
2996
2997(define_insn "sssubaddv2hi3"
2998 [(set (match_operand:V2HI 0 "register_operand" "=d")
2999 (vec_concat:V2HI
3000 (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3001 (parallel [(const_int 0)]))
3002 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3003 (parallel [(const_int 0)])))
3004 (ss_plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
3005 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3006 ""
bbbc206e 3007 "%0 = %1 -|+ %2 (S)%!"
75d8b2d0
BS
3008 [(set_attr "type" "dsp32")])
3009
3010(define_insn "sublohiv2hi3"
3011 [(set (match_operand:HI 0 "register_operand" "=d")
3012 (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3013 (parallel [(const_int 1)]))
3014 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3015 (parallel [(const_int 0)]))))]
3016 ""
bbbc206e 3017 "%h0 = %d1 - %h2%!"
75d8b2d0
BS
3018 [(set_attr "type" "dsp32")])
3019
3020(define_insn "subhilov2hi3"
3021 [(set (match_operand:HI 0 "register_operand" "=d")
3022 (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3023 (parallel [(const_int 0)]))
3024 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3025 (parallel [(const_int 1)]))))]
3026 ""
bbbc206e 3027 "%h0 = %h1 - %d2%!"
75d8b2d0
BS
3028 [(set_attr "type" "dsp32")])
3029
3030(define_insn "sssublohiv2hi3"
3031 [(set (match_operand:HI 0 "register_operand" "=d")
3032 (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3033 (parallel [(const_int 1)]))
3034 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3035 (parallel [(const_int 0)]))))]
3036 ""
bbbc206e 3037 "%h0 = %d1 - %h2 (S)%!"
75d8b2d0
BS
3038 [(set_attr "type" "dsp32")])
3039
3040(define_insn "sssubhilov2hi3"
3041 [(set (match_operand:HI 0 "register_operand" "=d")
3042 (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3043 (parallel [(const_int 0)]))
3044 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3045 (parallel [(const_int 1)]))))]
3046 ""
bbbc206e 3047 "%h0 = %h1 - %d2 (S)%!"
75d8b2d0
BS
3048 [(set_attr "type" "dsp32")])
3049
3050(define_insn "addlohiv2hi3"
3051 [(set (match_operand:HI 0 "register_operand" "=d")
3052 (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3053 (parallel [(const_int 1)]))
3054 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3055 (parallel [(const_int 0)]))))]
3056 ""
bbbc206e 3057 "%h0 = %d1 + %h2%!"
75d8b2d0
BS
3058 [(set_attr "type" "dsp32")])
3059
3060(define_insn "addhilov2hi3"
3061 [(set (match_operand:HI 0 "register_operand" "=d")
3062 (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3063 (parallel [(const_int 0)]))
3064 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3065 (parallel [(const_int 1)]))))]
3066 ""
bbbc206e 3067 "%h0 = %h1 + %d2%!"
75d8b2d0
BS
3068 [(set_attr "type" "dsp32")])
3069
3070(define_insn "ssaddlohiv2hi3"
3071 [(set (match_operand:HI 0 "register_operand" "=d")
3072 (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3073 (parallel [(const_int 1)]))
3074 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3075 (parallel [(const_int 0)]))))]
3076 ""
bbbc206e 3077 "%h0 = %d1 + %h2 (S)%!"
75d8b2d0
BS
3078 [(set_attr "type" "dsp32")])
3079
3080(define_insn "ssaddhilov2hi3"
3081 [(set (match_operand:HI 0 "register_operand" "=d")
3082 (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3083 (parallel [(const_int 0)]))
3084 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3085 (parallel [(const_int 1)]))))]
3086 ""
bbbc206e 3087 "%h0 = %h1 + %d2 (S)%!"
75d8b2d0
BS
3088 [(set_attr "type" "dsp32")])
3089
c9b3f817 3090(define_insn "sminv2hi3"
0d4a78eb
BS
3091 [(set (match_operand:V2HI 0 "register_operand" "=d")
3092 (smin:V2HI (match_operand:V2HI 1 "register_operand" "d")
3093 (match_operand:V2HI 2 "register_operand" "d")))]
3094 ""
bbbc206e 3095 "%0 = MIN (%1, %2) (V)%!"
0d4a78eb
BS
3096 [(set_attr "type" "dsp32")])
3097
c9b3f817 3098(define_insn "smaxv2hi3"
0d4a78eb
BS
3099 [(set (match_operand:V2HI 0 "register_operand" "=d")
3100 (smax:V2HI (match_operand:V2HI 1 "register_operand" "d")
3101 (match_operand:V2HI 2 "register_operand" "d")))]
3102 ""
bbbc206e 3103 "%0 = MAX (%1, %2) (V)%!"
0d4a78eb
BS
3104 [(set_attr "type" "dsp32")])
3105
75d8b2d0
BS
3106;; Multiplications.
3107
3108;; The Blackfin allows a lot of different options, and we need many patterns to
3109;; cover most of the hardware's abilities.
3110;; There are a few simple patterns using MULT rtx codes, but most of them use
3111;; an unspec with a const_int operand that determines which flag to use in the
3112;; instruction.
3113;; There are variants for single and parallel multiplications.
942fd98f 3114;; There are variants which just use 16-bit lowparts as inputs, and variants
75d8b2d0
BS
3115;; which allow the user to choose just which halves to use as input values.
3116;; There are variants which set D registers, variants which set accumulators,
3117;; variants which set both, some of them optionally using the accumulators as
3118;; inputs for multiply-accumulate operations.
3119
3120(define_insn "flag_mulhi"
3121 [(set (match_operand:HI 0 "register_operand" "=d")
3122 (unspec:HI [(match_operand:HI 1 "register_operand" "d")
3123 (match_operand:HI 2 "register_operand" "d")
3124 (match_operand 3 "const_int_operand" "n")]
3125 UNSPEC_MUL_WITH_FLAG))]
3126 ""
bbbc206e 3127 "%h0 = %h1 * %h2 %M3%!"
75d8b2d0
BS
3128 [(set_attr "type" "dsp32")])
3129
3130(define_insn "flag_mulhisi"
3131 [(set (match_operand:SI 0 "register_operand" "=d")
3132 (unspec:SI [(match_operand:HI 1 "register_operand" "d")
3133 (match_operand:HI 2 "register_operand" "d")
3134 (match_operand 3 "const_int_operand" "n")]
3135 UNSPEC_MUL_WITH_FLAG))]
3136 ""
bbbc206e 3137 "%0 = %h1 * %h2 %M3%!"
75d8b2d0
BS
3138 [(set_attr "type" "dsp32")])
3139
3140(define_insn "flag_mulhisi_parts"
3141 [(set (match_operand:SI 0 "register_operand" "=d")
3142 (unspec:SI [(vec_select:HI
3143 (match_operand:V2HI 1 "register_operand" "d")
554006bd 3144 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
75d8b2d0
BS
3145 (vec_select:HI
3146 (match_operand:V2HI 2 "register_operand" "d")
554006bd 3147 (parallel [(match_operand 4 "const01_operand" "P0P1")]))
75d8b2d0
BS
3148 (match_operand 5 "const_int_operand" "n")]
3149 UNSPEC_MUL_WITH_FLAG))]
3150 ""
3151{
3152 const char *templates[] = {
bbbc206e
BS
3153 "%0 = %h1 * %h2 %M5%!",
3154 "%0 = %d1 * %h2 %M5%!",
3155 "%0 = %h1 * %d2 %M5%!",
3156 "%0 = %d1 * %d2 %M5%!" };
75d8b2d0
BS
3157 int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
3158 return templates[alt];
3159}
3160 [(set_attr "type" "dsp32")])
3161
3efd5670
BS
3162;; Three alternatives here to cover all possible allocations:
3163;; 0. mac flag is usable only for accumulator 1 - use A1 and odd DREG
3164;; 1. mac flag is usable for accumulator 0 - use A0 and even DREG
3165;; 2. mac flag is usable in any accumulator - use A1 and odd DREG
3166;; Other patterns which don't have a DREG destination can collapse cases
3167;; 1 and 2 into one.
75d8b2d0 3168(define_insn "flag_machi"
3efd5670
BS
3169 [(set (match_operand:HI 0 "register_operand" "=W,D,W")
3170 (unspec:HI [(match_operand:HI 2 "register_operand" "d,d,d")
3171 (match_operand:HI 3 "register_operand" "d,d,d")
3172 (match_operand 4 "register_operand" "1,1,1")
3173 (match_operand 5 "const01_operand" "P0P1,P0P1,P0P1")
3174 (match_operand 6 "const_int_operand" "PB,PA,PA")]
75d8b2d0 3175 UNSPEC_MAC_WITH_FLAG))
3efd5670 3176 (set (match_operand:PDI 1 "register_operand" "=B,A,B")
75d8b2d0
BS
3177 (unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)
3178 (match_dup 4) (match_dup 5)]
3179 UNSPEC_MAC_WITH_FLAG))]
3180 ""
3efd5670 3181 "%h0 = (%1 %b5 %h2 * %h3) %M6%!"
75d8b2d0
BS
3182 [(set_attr "type" "dsp32")])
3183
3184(define_insn "flag_machi_acconly"
3efd5670
BS
3185 [(set (match_operand:PDI 0 "register_operand" "=B,e")
3186 (unspec:PDI [(match_operand:HI 1 "register_operand" "d,d")
3187 (match_operand:HI 2 "register_operand" "d,d")
3188 (match_operand 3 "register_operand" "0,0")
3189 (match_operand 4 "const01_operand" "P0P1,P0P1")
3190 (match_operand 5 "const_int_operand" "PB,PA")]
75d8b2d0
BS
3191 UNSPEC_MAC_WITH_FLAG))]
3192 ""
3efd5670
BS
3193 "%0 %b4 %h1 * %h2 %M5%!"
3194 [(set_attr "type" "dsp32")])
3195
3196(define_insn "flag_machi_parts_acconly"
3197 [(set (match_operand:PDI 0 "register_operand" "=B,e")
3198 (unspec:PDI [(vec_select:HI
3199 (match_operand:V2HI 1 "register_operand" "d,d")
3200 (parallel [(match_operand 3 "const01_operand" "P0P1,P0P1")]))
3201 (vec_select:HI
3202 (match_operand:V2HI 2 "register_operand" "d,d")
3203 (parallel [(match_operand 4 "const01_operand" "P0P1,P0P1")]))
3204 (match_operand:PDI 5 "register_operand" "0,0")
3205 (match_operand 6 "const01_operand" "P0P1,P0P1")
3206 (match_operand 7 "const_int_operand" "PB,PA")]
3207 UNSPEC_MAC_WITH_FLAG))]
3208 ""
3209{
3210 const char *templates[] = {
3211 "%0 %b6 %h1 * %h2 %M7%!",
3212 "%0 %b6 %d1 * %h2 %M7%!",
3213 "%0 %b6 %h1 * %d2 %M7%!",
3214 "%0 %b6 %d1 * %d2 %M7%!"
3215 };
3216 int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
3217 return templates[alt];
3218}
75d8b2d0
BS
3219 [(set_attr "type" "dsp32")])
3220
3221(define_insn "flag_macinithi"
3efd5670
BS
3222 [(set (match_operand:HI 0 "register_operand" "=W,D,W")
3223 (unspec:HI [(match_operand:HI 1 "register_operand" "d,d,d")
3224 (match_operand:HI 2 "register_operand" "d,d,d")
3225 (match_operand 3 "const_int_operand" "PB,PA,PA")]
75d8b2d0 3226 UNSPEC_MAC_WITH_FLAG))
3efd5670 3227 (set (match_operand:PDI 4 "register_operand" "=B,A,B")
75d8b2d0
BS
3228 (unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)]
3229 UNSPEC_MAC_WITH_FLAG))]
3230 ""
3efd5670 3231 "%h0 = (%4 = %h1 * %h2) %M3%!"
75d8b2d0
BS
3232 [(set_attr "type" "dsp32")])
3233
3234(define_insn "flag_macinit1hi"
3efd5670
BS
3235 [(set (match_operand:PDI 0 "register_operand" "=B,e")
3236 (unspec:PDI [(match_operand:HI 1 "register_operand" "d,d")
3237 (match_operand:HI 2 "register_operand" "d,d")
3238 (match_operand 3 "const_int_operand" "PB,PA")]
75d8b2d0
BS
3239 UNSPEC_MAC_WITH_FLAG))]
3240 ""
bbbc206e 3241 "%0 = %h1 * %h2 %M3%!"
75d8b2d0
BS
3242 [(set_attr "type" "dsp32")])
3243
c9b3f817 3244(define_insn "mulv2hi3"
0d4a78eb
BS
3245 [(set (match_operand:V2HI 0 "register_operand" "=d")
3246 (mult:V2HI (match_operand:V2HI 1 "register_operand" "d")
3247 (match_operand:V2HI 2 "register_operand" "d")))]
3248 ""
bbbc206e 3249 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 (IS)%!"
0d4a78eb
BS
3250 [(set_attr "type" "dsp32")])
3251
75d8b2d0
BS
3252(define_insn "flag_mulv2hi"
3253 [(set (match_operand:V2HI 0 "register_operand" "=d")
3254 (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "d")
3255 (match_operand:V2HI 2 "register_operand" "d")
3256 (match_operand 3 "const_int_operand" "n")]
3257 UNSPEC_MUL_WITH_FLAG))]
3258 ""
bbbc206e 3259 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 %M3%!"
75d8b2d0
BS
3260 [(set_attr "type" "dsp32")])
3261
3262(define_insn "flag_mulv2hi_parts"
3263 [(set (match_operand:V2HI 0 "register_operand" "=d")
3264 (unspec:V2HI [(vec_concat:V2HI
3265 (vec_select:HI
3266 (match_operand:V2HI 1 "register_operand" "d")
554006bd 3267 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
75d8b2d0
BS
3268 (vec_select:HI
3269 (match_dup 1)
554006bd 3270 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
75d8b2d0
BS
3271 (vec_concat:V2HI
3272 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
554006bd 3273 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
75d8b2d0 3274 (vec_select:HI (match_dup 2)
554006bd 3275 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
75d8b2d0
BS
3276 (match_operand 7 "const_int_operand" "n")]
3277 UNSPEC_MUL_WITH_FLAG))]
3278 ""
3279{
3280 const char *templates[] = {
bbbc206e
BS
3281 "%h0 = %h1 * %h2, %d0 = %h1 * %h2 %M7%!",
3282 "%h0 = %d1 * %h2, %d0 = %h1 * %h2 %M7%!",
3283 "%h0 = %h1 * %h2, %d0 = %d1 * %h2 %M7%!",
3284 "%h0 = %d1 * %h2, %d0 = %d1 * %h2 %M7%!",
3285 "%h0 = %h1 * %d2, %d0 = %h1 * %h2 %M7%!",
3286 "%h0 = %d1 * %d2, %d0 = %h1 * %h2 %M7%!",
3287 "%h0 = %h1 * %d2, %d0 = %d1 * %h2 %M7%!",
3288 "%h0 = %d1 * %d2, %d0 = %d1 * %h2 %M7%!",
3289 "%h0 = %h1 * %h2, %d0 = %h1 * %d2 %M7%!",
3290 "%h0 = %d1 * %h2, %d0 = %h1 * %d2 %M7%!",
3291 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 %M7%!",
3292 "%h0 = %d1 * %h2, %d0 = %d1 * %d2 %M7%!",
3293 "%h0 = %h1 * %d2, %d0 = %h1 * %d2 %M7%!",
3294 "%h0 = %d1 * %d2, %d0 = %h1 * %d2 %M7%!",
3295 "%h0 = %h1 * %d2, %d0 = %d1 * %d2 %M7%!",
3296 "%h0 = %d1 * %d2, %d0 = %d1 * %d2 %M7%!" };
75d8b2d0
BS
3297 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3298 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3299 return templates[alt];
3300}
3301 [(set_attr "type" "dsp32")])
3302
3303;; A slightly complicated pattern.
3304;; Operand 0 is the halfword output; operand 11 is the accumulator output
3305;; Halfword inputs are operands 1 and 2; operands 3, 4, 5 and 6 specify which
3306;; parts of these 2x16 bit registers to use.
3307;; Operand 7 is the accumulator input.
3308;; Operands 8/9 specify whether low/high parts are mac (0) or msu (1)
3309;; Operand 10 is the macflag to be used.
3310(define_insn "flag_macv2hi_parts"
3311 [(set (match_operand:V2HI 0 "register_operand" "=d")
3312 (unspec:V2HI [(vec_concat:V2HI
3313 (vec_select:HI
3314 (match_operand:V2HI 1 "register_operand" "d")
554006bd 3315 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
75d8b2d0
BS
3316 (vec_select:HI
3317 (match_dup 1)
554006bd 3318 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
75d8b2d0
BS
3319 (vec_concat:V2HI
3320 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
554006bd 3321 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
75d8b2d0 3322 (vec_select:HI (match_dup 2)
554006bd 3323 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
75d8b2d0
BS
3324 (match_operand:V2PDI 7 "register_operand" "e")
3325 (match_operand 8 "const01_operand" "P0P1")
3326 (match_operand 9 "const01_operand" "P0P1")
3327 (match_operand 10 "const_int_operand" "n")]
3328 UNSPEC_MAC_WITH_FLAG))
3329 (set (match_operand:V2PDI 11 "register_operand" "=e")
3330 (unspec:V2PDI [(vec_concat:V2HI
3331 (vec_select:HI (match_dup 1) (parallel [(match_dup 3)]))
3332 (vec_select:HI (match_dup 1) (parallel [(match_dup 4)])))
3333 (vec_concat:V2HI
3334 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)]))
3335 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)])))
3336 (match_dup 7) (match_dup 8) (match_dup 9) (match_dup 10)]
3337 UNSPEC_MAC_WITH_FLAG))]
3338 ""
3339{
3340 const char *templates[] = {
bbbc206e
BS
3341 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3342 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3343 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3344 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3345 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3346 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3347 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3348 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3349 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3350 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3351 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %d1 * %d2) %M10%!",
3352 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %d1 * %d2) %M10%!",
3353 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3354 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3355 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %d1 * %d2) %M10%!",
3356 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %d1 * %d2) %M10%!" };
75d8b2d0
BS
3357 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3358 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3359 return templates[alt];
3360}
3361 [(set_attr "type" "dsp32")])
3362
3363(define_insn "flag_macv2hi_parts_acconly"
3364 [(set (match_operand:V2PDI 0 "register_operand" "=e")
3365 (unspec:V2PDI [(vec_concat:V2HI
3366 (vec_select:HI
3367 (match_operand:V2HI 1 "register_operand" "d")
554006bd 3368 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
75d8b2d0
BS
3369 (vec_select:HI
3370 (match_dup 1)
554006bd 3371 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
75d8b2d0
BS
3372 (vec_concat:V2HI
3373 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
554006bd 3374 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
75d8b2d0 3375 (vec_select:HI (match_dup 2)
554006bd 3376 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
75d8b2d0
BS
3377 (match_operand:V2PDI 7 "register_operand" "e")
3378 (match_operand 8 "const01_operand" "P0P1")
3379 (match_operand 9 "const01_operand" "P0P1")
3380 (match_operand 10 "const_int_operand" "n")]
3381 UNSPEC_MAC_WITH_FLAG))]
3382 ""
3383{
3384 const char *templates[] = {
bbbc206e
BS
3385 "A0 %b8 %h1 * %h2, A1 %b9 %h1 * %h2 %M10%!",
3386 "A0 %b8 %d1 * %h2, A1 %b9 %h1 * %h2 %M10%!",
3387 "A0 %b8 %h1 * %h2, A1 %b9 %d1 * %h2 %M10%!",
3388 "A0 %b8 %d1 * %h2, A1 %b9 %d1 * %h2 %M10%!",
3389 "A0 %b8 %h1 * %d2, A1 %b9 %h1 * %h2 %M10%!",
3390 "A0 %b8 %d1 * %d2, A1 %b9 %h1 * %h2 %M10%!",
3391 "A0 %b8 %h1 * %d2, A1 %b9 %d1 * %h2 %M10%!",
3392 "A0 %b8 %d1 * %d2, A1 %b9 %d1 * %h2 %M10%!",
3393 "A0 %b8 %h1 * %h2, A1 %b9 %h1 * %d2 %M10%!",
3394 "A0 %b8 %d1 * %h2, A1 %b9 %h1 * %d2 %M10%!",
3395 "A0 %b8 %h1 * %h2, A1 %b9 %d1 * %d2 %M10%!",
3396 "A0 %b8 %d1 * %h2, A1 %b9 %d1 * %d2 %M10%!",
3397 "A0 %b8 %h1 * %d2, A1 %b9 %h1 * %d2 %M10%!",
3398 "A0 %b8 %d1 * %d2, A1 %b9 %h1 * %d2 %M10%!",
3399 "A0 %b8 %h1 * %d2, A1 %b9 %d1 * %d2 %M10%!",
3400 "A0 %b8 %d1 * %d2, A1 %b9 %d1 * %d2 %M10%!" };
75d8b2d0
BS
3401 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3402 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3403 return templates[alt];
3404}
3405 [(set_attr "type" "dsp32")])
3406
3407;; Same as above, but initializing the accumulators and therefore a couple fewer
3408;; necessary operands.
3409(define_insn "flag_macinitv2hi_parts"
0d4a78eb 3410 [(set (match_operand:V2HI 0 "register_operand" "=d")
75d8b2d0
BS
3411 (unspec:V2HI [(vec_concat:V2HI
3412 (vec_select:HI
3413 (match_operand:V2HI 1 "register_operand" "d")
554006bd 3414 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
75d8b2d0
BS
3415 (vec_select:HI
3416 (match_dup 1)
554006bd 3417 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
75d8b2d0
BS
3418 (vec_concat:V2HI
3419 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
554006bd 3420 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
75d8b2d0 3421 (vec_select:HI (match_dup 2)
554006bd 3422 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
75d8b2d0
BS
3423 (match_operand 7 "const_int_operand" "n")]
3424 UNSPEC_MAC_WITH_FLAG))
3425 (set (match_operand:V2PDI 8 "register_operand" "=e")
3426 (unspec:V2PDI [(vec_concat:V2HI
3427 (vec_select:HI (match_dup 1) (parallel [(match_dup 3)]))
3428 (vec_select:HI (match_dup 1) (parallel [(match_dup 4)])))
3429 (vec_concat:V2HI
3430 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)]))
3431 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)])))
3432 (match_dup 7)]
3433 UNSPEC_MAC_WITH_FLAG))]
3434 ""
3435{
3436 const char *templates[] = {
bbbc206e
BS
3437 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %h1 * %h2) %M7%!",
3438 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %h1 * %h2) %M7%!",
3439 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %d1 * %h2) %M7%!",
3440 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %d1 * %h2) %M7%!",
3441 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %h1 * %h2) %M7%!",
3442 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %h1 * %h2) %M7%!",
3443 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %d1 * %h2) %M7%!",
3444 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %d1 * %h2) %M7%!",
3445 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %h1 * %d2) %M7%!",
3446 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %h1 * %d2) %M7%!",
3447 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %d1 * %d2) %M7%!",
3448 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %d1 * %d2) %M7%!",
3449 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %h1 * %d2) %M7%!",
3450 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %h1 * %d2) %M7%!",
3451 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %d1 * %d2) %M7%!",
3452 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %d1 * %d2) %M7%!" };
75d8b2d0
BS
3453 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3454 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3455 return templates[alt];
3456}
3457 [(set_attr "type" "dsp32")])
3458
3459(define_insn "flag_macinit1v2hi_parts"
3460 [(set (match_operand:V2PDI 0 "register_operand" "=e")
3461 (unspec:V2PDI [(vec_concat:V2HI
3462 (vec_select:HI
3463 (match_operand:V2HI 1 "register_operand" "d")
554006bd 3464 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
75d8b2d0
BS
3465 (vec_select:HI
3466 (match_dup 1)
554006bd 3467 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
75d8b2d0
BS
3468 (vec_concat:V2HI
3469 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
554006bd 3470 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
75d8b2d0 3471 (vec_select:HI (match_dup 2)
554006bd 3472 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
75d8b2d0
BS
3473 (match_operand 7 "const_int_operand" "n")]
3474 UNSPEC_MAC_WITH_FLAG))]
3475 ""
3476{
3477 const char *templates[] = {
bbbc206e
BS
3478 "A0 = %h1 * %h2, A1 = %h1 * %h2 %M7%!",
3479 "A0 = %d1 * %h2, A1 = %h1 * %h2 %M7%!",
3480 "A0 = %h1 * %h2, A1 = %d1 * %h2 %M7%!",
3481 "A0 = %d1 * %h2, A1 = %d1 * %h2 %M7%!",
3482 "A0 = %h1 * %d2, A1 = %h1 * %h2 %M7%!",
3483 "A0 = %d1 * %d2, A1 = %h1 * %h2 %M7%!",
3484 "A0 = %h1 * %d2, A1 = %d1 * %h2 %M7%!",
3485 "A0 = %d1 * %d2, A1 = %d1 * %h2 %M7%!",
3486 "A0 = %h1 * %h2, A1 = %h1 * %d2 %M7%!",
3487 "A0 = %d1 * %h2, A1 = %h1 * %d2 %M7%!",
3488 "A0 = %h1 * %h2, A1 = %d1 * %d2 %M7%!",
3489 "A0 = %d1 * %h2, A1 = %d1 * %d2 %M7%!",
3490 "A0 = %h1 * %d2, A1 = %h1 * %d2 %M7%!",
3491 "A0 = %d1 * %d2, A1 = %h1 * %d2 %M7%!",
3492 "A0 = %h1 * %d2, A1 = %d1 * %d2 %M7%!",
3493 "A0 = %d1 * %d2, A1 = %d1 * %d2 %M7%!" };
75d8b2d0
BS
3494 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3495 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3496 return templates[alt];
3497}
3498 [(set_attr "type" "dsp32")])
3499
3efd5670
BS
3500;; A mixture of multiply and multiply-accumulate for when we only want to
3501;; initialize one part.
3502(define_insn "flag_mul_macv2hi_parts_acconly"
3503 [(set (match_operand:PDI 0 "register_operand" "=B,e,e")
3504 (unspec:PDI [(vec_select:HI
3505 (match_operand:V2HI 2 "register_operand" "d,d,d")
3506 (parallel [(match_operand 4 "const01_operand" "P0P1,P0P1,P0P1")]))
3507 (vec_select:HI
3508 (match_operand:V2HI 3 "register_operand" "d,d,d")
3509 (parallel [(match_operand 6 "const01_operand" "P0P1,P0P1,P0P1")]))
3510 (match_operand 10 "const_int_operand" "PB,PA,PA")]
3511 UNSPEC_MUL_WITH_FLAG))
3512 (set (match_operand:PDI 1 "register_operand" "=B,e,e")
3513 (unspec:PDI [(vec_select:HI
3514 (match_dup 2)
3515 (parallel [(match_operand 5 "const01_operand" "P0P1,P0P1,P0P1")]))
3516 (vec_select:HI
3517 (match_dup 3)
3518 (parallel [(match_operand 7 "const01_operand" "P0P1,P0P1,P0P1")]))
3519 (match_operand:PDI 8 "register_operand" "1,1,1")
3520 (match_operand 9 "const01_operand" "P0P1,P0P1,P0P1")
3521 (match_operand 11 "const_int_operand" "PA,PB,PA")]
3522 UNSPEC_MAC_WITH_FLAG))]
3523 "MACFLAGS_MATCH_P (INTVAL (operands[10]), INTVAL (operands[11]))"
3524{
3525 rtx xops[6];
3526 const char *templates[] = {
3527 "%0 = %h2 * %h3, %1 %b4 %h2 * %h3 %M5%!",
3528 "%0 = %d2 * %h3, %1 %b4 %h2 * %h3 %M5%!",
3529 "%0 = %h2 * %h3, %1 %b4 %d2 * %h3 %M5%!",
3530 "%0 = %d2 * %h3, %1 %b4 %d2 * %h3 %M5%!",
3531 "%0 = %h2 * %d3, %1 %b4 %h2 * %h3 %M5%!",
3532 "%0 = %d2 * %d3, %1 %b4 %h2 * %h3 %M5%!",
3533 "%0 = %h2 * %d3, %1 %b4 %d2 * %h3 %M5%!",
3534 "%0 = %d2 * %d3, %1 %b4 %d2 * %h3 %M5%!",
3535 "%0 = %h2 * %h3, %1 %b4 %h2 * %d3 %M5%!",
3536 "%0 = %d2 * %h3, %1 %b4 %h2 * %d3 %M5%!",
3537 "%0 = %h2 * %h3, %1 %b4 %d2 * %d3 %M5%!",
3538 "%0 = %d2 * %h3, %1 %b4 %d2 * %d3 %M5%!",
3539 "%0 = %h2 * %d3, %1 %b4 %h2 * %d3 %M5%!",
3540 "%0 = %d2 * %d3, %1 %b4 %h2 * %d3 %M5%!",
3541 "%0 = %h2 * %d3, %1 %b4 %d2 * %d3 %M5%!",
3542 "%0 = %d2 * %d3, %1 %b4 %d2 * %d3 %M5%!" };
3543 int alt = (INTVAL (operands[4]) + (INTVAL (operands[5]) << 1)
3544 + (INTVAL (operands[6]) << 2) + (INTVAL (operands[7]) << 3));
3545 xops[0] = operands[0];
3546 xops[1] = operands[1];
3547 xops[2] = operands[2];
3548 xops[3] = operands[3];
3549 xops[4] = operands[9];
3550 xops[5] = which_alternative == 0 ? operands[10] : operands[11];
3551 output_asm_insn (templates[alt], xops);
3552 return "";
3553}
3554 [(set_attr "type" "dsp32")])
3555
3556
2889abed
BS
3557(define_code_macro s_or_u [sign_extend zero_extend])
3558(define_code_attr su_optab [(sign_extend "mul")
3559 (zero_extend "umul")])
3560(define_code_attr su_modifier [(sign_extend "IS")
3561 (zero_extend "FU")])
3562
3563(define_insn "<su_optab>hisi_ll"
75d8b2d0 3564 [(set (match_operand:SI 0 "register_operand" "=d")
2889abed 3565 (mult:SI (s_or_u:SI
75d8b2d0
BS
3566 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3567 (parallel [(const_int 0)])))
2889abed 3568 (s_or_u:SI
75d8b2d0
BS
3569 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3570 (parallel [(const_int 0)])))))]
3571 ""
2889abed 3572 "%0 = %h1 * %h2 (<su_modifier>)%!"
75d8b2d0
BS
3573 [(set_attr "type" "dsp32")])
3574
2889abed 3575(define_insn "<su_optab>hisi_lh"
75d8b2d0 3576 [(set (match_operand:SI 0 "register_operand" "=d")
2889abed
BS
3577 (mult:SI (s_or_u:SI
3578 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
75d8b2d0 3579 (parallel [(const_int 0)])))
2889abed 3580 (s_or_u:SI
75d8b2d0
BS
3581 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3582 (parallel [(const_int 1)])))))]
3583 ""
2889abed 3584 "%0 = %h1 * %d2 (<su_modifier>)%!"
75d8b2d0
BS
3585 [(set_attr "type" "dsp32")])
3586
2889abed 3587(define_insn "<su_optab>hisi_hl"
75d8b2d0 3588 [(set (match_operand:SI 0 "register_operand" "=d")
2889abed
BS
3589 (mult:SI (s_or_u:SI
3590 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3591 (parallel [(const_int 1)])))
3592 (s_or_u:SI
3593 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3594 (parallel [(const_int 0)])))))]
3595 ""
3596 "%0 = %d1 * %h2 (<su_modifier>)%!"
3597 [(set_attr "type" "dsp32")])
3598
3599(define_insn "<su_optab>hisi_hh"
3600 [(set (match_operand:SI 0 "register_operand" "=d")
3601 (mult:SI (s_or_u:SI
75d8b2d0
BS
3602 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3603 (parallel [(const_int 1)])))
2889abed
BS
3604 (s_or_u:SI
3605 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3606 (parallel [(const_int 1)])))))]
3607 ""
3608 "%0 = %d1 * %d2 (<su_modifier>)%!"
3609 [(set_attr "type" "dsp32")])
3610
3611;; Additional variants for signed * unsigned multiply.
3612
3613(define_insn "usmulhisi_ull"
3614 [(set (match_operand:SI 0 "register_operand" "=W")
3615 (mult:SI (zero_extend:SI
3616 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3617 (parallel [(const_int 0)])))
75d8b2d0
BS
3618 (sign_extend:SI
3619 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3620 (parallel [(const_int 0)])))))]
3621 ""
2889abed 3622 "%0 = %h2 * %h1 (IS,M)%!"
75d8b2d0
BS
3623 [(set_attr "type" "dsp32")])
3624
2889abed
BS
3625(define_insn "usmulhisi_ulh"
3626 [(set (match_operand:SI 0 "register_operand" "=W")
3627 (mult:SI (zero_extend:SI
3628 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3629 (parallel [(const_int 0)])))
3630 (sign_extend:SI
3631 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3632 (parallel [(const_int 1)])))))]
3633 ""
3634 "%0 = %d2 * %h1 (IS,M)%!"
3635 [(set_attr "type" "dsp32")])
3636
3637(define_insn "usmulhisi_uhl"
3638 [(set (match_operand:SI 0 "register_operand" "=W")
3639 (mult:SI (zero_extend:SI
3640 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3641 (parallel [(const_int 1)])))
3642 (sign_extend:SI
3643 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3644 (parallel [(const_int 0)])))))]
3645 ""
3646 "%0 = %h2 * %d1 (IS,M)%!"
3647 [(set_attr "type" "dsp32")])
3648
3649(define_insn "usmulhisi_uhh"
3650 [(set (match_operand:SI 0 "register_operand" "=W")
3651 (mult:SI (zero_extend:SI
75d8b2d0
BS
3652 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3653 (parallel [(const_int 1)])))
3654 (sign_extend:SI
3655 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3656 (parallel [(const_int 1)])))))]
3657 ""
2889abed
BS
3658 "%0 = %d2 * %d1 (IS,M)%!"
3659 [(set_attr "type" "dsp32")])
3660
3661;; Parallel versions of these operations. First, normal signed or unsigned
3662;; multiplies.
3663
3664(define_insn "<su_optab>hisi_ll_lh"
3665 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3666 (mult:SI (s_or_u:SI
3667 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3668 (parallel [(const_int 0)])))
3669 (s_or_u:SI
3670 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3671 (parallel [(const_int 0)])))))
3672 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3673 (mult:SI (s_or_u:SI
3674 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3675 (s_or_u:SI
3676 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3677 ""
3678 "%0 = %h1 * %h2, %3 = %h1 * %d2 (<su_modifier>)%!"
3679 [(set_attr "type" "dsp32")])
3680
3681(define_insn "<su_optab>hisi_ll_hl"
3682 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3683 (mult:SI (s_or_u:SI
3684 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3685 (parallel [(const_int 0)])))
3686 (s_or_u:SI
3687 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3688 (parallel [(const_int 0)])))))
3689 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3690 (mult:SI (s_or_u:SI
3691 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3692 (s_or_u:SI
3693 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3694 ""
3695 "%0 = %h1 * %h2, %3 = %d1 * %h2 (<su_modifier>)%!"
3696 [(set_attr "type" "dsp32")])
3697
3698(define_insn "<su_optab>hisi_ll_hh"
3699 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3700 (mult:SI (s_or_u:SI
3701 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3702 (parallel [(const_int 0)])))
3703 (s_or_u:SI
3704 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3705 (parallel [(const_int 0)])))))
3706 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3707 (mult:SI (s_or_u:SI
3708 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3709 (s_or_u:SI
3710 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3711 ""
3712 "%0 = %h1 * %h2, %3 = %d1 * %d2 (<su_modifier>)%!"
3713 [(set_attr "type" "dsp32")])
3714
3715(define_insn "<su_optab>hisi_lh_hl"
3716 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3717 (mult:SI (s_or_u:SI
3718 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3719 (parallel [(const_int 0)])))
3720 (s_or_u:SI
3721 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3722 (parallel [(const_int 1)])))))
3723 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3724 (mult:SI (s_or_u:SI
3725 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3726 (s_or_u:SI
3727 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3728 ""
3729 "%0 = %h1 * %d2, %3 = %d1 * %h2 (<su_modifier>)%!"
3730 [(set_attr "type" "dsp32")])
3731
3732(define_insn "<su_optab>hisi_lh_hh"
3733 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3734 (mult:SI (s_or_u:SI
3735 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3736 (parallel [(const_int 0)])))
3737 (s_or_u:SI
3738 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3739 (parallel [(const_int 1)])))))
3740 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3741 (mult:SI (s_or_u:SI
3742 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3743 (s_or_u:SI
3744 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3745 ""
3746 "%0 = %h1 * %d2, %3 = %d1 * %d2 (<su_modifier>)%!"
3747 [(set_attr "type" "dsp32")])
3748
3749(define_insn "<su_optab>hisi_hl_hh"
3750 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3751 (mult:SI (s_or_u:SI
3752 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3753 (parallel [(const_int 1)])))
3754 (s_or_u:SI
3755 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3756 (parallel [(const_int 0)])))))
3757 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3758 (mult:SI (s_or_u:SI
3759 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3760 (s_or_u:SI
3761 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3762 ""
3763 "%0 = %d1 * %h2, %3 = %d1 * %d2 (<su_modifier>)%!"
3764 [(set_attr "type" "dsp32")])
3765
3766;; Special signed * unsigned variants.
3767
3768(define_insn "usmulhisi_ll_lul"
3769 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3770 (mult:SI (sign_extend:SI
3771 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3772 (parallel [(const_int 0)])))
3773 (sign_extend:SI
3774 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3775 (parallel [(const_int 0)])))))
3776 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3777 (mult:SI (sign_extend:SI
3778 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3779 (zero_extend:SI
3780 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3781 ""
3782 "%0 = %h1 * %h2, %3 = %h1 * %h2 (IS,M)%!"
3783 [(set_attr "type" "dsp32")])
3784
3785(define_insn "usmulhisi_ll_luh"
3786 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3787 (mult:SI (sign_extend:SI
3788 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3789 (parallel [(const_int 0)])))
3790 (sign_extend:SI
3791 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3792 (parallel [(const_int 0)])))))
3793 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3794 (mult:SI (sign_extend:SI
3795 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3796 (zero_extend:SI
3797 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3798 ""
3799 "%0 = %h1 * %h2, %3 = %h1 * %d2 (IS,M)%!"
3800 [(set_attr "type" "dsp32")])
3801
3802(define_insn "usmulhisi_ll_hul"
3803 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3804 (mult:SI (sign_extend:SI
3805 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3806 (parallel [(const_int 0)])))
3807 (sign_extend:SI
3808 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3809 (parallel [(const_int 0)])))))
3810 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3811 (mult:SI (sign_extend:SI
3812 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3813 (zero_extend:SI
3814 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3815 ""
3816 "%0 = %h1 * %h2, %3 = %d1 * %h2 (IS,M)%!"
3817 [(set_attr "type" "dsp32")])
3818
3819(define_insn "usmulhisi_ll_huh"
3820 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3821 (mult:SI (sign_extend:SI
3822 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3823 (parallel [(const_int 0)])))
3824 (sign_extend:SI
3825 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3826 (parallel [(const_int 0)])))))
3827 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3828 (mult:SI (sign_extend:SI
3829 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3830 (zero_extend:SI
3831 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3832 ""
3833 "%0 = %h1 * %h2, %3 = %d1 * %d2 (IS,M)%!"
3834 [(set_attr "type" "dsp32")])
3835
3836(define_insn "usmulhisi_lh_lul"
3837 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3838 (mult:SI (sign_extend:SI
3839 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3840 (parallel [(const_int 0)])))
3841 (sign_extend:SI
3842 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3843 (parallel [(const_int 1)])))))
3844 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3845 (mult:SI (sign_extend:SI
3846 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3847 (zero_extend:SI
3848 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3849 ""
3850 "%0 = %h1 * %d2, %3 = %h1 * %h2 (IS,M)%!"
3851 [(set_attr "type" "dsp32")])
3852
3853(define_insn "usmulhisi_lh_luh"
3854 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3855 (mult:SI (sign_extend:SI
3856 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3857 (parallel [(const_int 0)])))
3858 (sign_extend:SI
3859 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3860 (parallel [(const_int 1)])))))
3861 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3862 (mult:SI (sign_extend:SI
3863 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3864 (zero_extend:SI
3865 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3866 ""
3867 "%0 = %h1 * %d2, %3 = %h1 * %d2 (IS,M)%!"
3868 [(set_attr "type" "dsp32")])
3869
3870(define_insn "usmulhisi_lh_hul"
3871 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3872 (mult:SI (sign_extend:SI
3873 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3874 (parallel [(const_int 0)])))
3875 (sign_extend:SI
3876 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3877 (parallel [(const_int 1)])))))
3878 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3879 (mult:SI (sign_extend:SI
3880 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3881 (zero_extend:SI
3882 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3883 ""
3884 "%0 = %h1 * %d2, %3 = %d1 * %h2 (IS,M)%!"
3885 [(set_attr "type" "dsp32")])
3886
3887(define_insn "usmulhisi_lh_huh"
3888 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3889 (mult:SI (sign_extend:SI
3890 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3891 (parallel [(const_int 0)])))
3892 (sign_extend:SI
3893 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3894 (parallel [(const_int 1)])))))
3895 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3896 (mult:SI (sign_extend:SI
3897 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3898 (zero_extend:SI
3899 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3900 ""
3901 "%0 = %h1 * %d2, %3 = %d1 * %d2 (IS,M)%!"
3902 [(set_attr "type" "dsp32")])
3903
3904(define_insn "usmulhisi_hl_lul"
3905 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3906 (mult:SI (sign_extend:SI
3907 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3908 (parallel [(const_int 1)])))
3909 (sign_extend:SI
3910 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3911 (parallel [(const_int 0)])))))
3912 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3913 (mult:SI (sign_extend:SI
3914 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3915 (zero_extend:SI
3916 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3917 ""
3918 "%0 = %d1 * %h2, %3 = %h1 * %h2 (IS,M)%!"
3919 [(set_attr "type" "dsp32")])
3920
3921(define_insn "usmulhisi_hl_luh"
3922 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3923 (mult:SI (sign_extend:SI
3924 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3925 (parallel [(const_int 1)])))
3926 (sign_extend:SI
3927 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3928 (parallel [(const_int 0)])))))
3929 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3930 (mult:SI (sign_extend:SI
3931 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3932 (zero_extend:SI
3933 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3934 ""
3935 "%0 = %d1 * %h2, %3 = %h1 * %d2 (IS,M)%!"
3936 [(set_attr "type" "dsp32")])
3937
3938(define_insn "usmulhisi_hl_hul"
3939 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3940 (mult:SI (sign_extend:SI
3941 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3942 (parallel [(const_int 1)])))
3943 (sign_extend:SI
3944 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3945 (parallel [(const_int 0)])))))
3946 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3947 (mult:SI (sign_extend:SI
3948 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3949 (zero_extend:SI
3950 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3951 ""
3952 "%0 = %d1 * %h2, %3 = %d1 * %h2 (IS,M)%!"
3953 [(set_attr "type" "dsp32")])
3954
3955(define_insn "usmulhisi_hl_huh"
3956 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3957 (mult:SI (sign_extend:SI
3958 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3959 (parallel [(const_int 1)])))
3960 (sign_extend:SI
3961 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3962 (parallel [(const_int 0)])))))
3963 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3964 (mult:SI (sign_extend:SI
3965 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3966 (zero_extend:SI
3967 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3968 ""
3969 "%0 = %d1 * %h2, %3 = %d1 * %d2 (IS,M)%!"
3970 [(set_attr "type" "dsp32")])
3971
3972(define_insn "usmulhisi_hh_lul"
3973 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3974 (mult:SI (sign_extend:SI
3975 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3976 (parallel [(const_int 1)])))
3977 (sign_extend:SI
3978 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3979 (parallel [(const_int 1)])))))
3980 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3981 (mult:SI (sign_extend:SI
3982 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3983 (zero_extend:SI
3984 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3985 ""
3986 "%0 = %d1 * %d2, %3 = %h1 * %h2 (IS,M)%!"
75d8b2d0
BS
3987 [(set_attr "type" "dsp32")])
3988
2889abed
BS
3989(define_insn "usmulhisi_hh_luh"
3990 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3991 (mult:SI (sign_extend:SI
3992 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3993 (parallel [(const_int 1)])))
3994 (sign_extend:SI
3995 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3996 (parallel [(const_int 1)])))))
3997 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3998 (mult:SI (sign_extend:SI
3999 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
4000 (zero_extend:SI
4001 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
4002 ""
4003 "%0 = %d1 * %d2, %3 = %h1 * %d2 (IS,M)%!"
4004 [(set_attr "type" "dsp32")])
4005
4006(define_insn "usmulhisi_hh_hul"
4007 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4008 (mult:SI (sign_extend:SI
4009 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4010 (parallel [(const_int 1)])))
4011 (sign_extend:SI
4012 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4013 (parallel [(const_int 1)])))))
4014 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4015 (mult:SI (sign_extend:SI
4016 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4017 (zero_extend:SI
4018 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
4019 ""
4020 "%0 = %d1 * %d2, %3 = %d1 * %h2 (IS,M)%!"
4021 [(set_attr "type" "dsp32")])
4022
4023(define_insn "usmulhisi_hh_huh"
4024 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4025 (mult:SI (sign_extend:SI
4026 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4027 (parallel [(const_int 1)])))
4028 (sign_extend:SI
4029 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4030 (parallel [(const_int 1)])))))
4031 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4032 (mult:SI (sign_extend:SI
4033 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4034 (zero_extend:SI
4035 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
4036 ""
4037 "%0 = %d1 * %d2, %3 = %d1 * %d2 (IS,M)%!"
4038 [(set_attr "type" "dsp32")])
4039
4040;; Vector neg/abs.
4041
75d8b2d0
BS
4042(define_insn "ssnegv2hi2"
4043 [(set (match_operand:V2HI 0 "register_operand" "=d")
4044 (ss_neg:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
0d4a78eb 4045 ""
bbbc206e 4046 "%0 = - %1 (V)%!"
0d4a78eb
BS
4047 [(set_attr "type" "dsp32")])
4048
26c5953d 4049(define_insn "ssabsv2hi2"
0d4a78eb 4050 [(set (match_operand:V2HI 0 "register_operand" "=d")
26c5953d 4051 (ss_abs:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
0d4a78eb 4052 ""
bbbc206e 4053 "%0 = ABS %1 (V)%!"
0d4a78eb
BS
4054 [(set_attr "type" "dsp32")])
4055
75d8b2d0
BS
4056;; Shifts.
4057
4058(define_insn "ssashiftv2hi3"
4059 [(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
4060 (if_then_else:V2HI
26c5953d 4061 (lt (match_operand:HI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
75d8b2d0
BS
4062 (ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" "d,d,d")
4063 (match_dup 2))
4064 (ss_ashift:V2HI (match_dup 1) (match_dup 2))))]
4065 ""
4066 "@
329437dd 4067 %0 = ASHIFT %1 BY %h2 (V, S)%!
58f76679
BS
4068 %0 = %1 << %2 (V,S)%!
4069 %0 = %1 >>> %N2 (V,S)%!"
75d8b2d0
BS
4070 [(set_attr "type" "dsp32")])
4071
4072(define_insn "ssashifthi3"
4073 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
4074 (if_then_else:HI
26c5953d 4075 (lt (match_operand:HI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
75d8b2d0
BS
4076 (ashiftrt:HI (match_operand:HI 1 "register_operand" "d,d,d")
4077 (match_dup 2))
4078 (ss_ashift:HI (match_dup 1) (match_dup 2))))]
4079 ""
4080 "@
329437dd 4081 %0 = ASHIFT %1 BY %h2 (V, S)%!
58f76679
BS
4082 %0 = %1 << %2 (V,S)%!
4083 %0 = %1 >>> %N2 (V,S)%!"
75d8b2d0
BS
4084 [(set_attr "type" "dsp32")])
4085
26c5953d
BS
4086(define_insn "ssashiftsi3"
4087 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
4088 (if_then_else:SI
4089 (lt (match_operand:HI 2 "reg_or_const_int_operand" "d,Ku5,Ks5") (const_int 0))
4090 (ashiftrt:SI (match_operand:HI 1 "register_operand" "d,d,d")
4091 (match_dup 2))
4092 (ss_ashift:SI (match_dup 1) (match_dup 2))))]
4093 ""
4094 "@
4095 %0 = ASHIFT %1 BY %h2 (S)%!
4096 %0 = %1 << %2 (S)%!
4097 %0 = %1 >>> %N2 (S)%!"
4098 [(set_attr "type" "dsp32")])
4099
75d8b2d0
BS
4100(define_insn "lshiftv2hi3"
4101 [(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
4102 (if_then_else:V2HI
26c5953d 4103 (lt (match_operand:HI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
75d8b2d0
BS
4104 (lshiftrt:V2HI (match_operand:V2HI 1 "register_operand" "d,d,d")
4105 (match_dup 2))
4106 (ashift:V2HI (match_dup 1) (match_dup 2))))]
4107 ""
4108 "@
329437dd 4109 %0 = LSHIFT %1 BY %h2 (V)%!
58f76679
BS
4110 %0 = %1 << %2 (V)%!
4111 %0 = %1 >> %N2 (V)%!"
75d8b2d0
BS
4112 [(set_attr "type" "dsp32")])
4113
4114(define_insn "lshifthi3"
4115 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
4116 (if_then_else:HI
26c5953d 4117 (lt (match_operand:HI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
75d8b2d0
BS
4118 (lshiftrt:HI (match_operand:HI 1 "register_operand" "d,d,d")
4119 (match_dup 2))
4120 (ashift:HI (match_dup 1) (match_dup 2))))]
4121 ""
4122 "@
329437dd 4123 %0 = LSHIFT %1 BY %h2 (V)%!
58f76679
BS
4124 %0 = %1 << %2 (V)%!
4125 %0 = %1 >> %N2 (V)%!"
75d8b2d0
BS
4126 [(set_attr "type" "dsp32")])
4127