mep.md 64 KB

;; Toshiba Media Processor Machine description template ;; Copyright (C) 2001-2015 Free Software Foundation, Inc. ;; Contributed by Red Hat Inc ;; ;; 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/. */

;; Constraints: ;; ;; a $sp ;; b $tp ;; c control regs ;; h $hi ($23) ;; l $lo ($24) ;; d $hi/$lo pair (DImode) ;; j $rpc ($22) ;; r $0..$15 ;; t $0..$7 ;; v $gp ;; x $c0..$c31 ;; ex coprocessor registers that can be moved to other coprocessor registers ;; er coprocessor registers that can be moved to and from core registers ;; em coprocessor registers that can be moves to and from memory ;; y $ccr0..$ccr31 ;; z $0 ;; ;; I sign imm16 mov/add ;; J zero imm16 mov/add ;; K zero imm24 mov ;; L sign imm6 add ;; M zero imm5 slt,shifts ;; N zero imm4 bCC ;; O high imm16 mov ;; ;; R near symbol ;; S sign imm8 mov ;; T tp or gp relative symbol ;; U non-absolute memory ;; W %hi(sym) ;; Y (Rn) ;; Z Control Bus Symbol ;; ;; Modifiers: ;; ;; b print unique bit in mask ;; B print bits required for value (for clip) ;; h print decimal >> 16. ;; I print decimal, with hex comment if more than 8 bits ;; J print unsigned hex ;; L print set, clr or not (for bitops) ;; P print memory as a post-inc with no increment ;; U print bits required for value (for clipu) ;; x print unsigned decimal or hex, depending on where set bits are

(define_constants [

       (REGSAVE_CONTROL_TEMP 11)
       (FP_REGNO 8)
       (TP_REGNO 13)
       (GP_REGNO 14)
       (SP_REGNO 15)
       (PSW_REGNO 16)
       (LP_REGNO 17)
       (SAR_REGNO 18)
       (RPB_REGNO 20)
       (RPE_REGNO 21)
       (RPC_REGNO 22)
       (HI_REGNO 23)
       (LO_REGNO 24)
       (CBCR_REGNO 81)
       ])

(define_constants [

       (UNS_BLOCKAGE 0)
       (UNS_TPREL 2)
       (UNS_GPREL 3)
       (UNS_REPEAT_BEG 4)
       (UNS_REPEAT_END 5)
       (UNS_EH_EPILOGUE 6)
       (UNS_EREPEAT_BEG 7)
       (UNS_EREPEAT_END 8)
       (UNS_BB_TRACE_RET 9)
       (UNS_DISABLE_INT 10)
       (UNS_ENABLE_INT 11)
       (UNS_RETI 12)
      ])

;; This attribute determines the VLIW packing mechanism. The IVC2 ;; coprocessor has two pipelines (P0 and P1), and a MeP+IVC2 can issue ;; up to three insns at a time. Most IVC2 insns can run on either ;; pipeline, however, scheduling some insns on P0 precludes packing a ;; core insn with it, and only 16-bit core insns can pack with any P0 ;; insn. (define_attr "vliw" "basic,ivc2" (const (symbol_ref "TARGET_IVC2")))

;; This attribute describes the kind of memory operand present in the ;; instruction. This is used to compute the length of the insn based ;; on the addressing mode used. (define_attr "memop" "none,core0,core1,cop0,cop1" (const_string "none"))

(define_attr "intrinsic" "none,cmov,cmov1,cmov2,cmovc1,cmovc2,cmovh1,cmovh2" (const_string "none"))

;; This attribute describes how the instruction may be bundled in a ;; VLIW instruction. Type MULTI is assumed to use both slots. (define_attr "slot" "core,cop,multi" (cond [(eq_attr "intrinsic" "!none")

   (const_string "cop")]
(const_string "core")))

;; This attribute describes the latency of the opcode (ready delay). ;; The 0 is used to indicate "unspecified". An instruction that ;; completes immediately with no potential stalls would have a value ;; of 1, a one cycle stall would be 2, etc. (define_attr "latency" "" (const_int 0))

(define_attr "shiftop" "none,operand2" (const_string "none"))

;; This attribute describes the size of the instruction in bytes. ;; This must be exact unless the pattern is SLOT_MULTI, as this ;; is used by the VLIW bundling code. (define_attr "length" "" (cond [(eq_attr "memop" "core0")

   (symbol_ref "mep_core_address_length (insn, 0)")
 (eq_attr "memop" "core1")
   (symbol_ref "mep_core_address_length (insn, 1)")
 (eq_attr "memop" "cop0")
   (symbol_ref "mep_cop_address_length (insn, 0)")
 (eq_attr "memop" "cop1")
   (symbol_ref "mep_cop_address_length (insn, 1)")
     ]
 ; Catch patterns that don't define the length properly.
     (symbol_ref "(abort (), 0)")))

;; This attribute describes a pipeline hazard seen in the insn. (define_attr "stall" "none,int2,ssarb,load,store,ldc,stc,ldcb,stcb,ssrab,fsft,ret,advck,mul,mulr,div" (cond [(and (eq_attr "shiftop" "operand2")

      (not (match_operand:SI 2 "mep_single_shift_operand" "")))
 (const_string "int2")]
(const_string "none")))

(define_attr "may_trap" "no,yes" (const_string "no"))

;; Describe a user's asm statement. (define_asm_attributes [(set_attr "length" "4") (set_attr "slot" "multi")])

;; Each IVC2 instruction uses one of these two pipelines. P0S insns ;; use P0; C3 insns use P1. (define_automaton "mep_ivc2") (define_cpu_unit "ivc2_core,ivc2_p0,ivc2_p1" "mep_ivc2")

;; Each core or IVC2 instruction is bundled into one of these slots. ;; Supported bundlings: ;; ;; Core mode: ;; ;; C1 [-----core-----] ;; C2 [-------------core-------------] ;; C3 [--------------c3--------------] ;; ;; VLIW mode: ;; ;; V1 [-----core-----][--------p0s-------][------------p1------------] ;; V2 [-------------core-------------]xxxx[------------p1------------] ;; V3 1111[--p0--]0111[--------p0--------][------------p1------------]

(define_attr "slots" "core,c3,p0,p0_p0s,p0_p1,p0s,p0s_p1,p1" (const_string "core"))

(define_cpu_unit "ivc2_slot_c16,ivc2_slot_c32,ivc2_slot_c3,ivc2_slot_p0s,ivc2_slot_p0,ivc2_slot_p1" "mep_ivc2")

(define_insn_reservation "ivc2_insn_core16" 1 (and (eq_attr "vliw" "ivc2")

   (and (eq (symbol_ref "get_attr_length(insn)") (const_int 2))
    (and (eq_attr "intrinsic" "none")
     (eq_attr "slot" "!cop"))))

"ivc2_core+ivc2_slot_c16")

(define_insn_reservation "ivc2_insn_core32" 1 (and (eq_attr "vliw" "ivc2")

   (and (eq (symbol_ref "get_attr_length(insn)") (const_int 4))
    (and (eq_attr "intrinsic" "none")
     (eq_attr "slot" "!cop"))))

"ivc2_core+ivc2_slot_c32")

;; These shouldn't happen when in VLIW mode. (define_insn_reservation "ivc2_insn_c3" 1 (and (eq_attr "vliw" "ivc2")

   (eq_attr "slots" "c3"))

"ivc2_p1+ivc2_slot_c3")

(define_insn_reservation "ivc2_insn_p0" 1 (and (eq_attr "vliw" "ivc2")

   (eq_attr "slots" "p0"))

"ivc2_p0+ivc2_slot_p0")

(define_insn_reservation "ivc2_insn_p0_p0s" 1 (and (eq_attr "vliw" "ivc2")

   (eq_attr "slots" "p0_p0s"))

"ivc2_p0+ivc2_slot_p0|ivc2_p0+ivc2_slot_p0s")

(define_insn_reservation "ivc2_insn_p0_p1" 1 (and (eq_attr "vliw" "ivc2")

   (eq_attr "slots" "p0_p1"))

"ivc2_p0+ivc2_slot_p0|ivc2_p1+ivc2_slot_p1")

(define_insn_reservation "ivc2_insn_p0s" 1 (and (eq_attr "vliw" "ivc2")

   (eq_attr "slots" "p0s"))

"ivc2_p0+ivc2_slot_p0s")

(define_insn_reservation "ivc2_insn_p0s_p1" 1 (and (eq_attr "vliw" "ivc2")

   (eq_attr "slots" "p0s_p1"))

"ivc2_p0+ivc2_slot_p0s|ivc2_p1+ivc2_slot_p1")

(define_insn_reservation "ivc2_insn_p1" 1 (and (eq_attr "vliw" "ivc2")

   (eq_attr "slots" "p1"))

"ivc2_p1+ivc2_slot_p1")

;; these run in C3 also, but when we're doing VLIW scheduling, they ;; only run in P0. (define_insn_reservation "ivc2_insn_cmov" 1 (and (eq_attr "vliw" "ivc2")

   (eq_attr "intrinsic" "!none"))

"ivc2_p0+ivc2_slot_p0")

(exclusion_set "ivc2_slot_c32"

       "ivc2_slot_p0,ivc2_slot_p0s")

(exclusion_set "ivc2_slot_p0"

       "ivc2_slot_p0s")

(exclusion_set "ivc2_slot_c16"

       "ivc2_slot_p0")

(exclusion_set "ivc2_slot_c16"

       "ivc2_slot_c32")

;; Non-IVC2 scheduling. (define_automaton "mep") (define_cpu_unit "core,cop" "mep")

;; Latencies are the time between one insn entering the second pipeline ;; stage (E2, LD, A2 or V2) and the next instruction entering the same ;; stage. When an instruction assigns to general registers, the default ;; latencies are for when the next instruction receives the register ;; through bypass 1.

;; Arithmetic instructions that execute in a single stage. (define_insn_reservation "h1_int1" 2 (and (eq_attr "slot" "!cop")

   (eq_attr "stall" "none"))

"core") (define_bypass 1 "h1_int1" "h1_int1,h1_ssarb") (define_bypass 1 "h1_int1" "h1_store" "mep_store_data_bypass_p")

