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, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, 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.
112 ;; Constants used in UNSPECs and UNSPEC_VOLATILEs.
115 [(UNSPEC_CBRANCH_TAKEN 0)
116 (UNSPEC_CBRANCH_NOPS 1)
119 (UNSPEC_LIBRARY_OFFSET 4)
120 (UNSPEC_PUSH_MULTIPLE 5)])
123 [(UNSPEC_VOLATILE_EH_RETURN 0)])
126 "move,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,compare,dummy"
127 (const_string "misc"))
129 ;; Scheduling definitions
131 (define_automaton "bfin")
133 (define_cpu_unit "core" "bfin")
135 (define_insn_reservation "alu" 1
136 (eq_attr "type" "move,mvi,mcst,dsp32,alu0,shft,brcc,br,call,misc,compare")
139 (define_insn_reservation "imul" 3
140 (eq_attr "type" "mult")
143 (define_insn_reservation "load" 1
144 (eq_attr "type" "mcld")
147 ;; Make sure genautomata knows about the maximum latency that can be produced
148 ;; by the adjust_cost function.
149 (define_insn_reservation "dummy" 5
150 (eq_attr "type" "mcld")
153 ;; Operand and operator predicates
155 (include "predicates.md")
158 ;;; FRIO branches have been optimized for code density
159 ;;; this comes at a slight cost of complexity when
160 ;;; a compiler needs to generate branches in the general
161 ;;; case. In order to generate the correct branching
162 ;;; mechanisms the compiler needs keep track of instruction
163 ;;; lengths. The follow table describes how to count instructions
164 ;;; for the FRIO architecture.
166 ;;; unconditional br are 12-bit imm pcrelative branches *2
167 ;;; conditional br are 10-bit imm pcrelative branches *2
169 ;;; 1024 10-bit imm *2 is 2048 (-1024..1022)
171 ;;; 4096 12-bit imm *2 is 8192 (-4096..4094)
172 ;;; NOTE : For brcc we generate instructions such as
173 ;;; if cc jmp; jump.[sl] offset
174 ;;; offset of jump.[sl] is from the jump instruction but
175 ;;; gcc calculates length from the if cc jmp instruction
176 ;;; hence our range is (-4094, 4096) instead of (-4096, 4094) for a br
178 ;;; The way the (pc) rtx works in these calculations is somewhat odd;
179 ;;; for backward branches it's the address of the current instruction,
180 ;;; for forward branches it's the previously known address of the following
181 ;;; instruction - we have to take this into account by reducing the range
182 ;;; for a forward branch.
184 ;; Lengths for type "mvi" insns are always defined by the instructions
186 (define_attr "length" ""
187 (cond [(eq_attr "type" "mcld")
188 (if_then_else (match_operand 1 "effective_address_32bit_p" "")
189 (const_int 4) (const_int 2))
191 (eq_attr "type" "mcst")
192 (if_then_else (match_operand 0 "effective_address_32bit_p" "")
193 (const_int 4) (const_int 2))
195 (eq_attr "type" "move") (const_int 2)
197 (eq_attr "type" "dsp32") (const_int 4)
198 (eq_attr "type" "call") (const_int 4)
200 (eq_attr "type" "br")
202 (le (minus (match_dup 0) (pc)) (const_int 4092))
203 (ge (minus (match_dup 0) (pc)) (const_int -4096)))
207 (eq_attr "type" "brcc")
209 (le (minus (match_dup 3) (pc)) (const_int 1020))
210 (ge (minus (match_dup 3) (pc)) (const_int -1024)))
213 (le (minus (match_dup 3) (pc)) (const_int 4096))
214 (ge (minus (match_dup 3) (pc)) (const_int -4094)))
223 (define_expand "movsicc"
224 [(set (match_operand:SI 0 "register_operand" "")
225 (if_then_else:SI (match_operand 1 "comparison_operator" "")
226 (match_operand:SI 2 "register_operand" "")
227 (match_operand:SI 3 "register_operand" "")))]
230 operands[1] = bfin_gen_compare (operands[1], SImode);
233 (define_insn "*movsicc_insn1"
234 [(set (match_operand:SI 0 "register_operand" "=da,da,da")
236 (eq:BI (match_operand:BI 3 "cc_operand" "C,C,C")
238 (match_operand:SI 1 "register_operand" "da,0,da")
239 (match_operand:SI 2 "register_operand" "0,da,da")))]
242 if !cc %0 =%1; /* movsicc-1a */
243 if cc %0 =%2; /* movsicc-1b */
244 if !cc %0 =%1; if cc %0=%2; /* movsicc-1 */"
245 [(set_attr "length" "2,2,4")
246 (set_attr "type" "move")])
248 (define_insn "*movsicc_insn2"
249 [(set (match_operand:SI 0 "register_operand" "=da,da,da")
251 (ne:BI (match_operand:BI 3 "cc_operand" "C,C,C")
253 (match_operand:SI 1 "register_operand" "0,da,da")
254 (match_operand:SI 2 "register_operand" "da,0,da")))]
257 if !cc %0 =%2; /* movsicc-2b */
258 if cc %0 =%1; /* movsicc-2a */
259 if cc %0 =%1; if !cc %0=%2; /* movsicc-1 */"
260 [(set_attr "length" "2,2,4")
261 (set_attr "type" "move")])
263 ;; Insns to load HIGH and LO_SUM
265 (define_insn "movsi_high"
266 [(set (match_operand:SI 0 "register_operand" "=x")
267 (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
270 [(set_attr "type" "mvi")
271 (set_attr "length" "4")])
273 (define_insn "movstricthi_high"
274 [(set (match_operand:SI 0 "register_operand" "+x")
275 (ior:SI (and:SI (match_dup 0) (const_int 65535))
276 (match_operand:SI 1 "immediate_operand" "i")))]
279 [(set_attr "type" "mvi")
280 (set_attr "length" "4")])
282 (define_insn "movsi_low"
283 [(set (match_operand:SI 0 "register_operand" "=x")
284 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
285 (match_operand:SI 2 "immediate_operand" "i")))]
288 [(set_attr "type" "mvi")
289 (set_attr "length" "4")])
291 (define_insn "movsi_high_pic"
292 [(set (match_operand:SI 0 "register_operand" "=x")
293 (high:SI (unspec:SI [(match_operand:SI 1 "" "")]
297 [(set_attr "type" "mvi")
298 (set_attr "length" "4")])
300 (define_insn "movsi_low_pic"
301 [(set (match_operand:SI 0 "register_operand" "=x")
302 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
303 (unspec:SI [(match_operand:SI 2 "" "")]
306 "%h0 = %h2@GOT_HIGH;"
307 [(set_attr "type" "mvi")
308 (set_attr "length" "4")])
310 ;;; Move instructions
312 (define_insn_and_split "movdi_insn"
313 [(set (match_operand:DI 0 "nonimmediate_operand" "=x,mx,r")
314 (match_operand:DI 1 "general_operand" "iFx,r,mx"))]
315 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
318 [(set (match_dup 2) (match_dup 3))
319 (set (match_dup 4) (match_dup 5))]
321 rtx lo_half[2], hi_half[2];
322 split_di (operands, 2, lo_half, hi_half);
324 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
326 operands[2] = hi_half[0];
327 operands[3] = hi_half[1];
328 operands[4] = lo_half[0];
329 operands[5] = lo_half[1];
333 operands[2] = lo_half[0];
334 operands[3] = lo_half[1];
335 operands[4] = hi_half[0];
336 operands[5] = hi_half[1];
341 [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,mr,C,d")
342 (match_operand:BI 1 "general_operand" "x,xKs3,mr,d,d,C"))]
352 [(set_attr "type" "move,mvi,mcld,mcst,compare,compare")
353 (set_attr "length" "2,2,*,*,2,2")])
355 (define_insn "movpdi"
356 [(set (match_operand:PDI 0 "nonimmediate_operand" "=e,<,e")
357 (match_operand:PDI 1 "general_operand" " e,e,>"))]
363 [(set_attr "type" "move,mcst,mcld")])
365 (define_insn "*pushsi_insn"
366 [(set (mem:SI (pre_dec:SI (reg:SI REG_SP)))
367 (match_operand:SI 0 "register_operand" "xy"))]
370 [(set_attr "type" "mcst")
371 (set_attr "length" "2")])
373 (define_insn "*popsi_insn"
374 [(set (match_operand:SI 0 "register_operand" "=xy")
375 (mem:SI (post_inc:SI (reg:SI REG_SP))))]
378 [(set_attr "type" "mcld")
379 (set_attr "length" "2")])
381 ;; The first alternative is used to make reload choose a limited register
382 ;; class when faced with a movsi_insn that had its input operand replaced
383 ;; with a PLUS. We generally require fewer secondary reloads this way.
384 (define_insn "*movsi_insn"
385 [(set (match_operand:SI 0 "nonimmediate_operand" "=da,x*y,da,x,x,x,da,mr")
386 (match_operand:SI 1 "general_operand" "da,x*y,xKs7,xKsh,xKuh,ix,mr,da"))]
388 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
398 [(set_attr "type" "move,move,mvi,mvi,mvi,*,mcld,mcst")
399 (set_attr "length" "2,2,2,4,4,*,*,*")])
401 (define_insn "*movv2hi_insn"
402 [(set (match_operand:V2HI 0 "nonimmediate_operand" "=da,d,m")
403 (match_operand:V2HI 1 "general_operand" "d,m,d"))]
405 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
407 [(set_attr "type" "move,mcld,mcst")
408 (set_attr "length" "2,*,*")])
410 (define_insn "*movhi_insn"
411 [(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr")
412 (match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
413 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
420 [(set_attr "type" "move,mvi,mvi,mcld,mcst")
421 (set_attr "length" "2,2,4,*,*")])
423 (define_insn "*movqi_insn"
424 [(set (match_operand:QI 0 "nonimmediate_operand" "=x,da,x,d,mr")
425 (match_operand:QI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
426 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
433 [(set_attr "type" "move,mvi,mvi,mcld,mcst")
434 (set_attr "length" "2,2,4,*,*")])
436 (define_insn "*movsf_insn"
437 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,da,mr")
438 (match_operand:SF 1 "general_operand" "x,Fx,mr,da"))]
439 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
445 [(set_attr "type" "move,*,mcld,mcst")])
447 (define_insn_and_split "movdf_insn"
448 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,mx,r")
449 (match_operand:DF 1 "general_operand" "iFx,r,mx"))]
450 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
453 [(set (match_dup 2) (match_dup 3))
454 (set (match_dup 4) (match_dup 5))]
456 rtx lo_half[2], hi_half[2];
457 split_di (operands, 2, lo_half, hi_half);
459 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
461 operands[2] = hi_half[0];
462 operands[3] = hi_half[1];
463 operands[4] = lo_half[0];
464 operands[5] = lo_half[1];
468 operands[2] = lo_half[0];
469 operands[3] = lo_half[1];
470 operands[4] = hi_half[0];
471 operands[5] = hi_half[1];
475 ;; This is the main "hook" for PIC code. When generating
476 ;; PIC, movsi is responsible for determining when the source address
477 ;; needs PIC relocation and appropriately calling legitimize_pic_address
478 ;; to perform the actual relocation.
480 (define_expand "movsi"
481 [(set (match_operand:SI 0 "nonimmediate_operand" "")
482 (match_operand:SI 1 "general_operand" ""))]
484 "expand_move (operands, SImode);")
486 (define_expand "movv2hi"
487 [(set (match_operand:V2HI 0 "nonimmediate_operand" "")
488 (match_operand:V2HI 1 "general_operand" ""))]
490 "expand_move (operands, V2HImode);")
492 (define_expand "movdi"
493 [(set (match_operand:DI 0 "nonimmediate_operand" "")
494 (match_operand:DI 1 "general_operand" ""))]
496 "expand_move (operands, DImode);")
498 (define_expand "movsf"
499 [(set (match_operand:SF 0 "nonimmediate_operand" "")
500 (match_operand:SF 1 "general_operand" ""))]
502 "expand_move (operands, SFmode);")
504 (define_expand "movdf"
505 [(set (match_operand:DF 0 "nonimmediate_operand" "")
506 (match_operand:DF 1 "general_operand" ""))]
508 "expand_move (operands, DFmode);")
510 (define_expand "movhi"
511 [(set (match_operand:HI 0 "nonimmediate_operand" "")
512 (match_operand:HI 1 "general_operand" ""))]
514 "expand_move (operands, HImode);")
516 (define_expand "movqi"
517 [(set (match_operand:QI 0 "nonimmediate_operand" "")
518 (match_operand:QI 1 "general_operand" ""))]
520 " expand_move (operands, QImode); ")
522 ;; Some define_splits to break up SI/SFmode loads of immediate constants.
525 [(set (match_operand:SI 0 "register_operand" "")
526 (match_operand:SI 1 "symbolic_or_const_operand" ""))]
528 /* Always split symbolic operands; split integer constants that are
529 too large for a single instruction. */
530 && (GET_CODE (operands[1]) != CONST_INT
531 || (INTVAL (operands[1]) < -32768
532 || INTVAL (operands[1]) >= 65536
533 || (INTVAL (operands[1]) >= 32768 && PREG_P (operands[0]))))"
534 [(set (match_dup 0) (high:SI (match_dup 1)))
535 (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))]
537 if (GET_CODE (operands[1]) == CONST_INT
538 && split_load_immediate (operands))
540 /* ??? Do something about TARGET_LOW_64K. */
544 [(set (match_operand:SF 0 "register_operand" "")
545 (match_operand:SF 1 "immediate_operand" ""))]
547 [(set (match_dup 2) (high:SI (match_dup 3)))
548 (set (match_dup 2) (lo_sum:SI (match_dup 2) (match_dup 3)))]
551 REAL_VALUE_TYPE value;
553 if (GET_CODE (operands[1]) != CONST_DOUBLE)
556 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
557 REAL_VALUE_TO_TARGET_SINGLE (value, values);
559 operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0]));
560 operands[3] = GEN_INT (trunc_int_for_mode (values, SImode));
561 if (values >= -32768 && values < 65536)
563 emit_move_insn (operands[2], operands[3]);
566 if (split_load_immediate (operands + 2))
570 ;; Sadly, this can't be a proper named movstrict pattern, since the compiler
571 ;; expects to be able to use registers for operand 1.
572 ;; Note that the asm instruction is defined by the manual to take an unsigned
573 ;; constant, but it doesn't matter to the assembler, and the compiler only
574 ;; deals with sign-extended constants. Hence "Ksh".
575 (define_insn "*movstricthi"
576 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+x"))
577 (match_operand:HI 1 "immediate_operand" "Ksh"))]
580 [(set_attr "type" "mvi")
581 (set_attr "length" "4")])
583 ;; Sign and zero extensions
585 (define_insn "extendhisi2"
586 [(set (match_operand:SI 0 "register_operand" "=d, d")
587 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
592 [(set_attr "type" "alu0,mcld")])
594 (define_insn "zero_extendhisi2"
595 [(set (match_operand:SI 0 "register_operand" "=d, d")
596 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
601 [(set_attr "type" "alu0,mcld")])
603 (define_insn "zero_extendbisi2"
604 [(set (match_operand:SI 0 "register_operand" "=d")
605 (zero_extend:SI (match_operand:BI 1 "nonimmediate_operand" "C")))]
608 [(set_attr "type" "compare")])
610 (define_insn "extendqihi2"
611 [(set (match_operand:HI 0 "register_operand" "=d, d")
612 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
617 [(set_attr "type" "mcld,alu0")])
619 (define_insn "extendqisi2"
620 [(set (match_operand:SI 0 "register_operand" "=d, d")
621 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
626 [(set_attr "type" "mcld,alu0")])
629 (define_insn "zero_extendqihi2"
630 [(set (match_operand:HI 0 "register_operand" "=d, d")
631 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
636 [(set_attr "type" "mcld,alu0")])
639 (define_insn "zero_extendqisi2"
640 [(set (match_operand:SI 0 "register_operand" "=d, d")
641 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
646 [(set_attr "type" "mcld,alu0")])
648 ;; DImode logical operations
650 (define_code_macro any_logical [and ior xor])
651 (define_code_attr optab [(and "and")
654 (define_code_attr op [(and "&")
657 (define_code_attr high_result [(and "0")
661 (define_insn "<optab>di3"
662 [(set (match_operand:DI 0 "register_operand" "=d")
663 (any_logical:DI (match_operand:DI 1 "register_operand" "0")
664 (match_operand:DI 2 "register_operand" "d")))]
666 "%0 = %1 <op> %2;\\n\\t%H0 = %H1 <op> %H2;"
667 [(set_attr "length" "4")])
669 (define_insn "*<optab>di_zesidi_di"
670 [(set (match_operand:DI 0 "register_operand" "=d")
671 (any_logical:DI (zero_extend:DI
672 (match_operand:SI 2 "register_operand" "d"))
673 (match_operand:DI 1 "register_operand" "d")))]
675 "%0 = %1 <op> %2;\\n\\t%H0 = <high_result>;"
676 [(set_attr "length" "4")])
678 (define_insn "*<optab>di_sesdi_di"
679 [(set (match_operand:DI 0 "register_operand" "=d")
680 (any_logical:DI (sign_extend:DI
681 (match_operand:SI 2 "register_operand" "d"))
682 (match_operand:DI 1 "register_operand" "0")))
683 (clobber (match_scratch:SI 3 "=&d"))]
685 "%0 = %1 <op> %2;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 <op> %3;"
686 [(set_attr "length" "8")])
688 (define_insn "negdi2"
689 [(set (match_operand:DI 0 "register_operand" "=d")
690 (neg:DI (match_operand:DI 1 "register_operand" "d")))
691 (clobber (match_scratch:SI 2 "=&d"))
692 (clobber (reg:CC REG_CC))]
694 "%2 = 0; %2 = %2 - %1; cc = ac0; cc = !cc; %2 = cc;\\n\\t%0 = -%1; %H0 = -%H1; %H0 = %H0 - %2;"
695 [(set_attr "length" "16")])
697 (define_insn "one_cmpldi2"
698 [(set (match_operand:DI 0 "register_operand" "=d")
699 (not:DI (match_operand:DI 1 "register_operand" "d")))]
701 "%0 = ~%1;\\n\\t%H0 = ~%H1;"
702 [(set_attr "length" "4")])
704 ;; DImode zero and sign extend patterns
706 (define_insn_and_split "zero_extendsidi2"
707 [(set (match_operand:DI 0 "register_operand" "=d")
708 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
712 [(set (match_dup 3) (const_int 0))]
714 split_di (operands, 1, operands + 2, operands + 3);
715 if (REGNO (operands[0]) != REGNO (operands[1]))
716 emit_move_insn (operands[2], operands[1]);
719 (define_insn "zero_extendqidi2"
720 [(set (match_operand:DI 0 "register_operand" "=d")
721 (zero_extend:DI (match_operand:QI 1 "register_operand" "d")))]
723 "%0 = %T1 (Z);\\n\\t%H0 = 0;"
724 [(set_attr "length" "4")])
726 (define_insn "zero_extendhidi2"
727 [(set (match_operand:DI 0 "register_operand" "=d")
728 (zero_extend:DI (match_operand:HI 1 "register_operand" "d")))]
730 "%0 = %h1 (Z);\\n\\t%H0 = 0;"
731 [(set_attr "length" "4")])
733 (define_insn_and_split "extendsidi2"
734 [(set (match_operand:DI 0 "register_operand" "=d")
735 (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))]
739 [(set (match_dup 3) (match_dup 1))
740 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
742 split_di (operands, 1, operands + 2, operands + 3);
743 if (REGNO (operands[0]) != REGNO (operands[1]))
744 emit_move_insn (operands[2], operands[1]);
747 (define_insn_and_split "extendqidi2"
748 [(set (match_operand:DI 0 "register_operand" "=d")
749 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
753 [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
754 (set (match_dup 3) (sign_extend:SI (match_dup 1)))
755 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
757 split_di (operands, 1, operands + 2, operands + 3);
760 (define_insn_and_split "extendhidi2"
761 [(set (match_operand:DI 0 "register_operand" "=d")
762 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
766 [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
767 (set (match_dup 3) (sign_extend:SI (match_dup 1)))
768 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
770 split_di (operands, 1, operands + 2, operands + 3);
773 ;; DImode arithmetic operations
775 (define_insn "adddi3"
776 [(set (match_operand:DI 0 "register_operand" "=&d,&d,&d")
777 (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
778 (match_operand:DI 2 "nonmemory_operand" "Kn7,Ks7,d")))
779 (clobber (match_scratch:SI 3 "=&d,&d,&d"))
780 (clobber (reg:CC 34))]
783 %0 += %2; cc = ac0; %3 = cc; %H0 += -1; %H0 = %H0 + %3;
784 %0 += %2; cc = ac0; %3 = cc; %H0 = %H0 + %3;
785 %0 = %0 + %2; cc = ac0; %3 = cc; %H0 = %H0 + %H2; %H0 = %H0 + %3;"
786 [(set_attr "type" "alu0")
787 (set_attr "length" "10,8,10")])
789 (define_insn "subdi3"
790 [(set (match_operand:DI 0 "register_operand" "=&d")
791 (minus:DI (match_operand:DI 1 "register_operand" "0")
792 (match_operand:DI 2 "register_operand" "d")))
793 (clobber (reg:CC 34))]
795 "%0 = %1-%2;\\n\\tcc = ac0;\\n\\t%H0 = %H1-%H2;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
796 [(set_attr "length" "10")])
798 (define_insn "*subdi_di_zesidi"
799 [(set (match_operand:DI 0 "register_operand" "=d")
800 (minus:DI (match_operand:DI 1 "register_operand" "0")
802 (match_operand:SI 2 "register_operand" "d"))))
803 (clobber (match_scratch:SI 3 "=&d"))
804 (clobber (reg:CC 34))]
806 "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%H0 = %H1 - %3;"
807 [(set_attr "length" "10")])
809 (define_insn "*subdi_zesidi_di"
810 [(set (match_operand:DI 0 "register_operand" "=d")
811 (minus:DI (zero_extend:DI
812 (match_operand:SI 2 "register_operand" "d"))
813 (match_operand:DI 1 "register_operand" "0")))
814 (clobber (match_scratch:SI 3 "=&d"))
815 (clobber (reg:CC 34))]
817 "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%3 = -%3;\\n\\t%H0 = %3 - %H1"
818 [(set_attr "length" "12")])
820 (define_insn "*subdi_di_sesidi"
821 [(set (match_operand:DI 0 "register_operand" "=d")
822 (minus:DI (match_operand:DI 1 "register_operand" "0")
824 (match_operand:SI 2 "register_operand" "d"))))
825 (clobber (match_scratch:SI 3 "=&d"))
826 (clobber (reg:CC 34))]
828 "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 - %3;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
829 [(set_attr "length" "14")])
831 (define_insn "*subdi_sesidi_di"
832 [(set (match_operand:DI 0 "register_operand" "=d")
833 (minus:DI (sign_extend:DI
834 (match_operand:SI 2 "register_operand" "d"))
835 (match_operand:DI 1 "register_operand" "0")))
836 (clobber (match_scratch:SI 3 "=&d"))
837 (clobber (reg:CC 34))]
839 "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %3 - %H1;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
840 [(set_attr "length" "14")])
842 ;; Combined shift/add instructions
845 [(set (match_operand:SI 0 "register_operand" "=a,d")
846 (ashift:SI (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
847 (match_operand:SI 2 "register_operand" "a,d"))
848 (match_operand:SI 3 "pos_scale_operand" "P1P2,P1P2")))]
850 "%0 = (%0 + %2) << %3;" /* "shadd %0,%2,%3;" */
851 [(set_attr "type" "alu0")])
854 [(set (match_operand:SI 0 "register_operand" "=a")
855 (plus:SI (match_operand:SI 1 "register_operand" "a")
856 (mult:SI (match_operand:SI 2 "register_operand" "a")
857 (match_operand:SI 3 "scale_by_operand" "i"))))]
859 "%0 = %1 + (%2 << %X3);"
860 [(set_attr "type" "alu0")])
863 [(set (match_operand:SI 0 "register_operand" "=a")
864 (plus:SI (match_operand:SI 1 "register_operand" "a")
865 (ashift:SI (match_operand:SI 2 "register_operand" "a")
866 (match_operand:SI 3 "pos_scale_operand" "i"))))]
868 "%0 = %1 + (%2 << %3);"
869 [(set_attr "type" "alu0")])
872 [(set (match_operand:SI 0 "register_operand" "=a")
873 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "a")
874 (match_operand:SI 2 "scale_by_operand" "i"))
875 (match_operand:SI 3 "register_operand" "a")))]
877 "%0 = %3 + (%1 << %X2);"
878 [(set_attr "type" "alu0")])
881 [(set (match_operand:SI 0 "register_operand" "=a")
882 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "a")
883 (match_operand:SI 2 "pos_scale_operand" "i"))
884 (match_operand:SI 3 "register_operand" "a")))]
886 "%0 = %3 + (%1 << %2);"
887 [(set_attr "type" "alu0")])
889 (define_insn "mulhisi3"
890 [(set (match_operand:SI 0 "register_operand" "=d")
891 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%d"))
892 (sign_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
894 "%0 = %h1 * %h2 (IS);"
895 [(set_attr "type" "dsp32")])
897 (define_insn "umulhisi3"
898 [(set (match_operand:SI 0 "register_operand" "=d")
899 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%d"))
900 (zero_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
902 "%0 = %h1 * %h2 (FU);"
903 [(set_attr "type" "dsp32")])
905 ;; The processor also supports ireg += mreg or ireg -= mreg, but these
906 ;; are unusable if we don't ensure that the corresponding lreg is zero.
907 ;; The same applies to the add/subtract constant versions involving
910 (define_insn "addsi3"
911 [(set (match_operand:SI 0 "register_operand" "=ad,a,d")
912 (plus:SI (match_operand:SI 1 "register_operand" "%0, a,d")
913 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7, a,d")))]
919 [(set_attr "type" "alu0")
920 (set_attr "length" "2,2,2")])
922 (define_expand "subsi3"
923 [(set (match_operand:SI 0 "register_operand" "")
924 (minus:SI (match_operand:SI 1 "register_operand" "")
925 (match_operand:SI 2 "reg_or_7bit_operand" "")))]
930 [(set (match_operand:SI 0 "register_operand" "=da,d,a")
931 (minus:SI (match_operand:SI 1 "register_operand" "0,d,0")
932 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7,d,a")))]
933 "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -64"
935 static const char *const strings_subsi3[] = {
941 if (CONSTANT_P (operands[2]) && INTVAL (operands[2]) < 0) {
942 rtx tmp_op = operands[2];
943 operands[2] = GEN_INT (-INTVAL (operands[2]));
944 output_asm_insn ("%0 += %2;", operands);
945 operands[2] = tmp_op;
949 return strings_subsi3[which_alternative];
951 [(set_attr "type" "alu0")])
953 ;; Bit test instructions
955 (define_insn "*not_bittst"
956 [(set (match_operand:BI 0 "cc_operand" "=C")
957 (eq:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
959 (match_operand:SI 2 "immediate_operand" "Ku5"))
962 "cc = !BITTST (%1,%2);"
963 [(set_attr "type" "alu0")])
965 (define_insn "*bittst"
966 [(set (match_operand:BI 0 "cc_operand" "=C")
967 (ne:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
969 (match_operand:SI 2 "immediate_operand" "Ku5"))
972 "cc = BITTST (%1,%2);"
973 [(set_attr "type" "alu0")])
975 (define_insn_and_split "*bit_extract"
976 [(set (match_operand:SI 0 "register_operand" "=d")
977 (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
979 (match_operand:SI 2 "immediate_operand" "Ku5")))
980 (clobber (reg:BI REG_CC))]
984 [(set (reg:BI REG_CC)
985 (ne:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
988 (ne:SI (reg:BI REG_CC) (const_int 0)))])
990 (define_insn_and_split "*not_bit_extract"
991 [(set (match_operand:SI 0 "register_operand" "=d")
992 (zero_extract:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
994 (match_operand:SI 2 "immediate_operand" "Ku5")))
995 (clobber (reg:BI REG_CC))]
999 [(set (reg:BI REG_CC)
1000 (eq:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1003 (ne:SI (reg:BI REG_CC) (const_int 0)))])
1005 (define_insn "*andsi_insn"
1006 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
1007 (and:SI (match_operand:SI 1 "register_operand" "%0,d,d,d")
1008 (match_operand:SI 2 "rhs_andsi3_operand" "L,M1,M2,d")))]
1015 [(set_attr "type" "alu0")])
1017 (define_expand "andsi3"
1018 [(set (match_operand:SI 0 "register_operand" "")
1019 (and:SI (match_operand:SI 1 "register_operand" "")
1020 (match_operand:SI 2 "general_operand" "")))]
1023 if (highbits_operand (operands[2], SImode))
1025 operands[2] = GEN_INT (exact_log2 (-INTVAL (operands[2])));
1026 emit_insn (gen_ashrsi3 (operands[0], operands[1], operands[2]));
1027 emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
1030 if (! rhs_andsi3_operand (operands[2], SImode))
1031 operands[2] = force_reg (SImode, operands[2]);
1034 (define_insn "iorsi3"
1035 [(set (match_operand:SI 0 "register_operand" "=d,d")
1036 (ior:SI (match_operand:SI 1 "register_operand" "%0,d")
1037 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1042 [(set_attr "type" "alu0")])
1044 (define_insn "xorsi3"
1045 [(set (match_operand:SI 0 "register_operand" "=d,d")
1046 (xor:SI (match_operand:SI 1 "register_operand" "%0,d")
1047 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1052 [(set_attr "type" "alu0")])
1054 (define_insn "smaxsi3"
1055 [(set (match_operand:SI 0 "register_operand" "=d")
1056 (smax:SI (match_operand:SI 1 "register_operand" "d")
1057 (match_operand:SI 2 "register_operand" "d")))]
1060 [(set_attr "type" "dsp32")])
1062 (define_insn "sminsi3"
1063 [(set (match_operand:SI 0 "register_operand" "=d")
1064 (smin:SI (match_operand:SI 1 "register_operand" "d")
1065 (match_operand:SI 2 "register_operand" "d")))]
1068 [(set_attr "type" "dsp32")])
1070 (define_insn "abssi2"
1071 [(set (match_operand:SI 0 "register_operand" "=d")
1072 (abs:SI (match_operand:SI 1 "register_operand" " d")))]
1075 [(set_attr "type" "dsp32")])
1078 (define_insn "negsi2"
1079 [(set (match_operand:SI 0 "register_operand" "=d")
1080 (neg:SI (match_operand:SI 1 "register_operand" " d")))]
1083 [(set_attr "type" "alu0")])
1085 (define_insn "one_cmplsi2"
1086 [(set (match_operand:SI 0 "register_operand" "=d")
1087 (not:SI (match_operand:SI 1 "register_operand" " d")))]
1090 [(set_attr "type" "alu0")])
1092 (define_insn "mulsi3"
1093 [(set (match_operand:SI 0 "register_operand" "=d")
1094 (mult:SI (match_operand:SI 1 "register_operand" "%0")
1095 (match_operand:SI 2 "register_operand" "d")))]
1098 [(set_attr "type" "mult")])
1100 (define_expand "ashlsi3"
1101 [(set (match_operand:SI 0 "register_operand" "")
1102 (ashift:SI (match_operand:SI 1 "register_operand" "")
1103 (match_operand:SI 2 "nonmemory_operand" "")))]
1106 if (GET_CODE (operands[2]) == CONST_INT
1107 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1109 emit_insn (gen_movsi (operands[0], const0_rtx));
1114 (define_insn_and_split "*ashlsi3_insn"
1115 [(set (match_operand:SI 0 "register_operand" "=d,a,a,a")
1116 (ashift:SI (match_operand:SI 1 "register_operand" "0,a,a,a")
1117 (match_operand:SI 2 "nonmemory_operand" "dKu5,P1,P2,?P3P4")))]
1124 "PREG_P (operands[0]) && INTVAL (operands[2]) > 2"
1125 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
1126 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
1127 "operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
1128 [(set_attr "type" "shft")])
1130 (define_insn "ashrsi3"
1131 [(set (match_operand:SI 0 "register_operand" "=d")
1132 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1133 (match_operand:SI 2 "nonmemory_operand" "dKu5")))]
1136 [(set_attr "type" "shft")])
1138 (define_insn "lshrsi3"
1139 [(set (match_operand:SI 0 "register_operand" "=d,a")
1140 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0,a")
1141 (match_operand:SI 2 "nonmemory_operand" "dKu5,P1P2")))]
1146 [(set_attr "type" "shft")])
1148 ;; A pattern to reload the equivalent of
1149 ;; (set (Dreg) (plus (FP) (large_constant)))
1151 ;; (set (dagreg) (plus (FP) (arbitrary_constant)))
1152 ;; using a scratch register
1153 (define_expand "reload_insi"
1154 [(parallel [(set (match_operand:SI 0 "register_operand" "=w")
1155 (match_operand:SI 1 "fp_plus_const_operand" ""))
1156 (clobber (match_operand:SI 2 "register_operand" "=&a"))])]
1159 rtx fp_op = XEXP (operands[1], 0);
1160 rtx const_op = XEXP (operands[1], 1);
1161 rtx primary = operands[0];
1162 rtx scratch = operands[2];
1164 emit_move_insn (scratch, const_op);
1165 emit_insn (gen_addsi3 (scratch, scratch, fp_op));
1166 emit_move_insn (primary, scratch);
1170 ;; Jump instructions
1174 (label_ref (match_operand 0 "" "")))]
1177 if (get_attr_length (insn) == 2)
1178 return "jump.s %0;";
1180 return "jump.l %0;";
1182 [(set_attr "type" "br")])
1184 (define_insn "indirect_jump"
1186 (match_operand:SI 0 "register_operand" "a"))]
1189 [(set_attr "type" "misc")])
1191 (define_expand "tablejump"
1192 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1193 (use (label_ref (match_operand 1 "" "")))])]
1196 /* In PIC mode, the table entries are stored PC relative.
1197 Convert the relative address to an absolute address. */
1200 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1202 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1203 op1, NULL_RTX, 0, OPTAB_DIRECT);
1207 (define_insn "*tablejump_internal"
1208 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1209 (use (label_ref (match_operand 1 "" "")))]
1212 [(set_attr "type" "misc")])
1214 ;; Call instructions..
1216 (define_expand "call"
1217 [(call (match_operand:SI 0 "" "")
1218 (match_operand 1 "" ""))]
1220 "bfin_expand_call (NULL_RTX, operands[0], operands[1], 0); DONE;")
1222 (define_expand "sibcall"
1223 [(parallel [(call (match_operand:SI 0 "" "")
1224 (match_operand 1 "" ""))
1227 "bfin_expand_call (NULL_RTX, operands[0], operands[1], 1); DONE;")
1229 (define_expand "call_value"
1230 [(set (match_operand 0 "register_operand" "")
1231 (call (match_operand:SI 1 "" "")
1232 (match_operand 2 "" "")))]
1234 "bfin_expand_call (operands[0], operands[1], operands[2], 0); DONE;")
1236 (define_expand "sibcall_value"
1237 [(parallel [(set (match_operand 0 "register_operand" "")
1238 (call (match_operand:SI 1 "" "")
1239 (match_operand 2 "" "")))
1242 "bfin_expand_call (operands[0], operands[1], operands[2], 1); DONE;")
1244 (define_insn "*call_insn"
1245 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "a,Q"))
1246 (match_operand 1 "general_operand" "g,g"))]
1247 "! SIBLING_CALL_P (insn)
1248 && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
1252 [(set_attr "type" "call")
1253 (set_attr "length" "2,4")])
1255 (define_insn "*sibcall_insn"
1256 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "z,Q"))
1257 (match_operand 1 "general_operand" "g,g"))
1259 "SIBLING_CALL_P (insn)
1260 && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
1264 [(set_attr "type" "br")
1265 (set_attr "length" "2,4")])
1267 (define_insn "*call_value_insn"
1268 [(set (match_operand 0 "register_operand" "=d,d")
1269 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "a,Q"))
1270 (match_operand 2 "general_operand" "g,g")))]
1271 "! SIBLING_CALL_P (insn)
1272 && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
1276 [(set_attr "type" "call")
1277 (set_attr "length" "2,4")])
1279 (define_insn "*sibcall_value_insn"
1280 [(set (match_operand 0 "register_operand" "=d,d")
1281 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "z,Q"))
1282 (match_operand 2 "general_operand" "g,g")))
1284 "SIBLING_CALL_P (insn)
1285 && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
1289 [(set_attr "type" "br")
1290 (set_attr "length" "2,4")])
1292 ;; Block move patterns
1294 ;; We cheat. This copies one more word than operand 2 indicates.
1296 (define_insn "rep_movsi"
1297 [(set (match_operand:SI 0 "register_operand" "=&a")
1298 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1299 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1302 (set (match_operand:SI 1 "register_operand" "=&b")
1303 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1304 (ashift:SI (match_dup 2) (const_int 2)))
1306 (set (mem:BLK (match_dup 3))
1307 (mem:BLK (match_dup 4)))
1309 (clobber (match_scratch:HI 5 "=&d"))]
1311 "lsetup (1f, 1f) LC1 = %2; %5 = [%4++]; 1: MNOP || [%3++] = %5 || %5 = [%4++]; [%3++] = %5;"
1312 [(set_attr "type" "misc")
1313 (set_attr "length" "16")])
1315 (define_insn "rep_movhi"
1316 [(set (match_operand:SI 0 "register_operand" "=&a")
1317 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1318 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1321 (set (match_operand:SI 1 "register_operand" "=&b")
1322 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1323 (ashift:SI (match_dup 2) (const_int 1)))
1325 (set (mem:BLK (match_dup 3))
1326 (mem:BLK (match_dup 4)))
1328 (clobber (match_scratch:HI 5 "=&d"))]
1330 "lsetup (1f, 1f) LC1 = %2; %h5 = W[%4++]; 1: MNOP || W [%3++] = %5 || %h5 = W [%4++]; W [%3++] = %5;"
1331 [(set_attr "type" "misc")
1332 (set_attr "length" "16")])
1334 (define_expand "movstrsi"
1335 [(match_operand:BLK 0 "general_operand" "")
1336 (match_operand:BLK 1 "general_operand" "")
1337 (match_operand:SI 2 "const_int_operand" "")
1338 (match_operand:SI 3 "const_int_operand" "")]
1341 if (bfin_expand_strmov (operands[0], operands[1], operands[2], operands[3]))
1346 ;; Conditional branch patterns
1347 ;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
1349 ;; The only outcome of this pattern is that global variables
1350 ;; bfin_compare_op[01] are set for use in bcond patterns.
1352 (define_expand "cmpbi"
1353 [(set (cc0) (compare (match_operand:BI 0 "register_operand" "")
1354 (match_operand:BI 1 "immediate_operand" "")))]
1357 bfin_compare_op0 = operands[0];
1358 bfin_compare_op1 = operands[1];
1362 (define_expand "cmpsi"
1363 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
1364 (match_operand:SI 1 "nonmemory_operand" "")))]
1367 bfin_compare_op0 = operands[0];
1368 bfin_compare_op1 = operands[1];
1373 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1374 (eq:BI (match_operand:SI 1 "register_operand" "d,a")
1375 (match_operand:SI 2 "nonmemory_operand" "dKs3,aKs3")))]
1378 [(set_attr "type" "compare")])
1381 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1382 (ne:BI (match_operand:SI 1 "register_operand" "d,a")
1383 (match_operand:SI 2 "nonmemory_operand" "dKs3,aKs3")))]
1386 [(set_attr "type" "compare")])
1389 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1390 (lt:BI (match_operand:SI 1 "register_operand" "d,a")
1391 (match_operand:SI 2 "nonmemory_operand" "dKs3,aKs3")))]
1394 [(set_attr "type" "compare")])
1397 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1398 (le:BI (match_operand:SI 1 "register_operand" "d,a")
1399 (match_operand:SI 2 "nonmemory_operand" "dKs3,aKs3")))]
1402 [(set_attr "type" "compare")])
1405 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1406 (leu:BI (match_operand:SI 1 "register_operand" "d,a")
1407 (match_operand:SI 2 "nonmemory_operand" "dKu3,aKu3")))]
1410 [(set_attr "type" "compare")])
1413 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1414 (ltu:BI (match_operand:SI 1 "register_operand" "d,a")
1415 (match_operand:SI 2 "nonmemory_operand" "dKu3,aKu3")))]
1418 [(set_attr "type" "compare")])
1420 (define_expand "beq"
1421 [(set (match_dup 1) (match_dup 2))
1423 (if_then_else (match_dup 3)
1424 (label_ref (match_operand 0 "" ""))
1428 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1429 operands[1] = bfin_cc_rtx; /* hard register: CC */
1430 operands[2] = gen_rtx_EQ (BImode, op0, op1);
1431 /* If we have a BImode input, then we already have a compare result, and
1432 do not need to emit another comparison. */
1433 if (GET_MODE (bfin_compare_op0) == BImode)
1435 if (bfin_compare_op1 == const0_rtx)
1437 emit_insn (gen_cbranchbi4 (operands[2], op0, op1,
1445 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1448 (define_expand "bne"
1449 [(set (match_dup 1) (match_dup 2))
1451 (if_then_else (match_dup 3)
1452 (label_ref (match_operand 0 "" ""))
1456 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1457 /* If we have a BImode input, then we already have a compare result, and
1458 do not need to emit another comparison. */
1459 if (GET_MODE (bfin_compare_op0) == BImode)
1461 if (bfin_compare_op1 == const0_rtx)
1463 rtx cmp = gen_rtx_NE (BImode, op0, op1);
1464 emit_insn (gen_cbranchbi4 (cmp, op0, op1, operands[0]));
1471 operands[1] = bfin_cc_rtx; /* hard register: CC */
1472 operands[2] = gen_rtx_EQ (BImode, op0, op1);
1473 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1476 (define_expand "bgt"
1477 [(set (match_dup 1) (match_dup 2))
1479 (if_then_else (match_dup 3)
1480 (label_ref (match_operand 0 "" ""))
1484 operands[1] = bfin_cc_rtx;
1485 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1486 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1489 (define_expand "bgtu"
1490 [(set (match_dup 1) (match_dup 2))
1492 (if_then_else (match_dup 3)
1493 (label_ref (match_operand 0 "" ""))
1497 operands[1] = bfin_cc_rtx;
1498 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1499 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1502 (define_expand "blt"
1503 [(set (match_dup 1) (match_dup 2))
1505 (if_then_else (match_dup 3)
1506 (label_ref (match_operand 0 "" ""))
1510 operands[1] = bfin_cc_rtx;
1511 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1512 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1515 (define_expand "bltu"
1516 [(set (match_dup 1) (match_dup 2))
1518 (if_then_else (match_dup 3)
1519 (label_ref (match_operand 0 "" ""))
1523 operands[1] = bfin_cc_rtx;
1524 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1525 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1529 (define_expand "bge"
1530 [(set (match_dup 1) (match_dup 2))
1532 (if_then_else (match_dup 3)
1533 (label_ref (match_operand 0 "" ""))
1537 operands[1] = bfin_cc_rtx;
1538 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1539 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1542 (define_expand "bgeu"
1543 [(set (match_dup 1) (match_dup 2))
1545 (if_then_else (match_dup 3)
1546 (label_ref (match_operand 0 "" ""))
1550 operands[1] = bfin_cc_rtx;
1551 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1552 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1555 (define_expand "ble"
1556 [(set (match_dup 1) (match_dup 2))
1558 (if_then_else (match_dup 3)
1559 (label_ref (match_operand 0 "" ""))
1563 operands[1] = bfin_cc_rtx;
1564 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1565 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1568 (define_expand "bleu"
1569 [(set (match_dup 1) (match_dup 2))
1571 (if_then_else (match_dup 3)
1572 (label_ref (match_operand 0 "" ""))
1577 operands[1] = bfin_cc_rtx;
1578 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1579 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1582 (define_insn "cbranchbi4"
1585 (match_operator 0 "bfin_cbranch_operator"
1586 [(match_operand:BI 1 "cc_operand" "C")
1587 (match_operand:BI 2 "immediate_operand" "P0")])
1588 (label_ref (match_operand 3 "" ""))
1592 asm_conditional_branch (insn, operands, 0, 0);
1595 [(set_attr "type" "brcc")])
1597 ;; Special cbranch patterns to deal with the speculative load problem - see
1598 ;; bfin_reorg for details.
1600 (define_insn "cbranch_predicted_taken"
1603 (match_operator 0 "bfin_cbranch_operator"
1604 [(match_operand:BI 1 "cc_operand" "C")
1605 (match_operand:BI 2 "immediate_operand" "P0")])
1606 (label_ref (match_operand 3 "" ""))
1608 (unspec [(const_int 0)] UNSPEC_CBRANCH_TAKEN)]
1611 asm_conditional_branch (insn, operands, 0, 1);
1614 [(set_attr "type" "brcc")])
1616 (define_insn "cbranch_with_nops"
1619 (match_operator 0 "bfin_cbranch_operator"
1620 [(match_operand:BI 1 "cc_operand" "C")
1621 (match_operand:BI 2 "immediate_operand" "P0")])
1622 (label_ref (match_operand 3 "" ""))
1624 (unspec [(match_operand 4 "immediate_operand" "")] UNSPEC_CBRANCH_NOPS)]
1627 asm_conditional_branch (insn, operands, INTVAL (operands[4]), 0);
1630 [(set_attr "type" "brcc")
1631 (set_attr "length" "6")])
1634 (define_expand "seq"
1635 [(set (match_dup 1) (eq:BI (match_dup 2) (match_dup 3)))
1636 (set (match_operand:SI 0 "register_operand" "")
1637 (ne:SI (match_dup 1) (const_int 0)))]
1640 operands[2] = bfin_compare_op0;
1641 operands[3] = bfin_compare_op1;
1642 operands[1] = bfin_cc_rtx;
1645 (define_expand "slt"
1646 [(set (match_dup 1) (lt:BI (match_dup 2) (match_dup 3)))
1647 (set (match_operand:SI 0 "register_operand" "")
1648 (ne:SI (match_dup 1) (const_int 0)))]
1651 operands[2] = bfin_compare_op0;
1652 operands[3] = bfin_compare_op1;
1653 operands[1] = bfin_cc_rtx;
1656 (define_expand "sle"
1657 [(set (match_dup 1) (le:BI (match_dup 2) (match_dup 3)))
1658 (set (match_operand:SI 0 "register_operand" "")
1659 (ne:SI (match_dup 1) (const_int 0)))]
1662 operands[2] = bfin_compare_op0;
1663 operands[3] = bfin_compare_op1;
1664 operands[1] = bfin_cc_rtx;
1667 (define_expand "sltu"
1668 [(set (match_dup 1) (ltu:BI (match_dup 2) (match_dup 3)))
1669 (set (match_operand:SI 0 "register_operand" "")
1670 (ne:SI (match_dup 1) (const_int 0)))]
1673 operands[2] = bfin_compare_op0;
1674 operands[3] = bfin_compare_op1;
1675 operands[1] = bfin_cc_rtx;
1678 (define_expand "sleu"
1679 [(set (match_dup 1) (leu:BI (match_dup 2) (match_dup 3)))
1680 (set (match_operand:SI 0 "register_operand" "")
1681 (ne:SI (match_dup 1) (const_int 0)))]
1684 operands[2] = bfin_compare_op0;
1685 operands[3] = bfin_compare_op1;
1686 operands[1] = bfin_cc_rtx;
1694 ;;;;;;;;;;;;;;;;;;;; CC2dreg ;;;;;;;;;;;;;;;;;;;;;;;;;
1695 (define_insn "movsibi"
1696 [(set (match_operand:BI 0 "cc_operand" "=C")
1697 (ne:BI (match_operand:SI 1 "register_operand" "d")
1701 [(set_attr "length" "2")])
1703 (define_insn "movbisi"
1704 [(set (match_operand:SI 0 "register_operand" "=d")
1705 (ne:SI (match_operand:BI 1 "cc_operand" "C")
1709 [(set_attr "length" "2")])
1712 [(set (match_operand:BI 0 "cc_operand" "=C")
1713 (eq:BI (match_operand:BI 1 "cc_operand" " 0")
1716 "%0 = ! %0;" /* NOT CC;" */
1717 [(set_attr "type" "compare")])
1719 ;; Vector and DSP insns
1722 [(set (match_operand:SI 0 "register_operand" "=d")
1723 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1725 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1728 "%0 = ALIGN8(%1, %2);"
1729 [(set_attr "type" "dsp32")])
1732 [(set (match_operand:SI 0 "register_operand" "=d")
1733 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1735 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1738 "%0 = ALIGN16(%1, %2);"
1739 [(set_attr "type" "dsp32")])
1742 [(set (match_operand:SI 0 "register_operand" "=d")
1743 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1745 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1748 "%0 = ALIGN24(%1, %2);"
1749 [(set_attr "type" "dsp32")])
1751 ;; Prologue and epilogue.
1753 (define_expand "prologue"
1756 "bfin_expand_prologue (); DONE;")
1758 (define_expand "epilogue"
1761 "bfin_expand_epilogue (1, 0); DONE;")
1763 (define_expand "sibcall_epilogue"
1766 "bfin_expand_epilogue (0, 0); DONE;")
1768 (define_expand "eh_return"
1769 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")]
1770 UNSPEC_VOLATILE_EH_RETURN)]
1773 emit_move_insn (EH_RETURN_HANDLER_RTX, operands[0]);
1774 emit_insn (gen_eh_return_internal ());
1778 (define_insn_and_split "eh_return_internal"
1779 [(unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN)]
1784 "bfin_expand_epilogue (1, 1); DONE;")
1787 [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS))
1788 (set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:SI REG_FP))
1789 (set (reg:SI REG_FP)
1790 (plus:SI (reg:SI REG_SP) (const_int -8)))
1791 (set (reg:SI REG_SP)
1792 (plus:SI (reg:SI REG_SP) (match_operand:SI 0 "immediate_operand" "i")))]
1795 [(set_attr "length" "4")])
1797 (define_insn "unlink"
1798 [(set (reg:SI REG_FP) (mem:SI (reg:SI REG_FP)))
1799 (set (reg:SI REG_RETS) (mem:SI (plus:SI (reg:SI REG_FP) (const_int 4))))
1800 (set (reg:SI REG_SP) (plus:SI (reg:SI REG_FP) (const_int 8)))]
1803 [(set_attr "length" "4")])
1805 ;; This pattern is slightly clumsy. The stack adjust must be the final SET in
1806 ;; the pattern, otherwise dwarf2out becomes very confused about which reg goes
1807 ;; where on the stack, since it goes through all elements of the parallel in
1809 (define_insn "push_multiple"
1810 [(match_parallel 0 "push_multiple_operation"
1811 [(unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_PUSH_MULTIPLE)])]
1814 output_push_multiple (insn, operands);
1818 (define_insn "pop_multiple"
1819 [(match_parallel 0 "pop_multiple_operation"
1820 [(set (reg:SI REG_SP)
1821 (plus:SI (reg:SI REG_SP) (match_operand:SI 1 "immediate_operand" "i")))])]
1824 output_pop_multiple (insn, operands);
1828 (define_insn "return_internal"
1830 (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)]
1833 switch (INTVAL (operands[0]))
1839 case INTERRUPT_HANDLER:
1847 ;;; Vector instructions
1849 (define_insn "addv2hi"
1850 [(set (match_operand:V2HI 0 "register_operand" "=d")
1851 (plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
1852 (match_operand:V2HI 2 "register_operand" "d")))]
1855 [(set_attr "type" "dsp32")])
1857 (define_insn "subv2hi"
1858 [(set (match_operand:V2HI 0 "register_operand" "=d")
1859 (minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
1860 (match_operand:V2HI 2 "register_operand" "d")))]
1863 [(set_attr "type" "dsp32")])
1865 (define_insn "sminv2hi"
1866 [(set (match_operand:V2HI 0 "register_operand" "=d")
1867 (smin:V2HI (match_operand:V2HI 1 "register_operand" "d")
1868 (match_operand:V2HI 2 "register_operand" "d")))]
1870 "%0 = MIN (%1, %2) (V);"
1871 [(set_attr "type" "dsp32")])
1873 (define_insn "smaxv2hi"
1874 [(set (match_operand:V2HI 0 "register_operand" "=d")
1875 (smax:V2HI (match_operand:V2HI 1 "register_operand" "d")
1876 (match_operand:V2HI 2 "register_operand" "d")))]
1878 "%0 = MAX (%1, %2) (V);"
1879 [(set_attr "type" "dsp32")])
1881 (define_insn "mulv2hi"
1882 [(set (match_operand:V2HI 0 "register_operand" "=d")
1883 (mult:V2HI (match_operand:V2HI 1 "register_operand" "d")
1884 (match_operand:V2HI 2 "register_operand" "d")))]
1886 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 (IS);"
1887 [(set_attr "type" "dsp32")])
1889 (define_insn "negv2hi"
1890 [(set (match_operand:V2HI 0 "register_operand" "=d")
1891 (neg:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
1894 [(set_attr "type" "dsp32")])
1896 (define_insn "absv2hi"
1897 [(set (match_operand:V2HI 0 "register_operand" "=d")
1898 (abs:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
1901 [(set_attr "type" "dsp32")])