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