OSDN Git Service

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