OSDN Git Service

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