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