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