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