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