aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8.1/gcc/config/microblaze/microblaze.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8.1/gcc/config/microblaze/microblaze.md')
-rw-r--r--gcc-4.8.1/gcc/config/microblaze/microblaze.md2223
1 files changed, 0 insertions, 2223 deletions
diff --git a/gcc-4.8.1/gcc/config/microblaze/microblaze.md b/gcc-4.8.1/gcc/config/microblaze/microblaze.md
deleted file mode 100644
index 3618cad52..000000000
--- a/gcc-4.8.1/gcc/config/microblaze/microblaze.md
+++ /dev/null
@@ -1,2223 +0,0 @@
-;; microblaze.md -- Machine description for Xilinx MicroBlaze processors.
-;; Copyright (C) 2009-2013 Free Software Foundation, Inc.
-
-;; Contributed by Michael Eager <eager@eagercon.com>.
-
-;; This file is part of GCC.
-
-;; GCC is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-
-;; GCC is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GCC; see the file COPYING3. If not see
-;; <http://www.gnu.org/licenses/>. */
-
-(include "constraints.md")
-(include "predicates.md")
-
-;;----------------------------------------------------
-;; Constants
-;;----------------------------------------------------
-(define_constants [
- (R_SP 1) ;; Stack pointer reg
- (R_SR 15) ;; Sub-routine return addr reg
- (R_IR 14) ;; Interrupt return addr reg
- (R_DR 16) ;; Debug trap return addr reg
- (R_ER 17) ;; Exception return addr reg
- (R_TMP 18) ;; Assembler temporary reg
- (R_GOT 20) ;; GOT ptr reg
- (MB_PIPE_3 0) ;; Microblaze 3-stage pipeline
- (MB_PIPE_5 1) ;; Microblaze 5-stage pipeline
- (UNSPEC_SET_GOT 101) ;;
- (UNSPEC_GOTOFF 102) ;; GOT offset
- (UNSPEC_PLT 103) ;; jump table
- (UNSPEC_CMP 104) ;; signed compare
- (UNSPEC_CMPU 105) ;; unsigned compare
- (UNSPEC_TLS 106) ;; jump table
-])
-
-
-;;----------------------------------------------------
-;; Instruction Attributes
-;;----------------------------------------------------
-
-;; Classification of each insn.
-;; branch conditional branch
-;; jump unconditional jump
-;; call unconditional call
-;; load load instruction(s)
-;; store store instruction(s)
-;; move data movement within same register set
-;; arith integer arithmetic instruction
-;; darith double precision integer arithmetic instructions
-;; imul integer multiply
-;; idiv integer divide
-;; icmp integer compare
-;; Xfadd floating point add/subtract
-;; Xfmul floating point multiply
-;; Xfmadd floating point multiply-add
-;; Xfdiv floating point divide
-;; Xfabs floating point absolute value
-;; Xfneg floating point negation
-;; Xfcmp floating point compare
-;; Xfcvt floating point convert
-;; Xfsqrt floating point square root
-;; multi multiword sequence (or user asm statements)
-;; nop no operation
-;; bshift Shift operations
-
-(define_attr "type"
- "unknown,branch,jump,call,load,store,move,arith,darith,imul,idiv,icmp,multi,nop,no_delay_arith,no_delay_load,no_delay_store,no_delay_imul,no_delay_move,bshift,fadd,frsub,fmul,fdiv,fcmp,fsl,fsqrt,fcvt"
- (const_string "unknown"))
-
-;; Main data type used by the insn
-(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF" (const_string "unknown"))
-
-;; # instructions (4 bytes each)
-(define_attr "length" "" (const_int 4))
-
-(define_code_iterator any_return [return simple_return])
-
-;; <optab> expands to the name of the optab for a particular code.
-(define_code_attr optab [(return "return")
- (simple_return "simple_return")])
-
-
-;;----------------------------------------------------
-;; Attribute describing the processor.
-;;----------------------------------------------------
-
-;; Describe a user's asm statement.
-(define_asm_attributes
- [(set_attr "type" "multi")])
-
-;; whether or not generating calls to position independent functions
-(define_attr "abicalls" "no,yes"
- (const (symbol_ref "microblaze_abicalls_attr")))
-
-;;----------------------------------------------------------------
-;; Microblaze DFA Pipeline description
-;;----------------------------------------------------------------
-
-;;-----------------------------------------------------------------
-/*
- This is description of pipeline hazards based on DFA. The
- following constructions can be used for this:
-
- o define_cpu_unit string [string]) describes a cpu functional unit
- (separated by comma).
-
- 1st operand: Names of cpu function units.
- 2nd operand: Name of automaton (see comments for
- DEFINE_AUTOMATON).
-
- All define_reservations and define_cpu_units should have unique
- names which can not be "nothing".
-
- o (exclusion_set string string) means that each CPU function unit
- in the first string can not be reserved simultaneously with each
- unit whose name is in the second string and vise versa. CPU
- units in the string are separated by commas. For example, it is
- useful for description CPU with fully pipelined floating point
- functional unit which can execute simultaneously only single
- floating point insns or only double floating point insns.
-
- o (presence_set string string) means that each CPU function unit in
- the first string can not be reserved unless at least one of units
- whose names are in the second string is reserved. This is an
- asymmetric relation. CPU units in the string are separated by
- commas. For example, it is useful for description that slot1 is
- reserved after slot0 reservation for a VLIW processor.
-
- o (absence_set string string) means that each CPU function unit in
- the first string can not be reserved only if each unit whose name
- is in the second string is not reserved. This is an asymmetric
- relation (actually exclusion set is analogous to this one but it
- is symmetric). CPU units in the string are separated by commas.
- For example, it is useful for description that slot0 can not be
- reserved after slot1 or slot2 reservation for a VLIW processor.
-
- o (define_bypass number out_insn_names in_insn_names) names bypass with
- given latency (the first number) from insns given by the first
- string (see define_insn_reservation) into insns given by the
- second string. Insn names in the strings are separated by
- commas.
-
- o (define_automaton string) describes names of an automaton
- generated and used for pipeline hazards recognition. The names
- are separated by comma. Actually it is possibly to generate the
- single automaton but unfortunately it can be very large. If we
- use more one automata, the summary size of the automata usually
- is less than the single one. The automaton name is used in
- define_cpu_unit. All automata should have unique names.
-
- o (define_reservation string string) names reservation (the first
- string) of cpu functional units (the 2nd string). Sometimes unit
- reservations for different insns contain common parts. In such
- case, you describe common part and use one its name (the 1st
- parameter) in regular expression in define_insn_reservation. All
- define_reservations, define results and define_cpu_units should
- have unique names which can not be "nothing".
-
- o (define_insn_reservation name default_latency condition regexpr)
- describes reservation of cpu functional units (the 3nd operand)
- for instruction which is selected by the condition (the 2nd
- parameter). The first parameter is used for output of debugging
- information. The reservations are described by a regular
- expression according the following syntax:
-
- regexp = regexp "," oneof
- | oneof
-
- oneof = oneof "|" allof
- | allof
-
- allof = allof "+" repeat
- | repeat
-
- repeat = element "*" number
- | element
-
- element = cpu_function_name
- | reservation_name
- | result_name
- | "nothing"
- | "(" regexp ")"
-
- 1. "," is used for describing start of the next cycle in
- reservation.
-
- 2. "|" is used for describing the reservation described by the
- first regular expression *or* the reservation described by
- the second regular expression *or* etc.
-
- 3. "+" is used for describing the reservation described by the
- first regular expression *and* the reservation described by
- the second regular expression *and* etc.
-
- 4. "*" is used for convenience and simply means sequence in
- which the regular expression are repeated NUMBER times with
- cycle advancing (see ",").
-
- 5. cpu function unit name which means reservation.
-
- 6. reservation name -- see define_reservation.
-
- 7. string "nothing" means no units reservation.
-
-*/
-;;-----------------------------------------------------------------
-
-
-;;----------------------------------------------------------------
-;; Microblaze 5-stage pipeline description (v5.00.a and later)
-;;----------------------------------------------------------------
-
-(define_automaton "mbpipe_5")
-(define_cpu_unit "mb_issue,mb_iu,mb_wb,mb_fpu,mb_fpu_2,mb_mul,mb_mul_2,mb_div,mb_div_2,mb_bs,mb_bs_2" "mbpipe_5")
-
-(define_insn_reservation "mb-integer" 1
- (and (eq_attr "type" "branch,jump,call,arith,darith,icmp,nop,no_delay_arith")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_5)))
- "mb_issue,mb_iu,mb_wb")
-
-(define_insn_reservation "mb-special-move" 2
- (and (eq_attr "type" "move")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_5)))
- "mb_issue,mb_iu*2,mb_wb")
-
-(define_insn_reservation "mb-mem-load" 3
- (and (eq_attr "type" "load,no_delay_load")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_5)))
- "mb_issue,mb_iu,mb_wb")
-
-(define_insn_reservation "mb-mem-store" 1
- (and (eq_attr "type" "store,no_delay_store")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_5)))
- "mb_issue,mb_iu,mb_wb")
-
-(define_insn_reservation "mb-mul" 3
- (and (eq_attr "type" "imul,no_delay_imul")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_5)))
- "mb_issue,mb_mul,mb_mul_2*2,mb_wb")
-
-(define_insn_reservation "mb-div" 34
- (and (eq_attr "type" "idiv")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_5)))
- "mb_issue,mb_div,mb_div_2*33,mb_wb")
-
-(define_insn_reservation "mb-bs" 2
- (and (eq_attr "type" "bshift")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_5)))
- "mb_issue,mb_bs,mb_bs_2,mb_wb")
-
-(define_insn_reservation "mb-fpu-add-sub-mul" 6
- (and (eq_attr "type" "fadd,frsub,fmul")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_5)))
- "mb_issue,mb_fpu,mb_fpu_2*5,mb_wb")
-
-(define_insn_reservation "mb-fpu-fcmp" 3
- (and (eq_attr "type" "fcmp")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_5)))
- "mb_issue,mb_fpu,mb_fpu*2,mb_wb")
-
-(define_insn_reservation "mb-fpu-div" 30
- (and (eq_attr "type" "fdiv")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_5)))
- "mb_issue,mb_fpu,mb_fpu_2*29,mb_wb")
-
-(define_insn_reservation "mb-fpu-sqrt" 30
- (and (eq_attr "type" "fsqrt")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_5)))
- "mb_issue,mb_fpu,mb_fpu_2*29,mb_wb")
-
-(define_insn_reservation "mb-fpu-fcvt" 4
- (and (eq_attr "type" "fcvt")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_5)))
- "mb_issue,mb_fpu,mb_fpu_2*3,mb_wb")
-
-;;----------------------------------------------------------------
-;; Microblaze 3-stage pipeline description (for v4.00.a and earlier)
-;;----------------------------------------------------------------
-
-(define_automaton "mbpipe_3")
-(define_cpu_unit "mb3_iu" "mbpipe_3")
-
-(define_insn_reservation "mb3-integer" 1
- (and (eq_attr "type" "branch,jump,call,arith,darith,icmp,nop,no_delay_arith")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_3)))
- "mb3_iu")
-
-(define_insn_reservation "mb3-special-move" 2
- (and (eq_attr "type" "move")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_3)))
- "mb3_iu*2")
-
-(define_insn_reservation "mb3-mem-load" 2
- (and (eq_attr "type" "load,no_delay_load")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_3)))
- "mb3_iu")
-
-(define_insn_reservation "mb3-mem-store" 1
- (and (eq_attr "type" "store,no_delay_store")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_3)))
- "mb3_iu")
-
-(define_insn_reservation "mb3-mul" 3
- (and (eq_attr "type" "imul,no_delay_imul")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_3)))
- "mb3_iu")
-
-(define_insn_reservation "mb3-div" 34
- (and (eq_attr "type" "idiv")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_3)))
- "mb3_iu")
-
-(define_insn_reservation "mb3-bs" 2
- (and (eq_attr "type" "bshift")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_3)))
- "mb3_iu")
-
-(define_insn_reservation "mb3-fpu-add-sub-mul" 6
- (and (eq_attr "type" "fadd,frsub,fmul")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_3)))
- "mb3_iu")
-
-(define_insn_reservation "mb3-fpu-fcmp" 3
- (and (eq_attr "type" "fcmp")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_3)))
- "mb3_iu")
-
-(define_insn_reservation "mb3-fpu-div" 30
- (and (eq_attr "type" "fdiv")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_3)))
- "mb3_iu")
-
-(define_insn_reservation "mb3-fpu-sqrt" 30
- (and (eq_attr "type" "fsqrt")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_3)))
- "mb3_iu")
-
-(define_insn_reservation "mb3-fpu-fcvt" 4
- (and (eq_attr "type" "fcvt")
- (eq (symbol_ref "microblaze_pipe") (const_int MB_PIPE_3)))
- "mb3_iu")
-
-(automata_option "v")
-(automata_option "time")
-(automata_option "progress")
-
-(define_insn "bswapsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (bswap:SI (match_operand:SI 1 "register_operand" "r")))]
- "TARGET_REORDER"
- "swapb %0, %1"
-)
-
-(define_insn "bswaphi2"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
- "TARGET_REORDER"
- "swaph %0, %1"
-)
-
-;;----------------------------------------------------------------
-;; Microblaze delay slot description
-;;----------------------------------------------------------------
-(define_delay (eq_attr "type" "branch,call,jump")
- [(and (eq_attr "type" "!branch,call,jump,icmp,multi,no_delay_arith,no_delay_load,no_delay_store,no_delay_imul,no_delay_move,darith")
- (ior (not (match_test "microblaze_no_unsafe_delay"))
- (eq_attr "type" "!fadd,frsub,fmul,fdiv,fcmp,store,load")
- ))
- (nil) (nil)])
-
-
-;;----------------------------------------------------------------
-;; Microblaze FPU
-;;----------------------------------------------------------------
-
-(define_insn "addsf3"
- [(set (match_operand:SF 0 "register_operand" "=d")
- (plus:SF (match_operand:SF 1 "register_operand" "d")
- (match_operand:SF 2 "register_operand" "d")))]
- "TARGET_HARD_FLOAT"
- "fadd\t%0,%1,%2"
- [(set_attr "type" "fadd")
- (set_attr "mode" "SF")
- (set_attr "length" "4")])
-
-(define_insn "subsf3"
- [(set (match_operand:SF 0 "register_operand" "=d")
- (minus:SF (match_operand:SF 1 "register_operand" "d")
- (match_operand:SF 2 "register_operand" "d")))]
- "TARGET_HARD_FLOAT"
- "frsub\t%0,%2,%1"
- [(set_attr "type" "frsub")
- (set_attr "mode" "SF")
- (set_attr "length" "4")])
-
-(define_insn "mulsf3"
- [(set (match_operand:SF 0 "register_operand" "=d")
- (mult:SF (match_operand:SF 1 "register_operand" "d")
- (match_operand:SF 2 "register_operand" "d")))]
- "TARGET_HARD_FLOAT"
- "fmul\t%0,%1,%2"
- [(set_attr "type" "fmul")
- (set_attr "mode" "SF")
- (set_attr "length" "4")])
-
-
-(define_insn "divsf3"
- [(set (match_operand:SF 0 "register_operand" "=d")
- (div:SF (match_operand:SF 1 "register_operand" "d")
- (match_operand:SF 2 "register_operand" "d")))]
- "TARGET_HARD_FLOAT"
- "fdiv\t%0,%2,%1"
- [(set_attr "type" "fdiv")
- (set_attr "mode" "SF")
- (set_attr "length" "4")])
-
-(define_insn "sqrtsf2"
- [(set (match_operand:SF 0 "register_operand" "=d")
- (sqrt:SF (match_operand:SF 1 "register_operand" "d")))]
- "TARGET_HARD_FLOAT && TARGET_FLOAT_SQRT"
- "fsqrt\t%0,%1"
- [(set_attr "type" "fsqrt")
- (set_attr "mode" "SF")
- (set_attr "length" "4")])
-
-(define_insn "floatsisf2"
- [(set (match_operand:SF 0 "register_operand" "=d")
- (float:SF (match_operand:SI 1 "register_operand" "d")))]
- "TARGET_HARD_FLOAT && TARGET_FLOAT_CONVERT"
- "flt\t%0,%1"
- [(set_attr "type" "fcvt")
- (set_attr "mode" "SF")
- (set_attr "length" "4")])
-
-(define_insn "fix_truncsfsi2"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (fix:SI (match_operand:SF 1 "register_operand" "d")))]
- "TARGET_HARD_FLOAT && TARGET_FLOAT_CONVERT"
- "fint\t%0,%1"
- [(set_attr "type" "fcvt")
- (set_attr "mode" "SF")
- (set_attr "length" "4")])
-
-;;----------------------------------------------------------------
-;; Add
-;;----------------------------------------------------------------
-
-;; Add 2 SImode integers [ src1 = reg ; src2 = arith ; dest = reg ]
-;; Leave carry as is
-(define_insn "addsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d,d")
- (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%dJ,dJ,dJ")
- (match_operand:SI 2 "arith_plus_operand" "d,I,i")))]
- ""
- "@
- addk\t%0,%z1,%2
- addik\t%0,%z1,%2
- addik\t%0,%z1,%2"
- [(set_attr "type" "arith,arith,no_delay_arith")
- (set_attr "mode" "SI,SI,SI")
- (set_attr "length" "4,4,8")])
-
-;;----------------------------------------------------------------
-;; Double Precision Additions
-;;----------------------------------------------------------------
-
-;; reg_DI_dest = reg_DI_src1 + DI_src2
-
-;; Adding 2 DI operands in register or reg/imm
-
-(define_insn "adddi3"
- [(set (match_operand:DI 0 "register_operand" "=d,d,d")
- (plus:DI (match_operand:DI 1 "register_operand" "%d,d,d")
- (match_operand:DI 2 "arith_operand32" "d,P,N")))]
- ""
- "@
- add\t%L0,%L1,%L2\;addc\t%M0,%M1,%M2
- addi\t%L0,%L1,%2\;addc\t%M0,%M1,r0
- addi\t%L0,%L1,%2\;addc\t%M0,%M1,r0\;addi\t%M0,%M0,-1"
- [(set_attr "type" "darith")
- (set_attr "mode" "DI")
- (set_attr "length" "8,8,12")])
-
-;;----------------------------------------------------------------
-;; Subtraction
-;;----------------------------------------------------------------
-
-(define_insn "subsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (minus:SI (match_operand:SI 1 "arith_operand" "d,d")
- (match_operand:SI 2 "arith_operand" "d,n")))]
- ""
- "@
- rsubk\t%0,%2,%z1
- addik\t%0,%z1,-%2"
- [(set_attr "type" "arith,no_delay_arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4,8")])
-
-
-;;----------------------------------------------------------------
-;; Double Precision Subtraction
-;;----------------------------------------------------------------
-
-(define_insn "subdi3"
- [(set (match_operand:DI 0 "register_operand" "=&d")
- (minus:DI (match_operand:DI 1 "register_operand" "d")
- (match_operand:DI 2 "arith_operand32" "d")))]
- ""
- "@
- rsub\t%L0,%L2,%L1\;rsubc\t%M0,%M2,%M1"
- [(set_attr "type" "darith")
- (set_attr "mode" "DI")
- (set_attr "length" "8")])
-
-
-;;----------------------------------------------------------------
-;; Multiplication
-;;----------------------------------------------------------------
-
-(define_insn "mulsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d,d")
- (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
- (match_operand:SI 2 "arith_operand" "d,I,i")))]
- "!TARGET_SOFT_MUL"
- "@
- mul\t%0,%1,%2
- muli\t%0,%1,%2
- muli\t%0,%1,%2"
- [(set_attr "type" "imul,imul,no_delay_imul")
- (set_attr "mode" "SI")
- (set_attr "length" "4,4,8")])
-
-(define_insn "mulsidi3"
- [(set (match_operand:DI 0 "register_operand" "=&d")
- (mult:DI
- (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
- (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
- "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH"
- "mul\t%L0,%1,%2\;mulh\t%M0,%1,%2"
- [(set_attr "type" "no_delay_arith")
- (set_attr "mode" "DI")
- (set_attr "length" "8")])
-
-(define_insn "umulsidi3"
- [(set (match_operand:DI 0 "register_operand" "=&d")
- (mult:DI
- (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
- (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
- "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH"
- "mul\t%L0,%1,%2\;mulhu\t%M0,%1,%2"
- [(set_attr "type" "no_delay_arith")
- (set_attr "mode" "DI")
- (set_attr "length" "8")])
-
-(define_insn "usmulsidi3"
- [(set (match_operand:DI 0 "register_operand" "=&d")
- (mult:DI
- (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
- (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
- "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH"
- "mul\t%L0,%1,%2\;mulhsu\t%M0,%2,%1"
- [(set_attr "type" "no_delay_arith")
- (set_attr "mode" "DI")
- (set_attr "length" "8")])
-
-(define_insn "*smulsi3_highpart"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (truncate:SI
- (lshiftrt:DI
- (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
- (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
- (const_int 32))))]
- "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH"
- "mulh\t%0,%1,%2"
- [(set_attr "type" "imul")
- (set_attr "mode" "SI")
- (set_attr "length" "4")])
-
-(define_insn "*umulsi3_highpart"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (truncate:SI
- (lshiftrt:DI
- (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
- (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))
-)
- (const_int 32))))]
- "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH"
- "mulhu\t%0,%1,%2"
- [(set_attr "type" "imul")
- (set_attr "mode" "SI")
- (set_attr "length" "4")])
-
-(define_insn "*usmulsi3_highpart"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (truncate:SI
- (lshiftrt:DI
- (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
- (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))
-)
- (const_int 32))))]
- "!TARGET_SOFT_MUL && TARGET_MULTIPLY_HIGH"
- "mulhsu\t%0,%2,%1"
- [(set_attr "type" "imul")
- (set_attr "mode" "SI")
- (set_attr "length" "4")])
-
-
-;;----------------------------------------------------------------
-;; Division and remainder
-;;----------------------------------------------------------------
-(define_expand "divsi3"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (div:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "register_operand" "d")))
- ]
- "(!TARGET_SOFT_DIV) || (TARGET_BARREL_SHIFT && TARGET_SMALL_DIVIDES)"
- {
- if (TARGET_SOFT_DIV && TARGET_BARREL_SHIFT && TARGET_SMALL_DIVIDES)
- {
- microblaze_expand_divide (operands);
- DONE;
- }
- else if (!TARGET_SOFT_DIV)
- {
- emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
- DONE;
- }
- }
-)
-
-
-(define_insn "divsi3_internal"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (div:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "register_operand" "d")))
- ]
- "!TARGET_SOFT_DIV"
- "idiv\t%0,%2,%1"
- [(set_attr "type" "idiv")
- (set_attr "mode" "SI")
- (set_attr "length" "4")]
-)
-
-(define_insn "udivsi3"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (udiv:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "register_operand" "d")))
- ]
- "!TARGET_SOFT_DIV"
- "idivu\t%0,%2,%1"
- [(set_attr "type" "idiv")
- (set_attr "mode" "SI")
- (set_attr "length" "4")])
-
-
-;;----------------------------------------------------------------
-;; Negation and one's complement
-;;----------------------------------------------------------------
-
-(define_insn "negsi2"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (neg:SI (match_operand:SI 1 "register_operand" "d")))]
- ""
- "rsubk\t%0,%1,r0"
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")])
-
-(define_insn "negdi2"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (neg:DI (match_operand:DI 1 "register_operand" "d")))]
- ""
- "rsub\t%L0,%L1,r0\;rsubc\t%M0,%M1,r0"
- [(set_attr "type" "darith")
- (set_attr "mode" "DI")
- (set_attr "length" "8")])
-
-
-(define_insn "one_cmplsi2"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (not:SI (match_operand:SI 1 "register_operand" "d")))]
- ""
- "xori\t%0,%1,-1"
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")])
-
-(define_insn "*one_cmpldi2"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (not:DI (match_operand:DI 1 "register_operand" "d")))]
- ""
- "nor\t%M0,r0,%M1\;nor\t%L0,r0,%L1"
- [(set_attr "type" "darith")
- (set_attr "mode" "DI")
- (set_attr "length" "8")]
-)
-
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (not:DI (match_operand:DI 1 "register_operand" "")))]
- "reload_completed
- && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
- && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
-
- [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
- (set (subreg:SI (match_dup 0) 4) (not:SI (subreg:SI (match_dup 1) 4)))]
- "")
-
-
-;;----------------------------------------------------------------
-;; Logical
-;;----------------------------------------------------------------
-
-(define_insn "andsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
- (and:SI (match_operand:SI 1 "arith_operand" "%d,d,d,d")
- (match_operand:SI 2 "arith_operand" "d,I,i,M")))]
- ""
- "@
- and\t%0,%1,%2
- andi\t%0,%1,%2 #and1
- andi\t%0,%1,%2 #and2
- andi\t%0,%1,%2 #and3"
- [(set_attr "type" "arith,arith,no_delay_arith,no_delay_arith")
- (set_attr "mode" "SI,SI,SI,SI")
- (set_attr "length" "4,8,8,8")])
-
-
-(define_insn "iorsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
- (ior:SI (match_operand:SI 1 "arith_operand" "%d,d,d,d")
- (match_operand:SI 2 "arith_operand" "d,I,M,i")))]
- ""
- "@
- or\t%0,%1,%2
- ori\t%0,%1,%2
- ori\t%0,%1,%2
- ori\t%0,%1,%2"
- [(set_attr "type" "arith,no_delay_arith,no_delay_arith,no_delay_arith")
- (set_attr "mode" "SI,SI,SI,SI")
- (set_attr "length" "4,8,8,8")])
-
-(define_insn "xorsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d,d")
- (xor:SI (match_operand:SI 1 "arith_operand" "%d,d,d")
- (match_operand:SI 2 "arith_operand" "d,I,i")))]
- ""
- "@
- xor\t%0,%1,%2
- xori\t%0,%1,%2
- xori\t%0,%1,%2"
- [(set_attr "type" "arith,arith,no_delay_arith")
- (set_attr "mode" "SI,SI,SI")
- (set_attr "length" "4,8,8")])
-
-;;----------------------------------------------------------------
-;; Zero extension
-;;----------------------------------------------------------------
-
-(define_insn "zero_extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=d,d,d")
- (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
- ""
- "@
- andi\t%0,%1,0xffff
- lhu%i1\t%0,%1
- lhu%i1\t%0,%1"
- [(set_attr "type" "no_delay_arith,load,no_delay_load")
- (set_attr "mode" "SI,SI,SI")
- (set_attr "length" "8,4,8")])
-
-(define_insn "zero_extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=d,d,d")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
- ""
- "@
- andi\t%0,%1,0x00ff
- lbu%i1\t%0,%1
- lbu%i1\t%0,%1"
- [(set_attr "type" "arith,load,no_delay_load")
- (set_attr "mode" "HI")
- (set_attr "length" "4,4,8")])
-
-(define_insn "zero_extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=d,d,d")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
- ""
- "@
- andi\t%0,%1,0x00ff
- lbu%i1\t%0,%1
- lbu%i1\t%0,%1"
- [(set_attr "type" "arith,load,no_delay_load")
- (set_attr "mode" "SI,SI,SI")
- (set_attr "length" "4,4,8")])
-
-;;----------------------------------------------------------------
-;; Sign extension
-;;----------------------------------------------------------------
-
-;; basic Sign Extend Operations
-
-(define_insn "extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
- ""
- "sext8\t%0,%1"
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")])
-
-(define_insn "extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
- ""
- "sext16\t%0,%1"
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")])
-
-;; Those for integer source operand are ordered
-;; widest source type first.
-
-(define_insn "extendsidi2"
- [(set (match_operand:DI 0 "register_operand" "=d,d,d")
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
- ""
- {
- if (which_alternative == 0)
- output_asm_insn ("addk\t%L0,r0,%1", operands);
- else
- output_asm_insn ("lw%i1\t%L0,%1", operands);
-
- output_asm_insn ("add\t%M0,%L0,%L0", operands);
- output_asm_insn ("addc\t%M0,r0,r0", operands);
- output_asm_insn ("beqi\t%M0,.+8", operands);
- return "addi\t%M0,r0,0xffffffff";
- }
- [(set_attr "type" "multi,multi,multi")
- (set_attr "mode" "DI")
- (set_attr "length" "20,20,20")])
-
-;;----------------------------------------------------------------
-;; Data movement
-;;----------------------------------------------------------------
-
-;; 64-bit integer moves
-
-;; Unlike most other insns, the move insns can't be split with
-;; different predicates, because register spilling and other parts of
-;; the compiler, have memoized the insn number already.
-
-(define_expand "movdi"
- [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (match_operand:DI 1 "general_operand" ""))]
- ""
- {
- /* If operands[1] is a constant address illegal for pic, then we need to
- handle it just like microblaze_legitimize_address does. */
- if (flag_pic && pic_address_needs_scratch (operands[1]))
- {
- rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
- rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
- emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2));
- DONE;
- }
-
-
- if ((reload_in_progress | reload_completed) == 0
- && !register_operand (operands[0], DImode)
- && !register_operand (operands[1], DImode)
- && (((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
- && operands[1] != CONST0_RTX (DImode))))
- {
-
- rtx temp = force_reg (DImode, operands[1]);
- emit_move_insn (operands[0], temp);
- DONE;
- }
- }
-)
-
-
-
-(define_insn "*movdi_internal"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,o")
- (match_operand:DI 1 "general_operand" " d,i,J,R,o,d,d"))]
- ""
- {
- switch (which_alternative)
- {
- case 0:
- return "addk\t%0,%1\n\taddk\t%D0,%d1";
- case 1:
- return "addik\t%M0,r0,%h1\n\taddik\t%L0,r0,%j1 #li => la";
- case 2:
- return "addk\t%0,r0,r0\n\taddk\t%D0,r0,r0";
- case 3:
- case 4:
- if (reg_mentioned_p (operands[0], operands[1]))
- return "lwi\t%D0,%o1\n\tlwi\t%0,%1";
- else
- return "lwi\t%0,%1\n\tlwi\t%D0,%o1";
- case 5:
- case 6:
- return "swi\t%1,%0\n\tswi\t%D1,%o0";
- }
- return "unreachable";
- }
- [(set_attr "type" "no_delay_move,no_delay_arith,no_delay_arith,no_delay_load,no_delay_load,no_delay_store,no_delay_store")
- (set_attr "mode" "DI")
- (set_attr "length" "8,8,8,8,12,8,12")])
-
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" ""))]
- "reload_completed
- && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
- && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
- && (REGNO(operands[0]) == (REGNO(operands[1]) + 1))"
-
- [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))
- (set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))]
- "")
-
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" ""))]
- "reload_completed
- && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
- && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
- && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))"
-
- [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
- (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
- "")
-
-;; Unlike most other insns, the move insns can't be split with
-;; different predicates, because register spilling and other parts of
-;; the compiler, have memoized the insn number already.
-
-(define_expand "movsi"
- [(set (match_operand:SI 0 "nonimmediate_operand" "")
- (match_operand:SI 1 "general_operand" ""))]
- ""
- {
- if (microblaze_expand_move (SImode, operands)) DONE;
- }
-)
-
-;; Added for status registers
-(define_insn "movsi_status"
- [(set (match_operand:SI 0 "register_operand" "=d,d,z")
- (match_operand:SI 1 "register_operand" "z,d,d"))]
- "microblaze_is_interrupt_variant ()"
- "@
- mfs\t%0,%1 #mfs
- addk\t%0,%1,r0 #add movsi
- mts\t%0,%1 #mts"
- [(set_attr "type" "move")
- (set_attr "mode" "SI")
- (set_attr "length" "12")])
-
-;; This move will be not be moved to delay slot.
-(define_insn "*movsi_internal3"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d")
- (match_operand:SI 1 "immediate_operand" "J,I,Mnis"))]
- "(register_operand (operands[0], SImode) &&
- (GET_CODE (operands[1]) == CONST_INT &&
- (INTVAL (operands[1]) <= 32767 && INTVAL (operands[1]) >= -32768)))"
- "@
- addk\t%0,r0,r0
- addik\t%0,r0,%1\t# %X1
- addik\t%0,r0,%1\t# %X1"
- [(set_attr "type" "arith,arith,no_delay_arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")])
-
-;; This move may be used for PLT label operand
-(define_insn "*movsi_internal5_pltop"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (match_operand:SI 1 "call_insn_operand" ""))]
- "(register_operand (operands[0], Pmode) &&
- PLT_ADDR_P (operands[1]))"
- {
- gcc_unreachable ();
- }
- [(set_attr "type" "load")
- (set_attr "mode" "SI")
- (set_attr "length" "4")])
-
-(define_insn "*movsi_internal2"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d, d,d,R,m")
- (match_operand:SI 1 "move_src_operand" " d,I,Mnis,R,m,dJ,dJ"))]
- ""
- "@
- addk\t%0,%1,r0
- addik\t%0,r0,%1\t# %X1
- addik\t%0,%a1
- lw%i1\t%0,%1
- lw%i1\t%0,%1
- sw%i0\t%z1,%0
- sw%i0\t%z1,%0"
- [(set_attr "type" "load,load,no_delay_load,load,no_delay_load,store,no_delay_store")
- (set_attr "mode" "SI")
- (set_attr "length" "4,4,8,4,8,4,8")])
-
-
-;; 16-bit Integer moves
-
-;; Unlike most other insns, the move insns can't be split with
-;; different predicates, because register spilling and other parts of
-;; the compiler, have memoized the insn number already.
-;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
-
-(define_expand "movhi"
- [(set (match_operand:HI 0 "nonimmediate_operand" "")
- (match_operand:HI 1 "general_operand" ""))]
- ""
- {
- if ((reload_in_progress | reload_completed) == 0
- && !register_operand (operands[0], HImode)
- && !register_operand (operands[1], HImode)
- && ((GET_CODE (operands[1]) != CONST_INT
- || INTVAL (operands[1]) != 0)))
- {
- rtx temp = force_reg (HImode, operands[1]);
- emit_move_insn (operands[0], temp);
- DONE;
- }
- }
-)
-
-(define_insn "*movhi_internal2"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m")
- (match_operand:HI 1 "general_operand" "I,d,R,m,dJ,dJ"))]
- ""
- "@
- addik\t%0,r0,%1\t# %X1
- addk\t%0,%1,r0
- lhui\t%0,%1
- lhui\t%0,%1
- sh%i0\t%z1,%0
- sh%i0\t%z1,%0"
- [(set_attr "type" "arith,move,load,no_delay_load,store,no_delay_store")
- (set_attr "mode" "HI")
- (set_attr "length" "4,4,4,8,8,8")])
-
-;; 8-bit Integer moves
-
-;; Unlike most other insns, the move insns can't be split with
-;; different predicates, because register spilling and other parts of
-;; the compiler, have memoized the insn number already.
-;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
-
-(define_expand "movqi"
- [(set (match_operand:QI 0 "nonimmediate_operand" "")
- (match_operand:QI 1 "general_operand" ""))]
- ""
- {
- if ((reload_in_progress | reload_completed) == 0
- && !register_operand (operands[0], QImode)
- && !register_operand (operands[1], QImode)
- && ((GET_CODE (operands[1]) != CONST_INT
- || INTVAL (operands[1]) != 0)))
- {
- rtx temp = force_reg (QImode, operands[1]);
- emit_move_insn (operands[0], temp);
- DONE;
- }
- }
-)
-
-(define_insn "*movqi_internal2"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m")
- (match_operand:QI 1 "general_operand" "J,I,d,R,m,dJ,dJ"))]
- ""
- "@
- addk\t%0,r0,%z1
- addik\t%0,r0,%1\t# %X1
- addk\t%0,%1,r0
- lbu%i1\t%0,%1
- lbu%i1\t%0,%1
- sb%i0\t%z1,%0
- sbi\t%z1,%0"
- [(set_attr "type" "arith,arith,move,load,no_delay_load,store,no_delay_store")
- (set_attr "mode" "QI")
- (set_attr "length" "4,4,8,4,8,4,8")])
-
-;; Block moves, see microblaze.c for more details.
-;; Argument 0 is the destination
-;; Argument 1 is the source
-;; Argument 2 is the length
-;; Argument 3 is the alignment
-
-(define_expand "movmemsi"
- [(parallel [(set (match_operand:BLK 0 "general_operand")
- (match_operand:BLK 1 "general_operand"))
- (use (match_operand:SI 2 ""))
- (use (match_operand:SI 3 "const_int_operand"))])]
- ""
- {
- if (microblaze_expand_block_move (operands[0], operands[1],
- operands[2], operands[3]))
- DONE;
- else
- FAIL;
- }
-)
-
-;; 32-bit floating point moves
-
-(define_expand "movsf"
- [(set (match_operand:SF 0 "nonimmediate_operand" "")
- (match_operand:SF 1 "general_operand" ""))]
- ""
- {
- if ((reload_in_progress | reload_completed) == 0
- && !register_operand (operands[0], SFmode)
- && !register_operand (operands[1], SFmode)
- && ( ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
- && operands[1] != CONST0_RTX (SFmode))))
- {
- rtx temp = force_reg (SFmode, operands[1]);
- emit_move_insn (operands[0], temp);
- DONE;
- }
- }
-)
-
-;; Applies to both TARGET_SOFT_FLOAT and TARGET_HARD_FLOAT
-;;
-(define_insn "*movsf_internal"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,d,d,R,m")
- (match_operand:SF 1 "general_operand" "G,d,R,F,m,d,d"))]
- "(register_operand (operands[0], SFmode)
- || register_operand (operands[1], SFmode)
- || operands[1] == CONST0_RTX (SFmode))"
- "@
- addk\t%0,r0,r0
- addk\t%0,%1,r0
- lw%i1\t%0,%1
- addik\t%0,r0,%F1
- lw%i1\t%0,%1
- sw%i0\t%z1,%0
- swi\t%z1,%0"
- [(set_attr "type" "move,no_delay_load,load,no_delay_load,no_delay_load,store,no_delay_store")
- (set_attr "mode" "SF")
- (set_attr "length" "4,4,4,4,4,4,4")])
-
-;; 64-bit floating point moves
-(define_expand "movdf"
- [(set (match_operand:DF 0 "nonimmediate_operand" "")
- (match_operand:DF 1 "general_operand" ""))]
- ""
- {
- if (flag_pic == 2) {
- if (GET_CODE (operands[1]) == MEM
- && !microblaze_legitimate_address_p (DFmode, XEXP (operands[1],0), 0))
- {
- rtx ptr_reg;
- rtx result;
- ptr_reg = force_reg (Pmode, XEXP (operands[1],0));
- result = gen_rtx_MEM (DFmode, ptr_reg);
- emit_move_insn (operands[0], result);
- DONE;
- }
- }
- if ((reload_in_progress | reload_completed) == 0
- && !register_operand (operands[0], DFmode)
- && !register_operand (operands[1], DFmode)
- && (((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
- && operands[1] != CONST0_RTX (DFmode))))
- {
- rtx temp = force_reg (DFmode, operands[1]);
- emit_move_insn (operands[0], temp);
- DONE;
- }
- }
-)
-
-;; movdf_internal
-;; Applies to both TARGET_SOFT_FLOAT and TARGET_HARD_FLOAT
-;;
-(define_insn "*movdf_internal"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,d,o")
- (match_operand:DF 1 "general_operand" "dG,o,F,T,d"))]
- ""
- {
- switch (which_alternative)
- {
- case 0:
- return "addk\t%0,r0,r0\n\taddk\t%D0,r0,r0";
- case 1:
- case 3:
- if (reg_mentioned_p (operands[0], operands[1]))
- return "lwi\t%D0,%o1\n\tlwi\t%0,%1";
- else
- return "lwi\t%0,%1\n\tlwi\t%D0,%o1";
- case 2:
- {
- return "addik\t%0,r0,%h1 \n\taddik\t%D0,r0,%j1 #Xfer Lo";
- }
- case 4:
- return "swi\t%1,%0\n\tswi\t%D1,%o0";
- }
- gcc_unreachable ();
- }
- [(set_attr "type" "no_delay_move,no_delay_load,no_delay_load,no_delay_load,no_delay_store")
- (set_attr "mode" "DF")
- (set_attr "length" "4,8,8,16,8")])
-
-(define_split
- [(set (match_operand:DF 0 "register_operand" "")
- (match_operand:DF 1 "register_operand" ""))]
- "reload_completed
- && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
- && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
- && (REGNO (operands[0]) == (REGNO (operands[1]) + 1))"
- [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))
- (set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))]
- "")
-
-(define_split
- [(set (match_operand:DF 0 "register_operand" "")
- (match_operand:DF 1 "register_operand" ""))]
- "reload_completed
- && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
- && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
- && (REGNO (operands[0]) != (REGNO (operands[1]) + 1))"
- [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
- (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
- "")
-
-;;----------------------------------------------------------------
-;; Shifts
-;;----------------------------------------------------------------
-
-;;----------------------------------------------------------------
-;; 32-bit left shifts
-;;----------------------------------------------------------------
-(define_expand "ashlsi3"
- [(set (match_operand:SI 0 "register_operand" "=&d")
- (ashift:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "arith_operand" "")))]
- ""
- {
- /* Avoid recursion for trivial cases. */
- if (!((GET_CODE (operands [2]) == CONST_INT) && (INTVAL (operands[2]) == 1)))
- if (microblaze_expand_shift (operands))
- DONE;
- }
-)
-
-;; Irrespective of if we have a barrel-shifter or not, we want to match
-;; shifts by 1 with a special pattern. When a barrel shifter is present,
-;; saves a cycle. If not, allows us to annotate the instruction for delay
-;; slot optimization
-(define_insn "*ashlsi3_byone"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ashift:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "arith_operand" "I")))]
- "(INTVAL (operands[2]) == 1)"
- "addk\t%0,%1,%1"
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")]
-)
-
-;; Barrel shift left
-(define_insn "ashlsi3_bshift"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (ashift:SI (match_operand:SI 1 "register_operand" "d,d")
- (match_operand:SI 2 "arith_operand" "I,d")))]
- "TARGET_BARREL_SHIFT"
- "@
- bslli\t%0,%1,%2
- bsll\t%0,%1,%2"
- [(set_attr "type" "bshift,bshift")
- (set_attr "mode" "SI,SI")
- (set_attr "length" "4,4")]
-)
-
-;; The following patterns apply when there is no barrel shifter present
-
-(define_insn "*ashlsi3_with_mul_delay"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ashift:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "immediate_operand" "I")))]
- "!TARGET_SOFT_MUL
- && ((1 << INTVAL (operands[2])) <= 32767 && (1 << INTVAL (operands[2])) >= -32768)"
- "muli\t%0,%1,%m2"
- ;; This MUL will not generate an imm. Can go into a delay slot.
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")]
-)
-
-(define_insn "*ashlsi3_with_mul_nodelay"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ashift:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "immediate_operand" "I")))]
- "!TARGET_SOFT_MUL"
- "muli\t%0,%1,%m2"
- ;; This MUL will generate an IMM. Cannot go into a delay slot
- [(set_attr "type" "no_delay_arith")
- (set_attr "mode" "SI")
- (set_attr "length" "8")]
-)
-
-(define_insn "*ashlsi3_with_size_opt"
- [(set (match_operand:SI 0 "register_operand" "=&d")
- (ashift:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "immediate_operand" "I")))]
- "(INTVAL (operands[2]) > 5 && optimize_size)"
- {
- operands[3] = gen_rtx_REG (SImode, MB_ABI_ASM_TEMP_REGNUM);
-
- output_asm_insn ("ori\t%3,r0,%2", operands);
- if (REGNO (operands[0]) != REGNO (operands[1]))
- output_asm_insn ("addk\t%0,%1,r0", operands);
-
- output_asm_insn ("addik\t%3,%3,-1", operands);
- output_asm_insn ("bneid\t%3,.-4", operands);
- return "addk\t%0,%0,%0";
- }
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")
- (set_attr "length" "20")]
-)
-
-(define_insn "*ashlsi3_with_rotate"
- [(set (match_operand:SI 0 "register_operand" "=&d")
- (ashift:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "immediate_operand" "I")))]
- "(INTVAL (operands[2]) > 17 && !optimize_size)"
- {
- int i, nshift;
-
- nshift = INTVAL (operands[2]);
- operands[3] = gen_int_mode (0xFFFFFFFF << nshift, SImode);
-
- /* We do one extra shift so that the first bit (carry) coming into the MSB
- will be masked out */
- output_asm_insn ("src\t%0,%1", operands);
- for (i = 0; i < (32 - nshift); i++)
- output_asm_insn ("src\t%0,%0", operands);
-
- return "andi\t%0,%0,%3";
- }
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")
- (set_attr "length" "80")]
-)
-
-(define_insn "*ashlsi_inline"
- [(set (match_operand:SI 0 "register_operand" "=&d")
- (ashift:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "immediate_operand" "I")))]
- ""
- {
- int i;
- int nshift = INTVAL (operands[2]);
- if (REGNO (operands[0]) != REGNO (operands[1]))
- output_asm_insn ("addk\t%0,r0,%1", operands);
- output_asm_insn ("addk\t%0,%1,%1", operands);
- for (i = 0; i < (nshift - 2); i++)
- output_asm_insn ("addk\t%0,%0,%0", operands);
- return "addk\t%0,%0,%0";
- }
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")
- (set_attr "length" "124")]
-)
-
-(define_insn "*ashlsi_reg"
- [(set (match_operand:SI 0 "register_operand" "=&d")
- (ashift:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "register_operand" "d")))]
- ""
- {
- operands[3] = gen_rtx_REG (SImode, MB_ABI_ASM_TEMP_REGNUM);
- output_asm_insn ("andi\t%3,%2,31", operands);
- if (REGNO (operands[0]) != REGNO (operands[1]))
- output_asm_insn ("addk\t%0,r0,%1", operands);
- /* Exit the loop if zero shift. */
- output_asm_insn ("beqid\t%3,.+20", operands);
- /* Emit the loop. */
- output_asm_insn ("addk\t%0,%0,r0", operands);
- output_asm_insn ("addik\t%3,%3,-1", operands);
- output_asm_insn ("bneid\t%3,.-4", operands);
- return "addk\t%0,%0,%0";
- }
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")
- (set_attr "length" "28")]
-)
-
-
-;;----------------------------------------------------------------
-;; 32-bit right shifts
-;;----------------------------------------------------------------
-(define_expand "ashrsi3"
- [(set (match_operand:SI 0 "register_operand" "=&d")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "arith_operand" "")))]
- ""
- {
- /* Avoid recursion for trivial cases. */
- if (!((GET_CODE (operands [2]) == CONST_INT) && (INTVAL (operands[2]) == 1)))
- if (microblaze_expand_shift (operands))
- DONE;
- }
-)
-
-;; Irrespective of if we have a barrel-shifter or not, we want to match
-;; shifts by 1 with a special pattern. When a barrel shifter is present,
-;; saves a cycle. If not, allows us to annotate the instruction for delay
-;; slot optimization
-(define_insn "*ashrsi3_byone"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "arith_operand" "I")))]
- "(INTVAL (operands[2]) == 1)"
- "sra\t%0,%1"
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")]
-)
-
-;; Barrel shift right logical
-(define_insn "*ashrsi3_bshift"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "d,d")
- (match_operand:SI 2 "arith_operand" "I,d")))]
- "TARGET_BARREL_SHIFT"
- "@
- bsrai\t%0,%1,%2
- bsra\t%0,%1,%2"
- [(set_attr "type" "bshift,bshift")
- (set_attr "mode" "SI,SI")
- (set_attr "length" "4,4")]
-)
-
-(define_insn "*ashrsi_inline"
- [(set (match_operand:SI 0 "register_operand" "=&d")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "immediate_operand" "I")))]
- ""
- {
- int i;
- int nshift = INTVAL (operands[2]);
- if (REGNO (operands[0]) != REGNO (operands[1]))
- output_asm_insn ("addk\t%0,r0,%1", operands);
- output_asm_insn ("sra\t%0,%1", operands);
- for (i = 0; i < (nshift - 2); i++)
- output_asm_insn ("sra\t%0,%0", operands);
- return "sra\t%0,%0";
- }
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")
- (set_attr "length" "124")]
-)
-
-(define_insn "*ashlri_reg"
- [(set (match_operand:SI 0 "register_operand" "=&d")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "register_operand" "d")))]
- ""
- {
- operands[3] = gen_rtx_REG (SImode, MB_ABI_ASM_TEMP_REGNUM);
- output_asm_insn ("andi\t%3,%2,31", operands);
- if (REGNO (operands[0]) != REGNO (operands[1]))
- output_asm_insn ("addk\t%0,r0,%1", operands);
- /* Exit the loop if zero shift. */
- output_asm_insn ("beqid\t%3,.+20", operands);
- /* Emit the loop. */
- output_asm_insn ("addk\t%0,%0,r0", operands);
- output_asm_insn ("addik\t%3,%3,-1", operands);
- output_asm_insn ("bneid\t%3,.-4", operands);
- return "sra\t%0,%0";
- }
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")
- (set_attr "length" "28")]
-)
-
-;;----------------------------------------------------------------
-;; 32-bit right shifts (logical)
-;;----------------------------------------------------------------
-
-(define_expand "lshrsi3"
- [(set (match_operand:SI 0 "register_operand" "=&d")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "arith_operand" "")))]
- ""
- {
- /* Avoid recursion for trivial cases. */
- if (!((GET_CODE (operands [2]) == CONST_INT) && (INTVAL (operands[2]) == 1)))
- if (microblaze_expand_shift (operands))
- DONE;
- }
-)
-
-;; Irrespective of if we have a barrel-shifter or not, we want to match
-;; shifts by 1 with a special pattern. When a barrel shifter is present,
-;; saves a cycle. If not, allows us to annotate the instruction for delay
-;; slot optimization
-(define_insn "*lshrsi3_byone"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "arith_operand" "I")))]
- "(INTVAL (operands[2]) == 1)"
- "srl\t%0,%1"
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")]
-)
-
-;; Barrel shift right logical
-(define_insn "*lshrsi3_bshift"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "d,d")
- (match_operand:SI 2 "arith_operand" "I,d")))]
- "TARGET_BARREL_SHIFT"
- "@
- bsrli\t%0,%1,%2
- bsrl\t%0,%1,%2"
- [(set_attr "type" "bshift,bshift")
- (set_attr "mode" "SI,SI")
- (set_attr "length" "4,4")]
-)
-
-(define_insn "*lshrsi_inline"
- [(set (match_operand:SI 0 "register_operand" "=&d")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "immediate_operand" "I")))]
- ""
- {
- int i;
- int nshift = INTVAL (operands[2]);
- if (REGNO (operands[0]) != REGNO (operands[1]))
- output_asm_insn ("addk\t%0,r0,%1", operands);
- output_asm_insn ("srl\t%0,%1", operands);
- for (i = 0; i < (nshift - 2); i++)
- output_asm_insn ("srl\t%0,%0", operands);
- return "srl\t%0,%0";
- }
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")
- (set_attr "length" "124")]
-)
-
-(define_insn "*lshlri_reg"
- [(set (match_operand:SI 0 "register_operand" "=&d")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "register_operand" "d")))]
- ""
- {
- operands[3] = gen_rtx_REG (SImode, MB_ABI_ASM_TEMP_REGNUM);
- output_asm_insn ("andi\t%3,%2,31", operands);
- if (REGNO (operands[0]) != REGNO (operands[1]))
- output_asm_insn ("addk\t%0,r0,%1", operands);
- /* Exit the loop if zero shift. */
- output_asm_insn ("beqid\t%3,.+20", operands);
- /* Emit the loop. */
- output_asm_insn ("addk\t%0,%0,r0", operands);
- output_asm_insn ("addik\t%3,%3,-1", operands);
- output_asm_insn ("bneid\t%3,.-4", operands);
- return "srl\t%0,%0";
- }
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")
- (set_attr "length" "28")]
-)
-
-;;----------------------------------------------------------------
-;; Setting a register from an integer comparison.
-;;----------------------------------------------------------------
-(define_expand "cstoresi4"
- [(set (match_operand:SI 0 "register_operand")
- (match_operator:SI 1 "ordered_comparison_operator"
- [(match_operand:SI 2 "register_operand")
- (match_operand:SI 3 "register_operand")]))]
- "TARGET_PATTERN_COMPARE"
- "if (GET_CODE (operand1) != EQ && GET_CODE (operand1) != NE)
- FAIL;
- "
-)
-
-(define_insn "seq_internal_pat"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (eq:SI
- (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "register_operand" "d")))]
- "TARGET_PATTERN_COMPARE"
- "pcmpeq\t%0,%1,%2"
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")]
-)
-
-(define_insn "sne_internal_pat"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ne:SI
- (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "register_operand" "d")))]
- "TARGET_PATTERN_COMPARE"
- "pcmpne\t%0,%1,%2"
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")]
-)
-
-(define_insn "signed_compare"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (unspec
- [(match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "register_operand" "d")] UNSPEC_CMP))]
- ""
- "cmp\t%0,%1,%2"
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")])
-
-(define_insn "unsigned_compare"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (unspec
- [(match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "register_operand" "d")] UNSPEC_CMPU))]
- ""
- "cmpu\t%0,%1,%2"
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")])
-
-;;----------------------------------------------------------------
-;; Setting a register from an floating point comparison.
-;;----------------------------------------------------------------
-(define_insn "cstoresf4"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operator 1 "comparison_operator"
- [(match_operand:SF 2 "register_operand" "r")
- (match_operand:SF 3 "register_operand" "r")]))]
- "TARGET_HARD_FLOAT"
- "fcmp.%C1\t%0,%3,%2"
- [(set_attr "type" "fcmp")
- (set_attr "mode" "SF")
- (set_attr "length" "4")]
-)
-
-;;----------------------------------------------------------------
-;; Conditional branches
-;;----------------------------------------------------------------
-
-(define_expand "cbranchsi4"
- [(set (pc)
- (if_then_else (match_operator 0 "ordered_comparison_operator"
- [(match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "arith_operand")])
- (label_ref (match_operand 3 ""))
- (pc)))]
- ""
-{
- microblaze_expand_conditional_branch (SImode, operands);
- DONE;
-})
-
-(define_expand "cbranchsf4"
- [(set (pc)
- (if_then_else (match_operator 0 "comparison_operator"
- [(match_operand:SF 1 "register_operand")
- (match_operand:SF 2 "register_operand")])
- (label_ref (match_operand 3 ""))
- (pc)))]
- "TARGET_HARD_FLOAT"
-{
- microblaze_expand_conditional_branch_sf (operands);
- DONE;
-
-})
-
-;; Used to implement comparison instructions
-(define_expand "condjump"
- [(set (pc)
- (if_then_else (match_operand 0)
- (label_ref (match_operand 1))
- (pc)))])
-
-(define_insn "branch_zero"
- [(set (pc)
- (if_then_else (match_operator:SI 0 "ordered_comparison_operator"
- [(match_operand:SI 1 "register_operand" "d")
- (const_int 0)])
- (match_operand:SI 2 "pc_or_label_operand" "")
- (match_operand:SI 3 "pc_or_label_operand" "")))
- ]
- ""
- {
- if (operands[3] == pc_rtx)
- return "b%C0i%?\t%z1,%2";
- else
- return "b%N0i%?\t%z1,%3";
- }
- [(set_attr "type" "branch")
- (set_attr "mode" "none")
- (set_attr "length" "4")]
-)
-
-;;----------------------------------------------------------------
-;; Unconditional branches
-;;----------------------------------------------------------------
-(define_insn "jump"
- [(set (pc)
- (label_ref (match_operand 0 "" "")))]
- ""
- {
- if (GET_CODE (operands[0]) == REG)
- return "br%?\t%0";
- else
- return "bri%?\t%l0";
- }
- [(set_attr "type" "jump")
- (set_attr "mode" "none")
- (set_attr "length" "4")])
-
-(define_expand "indirect_jump"
- [(set (pc) (match_operand 0 "register_operand" "d"))]
- ""
- {
- rtx dest = operands[0];
- if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
- operands[0] = copy_to_mode_reg (Pmode, dest);
-
- emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
- DONE;
- }
-)
-
-;; Indirect jumps. Jump to register values. Assuming absolute jumps
-
-(define_insn "indirect_jump_internal1"
- [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
- ""
- "bra%?\t%0"
- [(set_attr "type" "jump")
- (set_attr "mode" "none")
- (set_attr "length" "4")])
-
-(define_expand "tablejump"
- [(set (pc)
- (match_operand 0 "register_operand" "d"))
- (use (label_ref (match_operand 1 "" "")))]
- ""
- {
- gcc_assert (GET_MODE (operands[0]) == Pmode);
-
- if (!flag_pic)
- emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
- else
- emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
- DONE;
- }
-)
-
-(define_insn "tablejump_internal1"
- [(set (pc)
- (match_operand:SI 0 "register_operand" "d"))
- (use (label_ref (match_operand 1 "" "")))]
- ""
- "bra%?\t%0 "
- [(set_attr "type" "jump")
- (set_attr "mode" "none")
- (set_attr "length" "4")])
-
-(define_expand "tablejump_internal3"
- [(parallel [(set (pc)
- (plus:SI (match_operand:SI 0 "register_operand" "d")
- (label_ref:SI (match_operand:SI 1 "" ""))))
- (use (label_ref:SI (match_dup 1)))])]
- ""
- ""
-)
-
-;; need to change for MicroBlaze PIC
-(define_insn ""
- [(set (pc)
- (plus:SI (match_operand:SI 0 "register_operand" "d")
- (label_ref:SI (match_operand 1 "" ""))))
- (use (label_ref:SI (match_dup 1)))]
- "next_active_insn (insn) != 0
- && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
- && PREV_INSN (next_active_insn (insn)) == operands[1]
- && flag_pic"
- {
- output_asm_insn ("addk\t%0,%0,r20",operands);
- return "bra%?\t%0";
-}
- [(set_attr "type" "jump")
- (set_attr "mode" "none")
- (set_attr "length" "4")])
-
-(define_expand "tablejump_internal4"
- [(parallel [(set (pc)
- (plus:DI (match_operand:DI 0 "register_operand" "d")
- (label_ref:DI (match_operand:SI 1 "" ""))))
- (use (label_ref:DI (match_dup 1)))])]
- ""
- ""
-)
-
-;;----------------------------------------------------------------
-;; Function prologue/epilogue and stack allocation
-;;----------------------------------------------------------------
-(define_expand "prologue"
- [(const_int 1)]
- ""
- {
- microblaze_expand_prologue ();
- DONE;
- }
-)
-
-(define_expand "epilogue"
- [(use (const_int 0))]
- ""
- {
- microblaze_expand_epilogue ();
- DONE;
- }
-)
-
-;; An insn to allocate new stack space for dynamic use (e.g., alloca).
-;; We copy the return address, decrement the stack pointer and save the
-;; return address again at the new stack top
-
-(define_expand "allocate_stack"
- [(set (match_operand 0 "register_operand" "=r")
- (minus (reg 1) (match_operand 1 "register_operand" "")))
- (set (reg 1)
- (minus (reg 1) (match_dup 1)))]
- ""
- {
- rtx retaddr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
- rtx rtmp = gen_rtx_REG (SImode, R_TMP);
- rtx neg_op0;
-
- emit_move_insn (rtmp, retaddr);
- if (GET_CODE (operands[1]) != CONST_INT)
- {
- neg_op0 = gen_reg_rtx (Pmode);
- emit_insn (gen_negsi2 (neg_op0, operands[1]));
- } else
- neg_op0 = GEN_INT (- INTVAL (operands[1]));
-
- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, neg_op0));
- emit_move_insn (gen_rtx_MEM (Pmode, stack_pointer_rtx), rtmp);
- emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
- emit_insn (gen_rtx_CLOBBER (SImode, rtmp));
- DONE;
- }
-)
-
-(define_expand "save_stack_block"
- [(match_operand 0 "register_operand" "")
- (match_operand 1 "register_operand" "")]
- ""
- {
- emit_move_insn (operands[0], operands[1]);
- DONE;
- }
-)
-
-(define_expand "restore_stack_block"
- [(match_operand 0 "register_operand" "")
- (match_operand 1 "register_operand" "")]
- ""
- {
- rtx retaddr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
- rtx rtmp = gen_rtx_REG (SImode, R_TMP);
-
- /* Move the retaddr. */
- emit_move_insn (rtmp, retaddr);
- emit_move_insn (operands[0], operands[1]);
- emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), rtmp);
- DONE;
- }
-)
-
-;; Trivial return. Make it look like a normal return insn as that
-;; allows jump optimizations to work better .
-(define_expand "return"
- [(simple_return)]
- "microblaze_can_use_return_insn ()"
- {}
-)
-
-(define_expand "simple_return"
- [(simple_return)]
- ""
- {}
-)
-
-(define_insn "*<optab>"
- [(any_return)]
- ""
- {
- if (microblaze_is_interrupt_variant ())
- return "rtid\tr14, 0\;%#";
- else
- return "rtsd\tr15, 8\;%#";
- }
- [(set_attr "type" "jump")
- (set_attr "mode" "none")
- (set_attr "length" "4")]
-)
-
-;; Normal return.
-
-(define_insn "<optab>_internal"
- [(any_return)
- (use (match_operand:SI 0 "register_operand" ""))]
- ""
- {
- if (microblaze_is_interrupt_variant ())
- return "rtid\tr14,0 \;%#";
- else
- return "rtsd\tr15,8 \;%#";
- }
- [(set_attr "type" "jump")
- (set_attr "mode" "none")
- (set_attr "length" "4")])
-
-
-;; Block any insns from across this point
-;; Useful to group sequences together.
-(define_insn "blockage"
- [(unspec_volatile [(const_int 0)] 0)]
- ""
- ""
- [(set_attr "type" "unknown")
- (set_attr "mode" "none")
- (set_attr "length" "0")])
-
-
-;;----------------------------------------------------------------
-;; Function calls
-;;----------------------------------------------------------------
-
-(define_expand "call"
- [(parallel [(call (match_operand 0 "memory_operand" "m")
- (match_operand 1 "" "i"))
- (clobber (reg:SI R_SR))
- (use (match_operand 2 "" ""))
- (use (match_operand 3 "" ""))])]
- ""
- {
- rtx addr = XEXP (operands[0], 0);
-
- if (flag_pic == 2 && GET_CODE (addr) == SYMBOL_REF
- && !SYMBOL_REF_LOCAL_P (addr))
- {
- rtx temp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PLT);
- XEXP (operands[0], 0) = temp;
- }
-
- if ((GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr))
- || !call_insn_operand (addr, VOIDmode))
- XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
-
- if (GET_CODE (XEXP (operands[0], 0)) == UNSPEC)
- emit_call_insn (gen_call_internal_plt0 (operands[0], operands[1],
- gen_rtx_REG (SImode,
- GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM),
- pic_offset_table_rtx));
- else
- emit_call_insn (gen_call_internal0 (operands[0], operands[1],
- gen_rtx_REG (SImode,
- GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM)));
-
- DONE;
- }
-)
-
-(define_expand "call_internal0"
- [(parallel [(call (match_operand 0 "" "")
- (match_operand 1 "" ""))
- (clobber (match_operand:SI 2 "" ""))])]
- ""
- {
- }
-)
-
-(define_expand "call_internal_plt0"
- [(parallel [(call (match_operand 0 "" "")
- (match_operand 1 "" ""))
- (clobber (match_operand:SI 2 "" ""))
- (use (match_operand:SI 3 "" ""))])]
- ""
- {
- }
-)
-
-(define_insn "call_internal_plt"
- [(call (mem (match_operand:SI 0 "call_insn_plt_operand" ""))
- (match_operand:SI 1 "" "i"))
- (clobber (reg:SI R_SR))
- (use (reg:SI R_GOT))]
- "flag_pic"
- {
- register rtx target2 = gen_rtx_REG (Pmode,
- GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
- gen_rtx_CLOBBER (VOIDmode, target2);
- return "brlid\tr15,%0\;%#";
- }
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "4")])
-
-(define_insn "call_internal1"
- [(call (mem (match_operand:SI 0 "call_insn_simple_operand" "ri"))
- (match_operand:SI 1 "" "i"))
- (clobber (reg:SI R_SR))]
- ""
- {
- register rtx target = operands[0];
- register rtx target2 = gen_rtx_REG (Pmode,
- GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
- if (GET_CODE (target) == SYMBOL_REF) {
- gen_rtx_CLOBBER (VOIDmode, target2);
- return "brlid\tr15,%0\;%#";
- } else if (GET_CODE (target) == CONST_INT)
- return "la\t%@,r0,%0\;brald\tr15,%@\;%#";
- else if (GET_CODE (target) == REG)
- return "brald\tr15,%0\;%#";
- else {
- fprintf (stderr,"Unsupported call insn\n");
- return NULL;
- }
- }
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "4")])
-
-;; calls.c now passes a fourth argument, make saber happy
-
-(define_expand "call_value"
- [(parallel [(set (match_operand 0 "register_operand" "=d")
- (call (match_operand 1 "memory_operand" "m")
- (match_operand 2 "" "i")))
- (clobber (reg:SI R_SR))
- (use (match_operand 3 "" ""))])] ;; next_arg_reg
- ""
- {
- rtx addr = XEXP (operands[1], 0);
-
- if (flag_pic == 2 && GET_CODE (addr) == SYMBOL_REF
- && !SYMBOL_REF_LOCAL_P (addr))
- {
- rtx temp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PLT);
- XEXP (operands[1], 0) = temp;
- }
-
- if ((GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr))
- || !call_insn_operand (addr, VOIDmode))
- XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
-
- if (GET_CODE (XEXP (operands[1], 0)) == UNSPEC)
- emit_call_insn (gen_call_value_intern_plt0 (operands[0], operands[1],
- operands[2],
- gen_rtx_REG (SImode,
- GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM),
- pic_offset_table_rtx));
- else
- emit_call_insn (gen_call_value_internal (operands[0], operands[1],
- operands[2],
- gen_rtx_REG (SImode,
- GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM)));
-
- DONE;
- }
-)
-
-
-(define_expand "call_value_internal"
- [(parallel [(set (match_operand 0 "" "")
- (call (match_operand 1 "" "")
- (match_operand 2 "" "")))
- (clobber (match_operand:SI 3 "" ""))
- ])]
- ""
- {}
-)
-
-(define_expand "call_value_intern_plt0"
- [(parallel[(set (match_operand 0 "" "")
- (call (match_operand 1 "" "")
- (match_operand 2 "" "")))
- (clobber (match_operand:SI 3 "" ""))
- (use (match_operand:SI 4 "" ""))])]
- "flag_pic"
- {}
-)
-
-(define_insn "call_value_intern_plt"
- [(set (match_operand:VOID 0 "register_operand" "=d")
- (call (mem (match_operand:SI 1 "call_insn_plt_operand" ""))
- (match_operand:SI 2 "" "i")))
- (clobber (match_operand:SI 3 "register_operand" "=d"))
- (use (match_operand:SI 4 "register_operand"))]
- "flag_pic"
- {
- register rtx target2=gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
-
- gen_rtx_CLOBBER (VOIDmode,target2);
- return "brlid\tr15,%1\;%#";
- }
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "4")])
-
-(define_insn "call_value_intern"
- [(set (match_operand:VOID 0 "register_operand" "=d")
- (call (mem (match_operand:VOID 1 "call_insn_operand" "ri"))
- (match_operand:SI 2 "" "i")))
- (clobber (match_operand:SI 3 "register_operand" "=d"))]
- ""
- {
- register rtx target = operands[1];
- register rtx target2=gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
-
- if (GET_CODE (target) == SYMBOL_REF)
- {
- gen_rtx_CLOBBER (VOIDmode,target2);
- if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
- {
- return "brlid\tr15,%1\;%#";
- }
- else
- {
- return "bralid\tr15,%1\;%#";
- }
- }
- else if (GET_CODE (target) == CONST_INT)
- return "la\t%@,r0,%1\;brald\tr15,%@\;%#";
- else if (GET_CODE (target) == REG)
- return "brald\tr15,%1\;%#";
- else
- return "Unsupported call insn\n";
- }
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "4")])
-
-
-;; Call subroutine returning any type.
-(define_expand "untyped_call"
- [(parallel [(call (match_operand 0 "" "")
- (const_int 0))
- (match_operand 1 "" "")
- (match_operand 2 "" "")])]
- ""
- {
- if (operands[0]) /* silence statement not reached warnings */
- {
- int i;
-
- emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
-
- for (i = 0; i < XVECLEN (operands[2], 0); i++)
- {
- rtx set = XVECEXP (operands[2], 0, i);
- emit_move_insn (SET_DEST (set), SET_SRC (set));
- }
-
- emit_insn (gen_blockage ());
- DONE;
- }
- }
-)
-
-;;----------------------------------------------------------------
-;; Misc.
-;;----------------------------------------------------------------
-
-(define_insn "nop"
- [(const_int 0)]
- ""
- "nop"
- [(set_attr "type" "nop")
- (set_attr "mode" "none")
- (set_attr "length" "4")])
-
-;; The insn to set GOT. The hardcoded number "8" accounts for $pc difference
-;; between "mfs" and "addik" instructions.
-(define_insn "set_got"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))]
- ""
- "mfs\t%0,rpc\n\taddik\t%0,%0,_GLOBAL_OFFSET_TABLE_+8"
- [(set_attr "type" "multi")
- (set_attr "length" "12")])
-
-;; This insn gives the count of leading number of zeros for the second
-;; operand and stores the result in first operand.
-(define_insn "clzsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (clz:SI (match_operand:SI 1 "register_operand" "r")))]
- "TARGET_HAS_CLZ"
- "clz\t%0,%1"
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "4")])