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