Home | History | Annotate | Line # | Download | only in c6x
c6x.md revision 1.3
      1 ;; Machine description for TI C6X.
      2 ;; Copyright (C) 2010-2015 Free Software Foundation, Inc.
      3 ;; Contributed by Andrew Jenner <andrew (a] codesourcery.com>
      4 ;; Contributed by Bernd Schmidt <bernds (a] codesourcery.com>
      5 ;; Contributed by CodeSourcery.
      6 ;;
      7 ;; This file is part of GCC.
      8 ;;
      9 ;; GCC is free software; you can redistribute it and/or modify
     10 ;; it under the terms of the GNU General Public License as published by
     11 ;; the Free Software Foundation; either version 3, or (at your option)
     12 ;; any later version.
     13 ;;
     14 ;; GCC is distributed in the hope that it will be useful,
     15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 ;; GNU General Public License for more details.
     18 ;;
     19 ;; You should have received a copy of the GNU General Public License
     20 ;; along with GCC; see the file COPYING3.  If not see
     21 ;; <http://www.gnu.org/licenses/>.
     22 
     23 
     24 ;; Register names
     25 
     26 (define_constants
     27   [(REG_A0 0)
     28    (REG_A1 1)
     29    (REG_A2 2)
     30    (REG_A3 3)
     31    (REG_A4 4)
     32    (REG_A5 5)
     33    (REG_A6 6)
     34    (REG_A7 7)
     35    (REG_A8 8)
     36    (REG_A9 9)
     37    (REG_A10 10)
     38    (REG_A11 11)
     39    (REG_A12 12)
     40    (REG_A13 13)
     41    (REG_A14 14)
     42    (REG_A15 15)
     43    (REG_A16 16)
     44    (REG_A17 17)
     45    (REG_A18 18)
     46    (REG_A19 19)
     47    (REG_A20 20)
     48    (REG_A21 21)
     49    (REG_A22 22)
     50    (REG_A23 23)
     51    (REG_A24 24)
     52    (REG_A25 25)
     53    (REG_A26 26)
     54    (REG_A27 27)
     55    (REG_A28 28)
     56    (REG_A29 29)
     57    (REG_A30 30)
     58    (REG_A31 31)
     59    (REG_B0 32)
     60    (REG_B1 33)
     61    (REG_B2 34)
     62    (REG_B3 35)
     63    (REG_B4 36)
     64    (REG_B5 37)
     65    (REG_B6 38)
     66    (REG_B7 39)
     67    (REG_B8 40)
     68    (REG_B9 41)
     69    (REG_B10 42)
     70    (REG_B11 43)
     71    (REG_B12 44)
     72    (REG_B13 45)
     73    (REG_B14 46)
     74    (REG_SP 47)
     75    (REG_B15 47)
     76    (REG_B16 48)
     77    (REG_B17 49)
     78    (REG_B18 50)
     79    (REG_B19 51)
     80    (REG_B20 52)
     81    (REG_B21 53)
     82    (REG_B22 54)
     83    (REG_B23 55)
     84    (REG_B24 56)
     85    (REG_B25 57)
     86    (REG_B26 58)
     87    (REG_B27 59)
     88    (REG_B28 60)
     89    (REG_B29 61)
     90    (REG_B30 62)
     91    (REG_B31 63)
     92    (REG_FRAME 64)
     93    (REG_ARGP 65)
     94    (REG_ILC 66)])
     95 
     96 (define_c_enum "unspec" [
     97    UNSPEC_NOP
     98    UNSPEC_RCP
     99    UNSPEC_MISALIGNED_ACCESS
    100    UNSPEC_ADDKPC
    101    UNSPEC_SETUP_DSBT
    102    UNSPEC_LOAD_GOT
    103    UNSPEC_LOAD_SDATA
    104    UNSPEC_BITREV
    105    UNSPEC_GOTOFF
    106    UNSPEC_MVILC
    107    UNSPEC_REAL_JUMP
    108    UNSPEC_REAL_LOAD
    109    UNSPEC_REAL_MULT
    110    UNSPEC_JUMP_SHADOW
    111    UNSPEC_LOAD_SHADOW
    112    UNSPEC_MULT_SHADOW
    113    UNSPEC_EPILOGUE_BARRIER
    114    UNSPEC_ATOMIC
    115    UNSPEC_CLR
    116    UNSPEC_EXT
    117    UNSPEC_EXTU
    118    UNSPEC_SUBC
    119    UNSPEC_AVG
    120 ])
    121 
    122 (define_c_enum "unspecv" [
    123    UNSPECV_BLOCKAGE
    124    UNSPECV_SPLOOP
    125    UNSPECV_SPKERNEL
    126    UNSPECV_EH_RETURN
    127    UNSPECV_CAS
    128 ])
    129 
    130 ;; -------------------------------------------------------------------------
    131 ;; Instruction attributes
    132 ;; -------------------------------------------------------------------------
    133 
    134 (define_attr "cpu"
    135   "c62x,c64x,c64xp,c67x,c67xp,c674x"
    136   (const (symbol_ref "(enum attr_cpu)c6x_arch")))
    137 
    138 ;; Define a type for each insn which is used in the scheduling description.
    139 ;; These correspond to the types defined in chapter 4 of the C674x manual.
    140 (define_attr "type"
    141   "unknown,single,mpy2,store,storen,mpy4,load,loadn,branch,call,callp,dp2,fp4,
    142    intdp,cmpdp,adddp,mpy,mpyi,mpyid,mpydp,mpyspdp,mpysp2dp,spkernel,sploop,
    143    mvilc,blockage,shadow,load_shadow,mult_shadow,atomic"
    144   (const_string "single"))
    145 
    146 ;; The register file used by an instruction's destination register.
    147 ;; The function destreg_file computes this; instructions can override the
    148 ;; attribute if they aren't a single_set.
    149 (define_attr "dest_regfile"
    150   "unknown,any,a,b"
    151   (cond [(eq_attr "type" "single,load,mpy2,mpy4,dp2,fp4,intdp,cmpdp,adddp,mpy,mpyi,mpyid,mpydp,mpyspdp,mpysp2dp")
    152 	 (cond [(match_operand 0 "a_register" "") (const_string "a")
    153 		(match_operand 0 "b_register" "") (const_string "b")]
    154 	       (const_string "unknown"))
    155 	 (eq_attr "type" "store")
    156 		(cond [(match_operand 1 "a_register" "") (const_string "a")
    157 		       (match_operand 1 "b_register" "") (const_string "b")]
    158 	       (const_string "unknown"))]
    159 	(const_string "unknown")))
    160 
    161 (define_attr "addr_regfile"
    162   "unknown,a,b"
    163   (const_string "unknown"))
    164 
    165 (define_attr "cross"
    166   "n,y"
    167   (const_string "n"))
    168 
    169 ;; This describes the relationship between operands and register files.
    170 ;; For example, "sxs" means that operands 0 and 2 determine the side of
    171 ;; the machine, and operand 1 can optionally use the cross path.  "dt" and
    172 ;; "td" are used to describe loads and stores.
    173 ;; Used for register renaming in loops for improving modulo scheduling.
    174 (define_attr "op_pattern"
    175   "unknown,dt,td,sx,sxs,ssx"
    176   (cond [(eq_attr "type" "load") (const_string "td")
    177 	 (eq_attr "type" "store") (const_string "dt")]
    178 	(const_string "unknown")))
    179 
    180 (define_attr "has_shadow"
    181   "n,y"
    182   (const_string "n"))
    183 
    184 ;; The number of cycles the instruction takes to finish.  Any cycles above
    185 ;; the first are delay slots.
    186 (define_attr "cycles" ""
    187   (cond [(eq_attr "type" "branch,call") (const_int 6)
    188 	 (eq_attr "type" "load,loadn") (const_int 5)
    189 	 (eq_attr "type" "dp2") (const_int 2)
    190 	 (eq_attr "type" "mpy2") (const_int 2)
    191 	 (eq_attr "type" "mpy4") (const_int 4)
    192 	 (eq_attr "type" "fp4") (const_int 4)
    193 	 (eq_attr "type" "mvilc") (const_int 4)
    194 	 (eq_attr "type" "cmpdp") (const_int 2)
    195 	 (eq_attr "type" "intdp") (const_int 5)
    196 	 (eq_attr "type" "adddp") (const_int 7)
    197 	 (eq_attr "type" "mpydp") (const_int 10)
    198 	 (eq_attr "type" "mpyi") (const_int 9)
    199 	 (eq_attr "type" "mpyid") (const_int 10)
    200 	 (eq_attr "type" "mpyspdp") (const_int 7)
    201 	 (eq_attr "type" "mpysp2dp") (const_int 5)]
    202 	(const_int 1)))
    203 
    204 ;; The number of cycles during which the instruction reserves functional
    205 ;; units.
    206 (define_attr "reserve_cycles" ""
    207   (cond [(eq_attr "type" "cmpdp") (const_int 2)
    208 	 (eq_attr "type" "adddp") (const_int 2)
    209 	 (eq_attr "type" "mpydp") (const_int 4)
    210 	 (eq_attr "type" "mpyi") (const_int 4)
    211 	 (eq_attr "type" "mpyid") (const_int 4)
    212 	 (eq_attr "type" "mpyspdp") (const_int 2)]
    213 	(const_int 1)))
    214 
    215 (define_attr "predicable" "no,yes"
    216   (const_string "yes"))
    217 
    218 (define_attr "enabled" "no,yes"
    219   (const_string "yes"))
    220 
    221 ;; Specify which units can be used by a given instruction.  Normally,
    222 ;; dest_regfile is used to select between the two halves of the machine.
    223 ;; D_ADDR is for load/store instructions; they use the D unit and use
    224 ;; addr_regfile to choose between D1 and D2.
    225 
    226 (define_attr "units62"
    227   "unknown,d,d_addr,l,m,s,dl,ds,dls,ls"
    228   (const_string "unknown"))
    229 
    230 (define_attr "units64"
    231   "unknown,d,d_addr,l,m,s,dl,ds,dls,ls"
    232   (const_string "unknown"))
    233 
    234 (define_attr "units64p"
    235   "unknown,d,d_addr,l,m,s,dl,ds,dls,ls"
    236   (attr "units64"))
    237 
    238 (define_attr "units67"
    239   "unknown,d,d_addr,l,m,s,dl,ds,dls,ls"
    240   (attr "units62"))
    241 
    242 (define_attr "units67p"
    243   "unknown,d,d_addr,l,m,s,dl,ds,dls,ls"
    244   (attr "units67"))
    245 
    246 (define_attr "units674"
    247   "unknown,d,d_addr,l,m,s,dl,ds,dls,ls"
    248   (attr "units64"))
    249 
    250 (define_attr "units"
    251   "unknown,d,d_addr,l,m,s,dl,ds,dls,ls"
    252   (cond [(eq_attr "cpu" "c62x")
    253 	   (attr "units62")
    254 	 (eq_attr "cpu" "c67x")
    255 	   (attr "units67")
    256 	 (eq_attr "cpu" "c67xp")
    257 	   (attr "units67p")
    258 	 (eq_attr "cpu" "c64x")
    259 	   (attr "units64")
    260 	 (eq_attr "cpu" "c64xp")
    261 	   (attr "units64p")
    262 	 (eq_attr "cpu" "c674x")
    263 	   (attr "units674")
    264 	]
    265 	(const_string "unknown")))
    266 
    267 (define_automaton "c6x_1,c6x_2,c6x_m1,c6x_m2,c6x_t1,c6x_t2,c6x_branch")
    268 (automata_option "no-comb-vect")
    269 (automata_option "ndfa")
    270 (automata_option "collapse-ndfa")
    271 
    272 (define_query_cpu_unit "d1,l1,s1" "c6x_1")
    273 (define_cpu_unit "x1" "c6x_1")
    274 (define_cpu_unit "l1w,s1w" "c6x_1")
    275 (define_query_cpu_unit "m1" "c6x_m1")
    276 (define_cpu_unit "m1w" "c6x_m1")
    277 (define_cpu_unit "t1" "c6x_t1")
    278 (define_query_cpu_unit "d2,l2,s2" "c6x_2")
    279 (define_cpu_unit "x2" "c6x_2")
    280 (define_cpu_unit "l2w,s2w" "c6x_2")
    281 (define_query_cpu_unit "m2" "c6x_m2")
    282 (define_cpu_unit "m2w" "c6x_m2")
    283 (define_cpu_unit "t2" "c6x_t2")
    284 ;; A special set of units used to identify specific reservations, rather than
    285 ;; just units.
    286 (define_query_cpu_unit "fps1,fpl1,adddps1,adddpl1" "c6x_1")
    287 (define_query_cpu_unit "fps2,fpl2,adddps2,adddpl2" "c6x_2")
    288 
    289 ;; There can be up to two branches in one cycle (on the .s1 and .s2
    290 ;; units), but some instructions must not be scheduled in parallel
    291 ;; with a branch.  We model this by reserving either br0 or br1 for a
    292 ;; normal branch, and both of them for an insn such as callp.
    293 ;; Another constraint is that two branches may only execute in parallel
    294 ;; if one uses an offset, and the other a register.  We can distinguish
    295 ;; these by the dest_regfile attribute; it is "any" iff the branch uses
    296 ;; an offset.  br0 is reserved for these, while br1 is reserved for
    297 ;; branches using a register.
    298 (define_cpu_unit "br0,br1" "c6x_branch")
    299 
    300 (include "c6x-sched.md")
    301 
    302 ;; Some reservations which aren't generated from c6x-sched.md.in
    303 
    304 (define_insn_reservation "branch_s1any" 6
    305   (and (eq_attr "type" "branch")
    306        (and (eq_attr "cross" "n")
    307 	    (and (eq_attr "units" "s")
    308 		 (eq_attr "dest_regfile" "any"))))
    309   "s1+s1w+br0")
    310 
    311 ;; For calls, we also reserve the units needed in the following cycles
    312 ;; to load the return address.  There are two options; using addkpc or
    313 ;; mvkh/mvkl.  The code in c6x_reorg knows whether to use one of these
    314 ;; or whether to use callp.  The actual insns are emitted only after
    315 ;; the final scheduling pass is complete.
    316 ;; We always reserve S2 for PC-relative call insns, since that allows
    317 ;; us to turn them into callp insns later on.
    318 (define_insn_reservation "call_addkpc_s1any" 6
    319   (and (eq_attr "type" "call")
    320        (and (ne (symbol_ref "TARGET_INSNS_64") (const_int 0))
    321 	    (and (eq_attr "cross" "n")
    322 		 (and (eq_attr "units" "s")
    323 		      (eq_attr "dest_regfile" "any")))))
    324   "s2+s2w+br0,s2+s2w+br0+br1")
    325 
    326 (define_insn_reservation "call_mvk_s1any" 6
    327   (and (eq_attr "type" "call")
    328        (and (eq (symbol_ref "TARGET_INSNS_64") (const_int 0))
    329 	    (and (eq_attr "cross" "n")
    330 		 (and (eq_attr "units" "s")
    331 		      (eq_attr "dest_regfile" "any")))))
    332   "s2+s2w+br0,s2+s2w,s2+s2w")
    333 
    334 (define_reservation "all" "s1+s2+d1+d2+l1+l2+m1+m2")
    335 
    336 (define_insn_reservation "callp_s1" 1
    337   (and (eq_attr "type" "callp") (eq_attr "dest_regfile" "a"))
    338   "s1+s1w,all*5")
    339 
    340 (define_insn_reservation "callp_s2" 1
    341   (and (eq_attr "type" "callp") (eq_attr "dest_regfile" "b"))
    342   "s2+s2w,all*5")
    343 
    344 ;; Constraints
    345 
    346 (include "constraints.md")
    347 
    348 ;; Predicates
    349 
    350 (include "predicates.md")
    351 
    352 ;; General predication pattern.
    353 
    354 (define_cond_exec
    355   [(match_operator 0 "eqne_operator"
    356     [(match_operand 1 "predicate_register" "AB")
    357      (const_int 0)])]
    358   ""
    359   "")
    360 
    361 ;; -------------------------------------------------------------------------
    362 ;; NOP instruction
    363 ;; -------------------------------------------------------------------------
    364 
    365 (define_insn "nop"
    366   [(const_int 0)]
    367   ""
    368   "nop")
    369 
    370 (define_insn "nop_count"
    371   [(unspec [(match_operand 0 "const_int_operand" "n")] UNSPEC_NOP)]
    372   ""
    373   "%|%.\\tnop\\t%0")
    374 
    375 ;; -------------------------------------------------------------------------
    376 ;; Move instructions
    377 ;; -------------------------------------------------------------------------
    378 
    379 (define_mode_iterator QIHIM [QI HI])
    380 (define_mode_iterator SIDIM [SI DI])
    381 (define_mode_iterator SIDIVM [SI DI V2HI V4QI])
    382 (define_mode_iterator VEC4M [V2HI V4QI])
    383 (define_mode_iterator VEC8M [V2SI V4HI V8QI])
    384 (define_mode_iterator SISFVM [SI SF V2HI V4QI])
    385 (define_mode_iterator DIDFM [DI DF])
    386 (define_mode_iterator DIDFVM [DI DF V2SI V4HI V8QI])
    387 (define_mode_iterator SFDFM [SF DF])
    388 (define_mode_iterator M32 [QI HI SI SF V2HI V4QI])
    389 
    390 ;; The C6X LO_SUM and HIGH are backwards - HIGH sets the low bits, and
    391 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
    392 ;; so this does not matter.
    393 (define_insn "movsi_lo_sum"
    394   [(set (match_operand:SI 0 "register_operand" "=ab")
    395 	(lo_sum:SI (match_operand:SI 1 "register_operand" "0")
    396 		   (match_operand:SI 2 "const_int_or_symbolic_operand" "i")))]
    397   "reload_completed"
    398   "%|%.\\tmvkh\\t%$\\t%2, %0"
    399   [(set_attr "units" "s")])
    400 
    401 (define_insn "movsi_high"
    402   [(set (match_operand:SI 0 "register_operand" "=ab")
    403 	(high:SI (match_operand:SI 1 "const_int_or_symbolic_operand" "i")))]
    404   "reload_completed"
    405   "%|%.\\tmvkl\\t%$\\t%1, %0"
    406   [(set_attr "units" "s")])
    407 
    408 (define_insn "movsi_gotoff_lo_sum"
    409   [(set (match_operand:SI 0 "register_operand" "=ab")
    410 	(lo_sum:SI (match_operand:SI 1 "register_operand" "0")
    411 		   (unspec:SI [(match_operand:SI 2 "symbolic_operand" "S2")]
    412 			      UNSPEC_GOTOFF)))]
    413   "flag_pic == 2"
    414   "%|%.\\tmvkh\\t%$\\t$dpr_got%2, %0"
    415   [(set_attr "units" "s")])
    416 
    417 (define_insn "movsi_gotoff_high"
    418   [(set (match_operand:SI 0 "register_operand" "=ab")
    419 	(high:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "S2")]
    420 			    UNSPEC_GOTOFF)))]
    421   "flag_pic == 2"
    422   "%|%.\\tmvkl\\t%$\\t$dpr_got%1, %0"
    423   [(set_attr "units" "s")])
    424 
    425 ;; Normally we'd represent this as a normal load insn, but we can't currently
    426 ;; represent the addressing mode.
    427 (define_insn "load_got_gotoff"
    428   [(set (match_operand:SI 0 "register_operand" "=a,b")
    429 	(unspec:SI [(match_operand:SI 1 "register_operand" "Z,Z")
    430 		    (match_operand:SI 2 "register_operand" "b,b")]
    431 		   UNSPEC_GOTOFF))]
    432   "flag_pic == 2"
    433   "%|%.\\tldw\\t%$\\t*+%1[%2], %0"
    434   [(set_attr "type" "load")
    435    (set_attr "units" "d_addr")
    436    (set_attr "op_pattern" "unknown")
    437    (set_attr "dest_regfile" "a,b")
    438    (set_attr "addr_regfile" "b")])
    439 
    440 (define_insn "*movstricthi_high"
    441   [(set (match_operand:SI 0 "register_operand" "+ab")
    442 	(ior:SI (and:SI (match_dup 0) (const_int 65535))
    443 		(ashift:SI (match_operand:SI 1 "const_int_operand" "IuB")
    444 			   (const_int 16))))]
    445   "reload_completed"
    446   "%|%.\\tmvklh\\t%$\\t%1, %0"
    447   [(set_attr "units" "s")])
    448 
    449 ;; Break up SImode loads of immediate operands.
    450 
    451 (define_split
    452   [(set (match_operand:SI 0 "register_operand" "")
    453 	(match_operand:SI 1 "const_int_operand" ""))]
    454   "reload_completed
    455    && !satisfies_constraint_IsB (operands[1])"
    456   [(set (match_dup 0) (match_dup 2))
    457    (set (match_dup 0) (ior:SI (and:SI (match_dup 0) (const_int 65535))
    458 			      (ashift:SI (match_dup 3) (const_int 16))))]
    459 {
    460   HOST_WIDE_INT val = INTVAL (operands[1]);
    461   operands[2] = GEN_INT (trunc_int_for_mode (val, HImode));
    462   operands[3] = GEN_INT ((val >> 16) & 65535);
    463 })
    464 
    465 (define_split
    466   [(set (match_operand:VEC4M 0 "register_operand" "")
    467 	(match_operand:VEC4M 1 "const_vector_operand" ""))]
    468   "reload_completed"
    469   [(set (match_dup 2) (match_dup 3))]
    470 {
    471   unsigned HOST_WIDE_INT mask, val;
    472   machine_mode inner_mode = GET_MODE_INNER (<MODE>mode);
    473   int i;
    474 
    475   val = 0;
    476   mask = GET_MODE_MASK (inner_mode);
    477   if (TARGET_BIG_ENDIAN)
    478     {
    479       for (i = 0; i < GET_MODE_NUNITS (<MODE>mode); i++)
    480 	{
    481 	  val <<= GET_MODE_BITSIZE (inner_mode);
    482 	  val |= INTVAL (CONST_VECTOR_ELT (operands[1], i)) & mask;
    483 	}
    484     }
    485   else
    486     {
    487       i = GET_MODE_NUNITS (<MODE>mode);
    488       while (i-- > 0)
    489 	{
    490 	  val <<= GET_MODE_BITSIZE (inner_mode);
    491 	  val |= INTVAL (CONST_VECTOR_ELT (operands[1], i)) & mask;
    492 	}
    493     }
    494   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));
    495   operands[3] = GEN_INT (trunc_int_for_mode (val, SImode));
    496 })
    497 
    498 (define_split
    499   [(set (match_operand:VEC8M 0 "register_operand" "")
    500 	(match_operand:VEC8M 1 "const_vector_operand" ""))]
    501   "reload_completed"
    502   [(set (match_dup 2) (match_dup 3))
    503    (set (match_dup 4) (match_dup 5))]
    504 {
    505   unsigned HOST_WIDE_INT mask;
    506   unsigned HOST_WIDE_INT val[2];
    507   rtx lo_half, hi_half;
    508   machine_mode inner_mode = GET_MODE_INNER (<MODE>mode);
    509   int i, j;
    510 
    511   split_di (operands, 1, &lo_half, &hi_half);
    512 
    513   val[0] = val[1] = 0;
    514   mask = GET_MODE_MASK (inner_mode);
    515   if (TARGET_BIG_ENDIAN)
    516     {
    517       for (i = 0, j = 1; i < GET_MODE_NUNITS (<MODE>mode); i++)
    518 	{
    519 	  if (i * 2 == GET_MODE_NUNITS (<MODE>mode))
    520 	    j--;
    521 	  val[j] <<= GET_MODE_BITSIZE (inner_mode);
    522 	  val[j] |= INTVAL (CONST_VECTOR_ELT (operands[1], i)) & mask;
    523 	}
    524     }
    525   else
    526     {
    527       i = GET_MODE_NUNITS (<MODE>mode);
    528       j = 1;
    529       while (i-- > 0)
    530         {
    531 	  val[j] <<= GET_MODE_BITSIZE (inner_mode);
    532 	  val[j] |= INTVAL (CONST_VECTOR_ELT (operands[1], i)) & mask;
    533 	  if (i * 2 == GET_MODE_NUNITS (<MODE>mode))
    534 	    j--;
    535 	}
    536     }
    537   operands[2] = lo_half;
    538   operands[3] = GEN_INT (trunc_int_for_mode (val[0], SImode));
    539   operands[4] = hi_half;
    540   operands[5] = GEN_INT (trunc_int_for_mode (val[1], SImode));
    541 })
    542 
    543 (define_split
    544   [(set (match_operand:SF 0 "register_operand" "")
    545 	(match_operand:SF 1 "immediate_operand" ""))]
    546   "reload_completed"
    547   [(set (match_dup 2) (match_dup 3))
    548    (set (match_dup 2) (ior:SI (and:SI (match_dup 2) (const_int 65535))
    549 			      (ashift:SI (match_dup 4) (const_int 16))))]
    550 {
    551   long values;
    552   REAL_VALUE_TYPE value;
    553 
    554   gcc_assert (GET_CODE (operands[1]) == CONST_DOUBLE);
    555 
    556   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
    557   REAL_VALUE_TO_TARGET_SINGLE (value, values);
    558 
    559   operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0]));
    560   operands[3] = GEN_INT (trunc_int_for_mode (values, HImode));
    561   if (values >= -32768 && values < 32768)
    562     {
    563       emit_move_insn (operands[2], operands[3]);
    564       DONE;
    565     }
    566   operands[4] = GEN_INT ((values >> 16) & 65535);
    567 })
    568 
    569 (define_split
    570   [(set (match_operand:SI 0 "register_operand" "")
    571 	(match_operand:SI 1 "symbolic_operand" ""))]
    572   "reload_completed
    573    && (!TARGET_INSNS_64PLUS
    574        || !sdata_symbolic_operand (operands[1], SImode))"
    575   [(set (match_dup 0) (high:SI (match_dup 1)))
    576    (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))]
    577   "")
    578 
    579 ;; Normally, we represent the load of an sdata address as a normal
    580 ;; move of a SYMBOL_REF.  In DSBT mode, B14 is not constant, so we
    581 ;; should show the dependency.
    582 (define_insn "load_sdata_pic"
    583   [(set (match_operand:SI 0 "register_operand" "=a,b")
    584 	(plus:SI (match_operand:SI 1 "pic_register_operand" "Z,Z")
    585 		 (unspec:SI [(match_operand:SI 2 "sdata_symbolic_operand" "S0,S0")]
    586 			    UNSPEC_LOAD_SDATA)))]
    587   "flag_pic"
    588   "@
    589    %|%.\\tadda%D2\\t%$\\t%1, %2, %0
    590    %|%.\\tadda%D2\\t%$\\t%1, %2, %0"
    591   [(set_attr "units" "d")
    592    (set_attr "cross" "y,n")
    593    (set_attr "op_pattern" "unknown")
    594    (set_attr "predicable" "no")])
    595 
    596 ;; Move instruction patterns
    597 
    598 (define_mode_attr LDST_SUFFIX [(QI "b") (HI "h")
    599 			       (SI "w") (SF "w") (V2HI "w") (V4QI "w")
    600 			       (DI "dw") (V2SI "dw") (V4HI "dw") (V8QI "dw")])
    601 
    602 (define_insn "mov<mode>_insn"
    603  [(set (match_operand:QIHIM 0 "nonimmediate_operand"
    604         "=a,b, a, b, ab, ab,a,?a, b,?b, Q, R, R, Q")
    605        (match_operand:QIHIM 1 "general_operand"
    606          "a,b,?b,?a,Is5,IsB,Q, R, R, Q, a,?a, b,?b"))]
    607   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
    608  "@
    609   %|%.\\tmv\\t%$\\t%1, %0
    610   %|%.\\tmv\\t%$\\t%1, %0
    611   %|%.\\tmv\\t%$\\t%1, %0
    612   %|%.\\tmv\\t%$\\t%1, %0
    613   %|%.\\tmvk\\t%$\\t%1, %0
    614   %|%.\\tmvk\\t%$\\t%1, %0
    615   %|%.\\tld<LDST_SUFFIX>\\t%$\\t%1, %0
    616   %|%.\\tld<LDST_SUFFIX>\\t%$\\t%1, %0
    617   %|%.\\tld<LDST_SUFFIX>\\t%$\\t%1, %0
    618   %|%.\\tld<LDST_SUFFIX>\\t%$\\t%1, %0
    619   %|%.\\tst<LDST_SUFFIX>\\t%$\\t%1, %0
    620   %|%.\\tst<LDST_SUFFIX>\\t%$\\t%1, %0
    621   %|%.\\tst<LDST_SUFFIX>\\t%$\\t%1, %0
    622   %|%.\\tst<LDST_SUFFIX>\\t%$\\t%1, %0"
    623   [(set_attr "type" "*,*,*,*,*,*,load,load,load,load,store,store,store,store")
    624    (set_attr "units62" "dls,dls,ls,ls,s,s,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr")
    625    (set_attr "units64" "dls,dls,ls,ls,dl,s,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr")
    626    (set_attr "op_pattern" "sx,sx,sx,sx,*,*,*,*,*,*,*,*,*,*")
    627    (set_attr "addr_regfile" "*,*,*,*,*,*,a,b,b,a,a,b,b,a")
    628    (set_attr "dest_regfile" "*,*,*,*,*,*,a,a,b,b,a,a,b,b")
    629    (set_attr "cross" "n,n,y,y,n,n,n,y,n,y,n,y,n,y")])
    630 
    631 (define_insn "mov<mode>_insn"
    632  [(set (match_operand:SISFVM 0 "nonimmediate_operand"
    633         "=a,b, a, b, ab, ab,a,b,ab,a,?a, b,?b, Q, R, R, Q")
    634        (match_operand:SISFVM 1 "general_operand"
    635          "a,b,?b,?a,Is5,IsB,S0,S0,Si,Q, R, R, Q, a,?a, b,?b"))]
    636   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG
    637     || (GET_CODE (operands[1]) == SUBREG && REG_P (SUBREG_REG (operands[1]))))"
    638  "@
    639   %|%.\\tmv\\t%$\\t%1, %0
    640   %|%.\\tmv\\t%$\\t%1, %0
    641   %|%.\\tmv\\t%$\\t%1, %0
    642   %|%.\\tmv\\t%$\\t%1, %0
    643   %|%.\\tmvk\\t%$\\t%1, %0
    644   %|%.\\tmvk\\t%$\\t%1, %0
    645   %|%.\\tadda%D1\\t%$\\tB14, %1, %0
    646   %|%.\\tadda%D1\\t%$\\tB14, %1, %0
    647   #
    648   %|%.\\tldw\\t%$\\t%1, %0
    649   %|%.\\tldw\\t%$\\t%1, %0
    650   %|%.\\tldw\\t%$\\t%1, %0
    651   %|%.\\tldw\\t%$\\t%1, %0
    652   %|%.\\tstw\\t%$\\t%1, %0
    653   %|%.\\tstw\\t%$\\t%1, %0
    654   %|%.\\tstw\\t%$\\t%1, %0
    655   %|%.\\tstw\\t%$\\t%1, %0"
    656   [(set_attr "type" "*,*,*,*,*,*,*,*,*,load,load,load,load,store,store,store,store")
    657    (set_attr "units62" "dls,dls,ls,ls,s,s,d,d,*,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr")
    658    (set_attr "units64" "dls,dls,ls,ls,dl,s,d,d,*,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr")
    659    (set_attr "op_pattern" "sx,sx,sx,sx,*,*,*,*,*,*,*,*,*,*,*,*,*")
    660    (set_attr "addr_regfile" "*,*,*,*,*,*,*,*,*,a,b,b,a,a,b,b,a")
    661    (set_attr "dest_regfile" "*,*,*,*,*,*,*,*,*,a,a,b,b,a,a,b,b")
    662    (set_attr "cross" "n,n,y,y,n,n,y,n,*,n,y,n,y,n,y,n,y")
    663    (set_attr "predicable" "yes,yes,yes,yes,yes,yes,no,no,yes,yes,yes,yes,yes,yes,yes,yes,yes")])
    664 
    665 (define_insn "*mov<mode>_insn"
    666   [(set (match_operand:DIDFVM 0 "nonimmediate_operand"
    667          "=a,b, a, b,ab,a,?a, b,?b, Q, R, R, Q")
    668         (match_operand:DIDFVM 1 "general_operand"
    669           "a,b,?b,?a,iF,Q, R, R, Q, a,?a, b,?b"))]
    670   "(!MEM_P (operands[0]) || REG_P (operands[1])
    671     || (GET_CODE (operands[1]) == SUBREG && REG_P (SUBREG_REG (operands[1]))))"
    672 {
    673   if (MEM_P (operands[1]) && TARGET_LDDW)
    674     return "%|%.\\tlddw\\t%$\\t%1, %0";
    675   if (MEM_P (operands[0]) && TARGET_STDW)
    676     return "%|%.\\tstdw\\t%$\\t%1, %0";
    677   if (TARGET_INSNS_64PLUS && REG_P (operands[0]) && REG_P (operands[1])
    678       && A_REGNO_P (REGNO (operands[0])) == A_REGNO_P (REGNO (operands[1])))
    679     return "%|%.\\tdmv\\t%$\\t%P1, %p1, %0";
    680   return "#";
    681 }
    682   [(set_attr "units" "s,s,*,*,*,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr,d_addr")
    683    (set_attr "addr_regfile" "*,*,*,*,*,a,b,b,a,a,b,b,a")
    684    (set_attr "dest_regfile" "*,*,*,*,*,a,a,b,b,a,a,b,b")
    685    (set_attr "type" "*,*,*,*,*,load,load,load,load,store,store,store,store")
    686    (set_attr "cross" "n,n,y,y,*,n,y,n,y,n,y,n,y")])
    687 
    688 (define_split
    689   [(set (match_operand:DIDFVM 0 "nonimmediate_operand" "")
    690   	(match_operand:DIDFVM 1 "general_operand" ""))]
    691   "reload_completed
    692    && !((MEM_P (operands[0]) && TARGET_STDW)
    693  	|| (MEM_P (operands[1]) && TARGET_LDDW))
    694    && !const_vector_operand (operands[1], <MODE>mode)
    695    && !(TARGET_INSNS_64PLUS && REG_P (operands[0]) && REG_P (operands[1])
    696 	&& A_REGNO_P (REGNO (operands[0])) == A_REGNO_P (REGNO (operands[1])))"
    697   [(set (match_dup 2) (match_dup 3))
    698    (set (match_dup 4) (match_dup 5))]
    699 {
    700   rtx lo_half[2], hi_half[2];
    701   split_di (operands, 2, lo_half, hi_half);
    702 
    703   /* We can't have overlap for a register-register move, but if
    704      memory is involved, we have to make sure we don't clobber the
    705      address.  */
    706   if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
    707     {
    708       operands[2] = hi_half[0];
    709       operands[3] = hi_half[1];
    710       operands[4] = lo_half[0];
    711       operands[5] = lo_half[1];
    712     }
    713   else
    714     {
    715       operands[2] = lo_half[0];
    716       operands[3] = lo_half[1];
    717       operands[4] = hi_half[0];
    718       operands[5] = hi_half[1];
    719     }
    720 })
    721 
    722 (define_insn "real_load<mode>"
    723   [(unspec [(match_operand 0 "const_int_operand" "JA,JA,JB,JB")
    724 	    (match_operand:M32 1 "memory_operand" "Q,R,R,Q")]
    725 	   UNSPEC_REAL_LOAD)]
    726   ""
    727   "%|%.\\tld<LDST_SUFFIX>\\t%$\\t%1, %k0"
    728   [(set_attr "type" "load")
    729    (set_attr "units" "d_addr")
    730    (set_attr "addr_regfile" "a,b,b,a")
    731    (set_attr "dest_regfile" "a,a,b,b")
    732    (set_attr "cross" "n,y,n,y")])
    733 
    734 (define_insn "real_load<mode>"
    735   [(unspec [(match_operand 0 "const_int_operand" "JA,JA,JB,JB")
    736 	    (match_operand:DIDFVM 1 "memory_operand" "Q,R,R,Q")]
    737 	   UNSPEC_REAL_LOAD)]
    738   "TARGET_LDDW"
    739   "%|%.\\tlddw\\t%$\\t%1, %K0"
    740   [(set_attr "type" "load")
    741    (set_attr "units" "d_addr")
    742    (set_attr "addr_regfile" "a,b,b,a")
    743    (set_attr "dest_regfile" "a,a,b,b")
    744    (set_attr "cross" "n,y,n,y")])
    745 
    746 (define_insn "load_shadow"
    747   [(set (match_operand 0 "register_operand" "=ab")
    748  	(unspec [(pc)] UNSPEC_LOAD_SHADOW))]
    749   ""
    750   ";; load to %0 occurs"
    751   [(set_attr "type" "load_shadow")])
    752 
    753 (define_insn "mult_shadow"
    754   [(set (match_operand 0 "register_operand" "=ab")
    755  	(unspec [(pc)] UNSPEC_MULT_SHADOW))]
    756   ""
    757   ";; multiplication occurs and stores to %0"
    758   [(set_attr "type" "mult_shadow")])
    759 
    760 
    761 (define_mode_iterator MOV [QI HI SI SF DI DF V2HI V4QI V2SI V4HI V8QI])
    762 
    763 (define_expand "mov<mode>"
    764   [(set (match_operand:MOV 0 "nonimmediate_operand" "")
    765 	(match_operand:MOV 1 "general_operand" ""))]
    766   ""
    767 {
    768   if (expand_move (operands, <MODE>mode))
    769     DONE;
    770 })
    771 
    772 (define_expand "movmisalign<mode>"
    773   [(set (match_operand:SIDIVM 0 "nonimmediate_operand"	      "")
    774 	(unspec:SIDIVM [(match_operand:SIDIVM 1 "nonimmediate_operand" "")]
    775 		       UNSPEC_MISALIGNED_ACCESS))]
    776   "TARGET_INSNS_64"
    777 {
    778   if (MEM_P (operands[0]))
    779     {
    780       emit_insn (gen_movmisalign<mode>_store (operands[0], operands[1]));
    781       DONE;
    782     }
    783 })
    784 
    785 (define_insn_and_split "movmisalign<mode>_store"
    786   [(set (match_operand:SIDIVM 0 "memory_operand" "=W,Q,T,Q,T")
    787 	(unspec:SIDIVM [(match_operand:SIDIVM 1 "register_operand" "r,a,b,b,a")]
    788 		       UNSPEC_MISALIGNED_ACCESS))
    789    (clobber (match_scratch:SI 2 "=r,X,X,X,X"))]
    790   "TARGET_INSNS_64"
    791   "@
    792    #
    793    %|%.\\tstn<LDST_SUFFIX>\\t%$\\t%1, %0
    794    %|%.\\tstn<LDST_SUFFIX>\\t%$\\t%1, %0
    795    %|%.\\tstn<LDST_SUFFIX>\\t%$\\t%1, %0
    796    %|%.\\tstn<LDST_SUFFIX>\\t%$\\t%1, %0"
    797   "&& reload_completed && satisfies_constraint_W (operands[0])"
    798   [(parallel
    799     [(set (match_dup 3) (unspec:SIDIVM [(match_dup 1)] UNSPEC_MISALIGNED_ACCESS))
    800      (clobber (match_dup 4))])]
    801 {
    802   rtx addr = XEXP (operands[0], 0);
    803   rtx tmpreg = operands[2];
    804 
    805   if (GET_CODE (addr) == PLUS && XEXP (addr, 0) == stack_pointer_rtx
    806       && GET_CODE (XEXP (addr, 1)) == CONST_INT)
    807     {
    808       unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
    809       val &= GET_MODE_SIZE (<MODE>mode) - 1;
    810       if (val == 0)
    811 	{
    812 	  emit_move_insn (operands[0], operands[1]);
    813 	  DONE;
    814 	}
    815     }
    816   operands[3] = change_address (operands[0], <MODE>mode, tmpreg);
    817   emit_move_insn (tmpreg, addr);
    818   operands[4] = gen_rtx_SCRATCH (SImode);
    819 }
    820   [(set_attr "type" "storen")
    821    (set_attr "units" "d_addr")
    822    (set_attr "addr_regfile" "*,a,b,a,b")
    823    (set_attr "dest_regfile" "*,a,b,b,a")
    824    (set_attr "cross" "*,n,n,y,y")])
    825 
    826 (define_insn_and_split "movmisalign<mode>_load"
    827   [(set (match_operand:SIDIVM 0 "register_operand" "=ab,a,b,b,a")
    828 	(unspec:SIDIVM [(match_operand:SIDIVM 1 "memory_operand" "W,Q,T,Q,T")]
    829 		       UNSPEC_MISALIGNED_ACCESS))]
    830   "TARGET_INSNS_64"
    831   "@
    832    #
    833    %|%.\\tldn<LDST_SUFFIX>\\t%$\\t%1, %0
    834    %|%.\\tldn<LDST_SUFFIX>\\t%$\\t%1, %0
    835    %|%.\\tldn<LDST_SUFFIX>\\t%$\\t%1, %0
    836    %|%.\\tldn<LDST_SUFFIX>\\t%$\\t%1, %0"
    837   "&& reload_completed && satisfies_constraint_W (operands[1])"
    838   [(set (match_dup 0) (unspec:SIDIVM [(match_dup 2)] UNSPEC_MISALIGNED_ACCESS))]
    839 {
    840   rtx addr = XEXP (operands[1], 0);
    841   rtx tmpreg = (GET_MODE (operands[0]) == SImode ? operands[0]
    842 		: operand_subword_force (operands[0], 0, DImode));
    843 
    844   if (GET_CODE (addr) == PLUS && XEXP (addr, 0) == stack_pointer_rtx
    845       && GET_CODE (XEXP (addr, 1)) == CONST_INT)
    846     {
    847       unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
    848       val &= GET_MODE_SIZE (<MODE>mode) - 1;
    849       if (val == 0)
    850 	{
    851 	  emit_move_insn (operands[0], operands[1]);
    852 	  DONE;
    853 	}
    854     }
    855   operands[2] = change_address (operands[1], <MODE>mode, tmpreg);
    856   emit_move_insn (tmpreg, addr);
    857 }
    858   [(set_attr "type" "loadn")
    859    (set_attr "units" "d_addr")
    860    (set_attr "addr_regfile" "*,a,b,a,b")
    861    (set_attr "dest_regfile" "*,a,b,b,a")
    862    (set_attr "cross" "*,n,n,y,y")])
    863 
    864 ;;
    865 
    866 ;; -------------------------------------------------------------------------
    867 ;; Extensions/extractions
    868 ;; -------------------------------------------------------------------------
    869 
    870 (define_code_iterator any_extract [zero_extract sign_extract])
    871 (define_code_iterator any_ext [zero_extend sign_extend])
    872 
    873 (define_code_attr ext_name [(zero_extend "zero_extend") (sign_extend "sign_extend")])
    874 
    875 (define_code_attr u [(zero_extend "u") (sign_extend "")])
    876 
    877 (define_code_attr z [(zero_extract "z") (sign_extract "")])
    878 (define_code_attr zu [(zero_extract "u") (sign_extract "")])
    879 
    880 (define_mode_attr ext_shift [(QI "24") (HI "16")])
    881 
    882 (define_insn "<ext_name><mode>si2"
    883  [(set (match_operand:SI 0 "register_operand" "=a,b,a,?a, b,?b")
    884        (any_ext:SI (match_operand:QIHIM 1 "nonimmediate_operand" "a,b,Q, R, R, Q")))]
    885   ""
    886  "@
    887   %|%.\\text<u>\\t%$\\t%1, <ext_shift>, <ext_shift>, %0
    888   %|%.\\text<u>\\t%$\\t%1, <ext_shift>, <ext_shift>, %0
    889   %|%.\\tld<LDST_SUFFIX><u>\\t%$\\t%1, %0
    890   %|%.\\tld<LDST_SUFFIX><u>\\t%$\\t%1, %0
    891   %|%.\\tld<LDST_SUFFIX><u>\\t%$\\t%1, %0
    892   %|%.\\tld<LDST_SUFFIX><u>\\t%$\\t%1, %0"
    893   [(set_attr "type" "*,*,load,load,load,load")
    894    (set_attr "units" "s,s,d_addr,d_addr,d_addr,d_addr")
    895    (set_attr "addr_regfile" "*,*,a,b,b,a")
    896    (set_attr "dest_regfile" "*,*,a,a,b,b")
    897    (set_attr "cross" "n,n,n,y,n,y")])
    898 
    899 (define_insn "*ext<z>v_const"
    900   [(set (match_operand:SI 0 "nonimmediate_operand" "=a,b")
    901 	(any_extract:SI (match_operand:SI 1 "register_operand" "a,b")
    902 			(match_operand:SI 2 "const_int_operand" "n,n")
    903 			(match_operand:SI 3 "const_int_operand" "n,n")))]
    904   "INTVAL (operands[3]) >= 0
    905    && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
    906 {
    907   int pos = INTVAL (operands[3]);
    908   int len = INTVAL (operands[2]);
    909   rtx xop[4];
    910   xop[0] = operands[0];
    911   xop[1] = operands[1];
    912   xop[2] = GEN_INT (32 - pos - len);
    913   xop[3] = GEN_INT (32 - len);
    914 
    915   output_asm_insn ("%|%.\\text<zu>\\t%$\\t%1, %2, %3, %0", xop);
    916   return "";
    917 }
    918   [(set_attr "units" "s")
    919    (set_attr "cross" "n")])
    920 
    921 (define_expand "ext<z>v"
    922   [(set (match_operand:SI 0 "register_operand" "")
    923 	(any_extract:SI (match_operand:SI 1 "register_operand" "")
    924 			(match_operand:SI 2 "const_int_operand" "")
    925 			(match_operand:SI 3 "const_int_operand" "")))]
    926   ""
    927 {
    928    if (INTVAL (operands[2]) < 0
    929        || INTVAL (operands[2]) + INTVAL (operands[3]) > 32)
    930      FAIL;
    931 })
    932 
    933 (define_insn "real_<ext_name><mode>"
    934   [(unspec [(match_operand 0 "const_int_operand" "JA,JA,JB,JB")
    935 	    (any_ext:SI (match_operand:QIHIM 1 "memory_operand" "Q,R,R,Q"))]
    936 	   UNSPEC_REAL_LOAD)]
    937   ""
    938   "%|%.\\tld<LDST_SUFFIX><u>\\t%$\\t%1, %k0"
    939   [(set_attr "type" "load")
    940    (set_attr "units" "d_addr")
    941    (set_attr "addr_regfile" "a,b,b,a")
    942    (set_attr "dest_regfile" "a,a,b,b")
    943    (set_attr "cross" "n,y,n,y")])
    944 
    945 (define_insn "clrr"
    946   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b")
    947 	(unspec:SI [(match_operand:SI 1 "register_operand" "0,0,0,0")
    948 		    (match_operand:SI 2 "register_operand" "a,b,?b,?a")
    949 		    (match_operand:SI 3 "reg_or_const_int_operand" "ai,bi,a,b")]
    950 		   UNSPEC_CLR))]
    951   ""
    952 {
    953   if (CONST_INT_P (operands[2]))
    954     {
    955       rtx xops[4];
    956       int v1 = INTVAL (operands[2]);
    957       int v2 = (v1 >> 5) & 0x1f;
    958       v1 &= 0x1f;
    959       xops[0] = operands[0];
    960       xops[1] = operands[1];
    961       xops[2] = GEN_INT (v1);
    962       xops[3] = GEN_INT (v2);
    963       output_asm_insn ("%|%.\\tclr\\t%$\\t%1, %3, %2, %0", xops);
    964       return "";
    965     }
    966   return "%|%.\\tclr\\t%$\\t%2, %3, %0";
    967 }
    968   [(set_attr "units" "s")
    969    (set_attr "cross" "n,n,y,y")])
    970 
    971 (define_insn "extr"
    972   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b")
    973 	(unspec:SI [(match_operand:SI 1 "register_operand" "a,b,?b,?a")
    974 		    (match_operand:SI 2 "reg_or_const_int_operand" "ai,bi,a,b")]
    975 		   UNSPEC_EXT))]
    976   ""
    977 {
    978   if (CONST_INT_P (operands[2]))
    979     {
    980       rtx xops[4];
    981       int v1 = INTVAL (operands[2]);
    982       int v2 = (v1 >> 5) & 0x1f;
    983       v1 &= 0x1f;
    984       xops[0] = operands[0];
    985       xops[1] = operands[1];
    986       xops[2] = GEN_INT (v1);
    987       xops[3] = GEN_INT (v2);
    988       output_asm_insn ("%|%.\\text\\t%$\\t%1, %3, %2, %0", xops);
    989       return "";
    990     }
    991   return "%|%.\\text\\t%$\\t%1, %2, %0";
    992 }
    993   [(set_attr "units" "s")
    994    (set_attr "cross" "n,n,y,y")])
    995 
    996 (define_insn "extru"
    997   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b")
    998 	(unspec:SI [(match_operand:SI 1 "register_operand" "a,b,?b,?a")
    999 		    (match_operand:SI 2 "reg_or_const_int_operand" "ai,bi,a,b")]
   1000 		   UNSPEC_EXTU))]
   1001   ""
   1002 {
   1003   if (CONST_INT_P (operands[2]))
   1004     {
   1005       rtx xops[4];
   1006       int v1 = INTVAL (operands[2]);
   1007       int v2 = (v1 >> 5) & 0x1f;
   1008       v1 &= 0x1f;
   1009       xops[0] = operands[0];
   1010       xops[1] = operands[1];
   1011       xops[2] = GEN_INT (v1);
   1012       xops[3] = GEN_INT (v2);
   1013       output_asm_insn ("%|%.\\textu\\t%$\\t%1, %3, %2, %0", xops);
   1014       return "";
   1015     }
   1016   return "%|%.\\textu\\t%$\\t%1, %2, %0";
   1017 }
   1018   [(set_attr "units" "s")
   1019    (set_attr "cross" "n,y,n,y")])
   1020 
   1021 ;; -------------------------------------------------------------------------
   1022 ;; Compare instructions
   1023 ;; -------------------------------------------------------------------------
   1024 
   1025 (define_insn "scmpsi_insn"
   1026   [(set (match_operand:SI 0 "register_operand" "=ab,a,b,a,b")
   1027 	(match_operator:SI 1 "eqltgt_operator"
   1028 	   [(match_operand:SI 2 "register_operand" "ab,a,b,?b,?a")
   1029 	    (match_operand:SI 3 "reg_or_scst5_operand" "Is5,aIs5,bIs5,aIs5,bIs5")]))]
   1030   ""
   1031   "%|%.\\tcmp%C1\\t%$\\t%3, %2, %0"
   1032   [(set_attr "units" "l")
   1033    (set (attr "cross")
   1034 	(symbol_ref "CROSS_OPERANDS (operands[0], operands[2])"))])
   1035 
   1036 (define_insn "*ucmpsi_insn_64"
   1037   [(set (match_operand:SI 0 "register_operand" "=ab,a,b,a,b")
   1038 	(match_operator:SI 1 "ltugtu_operator"
   1039 	   [(match_operand:SI 2 "register_operand" "ab,a,b,?b,?a")
   1040 	    (match_operand:SI 3 "reg_or_ucst5_operand" "Iu5,aIu5,bIu5,aIu5,bIu5")]))]
   1041   "TARGET_INSNS_64"
   1042   "%|%.\\tcmp%C1\\t%$\\t%3, %2, %0"
   1043   [(set_attr "units" "l")
   1044    (set (attr "cross")
   1045 	(symbol_ref "CROSS_OPERANDS (operands[0], operands[2])"))])
   1046 
   1047 (define_insn "*ucmpsi_insn"
   1048   [(set (match_operand:SI 0 "register_operand" "=ab,a,b,a,b")
   1049 	(match_operator:SI 1 "ltugtu_operator"
   1050 	   [(match_operand:SI 2 "register_operand" "ab,a,b,?b,?a")
   1051 	    (match_operand:SI 3 "reg_or_ucst4_operand" "Iu4,aIu4,bIu4,aIu4,bIu4")]))]
   1052   "!TARGET_INSNS_64"
   1053   "%|%.\\tcmp%C1\\t%$\\t%3, %2, %0"
   1054   [(set_attr "units" "l")
   1055    (set (attr "cross")
   1056 	(symbol_ref "CROSS_OPERANDS (operands[0], operands[2])"))])
   1057 
   1058 (define_code_iterator andior_eqne [eq ne])
   1059 (define_code_attr andior_name [(eq "and") (ne "ior")])
   1060 (define_code_attr andior_condmod [(eq "") (ne "!")])
   1061 
   1062 (define_insn "*scmpsi_<andior_name>_insn"
   1063   [(set (match_operand:SI 0 "register_operand" "=A,B,A,B")
   1064 	(if_then_else:SI
   1065 	 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0")
   1066 			 (const_int 0))
   1067 	 (match_dup 4)
   1068 	 (match_operator:SI 1 "eqltgt_operator"
   1069 	  [(match_operand:SI 2 "register_operand" "a,b,?b,?a")
   1070 	   (match_operand:SI 3 "reg_or_scst5_operand" "aIs5,bIs5,aIs5,bIs5")])))]
   1071   ""
   1072   "%|[<andior_condmod>%4]\\tcmp%C1\\t%$\\t%3, %2, %0"
   1073   [(set_attr "units" "l")
   1074    (set_attr "cross" "n,n,y,y")
   1075    (set_attr "predicable" "no")])
   1076 
   1077 (define_insn "*ucmpsi_<andior_name>_insn_64"
   1078   [(set (match_operand:SI 0 "register_operand" "=A,B,A,B")
   1079 	(if_then_else:SI
   1080 	 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0")
   1081 			 (const_int 0))
   1082 	 (match_dup 4)
   1083 	 (match_operator:SI 1 "ltugtu_operator"
   1084 	  [(match_operand:SI 2 "register_operand" "a,b,?b,?a")
   1085 	   (match_operand:SI 3 "reg_or_ucst5_operand" "aIu5,bIu5,aIu5,bIu5")])))]
   1086   "TARGET_INSNS_64"
   1087   "%|[<andior_condmod>%4]\\tcmp%C1\\t%$\\t%3, %2, %0"
   1088   [(set_attr "units" "l")
   1089    (set_attr "cross" "n,n,y,y")
   1090    (set_attr "predicable" "no")])
   1091 
   1092 (define_insn "*ucmpsi_<andior_name>_insn"
   1093   [(set (match_operand:SI 0 "register_operand" "=A,B,A,B")
   1094 	(if_then_else:SI
   1095 	 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0")
   1096 			 (const_int 0))
   1097 	 (match_dup 4)
   1098 	 (match_operator:SI 1 "ltugtu_operator"
   1099 	  [(match_operand:SI 2 "register_operand" "a,b,?b,?a")
   1100 	   (match_operand:SI 3 "reg_or_ucst4_operand" "aIu4,bIu4,aIu4,bIu4")])))]
   1101   "!TARGET_INSNS_64"
   1102   "%|[<andior_condmod>%4]\\tcmp%C1\\t%$\\t%3, %2, %0"
   1103   [(set_attr "units" "l")
   1104    (set_attr "cross" "n,n,y,y")
   1105    (set_attr "predicable" "no")])
   1106 
   1107 (define_expand "cmpsi_<andior_name>"
   1108   [(set (match_operand:SI 0 "register_operand" "")
   1109 	(if_then_else:SI
   1110 	 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0")
   1111 			 (const_int 0))
   1112 	 (match_dup 4)
   1113 	 (match_operator:SI 1 "c6x_comparison_operator"
   1114 	  [(match_operand:SI 2 "register_operand" "")
   1115 	   (match_operand:SI 3 "reg_or_const_int_operand" "")])))]
   1116   ""
   1117 {
   1118   if (c6x_force_op_for_comparison_p (GET_CODE (operands[1]), operands[3]))
   1119     operands[3] = force_reg (SImode, operands[3]);
   1120 })
   1121 
   1122 (define_insn "*cmpsf_insn"
   1123   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b")
   1124 	(match_operator:SI 1 "eqltgt_operator"
   1125 	   [(match_operand:SF 2 "register_operand" "a,b,a,b")
   1126 	    (match_operand:SF 3 "register_operand" "a,b,?b,?a")]))]
   1127   "TARGET_FP"
   1128   "%|%.\\tcmp%c1sp\\t%$\\t%2, %3, %0"
   1129   [(set_attr "units" "s")
   1130    (set_attr "cross" "n,n,y,y")])
   1131 
   1132 (define_insn "*cmpdf_insn"
   1133   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b")
   1134 	(match_operator:SI 1 "eqltgt_operator"
   1135 	   [(match_operand:DF 2 "register_operand" "a,b,a,b")
   1136 	    (match_operand:DF 3 "register_operand" "a,b,?b,?a")]))]
   1137   "TARGET_FP"
   1138   "%|%.\\tcmp%c1dp\\t%$\\t%2, %3, %0"
   1139   [(set_attr "type" "cmpdp")
   1140    (set_attr "units" "s")
   1141    (set_attr "cross" "n,n,y,y")])
   1142 
   1143 (define_expand "cmp<mode>_<andior_name>"
   1144   [(set (match_operand:SI 0 "register_operand" "")
   1145 	(if_then_else:SI
   1146 	 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0")
   1147 			 (const_int 0))
   1148 	 (match_dup 4)
   1149 	 (match_operator:SI 1 "eqltgt_operator"
   1150 	   [(match_operand:SFDFM 2 "register_operand" "")
   1151 	    (match_operand:SFDFM 3 "register_operand" "")])))]
   1152   "TARGET_FP")
   1153 
   1154 (define_insn "*cmpsf_<andior_name>_insn"
   1155   [(set (match_operand:SI 0 "register_operand" "=A,B,A,B")
   1156 	(if_then_else:SI
   1157 	 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0")
   1158 			 (const_int 0))
   1159 	 (match_dup 4)
   1160 	 (match_operator:SI 1 "eqltgt_operator"
   1161 	   [(match_operand:SF 2 "register_operand" "a,b,a,b")
   1162 	    (match_operand:SF 3 "register_operand" "a,b,?b,?a")])))]
   1163   "TARGET_FP"
   1164   "%|[<andior_condmod>%4]\\tcmp%c1sp\\t%$\\t%2, %3, %0"
   1165   [(set_attr "units" "s")
   1166    (set_attr "cross" "n,n,y,y")
   1167    (set_attr "predicable" "no")])
   1168 
   1169 ;; reload_reg_class_lower will ensure that two-word reloads are allocated first,
   1170 ;; which could exhaust the predicate registers if we used just "a" and "b"
   1171 ;; constraints on operands 2 and 3.
   1172 (define_insn "*cmpdf_<andior_name>_insn"
   1173   [(set (match_operand:SI 0 "register_operand" "=A,B,A,B")
   1174 	(if_then_else:SI
   1175 	 (andior_eqne:SI (match_operand:SI 4 "register_operand" "0,0,0,0")
   1176 			 (const_int 0))
   1177 	 (match_dup 4)
   1178 	 (match_operator:SI 1 "eqltgt_operator"
   1179 	   [(match_operand:DF 2 "register_operand" "Da,Db,Da,Db")
   1180 	    (match_operand:DF 3 "register_operand" "Da,Db,?Db,?Da")])))]
   1181   "TARGET_FP"
   1182   "%|[<andior_condmod>%4]\\tcmp%c1dp\\t%$\\t%2, %3, %0"
   1183   [(set_attr "type" "cmpdp")
   1184    (set_attr "units" "s")
   1185    (set_attr "cross" "n,n,y,y")
   1186    (set_attr "predicable" "no")])
   1187 
   1188 (define_split
   1189   [(set (match_operand:SI 0 "register_operand" "")
   1190 	(ior:SI (match_operand 1 "c6x_any_comparison_operand" "")
   1191 		(match_operand 2 "c6x_any_comparison_operand" "")))]
   1192   "!reg_overlap_mentioned_p (operands[0], operands[2])"
   1193   [(set (match_dup 0) (match_dup 1))
   1194    (set (match_dup 0)
   1195 	(if_then_else:SI (ne:SI (match_dup 0) (const_int 0))
   1196 			 (match_dup 0)
   1197 			 (match_dup 2)))])
   1198 
   1199 (define_split
   1200   [(set (match_operand:SI 0 "register_operand" "")
   1201 	(and:SI (match_operand 1 "c6x_any_comparison_operand" "")
   1202 		(match_operand 2 "c6x_any_comparison_operand" "")))]
   1203   "!reg_overlap_mentioned_p (operands[0], operands[2])"
   1204   [(set (match_dup 0) (match_dup 1))
   1205    (set (match_dup 0)
   1206 	(if_then_else:SI (eq:SI (match_dup 0) (const_int 0))
   1207 			 (match_dup 0)
   1208 			 (match_dup 2)))])
   1209 
   1210 
   1211 ;; -------------------------------------------------------------------------
   1212 ;; setcc instructions
   1213 ;; -------------------------------------------------------------------------
   1214 
   1215 (define_expand "cstoresi4"
   1216   [(set (match_operand:SI 0 "register_operand" "")
   1217 	(match_operator:SI 1 "comparison_operator"
   1218 	 [(match_operand:SI 2 "register_operand" "")
   1219 	  (match_operand:SI 3 "reg_or_ucst4_operand" "")]))]
   1220   ""
   1221 {
   1222   if (!c6x_comparison_operator (operands[1], SImode))
   1223     {
   1224       rtx tmpreg = gen_reg_rtx (SImode);
   1225       rtx t = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
   1226 			      SImode, operands[2], operands[3]);
   1227       emit_insn (gen_rtx_SET (VOIDmode, tmpreg, t));
   1228       emit_insn (gen_scmpsi_insn (operands[0],
   1229 				  gen_rtx_fmt_ee (EQ, SImode, tmpreg, const0_rtx),
   1230 				  tmpreg, const0_rtx));
   1231       DONE;
   1232     }
   1233 })
   1234 
   1235 ;; -------------------------------------------------------------------------
   1236 ;; Jump instructions
   1237 ;; -------------------------------------------------------------------------
   1238 
   1239 (define_insn "indirect_jump"
   1240   [(set (pc) (match_operand:SI 0 "register_operand" "a,b"))]
   1241   ""
   1242   "%|%.\\tb\\t%$\\t%0"
   1243   [(set_attr "type" "branch")
   1244    (set_attr "units" "s")
   1245    (set_attr "cross" "y,n")
   1246    (set_attr "dest_regfile" "b")])
   1247 
   1248 (define_insn "jump"
   1249   [(set (pc)
   1250 	(label_ref (match_operand 0 "" "")))]
   1251   ""
   1252   "%|%.\\tb\\t%$\\t%l0"
   1253   [(set_attr "type" "branch")
   1254    (set_attr "units" "s")
   1255    (set_attr "dest_regfile" "any")])
   1256 
   1257 (define_expand "tablejump"
   1258   [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
   1259               (use (label_ref (match_operand 1 "" "")))])]
   1260   "!flag_pic || !TARGET_INSNS_64"
   1261 {
   1262 })
   1263 
   1264 (define_insn "*tablejump_internal"
   1265   [(set (pc) (match_operand:SI 0 "register_operand" "b"))
   1266    (use (label_ref (match_operand 1 "" "")))]
   1267   "!flag_pic || !TARGET_INSNS_64"
   1268   "%|\\tb\\t%$\\t%0"
   1269   [(set_attr "type" "branch")
   1270    (set_attr "predicable" "no")
   1271    (set_attr "units" "s")
   1272    (set_attr "dest_regfile" "b")])
   1273 
   1274 ;; Implement switch statements when generating PIC code.  Switches are
   1275 ;; implemented by `tablejump' when not using -fpic.
   1276 
   1277 ;; Emit code here to do the range checking and make the index zero based.
   1278 ;; operand 0 is the index
   1279 ;; operand 1 is the lower bound
   1280 ;; operand 2 is the range of indices (highest - lowest + 1)
   1281 ;; operand 3 is the label that precedes the table itself
   1282 ;; operand 4 is the fall through label
   1283 
   1284 (define_expand "casesi"
   1285   [(use (match_operand:SI 0 "register_operand" ""))
   1286    (use (match_operand:SI 1 "const_int_operand" ""))
   1287    (use (match_operand:SI 2 "const_int_operand" ""))
   1288    (use (match_operand 3 "" ""))
   1289    (use (match_operand 4 "" ""))]
   1290   "flag_pic && TARGET_INSNS_64"
   1291 {
   1292   rtx indx;
   1293   rtx low = operands[1];
   1294   rtx range = operands[2];
   1295   rtx table = operands[3];
   1296   rtx fail = operands[4];
   1297 
   1298   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
   1299   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
   1300 
   1301   if (!reg_or_ucst4_operand (range, SImode))
   1302     range = force_reg (SImode, range);
   1303 
   1304   /* If low bound is 0, we don't have to subtract it.  */
   1305   if (INTVAL (operands[1]) == 0)
   1306     indx = operands[0];
   1307   else
   1308     {
   1309       rtx offset = GEN_INT (-INTVAL (low));
   1310       indx = gen_reg_rtx (SImode);
   1311       if (!addsi_operand (offset, SImode))
   1312         offset = force_reg (SImode, offset);
   1313       emit_insn (gen_addsi3 (indx, operands[0], offset));
   1314     }
   1315   emit_cmp_and_jump_insns (indx, range, GTU, NULL_RTX, SImode, 1, fail);
   1316 
   1317   emit_jump_insn (gen_casesi_internal (indx, table));
   1318   DONE;
   1319 })
   1320 
   1321 ;; This is the only instance in this file where a pattern emits more than
   1322 ;; one instruction.  The concern here is that the addkpc insn could otherwise
   1323 ;; be scheduled too far away from the label.  A tablejump always ends an
   1324 ;; extended basic block, so it shouldn't happen that the scheduler places
   1325 ;; something in the delay slots.
   1326 (define_insn "casesi_internal"
   1327   [(set (pc)
   1328 	(mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "b")
   1329 				  (const_int 4))
   1330 			 (label_ref (match_operand 1 "" "")))))
   1331    (clobber (match_scratch:SI 2 "=&b"))
   1332    (clobber (match_scratch:SI 3 "=b"))]
   1333   "flag_pic && TARGET_INSNS_64"
   1334   "addkpc\t.s2\t%l1,%2, 0\n\t\tldw\t.d2t2\t*+%2[%0], %3\n\t\tnop\t\t4\n\t\tadd\t.l2\t%2, %3, %3\n\t\tb\t.s2\t%3"
   1335   [(set_attr "type" "branch")
   1336    (set_attr "predicable" "no")
   1337    (set_attr "dest_regfile" "b")])
   1338 
   1339 (define_expand "cbranch<mode>4"
   1340   [(set (pc)
   1341 	(if_then_else (match_operator 0 "comparison_operator"
   1342 		       [(match_operand:SIDIM 1 "register_operand" "")
   1343 			(match_operand:SIDIM 2 "reg_or_const_int_operand" "")])
   1344 		      (label_ref (match_operand 3 "" ""))
   1345 		      (pc)))]
   1346   ""
   1347 {
   1348   rtx t = c6x_expand_compare (operands[0], VOIDmode);
   1349   operands[0] = t;
   1350   operands[1] = XEXP (t, 0);
   1351   operands[2] = XEXP (t, 1);
   1352 })
   1353 
   1354 (define_expand "cbranch<mode>4"
   1355   [(set (pc)
   1356 	(if_then_else (match_operator 0 "c6x_fp_comparison_operator"
   1357 		       [(match_operand:SFDFM 1 "register_operand" "")
   1358 			(match_operand:SFDFM 2 "register_operand" "")])
   1359 		      (label_ref (match_operand 3 "" ""))
   1360 		      (pc)))]
   1361   ""
   1362 {
   1363   rtx t = c6x_expand_compare (operands[0], VOIDmode);
   1364   operands[0] = t;
   1365   operands[1] = XEXP (t, 0);
   1366   operands[2] = XEXP (t, 1);
   1367 })
   1368 
   1369 (define_insn "br_true"
   1370   [(set (pc)
   1371 	(if_then_else (match_operator 0 "predicate_operator"
   1372 			[(match_operand:SI 1 "register_operand" "AB")
   1373 			 (const_int 0)])
   1374 		      (label_ref (match_operand 2 "" ""))
   1375 		      (pc)))]
   1376   ""
   1377   "%|[%J0]\\tb\\t%$\\t%l2"
   1378   [(set_attr "type" "branch")
   1379    (set_attr "predicable" "no")
   1380    (set_attr "units" "s")
   1381    (set_attr "dest_regfile" "any")])
   1382 
   1383 (define_insn "br_false"
   1384   [(set (pc)
   1385 	(if_then_else (match_operator 0 "predicate_operator"
   1386 			[(match_operand:SI 1 "register_operand" "AB")
   1387 			 (const_int 0)])
   1388 		      (pc)
   1389 		      (label_ref (match_operand 2 "" ""))))]
   1390   ""
   1391   "%|[%j0]\\tb\\t%$\\t%l2"
   1392   [(set_attr "type" "branch")
   1393    (set_attr "predicable" "no")
   1394    (set_attr "units" "s")
   1395    (set_attr "dest_regfile" "any")])
   1396 
   1397 (define_expand "return"
   1398   [(parallel
   1399     [(return)
   1400      (use (reg:SI REG_B3))])]
   1401   "reload_completed && get_frame_size () == 0 && c6x_nsaved_regs () == 0")
   1402 
   1403 ;; We can't expand this before we know where the link register is stored.
   1404 (define_insn_and_split "eh_return"
   1405   [(unspec_volatile [(match_operand:SI 0 "register_operand" "ab")]
   1406 		    UNSPECV_EH_RETURN)
   1407    (clobber (match_scratch:SI 1 "=&ab"))]
   1408   ""
   1409   "#"
   1410   "&& reload_completed"
   1411   [(const_int 0)]
   1412   "
   1413   {
   1414     c6x_set_return_address (operands[0], operands[1]);
   1415     DONE;
   1416   }"
   1417 )
   1418 
   1419 ;; -------------------------------------------------------------------------
   1420 ;; Doloop
   1421 ;; -------------------------------------------------------------------------
   1422 
   1423 ; operand 0 is the loop count pseudo register
   1424 ; operand 1 is the label to jump to at the top of the loop
   1425 (define_expand "doloop_end"
   1426   [(parallel [(set (pc) (if_then_else
   1427 			  (ne (match_operand:SI 0 "" "")
   1428 			      (const_int 1))
   1429 			  (label_ref (match_operand 1 "" ""))
   1430 			  (pc)))
   1431 	      (set (match_dup 0)
   1432 		   (plus:SI (match_dup 0)
   1433 			    (const_int -1)))
   1434 	      (clobber (match_dup 2))])] ; match_scratch
   1435   "TARGET_INSNS_64PLUS && optimize"
   1436 {
   1437   /* The loop optimizer doesn't check the predicates... */
   1438   if (GET_MODE (operands[0]) != SImode)
   1439     FAIL;
   1440   operands[2] = gen_rtx_SCRATCH (SImode);
   1441 })
   1442 
   1443 (define_insn "mvilc"
   1444   [(set (reg:SI REG_ILC)
   1445 	(unspec [(match_operand:SI 0 "register_operand" "a,b")] UNSPEC_MVILC))]
   1446   "TARGET_INSNS_64PLUS"
   1447   "%|%.\\tmvc\\t%$\\t%0, ILC"
   1448   [(set_attr "predicable" "no")
   1449    (set_attr "cross" "y,n")
   1450    (set_attr "units" "s")
   1451    (set_attr "dest_regfile" "b")
   1452    (set_attr "type" "mvilc")])
   1453   
   1454 (define_insn "sploop"
   1455   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
   1456 		     (reg:SI REG_ILC)]
   1457 		    UNSPECV_SPLOOP)]
   1458   "TARGET_INSNS_64PLUS"
   1459   "%|%.\\tsploop\t%0"
   1460   [(set_attr "predicable" "no")
   1461    (set_attr "type" "sploop")])
   1462   
   1463 (define_insn "spkernel"
   1464   [(set (pc)
   1465 	(if_then_else
   1466 	 (ne (unspec_volatile:SI
   1467 	      [(match_operand:SI 0 "const_int_operand" "i")
   1468 	       (match_operand:SI 1 "const_int_operand" "i")]
   1469 	      UNSPECV_SPKERNEL)
   1470 	     (const_int 1))
   1471 	 (label_ref (match_operand 2 "" ""))
   1472 	 (pc)))]
   1473   "TARGET_INSNS_64PLUS"
   1474   "%|%.\\tspkernel\t%0, %1"
   1475   [(set_attr "predicable" "no")
   1476    (set_attr "type" "spkernel")])
   1477   
   1478 (define_insn "loop_end"
   1479   [(set (pc)
   1480 	(if_then_else (ne (match_operand:SI 3 "nonimmediate_operand" "0,0,0,*r")
   1481 			  (const_int 1))
   1482 		      (label_ref (match_operand 1 "" ""))
   1483 		      (pc)))
   1484    (set (match_operand:SI 0 "nonimmediate_operand" "=AB,*r,m,m")
   1485 	(plus:SI (match_dup 3)
   1486 		 (const_int -1)))
   1487    (clobber (match_scratch:SI 2 "=X,&AB,&AB,&AB"))]
   1488   "TARGET_INSNS_64PLUS && optimize"
   1489   "#"
   1490   [(set_attr "type" "spkernel")])
   1491 
   1492 (define_split
   1493   [(set (pc)
   1494 	(if_then_else (ne (match_operand:SI 3 "nonimmediate_operand" "")
   1495 			  (const_int 1))
   1496 		      (label_ref (match_operand 1 "" ""))
   1497 		      (pc)))
   1498    (set (match_operand:SI 0 "memory_operand" "")
   1499 	(plus:SI (match_dup 3)
   1500 		 (const_int -1)))
   1501    (clobber (match_scratch 2))]
   1502   ""
   1503   [(set (match_dup 2) (plus:SI (match_dup 3) (const_int -1)))
   1504    (set (match_dup 0) (match_dup 2))
   1505    (set (pc)
   1506 	(if_then_else (ne (match_dup 2) (const_int 0))
   1507 		      (label_ref (match_dup 1))
   1508 		      (pc)))]
   1509 {
   1510   if (!REG_P (operands[3]))
   1511     {
   1512       emit_move_insn (operands[2], operands[3]);
   1513       operands[3] = operands[2];
   1514     }
   1515 })
   1516 
   1517 ;; -------------------------------------------------------------------------
   1518 ;; Delayed-branch real jumps and shadows
   1519 ;; -------------------------------------------------------------------------
   1520 
   1521 (define_insn "real_jump"
   1522   [(unspec [(match_operand 0 "c6x_jump_operand" "a,b,S3") (const_int 0)]
   1523 	   UNSPEC_REAL_JUMP)]
   1524   ""
   1525 {
   1526   if (GET_CODE (operands[0]) == LABEL_REF)
   1527     return "%|%.\\tb\\t%$\\t%l0";
   1528   return "%|%.\\tb\\t%$\\t%0";
   1529 }
   1530   [(set_attr "type" "branch")
   1531    (set_attr "has_shadow" "y")
   1532    (set_attr "units" "s")
   1533    (set_attr "cross" "y,n,n")
   1534    (set_attr "dest_regfile" "b,b,any")])
   1535 
   1536 (define_insn "real_call"
   1537   [(unspec [(match_operand 0 "c6x_call_operand" "a,b,S1") (const_int 1)]
   1538 	   UNSPEC_REAL_JUMP)
   1539    (clobber (reg:SI REG_B3))]
   1540   ""
   1541   "%|%.\\tcall\\t%$\\t%0"
   1542   [(set_attr "type" "call")
   1543    (set_attr "has_shadow" "y")
   1544    (set_attr "predicable" "no")
   1545    (set_attr "units" "s")
   1546    (set_attr "cross" "y,n,n")
   1547    (set_attr "dest_regfile" "b,b,any")])
   1548 
   1549 (define_insn "real_ret"
   1550   [(unspec [(match_operand 0 "register_operand" "a,b") (const_int 2)]
   1551 	   UNSPEC_REAL_JUMP)]
   1552   ""
   1553   "%|%.\\tret\\t%$\\t%0"
   1554   [(set_attr "type" "branch")
   1555    (set_attr "has_shadow" "y")
   1556    (set_attr "units" "s")
   1557    (set_attr "cross" "y,n")
   1558    (set_attr "dest_regfile" "b")])
   1559 
   1560 ;; computed_jump_p returns true if it finds a constant; so use one in the
   1561 ;; unspec.
   1562 (define_insn "indirect_jump_shadow"
   1563   [(set (pc) (unspec [(const_int 1)] UNSPEC_JUMP_SHADOW))]
   1564   ""
   1565   ";; indirect jump occurs"
   1566   [(set_attr "type" "shadow")])
   1567 
   1568 ;; Operand 0 may be a PARALLEL which isn't handled by output_operand, so
   1569 ;; we don't try to print it.
   1570 (define_insn "indirect_call_value_shadow"
   1571   [(set (match_operand 0 "" "")
   1572 	(call (unspec [(pc)] UNSPEC_JUMP_SHADOW)
   1573 	      (const_int 0)))]
   1574   ""
   1575   ";; indirect call occurs, with return value"
   1576   [(set_attr "type" "shadow")])
   1577 
   1578 (define_insn "indirect_sibcall_shadow"
   1579   [(call (unspec [(pc)] UNSPEC_JUMP_SHADOW)
   1580 	 (const_int 0))]
   1581   "SIBLING_CALL_P (insn)"
   1582   ";; indirect sibcall occurs"
   1583   [(set_attr "type" "shadow")])
   1584 
   1585 (define_insn "indirect_call_shadow"
   1586   [(call (unspec [(pc)] UNSPEC_JUMP_SHADOW)
   1587 	 (const_int 0))]
   1588   ""
   1589   ";; indirect call occurs"
   1590   [(set_attr "type" "shadow")])
   1591 
   1592 (define_insn "call_value_shadow"
   1593   [(set (match_operand 0 "" "")
   1594 	(call (unspec [(match_operand 1 "" "")] UNSPEC_JUMP_SHADOW)
   1595 	      (const_int 0)))]
   1596   ""
   1597   ";; call to %1 occurs, with return value"
   1598   [(set_attr "type" "shadow")])
   1599 
   1600 (define_insn "call_shadow"
   1601   [(call (unspec [(match_operand 0 "" "")] UNSPEC_JUMP_SHADOW)
   1602 	 (const_int 0))]
   1603   "!SIBLING_CALL_P (insn)"
   1604   ";; call to %0 occurs"
   1605   [(set_attr "type" "shadow")])
   1606 
   1607 (define_insn "sibcall_shadow"
   1608   [(call (unspec [(match_operand 0 "" "")] UNSPEC_JUMP_SHADOW)
   1609 	 (const_int 0))]
   1610   "SIBLING_CALL_P (insn)"
   1611   ";; sibcall to %0 occurs"
   1612   [(set_attr "type" "shadow")])
   1613 
   1614 (define_insn "jump_shadow"
   1615   [(set (pc) (unspec [(match_operand 0 "" "")] UNSPEC_JUMP_SHADOW))]
   1616   ""
   1617   ";; jump to %0 occurs"
   1618   [(set_attr "type" "shadow")])
   1619 
   1620 (define_insn "condjump_shadow"
   1621   [(set (pc)
   1622 	(if_then_else (eq (unspec [(const_int 0)] UNSPEC_JUMP_SHADOW)
   1623 			  (const_int 0))
   1624 		      (match_operand 0 "" "")
   1625 		      (pc)))]
   1626   ""
   1627   ";; condjump to %0 occurs"
   1628   [(set_attr "type" "shadow")])
   1629 
   1630 (define_insn "return_shadow"
   1631   [(unspec [(const_int 0)] UNSPEC_JUMP_SHADOW)
   1632    (return)]
   1633   ""
   1634   ";; return occurs"
   1635   [(set_attr "type" "shadow")])
   1636 
   1637 ;; -------------------------------------------------------------------------
   1638 ;; Add instructions
   1639 ;; -------------------------------------------------------------------------
   1640 
   1641 (define_insn "addsi3"
   1642   [(set (match_operand:SI 0 "register_operand"
   1643               "=a   ,b   , a, b, a, b,    a,    b, ab,  a,  b,  a,  b,ab")
   1644     (plus:SI (match_operand:SI 1 "register_operand"
   1645               "%a   ,b   , a, b, b, a,    b,    a,  0,  a,  b,  z,  z,0")
   1646   	     (match_operand:SI 2 "addsi_operand"
   1647                "aIs5,bIs5,?b,?a,?a,?b,?aIs5,?bIs5,I5x,I5x,I5x,Iux,Iux,IsB")))]
   1648   ""
   1649 {
   1650   if (CONSTANT_P (operands[2]))
   1651     {
   1652       HOST_WIDE_INT val = INTVAL (operands[2]);
   1653 
   1654       if (c6x_get_unit_specifier (insn) == 'd')
   1655 	{
   1656 	  bool issp = (TARGET_INSNS_64PLUS
   1657 		       && operands[1] == stack_pointer_rtx
   1658 		       && GET_CODE (PATTERN (insn)) != COND_EXEC);
   1659 
   1660 	  if (get_attr_cross (insn) == CROSS_N)
   1661 	    {
   1662 	      if (satisfies_constraint_Iu5 (operands[2]))
   1663 		return "%|%.\\tadd\\t%$\\t%1, %2, %0";
   1664 	      else if (satisfies_constraint_In5 (operands[2]))
   1665 		return "%|%.\\tsub\\t%$\\t%1, %n2, %0";
   1666 	    }
   1667 
   1668 	  if (issp && val > 0 && val < 32768)
   1669 	    {
   1670 	      return "%|%.\\taddab\\t%$\\t%1, %2, %0";
   1671 	    }
   1672 	  if ((val & 1) == 0 && ((val >= -62 && val <= 62)
   1673 				 || (issp && val > 0 && val < 65536)))
   1674 	    {
   1675 	      if (val < 0)
   1676 		return "%|%.\\tsubah\\t%$\\t%1, %r2, %0";
   1677 	      else
   1678 		return "%|%.\\taddah\\t%$\\t%1, %r2, %0";
   1679 	    }
   1680 	  else if ((val & 3) == 0 && ((val >= -124 && val <= 124)
   1681 				       || (issp && val > 0 && val < 131072)))
   1682 	    {
   1683 	      if (val < 0)
   1684 		return "%|%.\\tsubaw\\t%$\\t%1, %R2, %0";
   1685 	      else
   1686 		return "%|%.\\taddaw\\t%$\\t%1, %R2, %0";
   1687 	    }
   1688 	  else if ((val & 7) == 0 && val > 0 && val <= 248)
   1689 	    {
   1690 	      rtx xop[3];
   1691 	      xop[0] = operands[0];
   1692 	      xop[1] = operands[1];
   1693 	      xop[2] = GEN_INT (val >> 3);
   1694 	      output_asm_insn ("%|%.\\taddad\\t%$\\t%1, %2, %0", xop);
   1695 	      return "";
   1696 	    }
   1697 	}
   1698       else
   1699         {
   1700 	  if (satisfies_constraint_Is5 (operands[2]))
   1701 	    return "%|%.\\tadd\\t%$\\t%2, %1, %0";
   1702 	}
   1703       gcc_assert (rtx_equal_p (operands[0], operands[1]));
   1704       return "%|%.\\taddk\\t%$\\t%2, %0";
   1705     }
   1706   if (which_alternative == 4 || which_alternative == 5)
   1707     return "%|%.\\tadd\\t%$\\t%2, %1, %0";
   1708   else
   1709     return "%|%.\\tadd\\t%$\\t%1, %2, %0";
   1710 }
   1711   [(set_attr "units62" "dls,dls,ls,ls,ls,ls,ls,ls,s,d,d,*,*,s")
   1712    (set_attr "units67" "dls,dls,ls,ls,ls,ls,ls,ls,ds,d,d,*,*,s")
   1713    (set_attr "units64" "dls,dls,dls,dls,dls,dls,ls,ls,ds,d,d,d,d,s")
   1714    (set_attr "cross" "n,n,y,y,y,y,y,y,n,n,n,y,n,n")
   1715    (set_attr "predicable" "yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,no,no,yes")])
   1716 
   1717 (define_insn "subsi3"
   1718   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b,a,b")
   1719 	(minus:SI (match_operand:SI 1 "reg_or_scst5_operand" "a,b,aIs5,bIs5,bIs5,aIs5")
   1720 		  (match_operand:SI 2 "register_operand" "a,b,a,b,?a,?b")))]
   1721   ""
   1722   "%|%.\\tsub\\t%$\\t%1, %2, %0"
   1723   [(set_attr "units62" "dls,dls,ls,ls,l,l")
   1724    (set_attr "units64" "dls,dls,ls,ls,ls,ls")
   1725    (set_attr "cross" "n,n,n,n,y,y")])
   1726 
   1727 (define_insn "*addshiftsi"
   1728   [(set (match_operand:SI 0 "register_operand" "=a,b")
   1729 	(plus:SI (mult:SI (match_operand:SI 2 "register_operand" "a,b")
   1730 			  (match_operand:SI 3 "adda_scale_operand" "n,n"))
   1731 		 (match_operand:SI 1 "register_operand" "a,b")))]
   1732   ""
   1733   "%|%.\\tadda%d3\\t%$\\t%1, %2, %0"
   1734   [(set_attr "units" "d")])
   1735 
   1736 (define_insn "*subshiftsi"
   1737   [(set (match_operand:SI 0 "register_operand" "=a,b")
   1738 	(minus:SI (match_operand:SI 1 "register_operand" "a,b")
   1739 		  (mult:SI (match_operand:SI 2 "register_operand" "a,b")
   1740 			   (match_operand:SI 3 "suba_scale_operand" "n,n"))))]
   1741   ""
   1742   "%|%.\\tsuba%d3\\t%$\\t%1, %2, %0"
   1743   [(set_attr "units" "d")])
   1744 
   1745 (define_insn "addsidi3_widen"
   1746   [(set (match_operand:DI 0 "register_operand" "=a,b,a,b")
   1747 	(plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a,b,a,b"))
   1748 		 (zero_extend:DI (match_operand:SI 2 "register_operand" "a,b,?b,?a"))))]
   1749   ""
   1750   "%|%.\\taddu\\t%$\\t%1, %2, %0"
   1751   [(set_attr "units" "l")
   1752    (set_attr "cross" "n,n,y,y")])
   1753 
   1754 (define_expand "adddi3"
   1755   [(set (match_operand:DI 0 "register_operand" "")
   1756 	(plus:DI (match_operand:DI 1 "register_operand" "")
   1757 		 (match_operand:DI 2 "register_operand" "")))]
   1758   ""
   1759 {
   1760   rtx tmp;
   1761   rtx lo_half[3], hi_half[3];
   1762   split_di (operands + 1, 2, lo_half + 1, hi_half + 1);
   1763   if (reg_overlap_mentioned_p (operands[0], hi_half[1])
   1764       || reg_overlap_mentioned_p (operands[0], hi_half[2]))
   1765     tmp = gen_reg_rtx (DImode);
   1766   else
   1767     tmp = operands[0];
   1768   split_di (&tmp, 1, lo_half, hi_half);
   1769   emit_insn (gen_addsidi3_widen (tmp, lo_half[1], lo_half[2]));
   1770   emit_insn (gen_addsi3 (hi_half[0], copy_rtx (hi_half[0]), hi_half[1]));
   1771   emit_insn (gen_addsi3 (copy_rtx (hi_half[0]),
   1772 			 copy_rtx (hi_half[0]), hi_half[2]));
   1773   if (tmp != operands[0])
   1774     emit_move_insn (operands[0], tmp);
   1775   DONE;
   1776 })
   1777 
   1778 (define_insn "addsf3"
   1779   [(set (match_operand:SF 0 "register_operand" "=a,b,a,b")
   1780 	(plus:SF (match_operand:SF 1 "register_operand" "%a,b,a,b")
   1781 		 (match_operand:SF 2 "register_operand" "a,b,?b,?a")))]
   1782   "TARGET_FP"
   1783   "%|%.\\taddsp\\t%$\\t%1, %2, %0"
   1784   [(set_attr "type" "fp4")
   1785    (set_attr "units67" "l")
   1786    (set_attr "units67p" "ls")
   1787    (set_attr "units674" "ls")
   1788    (set_attr "cross" "n,n,y,y")])
   1789 
   1790 (define_insn "adddf3"
   1791   [(set (match_operand:DF 0 "register_operand" "=a,b,a,b")
   1792 	(plus:DF (match_operand:DF 1 "register_operand" "%a,b,a,b")
   1793 		 (match_operand:DF 2 "register_operand" "a,b,?b,?a")))]
   1794   "TARGET_FP"
   1795   "%|%.\\tadddp\\t%$\\t%1, %2, %0"
   1796   [(set_attr "type" "adddp")
   1797    (set_attr "units67" "l")
   1798    (set_attr "units67p" "ls")
   1799    (set_attr "units674" "ls")
   1800    (set_attr "cross" "n,n,y,y")])
   1801 
   1802 (define_insn "subsf3"
   1803   [(set (match_operand:SF 0 "register_operand" "=a,b, a, b, a, b")
   1804 	(minus:SF (match_operand:SF 1 "register_operand" "a,b, b, a, a, b")
   1805 		  (match_operand:SF 2 "register_operand" "a,b,?a,?b,?b,?a")))]
   1806   "TARGET_FP"
   1807   "%|%.\\tsubsp\\t%$\\t%1, %2, %0"
   1808   [(set_attr "type" "fp4")
   1809    (set_attr "units67" "l")
   1810    (set_attr "units67p" "ls")
   1811    (set_attr "units674" "ls")
   1812    (set_attr "cross" "n,n,y,y,y,y")])
   1813 
   1814 (define_insn "subdf3"
   1815   [(set (match_operand:DF 0 "register_operand" "=a,b, a, b, a, b")
   1816 	(minus:DF (match_operand:DF 1 "register_operand" "a,b, b, a, a, b")
   1817 		  (match_operand:DF 2 "register_operand" "a,b,?a,?b,?b,?a")))]
   1818   "TARGET_FP"
   1819   "%|%.\\tsubdp\\t%$\\t%1, %2, %0"
   1820   [(set_attr "type" "adddp")
   1821    (set_attr "units67" "l")
   1822    (set_attr "units67p" "ls")
   1823    (set_attr "units674" "ls")
   1824    (set_attr "cross" "n,n,y,y,y,y")])
   1825 
   1826 ;; -------------------------------------------------------------------------
   1827 ;; Logical instructions
   1828 ;; -------------------------------------------------------------------------
   1829 
   1830 (define_insn "andsi3"
   1831   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b,a,b")
   1832 	(and:SI (match_operand:SI 1 "register_operand" "%a,b,b,a,a,b")
   1833 		(match_operand:SI 2 "andsi_operand" "aIs5,bIs5,?aIs5,?bIs5,aJc,bJc")))]
   1834   ""
   1835 {
   1836   if (which_alternative < 4)
   1837     return "%|%.\\tand\\t%$\\t%2, %1, %0";
   1838   else
   1839     return "%|%.\\tclr\\t%$\\t%1, %f2, %F2, %0";
   1840 }
   1841   [(set_attr "units62" "ls,ls,ls,ls,s,s")
   1842    (set_attr "units64" "dls,dls,dls,dls,s,s")
   1843    (set_attr "cross" "n,n,y,y,n,n")])
   1844 
   1845 (define_insn "iorsi3"
   1846   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b,a,b")
   1847 	(ior:SI (match_operand:SI 1 "register_operand" "%a,b,b,a,a,b")
   1848 		(match_operand:SI 2 "iorsi_operand" "aIs5,bIs5,?aIs5,?bIs5,aJs,bJs")))]
   1849   ""
   1850 {
   1851   if (which_alternative < 4)
   1852     return "%|%.\\tor\\t%$\\t%2, %1, %0";
   1853   else
   1854     return "%|%.\\tset\\t%$\\t%1, %s2, %S2, %0";
   1855 }
   1856   [(set_attr "units62" "ls,ls,ls,ls,s,s")
   1857    (set_attr "units64" "dls,dls,dls,dls,s,s")
   1858    (set_attr "cross" "n,n,y,y,n,n")])
   1859 
   1860 (define_insn "xorsi3"
   1861   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b")
   1862 	(xor:SI (match_operand:SI 1 "register_operand" "%a,b,b,a")
   1863 		(match_operand:SI 2 "reg_or_scst5_operand" "aIs5,bIs5,?aIs5,?bIs5")))]
   1864   ""
   1865   "%|%.\\txor\\t%$\\t%2, %1, %0"
   1866   [(set_attr "units62" "ls")
   1867    (set_attr "units64" "dls")
   1868    (set_attr "cross" "n,n,y,y")])
   1869 
   1870 ;; -------------------------------------------------------------------------
   1871 ;; Conversions
   1872 ;; -------------------------------------------------------------------------
   1873 
   1874 (define_insn "extendsfdf2"
   1875   [(set (match_operand:DF 0 "register_operand" "=a,b,a,b")
   1876 	(float_extend:DF (match_operand:SF 1 "register_operand" "a,b,?b,?a")))]
   1877   "TARGET_FP"
   1878   "%|%.\\tspdp\\t%$\\t%1,%0"
   1879   [(set_attr "type" "dp2")
   1880    (set_attr "units" "s")
   1881    (set_attr "cross" "n,n,y,y")])
   1882 
   1883 (define_insn "truncdfsf2"
   1884   [(set (match_operand:SF 0 "register_operand" "=a,b")
   1885 	(float_truncate:SF (match_operand:DF 1 "register_operand" "a,b")))]
   1886   "TARGET_FP"
   1887   "%|%.\\tdpsp\\t%$\\t%1,%0"
   1888   [(set_attr "type" "fp4")
   1889    (set_attr "units" "l")
   1890    (set_attr "cross" "n")])
   1891 
   1892 ;;;; Convert between signed integer types and floating point.
   1893 (define_insn "floatsisf2"
   1894   [(set (match_operand:SF 0 "register_operand" "=a,b,a,b")
   1895 	(float:SF (match_operand:SI 1 "register_operand" "a,b,?b,?a")))]
   1896   "TARGET_FP"
   1897   "%|%.\\tintsp\\t%$\\t%1,%0"
   1898   [(set_attr "type" "fp4")
   1899    (set_attr "units" "l")
   1900    (set_attr "cross" "n,n,y,y")])
   1901 
   1902 (define_insn "floatunssisf2"
   1903   [(set (match_operand:SF 0 "register_operand" "=a,b,a,b")
   1904 	(unsigned_float:SF (match_operand:SI 1 "register_operand" "a,b,?b,?a")))]
   1905   "TARGET_FP"
   1906   "%|%.\\tintspu\\t%$\\t%1,%0"
   1907   [(set_attr "type" "fp4")
   1908    (set_attr "units" "l")
   1909    (set_attr "cross" "n,n,y,y")])
   1910 
   1911 (define_insn "floatsidf2"
   1912   [(set (match_operand:DF 0 "register_operand" "=a,b,a,b")
   1913 	(float:DF (match_operand:SI 1 "register_operand" "a,b,?b,?a")))]
   1914   "TARGET_FP"
   1915   "%|%.\\tintdp\\t%$\\t%1,%0"
   1916   [(set_attr "type" "intdp")
   1917    (set_attr "units" "l")
   1918    (set_attr "cross" "n,n,y,y")])
   1919 
   1920 (define_insn "floatunssidf2"
   1921   [(set (match_operand:DF 0 "register_operand" "=a,b,a,b")
   1922 	(unsigned_float:DF (match_operand:SI 1 "register_operand" "a,b,?b,?a")))]
   1923   "TARGET_FP"
   1924   "%|%.\\tintdpu\\t%$\\t%1,%0"
   1925   [(set_attr "type" "intdp")
   1926    (set_attr "units" "l")
   1927    (set_attr "cross" "n,n,y,y")])
   1928 
   1929 (define_insn "fix_truncsfsi2"
   1930   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b")
   1931 	(fix:SI (match_operand:SF 1 "register_operand" "a,b,?b,?a")))]
   1932   "TARGET_FP"
   1933   "%|%.\\tsptrunc\\t%$\\t%1,%0"
   1934   [(set_attr "type" "fp4")
   1935    (set_attr "units" "l")
   1936    (set_attr "cross" "n,n,y,y")])
   1937 
   1938 (define_insn "fix_truncdfsi2"
   1939   [(set (match_operand:SI 0 "register_operand" "=a,b")
   1940 	(fix:SI (match_operand:DF 1 "register_operand" "a,b")))]
   1941   "TARGET_FP"
   1942   "%|%.\\tdptrunc\\t%$\\t%1,%0"
   1943   [(set_attr "type" "fp4")
   1944    (set_attr "units" "l")
   1945    (set_attr "cross" "n")])
   1946 
   1947 ;; -------------------------------------------------------------------------
   1948 ;; Saturating arithmetic
   1949 ;; -------------------------------------------------------------------------
   1950 
   1951 (define_insn "saddsi3"
   1952   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b,a,b,a,b")
   1953 	(ss_plus:SI (match_operand:SI 1 "register_operand" "a,b,?b,?a,a,b,?b,?a")
   1954 		    (match_operand:SI 2 "reg_or_const_int_operand" "a,b,a,b,aIs5,bIs5,aIs5,bIs5")))]
   1955   ""
   1956   "%|%.\\tsadd\\t%$\\t%2, %1, %0"
   1957   [(set_attr "units" "ls,ls,ls,ls,l,l,l,l")
   1958    (set_attr "cross" "n,n,y,y,n,n,y,y")])
   1959 
   1960 (define_insn "ssubsi3"
   1961   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b")
   1962 	(ss_minus:SI (match_operand:SI 1 "reg_or_scst5_operand" "aIs5,bIs5,?bIs5,?aIs5")
   1963 		     (match_operand:SI 2 "register_operand" "a,b,a,b")))]
   1964   ""
   1965   "%|%.\\tssub\\t%$\\t%1, %2, %0"
   1966   [(set_attr "units" "l")
   1967    (set_attr "cross" "n,n,y,y")])
   1968 
   1969 (define_insn "subcsi3"
   1970   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b")
   1971 	(unspec:SI
   1972 	 [(match_operand:SI 1 "register_operand" "a,b,a,b")
   1973 	  (match_operand:SI 2 "register_operand" "a,b,?b,?a")]
   1974 	 UNSPEC_SUBC))]
   1975   ""
   1976   "%|%.\\tsubc\\t%$\\t%1, %2, %0"
   1977   [(set_attr "units" "l")
   1978    (set_attr "cross" "n,n,y,y")])
   1979 
   1980 ;; -------------------------------------------------------------------------
   1981 ;; Call instructions
   1982 ;; -------------------------------------------------------------------------
   1983 
   1984 (define_expand "call"
   1985  [(match_operand 0 "" "")]
   1986  ""
   1987 {
   1988   c6x_expand_call (NULL_RTX, operands[0], false);
   1989   DONE;
   1990 })
   1991 
   1992 (define_expand "call_value"
   1993   [(match_operand 0 "" "")
   1994    (match_operand 1 "" "")]
   1995  ""
   1996 {
   1997   c6x_expand_call (operands[0], operands[1], false);
   1998   DONE;
   1999 })
   2000 
   2001 (define_expand "sibcall"
   2002  [(match_operand 0 "" "")]
   2003  ""
   2004 {
   2005   c6x_expand_call (NULL_RTX, operands[0], true);
   2006   cfun->machine->contains_sibcall = true;
   2007   DONE;
   2008 })
   2009 
   2010 (define_expand "sibcall_value"
   2011   [(match_operand 0 "" "")
   2012    (match_operand 1 "" "")]
   2013  ""
   2014 {
   2015   c6x_expand_call (operands[0], operands[1], true);
   2016   cfun->machine->contains_sibcall = true;
   2017   DONE;
   2018 })
   2019 
   2020 (define_insn "call_internal"
   2021   [(call (mem (match_operand:SI 0 "c6x_call_operand" "S1,a,b"))
   2022 	 (const_int 0))]
   2023   "!SIBLING_CALL_P (insn)"
   2024   "%|%.\\tcall\\t%$\\t%0"
   2025   [(set_attr "type" "call")
   2026    (set_attr "predicable" "no")
   2027    (set_attr "units" "s")
   2028    (set_attr "dest_regfile" "any,b,b")
   2029    (set_attr "cross" "n,y,n")])
   2030 
   2031 (define_insn "call_value_internal"
   2032   [(set (match_operand 0 "" "")
   2033 	(call (mem (match_operand:SI 1 "c6x_call_operand" "S1,a,b"))
   2034 	      (const_int 0)))]
   2035   ""
   2036   "%|%.\\tcall\\t%$\\t%1"
   2037   [(set_attr "type" "call")
   2038    (set_attr "predicable" "no")
   2039    (set_attr "units" "s")
   2040    (set_attr "dest_regfile" "any,b,b")
   2041    (set_attr "cross" "n,y,n")])
   2042 
   2043 (define_insn "sibcall_internal"
   2044   [(call (mem (match_operand:SI 0 "c6x_call_operand" "S1,C"))
   2045 	 (const_int 0))]
   2046   "SIBLING_CALL_P (insn)"
   2047   "%|%.\\tb\\t%$\\t%0"
   2048   [(set_attr "type" "branch")
   2049    (set_attr "predicable" "no")
   2050    (set_attr "units" "s")
   2051    (set_attr "dest_regfile" "any,b")])
   2052 
   2053 (define_insn "callp"
   2054   [(call (mem (match_operand:SI 0 "c6x_call_operand" "S1"))
   2055 	 (const_int 0))
   2056    (unspec [(const_int 6)] UNSPEC_NOP)]
   2057   "!SIBLING_CALL_P (insn)"
   2058   "%|%.\\tcallp\\t%$\\t%0, B3"
   2059   [(set_attr "type" "callp")
   2060    (set_attr "predicable" "no")
   2061    (set_attr "units" "s")
   2062    (set_attr "dest_regfile" "b")
   2063    (set_attr "cross" "n")])
   2064 
   2065 (define_insn "callp_value"
   2066   [(set (match_operand:SI 0 "register_operand" "")
   2067 	(call (mem (match_operand:SI 1 "c6x_call_operand" "S1"))
   2068 	      (const_int 0)))
   2069    (unspec [(const_int 6)] UNSPEC_NOP)]
   2070   "!SIBLING_CALL_P (insn)"
   2071   "%|%.\\tcallp\\t%$\\t%1, B3"
   2072   [(set_attr "type" "callp")
   2073    (set_attr "predicable" "no")
   2074    (set_attr "units" "s")
   2075    (set_attr "dest_regfile" "b")
   2076    (set_attr "cross" "n")])
   2077 
   2078 (define_insn "return_internal"
   2079   [(return)
   2080    (use (match_operand:SI 0 "register_operand" "b"))]
   2081   "reload_completed"
   2082   "%|%.\\tret\\t%$\\t%0"
   2083   [(set_attr "type" "branch")
   2084    (set_attr "units" "s")
   2085    (set_attr "dest_regfile" "b")])
   2086 
   2087 (define_insn "addkpc"
   2088   [(set (match_operand:SI 0 "register_operand" "=b")
   2089 	(unspec:SI [(match_operand 1 "" "")] UNSPEC_ADDKPC))
   2090    (unspec [(match_operand 2 "const_int_operand" "n")] UNSPEC_NOP)]
   2091   "TARGET_INSNS_64"
   2092   "%|%.\\taddkpc\\t%$\\t%l1, %0, %2"
   2093   [(set_attr "units" "s")
   2094    (set_attr "dest_regfile" "b")])
   2095 
   2096 ;; -------------------------------------------------------------------------
   2097 ;; Unary operations
   2098 ;; -------------------------------------------------------------------------
   2099 
   2100 (define_insn "negsi2"
   2101   [(set (match_operand:SI 0 "register_operand" "=a, a, b, b")
   2102         (neg:SI (match_operand:SI 1 "register_operand" "a,?b, b,?a")))]
   2103   ""
   2104   "%|%.\\tneg\\t%$\\t%1, %0"
   2105   [(set_attr "units" "ls")
   2106    (set_attr "cross" "n,y,n,y")])
   2107 
   2108 (define_insn "one_cmplsi2"
   2109   [(set (match_operand:SI 0 "register_operand" "=a, a, b, b")
   2110 	(not:SI (match_operand:SI 1 "register_operand" "a,?b, b,?a")))]
   2111   ""
   2112   "%|%.\\tnot\\t%$\\t%1, %0"
   2113   [(set_attr "units" "ls")
   2114    (set_attr "cross" "n,y,n,y")])
   2115 
   2116 (define_insn "clrsbsi2"
   2117   [(set (match_operand:SI 0 "register_operand" "=a, a, b, b")
   2118 	(clrsb:SI (match_operand:SI 1 "register_operand" "a,?b, b,?a")))]
   2119   ""
   2120   "%|%.\\tnorm\\t%$\\t%1, %0"
   2121   [(set_attr "units" "l")
   2122    (set_attr "cross" "n,y,n,y")])
   2123 
   2124 (define_insn "clzsi2"
   2125   [(set (match_operand:SI 0 "register_operand" "=a, a, b, b")
   2126 	(clz:SI (match_operand:SI 1 "register_operand" "a,?b, b,?a")))]
   2127   ""
   2128   "%|%.\\tlmbd\\t%$\\t1, %1, %0"
   2129   [(set_attr "units" "l")
   2130    (set_attr "cross" "n,y,n,y")])
   2131 
   2132 ;; bitrevsi2 is defined in c6x-mult.md.in.
   2133 
   2134 (define_expand "ctzsi2"
   2135   [(set (match_operand:SI 0 "register_operand" "")
   2136 	(ctz:SI (match_operand:SI 1 "register_operand" "")))]
   2137   "TARGET_INSNS_64"
   2138 {
   2139   rtx tmpreg = gen_reg_rtx (SImode);
   2140   emit_insn (gen_bitrevsi2 (tmpreg, operands[1]));
   2141   emit_insn (gen_clzsi2 (operands[0], tmpreg));
   2142   DONE;
   2143 })
   2144 
   2145 (define_expand "ctzdi2"
   2146   [(set (match_operand:DI 0 "register_operand" "")
   2147 	(ctz:DI (match_operand:DI 1 "register_operand" "")))]
   2148   "TARGET_INSNS_64"
   2149 {
   2150   rtx tmpreg = gen_reg_rtx (DImode);
   2151   rtx out;
   2152   emit_insn (gen_bitrevsi2 (gen_highpart (SImode, tmpreg),
   2153 			    gen_lowpart (SImode, operands[1])));
   2154   emit_insn (gen_bitrevsi2 (gen_lowpart (SImode, tmpreg),
   2155 			    gen_highpart (SImode, operands[1])));
   2156   out = expand_unop (DImode, clz_optab, tmpreg, operands[0], 1);
   2157   if (!rtx_equal_p (out, operands[0]))
   2158     emit_move_insn (operands[0], out);
   2159   DONE;
   2160 })
   2161 
   2162 (define_insn "ssabssi2"
   2163   [(set (match_operand:SI 0 "register_operand" "=a, a, b, b")
   2164         (ss_abs:SI (match_operand:SI 1 "register_operand" "a,?b, b,?a")))]
   2165   ""
   2166   "%|%.\\tabs\\t%$\\t%1, %0"
   2167   [(set_attr "units" "l")
   2168    (set_attr "cross" "n,y,n,y")])
   2169 
   2170 ;; -------------------------------------------------------------------------
   2171 ;; Shift instructions
   2172 ;; -------------------------------------------------------------------------
   2173 
   2174 (define_code_iterator any_shift [ss_ashift ashift ashiftrt lshiftrt])
   2175 (define_code_iterator any_rshift [ashiftrt lshiftrt])
   2176 (define_code_attr shift_code [(ss_ashift "ss_ashl") (ashift "ashl")
   2177 			      (ashiftrt "ashr") (lshiftrt "lshr")])
   2178 (define_code_attr shift_insn [(ss_ashift "sshl") (ashift "shl")
   2179 			      (ashiftrt "shr") (lshiftrt "shru")])
   2180 
   2181 (define_insn "<shift_code>si3"
   2182   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b")
   2183         (any_shift:SI (match_operand:SI 1 "register_operand" "a,b,?b,?a")
   2184 		      (match_operand:SI 2 "reg_or_ucst5_operand" "aIu5,bIu5,aIu5,bIu5")))]
   2185   ""
   2186   "%|%.\\t<shift_insn>\\t%$\\t%1, %2, %0"
   2187   [(set_attr "units" "s")
   2188    (set_attr "cross" "n,n,y,y")])
   2189 
   2190 ;; See c6x-mult.md.in for the rotlsi3 pattern.
   2191 
   2192 (define_insn "rotrdi3_16"
   2193   [(set (match_operand:DI 0 "register_operand" "=a,b")
   2194         (rotatert:DI (match_operand:DI 1 "register_operand" "a,b")
   2195 		     (const_int 16)))]
   2196   "TARGET_INSNS_64PLUS"
   2197   "%|%.\\tdpackx2\\t%$\\t%P1, %p1, %0"
   2198   [(set_attr "units" "l")
   2199    (set_attr "cross" "n")])
   2200 
   2201 (define_insn "shlmbsi3"
   2202   [(set (match_operand:SI 0 "register_operand" "=a,b,a,b")
   2203         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "a,b,?b,?a")
   2204 			   (const_int 8))
   2205 		(lshiftrt:SI (match_operand:SI 2 "register_operand" "a,b,a,b")
   2206 			     (const_int 24))))]
   2207   "TARGET_INSNS_64"
   2208   "%|%.\\tshlmb\\t%$\\t%2, %1, %0"
   2209   [(set_attr "units" "ls")
   2210    (set_attr "cross" "n,n,y,y")])
   2211 
   2212 (define_expand "ashldi3"
   2213   [(set (match_operand:DI 0 "register_operand" "")
   2214         (ashift:DI (match_operand:DI 1 "register_operand" "")
   2215 		   (match_operand:SI 2 "const_int_operand" "")))]
   2216   "TARGET_INSNS_64"
   2217 {
   2218   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 8)
   2219     {
   2220       rtx lo0, lo1, hi0, hi1, tmp;
   2221       lo0 = gen_lowpart (SImode, operands[0]);
   2222       hi0 = gen_highpart (SImode, operands[0]);
   2223       lo1 = gen_lowpart (SImode, operands[1]);
   2224       hi1 = gen_highpart (SImode, operands[1]);
   2225       if (reg_overlap_mentioned_p (hi0, lo1))
   2226         tmp = gen_reg_rtx (SImode);
   2227       else
   2228         tmp = hi0;
   2229       emit_insn (gen_shlmbsi3 (tmp, hi1, lo1));
   2230       emit_insn (gen_ashlsi3 (lo0, lo1, operands[2]));
   2231       if (tmp != hi0)
   2232         emit_move_insn (hi0, tmp);
   2233       DONE;
   2234     }
   2235   FAIL;
   2236 })
   2237 
   2238 (define_expand "rotrdi3"
   2239   [(set (match_operand:DI 0 "register_operand" "")
   2240         (rotatert:DI (match_operand:DI 1 "register_operand" "")
   2241 		     (match_operand:SI 2 "const_int_operand" "")))]
   2242   "TARGET_INSNS_64PLUS"
   2243 {
   2244   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 16)
   2245     {
   2246       emit_insn (gen_rotrdi3_16 (operands[0], operands[1]));
   2247       DONE;
   2248     }
   2249   FAIL;
   2250 })
   2251 
   2252 (define_insn "bswapv2hi2"
   2253   [(set (match_operand:V2HI 0 "register_operand" "=a,b,a,b")
   2254         (bswap:V2HI (match_operand:V2HI 1 "register_operand" "a,b,?b,?a")))]
   2255   "TARGET_INSNS_64"
   2256   "%|%.\\tswap4\\t%$\\t%1, %0"
   2257   [(set_attr "units" "l")
   2258    (set_attr "cross" "n,n,y,y")])
   2259 
   2260 (define_expand "bswapsi2"
   2261   [(set (match_operand:SI 0 "register_operand" "")
   2262 	(bswap:SI (match_operand:SI 1 "register_operand" "")))]
   2263   "TARGET_INSNS_64"
   2264 {
   2265   rtx tmpreg = gen_reg_rtx (SImode);
   2266   rtx tmpv2 = gen_lowpart (V2HImode, tmpreg);
   2267   rtx op0v2 = gen_lowpart (V2HImode, operands[0]);
   2268   emit_insn (gen_rotlsi3 (tmpreg, operands[1], GEN_INT (16)));
   2269   emit_insn (gen_bswapv2hi2 (op0v2, tmpv2));
   2270   DONE;
   2271 })
   2272 
   2273 ;; -------------------------------------------------------------------------
   2274 ;; Division
   2275 ;; -------------------------------------------------------------------------
   2276 
   2277 (define_insn "divsi3_insn"
   2278   [(set (reg:SI REG_A4) (div:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2279    (clobber (reg:SI REG_A0))
   2280    (clobber (reg:SI REG_A1))
   2281    (clobber (reg:SI REG_A2))
   2282    (clobber (reg:SI REG_A6))
   2283    (clobber (reg:SI REG_B0))
   2284    (clobber (reg:SI REG_B1))
   2285    (clobber (reg:SI REG_B2))
   2286    (clobber (reg:SI REG_B3))
   2287    (clobber (reg:SI REG_B4))
   2288    (clobber (reg:SI REG_B5))
   2289    (clobber (reg:SI REG_B30))
   2290    (clobber (reg:SI REG_B31))]
   2291   ""
   2292   "%|%.\\tcall\\t%$\\t__c6xabi_divi"
   2293   [(set_attr "type" "call")
   2294    (set_attr "dest_regfile" "any")
   2295    (set_attr "units" "s")
   2296    (set_attr "cross" "n")])
   2297 
   2298 (define_insn "divsi3_insn_indcall"
   2299   [(set (reg:SI REG_A4) (div:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2300    (use (match_operand:SI 0 "register_operand" "b"))
   2301    (clobber (reg:SI REG_A0))
   2302    (clobber (reg:SI REG_A1))
   2303    (clobber (reg:SI REG_A2))
   2304    (clobber (reg:SI REG_A6))
   2305    (clobber (reg:SI REG_B0))
   2306    (clobber (reg:SI REG_B1))
   2307    (clobber (reg:SI REG_B2))
   2308    (clobber (reg:SI REG_B3))
   2309    (clobber (reg:SI REG_B4))
   2310    (clobber (reg:SI REG_B5))
   2311    (clobber (reg:SI REG_B30))
   2312    (clobber (reg:SI REG_B31))]
   2313   ""
   2314   "%|%.\\tcall\\t%$\\t%0"
   2315   [(set_attr "type" "call")
   2316    (set_attr "dest_regfile" "any")
   2317    (set_attr "units" "s")
   2318    (set_attr "cross" "n")])
   2319 
   2320 (define_insn "udivsi3_insn"
   2321   [(set (reg:SI REG_A4) (udiv:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2322    (clobber (reg:SI REG_A0))
   2323    (clobber (reg:SI REG_A1))
   2324    (clobber (reg:SI REG_A2))
   2325    (clobber (reg:SI REG_A6))
   2326    (clobber (reg:SI REG_B0))
   2327    (clobber (reg:SI REG_B1))
   2328    (clobber (reg:SI REG_B2))
   2329    (clobber (reg:SI REG_B3))
   2330    (clobber (reg:SI REG_B4))
   2331    (clobber (reg:SI REG_B30))
   2332    (clobber (reg:SI REG_B31))]
   2333   ""
   2334   "%|%.\\tcall\\t%$\\t__c6xabi_divu"
   2335   [(set_attr "type" "call")
   2336    (set_attr "dest_regfile" "any")
   2337    (set_attr "units" "s")
   2338    (set_attr "cross" "n")])
   2339 
   2340 (define_insn "udivsi3_insn_indcall"
   2341   [(set (reg:SI REG_A4) (udiv:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2342    (use (match_operand:SI 0 "register_operand" "b"))
   2343    (clobber (reg:SI REG_A0))
   2344    (clobber (reg:SI REG_A1))
   2345    (clobber (reg:SI REG_A2))
   2346    (clobber (reg:SI REG_A6))
   2347    (clobber (reg:SI REG_B0))
   2348    (clobber (reg:SI REG_B1))
   2349    (clobber (reg:SI REG_B2))
   2350    (clobber (reg:SI REG_B3))
   2351    (clobber (reg:SI REG_B4))
   2352    (clobber (reg:SI REG_B30))
   2353    (clobber (reg:SI REG_B31))]
   2354   ""
   2355   "%|%.\\tcall\\t%$\\t%0"
   2356   [(set_attr "type" "call")
   2357    (set_attr "dest_regfile" "any")
   2358    (set_attr "units" "s")
   2359    (set_attr "cross" "n")])
   2360 
   2361 (define_insn "modsi3_insn"
   2362   [(set (reg:SI REG_A4) (mod:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2363    (clobber (reg:SI REG_A1))
   2364    (clobber (reg:SI REG_A2))
   2365    (clobber (reg:SI REG_A5))
   2366    (clobber (reg:SI REG_A6))
   2367    (clobber (reg:SI REG_B0))
   2368    (clobber (reg:SI REG_B1))
   2369    (clobber (reg:SI REG_B2))
   2370    (clobber (reg:SI REG_B3))
   2371    (clobber (reg:SI REG_B4))
   2372    (clobber (reg:SI REG_B30))
   2373    (clobber (reg:SI REG_B31))]
   2374   ""
   2375   "%|%.\\tcall\\t%$\\t__c6xabi_remi"
   2376   [(set_attr "type" "call")
   2377    (set_attr "dest_regfile" "any")
   2378    (set_attr "units" "s")
   2379    (set_attr "cross" "n")])
   2380 
   2381 (define_insn "modsi3_insn_indcall"
   2382   [(set (reg:SI REG_A4) (mod:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2383    (use (match_operand:SI 0 "register_operand" "b"))
   2384    (clobber (reg:SI REG_A1))
   2385    (clobber (reg:SI REG_A2))
   2386    (clobber (reg:SI REG_A5))
   2387    (clobber (reg:SI REG_A6))
   2388    (clobber (reg:SI REG_B0))
   2389    (clobber (reg:SI REG_B1))
   2390    (clobber (reg:SI REG_B2))
   2391    (clobber (reg:SI REG_B3))
   2392    (clobber (reg:SI REG_B4))
   2393    (clobber (reg:SI REG_B30))
   2394    (clobber (reg:SI REG_B31))]
   2395   ""
   2396   "%|%.\\tcall\\t%$\\t%0"
   2397   [(set_attr "type" "call")
   2398    (set_attr "dest_regfile" "any")
   2399    (set_attr "units" "s")
   2400    (set_attr "cross" "n")])
   2401 
   2402 (define_insn "divmodsi4_insn"
   2403   [(set (reg:SI REG_A4) (div:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2404    (set (reg:SI REG_A5) (mod:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2405    (clobber (reg:SI REG_A1))
   2406    (clobber (reg:SI REG_A2))
   2407    (clobber (reg:SI REG_A6))
   2408    (clobber (reg:SI REG_B0))
   2409    (clobber (reg:SI REG_B1))
   2410    (clobber (reg:SI REG_B2))
   2411    (clobber (reg:SI REG_B3))
   2412    (clobber (reg:SI REG_B4))
   2413    (clobber (reg:SI REG_B30))
   2414    (clobber (reg:SI REG_B31))]
   2415   ""
   2416   "%|%.\\tcall\\t%$\\t__c6xabi_divremi"
   2417   [(set_attr "type" "call")
   2418    (set_attr "dest_regfile" "any")
   2419    (set_attr "units" "s")
   2420    (set_attr "cross" "n")])
   2421 
   2422 (define_insn "divmodsi4_insn_indcall"
   2423   [(set (reg:SI REG_A4) (div:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2424    (set (reg:SI REG_A5) (mod:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2425    (use (match_operand:SI 0 "register_operand" "b"))
   2426    (clobber (reg:SI REG_A1))
   2427    (clobber (reg:SI REG_A2))
   2428    (clobber (reg:SI REG_A5))
   2429    (clobber (reg:SI REG_A6))
   2430    (clobber (reg:SI REG_B0))
   2431    (clobber (reg:SI REG_B1))
   2432    (clobber (reg:SI REG_B2))
   2433    (clobber (reg:SI REG_B3))
   2434    (clobber (reg:SI REG_B4))
   2435    (clobber (reg:SI REG_B30))
   2436    (clobber (reg:SI REG_B31))]
   2437   ""
   2438   "%|%.\\tcall\\t%$\\t%0"
   2439   [(set_attr "type" "call")
   2440    (set_attr "dest_regfile" "any")
   2441    (set_attr "units" "s")
   2442    (set_attr "cross" "n")])
   2443 
   2444 (define_insn "umodsi3_insn"
   2445   [(set (reg:SI REG_A4) (umod:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2446    (clobber (reg:SI REG_A1))
   2447    (clobber (reg:SI REG_A5))
   2448    (clobber (reg:SI REG_A7))
   2449    (clobber (reg:SI REG_B0))
   2450    (clobber (reg:SI REG_B1))
   2451    (clobber (reg:SI REG_B2))
   2452    (clobber (reg:SI REG_B3))
   2453    (clobber (reg:SI REG_B4))
   2454    (clobber (reg:SI REG_B30))
   2455    (clobber (reg:SI REG_B31))]
   2456   ""
   2457   "%|%.\\tcall\\t%$\\t__c6xabi_remu"
   2458   [(set_attr "type" "call")
   2459    (set_attr "dest_regfile" "any")
   2460    (set_attr "units" "s")
   2461    (set_attr "cross" "n")])
   2462 
   2463 (define_insn "umodsi3_insn_indcall"
   2464   [(set (reg:SI REG_A4) (umod:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2465    (use (match_operand:SI 0 "register_operand" "b"))
   2466    (clobber (reg:SI REG_A1))
   2467    (clobber (reg:SI REG_A5))
   2468    (clobber (reg:SI REG_A7))
   2469    (clobber (reg:SI REG_B0))
   2470    (clobber (reg:SI REG_B1))
   2471    (clobber (reg:SI REG_B2))
   2472    (clobber (reg:SI REG_B3))
   2473    (clobber (reg:SI REG_B4))
   2474    (clobber (reg:SI REG_B30))
   2475    (clobber (reg:SI REG_B31))]
   2476   ""
   2477   "%|%.\\tcall\\t%$\\t%0"
   2478   [(set_attr "type" "call")
   2479    (set_attr "dest_regfile" "any")
   2480    (set_attr "units" "s")
   2481    (set_attr "cross" "n")])
   2482 
   2483 (define_insn "udivmodsi4_insn"
   2484   [(set (reg:SI REG_A4) (udiv:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2485    (set (reg:SI REG_A5) (umod:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2486    (clobber (reg:SI REG_A0))
   2487    (clobber (reg:SI REG_A1))
   2488    (clobber (reg:SI REG_A2))
   2489    (clobber (reg:SI REG_A6))
   2490    (clobber (reg:SI REG_B0))
   2491    (clobber (reg:SI REG_B1))
   2492    (clobber (reg:SI REG_B2))
   2493    (clobber (reg:SI REG_B3))
   2494    (clobber (reg:SI REG_B4))
   2495    (clobber (reg:SI REG_B30))
   2496    (clobber (reg:SI REG_B31))]
   2497   ""
   2498   "%|%.\\tcall\\t%$\\t__c6xabi_divremu"
   2499   [(set_attr "type" "call")
   2500    (set_attr "dest_regfile" "any")
   2501    (set_attr "units" "s")
   2502    (set_attr "cross" "n")])
   2503 
   2504 (define_insn "udivmodsi4_insn_indcall"
   2505   [(set (reg:SI REG_A4) (udiv:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2506    (set (reg:SI REG_A5) (umod:SI (reg:SI REG_A4) (reg:SI REG_B4)))
   2507    (use (match_operand:SI 0 "register_operand" "b"))
   2508    (clobber (reg:SI REG_A0))
   2509    (clobber (reg:SI REG_A1))
   2510    (clobber (reg:SI REG_A2))
   2511    (clobber (reg:SI REG_A6))
   2512    (clobber (reg:SI REG_B0))
   2513    (clobber (reg:SI REG_B1))
   2514    (clobber (reg:SI REG_B2))
   2515    (clobber (reg:SI REG_B3))
   2516    (clobber (reg:SI REG_B4))
   2517    (clobber (reg:SI REG_B30))
   2518    (clobber (reg:SI REG_B31))]
   2519   ""
   2520   "%|%.\\tcall\\t%$\\t%0"
   2521   [(set_attr "type" "call")
   2522    (set_attr "dest_regfile" "any")
   2523    (set_attr "units" "s")
   2524    (set_attr "cross" "n")])
   2525 
   2526 (define_insn_and_split "divmodsi4"
   2527   [(set (match_operand:SI 0 "register_operand" "")
   2528 	(div:SI (match_operand:SI 1 "register_operand" "")
   2529 		   (match_operand:SI 2 "register_operand" "")))
   2530    (set (match_operand:SI 3 "register_operand" "")
   2531 	(mod:SI (match_dup 1) (match_dup 2)))
   2532    (clobber (reg:SI REG_A0))
   2533    (clobber (reg:SI REG_A1))
   2534    (clobber (reg:SI REG_A2))
   2535    (clobber (reg:SI REG_A4))
   2536    (clobber (reg:SI REG_A5))
   2537    (clobber (reg:SI REG_A6))
   2538    (clobber (reg:SI REG_B0))
   2539    (clobber (reg:SI REG_B1))
   2540    (clobber (reg:SI REG_B2))
   2541    (clobber (reg:SI REG_B3))
   2542    (clobber (reg:SI REG_B4))
   2543    (clobber (reg:SI REG_B5))
   2544    (clobber (reg:SI REG_B30))
   2545    (clobber (reg:SI REG_B31))]
   2546   ""
   2547   "#"
   2548   ""
   2549   [(const_int 0)]
   2550 {
   2551   rtx reg = NULL_RTX;
   2552 
   2553   if (TARGET_LONG_CALLS)
   2554     {
   2555       if (reload_completed)
   2556 	reg = gen_rtx_REG (SImode, REG_A6);
   2557       else
   2558         reg = gen_reg_rtx (SImode);
   2559     }
   2560   emit_move_insn (gen_rtx_REG (SImode, REG_A4), operands[1]);
   2561   emit_move_insn (gen_rtx_REG (SImode, REG_B4), operands[2]);
   2562   if (find_reg_note (curr_insn, REG_UNUSED, operands[3]))
   2563     {
   2564       if (TARGET_LONG_CALLS)
   2565 	{
   2566 	  emit_move_insn (reg, optab_libfunc (sdiv_optab, SImode));
   2567 	  emit_insn (gen_divsi3_insn_indcall (reg));
   2568 	}
   2569       else
   2570         emit_insn (gen_divsi3_insn ());
   2571       emit_move_insn (operands[0], gen_rtx_REG (SImode, REG_A4));
   2572     }
   2573   else if (find_reg_note (curr_insn, REG_UNUSED, operands[0]))
   2574     {
   2575       if (TARGET_LONG_CALLS)
   2576 	{
   2577 	  emit_move_insn (reg, optab_libfunc (smod_optab, SImode));
   2578 	  emit_insn (gen_modsi3_insn_indcall (reg));
   2579 	}
   2580       else
   2581         emit_insn (gen_modsi3_insn ());
   2582       emit_move_insn (operands[3], gen_rtx_REG (SImode, REG_A4));
   2583     }
   2584   else
   2585     {
   2586       if (TARGET_LONG_CALLS)
   2587 	{
   2588 	  emit_move_insn (reg, optab_libfunc (sdivmod_optab, SImode));
   2589 	  emit_insn (gen_divmodsi4_insn_indcall (reg));
   2590 	}
   2591       else
   2592         emit_insn (gen_divmodsi4_insn ());
   2593       emit_move_insn (operands[0], gen_rtx_REG (SImode, REG_A4));
   2594       emit_move_insn (operands[3], gen_rtx_REG (SImode, REG_A5));
   2595     }
   2596   DONE;
   2597 })
   2598 
   2599 (define_insn_and_split "udivmodsi4"
   2600   [(set (match_operand:SI 0 "register_operand" "")
   2601 	(udiv:SI (match_operand:SI 1 "register_operand" "")
   2602 		   (match_operand:SI 2 "register_operand" "")))
   2603    (set (match_operand:SI 3 "register_operand" "")
   2604 	(umod:SI (match_dup 1) (match_dup 2)))
   2605    (clobber (reg:SI REG_A0))
   2606    (clobber (reg:SI REG_A1))
   2607    (clobber (reg:SI REG_A2))
   2608    (clobber (reg:SI REG_A4))
   2609    (clobber (reg:SI REG_A5))
   2610    (clobber (reg:SI REG_A6))
   2611    (clobber (reg:SI REG_A7))
   2612    (clobber (reg:SI REG_B0))
   2613    (clobber (reg:SI REG_B1))
   2614    (clobber (reg:SI REG_B2))
   2615    (clobber (reg:SI REG_B3))
   2616    (clobber (reg:SI REG_B4))
   2617    (clobber (reg:SI REG_B30))
   2618    (clobber (reg:SI REG_B31))]
   2619   ""
   2620   "#"
   2621   ""
   2622   [(const_int 0)]
   2623 {
   2624   rtx reg = NULL_RTX;
   2625 
   2626   if (TARGET_LONG_CALLS)
   2627     {
   2628       if (reload_completed)
   2629 	reg = gen_rtx_REG (SImode, REG_A6);
   2630       else
   2631         reg = gen_reg_rtx (SImode);
   2632     }
   2633 
   2634   emit_move_insn (gen_rtx_REG (SImode, REG_A4), operands[1]);
   2635   emit_move_insn (gen_rtx_REG (SImode, REG_B4), operands[2]);
   2636   if (find_reg_note (curr_insn, REG_UNUSED, operands[3]))
   2637     {
   2638       if (TARGET_LONG_CALLS)
   2639 	{
   2640 	  emit_move_insn (reg, optab_libfunc (udiv_optab, SImode));
   2641 	  emit_insn (gen_udivsi3_insn_indcall (reg));
   2642 	}
   2643       else
   2644         emit_insn (gen_udivsi3_insn ());
   2645       emit_move_insn (operands[0], gen_rtx_REG (SImode, REG_A4));
   2646     }
   2647   else if (find_reg_note (curr_insn, REG_UNUSED, operands[0]))
   2648     {
   2649       if (TARGET_LONG_CALLS)
   2650 	{
   2651 	  emit_move_insn (reg, optab_libfunc (umod_optab, SImode));
   2652 	  emit_insn (gen_umodsi3_insn_indcall (reg));
   2653 	}
   2654       else
   2655         emit_insn (gen_umodsi3_insn ());
   2656       emit_move_insn (operands[3], gen_rtx_REG (SImode, REG_A4));
   2657     }
   2658   else
   2659     {
   2660       if (TARGET_LONG_CALLS)
   2661 	{
   2662 	  emit_move_insn (reg, optab_libfunc (udivmod_optab, SImode));
   2663 	  emit_insn (gen_udivmodsi4_insn_indcall (reg));
   2664 	}
   2665       else
   2666         emit_insn (gen_udivmodsi4_insn ());
   2667       emit_move_insn (operands[0], gen_rtx_REG (SImode, REG_A4));
   2668       emit_move_insn (operands[3], gen_rtx_REG (SImode, REG_A5));
   2669     }
   2670   DONE;
   2671 })
   2672 
   2673 ;; -------------------------------------------------------------------------
   2674 ;; Multiplication
   2675 ;; See c6x-mult.md.in for define_insn patterns.
   2676 ;; -------------------------------------------------------------------------
   2677 
   2678 (define_expand "mulhisi3"
   2679   [(set (match_operand:SI 0 "register_operand" "")
   2680         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
   2681                  (sign_extend:SI (match_operand:HI 2 "reg_or_scst5_operand" ""))))]
   2682   ""
   2683 {
   2684   if (CONSTANT_P (operands[2]))
   2685     {
   2686       emit_insn (gen_mulhisi3_const (operands[0], operands[1], operands[2]));
   2687       DONE;
   2688     }
   2689 })
   2690 
   2691 (define_expand "usmulhisi3"
   2692   [(set (match_operand:SI 0 "register_operand" "")
   2693         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
   2694                  (sign_extend:SI (match_operand:HI 2 "reg_or_scst5_operand" ""))))]
   2695  ""
   2696 {
   2697   if (CONSTANT_P (operands[2]))
   2698     {
   2699       emit_insn (gen_usmulhisi3_const (operands[0], operands[1], operands[2]));
   2700       DONE;
   2701     }
   2702 })
   2703 
   2704 (define_expand "mulsi3"
   2705   [(set (match_operand:SI 0 "register_operand" "")
   2706 	(mult:SI (match_operand:SI 1 "register_operand" "")
   2707 		 (match_operand:SI 2 "register_operand" "")))]
   2708   ""
   2709 {
   2710   if (!TARGET_MPY32)
   2711     {
   2712       rtx lo1 = gen_lowpart (HImode, operands[1]);
   2713       rtx lo2 = gen_lowpart (HImode, operands[2]);
   2714       /*   (N * AH + AL) * (N * BH + BL)
   2715          = N*(AH * BL + BH * AL) + AL*BL  */
   2716       rtx tmp1 = gen_reg_rtx (SImode);
   2717       rtx tmp2 = gen_reg_rtx (SImode);
   2718       rtx tmp3 = gen_reg_rtx (SImode);
   2719       emit_insn (gen_umulhisi3 (tmp1, lo1, lo2));
   2720       emit_insn (gen_umulhisi3_lh (tmp2, lo1, operands[2]));
   2721       emit_insn (gen_umulhisi3_hl (tmp3, operands[1], lo2));
   2722       emit_insn (gen_addsi3 (tmp2, tmp2, tmp3));
   2723       emit_insn (gen_ashlsi3 (tmp2, tmp2, GEN_INT (16)));
   2724       emit_insn (gen_addsi3 (operands[0], tmp1, tmp2));
   2725       DONE;
   2726     }
   2727 })
   2728 
   2729 ;; -------------------------------------------------------------------------
   2730 ;; Floating point multiplication
   2731 ;; -------------------------------------------------------------------------
   2732 
   2733 (define_insn "mulsf3"
   2734   [(set (match_operand:SF 0 "register_operand" "=a,b,a,b")
   2735 	(mult:SF (match_operand:SF 1 "register_operand" "%a,b,?a,?b")
   2736 		 (match_operand:SF 2 "register_operand" "a,b,b,a")))]
   2737   "TARGET_FP"
   2738   "%|%.\\tmpysp\\t%$\\t%1, %2, %0"
   2739  [(set_attr "type" "mpy4")
   2740   (set_attr "units" "m")
   2741   (set_attr "cross" "n,n,y,y")])
   2742 
   2743 (define_insn "muldf3"
   2744   [(set (match_operand:DF 0 "register_operand" "=a,b")
   2745 	(mult:DF (match_operand:DF 1 "register_operand" "%a,b")
   2746 		 (match_operand:DF 2 "register_operand" "a,b")))]
   2747   "TARGET_FP"
   2748   "%|%.\\tmpydp\\t%$\\t%1, %2, %0"
   2749  [(set_attr "type" "mpydp")
   2750   (set_attr "units" "m")
   2751   (set_attr "cross" "n")])
   2752 
   2753 ;; Note that mpyspdp and mpysp2dp are available on C67x, despite what the
   2754 ;; manual says.
   2755 (define_insn "*muldf_ext1"
   2756   [(set (match_operand:DF 0 "register_operand" "=a,b,a,b")
   2757 	(mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "a,b,a,b"))
   2758 		 (match_operand:DF 2 "register_operand" "a,b,?b,?a")))]
   2759   "TARGET_FP_EXT"
   2760   "%|%.\\tmpyspdp\\t%$\\t%1, %2, %0"
   2761  [(set_attr "type" "mpyspdp")
   2762   (set_attr "units" "m")
   2763   (set_attr "cross" "n,n,y,y")])
   2764 
   2765 (define_insn "*muldf_ext2"
   2766   [(set (match_operand:DF 0 "register_operand" "=a,b,a,b")
   2767 	(mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "%a,b,a,b"))
   2768 		 (float_extend:DF (match_operand:SF 2 "register_operand" "a,b,?b,?a"))))]
   2769   "TARGET_FP_EXT"
   2770   "%|%.\\tmpysp2dp\\t%$\\t%1, %2, %0"
   2771  [(set_attr "type" "mpysp2dp")
   2772   (set_attr "units" "m")
   2773   (set_attr "cross" "n,n,y,y")])
   2774 
   2775 ;; -------------------------------------------------------------------------
   2776 ;; Floating point division
   2777 ;; -------------------------------------------------------------------------
   2778 
   2779 (define_insn "rcpsf2"
   2780   [(set (match_operand:SF 0 "register_operand" "=a,b,a,b")
   2781 	(unspec:SF [(match_operand:SF 1 "register_operand" "a,b,?b,?a")]
   2782 		   UNSPEC_RCP))]
   2783   "TARGET_FP"
   2784   "%|%.\\trcpsp\\t%$\\t%1, %0"
   2785  [(set_attr "units" "s")
   2786   (set_attr "cross" "n,n,y,y")])
   2787 
   2788 (define_insn "rcpdf2"
   2789   [(set (match_operand:DF 0 "register_operand" "=a,b")
   2790 	(unspec:DF [(match_operand:DF 1 "register_operand" "a,b")]
   2791 		   UNSPEC_RCP))]
   2792   "TARGET_FP"
   2793   "%|%.\\trcpdp\\t%$\\t%1, %0"
   2794  [(set_attr "type" "dp2")
   2795   (set_attr "units" "s")
   2796   (set_attr "cross" "n")])
   2797 
   2798 (define_expand "divsf3"
   2799   [(set (match_dup 4)
   2800 	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
   2801 		   UNSPEC_RCP))
   2802    (set (match_dup 5) (mult:SF (match_dup 2) (match_dup 4)))
   2803    (set (match_dup 6) (minus:SF (match_dup 3) (match_dup 5)))
   2804    (set (match_dup 4) (mult:SF (match_dup 4) (match_dup 6)))
   2805    (set (match_dup 5) (mult:SF (match_dup 2) (match_dup 4)))
   2806    (set (match_dup 6) (minus:SF (match_dup 3) (match_dup 5)))
   2807    (set (match_dup 4) (mult:SF (match_dup 4) (match_dup 6)))
   2808    (set (match_operand:SF 0 "register_operand" "")
   2809 	(mult:SF (match_operand:SF 1 "register_operand")
   2810 		 (match_dup 4)))]
   2811   "TARGET_FP && flag_reciprocal_math"
   2812 {
   2813   operands[3] = force_reg (SFmode,
   2814 			   CONST_DOUBLE_FROM_REAL_VALUE (dconst2, SFmode));
   2815   operands[4] = gen_reg_rtx (SFmode);
   2816   operands[5] = gen_reg_rtx (SFmode);
   2817   operands[6] = gen_reg_rtx (SFmode);
   2818 })
   2819 
   2820 (define_expand "divdf3"
   2821   [(set (match_dup 4)
   2822 	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
   2823 		   UNSPEC_RCP))
   2824    (set (match_dup 5) (mult:DF (match_dup 2) (match_dup 4)))
   2825    (set (match_dup 6) (minus:DF (match_dup 3) (match_dup 5)))
   2826    (set (match_dup 4) (mult:DF (match_dup 4) (match_dup 6)))
   2827    (set (match_dup 5) (mult:DF (match_dup 2) (match_dup 4)))
   2828    (set (match_dup 6) (minus:DF (match_dup 3) (match_dup 5)))
   2829    (set (match_dup 4) (mult:DF (match_dup 4) (match_dup 6)))
   2830    (set (match_dup 5) (mult:DF (match_dup 2) (match_dup 4)))
   2831    (set (match_dup 6) (minus:DF (match_dup 3) (match_dup 5)))
   2832    (set (match_dup 4) (mult:DF (match_dup 4) (match_dup 6)))
   2833    (set (match_operand:DF 0 "register_operand" "")
   2834 	(mult:DF (match_operand:DF 1 "register_operand")
   2835 		 (match_dup 4)))]
   2836   "TARGET_FP && flag_reciprocal_math"
   2837 {
   2838   operands[3] = force_reg (DFmode,
   2839 			   CONST_DOUBLE_FROM_REAL_VALUE (dconst2, DFmode));
   2840   operands[4] = gen_reg_rtx (DFmode);
   2841   operands[5] = gen_reg_rtx (DFmode);
   2842   operands[6] = gen_reg_rtx (DFmode);
   2843 })
   2844 
   2845 ;; -------------------------------------------------------------------------
   2846 ;; Block moves
   2847 ;; -------------------------------------------------------------------------
   2848 
   2849 (define_expand "movmemsi"
   2850   [(use (match_operand:BLK 0 "memory_operand" ""))
   2851    (use (match_operand:BLK 1 "memory_operand" ""))
   2852    (use (match_operand:SI 2 "nonmemory_operand" ""))
   2853    (use (match_operand:SI 3 "const_int_operand" ""))
   2854    (use (match_operand:SI 4 "const_int_operand" ""))
   2855    (use (match_operand:SI 5 "const_int_operand" ""))]
   2856   ""
   2857 {
   2858  if (c6x_expand_movmem (operands[0], operands[1], operands[2], operands[3],
   2859 			operands[4], operands[5]))
   2860    DONE;
   2861  else
   2862    FAIL;
   2863 })
   2864 
   2865 ;; -------------------------------------------------------------------------
   2866 ;; Prologue and epilogue.
   2867 ;; -------------------------------------------------------------------------
   2868 
   2869 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
   2870 ;; all of memory.  This blocks insns from being moved across this point.
   2871 
   2872 (define_insn "blockage"
   2873   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
   2874   ""
   2875   ""
   2876   [(set_attr "type" "blockage")])
   2877 
   2878 (define_insn "push_rts"
   2879   [(set (mem:SI (reg:SI REG_SP)) (reg:SI REG_B14))
   2880    (set (mem:DI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:DI REG_A14))
   2881    (set (mem:DI (plus:SI (reg:SI REG_SP) (const_int -16))) (reg:DI REG_B12))
   2882    (set (mem:DI (plus:SI (reg:SI REG_SP) (const_int -24))) (reg:DI REG_A12))
   2883    (set (mem:DI (plus:SI (reg:SI REG_SP) (const_int -32))) (reg:DI REG_B10))
   2884    (set (mem:DI (plus:SI (reg:SI REG_SP) (const_int -40))) (reg:DI REG_A10))
   2885    (set (mem:DI (plus:SI (reg:SI REG_SP) (const_int -48))) (reg:DI REG_B2))
   2886    (set (reg:SI REG_SP) (plus:SI (reg:SI REG_SP) (const_int -56)))
   2887    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
   2888    (clobber (reg:SI REG_A3))]
   2889   "TARGET_INSNS_64PLUS"
   2890   "%|%.\\tcallp\\t%$\\t__c6xabi_push_rts, a3"
   2891   [(set_attr "type" "callp")
   2892    (set_attr "dest_regfile" "a")
   2893    (set_attr "units" "s")
   2894    (set_attr "cross" "n")])
   2895 
   2896 (define_insn "pop_rts"
   2897   [(set (reg:SI REG_B14) (mem:SI (plus:SI (reg:SI REG_SP) (const_int 56))))
   2898    (set (reg:DI REG_A14) (mem:DI (plus:SI (reg:SI REG_SP) (const_int 48))))
   2899    (set (reg:DI REG_B12) (mem:DI (plus:SI (reg:SI REG_SP) (const_int 40))))
   2900    (set (reg:DI REG_A12) (mem:DI (plus:SI (reg:SI REG_SP) (const_int 32))))
   2901    (set (reg:DI REG_B10) (mem:DI (plus:SI (reg:SI REG_SP) (const_int 24))))
   2902    (set (reg:DI REG_A10) (mem:DI (plus:SI (reg:SI REG_SP) (const_int 16))))
   2903    (set (reg:DI REG_B2) (mem:DI (plus:SI (reg:SI REG_SP) (const_int 8))))
   2904    (set (reg:SI REG_SP) (plus:SI (reg:SI REG_SP) (const_int 56)))
   2905    (clobber (reg:SI REG_A3))
   2906    (return)]
   2907   "TARGET_INSNS_64PLUS"
   2908   "%|%.\\tretp\\t%$\\t__c6xabi_pop_rts, a3"
   2909   [(set_attr "type" "callp")
   2910    (set_attr "dest_regfile" "a")
   2911    (set_attr "units" "s")
   2912    (set_attr "cross" "n")])
   2913 
   2914 (define_expand "prologue"
   2915   [(const_int 1)]
   2916   ""
   2917   "c6x_expand_prologue (); DONE;")
   2918 
   2919 (define_expand "epilogue"
   2920   [(const_int 1)]
   2921   ""
   2922   "c6x_expand_epilogue (false); DONE;")
   2923 
   2924 (define_expand "sibcall_epilogue"
   2925   [(return)]
   2926   ""
   2927 {
   2928   c6x_expand_epilogue (true);
   2929   DONE;
   2930 })
   2931 
   2932 (define_insn "setup_dsbt"
   2933   [(set (match_operand:SI 0 "pic_register_operand" "+Z")
   2934 	(unspec:SI [(match_dup 0)
   2935 		    (match_operand:SI 1 "symbolic_operand" "")]
   2936 		   UNSPEC_SETUP_DSBT))]
   2937   "TARGET_DSBT"
   2938   "%|%.\\tldw\\t%$\\t*+%0($DSBT_index%1), %0"
   2939   [(set_attr "type" "load")
   2940    (set_attr "units" "d_addr")
   2941    (set_attr "dest_regfile" "b")
   2942    (set_attr "addr_regfile" "b")])
   2943 
   2944 
   2945 ;; A dummy use/set to prevent prologue and epiloge overlapping.
   2946 ;; This can be caused by sched-ebb in the presence of multiple
   2947 ;; exit sequences, and causes the unwinding table generation to explode.
   2948 (define_insn "epilogue_barrier"
   2949  [(set (match_operand:SI 0 "register_operand" "")
   2950        (unspec:SI [(match_operand:SI 1 "register_operand" "")]
   2951 		  UNSPEC_EPILOGUE_BARRIER))]
   2952  ""
   2953  ""
   2954  [(set_attr "type" "blockage")])
   2955 
   2956 ;; -------------------------------------------------------------------------
   2957 ;; Vector insns
   2958 ;; -------------------------------------------------------------------------
   2959 
   2960 (define_code_iterator logical [and ior xor])
   2961 (define_code_attr logical_insn [(and "and") (ior "ior") (xor "xor")])
   2962 (define_code_attr logical_opcode [(and "and") (ior "or") (xor "xor")])
   2963 (define_code_iterator plusminus [plus minus])
   2964 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
   2965 (define_code_iterator ss_plusminus [ss_plus ss_minus])
   2966 (define_code_attr ss_plusminus_insn [(ss_plus "add") (ss_minus "sub")])
   2967 
   2968 ;; Vector logical insns
   2969 
   2970 (define_insn "<logical_insn><mode>3"
   2971   [(set (match_operand:VEC4M 0 "register_operand" "=a,b,a,b")
   2972 	(logical:VEC4M (match_operand:VEC4M 1 "register_operand" "a,b,a,b")
   2973 		      (match_operand:VEC4M 2 "register_operand" "a,b,?b,?a")))]
   2974   ""
   2975   "%|%.\\t<logical_opcode>\\t%$\\t%1, %2, %0"
   2976   [(set_attr "units62" "ls")
   2977    (set_attr "units64" "dls")
   2978    (set_attr "cross" "n,n,y,y")])
   2979 
   2980 ;; Vector add/subtract
   2981 
   2982 (define_insn "<plusminus_insn>v2hi3"
   2983   [(set (match_operand:V2HI 0 "register_operand" "=a,b,a,b")
   2984 	(plusminus:V2HI (match_operand:V2HI 1 "register_operand" "a,b,a,b")
   2985 			(match_operand:V2HI 2 "register_operand" "a,b,?b,?a")))]
   2986   ""
   2987   "%|%.\\t<plusminus_insn>2\\t%$\\t%1, %2, %0"
   2988  [(set_attr "units62" "l")
   2989   (set_attr "units64" "dls")
   2990   (set_attr "cross" "n,n,y,y")])
   2991 
   2992 (define_insn "<plusminus_insn>v4qi3"
   2993   [(set (match_operand:V4QI 0 "register_operand" "=a,b,a,b")
   2994 	(plusminus:V4QI (match_operand:V4QI 1 "register_operand" "a,b,a,b")
   2995 			(match_operand:V4QI 2 "register_operand" "a,b,?b,?a")))]
   2996   "TARGET_INSNS_64"
   2997   "%|%.\\t<plusminus_insn>4\\t%$\\t%1, %2, %0"
   2998  [(set_attr "units" "l")
   2999   (set_attr "cross" "n,n,y,y")])
   3000 
   3001 (define_insn "ss_addv2hi3"
   3002   [(set (match_operand:V2HI 0 "register_operand" "=a,b,a,b")
   3003 	(ss_plus:V2HI (match_operand:V2HI 1 "register_operand" "a,b,a,b")
   3004 		      (match_operand:V2HI 2 "register_operand" "a,b,?b,?a")))]
   3005   "TARGET_INSNS_64"
   3006   "%|%.\\tsadd2\\t%$\\t%1, %2, %0"
   3007  [(set_attr "units" "s")
   3008   (set_attr "cross" "n,n,y,y")])
   3009 
   3010 (define_insn "ss_subv2hi3"
   3011   [(set (match_operand:V2HI 0 "register_operand" "=a,b,a,b")
   3012 	(ss_minus:V2HI (match_operand:V2HI 1 "register_operand" "a,b,a,b")
   3013 		       (match_operand:V2HI 2 "register_operand" "a,b,?b,?a")))]
   3014   "TARGET_INSNS_64"
   3015   "%|%.\\tssub2\\t%$\\t%1, %2, %0"
   3016  [(set_attr "units" "l")
   3017   (set_attr "cross" "n,n,y,y")])
   3018 
   3019 (define_insn "us_addv4qi3"
   3020   [(set (match_operand:V4QI 0 "register_operand" "=a,b,a,b")
   3021 	(ss_plus:V4QI (match_operand:V4QI 1 "register_operand" "a,b,a,b")
   3022 		      (match_operand:V4QI 2 "register_operand" "a,b,?b,?a")))]
   3023   "TARGET_INSNS_64"
   3024   "%|%.\\tsaddu4\\t%$\\t%1, %2, %0"
   3025  [(set_attr "units" "s")
   3026   (set_attr "cross" "n,n,y,y")])
   3027 
   3028 ;; Vector/scalar min/max
   3029 
   3030 (define_mode_iterator SMINMAX [HI V2HI])
   3031 (define_mode_iterator UMINMAX [QI V4QI])
   3032 
   3033 (define_insn "smax<mode>3"
   3034   [(set (match_operand:SMINMAX 0 "register_operand" "=a,b,a,b")
   3035 	(smax:SMINMAX (match_operand:SMINMAX 1 "register_operand" "a,b,a,b")
   3036 		      (match_operand:SMINMAX 2 "register_operand" "a,b,?b,?a")))]
   3037   "TARGET_INSNS_64"
   3038   "%|%.\\tmax2\\t%$\\t%1, %2, %0"
   3039   [(set_attr "units64" "l")
   3040    (set_attr "units64p" "ls")
   3041    (set_attr "cross" "n,n,y,y")])
   3042 
   3043 (define_insn "smin<mode>3"
   3044   [(set (match_operand:SMINMAX 0 "register_operand" "=a,b,a,b")
   3045 	(smin:SMINMAX (match_operand:SMINMAX 1 "register_operand" "a,b,a,b")
   3046 		      (match_operand:SMINMAX 2 "register_operand" "a,b,?b,?a")))]
   3047   "TARGET_INSNS_64"
   3048   "%|%.\\tmin2\\t%$\\t%1, %2, %0"
   3049   [(set_attr "units64" "l")
   3050    (set_attr "units64p" "ls")
   3051    (set_attr "cross" "n,n,y,y")])
   3052 
   3053 (define_insn "umax<mode>3"
   3054   [(set (match_operand:UMINMAX 0 "register_operand" "=a,b,a,b")
   3055 	(umax:UMINMAX (match_operand:UMINMAX 1 "register_operand" "a,b,a,b")
   3056 		      (match_operand:UMINMAX 2 "register_operand" "a,b,?b,?a")))]
   3057   "TARGET_INSNS_64"
   3058   "%|%.\\tmaxu4\\t%$\\t%1, %2, %0"
   3059   [(set_attr "units" "l")
   3060    (set_attr "cross" "n,n,y,y")])
   3061 
   3062 (define_insn "umin<mode>3"
   3063   [(set (match_operand:UMINMAX 0 "register_operand" "=a,b,a,b")
   3064 	(umin:UMINMAX (match_operand:UMINMAX 1 "register_operand" "a,b,a,b")
   3065 		      (match_operand:UMINMAX 2 "register_operand" "a,b,?b,?a")))]
   3066   "TARGET_INSNS_64"
   3067   "%|%.\\tminu4\\t%$\\t%1, %2, %0"
   3068   [(set_attr "units" "l")
   3069    (set_attr "cross" "n,n,y,y")])
   3070 
   3071 ;; Vector shifts
   3072 
   3073 (define_insn "<shift_code>v2hi3"
   3074   [(set (match_operand:V2HI 0 "register_operand" "=a,b,a,b")
   3075         (any_rshift:V2HI (match_operand:V2HI 1 "register_operand" "a,b,?b,?a")
   3076 			 (match_operand:SI 2 "reg_or_ucst5_operand" "aIu5,bIu5,aIu5,bIu5")))]
   3077   "TARGET_INSNS_64"
   3078   "%|%.\\t<shift_insn>2\\t%$\\t%1, %2, %0"
   3079   [(set_attr "units" "s")
   3080    (set_attr "cross" "n,n,y,y")])
   3081 
   3082 ;; See c6x-mult.md.in for avg2/avgu4
   3083 
   3084 ;; Widening vector multiply and dot product.
   3085 ;; See c6x-mult.md.in for the define_insn patterns
   3086 
   3087 (define_expand "sdot_prodv2hi"
   3088   [(match_operand:SI 0 "register_operand" "")
   3089    (match_operand:V2HI 1 "register_operand" "")
   3090    (match_operand:V2HI 2 "register_operand" "")
   3091    (match_operand:SI 3 "register_operand" "")]
   3092   "TARGET_INSNS_64"
   3093 {
   3094   rtx t = gen_reg_rtx (SImode);
   3095   emit_insn (gen_dotv2hi (t, operands[1], operands[2]));
   3096   emit_insn (gen_addsi3 (operands[0], operands[3], t));
   3097   DONE;
   3098 })
   3099 
   3100 ;; Unary vector operations
   3101 
   3102 (define_insn "ssabsv2hi2"
   3103   [(set (match_operand:V2HI 0 "register_operand" "=a, a, b, b")
   3104         (ss_abs:V2HI (match_operand:V2HI 1 "register_operand" "a,?b, b,?a")))]
   3105   "TARGET_INSNS_64"
   3106   "%|%.\\tabs2\\t%$\\t%1, %0"
   3107   [(set_attr "units" "l")
   3108    (set_attr "cross" "n,y,n,y")])
   3109 
   3110 ;; Pack insns
   3111 
   3112 (define_insn "*packv2hi_insv"
   3113   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+a,b,a,b,ab")
   3114 			 (const_int 16)
   3115 			 (const_int 16))
   3116 	(match_operand:SI 1 "nonmemory_operand" "a,b,?b,?a,n"))]
   3117   "TARGET_INSNS_64"
   3118   "@
   3119    %|%.\\tpack2\\t%$\\t%1, %0, %0
   3120    %|%.\\tpack2\\t%$\\t%1, %0, %0
   3121    %|%.\\tpack2\\t%$\\t%1, %0, %0
   3122    %|%.\\tpack2\\t%$\\t%1, %0, %0
   3123    %|%.\\tmvklh\\t%$\\t%1, %0"
   3124   [(set_attr "units" "ls")
   3125    (set_attr "cross" "n,n,y,y,n")])
   3126 
   3127 (define_insn "movstricthi"
   3128   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+a,b,a,b"))
   3129 	(match_operand:HI 1 "register_operand" "a,b,?b,?a"))]
   3130   "TARGET_INSNS_64"
   3131   "%|%.\\tpackhl2\\t%$\\t%0, %1, %0"
   3132   [(set_attr "units" "ls")
   3133    (set_attr "cross" "n,n,y,y")])
   3134 
   3135 (include "c6x-mult.md")
   3136 (include "sync.md")
   3137