OSDN Git Service

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