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)
124 (UNSPEC_VOLATILE_CSYNC 1)
125 (UNSPEC_VOLATILE_SSYNC 2)])
128 "move,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,compare,dummy"
129 (const_string "misc"))
131 ;; Scheduling definitions
133 (define_automaton "bfin")
135 (define_cpu_unit "core" "bfin")
137 (define_insn_reservation "alu" 1
138 (eq_attr "type" "move,mvi,mcst,dsp32,alu0,shft,brcc,br,call,misc,compare")
141 (define_insn_reservation "imul" 3
142 (eq_attr "type" "mult")
145 (define_insn_reservation "load" 1
146 (eq_attr "type" "mcld")
149 ;; Make sure genautomata knows about the maximum latency that can be produced
150 ;; by the adjust_cost function.
151 (define_insn_reservation "dummy" 5
152 (eq_attr "type" "mcld")
155 ;; Operand and operator predicates
157 (include "predicates.md")
160 ;;; FRIO branches have been optimized for code density
161 ;;; this comes at a slight cost of complexity when
162 ;;; a compiler needs to generate branches in the general
163 ;;; case. In order to generate the correct branching
164 ;;; mechanisms the compiler needs keep track of instruction
165 ;;; lengths. The follow table describes how to count instructions
166 ;;; for the FRIO architecture.
168 ;;; unconditional br are 12-bit imm pcrelative branches *2
169 ;;; conditional br are 10-bit imm pcrelative branches *2
171 ;;; 1024 10-bit imm *2 is 2048 (-1024..1022)
173 ;;; 4096 12-bit imm *2 is 8192 (-4096..4094)
174 ;;; NOTE : For brcc we generate instructions such as
175 ;;; if cc jmp; jump.[sl] offset
176 ;;; offset of jump.[sl] is from the jump instruction but
177 ;;; gcc calculates length from the if cc jmp instruction
178 ;;; furthermore gcc takes the end address of the branch instruction
179 ;;; as (pc) for a forward branch
180 ;;; hence our range is (-4094, 4092) instead of (-4096, 4094) for a br
182 ;;; The way the (pc) rtx works in these calculations is somewhat odd;
183 ;;; for backward branches it's the address of the current instruction,
184 ;;; for forward branches it's the previously known address of the following
185 ;;; instruction - we have to take this into account by reducing the range
186 ;;; for a forward branch.
188 ;; Lengths for type "mvi" insns are always defined by the instructions
190 (define_attr "length" ""
191 (cond [(eq_attr "type" "mcld")
192 (if_then_else (match_operand 1 "effective_address_32bit_p" "")
193 (const_int 4) (const_int 2))
195 (eq_attr "type" "mcst")
196 (if_then_else (match_operand 0 "effective_address_32bit_p" "")
197 (const_int 4) (const_int 2))
199 (eq_attr "type" "move") (const_int 2)
201 (eq_attr "type" "dsp32") (const_int 4)
202 (eq_attr "type" "call") (const_int 4)
204 (eq_attr "type" "br")
206 (le (minus (match_dup 0) (pc)) (const_int 4092))
207 (ge (minus (match_dup 0) (pc)) (const_int -4096)))
211 (eq_attr "type" "brcc")
213 (le (minus (match_dup 3) (pc)) (const_int 1020))
214 (ge (minus (match_dup 3) (pc)) (const_int -1024)))
217 (le (minus (match_dup 3) (pc)) (const_int 4092))
218 (ge (minus (match_dup 3) (pc)) (const_int -4094)))
227 (define_expand "movsicc"
228 [(set (match_operand:SI 0 "register_operand" "")
229 (if_then_else:SI (match_operand 1 "comparison_operator" "")
230 (match_operand:SI 2 "register_operand" "")
231 (match_operand:SI 3 "register_operand" "")))]
234 operands[1] = bfin_gen_compare (operands[1], SImode);
237 (define_insn "*movsicc_insn1"
238 [(set (match_operand:SI 0 "register_operand" "=da,da,da")
240 (eq:BI (match_operand:BI 3 "cc_operand" "C,C,C")
242 (match_operand:SI 1 "register_operand" "da,0,da")
243 (match_operand:SI 2 "register_operand" "0,da,da")))]
246 if !cc %0 =%1; /* movsicc-1a */
247 if cc %0 =%2; /* movsicc-1b */
248 if !cc %0 =%1; if cc %0=%2; /* movsicc-1 */"
249 [(set_attr "length" "2,2,4")
250 (set_attr "type" "move")])
252 (define_insn "*movsicc_insn2"
253 [(set (match_operand:SI 0 "register_operand" "=da,da,da")
255 (ne:BI (match_operand:BI 3 "cc_operand" "C,C,C")
257 (match_operand:SI 1 "register_operand" "0,da,da")
258 (match_operand:SI 2 "register_operand" "da,0,da")))]
261 if !cc %0 =%2; /* movsicc-2b */
262 if cc %0 =%1; /* movsicc-2a */
263 if cc %0 =%1; if !cc %0=%2; /* movsicc-1 */"
264 [(set_attr "length" "2,2,4")
265 (set_attr "type" "move")])
267 ;; Insns to load HIGH and LO_SUM
269 (define_insn "movsi_high"
270 [(set (match_operand:SI 0 "register_operand" "=x")
271 (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
274 [(set_attr "type" "mvi")
275 (set_attr "length" "4")])
277 (define_insn "movstricthi_high"
278 [(set (match_operand:SI 0 "register_operand" "+x")
279 (ior:SI (and:SI (match_dup 0) (const_int 65535))
280 (match_operand:SI 1 "immediate_operand" "i")))]
283 [(set_attr "type" "mvi")
284 (set_attr "length" "4")])
286 (define_insn "movsi_low"
287 [(set (match_operand:SI 0 "register_operand" "=x")
288 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
289 (match_operand:SI 2 "immediate_operand" "i")))]
292 [(set_attr "type" "mvi")
293 (set_attr "length" "4")])
295 (define_insn "movsi_high_pic"
296 [(set (match_operand:SI 0 "register_operand" "=x")
297 (high:SI (unspec:SI [(match_operand:SI 1 "" "")]
301 [(set_attr "type" "mvi")
302 (set_attr "length" "4")])
304 (define_insn "movsi_low_pic"
305 [(set (match_operand:SI 0 "register_operand" "=x")
306 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
307 (unspec:SI [(match_operand:SI 2 "" "")]
310 "%h0 = %h2@GOT_HIGH;"
311 [(set_attr "type" "mvi")
312 (set_attr "length" "4")])
314 ;;; Move instructions
316 (define_insn_and_split "movdi_insn"
317 [(set (match_operand:DI 0 "nonimmediate_operand" "=x,mx,r")
318 (match_operand:DI 1 "general_operand" "iFx,r,mx"))]
319 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
322 [(set (match_dup 2) (match_dup 3))
323 (set (match_dup 4) (match_dup 5))]
325 rtx lo_half[2], hi_half[2];
326 split_di (operands, 2, lo_half, hi_half);
328 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
330 operands[2] = hi_half[0];
331 operands[3] = hi_half[1];
332 operands[4] = lo_half[0];
333 operands[5] = lo_half[1];
337 operands[2] = lo_half[0];
338 operands[3] = lo_half[1];
339 operands[4] = hi_half[0];
340 operands[5] = hi_half[1];
345 [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,mr,C,d")
346 (match_operand:BI 1 "general_operand" "x,xKs3,mr,d,d,C"))]
356 [(set_attr "type" "move,mvi,mcld,mcst,compare,compare")
357 (set_attr "length" "2,2,*,*,2,2")])
359 (define_insn "movpdi"
360 [(set (match_operand:PDI 0 "nonimmediate_operand" "=e,<,e")
361 (match_operand:PDI 1 "general_operand" " e,e,>"))]
367 [(set_attr "type" "move,mcst,mcld")])
369 (define_insn "*pushsi_insn"
370 [(set (mem:SI (pre_dec:SI (reg:SI REG_SP)))
371 (match_operand:SI 0 "register_operand" "xy"))]
374 [(set_attr "type" "mcst")
375 (set_attr "length" "2")])
377 (define_insn "*popsi_insn"
378 [(set (match_operand:SI 0 "register_operand" "=xy")
379 (mem:SI (post_inc:SI (reg:SI REG_SP))))]
382 [(set_attr "type" "mcld")
383 (set_attr "length" "2")])
385 ;; The first alternative is used to make reload choose a limited register
386 ;; class when faced with a movsi_insn that had its input operand replaced
387 ;; with a PLUS. We generally require fewer secondary reloads this way.
388 (define_insn "*movsi_insn"
389 [(set (match_operand:SI 0 "nonimmediate_operand" "=da,x*y,da,x,x,x,da,mr")
390 (match_operand:SI 1 "general_operand" "da,x*y,xKs7,xKsh,xKuh,ix,mr,da"))]
392 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
402 [(set_attr "type" "move,move,mvi,mvi,mvi,*,mcld,mcst")
403 (set_attr "length" "2,2,2,4,4,*,*,*")])
405 (define_insn "*movv2hi_insn"
406 [(set (match_operand:V2HI 0 "nonimmediate_operand" "=da,d,m")
407 (match_operand:V2HI 1 "general_operand" "d,m,d"))]
409 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
411 [(set_attr "type" "move,mcld,mcst")
412 (set_attr "length" "2,*,*")])
414 (define_insn "*movhi_insn"
415 [(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr")
416 (match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
417 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
424 [(set_attr "type" "move,mvi,mvi,mcld,mcst")
425 (set_attr "length" "2,2,4,*,*")])
427 (define_insn "*movqi_insn"
428 [(set (match_operand:QI 0 "nonimmediate_operand" "=x,da,x,d,mr")
429 (match_operand:QI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
430 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
437 [(set_attr "type" "move,mvi,mvi,mcld,mcst")
438 (set_attr "length" "2,2,4,*,*")])
440 (define_insn "*movsf_insn"
441 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,da,mr")
442 (match_operand:SF 1 "general_operand" "x,Fx,mr,da"))]
443 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
449 [(set_attr "type" "move,*,mcld,mcst")])
451 (define_insn_and_split "movdf_insn"
452 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,mx,r")
453 (match_operand:DF 1 "general_operand" "iFx,r,mx"))]
454 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
457 [(set (match_dup 2) (match_dup 3))
458 (set (match_dup 4) (match_dup 5))]
460 rtx lo_half[2], hi_half[2];
461 split_di (operands, 2, lo_half, hi_half);
463 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
465 operands[2] = hi_half[0];
466 operands[3] = hi_half[1];
467 operands[4] = lo_half[0];
468 operands[5] = lo_half[1];
472 operands[2] = lo_half[0];
473 operands[3] = lo_half[1];
474 operands[4] = hi_half[0];
475 operands[5] = hi_half[1];
479 ;; This is the main "hook" for PIC code. When generating
480 ;; PIC, movsi is responsible for determining when the source address
481 ;; needs PIC relocation and appropriately calling legitimize_pic_address
482 ;; to perform the actual relocation.
484 (define_expand "movsi"
485 [(set (match_operand:SI 0 "nonimmediate_operand" "")
486 (match_operand:SI 1 "general_operand" ""))]
488 "expand_move (operands, SImode);")
490 (define_expand "movv2hi"
491 [(set (match_operand:V2HI 0 "nonimmediate_operand" "")
492 (match_operand:V2HI 1 "general_operand" ""))]
494 "expand_move (operands, V2HImode);")
496 (define_expand "movdi"
497 [(set (match_operand:DI 0 "nonimmediate_operand" "")
498 (match_operand:DI 1 "general_operand" ""))]
500 "expand_move (operands, DImode);")
502 (define_expand "movsf"
503 [(set (match_operand:SF 0 "nonimmediate_operand" "")
504 (match_operand:SF 1 "general_operand" ""))]
506 "expand_move (operands, SFmode);")
508 (define_expand "movdf"
509 [(set (match_operand:DF 0 "nonimmediate_operand" "")
510 (match_operand:DF 1 "general_operand" ""))]
512 "expand_move (operands, DFmode);")
514 (define_expand "movhi"
515 [(set (match_operand:HI 0 "nonimmediate_operand" "")
516 (match_operand:HI 1 "general_operand" ""))]
518 "expand_move (operands, HImode);")
520 (define_expand "movqi"
521 [(set (match_operand:QI 0 "nonimmediate_operand" "")
522 (match_operand:QI 1 "general_operand" ""))]
524 " expand_move (operands, QImode); ")
526 ;; Some define_splits to break up SI/SFmode loads of immediate constants.
529 [(set (match_operand:SI 0 "register_operand" "")
530 (match_operand:SI 1 "symbolic_or_const_operand" ""))]
532 /* Always split symbolic operands; split integer constants that are
533 too large for a single instruction. */
534 && (GET_CODE (operands[1]) != CONST_INT
535 || (INTVAL (operands[1]) < -32768
536 || INTVAL (operands[1]) >= 65536
537 || (INTVAL (operands[1]) >= 32768 && PREG_P (operands[0]))))"
538 [(set (match_dup 0) (high:SI (match_dup 1)))
539 (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))]
541 if (GET_CODE (operands[1]) == CONST_INT
542 && split_load_immediate (operands))
544 /* ??? Do something about TARGET_LOW_64K. */
548 [(set (match_operand:SF 0 "register_operand" "")
549 (match_operand:SF 1 "immediate_operand" ""))]
551 [(set (match_dup 2) (high:SI (match_dup 3)))
552 (set (match_dup 2) (lo_sum:SI (match_dup 2) (match_dup 3)))]
555 REAL_VALUE_TYPE value;
557 gcc_assert (GET_CODE (operands[1]) == CONST_DOUBLE);
559 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
560 REAL_VALUE_TO_TARGET_SINGLE (value, values);
562 operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0]));
563 operands[3] = GEN_INT (trunc_int_for_mode (values, SImode));
564 if (values >= -32768 && values < 65536)
566 emit_move_insn (operands[2], operands[3]);
569 if (split_load_immediate (operands + 2))
573 ;; Sadly, this can't be a proper named movstrict pattern, since the compiler
574 ;; expects to be able to use registers for operand 1.
575 ;; Note that the asm instruction is defined by the manual to take an unsigned
576 ;; constant, but it doesn't matter to the assembler, and the compiler only
577 ;; deals with sign-extended constants. Hence "Ksh".
578 (define_insn "*movstricthi"
579 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+x"))
580 (match_operand:HI 1 "immediate_operand" "Ksh"))]
583 [(set_attr "type" "mvi")
584 (set_attr "length" "4")])
586 ;; Sign and zero extensions
588 (define_insn "extendhisi2"
589 [(set (match_operand:SI 0 "register_operand" "=d, d")
590 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
595 [(set_attr "type" "alu0,mcld")])
597 (define_insn "zero_extendhisi2"
598 [(set (match_operand:SI 0 "register_operand" "=d, d")
599 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
604 [(set_attr "type" "alu0,mcld")])
606 (define_insn "zero_extendbisi2"
607 [(set (match_operand:SI 0 "register_operand" "=d")
608 (zero_extend:SI (match_operand:BI 1 "nonimmediate_operand" "C")))]
611 [(set_attr "type" "compare")])
613 (define_insn "extendqihi2"
614 [(set (match_operand:HI 0 "register_operand" "=d, d")
615 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
620 [(set_attr "type" "mcld,alu0")])
622 (define_insn "extendqisi2"
623 [(set (match_operand:SI 0 "register_operand" "=d, d")
624 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
629 [(set_attr "type" "mcld,alu0")])
632 (define_insn "zero_extendqihi2"
633 [(set (match_operand:HI 0 "register_operand" "=d, d")
634 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
639 [(set_attr "type" "mcld,alu0")])
642 (define_insn "zero_extendqisi2"
643 [(set (match_operand:SI 0 "register_operand" "=d, d")
644 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
649 [(set_attr "type" "mcld,alu0")])
651 ;; DImode logical operations
653 (define_code_macro any_logical [and ior xor])
654 (define_code_attr optab [(and "and")
657 (define_code_attr op [(and "&")
660 (define_code_attr high_result [(and "0")
664 (define_insn "<optab>di3"
665 [(set (match_operand:DI 0 "register_operand" "=d")
666 (any_logical:DI (match_operand:DI 1 "register_operand" "0")
667 (match_operand:DI 2 "register_operand" "d")))]
669 "%0 = %1 <op> %2;\\n\\t%H0 = %H1 <op> %H2;"
670 [(set_attr "length" "4")])
672 (define_insn "*<optab>di_zesidi_di"
673 [(set (match_operand:DI 0 "register_operand" "=d")
674 (any_logical:DI (zero_extend:DI
675 (match_operand:SI 2 "register_operand" "d"))
676 (match_operand:DI 1 "register_operand" "d")))]
678 "%0 = %1 <op> %2;\\n\\t%H0 = <high_result>;"
679 [(set_attr "length" "4")])
681 (define_insn "*<optab>di_sesdi_di"
682 [(set (match_operand:DI 0 "register_operand" "=d")
683 (any_logical:DI (sign_extend:DI
684 (match_operand:SI 2 "register_operand" "d"))
685 (match_operand:DI 1 "register_operand" "0")))
686 (clobber (match_scratch:SI 3 "=&d"))]
688 "%0 = %1 <op> %2;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 <op> %3;"
689 [(set_attr "length" "8")])
691 (define_insn "negdi2"
692 [(set (match_operand:DI 0 "register_operand" "=d")
693 (neg:DI (match_operand:DI 1 "register_operand" "d")))
694 (clobber (match_scratch:SI 2 "=&d"))
695 (clobber (reg:CC REG_CC))]
697 "%2 = 0; %2 = %2 - %1; cc = ac0; cc = !cc; %2 = cc;\\n\\t%0 = -%1; %H0 = -%H1; %H0 = %H0 - %2;"
698 [(set_attr "length" "16")])
700 (define_insn "one_cmpldi2"
701 [(set (match_operand:DI 0 "register_operand" "=d")
702 (not:DI (match_operand:DI 1 "register_operand" "d")))]
704 "%0 = ~%1;\\n\\t%H0 = ~%H1;"
705 [(set_attr "length" "4")])
707 ;; DImode zero and sign extend patterns
709 (define_insn_and_split "zero_extendsidi2"
710 [(set (match_operand:DI 0 "register_operand" "=d")
711 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
715 [(set (match_dup 3) (const_int 0))]
717 split_di (operands, 1, operands + 2, operands + 3);
718 if (REGNO (operands[0]) != REGNO (operands[1]))
719 emit_move_insn (operands[2], operands[1]);
722 (define_insn "zero_extendqidi2"
723 [(set (match_operand:DI 0 "register_operand" "=d")
724 (zero_extend:DI (match_operand:QI 1 "register_operand" "d")))]
726 "%0 = %T1 (Z);\\n\\t%H0 = 0;"
727 [(set_attr "length" "4")])
729 (define_insn "zero_extendhidi2"
730 [(set (match_operand:DI 0 "register_operand" "=d")
731 (zero_extend:DI (match_operand:HI 1 "register_operand" "d")))]
733 "%0 = %h1 (Z);\\n\\t%H0 = 0;"
734 [(set_attr "length" "4")])
736 (define_insn_and_split "extendsidi2"
737 [(set (match_operand:DI 0 "register_operand" "=d")
738 (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))]
742 [(set (match_dup 3) (match_dup 1))
743 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
745 split_di (operands, 1, operands + 2, operands + 3);
746 if (REGNO (operands[0]) != REGNO (operands[1]))
747 emit_move_insn (operands[2], operands[1]);
750 (define_insn_and_split "extendqidi2"
751 [(set (match_operand:DI 0 "register_operand" "=d")
752 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
756 [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
757 (set (match_dup 3) (sign_extend:SI (match_dup 1)))
758 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
760 split_di (operands, 1, operands + 2, operands + 3);
763 (define_insn_and_split "extendhidi2"
764 [(set (match_operand:DI 0 "register_operand" "=d")
765 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
769 [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
770 (set (match_dup 3) (sign_extend:SI (match_dup 1)))
771 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
773 split_di (operands, 1, operands + 2, operands + 3);
776 ;; DImode arithmetic operations
778 (define_insn "adddi3"
779 [(set (match_operand:DI 0 "register_operand" "=&d,&d,&d")
780 (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
781 (match_operand:DI 2 "nonmemory_operand" "Kn7,Ks7,d")))
782 (clobber (match_scratch:SI 3 "=&d,&d,&d"))
783 (clobber (reg:CC 34))]
786 %0 += %2; cc = ac0; %3 = cc; %H0 += -1; %H0 = %H0 + %3;
787 %0 += %2; cc = ac0; %3 = cc; %H0 = %H0 + %3;
788 %0 = %0 + %2; cc = ac0; %3 = cc; %H0 = %H0 + %H2; %H0 = %H0 + %3;"
789 [(set_attr "type" "alu0")
790 (set_attr "length" "10,8,10")])
792 (define_insn "subdi3"
793 [(set (match_operand:DI 0 "register_operand" "=&d")
794 (minus:DI (match_operand:DI 1 "register_operand" "0")
795 (match_operand:DI 2 "register_operand" "d")))
796 (clobber (reg:CC 34))]
798 "%0 = %1-%2;\\n\\tcc = ac0;\\n\\t%H0 = %H1-%H2;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
799 [(set_attr "length" "10")])
801 (define_insn "*subdi_di_zesidi"
802 [(set (match_operand:DI 0 "register_operand" "=d")
803 (minus:DI (match_operand:DI 1 "register_operand" "0")
805 (match_operand:SI 2 "register_operand" "d"))))
806 (clobber (match_scratch:SI 3 "=&d"))
807 (clobber (reg:CC 34))]
809 "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%H0 = %H1 - %3;"
810 [(set_attr "length" "10")])
812 (define_insn "*subdi_zesidi_di"
813 [(set (match_operand:DI 0 "register_operand" "=d")
814 (minus:DI (zero_extend:DI
815 (match_operand:SI 2 "register_operand" "d"))
816 (match_operand:DI 1 "register_operand" "0")))
817 (clobber (match_scratch:SI 3 "=&d"))
818 (clobber (reg:CC 34))]
820 "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%3 = -%3;\\n\\t%H0 = %3 - %H1"
821 [(set_attr "length" "12")])
823 (define_insn "*subdi_di_sesidi"
824 [(set (match_operand:DI 0 "register_operand" "=d")
825 (minus:DI (match_operand:DI 1 "register_operand" "0")
827 (match_operand:SI 2 "register_operand" "d"))))
828 (clobber (match_scratch:SI 3 "=&d"))
829 (clobber (reg:CC 34))]
831 "%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:"
832 [(set_attr "length" "14")])
834 (define_insn "*subdi_sesidi_di"
835 [(set (match_operand:DI 0 "register_operand" "=d")
836 (minus:DI (sign_extend:DI
837 (match_operand:SI 2 "register_operand" "d"))
838 (match_operand:DI 1 "register_operand" "0")))
839 (clobber (match_scratch:SI 3 "=&d"))
840 (clobber (reg:CC 34))]
842 "%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:"
843 [(set_attr "length" "14")])
845 ;; Combined shift/add instructions
848 [(set (match_operand:SI 0 "register_operand" "=a,d")
849 (ashift:SI (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
850 (match_operand:SI 2 "register_operand" "a,d"))
851 (match_operand:SI 3 "pos_scale_operand" "P1P2,P1P2")))]
853 "%0 = (%0 + %2) << %3;" /* "shadd %0,%2,%3;" */
854 [(set_attr "type" "alu0")])
857 [(set (match_operand:SI 0 "register_operand" "=a")
858 (plus:SI (match_operand:SI 1 "register_operand" "a")
859 (mult:SI (match_operand:SI 2 "register_operand" "a")
860 (match_operand:SI 3 "scale_by_operand" "i"))))]
862 "%0 = %1 + (%2 << %X3);"
863 [(set_attr "type" "alu0")])
866 [(set (match_operand:SI 0 "register_operand" "=a")
867 (plus:SI (match_operand:SI 1 "register_operand" "a")
868 (ashift:SI (match_operand:SI 2 "register_operand" "a")
869 (match_operand:SI 3 "pos_scale_operand" "i"))))]
871 "%0 = %1 + (%2 << %3);"
872 [(set_attr "type" "alu0")])
875 [(set (match_operand:SI 0 "register_operand" "=a")
876 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "a")
877 (match_operand:SI 2 "scale_by_operand" "i"))
878 (match_operand:SI 3 "register_operand" "a")))]
880 "%0 = %3 + (%1 << %X2);"
881 [(set_attr "type" "alu0")])
884 [(set (match_operand:SI 0 "register_operand" "=a")
885 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "a")
886 (match_operand:SI 2 "pos_scale_operand" "i"))
887 (match_operand:SI 3 "register_operand" "a")))]
889 "%0 = %3 + (%1 << %2);"
890 [(set_attr "type" "alu0")])
892 (define_insn "mulhisi3"
893 [(set (match_operand:SI 0 "register_operand" "=d")
894 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%d"))
895 (sign_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
897 "%0 = %h1 * %h2 (IS);"
898 [(set_attr "type" "dsp32")])
900 (define_insn "umulhisi3"
901 [(set (match_operand:SI 0 "register_operand" "=d")
902 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%d"))
903 (zero_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
905 "%0 = %h1 * %h2 (FU);"
906 [(set_attr "type" "dsp32")])
908 ;; The processor also supports ireg += mreg or ireg -= mreg, but these
909 ;; are unusable if we don't ensure that the corresponding lreg is zero.
910 ;; The same applies to the add/subtract constant versions involving
913 (define_insn "addsi3"
914 [(set (match_operand:SI 0 "register_operand" "=ad,a,d")
915 (plus:SI (match_operand:SI 1 "register_operand" "%0, a,d")
916 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7, a,d")))]
922 [(set_attr "type" "alu0")
923 (set_attr "length" "2,2,2")])
925 (define_expand "subsi3"
926 [(set (match_operand:SI 0 "register_operand" "")
927 (minus:SI (match_operand:SI 1 "register_operand" "")
928 (match_operand:SI 2 "reg_or_7bit_operand" "")))]
933 [(set (match_operand:SI 0 "register_operand" "=da,d,a")
934 (minus:SI (match_operand:SI 1 "register_operand" "0,d,0")
935 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7,d,a")))]
936 "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -64"
938 static const char *const strings_subsi3[] = {
944 if (CONSTANT_P (operands[2]) && INTVAL (operands[2]) < 0) {
945 rtx tmp_op = operands[2];
946 operands[2] = GEN_INT (-INTVAL (operands[2]));
947 output_asm_insn ("%0 += %2;", operands);
948 operands[2] = tmp_op;
952 return strings_subsi3[which_alternative];
954 [(set_attr "type" "alu0")])
956 ;; Bit test instructions
958 (define_insn "*not_bittst"
959 [(set (match_operand:BI 0 "cc_operand" "=C")
960 (eq:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
962 (match_operand:SI 2 "immediate_operand" "Ku5"))
965 "cc = !BITTST (%1,%2);"
966 [(set_attr "type" "alu0")])
968 (define_insn "*bittst"
969 [(set (match_operand:BI 0 "cc_operand" "=C")
970 (ne:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
972 (match_operand:SI 2 "immediate_operand" "Ku5"))
975 "cc = BITTST (%1,%2);"
976 [(set_attr "type" "alu0")])
978 (define_insn_and_split "*bit_extract"
979 [(set (match_operand:SI 0 "register_operand" "=d")
980 (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
982 (match_operand:SI 2 "immediate_operand" "Ku5")))
983 (clobber (reg:BI REG_CC))]
987 [(set (reg:BI REG_CC)
988 (ne:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
991 (ne:SI (reg:BI REG_CC) (const_int 0)))])
993 (define_insn_and_split "*not_bit_extract"
994 [(set (match_operand:SI 0 "register_operand" "=d")
995 (zero_extract:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
997 (match_operand:SI 2 "immediate_operand" "Ku5")))
998 (clobber (reg:BI REG_CC))]
1002 [(set (reg:BI REG_CC)
1003 (eq:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1006 (ne:SI (reg:BI REG_CC) (const_int 0)))])
1008 (define_insn "*andsi_insn"
1009 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
1010 (and:SI (match_operand:SI 1 "register_operand" "%0,d,d,d")
1011 (match_operand:SI 2 "rhs_andsi3_operand" "L,M1,M2,d")))]
1018 [(set_attr "type" "alu0")])
1020 (define_expand "andsi3"
1021 [(set (match_operand:SI 0 "register_operand" "")
1022 (and:SI (match_operand:SI 1 "register_operand" "")
1023 (match_operand:SI 2 "general_operand" "")))]
1026 if (highbits_operand (operands[2], SImode))
1028 operands[2] = GEN_INT (exact_log2 (-INTVAL (operands[2])));
1029 emit_insn (gen_ashrsi3 (operands[0], operands[1], operands[2]));
1030 emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
1033 if (! rhs_andsi3_operand (operands[2], SImode))
1034 operands[2] = force_reg (SImode, operands[2]);
1037 (define_insn "iorsi3"
1038 [(set (match_operand:SI 0 "register_operand" "=d,d")
1039 (ior:SI (match_operand:SI 1 "register_operand" "%0,d")
1040 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1045 [(set_attr "type" "alu0")])
1047 (define_insn "xorsi3"
1048 [(set (match_operand:SI 0 "register_operand" "=d,d")
1049 (xor:SI (match_operand:SI 1 "register_operand" "%0,d")
1050 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1055 [(set_attr "type" "alu0")])
1057 (define_insn "smaxsi3"
1058 [(set (match_operand:SI 0 "register_operand" "=d")
1059 (smax:SI (match_operand:SI 1 "register_operand" "d")
1060 (match_operand:SI 2 "register_operand" "d")))]
1063 [(set_attr "type" "dsp32")])
1065 (define_insn "sminsi3"
1066 [(set (match_operand:SI 0 "register_operand" "=d")
1067 (smin:SI (match_operand:SI 1 "register_operand" "d")
1068 (match_operand:SI 2 "register_operand" "d")))]
1071 [(set_attr "type" "dsp32")])
1073 (define_insn "abssi2"
1074 [(set (match_operand:SI 0 "register_operand" "=d")
1075 (abs:SI (match_operand:SI 1 "register_operand" " d")))]
1078 [(set_attr "type" "dsp32")])
1081 (define_insn "negsi2"
1082 [(set (match_operand:SI 0 "register_operand" "=d")
1083 (neg:SI (match_operand:SI 1 "register_operand" " d")))]
1086 [(set_attr "type" "alu0")])
1088 (define_insn "one_cmplsi2"
1089 [(set (match_operand:SI 0 "register_operand" "=d")
1090 (not:SI (match_operand:SI 1 "register_operand" " d")))]
1093 [(set_attr "type" "alu0")])
1095 (define_insn "mulsi3"
1096 [(set (match_operand:SI 0 "register_operand" "=d")
1097 (mult:SI (match_operand:SI 1 "register_operand" "%0")
1098 (match_operand:SI 2 "register_operand" "d")))]
1101 [(set_attr "type" "mult")])
1103 (define_expand "ashlsi3"
1104 [(set (match_operand:SI 0 "register_operand" "")
1105 (ashift:SI (match_operand:SI 1 "register_operand" "")
1106 (match_operand:SI 2 "nonmemory_operand" "")))]
1109 if (GET_CODE (operands[2]) == CONST_INT
1110 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1112 emit_insn (gen_movsi (operands[0], const0_rtx));
1117 (define_insn_and_split "*ashlsi3_insn"
1118 [(set (match_operand:SI 0 "register_operand" "=d,a,a,a")
1119 (ashift:SI (match_operand:SI 1 "register_operand" "0,a,a,a")
1120 (match_operand:SI 2 "nonmemory_operand" "dKu5,P1,P2,?P3P4")))]
1127 "PREG_P (operands[0]) && INTVAL (operands[2]) > 2"
1128 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
1129 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
1130 "operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
1131 [(set_attr "type" "shft")])
1133 (define_insn "ashrsi3"
1134 [(set (match_operand:SI 0 "register_operand" "=d")
1135 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1136 (match_operand:SI 2 "nonmemory_operand" "dKu5")))]
1139 [(set_attr "type" "shft")])
1141 (define_insn "lshrsi3"
1142 [(set (match_operand:SI 0 "register_operand" "=d,a")
1143 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0,a")
1144 (match_operand:SI 2 "nonmemory_operand" "dKu5,P1P2")))]
1149 [(set_attr "type" "shft")])
1151 ;; A pattern to reload the equivalent of
1152 ;; (set (Dreg) (plus (FP) (large_constant)))
1154 ;; (set (dagreg) (plus (FP) (arbitrary_constant)))
1155 ;; using a scratch register
1156 (define_expand "reload_insi"
1157 [(parallel [(set (match_operand:SI 0 "register_operand" "=w")
1158 (match_operand:SI 1 "fp_plus_const_operand" ""))
1159 (clobber (match_operand:SI 2 "register_operand" "=&a"))])]
1162 rtx fp_op = XEXP (operands[1], 0);
1163 rtx const_op = XEXP (operands[1], 1);
1164 rtx primary = operands[0];
1165 rtx scratch = operands[2];
1167 emit_move_insn (scratch, const_op);
1168 emit_insn (gen_addsi3 (scratch, scratch, fp_op));
1169 emit_move_insn (primary, scratch);
1173 ;; Jump instructions
1177 (label_ref (match_operand 0 "" "")))]
1180 if (get_attr_length (insn) == 2)
1181 return "jump.s %0;";
1183 return "jump.l %0;";
1185 [(set_attr "type" "br")])
1187 (define_insn "indirect_jump"
1189 (match_operand:SI 0 "register_operand" "a"))]
1192 [(set_attr "type" "misc")])
1194 (define_expand "tablejump"
1195 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1196 (use (label_ref (match_operand 1 "" "")))])]
1199 /* In PIC mode, the table entries are stored PC relative.
1200 Convert the relative address to an absolute address. */
1203 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1205 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1206 op1, NULL_RTX, 0, OPTAB_DIRECT);
1210 (define_insn "*tablejump_internal"
1211 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1212 (use (label_ref (match_operand 1 "" "")))]
1215 [(set_attr "type" "misc")])
1217 ;; Call instructions..
1219 (define_expand "call"
1220 [(call (match_operand:SI 0 "" "")
1221 (match_operand 1 "" ""))]
1223 "bfin_expand_call (NULL_RTX, operands[0], operands[1], 0); DONE;")
1225 (define_expand "sibcall"
1226 [(parallel [(call (match_operand:SI 0 "" "")
1227 (match_operand 1 "" ""))
1230 "bfin_expand_call (NULL_RTX, operands[0], operands[1], 1); DONE;")
1232 (define_expand "call_value"
1233 [(set (match_operand 0 "register_operand" "")
1234 (call (match_operand:SI 1 "" "")
1235 (match_operand 2 "" "")))]
1237 "bfin_expand_call (operands[0], operands[1], operands[2], 0); DONE;")
1239 (define_expand "sibcall_value"
1240 [(parallel [(set (match_operand 0 "register_operand" "")
1241 (call (match_operand:SI 1 "" "")
1242 (match_operand 2 "" "")))
1245 "bfin_expand_call (operands[0], operands[1], operands[2], 1); DONE;")
1247 (define_insn "*call_insn"
1248 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "a,Q"))
1249 (match_operand 1 "general_operand" "g,g"))]
1250 "! SIBLING_CALL_P (insn)
1251 && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
1255 [(set_attr "type" "call")
1256 (set_attr "length" "2,4")])
1258 (define_insn "*sibcall_insn"
1259 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "z,Q"))
1260 (match_operand 1 "general_operand" "g,g"))
1262 "SIBLING_CALL_P (insn)
1263 && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
1267 [(set_attr "type" "br")
1268 (set_attr "length" "2,4")])
1270 (define_insn "*call_value_insn"
1271 [(set (match_operand 0 "register_operand" "=d,d")
1272 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "a,Q"))
1273 (match_operand 2 "general_operand" "g,g")))]
1274 "! SIBLING_CALL_P (insn)
1275 && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
1279 [(set_attr "type" "call")
1280 (set_attr "length" "2,4")])
1282 (define_insn "*sibcall_value_insn"
1283 [(set (match_operand 0 "register_operand" "=d,d")
1284 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "z,Q"))
1285 (match_operand 2 "general_operand" "g,g")))
1287 "SIBLING_CALL_P (insn)
1288 && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
1292 [(set_attr "type" "br")
1293 (set_attr "length" "2,4")])
1295 ;; Block move patterns
1297 ;; We cheat. This copies one more word than operand 2 indicates.
1299 (define_insn "rep_movsi"
1300 [(set (match_operand:SI 0 "register_operand" "=&a")
1301 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1302 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1305 (set (match_operand:SI 1 "register_operand" "=&b")
1306 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1307 (ashift:SI (match_dup 2) (const_int 2)))
1309 (set (mem:BLK (match_dup 3))
1310 (mem:BLK (match_dup 4)))
1312 (clobber (match_scratch:HI 5 "=&d"))]
1314 "lsetup (1f, 1f) LC1 = %2; %5 = [%4++]; 1: MNOP || [%3++] = %5 || %5 = [%4++]; [%3++] = %5;"
1315 [(set_attr "type" "misc")
1316 (set_attr "length" "16")])
1318 (define_insn "rep_movhi"
1319 [(set (match_operand:SI 0 "register_operand" "=&a")
1320 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1321 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1324 (set (match_operand:SI 1 "register_operand" "=&b")
1325 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1326 (ashift:SI (match_dup 2) (const_int 1)))
1328 (set (mem:BLK (match_dup 3))
1329 (mem:BLK (match_dup 4)))
1331 (clobber (match_scratch:HI 5 "=&d"))]
1333 "lsetup (1f, 1f) LC1 = %2; %h5 = W[%4++]; 1: MNOP || W [%3++] = %5 || %h5 = W [%4++]; W [%3++] = %5;"
1334 [(set_attr "type" "misc")
1335 (set_attr "length" "16")])
1337 (define_expand "movstrsi"
1338 [(match_operand:BLK 0 "general_operand" "")
1339 (match_operand:BLK 1 "general_operand" "")
1340 (match_operand:SI 2 "const_int_operand" "")
1341 (match_operand:SI 3 "const_int_operand" "")]
1344 if (bfin_expand_strmov (operands[0], operands[1], operands[2], operands[3]))
1349 ;; Conditional branch patterns
1350 ;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
1352 ;; The only outcome of this pattern is that global variables
1353 ;; bfin_compare_op[01] are set for use in bcond patterns.
1355 (define_expand "cmpbi"
1356 [(set (cc0) (compare (match_operand:BI 0 "register_operand" "")
1357 (match_operand:BI 1 "immediate_operand" "")))]
1360 bfin_compare_op0 = operands[0];
1361 bfin_compare_op1 = operands[1];
1365 (define_expand "cmpsi"
1366 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
1367 (match_operand:SI 1 "nonmemory_operand" "")))]
1370 bfin_compare_op0 = operands[0];
1371 bfin_compare_op1 = operands[1];
1376 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1377 (eq:BI (match_operand:SI 1 "register_operand" "d,a")
1378 (match_operand:SI 2 "nonmemory_operand" "dKs3,aKs3")))]
1381 [(set_attr "type" "compare")])
1384 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1385 (ne:BI (match_operand:SI 1 "register_operand" "d,a")
1386 (match_operand:SI 2 "nonmemory_operand" "dKs3,aKs3")))]
1389 [(set_attr "type" "compare")])
1392 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1393 (lt:BI (match_operand:SI 1 "register_operand" "d,a")
1394 (match_operand:SI 2 "nonmemory_operand" "dKs3,aKs3")))]
1397 [(set_attr "type" "compare")])
1400 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1401 (le:BI (match_operand:SI 1 "register_operand" "d,a")
1402 (match_operand:SI 2 "nonmemory_operand" "dKs3,aKs3")))]
1405 [(set_attr "type" "compare")])
1408 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1409 (leu:BI (match_operand:SI 1 "register_operand" "d,a")
1410 (match_operand:SI 2 "nonmemory_operand" "dKu3,aKu3")))]
1413 [(set_attr "type" "compare")])
1416 [(set (match_operand:BI 0 "cc_operand" "=C,C")
1417 (ltu:BI (match_operand:SI 1 "register_operand" "d,a")
1418 (match_operand:SI 2 "nonmemory_operand" "dKu3,aKu3")))]
1421 [(set_attr "type" "compare")])
1423 (define_expand "beq"
1424 [(set (match_dup 1) (match_dup 2))
1426 (if_then_else (match_dup 3)
1427 (label_ref (match_operand 0 "" ""))
1431 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1432 operands[1] = bfin_cc_rtx; /* hard register: CC */
1433 operands[2] = gen_rtx_EQ (BImode, op0, op1);
1434 /* If we have a BImode input, then we already have a compare result, and
1435 do not need to emit another comparison. */
1436 if (GET_MODE (bfin_compare_op0) == BImode)
1438 gcc_assert (bfin_compare_op1 == const0_rtx);
1439 emit_insn (gen_cbranchbi4 (operands[2], op0, op1, operands[0]));
1443 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1446 (define_expand "bne"
1447 [(set (match_dup 1) (match_dup 2))
1449 (if_then_else (match_dup 3)
1450 (label_ref (match_operand 0 "" ""))
1454 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1455 /* If we have a BImode input, then we already have a compare result, and
1456 do not need to emit another comparison. */
1457 if (GET_MODE (bfin_compare_op0) == BImode)
1459 rtx cmp = gen_rtx_NE (BImode, op0, op1);
1461 gcc_assert (bfin_compare_op1 == const0_rtx);
1462 emit_insn (gen_cbranchbi4 (cmp, op0, op1, operands[0]));
1466 operands[1] = bfin_cc_rtx; /* hard register: CC */
1467 operands[2] = gen_rtx_EQ (BImode, op0, op1);
1468 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1471 (define_expand "bgt"
1472 [(set (match_dup 1) (match_dup 2))
1474 (if_then_else (match_dup 3)
1475 (label_ref (match_operand 0 "" ""))
1479 operands[1] = bfin_cc_rtx;
1480 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1481 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1484 (define_expand "bgtu"
1485 [(set (match_dup 1) (match_dup 2))
1487 (if_then_else (match_dup 3)
1488 (label_ref (match_operand 0 "" ""))
1492 operands[1] = bfin_cc_rtx;
1493 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1494 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1497 (define_expand "blt"
1498 [(set (match_dup 1) (match_dup 2))
1500 (if_then_else (match_dup 3)
1501 (label_ref (match_operand 0 "" ""))
1505 operands[1] = bfin_cc_rtx;
1506 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1507 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1510 (define_expand "bltu"
1511 [(set (match_dup 1) (match_dup 2))
1513 (if_then_else (match_dup 3)
1514 (label_ref (match_operand 0 "" ""))
1518 operands[1] = bfin_cc_rtx;
1519 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1520 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1524 (define_expand "bge"
1525 [(set (match_dup 1) (match_dup 2))
1527 (if_then_else (match_dup 3)
1528 (label_ref (match_operand 0 "" ""))
1532 operands[1] = bfin_cc_rtx;
1533 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1534 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1537 (define_expand "bgeu"
1538 [(set (match_dup 1) (match_dup 2))
1540 (if_then_else (match_dup 3)
1541 (label_ref (match_operand 0 "" ""))
1545 operands[1] = bfin_cc_rtx;
1546 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1547 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1550 (define_expand "ble"
1551 [(set (match_dup 1) (match_dup 2))
1553 (if_then_else (match_dup 3)
1554 (label_ref (match_operand 0 "" ""))
1558 operands[1] = bfin_cc_rtx;
1559 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1560 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1563 (define_expand "bleu"
1564 [(set (match_dup 1) (match_dup 2))
1566 (if_then_else (match_dup 3)
1567 (label_ref (match_operand 0 "" ""))
1572 operands[1] = bfin_cc_rtx;
1573 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1574 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1577 (define_insn "cbranchbi4"
1580 (match_operator 0 "bfin_cbranch_operator"
1581 [(match_operand:BI 1 "cc_operand" "C")
1582 (match_operand:BI 2 "immediate_operand" "P0")])
1583 (label_ref (match_operand 3 "" ""))
1587 asm_conditional_branch (insn, operands, 0, 0);
1590 [(set_attr "type" "brcc")])
1592 ;; Special cbranch patterns to deal with the speculative load problem - see
1593 ;; bfin_reorg for details.
1595 (define_insn "cbranch_predicted_taken"
1598 (match_operator 0 "bfin_cbranch_operator"
1599 [(match_operand:BI 1 "cc_operand" "C")
1600 (match_operand:BI 2 "immediate_operand" "P0")])
1601 (label_ref (match_operand 3 "" ""))
1603 (unspec [(const_int 0)] UNSPEC_CBRANCH_TAKEN)]
1606 asm_conditional_branch (insn, operands, 0, 1);
1609 [(set_attr "type" "brcc")])
1611 (define_insn "cbranch_with_nops"
1614 (match_operator 0 "bfin_cbranch_operator"
1615 [(match_operand:BI 1 "cc_operand" "C")
1616 (match_operand:BI 2 "immediate_operand" "P0")])
1617 (label_ref (match_operand 3 "" ""))
1619 (unspec [(match_operand 4 "immediate_operand" "")] UNSPEC_CBRANCH_NOPS)]
1622 asm_conditional_branch (insn, operands, INTVAL (operands[4]), 0);
1625 [(set_attr "type" "brcc")
1626 (set_attr "length" "6")])
1629 (define_expand "seq"
1630 [(set (match_dup 1) (eq:BI (match_dup 2) (match_dup 3)))
1631 (set (match_operand:SI 0 "register_operand" "")
1632 (ne:SI (match_dup 1) (const_int 0)))]
1635 operands[2] = bfin_compare_op0;
1636 operands[3] = bfin_compare_op1;
1637 operands[1] = bfin_cc_rtx;
1640 (define_expand "slt"
1641 [(set (match_dup 1) (lt:BI (match_dup 2) (match_dup 3)))
1642 (set (match_operand:SI 0 "register_operand" "")
1643 (ne:SI (match_dup 1) (const_int 0)))]
1646 operands[2] = bfin_compare_op0;
1647 operands[3] = bfin_compare_op1;
1648 operands[1] = bfin_cc_rtx;
1651 (define_expand "sle"
1652 [(set (match_dup 1) (le:BI (match_dup 2) (match_dup 3)))
1653 (set (match_operand:SI 0 "register_operand" "")
1654 (ne:SI (match_dup 1) (const_int 0)))]
1657 operands[2] = bfin_compare_op0;
1658 operands[3] = bfin_compare_op1;
1659 operands[1] = bfin_cc_rtx;
1662 (define_expand "sltu"
1663 [(set (match_dup 1) (ltu:BI (match_dup 2) (match_dup 3)))
1664 (set (match_operand:SI 0 "register_operand" "")
1665 (ne:SI (match_dup 1) (const_int 0)))]
1668 operands[2] = bfin_compare_op0;
1669 operands[3] = bfin_compare_op1;
1670 operands[1] = bfin_cc_rtx;
1673 (define_expand "sleu"
1674 [(set (match_dup 1) (leu:BI (match_dup 2) (match_dup 3)))
1675 (set (match_operand:SI 0 "register_operand" "")
1676 (ne:SI (match_dup 1) (const_int 0)))]
1679 operands[2] = bfin_compare_op0;
1680 operands[3] = bfin_compare_op1;
1681 operands[1] = bfin_cc_rtx;
1689 ;;;;;;;;;;;;;;;;;;;; CC2dreg ;;;;;;;;;;;;;;;;;;;;;;;;;
1690 (define_insn "movsibi"
1691 [(set (match_operand:BI 0 "cc_operand" "=C")
1692 (ne:BI (match_operand:SI 1 "register_operand" "d")
1696 [(set_attr "length" "2")])
1698 (define_insn "movbisi"
1699 [(set (match_operand:SI 0 "register_operand" "=d")
1700 (ne:SI (match_operand:BI 1 "cc_operand" "C")
1704 [(set_attr "length" "2")])
1707 [(set (match_operand:BI 0 "cc_operand" "=C")
1708 (eq:BI (match_operand:BI 1 "cc_operand" " 0")
1711 "%0 = ! %0;" /* NOT CC;" */
1712 [(set_attr "type" "compare")])
1714 ;; Vector and DSP insns
1717 [(set (match_operand:SI 0 "register_operand" "=d")
1718 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1720 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1723 "%0 = ALIGN8(%1, %2);"
1724 [(set_attr "type" "dsp32")])
1727 [(set (match_operand:SI 0 "register_operand" "=d")
1728 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1730 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1733 "%0 = ALIGN16(%1, %2);"
1734 [(set_attr "type" "dsp32")])
1737 [(set (match_operand:SI 0 "register_operand" "=d")
1738 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1740 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1743 "%0 = ALIGN24(%1, %2);"
1744 [(set_attr "type" "dsp32")])
1746 ;; Prologue and epilogue.
1748 (define_expand "prologue"
1751 "bfin_expand_prologue (); DONE;")
1753 (define_expand "epilogue"
1756 "bfin_expand_epilogue (1, 0); DONE;")
1758 (define_expand "sibcall_epilogue"
1761 "bfin_expand_epilogue (0, 0); DONE;")
1763 (define_expand "eh_return"
1764 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")]
1765 UNSPEC_VOLATILE_EH_RETURN)]
1768 emit_move_insn (EH_RETURN_HANDLER_RTX, operands[0]);
1769 emit_insn (gen_eh_return_internal ());
1774 (define_insn_and_split "eh_return_internal"
1775 [(unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN)]
1780 "bfin_expand_epilogue (1, 1); DONE;")
1783 [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS))
1784 (set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:SI REG_FP))
1785 (set (reg:SI REG_FP)
1786 (plus:SI (reg:SI REG_SP) (const_int -8)))
1787 (set (reg:SI REG_SP)
1788 (plus:SI (reg:SI REG_SP) (match_operand:SI 0 "immediate_operand" "i")))]
1791 [(set_attr "length" "4")])
1793 (define_insn "unlink"
1794 [(set (reg:SI REG_FP) (mem:SI (reg:SI REG_FP)))
1795 (set (reg:SI REG_RETS) (mem:SI (plus:SI (reg:SI REG_FP) (const_int 4))))
1796 (set (reg:SI REG_SP) (plus:SI (reg:SI REG_FP) (const_int 8)))]
1799 [(set_attr "length" "4")])
1801 ;; This pattern is slightly clumsy. The stack adjust must be the final SET in
1802 ;; the pattern, otherwise dwarf2out becomes very confused about which reg goes
1803 ;; where on the stack, since it goes through all elements of the parallel in
1805 (define_insn "push_multiple"
1806 [(match_parallel 0 "push_multiple_operation"
1807 [(unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_PUSH_MULTIPLE)])]
1810 output_push_multiple (insn, operands);
1814 (define_insn "pop_multiple"
1815 [(match_parallel 0 "pop_multiple_operation"
1816 [(set (reg:SI REG_SP)
1817 (plus:SI (reg:SI REG_SP) (match_operand:SI 1 "immediate_operand" "i")))])]
1820 output_pop_multiple (insn, operands);
1824 (define_insn "return_internal"
1826 (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)]
1829 switch (INTVAL (operands[0]))
1835 case INTERRUPT_HANDLER:
1843 (define_insn "csync"
1844 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
1847 [(set_attr "type" "misc")])
1849 (define_insn "ssync"
1850 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_SSYNC)]
1853 [(set_attr "type" "misc")])
1855 ;;; Vector instructions
1857 (define_insn "addv2hi"
1858 [(set (match_operand:V2HI 0 "register_operand" "=d")
1859 (plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
1860 (match_operand:V2HI 2 "register_operand" "d")))]
1863 [(set_attr "type" "dsp32")])
1865 (define_insn "subv2hi"
1866 [(set (match_operand:V2HI 0 "register_operand" "=d")
1867 (minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
1868 (match_operand:V2HI 2 "register_operand" "d")))]
1871 [(set_attr "type" "dsp32")])
1873 (define_insn "sminv2hi"
1874 [(set (match_operand:V2HI 0 "register_operand" "=d")
1875 (smin:V2HI (match_operand:V2HI 1 "register_operand" "d")
1876 (match_operand:V2HI 2 "register_operand" "d")))]
1878 "%0 = MIN (%1, %2) (V);"
1879 [(set_attr "type" "dsp32")])
1881 (define_insn "smaxv2hi"
1882 [(set (match_operand:V2HI 0 "register_operand" "=d")
1883 (smax:V2HI (match_operand:V2HI 1 "register_operand" "d")
1884 (match_operand:V2HI 2 "register_operand" "d")))]
1886 "%0 = MAX (%1, %2) (V);"
1887 [(set_attr "type" "dsp32")])
1889 (define_insn "mulv2hi"
1890 [(set (match_operand:V2HI 0 "register_operand" "=d")
1891 (mult:V2HI (match_operand:V2HI 1 "register_operand" "d")
1892 (match_operand:V2HI 2 "register_operand" "d")))]
1894 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 (IS);"
1895 [(set_attr "type" "dsp32")])
1897 (define_insn "negv2hi"
1898 [(set (match_operand:V2HI 0 "register_operand" "=d")
1899 (neg:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
1902 [(set_attr "type" "dsp32")])
1904 (define_insn "absv2hi"
1905 [(set (match_operand:V2HI 0 "register_operand" "=d")
1906 (abs:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
1909 [(set_attr "type" "dsp32")])