OSDN Git Service

Update FSF address.
[pf3gnuchains/gcc-fork.git] / gcc / config / bfin / bfin.md
1 ;;- Machine description for Blackfin for GNU compiler
2 ;;  Copyright 2005  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 ;     B
50 ;     c (i0..i3,m0..m3) CIRCREGS
51 ;     C (CC)            CCREGS
52 ;
53
54 ;; Define constants for hard registers.
55
56 (define_constants
57   [(REG_R0 0)
58    (REG_R1 1)
59    (REG_R2 2)
60    (REG_R3 3)
61    (REG_R4 4)
62    (REG_R5 5)
63    (REG_R6 6)
64    (REG_R7 7)
65
66    (REG_P0 8)
67    (REG_P1 9)
68    (REG_P2 10)
69    (REG_P3 11)
70    (REG_P4 12)
71    (REG_P5 13)
72    (REG_P6 14)
73    (REG_P7 15)
74
75    (REG_SP 14)
76    (REG_FP 15)
77
78    (REG_I0 16)
79    (REG_B0 17)
80    (REG_L0 18)
81    (REG_I1 19)
82    (REG_B1 20)
83    (REG_L1 21)
84    (REG_I2 22)
85    (REG_B2 23)
86    (REG_L2 24)
87    (REG_I3 25)
88    (REG_B3 26)
89    (REG_L3 27)
90
91    (REG_M0 28)
92    (REG_M1 29)
93    (REG_M2 30)
94    (REG_M3 31)
95
96    (REG_A0 32)
97    (REG_A1 33)
98
99    (REG_CC 34)
100    (REG_RETS 35)
101    (REG_RETI 36)
102    (REG_RETX 37)
103    (REG_RETN 38)
104    (REG_RETE 39)
105
106    (REG_ASTAT 40)
107    (REG_SEQSTAT 41)
108    (REG_USP 42)
109
110    (REG_ARGP 43)])
111
112 ;; Constants used in UNSPECs and UNSPEC_VOLATILEs.
113
114 (define_constants
115   [(UNSPEC_CBRANCH_TAKEN 0)
116    (UNSPEC_CBRANCH_NOPS 1)
117    (UNSPEC_RETURN 2)
118    (UNSPEC_MOVE_PIC 3)
119    (UNSPEC_LIBRARY_OFFSET 4)
120    (UNSPEC_PUSH_MULTIPLE 5)])
121
122 (define_constants
123   [(UNSPEC_VOLATILE_EH_RETURN 0)
124    (UNSPEC_VOLATILE_CSYNC 1)
125    (UNSPEC_VOLATILE_SSYNC 2)])
126
127 (define_attr "type"
128   "move,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,compare,dummy"
129   (const_string "misc"))
130
131 ;; Scheduling definitions
132
133 (define_automaton "bfin")
134
135 (define_cpu_unit "core" "bfin")
136
137 (define_insn_reservation "alu" 1
138   (eq_attr "type" "move,mvi,mcst,dsp32,alu0,shft,brcc,br,call,misc,compare")
139   "core")
140
141 (define_insn_reservation "imul" 3
142   (eq_attr "type" "mult")
143   "core*3")
144
145 (define_insn_reservation "load" 1
146   (eq_attr "type" "mcld")
147   "core")
148
149 ;; Make sure genautomata knows about the maximum latency that can be produced
150 ;; by the adjust_cost function.
151 (define_insn_reservation "dummy" 5
152   (eq_attr "type" "mcld")
153   "core")
154 \f
155 ;; Operand and operator predicates
156
157 (include "predicates.md")
158
159 \f
160 ;;; FRIO branches have been optimized for code density
161 ;;; this comes at a slight cost of complexity when
162 ;;; a compiler needs to generate branches in the general
163 ;;; case.  In order to generate the correct branching
164 ;;; mechanisms the compiler needs keep track of instruction
165 ;;; lengths.  The follow table describes how to count instructions
166 ;;; for the FRIO architecture.
167 ;;;
168 ;;; unconditional br are 12-bit imm pcrelative branches *2
169 ;;; conditional   br are 10-bit imm pcrelative branches *2
170 ;;; brcc 10-bit:
171 ;;;   1024 10-bit imm *2 is 2048 (-1024..1022)
172 ;;; br 12-bit  :
173 ;;;   4096 12-bit imm *2 is 8192 (-4096..4094)
174 ;;; NOTE : For brcc we generate instructions such as
175 ;;;   if cc jmp; jump.[sl] offset
176 ;;;   offset of jump.[sl] is from the jump instruction but
177 ;;;     gcc calculates length from the if cc jmp instruction
178 ;;;     furthermore gcc takes the end address of the branch instruction
179 ;;;     as (pc) for a forward branch
180 ;;;     hence our range is (-4094, 4092) instead of (-4096, 4094) for a br
181 ;;;
182 ;;; The way the (pc) rtx works in these calculations is somewhat odd;
183 ;;; for backward branches it's the address of the current instruction,
184 ;;; for forward branches it's the previously known address of the following
185 ;;; instruction - we have to take this into account by reducing the range
186 ;;; for a forward branch.
187
188 ;; Lengths for type "mvi" insns are always defined by the instructions
189 ;; themselves.
190 (define_attr "length" ""
191   (cond [(eq_attr "type" "mcld")
192          (if_then_else (match_operand 1 "effective_address_32bit_p" "")
193                        (const_int 4) (const_int 2))
194
195          (eq_attr "type" "mcst")
196          (if_then_else (match_operand 0 "effective_address_32bit_p" "")
197                        (const_int 4) (const_int 2))
198
199          (eq_attr "type" "move") (const_int 2)
200
201          (eq_attr "type" "dsp32") (const_int 4)
202          (eq_attr "type" "call")  (const_int 4)
203
204          (eq_attr "type" "br")
205          (if_then_else (and
206                           (le (minus (match_dup 0) (pc)) (const_int 4092))
207                           (ge (minus (match_dup 0) (pc)) (const_int -4096)))
208                   (const_int 2)
209                   (const_int 4))
210
211          (eq_attr "type" "brcc")
212          (cond [(and
213                     (le (minus (match_dup 3) (pc)) (const_int 1020))
214                     (ge (minus (match_dup 3) (pc)) (const_int -1024)))
215                   (const_int 2)
216                 (and
217                     (le (minus (match_dup 3) (pc)) (const_int 4092))
218                     (ge (minus (match_dup 3) (pc)) (const_int -4094)))
219                   (const_int 4)]
220                (const_int 6))
221         ]
222
223         (const_int 2)))
224
225 ;; Conditional moves
226
227 (define_expand "movsicc"
228   [(set (match_operand:SI 0 "register_operand" "")
229         (if_then_else:SI (match_operand 1 "comparison_operator" "")
230                          (match_operand:SI 2 "register_operand" "")
231                          (match_operand:SI 3 "register_operand" "")))]
232   ""
233 {
234   operands[1] = bfin_gen_compare (operands[1], SImode);
235 })
236
237 (define_insn "*movsicc_insn1"
238   [(set (match_operand:SI 0 "register_operand" "=da,da,da")
239         (if_then_else:SI
240             (eq:BI (match_operand:BI 3 "cc_operand" "C,C,C")
241                 (const_int 0))
242             (match_operand:SI 1 "register_operand" "da,0,da")
243             (match_operand:SI 2 "register_operand" "0,da,da")))]
244   ""
245   "@
246     if !cc %0 =%1; /* movsicc-1a */
247     if cc %0 =%2; /* movsicc-1b */
248     if !cc %0 =%1; if cc %0=%2; /* movsicc-1 */"
249   [(set_attr "length" "2,2,4")
250    (set_attr "type" "move")])
251
252 (define_insn "*movsicc_insn2"
253   [(set (match_operand:SI 0 "register_operand" "=da,da,da")
254         (if_then_else:SI
255             (ne:BI (match_operand:BI 3 "cc_operand" "C,C,C")
256                 (const_int 0))
257             (match_operand:SI 1 "register_operand" "0,da,da")
258             (match_operand:SI 2 "register_operand" "da,0,da")))]
259   ""
260   "@
261    if !cc %0 =%2; /* movsicc-2b */
262    if cc %0 =%1; /* movsicc-2a */
263    if cc %0 =%1; if !cc %0=%2; /* movsicc-1 */"
264   [(set_attr "length" "2,2,4")
265    (set_attr "type" "move")])
266
267 ;; Insns to load HIGH and LO_SUM
268
269 (define_insn "movsi_high"
270   [(set (match_operand:SI 0 "register_operand" "=x")
271         (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
272   "reload_completed"
273   "%d0 = %d1;"
274   [(set_attr "type" "mvi")
275    (set_attr "length" "4")])
276
277 (define_insn "movstricthi_high"
278   [(set (match_operand:SI 0 "register_operand" "+x")
279         (ior:SI (and:SI (match_dup 0) (const_int 65535))
280                 (match_operand:SI 1 "immediate_operand" "i")))]
281   "reload_completed"
282   "%d0 = %d1;"
283   [(set_attr "type" "mvi")
284    (set_attr "length" "4")])
285
286 (define_insn "movsi_low"
287   [(set (match_operand:SI 0 "register_operand" "=x")
288         (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
289                    (match_operand:SI 2 "immediate_operand" "i")))]
290   "reload_completed"
291   "%h0 = %h2;"
292   [(set_attr "type" "mvi")
293    (set_attr "length" "4")])
294
295 (define_insn "movsi_high_pic"
296   [(set (match_operand:SI 0 "register_operand" "=x")
297         (high:SI (unspec:SI [(match_operand:SI 1 "" "")]
298                             UNSPEC_MOVE_PIC)))]
299   ""
300   "%d0 = %1@GOT_LOW;"
301   [(set_attr "type" "mvi")
302    (set_attr "length" "4")])
303
304 (define_insn "movsi_low_pic"
305   [(set (match_operand:SI 0 "register_operand" "=x")
306         (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
307                    (unspec:SI [(match_operand:SI 2 "" "")]
308                               UNSPEC_MOVE_PIC)))]
309   ""
310   "%h0 = %h2@GOT_HIGH;"
311   [(set_attr "type" "mvi")
312    (set_attr "length" "4")])
313
314 ;;; Move instructions
315
316 (define_insn_and_split "movdi_insn"
317   [(set (match_operand:DI 0 "nonimmediate_operand" "=x,mx,r")
318         (match_operand:DI 1 "general_operand" "iFx,r,mx"))]
319   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
320   "#"
321   "reload_completed"
322   [(set (match_dup 2) (match_dup 3))
323    (set (match_dup 4) (match_dup 5))]
324 {
325   rtx lo_half[2], hi_half[2];
326   split_di (operands, 2, lo_half, hi_half);
327
328   if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
329     {
330       operands[2] = hi_half[0];
331       operands[3] = hi_half[1];
332       operands[4] = lo_half[0];
333       operands[5] = lo_half[1];
334     }
335   else
336     {
337       operands[2] = lo_half[0];
338       operands[3] = lo_half[1];
339       operands[4] = hi_half[0];
340       operands[5] = hi_half[1];
341     }
342 })
343
344 (define_insn "movbi"
345   [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,mr,C,d")
346         (match_operand:BI 1 "general_operand" "x,xKs3,mr,d,d,C"))]
347
348   ""
349   "@
350    %0 = %1;
351    %0 = %1 (X);
352    %0 = %1;
353    %0 = %1;
354    CC = %1;
355    %0 = CC;"
356   [(set_attr "type" "move,mvi,mcld,mcst,compare,compare")
357    (set_attr "length" "2,2,*,*,2,2")])
358
359 (define_insn "movpdi"
360   [(set (match_operand:PDI 0 "nonimmediate_operand" "=e,<,e")
361         (match_operand:PDI 1 "general_operand" " e,e,>"))]
362   ""
363   "@
364    %0 = %1;
365    %0 = %x1; %0 = %w1;
366    %w0 = %1; %x0 = %1;"
367   [(set_attr "type" "move,mcst,mcld")])
368
369 (define_insn "*pushsi_insn"
370   [(set (mem:SI (pre_dec:SI (reg:SI REG_SP)))
371         (match_operand:SI 0 "register_operand" "xy"))]
372   ""
373   "[--SP] = %0;"
374   [(set_attr "type" "mcst")
375    (set_attr "length" "2")])
376
377 (define_insn "*popsi_insn"
378   [(set (match_operand:SI 0 "register_operand" "=xy")
379         (mem:SI (post_inc:SI (reg:SI REG_SP))))]
380   ""
381   "%0 = [SP++];"
382   [(set_attr "type" "mcld")
383    (set_attr "length" "2")])
384
385 ;; The first alternative is used to make reload choose a limited register
386 ;; class when faced with a movsi_insn that had its input operand replaced
387 ;; with a PLUS.  We generally require fewer secondary reloads this way.
388 (define_insn "*movsi_insn"
389   [(set (match_operand:SI 0 "nonimmediate_operand" "=da,x*y,da,x,x,x,da,mr")
390         (match_operand:SI 1 "general_operand" "da,x*y,xKs7,xKsh,xKuh,ix,mr,da"))]
391
392   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
393   "@
394    %0 = %1;
395    %0 = %1;
396    %0 = %1 (X);
397    %0 = %1 (X);
398    %0 = %1 (Z);
399    #
400    %0 = %1;
401    %0 = %1;"
402   [(set_attr "type" "move,move,mvi,mvi,mvi,*,mcld,mcst")
403    (set_attr "length" "2,2,2,4,4,*,*,*")])
404
405 (define_insn "*movv2hi_insn"
406   [(set (match_operand:V2HI 0 "nonimmediate_operand" "=da,d,m")
407         (match_operand:V2HI 1 "general_operand" "d,m,d"))]
408
409   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
410   "%0 = %1;"
411   [(set_attr "type" "move,mcld,mcst")
412    (set_attr "length" "2,*,*")])
413
414 (define_insn "*movhi_insn"
415   [(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr")
416         (match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
417   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
418   "@
419    %0 = %1;
420    %0 = %1 (X);
421    %0 = %1 (X);
422    %0 = W %1 (X);
423    W %0 = %1;"
424   [(set_attr "type" "move,mvi,mvi,mcld,mcst")
425    (set_attr "length" "2,2,4,*,*")])
426
427 (define_insn "*movqi_insn"
428   [(set (match_operand:QI 0 "nonimmediate_operand" "=x,da,x,d,mr")
429         (match_operand:QI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
430   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
431   "@
432    %0 = %1;
433    %0 = %1 (X);
434    %0 = %1 (X);
435    %0 = B %1 (X);
436    B %0 = %1;"
437   [(set_attr "type" "move,mvi,mvi,mcld,mcst")
438    (set_attr "length" "2,2,4,*,*")])
439
440 (define_insn "*movsf_insn"
441   [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,da,mr")
442         (match_operand:SF 1 "general_operand" "x,Fx,mr,da"))]
443   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
444   "@
445    %0 = %1;
446    #
447    %0 = %1;
448    %0 = %1;"
449   [(set_attr "type" "move,*,mcld,mcst")])
450
451 (define_insn_and_split "movdf_insn"
452   [(set (match_operand:DF 0 "nonimmediate_operand" "=x,mx,r")
453         (match_operand:DF 1 "general_operand" "iFx,r,mx"))]
454   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
455   "#"
456   "reload_completed"
457   [(set (match_dup 2) (match_dup 3))
458    (set (match_dup 4) (match_dup 5))]
459 {
460   rtx lo_half[2], hi_half[2];
461   split_di (operands, 2, lo_half, hi_half);
462
463   if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
464     {
465       operands[2] = hi_half[0];
466       operands[3] = hi_half[1];
467       operands[4] = lo_half[0];
468       operands[5] = lo_half[1];
469     }
470   else
471     {
472       operands[2] = lo_half[0];
473       operands[3] = lo_half[1];
474       operands[4] = hi_half[0];
475       operands[5] = hi_half[1];
476     }
477 })
478
479 ;; This is the main "hook" for PIC code.  When generating
480 ;; PIC, movsi is responsible for determining when the source address
481 ;; needs PIC relocation and appropriately calling legitimize_pic_address
482 ;; to perform the actual relocation.
483
484 (define_expand "movsi"
485   [(set (match_operand:SI 0 "nonimmediate_operand" "")
486         (match_operand:SI 1 "general_operand" ""))]
487   ""
488   "expand_move (operands, SImode);")
489
490 (define_expand "movv2hi"
491   [(set (match_operand:V2HI 0 "nonimmediate_operand" "")
492         (match_operand:V2HI 1 "general_operand" ""))]
493   ""
494   "expand_move (operands, V2HImode);")
495
496 (define_expand "movdi"
497   [(set (match_operand:DI 0 "nonimmediate_operand" "")
498         (match_operand:DI 1 "general_operand" ""))]
499   ""
500   "expand_move (operands, DImode);")
501
502 (define_expand "movsf"
503  [(set (match_operand:SF 0 "nonimmediate_operand" "")
504        (match_operand:SF 1 "general_operand" ""))]
505   ""
506   "expand_move (operands, SFmode);")
507
508 (define_expand "movdf"
509  [(set (match_operand:DF 0 "nonimmediate_operand" "")
510        (match_operand:DF 1 "general_operand" ""))]
511   ""
512   "expand_move (operands, DFmode);")
513
514 (define_expand "movhi"
515   [(set (match_operand:HI 0 "nonimmediate_operand" "")
516         (match_operand:HI 1 "general_operand" ""))]
517   ""
518   "expand_move (operands, HImode);")
519
520 (define_expand "movqi"
521   [(set (match_operand:QI 0 "nonimmediate_operand" "")
522         (match_operand:QI 1 "general_operand" ""))]
523   ""
524   " expand_move (operands, QImode); ")
525
526 ;; Some define_splits to break up SI/SFmode loads of immediate constants.
527
528 (define_split
529   [(set (match_operand:SI 0 "register_operand" "")
530         (match_operand:SI 1 "symbolic_or_const_operand" ""))]
531   "reload_completed
532    /* Always split symbolic operands; split integer constants that are
533       too large for a single instruction.  */
534    && (GET_CODE (operands[1]) != CONST_INT
535        || (INTVAL (operands[1]) < -32768
536            || INTVAL (operands[1]) >= 65536
537            || (INTVAL (operands[1]) >= 32768 && PREG_P (operands[0]))))"
538   [(set (match_dup 0) (high:SI (match_dup 1)))
539    (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))]
540 {
541   if (GET_CODE (operands[1]) == CONST_INT
542       && split_load_immediate (operands))
543     DONE;
544   /* ??? Do something about TARGET_LOW_64K.  */
545 })
546
547 (define_split
548   [(set (match_operand:SF 0 "register_operand" "")
549         (match_operand:SF 1 "immediate_operand" ""))]
550   "reload_completed"
551   [(set (match_dup 2) (high:SI (match_dup 3)))
552    (set (match_dup 2) (lo_sum:SI (match_dup 2) (match_dup 3)))]
553 {
554   long values;
555   REAL_VALUE_TYPE value;
556
557   gcc_assert (GET_CODE (operands[1]) == CONST_DOUBLE);
558
559   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
560   REAL_VALUE_TO_TARGET_SINGLE (value, values);
561
562   operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0]));
563   operands[3] = GEN_INT (trunc_int_for_mode (values, SImode));
564   if (values >= -32768 && values < 65536)
565     {
566       emit_move_insn (operands[2], operands[3]);
567       DONE;
568     }
569   if (split_load_immediate (operands + 2))
570     DONE;
571 })
572
573 ;; Sadly, this can't be a proper named movstrict pattern, since the compiler
574 ;; expects to be able to use registers for operand 1.
575 ;; Note that the asm instruction is defined by the manual to take an unsigned
576 ;; constant, but it doesn't matter to the assembler, and the compiler only
577 ;; deals with sign-extended constants.  Hence "Ksh".
578 (define_insn "*movstricthi"
579   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+x"))
580         (match_operand:HI 1 "immediate_operand" "Ksh"))]
581   ""
582   "%h0 = %1;"
583   [(set_attr "type" "mvi")
584    (set_attr "length" "4")])
585
586 ;; Sign and zero extensions
587
588 (define_insn "extendhisi2"
589   [(set (match_operand:SI 0 "register_operand" "=d, d")
590         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
591   ""
592   "@
593    %0 = %h1 (X);
594    %0 = W %h1 (X);"
595   [(set_attr "type" "alu0,mcld")])
596
597 (define_insn "zero_extendhisi2"
598   [(set (match_operand:SI 0 "register_operand" "=d, d")
599         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
600   ""
601   "@
602    %0 = %h1 (Z);
603    %0 = W%h1 (Z);"
604   [(set_attr "type" "alu0,mcld")])
605
606 (define_insn "zero_extendbisi2"
607   [(set (match_operand:SI 0 "register_operand" "=d")
608         (zero_extend:SI (match_operand:BI 1 "nonimmediate_operand" "C")))]
609   ""
610   "%0 = %1;"
611   [(set_attr "type" "compare")])
612
613 (define_insn "extendqihi2"
614   [(set (match_operand:HI 0 "register_operand" "=d, d")
615         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
616   ""
617   "@
618    %0 = B %1 (X);
619    %0 = %T1 (X);"
620   [(set_attr "type" "mcld,alu0")])
621
622 (define_insn "extendqisi2"
623   [(set (match_operand:SI 0 "register_operand" "=d, d")
624         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
625   ""
626   "@
627    %0 = B %1 (X);
628    %0 = %T1 (X);"
629   [(set_attr "type" "mcld,alu0")])
630
631
632 (define_insn "zero_extendqihi2"
633   [(set (match_operand:HI 0 "register_operand" "=d, d")
634         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
635   ""
636   "@
637    %0 = B %1 (Z);
638    %0 = %T1 (Z);"
639   [(set_attr "type" "mcld,alu0")])
640
641
642 (define_insn "zero_extendqisi2"
643   [(set (match_operand:SI 0 "register_operand" "=d, d")
644         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
645   ""
646   "@
647    %0 = B %1 (Z);
648    %0 = %T1 (Z);"
649   [(set_attr "type" "mcld,alu0")])
650
651 ;; DImode logical operations
652
653 (define_code_macro any_logical [and ior xor])
654 (define_code_attr optab [(and "and")
655                          (ior "ior")
656                          (xor "xor")])
657 (define_code_attr op [(and "&")
658                       (ior "|")
659                       (xor "^")])
660 (define_code_attr high_result [(and "0")
661                                (ior "%H1")
662                                (xor "%H1")])
663
664 (define_insn "<optab>di3"
665   [(set (match_operand:DI 0 "register_operand" "=d")
666         (any_logical:DI (match_operand:DI 1 "register_operand" "0")
667                         (match_operand:DI 2 "register_operand" "d")))]
668   ""
669   "%0 = %1 <op> %2;\\n\\t%H0 = %H1 <op> %H2;"
670   [(set_attr "length" "4")])
671
672 (define_insn "*<optab>di_zesidi_di"
673   [(set (match_operand:DI 0 "register_operand" "=d")
674         (any_logical:DI (zero_extend:DI
675                          (match_operand:SI 2 "register_operand" "d"))
676                         (match_operand:DI 1 "register_operand" "d")))]
677   ""
678   "%0 = %1 <op>  %2;\\n\\t%H0 = <high_result>;"
679   [(set_attr "length" "4")])
680
681 (define_insn "*<optab>di_sesdi_di"
682   [(set (match_operand:DI 0 "register_operand" "=d")
683         (any_logical:DI (sign_extend:DI
684                          (match_operand:SI 2 "register_operand" "d"))
685                         (match_operand:DI 1 "register_operand" "0")))
686    (clobber (match_scratch:SI 3 "=&d"))]
687   ""
688   "%0 = %1 <op> %2;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 <op> %3;"
689   [(set_attr "length" "8")])
690
691 (define_insn "negdi2"
692   [(set (match_operand:DI 0 "register_operand" "=d")
693         (neg:DI (match_operand:DI 1 "register_operand" "d")))
694    (clobber (match_scratch:SI 2 "=&d"))
695    (clobber (reg:CC REG_CC))]
696   ""
697   "%2 = 0; %2 = %2 - %1; cc = ac0; cc = !cc; %2 = cc;\\n\\t%0 = -%1; %H0 = -%H1; %H0 = %H0 - %2;"
698   [(set_attr "length" "16")])
699
700 (define_insn "one_cmpldi2"
701   [(set (match_operand:DI 0 "register_operand" "=d")
702         (not:DI (match_operand:DI 1 "register_operand" "d")))]
703   ""
704   "%0 = ~%1;\\n\\t%H0 = ~%H1;"
705   [(set_attr "length" "4")])
706
707 ;; DImode zero and sign extend patterns
708
709 (define_insn_and_split "zero_extendsidi2"
710   [(set (match_operand:DI 0 "register_operand" "=d")
711         (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
712   ""
713   "#"
714   "reload_completed"
715   [(set (match_dup 3) (const_int 0))]
716 {
717   split_di (operands, 1, operands + 2, operands + 3);
718   if (REGNO (operands[0]) != REGNO (operands[1]))
719     emit_move_insn (operands[2], operands[1]);
720 })
721
722 (define_insn "zero_extendqidi2"
723   [(set (match_operand:DI 0 "register_operand" "=d")
724         (zero_extend:DI (match_operand:QI 1 "register_operand" "d")))]
725   ""
726   "%0 = %T1 (Z);\\n\\t%H0 = 0;"
727   [(set_attr "length" "4")])
728
729 (define_insn "zero_extendhidi2"
730   [(set (match_operand:DI 0 "register_operand" "=d")
731         (zero_extend:DI (match_operand:HI 1 "register_operand" "d")))]
732   ""
733   "%0 = %h1 (Z);\\n\\t%H0 = 0;"
734   [(set_attr "length" "4")])
735
736 (define_insn_and_split "extendsidi2"
737   [(set (match_operand:DI 0 "register_operand" "=d")
738         (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))]
739   ""
740   "#"
741   "reload_completed"
742   [(set (match_dup 3) (match_dup 1))
743    (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
744 {
745   split_di (operands, 1, operands + 2, operands + 3);
746   if (REGNO (operands[0]) != REGNO (operands[1]))
747     emit_move_insn (operands[2], operands[1]);
748 })
749
750 (define_insn_and_split "extendqidi2"
751   [(set (match_operand:DI 0 "register_operand" "=d")
752         (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
753   ""
754   "#"
755   "reload_completed"
756   [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
757    (set (match_dup 3) (sign_extend:SI (match_dup 1)))
758    (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
759 {
760   split_di (operands, 1, operands + 2, operands + 3);
761 })
762
763 (define_insn_and_split "extendhidi2"
764   [(set (match_operand:DI 0 "register_operand" "=d")
765         (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
766   ""
767   "#"
768   "reload_completed"
769   [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
770    (set (match_dup 3) (sign_extend:SI (match_dup 1)))
771    (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
772 {
773   split_di (operands, 1, operands + 2, operands + 3);
774 })
775
776 ;; DImode arithmetic operations
777
778 (define_insn "adddi3"
779   [(set (match_operand:DI 0 "register_operand" "=&d,&d,&d")
780         (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
781                  (match_operand:DI 2 "nonmemory_operand" "Kn7,Ks7,d")))
782    (clobber (match_scratch:SI 3 "=&d,&d,&d"))
783    (clobber (reg:CC 34))]
784   ""
785   "@
786    %0 += %2; cc = ac0; %3 = cc; %H0 += -1; %H0 = %H0 + %3;
787    %0 += %2; cc = ac0; %3 = cc; %H0 = %H0 + %3;
788    %0 = %0 + %2; cc = ac0; %3 = cc; %H0 = %H0 + %H2; %H0 = %H0 + %3;"
789   [(set_attr "type" "alu0")
790    (set_attr "length" "10,8,10")])
791
792 (define_insn "subdi3"
793   [(set (match_operand:DI 0 "register_operand" "=&d")
794         (minus:DI (match_operand:DI 1 "register_operand" "0")
795                   (match_operand:DI 2 "register_operand" "d")))
796    (clobber (reg:CC 34))]
797   ""
798   "%0 = %1-%2;\\n\\tcc = ac0;\\n\\t%H0 = %H1-%H2;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
799   [(set_attr "length" "10")])
800
801 (define_insn "*subdi_di_zesidi"
802   [(set (match_operand:DI 0 "register_operand" "=d")
803         (minus:DI (match_operand:DI 1 "register_operand" "0")
804                   (zero_extend:DI
805                   (match_operand:SI 2 "register_operand" "d"))))
806    (clobber (match_scratch:SI 3 "=&d"))
807    (clobber (reg:CC 34))]
808   ""
809   "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%H0 = %H1 - %3;"
810   [(set_attr "length" "10")])
811
812 (define_insn "*subdi_zesidi_di"
813   [(set (match_operand:DI 0 "register_operand" "=d")
814         (minus:DI (zero_extend:DI
815                   (match_operand:SI 2 "register_operand" "d"))
816                   (match_operand:DI 1 "register_operand" "0")))
817    (clobber (match_scratch:SI 3 "=&d"))
818    (clobber (reg:CC 34))]
819   ""
820   "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%3 = -%3;\\n\\t%H0 = %3 - %H1"
821   [(set_attr "length" "12")])
822
823 (define_insn "*subdi_di_sesidi"
824   [(set (match_operand:DI 0 "register_operand" "=d")
825         (minus:DI (match_operand:DI 1 "register_operand" "0")
826                   (sign_extend:DI
827                   (match_operand:SI 2 "register_operand" "d"))))
828    (clobber (match_scratch:SI 3 "=&d"))
829    (clobber (reg:CC 34))]
830   ""
831   "%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:"
832   [(set_attr "length" "14")])
833
834 (define_insn "*subdi_sesidi_di"
835   [(set (match_operand:DI 0 "register_operand" "=d")
836         (minus:DI (sign_extend:DI
837                   (match_operand:SI 2 "register_operand" "d"))
838                   (match_operand:DI 1 "register_operand" "0")))
839    (clobber (match_scratch:SI 3 "=&d"))
840    (clobber (reg:CC 34))]
841   ""
842   "%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:"
843   [(set_attr "length" "14")])
844
845 ;; Combined shift/add instructions
846
847 (define_insn ""
848   [(set (match_operand:SI 0 "register_operand" "=a,d")
849         (ashift:SI (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
850                             (match_operand:SI 2 "register_operand" "a,d"))
851                    (match_operand:SI 3 "pos_scale_operand" "P1P2,P1P2")))]
852   ""
853   "%0 = (%0 + %2) << %3;" /* "shadd %0,%2,%3;" */
854   [(set_attr "type" "alu0")])
855
856 (define_insn ""
857   [(set (match_operand:SI 0 "register_operand" "=a")
858         (plus:SI (match_operand:SI 1 "register_operand" "a")
859                  (mult:SI (match_operand:SI 2 "register_operand" "a")
860                           (match_operand:SI 3 "scale_by_operand" "i"))))]
861   ""
862   "%0 = %1 + (%2 << %X3);"
863   [(set_attr "type" "alu0")])
864
865 (define_insn ""
866   [(set (match_operand:SI 0 "register_operand" "=a")
867         (plus:SI (match_operand:SI 1 "register_operand" "a")
868                  (ashift:SI (match_operand:SI 2 "register_operand" "a")
869                             (match_operand:SI 3 "pos_scale_operand" "i"))))]
870   ""
871   "%0 = %1 + (%2 << %3);"
872   [(set_attr "type" "alu0")])
873
874 (define_insn ""
875   [(set (match_operand:SI 0 "register_operand" "=a")
876         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "a")
877                           (match_operand:SI 2 "scale_by_operand" "i"))
878                  (match_operand:SI 3 "register_operand" "a")))]
879   ""
880   "%0 = %3 + (%1 << %X2);"
881   [(set_attr "type" "alu0")])
882
883 (define_insn ""
884   [(set (match_operand:SI 0 "register_operand" "=a")
885         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "a")
886                             (match_operand:SI 2 "pos_scale_operand" "i"))
887                  (match_operand:SI 3 "register_operand" "a")))]
888   ""
889   "%0 = %3 + (%1 << %2);"
890   [(set_attr "type" "alu0")])
891
892 (define_insn "mulhisi3"
893   [(set (match_operand:SI 0 "register_operand" "=d")
894         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%d"))
895                  (sign_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
896   ""
897   "%0 = %h1 * %h2 (IS);"
898   [(set_attr "type" "dsp32")])
899
900 (define_insn "umulhisi3"
901   [(set (match_operand:SI 0 "register_operand" "=d")
902         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%d"))
903                  (zero_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
904   ""
905   "%0 = %h1 * %h2 (FU);"
906   [(set_attr "type" "dsp32")])
907
908 ;; The processor also supports ireg += mreg or ireg -= mreg, but these
909 ;; are unusable if we don't ensure that the corresponding lreg is zero.
910 ;; The same applies to the add/subtract constant versions involving
911 ;; iregs
912
913 (define_insn "addsi3"
914   [(set (match_operand:SI 0 "register_operand" "=ad,a,d")
915         (plus:SI (match_operand:SI 1 "register_operand" "%0, a,d")
916                  (match_operand:SI 2 "reg_or_7bit_operand" "Ks7, a,d")))]
917   ""
918   "@
919    %0 += %2;
920    %0 = %1 + %2;
921    %0 = %1 + %2;"
922   [(set_attr "type" "alu0")
923    (set_attr "length" "2,2,2")])
924
925 (define_expand "subsi3"
926   [(set (match_operand:SI 0 "register_operand" "")
927         (minus:SI (match_operand:SI 1 "register_operand" "")
928                   (match_operand:SI 2 "reg_or_7bit_operand" "")))]
929   ""
930   "")
931
932 (define_insn ""
933   [(set (match_operand:SI 0 "register_operand" "=da,d,a")
934         (minus:SI (match_operand:SI 1 "register_operand" "0,d,0")
935                   (match_operand:SI 2 "reg_or_7bit_operand" "Ks7,d,a")))]
936   "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -64"
937 {
938   static const char *const strings_subsi3[] = {
939     "%0 += -%2;",
940     "%0 = %1 - %2;",
941     "%0 -= %2;",
942   };
943
944   if (CONSTANT_P (operands[2]) && INTVAL (operands[2]) < 0) {
945      rtx tmp_op = operands[2];
946      operands[2] = GEN_INT (-INTVAL (operands[2]));
947      output_asm_insn ("%0 += %2;", operands);
948      operands[2] = tmp_op;
949      return "";
950   }
951
952   return strings_subsi3[which_alternative];
953 }
954   [(set_attr "type" "alu0")])
955
956 ;; Bit test instructions
957
958 (define_insn "*not_bittst"
959  [(set (match_operand:BI 0 "cc_operand" "=C")
960        (eq:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
961                                (const_int 1)
962                                (match_operand:SI 2 "immediate_operand" "Ku5"))
963               (const_int 0)))]
964  ""
965  "cc = !BITTST (%1,%2);"
966   [(set_attr "type" "alu0")])
967
968 (define_insn "*bittst"
969  [(set (match_operand:BI 0 "cc_operand" "=C")
970        (ne:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
971                                (const_int 1)
972                                (match_operand:SI 2 "immediate_operand" "Ku5"))
973                 (const_int 0)))]
974  ""
975  "cc = BITTST (%1,%2);"
976   [(set_attr "type" "alu0")])
977
978 (define_insn_and_split "*bit_extract"
979   [(set (match_operand:SI 0 "register_operand" "=d")
980         (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
981                          (const_int 1)
982                          (match_operand:SI 2 "immediate_operand" "Ku5")))
983    (clobber (reg:BI REG_CC))]
984   ""
985   "#"
986   ""
987   [(set (reg:BI REG_CC)
988         (ne:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
989                (const_int 0)))
990    (set (match_dup 0)
991         (ne:SI (reg:BI REG_CC) (const_int 0)))])
992
993 (define_insn_and_split "*not_bit_extract"
994   [(set (match_operand:SI 0 "register_operand" "=d")
995         (zero_extract:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
996                          (const_int 1)
997                          (match_operand:SI 2 "immediate_operand" "Ku5")))
998    (clobber (reg:BI REG_CC))]
999   ""
1000   "#"
1001   ""
1002   [(set (reg:BI REG_CC)
1003         (eq:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1004                (const_int 0)))
1005    (set (match_dup 0)
1006         (ne:SI (reg:BI REG_CC) (const_int 0)))])
1007
1008 (define_insn "*andsi_insn"
1009   [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
1010         (and:SI (match_operand:SI 1 "register_operand" "%0,d,d,d")
1011                 (match_operand:SI 2 "rhs_andsi3_operand" "L,M1,M2,d")))]
1012   ""
1013   "@
1014    BITCLR (%0,%Y2);
1015    %0 = %T1 (Z);
1016    %0 = %h1 (Z);
1017    %0 = %1 & %2;"
1018   [(set_attr "type" "alu0")])
1019
1020 (define_expand "andsi3"
1021   [(set (match_operand:SI 0 "register_operand" "")
1022         (and:SI (match_operand:SI 1 "register_operand" "")
1023                 (match_operand:SI 2 "general_operand" "")))]
1024   ""
1025 {
1026   if (highbits_operand (operands[2], SImode))
1027     {
1028       operands[2] = GEN_INT (exact_log2 (-INTVAL (operands[2])));
1029       emit_insn (gen_ashrsi3 (operands[0], operands[1], operands[2]));
1030       emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
1031       DONE;
1032     }
1033   if (! rhs_andsi3_operand (operands[2], SImode))
1034     operands[2] = force_reg (SImode, operands[2]);
1035 })
1036
1037 (define_insn "iorsi3"
1038   [(set (match_operand:SI 0 "register_operand" "=d,d")
1039         (ior:SI (match_operand:SI 1 "register_operand" "%0,d")
1040                 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1041   ""
1042   "@
1043    BITSET (%0, %X2);
1044    %0 = %1 | %2;"
1045   [(set_attr "type" "alu0")])
1046
1047 (define_insn "xorsi3"
1048   [(set (match_operand:SI 0 "register_operand" "=d,d")
1049         (xor:SI (match_operand:SI 1 "register_operand" "%0,d")
1050                   (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1051   ""
1052   "@
1053    BITTGL (%0, %X2);
1054    %0 = %1 ^ %2;"
1055   [(set_attr "type" "alu0")])
1056
1057 (define_insn "smaxsi3"
1058   [(set (match_operand:SI 0 "register_operand" "=d")
1059         (smax:SI (match_operand:SI 1 "register_operand" "d")
1060                  (match_operand:SI 2 "register_operand" "d")))]
1061   ""
1062   "%0 =max(%1,%2);"
1063   [(set_attr "type" "dsp32")])
1064
1065 (define_insn "sminsi3"
1066   [(set (match_operand:SI 0 "register_operand" "=d")
1067         (smin:SI (match_operand:SI 1 "register_operand" "d")
1068                  (match_operand:SI 2 "register_operand" "d")))]
1069   ""
1070   "%0 =min(%1,%2);"
1071   [(set_attr "type" "dsp32")])
1072
1073 (define_insn "abssi2"
1074   [(set (match_operand:SI 0 "register_operand" "=d")
1075         (abs:SI (match_operand:SI 1 "register_operand" " d")))]
1076   ""
1077   "%0 =abs %1;"
1078   [(set_attr "type" "dsp32")])
1079
1080
1081 (define_insn "negsi2"
1082   [(set (match_operand:SI 0 "register_operand" "=d")
1083         (neg:SI (match_operand:SI 1 "register_operand" " d")))]
1084   ""
1085   "%0 =-%1;"
1086   [(set_attr "type" "alu0")])
1087
1088 (define_insn "one_cmplsi2"
1089   [(set (match_operand:SI 0 "register_operand" "=d")
1090         (not:SI (match_operand:SI 1 "register_operand" " d")))]
1091   ""
1092   "%0 =~%1;"
1093   [(set_attr "type" "alu0")])
1094
1095 (define_insn "mulsi3"
1096   [(set (match_operand:SI 0 "register_operand" "=d")
1097         (mult:SI (match_operand:SI 1 "register_operand" "%0")
1098                  (match_operand:SI 2 "register_operand" "d")))]
1099   ""
1100   "%0 *=%2;"
1101   [(set_attr "type" "mult")])
1102
1103 (define_expand "ashlsi3"
1104   [(set (match_operand:SI 0 "register_operand" "")
1105         (ashift:SI (match_operand:SI 1 "register_operand" "")
1106                    (match_operand:SI 2 "nonmemory_operand" "")))]
1107   ""
1108 {
1109  if (GET_CODE (operands[2]) == CONST_INT
1110      && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1111    {
1112      emit_insn (gen_movsi (operands[0], const0_rtx));
1113      DONE;
1114    }
1115 })
1116
1117 (define_insn_and_split "*ashlsi3_insn"
1118   [(set (match_operand:SI 0 "register_operand" "=d,a,a,a")
1119         (ashift:SI (match_operand:SI 1 "register_operand" "0,a,a,a")
1120                    (match_operand:SI 2 "nonmemory_operand" "dKu5,P1,P2,?P3P4")))]
1121   ""
1122   "@
1123    %0 <<= %2;
1124    %0 = %1 + %1;
1125    %0 = %1 << %2;
1126    #"
1127   "PREG_P (operands[0]) && INTVAL (operands[2]) > 2"
1128   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
1129    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
1130   "operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
1131   [(set_attr "type" "shft")])
1132
1133 (define_insn "ashrsi3"
1134   [(set (match_operand:SI 0 "register_operand" "=d")
1135         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1136                      (match_operand:SI 2 "nonmemory_operand" "dKu5")))]
1137   ""
1138   "%0 >>>= %2;"
1139   [(set_attr "type" "shft")])
1140
1141 (define_insn "lshrsi3"
1142   [(set (match_operand:SI 0 "register_operand" "=d,a")
1143         (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0,a")
1144                      (match_operand:SI 2 "nonmemory_operand" "dKu5,P1P2")))]
1145   ""
1146   "@
1147    %0 >>= %2;
1148    %0 = %1 >> %2;"
1149   [(set_attr "type" "shft")])
1150
1151 ;; A pattern to reload the equivalent of
1152 ;;   (set (Dreg) (plus (FP) (large_constant)))
1153 ;; or
1154 ;;   (set (dagreg) (plus (FP) (arbitrary_constant))) 
1155 ;; using a scratch register
1156 (define_expand "reload_insi"
1157   [(parallel [(set (match_operand:SI 0 "register_operand" "=w")
1158                    (match_operand:SI 1 "fp_plus_const_operand" ""))
1159               (clobber (match_operand:SI 2 "register_operand" "=&a"))])]
1160   ""
1161 {
1162   rtx fp_op = XEXP (operands[1], 0);
1163   rtx const_op = XEXP (operands[1], 1);
1164   rtx primary = operands[0];
1165   rtx scratch = operands[2];
1166
1167   emit_move_insn (scratch, const_op);
1168   emit_insn (gen_addsi3 (scratch, scratch, fp_op));
1169   emit_move_insn (primary, scratch);
1170   DONE;
1171 })
1172
1173 ;; Jump instructions
1174
1175 (define_insn "jump"
1176   [(set (pc)
1177         (label_ref (match_operand 0 "" "")))]
1178   ""
1179 {
1180   if (get_attr_length (insn) == 2)
1181     return "jump.s %0;";
1182   else
1183     return "jump.l %0;";
1184 }
1185   [(set_attr "type" "br")])
1186
1187 (define_insn "indirect_jump"
1188   [(set (pc)
1189         (match_operand:SI 0 "register_operand" "a"))]
1190   ""
1191   "jump (%0);"
1192   [(set_attr "type" "misc")])
1193
1194 (define_expand "tablejump"
1195   [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1196               (use (label_ref (match_operand 1 "" "")))])]
1197   ""
1198 {
1199   /* In PIC mode, the table entries are stored PC relative.
1200      Convert the relative address to an absolute address.  */
1201   if (flag_pic)
1202     {
1203       rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1204
1205       operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1206                                          op1, NULL_RTX, 0, OPTAB_DIRECT);
1207     }
1208 })
1209
1210 (define_insn "*tablejump_internal"
1211   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1212    (use (label_ref (match_operand 1 "" "")))]
1213   ""
1214   "jump (%0);"
1215   [(set_attr "type" "misc")])
1216
1217 ;;  Call instructions..
1218
1219 (define_expand "call"
1220   [(call (match_operand:SI 0 "" "")
1221          (match_operand 1 "" ""))]
1222   ""
1223   "bfin_expand_call (NULL_RTX, operands[0], operands[1], 0); DONE;")
1224
1225 (define_expand "sibcall"
1226   [(parallel [(call (match_operand:SI 0 "" "")
1227                     (match_operand 1 "" ""))
1228               (return)])]
1229   ""
1230   "bfin_expand_call (NULL_RTX, operands[0], operands[1], 1); DONE;")
1231
1232 (define_expand "call_value"
1233   [(set (match_operand 0 "register_operand" "")
1234          (call (match_operand:SI 1 "" "")
1235                (match_operand 2 "" "")))]
1236   ""
1237   "bfin_expand_call (operands[0], operands[1], operands[2], 0); DONE;")
1238
1239 (define_expand "sibcall_value"
1240   [(parallel [(set (match_operand 0 "register_operand" "")
1241                    (call (match_operand:SI 1 "" "")
1242                          (match_operand 2 "" "")))
1243               (return)])]
1244   ""
1245   "bfin_expand_call (operands[0], operands[1], operands[2], 1); DONE;")
1246
1247 (define_insn "*call_insn"
1248   [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "a,Q"))
1249          (match_operand 1 "general_operand" "g,g"))]
1250   "! SIBLING_CALL_P (insn)
1251    && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
1252   "@
1253   call (%0);
1254   call %G0;"
1255   [(set_attr "type" "call")
1256    (set_attr "length" "2,4")])
1257
1258 (define_insn "*sibcall_insn"
1259   [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "z,Q"))
1260          (match_operand 1 "general_operand" "g,g"))
1261    (return)]
1262   "SIBLING_CALL_P (insn)
1263    && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
1264   "@
1265   jump (%0);
1266   jump.l %G0;"
1267   [(set_attr "type" "br")
1268    (set_attr "length" "2,4")])
1269
1270 (define_insn "*call_value_insn"
1271   [(set (match_operand 0 "register_operand" "=d,d")
1272         (call (mem:SI (match_operand:SI 1 "call_insn_operand" "a,Q"))
1273               (match_operand 2 "general_operand" "g,g")))]
1274   "! SIBLING_CALL_P (insn)
1275    && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
1276   "@
1277   call (%1);
1278   call %G1;"
1279   [(set_attr "type" "call")
1280    (set_attr "length" "2,4")])
1281
1282 (define_insn "*sibcall_value_insn"
1283   [(set (match_operand 0 "register_operand" "=d,d")
1284          (call (mem:SI (match_operand:SI 1 "call_insn_operand" "z,Q"))
1285                (match_operand 2 "general_operand" "g,g")))
1286    (return)]
1287   "SIBLING_CALL_P (insn)
1288    && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
1289   "@
1290   jump (%1);
1291   jump.l %G1;"
1292   [(set_attr "type" "br")
1293    (set_attr "length" "2,4")])
1294
1295 ;; Block move patterns
1296
1297 ;; We cheat.  This copies one more word than operand 2 indicates.
1298
1299 (define_insn "rep_movsi"
1300   [(set (match_operand:SI 0 "register_operand" "=&a")
1301         (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1302                           (ashift:SI (match_operand:SI 2 "register_operand" "a")
1303                                      (const_int 2)))
1304                  (const_int 4)))
1305    (set (match_operand:SI 1 "register_operand" "=&b")
1306         (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1307                           (ashift:SI (match_dup 2) (const_int 2)))
1308                  (const_int 4)))
1309    (set (mem:BLK (match_dup 3))
1310         (mem:BLK (match_dup 4)))
1311    (use (match_dup 2))
1312    (clobber (match_scratch:HI 5 "=&d"))]
1313   ""
1314   "lsetup (1f, 1f) LC1 = %2; %5 = [%4++]; 1: MNOP || [%3++] = %5 || %5 = [%4++]; [%3++] = %5;"
1315   [(set_attr "type" "misc")
1316    (set_attr "length" "16")])
1317
1318 (define_insn "rep_movhi"
1319   [(set (match_operand:SI 0 "register_operand" "=&a")
1320         (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1321                           (ashift:SI (match_operand:SI 2 "register_operand" "a")
1322                                      (const_int 1)))
1323                  (const_int 2)))
1324    (set (match_operand:SI 1 "register_operand" "=&b")
1325         (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1326                           (ashift:SI (match_dup 2) (const_int 1)))
1327                  (const_int 2)))
1328    (set (mem:BLK (match_dup 3))
1329         (mem:BLK (match_dup 4)))
1330    (use (match_dup 2))
1331    (clobber (match_scratch:HI 5 "=&d"))]
1332   ""
1333   "lsetup (1f, 1f) LC1 = %2; %h5 = W[%4++]; 1: MNOP || W [%3++] = %5 || %h5 = W [%4++]; W [%3++] = %5;"
1334   [(set_attr "type" "misc")
1335    (set_attr "length" "16")])
1336
1337 (define_expand "movstrsi"
1338   [(match_operand:BLK 0 "general_operand" "")
1339    (match_operand:BLK 1 "general_operand" "")
1340    (match_operand:SI 2 "const_int_operand" "")
1341    (match_operand:SI 3 "const_int_operand" "")]
1342   ""
1343 {
1344   if (bfin_expand_strmov (operands[0], operands[1], operands[2], operands[3]))
1345     DONE;
1346   FAIL;
1347 })
1348
1349 ;; Conditional branch patterns
1350 ;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
1351
1352 ;; The only outcome of this pattern is that global variables
1353 ;; bfin_compare_op[01] are set for use in bcond patterns.
1354
1355 (define_expand "cmpbi"
1356  [(set (cc0) (compare (match_operand:BI 0 "register_operand" "")
1357                       (match_operand:BI 1 "immediate_operand" "")))]
1358  ""
1359 {
1360   bfin_compare_op0 = operands[0];
1361   bfin_compare_op1 = operands[1];
1362   DONE;
1363 })
1364
1365 (define_expand "cmpsi"
1366  [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
1367                       (match_operand:SI 1 "nonmemory_operand" "")))]
1368  ""
1369 {
1370   bfin_compare_op0 = operands[0];
1371   bfin_compare_op1 = operands[1];
1372   DONE;
1373 })
1374
1375 (define_insn ""
1376   [(set (match_operand:BI 0 "cc_operand" "=C,C")
1377         (eq:BI (match_operand:SI 1 "register_operand" "d,a")
1378                (match_operand:SI 2 "nonmemory_operand" "dKs3,aKs3")))]
1379   ""
1380   "cc =%1==%2;"
1381   [(set_attr "type" "compare")])
1382
1383 (define_insn ""
1384   [(set (match_operand:BI 0 "cc_operand" "=C,C")
1385         (ne:BI (match_operand:SI 1 "register_operand" "d,a")
1386                (match_operand:SI 2 "nonmemory_operand" "dKs3,aKs3")))]
1387   "0"
1388   "cc =%1!=%2;"
1389   [(set_attr "type" "compare")])
1390
1391 (define_insn ""
1392   [(set (match_operand:BI 0 "cc_operand" "=C,C")
1393         (lt:BI (match_operand:SI 1 "register_operand" "d,a")
1394                (match_operand:SI 2 "nonmemory_operand" "dKs3,aKs3")))]
1395   ""
1396   "cc =%1<%2;"
1397   [(set_attr "type" "compare")])
1398
1399 (define_insn ""
1400   [(set (match_operand:BI 0 "cc_operand" "=C,C")
1401         (le:BI (match_operand:SI 1 "register_operand" "d,a")
1402                (match_operand:SI 2 "nonmemory_operand" "dKs3,aKs3")))]
1403   ""
1404   "cc =%1<=%2;"
1405   [(set_attr "type" "compare")])
1406
1407 (define_insn ""
1408   [(set (match_operand:BI 0 "cc_operand" "=C,C")
1409         (leu:BI (match_operand:SI 1 "register_operand" "d,a")
1410                 (match_operand:SI 2 "nonmemory_operand" "dKu3,aKu3")))]
1411   ""
1412   "cc =%1<=%2 (iu);"
1413   [(set_attr "type" "compare")])
1414
1415 (define_insn ""
1416   [(set (match_operand:BI 0 "cc_operand" "=C,C")
1417         (ltu:BI (match_operand:SI 1 "register_operand" "d,a")
1418                 (match_operand:SI 2 "nonmemory_operand" "dKu3,aKu3")))]
1419   ""
1420   "cc =%1<%2 (iu);"
1421   [(set_attr "type" "compare")])
1422
1423 (define_expand "beq"
1424   [(set (match_dup 1) (match_dup 2))
1425    (set (pc)
1426         (if_then_else (match_dup 3)
1427                    (label_ref (match_operand 0 "" ""))
1428                    (pc)))]
1429   ""
1430 {
1431   rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1432   operands[1] = bfin_cc_rtx;    /* hard register: CC */
1433   operands[2] = gen_rtx_EQ (BImode, op0, op1);
1434   /* If we have a BImode input, then we already have a compare result, and
1435      do not need to emit another comparison.  */
1436   if (GET_MODE (bfin_compare_op0) == BImode)
1437     {
1438       gcc_assert (bfin_compare_op1 == const0_rtx);
1439       emit_insn (gen_cbranchbi4 (operands[2], op0, op1, operands[0]));
1440       DONE;
1441     }
1442
1443   operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1444 })
1445
1446 (define_expand "bne"
1447   [(set (match_dup 1) (match_dup 2))
1448    (set (pc)
1449         (if_then_else (match_dup 3)
1450                       (label_ref (match_operand 0 "" ""))
1451                     (pc)))]
1452   ""
1453 {
1454   rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1455   /* If we have a BImode input, then we already have a compare result, and
1456      do not need to emit another comparison.  */
1457   if (GET_MODE (bfin_compare_op0) == BImode)
1458     {
1459       rtx cmp = gen_rtx_NE (BImode, op0, op1);
1460
1461       gcc_assert (bfin_compare_op1 == const0_rtx);
1462       emit_insn (gen_cbranchbi4 (cmp, op0, op1, operands[0]));
1463       DONE;
1464     }
1465
1466   operands[1] = bfin_cc_rtx;    /* hard register: CC */
1467   operands[2] = gen_rtx_EQ (BImode, op0, op1);
1468   operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1469 })
1470
1471 (define_expand "bgt"
1472   [(set (match_dup 1) (match_dup 2))
1473    (set (pc)
1474         (if_then_else (match_dup 3)
1475                       (label_ref (match_operand 0 "" ""))
1476                     (pc)))]
1477   ""
1478 {
1479   operands[1] = bfin_cc_rtx;
1480   operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1481   operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1482 })
1483
1484 (define_expand "bgtu"
1485   [(set (match_dup 1) (match_dup 2))
1486    (set (pc)
1487         (if_then_else (match_dup 3)
1488                       (label_ref (match_operand 0 "" ""))
1489                     (pc)))]
1490   ""
1491 {
1492   operands[1] = bfin_cc_rtx;
1493   operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1494   operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1495 })
1496
1497 (define_expand "blt"
1498   [(set (match_dup 1) (match_dup 2))
1499    (set (pc)
1500         (if_then_else (match_dup 3)
1501                       (label_ref (match_operand 0 "" ""))
1502                     (pc)))]
1503   ""
1504 {
1505   operands[1] = bfin_cc_rtx;
1506   operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1507   operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1508 })
1509
1510 (define_expand "bltu"
1511   [(set (match_dup 1) (match_dup 2))
1512    (set (pc)
1513         (if_then_else (match_dup 3)
1514                       (label_ref (match_operand 0 "" ""))
1515                       (pc)))]
1516   ""
1517 {
1518   operands[1] = bfin_cc_rtx;
1519   operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1520   operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1521 })
1522
1523
1524 (define_expand "bge"
1525   [(set (match_dup 1) (match_dup 2))
1526    (set (pc)
1527         (if_then_else (match_dup 3)
1528                       (label_ref (match_operand 0 "" ""))
1529                       (pc)))]
1530   ""
1531 {
1532   operands[1] = bfin_cc_rtx;
1533   operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1534   operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1535 })
1536
1537 (define_expand "bgeu"
1538   [(set (match_dup 1) (match_dup 2))
1539    (set (pc)
1540         (if_then_else (match_dup 3)
1541                       (label_ref (match_operand 0 "" ""))
1542                       (pc)))]
1543   ""
1544 {
1545   operands[1] = bfin_cc_rtx;
1546   operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1547   operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1548 })
1549
1550 (define_expand "ble"
1551   [(set (match_dup 1) (match_dup 2))
1552    (set (pc)
1553         (if_then_else (match_dup 3)
1554                       (label_ref (match_operand 0 "" ""))
1555                       (pc)))]
1556   ""
1557 {
1558   operands[1] = bfin_cc_rtx;
1559   operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1560   operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1561 })
1562
1563 (define_expand "bleu"
1564   [(set (match_dup 1) (match_dup 2))
1565    (set (pc)
1566         (if_then_else (match_dup 3)
1567                       (label_ref (match_operand 0 "" ""))
1568                       (pc)))
1569   ]
1570   ""
1571 {
1572   operands[1] = bfin_cc_rtx;
1573   operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1574   operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1575 })
1576
1577 (define_insn "cbranchbi4"
1578   [(set (pc)
1579         (if_then_else
1580          (match_operator 0 "bfin_cbranch_operator"
1581                          [(match_operand:BI 1 "cc_operand" "C")
1582                           (match_operand:BI 2 "immediate_operand" "P0")])
1583          (label_ref (match_operand 3 "" ""))
1584          (pc)))]
1585   ""
1586 {
1587   asm_conditional_branch (insn, operands, 0, 0);
1588   return "";
1589 }
1590   [(set_attr "type" "brcc")])
1591
1592 ;; Special cbranch patterns to deal with the speculative load problem - see
1593 ;; bfin_reorg for details.
1594
1595 (define_insn "cbranch_predicted_taken"
1596   [(set (pc)
1597         (if_then_else
1598          (match_operator 0 "bfin_cbranch_operator"
1599                          [(match_operand:BI 1 "cc_operand" "C")
1600                           (match_operand:BI 2 "immediate_operand" "P0")])
1601          (label_ref (match_operand 3 "" ""))
1602          (pc)))
1603    (unspec [(const_int 0)] UNSPEC_CBRANCH_TAKEN)]
1604   ""
1605 {
1606   asm_conditional_branch (insn, operands, 0, 1);
1607   return "";
1608 }
1609   [(set_attr "type" "brcc")])
1610
1611 (define_insn "cbranch_with_nops"
1612   [(set (pc)
1613         (if_then_else
1614          (match_operator 0 "bfin_cbranch_operator"
1615                          [(match_operand:BI 1 "cc_operand" "C")
1616                           (match_operand:BI 2 "immediate_operand" "P0")])
1617          (label_ref (match_operand 3 "" ""))
1618          (pc)))
1619    (unspec [(match_operand 4 "immediate_operand" "")] UNSPEC_CBRANCH_NOPS)]
1620   "reload_completed"
1621 {
1622   asm_conditional_branch (insn, operands, INTVAL (operands[4]), 0);
1623   return "";
1624 }
1625   [(set_attr "type" "brcc")
1626    (set_attr "length" "6")])
1627
1628 ;; setcc insns.  */
1629 (define_expand "seq"
1630   [(set (match_dup 1) (eq:BI (match_dup 2) (match_dup 3)))
1631    (set (match_operand:SI 0 "register_operand" "")
1632         (ne:SI (match_dup 1) (const_int 0)))]
1633   ""
1634 {
1635   operands[2] = bfin_compare_op0;
1636   operands[3] = bfin_compare_op1;
1637   operands[1] = bfin_cc_rtx;
1638 })
1639
1640 (define_expand "slt"
1641   [(set (match_dup 1) (lt:BI (match_dup 2) (match_dup 3)))
1642    (set (match_operand:SI 0 "register_operand" "")
1643         (ne:SI (match_dup 1) (const_int 0)))]
1644   ""
1645 {
1646    operands[2] = bfin_compare_op0;
1647    operands[3] = bfin_compare_op1;
1648    operands[1] = bfin_cc_rtx;
1649 })
1650
1651 (define_expand "sle"
1652   [(set (match_dup 1) (le:BI (match_dup 2) (match_dup 3)))
1653    (set (match_operand:SI 0 "register_operand" "")
1654         (ne:SI (match_dup 1) (const_int 0)))]
1655   ""
1656 {
1657    operands[2] = bfin_compare_op0;
1658    operands[3] = bfin_compare_op1;
1659    operands[1] = bfin_cc_rtx;
1660 })
1661
1662 (define_expand "sltu"
1663   [(set (match_dup 1) (ltu:BI (match_dup 2) (match_dup 3)))
1664    (set (match_operand:SI 0 "register_operand" "")
1665         (ne:SI (match_dup 1) (const_int 0)))]
1666   ""
1667 {
1668    operands[2] = bfin_compare_op0;
1669    operands[3] = bfin_compare_op1;
1670    operands[1] = bfin_cc_rtx;
1671 })
1672
1673 (define_expand "sleu"
1674   [(set (match_dup 1) (leu:BI (match_dup 2) (match_dup 3)))
1675    (set (match_operand:SI 0 "register_operand" "")
1676         (ne:SI (match_dup 1) (const_int 0)))]
1677   ""
1678 {
1679    operands[2] = bfin_compare_op0;
1680    operands[3] = bfin_compare_op1;
1681    operands[1] = bfin_cc_rtx;
1682 })
1683
1684 (define_insn "nop"
1685   [(const_int 0)]
1686   ""
1687   "nop;")
1688
1689 ;;;;;;;;;;;;;;;;;;;;   CC2dreg   ;;;;;;;;;;;;;;;;;;;;;;;;;
1690 (define_insn "movsibi"
1691   [(set (match_operand:BI 0 "cc_operand" "=C")
1692         (ne:BI (match_operand:SI 1 "register_operand" "d")
1693                (const_int 0)))]
1694   ""
1695   "CC = %1;"
1696   [(set_attr "length" "2")])
1697
1698 (define_insn "movbisi"
1699   [(set (match_operand:SI 0 "register_operand" "=d")
1700         (ne:SI (match_operand:BI 1 "cc_operand" "C")
1701                (const_int 0)))]
1702   ""
1703   "%0 = CC;"
1704   [(set_attr "length" "2")])
1705
1706 (define_insn ""
1707   [(set (match_operand:BI 0 "cc_operand" "=C")
1708         (eq:BI (match_operand:BI 1 "cc_operand" " 0")
1709                (const_int 0)))]
1710   ""
1711   "%0 = ! %0;"    /*  NOT CC;"  */
1712   [(set_attr "type" "compare")])
1713
1714 ;; Vector and DSP insns
1715
1716 (define_insn ""
1717   [(set (match_operand:SI 0 "register_operand" "=d")
1718         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1719                            (const_int 24))
1720                 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1721                              (const_int 8))))]
1722   ""
1723   "%0 = ALIGN8(%1, %2);"
1724   [(set_attr "type" "dsp32")])
1725
1726 (define_insn ""
1727   [(set (match_operand:SI 0 "register_operand" "=d")
1728         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1729                            (const_int 16))
1730                 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1731                              (const_int 16))))]
1732   ""
1733   "%0 = ALIGN16(%1, %2);"
1734   [(set_attr "type" "dsp32")])
1735
1736 (define_insn ""
1737   [(set (match_operand:SI 0 "register_operand" "=d")
1738         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1739                            (const_int 8))
1740                 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1741                              (const_int 24))))]
1742   ""
1743   "%0 = ALIGN24(%1, %2);"
1744   [(set_attr "type" "dsp32")])
1745
1746 ;; Prologue and epilogue.
1747
1748 (define_expand "prologue"
1749   [(const_int 1)]
1750   ""
1751   "bfin_expand_prologue (); DONE;")
1752
1753 (define_expand "epilogue"
1754   [(const_int 1)]
1755   ""
1756   "bfin_expand_epilogue (1, 0); DONE;")
1757
1758 (define_expand "sibcall_epilogue"
1759   [(const_int 1)]
1760   ""
1761   "bfin_expand_epilogue (0, 0); DONE;")
1762
1763 (define_expand "eh_return"
1764   [(unspec_volatile [(match_operand:SI 0 "register_operand" "")]
1765                     UNSPEC_VOLATILE_EH_RETURN)]
1766   ""
1767 {
1768   emit_move_insn (EH_RETURN_HANDLER_RTX, operands[0]);
1769   emit_insn (gen_eh_return_internal ());
1770   emit_barrier ();
1771   DONE;
1772 })
1773
1774 (define_insn_and_split "eh_return_internal"
1775   [(unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN)]
1776   ""
1777   "#"
1778   "reload_completed"
1779   [(const_int 1)]
1780   "bfin_expand_epilogue (1, 1); DONE;")
1781
1782 (define_insn "link"
1783   [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS))
1784    (set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:SI REG_FP))
1785    (set (reg:SI REG_FP)
1786         (plus:SI (reg:SI REG_SP) (const_int -8)))
1787    (set (reg:SI REG_SP)
1788         (plus:SI (reg:SI REG_SP) (match_operand:SI 0 "immediate_operand" "i")))]
1789   ""
1790   "LINK %Z0;"
1791   [(set_attr "length" "4")])
1792
1793 (define_insn "unlink"
1794   [(set (reg:SI REG_FP) (mem:SI (reg:SI REG_FP)))
1795    (set (reg:SI REG_RETS) (mem:SI (plus:SI (reg:SI REG_FP) (const_int 4))))
1796    (set (reg:SI REG_SP) (plus:SI (reg:SI REG_FP) (const_int 8)))]
1797   ""
1798   "UNLINK;"
1799   [(set_attr "length" "4")])
1800
1801 ;; This pattern is slightly clumsy.  The stack adjust must be the final SET in
1802 ;; the pattern, otherwise dwarf2out becomes very confused about which reg goes
1803 ;; where on the stack, since it goes through all elements of the parallel in
1804 ;; sequence.
1805 (define_insn "push_multiple"
1806   [(match_parallel 0 "push_multiple_operation"
1807     [(unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_PUSH_MULTIPLE)])]
1808   ""
1809 {
1810   output_push_multiple (insn, operands);
1811   return "";
1812 })
1813
1814 (define_insn "pop_multiple"
1815   [(match_parallel 0 "pop_multiple_operation"
1816     [(set (reg:SI REG_SP)
1817           (plus:SI (reg:SI REG_SP) (match_operand:SI 1 "immediate_operand" "i")))])]
1818   ""
1819 {
1820   output_pop_multiple (insn, operands);
1821   return "";
1822 })
1823
1824 (define_insn "return_internal"
1825   [(return)
1826    (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)]
1827   "reload_completed"
1828 {
1829   switch (INTVAL (operands[0]))
1830     {
1831     case EXCPT_HANDLER:
1832       return "rtx;";
1833     case NMI_HANDLER:
1834       return "rtn;";
1835     case INTERRUPT_HANDLER:
1836       return "rti;";
1837     case SUBROUTINE:
1838       return "rts;";
1839     }
1840   gcc_unreachable ();
1841 })
1842
1843 (define_insn "csync"
1844   [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
1845   ""
1846   "csync;"
1847   [(set_attr "type" "misc")])
1848
1849 (define_insn "ssync"
1850   [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_SSYNC)]
1851   ""
1852   "ssync;"
1853   [(set_attr "type" "misc")])
1854
1855 ;;; Vector instructions
1856
1857 (define_insn "addv2hi"
1858   [(set (match_operand:V2HI 0 "register_operand" "=d")
1859         (plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
1860                    (match_operand:V2HI 2 "register_operand" "d")))]
1861   ""
1862   "%0 = %1 +|+ %2;"
1863   [(set_attr "type" "dsp32")])
1864
1865 (define_insn "subv2hi"
1866   [(set (match_operand:V2HI 0 "register_operand" "=d")
1867         (minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
1868                    (match_operand:V2HI 2 "register_operand" "d")))]
1869   ""
1870   "%0 = %1 -|- %2;"
1871   [(set_attr "type" "dsp32")])
1872
1873 (define_insn "sminv2hi"
1874   [(set (match_operand:V2HI 0 "register_operand" "=d")
1875         (smin:V2HI (match_operand:V2HI 1 "register_operand" "d")
1876                    (match_operand:V2HI 2 "register_operand" "d")))]
1877   ""
1878   "%0 = MIN (%1, %2) (V);"
1879   [(set_attr "type" "dsp32")])
1880
1881 (define_insn "smaxv2hi"
1882   [(set (match_operand:V2HI 0 "register_operand" "=d")
1883         (smax:V2HI (match_operand:V2HI 1 "register_operand" "d")
1884                    (match_operand:V2HI 2 "register_operand" "d")))]
1885   ""
1886   "%0 = MAX (%1, %2) (V);"
1887   [(set_attr "type" "dsp32")])
1888
1889 (define_insn "mulv2hi"
1890   [(set (match_operand:V2HI 0 "register_operand" "=d")
1891         (mult:V2HI (match_operand:V2HI 1 "register_operand" "d")
1892                    (match_operand:V2HI 2 "register_operand" "d")))]
1893   ""
1894   "%h0 = %h1 * %h2, %d0 = %d1 * %d2 (IS);"
1895   [(set_attr "type" "dsp32")])
1896
1897 (define_insn "negv2hi"
1898   [(set (match_operand:V2HI 0 "register_operand" "=d")
1899         (neg:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
1900   ""
1901   "%0 = - %1 (V);"
1902   [(set_attr "type" "dsp32")])
1903
1904 (define_insn "absv2hi"
1905   [(set (match_operand:V2HI 0 "register_operand" "=d")
1906         (abs:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
1907   ""
1908   "%0 = ABS %1 (V);"
1909   [(set_attr "type" "dsp32")])
1910