OSDN Git Service

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