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 (define_insn "usmulhisi3"
912 [(set (match_operand:SI 0 "register_operand" "=W")
913 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "W"))
914 (sign_extend:SI (match_operand:HI 2 "register_operand" "W"))))]
916 "%0 = %h2 * %h1 (IS,M);"
917 [(set_attr "type" "dsp32")])
919 ;; The processor also supports ireg += mreg or ireg -= mreg, but these
920 ;; are unusable if we don't ensure that the corresponding lreg is zero.
921 ;; The same applies to the add/subtract constant versions involving
924 (define_insn "addsi3"
925 [(set (match_operand:SI 0 "register_operand" "=ad,a,d")
926 (plus:SI (match_operand:SI 1 "register_operand" "%0, a,d")
927 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7, a,d")))]
933 [(set_attr "type" "alu0")
934 (set_attr "length" "2,2,2")])
936 (define_expand "subsi3"
937 [(set (match_operand:SI 0 "register_operand" "")
938 (minus:SI (match_operand:SI 1 "register_operand" "")
939 (match_operand:SI 2 "reg_or_7bit_operand" "")))]
944 [(set (match_operand:SI 0 "register_operand" "=da,d,a")
945 (minus:SI (match_operand:SI 1 "register_operand" "0,d,0")
946 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7,d,a")))]
947 "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -64"
949 static const char *const strings_subsi3[] = {
955 if (CONSTANT_P (operands[2]) && INTVAL (operands[2]) < 0) {
956 rtx tmp_op = operands[2];
957 operands[2] = GEN_INT (-INTVAL (operands[2]));
958 output_asm_insn ("%0 += %2;", operands);
959 operands[2] = tmp_op;
963 return strings_subsi3[which_alternative];
965 [(set_attr "type" "alu0")])
967 ;; Bit test instructions
969 (define_insn "*not_bittst"
970 [(set (match_operand:BI 0 "cc_operand" "=C")
971 (eq:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
973 (match_operand:SI 2 "immediate_operand" "Ku5"))
976 "cc = !BITTST (%1,%2);"
977 [(set_attr "type" "alu0")])
979 (define_insn "*bittst"
980 [(set (match_operand:BI 0 "cc_operand" "=C")
981 (ne:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
983 (match_operand:SI 2 "immediate_operand" "Ku5"))
986 "cc = BITTST (%1,%2);"
987 [(set_attr "type" "alu0")])
989 (define_insn_and_split "*bit_extract"
990 [(set (match_operand:SI 0 "register_operand" "=d")
991 (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
993 (match_operand:SI 2 "immediate_operand" "Ku5")))
994 (clobber (reg:BI REG_CC))]
998 [(set (reg:BI REG_CC)
999 (ne:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1002 (ne:SI (reg:BI REG_CC) (const_int 0)))])
1004 (define_insn_and_split "*not_bit_extract"
1005 [(set (match_operand:SI 0 "register_operand" "=d")
1006 (zero_extract:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1008 (match_operand:SI 2 "immediate_operand" "Ku5")))
1009 (clobber (reg:BI REG_CC))]
1013 [(set (reg:BI REG_CC)
1014 (eq:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1017 (ne:SI (reg:BI REG_CC) (const_int 0)))])
1019 (define_insn "*andsi_insn"
1020 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
1021 (and:SI (match_operand:SI 1 "register_operand" "%0,d,d,d")
1022 (match_operand:SI 2 "rhs_andsi3_operand" "L,M1,M2,d")))]
1029 [(set_attr "type" "alu0")])
1031 (define_expand "andsi3"
1032 [(set (match_operand:SI 0 "register_operand" "")
1033 (and:SI (match_operand:SI 1 "register_operand" "")
1034 (match_operand:SI 2 "general_operand" "")))]
1037 if (highbits_operand (operands[2], SImode))
1039 operands[2] = GEN_INT (exact_log2 (-INTVAL (operands[2])));
1040 emit_insn (gen_ashrsi3 (operands[0], operands[1], operands[2]));
1041 emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
1044 if (! rhs_andsi3_operand (operands[2], SImode))
1045 operands[2] = force_reg (SImode, operands[2]);
1048 (define_insn "iorsi3"
1049 [(set (match_operand:SI 0 "register_operand" "=d,d")
1050 (ior:SI (match_operand:SI 1 "register_operand" "%0,d")
1051 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1056 [(set_attr "type" "alu0")])
1058 (define_insn "xorsi3"
1059 [(set (match_operand:SI 0 "register_operand" "=d,d")
1060 (xor:SI (match_operand:SI 1 "register_operand" "%0,d")
1061 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1066 [(set_attr "type" "alu0")])
1068 (define_insn "smaxsi3"
1069 [(set (match_operand:SI 0 "register_operand" "=d")
1070 (smax:SI (match_operand:SI 1 "register_operand" "d")
1071 (match_operand:SI 2 "register_operand" "d")))]
1074 [(set_attr "type" "dsp32")])
1076 (define_insn "sminsi3"
1077 [(set (match_operand:SI 0 "register_operand" "=d")
1078 (smin:SI (match_operand:SI 1 "register_operand" "d")
1079 (match_operand:SI 2 "register_operand" "d")))]
1082 [(set_attr "type" "dsp32")])
1084 (define_insn "abssi2"
1085 [(set (match_operand:SI 0 "register_operand" "=d")
1086 (abs:SI (match_operand:SI 1 "register_operand" " d")))]
1089 [(set_attr "type" "dsp32")])
1092 (define_insn "negsi2"
1093 [(set (match_operand:SI 0 "register_operand" "=d")
1094 (neg:SI (match_operand:SI 1 "register_operand" " d")))]
1097 [(set_attr "type" "alu0")])
1099 (define_insn "one_cmplsi2"
1100 [(set (match_operand:SI 0 "register_operand" "=d")
1101 (not:SI (match_operand:SI 1 "register_operand" " d")))]
1104 [(set_attr "type" "alu0")])
1106 (define_insn "mulsi3"
1107 [(set (match_operand:SI 0 "register_operand" "=d")
1108 (mult:SI (match_operand:SI 1 "register_operand" "%0")
1109 (match_operand:SI 2 "register_operand" "d")))]
1112 [(set_attr "type" "mult")])
1114 (define_expand "ashlsi3"
1115 [(set (match_operand:SI 0 "register_operand" "")
1116 (ashift:SI (match_operand:SI 1 "register_operand" "")
1117 (match_operand:SI 2 "nonmemory_operand" "")))]
1120 if (GET_CODE (operands[2]) == CONST_INT
1121 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1123 emit_insn (gen_movsi (operands[0], const0_rtx));
1128 (define_insn_and_split "*ashlsi3_insn"
1129 [(set (match_operand:SI 0 "register_operand" "=d,a,a,a")
1130 (ashift:SI (match_operand:SI 1 "register_operand" "0,a,a,a")
1131 (match_operand:SI 2 "nonmemory_operand" "dKu5,P1,P2,?P3P4")))]
1138 "PREG_P (operands[0]) && INTVAL (operands[2]) > 2"
1139 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
1140 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
1141 "operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
1142 [(set_attr "type" "shft")])
1144 (define_insn "ashrsi3"
1145 [(set (match_operand:SI 0 "register_operand" "=d")
1146 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1147 (match_operand:SI 2 "nonmemory_operand" "dKu5")))]
1150 [(set_attr "type" "shft")])
1152 (define_insn "ror_one"
1153 [(set (match_operand:SI 0 "register_operand" "=d")
1154 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1155 (ashift:SI (zero_extend:SI (reg:BI REG_CC)) (const_int 31))))
1156 (set (reg:BI REG_CC)
1157 (zero_extract:BI (match_dup 1) (const_int 1) (const_int 0)))]
1159 "%0 = ROT %1 BY -1;"
1160 [(set_attr "type" "shft")
1161 (set_attr "length" "4")])
1163 (define_insn "rol_one"
1164 [(set (match_operand:SI 0 "register_operand" "+d")
1165 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1166 (zero_extend:SI (reg:BI REG_CC))))
1167 (set (reg:BI REG_CC)
1168 (zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))]
1171 [(set_attr "type" "shft")
1172 (set_attr "length" "4")])
1174 (define_expand "lshrdi3"
1175 [(set (match_operand:DI 0 "register_operand" "")
1176 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1177 (match_operand:DI 2 "general_operand" "")))]
1180 rtx lo_half[2], hi_half[2];
1182 if (operands[2] != const1_rtx)
1184 if (! rtx_equal_p (operands[0], operands[1]))
1185 emit_move_insn (operands[0], operands[1]);
1187 split_di (operands, 2, lo_half, hi_half);
1189 emit_move_insn (bfin_cc_rtx, const0_rtx);
1190 emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1191 emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1195 (define_expand "ashrdi3"
1196 [(set (match_operand:DI 0 "register_operand" "")
1197 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1198 (match_operand:DI 2 "general_operand" "")))]
1201 rtx lo_half[2], hi_half[2];
1203 if (operands[2] != const1_rtx)
1205 if (! rtx_equal_p (operands[0], operands[1]))
1206 emit_move_insn (operands[0], operands[1]);
1208 split_di (operands, 2, lo_half, hi_half);
1210 emit_insn (gen_compare_lt (gen_rtx_REG (BImode, REG_CC),
1211 hi_half[1], const0_rtx));
1212 emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1213 emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1217 (define_expand "ashldi3"
1218 [(set (match_operand:DI 0 "register_operand" "")
1219 (ashift:DI (match_operand:DI 1 "register_operand" "")
1220 (match_operand:DI 2 "general_operand" "")))]
1223 rtx lo_half[2], hi_half[2];
1225 if (operands[2] != const1_rtx)
1227 if (! rtx_equal_p (operands[0], operands[1]))
1228 emit_move_insn (operands[0], operands[1]);
1230 split_di (operands, 2, lo_half, hi_half);
1232 emit_move_insn (bfin_cc_rtx, const0_rtx);
1233 emit_insn (gen_rol_one (lo_half[0], lo_half[0]));
1234 emit_insn (gen_rol_one (hi_half[0], hi_half[0]));
1238 (define_insn "lshrsi3"
1239 [(set (match_operand:SI 0 "register_operand" "=d,a")
1240 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0,a")
1241 (match_operand:SI 2 "nonmemory_operand" "dKu5,P1P2")))]
1246 [(set_attr "type" "shft")])
1248 ;; A pattern to reload the equivalent of
1249 ;; (set (Dreg) (plus (FP) (large_constant)))
1251 ;; (set (dagreg) (plus (FP) (arbitrary_constant)))
1252 ;; using a scratch register
1253 (define_expand "reload_insi"
1254 [(parallel [(set (match_operand:SI 0 "register_operand" "=w")
1255 (match_operand:SI 1 "fp_plus_const_operand" ""))
1256 (clobber (match_operand:SI 2 "register_operand" "=&a"))])]
1259 rtx fp_op = XEXP (operands[1], 0);
1260 rtx const_op = XEXP (operands[1], 1);
1261 rtx primary = operands[0];
1262 rtx scratch = operands[2];
1264 emit_move_insn (scratch, const_op);
1265 emit_insn (gen_addsi3 (scratch, scratch, fp_op));
1266 emit_move_insn (primary, scratch);
1270 ;; Jump instructions
1274 (label_ref (match_operand 0 "" "")))]
1277 if (get_attr_length (insn) == 2)
1278 return "jump.s %0;";
1280 return "jump.l %0;";
1282 [(set_attr "type" "br")])
1284 (define_insn "indirect_jump"
1286 (match_operand:SI 0 "register_operand" "a"))]
1289 [(set_attr "type" "misc")])
1291 (define_expand "tablejump"
1292 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1293 (use (label_ref (match_operand 1 "" "")))])]
1296 /* In PIC mode, the table entries are stored PC relative.
1297 Convert the relative address to an absolute address. */
1300 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1302 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1303 op1, NULL_RTX, 0, OPTAB_DIRECT);
1307 (define_insn "*tablejump_internal"
1308 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1309 (use (label_ref (match_operand 1 "" "")))]
1312 [(set_attr "type" "misc")])
1314 ;; Call instructions..
1316 (define_expand "call"
1317 [(parallel [(call (match_operand:SI 0 "" "")
1318 (match_operand 1 "" ""))
1319 (use (match_operand 2 "" ""))])]
1322 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 0);
1326 (define_expand "sibcall"
1327 [(parallel [(call (match_operand:SI 0 "" "")
1328 (match_operand 1 "" ""))
1329 (use (match_operand 2 "" ""))
1333 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 1);
1337 (define_expand "call_value"
1338 [(parallel [(set (match_operand 0 "register_operand" "")
1339 (call (match_operand:SI 1 "" "")
1340 (match_operand 2 "" "")))
1341 (use (match_operand 3 "" ""))])]
1344 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 0);
1348 (define_expand "sibcall_value"
1349 [(parallel [(set (match_operand 0 "register_operand" "")
1350 (call (match_operand:SI 1 "" "")
1351 (match_operand 2 "" "")))
1352 (use (match_operand 3 "" ""))
1356 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 1);
1360 (define_insn "*call_symbol"
1361 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1362 (match_operand 1 "general_operand" "g"))
1363 (use (match_operand 2 "" ""))]
1364 "! SIBLING_CALL_P (insn)
1366 && GET_CODE (operands[0]) == SYMBOL_REF
1367 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
1369 [(set_attr "type" "call")
1370 (set_attr "length" "4")])
1372 (define_insn "*sibcall_symbol"
1373 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1374 (match_operand 1 "general_operand" "g"))
1375 (use (match_operand 2 "" ""))
1377 "SIBLING_CALL_P (insn)
1379 && GET_CODE (operands[0]) == SYMBOL_REF
1380 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
1382 [(set_attr "type" "br")
1383 (set_attr "length" "4")])
1385 (define_insn "*call_value_symbol"
1386 [(set (match_operand 0 "register_operand" "=d")
1387 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1388 (match_operand 2 "general_operand" "g")))
1389 (use (match_operand 3 "" ""))]
1390 "! SIBLING_CALL_P (insn)
1392 && GET_CODE (operands[1]) == SYMBOL_REF
1393 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
1395 [(set_attr "type" "call")
1396 (set_attr "length" "4")])
1398 (define_insn "*sibcall_value_symbol"
1399 [(set (match_operand 0 "register_operand" "=d")
1400 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1401 (match_operand 2 "general_operand" "g")))
1402 (use (match_operand 3 "" ""))
1404 "SIBLING_CALL_P (insn)
1406 && GET_CODE (operands[1]) == SYMBOL_REF
1407 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
1409 [(set_attr "type" "br")
1410 (set_attr "length" "4")])
1412 (define_insn "*call_insn"
1413 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a"))
1414 (match_operand 1 "general_operand" "g"))
1415 (use (match_operand 2 "" ""))]
1416 "! SIBLING_CALL_P (insn)"
1418 [(set_attr "type" "call")
1419 (set_attr "length" "2")])
1421 (define_insn "*sibcall_insn"
1422 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "z"))
1423 (match_operand 1 "general_operand" "g"))
1424 (use (match_operand 2 "" ""))
1426 "SIBLING_CALL_P (insn)"
1428 [(set_attr "type" "br")
1429 (set_attr "length" "2")])
1431 (define_insn "*call_value_insn"
1432 [(set (match_operand 0 "register_operand" "=d")
1433 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a"))
1434 (match_operand 2 "general_operand" "g")))
1435 (use (match_operand 3 "" ""))]
1436 "! SIBLING_CALL_P (insn)"
1438 [(set_attr "type" "call")
1439 (set_attr "length" "2")])
1441 (define_insn "*sibcall_value_insn"
1442 [(set (match_operand 0 "register_operand" "=d")
1443 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "z"))
1444 (match_operand 2 "general_operand" "g")))
1445 (use (match_operand 3 "" ""))
1447 "SIBLING_CALL_P (insn)"
1449 [(set_attr "type" "br")
1450 (set_attr "length" "2")])
1452 ;; Block move patterns
1454 ;; We cheat. This copies one more word than operand 2 indicates.
1456 (define_insn "rep_movsi"
1457 [(set (match_operand:SI 0 "register_operand" "=&a")
1458 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1459 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1462 (set (match_operand:SI 1 "register_operand" "=&b")
1463 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1464 (ashift:SI (match_dup 2) (const_int 2)))
1466 (set (mem:BLK (match_dup 3))
1467 (mem:BLK (match_dup 4)))
1469 (clobber (match_scratch:HI 5 "=&d"))]
1471 "%5 = [%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || [%3++] = %5 || %5 = [%4++]; [%3++] = %5;"
1472 [(set_attr "type" "misc")
1473 (set_attr "length" "16")])
1475 (define_insn "rep_movhi"
1476 [(set (match_operand:SI 0 "register_operand" "=&a")
1477 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1478 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1481 (set (match_operand:SI 1 "register_operand" "=&b")
1482 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1483 (ashift:SI (match_dup 2) (const_int 1)))
1485 (set (mem:BLK (match_dup 3))
1486 (mem:BLK (match_dup 4)))
1488 (clobber (match_scratch:HI 5 "=&d"))]
1490 "%h5 = W[%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || W [%3++] = %5 || %h5 = W [%4++]; W [%3++] = %5;"
1491 [(set_attr "type" "misc")
1492 (set_attr "length" "16")])
1494 (define_expand "movstrsi"
1495 [(match_operand:BLK 0 "general_operand" "")
1496 (match_operand:BLK 1 "general_operand" "")
1497 (match_operand:SI 2 "const_int_operand" "")
1498 (match_operand:SI 3 "const_int_operand" "")]
1501 if (bfin_expand_strmov (operands[0], operands[1], operands[2], operands[3]))
1506 ;; Conditional branch patterns
1507 ;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
1509 ;; The only outcome of this pattern is that global variables
1510 ;; bfin_compare_op[01] are set for use in bcond patterns.
1512 (define_expand "cmpbi"
1513 [(set (cc0) (compare (match_operand:BI 0 "register_operand" "")
1514 (match_operand:BI 1 "immediate_operand" "")))]
1517 bfin_compare_op0 = operands[0];
1518 bfin_compare_op1 = operands[1];
1522 (define_expand "cmpsi"
1523 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
1524 (match_operand:SI 1 "reg_or_const_int_operand" "")))]
1527 bfin_compare_op0 = operands[0];
1528 bfin_compare_op1 = operands[1];
1532 (define_insn "compare_eq"
1533 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1534 (eq: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_ne"
1541 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1542 (ne: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_lt"
1549 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1550 (lt: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_le"
1557 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1558 (le:BI (match_operand:SI 1 "register_operand" "d,a")
1559 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
1562 [(set_attr "type" "compare")])
1564 (define_insn "compare_leu"
1565 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1566 (leu: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_insn "compare_ltu"
1573 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1574 (ltu:BI (match_operand:SI 1 "register_operand" "d,a")
1575 (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
1578 [(set_attr "type" "compare")])
1580 (define_expand "beq"
1581 [(set (match_dup 1) (match_dup 2))
1583 (if_then_else (match_dup 3)
1584 (label_ref (match_operand 0 "" ""))
1588 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1589 operands[1] = bfin_cc_rtx; /* hard register: CC */
1590 operands[2] = gen_rtx_EQ (BImode, op0, op1);
1591 /* If we have a BImode input, then we already have a compare result, and
1592 do not need to emit another comparison. */
1593 if (GET_MODE (bfin_compare_op0) == BImode)
1595 gcc_assert (bfin_compare_op1 == const0_rtx);
1596 emit_insn (gen_cbranchbi4 (operands[2], op0, op1, operands[0]));
1600 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1603 (define_expand "bne"
1604 [(set (match_dup 1) (match_dup 2))
1606 (if_then_else (match_dup 3)
1607 (label_ref (match_operand 0 "" ""))
1611 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1612 /* If we have a BImode input, then we already have a compare result, and
1613 do not need to emit another comparison. */
1614 if (GET_MODE (bfin_compare_op0) == BImode)
1616 rtx cmp = gen_rtx_NE (BImode, op0, op1);
1618 gcc_assert (bfin_compare_op1 == const0_rtx);
1619 emit_insn (gen_cbranchbi4 (cmp, op0, op1, operands[0]));
1623 operands[1] = bfin_cc_rtx; /* hard register: CC */
1624 operands[2] = gen_rtx_EQ (BImode, op0, op1);
1625 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1628 (define_expand "bgt"
1629 [(set (match_dup 1) (match_dup 2))
1631 (if_then_else (match_dup 3)
1632 (label_ref (match_operand 0 "" ""))
1636 operands[1] = bfin_cc_rtx;
1637 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1638 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1641 (define_expand "bgtu"
1642 [(set (match_dup 1) (match_dup 2))
1644 (if_then_else (match_dup 3)
1645 (label_ref (match_operand 0 "" ""))
1649 operands[1] = bfin_cc_rtx;
1650 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1651 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1654 (define_expand "blt"
1655 [(set (match_dup 1) (match_dup 2))
1657 (if_then_else (match_dup 3)
1658 (label_ref (match_operand 0 "" ""))
1662 operands[1] = bfin_cc_rtx;
1663 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1664 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1667 (define_expand "bltu"
1668 [(set (match_dup 1) (match_dup 2))
1670 (if_then_else (match_dup 3)
1671 (label_ref (match_operand 0 "" ""))
1675 operands[1] = bfin_cc_rtx;
1676 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1677 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1681 (define_expand "bge"
1682 [(set (match_dup 1) (match_dup 2))
1684 (if_then_else (match_dup 3)
1685 (label_ref (match_operand 0 "" ""))
1689 operands[1] = bfin_cc_rtx;
1690 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1691 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1694 (define_expand "bgeu"
1695 [(set (match_dup 1) (match_dup 2))
1697 (if_then_else (match_dup 3)
1698 (label_ref (match_operand 0 "" ""))
1702 operands[1] = bfin_cc_rtx;
1703 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1704 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1707 (define_expand "ble"
1708 [(set (match_dup 1) (match_dup 2))
1710 (if_then_else (match_dup 3)
1711 (label_ref (match_operand 0 "" ""))
1715 operands[1] = bfin_cc_rtx;
1716 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1717 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1720 (define_expand "bleu"
1721 [(set (match_dup 1) (match_dup 2))
1723 (if_then_else (match_dup 3)
1724 (label_ref (match_operand 0 "" ""))
1729 operands[1] = bfin_cc_rtx;
1730 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1731 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1734 (define_insn "cbranchbi4"
1737 (match_operator 0 "bfin_cbranch_operator"
1738 [(match_operand:BI 1 "cc_operand" "C")
1739 (match_operand:BI 2 "immediate_operand" "P0")])
1740 (label_ref (match_operand 3 "" ""))
1744 asm_conditional_branch (insn, operands, 0, 0);
1747 [(set_attr "type" "brcc")])
1749 ;; Special cbranch patterns to deal with the speculative load problem - see
1750 ;; bfin_reorg for details.
1752 (define_insn "cbranch_predicted_taken"
1755 (match_operator 0 "bfin_cbranch_operator"
1756 [(match_operand:BI 1 "cc_operand" "C")
1757 (match_operand:BI 2 "immediate_operand" "P0")])
1758 (label_ref (match_operand 3 "" ""))
1760 (unspec [(const_int 0)] UNSPEC_CBRANCH_TAKEN)]
1763 asm_conditional_branch (insn, operands, 0, 1);
1766 [(set_attr "type" "brcc")])
1768 (define_insn "cbranch_with_nops"
1771 (match_operator 0 "bfin_cbranch_operator"
1772 [(match_operand:BI 1 "cc_operand" "C")
1773 (match_operand:BI 2 "immediate_operand" "P0")])
1774 (label_ref (match_operand 3 "" ""))
1776 (unspec [(match_operand 4 "immediate_operand" "")] UNSPEC_CBRANCH_NOPS)]
1779 asm_conditional_branch (insn, operands, INTVAL (operands[4]), 0);
1782 [(set_attr "type" "brcc")
1783 (set_attr "length" "6")])
1786 (define_expand "seq"
1787 [(set (match_dup 1) (eq:BI (match_dup 2) (match_dup 3)))
1788 (set (match_operand:SI 0 "register_operand" "")
1789 (ne:SI (match_dup 1) (const_int 0)))]
1792 operands[2] = bfin_compare_op0;
1793 operands[3] = bfin_compare_op1;
1794 operands[1] = bfin_cc_rtx;
1797 (define_expand "slt"
1798 [(set (match_dup 1) (lt:BI (match_dup 2) (match_dup 3)))
1799 (set (match_operand:SI 0 "register_operand" "")
1800 (ne:SI (match_dup 1) (const_int 0)))]
1803 operands[2] = bfin_compare_op0;
1804 operands[3] = bfin_compare_op1;
1805 operands[1] = bfin_cc_rtx;
1808 (define_expand "sle"
1809 [(set (match_dup 1) (le:BI (match_dup 2) (match_dup 3)))
1810 (set (match_operand:SI 0 "register_operand" "")
1811 (ne:SI (match_dup 1) (const_int 0)))]
1814 operands[2] = bfin_compare_op0;
1815 operands[3] = bfin_compare_op1;
1816 operands[1] = bfin_cc_rtx;
1819 (define_expand "sltu"
1820 [(set (match_dup 1) (ltu:BI (match_dup 2) (match_dup 3)))
1821 (set (match_operand:SI 0 "register_operand" "")
1822 (ne:SI (match_dup 1) (const_int 0)))]
1825 operands[2] = bfin_compare_op0;
1826 operands[3] = bfin_compare_op1;
1827 operands[1] = bfin_cc_rtx;
1830 (define_expand "sleu"
1831 [(set (match_dup 1) (leu:BI (match_dup 2) (match_dup 3)))
1832 (set (match_operand:SI 0 "register_operand" "")
1833 (ne:SI (match_dup 1) (const_int 0)))]
1836 operands[2] = bfin_compare_op0;
1837 operands[3] = bfin_compare_op1;
1838 operands[1] = bfin_cc_rtx;
1846 ;;;;;;;;;;;;;;;;;;;; CC2dreg ;;;;;;;;;;;;;;;;;;;;;;;;;
1847 (define_insn "movsibi"
1848 [(set (match_operand:BI 0 "cc_operand" "=C")
1849 (ne:BI (match_operand:SI 1 "register_operand" "d")
1853 [(set_attr "length" "2")])
1855 (define_insn "movbisi"
1856 [(set (match_operand:SI 0 "register_operand" "=d")
1857 (ne:SI (match_operand:BI 1 "cc_operand" "C")
1861 [(set_attr "length" "2")])
1864 [(set (match_operand:BI 0 "cc_operand" "=C")
1865 (eq:BI (match_operand:BI 1 "cc_operand" " 0")
1868 "%0 = ! %0;" /* NOT CC;" */
1869 [(set_attr "type" "compare")])
1871 ;; Vector and DSP insns
1874 [(set (match_operand:SI 0 "register_operand" "=d")
1875 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1877 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1880 "%0 = ALIGN8(%1, %2);"
1881 [(set_attr "type" "dsp32")])
1884 [(set (match_operand:SI 0 "register_operand" "=d")
1885 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1887 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1890 "%0 = ALIGN16(%1, %2);"
1891 [(set_attr "type" "dsp32")])
1894 [(set (match_operand:SI 0 "register_operand" "=d")
1895 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1897 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1900 "%0 = ALIGN24(%1, %2);"
1901 [(set_attr "type" "dsp32")])
1903 ;; Prologue and epilogue.
1905 (define_expand "prologue"
1908 "bfin_expand_prologue (); DONE;")
1910 (define_expand "epilogue"
1913 "bfin_expand_epilogue (1, 0); DONE;")
1915 (define_expand "sibcall_epilogue"
1918 "bfin_expand_epilogue (0, 0); DONE;")
1920 (define_expand "eh_return"
1921 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")]
1922 UNSPEC_VOLATILE_EH_RETURN)]
1925 emit_move_insn (EH_RETURN_HANDLER_RTX, operands[0]);
1926 emit_insn (gen_eh_return_internal ());
1931 (define_insn_and_split "eh_return_internal"
1932 [(unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN)]
1937 "bfin_expand_epilogue (1, 1); DONE;")
1940 [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS))
1941 (set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:SI REG_FP))
1942 (set (reg:SI REG_FP)
1943 (plus:SI (reg:SI REG_SP) (const_int -8)))
1944 (set (reg:SI REG_SP)
1945 (plus:SI (reg:SI REG_SP) (match_operand:SI 0 "immediate_operand" "i")))]
1948 [(set_attr "length" "4")])
1950 (define_insn "unlink"
1951 [(set (reg:SI REG_FP) (mem:SI (reg:SI REG_FP)))
1952 (set (reg:SI REG_RETS) (mem:SI (plus:SI (reg:SI REG_FP) (const_int 4))))
1953 (set (reg:SI REG_SP) (plus:SI (reg:SI REG_FP) (const_int 8)))]
1956 [(set_attr "length" "4")])
1958 ;; This pattern is slightly clumsy. The stack adjust must be the final SET in
1959 ;; the pattern, otherwise dwarf2out becomes very confused about which reg goes
1960 ;; where on the stack, since it goes through all elements of the parallel in
1962 (define_insn "push_multiple"
1963 [(match_parallel 0 "push_multiple_operation"
1964 [(unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_PUSH_MULTIPLE)])]
1967 output_push_multiple (insn, operands);
1971 (define_insn "pop_multiple"
1972 [(match_parallel 0 "pop_multiple_operation"
1973 [(set (reg:SI REG_SP)
1974 (plus:SI (reg:SI REG_SP) (match_operand:SI 1 "immediate_operand" "i")))])]
1977 output_pop_multiple (insn, operands);
1981 (define_insn "return_internal"
1983 (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)]
1986 switch (INTVAL (operands[0]))
1992 case INTERRUPT_HANDLER:
2000 (define_insn "csync"
2001 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
2004 [(set_attr "type" "sync")])
2006 (define_insn "ssync"
2007 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_SSYNC)]
2010 [(set_attr "type" "sync")])
2013 [(trap_if (const_int 1) (const_int 3))]
2016 [(set_attr "type" "misc")
2017 (set_attr "length" "2")])
2019 (define_insn "trapifcc"
2020 [(trap_if (reg:BI REG_CC) (const_int 3))]
2022 "if !cc jump 4 (bp); excpt 3;"
2023 [(set_attr "type" "misc")
2024 (set_attr "length" "4")])
2026 ;;; Vector instructions
2028 (define_insn "addv2hi3"
2029 [(set (match_operand:V2HI 0 "register_operand" "=d")
2030 (plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2031 (match_operand:V2HI 2 "register_operand" "d")))]
2034 [(set_attr "type" "dsp32")])
2036 (define_insn "subv2hi3"
2037 [(set (match_operand:V2HI 0 "register_operand" "=d")
2038 (minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2039 (match_operand:V2HI 2 "register_operand" "d")))]
2042 [(set_attr "type" "dsp32")])
2044 (define_insn "sminv2hi3"
2045 [(set (match_operand:V2HI 0 "register_operand" "=d")
2046 (smin:V2HI (match_operand:V2HI 1 "register_operand" "d")
2047 (match_operand:V2HI 2 "register_operand" "d")))]
2049 "%0 = MIN (%1, %2) (V);"
2050 [(set_attr "type" "dsp32")])
2052 (define_insn "smaxv2hi3"
2053 [(set (match_operand:V2HI 0 "register_operand" "=d")
2054 (smax:V2HI (match_operand:V2HI 1 "register_operand" "d")
2055 (match_operand:V2HI 2 "register_operand" "d")))]
2057 "%0 = MAX (%1, %2) (V);"
2058 [(set_attr "type" "dsp32")])
2060 (define_insn "mulv2hi3"
2061 [(set (match_operand:V2HI 0 "register_operand" "=d")
2062 (mult:V2HI (match_operand:V2HI 1 "register_operand" "d")
2063 (match_operand:V2HI 2 "register_operand" "d")))]
2065 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 (IS);"
2066 [(set_attr "type" "dsp32")])
2068 (define_insn "negv2hi2"
2069 [(set (match_operand:V2HI 0 "register_operand" "=d")
2070 (neg:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
2073 [(set_attr "type" "dsp32")])
2075 (define_insn "absv2hi2"
2076 [(set (match_operand:V2HI 0 "register_operand" "=d")
2077 (abs:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
2080 [(set_attr "type" "dsp32")])