;; $sar can be read by an immediately following fsft or ldc. (define_insn_reservation "h1_ssarb" 1 (eq_attr "stall" "ssarb") "core")

;; Arithmetic instructions that execute in two stages. (define_insn_reservation "h1_int2" 2 (eq_attr "stall" "int2,fsft") "core") (define_bypass 1 "h1_int2" "h1_int1,h1_ssarb") (define_bypass 1 "h1_int2" "h1_store" "mep_store_data_bypass_p")

(define_insn_reservation "h1_load" 4 (eq_attr "stall" "load") "core") (define_bypass 3 "h1_load" "h1_int1,h1_ssarb") (define_bypass 3 "h1_load" "h1_store" "mep_store_data_bypass_p")

(define_insn_reservation "h1_store" 1 (eq_attr "stall" "store") "core")

(define_insn_reservation "h1_ipipe_ldc" 2 (and (eq_attr "stall" "ldc")

   (ne (symbol_ref "mep_ipipe_ldc_p(insn)") (const_int 0)))

"core") (define_bypass 1 "h1_ipipe_ldc" "h1_int1,h1_ssarb") (define_bypass 1 "h1_ipipe_ldc" "h1_store" "mep_store_data_bypass_p")

(define_insn_reservation "h1_apipe_ldc" 2 (and (eq_attr "stall" "ldc")

   (eq (symbol_ref "mep_ipipe_ldc_p(insn)") (const_int 0)))

"core")

;; 2 is correct for stc->ret and stc->fsft. The most important remaining ;; case is stc->madd, which induces no stall. (define_insn_reservation "h1_stc" 2 (eq_attr "stall" "stc") "core") (define_bypass 1 "h1_stc" "h1_mul")

;; ??? Parameterised latency. (define_insn_reservation "h1_ldcb" 5 (eq_attr "stall" "ldcb") "core")

(define_insn_reservation "h1_stcb" 1 (eq_attr "stall" "stcb") "core")

(define_insn_reservation "h1_advck" 6 (eq_attr "stall" "advck") "core")

(define_insn_reservation "h1_mul" 5 (eq_attr "stall" "mul,mulr") "core") (define_bypass 4 "h1_mul" "h1_int1,h1_ssarb") (define_bypass 4 "h1_mul" "h1_store" "mep_store_data_bypass_p") (define_bypass 1 "h1_mul" "h1_mul" "mep_mul_hilo_bypass_p")

(define_insn_reservation "h1_div" 36 (eq_attr "stall" "div") "core")

(define_insn_reservation "h1_cop" 1 (eq_attr "slot" "cop") "cop") (include "predicates.md") (include "constraints.md") (include "intrinsics.md") ;; :::::::::::::::::::: ;; :: ;; :: Moves ;; :: ;; ::::::::::::::::::::

(define_expand "movqi" [(set (match_operand:QI 0 "general_operand" "")

(match_operand:QI 1 "general_operand" ""))]

"" " { if (mep_expand_mov (operands, QImode))

DONE;

}")

;; The Idea here is to prefer the 16-bit tp-relative load, but to fall back ;; to the general 32-bit load rather than do silly things with spill regs. (define_insn "*movqi_tprel_load" [(set (match_operand:QI 0 "mep_tprel_operand" "=t,*r")

(mem:QI (plus:SI (match_operand:SI 1 "mep_tp_operand" "b,*r")
         (const:SI (unspec:SI [(match_operand:SI 2
                    "symbolic_operand" "s,s")]
                      UNS_TPREL)))))]

"" "lb\t%0, %%tpoff(%2)(%1)" [(set_attr "length" "2,4") (set_attr "stall" "load")])

(define_insn "*movqi_tprel_store" [(set (mem:QI (plus:SI (match_operand:SI 0 "mep_tp_operand" "b,*r")

         (const:SI (unspec:SI [(match_operand:SI 1
                    "symbolic_operand" "s,s")]
                      UNS_TPREL))))
(match_operand:QI 2 "mep_tprel_operand" "t,*r"))]

"" "sb\t%2, %%tpoff(%1)(%0)" [(set_attr "length" "2,4") (set_attr "stall" "store")])

(define_insn "*movqi_internal" [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r, r,m,r,c,r,y,r,er,ex,em,Y")

(match_operand:QI 1 "general_operand" " r,n,rm,r,c,r,y,r,er,r,ex,Y,em"))]

"mep_mov_ok (operands, QImode)" "@ mov\t%0, %1 mov\t%0, %1 lb\t%0, %1 sb\t%1, %0 ldc\t%0, %1 stc\t%1, %0 cmovc\t%0, %1 cmovc\t%0, %1 cmov\t%0, %1 cmov\t%0, %1 %<\t%0, %M1 lbcpa\t%0, %P1 sbcpa\t%1, %P0" [(set_attr "length" "2,2,,,2,2,4,4,4,4,,4,4") (set_attr "intrinsic" ",,,,,,cmovc2,cmovc1,cmov2,cmov1,cmov,,") (set_attr "stall" ",,load,store,ldc,stc,,,,,,load,store") (set_attr "memop" ",,core1,core0,,,,,,,,,*")])

(define_expand "movhi" [(set (match_operand:HI 0 "general_operand" "")

(match_operand:HI 1 "general_operand" ""))]

"" " { if (mep_expand_mov (operands, HImode))

DONE;

}")

(define_insn "*movhi_tprel_load" [(set (match_operand:HI 0 "mep_tprel_operand" "=t,*r")

(mem:HI (plus:SI (match_operand:SI 1 "mep_tp_operand" "b,*r")
         (const:SI (unspec:SI [(match_operand:SI 2
                    "symbolic_operand" "s,s")]
                      UNS_TPREL)))))]

"" "lh\t%0, %%tpoff(%2)(%1)" [(set_attr "length" "2,4") (set_attr "stall" "load")])

(define_insn "*movhi_tprel_store" [(set (mem:HI (plus:SI (match_operand:SI 0 "mep_tp_operand" "b,*r")

         (const:SI (unspec:SI [(match_operand:SI 1
                    "symbolic_operand" "s,s")]
                      UNS_TPREL))))
(match_operand:HI 2 "mep_tprel_operand" "t,*r"))]

"" "sh\t%2, %%tpoff(%1)(%0)" [(set_attr "length" "2,4") (set_attr "stall" "store")])

(define_insn "*movhi_internal" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,m,r,c,r,y,r,er,ex,em,Y")

(match_operand:HI 1 "general_operand" " r,S,n,m,r,c,r,y,r,er,r,ex,Y,em"))]

"mep_mov_ok (operands, HImode)" "@ mov\t%0, %1 mov\t%0, %I1 mov\t%0, %I1 lh\t%0, %1 sh\t%1, %0 ldc\t%0, %1 stc\t%1, %0 cmovc\t%0, %1 cmovc\t%0, %1 cmov\t%0, %1 cmov\t%0, %1 %<\t%0, %M1 lhcpa\t%0, %P1 shcpa\t%1, %P0" [(set_attr "length" "2,2,4,,,2,2,4,4,4,4,,4,4") (set_attr "intrinsic" ",,,,,,,cmovc2,cmovc1,cmov2,cmov1,cmov,,") (set_attr "stall" ",,,load,store,ldc,stc,,,,,,load,store") (set_attr "memop" ",,,core1,core0,,,,,,,,,")])

(define_expand "movsi" [(set (match_operand:SI 0 "nonimmediate_operand" "")

(match_operand:SI 1 "general_operand" ""))]

"" " { if (mep_expand_mov (operands, SImode))

DONE;

}")

(define_insn "*movsi_tprel_load" [(set (match_operand:SI 0 "mep_tprel_operand" "=t,*r")

(mem:SI (plus:SI (match_operand:SI 1 "mep_tp_operand" "b,*r")
         (const:SI (unspec:SI [(match_operand:SI 2
                    "symbolic_operand" "s,s")]
                      UNS_TPREL)))))]

"" "lw\t%0, %%tpoff(%2)(%1)" [(set_attr "length" "2,4") (set_attr "stall" "load")])

(define_insn "*movsi_tprel_store" [(set (mem:SI (plus:SI (match_operand:SI 0 "mep_tp_operand" "b,*r")

         (const:SI (unspec:SI [(match_operand:SI 1
                    "symbolic_operand" "s,s")]
                      UNS_TPREL))))
(match_operand:SI 2 "mep_tprel_operand" "t,*r"))]

"" "sw\t%2, %%tpoff(%1)(%0)" [(set_attr "length" "2,4") (set_attr "stall" "store")])

(define_insn "movsi_topsym_s" [(set (match_operand:SI 0 "register_operand" "=r")

(high:SI (match_operand:SI 1 "symbolic_operand" "s")))]

"" "movh\t%0, %%hi(%1)" [(set_attr "length" "4")])

(define_insn "movsi_botsym_s" [(set (match_operand:SI 0 "register_operand" "=r")

(lo_sum:SI (match_operand:SI 1 "register_operand" "0")
       (match_operand:SI 2 "symbolic_operand" "s")))]

"" "add3\t%0, %1, %%lo(%2)" [(set_attr "length" "4")])

(define_insn "cmovh_getsub" [(set (match_operand:SI 0 "register_operand" "=r")

(subreg:SI (match_operand:DI 1 "register_operand" "er") 4))]

"0 && TARGET_64BIT_CR_REGS" "cmovh\t%0, %1" [(set_attr "intrinsic" "cmovh2") (set_attr "length" "4")])

