1 ;;- Machine description for Blackfin for GNU compiler
2 ;; Copyright 2005 Free Software Foundation, Inc.
3 ;; Contributed by Analog Devices.
5 ;; This file is part of GCC.
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.
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.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 ;; Boston, MA 02110-1301, USA.
22 ; operand punctuation marks:
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
33 ; constant operand classes
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
50 ; c (i0..i3,m0..m3) CIRCREGS
54 ;; Define constants for hard registers.
114 ;; Constants used in UNSPECs and UNSPEC_VOLATILEs.
117 [(UNSPEC_CBRANCH_TAKEN 0)
118 (UNSPEC_CBRANCH_NOPS 1)
121 (UNSPEC_LIBRARY_OFFSET 4)
122 (UNSPEC_PUSH_MULTIPLE 5)])
125 [(UNSPEC_VOLATILE_EH_RETURN 0)
126 (UNSPEC_VOLATILE_CSYNC 1)
127 (UNSPEC_VOLATILE_SSYNC 2)])
130 "move,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy"
131 (const_string "misc"))
133 ;; Scheduling definitions
135 (define_automaton "bfin")
137 (define_cpu_unit "core" "bfin")
139 (define_insn_reservation "alu" 1
140 (eq_attr "type" "move,mvi,mcst,dsp32,alu0,shft,brcc,br,call,misc,sync,compare")
143 (define_insn_reservation "imul" 3
144 (eq_attr "type" "mult")
147 (define_insn_reservation "load" 1
148 (eq_attr "type" "mcld")
151 ;; Make sure genautomata knows about the maximum latency that can be produced
152 ;; by the adjust_cost function.
153 (define_insn_reservation "dummy" 5
154 (eq_attr "type" "mcld")
157 ;; Operand and operator predicates
159 (include "predicates.md")
162 ;;; FRIO branches have been optimized for code density
163 ;;; this comes at a slight cost of complexity when
164 ;;; a compiler needs to generate branches in the general
165 ;;; case. In order to generate the correct branching
166 ;;; mechanisms the compiler needs keep track of instruction
167 ;;; lengths. The follow table describes how to count instructions
168 ;;; for the FRIO architecture.
170 ;;; unconditional br are 12-bit imm pcrelative branches *2
171 ;;; conditional br are 10-bit imm pcrelative branches *2
173 ;;; 1024 10-bit imm *2 is 2048 (-1024..1022)
175 ;;; 4096 12-bit imm *2 is 8192 (-4096..4094)
176 ;;; NOTE : For brcc we generate instructions such as
177 ;;; if cc jmp; jump.[sl] offset
178 ;;; offset of jump.[sl] is from the jump instruction but
179 ;;; gcc calculates length from the if cc jmp instruction
180 ;;; furthermore gcc takes the end address of the branch instruction
181 ;;; as (pc) for a forward branch
182 ;;; hence our range is (-4094, 4092) instead of (-4096, 4094) for a br
184 ;;; The way the (pc) rtx works in these calculations is somewhat odd;
185 ;;; for backward branches it's the address of the current instruction,
186 ;;; for forward branches it's the previously known address of the following
187 ;;; instruction - we have to take this into account by reducing the range
188 ;;; for a forward branch.
190 ;; Lengths for type "mvi" insns are always defined by the instructions
192 (define_attr "length" ""
193 (cond [(eq_attr "type" "mcld")
194 (if_then_else (match_operand 1 "effective_address_32bit_p" "")
195 (const_int 4) (const_int 2))
197 (eq_attr "type" "mcst")
198 (if_then_else (match_operand 0 "effective_address_32bit_p" "")
199 (const_int 4) (const_int 2))
201 (eq_attr "type" "move") (const_int 2)
203 (eq_attr "type" "dsp32") (const_int 4)
204 (eq_attr "type" "call") (const_int 4)
206 (eq_attr "type" "br")
208 (le (minus (match_dup 0) (pc)) (const_int 4092))
209 (ge (minus (match_dup 0) (pc)) (const_int -4096)))
213 (eq_attr "type" "brcc")
215 (le (minus (match_dup 3) (pc)) (const_int 1020))
216 (ge (minus (match_dup 3) (pc)) (const_int -1024)))
219 (le (minus (match_dup 3) (pc)) (const_int 4092))
220 (ge (minus (match_dup 3) (pc)) (const_int -4094)))
229 (define_expand "movsicc"
230 [(set (match_operand:SI 0 "register_operand" "")
231 (if_then_else:SI (match_operand 1 "comparison_operator" "")
232 (match_operand:SI 2 "register_operand" "")
233 (match_operand:SI 3 "register_operand" "")))]
236 operands[1] = bfin_gen_compare (operands[1], SImode);
239 (define_insn "*movsicc_insn1"
240 [(set (match_operand:SI 0 "register_operand" "=da,da,da")
242 (eq:BI (match_operand:BI 3 "cc_operand" "C,C,C")
244 (match_operand:SI 1 "register_operand" "da,0,da")
245 (match_operand:SI 2 "register_operand" "0,da,da")))]
248 if !cc %0 =%1; /* movsicc-1a */
249 if cc %0 =%2; /* movsicc-1b */
250 if !cc %0 =%1; if cc %0=%2; /* movsicc-1 */"
251 [(set_attr "length" "2,2,4")
252 (set_attr "type" "move")])
254 (define_insn "*movsicc_insn2"
255 [(set (match_operand:SI 0 "register_operand" "=da,da,da")
257 (ne:BI (match_operand:BI 3 "cc_operand" "C,C,C")
259 (match_operand:SI 1 "register_operand" "0,da,da")
260 (match_operand:SI 2 "register_operand" "da,0,da")))]
263 if !cc %0 =%2; /* movsicc-2b */
264 if cc %0 =%1; /* movsicc-2a */
265 if cc %0 =%1; if !cc %0=%2; /* movsicc-1 */"
266 [(set_attr "length" "2,2,4")
267 (set_attr "type" "move")])
269 ;; Insns to load HIGH and LO_SUM
271 (define_insn "movsi_high"
272 [(set (match_operand:SI 0 "register_operand" "=x")
273 (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
276 [(set_attr "type" "mvi")
277 (set_attr "length" "4")])
279 (define_insn "movstricthi_high"
280 [(set (match_operand:SI 0 "register_operand" "+x")
281 (ior:SI (and:SI (match_dup 0) (const_int 65535))
282 (match_operand:SI 1 "immediate_operand" "i")))]
285 [(set_attr "type" "mvi")
286 (set_attr "length" "4")])
288 (define_insn "movsi_low"
289 [(set (match_operand:SI 0 "register_operand" "=x")
290 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
291 (match_operand:SI 2 "immediate_operand" "i")))]
294 [(set_attr "type" "mvi")
295 (set_attr "length" "4")])
297 (define_insn "movsi_high_pic"
298 [(set (match_operand:SI 0 "register_operand" "=x")
299 (high:SI (unspec:SI [(match_operand:SI 1 "" "")]
303 [(set_attr "type" "mvi")
304 (set_attr "length" "4")])
306 (define_insn "movsi_low_pic"
307 [(set (match_operand:SI 0 "register_operand" "=x")
308 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
309 (unspec:SI [(match_operand:SI 2 "" "")]
312 "%h0 = %h2@GOT_HIGH;"
313 [(set_attr "type" "mvi")
314 (set_attr "length" "4")])
316 ;;; Move instructions
318 (define_insn_and_split "movdi_insn"
319 [(set (match_operand:DI 0 "nonimmediate_operand" "=x,mx,r")
320 (match_operand:DI 1 "general_operand" "iFx,r,mx"))]
321 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
324 [(set (match_dup 2) (match_dup 3))
325 (set (match_dup 4) (match_dup 5))]
327 rtx lo_half[2], hi_half[2];
328 split_di (operands, 2, lo_half, hi_half);
330 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
332 operands[2] = hi_half[0];
333 operands[3] = hi_half[1];
334 operands[4] = lo_half[0];
335 operands[5] = lo_half[1];
339 operands[2] = lo_half[0];
340 operands[3] = lo_half[1];
341 operands[4] = hi_half[0];
342 operands[5] = hi_half[1];
347 [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,mr,C,d,C")
348 (match_operand:BI 1 "general_operand" "x,xKs3,mr,d,d,C,P0"))]
358 R0 = R0 | R0; CC = AC0;"
359 [(set_attr "type" "move,mvi,mcld,mcst,compare,compare,alu0")
360 (set_attr "length" "2,2,*,*,2,2,4")])
362 (define_insn "movpdi"
363 [(set (match_operand:PDI 0 "nonimmediate_operand" "=e,<,e")
364 (match_operand:PDI 1 "general_operand" " e,e,>"))]
370 [(set_attr "type" "move,mcst,mcld")])
372 (define_insn "*pushsi_insn"
373 [(set (mem:SI (pre_dec:SI (reg:SI REG_SP)))
374 (match_operand:SI 0 "register_operand" "xy"))]
377 [(set_attr "type" "mcst")
378 (set_attr "length" "2")])
380 (define_insn "*popsi_insn"
381 [(set (match_operand:SI 0 "register_operand" "=xy")
382 (mem:SI (post_inc:SI (reg:SI REG_SP))))]
385 [(set_attr "type" "mcld")
386 (set_attr "length" "2")])
388 ;; The first alternative is used to make reload choose a limited register
389 ;; class when faced with a movsi_insn that had its input operand replaced
390 ;; with a PLUS. We generally require fewer secondary reloads this way.
391 (define_insn "*movsi_insn"
392 [(set (match_operand:SI 0 "nonimmediate_operand" "=da,x*y,da,x,x,x,da,mr")
393 (match_operand:SI 1 "general_operand" "da,x*y,xKs7,xKsh,xKuh,ix,mr,da"))]
395 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
405 [(set_attr "type" "move,move,mvi,mvi,mvi,*,mcld,mcst")
406 (set_attr "length" "2,2,2,4,4,*,*,*")])
408 (define_insn "*movv2hi_insn"
409 [(set (match_operand:V2HI 0 "nonimmediate_operand" "=da,d,m")
410 (match_operand:V2HI 1 "general_operand" "d,m,d"))]
412 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
414 [(set_attr "type" "move,mcld,mcst")
415 (set_attr "length" "2,*,*")])
417 (define_insn "*movhi_insn"
418 [(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr")
419 (match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
420 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
427 [(set_attr "type" "move,mvi,mvi,mcld,mcst")
428 (set_attr "length" "2,2,4,*,*")])
430 (define_insn "*movqi_insn"
431 [(set (match_operand:QI 0 "nonimmediate_operand" "=x,da,x,d,mr")
432 (match_operand:QI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
433 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
440 [(set_attr "type" "move,mvi,mvi,mcld,mcst")
441 (set_attr "length" "2,2,4,*,*")])
443 (define_insn "*movsf_insn"
444 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,da,mr")
445 (match_operand:SF 1 "general_operand" "x,Fx,mr,da"))]
446 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
452 [(set_attr "type" "move,*,mcld,mcst")])
454 (define_insn_and_split "movdf_insn"
455 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,mx,r")
456 (match_operand:DF 1 "general_operand" "iFx,r,mx"))]
457 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
460 [(set (match_dup 2) (match_dup 3))
461 (set (match_dup 4) (match_dup 5))]
463 rtx lo_half[2], hi_half[2];
464 split_di (operands, 2, lo_half, hi_half);
466 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
468 operands[2] = hi_half[0];
469 operands[3] = hi_half[1];
470 operands[4] = lo_half[0];
471 operands[5] = lo_half[1];
475 operands[2] = lo_half[0];
476 operands[3] = lo_half[1];
477 operands[4] = hi_half[0];
478 operands[5] = hi_half[1];
482 ;; This is the main "hook" for PIC code. When generating
483 ;; PIC, movsi is responsible for determining when the source address
484 ;; needs PIC relocation and appropriately calling legitimize_pic_address
485 ;; to perform the actual relocation.
487 (define_expand "movsi"
488 [(set (match_operand:SI 0 "nonimmediate_operand" "")
489 (match_operand:SI 1 "general_operand" ""))]
491 "expand_move (operands, SImode);")
493 (define_expand "movv2hi"
494 [(set (match_operand:V2HI 0 "nonimmediate_operand" "")
495 (match_operand:V2HI 1 "general_operand" ""))]
497 "expand_move (operands, V2HImode);")
499 (define_expand "movdi"
500 [(set (match_operand:DI 0 "nonimmediate_operand" "")
501 (match_operand:DI 1 "general_operand" ""))]
503 "expand_move (operands, DImode);")
505 (define_expand "movsf"
506 [(set (match_operand:SF 0 "nonimmediate_operand" "")
507 (match_operand:SF 1 "general_operand" ""))]
509 "expand_move (operands, SFmode);")
511 (define_expand "movdf"
512 [(set (match_operand:DF 0 "nonimmediate_operand" "")
513 (match_operand:DF 1 "general_operand" ""))]
515 "expand_move (operands, DFmode);")
517 (define_expand "movhi"
518 [(set (match_operand:HI 0 "nonimmediate_operand" "")
519 (match_operand:HI 1 "general_operand" ""))]
521 "expand_move (operands, HImode);")
523 (define_expand "movqi"
524 [(set (match_operand:QI 0 "nonimmediate_operand" "")
525 (match_operand:QI 1 "general_operand" ""))]
527 " expand_move (operands, QImode); ")
529 ;; Some define_splits to break up SI/SFmode loads of immediate constants.
532 [(set (match_operand:SI 0 "register_operand" "")
533 (match_operand:SI 1 "symbolic_or_const_operand" ""))]
535 /* Always split symbolic operands; split integer constants that are
536 too large for a single instruction. */
537 && (GET_CODE (operands[1]) != CONST_INT
538 || (INTVAL (operands[1]) < -32768
539 || INTVAL (operands[1]) >= 65536
540 || (INTVAL (operands[1]) >= 32768 && PREG_P (operands[0]))))"
541 [(set (match_dup 0) (high:SI (match_dup 1)))
542 (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))]
544 if (GET_CODE (operands[1]) == CONST_INT
545 && split_load_immediate (operands))
547 /* ??? Do something about TARGET_LOW_64K. */
551 [(set (match_operand:SF 0 "register_operand" "")
552 (match_operand:SF 1 "immediate_operand" ""))]
554 [(set (match_dup 2) (high:SI (match_dup 3)))
555 (set (match_dup 2) (lo_sum:SI (match_dup 2) (match_dup 3)))]
558 REAL_VALUE_TYPE value;
560 gcc_assert (GET_CODE (operands[1]) == CONST_DOUBLE);
562 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
563 REAL_VALUE_TO_TARGET_SINGLE (value, values);
565 operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0]));
566 operands[3] = GEN_INT (trunc_int_for_mode (values, SImode));
567 if (values >= -32768 && values < 65536)
569 emit_move_insn (operands[2], operands[3]);
572 if (split_load_immediate (operands + 2))
576 ;; Sadly, this can't be a proper named movstrict pattern, since the compiler
577 ;; expects to be able to use registers for operand 1.
578 ;; Note that the asm instruction is defined by the manual to take an unsigned
579 ;; constant, but it doesn't matter to the assembler, and the compiler only
580 ;; deals with sign-extended constants. Hence "Ksh".
581 (define_insn "*movstricthi"
582 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+x"))
583 (match_operand:HI 1 "immediate_operand" "Ksh"))]
586 [(set_attr "type" "mvi")
587 (set_attr "length" "4")])
589 ;; Sign and zero extensions
591 (define_insn "extendhisi2"
592 [(set (match_operand:SI 0 "register_operand" "=d, d")
593 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
598 [(set_attr "type" "alu0,mcld")])
600 (define_insn "zero_extendhisi2"
601 [(set (match_operand:SI 0 "register_operand" "=d, d")
602 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
607 [(set_attr "type" "alu0,mcld")])
609 (define_insn "zero_extendbisi2"
610 [(set (match_operand:SI 0 "register_operand" "=d")
611 (zero_extend:SI (match_operand:BI 1 "nonimmediate_operand" "C")))]
614 [(set_attr "type" "compare")])
616 (define_insn "extendqihi2"
617 [(set (match_operand:HI 0 "register_operand" "=d, d")
618 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
623 [(set_attr "type" "mcld,alu0")])
625 (define_insn "extendqisi2"
626 [(set (match_operand:SI 0 "register_operand" "=d, d")
627 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
632 [(set_attr "type" "mcld,alu0")])
635 (define_insn "zero_extendqihi2"
636 [(set (match_operand:HI 0 "register_operand" "=d, d")
637 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
642 [(set_attr "type" "mcld,alu0")])
645 (define_insn "zero_extendqisi2"
646 [(set (match_operand:SI 0 "register_operand" "=d, d")
647 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
652 [(set_attr "type" "mcld,alu0")])
654 ;; DImode logical operations
656 (define_code_macro any_logical [and ior xor])
657 (define_code_attr optab [(and "and")
660 (define_code_attr op [(and "&")
663 (define_code_attr high_result [(and "0")
667 (define_insn "<optab>di3"
668 [(set (match_operand:DI 0 "register_operand" "=d")
669 (any_logical:DI (match_operand:DI 1 "register_operand" "0")
670 (match_operand:DI 2 "register_operand" "d")))]
672 "%0 = %1 <op> %2;\\n\\t%H0 = %H1 <op> %H2;"
673 [(set_attr "length" "4")])
675 (define_insn "*<optab>di_zesidi_di"
676 [(set (match_operand:DI 0 "register_operand" "=d")
677 (any_logical:DI (zero_extend:DI
678 (match_operand:SI 2 "register_operand" "d"))
679 (match_operand:DI 1 "register_operand" "d")))]
681 "%0 = %1 <op> %2;\\n\\t%H0 = <high_result>;"
682 [(set_attr "length" "4")])
684 (define_insn "*<optab>di_sesdi_di"
685 [(set (match_operand:DI 0 "register_operand" "=d")
686 (any_logical:DI (sign_extend:DI
687 (match_operand:SI 2 "register_operand" "d"))
688 (match_operand:DI 1 "register_operand" "0")))
689 (clobber (match_scratch:SI 3 "=&d"))]
691 "%0 = %1 <op> %2;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 <op> %3;"
692 [(set_attr "length" "8")])
694 (define_insn "negdi2"
695 [(set (match_operand:DI 0 "register_operand" "=d")
696 (neg:DI (match_operand:DI 1 "register_operand" "d")))
697 (clobber (match_scratch:SI 2 "=&d"))
698 (clobber (reg:CC REG_CC))]
700 "%2 = 0; %2 = %2 - %1; cc = ac0; cc = !cc; %2 = cc;\\n\\t%0 = -%1; %H0 = -%H1; %H0 = %H0 - %2;"
701 [(set_attr "length" "16")])
703 (define_insn "one_cmpldi2"
704 [(set (match_operand:DI 0 "register_operand" "=d")
705 (not:DI (match_operand:DI 1 "register_operand" "d")))]
707 "%0 = ~%1;\\n\\t%H0 = ~%H1;"
708 [(set_attr "length" "4")])
710 ;; DImode zero and sign extend patterns
712 (define_insn_and_split "zero_extendsidi2"
713 [(set (match_operand:DI 0 "register_operand" "=d")
714 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
718 [(set (match_dup 3) (const_int 0))]
720 split_di (operands, 1, operands + 2, operands + 3);
721 if (REGNO (operands[0]) != REGNO (operands[1]))
722 emit_move_insn (operands[2], operands[1]);
725 (define_insn "zero_extendqidi2"
726 [(set (match_operand:DI 0 "register_operand" "=d")
727 (zero_extend:DI (match_operand:QI 1 "register_operand" "d")))]
729 "%0 = %T1 (Z);\\n\\t%H0 = 0;"
730 [(set_attr "length" "4")])
732 (define_insn "zero_extendhidi2"
733 [(set (match_operand:DI 0 "register_operand" "=d")
734 (zero_extend:DI (match_operand:HI 1 "register_operand" "d")))]
736 "%0 = %h1 (Z);\\n\\t%H0 = 0;"
737 [(set_attr "length" "4")])
739 (define_insn_and_split "extendsidi2"
740 [(set (match_operand:DI 0 "register_operand" "=d")
741 (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))]
745 [(set (match_dup 3) (match_dup 1))
746 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
748 split_di (operands, 1, operands + 2, operands + 3);
749 if (REGNO (operands[0]) != REGNO (operands[1]))
750 emit_move_insn (operands[2], operands[1]);
753 (define_insn_and_split "extendqidi2"
754 [(set (match_operand:DI 0 "register_operand" "=d")
755 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
759 [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
760 (set (match_dup 3) (sign_extend:SI (match_dup 1)))
761 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
763 split_di (operands, 1, operands + 2, operands + 3);
766 (define_insn_and_split "extendhidi2"
767 [(set (match_operand:DI 0 "register_operand" "=d")
768 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
772 [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
773 (set (match_dup 3) (sign_extend:SI (match_dup 1)))
774 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
776 split_di (operands, 1, operands + 2, operands + 3);
779 ;; DImode arithmetic operations
781 (define_insn "adddi3"
782 [(set (match_operand:DI 0 "register_operand" "=&d,&d,&d")
783 (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
784 (match_operand:DI 2 "nonmemory_operand" "Kn7,Ks7,d")))
785 (clobber (match_scratch:SI 3 "=&d,&d,&d"))
786 (clobber (reg:CC 34))]
789 %0 += %2; cc = ac0; %3 = cc; %H0 += -1; %H0 = %H0 + %3;
790 %0 += %2; cc = ac0; %3 = cc; %H0 = %H0 + %3;
791 %0 = %0 + %2; cc = ac0; %3 = cc; %H0 = %H0 + %H2; %H0 = %H0 + %3;"
792 [(set_attr "type" "alu0")
793 (set_attr "length" "10,8,10")])
795 (define_insn "subdi3"
796 [(set (match_operand:DI 0 "register_operand" "=&d")
797 (minus:DI (match_operand:DI 1 "register_operand" "0")
798 (match_operand:DI 2 "register_operand" "d")))
799 (clobber (reg:CC 34))]
801 "%0 = %1-%2;\\n\\tcc = ac0;\\n\\t%H0 = %H1-%H2;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
802 [(set_attr "length" "10")])
804 (define_insn "*subdi_di_zesidi"
805 [(set (match_operand:DI 0 "register_operand" "=d")
806 (minus:DI (match_operand:DI 1 "register_operand" "0")
808 (match_operand:SI 2 "register_operand" "d"))))
809 (clobber (match_scratch:SI 3 "=&d"))
810 (clobber (reg:CC 34))]
812 "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%H0 = %H1 - %3;"
813 [(set_attr "length" "10")])
815 (define_insn "*subdi_zesidi_di"
816 [(set (match_operand:DI 0 "register_operand" "=d")
817 (minus:DI (zero_extend:DI
818 (match_operand:SI 2 "register_operand" "d"))
819 (match_operand:DI 1 "register_operand" "0")))
820 (clobber (match_scratch:SI 3 "=&d"))
821 (clobber (reg:CC 34))]
823 "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%3 = -%3;\\n\\t%H0 = %3 - %H1"
824 [(set_attr "length" "12")])
826 (define_insn "*subdi_di_sesidi"
827 [(set (match_operand:DI 0 "register_operand" "=d")
828 (minus:DI (match_operand:DI 1 "register_operand" "0")
830 (match_operand:SI 2 "register_operand" "d"))))
831 (clobber (match_scratch:SI 3 "=&d"))
832 (clobber (reg:CC 34))]
834 "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 - %3;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
835 [(set_attr "length" "14")])
837 (define_insn "*subdi_sesidi_di"
838 [(set (match_operand:DI 0 "register_operand" "=d")
839 (minus:DI (sign_extend:DI
840 (match_operand:SI 2 "register_operand" "d"))
841 (match_operand:DI 1 "register_operand" "0")))
842 (clobber (match_scratch:SI 3 "=&d"))
843 (clobber (reg:CC 34))]
845 "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %3 - %H1;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
846 [(set_attr "length" "14")])
848 ;; Combined shift/add instructions
851 [(set (match_operand:SI 0 "register_operand" "=a,d")
852 (ashift:SI (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
853 (match_operand:SI 2 "register_operand" "a,d"))
854 (match_operand:SI 3 "pos_scale_operand" "P1P2,P1P2")))]
856 "%0 = (%0 + %2) << %3;" /* "shadd %0,%2,%3;" */
857 [(set_attr "type" "alu0")])
860 [(set (match_operand:SI 0 "register_operand" "=a")
861 (plus:SI (match_operand:SI 1 "register_operand" "a")
862 (mult:SI (match_operand:SI 2 "register_operand" "a")
863 (match_operand:SI 3 "scale_by_operand" "i"))))]
865 "%0 = %1 + (%2 << %X3);"
866 [(set_attr "type" "alu0")])
869 [(set (match_operand:SI 0 "register_operand" "=a")
870 (plus:SI (match_operand:SI 1 "register_operand" "a")
871 (ashift:SI (match_operand:SI 2 "register_operand" "a")
872 (match_operand:SI 3 "pos_scale_operand" "i"))))]
874 "%0 = %1 + (%2 << %3);"
875 [(set_attr "type" "alu0")])
878 [(set (match_operand:SI 0 "register_operand" "=a")
879 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "a")
880 (match_operand:SI 2 "scale_by_operand" "i"))
881 (match_operand:SI 3 "register_operand" "a")))]
883 "%0 = %3 + (%1 << %X2);"
884 [(set_attr "type" "alu0")])
887 [(set (match_operand:SI 0 "register_operand" "=a")
888 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "a")
889 (match_operand:SI 2 "pos_scale_operand" "i"))
890 (match_operand:SI 3 "register_operand" "a")))]
892 "%0 = %3 + (%1 << %2);"
893 [(set_attr "type" "alu0")])
895 (define_insn "mulhisi3"
896 [(set (match_operand:SI 0 "register_operand" "=d")
897 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%d"))
898 (sign_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
900 "%0 = %h1 * %h2 (IS);"
901 [(set_attr "type" "dsp32")])
903 (define_insn "umulhisi3"
904 [(set (match_operand:SI 0 "register_operand" "=d")
905 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%d"))
906 (zero_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
908 "%0 = %h1 * %h2 (FU);"
909 [(set_attr "type" "dsp32")])
911 ;; The processor also supports ireg += mreg or ireg -= mreg, but these
912 ;; are unusable if we don't ensure that the corresponding lreg is zero.
913 ;; The same applies to the add/subtract constant versions involving
916 (define_insn "addsi3"
917 [(set (match_operand:SI 0 "register_operand" "=ad,a,d")
918 (plus:SI (match_operand:SI 1 "register_operand" "%0, a,d")
919 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7, a,d")))]
925 [(set_attr "type" "alu0")
926 (set_attr "length" "2,2,2")])
928 (define_expand "subsi3"
929 [(set (match_operand:SI 0 "register_operand" "")
930 (minus:SI (match_operand:SI 1 "register_operand" "")
931 (match_operand:SI 2 "reg_or_7bit_operand" "")))]
936 [(set (match_operand:SI 0 "register_operand" "=da,d,a")
937 (minus:SI (match_operand:SI 1 "register_operand" "0,d,0")
938 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7,d,a")))]
939 "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -64"
941 static const char *const strings_subsi3[] = {
947 if (CONSTANT_P (operands[2]) && INTVAL (operands[2]) < 0) {
948 rtx tmp_op = operands[2];
949 operands[2] = GEN_INT (-INTVAL (operands[2]));
950 output_asm_insn ("%0 += %2;", operands);
951 operands[2] = tmp_op;
955 return strings_subsi3[which_alternative];
957 [(set_attr "type" "alu0")])
959 ;; Bit test instructions
961 (define_insn "*not_bittst"
962 [(set (match_operand:BI 0 "cc_operand" "=C")
963 (eq:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
965 (match_operand:SI 2 "immediate_operand" "Ku5"))
968 "cc = !BITTST (%1,%2);"
969 [(set_attr "type" "alu0")])
971 (define_insn "*bittst"
972 [(set (match_operand:BI 0 "cc_operand" "=C")
973 (ne:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
975 (match_operand:SI 2 "immediate_operand" "Ku5"))
978 "cc = BITTST (%1,%2);"
979 [(set_attr "type" "alu0")])
981 (define_insn_and_split "*bit_extract"
982 [(set (match_operand:SI 0 "register_operand" "=d")
983 (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
985 (match_operand:SI 2 "immediate_operand" "Ku5")))
986 (clobber (reg:BI REG_CC))]
990 [(set (reg:BI REG_CC)
991 (ne:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
994 (ne:SI (reg:BI REG_CC) (const_int 0)))])
996 (define_insn_and_split "*not_bit_extract"
997 [(set (match_operand:SI 0 "register_operand" "=d")
998 (zero_extract:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1000 (match_operand:SI 2 "immediate_operand" "Ku5")))
1001 (clobber (reg:BI REG_CC))]
1005 [(set (reg:BI REG_CC)
1006 (eq:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1009 (ne:SI (reg:BI REG_CC) (const_int 0)))])
1011 (define_insn "*andsi_insn"
1012 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
1013 (and:SI (match_operand:SI 1 "register_operand" "%0,d,d,d")
1014 (match_operand:SI 2 "rhs_andsi3_operand" "L,M1,M2,d")))]
1021 [(set_attr "type" "alu0")])
1023 (define_expand "andsi3"
1024 [(set (match_operand:SI 0 "register_operand" "")
1025 (and:SI (match_operand:SI 1 "register_operand" "")
1026 (match_operand:SI 2 "general_operand" "")))]
1029 if (highbits_operand (operands[2], SImode))
1031 operands[2] = GEN_INT (exact_log2 (-INTVAL (operands[2])));
1032 emit_insn (gen_ashrsi3 (operands[0], operands[1], operands[2]));
1033 emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
1036 if (! rhs_andsi3_operand (operands[2], SImode))
1037 operands[2] = force_reg (SImode, operands[2]);
1040 (define_insn "iorsi3"
1041 [(set (match_operand:SI 0 "register_operand" "=d,d")
1042 (ior:SI (match_operand:SI 1 "register_operand" "%0,d")
1043 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1048 [(set_attr "type" "alu0")])
1050 (define_insn "xorsi3"
1051 [(set (match_operand:SI 0 "register_operand" "=d,d")
1052 (xor:SI (match_operand:SI 1 "register_operand" "%0,d")
1053 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1058 [(set_attr "type" "alu0")])
1060 (define_insn "smaxsi3"
1061 [(set (match_operand:SI 0 "register_operand" "=d")
1062 (smax:SI (match_operand:SI 1 "register_operand" "d")
1063 (match_operand:SI 2 "register_operand" "d")))]
1066 [(set_attr "type" "dsp32")])
1068 (define_insn "sminsi3"
1069 [(set (match_operand:SI 0 "register_operand" "=d")
1070 (smin:SI (match_operand:SI 1 "register_operand" "d")
1071 (match_operand:SI 2 "register_operand" "d")))]
1074 [(set_attr "type" "dsp32")])
1076 (define_insn "abssi2"
1077 [(set (match_operand:SI 0 "register_operand" "=d")
1078 (abs:SI (match_operand:SI 1 "register_operand" " d")))]
1081 [(set_attr "type" "dsp32")])
1084 (define_insn "negsi2"
1085 [(set (match_operand:SI 0 "register_operand" "=d")
1086 (neg:SI (match_operand:SI 1 "register_operand" " d")))]
1089 [(set_attr "type" "alu0")])
1091 (define_insn "one_cmplsi2"
1092 [(set (match_operand:SI 0 "register_operand" "=d")
1093 (not:SI (match_operand:SI 1 "register_operand" " d")))]
1096 [(set_attr "type" "alu0")])
1098 (define_insn "mulsi3"
1099 [(set (match_operand:SI 0 "register_operand" "=d")
1100 (mult:SI (match_operand:SI 1 "register_operand" "%0")
1101 (match_operand:SI 2 "register_operand" "d")))]
1104 [(set_attr "type" "mult")])
1106 (define_expand "ashlsi3"
1107 [(set (match_operand:SI 0 "register_operand" "")
1108 (ashift:SI (match_operand:SI 1 "register_operand" "")
1109 (match_operand:SI 2 "nonmemory_operand" "")))]
1112 if (GET_CODE (operands[2]) == CONST_INT
1113 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1115 emit_insn (gen_movsi (operands[0], const0_rtx));
1120 (define_insn_and_split "*ashlsi3_insn"
1121 [(set (match_operand:SI 0 "register_operand" "=d,a,a,a")
1122 (ashift:SI (match_operand:SI 1 "register_operand" "0,a,a,a")
1123 (match_operand:SI 2 "nonmemory_operand" "dKu5,P1,P2,?P3P4")))]
1130 "PREG_P (operands[0]) && INTVAL (operands[2]) > 2"
1131 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
1132 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
1133 "operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
1134 [(set_attr "type" "shft")])
1136 (define_insn "ashrsi3"
1137 [(set (match_operand:SI 0 "register_operand" "=d")
1138 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1139 (match_operand:SI 2 "nonmemory_operand" "dKu5")))]
1142 [(set_attr "type" "shft")])
1144 (define_insn "ror_one"
1145 [(set (match_operand:SI 0 "register_operand" "=d")
1146 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1147 (ashift:SI (zero_extend:SI (reg:BI REG_CC)) (const_int 31))))
1148 (set (reg:BI REG_CC)
1149 (zero_extract:BI (match_dup 1) (const_int 1) (const_int 0)))]
1151 "%0 = ROT %1 BY -1;"
1152 [(set_attr "type" "shft")
1153 (set_attr "length" "4")])
1155 (define_insn "rol_one"
1156 [(set (match_operand:SI 0 "register_operand" "+d")
1157 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1158 (zero_extend:SI (reg:BI REG_CC))))
1159 (set (reg:BI REG_CC)
1160 (zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))]
1163 [(set_attr "type" "shft")
1164 (set_attr "length" "4")])
1166 (define_expand "lshrdi3"
1167 [(set (match_operand:DI 0 "register_operand" "")
1168 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1169 (match_operand:DI 2 "general_operand" "")))]
1172 rtx lo_half[2], hi_half[2];
1174 if (operands[2] != const1_rtx)
1176 if (! rtx_equal_p (operands[0], operands[1]))
1177 emit_move_insn (operands[0], operands[1]);
1179 split_di (operands, 2, lo_half, hi_half);
1181 emit_move_insn (bfin_cc_rtx, const0_rtx);
1182 emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1183 emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1187 (define_expand "ashrdi3"
1188 [(set (match_operand:DI 0 "register_operand" "")
1189 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1190 (match_operand:DI 2 "general_operand" "")))]
1193 rtx lo_half[2], hi_half[2];
1195 if (operands[2] != const1_rtx)
1197 if (! rtx_equal_p (operands[0], operands[1]))
1198 emit_move_insn (operands[0], operands[1]);
1200 split_di (operands, 2, lo_half, hi_half);
1202 emit_insn (gen_compare_lt (gen_rtx_REG (BImode, REG_CC),
1203 hi_half[1], const0_rtx));
1204 emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1205 emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1209 (define_expand "ashldi3"
1210 [(set (match_operand:DI 0 "register_operand" "")
1211 (ashift:DI (match_operand:DI 1 "register_operand" "")
1212 (match_operand:DI 2 "general_operand" "")))]
1215 rtx lo_half[2], hi_half[2];
1217 if (operands[2] != const1_rtx)
1219 if (! rtx_equal_p (operands[0], operands[1]))
1220 emit_move_insn (operands[0], operands[1]);
1222 split_di (operands, 2, lo_half, hi_half);
1224 emit_move_insn (bfin_cc_rtx, const0_rtx);
1225 emit_insn (gen_rol_one (lo_half[0], lo_half[0]));
1226 emit_insn (gen_rol_one (hi_half[0], hi_half[0]));
1230 (define_insn "lshrsi3"
1231 [(set (match_operand:SI 0 "register_operand" "=d,a")
1232 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0,a")
1233 (match_operand:SI 2 "nonmemory_operand" "dKu5,P1P2")))]
1238 [(set_attr "type" "shft")])
1240 ;; A pattern to reload the equivalent of
1241 ;; (set (Dreg) (plus (FP) (large_constant)))
1243 ;; (set (dagreg) (plus (FP) (arbitrary_constant)))
1244 ;; using a scratch register
1245 (define_expand "reload_insi"
1246 [(parallel [(set (match_operand:SI 0 "register_operand" "=w")
1247 (match_operand:SI 1 "fp_plus_const_operand" ""))
1248 (clobber (match_operand:SI 2 "register_operand" "=&a"))])]
1251 rtx fp_op = XEXP (operands[1], 0);
1252 rtx const_op = XEXP (operands[1], 1);
1253 rtx primary = operands[0];
1254 rtx scratch = operands[2];
1256 emit_move_insn (scratch, const_op);
1257 emit_insn (gen_addsi3 (scratch, scratch, fp_op));
1258 emit_move_insn (primary, scratch);
1262 ;; Jump instructions
1266 (label_ref (match_operand 0 "" "")))]
1269 if (get_attr_length (insn) == 2)
1270 return "jump.s %0;";
1272 return "jump.l %0;";
1274 [(set_attr "type" "br")])
1276 (define_insn "indirect_jump"
1278 (match_operand:SI 0 "register_operand" "a"))]
1281 [(set_attr "type" "misc")])
1283 (define_expand "tablejump"
1284 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1285 (use (label_ref (match_operand 1 "" "")))])]
1288 /* In PIC mode, the table entries are stored PC relative.
1289 Convert the relative address to an absolute address. */
1292 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1294 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1295 op1, NULL_RTX, 0, OPTAB_DIRECT);
1299 (define_insn "*tablejump_internal"
1300 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1301 (use (label_ref (match_operand 1 "" "")))]
1304 [(set_attr "type" "misc")])
1306 ;; Call instructions..
1308 (define_expand "call"
1309 [(parallel [(call (match_operand:SI 0 "" "")
1310 (match_operand 1 "" ""))
1311 (use (match_operand 2 "" ""))])]
1314 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 0);
1318 (define_expand "sibcall"
1319 [(parallel [(call (match_operand:SI 0 "" "")
1320 (match_operand 1 "" ""))
1321 (use (match_operand 2 "" ""))
1325 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 1);
1329 (define_expand "call_value"
1330 [(parallel [(set (match_operand 0 "register_operand" "")
1331 (call (match_operand:SI 1 "" "")
1332 (match_operand 2 "" "")))
1333 (use (match_operand 3 "" ""))])]
1336 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 0);
1340 (define_expand "sibcall_value"
1341 [(parallel [(set (match_operand 0 "register_operand" "")
1342 (call (match_operand:SI 1 "" "")
1343 (match_operand 2 "" "")))
1344 (use (match_operand 3 "" ""))
1348 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 1);
1352 (define_insn "*call_symbol"
1353 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1354 (match_operand 1 "general_operand" "g"))
1355 (use (match_operand 2 "" ""))]
1356 "! SIBLING_CALL_P (insn)
1357 && !TARGET_ID_SHARED_LIBRARY
1358 && GET_CODE (operands[0]) == SYMBOL_REF
1359 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
1361 [(set_attr "type" "call")
1362 (set_attr "length" "4")])
1364 (define_insn "*sibcall_symbol"
1365 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1366 (match_operand 1 "general_operand" "g"))
1367 (use (match_operand 2 "" ""))
1369 "SIBLING_CALL_P (insn)
1370 && !TARGET_ID_SHARED_LIBRARY
1371 && GET_CODE (operands[0]) == SYMBOL_REF
1372 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
1374 [(set_attr "type" "br")
1375 (set_attr "length" "4")])
1377 (define_insn "*call_value_symbol"
1378 [(set (match_operand 0 "register_operand" "=d")
1379 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1380 (match_operand 2 "general_operand" "g")))
1381 (use (match_operand 3 "" ""))]
1382 "! SIBLING_CALL_P (insn)
1383 && !TARGET_ID_SHARED_LIBRARY
1384 && GET_CODE (operands[1]) == SYMBOL_REF
1385 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
1387 [(set_attr "type" "call")
1388 (set_attr "length" "4")])
1390 (define_insn "*sibcall_value_symbol"
1391 [(set (match_operand 0 "register_operand" "=d")
1392 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1393 (match_operand 2 "general_operand" "g")))
1394 (use (match_operand 3 "" ""))
1396 "SIBLING_CALL_P (insn)
1397 && !TARGET_ID_SHARED_LIBRARY
1398 && GET_CODE (operands[1]) == SYMBOL_REF
1399 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
1401 [(set_attr "type" "br")
1402 (set_attr "length" "4")])
1404 (define_insn "*call_insn"
1405 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a"))
1406 (match_operand 1 "general_operand" "g"))
1407 (use (match_operand 2 "" ""))]
1408 "! SIBLING_CALL_P (insn)"
1410 [(set_attr "type" "call")
1411 (set_attr "length" "2")])
1413 (define_insn "*sibcall_insn"
1414 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "z"))
1415 (match_operand 1 "general_operand" "g"))
1416 (use (match_operand 2 "" ""))
1418 "SIBLING_CALL_P (insn)"
1420 [(set_attr "type" "br")
1421 (set_attr "length" "2")])
1423 (define_insn "*call_value_insn"
1424 [(set (match_operand 0 "register_operand" "=d")
1425 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a"))
1426 (match_operand 2 "general_operand" "g")))
1427 (use (match_operand 3 "" ""))]
1428 "! SIBLING_CALL_P (insn)"
1430 [(set_attr "type" "call")
1431 (set_attr "length" "2")])
1433 (define_insn "*sibcall_value_insn"
1434 [(set (match_operand 0 "register_operand" "=d")
1435 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "z"))
1436 (match_operand 2 "general_operand" "g")))
1437 (use (match_operand 3 "" ""))
1439 "SIBLING_CALL_P (insn)"
1441 [(set_attr "type" "br")
1442 (set_attr "length" "2")])
1444 ;; Block move patterns
1446 ;; We cheat. This copies one more word than operand 2 indicates.
1448 (define_insn "rep_movsi"
1449 [(set (match_operand:SI 0 "register_operand" "=&a")
1450 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1451 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1454 (set (match_operand:SI 1 "register_operand" "=&b")
1455 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1456 (ashift:SI (match_dup 2) (const_int 2)))
1458 (set (mem:BLK (match_dup 3))
1459 (mem:BLK (match_dup 4)))
1461 (clobber (match_scratch:HI 5 "=&d"))]
1463 "%5 = [%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || [%3++] = %5 || %5 = [%4++]; [%3++] = %5;"
1464 [(set_attr "type" "misc")
1465 (set_attr "length" "16")])
1467 (define_insn "rep_movhi"
1468 [(set (match_operand:SI 0 "register_operand" "=&a")
1469 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1470 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1473 (set (match_operand:SI 1 "register_operand" "=&b")
1474 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1475 (ashift:SI (match_dup 2) (const_int 1)))
1477 (set (mem:BLK (match_dup 3))
1478 (mem:BLK (match_dup 4)))
1480 (clobber (match_scratch:HI 5 "=&d"))]
1482 "%h5 = W[%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || W [%3++] = %5 || %h5 = W [%4++]; W [%3++] = %5;"
1483 [(set_attr "type" "misc")
1484 (set_attr "length" "16")])
1486 (define_expand "movmemsi"
1487 [(match_operand:BLK 0 "general_operand" "")
1488 (match_operand:BLK 1 "general_operand" "")
1489 (match_operand:SI 2 "const_int_operand" "")
1490 (match_operand:SI 3 "const_int_operand" "")]
1493 if (bfin_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
1498 ;; Conditional branch patterns
1499 ;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
1501 ;; The only outcome of this pattern is that global variables
1502 ;; bfin_compare_op[01] are set for use in bcond patterns.
1504 (define_expand "cmpbi"
1505 [(set (cc0) (compare (match_operand:BI 0 "register_operand" "")
1506 (match_operand:BI 1 "immediate_operand" "")))]
1509 bfin_compare_op0 = operands[0];
1510 bfin_compare_op1 = operands[1];
1514 (define_expand "cmpsi"
1515 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
1516 (match_operand:SI 1 "reg_or_const_int_operand" "")))]
1519 bfin_compare_op0 = operands[0];
1520 bfin_compare_op1 = operands[1];
1524 (define_insn "compare_eq"
1525 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1526 (eq:BI (match_operand:SI 1 "register_operand" "d,a")
1527 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
1530 [(set_attr "type" "compare")])
1532 (define_insn "compare_ne"
1533 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1534 (ne:BI (match_operand:SI 1 "register_operand" "d,a")
1535 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
1538 [(set_attr "type" "compare")])
1540 (define_insn "compare_lt"
1541 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1542 (lt:BI (match_operand:SI 1 "register_operand" "d,a")
1543 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
1546 [(set_attr "type" "compare")])
1548 (define_insn "compare_le"
1549 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1550 (le:BI (match_operand:SI 1 "register_operand" "d,a")
1551 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
1554 [(set_attr "type" "compare")])
1556 (define_insn "compare_leu"
1557 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1558 (leu:BI (match_operand:SI 1 "register_operand" "d,a")
1559 (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
1562 [(set_attr "type" "compare")])
1564 (define_insn "compare_ltu"
1565 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1566 (ltu:BI (match_operand:SI 1 "register_operand" "d,a")
1567 (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
1570 [(set_attr "type" "compare")])
1572 (define_expand "beq"
1573 [(set (match_dup 1) (match_dup 2))
1575 (if_then_else (match_dup 3)
1576 (label_ref (match_operand 0 "" ""))
1580 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1581 operands[1] = bfin_cc_rtx; /* hard register: CC */
1582 operands[2] = gen_rtx_EQ (BImode, op0, op1);
1583 /* If we have a BImode input, then we already have a compare result, and
1584 do not need to emit another comparison. */
1585 if (GET_MODE (bfin_compare_op0) == BImode)
1587 gcc_assert (bfin_compare_op1 == const0_rtx);
1588 emit_insn (gen_cbranchbi4 (operands[2], op0, op1, operands[0]));
1592 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1595 (define_expand "bne"
1596 [(set (match_dup 1) (match_dup 2))
1598 (if_then_else (match_dup 3)
1599 (label_ref (match_operand 0 "" ""))
1603 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1604 /* If we have a BImode input, then we already have a compare result, and
1605 do not need to emit another comparison. */
1606 if (GET_MODE (bfin_compare_op0) == BImode)
1608 rtx cmp = gen_rtx_NE (BImode, op0, op1);
1610 gcc_assert (bfin_compare_op1 == const0_rtx);
1611 emit_insn (gen_cbranchbi4 (cmp, op0, op1, operands[0]));
1615 operands[1] = bfin_cc_rtx; /* hard register: CC */
1616 operands[2] = gen_rtx_EQ (BImode, op0, op1);
1617 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1620 (define_expand "bgt"
1621 [(set (match_dup 1) (match_dup 2))
1623 (if_then_else (match_dup 3)
1624 (label_ref (match_operand 0 "" ""))
1628 operands[1] = bfin_cc_rtx;
1629 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1630 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1633 (define_expand "bgtu"
1634 [(set (match_dup 1) (match_dup 2))
1636 (if_then_else (match_dup 3)
1637 (label_ref (match_operand 0 "" ""))
1641 operands[1] = bfin_cc_rtx;
1642 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1643 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1646 (define_expand "blt"
1647 [(set (match_dup 1) (match_dup 2))
1649 (if_then_else (match_dup 3)
1650 (label_ref (match_operand 0 "" ""))
1654 operands[1] = bfin_cc_rtx;
1655 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1656 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1659 (define_expand "bltu"
1660 [(set (match_dup 1) (match_dup 2))
1662 (if_then_else (match_dup 3)
1663 (label_ref (match_operand 0 "" ""))
1667 operands[1] = bfin_cc_rtx;
1668 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1669 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1673 (define_expand "bge"
1674 [(set (match_dup 1) (match_dup 2))
1676 (if_then_else (match_dup 3)
1677 (label_ref (match_operand 0 "" ""))
1681 operands[1] = bfin_cc_rtx;
1682 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1683 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1686 (define_expand "bgeu"
1687 [(set (match_dup 1) (match_dup 2))
1689 (if_then_else (match_dup 3)
1690 (label_ref (match_operand 0 "" ""))
1694 operands[1] = bfin_cc_rtx;
1695 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1696 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1699 (define_expand "ble"
1700 [(set (match_dup 1) (match_dup 2))
1702 (if_then_else (match_dup 3)
1703 (label_ref (match_operand 0 "" ""))
1707 operands[1] = bfin_cc_rtx;
1708 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1709 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1712 (define_expand "bleu"
1713 [(set (match_dup 1) (match_dup 2))
1715 (if_then_else (match_dup 3)
1716 (label_ref (match_operand 0 "" ""))
1721 operands[1] = bfin_cc_rtx;
1722 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1723 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1726 (define_insn "cbranchbi4"
1729 (match_operator 0 "bfin_cbranch_operator"
1730 [(match_operand:BI 1 "cc_operand" "C")
1731 (match_operand:BI 2 "immediate_operand" "P0")])
1732 (label_ref (match_operand 3 "" ""))
1736 asm_conditional_branch (insn, operands, 0, 0);
1739 [(set_attr "type" "brcc")])
1741 ;; Special cbranch patterns to deal with the speculative load problem - see
1742 ;; bfin_reorg for details.
1744 (define_insn "cbranch_predicted_taken"
1747 (match_operator 0 "bfin_cbranch_operator"
1748 [(match_operand:BI 1 "cc_operand" "C")
1749 (match_operand:BI 2 "immediate_operand" "P0")])
1750 (label_ref (match_operand 3 "" ""))
1752 (unspec [(const_int 0)] UNSPEC_CBRANCH_TAKEN)]
1755 asm_conditional_branch (insn, operands, 0, 1);
1758 [(set_attr "type" "brcc")])
1760 (define_insn "cbranch_with_nops"
1763 (match_operator 0 "bfin_cbranch_operator"
1764 [(match_operand:BI 1 "cc_operand" "C")
1765 (match_operand:BI 2 "immediate_operand" "P0")])
1766 (label_ref (match_operand 3 "" ""))
1768 (unspec [(match_operand 4 "immediate_operand" "")] UNSPEC_CBRANCH_NOPS)]
1771 asm_conditional_branch (insn, operands, INTVAL (operands[4]), 0);
1774 [(set_attr "type" "brcc")
1775 (set_attr "length" "6")])
1778 (define_expand "seq"
1779 [(set (match_dup 1) (eq:BI (match_dup 2) (match_dup 3)))
1780 (set (match_operand:SI 0 "register_operand" "")
1781 (ne:SI (match_dup 1) (const_int 0)))]
1784 operands[2] = bfin_compare_op0;
1785 operands[3] = bfin_compare_op1;
1786 operands[1] = bfin_cc_rtx;
1789 (define_expand "slt"
1790 [(set (match_dup 1) (lt:BI (match_dup 2) (match_dup 3)))
1791 (set (match_operand:SI 0 "register_operand" "")
1792 (ne:SI (match_dup 1) (const_int 0)))]
1795 operands[2] = bfin_compare_op0;
1796 operands[3] = bfin_compare_op1;
1797 operands[1] = bfin_cc_rtx;
1800 (define_expand "sle"
1801 [(set (match_dup 1) (le:BI (match_dup 2) (match_dup 3)))
1802 (set (match_operand:SI 0 "register_operand" "")
1803 (ne:SI (match_dup 1) (const_int 0)))]
1806 operands[2] = bfin_compare_op0;
1807 operands[3] = bfin_compare_op1;
1808 operands[1] = bfin_cc_rtx;
1811 (define_expand "sltu"
1812 [(set (match_dup 1) (ltu:BI (match_dup 2) (match_dup 3)))
1813 (set (match_operand:SI 0 "register_operand" "")
1814 (ne:SI (match_dup 1) (const_int 0)))]
1817 operands[2] = bfin_compare_op0;
1818 operands[3] = bfin_compare_op1;
1819 operands[1] = bfin_cc_rtx;
1822 (define_expand "sleu"
1823 [(set (match_dup 1) (leu:BI (match_dup 2) (match_dup 3)))
1824 (set (match_operand:SI 0 "register_operand" "")
1825 (ne:SI (match_dup 1) (const_int 0)))]
1828 operands[2] = bfin_compare_op0;
1829 operands[3] = bfin_compare_op1;
1830 operands[1] = bfin_cc_rtx;
1838 ;;;;;;;;;;;;;;;;;;;; CC2dreg ;;;;;;;;;;;;;;;;;;;;;;;;;
1839 (define_insn "movsibi"
1840 [(set (match_operand:BI 0 "cc_operand" "=C")
1841 (ne:BI (match_operand:SI 1 "register_operand" "d")
1845 [(set_attr "length" "2")])
1847 (define_insn "movbisi"
1848 [(set (match_operand:SI 0 "register_operand" "=d")
1849 (ne:SI (match_operand:BI 1 "cc_operand" "C")
1853 [(set_attr "length" "2")])
1856 [(set (match_operand:BI 0 "cc_operand" "=C")
1857 (eq:BI (match_operand:BI 1 "cc_operand" " 0")
1860 "%0 = ! %0;" /* NOT CC;" */
1861 [(set_attr "type" "compare")])
1863 ;; Vector and DSP insns
1866 [(set (match_operand:SI 0 "register_operand" "=d")
1867 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1869 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1872 "%0 = ALIGN8(%1, %2);"
1873 [(set_attr "type" "dsp32")])
1876 [(set (match_operand:SI 0 "register_operand" "=d")
1877 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1879 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1882 "%0 = ALIGN16(%1, %2);"
1883 [(set_attr "type" "dsp32")])
1886 [(set (match_operand:SI 0 "register_operand" "=d")
1887 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1889 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1892 "%0 = ALIGN24(%1, %2);"
1893 [(set_attr "type" "dsp32")])
1895 ;; Prologue and epilogue.
1897 (define_expand "prologue"
1900 "bfin_expand_prologue (); DONE;")
1902 (define_expand "epilogue"
1905 "bfin_expand_epilogue (1, 0); DONE;")
1907 (define_expand "sibcall_epilogue"
1910 "bfin_expand_epilogue (0, 0); DONE;")
1912 (define_expand "eh_return"
1913 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")]
1914 UNSPEC_VOLATILE_EH_RETURN)]
1917 emit_move_insn (EH_RETURN_HANDLER_RTX, operands[0]);
1918 emit_jump_insn (gen_eh_return_internal ());
1923 (define_insn_and_split "eh_return_internal"
1925 (unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN))]
1930 "bfin_expand_epilogue (1, 1); DONE;")
1933 [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS))
1934 (set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:SI REG_FP))
1935 (set (reg:SI REG_FP)
1936 (plus:SI (reg:SI REG_SP) (const_int -8)))
1937 (set (reg:SI REG_SP)
1938 (plus:SI (reg:SI REG_SP) (match_operand:SI 0 "immediate_operand" "i")))]
1941 [(set_attr "length" "4")])
1943 (define_insn "unlink"
1944 [(set (reg:SI REG_FP) (mem:SI (reg:SI REG_FP)))
1945 (set (reg:SI REG_RETS) (mem:SI (plus:SI (reg:SI REG_FP) (const_int 4))))
1946 (set (reg:SI REG_SP) (plus:SI (reg:SI REG_FP) (const_int 8)))]
1949 [(set_attr "length" "4")])
1951 ;; This pattern is slightly clumsy. The stack adjust must be the final SET in
1952 ;; the pattern, otherwise dwarf2out becomes very confused about which reg goes
1953 ;; where on the stack, since it goes through all elements of the parallel in
1955 (define_insn "push_multiple"
1956 [(match_parallel 0 "push_multiple_operation"
1957 [(unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_PUSH_MULTIPLE)])]
1960 output_push_multiple (insn, operands);
1964 (define_insn "pop_multiple"
1965 [(match_parallel 0 "pop_multiple_operation"
1966 [(set (reg:SI REG_SP)
1967 (plus:SI (reg:SI REG_SP) (match_operand:SI 1 "immediate_operand" "i")))])]
1970 output_pop_multiple (insn, operands);
1974 (define_insn "return_internal"
1976 (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)]
1979 switch (INTVAL (operands[0]))
1985 case INTERRUPT_HANDLER:
1993 (define_insn "csync"
1994 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
1997 [(set_attr "type" "sync")])
1999 (define_insn "ssync"
2000 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_SSYNC)]
2003 [(set_attr "type" "sync")])
2006 [(trap_if (const_int 1) (const_int 3))]
2009 [(set_attr "type" "misc")
2010 (set_attr "length" "2")])
2012 (define_insn "trapifcc"
2013 [(trap_if (reg:BI REG_CC) (const_int 3))]
2015 "if !cc jump 4 (bp); excpt 3;"
2016 [(set_attr "type" "misc")
2017 (set_attr "length" "4")])
2019 ;;; Vector instructions
2021 (define_insn "addv2hi3"
2022 [(set (match_operand:V2HI 0 "register_operand" "=d")
2023 (plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2024 (match_operand:V2HI 2 "register_operand" "d")))]
2027 [(set_attr "type" "dsp32")])
2029 (define_insn "subv2hi3"
2030 [(set (match_operand:V2HI 0 "register_operand" "=d")
2031 (minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2032 (match_operand:V2HI 2 "register_operand" "d")))]
2035 [(set_attr "type" "dsp32")])
2037 (define_insn "sminv2hi3"
2038 [(set (match_operand:V2HI 0 "register_operand" "=d")
2039 (smin:V2HI (match_operand:V2HI 1 "register_operand" "d")
2040 (match_operand:V2HI 2 "register_operand" "d")))]
2042 "%0 = MIN (%1, %2) (V);"
2043 [(set_attr "type" "dsp32")])
2045 (define_insn "smaxv2hi3"
2046 [(set (match_operand:V2HI 0 "register_operand" "=d")
2047 (smax:V2HI (match_operand:V2HI 1 "register_operand" "d")
2048 (match_operand:V2HI 2 "register_operand" "d")))]
2050 "%0 = MAX (%1, %2) (V);"
2051 [(set_attr "type" "dsp32")])
2053 (define_insn "mulv2hi3"
2054 [(set (match_operand:V2HI 0 "register_operand" "=d")
2055 (mult:V2HI (match_operand:V2HI 1 "register_operand" "d")
2056 (match_operand:V2HI 2 "register_operand" "d")))]
2058 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 (IS);"
2059 [(set_attr "type" "dsp32")])
2061 (define_insn "negv2hi2"
2062 [(set (match_operand:V2HI 0 "register_operand" "=d")
2063 (neg:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
2066 [(set_attr "type" "dsp32")])
2068 (define_insn "absv2hi2"
2069 [(set (match_operand:V2HI 0 "register_operand" "=d")
2070 (abs:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
2073 [(set_attr "type" "dsp32")])