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