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