]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/bfin/bfin.md
regclass.c (scan_one_insn): Remove splitting of two address insns.
[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
0d4a78eb
BS
1365(define_insn "negsi2"
1366 [(set (match_operand:SI 0 "register_operand" "=d")
75d8b2d0 1367 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
0d4a78eb 1368 ""
75d8b2d0 1369 "%0 = -%1;"
0d4a78eb
BS
1370 [(set_attr "type" "alu0")])
1371
75d8b2d0
BS
1372(define_insn "ssnegsi2"
1373 [(set (match_operand:SI 0 "register_operand" "=d")
1374 (ss_neg:SI (match_operand:SI 1 "register_operand" "d")))]
1375 ""
bbbc206e 1376 "%0 = -%1 (S)%!"
75d8b2d0
BS
1377 [(set_attr "type" "dsp32")])
1378
0d4a78eb
BS
1379(define_insn "one_cmplsi2"
1380 [(set (match_operand:SI 0 "register_operand" "=d")
75d8b2d0 1381 (not:SI (match_operand:SI 1 "register_operand" "d")))]
0d4a78eb 1382 ""
75d8b2d0 1383 "%0 = ~%1;"
0d4a78eb
BS
1384 [(set_attr "type" "alu0")])
1385
75d8b2d0
BS
1386(define_insn "signbitssi2"
1387 [(set (match_operand:HI 0 "register_operand" "=d")
1388 (if_then_else:HI
1389 (lt (match_operand:SI 1 "register_operand" "d") (const_int 0))
1390 (clz:HI (not:SI (match_dup 1)))
1391 (clz:HI (match_dup 1))))]
1392 ""
bbbc206e 1393 "%h0 = signbits %1%!"
75d8b2d0
BS
1394 [(set_attr "type" "dsp32")])
1395
1396(define_insn "smaxhi3"
1397 [(set (match_operand:HI 0 "register_operand" "=d")
1398 (smax:HI (match_operand:HI 1 "register_operand" "d")
1399 (match_operand:HI 2 "register_operand" "d")))]
1400 ""
bbbc206e 1401 "%0 = max(%1,%2) (V)%!"
75d8b2d0
BS
1402 [(set_attr "type" "dsp32")])
1403
1404(define_insn "sminhi3"
1405 [(set (match_operand:HI 0 "register_operand" "=d")
1406 (smin:HI (match_operand:HI 1 "register_operand" "d")
1407 (match_operand:HI 2 "register_operand" "d")))]
1408 ""
bbbc206e 1409 "%0 = min(%1,%2) (V)%!"
75d8b2d0
BS
1410 [(set_attr "type" "dsp32")])
1411
1412(define_insn "abshi2"
1413 [(set (match_operand:HI 0 "register_operand" "=d")
1414 (abs:HI (match_operand:HI 1 "register_operand" "d")))]
1415 ""
bbbc206e 1416 "%0 = abs %1 (V)%!"
75d8b2d0
BS
1417 [(set_attr "type" "dsp32")])
1418
1419(define_insn "neghi2"
1420 [(set (match_operand:HI 0 "register_operand" "=d")
1421 (neg:HI (match_operand:HI 1 "register_operand" "d")))]
1422 ""
1423 "%0 = -%1;"
bbbc206e 1424 [(set_attr "type" "alu0")])
75d8b2d0
BS
1425
1426(define_insn "ssneghi2"
1427 [(set (match_operand:HI 0 "register_operand" "=d")
1428 (ss_neg:HI (match_operand:HI 1 "register_operand" "d")))]
1429 ""
bbbc206e 1430 "%0 = -%1 (V)%!"
75d8b2d0
BS
1431 [(set_attr "type" "dsp32")])
1432
1433(define_insn "signbitshi2"
1434 [(set (match_operand:HI 0 "register_operand" "=d")
1435 (if_then_else:HI
1436 (lt (match_operand:HI 1 "register_operand" "d") (const_int 0))
1437 (clz:HI (not:HI (match_dup 1)))
1438 (clz:HI (match_dup 1))))]
1439 ""
bbbc206e 1440 "%h0 = signbits %h1%!"
75d8b2d0
BS
1441 [(set_attr "type" "dsp32")])
1442
0d4a78eb
BS
1443(define_insn "mulsi3"
1444 [(set (match_operand:SI 0 "register_operand" "=d")
1445 (mult:SI (match_operand:SI 1 "register_operand" "%0")
1446 (match_operand:SI 2 "register_operand" "d")))]
1447 ""
75d8b2d0 1448 "%0 *= %2;"
0d4a78eb
BS
1449 [(set_attr "type" "mult")])
1450
01e7cd6e 1451(define_expand "umulsi3_highpart"
3fbee523
BS
1452 [(parallel
1453 [(set (match_operand:SI 0 "register_operand" "")
1454 (truncate:SI
1455 (lshiftrt:DI
1456 (mult:DI (zero_extend:DI
1457 (match_operand:SI 1 "nonimmediate_operand" ""))
1458 (zero_extend:DI
1459 (match_operand:SI 2 "register_operand" "")))
1460 (const_int 32))))
1461 (clobber (reg:PDI REG_A0))
1462 (clobber (reg:PDI REG_A1))])]
01e7cd6e
BS
1463 ""
1464{
3fbee523
BS
1465 if (!optimize_size)
1466 {
1467 rtx a1reg = gen_rtx_REG (PDImode, REG_A1);
1468 rtx a0reg = gen_rtx_REG (PDImode, REG_A0);
1469 emit_insn (gen_flag_macinit1hi (a1reg,
1470 gen_lowpart (HImode, operands[1]),
1471 gen_lowpart (HImode, operands[2]),
1472 GEN_INT (MACFLAG_FU)));
1473 emit_insn (gen_lshrpdi3 (a1reg, a1reg, GEN_INT (16)));
1474 emit_insn (gen_flag_mul_macv2hi_parts_acconly (a0reg, a1reg,
1475 gen_lowpart (V2HImode, operands[1]),
1476 gen_lowpart (V2HImode, operands[2]),
1477 const1_rtx, const1_rtx,
1478 const1_rtx, const0_rtx, a1reg,
1479 const0_rtx, GEN_INT (MACFLAG_FU),
1480 GEN_INT (MACFLAG_FU)));
1481 emit_insn (gen_flag_machi_parts_acconly (a1reg,
1482 gen_lowpart (V2HImode, operands[2]),
1483 gen_lowpart (V2HImode, operands[1]),
1484 const1_rtx, const0_rtx,
1485 a1reg, const0_rtx, GEN_INT (MACFLAG_FU)));
1486 emit_insn (gen_lshrpdi3 (a1reg, a1reg, GEN_INT (16)));
1487 emit_insn (gen_sum_of_accumulators (operands[0], a0reg, a0reg, a1reg));
1488 }
1489 else
1490 {
1491 rtx umulsi3_highpart_libfunc
1492 = init_one_libfunc ("__umulsi3_highpart");
01e7cd6e 1493
3fbee523
BS
1494 emit_library_call_value (umulsi3_highpart_libfunc,
1495 operands[0], LCT_NORMAL, SImode,
1496 2, operands[1], SImode, operands[2], SImode);
1497 }
01e7cd6e
BS
1498 DONE;
1499})
1500
1501(define_expand "smulsi3_highpart"
3fbee523
BS
1502 [(parallel
1503 [(set (match_operand:SI 0 "register_operand" "")
1504 (truncate:SI
1505 (lshiftrt:DI
1506 (mult:DI (sign_extend:DI
1507 (match_operand:SI 1 "nonimmediate_operand" ""))
1508 (sign_extend:DI
1509 (match_operand:SI 2 "register_operand" "")))
1510 (const_int 32))))
1511 (clobber (reg:PDI REG_A0))
1512 (clobber (reg:PDI REG_A1))])]
01e7cd6e
BS
1513 ""
1514{
3fbee523
BS
1515 if (!optimize_size)
1516 {
1517 rtx a1reg = gen_rtx_REG (PDImode, REG_A1);
1518 rtx a0reg = gen_rtx_REG (PDImode, REG_A0);
1519 emit_insn (gen_flag_macinit1hi (a1reg,
1520 gen_lowpart (HImode, operands[1]),
1521 gen_lowpart (HImode, operands[2]),
1522 GEN_INT (MACFLAG_FU)));
1523 emit_insn (gen_lshrpdi3 (a1reg, a1reg, GEN_INT (16)));
1524 emit_insn (gen_flag_mul_macv2hi_parts_acconly (a0reg, a1reg,
1525 gen_lowpart (V2HImode, operands[1]),
1526 gen_lowpart (V2HImode, operands[2]),
1527 const1_rtx, const1_rtx,
1528 const1_rtx, const0_rtx, a1reg,
1529 const0_rtx, GEN_INT (MACFLAG_IS),
1530 GEN_INT (MACFLAG_IS_M)));
1531 emit_insn (gen_flag_machi_parts_acconly (a1reg,
1532 gen_lowpart (V2HImode, operands[2]),
1533 gen_lowpart (V2HImode, operands[1]),
1534 const1_rtx, const0_rtx,
1535 a1reg, const0_rtx, GEN_INT (MACFLAG_IS_M)));
1536 emit_insn (gen_ashrpdi3 (a1reg, a1reg, GEN_INT (16)));
1537 emit_insn (gen_sum_of_accumulators (operands[0], a0reg, a0reg, a1reg));
1538 }
1539 else
1540 {
1541 rtx smulsi3_highpart_libfunc
1542 = init_one_libfunc ("__smulsi3_highpart");
01e7cd6e 1543
3fbee523
BS
1544 emit_library_call_value (smulsi3_highpart_libfunc,
1545 operands[0], LCT_NORMAL, SImode,
1546 2, operands[1], SImode, operands[2], SImode);
1547 }
01e7cd6e
BS
1548 DONE;
1549})
1550
0d4a78eb
BS
1551(define_expand "ashlsi3"
1552 [(set (match_operand:SI 0 "register_operand" "")
1553 (ashift:SI (match_operand:SI 1 "register_operand" "")
1554 (match_operand:SI 2 "nonmemory_operand" "")))]
1555 ""
1556{
1557 if (GET_CODE (operands[2]) == CONST_INT
1558 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1559 {
1560 emit_insn (gen_movsi (operands[0], const0_rtx));
1561 DONE;
1562 }
1563})
1564
1565(define_insn_and_split "*ashlsi3_insn"
bbbc206e
BS
1566 [(set (match_operand:SI 0 "register_operand" "=d,d,a,a,a")
1567 (ashift:SI (match_operand:SI 1 "register_operand" "0,d,a,a,a")
1568 (match_operand:SI 2 "nonmemory_operand" "dKu5,Ku5,P1,P2,?P3P4")))]
0d4a78eb
BS
1569 ""
1570 "@
1571 %0 <<= %2;
bbbc206e 1572 %0 = %1 << %2%!
0d4a78eb
BS
1573 %0 = %1 + %1;
1574 %0 = %1 << %2;
1575 #"
1576 "PREG_P (operands[0]) && INTVAL (operands[2]) > 2"
1577 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
1578 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
1579 "operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
bbbc206e 1580 [(set_attr "type" "shft,dsp32,shft,shft,*")])
0d4a78eb
BS
1581
1582(define_insn "ashrsi3"
bbbc206e
BS
1583 [(set (match_operand:SI 0 "register_operand" "=d,d")
1584 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
1585 (match_operand:SI 2 "nonmemory_operand" "dKu5,Ku5")))]
0d4a78eb 1586 ""
bbbc206e
BS
1587 "@
1588 %0 >>>= %2;
1589 %0 = %1 >>> %2%!"
1590 [(set_attr "type" "shft,dsp32")])
0d4a78eb 1591
97130915
BS
1592(define_insn "rotl16"
1593 [(set (match_operand:SI 0 "register_operand" "=d")
1594 (rotate:SI (match_operand:SI 1 "register_operand" "d")
1595 (const_int 16)))]
1596 ""
1597 "%0 = PACK (%h1, %d1)%!"
1598 [(set_attr "type" "dsp32")])
1599
1600(define_expand "rotlsi3"
1601 [(set (match_operand:SI 0 "register_operand" "")
1602 (rotate:SI (match_operand:SI 1 "register_operand" "")
1603 (match_operand:SI 2 "immediate_operand" "")))]
1604 ""
1605{
1606 if (INTVAL (operands[2]) != 16)
1607 FAIL;
1608})
1609
1610(define_expand "rotrsi3"
1611 [(set (match_operand:SI 0 "register_operand" "")
1612 (rotatert:SI (match_operand:SI 1 "register_operand" "")
1613 (match_operand:SI 2 "immediate_operand" "")))]
1614 ""
1615{
1616 if (INTVAL (operands[2]) != 16)
1617 FAIL;
1618 emit_insn (gen_rotl16 (operands[0], operands[1]));
1619 DONE;
1620})
1621
1622
49373252
BS
1623(define_insn "ror_one"
1624 [(set (match_operand:SI 0 "register_operand" "=d")
1625 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1626 (ashift:SI (zero_extend:SI (reg:BI REG_CC)) (const_int 31))))
1627 (set (reg:BI REG_CC)
1628 (zero_extract:BI (match_dup 1) (const_int 1) (const_int 0)))]
1629 ""
bbbc206e
BS
1630 "%0 = ROT %1 BY -1%!"
1631 [(set_attr "type" "dsp32")])
49373252
BS
1632
1633(define_insn "rol_one"
1634 [(set (match_operand:SI 0 "register_operand" "+d")
1635 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1636 (zero_extend:SI (reg:BI REG_CC))))
1637 (set (reg:BI REG_CC)
1638 (zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))]
1639 ""
bbbc206e
BS
1640 "%0 = ROT %1 BY 1%!"
1641 [(set_attr "type" "dsp32")])
49373252
BS
1642
1643(define_expand "lshrdi3"
1644 [(set (match_operand:DI 0 "register_operand" "")
1645 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1646 (match_operand:DI 2 "general_operand" "")))]
1647 ""
1648{
1649 rtx lo_half[2], hi_half[2];
1650
1651 if (operands[2] != const1_rtx)
1652 FAIL;
1653 if (! rtx_equal_p (operands[0], operands[1]))
1654 emit_move_insn (operands[0], operands[1]);
1655
1656 split_di (operands, 2, lo_half, hi_half);
1657
1658 emit_move_insn (bfin_cc_rtx, const0_rtx);
1659 emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1660 emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1661 DONE;
1662})
1663
1664(define_expand "ashrdi3"
1665 [(set (match_operand:DI 0 "register_operand" "")
1666 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1667 (match_operand:DI 2 "general_operand" "")))]
1668 ""
1669{
1670 rtx lo_half[2], hi_half[2];
1671
1672 if (operands[2] != const1_rtx)
1673 FAIL;
1674 if (! rtx_equal_p (operands[0], operands[1]))
1675 emit_move_insn (operands[0], operands[1]);
1676
1677 split_di (operands, 2, lo_half, hi_half);
1678
1679 emit_insn (gen_compare_lt (gen_rtx_REG (BImode, REG_CC),
1680 hi_half[1], const0_rtx));
1681 emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1682 emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1683 DONE;
1684})
1685
1686(define_expand "ashldi3"
1687 [(set (match_operand:DI 0 "register_operand" "")
1688 (ashift:DI (match_operand:DI 1 "register_operand" "")
1689 (match_operand:DI 2 "general_operand" "")))]
1690 ""
1691{
1692 rtx lo_half[2], hi_half[2];
1693
1694 if (operands[2] != const1_rtx)
1695 FAIL;
1696 if (! rtx_equal_p (operands[0], operands[1]))
1697 emit_move_insn (operands[0], operands[1]);
1698
1699 split_di (operands, 2, lo_half, hi_half);
1700
1701 emit_move_insn (bfin_cc_rtx, const0_rtx);
1702 emit_insn (gen_rol_one (lo_half[0], lo_half[0]));
1703 emit_insn (gen_rol_one (hi_half[0], hi_half[0]));
1704 DONE;
1705})
1706
0d4a78eb 1707(define_insn "lshrsi3"
bbbc206e
BS
1708 [(set (match_operand:SI 0 "register_operand" "=d,d,a")
1709 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d,a")
1710 (match_operand:SI 2 "nonmemory_operand" "dKu5,Ku5,P1P2")))]
0d4a78eb
BS
1711 ""
1712 "@
1713 %0 >>= %2;
bbbc206e 1714 %0 = %1 >> %2%!
0d4a78eb 1715 %0 = %1 >> %2;"
bbbc206e 1716 [(set_attr "type" "shft,dsp32,shft")])
0d4a78eb 1717
3efd5670
BS
1718(define_insn "lshrpdi3"
1719 [(set (match_operand:PDI 0 "register_operand" "=e")
1720 (lshiftrt:PDI (match_operand:PDI 1 "register_operand" "0")
1721 (match_operand:SI 2 "nonmemory_operand" "Ku5")))]
1722 ""
1723 "%0 = %1 >> %2%!"
1724 [(set_attr "type" "dsp32")])
1725
1726(define_insn "ashrpdi3"
1727 [(set (match_operand:PDI 0 "register_operand" "=e")
1728 (ashiftrt:PDI (match_operand:PDI 1 "register_operand" "0")
1729 (match_operand:SI 2 "nonmemory_operand" "Ku5")))]
1730 ""
1731 "%0 = %1 >>> %2%!"
1732 [(set_attr "type" "dsp32")])
1733
0d4a78eb
BS
1734;; A pattern to reload the equivalent of
1735;; (set (Dreg) (plus (FP) (large_constant)))
1736;; or
1737;; (set (dagreg) (plus (FP) (arbitrary_constant)))
1738;; using a scratch register
1739(define_expand "reload_insi"
1740 [(parallel [(set (match_operand:SI 0 "register_operand" "=w")
1741 (match_operand:SI 1 "fp_plus_const_operand" ""))
1742 (clobber (match_operand:SI 2 "register_operand" "=&a"))])]
1743 ""
1744{
1745 rtx fp_op = XEXP (operands[1], 0);
1746 rtx const_op = XEXP (operands[1], 1);
1747 rtx primary = operands[0];
1748 rtx scratch = operands[2];
1749
1750 emit_move_insn (scratch, const_op);
1751 emit_insn (gen_addsi3 (scratch, scratch, fp_op));
1752 emit_move_insn (primary, scratch);
1753 DONE;
1754})
1755
1756;; Jump instructions
1757
1758(define_insn "jump"
1759 [(set (pc)
1760 (label_ref (match_operand 0 "" "")))]
1761 ""
1762{
1763 if (get_attr_length (insn) == 2)
1764 return "jump.s %0;";
1765 else
1766 return "jump.l %0;";
1767}
1768 [(set_attr "type" "br")])
1769
1770(define_insn "indirect_jump"
1771 [(set (pc)
1772 (match_operand:SI 0 "register_operand" "a"))]
1773 ""
1774 "jump (%0);"
1775 [(set_attr "type" "misc")])
1776
1777(define_expand "tablejump"
1778 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1779 (use (label_ref (match_operand 1 "" "")))])]
1780 ""
1781{
1782 /* In PIC mode, the table entries are stored PC relative.
1783 Convert the relative address to an absolute address. */
1784 if (flag_pic)
1785 {
1786 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1787
1788 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1789 op1, NULL_RTX, 0, OPTAB_DIRECT);
1790 }
1791})
1792
1793(define_insn "*tablejump_internal"
1794 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1795 (use (label_ref (match_operand 1 "" "")))]
1796 ""
1797 "jump (%0);"
1798 [(set_attr "type" "misc")])
1799
b03149e1
JZ
1800;; Hardware loop
1801
1802; operand 0 is the loop count pseudo register
1803; operand 1 is the number of loop iterations or 0 if it is unknown
1804; operand 2 is the maximum number of loop iterations
1805; operand 3 is the number of levels of enclosed loops
1806; operand 4 is the label to jump to at the top of the loop
1807(define_expand "doloop_end"
1808 [(parallel [(set (pc) (if_then_else
1809 (ne (match_operand:SI 0 "" "")
1810 (const_int 1))
1811 (label_ref (match_operand 4 "" ""))
1812 (pc)))
1813 (set (match_dup 0)
1814 (plus:SI (match_dup 0)
1815 (const_int -1)))
1816 (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1817 (clobber (match_scratch:SI 5 ""))])]
1818 ""
0a8f8c45 1819{
9b02a95e
BS
1820 /* The loop optimizer doesn't check the predicates... */
1821 if (GET_MODE (operands[0]) != SImode)
1822 FAIL;
0a8f8c45
BS
1823 /* Due to limitations in the hardware (an initial loop count of 0
1824 does not loop 2^32 times) we must avoid to generate a hardware
1825 loops when we cannot rule out this case. */
0a8f8c45
BS
1826 if (!flag_unsafe_loop_optimizations
1827 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 0xFFFFFFFF)
1828 FAIL;
1829 bfin_hardware_loop ();
1830})
b03149e1
JZ
1831
1832(define_insn "loop_end"
1833 [(set (pc)
a9c46998 1834 (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+a*d,*b*v*f,m")
b03149e1
JZ
1835 (const_int 1))
1836 (label_ref (match_operand 1 "" ""))
1837 (pc)))
1838 (set (match_dup 0)
1839 (plus (match_dup 0)
1840 (const_int -1)))
1841 (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1842 (clobber (match_scratch:SI 2 "=X,&r,&r"))]
1843 ""
1844 "@
1845 /* loop end %0 %l1 */
1846 #
1847 #"
1848 [(set_attr "length" "6,10,14")])
1849
1850(define_split
1851 [(set (pc)
1852 (if_then_else (ne (match_operand:SI 0 "nondp_reg_or_memory_operand" "")
1853 (const_int 1))
1854 (label_ref (match_operand 1 "" ""))
1855 (pc)))
1856 (set (match_dup 0)
1857 (plus (match_dup 0)
1858 (const_int -1)))
1859 (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1860 (clobber (match_scratch:SI 2 "=&r"))]
1861 "reload_completed"
1862 [(set (match_dup 2) (match_dup 0))
1863 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
1864 (set (match_dup 0) (match_dup 2))
1865 (set (reg:BI REG_CC) (eq:BI (match_dup 2) (const_int 0)))
1866 (set (pc)
1867 (if_then_else (eq (reg:BI REG_CC)
1868 (const_int 0))
1869 (label_ref (match_dup 1))
1870 (pc)))]
1871 "")
1872
1873(define_insn "lsetup_with_autoinit"
1874 [(set (match_operand:SI 0 "lt_register_operand" "=t")
1875 (label_ref (match_operand 1 "" "")))
a9c46998 1876 (set (match_operand:SI 2 "lb_register_operand" "=u")
b03149e1
JZ
1877 (label_ref (match_operand 3 "" "")))
1878 (set (match_operand:SI 4 "lc_register_operand" "=k")
1879 (match_operand:SI 5 "register_operand" "a"))]
1880 ""
1881 "LSETUP (%1, %3) %4 = %5;"
1882 [(set_attr "length" "4")])
1883
1884(define_insn "lsetup_without_autoinit"
1885 [(set (match_operand:SI 0 "lt_register_operand" "=t")
1886 (label_ref (match_operand 1 "" "")))
a9c46998 1887 (set (match_operand:SI 2 "lb_register_operand" "=u")
b03149e1
JZ
1888 (label_ref (match_operand 3 "" "")))
1889 (use (match_operand:SI 4 "lc_register_operand" "k"))]
1890 ""
1891 "LSETUP (%1, %3) %4;"
1892 [(set_attr "length" "4")])
1893
0d4a78eb
BS
1894;; Call instructions..
1895
6614f9f5
BS
1896;; The explicit MEM inside the UNSPEC prevents the compiler from moving
1897;; the load before a branch after a NULL test, or before a store that
1898;; initializes a function descriptor.
1899
1900(define_insn_and_split "load_funcdescsi"
1901 [(set (match_operand:SI 0 "register_operand" "=a")
1902 (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
1903 UNSPEC_VOLATILE_LOAD_FUNCDESC))]
1904 ""
1905 "#"
1906 "reload_completed"
1907 [(set (match_dup 0) (mem:SI (match_dup 1)))])
1908
0d4a78eb 1909(define_expand "call"
6d459e2b
BS
1910 [(parallel [(call (match_operand:SI 0 "" "")
1911 (match_operand 1 "" ""))
1912 (use (match_operand 2 "" ""))])]
0d4a78eb 1913 ""
6d459e2b
BS
1914{
1915 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 0);
1916 DONE;
1917})
0d4a78eb
BS
1918
1919(define_expand "sibcall"
1920 [(parallel [(call (match_operand:SI 0 "" "")
1921 (match_operand 1 "" ""))
6d459e2b 1922 (use (match_operand 2 "" ""))
0d4a78eb
BS
1923 (return)])]
1924 ""
6d459e2b
BS
1925{
1926 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 1);
1927 DONE;
1928})
0d4a78eb
BS
1929
1930(define_expand "call_value"
6d459e2b
BS
1931 [(parallel [(set (match_operand 0 "register_operand" "")
1932 (call (match_operand:SI 1 "" "")
1933 (match_operand 2 "" "")))
1934 (use (match_operand 3 "" ""))])]
0d4a78eb 1935 ""
6d459e2b
BS
1936{
1937 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 0);
1938 DONE;
1939})
0d4a78eb
BS
1940
1941(define_expand "sibcall_value"
1942 [(parallel [(set (match_operand 0 "register_operand" "")
1943 (call (match_operand:SI 1 "" "")
1944 (match_operand 2 "" "")))
6d459e2b 1945 (use (match_operand 3 "" ""))
0d4a78eb
BS
1946 (return)])]
1947 ""
6d459e2b
BS
1948{
1949 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 1);
1950 DONE;
1951})
0d4a78eb 1952
6614f9f5
BS
1953(define_insn "*call_symbol_fdpic"
1954 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1955 (match_operand 1 "general_operand" "g"))
1956 (use (match_operand:SI 2 "register_operand" "Z"))
1957 (use (match_operand 3 "" ""))]
1958 "! SIBLING_CALL_P (insn)
1959 && GET_CODE (operands[0]) == SYMBOL_REF
1960 && !bfin_longcall_p (operands[0], INTVAL (operands[3]))"
1961 "call %0;"
1962 [(set_attr "type" "call")
1963 (set_attr "length" "4")])
1964
1965(define_insn "*sibcall_symbol_fdpic"
1966 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1967 (match_operand 1 "general_operand" "g"))
1968 (use (match_operand:SI 2 "register_operand" "Z"))
1969 (use (match_operand 3 "" ""))
1970 (return)]
1971 "SIBLING_CALL_P (insn)
1972 && GET_CODE (operands[0]) == SYMBOL_REF
1973 && !bfin_longcall_p (operands[0], INTVAL (operands[3]))"
1974 "jump.l %0;"
1975 [(set_attr "type" "br")
1976 (set_attr "length" "4")])
1977
1978(define_insn "*call_value_symbol_fdpic"
1979 [(set (match_operand 0 "register_operand" "=d")
1980 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1981 (match_operand 2 "general_operand" "g")))
1982 (use (match_operand:SI 3 "register_operand" "Z"))
1983 (use (match_operand 4 "" ""))]
1984 "! SIBLING_CALL_P (insn)
1985 && GET_CODE (operands[1]) == SYMBOL_REF
1986 && !bfin_longcall_p (operands[1], INTVAL (operands[4]))"
1987 "call %1;"
1988 [(set_attr "type" "call")
1989 (set_attr "length" "4")])
1990
1991(define_insn "*sibcall_value_symbol_fdpic"
1992 [(set (match_operand 0 "register_operand" "=d")
1993 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1994 (match_operand 2 "general_operand" "g")))
1995 (use (match_operand:SI 3 "register_operand" "Z"))
1996 (use (match_operand 4 "" ""))
1997 (return)]
1998 "SIBLING_CALL_P (insn)
1999 && GET_CODE (operands[1]) == SYMBOL_REF
2000 && !bfin_longcall_p (operands[1], INTVAL (operands[4]))"
2001 "jump.l %1;"
2002 [(set_attr "type" "br")
2003 (set_attr "length" "4")])
2004
2005(define_insn "*call_insn_fdpic"
2006 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y"))
2007 (match_operand 1 "general_operand" "g"))
2008 (use (match_operand:SI 2 "register_operand" "Z"))
2009 (use (match_operand 3 "" ""))]
2010 "! SIBLING_CALL_P (insn)"
2011 "call (%0);"
2012 [(set_attr "type" "call")
2013 (set_attr "length" "2")])
2014
2015(define_insn "*sibcall_insn_fdpic"
2016 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y"))
2017 (match_operand 1 "general_operand" "g"))
2018 (use (match_operand:SI 2 "register_operand" "Z"))
2019 (use (match_operand 3 "" ""))
2020 (return)]
2021 "SIBLING_CALL_P (insn)"
2022 "jump (%0);"
2023 [(set_attr "type" "br")
2024 (set_attr "length" "2")])
2025
2026(define_insn "*call_value_insn_fdpic"
2027 [(set (match_operand 0 "register_operand" "=d")
2028 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y"))
2029 (match_operand 2 "general_operand" "g")))
2030 (use (match_operand:SI 3 "register_operand" "Z"))
2031 (use (match_operand 4 "" ""))]
2032 "! SIBLING_CALL_P (insn)"
2033 "call (%1);"
2034 [(set_attr "type" "call")
2035 (set_attr "length" "2")])
2036
2037(define_insn "*sibcall_value_insn_fdpic"
2038 [(set (match_operand 0 "register_operand" "=d")
2039 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y"))
2040 (match_operand 2 "general_operand" "g")))
2041 (use (match_operand:SI 3 "register_operand" "Z"))
2042 (use (match_operand 4 "" ""))
2043 (return)]
2044 "SIBLING_CALL_P (insn)"
2045 "jump (%1);"
2046 [(set_attr "type" "br")
2047 (set_attr "length" "2")])
2048
6d459e2b
BS
2049(define_insn "*call_symbol"
2050 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
2051 (match_operand 1 "general_operand" "g"))
2052 (use (match_operand 2 "" ""))]
0d4a78eb 2053 "! SIBLING_CALL_P (insn)
93147119 2054 && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
6d459e2b
BS
2055 && GET_CODE (operands[0]) == SYMBOL_REF
2056 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
96c30d2a 2057 "call %0;"
0d4a78eb 2058 [(set_attr "type" "call")
6d459e2b 2059 (set_attr "length" "4")])
0d4a78eb 2060
6d459e2b
BS
2061(define_insn "*sibcall_symbol"
2062 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
2063 (match_operand 1 "general_operand" "g"))
2064 (use (match_operand 2 "" ""))
0d4a78eb
BS
2065 (return)]
2066 "SIBLING_CALL_P (insn)
93147119 2067 && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
6d459e2b
BS
2068 && GET_CODE (operands[0]) == SYMBOL_REF
2069 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
96c30d2a 2070 "jump.l %0;"
0d4a78eb 2071 [(set_attr "type" "br")
6d459e2b 2072 (set_attr "length" "4")])
0d4a78eb 2073
6d459e2b
BS
2074(define_insn "*call_value_symbol"
2075 [(set (match_operand 0 "register_operand" "=d")
2076 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
2077 (match_operand 2 "general_operand" "g")))
2078 (use (match_operand 3 "" ""))]
0d4a78eb 2079 "! SIBLING_CALL_P (insn)
93147119 2080 && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
6d459e2b
BS
2081 && GET_CODE (operands[1]) == SYMBOL_REF
2082 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
96c30d2a 2083 "call %1;"
0d4a78eb 2084 [(set_attr "type" "call")
6d459e2b 2085 (set_attr "length" "4")])
0d4a78eb 2086
6d459e2b
BS
2087(define_insn "*sibcall_value_symbol"
2088 [(set (match_operand 0 "register_operand" "=d")
2089 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
2090 (match_operand 2 "general_operand" "g")))
2091 (use (match_operand 3 "" ""))
0d4a78eb
BS
2092 (return)]
2093 "SIBLING_CALL_P (insn)
93147119 2094 && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
6d459e2b
BS
2095 && GET_CODE (operands[1]) == SYMBOL_REF
2096 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
96c30d2a 2097 "jump.l %1;"
6d459e2b
BS
2098 [(set_attr "type" "br")
2099 (set_attr "length" "4")])
2100
2101(define_insn "*call_insn"
2102 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a"))
2103 (match_operand 1 "general_operand" "g"))
2104 (use (match_operand 2 "" ""))]
2105 "! SIBLING_CALL_P (insn)"
2106 "call (%0);"
2107 [(set_attr "type" "call")
2108 (set_attr "length" "2")])
2109
2110(define_insn "*sibcall_insn"
2111 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "z"))
2112 (match_operand 1 "general_operand" "g"))
2113 (use (match_operand 2 "" ""))
2114 (return)]
2115 "SIBLING_CALL_P (insn)"
2116 "jump (%0);"
2117 [(set_attr "type" "br")
2118 (set_attr "length" "2")])
2119
2120(define_insn "*call_value_insn"
2121 [(set (match_operand 0 "register_operand" "=d")
2122 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a"))
2123 (match_operand 2 "general_operand" "g")))
2124 (use (match_operand 3 "" ""))]
2125 "! SIBLING_CALL_P (insn)"
2126 "call (%1);"
2127 [(set_attr "type" "call")
2128 (set_attr "length" "2")])
2129
2130(define_insn "*sibcall_value_insn"
2131 [(set (match_operand 0 "register_operand" "=d")
2132 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "z"))
2133 (match_operand 2 "general_operand" "g")))
2134 (use (match_operand 3 "" ""))
2135 (return)]
2136 "SIBLING_CALL_P (insn)"
2137 "jump (%1);"
0d4a78eb 2138 [(set_attr "type" "br")
6d459e2b 2139 (set_attr "length" "2")])
0d4a78eb
BS
2140
2141;; Block move patterns
2142
2143;; We cheat. This copies one more word than operand 2 indicates.
2144
2145(define_insn "rep_movsi"
2146 [(set (match_operand:SI 0 "register_operand" "=&a")
2147 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
2148 (ashift:SI (match_operand:SI 2 "register_operand" "a")
2149 (const_int 2)))
2150 (const_int 4)))
2151 (set (match_operand:SI 1 "register_operand" "=&b")
2152 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
2153 (ashift:SI (match_dup 2) (const_int 2)))
2154 (const_int 4)))
2155 (set (mem:BLK (match_dup 3))
2156 (mem:BLK (match_dup 4)))
2157 (use (match_dup 2))
b03149e1
JZ
2158 (clobber (match_scratch:HI 5 "=&d"))
2159 (clobber (reg:SI REG_LT1))
2160 (clobber (reg:SI REG_LC1))
2161 (clobber (reg:SI REG_LB1))]
0d4a78eb 2162 ""
51a641fd 2163 "%5 = [%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || [%3++] = %5 || %5 = [%4++]; [%3++] = %5;"
0d4a78eb 2164 [(set_attr "type" "misc")
b03149e1
JZ
2165 (set_attr "length" "16")
2166 (set_attr "seq_insns" "multi")])
0d4a78eb
BS
2167
2168(define_insn "rep_movhi"
2169 [(set (match_operand:SI 0 "register_operand" "=&a")
2170 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
2171 (ashift:SI (match_operand:SI 2 "register_operand" "a")
2172 (const_int 1)))
2173 (const_int 2)))
2174 (set (match_operand:SI 1 "register_operand" "=&b")
2175 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
2176 (ashift:SI (match_dup 2) (const_int 1)))
2177 (const_int 2)))
2178 (set (mem:BLK (match_dup 3))
2179 (mem:BLK (match_dup 4)))
2180 (use (match_dup 2))
b03149e1
JZ
2181 (clobber (match_scratch:HI 5 "=&d"))
2182 (clobber (reg:SI REG_LT1))
2183 (clobber (reg:SI REG_LC1))
2184 (clobber (reg:SI REG_LB1))]
0d4a78eb 2185 ""
51a641fd 2186 "%h5 = W[%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || W [%3++] = %5 || %h5 = W [%4++]; W [%3++] = %5;"
0d4a78eb 2187 [(set_attr "type" "misc")
b03149e1
JZ
2188 (set_attr "length" "16")
2189 (set_attr "seq_insns" "multi")])
0d4a78eb 2190
144f8315 2191(define_expand "movmemsi"
0d4a78eb
BS
2192 [(match_operand:BLK 0 "general_operand" "")
2193 (match_operand:BLK 1 "general_operand" "")
2194 (match_operand:SI 2 "const_int_operand" "")
2195 (match_operand:SI 3 "const_int_operand" "")]
2196 ""
2197{
144f8315 2198 if (bfin_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
0d4a78eb
BS
2199 DONE;
2200 FAIL;
2201})
2202
2203;; Conditional branch patterns
2204;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
2205
2206;; The only outcome of this pattern is that global variables
2207;; bfin_compare_op[01] are set for use in bcond patterns.
2208
2209(define_expand "cmpbi"
2210 [(set (cc0) (compare (match_operand:BI 0 "register_operand" "")
2211 (match_operand:BI 1 "immediate_operand" "")))]
2212 ""
2213{
2214 bfin_compare_op0 = operands[0];
2215 bfin_compare_op1 = operands[1];
2216 DONE;
2217})
2218
2219(define_expand "cmpsi"
2220 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
7ddcf3d2 2221 (match_operand:SI 1 "reg_or_const_int_operand" "")))]
0d4a78eb
BS
2222 ""
2223{
2224 bfin_compare_op0 = operands[0];
2225 bfin_compare_op1 = operands[1];
2226 DONE;
2227})
2228
49373252 2229(define_insn "compare_eq"
4729dc92 2230 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 2231 (eq:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 2232 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
0d4a78eb
BS
2233 ""
2234 "cc =%1==%2;"
2235 [(set_attr "type" "compare")])
2236
49373252 2237(define_insn "compare_ne"
4729dc92 2238 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 2239 (ne:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 2240 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
0d4a78eb
BS
2241 "0"
2242 "cc =%1!=%2;"
2243 [(set_attr "type" "compare")])
2244
49373252 2245(define_insn "compare_lt"
4729dc92 2246 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 2247 (lt:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 2248 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
0d4a78eb
BS
2249 ""
2250 "cc =%1<%2;"
2251 [(set_attr "type" "compare")])
2252
49373252 2253(define_insn "compare_le"
4729dc92 2254 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 2255 (le:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 2256 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
0d4a78eb
BS
2257 ""
2258 "cc =%1<=%2;"
2259 [(set_attr "type" "compare")])
2260
49373252 2261(define_insn "compare_leu"
4729dc92 2262 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 2263 (leu:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 2264 (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
0d4a78eb
BS
2265 ""
2266 "cc =%1<=%2 (iu);"
2267 [(set_attr "type" "compare")])
2268
49373252 2269(define_insn "compare_ltu"
4729dc92 2270 [(set (match_operand:BI 0 "register_operand" "=C,C")
0d4a78eb 2271 (ltu:BI (match_operand:SI 1 "register_operand" "d,a")
7ddcf3d2 2272 (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
0d4a78eb
BS
2273 ""
2274 "cc =%1<%2 (iu);"
2275 [(set_attr "type" "compare")])
2276
2277(define_expand "beq"
2278 [(set (match_dup 1) (match_dup 2))
2279 (set (pc)
2280 (if_then_else (match_dup 3)
2281 (label_ref (match_operand 0 "" ""))
2282 (pc)))]
2283 ""
2284{
2285 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
2286 operands[1] = bfin_cc_rtx; /* hard register: CC */
2287 operands[2] = gen_rtx_EQ (BImode, op0, op1);
2288 /* If we have a BImode input, then we already have a compare result, and
2289 do not need to emit another comparison. */
2290 if (GET_MODE (bfin_compare_op0) == BImode)
2291 {
3b9dd769
NS
2292 gcc_assert (bfin_compare_op1 == const0_rtx);
2293 emit_insn (gen_cbranchbi4 (operands[2], op0, op1, operands[0]));
2294 DONE;
0d4a78eb
BS
2295 }
2296
2297 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2298})
2299
2300(define_expand "bne"
2301 [(set (match_dup 1) (match_dup 2))
2302 (set (pc)
2303 (if_then_else (match_dup 3)
2304 (label_ref (match_operand 0 "" ""))
2305 (pc)))]
2306 ""
2307{
2308 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
2309 /* If we have a BImode input, then we already have a compare result, and
2310 do not need to emit another comparison. */
2311 if (GET_MODE (bfin_compare_op0) == BImode)
2312 {
3b9dd769
NS
2313 rtx cmp = gen_rtx_NE (BImode, op0, op1);
2314
2315 gcc_assert (bfin_compare_op1 == const0_rtx);
2316 emit_insn (gen_cbranchbi4 (cmp, op0, op1, operands[0]));
2317 DONE;
0d4a78eb
BS
2318 }
2319
2320 operands[1] = bfin_cc_rtx; /* hard register: CC */
2321 operands[2] = gen_rtx_EQ (BImode, op0, op1);
2322 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2323})
2324
2325(define_expand "bgt"
2326 [(set (match_dup 1) (match_dup 2))
2327 (set (pc)
2328 (if_then_else (match_dup 3)
2329 (label_ref (match_operand 0 "" ""))
2330 (pc)))]
2331 ""
2332{
2333 operands[1] = bfin_cc_rtx;
2334 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
2335 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2336})
2337
2338(define_expand "bgtu"
2339 [(set (match_dup 1) (match_dup 2))
2340 (set (pc)
2341 (if_then_else (match_dup 3)
2342 (label_ref (match_operand 0 "" ""))
2343 (pc)))]
2344 ""
2345{
2346 operands[1] = bfin_cc_rtx;
2347 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
2348 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2349})
2350
2351(define_expand "blt"
2352 [(set (match_dup 1) (match_dup 2))
2353 (set (pc)
2354 (if_then_else (match_dup 3)
2355 (label_ref (match_operand 0 "" ""))
2356 (pc)))]
2357 ""
2358{
2359 operands[1] = bfin_cc_rtx;
2360 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
2361 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2362})
2363
2364(define_expand "bltu"
2365 [(set (match_dup 1) (match_dup 2))
2366 (set (pc)
2367 (if_then_else (match_dup 3)
2368 (label_ref (match_operand 0 "" ""))
2369 (pc)))]
2370 ""
2371{
2372 operands[1] = bfin_cc_rtx;
2373 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
2374 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2375})
2376
2377
2378(define_expand "bge"
2379 [(set (match_dup 1) (match_dup 2))
2380 (set (pc)
2381 (if_then_else (match_dup 3)
2382 (label_ref (match_operand 0 "" ""))
2383 (pc)))]
2384 ""
2385{
2386 operands[1] = bfin_cc_rtx;
2387 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
2388 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2389})
2390
2391(define_expand "bgeu"
2392 [(set (match_dup 1) (match_dup 2))
2393 (set (pc)
2394 (if_then_else (match_dup 3)
2395 (label_ref (match_operand 0 "" ""))
2396 (pc)))]
2397 ""
2398{
2399 operands[1] = bfin_cc_rtx;
2400 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
2401 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2402})
2403
2404(define_expand "ble"
2405 [(set (match_dup 1) (match_dup 2))
2406 (set (pc)
2407 (if_then_else (match_dup 3)
2408 (label_ref (match_operand 0 "" ""))
2409 (pc)))]
2410 ""
2411{
2412 operands[1] = bfin_cc_rtx;
2413 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
2414 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2415})
2416
2417(define_expand "bleu"
2418 [(set (match_dup 1) (match_dup 2))
2419 (set (pc)
2420 (if_then_else (match_dup 3)
2421 (label_ref (match_operand 0 "" ""))
2422 (pc)))
2423 ]
2424 ""
2425{
2426 operands[1] = bfin_cc_rtx;
2427 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
2428 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2429})
2430
2431(define_insn "cbranchbi4"
2432 [(set (pc)
2433 (if_then_else
2434 (match_operator 0 "bfin_cbranch_operator"
4729dc92 2435 [(match_operand:BI 1 "register_operand" "C")
0d4a78eb
BS
2436 (match_operand:BI 2 "immediate_operand" "P0")])
2437 (label_ref (match_operand 3 "" ""))
2438 (pc)))]
2439 ""
2440{
2441 asm_conditional_branch (insn, operands, 0, 0);
2442 return "";
2443}
2444 [(set_attr "type" "brcc")])
2445
2446;; Special cbranch patterns to deal with the speculative load problem - see
2447;; bfin_reorg for details.
2448
2449(define_insn "cbranch_predicted_taken"
2450 [(set (pc)
2451 (if_then_else
2452 (match_operator 0 "bfin_cbranch_operator"
4729dc92 2453 [(match_operand:BI 1 "register_operand" "C")
0d4a78eb
BS
2454 (match_operand:BI 2 "immediate_operand" "P0")])
2455 (label_ref (match_operand 3 "" ""))
2456 (pc)))
2457 (unspec [(const_int 0)] UNSPEC_CBRANCH_TAKEN)]
2458 ""
2459{
2460 asm_conditional_branch (insn, operands, 0, 1);
2461 return "";
2462}
2463 [(set_attr "type" "brcc")])
2464
2465(define_insn "cbranch_with_nops"
2466 [(set (pc)
2467 (if_then_else
2468 (match_operator 0 "bfin_cbranch_operator"
4729dc92 2469 [(match_operand:BI 1 "register_operand" "C")
0d4a78eb
BS
2470 (match_operand:BI 2 "immediate_operand" "P0")])
2471 (label_ref (match_operand 3 "" ""))
2472 (pc)))
2473 (unspec [(match_operand 4 "immediate_operand" "")] UNSPEC_CBRANCH_NOPS)]
2474 "reload_completed"
2475{
2476 asm_conditional_branch (insn, operands, INTVAL (operands[4]), 0);
2477 return "";
2478}
2479 [(set_attr "type" "brcc")
2480 (set_attr "length" "6")])
2481
2482;; setcc insns. */
2483(define_expand "seq"
2484 [(set (match_dup 1) (eq:BI (match_dup 2) (match_dup 3)))
2485 (set (match_operand:SI 0 "register_operand" "")
2486 (ne:SI (match_dup 1) (const_int 0)))]
2487 ""
2488{
2489 operands[2] = bfin_compare_op0;
2490 operands[3] = bfin_compare_op1;
2491 operands[1] = bfin_cc_rtx;
2492})
2493
2494(define_expand "slt"
2495 [(set (match_dup 1) (lt:BI (match_dup 2) (match_dup 3)))
2496 (set (match_operand:SI 0 "register_operand" "")
2497 (ne:SI (match_dup 1) (const_int 0)))]
2498 ""
2499{
2500 operands[2] = bfin_compare_op0;
2501 operands[3] = bfin_compare_op1;
2502 operands[1] = bfin_cc_rtx;
2503})
2504
2505(define_expand "sle"
2506 [(set (match_dup 1) (le:BI (match_dup 2) (match_dup 3)))
2507 (set (match_operand:SI 0 "register_operand" "")
2508 (ne:SI (match_dup 1) (const_int 0)))]
2509 ""
2510{
2511 operands[2] = bfin_compare_op0;
2512 operands[3] = bfin_compare_op1;
2513 operands[1] = bfin_cc_rtx;
2514})
2515
2516(define_expand "sltu"
2517 [(set (match_dup 1) (ltu:BI (match_dup 2) (match_dup 3)))
2518 (set (match_operand:SI 0 "register_operand" "")
2519 (ne:SI (match_dup 1) (const_int 0)))]
2520 ""
2521{
2522 operands[2] = bfin_compare_op0;
2523 operands[3] = bfin_compare_op1;
2524 operands[1] = bfin_cc_rtx;
2525})
2526
2527(define_expand "sleu"
2528 [(set (match_dup 1) (leu:BI (match_dup 2) (match_dup 3)))
2529 (set (match_operand:SI 0 "register_operand" "")
2530 (ne:SI (match_dup 1) (const_int 0)))]
2531 ""
2532{
2533 operands[2] = bfin_compare_op0;
2534 operands[3] = bfin_compare_op1;
2535 operands[1] = bfin_cc_rtx;
2536})
2537
2538(define_insn "nop"
2539 [(const_int 0)]
2540 ""
2541 "nop;")
2542
bbbc206e
BS
2543(define_insn "mnop"
2544 [(unspec [(const_int 0)] UNSPEC_32BIT)]
2545 ""
2546 "mnop%!"
2547 [(set_attr "type" "dsp32")])
2548
0d4a78eb
BS
2549;;;;;;;;;;;;;;;;;;;; CC2dreg ;;;;;;;;;;;;;;;;;;;;;;;;;
2550(define_insn "movsibi"
4729dc92 2551 [(set (match_operand:BI 0 "register_operand" "=C")
0d4a78eb
BS
2552 (ne:BI (match_operand:SI 1 "register_operand" "d")
2553 (const_int 0)))]
2554 ""
2555 "CC = %1;"
2556 [(set_attr "length" "2")])
2557
2558(define_insn "movbisi"
2559 [(set (match_operand:SI 0 "register_operand" "=d")
4729dc92 2560 (ne:SI (match_operand:BI 1 "register_operand" "C")
0d4a78eb
BS
2561 (const_int 0)))]
2562 ""
2563 "%0 = CC;"
2564 [(set_attr "length" "2")])
2565
2566(define_insn ""
4729dc92
BS
2567 [(set (match_operand:BI 0 "register_operand" "=C")
2568 (eq:BI (match_operand:BI 1 "register_operand" " 0")
0d4a78eb
BS
2569 (const_int 0)))]
2570 ""
2571 "%0 = ! %0;" /* NOT CC;" */
2572 [(set_attr "type" "compare")])
2573
2574;; Vector and DSP insns
2575
2576(define_insn ""
2577 [(set (match_operand:SI 0 "register_operand" "=d")
2578 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2579 (const_int 24))
2580 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2581 (const_int 8))))]
2582 ""
bbbc206e 2583 "%0 = ALIGN8(%1, %2)%!"
0d4a78eb
BS
2584 [(set_attr "type" "dsp32")])
2585
2586(define_insn ""
2587 [(set (match_operand:SI 0 "register_operand" "=d")
2588 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2589 (const_int 16))
2590 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2591 (const_int 16))))]
2592 ""
bbbc206e 2593 "%0 = ALIGN16(%1, %2)%!"
0d4a78eb
BS
2594 [(set_attr "type" "dsp32")])
2595
2596(define_insn ""
2597 [(set (match_operand:SI 0 "register_operand" "=d")
2598 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2599 (const_int 8))
2600 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2601 (const_int 24))))]
2602 ""
bbbc206e 2603 "%0 = ALIGN24(%1, %2)%!"
0d4a78eb
BS
2604 [(set_attr "type" "dsp32")])
2605
2606;; Prologue and epilogue.
2607
2608(define_expand "prologue"
2609 [(const_int 1)]
2610 ""
2611 "bfin_expand_prologue (); DONE;")
2612
2613(define_expand "epilogue"
2614 [(const_int 1)]
2615 ""
2616 "bfin_expand_epilogue (1, 0); DONE;")
2617
2618(define_expand "sibcall_epilogue"
2619 [(const_int 1)]
2620 ""
2621 "bfin_expand_epilogue (0, 0); DONE;")
2622
2623(define_expand "eh_return"
2624 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")]
2625 UNSPEC_VOLATILE_EH_RETURN)]
2626 ""
2627{
2628 emit_move_insn (EH_RETURN_HANDLER_RTX, operands[0]);
1e96b1c3 2629 emit_jump_insn (gen_eh_return_internal ());
0d4a78eb 2630 emit_barrier ();
4193ce73 2631 DONE;
0d4a78eb
BS
2632})
2633
2634(define_insn_and_split "eh_return_internal"
1e96b1c3
JZ
2635 [(set (pc)
2636 (unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN))]
0d4a78eb
BS
2637 ""
2638 "#"
2639 "reload_completed"
2640 [(const_int 1)]
2641 "bfin_expand_epilogue (1, 1); DONE;")
2642
2643(define_insn "link"
2644 [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS))
2645 (set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:SI REG_FP))
2646 (set (reg:SI REG_FP)
2647 (plus:SI (reg:SI REG_SP) (const_int -8)))
2648 (set (reg:SI REG_SP)
2649 (plus:SI (reg:SI REG_SP) (match_operand:SI 0 "immediate_operand" "i")))]
2650 ""
2651 "LINK %Z0;"
2652 [(set_attr "length" "4")])
2653
2654(define_insn "unlink"
2655 [(set (reg:SI REG_FP) (mem:SI (reg:SI REG_FP)))
2656 (set (reg:SI REG_RETS) (mem:SI (plus:SI (reg:SI REG_FP) (const_int 4))))
2657 (set (reg:SI REG_SP) (plus:SI (reg:SI REG_FP) (const_int 8)))]
2658 ""
2659 "UNLINK;"
2660 [(set_attr "length" "4")])
2661
2662;; This pattern is slightly clumsy. The stack adjust must be the final SET in
2663;; the pattern, otherwise dwarf2out becomes very confused about which reg goes
2664;; where on the stack, since it goes through all elements of the parallel in
2665;; sequence.
2666(define_insn "push_multiple"
2667 [(match_parallel 0 "push_multiple_operation"
2668 [(unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_PUSH_MULTIPLE)])]
2669 ""
2670{
2671 output_push_multiple (insn, operands);
2672 return "";
2673})
2674
2675(define_insn "pop_multiple"
2676 [(match_parallel 0 "pop_multiple_operation"
2677 [(set (reg:SI REG_SP)
2678 (plus:SI (reg:SI REG_SP) (match_operand:SI 1 "immediate_operand" "i")))])]
2679 ""
2680{
2681 output_pop_multiple (insn, operands);
2682 return "";
2683})
2684
2685(define_insn "return_internal"
2686 [(return)
2687 (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)]
2688 "reload_completed"
2689{
2690 switch (INTVAL (operands[0]))
2691 {
2692 case EXCPT_HANDLER:
2693 return "rtx;";
2694 case NMI_HANDLER:
2695 return "rtn;";
2696 case INTERRUPT_HANDLER:
2697 return "rti;";
2698 case SUBROUTINE:
2699 return "rts;";
2700 }
2701 gcc_unreachable ();
2702})
2703
5fcead21
BS
2704(define_insn "csync"
2705 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
2706 ""
2707 "csync;"
3fb192d2 2708 [(set_attr "type" "sync")])
5fcead21
BS
2709
2710(define_insn "ssync"
2711 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_SSYNC)]
2712 ""
2713 "ssync;"
3fb192d2 2714 [(set_attr "type" "sync")])
5fcead21 2715
3d33a056
JZ
2716(define_insn "trap"
2717 [(trap_if (const_int 1) (const_int 3))]
2718 ""
2719 "excpt 3;"
2720 [(set_attr "type" "misc")
2721 (set_attr "length" "2")])
2722
09350e36
BS
2723(define_insn "trapifcc"
2724 [(trap_if (reg:BI REG_CC) (const_int 3))]
2725 ""
2726 "if !cc jump 4 (bp); excpt 3;"
2727 [(set_attr "type" "misc")
b03149e1
JZ
2728 (set_attr "length" "4")
2729 (set_attr "seq_insns" "multi")])
09350e36 2730
0d4a78eb
BS
2731;;; Vector instructions
2732
75d8b2d0
BS
2733;; First, all sorts of move variants
2734
75d8b2d0
BS
2735(define_insn "movhiv2hi_low"
2736 [(set (match_operand:V2HI 0 "register_operand" "=d")
2737 (vec_concat:V2HI
2738 (match_operand:HI 2 "register_operand" "d")
2739 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2740 (parallel [(const_int 1)]))))]
2741 ""
bbbc206e 2742 "%h0 = %h2 << 0%!"
75d8b2d0
BS
2743 [(set_attr "type" "dsp32")])
2744
2745(define_insn "movhiv2hi_high"
2746 [(set (match_operand:V2HI 0 "register_operand" "=d")
2747 (vec_concat:V2HI
2748 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2749 (parallel [(const_int 0)]))
2750 (match_operand:HI 2 "register_operand" "d")))]
2751 ""
bbbc206e 2752 "%d0 = %h2 << 0%!"
75d8b2d0
BS
2753 [(set_attr "type" "dsp32")])
2754
2755;; No earlyclobber on alternative two since our sequence ought to be safe.
2756;; The order of operands is intentional to match the VDSP builtin (high word
2757;; is passed first).
2758(define_insn_and_split "composev2hi"
2759 [(set (match_operand:V2HI 0 "register_operand" "=d,d")
2760 (vec_concat:V2HI (match_operand:HI 2 "register_operand" "0,d")
2761 (match_operand:HI 1 "register_operand" "d,d")))]
2762 ""
2763 "@
bbbc206e 2764 %d0 = %h2 << 0%!
75d8b2d0
BS
2765 #"
2766 "reload_completed"
2767 [(set (match_dup 0)
2768 (vec_concat:V2HI
2769 (vec_select:HI (match_dup 0) (parallel [(const_int 0)]))
2770 (match_dup 2)))
2771 (set (match_dup 0)
2772 (vec_concat:V2HI
2773 (match_dup 1)
2774 (vec_select:HI (match_dup 0) (parallel [(const_int 1)]))))]
2775 ""
2776 [(set_attr "type" "dsp32")])
2777
2778; Like composev2hi, but operating on elements of V2HI vectors.
2779; Useful on its own, and as a combiner bridge for the multiply and
2780; mac patterns.
2781(define_insn "packv2hi"
2d3649b2 2782 [(set (match_operand:V2HI 0 "register_operand" "=d,d,d,d,d,d,d,d")
75d8b2d0 2783 (vec_concat:V2HI (vec_select:HI
2d3649b2
BS
2784 (match_operand:V2HI 1 "register_operand" "0,0,d,d,d,d,d,d")
2785 (parallel [(match_operand 3 "const01_operand" "P0,P0,P0,P1,P0,P1,P0,P1")]))
75d8b2d0 2786 (vec_select:HI
2d3649b2
BS
2787 (match_operand:V2HI 2 "register_operand" "d,d,0,0,d,d,d,d")
2788 (parallel [(match_operand 4 "const01_operand" "P0,P1,P1,P1,P0,P0,P1,P1")]))))]
75d8b2d0
BS
2789 ""
2790 "@
2d3649b2
BS
2791 %d0 = %h2 << 0%!
2792 %d0 = %d2 << 0%!
2793 %h0 = %h1 << 0%!
2794 %h0 = %d1 << 0%!
bbbc206e
BS
2795 %0 = PACK (%h2,%h1)%!
2796 %0 = PACK (%h2,%d1)%!
2797 %0 = PACK (%d2,%h1)%!
2798 %0 = PACK (%d2,%d1)%!"
75d8b2d0
BS
2799 [(set_attr "type" "dsp32")])
2800
2801(define_insn "movv2hi_hi"
2802 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
2803 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0,d,d")
554006bd 2804 (parallel [(match_operand 2 "const01_operand" "P0,P0,P1")])))]
75d8b2d0
BS
2805 ""
2806 "@
2807 /* optimized out */
bbbc206e
BS
2808 %h0 = %h1 << 0%!
2809 %h0 = %d1 << 0%!"
75d8b2d0
BS
2810 [(set_attr "type" "dsp32")])
2811
2812(define_expand "movv2hi_hi_low"
2813 [(set (match_operand:HI 0 "register_operand" "")
2814 (vec_select:HI (match_operand:V2HI 1 "register_operand" "")
2815 (parallel [(const_int 0)])))]
2816 ""
2817 "")
2818
2819(define_expand "movv2hi_hi_high"
2820 [(set (match_operand:HI 0 "register_operand" "")
2821 (vec_select:HI (match_operand:V2HI 1 "register_operand" "")
2822 (parallel [(const_int 1)])))]
2823 ""
2824 "")
2825
942fd98f 2826;; Unusual arithmetic operations on 16-bit registers.
75d8b2d0
BS
2827
2828(define_insn "ssaddhi3"
2829 [(set (match_operand:HI 0 "register_operand" "=d")
2830 (ss_plus:HI (match_operand:HI 1 "register_operand" "d")
2831 (match_operand:HI 2 "register_operand" "d")))]
2832 ""
bbbc206e 2833 "%h0 = %h1 + %h2 (S)%!"
75d8b2d0
BS
2834 [(set_attr "type" "dsp32")])
2835
2836(define_insn "sssubhi3"
2837 [(set (match_operand:HI 0 "register_operand" "=d")
2838 (ss_minus:HI (match_operand:HI 1 "register_operand" "d")
2839 (match_operand:HI 2 "register_operand" "d")))]
2840 ""
bbbc206e 2841 "%h0 = %h1 - %h2 (S)%!"
75d8b2d0
BS
2842 [(set_attr "type" "dsp32")])
2843
2844;; V2HI vector insns
2845
c9b3f817 2846(define_insn "addv2hi3"
0d4a78eb
BS
2847 [(set (match_operand:V2HI 0 "register_operand" "=d")
2848 (plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2849 (match_operand:V2HI 2 "register_operand" "d")))]
2850 ""
bbbc206e 2851 "%0 = %1 +|+ %2%!"
0d4a78eb
BS
2852 [(set_attr "type" "dsp32")])
2853
75d8b2d0
BS
2854(define_insn "ssaddv2hi3"
2855 [(set (match_operand:V2HI 0 "register_operand" "=d")
2856 (ss_plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2857 (match_operand:V2HI 2 "register_operand" "d")))]
2858 ""
bbbc206e 2859 "%0 = %1 +|+ %2 (S)%!"
75d8b2d0
BS
2860 [(set_attr "type" "dsp32")])
2861
c9b3f817 2862(define_insn "subv2hi3"
0d4a78eb
BS
2863 [(set (match_operand:V2HI 0 "register_operand" "=d")
2864 (minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2865 (match_operand:V2HI 2 "register_operand" "d")))]
2866 ""
bbbc206e 2867 "%0 = %1 -|- %2%!"
0d4a78eb
BS
2868 [(set_attr "type" "dsp32")])
2869
75d8b2d0
BS
2870(define_insn "sssubv2hi3"
2871 [(set (match_operand:V2HI 0 "register_operand" "=d")
2872 (ss_minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2873 (match_operand:V2HI 2 "register_operand" "d")))]
2874 ""
bbbc206e 2875 "%0 = %1 -|- %2 (S)%!"
75d8b2d0
BS
2876 [(set_attr "type" "dsp32")])
2877
2878(define_insn "addsubv2hi3"
2879 [(set (match_operand:V2HI 0 "register_operand" "=d")
2880 (vec_concat:V2HI
2881 (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2882 (parallel [(const_int 0)]))
2883 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2884 (parallel [(const_int 0)])))
2885 (minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2886 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2887 ""
bbbc206e 2888 "%0 = %1 +|- %2%!"
75d8b2d0
BS
2889 [(set_attr "type" "dsp32")])
2890
2891(define_insn "subaddv2hi3"
2892 [(set (match_operand:V2HI 0 "register_operand" "=d")
2893 (vec_concat:V2HI
2894 (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2895 (parallel [(const_int 0)]))
2896 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2897 (parallel [(const_int 0)])))
2898 (plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2899 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2900 ""
bbbc206e 2901 "%0 = %1 -|+ %2%!"
75d8b2d0
BS
2902 [(set_attr "type" "dsp32")])
2903
2904(define_insn "ssaddsubv2hi3"
2905 [(set (match_operand:V2HI 0 "register_operand" "=d")
2906 (vec_concat:V2HI
2907 (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2908 (parallel [(const_int 0)]))
2909 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2910 (parallel [(const_int 0)])))
2911 (ss_minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2912 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2913 ""
bbbc206e 2914 "%0 = %1 +|- %2 (S)%!"
75d8b2d0
BS
2915 [(set_attr "type" "dsp32")])
2916
2917(define_insn "sssubaddv2hi3"
2918 [(set (match_operand:V2HI 0 "register_operand" "=d")
2919 (vec_concat:V2HI
2920 (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2921 (parallel [(const_int 0)]))
2922 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2923 (parallel [(const_int 0)])))
2924 (ss_plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2925 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2926 ""
bbbc206e 2927 "%0 = %1 -|+ %2 (S)%!"
75d8b2d0
BS
2928 [(set_attr "type" "dsp32")])
2929
2930(define_insn "sublohiv2hi3"
2931 [(set (match_operand:HI 0 "register_operand" "=d")
2932 (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2933 (parallel [(const_int 1)]))
2934 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2935 (parallel [(const_int 0)]))))]
2936 ""
bbbc206e 2937 "%h0 = %d1 - %h2%!"
75d8b2d0
BS
2938 [(set_attr "type" "dsp32")])
2939
2940(define_insn "subhilov2hi3"
2941 [(set (match_operand:HI 0 "register_operand" "=d")
2942 (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2943 (parallel [(const_int 0)]))
2944 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2945 (parallel [(const_int 1)]))))]
2946 ""
bbbc206e 2947 "%h0 = %h1 - %d2%!"
75d8b2d0
BS
2948 [(set_attr "type" "dsp32")])
2949
2950(define_insn "sssublohiv2hi3"
2951 [(set (match_operand:HI 0 "register_operand" "=d")
2952 (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2953 (parallel [(const_int 1)]))
2954 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2955 (parallel [(const_int 0)]))))]
2956 ""
bbbc206e 2957 "%h0 = %d1 - %h2 (S)%!"
75d8b2d0
BS
2958 [(set_attr "type" "dsp32")])
2959
2960(define_insn "sssubhilov2hi3"
2961 [(set (match_operand:HI 0 "register_operand" "=d")
2962 (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2963 (parallel [(const_int 0)]))
2964 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2965 (parallel [(const_int 1)]))))]
2966 ""
bbbc206e 2967 "%h0 = %h1 - %d2 (S)%!"
75d8b2d0
BS
2968 [(set_attr "type" "dsp32")])
2969
2970(define_insn "addlohiv2hi3"
2971 [(set (match_operand:HI 0 "register_operand" "=d")
2972 (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2973 (parallel [(const_int 1)]))
2974 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2975 (parallel [(const_int 0)]))))]
2976 ""
bbbc206e 2977 "%h0 = %d1 + %h2%!"
75d8b2d0
BS
2978 [(set_attr "type" "dsp32")])
2979
2980(define_insn "addhilov2hi3"
2981 [(set (match_operand:HI 0 "register_operand" "=d")
2982 (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2983 (parallel [(const_int 0)]))
2984 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2985 (parallel [(const_int 1)]))))]
2986 ""
bbbc206e 2987 "%h0 = %h1 + %d2%!"
75d8b2d0
BS
2988 [(set_attr "type" "dsp32")])
2989
2990(define_insn "ssaddlohiv2hi3"
2991 [(set (match_operand:HI 0 "register_operand" "=d")
2992 (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2993 (parallel [(const_int 1)]))
2994 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2995 (parallel [(const_int 0)]))))]
2996 ""
bbbc206e 2997 "%h0 = %d1 + %h2 (S)%!"
75d8b2d0
BS
2998 [(set_attr "type" "dsp32")])
2999
3000(define_insn "ssaddhilov2hi3"
3001 [(set (match_operand:HI 0 "register_operand" "=d")
3002 (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3003 (parallel [(const_int 0)]))
3004 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3005 (parallel [(const_int 1)]))))]
3006 ""
bbbc206e 3007 "%h0 = %h1 + %d2 (S)%!"
75d8b2d0
BS
3008 [(set_attr "type" "dsp32")])
3009
c9b3f817 3010(define_insn "sminv2hi3"
0d4a78eb
BS
3011 [(set (match_operand:V2HI 0 "register_operand" "=d")
3012 (smin:V2HI (match_operand:V2HI 1 "register_operand" "d")
3013 (match_operand:V2HI 2 "register_operand" "d")))]
3014 ""
bbbc206e 3015 "%0 = MIN (%1, %2) (V)%!"
0d4a78eb
BS
3016 [(set_attr "type" "dsp32")])
3017
c9b3f817 3018(define_insn "smaxv2hi3"
0d4a78eb
BS
3019 [(set (match_operand:V2HI 0 "register_operand" "=d")
3020 (smax:V2HI (match_operand:V2HI 1 "register_operand" "d")
3021 (match_operand:V2HI 2 "register_operand" "d")))]
3022 ""
bbbc206e 3023 "%0 = MAX (%1, %2) (V)%!"
0d4a78eb
BS
3024 [(set_attr "type" "dsp32")])
3025
75d8b2d0
BS
3026;; Multiplications.
3027
3028;; The Blackfin allows a lot of different options, and we need many patterns to
3029;; cover most of the hardware's abilities.
3030;; There are a few simple patterns using MULT rtx codes, but most of them use
3031;; an unspec with a const_int operand that determines which flag to use in the
3032;; instruction.
3033;; There are variants for single and parallel multiplications.
942fd98f 3034;; There are variants which just use 16-bit lowparts as inputs, and variants
75d8b2d0
BS
3035;; which allow the user to choose just which halves to use as input values.
3036;; There are variants which set D registers, variants which set accumulators,
3037;; variants which set both, some of them optionally using the accumulators as
3038;; inputs for multiply-accumulate operations.
3039
3040(define_insn "flag_mulhi"
3041 [(set (match_operand:HI 0 "register_operand" "=d")
3042 (unspec:HI [(match_operand:HI 1 "register_operand" "d")
3043 (match_operand:HI 2 "register_operand" "d")
3044 (match_operand 3 "const_int_operand" "n")]
3045 UNSPEC_MUL_WITH_FLAG))]
3046 ""
bbbc206e 3047 "%h0 = %h1 * %h2 %M3%!"
75d8b2d0
BS
3048 [(set_attr "type" "dsp32")])
3049
3050(define_insn "flag_mulhisi"
3051 [(set (match_operand:SI 0 "register_operand" "=d")
3052 (unspec:SI [(match_operand:HI 1 "register_operand" "d")
3053 (match_operand:HI 2 "register_operand" "d")
3054 (match_operand 3 "const_int_operand" "n")]
3055 UNSPEC_MUL_WITH_FLAG))]
3056 ""
bbbc206e 3057 "%0 = %h1 * %h2 %M3%!"
75d8b2d0
BS
3058 [(set_attr "type" "dsp32")])
3059
3060(define_insn "flag_mulhisi_parts"
3061 [(set (match_operand:SI 0 "register_operand" "=d")
3062 (unspec:SI [(vec_select:HI
3063 (match_operand:V2HI 1 "register_operand" "d")
554006bd 3064 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
75d8b2d0
BS
3065 (vec_select:HI
3066 (match_operand:V2HI 2 "register_operand" "d")
554006bd 3067 (parallel [(match_operand 4 "const01_operand" "P0P1")]))
75d8b2d0
BS
3068 (match_operand 5 "const_int_operand" "n")]
3069 UNSPEC_MUL_WITH_FLAG))]
3070 ""
3071{
3072 const char *templates[] = {
bbbc206e
BS
3073 "%0 = %h1 * %h2 %M5%!",
3074 "%0 = %d1 * %h2 %M5%!",
3075 "%0 = %h1 * %d2 %M5%!",
3076 "%0 = %d1 * %d2 %M5%!" };
75d8b2d0
BS
3077 int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
3078 return templates[alt];
3079}
3080 [(set_attr "type" "dsp32")])
3081
3efd5670
BS
3082;; Three alternatives here to cover all possible allocations:
3083;; 0. mac flag is usable only for accumulator 1 - use A1 and odd DREG
3084;; 1. mac flag is usable for accumulator 0 - use A0 and even DREG
3085;; 2. mac flag is usable in any accumulator - use A1 and odd DREG
3086;; Other patterns which don't have a DREG destination can collapse cases
3087;; 1 and 2 into one.
75d8b2d0 3088(define_insn "flag_machi"
3efd5670
BS
3089 [(set (match_operand:HI 0 "register_operand" "=W,D,W")
3090 (unspec:HI [(match_operand:HI 2 "register_operand" "d,d,d")
3091 (match_operand:HI 3 "register_operand" "d,d,d")
3092 (match_operand 4 "register_operand" "1,1,1")
3093 (match_operand 5 "const01_operand" "P0P1,P0P1,P0P1")
3094 (match_operand 6 "const_int_operand" "PB,PA,PA")]
75d8b2d0 3095 UNSPEC_MAC_WITH_FLAG))
3efd5670 3096 (set (match_operand:PDI 1 "register_operand" "=B,A,B")
75d8b2d0
BS
3097 (unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)
3098 (match_dup 4) (match_dup 5)]
3099 UNSPEC_MAC_WITH_FLAG))]
3100 ""
3efd5670 3101 "%h0 = (%1 %b5 %h2 * %h3) %M6%!"
75d8b2d0
BS
3102 [(set_attr "type" "dsp32")])
3103
3104(define_insn "flag_machi_acconly"
3efd5670
BS
3105 [(set (match_operand:PDI 0 "register_operand" "=B,e")
3106 (unspec:PDI [(match_operand:HI 1 "register_operand" "d,d")
3107 (match_operand:HI 2 "register_operand" "d,d")
3108 (match_operand 3 "register_operand" "0,0")
3109 (match_operand 4 "const01_operand" "P0P1,P0P1")
3110 (match_operand 5 "const_int_operand" "PB,PA")]
75d8b2d0
BS
3111 UNSPEC_MAC_WITH_FLAG))]
3112 ""
3efd5670
BS
3113 "%0 %b4 %h1 * %h2 %M5%!"
3114 [(set_attr "type" "dsp32")])
3115
3116(define_insn "flag_machi_parts_acconly"
3117 [(set (match_operand:PDI 0 "register_operand" "=B,e")
3118 (unspec:PDI [(vec_select:HI
3119 (match_operand:V2HI 1 "register_operand" "d,d")
3120 (parallel [(match_operand 3 "const01_operand" "P0P1,P0P1")]))
3121 (vec_select:HI
3122 (match_operand:V2HI 2 "register_operand" "d,d")
3123 (parallel [(match_operand 4 "const01_operand" "P0P1,P0P1")]))
3124 (match_operand:PDI 5 "register_operand" "0,0")
3125 (match_operand 6 "const01_operand" "P0P1,P0P1")
3126 (match_operand 7 "const_int_operand" "PB,PA")]
3127 UNSPEC_MAC_WITH_FLAG))]
3128 ""
3129{
3130 const char *templates[] = {
3131 "%0 %b6 %h1 * %h2 %M7%!",
3132 "%0 %b6 %d1 * %h2 %M7%!",
3133 "%0 %b6 %h1 * %d2 %M7%!",
3134 "%0 %b6 %d1 * %d2 %M7%!"
3135 };
3136 int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
3137 return templates[alt];
3138}
75d8b2d0
BS
3139 [(set_attr "type" "dsp32")])
3140
3141(define_insn "flag_macinithi"
3efd5670
BS
3142 [(set (match_operand:HI 0 "register_operand" "=W,D,W")
3143 (unspec:HI [(match_operand:HI 1 "register_operand" "d,d,d")
3144 (match_operand:HI 2 "register_operand" "d,d,d")
3145 (match_operand 3 "const_int_operand" "PB,PA,PA")]
75d8b2d0 3146 UNSPEC_MAC_WITH_FLAG))
3efd5670 3147 (set (match_operand:PDI 4 "register_operand" "=B,A,B")
75d8b2d0
BS
3148 (unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)]
3149 UNSPEC_MAC_WITH_FLAG))]
3150 ""
3efd5670 3151 "%h0 = (%4 = %h1 * %h2) %M3%!"
75d8b2d0
BS
3152 [(set_attr "type" "dsp32")])
3153
3154(define_insn "flag_macinit1hi"
3efd5670
BS
3155 [(set (match_operand:PDI 0 "register_operand" "=B,e")
3156 (unspec:PDI [(match_operand:HI 1 "register_operand" "d,d")
3157 (match_operand:HI 2 "register_operand" "d,d")
3158 (match_operand 3 "const_int_operand" "PB,PA")]
75d8b2d0
BS
3159 UNSPEC_MAC_WITH_FLAG))]
3160 ""
bbbc206e 3161 "%0 = %h1 * %h2 %M3%!"
75d8b2d0
BS
3162 [(set_attr "type" "dsp32")])
3163
c9b3f817 3164(define_insn "mulv2hi3"
0d4a78eb
BS
3165 [(set (match_operand:V2HI 0 "register_operand" "=d")
3166 (mult:V2HI (match_operand:V2HI 1 "register_operand" "d")
3167 (match_operand:V2HI 2 "register_operand" "d")))]
3168 ""
bbbc206e 3169 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 (IS)%!"
0d4a78eb
BS
3170 [(set_attr "type" "dsp32")])
3171
75d8b2d0
BS
3172(define_insn "flag_mulv2hi"
3173 [(set (match_operand:V2HI 0 "register_operand" "=d")
3174 (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "d")
3175 (match_operand:V2HI 2 "register_operand" "d")
3176 (match_operand 3 "const_int_operand" "n")]
3177 UNSPEC_MUL_WITH_FLAG))]
3178 ""
bbbc206e 3179 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 %M3%!"
75d8b2d0
BS
3180 [(set_attr "type" "dsp32")])
3181
3182(define_insn "flag_mulv2hi_parts"
3183 [(set (match_operand:V2HI 0 "register_operand" "=d")
3184 (unspec:V2HI [(vec_concat:V2HI
3185 (vec_select:HI
3186 (match_operand:V2HI 1 "register_operand" "d")
554006bd 3187 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
75d8b2d0
BS
3188 (vec_select:HI
3189 (match_dup 1)
554006bd 3190 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
75d8b2d0
BS
3191 (vec_concat:V2HI
3192 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
554006bd 3193 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
75d8b2d0 3194 (vec_select:HI (match_dup 2)
554006bd 3195 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
75d8b2d0
BS
3196 (match_operand 7 "const_int_operand" "n")]
3197 UNSPEC_MUL_WITH_FLAG))]
3198 ""
3199{
3200 const char *templates[] = {
bbbc206e
BS
3201 "%h0 = %h1 * %h2, %d0 = %h1 * %h2 %M7%!",
3202 "%h0 = %d1 * %h2, %d0 = %h1 * %h2 %M7%!",
3203 "%h0 = %h1 * %h2, %d0 = %d1 * %h2 %M7%!",
3204 "%h0 = %d1 * %h2, %d0 = %d1 * %h2 %M7%!",
3205 "%h0 = %h1 * %d2, %d0 = %h1 * %h2 %M7%!",
3206 "%h0 = %d1 * %d2, %d0 = %h1 * %h2 %M7%!",
3207 "%h0 = %h1 * %d2, %d0 = %d1 * %h2 %M7%!",
3208 "%h0 = %d1 * %d2, %d0 = %d1 * %h2 %M7%!",
3209 "%h0 = %h1 * %h2, %d0 = %h1 * %d2 %M7%!",
3210 "%h0 = %d1 * %h2, %d0 = %h1 * %d2 %M7%!",
3211 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 %M7%!",
3212 "%h0 = %d1 * %h2, %d0 = %d1 * %d2 %M7%!",
3213 "%h0 = %h1 * %d2, %d0 = %h1 * %d2 %M7%!",
3214 "%h0 = %d1 * %d2, %d0 = %h1 * %d2 %M7%!",
3215 "%h0 = %h1 * %d2, %d0 = %d1 * %d2 %M7%!",
3216 "%h0 = %d1 * %d2, %d0 = %d1 * %d2 %M7%!" };
75d8b2d0
BS
3217 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3218 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3219 return templates[alt];
3220}
3221 [(set_attr "type" "dsp32")])
3222
3223;; A slightly complicated pattern.
3224;; Operand 0 is the halfword output; operand 11 is the accumulator output
3225;; Halfword inputs are operands 1 and 2; operands 3, 4, 5 and 6 specify which
3226;; parts of these 2x16 bit registers to use.
3227;; Operand 7 is the accumulator input.
3228;; Operands 8/9 specify whether low/high parts are mac (0) or msu (1)
3229;; Operand 10 is the macflag to be used.
3230(define_insn "flag_macv2hi_parts"
3231 [(set (match_operand:V2HI 0 "register_operand" "=d")
3232 (unspec:V2HI [(vec_concat:V2HI
3233 (vec_select:HI
3234 (match_operand:V2HI 1 "register_operand" "d")
554006bd 3235 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
75d8b2d0
BS
3236 (vec_select:HI
3237 (match_dup 1)
554006bd 3238 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
75d8b2d0
BS
3239 (vec_concat:V2HI
3240 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
554006bd 3241 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
75d8b2d0 3242 (vec_select:HI (match_dup 2)
554006bd 3243 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
75d8b2d0
BS
3244 (match_operand:V2PDI 7 "register_operand" "e")
3245 (match_operand 8 "const01_operand" "P0P1")
3246 (match_operand 9 "const01_operand" "P0P1")
3247 (match_operand 10 "const_int_operand" "n")]
3248 UNSPEC_MAC_WITH_FLAG))
3249 (set (match_operand:V2PDI 11 "register_operand" "=e")
3250 (unspec:V2PDI [(vec_concat:V2HI
3251 (vec_select:HI (match_dup 1) (parallel [(match_dup 3)]))
3252 (vec_select:HI (match_dup 1) (parallel [(match_dup 4)])))
3253 (vec_concat:V2HI
3254 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)]))
3255 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)])))
3256 (match_dup 7) (match_dup 8) (match_dup 9) (match_dup 10)]
3257 UNSPEC_MAC_WITH_FLAG))]
3258 ""
3259{
3260 const char *templates[] = {
bbbc206e
BS
3261 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3262 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3263 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3264 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3265 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3266 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3267 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3268 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3269 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3270 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3271 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %d1 * %d2) %M10%!",
3272 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %d1 * %d2) %M10%!",
3273 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3274 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3275 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %d1 * %d2) %M10%!",
3276 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %d1 * %d2) %M10%!" };
75d8b2d0
BS
3277 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3278 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3279 return templates[alt];
3280}
3281 [(set_attr "type" "dsp32")])
3282
3283(define_insn "flag_macv2hi_parts_acconly"
3284 [(set (match_operand:V2PDI 0 "register_operand" "=e")
3285 (unspec:V2PDI [(vec_concat:V2HI
3286 (vec_select:HI
3287 (match_operand:V2HI 1 "register_operand" "d")
554006bd 3288 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
75d8b2d0
BS
3289 (vec_select:HI
3290 (match_dup 1)
554006bd 3291 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
75d8b2d0
BS
3292 (vec_concat:V2HI
3293 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
554006bd 3294 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
75d8b2d0 3295 (vec_select:HI (match_dup 2)
554006bd 3296 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
75d8b2d0
BS
3297 (match_operand:V2PDI 7 "register_operand" "e")
3298 (match_operand 8 "const01_operand" "P0P1")
3299 (match_operand 9 "const01_operand" "P0P1")
3300 (match_operand 10 "const_int_operand" "n")]
3301 UNSPEC_MAC_WITH_FLAG))]
3302 ""
3303{
3304 const char *templates[] = {
bbbc206e
BS
3305 "A0 %b8 %h1 * %h2, A1 %b9 %h1 * %h2 %M10%!",
3306 "A0 %b8 %d1 * %h2, A1 %b9 %h1 * %h2 %M10%!",
3307 "A0 %b8 %h1 * %h2, A1 %b9 %d1 * %h2 %M10%!",
3308 "A0 %b8 %d1 * %h2, A1 %b9 %d1 * %h2 %M10%!",
3309 "A0 %b8 %h1 * %d2, A1 %b9 %h1 * %h2 %M10%!",
3310 "A0 %b8 %d1 * %d2, A1 %b9 %h1 * %h2 %M10%!",
3311 "A0 %b8 %h1 * %d2, A1 %b9 %d1 * %h2 %M10%!",
3312 "A0 %b8 %d1 * %d2, A1 %b9 %d1 * %h2 %M10%!",
3313 "A0 %b8 %h1 * %h2, A1 %b9 %h1 * %d2 %M10%!",
3314 "A0 %b8 %d1 * %h2, A1 %b9 %h1 * %d2 %M10%!",
3315 "A0 %b8 %h1 * %h2, A1 %b9 %d1 * %d2 %M10%!",
3316 "A0 %b8 %d1 * %h2, A1 %b9 %d1 * %d2 %M10%!",
3317 "A0 %b8 %h1 * %d2, A1 %b9 %h1 * %d2 %M10%!",
3318 "A0 %b8 %d1 * %d2, A1 %b9 %h1 * %d2 %M10%!",
3319 "A0 %b8 %h1 * %d2, A1 %b9 %d1 * %d2 %M10%!",
3320 "A0 %b8 %d1 * %d2, A1 %b9 %d1 * %d2 %M10%!" };
75d8b2d0
BS
3321 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3322 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3323 return templates[alt];
3324}
3325 [(set_attr "type" "dsp32")])
3326
3327;; Same as above, but initializing the accumulators and therefore a couple fewer
3328;; necessary operands.
3329(define_insn "flag_macinitv2hi_parts"
0d4a78eb 3330 [(set (match_operand:V2HI 0 "register_operand" "=d")
75d8b2d0
BS
3331 (unspec:V2HI [(vec_concat:V2HI
3332 (vec_select:HI
3333 (match_operand:V2HI 1 "register_operand" "d")
554006bd 3334 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
75d8b2d0
BS
3335 (vec_select:HI
3336 (match_dup 1)
554006bd 3337 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
75d8b2d0
BS
3338 (vec_concat:V2HI
3339 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
554006bd 3340 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
75d8b2d0 3341 (vec_select:HI (match_dup 2)
554006bd 3342 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
75d8b2d0
BS
3343 (match_operand 7 "const_int_operand" "n")]
3344 UNSPEC_MAC_WITH_FLAG))
3345 (set (match_operand:V2PDI 8 "register_operand" "=e")
3346 (unspec:V2PDI [(vec_concat:V2HI
3347 (vec_select:HI (match_dup 1) (parallel [(match_dup 3)]))
3348 (vec_select:HI (match_dup 1) (parallel [(match_dup 4)])))
3349 (vec_concat:V2HI
3350 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)]))
3351 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)])))
3352 (match_dup 7)]
3353 UNSPEC_MAC_WITH_FLAG))]
3354 ""
3355{
3356 const char *templates[] = {
bbbc206e
BS
3357 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %h1 * %h2) %M7%!",
3358 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %h1 * %h2) %M7%!",
3359 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %d1 * %h2) %M7%!",
3360 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %d1 * %h2) %M7%!",
3361 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %h1 * %h2) %M7%!",
3362 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %h1 * %h2) %M7%!",
3363 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %d1 * %h2) %M7%!",
3364 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %d1 * %h2) %M7%!",
3365 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %h1 * %d2) %M7%!",
3366 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %h1 * %d2) %M7%!",
3367 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %d1 * %d2) %M7%!",
3368 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %d1 * %d2) %M7%!",
3369 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %h1 * %d2) %M7%!",
3370 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %h1 * %d2) %M7%!",
3371 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %d1 * %d2) %M7%!",
3372 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %d1 * %d2) %M7%!" };
75d8b2d0
BS
3373 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3374 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3375 return templates[alt];
3376}
3377 [(set_attr "type" "dsp32")])
3378
3379(define_insn "flag_macinit1v2hi_parts"
3380 [(set (match_operand:V2PDI 0 "register_operand" "=e")
3381 (unspec:V2PDI [(vec_concat:V2HI
3382 (vec_select:HI
3383 (match_operand:V2HI 1 "register_operand" "d")
554006bd 3384 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
75d8b2d0
BS
3385 (vec_select:HI
3386 (match_dup 1)
554006bd 3387 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
75d8b2d0
BS
3388 (vec_concat:V2HI
3389 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
554006bd 3390 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
75d8b2d0 3391 (vec_select:HI (match_dup 2)
554006bd 3392 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
75d8b2d0
BS
3393 (match_operand 7 "const_int_operand" "n")]
3394 UNSPEC_MAC_WITH_FLAG))]
3395 ""
3396{
3397 const char *templates[] = {
bbbc206e
BS
3398 "A0 = %h1 * %h2, A1 = %h1 * %h2 %M7%!",
3399 "A0 = %d1 * %h2, A1 = %h1 * %h2 %M7%!",
3400 "A0 = %h1 * %h2, A1 = %d1 * %h2 %M7%!",
3401 "A0 = %d1 * %h2, A1 = %d1 * %h2 %M7%!",
3402 "A0 = %h1 * %d2, A1 = %h1 * %h2 %M7%!",
3403 "A0 = %d1 * %d2, A1 = %h1 * %h2 %M7%!",
3404 "A0 = %h1 * %d2, A1 = %d1 * %h2 %M7%!",
3405 "A0 = %d1 * %d2, A1 = %d1 * %h2 %M7%!",
3406 "A0 = %h1 * %h2, A1 = %h1 * %d2 %M7%!",
3407 "A0 = %d1 * %h2, A1 = %h1 * %d2 %M7%!",
3408 "A0 = %h1 * %h2, A1 = %d1 * %d2 %M7%!",
3409 "A0 = %d1 * %h2, A1 = %d1 * %d2 %M7%!",
3410 "A0 = %h1 * %d2, A1 = %h1 * %d2 %M7%!",
3411 "A0 = %d1 * %d2, A1 = %h1 * %d2 %M7%!",
3412 "A0 = %h1 * %d2, A1 = %d1 * %d2 %M7%!",
3413 "A0 = %d1 * %d2, A1 = %d1 * %d2 %M7%!" };
75d8b2d0
BS
3414 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3415 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3416 return templates[alt];
3417}
3418 [(set_attr "type" "dsp32")])
3419
3efd5670
BS
3420;; A mixture of multiply and multiply-accumulate for when we only want to
3421;; initialize one part.
3422(define_insn "flag_mul_macv2hi_parts_acconly"
3423 [(set (match_operand:PDI 0 "register_operand" "=B,e,e")
3424 (unspec:PDI [(vec_select:HI
3425 (match_operand:V2HI 2 "register_operand" "d,d,d")
3426 (parallel [(match_operand 4 "const01_operand" "P0P1,P0P1,P0P1")]))
3427 (vec_select:HI
3428 (match_operand:V2HI 3 "register_operand" "d,d,d")
3429 (parallel [(match_operand 6 "const01_operand" "P0P1,P0P1,P0P1")]))
3430 (match_operand 10 "const_int_operand" "PB,PA,PA")]
3431 UNSPEC_MUL_WITH_FLAG))
3432 (set (match_operand:PDI 1 "register_operand" "=B,e,e")
3433 (unspec:PDI [(vec_select:HI
3434 (match_dup 2)
3435 (parallel [(match_operand 5 "const01_operand" "P0P1,P0P1,P0P1")]))
3436 (vec_select:HI
3437 (match_dup 3)
3438 (parallel [(match_operand 7 "const01_operand" "P0P1,P0P1,P0P1")]))
3439 (match_operand:PDI 8 "register_operand" "1,1,1")
3440 (match_operand 9 "const01_operand" "P0P1,P0P1,P0P1")
3441 (match_operand 11 "const_int_operand" "PA,PB,PA")]
3442 UNSPEC_MAC_WITH_FLAG))]
3443 "MACFLAGS_MATCH_P (INTVAL (operands[10]), INTVAL (operands[11]))"
3444{
3445 rtx xops[6];
3446 const char *templates[] = {
3447 "%0 = %h2 * %h3, %1 %b4 %h2 * %h3 %M5%!",
3448 "%0 = %d2 * %h3, %1 %b4 %h2 * %h3 %M5%!",
3449 "%0 = %h2 * %h3, %1 %b4 %d2 * %h3 %M5%!",
3450 "%0 = %d2 * %h3, %1 %b4 %d2 * %h3 %M5%!",
3451 "%0 = %h2 * %d3, %1 %b4 %h2 * %h3 %M5%!",
3452 "%0 = %d2 * %d3, %1 %b4 %h2 * %h3 %M5%!",
3453 "%0 = %h2 * %d3, %1 %b4 %d2 * %h3 %M5%!",
3454 "%0 = %d2 * %d3, %1 %b4 %d2 * %h3 %M5%!",
3455 "%0 = %h2 * %h3, %1 %b4 %h2 * %d3 %M5%!",
3456 "%0 = %d2 * %h3, %1 %b4 %h2 * %d3 %M5%!",
3457 "%0 = %h2 * %h3, %1 %b4 %d2 * %d3 %M5%!",
3458 "%0 = %d2 * %h3, %1 %b4 %d2 * %d3 %M5%!",
3459 "%0 = %h2 * %d3, %1 %b4 %h2 * %d3 %M5%!",
3460 "%0 = %d2 * %d3, %1 %b4 %h2 * %d3 %M5%!",
3461 "%0 = %h2 * %d3, %1 %b4 %d2 * %d3 %M5%!",
3462 "%0 = %d2 * %d3, %1 %b4 %d2 * %d3 %M5%!" };
3463 int alt = (INTVAL (operands[4]) + (INTVAL (operands[5]) << 1)
3464 + (INTVAL (operands[6]) << 2) + (INTVAL (operands[7]) << 3));
3465 xops[0] = operands[0];
3466 xops[1] = operands[1];
3467 xops[2] = operands[2];
3468 xops[3] = operands[3];
3469 xops[4] = operands[9];
3470 xops[5] = which_alternative == 0 ? operands[10] : operands[11];
3471 output_asm_insn (templates[alt], xops);
3472 return "";
3473}
3474 [(set_attr "type" "dsp32")])
3475
3476
2889abed
BS
3477(define_code_macro s_or_u [sign_extend zero_extend])
3478(define_code_attr su_optab [(sign_extend "mul")
3479 (zero_extend "umul")])
3480(define_code_attr su_modifier [(sign_extend "IS")
3481 (zero_extend "FU")])
3482
3483(define_insn "<su_optab>hisi_ll"
75d8b2d0 3484 [(set (match_operand:SI 0 "register_operand" "=d")
2889abed 3485 (mult:SI (s_or_u:SI
75d8b2d0
BS
3486 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3487 (parallel [(const_int 0)])))
2889abed 3488 (s_or_u:SI
75d8b2d0
BS
3489 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3490 (parallel [(const_int 0)])))))]
3491 ""
2889abed 3492 "%0 = %h1 * %h2 (<su_modifier>)%!"
75d8b2d0
BS
3493 [(set_attr "type" "dsp32")])
3494
2889abed 3495(define_insn "<su_optab>hisi_lh"
75d8b2d0 3496 [(set (match_operand:SI 0 "register_operand" "=d")
2889abed
BS
3497 (mult:SI (s_or_u:SI
3498 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
75d8b2d0 3499 (parallel [(const_int 0)])))
2889abed 3500 (s_or_u:SI
75d8b2d0
BS
3501 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3502 (parallel [(const_int 1)])))))]
3503 ""
2889abed 3504 "%0 = %h1 * %d2 (<su_modifier>)%!"
75d8b2d0
BS
3505 [(set_attr "type" "dsp32")])
3506
2889abed 3507(define_insn "<su_optab>hisi_hl"
75d8b2d0 3508 [(set (match_operand:SI 0 "register_operand" "=d")
2889abed
BS
3509 (mult:SI (s_or_u:SI
3510 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3511 (parallel [(const_int 1)])))
3512 (s_or_u:SI
3513 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3514 (parallel [(const_int 0)])))))]
3515 ""
3516 "%0 = %d1 * %h2 (<su_modifier>)%!"
3517 [(set_attr "type" "dsp32")])
3518
3519(define_insn "<su_optab>hisi_hh"
3520 [(set (match_operand:SI 0 "register_operand" "=d")
3521 (mult:SI (s_or_u:SI
75d8b2d0
BS
3522 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3523 (parallel [(const_int 1)])))
2889abed
BS
3524 (s_or_u:SI
3525 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3526 (parallel [(const_int 1)])))))]
3527 ""
3528 "%0 = %d1 * %d2 (<su_modifier>)%!"
3529 [(set_attr "type" "dsp32")])
3530
3531;; Additional variants for signed * unsigned multiply.
3532
3533(define_insn "usmulhisi_ull"
3534 [(set (match_operand:SI 0 "register_operand" "=W")
3535 (mult:SI (zero_extend:SI
3536 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3537 (parallel [(const_int 0)])))
75d8b2d0
BS
3538 (sign_extend:SI
3539 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3540 (parallel [(const_int 0)])))))]
3541 ""
2889abed 3542 "%0 = %h2 * %h1 (IS,M)%!"
75d8b2d0
BS
3543 [(set_attr "type" "dsp32")])
3544
2889abed
BS
3545(define_insn "usmulhisi_ulh"
3546 [(set (match_operand:SI 0 "register_operand" "=W")
3547 (mult:SI (zero_extend:SI
3548 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3549 (parallel [(const_int 0)])))
3550 (sign_extend:SI
3551 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3552 (parallel [(const_int 1)])))))]
3553 ""
3554 "%0 = %d2 * %h1 (IS,M)%!"
3555 [(set_attr "type" "dsp32")])
3556
3557(define_insn "usmulhisi_uhl"
3558 [(set (match_operand:SI 0 "register_operand" "=W")
3559 (mult:SI (zero_extend:SI
3560 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3561 (parallel [(const_int 1)])))
3562 (sign_extend:SI
3563 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3564 (parallel [(const_int 0)])))))]
3565 ""
3566 "%0 = %h2 * %d1 (IS,M)%!"
3567 [(set_attr "type" "dsp32")])
3568
3569(define_insn "usmulhisi_uhh"
3570 [(set (match_operand:SI 0 "register_operand" "=W")
3571 (mult:SI (zero_extend:SI
75d8b2d0
BS
3572 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3573 (parallel [(const_int 1)])))
3574 (sign_extend:SI
3575 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3576 (parallel [(const_int 1)])))))]
3577 ""
2889abed
BS
3578 "%0 = %d2 * %d1 (IS,M)%!"
3579 [(set_attr "type" "dsp32")])
3580
3581;; Parallel versions of these operations. First, normal signed or unsigned
3582;; multiplies.
3583
3584(define_insn "<su_optab>hisi_ll_lh"
3585 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3586 (mult:SI (s_or_u:SI
3587 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3588 (parallel [(const_int 0)])))
3589 (s_or_u:SI
3590 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3591 (parallel [(const_int 0)])))))
3592 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3593 (mult:SI (s_or_u:SI
3594 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3595 (s_or_u:SI
3596 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3597 ""
3598 "%0 = %h1 * %h2, %3 = %h1 * %d2 (<su_modifier>)%!"
3599 [(set_attr "type" "dsp32")])
3600
3601(define_insn "<su_optab>hisi_ll_hl"
3602 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3603 (mult:SI (s_or_u:SI
3604 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3605 (parallel [(const_int 0)])))
3606 (s_or_u:SI
3607 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3608 (parallel [(const_int 0)])))))
3609 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3610 (mult:SI (s_or_u:SI
3611 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3612 (s_or_u:SI
3613 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3614 ""
3615 "%0 = %h1 * %h2, %3 = %d1 * %h2 (<su_modifier>)%!"
3616 [(set_attr "type" "dsp32")])
3617
3618(define_insn "<su_optab>hisi_ll_hh"
3619 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3620 (mult:SI (s_or_u:SI
3621 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3622 (parallel [(const_int 0)])))
3623 (s_or_u:SI
3624 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3625 (parallel [(const_int 0)])))))
3626 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3627 (mult:SI (s_or_u:SI
3628 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3629 (s_or_u:SI
3630 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3631 ""
3632 "%0 = %h1 * %h2, %3 = %d1 * %d2 (<su_modifier>)%!"
3633 [(set_attr "type" "dsp32")])
3634
3635(define_insn "<su_optab>hisi_lh_hl"
3636 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3637 (mult:SI (s_or_u:SI
3638 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3639 (parallel [(const_int 0)])))
3640 (s_or_u:SI
3641 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3642 (parallel [(const_int 1)])))))
3643 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3644 (mult:SI (s_or_u:SI
3645 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3646 (s_or_u:SI
3647 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3648 ""
3649 "%0 = %h1 * %d2, %3 = %d1 * %h2 (<su_modifier>)%!"
3650 [(set_attr "type" "dsp32")])
3651
3652(define_insn "<su_optab>hisi_lh_hh"
3653 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3654 (mult:SI (s_or_u:SI
3655 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3656 (parallel [(const_int 0)])))
3657 (s_or_u:SI
3658 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3659 (parallel [(const_int 1)])))))
3660 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3661 (mult:SI (s_or_u:SI
3662 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3663 (s_or_u:SI
3664 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3665 ""
3666 "%0 = %h1 * %d2, %3 = %d1 * %d2 (<su_modifier>)%!"
3667 [(set_attr "type" "dsp32")])
3668
3669(define_insn "<su_optab>hisi_hl_hh"
3670 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3671 (mult:SI (s_or_u:SI
3672 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3673 (parallel [(const_int 1)])))
3674 (s_or_u:SI
3675 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3676 (parallel [(const_int 0)])))))
3677 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3678 (mult:SI (s_or_u:SI
3679 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3680 (s_or_u:SI
3681 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3682 ""
3683 "%0 = %d1 * %h2, %3 = %d1 * %d2 (<su_modifier>)%!"
3684 [(set_attr "type" "dsp32")])
3685
3686;; Special signed * unsigned variants.
3687
3688(define_insn "usmulhisi_ll_lul"
3689 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3690 (mult:SI (sign_extend:SI
3691 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3692 (parallel [(const_int 0)])))
3693 (sign_extend:SI
3694 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3695 (parallel [(const_int 0)])))))
3696 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3697 (mult:SI (sign_extend:SI
3698 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3699 (zero_extend:SI
3700 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3701 ""
3702 "%0 = %h1 * %h2, %3 = %h1 * %h2 (IS,M)%!"
3703 [(set_attr "type" "dsp32")])
3704
3705(define_insn "usmulhisi_ll_luh"
3706 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3707 (mult:SI (sign_extend:SI
3708 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3709 (parallel [(const_int 0)])))
3710 (sign_extend:SI
3711 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3712 (parallel [(const_int 0)])))))
3713 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3714 (mult:SI (sign_extend:SI
3715 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3716 (zero_extend:SI
3717 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3718 ""
3719 "%0 = %h1 * %h2, %3 = %h1 * %d2 (IS,M)%!"
3720 [(set_attr "type" "dsp32")])
3721
3722(define_insn "usmulhisi_ll_hul"
3723 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3724 (mult:SI (sign_extend:SI
3725 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3726 (parallel [(const_int 0)])))
3727 (sign_extend:SI
3728 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3729 (parallel [(const_int 0)])))))
3730 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3731 (mult:SI (sign_extend:SI
3732 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3733 (zero_extend:SI
3734 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3735 ""
3736 "%0 = %h1 * %h2, %3 = %d1 * %h2 (IS,M)%!"
3737 [(set_attr "type" "dsp32")])
3738
3739(define_insn "usmulhisi_ll_huh"
3740 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3741 (mult:SI (sign_extend:SI
3742 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3743 (parallel [(const_int 0)])))
3744 (sign_extend:SI
3745 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3746 (parallel [(const_int 0)])))))
3747 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3748 (mult:SI (sign_extend:SI
3749 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3750 (zero_extend:SI
3751 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3752 ""
3753 "%0 = %h1 * %h2, %3 = %d1 * %d2 (IS,M)%!"
3754 [(set_attr "type" "dsp32")])
3755
3756(define_insn "usmulhisi_lh_lul"
3757 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3758 (mult:SI (sign_extend:SI
3759 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3760 (parallel [(const_int 0)])))
3761 (sign_extend:SI
3762 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3763 (parallel [(const_int 1)])))))
3764 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3765 (mult:SI (sign_extend:SI
3766 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3767 (zero_extend:SI
3768 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3769 ""
3770 "%0 = %h1 * %d2, %3 = %h1 * %h2 (IS,M)%!"
3771 [(set_attr "type" "dsp32")])
3772
3773(define_insn "usmulhisi_lh_luh"
3774 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3775 (mult:SI (sign_extend:SI
3776 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3777 (parallel [(const_int 0)])))
3778 (sign_extend:SI
3779 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3780 (parallel [(const_int 1)])))))
3781 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3782 (mult:SI (sign_extend:SI
3783 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3784 (zero_extend:SI
3785 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3786 ""
3787 "%0 = %h1 * %d2, %3 = %h1 * %d2 (IS,M)%!"
3788 [(set_attr "type" "dsp32")])
3789
3790(define_insn "usmulhisi_lh_hul"
3791 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3792 (mult:SI (sign_extend:SI
3793 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3794 (parallel [(const_int 0)])))
3795 (sign_extend:SI
3796 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3797 (parallel [(const_int 1)])))))
3798 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3799 (mult:SI (sign_extend:SI
3800 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3801 (zero_extend:SI
3802 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3803 ""
3804 "%0 = %h1 * %d2, %3 = %d1 * %h2 (IS,M)%!"
3805 [(set_attr "type" "dsp32")])
3806
3807(define_insn "usmulhisi_lh_huh"
3808 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3809 (mult:SI (sign_extend:SI
3810 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3811 (parallel [(const_int 0)])))
3812 (sign_extend:SI
3813 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3814 (parallel [(const_int 1)])))))
3815 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3816 (mult:SI (sign_extend:SI
3817 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3818 (zero_extend:SI
3819 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3820 ""
3821 "%0 = %h1 * %d2, %3 = %d1 * %d2 (IS,M)%!"
3822 [(set_attr "type" "dsp32")])
3823
3824(define_insn "usmulhisi_hl_lul"
3825 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3826 (mult:SI (sign_extend:SI
3827 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3828 (parallel [(const_int 1)])))
3829 (sign_extend:SI
3830 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3831 (parallel [(const_int 0)])))))
3832 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3833 (mult:SI (sign_extend:SI
3834 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3835 (zero_extend:SI
3836 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3837 ""
3838 "%0 = %d1 * %h2, %3 = %h1 * %h2 (IS,M)%!"
3839 [(set_attr "type" "dsp32")])
3840
3841(define_insn "usmulhisi_hl_luh"
3842 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3843 (mult:SI (sign_extend:SI
3844 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3845 (parallel [(const_int 1)])))
3846 (sign_extend:SI
3847 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3848 (parallel [(const_int 0)])))))
3849 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3850 (mult:SI (sign_extend:SI
3851 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3852 (zero_extend:SI
3853 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3854 ""
3855 "%0 = %d1 * %h2, %3 = %h1 * %d2 (IS,M)%!"
3856 [(set_attr "type" "dsp32")])
3857
3858(define_insn "usmulhisi_hl_hul"
3859 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3860 (mult:SI (sign_extend:SI
3861 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3862 (parallel [(const_int 1)])))
3863 (sign_extend:SI
3864 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3865 (parallel [(const_int 0)])))))
3866 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3867 (mult:SI (sign_extend:SI
3868 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3869 (zero_extend:SI
3870 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3871 ""
3872 "%0 = %d1 * %h2, %3 = %d1 * %h2 (IS,M)%!"
3873 [(set_attr "type" "dsp32")])
3874
3875(define_insn "usmulhisi_hl_huh"
3876 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3877 (mult:SI (sign_extend:SI
3878 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3879 (parallel [(const_int 1)])))
3880 (sign_extend:SI
3881 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3882 (parallel [(const_int 0)])))))
3883 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3884 (mult:SI (sign_extend:SI
3885 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3886 (zero_extend:SI
3887 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3888 ""
3889 "%0 = %d1 * %h2, %3 = %d1 * %d2 (IS,M)%!"
3890 [(set_attr "type" "dsp32")])
3891
3892(define_insn "usmulhisi_hh_lul"
3893 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3894 (mult:SI (sign_extend:SI
3895 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3896 (parallel [(const_int 1)])))
3897 (sign_extend:SI
3898 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3899 (parallel [(const_int 1)])))))
3900 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3901 (mult:SI (sign_extend:SI
3902 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3903 (zero_extend:SI
3904 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3905 ""
3906 "%0 = %d1 * %d2, %3 = %h1 * %h2 (IS,M)%!"
75d8b2d0
BS
3907 [(set_attr "type" "dsp32")])
3908
2889abed
BS
3909(define_insn "usmulhisi_hh_luh"
3910 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3911 (mult:SI (sign_extend:SI
3912 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3913 (parallel [(const_int 1)])))
3914 (sign_extend:SI
3915 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3916 (parallel [(const_int 1)])))))
3917 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3918 (mult:SI (sign_extend:SI
3919 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3920 (zero_extend:SI
3921 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3922 ""
3923 "%0 = %d1 * %d2, %3 = %h1 * %d2 (IS,M)%!"
3924 [(set_attr "type" "dsp32")])
3925
3926(define_insn "usmulhisi_hh_hul"
3927 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3928 (mult:SI (sign_extend:SI
3929 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3930 (parallel [(const_int 1)])))
3931 (sign_extend:SI
3932 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3933 (parallel [(const_int 1)])))))
3934 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3935 (mult:SI (sign_extend:SI
3936 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3937 (zero_extend:SI
3938 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3939 ""
3940 "%0 = %d1 * %d2, %3 = %d1 * %h2 (IS,M)%!"
3941 [(set_attr "type" "dsp32")])
3942
3943(define_insn "usmulhisi_hh_huh"
3944 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3945 (mult:SI (sign_extend:SI
3946 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3947 (parallel [(const_int 1)])))
3948 (sign_extend:SI
3949 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3950 (parallel [(const_int 1)])))))
3951 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3952 (mult:SI (sign_extend:SI
3953 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3954 (zero_extend:SI
3955 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3956 ""
3957 "%0 = %d1 * %d2, %3 = %d1 * %d2 (IS,M)%!"
3958 [(set_attr "type" "dsp32")])
3959
3960;; Vector neg/abs.
3961
75d8b2d0
BS
3962(define_insn "ssnegv2hi2"
3963 [(set (match_operand:V2HI 0 "register_operand" "=d")
3964 (ss_neg:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
0d4a78eb 3965 ""
bbbc206e 3966 "%0 = - %1 (V)%!"
0d4a78eb
BS
3967 [(set_attr "type" "dsp32")])
3968
c9b3f817 3969(define_insn "absv2hi2"
0d4a78eb
BS
3970 [(set (match_operand:V2HI 0 "register_operand" "=d")
3971 (abs:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
3972 ""
bbbc206e 3973 "%0 = ABS %1 (V)%!"
0d4a78eb
BS
3974 [(set_attr "type" "dsp32")])
3975
75d8b2d0
BS
3976;; Shifts.
3977
3978(define_insn "ssashiftv2hi3"
3979 [(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
3980 (if_then_else:V2HI
3981 (lt (match_operand:SI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
3982 (ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" "d,d,d")
3983 (match_dup 2))
3984 (ss_ashift:V2HI (match_dup 1) (match_dup 2))))]
3985 ""
3986 "@
329437dd 3987 %0 = ASHIFT %1 BY %h2 (V, S)%!
58f76679
BS
3988 %0 = %1 << %2 (V,S)%!
3989 %0 = %1 >>> %N2 (V,S)%!"
75d8b2d0
BS
3990 [(set_attr "type" "dsp32")])
3991
3992(define_insn "ssashifthi3"
3993 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3994 (if_then_else:HI
3995 (lt (match_operand:SI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
3996 (ashiftrt:HI (match_operand:HI 1 "register_operand" "d,d,d")
3997 (match_dup 2))
3998 (ss_ashift:HI (match_dup 1) (match_dup 2))))]
3999 ""
4000 "@
329437dd 4001 %0 = ASHIFT %1 BY %h2 (V, S)%!
58f76679
BS
4002 %0 = %1 << %2 (V,S)%!
4003 %0 = %1 >>> %N2 (V,S)%!"
75d8b2d0
BS
4004 [(set_attr "type" "dsp32")])
4005
4006(define_insn "lshiftv2hi3"
4007 [(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
4008 (if_then_else:V2HI
4009 (lt (match_operand:SI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
4010 (lshiftrt:V2HI (match_operand:V2HI 1 "register_operand" "d,d,d")
4011 (match_dup 2))
4012 (ashift:V2HI (match_dup 1) (match_dup 2))))]
4013 ""
4014 "@
329437dd 4015 %0 = LSHIFT %1 BY %h2 (V)%!
58f76679
BS
4016 %0 = %1 << %2 (V)%!
4017 %0 = %1 >> %N2 (V)%!"
75d8b2d0
BS
4018 [(set_attr "type" "dsp32")])
4019
4020(define_insn "lshifthi3"
4021 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
4022 (if_then_else:HI
4023 (lt (match_operand:SI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
4024 (lshiftrt:HI (match_operand:HI 1 "register_operand" "d,d,d")
4025 (match_dup 2))
4026 (ashift:HI (match_dup 1) (match_dup 2))))]
4027 ""
4028 "@
329437dd 4029 %0 = LSHIFT %1 BY %h2 (V)%!
58f76679
BS
4030 %0 = %1 << %2 (V)%!
4031 %0 = %1 >> %N2 (V)%!"
75d8b2d0
BS
4032 [(set_attr "type" "dsp32")])
4033