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