(define_insn "*movsi_internal" [(set (match_operand:SI 0 "mep_movdest_operand"

    "=r,r,r,r,r, t,t,r,r,r,Z,m,r,c,r,y,r, er,ex,em,U ")
(match_operand:SI 1 "general_operand"
    " r,S,I,J,OW,K,s,i,Z,m,r,r,c,r,y,r,er,r, ex,U, em"))]

"mep_mov_ok (operands, SImode)" "@ mov\t%0, %1 mov\t%0, %I1 mov\t%0, %I1 movu\t%0, %J1 movh\t%0, %h1 movu\t%0, %x1 movu\t%0, %1 # ldcb\t%0, %1 lw\t%0, %1 stcb\t%1, %0 sw\t%1, %0 ldc\t%0, %1 stc\t%1, %0 cmovc\t%0, %1 cmovc\t%0, %1 cmov\t%0, %1 cmov\t%0, %1 %<\t%0, %M1 lwcp\t%0, %1 swcp\t%1, %0" [(set_attr "length" "2,2,4,4,4,4,4,,4,,4,,2,2,4,4,4,4,4,,") (set_attr "intrinsic" ",,,,,,,,,,,,,,cmovc2,cmovc1,cmov2,cmov1,cmov,,") (set_attr "stall" ",,,,,,,,ldcb,load,stcb,store,ldc,stc,,,,,,load,store") (set_attr "memop" ",,,,,,,,,core1,,core0,,,,,,,,cop1,cop0") (set_attr "slot" ",,,,,,,multi,,,,,,,,,,,,,*")])

(define_split [(set (match_operand:SI 0 "register_operand" "")

    (match_operand:SI 1 "const_int_operand" ""))]

"mep_split_mov (operands, 0)" [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 3)))] " { HOST_WIDE_INT value; int lo, hi;

value = INTVAL (operands[1]);

lo = value & 0xffff; hi = trunc_int_for_mode (value & 0xffff0000, SImode);

operands[2] = GEN_INT (hi); operands[3] = GEN_INT (lo); }")

(define_split [(set (match_operand:SI 0 "register_operand" "")

    (match_operand:SI 1 "immediate_operand" ""))]

"mep_split_mov (operands, 1)" [(set (match_dup 0) (high:SI (match_dup 1))) (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))] "")

;; ??? What purpose do these two serve that high+lo_sum do not? (define_insn "movsi_topsym_u" [(set (match_operand:SI 0 "register_operand" "=r")

(and:SI (match_operand:SI 1 "symbolic_operand" "s")
    (const_int -65536)))]

"" "movh\t%0, %%uhi(%1)" [(set_attr "length" "4")])

(define_insn "movsi_botsym_u" [(set (match_operand:SI 0 "register_operand" "=r")

(ior:SI (match_operand:SI 1 "register_operand" "0")
    (and:SI (match_operand:SI 2 "symbolic_operand" "s")
        (const_int 65535))))]

"" "or3\t%0, %1, %%lo(%2)" [(set_attr "length" "4")])

(define_expand "movdi" [(set (match_operand:DI 0 "" "")

(match_operand:DI 1 "" ""))]

"" " { if (mep_expand_mov (operands, DImode))

DONE;

}")

(define_insn "*movdi_internal_32" [(set (match_operand:DI 0 "mep_movdest_operand" "= r,m,r,c,r,er,ex,em,U")

(match_operand:DI 1 "general_operand"     "rim,r,c,r,er,r,ex,U,em"))]

"TARGET_32BIT_CR_REGS && mep_mov_ok (operands, DImode)" "#" [(set_attr "slot" "multi")])

(define_insn "*movdi_internal_64" [(set (match_operand:DI 0 "mep_movdest_operand" "=r,r,m,r,c,r,er,ex,em,U")

(match_operand:DI 1 "general_operand"     "r,im,r,c,r,er,r,ex,U,em"))]

"TARGET_64BIT_CR_REGS && mep_mov_ok (operands, DImode)" "@ # # # # # # # %<\t%0, %M1 lmcp\t%0, %1 smcp\t%1, %0" [(set_attr "slot" "multi,multi,multi,multi,multi,multi,multi,,,") (set_attr "intrinsic" ",,,,,,,cmov,,") (set_attr "memop" ",,,,,,,cop0,cop1,cop0") (set_attr "stall" ",,,,,,,*,load,store")])

(define_insn "*movdi_cop_postinc" [(parallel [(set (match_operand:DI 0 "register_operand" "=em")

       (mem:DI (reg:SI SP_REGNO)))
      (set (reg:SI SP_REGNO)
       (plus:SI (reg:SI SP_REGNO)
            (const_int 8)))
      ]
     )]

"TARGET_COP" "lmcpi\t%0,($sp+)" [(set_attr "length" "2")])

(define_insn "*movdi_cop_postinc" [(parallel [(set (match_operand:DI 0 "register_operand" "=em")

       (mem:DI (match_operand:SI 2 "register_operand" "r")))
      (set (match_operand:SI 1 "register_operand" "=0")
       (plus:SI (match_operand:SI 3 "register_operand" "0")
            (const_int 8)))
      ]
     )]

"TARGET_COP" "lmcpi\t%0,(%1+)" [(set_attr "length" "2")])

(define_insn "*cmovh_set" [(set (zero_extract:SI (match_operand:DI 0 "register_operand" "+er")

         (const_int 32)
         (const_int 32))
(match_operand:SI 1 "register_operand" "r"))]

"TARGET_64BIT_CR_REGS" "cmovh\t%0, %1" [(set_attr "intrinsic" "cmovh1") (set_attr "length" "4")])

(define_insn "cmovh_get" [(set (match_operand:SI 0 "register_operand" "=r")

(zero_extract:SI (match_operand:DI 1 "register_operand" "er")
         (const_int 32)
         (const_int 32)))]

"TARGET_64BIT_CR_REGS" "cmovh\t%0, %1" [(set_attr "intrinsic" "cmovh2") (set_attr "length" "4")])

(define_split [(set (match_operand:DI 0 "mep_movdest_operand" "")

    (match_operand:DI 1 "general_operand" ""))]

"reload_completed && mep_multi_slot (insn)" [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))] "mep_split_wide_move (operands, DImode);")

;; Floating Point Moves

(define_expand "movsf" [(set (match_operand:SF 0 "nonimmediate_operand" "")

(match_operand:SF 1 "general_operand" ""))]

"" " { if (mep_expand_mov (operands, SFmode))

DONE;

}")

(define_insn "*movsf_tprel_load" [(set (match_operand:SF 0 "mep_tprel_operand" "=t,*r")

(mem:SF (plus:SI (match_operand:SI 1 "mep_tp_operand" "b,*r")
         (const:SI (unspec:SI [(match_operand:SI 2
                    "symbolic_operand" "s,s")]
                      UNS_TPREL)))))]

"" "lw\t%0, %%tpoff(%2)(%1)" [(set_attr "length" "2,4") (set_attr "stall" "load")])

(define_insn "*movsf_tprel_store" [(set (mem:SF (plus:SI (match_operand:SI 0 "mep_tp_operand" "b,*r")

         (const:SI (unspec:SI [(match_operand:SI 1
                    "symbolic_operand" "s,s")]
                      UNS_TPREL))))
(match_operand:SF 2 "mep_tprel_operand" "t,*r"))]

"" "sw\t%2, %%tpoff(%1)(%0)" [(set_attr "length" "2,4") (set_attr "stall" "store")])

(define_insn "*movsf_internal" [(set (match_operand:SF 0 "mep_movdest_operand"

    "=r,r,r,r,Z,m,r,c,r,y,r,er,ex,em,U")
(match_operand:SF 1 "general_operand"
    " r,F,Z,m,r,r,c,r,y,r,er,r,ex,U,em"))]

"mep_mov_ok (operands, SFmode)" "@ mov\t%0, %1 # ldcb\t%0, %1 lw\t%0, %1 stcb\t%1, %0 sw\t%1, %0 ldc\t%0, %1 stc\t%1, %0 cmovc\t%0, %1 cmovc\t%0, %1 cmov\t%0, %1 cmov\t%0, %1 %<\t%0, %M1 lwcp\t%0, %1 swcp\t%1, %0" [(set_attr "length" "2,,2,,2,,2,2,,,4,4,,,") (set_attr "intrinsic" ",,,,,,,,cmovc2,cmovc1,cmov2,cmov1,cmov,,") (set_attr "stall" ",,ldcb,load,stcb,store,ldc,stc,,,,,,load,store") (set_attr "memop" ",,,core1,,core0,,,,,,,,cop1,cop0")])

(define_split [(set (match_operand:SF 0 "register_operand" "")

    (match_operand:SF 1 "const_double_operand" ""))]

"reload_completed" [(const_int 0)] " { REAL_VALUE_TYPE rv; HOST_WIDE_INT value; HOST_WIDE_INT lo, hi; rtx out;

REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); REAL_VALUE_TO_TARGET_SINGLE (rv, value);

lo = value & 0xffff; hi = trunc_int_for_mode (value & 0xffff0000, SImode);

out = gen_rtx_REG (SImode, REGNO (operands[0])); emit_move_insn (out, GEN_INT (hi)); if (lo != 0)

emit_insn (gen_iorsi3 (out, out, GEN_INT (lo)));

DONE; }")

(define_expand "movdf" [(set (match_operand:DF 0 "" "")

(match_operand:DF 1 "" ""))]

"" " { if (mep_expand_mov (operands, DFmode))

DONE;

}")

(define_insn "*movdf_internal_32" [(set (match_operand:DF 0 "mep_movdest_operand" "= r,m,r,c,r,er,ex,em,U")

(match_operand:DF 1 "general_operand"     "rFm,r,c,r,er,r,ex,U,em"))]

"TARGET_32BIT_CR_REGS && mep_mov_ok (operands, DFmode)" "#" [(set_attr "slot" "multi")])

(define_insn "*movdf_internal_64" [(set (match_operand:DF 0 "mep_movdest_operand" "= r,m,r,c,r,er,ex,em,U")

(match_operand:DF 1 "general_operand"     "rFm,r,c,r,er,r,ex,U,em"))]

"TARGET_64BIT_CR_REGS && mep_mov_ok (operands, DFmode)" "@ # # # # # # %<\t%0, %M1 lmcp\t%0, %1 smcp\t%1, %0" [(set_attr "slot" "multi,multi,multi,multi,multi,multi,,,") (set_attr "intrinsic" ",,,,,,cmov,,") (set_attr "memop" ",,,,,,,cop1,cop0") (set_attr "stall" ",,,,,,*,load,store")])

