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