OSDN Git Service

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