(define_split [(set (match_operand:DF 0 "mep_movdest_operand" "")

    (match_operand:DF 1 "general_operand" ""))]

"reload_completed && mep_multi_slot (insn)" [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))] "mep_split_wide_move (operands, DFmode);")

(define_insn "*lbcpa" [(set (match_operand:SI 0 "register_operand" "=em")

(sign_extend:SI (mem:QI (match_operand:SI 2 "register_operand" "1"))))

(set (match_operand:SI 1 "register_operand" "=r")

(plus:SI (match_dup 2)
     (match_operand:SI 3 "cgen_h_sint_8a1_immediate" "")))]

"TARGET_COP && reload_completed" "lbcpa\t%0, (%1+), %3" [(set_attr "length" "4") (set_attr "stall" "load")])

(define_insn "*sbcpa" [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))

(match_operand:QI 2 "register_operand" "em"))

(set (match_operand:SI 0 "register_operand" "=r")

(plus:SI (match_dup 1)
     (match_operand:SI 3 "cgen_h_sint_8a1_immediate" "")))]

"TARGET_COP && reload_completed" "sbcpa\t%2, (%0+), %3" [(set_attr "length" "4") (set_attr "stall" "store")])

(define_insn "*lhcpa" [(set (match_operand:SI 0 "register_operand" "=em")

(sign_extend:SI (mem:HI (match_operand:SI 2 "register_operand" "1"))))

(set (match_operand:SI 1 "register_operand" "=r")

(plus:SI (match_dup 2)
     (match_operand:SI 3 "cgen_h_sint_7a2_immediate" "")))]

"TARGET_COP && reload_completed" "lhcpa\t%0, (%1+), %3" [(set_attr "length" "4") (set_attr "stall" "load")])

(define_insn "*shcpa" [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))

(match_operand:HI 2 "register_operand" "em"))

(set (match_operand:SI 0 "register_operand" "=r")

(plus:SI (match_dup 1)
     (match_operand:SI 3 "cgen_h_sint_7a2_immediate" "")))]

"TARGET_COP && reload_completed" "shcpa\t%2, (%0+), %3" [(set_attr "length" "4") (set_attr "stall" "store")])

(define_insn "*lwcpi" [(set (match_operand:SI 0 "register_operand" "=em")

(mem:SI (match_operand:SI 2 "register_operand" "1")))

(set (match_operand:SI 1 "register_operand" "=r")

(plus:SI (match_dup 2)
     (const_int 4)))]

"TARGET_COP && reload_completed" "lwcpi\t%0, (%1+)" [(set_attr "length" "2") (set_attr "stall" "load")])

(define_insn "*lwcpa" [(set (match_operand:SI 0 "register_operand" "=em")

(mem:SI (match_operand:SI 2 "register_operand" "1")))

(set (match_operand:SI 1 "register_operand" "=r")

(plus:SI (match_dup 2)
     (match_operand:SI 3 "cgen_h_sint_6a4_immediate" "")))]

"TARGET_COP && reload_completed" "lwcpa\t%0, (%1+), %3" [(set_attr "length" "4") (set_attr "stall" "load")])

(define_insn "*swcpi" [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))

(match_operand:SI 2 "register_operand" "em"))

(set (match_operand:SI 0 "register_operand" "=r")

(plus:SI (match_dup 1)
     (const_int 4)))]

"TARGET_COP && reload_completed" "swcpi\t%2, (%0+)" [(set_attr "length" "2") (set_attr "stall" "store")])

(define_insn "*swcpa" [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))

(match_operand:SI 2 "register_operand" "em"))

(set (match_operand:SI 0 "register_operand" "=r")

(plus:SI (match_dup 1)
     (match_operand:SI 3 "cgen_h_sint_6a4_immediate" "")))]

"TARGET_COP && reload_completed" "swcpa\t%2, (%0+), %3" [(set_attr "length" "4") (set_attr "stall" "store")])

(define_peephole2 [(set (match_operand:SI 0 "register_operand" "")

(plus:SI (match_dup 0)
     (match_operand:SI 1 "cgen_h_sint_8a1_immediate" "")))]

"TARGET_COP && mep_use_post_modify_p (insn, operands[0], operands[1])" [(const_int 0)] { emit_note (NOTE_INSN_DELETED); DONE; }) ;; :::::::::::::::::::: ;; :: ;; :: Reloads ;; :: ;; ::::::::::::::::::::

(define_expand "reload_insi" [(set (match_operand:SI 0 "mep_reload_operand" "")

    (match_operand:SI 1 "mep_reload_operand" "r"))

(clobber (match_operand:SI 2 "register_operand" "=&r"))] "" " { mep_expand_reload (operands, SImode); DONE; }")

(define_expand "reload_outsi" [(set (match_operand:SI 0 "mep_reload_operand" "=r")

    (match_operand:SI 1 "mep_reload_operand" ""))

(clobber (match_operand:SI 2 "register_operand" "=&r"))] "" " { mep_expand_reload (operands, SImode); DONE; }")

;; :::::::::::::::::::: ;; :: ;; :: Conversions ;; :: ;; ::::::::::::::::::::

(define_insn "extendqisi2" [(set (match_operand:SI 0 "register_operand" "=r,r,em")

(sign_extend:SI
  (match_operand:QI 1 "nonimmediate_operand" "0,m,Y")))]

"" "@ extb\t%0 lb\t%0, %1 lbcpa\t%0, %P1" [(set_attr "length" "2,,") (set_attr "stall" ",load,load") (set_attr "memop" ",core1,cop1")])

(define_insn "extendhisi2" [(set (match_operand:SI 0 "register_operand" "=r,r,em")

(sign_extend:SI
  (match_operand:HI 1 "nonimmediate_operand" "0,m,Y")))]

"" "@ exth\t%0 lh\t%0, %1 lhcpa\t%0, %P1" [(set_attr "length" "2,,") (set_attr "stall" ",load,load") (set_attr "memop" ",core1,cop1")])

(define_insn "zero_extendqisi2" [(set (match_operand:SI 0 "register_operand" "=r,r,r")

(zero_extend:SI
  (match_operand:QI 1 "nonimmediate_operand" "0,r,m")))]

"" "@ extub\t%0 and3\t%0, %1, 255 lbu\t%0, %1" [(set_attr "length" "2,4,") (set_attr "stall" ",,load") (set_attr "memop" ",*,core1")])

(define_insn "zero_extendhisi2" [(set (match_operand:SI 0 "register_operand" "=r,r,r")

(zero_extend:SI
  (match_operand:HI 1 "nonimmediate_operand" "0,r,m")))]

"" "@ extuh\t%0 and3\t%0, %1, 65535 lhu\t%0, %1" [(set_attr "length" "2,4,") (set_attr "stall" ",,load") (set_attr "memop" ",*,core1")]) ;; :::::::::::::::::::: ;; :: ;; :: 32 bit Integer arithmetic ;; :: ;; ::::::::::::::::::::

(define_insn "addsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r")

(plus:SI (match_operand:SI 1 "register_operand" "%r,0,r")
     (match_operand:SI 2 "mep_add_operand" "r,L,IT")))]

"" "@ add3\t%0, %1, %2 add\t%0, %2 add3\t%0, %1, %I2" [(set (attr "length")

(if_then_else (eq_attr "alternative" "2")
  (if_then_else (and (match_operand:SI 1 "mep_sp_operand" "")
             (match_operand:SI 2 "mep_imm7a4_operand" ""))
    (const_int 2)
    (const_int 4))
  (const_int 2)))])

;; The intention here is to combine the 16-bit add with the 16-bit ;; move to create a 32-bit add. It's the same size, but takes one ;; less machine cycle. It will happen to match a 32-bit add with a ;; 16-bit move also, but gcc shouldn't be doing that ;) (define_peephole2 [(set (match_operand:SI 0 "register_operand" "")

(plus:SI (match_operand:SI 1 "register_operand" "")
     (match_operand:SI 2 "immediate_operand" "")))

(set (match_operand:SI 3 "register_operand" "")

(match_operand:SI 4 "register_operand" ""))]

"REGNO (operands[0]) == REGNO (operands[1]) && REGNO (operands[0]) == REGNO (operands[4]) && GR_REGNO_P (REGNO (operands[3])) && dead_or_set_p (peep2_next_insn (1), operands[4])" [(set (match_dup 3)

(plus:SI (match_dup 1)
     (match_dup 2)))]

"")

(define_insn "subsi3" [(set (match_operand:SI 0 "register_operand" "=r")

(minus:SI (match_operand:SI 1 "register_operand" "0")
      (match_operand:SI 2 "register_operand" "r")))]

"" "sub\t%0, %2" [(set_attr "length" "2")])

(define_expand "mulsi3" [(set (match_operand:SI 0 "register_operand" "")

    (mult:SI (match_operand:SI 1 "register_operand" "")
             (match_operand:SI 2 "register_operand" "")))]

"TARGET_OPT_MULT || TARGET_COPRO_MULT" { emit_insn (gen_mulsi3_1 (operands[0], operands[1], operands[2])); DONE; })

;; Generated by mep_reuse_lo_p when no GPR destination is needed. (define_insn "mulsi3_lo" [(set (match_operand:SI 0 "mep_lo_operand" "=l")

(mult:SI (match_operand:SI 1 "register_operand" "r")
     (match_operand:SI 2 "register_operand" "r")))

(clobber (match_scratch:SI 3 "=h"))] "TARGET_OPT_MULT && reload_completed" "mul\t%1, %2" [(set_attr "length" "2") (set_attr "stall" "mul")])

;; Generated by mep_reuse_lo_p when both destinations of a mulr ;; are needed. (define_insn "mulsi3r" [(set (match_operand:SI 0 "mep_lo_operand" "=l")

(mult:SI (match_operand:SI 2 "register_operand" "1")
     (match_operand:SI 3 "register_operand" "r")))

(set (match_operand:SI 1 "register_operand" "=r")

(mult:SI (match_dup 2)
     (match_dup 3)))

(clobber (match_scratch:SI 4 "=h"))] "TARGET_OPT_MULT && reload_completed" "mulr\t%2, %3" [(set_attr "length" "2") (set_attr "stall" "mulr")])

