OSDN Git Service

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