(define_insn "mulsi3_1" [(set (match_operand:SI 0 "register_operand" "=r")

(mult:SI (match_operand:SI 1 "register_operand" "%0")
     (match_operand:SI 2 "register_operand" "r")))

(clobber (match_scratch:SI 3 "=l")) (clobber (match_scratch:SI 4 "=h"))] "TARGET_OPT_MULT" "mulr\t%1, %2" [(set_attr "length" "2") (set_attr "stall" "mulr")])

(define_expand "mulsidi3" [(set (match_operand:DI 0 "register_operand" "")

(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
     (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))]

"TARGET_OPT_MULT" " { rtx hi = gen_reg_rtx (SImode); rtx lo = gen_reg_rtx (SImode);

emit_insn (gen_mulsidi3_i (hi, lo, operands[1], operands[2])); emit_move_insn (gen_lowpart (SImode, operands[0]), lo); emit_move_insn (gen_highpart (SImode, operands[0]), hi); DONE; }")

(define_insn "mulsidi3_i" [(set (match_operand:SI 0 "mep_hi_operand" "=h")

(truncate:SI
 (lshiftrt:DI
  (mult:DI (sign_extend:DI
        (match_operand:SI 2 "register_operand" "r"))
       (sign_extend:DI
        (match_operand:SI 3 "register_operand" "r")))
  (const_int 32))))

(set (match_operand:SI 1 "mep_lo_operand" "=l")

(mult:SI (match_dup 2)
     (match_dup 3)))]

"TARGET_OPT_MULT" "mul\t%2, %3" [(set_attr "length" "2") (set_attr "stall" "mul")])

(define_insn "smulsi3_highpart" [(set (match_operand:SI 0 "mep_hi_operand" "=h")

(truncate:SI
 (lshiftrt:DI
  (mult:DI (sign_extend:DI
        (match_operand:SI 1 "register_operand" "r"))
       (sign_extend:DI
        (match_operand:SI 2 "register_operand" "r")))
  (const_int 32))))

(clobber (reg:SI LO_REGNO))] "TARGET_OPT_MULT" "mul\t%1, %2" [(set_attr "length" "2") (set_attr "stall" "mul")])

(define_expand "umulsidi3" [(set (match_operand:DI 0 "mep_hi_operand" "")

(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
     (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))]

"TARGET_OPT_MULT" " { rtx hi = gen_reg_rtx (SImode); rtx lo = gen_reg_rtx (SImode);

emit_insn (gen_umulsidi3_i (hi, lo, operands[1], operands[2])); emit_move_insn (gen_lowpart (SImode, operands[0]), lo); emit_move_insn (gen_highpart (SImode, operands[0]), hi); DONE; }")

(define_insn "umulsidi3_i" [(set (match_operand:SI 0 "mep_hi_operand" "=h")

(truncate:SI
 (lshiftrt:DI
  (mult:DI (zero_extend:DI
        (match_operand:SI 2 "register_operand" "r"))
       (zero_extend:DI
        (match_operand:SI 3 "register_operand" "r")))
  (const_int 32))))

(set (match_operand:SI 1 "mep_lo_operand" "=l")

(mult:SI (match_dup 2)
     (match_dup 3)))]

"TARGET_OPT_MULT" "mulu\t%2, %3" [(set_attr "length" "2") (set_attr "stall" "mul")])

(define_insn "umulsi3_highpart" [(set (match_operand:SI 0 "mep_hi_operand" "=h")

(truncate:SI
 (lshiftrt:DI
  (mult:DI (zero_extend:DI
        (match_operand:SI 1 "register_operand" "r"))
       (zero_extend:DI
        (match_operand:SI 2 "register_operand" "r")))
  (const_int 32))))

(clobber (reg:SI LO_REGNO))] "TARGET_OPT_MULT" "mulu %1, %2" [(set_attr "length" "2") (set_attr "stall" "mul")])

;; These two don't currently match because we don't have an adddi3 pattern. (define_insn "*smultdi_and_add" [(set (match_operand:DI 0 "mep_hi_operand" "=d")

(plus:DI (mult:DI (zero_extend:DI
           (match_operand:SI 1 "register_operand" "r"))
          (zero_extend:DI
           (match_operand:SI 2 "register_operand" "r")))
     (match_operand:DI 3 "mep_hi_operand" "0")))]

"TARGET_OPT_MULT && TARGET_BIG_ENDIAN" "maddu\t%1, %2" [(set_attr "length" "4") (set_attr "stall" "mul")])

(define_insn "*umultdi_and_add" [(set (match_operand:DI 0 "mep_hi_operand" "=d")

(plus:DI (mult:DI (sign_extend:DI
           (match_operand:SI 1 "register_operand" "r"))
          (sign_extend:DI
           (match_operand:SI 2 "register_operand" "r")))
     (match_operand:DI 3 "mep_hi_operand" "0")))]

"TARGET_OPT_MULT && TARGET_BIG_ENDIAN" "madd\t%1, %2" [(set_attr "length" "4") (set_attr "stall" "mul")])

;; A pattern for 'r1 = r2 * r3 + r4'. There are three possible ;; implementations: ;; ;; (1) 'mulr;add3'. This is usually the best choice if the instruction ;; is not part of a natural multiply-accumulate chain. It has the ;; same latency as 'stc;maddr' but doesn't tie up $lo for as long. ;; ;; (2) 'madd'. This is the best choice if the instruction is in the ;; middle of a natural multiply-accumulate chain. r4 will already ;; be in $lo and r1 will also be needed in $lo. ;; ;; (3) 'maddr'. This is the best choice if the instruction is at the ;; end of a natural multiply-accumulate chain. r4 will be in $lo ;; but r1 will be needed in a GPR. ;; ;; In theory, we could put all the alternatives into a single pattern and ;; leave the register allocator to choose between them. However, this can ;; sometimes produce poor results in practice. ;; ;; This pattern therefore describes a general GPR-to-GPR operation that ;; has a slight preference for cases in which operands 0 and 1 are tied. ;; After reload, we try to rewrite the patterns using peephole2s (if ;; enabled), falling back on define_splits if that fails. See also ;; mep_reuse_lo_p. (define_insn "maddsi3" [(set (match_operand:SI 0 "register_operand" "=r,r")

(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%0,r")
          (match_operand:SI 2 "register_operand" "r,r"))
     (match_operand:SI 3 "register_operand" "r,r")))

(clobber (match_scratch:SI 4 "=l,l")) (clobber (match_scratch:SI 5 "=h,h"))] "TARGET_OPT_MULT" "#" [(set_attr "length" "8") (set_attr "stall" "mulr")])

;; Implement maddsi3s using maddr if operand 3 is already available in $lo. (define_peephole2 [(parallel

[(set (match_operand:SI 0 "register_operand" "")
      (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
            (match_operand:SI 2 "register_operand" ""))
           (match_operand:SI 3 "register_operand" "")))
 (clobber (match_scratch:SI 4 ""))
 (clobber (match_scratch:SI 5 ""))])]

"TARGET_OPT_MULT && reload_completed && mep_reuse_lo_p (operands[4], operands[3], insn,

          !rtx_equal_p (operands[1], operands[3])
          && !rtx_equal_p (operands[2], operands[3])
          && (rtx_equal_p (operands[0], operands[3])
          || peep2_reg_dead_p (1, operands[3])))"

[(parallel

[(set (match_dup 4)
      (plus:SI (mult:SI (match_dup 0)
                (match_dup 2))
           (match_dup 4)))
 (set (match_dup 0)
      (plus:SI (mult:SI (match_dup 0)
            (match_dup 2))
           (match_dup 4)))
 (clobber (match_dup 5))])]

"operands[2] = mep_mulr_source (0, operands[0], operands[1], operands[2]);")

;; This splitter implements maddsi3 as "mulr;add3". It only works if ;; operands 0 and 3 are distinct, since operand 0 is clobbered before ;; operand 3 is used. (define_split [(set (match_operand:SI 0 "register_operand" "")

(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
          (match_operand:SI 2 "register_operand" ""))
     (match_operand:SI 3 "register_operand" "")))

(clobber (match_scratch:SI 4 "")) (clobber (match_scratch:SI 5 ""))] "TARGET_OPT_MULT && reload_completed && !rtx_equal_p (operands[0], operands[3])" [(parallel [(set (match_dup 0)

       (mult:SI (match_dup 0)
            (match_dup 2)))
      (clobber (match_dup 4))
      (clobber (match_dup 5))])

(set (match_dup 0)

(plus:SI (match_dup 0)
     (match_dup 3)))]

"operands[2] = mep_mulr_source (0, operands[0], operands[1], operands[2]);")

;; This is the fallback splitter for maddsi3. It moves operand 3 into ;; $lo and then uses maddr. (define_split [(set (match_operand:SI 0 "register_operand" "")

(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
          (match_operand:SI 2 "register_operand" ""))
     (match_operand:SI 3 "register_operand" "")))

(clobber (match_scratch:SI 4 "")) (clobber (match_scratch:SI 5 ""))] "TARGET_OPT_MULT && reload_completed" [(parallel [(set (match_dup 4)

       (plus:SI (mult:SI (match_dup 0)
                 (match_dup 2))
            (match_dup 4)))
      (set (match_dup 0)
       (plus:SI (mult:SI (match_dup 0)
                 (match_dup 2))
            (match_dup 4)))
      (clobber (match_dup 5))])]

{ emit_move_insn (operands[4], operands[3]); operands[2] = mep_mulr_source (0, operands[0], operands[1], operands[2]); })

;; Remove unnecessary stcs to $lo. This cleans up the moves generated ;; by earlier calls to mep_reuse_lo_p. (define_peephole2 [(set (match_operand:SI 0 "mep_lo_operand" "")

(match_operand:SI 1 "register_operand" ""))]

"TARGET_OPT_MULT && mep_reuse_lo_p (operands[0], operands[1], insn,

          peep2_reg_dead_p (1, operands[1]))"

[(const_int 0)] { emit_note (NOTE_INSN_DELETED); DONE; })

(define_insn "maddsi3_lo" [(set (match_operand:SI 0 "mep_lo_operand" "=l")

(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
          (match_operand:SI 2 "register_operand" "r"))
     (match_operand:SI 3 "mep_lo_operand" "0")))

(clobber (match_scratch:SI 4 "=h"))] "TARGET_OPT_MULT && reload_completed" "madd\t%1, %2" [(set_attr "length" "4") (set_attr "stall" "mul")])

(define_insn "maddsi3r" [(set (match_operand:SI 0 "mep_lo_operand" "=l")

(plus:SI (mult:SI (match_operand:SI 2 "register_operand" "1")
          (match_operand:SI 3 "register_operand" "r"))
     (match_operand:SI 4 "register_operand" "0")))

(set (match_operand:SI 1 "register_operand" "=r")

(plus:SI (mult:SI (match_dup 2)
          (match_dup 3))
     (match_dup 4)))

(clobber (match_scratch:SI 5 "=h"))] "TARGET_OPT_MULT && reload_completed" "maddr\t%2, %3" [(set_attr "length" "4") (set_attr "stall" "mulr")])

(define_insn "*shift_1_or_2_and_add" [(set (match_operand:SI 0 "mep_r0_operand" "=z")

(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
          (match_operand:SI 2 "mep_slad_operand" "n"))
     (match_operand:SI 3 "register_operand" "r")))]

"" "sl%b2ad3\t%0, %1, %3" [(set_attr "length" "2") (set_attr "stall" "int2")])

(define_insn "divmodsi4" [(set (match_operand:SI 0 "mep_lo_operand" "=l")

(div:SI (match_operand:SI 1 "register_operand" "r")
    (match_operand:SI 2 "register_operand" "r")))

(set (match_operand:SI 3 "mep_hi_operand" "=h")

(mod:SI (match_dup 1)
    (match_dup 2)))]

"TARGET_OPT_DIV" "div\t%1, %2" [(set_attr "length" "2") (set_attr "stall" "div") (set_attr "may_trap" "yes")])

(define_insn "udivmodsi4" [(set (match_operand:SI 0 "mep_lo_operand" "=l")

(udiv:SI (match_operand:SI 1 "register_operand" "r")
     (match_operand:SI 2 "register_operand" "r")))

(set (match_operand:SI 3 "mep_hi_operand" "=h")

(umod:SI (match_dup 1)
    (match_dup 2)))]

"TARGET_OPT_DIV" "divu\t%1, %2" [(set_attr "length" "2") (set_attr "stall" "div") (set_attr "may_trap" "yes")])

(define_insn "negsi2" [(set (match_operand:SI 0 "register_operand" "=r")

(neg:SI (match_operand:SI 1 "register_operand" "r")))]

"" "neg\t%0, %1" [(set_attr "length" "2")])

;; We have "absolute difference between two regs" which isn't quite ;; what gcc is expecting. (define_expand "abssi2" [(set (match_dup 2) (const_int 0)) (set (match_operand:SI 0 "register_operand" "")

(abs:SI (minus:SI (match_operand:SI 1 "register_operand" "")
          (match_dup 2))
    ))]

"TARGET_OPT_ABSDIFF" "operands[2] = gen_reg_rtx (SImode);")

(define_insn "*absdiff" [(set (match_operand:SI 0 "register_operand" "=r")

(abs:SI (minus:SI (match_operand:SI 1 "register_operand" "0")
          (match_operand:SI 2 "register_operand" "r"))))]

"TARGET_OPT_ABSDIFF" "abs\t%0, %2" [(set_attr "length" "4")])

(define_split [(set (match_operand:SI 0 "register_operand" "")

(abs:SI (plus:SI (match_operand:SI 1 "register_operand" "")
         (match_operand:SI 2 "immediate_operand" ""))))

(clobber (match_operand:SI 3 "register_operand" ""))] "!reload_completed" [(set (match_dup 3)

(match_dup 4))

(set (match_operand:SI 0 "register_operand" "")

(abs:SI (minus:SI (match_operand:SI 1 "register_operand" "")
          (match_dup 3))))]

"operands[4] = GEN_INT (-INTVAL (operands[2]));")

(define_insn "sminsi3" [(set (match_operand:SI 0 "register_operand" "=r")

(smin:SI (match_operand:SI 1 "register_operand" "0")
     (match_operand:SI 2 "nonmemory_operand" "r")))]

"TARGET_OPT_MINMAX" "min\t%0, %2" [(set_attr "length" "4")])

(define_insn "smaxsi3" [(set (match_operand:SI 0 "register_operand" "=r")

(smax:SI (match_operand:SI 1 "register_operand" "0")
     (match_operand:SI 2 "nonmemory_operand" "r")))]

"TARGET_OPT_MINMAX" "max\t%0, %2" [(set_attr "length" "4")])

(define_insn "uminsi3" [(set (match_operand:SI 0 "register_operand" "=r")

(umin:SI (match_operand:SI 1 "register_operand" "0")
     (match_operand:SI 2 "nonmemory_operand" "r")))]

"TARGET_OPT_MINMAX" "minu\t%0, %2" [(set_attr "length" "4")])

(define_insn "umaxsi3" [(set (match_operand:SI 0 "register_operand" "=r")

(umax:SI (match_operand:SI 1 "register_operand" "0")
     (match_operand:SI 2 "nonmemory_operand" "r")))]

"TARGET_OPT_MINMAX" "maxu\t%0, %2" [(set_attr "length" "4")])

;; Average: a = (b+c+1)>>1 (define_insn "*averagesi3" [(set (match_operand:SI 0 "register_operand" "=r")

(ashiftrt:SI (plus:SI (plus:SI
            (match_operand:SI 1 "register_operand" "0")
            (match_operand:SI 2 "register_operand" "r"))
              (const_int 1))
         (const_int 1)))]

"TARGET_OPT_AVERAGE" "ave\t%0, %2" [(set_attr "length" "4")])

;; clip support

(define_insn "clip_maxmin" [(set (match_operand:SI 0 "register_operand" "=r")

(smax:SI (smin:SI (match_operand:SI 1 "register_operand" "0")
          (match_operand:SI 2 "immediate_operand" "n"))
     (match_operand:SI 3 "immediate_operand" "n")))]

"mep_allow_clip (operands[2], operands[3], 1)" "clip\t%0, %B2" [(set_attr "length" "4")])

(define_insn "clip_minmax" [(set (match_operand:SI 0 "register_operand" "=r")

(smin:SI (smax:SI (match_operand:SI 1 "register_operand" "0")
          (match_operand:SI 2 "immediate_operand" "n"))
     (match_operand:SI 3 "immediate_operand" "n")))]

"mep_allow_clip (operands[3], operands[2], 1)" "clip\t%0, %B3" [(set_attr "length" "4")])

(define_insn "clipu_maxmin" [(set (match_operand:SI 0 "register_operand" "=r")

(smax:SI (smin:SI (match_operand:SI 1 "register_operand" "0")
          (match_operand:SI 2 "immediate_operand" "n"))
     (match_operand:SI 3 "immediate_operand" "n")))]

"mep_allow_clip (operands[2], operands[3], 0)" "clipu\t%0, %U2" [(set_attr "length" "4")])

(define_insn "clipu_minmax" [(set (match_operand:SI 0 "register_operand" "=r")

(smin:SI (smax:SI (match_operand:SI 1 "register_operand" "0")
          (match_operand:SI 2 "immediate_operand" "n"))
     (match_operand:SI 3 "immediate_operand" "n")))]

"mep_allow_clip (operands[3], operands[2], 0)" "clipu\t%0, %U3" [(set_attr "length" "4")]) ;; :::::::::::::::::::: ;; :: ;; :: 32 bit Integer Shifts and Rotates ;; :: ;; ::::::::::::::::::::

(define_insn "ashlsi3" [(set (match_operand:SI 0 "register_operand" "=r,z")

(ashift:SI (match_operand:SI 1 "register_operand" "0,r")
       (match_operand:SI 2 "nonmemory_operand" "rM,M")))]

"" "@ sll\t%0, %2 sll3\t%0, %1, %2" [(set_attr "length" "2,2") (set_attr "shiftop" "operand2")])

(define_insn "ashrsi3" [(set (match_operand:SI 0 "register_operand" "=r")

(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
         (match_operand:SI 2 "nonmemory_operand" "rM")))]

"" "sra\t%0, %2" [(set_attr "length" "2") (set_attr "shiftop" "operand2")])

(define_insn "lshrsi3" [(set (match_operand:SI 0 "register_operand" "=r")

(lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
         (match_operand:SI 2 "nonmemory_operand" "rM")))]

"" "srl\t%0, %2" [(set_attr "length" "2") (set_attr "shiftop" "operand2")]) ;; :::::::::::::::::::: ;; :: ;; :: 32 Bit Integer Logical operations ;; :: ;; ::::::::::::::::::::

(define_insn "andsi3" [(set (match_operand:SI 0 "register_operand" "=r,r")

(and:SI (match_operand:SI 1 "register_operand" "%0,r")
    (match_operand:SI 2 "nonmemory_operand" "r,J")))]

"" "@ and\t%0, %2 and3\t%0, %1, %J2" [(set_attr "length" "2,4")])

(define_insn "iorsi3" [(set (match_operand:SI 0 "register_operand" "=r,r")

(ior:SI (match_operand:SI 1 "register_operand" "%0,r")
    (match_operand:SI 2 "nonmemory_operand" "r,J")))]

"" "@ or\t%0, %2 or3\t%0, %1, %J2" [(set_attr "length" "2,4")])

(define_insn "xorsi3" [(set (match_operand:SI 0 "register_operand" "=r,r")

(xor:SI (match_operand:SI 1 "register_operand" "%0,r")
    (match_operand:SI 2 "nonmemory_operand" "r,J")))]

"" "@ xor\t%0, %2 xor3\t%0, %1, %J2" [(set_attr "length" "2,4")])

(define_expand "one_cmplsi2" [(set (match_operand:SI 0 "register_operand" "")

(not:SI (match_operand:SI 1 "register_operand" "")))]

"" "operands[2] = operands[1]; ")

;; No separate insn for this; use NOR (define_insn "*one_cmplsi3_internal" [(set (match_operand:SI 0 "register_operand" "=r")

(not:SI (match_operand:SI 1 "register_operand" "0")))]

"" "nor\t%0, %0" [(set_attr "length" "2")]) ;; :::::::::::::::::::: ;; :: ;; :: Bit Manipulation ;; :: ;; ::::::::::::::::::::

(define_insn "*bitop_be" [(set (match_operand:QI 0 "mep_Y_operand" "=Y")

(subreg:QI (match_operator:SI 3 "mep_bit_operator"
        [(subreg:SI (match_operand:QI 1 "mep_Y_operand" "0") 0)
         (match_operand 2 "immediate_operand" "n")])
       3)
)]

"TARGET_BIG_ENDIAN && TARGET_OPT_BITOPS && rtx_equal_p (operands[0], operands[1])" "b%L3m\t%0, %b2" [(set_attr "length" "2")])

(define_insn "*bitop_le" [(set (match_operand:QI 0 "mep_Y_operand" "=Y")

(subreg:QI (match_operator:SI 3 "mep_bit_operator"
        [(subreg:SI (match_operand:QI 1 "mep_Y_operand" "0") 0)
         (match_operand 2 "immediate_operand" "n")])
       0)
)]

"!TARGET_BIG_ENDIAN && TARGET_OPT_BITOPS && rtx_equal_p (operands[0], operands[1])" "b%L3m\t%0, %b2" [(set_attr "length" "2")])

(define_insn "btstm" [(set (match_operand:SI 0 "mep_r0_operand" "=z")

(and:SI (subreg:SI (match_operand:QI 1 "mep_Y_operand" "Y") 0)
    (match_operand 2 "immediate_operand" "n"))
)]

"TARGET_OPT_BITOPS && mep_bit_position_p (operands[2], 1)" "btstm\t%0, %1, %b2" [(set_attr "length" "2")])

(define_insn "tas" [(parallel [(set (match_operand:SI 0 "mep_r0_operand" "=z")

       (zero_extend:SI (match_operand:QI 1 "mep_Y_operand" "+Y")))
      (set (match_dup 1)
       (const_int 1))
      ]
     )]

"TARGET_OPT_BITOPS" "tas\t%0, %1" [(set_attr "length" "2")])

(define_peephole2 [(set (match_operand:SI 0 "mep_r0_operand" "")

(zero_extend:SI (match_operand:QI 1 "mep_Y_operand" "")))

(set (match_operand:QI 2 "register_operand" "")

(const_int 1))

(set (match_dup 1)

(match_dup 2))

] "TARGET_OPT_BITOPS" [(parallel [(set (match_dup 0)

       (zero_extend:SI (match_dup 1)))
      (set (match_dup 1)
       (const_int 1))
      ])]

"")

(define_peephole2 [(set (match_operand:SI 0 "mep_r0_operand" "")

(sign_extend:SI (match_operand:QI 1 "mep_Y_operand" "")))

(set (match_operand:QI 2 "register_operand" "")

(const_int 1))

(set (match_dup 1)

(match_dup 2))

] "TARGET_OPT_BITOPS" [(parallel [(set (match_dup 0)

       (zero_extend:SI (match_dup 1)))
      (set (match_dup 1)
       (const_int 1))
      ])

(set (match_dup 0)

(sign_extend:SI (match_dup 3)))]

"operands[3] = gen_lowpart (QImode, operands[0]);")

;; :::::::::::::::::::: ;; :: ;; :: Conditional branches and stores ;; :: ;; ::::::::::::::::::::

(define_expand "cbranchsi4" [(set (pc)

(if_then_else (match_operator 0 "ordered_comparison_operator"
                  [(match_operand:SI 1 "register_operand" "")
                   (match_operand:SI 2 "nonmemory_operand" "")])
          (label_ref (match_operand 3 "" ""))
          (pc)))]

"" "emit_jump_insn (gen_branch_true (operands[3],

               mep_expand_cbranch (operands)));

DONE;")

(define_expand "branch_true" [(set (pc)

(if_then_else (match_operand 1 "" "")
          (label_ref (match_operand 0 "" ""))
          (pc)))]

"" "")

(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 "nonmemory_operand" "")]))]

"" "if (mep_expand_setcc (operands)) DONE; else FAIL;")

;; ------------------------------------------------------------

(define_insn "*slt" [(set (match_operand:SI 0 "register_operand" "=z,z,r")

(lt:SI (match_operand:SI 1 "register_operand" "r,r,r")
    (match_operand:SI 2 "nonmemory_operand" "r,M,I")))]

"" "slt3\t%0, %1, %2" [(set_attr "length" "2,2,4")])

(define_insn "*sltu" [(set (match_operand:SI 0 "register_operand" "=z,z,r")

(ltu:SI (match_operand:SI 1 "register_operand" "r,r,r")
     (match_operand:SI 2 "nonmemory_operand" "r,M,J")))]

"" "sltu3\t%0, %1, %2" [(set_attr "length" "2,2,4")])

(define_insn "*bcpeq_true" [(set (pc)

(if_then_else (eq:SI (reg:SI CBCR_REGNO)
             (const_int 0))
          (label_ref (match_operand 0 "" ""))
          (pc)))]

"" "bcpeq\t0, %l0" [(set_attr "length" "4")])

(define_insn "*bcpeq_false" [(set (pc)

(if_then_else (eq:SI (reg:SI CBCR_REGNO)
             (const_int 0))
          (pc)
          (label_ref (match_operand 0 "" ""))))]

"" "bcpne\t0, %l0" [(set_attr "length" "4")])

(define_insn "*bcpne_true" [(set (pc)

(if_then_else (ne:SI (reg:SI CBCR_REGNO)
             (const_int 0))
          (label_ref (match_operand 0 "" ""))
          (pc)))]

"" "bcpne\t0, %l0" [(set_attr "length" "4")])

(define_insn "*bcpne_false" [(set (pc)

(if_then_else (ne:SI (reg:SI CBCR_REGNO)
             (const_int 0))
          (pc)
          (label_ref (match_operand 0 "" ""))))]

"" "bcpeq\t0, %l0" [(set_attr "length" "4")])

;; ??? The lengths here aren't correct, since no attempt it made to ;; find "beqz" in the 256-byte range. However, this should not affect ;; bundling, since we never run core branches in parallel.

(define_insn "mep_beq_true" [(set (pc)

(if_then_else (eq (match_operand:SI 0 "register_operand" "r")
          (match_operand:SI 1 "mep_reg_or_imm4_operand" "rN"))
          (label_ref (match_operand 2 "" ""))
          (pc)))]

"" "* return mep_emit_cbranch (operands, 0);" [(set_attr "length" "4")] )

(define_insn "*beq_false" [(set (pc)

(if_then_else (eq (match_operand:SI 0 "register_operand" "r")
          (match_operand:SI 1 "mep_reg_or_imm4_operand" "rN"))
          (pc)
          (label_ref (match_operand 2 "" ""))))]

"" "* return mep_emit_cbranch (operands, 1);" [(set_attr "length" "4")])

(define_insn "mep_bne_true" [(set (pc)

(if_then_else (ne (match_operand:SI 0 "register_operand" "r")
          (match_operand:SI 1 "mep_reg_or_imm4_operand" "rN"))
          (label_ref (match_operand 2 "" ""))
          (pc)))]

"" "* return mep_emit_cbranch (operands, 1); " [(set_attr "length" "4")])

(define_insn "*bne_false" [(set (pc)

(if_then_else (ne (match_operand:SI 0 "register_operand" "r")
          (match_operand:SI 1 "mep_reg_or_imm4_operand" "rN"))
          (pc)
          (label_ref (match_operand 2 "" ""))))]

"" "* return mep_emit_cbranch (operands, 0); " [(set_attr "length" "4")])

(define_insn "mep_blti" [(set (pc)

(if_then_else (lt (match_operand:SI 0 "register_operand" "r")
          (match_operand:SI 1 "mep_imm4_operand" "N"))
          (label_ref (match_operand 2 "" ""))
          (pc)))]

"" "blti\t%0, %1, %l2" [(set_attr "length" "4")])

(define_insn "*bgei" [(set (pc)

(if_then_else (ge (match_operand:SI 0 "register_operand" "r")
          (match_operand:SI 1 "mep_imm4_operand" "N"))
          (label_ref (match_operand 2 "" ""))
          (pc)))]

"" "bgei\t%0, %1, %l2" [(set_attr "length" "4")]) ;; :::::::::::::::::::: ;; :: ;; :: Call and branch instructions ;; :: ;; ::::::::::::::::::::

(define_expand "call" [(parallel [(call (match_operand:QI 0 "" "")

        (match_operand:SI 1 "" ""))
      (use (match_operand:SI 2 "" ""))
      (clobber (reg:SI REGSAVE_CONTROL_TEMP))
      ])]

"" " { mep_expand_call (operands, 0); DONE; }")

(define_insn "call_internal" [(call (mem (match_operand:SI 0 "mep_call_address_operand" "R,r"))

 (match_operand:SI 1 "" ""))

(use (match_operand:SI 2 "const_int_operand" "")) (use (match_operand:SI 3 "mep_tp_operand" "b,b")) (use (match_operand:SI 4 "mep_gp_operand" "v,v")) (clobber (reg:SI LP_REGNO)) (clobber (reg:SI REGSAVE_CONTROL_TEMP)) ] "" { static char const pattern[2][2][8] = {

{ "bsrv\t%0", "jsrv\t%0" },
{ "bsr\t%0", "jsr\t%0" }

};

return pattern[mep_vliw_mode_match (operands[2])][which_alternative]; } [(set_attr "length" "4,2")])

(define_expand "sibcall" [(parallel [(call (match_operand:QI 0 "" "")

        (match_operand:SI 1 "" ""))
      (use (match_operand:SI 2 "" ""))
      (use (reg:SI LP_REGNO))
      (clobber (reg:SI REGSAVE_CONTROL_TEMP))
      ])]

"" "")

(define_insn "*sibcall_internal" [(call (mem (match_operand:SI 0 "mep_nearsym_operand" "s"))

 (match_operand:SI 1 "" ""))

(use (match_operand:SI 2 "const_int_operand" "")) (use (reg:SI LP_REGNO)) (clobber (reg:SI REGSAVE_CONTROL_TEMP)) ] "SIBLING_CALL_P (insn)" { if (mep_vliw_jmp_match (operands[2]))

return "jmp\t%0";

else if (mep_vliw_mode_match (operands[2]))

return
    "movu   $0, %0\n\
jmp $0";

else

return
"ldc    $12, $lp\n\
movh    $11, %%hi(%0)\n\
xor3    $12, $12, 1\n\
add3    $11, $11, %%lo(%0+1)\n\
stc $12, $lp\n\
jmp $11";

} [(set_attr "length" "48") (set_attr "slot" "multi")])

(define_expand "call_value" [(parallel [(set (match_operand 0 "" "")

       (call (match_operand:QI 1 "" "")
             (match_operand:SI 2 "" "")))
      (use (match_operand:SI 3 "" ""))
      (clobber (reg:SI REGSAVE_CONTROL_TEMP))
      ])]

"" " { mep_expand_call (operands, 1); DONE; }")

(define_insn "call_value_internal" [(set (match_operand 0 "register_operand" "=rx,rx")

(call (mem:SI (match_operand:SI 1 "mep_call_address_operand" "R,r"))
      (match_operand:SI 2 "" "")))

(use (match_operand:SI 3 "const_int_operand" "")) (use (match_operand:SI 4 "mep_tp_operand" "b,b")) (use (match_operand:SI 5 "mep_gp_operand" "v,v")) (clobber (reg:SI LP_REGNO)) (clobber (reg:SI REGSAVE_CONTROL_TEMP)) ] "" { static char const pattern[2][2][8] = {

{ "bsrv\t%1", "jsrv\t%1" },
{ "bsr\t%1", "jsr\t%1" }

};

return pattern[mep_vliw_mode_match (operands[3])][which_alternative]; } [(set_attr "length" "4,2")])

(define_expand "sibcall_value" [(parallel [(set (match_operand 0 "" "")

       (call (match_operand:QI 1 "" "")
             (match_operand:SI 2 "" "")))
      (use (match_operand:SI 3 "" ""))
      (use (reg:SI LP_REGNO))
      (clobber (reg:SI REGSAVE_CONTROL_TEMP))
      ])]

"" "")

(define_insn "*sibcall_value_internal" [(set (match_operand 0 "register_operand" "=rx")

(call (mem (match_operand:SI 1 "mep_nearsym_operand" "s"))
      (match_operand:SI 2 "" "")))

(use (match_operand:SI 3 "const_int_operand" "")) (use (reg:SI LP_REGNO)) (clobber (reg:SI REGSAVE_CONTROL_TEMP)) ] "SIBLING_CALL_P (insn)" { if (mep_vliw_jmp_match (operands[3]))

return "jmp\t%1";

else if (mep_vliw_mode_match (operands[3]))

return
    "movu   $0, %1\n\
jmp $0";

else

return
"ldc    $12, $lp\n\
movh    $11, %%hi(%1)\n\
xor3    $12, $12, 1\n\
add3    $11, $11, %%lo(%1+1)\n\
stc $12, $lp\n\
jmp $11";

} [(set_attr "length" "48") (set_attr "slot" "multi")])

(define_insn "return_internal" [(return) (use (match_operand:SI 0 "register_operand" ""))] "" "* return (REGNO (operands[0]) == LP_REGNO) ? \"ret\" : \"jmp\t%0\";" [(set_attr "length" "2") (set_attr "stall" "ret")])

(define_insn "eh_return_internal" [(return) (use (reg:SI 10)) (use (reg:SI 11)) (use (reg:SI LP_REGNO)) (clobber (reg:SI REGSAVE_CONTROL_TEMP)) ] "" "ret" [(set_attr "length" "2") (set_attr "stall" "ret")])

;; The assembler replaces short jumps with long jumps as needed. (define_insn "jump" [(set (pc) (label_ref (match_operand 0 "" "")))] "" "bra\t%l0" [(set_attr "length" "4")])

(define_insn "indirect_jump" [(set (pc) (match_operand:SI 0 "register_operand" "r"))] "" "jmp\t%0" [(set_attr "length" "2")])

(define_insn "tablejump" [(set (pc) (match_operand:SI 0 "register_operand" "r")) (use (label_ref (match_operand 1 "" "")))] "" "jmp\t%0" [(set_attr "length" "2")])

;; :::::::::::::::::::: ;; :: ;; :: Low Overhead Looping ;; :: ;; ::::::::::::::::::::

;; This insn is volatile because we'd like it to stay in its original ;; position, just before the loop header. If it stays there, we might ;; be able to convert it into a "repeat" insn. (define_insn "doloop_begin_internal" [(set (match_operand:SI 0 "register_operand" "=r")

(unspec_volatile:SI
 [(match_operand:SI 1 "register_operand" "0")
  (match_operand 2 "const_int_operand" "")] UNS_REPEAT_BEG))]

"" { gcc_unreachable (); } [(set_attr "length" "4")])

(define_expand "doloop_begin" [(use (match_operand 0 "register_operand" "")) (use (match_operand 1 "" ""))] "!profile_arc_flag && TARGET_OPT_REPEAT" "mep_emit_doloop (operands, 0); DONE; ")

(define_insn "doloop_end_internal" [(set (pc)

(if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+r,cxy,*m")
          (const_int 0))
          (label_ref (match_operand 1 "" ""))
          (pc)))

(set (match_dup 0)

(plus:SI (match_dup 0)
     (const_int -1)))

(unspec [(match_operand 2 "const_int_operand" "")] UNS_REPEAT_END) (clobber (match_scratch:SI 3 "=X,&r,&r"))] "" { gcc_unreachable (); } ;; Worst case length: ;; ;; lw , 4 ;; add ,-1 2 ;; sw , 4 ;; jmp 4 ;; 1f: [(set_attr "length" "14") (set_attr "slot" "multi")])

(define_expand "doloop_end" [(use (match_operand 0 "nonimmediate_operand" "")) (use (label_ref (match_operand 1 "" "")))] "!profile_arc_flag && TARGET_OPT_REPEAT" "if (GET_CODE (operands[0]) == REG && GET_MODE (operands[0]) != SImode)

 FAIL;

mep_emit_doloop (operands, 1); DONE; ")

(define_insn "repeat" [(set (reg:SI RPC_REGNO)

(unspec:SI [(match_operand:SI 0 "mep_r0_15_operand" "r")
        (match_operand:SI 1 "" "")]
       UNS_REPEAT_BEG))]

"" "repeat\t%0,%l1" [(set_attr "length" "4")])

(define_insn "repeat_end" [(unspec [(const_int 0)] UNS_REPEAT_END)] "" "# repeat end" [(set_attr "length" "0")])

(define_insn "erepeat" [(unspec [(match_operand 0 "" "")] UNS_EREPEAT_BEG)] "" "erepeat\t%l0" [(set_attr "length" "4")])

(define_insn "erepeat_end" [(unspec [(const_int 0)] UNS_EREPEAT_END)] "" "# erepeat end" [(set_attr "length" "0") (set_attr "slot" "multi")])

;; :::::::::::::::::::: ;; :: ;; :: Prologue and Epilogue instructions ;; :: ;; ::::::::::::::::::::

(define_expand "prologue" [(const_int 1)] "" " { mep_expand_prologue (); DONE; }")

(define_expand "epilogue" [(return)] "" " { mep_expand_epilogue (); DONE; }")

(define_expand "eh_return" [(use (match_operand:SI 0 "register_operand" "r"))] "" " { mep_expand_eh_return (operands); DONE; }")

(define_insn_and_split "eh_epilogue" [(unspec [(match_operand:SI 0 "register_operand" "r")] UNS_EH_EPILOGUE) (use (reg:SI LP_REGNO))] "" "#" "epilogue_completed" [(const_int 1)] "mep_emit_eh_epilogue (operands); DONE;" [(set_attr "slot" "multi")])

(define_expand "sibcall_epilogue" [(const_int 0)] "" " { mep_expand_sibcall_epilogue (); DONE; }")

(define_insn "mep_bb_trace_ret" [(unspec_volatile [(const_int 0)] UNS_BB_TRACE_RET)] "" "* return mep_emit_bb_trace_ret ();" [(set_attr "slot" "multi")])

(define_insn "mep_disable_int" [(unspec_volatile [(const_int 0)] UNS_DISABLE_INT)] "" "di" [(set_attr "length" "2")])

(define_insn "mep_enable_int" [(unspec_volatile [(const_int 0)] UNS_ENABLE_INT)] "" "ei" [(set_attr "length" "2")])

(define_insn "mep_reti" [(return) (unspec_volatile [(const_int 0)] UNS_RETI)] "" "reti" [(set_attr "length" "2")]) ;; :::::::::::::::::::: ;; :: ;; :: Miscellaneous instructions ;; :: ;; ::::::::::::::::::::

(define_insn "nop" [(const_int 0)] "" "nop" [(set_attr "length" "2")])

(define_insn "nop32" [(const_int 1)] "" "or3\t$0, $0, 0" [(set_attr "length" "4")])

(define_insn "blockage" [(unspec_volatile [(const_int 0)] UNS_BLOCKAGE)] "" "" [(set_attr "length" "0") (set_attr "slot" "multi")])

(define_insn "djmark" [(unspec_volatile [(const_int 0)] 999)] "" "# dj" [(set_attr "length" "0") (set_attr "slot" "multi")])