xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/c6x/c6x.c (revision 867d70fc718005c0918b8b8b2f9d7f2d52d0a0db)
1 /* Target Code for TI C6X
2    Copyright (C) 2010-2019 Free Software Foundation, Inc.
3    Contributed by Andrew Jenner <andrew@codesourcery.com>
4    Contributed by Bernd Schmidt <bernds@codesourcery.com>
5 
6    This file is part of GCC.
7 
8    GCC is free software; you can redistribute it and/or modify it
9    under the terms of the GNU General Public License as published
10    by the Free Software Foundation; either version 3, or (at your
11    option) any later version.
12 
13    GCC is distributed in the hope that it will be useful, but WITHOUT
14    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16    License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with GCC; see the file COPYING3.  If not see
20    <http://www.gnu.org/licenses/>.  */
21 
22 #define IN_TARGET_CODE 1
23 
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "backend.h"
28 #include "target.h"
29 #include "rtl.h"
30 #include "tree.h"
31 #include "gimple-expr.h"
32 #include "cfghooks.h"
33 #include "df.h"
34 #include "memmodel.h"
35 #include "tm_p.h"
36 #include "stringpool.h"
37 #include "attribs.h"
38 #include "optabs.h"
39 #include "regs.h"
40 #include "emit-rtl.h"
41 #include "recog.h"
42 #include "cgraph.h"
43 #include "diagnostic-core.h"
44 #include "stor-layout.h"
45 #include "varasm.h"
46 #include "calls.h"
47 #include "output.h"
48 #include "insn-attr.h"
49 #include "explow.h"
50 #include "expr.h"
51 #include "cfgrtl.h"
52 #include "sched-int.h"
53 #include "tm-constrs.h"
54 #include "langhooks.h"
55 #include "sel-sched.h"
56 #include "debug.h"
57 #include "hw-doloop.h"
58 #include "regrename.h"
59 #include "dumpfile.h"
60 #include "builtins.h"
61 
62 /* This file should be included last.  */
63 #include "target-def.h"
64 
65 /* Table of supported architecture variants.  */
66 typedef struct
67 {
68   const char *arch;
69   enum c6x_cpu_type type;
70   unsigned short features;
71 } c6x_arch_table;
72 
73 /* A list of all ISAs, mapping each one to a representative device.
74    Used for -march selection.  */
75 static const c6x_arch_table all_isas[] =
76 {
77 #define C6X_ISA(NAME,DEVICE,FLAGS) \
78   { NAME, DEVICE, FLAGS },
79 #include "c6x-isas.def"
80 #undef C6X_ISA
81   { NULL, C6X_CPU_C62X, 0 }
82 };
83 
84 /* This is the parsed result of the "-march=" option, if given.  */
85 enum c6x_cpu_type c6x_arch = C6X_DEFAULT_ARCH;
86 
87 /* A mask of insn types that are allowed by the architecture selected by
88    the -march option.  */
89 unsigned long c6x_insn_mask = C6X_DEFAULT_INSN_MASK;
90 
91 /* The instruction that is being output (as obtained from FINAL_PRESCAN_INSN).
92  */
93 static rtx_insn *c6x_current_insn = NULL;
94 
95 /* A decl we build to access __c6xabi_DSBT_base.  */
96 static GTY(()) tree dsbt_decl;
97 
98 /* Determines whether we run our final scheduling pass or not.  We always
99    avoid the normal second scheduling pass.  */
100 static int c6x_flag_schedule_insns2;
101 
102 /* Determines whether we run variable tracking in machine dependent
103    reorganization.  */
104 static int c6x_flag_var_tracking;
105 
106 /* Determines whether we use modulo scheduling.  */
107 static int c6x_flag_modulo_sched;
108 
109 /* Record the state of flag_pic before we set it to 1 for DSBT.  */
110 int c6x_initial_flag_pic;
111 
112 typedef struct
113 {
114   /* We record the clock cycle for every insn during scheduling.  */
115   int clock;
116   /* After scheduling, we run assign_reservations to choose unit
117      reservations for all insns.  These are recorded here.  */
118   int reservation;
119   /* Records the new condition for insns which must be made
120      conditional after scheduling.  An entry of NULL_RTX means no such
121      change is necessary.  */
122   rtx new_cond;
123   /* True for the first insn that was scheduled in an ebb.  */
124   bool ebb_start;
125   /* The scheduler state after the insn, transformed into a mask of UNIT_QID
126      bits rather than storing the state.  Meaningful only for the last
127      insn in a cycle.  */
128   unsigned int unit_mask;
129 } c6x_sched_insn_info;
130 
131 
132 /* Record a c6x_sched_insn_info structure for every insn in the function.  */
133 static vec<c6x_sched_insn_info> insn_info;
134 
135 #define INSN_INFO_LENGTH (insn_info).length ()
136 #define INSN_INFO_ENTRY(N) (insn_info[(N)])
137 
138 static bool done_cfi_sections;
139 
140 #define RESERVATION_FLAG_D 1
141 #define RESERVATION_FLAG_L 2
142 #define RESERVATION_FLAG_S 4
143 #define RESERVATION_FLAG_M 8
144 #define RESERVATION_FLAG_DL (RESERVATION_FLAG_D | RESERVATION_FLAG_L)
145 #define RESERVATION_FLAG_DS (RESERVATION_FLAG_D | RESERVATION_FLAG_S)
146 #define RESERVATION_FLAG_LS (RESERVATION_FLAG_L | RESERVATION_FLAG_S)
147 #define RESERVATION_FLAG_DLS (RESERVATION_FLAG_D | RESERVATION_FLAG_LS)
148 
149 /* The DFA names of the units.  */
150 static const char *const c6x_unit_names[] =
151 {
152   "d1", "l1", "s1", "m1", "fps1", "fpl1", "adddps1", "adddpl1",
153   "d2", "l2", "s2", "m2", "fps2", "fpl2", "adddps2", "adddpl2"
154 };
155 
156 /* The DFA unit number for each unit in c6x_unit_names[].  */
157 static int c6x_unit_codes[ARRAY_SIZE (c6x_unit_names)];
158 
159 /* Unit query IDs.  */
160 #define UNIT_QID_D1 0
161 #define UNIT_QID_L1 1
162 #define UNIT_QID_S1 2
163 #define UNIT_QID_M1 3
164 #define UNIT_QID_FPS1 4
165 #define UNIT_QID_FPL1 5
166 #define UNIT_QID_ADDDPS1 6
167 #define UNIT_QID_ADDDPL1 7
168 #define UNIT_QID_SIDE_OFFSET 8
169 
170 #define RESERVATION_S1 2
171 #define RESERVATION_S2 10
172 
173 /* An enum for the unit requirements we count in the UNIT_REQS table.  */
174 enum unitreqs
175 {
176   UNIT_REQ_D,
177   UNIT_REQ_L,
178   UNIT_REQ_S,
179   UNIT_REQ_M,
180   UNIT_REQ_DL,
181   UNIT_REQ_DS,
182   UNIT_REQ_LS,
183   UNIT_REQ_DLS,
184   UNIT_REQ_T,
185   UNIT_REQ_X,
186   UNIT_REQ_MAX
187 };
188 
189 /* A table used to count unit requirements.  Used when computing minimum
190    iteration intervals.  */
191 typedef int unit_req_table[2][UNIT_REQ_MAX];
192 static unit_req_table unit_reqs;
193 
194 /* Register map for debugging.  */
195 unsigned const dbx_register_map[FIRST_PSEUDO_REGISTER] =
196 {
197   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,	/* A0 - A15.  */
198   37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,	/* A16 - A32.  */
199   50, 51, 52,
200   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,	/* B0 - B15.  */
201   29, 30, 31,
202   53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,	/* B16 - B32.  */
203   66, 67, 68,
204   -1, -1, -1						/* FP, ARGP, ILC.  */
205 };
206 
207 /* Allocate a new, cleared machine_function structure.  */
208 
209 static struct machine_function *
210 c6x_init_machine_status (void)
211 {
212   return ggc_cleared_alloc<machine_function> ();
213 }
214 
215 /* Implement TARGET_OPTION_OVERRIDE.  */
216 
217 static void
218 c6x_option_override (void)
219 {
220   unsigned i;
221 
222   if (global_options_set.x_c6x_arch_option)
223     {
224       c6x_arch = all_isas[c6x_arch_option].type;
225       c6x_insn_mask &= ~C6X_INSNS_ALL_CPU_BITS;
226       c6x_insn_mask |= all_isas[c6x_arch_option].features;
227     }
228 
229   c6x_flag_schedule_insns2 = flag_schedule_insns_after_reload;
230   flag_schedule_insns_after_reload = 0;
231 
232   c6x_flag_modulo_sched = flag_modulo_sched;
233   flag_modulo_sched = 0;
234 
235   init_machine_status = c6x_init_machine_status;
236 
237   for (i = 0; i < ARRAY_SIZE (c6x_unit_names); i++)
238     c6x_unit_codes[i] = get_cpu_unit_code (c6x_unit_names[i]);
239 
240   if (flag_pic && !TARGET_DSBT)
241     {
242       error ("%<-fpic%> and %<-fPIC%> not supported without %<-mdsbt%> "
243 	     "on this target");
244       flag_pic = 0;
245     }
246   c6x_initial_flag_pic = flag_pic;
247   if (TARGET_DSBT && !flag_pic)
248     flag_pic = 1;
249 }
250 
251 
252 /* Implement the TARGET_CONDITIONAL_REGISTER_USAGE hook.  */
253 
254 static void
255 c6x_conditional_register_usage (void)
256 {
257   int i;
258   if (c6x_arch == C6X_CPU_C62X || c6x_arch == C6X_CPU_C67X)
259     for (i = 16; i < 32; i++)
260       {
261 	fixed_regs[i] = 1;
262 	fixed_regs[32 + i] = 1;
263       }
264   if (TARGET_INSNS_64)
265     {
266       SET_HARD_REG_BIT (reg_class_contents[(int)PREDICATE_A_REGS],
267 			REG_A0);
268       SET_HARD_REG_BIT (reg_class_contents[(int)PREDICATE_REGS],
269 			REG_A0);
270       CLEAR_HARD_REG_BIT (reg_class_contents[(int)NONPREDICATE_A_REGS],
271 			  REG_A0);
272       CLEAR_HARD_REG_BIT (reg_class_contents[(int)NONPREDICATE_REGS],
273 			  REG_A0);
274     }
275 }
276 
277 static GTY(()) rtx eqdf_libfunc;
278 static GTY(()) rtx nedf_libfunc;
279 static GTY(()) rtx ledf_libfunc;
280 static GTY(()) rtx ltdf_libfunc;
281 static GTY(()) rtx gedf_libfunc;
282 static GTY(()) rtx gtdf_libfunc;
283 static GTY(()) rtx eqsf_libfunc;
284 static GTY(()) rtx nesf_libfunc;
285 static GTY(()) rtx lesf_libfunc;
286 static GTY(()) rtx ltsf_libfunc;
287 static GTY(()) rtx gesf_libfunc;
288 static GTY(()) rtx gtsf_libfunc;
289 static GTY(()) rtx strasgi_libfunc;
290 static GTY(()) rtx strasgi64p_libfunc;
291 
292 /* Implement the TARGET_INIT_LIBFUNCS macro.  We use this to rename library
293    functions to match the C6x ABI.  */
294 
295 static void
296 c6x_init_libfuncs (void)
297 {
298   /* Double-precision floating-point arithmetic.  */
299   set_optab_libfunc (add_optab, DFmode, "__c6xabi_addd");
300   set_optab_libfunc (sdiv_optab, DFmode, "__c6xabi_divd");
301   set_optab_libfunc (smul_optab, DFmode, "__c6xabi_mpyd");
302   set_optab_libfunc (neg_optab, DFmode, "__c6xabi_negd");
303   set_optab_libfunc (sub_optab, DFmode, "__c6xabi_subd");
304 
305   /* Single-precision floating-point arithmetic.  */
306   set_optab_libfunc (add_optab, SFmode, "__c6xabi_addf");
307   set_optab_libfunc (sdiv_optab, SFmode, "__c6xabi_divf");
308   set_optab_libfunc (smul_optab, SFmode, "__c6xabi_mpyf");
309   set_optab_libfunc (neg_optab, SFmode, "__c6xabi_negf");
310   set_optab_libfunc (sub_optab, SFmode, "__c6xabi_subf");
311 
312   /* Floating-point comparisons.  */
313   eqsf_libfunc = init_one_libfunc ("__c6xabi_eqf");
314   nesf_libfunc = init_one_libfunc ("__c6xabi_neqf");
315   lesf_libfunc = init_one_libfunc ("__c6xabi_lef");
316   ltsf_libfunc = init_one_libfunc ("__c6xabi_ltf");
317   gesf_libfunc = init_one_libfunc ("__c6xabi_gef");
318   gtsf_libfunc = init_one_libfunc ("__c6xabi_gtf");
319   eqdf_libfunc = init_one_libfunc ("__c6xabi_eqd");
320   nedf_libfunc = init_one_libfunc ("__c6xabi_neqd");
321   ledf_libfunc = init_one_libfunc ("__c6xabi_led");
322   ltdf_libfunc = init_one_libfunc ("__c6xabi_ltd");
323   gedf_libfunc = init_one_libfunc ("__c6xabi_ged");
324   gtdf_libfunc = init_one_libfunc ("__c6xabi_gtd");
325 
326   set_optab_libfunc (eq_optab, SFmode, NULL);
327   set_optab_libfunc (ne_optab, SFmode, "__c6xabi_neqf");
328   set_optab_libfunc (gt_optab, SFmode, NULL);
329   set_optab_libfunc (ge_optab, SFmode, NULL);
330   set_optab_libfunc (lt_optab, SFmode, NULL);
331   set_optab_libfunc (le_optab, SFmode, NULL);
332   set_optab_libfunc (unord_optab, SFmode, "__c6xabi_unordf");
333   set_optab_libfunc (eq_optab, DFmode, NULL);
334   set_optab_libfunc (ne_optab, DFmode, "__c6xabi_neqd");
335   set_optab_libfunc (gt_optab, DFmode, NULL);
336   set_optab_libfunc (ge_optab, DFmode, NULL);
337   set_optab_libfunc (lt_optab, DFmode, NULL);
338   set_optab_libfunc (le_optab, DFmode, NULL);
339   set_optab_libfunc (unord_optab, DFmode, "__c6xabi_unordd");
340 
341   /* Floating-point to integer conversions.  */
342   set_conv_libfunc (sfix_optab, SImode, DFmode, "__c6xabi_fixdi");
343   set_conv_libfunc (ufix_optab, SImode, DFmode, "__c6xabi_fixdu");
344   set_conv_libfunc (sfix_optab, DImode, DFmode, "__c6xabi_fixdlli");
345   set_conv_libfunc (ufix_optab, DImode, DFmode, "__c6xabi_fixdull");
346   set_conv_libfunc (sfix_optab, SImode, SFmode, "__c6xabi_fixfi");
347   set_conv_libfunc (ufix_optab, SImode, SFmode, "__c6xabi_fixfu");
348   set_conv_libfunc (sfix_optab, DImode, SFmode, "__c6xabi_fixflli");
349   set_conv_libfunc (ufix_optab, DImode, SFmode, "__c6xabi_fixfull");
350 
351   /* Conversions between floating types.  */
352   set_conv_libfunc (trunc_optab, SFmode, DFmode, "__c6xabi_cvtdf");
353   set_conv_libfunc (sext_optab, DFmode, SFmode, "__c6xabi_cvtfd");
354 
355   /* Integer to floating-point conversions.  */
356   set_conv_libfunc (sfloat_optab, DFmode, SImode, "__c6xabi_fltid");
357   set_conv_libfunc (ufloat_optab, DFmode, SImode, "__c6xabi_fltud");
358   set_conv_libfunc (sfloat_optab, DFmode, DImode, "__c6xabi_fltllid");
359   set_conv_libfunc (ufloat_optab, DFmode, DImode, "__c6xabi_fltulld");
360   set_conv_libfunc (sfloat_optab, SFmode, SImode, "__c6xabi_fltif");
361   set_conv_libfunc (ufloat_optab, SFmode, SImode, "__c6xabi_fltuf");
362   set_conv_libfunc (sfloat_optab, SFmode, DImode, "__c6xabi_fltllif");
363   set_conv_libfunc (ufloat_optab, SFmode, DImode, "__c6xabi_fltullf");
364 
365   /* Long long.  */
366   set_optab_libfunc (smul_optab, DImode, "__c6xabi_mpyll");
367   set_optab_libfunc (ashl_optab, DImode, "__c6xabi_llshl");
368   set_optab_libfunc (lshr_optab, DImode, "__c6xabi_llshru");
369   set_optab_libfunc (ashr_optab, DImode, "__c6xabi_llshr");
370 
371   set_optab_libfunc (sdiv_optab, SImode, "__c6xabi_divi");
372   set_optab_libfunc (udiv_optab, SImode, "__c6xabi_divu");
373   set_optab_libfunc (smod_optab, SImode, "__c6xabi_remi");
374   set_optab_libfunc (umod_optab, SImode, "__c6xabi_remu");
375   set_optab_libfunc (sdivmod_optab, SImode, "__c6xabi_divremi");
376   set_optab_libfunc (udivmod_optab, SImode, "__c6xabi_divremu");
377   set_optab_libfunc (sdiv_optab, DImode, "__c6xabi_divlli");
378   set_optab_libfunc (udiv_optab, DImode, "__c6xabi_divull");
379   set_optab_libfunc (smod_optab, DImode, "__c6xabi_remlli");
380   set_optab_libfunc (umod_optab, DImode, "__c6xabi_remull");
381   set_optab_libfunc (udivmod_optab, DImode, "__c6xabi_divremull");
382 
383   /* Block move.  */
384   strasgi_libfunc = init_one_libfunc ("__c6xabi_strasgi");
385   strasgi64p_libfunc = init_one_libfunc ("__c6xabi_strasgi_64plus");
386 }
387 
388 /* Begin the assembly file.  */
389 
390 static void
391 c6x_file_start (void)
392 {
393   /* Variable tracking should be run after all optimizations which change order
394      of insns.  It also needs a valid CFG.  This can't be done in
395      c6x_override_options, because flag_var_tracking is finalized after
396      that.  */
397   c6x_flag_var_tracking = flag_var_tracking;
398   flag_var_tracking = 0;
399 
400   done_cfi_sections = false;
401   default_file_start ();
402 
403   /* Arrays are aligned to 8-byte boundaries.  */
404   asm_fprintf (asm_out_file,
405 	       "\t.c6xabi_attribute Tag_ABI_array_object_alignment, 0\n");
406   asm_fprintf (asm_out_file,
407 	       "\t.c6xabi_attribute Tag_ABI_array_object_align_expected, 0\n");
408 
409   /* Stack alignment is 8 bytes.  */
410   asm_fprintf (asm_out_file,
411 	       "\t.c6xabi_attribute Tag_ABI_stack_align_needed, 0\n");
412   asm_fprintf (asm_out_file,
413 	       "\t.c6xabi_attribute Tag_ABI_stack_align_preserved, 0\n");
414 
415 #if 0 /* FIXME: Reenable when TI's tools are fixed.  */
416   /* ??? Ideally we'd check flag_short_wchar somehow.  */
417   asm_fprintf (asm_out_file, "\t.c6xabi_attribute Tag_ABI_wchar_t, %d\n", 2);
418 #endif
419 
420   /* We conform to version 1.0 of the ABI.  */
421   asm_fprintf (asm_out_file,
422 	       "\t.c6xabi_attribute Tag_ABI_conformance, \"1.0\"\n");
423 
424 }
425 
426 /* The LTO frontend only enables exceptions when it sees a function that
427    uses it.  This changes the return value of dwarf2out_do_frame, so we
428    have to check before every function.  */
429 
430 void
431 c6x_output_file_unwind (FILE * f)
432 {
433   if (done_cfi_sections)
434     return;
435 
436   /* Output a .cfi_sections directive.  */
437   if (dwarf2out_do_frame ())
438     {
439       if (flag_unwind_tables || flag_exceptions)
440 	{
441 	  if (write_symbols == DWARF2_DEBUG
442 	      || write_symbols == VMS_AND_DWARF2_DEBUG)
443 	    asm_fprintf (f, "\t.cfi_sections .debug_frame, .c6xabi.exidx\n");
444 	  else
445 	    asm_fprintf (f, "\t.cfi_sections .c6xabi.exidx\n");
446 	}
447       else
448 	asm_fprintf (f, "\t.cfi_sections .debug_frame\n");
449       done_cfi_sections = true;
450     }
451 }
452 
453 /* Output unwind directives at the end of a function.  */
454 
455 static void
456 c6x_output_fn_unwind (FILE * f)
457 {
458   /* Return immediately if we are not generating unwinding tables.  */
459   if (! (flag_unwind_tables || flag_exceptions))
460     return;
461 
462   /* If this function will never be unwound, then mark it as such.  */
463   if (!(flag_unwind_tables || crtl->uses_eh_lsda)
464       && (TREE_NOTHROW (current_function_decl)
465 	  || crtl->all_throwers_are_sibcalls))
466     fputs("\t.cantunwind\n", f);
467 
468   fputs ("\t.endp\n", f);
469 }
470 
471 
472 /* Stack and Calling.  */
473 
474 int argument_registers[10] =
475 {
476   REG_A4, REG_B4,
477   REG_A6, REG_B6,
478   REG_A8, REG_B8,
479   REG_A10, REG_B10,
480   REG_A12, REG_B12
481 };
482 
483 /* Implements the macro INIT_CUMULATIVE_ARGS defined in c6x.h.  */
484 
485 void
486 c6x_init_cumulative_args (CUMULATIVE_ARGS *cum, const_tree fntype, rtx libname,
487 			  int n_named_args ATTRIBUTE_UNUSED)
488 {
489   cum->count = 0;
490   cum->nregs = 10;
491   if (!libname && fntype)
492     {
493       /* We need to find out the number of named arguments.  Unfortunately,
494 	 for incoming arguments, N_NAMED_ARGS is set to -1.  */
495       if (stdarg_p (fntype))
496 	cum->nregs = type_num_arguments (fntype) - 1;
497       if (cum->nregs > 10)
498 	cum->nregs = 10;
499     }
500 }
501 
502 /* Implements the macro FUNCTION_ARG defined in c6x.h.  */
503 
504 static rtx
505 c6x_function_arg (cumulative_args_t cum_v, machine_mode mode,
506 		  const_tree type, bool named ATTRIBUTE_UNUSED)
507 {
508   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
509   if (cum->count >= cum->nregs)
510     return NULL_RTX;
511   if (type)
512     {
513       HOST_WIDE_INT size = int_size_in_bytes (type);
514       if (TARGET_BIG_ENDIAN && AGGREGATE_TYPE_P (type))
515 	{
516 	  if (size > 4)
517 	    {
518 	      rtx reg1 = gen_rtx_REG (SImode, argument_registers[cum->count] + 1);
519 	      rtx reg2 = gen_rtx_REG (SImode, argument_registers[cum->count]);
520 	      rtvec vec = gen_rtvec (2, gen_rtx_EXPR_LIST (VOIDmode, reg1, const0_rtx),
521 				     gen_rtx_EXPR_LIST (VOIDmode, reg2, GEN_INT (4)));
522 	      return gen_rtx_PARALLEL (mode, vec);
523 	    }
524 	}
525     }
526   return gen_rtx_REG (mode, argument_registers[cum->count]);
527 }
528 
529 static void
530 c6x_function_arg_advance (cumulative_args_t cum_v,
531 			  machine_mode mode ATTRIBUTE_UNUSED,
532 			  const_tree type ATTRIBUTE_UNUSED,
533 			  bool named ATTRIBUTE_UNUSED)
534 {
535   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
536   cum->count++;
537 }
538 
539 
540 /* Return true if BLOCK_REG_PADDING (MODE, TYPE, FIRST) should return
541    upward rather than downward.  */
542 
543 bool
544 c6x_block_reg_pad_upward (machine_mode mode ATTRIBUTE_UNUSED,
545 			  const_tree type, bool first)
546 {
547   HOST_WIDE_INT size;
548 
549   if (!TARGET_BIG_ENDIAN)
550     return true;
551   if (!first)
552     return true;
553   if (!type)
554     return true;
555   size = int_size_in_bytes (type);
556   return size == 3;
557 }
558 
559 /* Implement TARGET_FUNCTION_ARG_BOUNDARY.  */
560 
561 static unsigned int
562 c6x_function_arg_boundary (machine_mode mode, const_tree type)
563 {
564   unsigned int boundary = type ? TYPE_ALIGN (type) : GET_MODE_BITSIZE (mode);
565 
566   if (boundary > BITS_PER_WORD)
567     return 2 * BITS_PER_WORD;
568 
569   if (mode == BLKmode)
570     {
571       HOST_WIDE_INT size = int_size_in_bytes (type);
572       if (size > 4)
573 	return 2 * BITS_PER_WORD;
574       if (boundary < BITS_PER_WORD)
575 	{
576 	  if (size >= 3)
577 	    return BITS_PER_WORD;
578 	  if (size >= 2)
579 	    return 2 * BITS_PER_UNIT;
580 	}
581     }
582   return boundary;
583 }
584 
585 /* Implement TARGET_FUNCTION_ARG_ROUND_BOUNDARY.  */
586 static unsigned int
587 c6x_function_arg_round_boundary (machine_mode mode, const_tree type)
588 {
589   return c6x_function_arg_boundary (mode, type);
590 }
591 
592 /* TARGET_FUNCTION_VALUE implementation.  Returns an RTX representing the place
593    where function FUNC returns or receives a value of data type TYPE.  */
594 
595 static rtx
596 c6x_function_value (const_tree type, const_tree func ATTRIBUTE_UNUSED,
597 		    bool outgoing ATTRIBUTE_UNUSED)
598 {
599   /* Functions return values in register A4.  When returning aggregates, we may
600      have to adjust for endianness.  */
601   if (TARGET_BIG_ENDIAN && type && AGGREGATE_TYPE_P (type))
602     {
603       HOST_WIDE_INT size = int_size_in_bytes (type);
604       if (size > 4)
605 	{
606 
607 	  rtx reg1 = gen_rtx_REG (SImode, REG_A4 + 1);
608 	  rtx reg2 = gen_rtx_REG (SImode, REG_A4);
609 	  rtvec vec = gen_rtvec (2, gen_rtx_EXPR_LIST (VOIDmode, reg1, const0_rtx),
610 				 gen_rtx_EXPR_LIST (VOIDmode, reg2, GEN_INT (4)));
611 	  return gen_rtx_PARALLEL (TYPE_MODE (type), vec);
612 	}
613     }
614   return gen_rtx_REG (TYPE_MODE (type), REG_A4);
615 }
616 
617 /* Implement TARGET_LIBCALL_VALUE.  */
618 
619 static rtx
620 c6x_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
621 {
622   return gen_rtx_REG (mode, REG_A4);
623 }
624 
625 /* TARGET_STRUCT_VALUE_RTX implementation.  */
626 
627 static rtx
628 c6x_struct_value_rtx (tree type ATTRIBUTE_UNUSED, int incoming ATTRIBUTE_UNUSED)
629 {
630   return gen_rtx_REG (Pmode, REG_A3);
631 }
632 
633 /* Implement TARGET_FUNCTION_VALUE_REGNO_P.  */
634 
635 static bool
636 c6x_function_value_regno_p (const unsigned int regno)
637 {
638   return regno == REG_A4;
639 }
640 
641 /* Types larger than 64 bit, and variable sized types, are passed by
642    reference.  The callee must copy them; see c6x_callee_copies.  */
643 
644 static bool
645 c6x_pass_by_reference (cumulative_args_t cum_v ATTRIBUTE_UNUSED,
646 		       machine_mode mode, const_tree type,
647 		       bool named ATTRIBUTE_UNUSED)
648 {
649   int size = -1;
650   if (type)
651     size = int_size_in_bytes (type);
652   else if (mode != VOIDmode)
653     size = GET_MODE_SIZE (mode);
654   return size > 2 * UNITS_PER_WORD || size == -1;
655 }
656 
657 /* Decide whether a type should be returned in memory (true)
658    or in a register (false).  This is called by the macro
659    TARGET_RETURN_IN_MEMORY.  */
660 
661 static bool
662 c6x_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
663 {
664   int size = int_size_in_bytes (type);
665   return size > 2 * UNITS_PER_WORD || size == -1;
666 }
667 
668 /* Values which must be returned in the most-significant end of the return
669    register.  */
670 
671 static bool
672 c6x_return_in_msb (const_tree valtype)
673 {
674   HOST_WIDE_INT size = int_size_in_bytes (valtype);
675   return TARGET_BIG_ENDIAN && AGGREGATE_TYPE_P (valtype) && size == 3;
676 }
677 
678 /* Implement TARGET_CALLEE_COPIES.  */
679 
680 static bool
681 c6x_callee_copies (cumulative_args_t cum_v ATTRIBUTE_UNUSED,
682 		   machine_mode mode ATTRIBUTE_UNUSED,
683 		   const_tree type ATTRIBUTE_UNUSED,
684 		   bool named ATTRIBUTE_UNUSED)
685 {
686   return true;
687 }
688 
689 /* Return the type to use as __builtin_va_list.  */
690 static tree
691 c6x_build_builtin_va_list (void)
692 {
693   return build_pointer_type (char_type_node);
694 }
695 
696 static void
697 c6x_asm_trampoline_template (FILE *f)
698 {
699   fprintf (f, "\t.long\t0x0000002b\n"); /* mvkl .s2 fnlow,B0 */
700   fprintf (f, "\t.long\t0x01000028\n"); /* || mvkl .s1 sclow,A2 */
701   fprintf (f, "\t.long\t0x0000006b\n"); /* mvkh .s2 fnhigh,B0 */
702   fprintf (f, "\t.long\t0x01000068\n"); /* || mvkh .s1 schigh,A2 */
703   fprintf (f, "\t.long\t0x00000362\n"); /* b .s2 B0 */
704   fprintf (f, "\t.long\t0x00008000\n"); /* nop 5 */
705   fprintf (f, "\t.long\t0x00000000\n"); /* nop */
706   fprintf (f, "\t.long\t0x00000000\n"); /* nop */
707 }
708 
709 /* Emit RTL insns to initialize the variable parts of a trampoline at
710    TRAMP. FNADDR is an RTX for the address of the function's pure
711    code.  CXT is an RTX for the static chain value for the function.  */
712 
713 static void
714 c6x_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
715 {
716   rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
717   rtx t1 = copy_to_reg (fnaddr);
718   rtx t2 = copy_to_reg (cxt);
719   rtx mask = gen_reg_rtx (SImode);
720   int i;
721 
722   emit_block_move (tramp, assemble_trampoline_template (),
723 		   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
724 
725   emit_move_insn (mask, GEN_INT (0xffff << 7));
726 
727   for (i = 0; i < 4; i++)
728     {
729       rtx mem = adjust_address (tramp, SImode, i * 4);
730       rtx t = (i & 1) ? t2 : t1;
731       rtx v1 = gen_reg_rtx (SImode);
732       rtx v2 = gen_reg_rtx (SImode);
733       emit_move_insn (v1, mem);
734       if (i < 2)
735 	emit_insn (gen_ashlsi3 (v2, t, GEN_INT (7)));
736       else
737 	emit_insn (gen_lshrsi3 (v2, t, GEN_INT (9)));
738       emit_insn (gen_andsi3 (v2, v2, mask));
739       emit_insn (gen_iorsi3 (v2, v2, v1));
740       emit_move_insn (mem, v2);
741     }
742 #ifdef CLEAR_INSN_CACHE
743   tramp = XEXP (tramp, 0);
744   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__gnu_clear_cache"),
745 		     LCT_NORMAL, VOIDmode, tramp, Pmode,
746 		     plus_constant (Pmode, tramp, TRAMPOLINE_SIZE), Pmode);
747 #endif
748 }
749 
750 /* Determine whether c6x_output_mi_thunk can succeed.  */
751 
752 static bool
753 c6x_can_output_mi_thunk (const_tree thunk ATTRIBUTE_UNUSED,
754 			 HOST_WIDE_INT delta ATTRIBUTE_UNUSED,
755 			 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
756 			 const_tree function ATTRIBUTE_UNUSED)
757 {
758   return !TARGET_LONG_CALLS;
759 }
760 
761 /* Output the assembler code for a thunk function.  THUNK is the
762    declaration for the thunk function itself, FUNCTION is the decl for
763    the target function.  DELTA is an immediate constant offset to be
764    added to THIS.  If VCALL_OFFSET is nonzero, the word at
765    *(*this + vcall_offset) should be added to THIS.  */
766 
767 static void
768 c6x_output_mi_thunk (FILE *file ATTRIBUTE_UNUSED,
769 		     tree thunk ATTRIBUTE_UNUSED, HOST_WIDE_INT delta,
770 		     HOST_WIDE_INT vcall_offset, tree function)
771 {
772   rtx xops[5];
773   /* The this parameter is passed as the first argument.  */
774   rtx this_rtx = gen_rtx_REG (Pmode, REG_A4);
775 
776   c6x_current_insn = NULL;
777 
778   xops[4] = XEXP (DECL_RTL (function), 0);
779   if (!vcall_offset)
780     {
781       output_asm_insn ("b .s2 \t%4", xops);
782       if (!delta)
783 	output_asm_insn ("nop 5", xops);
784     }
785 
786   /* Adjust the this parameter by a fixed constant.  */
787   if (delta)
788     {
789       xops[0] = GEN_INT (delta);
790       xops[1] = this_rtx;
791       if (delta >= -16 && delta <= 15)
792 	{
793 	  output_asm_insn ("add .s1 %0, %1, %1", xops);
794 	  if (!vcall_offset)
795 	    output_asm_insn ("nop 4", xops);
796 	}
797       else if (delta >= 16 && delta < 32)
798 	{
799 	  output_asm_insn ("add .d1 %0, %1, %1", xops);
800 	  if (!vcall_offset)
801 	    output_asm_insn ("nop 4", xops);
802 	}
803       else if (delta >= -32768 && delta < 32768)
804 	{
805 	  output_asm_insn ("mvk .s1 %0, A0", xops);
806 	  output_asm_insn ("add .d1 %1, A0, %1", xops);
807 	  if (!vcall_offset)
808 	    output_asm_insn ("nop 3", xops);
809 	}
810       else
811 	{
812 	  output_asm_insn ("mvkl .s1 %0, A0", xops);
813 	  output_asm_insn ("mvkh .s1 %0, A0", xops);
814 	  output_asm_insn ("add .d1 %1, A0, %1", xops);
815 	  if (!vcall_offset)
816 	    output_asm_insn ("nop 3", xops);
817 	}
818     }
819 
820   /* Adjust the this parameter by a value stored in the vtable.  */
821   if (vcall_offset)
822     {
823       rtx a0tmp = gen_rtx_REG (Pmode, REG_A0);
824       rtx a3tmp = gen_rtx_REG (Pmode, REG_A3);
825 
826       xops[1] = a3tmp;
827       xops[2] = a0tmp;
828       xops[3] = gen_rtx_MEM (Pmode, a0tmp);
829       output_asm_insn ("mv .s1 a4, %2", xops);
830       output_asm_insn ("ldw .d1t1 %3, %2", xops);
831 
832       /* Adjust the this parameter.  */
833       xops[0] = gen_rtx_MEM (Pmode, plus_constant (Pmode, a0tmp,
834 						   vcall_offset));
835       if (!memory_operand (xops[0], Pmode))
836 	{
837 	  rtx tmp2 = gen_rtx_REG (Pmode, REG_A1);
838 	  xops[0] = GEN_INT (vcall_offset);
839 	  xops[1] = tmp2;
840 	  output_asm_insn ("mvkl .s1 %0, %1", xops);
841 	  output_asm_insn ("mvkh .s1 %0, %1", xops);
842 	  output_asm_insn ("nop 2", xops);
843 	  output_asm_insn ("add .d1 %2, %1, %2", xops);
844 	  xops[0] = gen_rtx_MEM (Pmode, a0tmp);
845 	}
846       else
847 	output_asm_insn ("nop 4", xops);
848       xops[2] = this_rtx;
849       output_asm_insn ("ldw .d1t1 %0, %1", xops);
850       output_asm_insn ("|| b .s2 \t%4", xops);
851       output_asm_insn ("nop 4", xops);
852       output_asm_insn ("add .d1 %2, %1, %2", xops);
853     }
854 }
855 
856 /* Return true if EXP goes in small data/bss.  */
857 
858 static bool
859 c6x_in_small_data_p (const_tree exp)
860 {
861   /* We want to merge strings, so we never consider them small data.  */
862   if (TREE_CODE (exp) == STRING_CST)
863     return false;
864 
865   /* Functions are never small data.  */
866   if (TREE_CODE (exp) == FUNCTION_DECL)
867     return false;
868 
869   if (TREE_CODE (exp) == VAR_DECL && DECL_WEAK (exp))
870     return false;
871 
872   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
873     {
874       const char *section = DECL_SECTION_NAME (exp);
875 
876       if (strcmp (section, ".neardata") == 0
877 	  || strncmp (section, ".neardata.", 10) == 0
878 	  || strncmp (section, ".gnu.linkonce.s.", 16) == 0
879 	  || strcmp (section, ".bss") == 0
880 	  || strncmp (section, ".bss.", 5) == 0
881 	  || strncmp (section, ".gnu.linkonce.sb.", 17) == 0
882 	  || strcmp (section, ".rodata") == 0
883 	  || strncmp (section, ".rodata.", 8) == 0
884 	  || strncmp (section, ".gnu.linkonce.s2.", 17) == 0)
885 	return true;
886     }
887   else
888     return PLACE_IN_SDATA_P (exp);
889 
890   return false;
891 }
892 
893 /* Return a section for X.  The only special thing we do here is to
894    honor small data.  We don't have a tree type, so we can't use the
895    PLACE_IN_SDATA_P macro we use everywhere else; we choose to place
896    everything sized 8 bytes or smaller into small data.  */
897 
898 static section *
899 c6x_select_rtx_section (machine_mode mode, rtx x,
900 			unsigned HOST_WIDE_INT align)
901 {
902   if (c6x_sdata_mode == C6X_SDATA_ALL
903       || (c6x_sdata_mode != C6X_SDATA_NONE && GET_MODE_SIZE (mode) <= 8))
904     /* ??? Consider using mergeable sdata sections.  */
905     return sdata_section;
906   else
907     return default_elf_select_rtx_section (mode, x, align);
908 }
909 
910 static section *
911 c6x_elf_select_section (tree decl, int reloc,
912 			unsigned HOST_WIDE_INT align)
913 {
914   const char *sname = NULL;
915   unsigned int flags = SECTION_WRITE;
916   if (c6x_in_small_data_p (decl))
917     {
918       switch (categorize_decl_for_section (decl, reloc))
919 	{
920 	case SECCAT_SRODATA:
921 	  sname = ".rodata";
922 	  flags = 0;
923 	  break;
924 	case SECCAT_SDATA:
925 	  sname = ".neardata";
926 	  break;
927 	case SECCAT_SBSS:
928 	  sname = ".bss";
929 	  flags |= SECTION_BSS;
930 	default:
931 	  break;
932 	}
933     }
934   else
935     {
936       switch (categorize_decl_for_section (decl, reloc))
937 	{
938 	case SECCAT_DATA:
939 	  sname = ".fardata";
940 	  break;
941 	case SECCAT_DATA_REL:
942 	  sname = ".fardata.rel";
943 	  break;
944 	case SECCAT_DATA_REL_LOCAL:
945 	  sname = ".fardata.rel.local";
946 	  break;
947 	case SECCAT_DATA_REL_RO:
948 	  sname = ".fardata.rel.ro";
949 	  break;
950 	case SECCAT_DATA_REL_RO_LOCAL:
951 	  sname = ".fardata.rel.ro.local";
952 	  break;
953 	case SECCAT_BSS:
954 	  sname = ".far";
955 	  flags |= SECTION_BSS;
956 	  break;
957 	case SECCAT_RODATA:
958 	  sname = ".const";
959 	  flags = 0;
960 	  break;
961 	case SECCAT_SRODATA:
962 	case SECCAT_SDATA:
963 	case SECCAT_SBSS:
964 	  gcc_unreachable ();
965 	default:
966 	  break;
967 	}
968     }
969   if (sname)
970     {
971       /* We might get called with string constants, but get_named_section
972 	 doesn't like them as they are not DECLs.  Also, we need to set
973 	 flags in that case.  */
974       if (!DECL_P (decl))
975 	return get_section (sname, flags, NULL);
976       return get_named_section (decl, sname, reloc);
977     }
978 
979   return default_elf_select_section (decl, reloc, align);
980 }
981 
982 /* Build up a unique section name, expressed as a
983    STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
984    RELOC indicates whether the initial value of EXP requires
985    link-time relocations.  */
986 
987 static void ATTRIBUTE_UNUSED
988 c6x_elf_unique_section (tree decl, int reloc)
989 {
990   const char *prefix = NULL;
991   /* We only need to use .gnu.linkonce if we don't have COMDAT groups.  */
992   bool one_only = DECL_COMDAT_GROUP (decl) && !HAVE_COMDAT_GROUP;
993 
994   if (c6x_in_small_data_p (decl))
995     {
996       switch (categorize_decl_for_section (decl, reloc))
997 	{
998 	case SECCAT_SDATA:
999           prefix = one_only ? ".s" : ".neardata";
1000 	  break;
1001 	case SECCAT_SBSS:
1002           prefix = one_only ? ".sb" : ".bss";
1003 	  break;
1004 	case SECCAT_SRODATA:
1005           prefix = one_only ? ".s2" : ".rodata";
1006 	  break;
1007 	case SECCAT_RODATA_MERGE_STR:
1008 	case SECCAT_RODATA_MERGE_STR_INIT:
1009 	case SECCAT_RODATA_MERGE_CONST:
1010 	case SECCAT_RODATA:
1011 	case SECCAT_DATA:
1012 	case SECCAT_DATA_REL:
1013 	case SECCAT_DATA_REL_LOCAL:
1014 	case SECCAT_DATA_REL_RO:
1015 	case SECCAT_DATA_REL_RO_LOCAL:
1016 	  gcc_unreachable ();
1017 	default:
1018 	  /* Everything else we place into default sections and hope for the
1019 	     best.  */
1020 	  break;
1021 	}
1022     }
1023   else
1024     {
1025       switch (categorize_decl_for_section (decl, reloc))
1026 	{
1027 	case SECCAT_DATA:
1028 	case SECCAT_DATA_REL:
1029 	case SECCAT_DATA_REL_LOCAL:
1030 	case SECCAT_DATA_REL_RO:
1031 	case SECCAT_DATA_REL_RO_LOCAL:
1032           prefix = one_only ? ".fd" : ".fardata";
1033 	  break;
1034 	case SECCAT_BSS:
1035           prefix = one_only ? ".fb" : ".far";
1036 	  break;
1037 	case SECCAT_RODATA:
1038 	case SECCAT_RODATA_MERGE_STR:
1039 	case SECCAT_RODATA_MERGE_STR_INIT:
1040 	case SECCAT_RODATA_MERGE_CONST:
1041           prefix = one_only ? ".fr" : ".const";
1042 	  break;
1043 	case SECCAT_SRODATA:
1044 	case SECCAT_SDATA:
1045 	case SECCAT_SBSS:
1046 	  gcc_unreachable ();
1047 	default:
1048 	  break;
1049 	}
1050     }
1051 
1052   if (prefix)
1053     {
1054       const char *name, *linkonce;
1055       char *string;
1056 
1057       name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
1058       name = targetm.strip_name_encoding (name);
1059 
1060       /* If we're using one_only, then there needs to be a .gnu.linkonce
1061 	 prefix to the section name.  */
1062       linkonce = one_only ? ".gnu.linkonce" : "";
1063 
1064       string = ACONCAT ((linkonce, prefix, ".", name, NULL));
1065 
1066       set_decl_section_name (decl, string);
1067       return;
1068     }
1069   default_unique_section (decl, reloc);
1070 }
1071 
1072 static unsigned int
1073 c6x_section_type_flags (tree decl, const char *name, int reloc)
1074 {
1075   unsigned int flags = 0;
1076 
1077   if (strcmp (name, ".far") == 0
1078       || strncmp (name, ".far.", 5) == 0)
1079     flags |= SECTION_BSS;
1080 
1081   flags |= default_section_type_flags (decl, name, reloc);
1082 
1083   return flags;
1084 }
1085 
1086 /* Checks whether the given CALL_EXPR would use a caller saved
1087    register.  This is used to decide whether sibling call optimization
1088    could be performed on the respective function call.  */
1089 
1090 static bool
1091 c6x_call_saved_register_used (tree call_expr)
1092 {
1093   CUMULATIVE_ARGS cum_v;
1094   cumulative_args_t cum;
1095   HARD_REG_SET call_saved_regset;
1096   tree parameter;
1097   machine_mode mode;
1098   tree type;
1099   rtx parm_rtx;
1100   int i;
1101 
1102   INIT_CUMULATIVE_ARGS (cum_v, NULL, NULL, 0, 0);
1103   cum = pack_cumulative_args (&cum_v);
1104 
1105   COMPL_HARD_REG_SET (call_saved_regset, call_used_reg_set);
1106   for (i = 0; i < call_expr_nargs (call_expr); i++)
1107     {
1108       parameter = CALL_EXPR_ARG (call_expr, i);
1109       gcc_assert (parameter);
1110 
1111       /* For an undeclared variable passed as parameter we will get
1112 	 an ERROR_MARK node here.  */
1113       if (TREE_CODE (parameter) == ERROR_MARK)
1114 	return true;
1115 
1116       type = TREE_TYPE (parameter);
1117       gcc_assert (type);
1118 
1119       mode = TYPE_MODE (type);
1120       gcc_assert (mode);
1121 
1122       if (pass_by_reference (&cum_v, mode, type, true))
1123  	{
1124  	  mode = Pmode;
1125  	  type = build_pointer_type (type);
1126  	}
1127 
1128        parm_rtx = c6x_function_arg (cum, mode, type, 0);
1129 
1130        c6x_function_arg_advance (cum, mode, type, 0);
1131 
1132        if (!parm_rtx)
1133 	 continue;
1134 
1135        if (REG_P (parm_rtx)
1136 	   && overlaps_hard_reg_set_p (call_saved_regset, GET_MODE (parm_rtx),
1137 				       REGNO (parm_rtx)))
1138 	 return true;
1139        if (GET_CODE (parm_rtx) == PARALLEL)
1140 	 {
1141 	   int n = XVECLEN (parm_rtx, 0);
1142 	   while (n-- > 0)
1143 	     {
1144 	       rtx x = XEXP (XVECEXP (parm_rtx, 0, n), 0);
1145 	       if (REG_P (x)
1146 		   && overlaps_hard_reg_set_p (call_saved_regset,
1147 					       GET_MODE (x), REGNO (x)))
1148 		 return true;
1149 	     }
1150 	 }
1151     }
1152   return false;
1153 }
1154 
1155 /* Decide whether we can make a sibling call to a function.  DECL is the
1156    declaration of the function being targeted by the call and EXP is the
1157    CALL_EXPR representing the call.  */
1158 
1159 static bool
1160 c6x_function_ok_for_sibcall (tree decl, tree exp)
1161 {
1162   /* Registers A10, A12, B10 and B12 are available as arguments
1163      register but unfortunately caller saved. This makes functions
1164      needing these registers for arguments not suitable for
1165      sibcalls.  */
1166   if (c6x_call_saved_register_used (exp))
1167     return false;
1168 
1169   if (!flag_pic)
1170     return true;
1171 
1172   if (TARGET_DSBT)
1173     {
1174       /* When compiling for DSBT, the calling function must be local,
1175 	 so that when we reload B14 in the sibcall epilogue, it will
1176 	 not change its value.  */
1177       struct cgraph_local_info *this_func;
1178 
1179       if (!decl)
1180 	/* Not enough information.  */
1181 	return false;
1182 
1183       this_func = cgraph_node::local_info (current_function_decl);
1184       return this_func->local;
1185     }
1186 
1187   return true;
1188 }
1189 
1190 /* Return true if DECL is known to be linked into section SECTION.  */
1191 
1192 static bool
1193 c6x_function_in_section_p (tree decl, section *section)
1194 {
1195   /* We can only be certain about functions defined in the same
1196      compilation unit.  */
1197   if (!TREE_STATIC (decl))
1198     return false;
1199 
1200   /* Make sure that SYMBOL always binds to the definition in this
1201      compilation unit.  */
1202   if (!targetm.binds_local_p (decl))
1203     return false;
1204 
1205   /* If DECL_SECTION_NAME is set, assume it is trustworthy.  */
1206   if (!DECL_SECTION_NAME (decl))
1207     {
1208       /* Make sure that we will not create a unique section for DECL.  */
1209       if (flag_function_sections || DECL_COMDAT_GROUP (decl))
1210 	return false;
1211     }
1212 
1213   return function_section (decl) == section;
1214 }
1215 
1216 /* Return true if a call to OP, which is a SYMBOL_REF, must be expanded
1217    as a long call.  */
1218 bool
1219 c6x_long_call_p (rtx op)
1220 {
1221   tree decl;
1222 
1223   if (!TARGET_LONG_CALLS)
1224     return false;
1225 
1226   decl = SYMBOL_REF_DECL (op);
1227 
1228   /* Try to determine whether the symbol is in the same section as the current
1229      function.  Be conservative, and only cater for cases in which the
1230      whole of the current function is placed in the same section.  */
1231   if (decl != NULL_TREE
1232       && !flag_reorder_blocks_and_partition
1233       && TREE_CODE (decl) == FUNCTION_DECL
1234       && c6x_function_in_section_p (decl, current_function_section ()))
1235     return false;
1236 
1237   return true;
1238 }
1239 
1240 /* Emit the sequence for a call.  */
1241 void
1242 c6x_expand_call (rtx retval, rtx address, bool sibcall)
1243 {
1244   rtx callee = XEXP (address, 0);
1245   rtx call_insn;
1246 
1247   if (!c6x_call_operand (callee, Pmode))
1248     {
1249       callee = force_reg (Pmode, callee);
1250       address = change_address (address, Pmode, callee);
1251     }
1252   call_insn = gen_rtx_CALL (VOIDmode, address, const0_rtx);
1253   if (sibcall)
1254     {
1255       call_insn = emit_call_insn (call_insn);
1256       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
1257 	       gen_rtx_REG (Pmode, REG_B3));
1258     }
1259   else
1260     {
1261       if (retval == NULL_RTX)
1262 	call_insn = emit_call_insn (call_insn);
1263       else
1264 	call_insn = emit_call_insn (gen_rtx_SET (retval, call_insn));
1265     }
1266   if (flag_pic)
1267     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
1268 }
1269 
1270 /* Legitimize PIC addresses.  If the address is already position-independent,
1271    we return ORIG.  Newly generated position-independent addresses go into a
1272    reg.  This is REG if nonzero, otherwise we allocate register(s) as
1273    necessary.  PICREG is the register holding the pointer to the PIC offset
1274    table.  */
1275 
1276 static rtx
1277 legitimize_pic_address (rtx orig, rtx reg, rtx picreg)
1278 {
1279   rtx addr = orig;
1280   rtx new_rtx = orig;
1281 
1282   if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
1283     {
1284       int unspec = UNSPEC_LOAD_GOT;
1285       rtx tmp;
1286 
1287       if (reg == 0)
1288 	{
1289 	  gcc_assert (can_create_pseudo_p ());
1290 	  reg = gen_reg_rtx (Pmode);
1291 	}
1292       if (flag_pic == 2)
1293 	{
1294 	  if (can_create_pseudo_p ())
1295 	    tmp = gen_reg_rtx (Pmode);
1296 	  else
1297 	    tmp = reg;
1298 	  emit_insn (gen_movsi_gotoff_high (tmp, addr));
1299 	  emit_insn (gen_movsi_gotoff_lo_sum (tmp, tmp, addr));
1300 	  emit_insn (gen_load_got_gotoff (reg, picreg, tmp));
1301 	}
1302       else
1303 	{
1304 	  tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), unspec);
1305 	  new_rtx = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, picreg, tmp));
1306 
1307 	  emit_move_insn (reg, new_rtx);
1308 	}
1309       if (picreg == pic_offset_table_rtx)
1310 	crtl->uses_pic_offset_table = 1;
1311       return reg;
1312     }
1313 
1314   else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
1315     {
1316       rtx base;
1317 
1318       if (GET_CODE (addr) == CONST)
1319 	{
1320 	  addr = XEXP (addr, 0);
1321 	  gcc_assert (GET_CODE (addr) == PLUS);
1322 	}
1323 
1324       if (XEXP (addr, 0) == picreg)
1325 	return orig;
1326 
1327       if (reg == 0)
1328 	{
1329 	  gcc_assert (can_create_pseudo_p ());
1330 	  reg = gen_reg_rtx (Pmode);
1331 	}
1332 
1333       base = legitimize_pic_address (XEXP (addr, 0), reg, picreg);
1334       addr = legitimize_pic_address (XEXP (addr, 1),
1335 				     base == reg ? NULL_RTX : reg,
1336 				     picreg);
1337 
1338       if (GET_CODE (addr) == CONST_INT)
1339 	{
1340 	  gcc_assert (! reload_in_progress && ! reload_completed);
1341 	  addr = force_reg (Pmode, addr);
1342 	}
1343 
1344       if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
1345 	{
1346 	  base = gen_rtx_PLUS (Pmode, base, XEXP (addr, 0));
1347 	  addr = XEXP (addr, 1);
1348 	}
1349 
1350       return gen_rtx_PLUS (Pmode, base, addr);
1351     }
1352 
1353   return new_rtx;
1354 }
1355 
1356 /* Expand a move operation in mode MODE.  The operands are in OPERANDS.
1357    Returns true if no further code must be generated, false if the caller
1358    should generate an insn to move OPERANDS[1] to OPERANDS[0].  */
1359 
1360 bool
1361 expand_move (rtx *operands, machine_mode mode)
1362 {
1363   rtx dest = operands[0];
1364   rtx op = operands[1];
1365 
1366   if ((reload_in_progress | reload_completed) == 0
1367       && GET_CODE (dest) == MEM && GET_CODE (op) != REG)
1368     operands[1] = force_reg (mode, op);
1369   else if (mode == SImode && symbolic_operand (op, SImode))
1370     {
1371       if (flag_pic)
1372 	{
1373 	  if (sdata_symbolic_operand (op, SImode))
1374 	    {
1375 	      emit_insn (gen_load_sdata_pic (dest, pic_offset_table_rtx, op));
1376 	      crtl->uses_pic_offset_table = 1;
1377 	      return true;
1378 	    }
1379 	  else
1380 	    {
1381 	      rtx temp = (reload_completed || reload_in_progress
1382 			  ? dest : gen_reg_rtx (Pmode));
1383 
1384 	      operands[1] = legitimize_pic_address (op, temp,
1385 						    pic_offset_table_rtx);
1386 	    }
1387 	}
1388       else if (reload_completed
1389 	       && !sdata_symbolic_operand (op, SImode))
1390 	{
1391 	  emit_insn (gen_movsi_high (dest, op));
1392 	  emit_insn (gen_movsi_lo_sum (dest, dest, op));
1393 	  return true;
1394 	}
1395     }
1396   return false;
1397 }
1398 
1399 /* This function is called when we're about to expand an integer compare
1400    operation which performs COMPARISON.  It examines the second operand,
1401    and if it is an integer constant that cannot be used directly on the
1402    current machine in a comparison insn, it returns true.  */
1403 bool
1404 c6x_force_op_for_comparison_p (enum rtx_code code, rtx op)
1405 {
1406   if (!CONST_INT_P (op) || satisfies_constraint_Iu4 (op))
1407     return false;
1408 
1409   if ((code == EQ || code == LT || code == GT)
1410        && !satisfies_constraint_Is5 (op))
1411     return true;
1412   if ((code == GTU || code == LTU)
1413       && (!TARGET_INSNS_64 || !satisfies_constraint_Iu5 (op)))
1414     return true;
1415 
1416   return false;
1417 }
1418 
1419 /* Emit comparison instruction if necessary, returning the expression
1420    that holds the compare result in the proper mode.  Return the comparison
1421    that should be used in the jump insn.  */
1422 
1423 rtx
1424 c6x_expand_compare (rtx comparison, machine_mode mode)
1425 {
1426   enum rtx_code code = GET_CODE (comparison);
1427   rtx op0 = XEXP (comparison, 0);
1428   rtx op1 = XEXP (comparison, 1);
1429   rtx cmp;
1430   enum rtx_code jump_code = code;
1431   machine_mode op_mode = GET_MODE (op0);
1432 
1433   if (op_mode == DImode && (code == NE || code == EQ) && op1 == const0_rtx)
1434     {
1435       rtx t = gen_reg_rtx (SImode);
1436       emit_insn (gen_iorsi3 (t, gen_lowpart (SImode, op0),
1437 			     gen_highpart (SImode, op0)));
1438       op_mode = SImode;
1439       cmp = t;
1440     }
1441   else if (op_mode == DImode)
1442     {
1443       rtx lo[2], high[2];
1444       rtx cmp1, cmp2;
1445 
1446       if (code == NE || code == GEU || code == LEU || code == GE || code == LE)
1447 	{
1448 	  code = reverse_condition (code);
1449 	  jump_code = EQ;
1450 	}
1451       else
1452 	jump_code = NE;
1453 
1454       split_di (&op0, 1, lo, high);
1455       split_di (&op1, 1, lo + 1, high + 1);
1456 
1457       if (c6x_force_op_for_comparison_p (code, high[1])
1458 	  || c6x_force_op_for_comparison_p (EQ, high[1]))
1459 	high[1] = force_reg (SImode, high[1]);
1460 
1461       cmp1 = gen_reg_rtx (SImode);
1462       cmp2 = gen_reg_rtx (SImode);
1463       emit_insn (gen_rtx_SET (cmp1, gen_rtx_fmt_ee (code, SImode,
1464 						    high[0], high[1])));
1465       if (code == EQ)
1466 	{
1467 	  if (c6x_force_op_for_comparison_p (code, lo[1]))
1468 	    lo[1] = force_reg (SImode, lo[1]);
1469 	  emit_insn (gen_rtx_SET (cmp2, gen_rtx_fmt_ee (code, SImode,
1470 							lo[0], lo[1])));
1471 	  emit_insn (gen_andsi3 (cmp1, cmp1, cmp2));
1472 	}
1473       else
1474 	{
1475 	  emit_insn (gen_rtx_SET (cmp2, gen_rtx_EQ (SImode, high[0],
1476 						    high[1])));
1477 	  if (code == GT)
1478 	    code = GTU;
1479 	  else if (code == LT)
1480 	    code = LTU;
1481 	  if (c6x_force_op_for_comparison_p (code, lo[1]))
1482 	    lo[1] = force_reg (SImode, lo[1]);
1483 	  emit_insn (gen_cmpsi_and (cmp2, gen_rtx_fmt_ee (code, SImode,
1484 							  lo[0], lo[1]),
1485 				    lo[0], lo[1], cmp2));
1486 	  emit_insn (gen_iorsi3 (cmp1, cmp1, cmp2));
1487 	}
1488       cmp = cmp1;
1489     }
1490   else if (TARGET_FP && !flag_finite_math_only
1491 	   && (op_mode == DFmode || op_mode == SFmode)
1492 	   && code != EQ && code != NE && code != LT && code != GT
1493 	   && code != UNLE && code != UNGE)
1494     {
1495       enum rtx_code code1, code2, code3;
1496       rtx (*fn) (rtx, rtx, rtx, rtx, rtx);
1497 
1498       jump_code = NE;
1499       code3 = UNKNOWN;
1500       switch (code)
1501 	{
1502 	case UNLT:
1503 	case UNGT:
1504 	  jump_code = EQ;
1505 	  /* fall through */
1506 	case LE:
1507 	case GE:
1508 	  code1 = code == LE || code == UNGT ? LT : GT;
1509 	  code2 = EQ;
1510 	  break;
1511 
1512 	case UNORDERED:
1513 	  jump_code = EQ;
1514 	  /* fall through */
1515 	case ORDERED:
1516 	  code3 = EQ;
1517 	  /* fall through */
1518 	case LTGT:
1519 	  code1 = LT;
1520 	  code2 = GT;
1521 	  break;
1522 
1523 	case UNEQ:
1524 	  code1 = LT;
1525 	  code2 = GT;
1526 	  jump_code = EQ;
1527 	  break;
1528 
1529 	default:
1530 	  gcc_unreachable ();
1531 	}
1532 
1533       cmp = gen_reg_rtx (SImode);
1534       emit_insn (gen_rtx_SET (cmp, gen_rtx_fmt_ee (code1, SImode, op0, op1)));
1535       fn = op_mode == DFmode ? gen_cmpdf_ior : gen_cmpsf_ior;
1536       emit_insn (fn (cmp, gen_rtx_fmt_ee (code2, SImode, op0, op1),
1537 		     op0, op1, cmp));
1538       if (code3 != UNKNOWN)
1539 	emit_insn (fn (cmp, gen_rtx_fmt_ee (code3, SImode, op0, op1),
1540 		       op0, op1, cmp));
1541     }
1542   else if (op_mode == SImode && (code == NE || code == EQ) && op1 == const0_rtx)
1543     cmp = op0;
1544   else
1545     {
1546       bool is_fp_libfunc;
1547       is_fp_libfunc = !TARGET_FP && (op_mode == DFmode || op_mode == SFmode);
1548 
1549       if ((code == NE || code == GEU || code == LEU || code == GE || code == LE)
1550 	  && !is_fp_libfunc)
1551 	{
1552 	  code = reverse_condition (code);
1553 	  jump_code = EQ;
1554 	}
1555       else if (code == UNGE)
1556 	{
1557 	  code = LT;
1558 	  jump_code = EQ;
1559 	}
1560       else if (code == UNLE)
1561 	{
1562 	  code = GT;
1563 	  jump_code = EQ;
1564 	}
1565       else
1566 	jump_code = NE;
1567 
1568       if (is_fp_libfunc)
1569 	{
1570 	  rtx_insn *insns;
1571 	  rtx libfunc;
1572 	  switch (code)
1573 	    {
1574 	    case EQ:
1575 	      libfunc = op_mode == DFmode ? eqdf_libfunc : eqsf_libfunc;
1576 	      break;
1577 	    case NE:
1578 	      libfunc = op_mode == DFmode ? nedf_libfunc : nesf_libfunc;
1579 	      break;
1580 	    case GT:
1581 	      libfunc = op_mode == DFmode ? gtdf_libfunc : gtsf_libfunc;
1582 	      break;
1583 	    case GE:
1584 	      libfunc = op_mode == DFmode ? gedf_libfunc : gesf_libfunc;
1585 	      break;
1586 	    case LT:
1587 	      libfunc = op_mode == DFmode ? ltdf_libfunc : ltsf_libfunc;
1588 	      break;
1589 	    case LE:
1590 	      libfunc = op_mode == DFmode ? ledf_libfunc : lesf_libfunc;
1591 	      break;
1592 	    default:
1593 	      gcc_unreachable ();
1594 	    }
1595 	  start_sequence ();
1596 
1597 	  cmp = emit_library_call_value (libfunc, 0, LCT_CONST, SImode,
1598 					 op0, op_mode, op1, op_mode);
1599 	  insns = get_insns ();
1600 	  end_sequence ();
1601 
1602 	  emit_libcall_block (insns, cmp, cmp,
1603 			      gen_rtx_fmt_ee (code, SImode, op0, op1));
1604 	}
1605       else
1606 	{
1607 	  cmp = gen_reg_rtx (SImode);
1608 	  if (c6x_force_op_for_comparison_p (code, op1))
1609 	    op1 = force_reg (SImode, op1);
1610 	  emit_insn (gen_rtx_SET (cmp, gen_rtx_fmt_ee (code, SImode,
1611 						       op0, op1)));
1612 	}
1613     }
1614 
1615   return gen_rtx_fmt_ee (jump_code, mode, cmp, const0_rtx);
1616 }
1617 
1618 /* Return one word of double-word value OP.  HIGH_P is true to select the
1619    high part, false to select the low part.  When encountering auto-increment
1620    addressing, we make the assumption that the low part is going to be accessed
1621    first.  */
1622 
1623 rtx
1624 c6x_subword (rtx op, bool high_p)
1625 {
1626   unsigned int byte;
1627   machine_mode mode;
1628 
1629   mode = GET_MODE (op);
1630   if (mode == VOIDmode)
1631     mode = DImode;
1632 
1633   if (TARGET_BIG_ENDIAN ? !high_p : high_p)
1634     byte = UNITS_PER_WORD;
1635   else
1636     byte = 0;
1637 
1638   if (MEM_P (op))
1639     {
1640       rtx addr = XEXP (op, 0);
1641       if (GET_CODE (addr) == PLUS || REG_P (addr))
1642 	return adjust_address (op, word_mode, byte);
1643       /* FIXME: should really support autoincrement addressing for
1644 	 multi-word modes.  */
1645       gcc_unreachable ();
1646     }
1647 
1648   return simplify_gen_subreg (word_mode, op, mode, byte);
1649 }
1650 
1651 /* Split one or more DImode RTL references into pairs of SImode
1652    references.  The RTL can be REG, offsettable MEM, integer constant, or
1653    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
1654    split and "num" is its length.  lo_half and hi_half are output arrays
1655    that parallel "operands".  */
1656 
1657 void
1658 split_di (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
1659 {
1660   while (num--)
1661     {
1662       rtx op = operands[num];
1663 
1664       lo_half[num] = c6x_subword (op, false);
1665       hi_half[num] = c6x_subword (op, true);
1666     }
1667 }
1668 
1669 /* Return true if VAL is a mask valid for a clr instruction.  */
1670 bool
1671 c6x_valid_mask_p (HOST_WIDE_INT val)
1672 {
1673   int i;
1674   for (i = 0; i < 32; i++)
1675     if (!(val & ((unsigned HOST_WIDE_INT)1 << i)))
1676       break;
1677   for (; i < 32; i++)
1678     if (val & ((unsigned HOST_WIDE_INT)1 << i))
1679       break;
1680   for (; i < 32; i++)
1681     if (!(val & ((unsigned HOST_WIDE_INT)1 << i)))
1682       return false;
1683   return true;
1684 }
1685 
1686 /* Expand a block move for a movmemM pattern.  */
1687 
1688 bool
1689 c6x_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
1690 		   rtx expected_align_exp ATTRIBUTE_UNUSED,
1691 		   rtx expected_size_exp ATTRIBUTE_UNUSED)
1692 {
1693   unsigned HOST_WIDE_INT align = 1;
1694   unsigned HOST_WIDE_INT src_mem_align, dst_mem_align, min_mem_align;
1695   unsigned HOST_WIDE_INT count = 0, offset = 0;
1696   unsigned int biggest_move = TARGET_STDW ? 8 : 4;
1697 
1698   if (CONST_INT_P (align_exp))
1699     align = INTVAL (align_exp);
1700 
1701   src_mem_align = MEM_ALIGN (src) / BITS_PER_UNIT;
1702   dst_mem_align = MEM_ALIGN (dst) / BITS_PER_UNIT;
1703   min_mem_align = MIN (src_mem_align, dst_mem_align);
1704 
1705   if (min_mem_align > align)
1706     align = min_mem_align / BITS_PER_UNIT;
1707   if (src_mem_align < align)
1708     src_mem_align = align;
1709   if (dst_mem_align < align)
1710     dst_mem_align = align;
1711 
1712   if (CONST_INT_P (count_exp))
1713     count = INTVAL (count_exp);
1714   else
1715     return false;
1716 
1717   /* Make sure we don't need to care about overflow later on.  */
1718   if (count > ((unsigned HOST_WIDE_INT) 1 << 30))
1719     return false;
1720 
1721   if (count >= 28 && (count & 3) == 0 && align >= 4)
1722     {
1723       tree dst_expr = MEM_EXPR (dst);
1724       tree src_expr = MEM_EXPR (src);
1725       rtx fn = TARGET_INSNS_64PLUS ? strasgi64p_libfunc : strasgi_libfunc;
1726       rtx srcreg = force_reg (Pmode, XEXP (src, 0));
1727       rtx dstreg = force_reg (Pmode, XEXP (dst, 0));
1728 
1729       if (src_expr)
1730 	mark_addressable (src_expr);
1731       if (dst_expr)
1732 	mark_addressable (dst_expr);
1733       emit_library_call (fn, LCT_NORMAL, VOIDmode,
1734 			 dstreg, Pmode, srcreg, Pmode, count_exp, SImode);
1735       return true;
1736     }
1737 
1738   if (biggest_move > align && !TARGET_INSNS_64)
1739     biggest_move = align;
1740 
1741   if (count / biggest_move > 7)
1742     return false;
1743 
1744   while (count > 0)
1745     {
1746       rtx reg, reg_lowpart;
1747       machine_mode srcmode, dstmode;
1748       unsigned HOST_WIDE_INT src_size, dst_size, src_left;
1749       int shift;
1750       rtx srcmem, dstmem;
1751 
1752       while (biggest_move > count)
1753 	biggest_move /= 2;
1754 
1755       src_size = dst_size = biggest_move;
1756       if (src_size > src_mem_align && src_size == 2)
1757 	src_size = 1;
1758       if (dst_size > dst_mem_align && dst_size == 2)
1759 	dst_size = 1;
1760 
1761       if (dst_size > src_size)
1762 	dst_size = src_size;
1763 
1764       srcmode = int_mode_for_size (src_size * BITS_PER_UNIT, 0).require ();
1765       dstmode = int_mode_for_size (dst_size * BITS_PER_UNIT, 0).require ();
1766       if (src_size >= 4)
1767 	reg_lowpart = reg = gen_reg_rtx (srcmode);
1768       else
1769 	{
1770 	  reg = gen_reg_rtx (SImode);
1771 	  reg_lowpart = gen_lowpart (srcmode, reg);
1772 	}
1773 
1774       srcmem = adjust_address (copy_rtx (src), srcmode, offset);
1775 
1776       if (src_size > src_mem_align)
1777 	{
1778 	  enum insn_code icode = (srcmode == SImode ? CODE_FOR_movmisalignsi
1779 				  : CODE_FOR_movmisaligndi);
1780 	  emit_insn (GEN_FCN (icode) (reg_lowpart, srcmem));
1781 	}
1782       else
1783 	emit_move_insn (reg_lowpart, srcmem);
1784 
1785       src_left = src_size;
1786       shift = TARGET_BIG_ENDIAN ? (src_size - dst_size) * BITS_PER_UNIT  : 0;
1787       while (src_left > 0)
1788 	{
1789 	  rtx dstreg = reg_lowpart;
1790 
1791 	  if (src_size > dst_size)
1792 	    {
1793 	      rtx srcword = reg;
1794 	      int shift_amount = shift & (BITS_PER_WORD - 1);
1795 	      if (src_size > 4)
1796 		srcword = operand_subword_force (srcword, src_left >= 4 ? 0 : 4,
1797 						 SImode);
1798 	      if (shift_amount > 0)
1799 		{
1800 		  dstreg = gen_reg_rtx (SImode);
1801 		  emit_insn (gen_lshrsi3 (dstreg, srcword,
1802 					  GEN_INT (shift_amount)));
1803 		}
1804 	      else
1805 		dstreg = srcword;
1806 	      dstreg = gen_lowpart (dstmode, dstreg);
1807 	    }
1808 
1809 	  dstmem = adjust_address (copy_rtx (dst), dstmode, offset);
1810 	  if (dst_size > dst_mem_align)
1811 	    {
1812 	      enum insn_code icode = (dstmode == SImode ? CODE_FOR_movmisalignsi
1813 				      : CODE_FOR_movmisaligndi);
1814 	      emit_insn (GEN_FCN (icode) (dstmem, dstreg));
1815 	    }
1816 	  else
1817 	    emit_move_insn (dstmem, dstreg);
1818 
1819 	  if (TARGET_BIG_ENDIAN)
1820 	    shift -= dst_size * BITS_PER_UNIT;
1821 	  else
1822 	    shift += dst_size * BITS_PER_UNIT;
1823 	  offset += dst_size;
1824 	  src_left -= dst_size;
1825 	}
1826       count -= src_size;
1827     }
1828   return true;
1829 }
1830 
1831 /* Subroutine of print_address_operand, print a single address offset OFF for
1832    a memory access of mode MEM_MODE, choosing between normal form and scaled
1833    form depending on the type of the insn.  Misaligned memory references must
1834    use the scaled form.  */
1835 
1836 static void
1837 print_address_offset (FILE *file, rtx off, machine_mode mem_mode)
1838 {
1839   rtx pat;
1840 
1841   if (c6x_current_insn != NULL_RTX)
1842     {
1843       pat = PATTERN (c6x_current_insn);
1844       if (GET_CODE (pat) == COND_EXEC)
1845 	pat = COND_EXEC_CODE (pat);
1846       if (GET_CODE (pat) == PARALLEL)
1847 	pat = XVECEXP (pat, 0, 0);
1848 
1849       if (GET_CODE (pat) == SET
1850 	  && GET_CODE (SET_SRC (pat)) == UNSPEC
1851 	  && XINT (SET_SRC (pat), 1) == UNSPEC_MISALIGNED_ACCESS)
1852 	{
1853 	  gcc_assert (CONST_INT_P (off)
1854 		      && (INTVAL (off) & (GET_MODE_SIZE (mem_mode) - 1)) == 0);
1855 	  fprintf (file, "[" HOST_WIDE_INT_PRINT_DEC "]",
1856 		   INTVAL (off) / GET_MODE_SIZE (mem_mode));
1857 	  return;
1858 	}
1859     }
1860   fputs ("(", file);
1861   output_address (mem_mode, off);
1862   fputs (")", file);
1863 }
1864 
1865 static bool
1866 c6x_print_operand_punct_valid_p (unsigned char c)
1867 {
1868   return c == '$' || c == '.' || c == '|';
1869 }
1870 
1871 static void c6x_print_operand (FILE *, rtx, int);
1872 
1873 /* Subroutine of c6x_print_operand; used to print a memory reference X to FILE.  */
1874 
1875 static void
1876 c6x_print_address_operand (FILE *file, rtx x, machine_mode mem_mode)
1877 {
1878   rtx off;
1879   switch (GET_CODE (x))
1880     {
1881     case PRE_MODIFY:
1882     case POST_MODIFY:
1883       if (GET_CODE (x) == POST_MODIFY)
1884 	output_address (mem_mode, XEXP (x, 0));
1885       off = XEXP (XEXP (x, 1), 1);
1886       if (XEXP (x, 0) == stack_pointer_rtx)
1887 	{
1888 	  if (GET_CODE (x) == PRE_MODIFY)
1889 	    gcc_assert (INTVAL (off) > 0);
1890 	  else
1891 	    gcc_assert (INTVAL (off) < 0);
1892 	}
1893       if (CONST_INT_P (off) && INTVAL (off) < 0)
1894 	{
1895 	  fprintf (file, "--");
1896 	  off = GEN_INT (-INTVAL (off));
1897 	}
1898       else
1899 	fprintf (file, "++");
1900       if (GET_CODE (x) == PRE_MODIFY)
1901 	output_address (mem_mode, XEXP (x, 0));
1902       print_address_offset (file, off, mem_mode);
1903       break;
1904 
1905     case PLUS:
1906       off = XEXP (x, 1);
1907       if (CONST_INT_P (off) && INTVAL (off) < 0)
1908 	{
1909 	  fprintf (file, "-");
1910 	  off = GEN_INT (-INTVAL (off));
1911 	}
1912       else
1913 	fprintf (file, "+");
1914       output_address (mem_mode, XEXP (x, 0));
1915       print_address_offset (file, off, mem_mode);
1916       break;
1917 
1918     case PRE_DEC:
1919       gcc_assert (XEXP (x, 0) != stack_pointer_rtx);
1920       fprintf (file, "--");
1921       output_address (mem_mode, XEXP (x, 0));
1922       fprintf (file, "[1]");
1923       break;
1924     case PRE_INC:
1925       fprintf (file, "++");
1926       output_address (mem_mode, XEXP (x, 0));
1927       fprintf (file, "[1]");
1928       break;
1929     case POST_INC:
1930       gcc_assert (XEXP (x, 0) != stack_pointer_rtx);
1931       output_address (mem_mode, XEXP (x, 0));
1932       fprintf (file, "++[1]");
1933       break;
1934     case POST_DEC:
1935       output_address (mem_mode, XEXP (x, 0));
1936       fprintf (file, "--[1]");
1937       break;
1938 
1939     case SYMBOL_REF:
1940     case CONST:
1941     case LABEL_REF:
1942       gcc_assert (sdata_symbolic_operand (x, Pmode));
1943       fprintf (file, "+B14(");
1944       output_addr_const (file, x);
1945       fprintf (file, ")");
1946       break;
1947 
1948     case UNSPEC:
1949       switch (XINT (x, 1))
1950 	{
1951 	case UNSPEC_LOAD_GOT:
1952 	  fputs ("$GOT(", file);
1953 	  output_addr_const (file, XVECEXP (x, 0, 0));
1954 	  fputs (")", file);
1955 	  break;
1956 	case UNSPEC_LOAD_SDATA:
1957 	  output_addr_const (file, XVECEXP (x, 0, 0));
1958 	  break;
1959 	default:
1960 	  gcc_unreachable ();
1961 	}
1962       break;
1963 
1964     default:
1965       gcc_assert (GET_CODE (x) != MEM);
1966       c6x_print_operand (file, x, 0);
1967       break;
1968     }
1969 }
1970 
1971 /* Return a single character, which is either 'l', 's', 'd' or 'm', which
1972    specifies the functional unit used by INSN.  */
1973 
1974 char
1975 c6x_get_unit_specifier (rtx_insn *insn)
1976 {
1977   enum attr_units units;
1978 
1979   if (insn_info.exists ())
1980     {
1981       int unit = INSN_INFO_ENTRY (INSN_UID (insn)).reservation;
1982       return c6x_unit_names[unit][0];
1983     }
1984 
1985   units = get_attr_units (insn);
1986   switch (units)
1987     {
1988     case UNITS_D:
1989     case UNITS_DL:
1990     case UNITS_DS:
1991     case UNITS_DLS:
1992     case UNITS_D_ADDR:
1993       return 'd';
1994     case UNITS_L:
1995     case UNITS_LS:
1996       return 'l';
1997     case UNITS_S:
1998       return 's';
1999     case UNITS_M:
2000       return 'm';
2001     default:
2002       gcc_unreachable ();
2003     }
2004 }
2005 
2006 /* Prints the unit specifier field.  */
2007 static void
2008 c6x_print_unit_specifier_field (FILE *file, rtx_insn *insn)
2009 {
2010   enum attr_units units = get_attr_units (insn);
2011   enum attr_cross cross = get_attr_cross (insn);
2012   enum attr_dest_regfile rf = get_attr_dest_regfile (insn);
2013   int half;
2014   char unitspec;
2015 
2016   if (units == UNITS_D_ADDR)
2017     {
2018       enum attr_addr_regfile arf = get_attr_addr_regfile (insn);
2019       int t_half;
2020       gcc_assert (arf != ADDR_REGFILE_UNKNOWN);
2021       half = arf == ADDR_REGFILE_A ? 1 : 2;
2022       t_half = rf == DEST_REGFILE_A ? 1 : 2;
2023       fprintf (file, ".d%dt%d", half, t_half);
2024       return;
2025     }
2026 
2027   if (insn_info.exists ())
2028     {
2029       int unit = INSN_INFO_ENTRY (INSN_UID (insn)).reservation;
2030       fputs (".", file);
2031       fputs (c6x_unit_names[unit], file);
2032       if (cross == CROSS_Y)
2033 	fputs ("x", file);
2034       return;
2035     }
2036 
2037   gcc_assert (rf != DEST_REGFILE_UNKNOWN);
2038   unitspec = c6x_get_unit_specifier (insn);
2039   half = rf == DEST_REGFILE_A ? 1 : 2;
2040   fprintf (file, ".%c%d%s", unitspec, half, cross == CROSS_Y ? "x" : "");
2041 }
2042 
2043 /* Output assembly language output for the address ADDR to FILE.  */
2044 static void
2045 c6x_print_operand_address (FILE *file, machine_mode mode, rtx addr)
2046 {
2047   c6x_print_address_operand (file, addr, mode);
2048 }
2049 
2050 /* Print an operand, X, to FILE, with an optional modifier in CODE.
2051 
2052    Meaning of CODE:
2053    $ -- print the unit specifier field for the instruction.
2054    . -- print the predicate for the instruction or an emptry string for an
2055         unconditional one.
2056    | -- print "||" if the insn should be issued in parallel with the previous
2057         one.
2058 
2059    C -- print an opcode suffix for a reversed condition
2060    d -- H, W or D as a suffix for ADDA, based on the factor given by the
2061         operand
2062    D -- print either B, H, W or D as a suffix for ADDA, based on the size of
2063         the operand
2064    J -- print a predicate
2065    j -- like J, but use reverse predicate
2066    k -- treat a CONST_INT as a register number and print it as a register
2067    k -- like k, but print out a doubleword register
2068    n -- print an integer operand, negated
2069    p -- print the low part of a DImode register
2070    P -- print the high part of a DImode register
2071    r -- print the absolute value of an integer operand, shifted right by 1
2072    R -- print the absolute value of an integer operand, shifted right by 2
2073    f -- the first clear bit in an integer operand assumed to be a mask for
2074         a clr instruction
2075    F -- the last clear bit in such a mask
2076    s -- the first set bit in an integer operand assumed to be a mask for
2077         a set instruction
2078    S -- the last set bit in such a mask
2079    U -- print either 1 or 2, depending on the side of the machine used by
2080         the operand  */
2081 
2082 static void
2083 c6x_print_operand (FILE *file, rtx x, int code)
2084 {
2085   int i;
2086   HOST_WIDE_INT v;
2087   tree t;
2088   machine_mode mode;
2089 
2090   if (code == '|')
2091     {
2092       if (GET_MODE (c6x_current_insn) != TImode)
2093 	fputs ("||", file);
2094       return;
2095     }
2096   if (code == '$')
2097     {
2098       c6x_print_unit_specifier_field (file, c6x_current_insn);
2099       return;
2100     }
2101 
2102   if (code == '.')
2103     {
2104       x = current_insn_predicate;
2105       if (x)
2106 	{
2107 	  unsigned int regno = REGNO (XEXP (x, 0));
2108 	  fputs ("[", file);
2109  	  if (GET_CODE (x) == EQ)
2110 	    fputs ("!", file);
2111 	  fputs (reg_names [regno], file);
2112 	  fputs ("]", file);
2113 	}
2114       return;
2115     }
2116 
2117   mode = GET_MODE (x);
2118 
2119   switch (code)
2120     {
2121     case 'C':
2122     case 'c':
2123       {
2124 	enum rtx_code c = GET_CODE (x);
2125 	if (code == 'C')
2126 	  c = swap_condition (c);
2127 	fputs (GET_RTX_NAME (c), file);
2128       }
2129       return;
2130 
2131     case 'J':
2132     case 'j':
2133       {
2134 	unsigned int regno = REGNO (XEXP (x, 0));
2135 	if ((GET_CODE (x) == EQ) == (code == 'J'))
2136 	  fputs ("!", file);
2137         fputs (reg_names [regno], file);
2138       }
2139       return;
2140 
2141     case 'k':
2142       gcc_assert (GET_CODE (x) == CONST_INT);
2143       v = INTVAL (x);
2144       fprintf (file, "%s", reg_names[v]);
2145       return;
2146     case 'K':
2147       gcc_assert (GET_CODE (x) == CONST_INT);
2148       v = INTVAL (x);
2149       gcc_assert ((v & 1) == 0);
2150       fprintf (file, "%s:%s", reg_names[v + 1], reg_names[v]);
2151       return;
2152 
2153     case 's':
2154     case 'S':
2155     case 'f':
2156     case 'F':
2157       gcc_assert (GET_CODE (x) == CONST_INT);
2158       v = INTVAL (x);
2159       for (i = 0; i < 32; i++)
2160 	{
2161 	  HOST_WIDE_INT tst = v & 1;
2162 	  if (((code == 'f' || code == 'F') && !tst)
2163 	      || ((code == 's' || code == 'S') && tst))
2164 	    break;
2165 	  v >>= 1;
2166 	}
2167       if (code == 'f' || code == 's')
2168 	{
2169 	  fprintf (file, "%d", i);
2170 	  return;
2171 	}
2172       for (;i < 32; i++)
2173 	{
2174 	  HOST_WIDE_INT tst = v & 1;
2175 	  if ((code == 'F' && tst) || (code == 'S' && !tst))
2176 	    break;
2177 	  v >>= 1;
2178 	}
2179       fprintf (file, "%d", i - 1);
2180       return;
2181 
2182     case 'n':
2183       gcc_assert (GET_CODE (x) == CONST_INT);
2184       output_addr_const (file, GEN_INT (-INTVAL (x)));
2185       return;
2186 
2187     case 'r':
2188       gcc_assert (GET_CODE (x) == CONST_INT);
2189       v = INTVAL (x);
2190       if (v < 0)
2191 	v = -v;
2192       output_addr_const (file, GEN_INT (v >> 1));
2193       return;
2194 
2195     case 'R':
2196       gcc_assert (GET_CODE (x) == CONST_INT);
2197       v = INTVAL (x);
2198       if (v < 0)
2199 	v = -v;
2200       output_addr_const (file, GEN_INT (v >> 2));
2201       return;
2202 
2203     case 'd':
2204       gcc_assert (GET_CODE (x) == CONST_INT);
2205       v = INTVAL (x);
2206       fputs (v == 2 ? "h" : v == 4 ? "w" : "d", file);
2207       return;
2208 
2209     case 'p':
2210     case 'P':
2211       gcc_assert (GET_CODE (x) == REG);
2212       v = REGNO (x);
2213       if (code == 'P')
2214 	v++;
2215       fputs (reg_names[v], file);
2216       return;
2217 
2218     case 'D':
2219       v = 0;
2220       if (GET_CODE (x) == CONST)
2221 	{
2222 	  x = XEXP (x, 0);
2223 	  gcc_assert (GET_CODE (x) == PLUS);
2224 	  gcc_assert (GET_CODE (XEXP (x, 1)) == CONST_INT);
2225 	  v = INTVAL (XEXP (x, 1));
2226 	  x = XEXP (x, 0);
2227 
2228 	}
2229       gcc_assert (GET_CODE (x) == SYMBOL_REF);
2230 
2231       t = SYMBOL_REF_DECL (x);
2232       if (DECL_P (t))
2233 	v |= DECL_ALIGN_UNIT (t);
2234       else
2235 	v |= TYPE_ALIGN_UNIT (TREE_TYPE (t));
2236       if (v & 1)
2237 	fputs ("b", file);
2238       else if (v & 2)
2239 	fputs ("h", file);
2240       else
2241 	fputs ("w", file);
2242       return;
2243 
2244     case 'U':
2245       if (MEM_P (x))
2246 	{
2247 	  x = XEXP (x, 0);
2248 	  if (GET_CODE (x) == PLUS
2249 	      || GET_RTX_CLASS (GET_CODE (x)) == RTX_AUTOINC)
2250 	    x = XEXP (x, 0);
2251 	  if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF)
2252 	    {
2253 	      gcc_assert (sdata_symbolic_operand (x, Pmode));
2254 	      fputs ("2", file);
2255 	      return;
2256 	    }
2257 	}
2258       gcc_assert (REG_P (x));
2259       if (A_REGNO_P (REGNO (x)))
2260 	fputs ("1", file);
2261       if (B_REGNO_P (REGNO (x)))
2262 	fputs ("2", file);
2263       return;
2264 
2265     default:
2266       switch (GET_CODE (x))
2267 	{
2268 	case REG:
2269 	  if (GET_MODE_SIZE (mode) == 8)
2270 	    fprintf (file, "%s:%s", reg_names[REGNO (x) + 1],
2271 		     reg_names[REGNO (x)]);
2272 	  else
2273 	    fprintf (file, "%s", reg_names[REGNO (x)]);
2274 	  break;
2275 
2276 	case MEM:
2277 	  fputc ('*', file);
2278 	  gcc_assert (XEXP (x, 0) != stack_pointer_rtx);
2279 	  c6x_print_address_operand (file, XEXP (x, 0), GET_MODE (x));
2280 	  break;
2281 
2282 	case SYMBOL_REF:
2283 	  fputc ('(', file);
2284 	  output_addr_const (file, x);
2285 	  fputc (')', file);
2286 	  break;
2287 
2288 	case CONST_INT:
2289 	  output_addr_const (file, x);
2290 	  break;
2291 
2292 	case CONST_DOUBLE:
2293 	  output_operand_lossage ("invalid const_double operand");
2294 	  break;
2295 
2296 	default:
2297 	  output_addr_const (file, x);
2298 	}
2299     }
2300 }
2301 
2302 /* Return TRUE if OP is a valid memory address with a base register of
2303    class C.  If SMALL_OFFSET is true, we disallow memory references which would
2304    require a long offset with B14/B15.  */
2305 
2306 bool
2307 c6x_mem_operand (rtx op, enum reg_class c, bool small_offset)
2308 {
2309   machine_mode mode = GET_MODE (op);
2310   rtx base = XEXP (op, 0);
2311   switch (GET_CODE (base))
2312     {
2313     case REG:
2314       break;
2315     case PLUS:
2316       if (small_offset
2317 	  && (XEXP (base, 0) == stack_pointer_rtx
2318 	      || XEXP (base, 0) == pic_offset_table_rtx))
2319 	{
2320 	  if (!c6x_legitimate_address_p_1 (mode, base, true, true))
2321 	    return false;
2322 	}
2323 
2324       /* fall through */
2325     case PRE_INC:
2326     case PRE_DEC:
2327     case PRE_MODIFY:
2328     case POST_INC:
2329     case POST_DEC:
2330     case POST_MODIFY:
2331       base = XEXP (base, 0);
2332       break;
2333 
2334     case CONST:
2335     case LABEL_REF:
2336     case SYMBOL_REF:
2337       gcc_assert (sdata_symbolic_operand (base, Pmode));
2338       return !small_offset && c == B_REGS;
2339 
2340     default:
2341       return false;
2342     }
2343   return TEST_HARD_REG_BIT (reg_class_contents[ (int) (c)], REGNO (base));
2344 }
2345 
2346 /* Returns true if X is a valid address for use in a memory reference
2347    of mode MODE.  If STRICT is true, we do not allow pseudo registers
2348    in the address.  NO_LARGE_OFFSET is true if we are examining an
2349    address for use in a load or store misaligned instruction, or
2350    recursively examining an operand inside a PRE/POST_MODIFY.  */
2351 
2352 bool
2353 c6x_legitimate_address_p_1 (machine_mode mode, rtx x, bool strict,
2354 			    bool no_large_offset)
2355 {
2356   int size, size1;
2357   HOST_WIDE_INT off;
2358   enum rtx_code code = GET_CODE (x);
2359 
2360   switch (code)
2361     {
2362     case PRE_MODIFY:
2363     case POST_MODIFY:
2364       /* We can't split these into word-sized pieces yet.  */
2365       if (!TARGET_STDW && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
2366 	return false;
2367       if (GET_CODE (XEXP (x, 1)) != PLUS)
2368 	return false;
2369       if (!c6x_legitimate_address_p_1 (mode, XEXP (x, 1), strict, true))
2370 	return false;
2371       if (!rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0)))
2372 	return false;
2373 
2374       /* fall through */
2375     case PRE_INC:
2376     case PRE_DEC:
2377     case POST_INC:
2378     case POST_DEC:
2379       /* We can't split these into word-sized pieces yet.  */
2380       if (!TARGET_STDW && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
2381 	return false;
2382       x = XEXP (x, 0);
2383       if (!REG_P (x))
2384 	return false;
2385 
2386       /* fall through */
2387     case REG:
2388       if (strict)
2389 	return REGNO_OK_FOR_BASE_STRICT_P (REGNO (x));
2390       else
2391 	return REGNO_OK_FOR_BASE_NONSTRICT_P (REGNO (x));
2392 
2393     case PLUS:
2394       if (!REG_P (XEXP (x, 0))
2395 	  || !c6x_legitimate_address_p_1 (mode, XEXP (x, 0), strict, false))
2396 	return false;
2397       /* We cannot ensure currently that both registers end up in the
2398 	 same register file.  */
2399       if (REG_P (XEXP (x, 1)))
2400 	return false;
2401 
2402       if (mode == BLKmode)
2403 	size = 4;
2404       else if (mode == VOIDmode)
2405 	/* ??? This can happen during ivopts.  */
2406 	size = 1;
2407       else
2408 	size = GET_MODE_SIZE (mode);
2409 
2410       if (flag_pic
2411 	  && GET_CODE (XEXP (x, 1)) == UNSPEC
2412 	  && XINT (XEXP (x, 1), 1) == UNSPEC_LOAD_SDATA
2413 	  && XEXP (x, 0) == pic_offset_table_rtx
2414 	  && sdata_symbolic_operand (XVECEXP (XEXP (x, 1), 0, 0), SImode))
2415 	return !no_large_offset && size <= 4;
2416       if (flag_pic == 1
2417 	  && mode == Pmode
2418 	  && GET_CODE (XEXP (x, 1)) == UNSPEC
2419 	  && XINT (XEXP (x, 1), 1) == UNSPEC_LOAD_GOT
2420 	  && XEXP (x, 0) == pic_offset_table_rtx
2421 	  && (GET_CODE (XVECEXP (XEXP (x, 1), 0, 0)) == SYMBOL_REF
2422 	      || GET_CODE (XVECEXP (XEXP (x, 1), 0, 0)) == LABEL_REF))
2423 	return !no_large_offset;
2424       if (GET_CODE (XEXP (x, 1)) != CONST_INT)
2425 	return false;
2426 
2427       off = INTVAL (XEXP (x, 1));
2428 
2429       /* If the machine does not have doubleword load/stores, we'll use
2430 	 word size accesses.  */
2431       size1 = size;
2432       if (size == 2 * UNITS_PER_WORD && !TARGET_STDW)
2433 	size = UNITS_PER_WORD;
2434 
2435       if (((HOST_WIDE_INT)size1 - 1) & off)
2436 	return false;
2437       off /= size;
2438       if (off > -32 && off < (size1 == size ? 32 : 28))
2439 	return true;
2440       if (no_large_offset || code != PLUS || XEXP (x, 0) != stack_pointer_rtx
2441 	  || size1 > UNITS_PER_WORD)
2442 	return false;
2443       return off >= 0 && off < 32768;
2444 
2445     case CONST:
2446     case SYMBOL_REF:
2447     case LABEL_REF:
2448       return (!no_large_offset
2449 	      /* With -fpic, we must wrap it in an unspec to show the B14
2450 		 dependency.  */
2451 	      && !flag_pic
2452 	      && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
2453 	      && sdata_symbolic_operand (x, Pmode));
2454 
2455     default:
2456       return false;
2457     }
2458 }
2459 
2460 static bool
2461 c6x_legitimate_address_p (machine_mode mode, rtx x, bool strict)
2462 {
2463   return c6x_legitimate_address_p_1 (mode, x, strict, false);
2464 }
2465 
2466 static bool
2467 c6x_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED,
2468 			   rtx x ATTRIBUTE_UNUSED)
2469 {
2470   return true;
2471 }
2472 
2473 /* Implements TARGET_PREFERRED_RENAME_CLASS.  */
2474 static reg_class_t
2475 c6x_preferred_rename_class (reg_class_t cl)
2476 {
2477   if (cl == A_REGS)
2478     return NONPREDICATE_A_REGS;
2479   if (cl == B_REGS)
2480     return NONPREDICATE_B_REGS;
2481   if (cl == ALL_REGS || cl == GENERAL_REGS)
2482     return NONPREDICATE_REGS;
2483   return NO_REGS;
2484 }
2485 
2486 /* Implements FINAL_PRESCAN_INSN.  */
2487 void
2488 c6x_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
2489 			int noperands ATTRIBUTE_UNUSED)
2490 {
2491   c6x_current_insn = insn;
2492 }
2493 
2494 /* A structure to describe the stack layout of a function.  The layout is
2495    as follows:
2496 
2497    [saved frame pointer (or possibly padding0)]
2498    --> incoming stack pointer, new hard frame pointer
2499    [saved call-used regs]
2500    [optional padding1]
2501    --> soft frame pointer
2502    [frame]
2503    [outgoing arguments]
2504    [optional padding2]
2505 
2506   The structure members are laid out in this order.  */
2507 
2508 struct c6x_frame
2509 {
2510   int padding0;
2511   /* Number of registers to save.  */
2512   int nregs;
2513   int padding1;
2514   HOST_WIDE_INT frame;
2515   int outgoing_arguments_size;
2516   int padding2;
2517 
2518   HOST_WIDE_INT to_allocate;
2519   /* The offsets relative to the incoming stack pointer (which
2520      becomes HARD_FRAME_POINTER).  */
2521   HOST_WIDE_INT frame_pointer_offset;
2522   HOST_WIDE_INT b3_offset;
2523 
2524   /* True if we should call push_rts/pop_rts to save and restore
2525      registers.  */
2526   bool push_rts;
2527 };
2528 
2529 /* Return true if we need to save and modify the PIC register in the
2530    prologue.  */
2531 
2532 static bool
2533 must_reload_pic_reg_p (void)
2534 {
2535   struct cgraph_local_info *i = NULL;
2536 
2537   if (!TARGET_DSBT)
2538     return false;
2539 
2540   i = cgraph_node::local_info (current_function_decl);
2541 
2542   if ((crtl->uses_pic_offset_table || !crtl->is_leaf) && !i->local)
2543     return true;
2544   return false;
2545 }
2546 
2547 /* Return 1 if we need to save REGNO.  */
2548 static int
2549 c6x_save_reg (unsigned int regno)
2550 {
2551   return ((df_regs_ever_live_p (regno)
2552 	   && !call_used_regs[regno]
2553 	   && !fixed_regs[regno])
2554 	  || (regno == RETURN_ADDR_REGNO
2555 	      && (df_regs_ever_live_p (regno)
2556 		  || !crtl->is_leaf))
2557 	  || (regno == PIC_OFFSET_TABLE_REGNUM && must_reload_pic_reg_p ()));
2558 }
2559 
2560 /* Examine the number of regs NREGS we've determined we must save.
2561    Return true if we should use __c6xabi_push_rts/__c6xabi_pop_rts for
2562    prologue and epilogue.  */
2563 
2564 static bool
2565 use_push_rts_p (int nregs)
2566 {
2567   if (TARGET_INSNS_64PLUS && optimize_function_for_size_p (cfun)
2568       && !cfun->machine->contains_sibcall
2569       && !cfun->returns_struct
2570       && !TARGET_LONG_CALLS
2571       && nregs >= 6 && !frame_pointer_needed)
2572     return true;
2573   return false;
2574 }
2575 
2576 /* Return number of saved general prupose registers.  */
2577 
2578 int
2579 c6x_nsaved_regs (void)
2580 {
2581   int nregs = 0;
2582   int regno;
2583 
2584   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
2585     if (c6x_save_reg (regno))
2586       nregs++;
2587   return nregs;
2588 }
2589 
2590 /* The safe debug order mandated by the ABI.  */
2591 static unsigned reg_save_order[] =
2592 {
2593   REG_A10, REG_A11, REG_A12, REG_A13,
2594   REG_A14, REG_B3,
2595   REG_B10, REG_B11, REG_B12, REG_B13,
2596   REG_B14, REG_A15
2597 };
2598 
2599 #define N_SAVE_ORDER (sizeof reg_save_order / sizeof *reg_save_order)
2600 
2601 /* Compute the layout of the stack frame and store it in FRAME.  */
2602 
2603 static void
2604 c6x_compute_frame_layout (struct c6x_frame *frame)
2605 {
2606   HOST_WIDE_INT size = get_frame_size ();
2607   HOST_WIDE_INT offset;
2608   int nregs;
2609 
2610   /* We use the four bytes which are technically inside the caller's frame,
2611      usually to save the frame pointer.  */
2612   offset = -4;
2613   frame->padding0 = 0;
2614   nregs = c6x_nsaved_regs ();
2615   frame->push_rts = false;
2616   frame->b3_offset = 0;
2617   if (use_push_rts_p (nregs))
2618     {
2619       frame->push_rts = true;
2620       frame->b3_offset = (TARGET_BIG_ENDIAN ? -12 : -13) * 4;
2621       nregs = 14;
2622     }
2623   else if (c6x_save_reg (REG_B3))
2624     {
2625       int idx;
2626       for (idx = N_SAVE_ORDER - 1; reg_save_order[idx] != REG_B3; idx--)
2627 	{
2628 	  if (c6x_save_reg (reg_save_order[idx]))
2629 	    frame->b3_offset -= 4;
2630 	}
2631     }
2632   frame->nregs = nregs;
2633 
2634   if (size == 0 && nregs == 0)
2635     {
2636       frame->padding0 = 4;
2637       frame->padding1 = frame->padding2 = 0;
2638       frame->frame_pointer_offset = frame->to_allocate = 0;
2639       frame->outgoing_arguments_size = 0;
2640       return;
2641     }
2642 
2643   if (!frame->push_rts)
2644     offset += frame->nregs * 4;
2645 
2646   if (offset == 0 && size == 0 && crtl->outgoing_args_size == 0
2647       && !crtl->is_leaf)
2648     /* Don't use the bottom of the caller's frame if we have no
2649        allocation of our own and call other functions.  */
2650     frame->padding0 = frame->padding1 = 4;
2651   else if (offset & 4)
2652     frame->padding1 = 4;
2653   else
2654     frame->padding1 = 0;
2655 
2656   offset += frame->padding0 + frame->padding1;
2657   frame->frame_pointer_offset = offset;
2658   offset += size;
2659 
2660   frame->outgoing_arguments_size = crtl->outgoing_args_size;
2661   offset += frame->outgoing_arguments_size;
2662 
2663   if ((offset & 4) == 0)
2664     frame->padding2 = 8;
2665   else
2666     frame->padding2 = 4;
2667   frame->to_allocate = offset + frame->padding2;
2668 }
2669 
2670 /* Return the offset between two registers, one to be eliminated, and the other
2671    its replacement, at the start of a routine.  */
2672 
2673 HOST_WIDE_INT
2674 c6x_initial_elimination_offset (int from, int to)
2675 {
2676   struct c6x_frame frame;
2677   c6x_compute_frame_layout (&frame);
2678 
2679   if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
2680     return 0;
2681   else if (from == FRAME_POINTER_REGNUM
2682 	   && to == HARD_FRAME_POINTER_REGNUM)
2683     return -frame.frame_pointer_offset;
2684   else
2685     {
2686       gcc_assert (to == STACK_POINTER_REGNUM);
2687 
2688       if (from == ARG_POINTER_REGNUM)
2689 	return frame.to_allocate + (frame.push_rts ? 56 : 0);
2690 
2691       gcc_assert (from == FRAME_POINTER_REGNUM);
2692       return frame.to_allocate - frame.frame_pointer_offset;
2693     }
2694 }
2695 
2696 /* Given FROM and TO register numbers, say whether this elimination is
2697    allowed.  Frame pointer elimination is automatically handled.  */
2698 
2699 static bool
2700 c6x_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
2701 {
2702   if (to == STACK_POINTER_REGNUM)
2703     return !frame_pointer_needed;
2704   return true;
2705 }
2706 
2707 /* Emit insns to increment the stack pointer by OFFSET.  If
2708    FRAME_RELATED_P, set the RTX_FRAME_RELATED_P flag on the insns.
2709    Does nothing if the offset is zero.  */
2710 
2711 static void
2712 emit_add_sp_const (HOST_WIDE_INT offset, bool frame_related_p)
2713 {
2714   rtx to_add = GEN_INT (offset);
2715   rtx orig_to_add = to_add;
2716   rtx_insn *insn;
2717 
2718   if (offset == 0)
2719     return;
2720 
2721   if (offset < -32768 || offset > 32767)
2722     {
2723       rtx reg = gen_rtx_REG (SImode, REG_A0);
2724       rtx low = GEN_INT (trunc_int_for_mode (offset, HImode));
2725 
2726       insn = emit_insn (gen_movsi_high (reg, low));
2727       if (frame_related_p)
2728 	RTX_FRAME_RELATED_P (insn) = 1;
2729       insn = emit_insn (gen_movsi_lo_sum (reg, reg, to_add));
2730       if (frame_related_p)
2731 	RTX_FRAME_RELATED_P (insn) = 1;
2732       to_add = reg;
2733     }
2734   insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2735 				to_add));
2736   if (frame_related_p)
2737     {
2738       if (REG_P (to_add))
2739 	add_reg_note (insn, REG_FRAME_RELATED_EXPR,
2740 		      gen_rtx_SET (stack_pointer_rtx,
2741 				   gen_rtx_PLUS (Pmode, stack_pointer_rtx,
2742 						 orig_to_add)));
2743 
2744       RTX_FRAME_RELATED_P (insn) = 1;
2745     }
2746 }
2747 
2748 /* Prologue and epilogue.  */
2749 void
2750 c6x_expand_prologue (void)
2751 {
2752   struct c6x_frame frame;
2753   rtx_insn *insn;
2754   rtx mem;
2755   int nsaved = 0;
2756   HOST_WIDE_INT initial_offset, off, added_already;
2757 
2758   c6x_compute_frame_layout (&frame);
2759 
2760   if (flag_stack_usage_info)
2761     current_function_static_stack_size = frame.to_allocate;
2762 
2763   initial_offset = -frame.to_allocate;
2764   if (frame.push_rts)
2765     {
2766       emit_insn (gen_push_rts ());
2767       nsaved = frame.nregs;
2768     }
2769 
2770   /* If the offsets would be too large for the memory references we will
2771      create to save registers, do the stack allocation in two parts.
2772      Ensure by subtracting 8 that we don't store to the word pointed to
2773      by the stack pointer.  */
2774   if (initial_offset < -32768)
2775     initial_offset = -frame.frame_pointer_offset - 8;
2776 
2777   if (frame.to_allocate > 0)
2778     gcc_assert (initial_offset != 0);
2779 
2780   off = -initial_offset + 4 - frame.padding0;
2781 
2782   mem = gen_frame_mem (Pmode, stack_pointer_rtx);
2783 
2784   added_already = 0;
2785   if (frame_pointer_needed)
2786     {
2787       rtx fp_reg = gen_rtx_REG (SImode, REG_A15);
2788       /* We go through some contortions here to both follow the ABI's
2789 	 recommendation that FP == incoming SP, and to avoid writing or
2790 	 reading the word pointed to by the stack pointer.  */
2791       rtx addr = gen_rtx_POST_MODIFY (Pmode, stack_pointer_rtx,
2792 				      gen_rtx_PLUS (Pmode, stack_pointer_rtx,
2793 						    GEN_INT (-8)));
2794       insn = emit_move_insn (gen_frame_mem (Pmode, addr), fp_reg);
2795       RTX_FRAME_RELATED_P (insn) = 1;
2796       nsaved++;
2797       insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, stack_pointer_rtx,
2798 				    GEN_INT (8)));
2799       RTX_FRAME_RELATED_P (insn) = 1;
2800       off -= 4;
2801       added_already = -8;
2802     }
2803 
2804   emit_add_sp_const (initial_offset - added_already, true);
2805 
2806   if (nsaved < frame.nregs)
2807     {
2808       unsigned i;
2809 
2810       for (i = 0; i < N_SAVE_ORDER; i++)
2811 	{
2812 	  int idx = N_SAVE_ORDER - i - 1;
2813 	  unsigned regno = reg_save_order[idx];
2814 	  rtx reg;
2815 	  machine_mode save_mode = SImode;
2816 
2817 	  if (regno == REG_A15 && frame_pointer_needed)
2818 	    /* Already saved.  */
2819 	    continue;
2820 	  if (!c6x_save_reg (regno))
2821 	    continue;
2822 
2823 	  if (TARGET_STDW && (off & 4) == 0 && off <= 256
2824 	      && (regno & 1) == 1
2825 	      && i + 1 < N_SAVE_ORDER
2826 	      && reg_save_order[idx - 1] == regno - 1
2827 	      && c6x_save_reg (regno - 1))
2828 	    {
2829 	      save_mode = DImode;
2830 	      regno--;
2831 	      i++;
2832 	    }
2833 	  reg = gen_rtx_REG (save_mode, regno);
2834 	  off -= GET_MODE_SIZE (save_mode);
2835 
2836 	  insn = emit_move_insn (adjust_address (mem, save_mode, off),
2837 				 reg);
2838 	  RTX_FRAME_RELATED_P (insn) = 1;
2839 
2840 	  nsaved += hard_regno_nregs (regno, save_mode);
2841 	}
2842     }
2843   gcc_assert (nsaved == frame.nregs);
2844   emit_add_sp_const (-frame.to_allocate - initial_offset, true);
2845   if (must_reload_pic_reg_p ())
2846     {
2847       if (dsbt_decl == NULL)
2848 	{
2849 	  tree t;
2850 
2851 	  t = build_index_type (integer_one_node);
2852 	  t = build_array_type (integer_type_node, t);
2853 	  t = build_decl (BUILTINS_LOCATION, VAR_DECL,
2854 			  get_identifier ("__c6xabi_DSBT_BASE"), t);
2855 	  DECL_ARTIFICIAL (t) = 1;
2856 	  DECL_IGNORED_P (t) = 1;
2857 	  DECL_EXTERNAL (t) = 1;
2858 	  TREE_STATIC (t) = 1;
2859 	  TREE_PUBLIC (t) = 1;
2860 	  TREE_USED (t) = 1;
2861 
2862 	  dsbt_decl = t;
2863 	}
2864       emit_insn (gen_setup_dsbt (pic_offset_table_rtx,
2865 				 XEXP (DECL_RTL (dsbt_decl), 0)));
2866     }
2867 }
2868 
2869 void
2870 c6x_expand_epilogue (bool sibcall)
2871 {
2872   unsigned i;
2873   struct c6x_frame frame;
2874   rtx mem;
2875   HOST_WIDE_INT off;
2876   int nsaved = 0;
2877 
2878   c6x_compute_frame_layout (&frame);
2879 
2880   mem = gen_frame_mem (Pmode, stack_pointer_rtx);
2881 
2882   /* Insert a dummy set/use of the stack pointer.  This creates a
2883      scheduler barrier between the prologue saves and epilogue restores. */
2884   emit_insn (gen_epilogue_barrier (stack_pointer_rtx, stack_pointer_rtx));
2885 
2886   /* If the offsets would be too large for the memory references we will
2887      create to restore registers, do a preliminary stack adjustment here.  */
2888   off = frame.to_allocate - frame.frame_pointer_offset + frame.padding1;
2889   if (frame.push_rts)
2890     {
2891       nsaved = frame.nregs;
2892     }
2893   else
2894     {
2895       if (frame.to_allocate > 32768)
2896 	{
2897 	  /* Don't add the entire offset so that we leave an unused word
2898 	     above the stack pointer.  */
2899 	  emit_add_sp_const ((off - 16) & ~7, false);
2900 	  off &= 7;
2901 	  off += 16;
2902 	}
2903       for (i = 0; i < N_SAVE_ORDER; i++)
2904 	{
2905 	  unsigned regno = reg_save_order[i];
2906 	  rtx reg;
2907 	  machine_mode save_mode = SImode;
2908 
2909 	  if (!c6x_save_reg (regno))
2910 	    continue;
2911 	  if (regno == REG_A15 && frame_pointer_needed)
2912 	    continue;
2913 
2914 	  if (TARGET_STDW && (off & 4) == 0 && off < 256
2915 	      && (regno & 1) == 0
2916 	      && i + 1 < N_SAVE_ORDER
2917 	      && reg_save_order[i + 1] == regno + 1
2918 	      && c6x_save_reg (regno + 1))
2919 	    {
2920 	      save_mode = DImode;
2921 	      i++;
2922 	    }
2923 	  reg = gen_rtx_REG (save_mode, regno);
2924 
2925 	  emit_move_insn (reg, adjust_address (mem, save_mode, off));
2926 
2927 	  off += GET_MODE_SIZE (save_mode);
2928 	  nsaved += hard_regno_nregs (regno, save_mode);
2929 	}
2930     }
2931   if (!frame_pointer_needed)
2932     emit_add_sp_const (off + frame.padding0 - 4, false);
2933   else
2934     {
2935       rtx fp_reg = gen_rtx_REG (SImode, REG_A15);
2936       rtx addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
2937 				      gen_rtx_PLUS (Pmode, stack_pointer_rtx,
2938 						    GEN_INT (8)));
2939       emit_insn (gen_addsi3 (stack_pointer_rtx, hard_frame_pointer_rtx,
2940 			     GEN_INT (-8)));
2941       emit_move_insn (fp_reg, gen_frame_mem (Pmode, addr));
2942       nsaved++;
2943     }
2944   gcc_assert (nsaved == frame.nregs);
2945   if (!sibcall)
2946     {
2947       if (frame.push_rts)
2948 	emit_jump_insn (gen_pop_rts ());
2949       else
2950 	emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode,
2951 							  RETURN_ADDR_REGNO)));
2952     }
2953 }
2954 
2955 /* Return the value of the return address for the frame COUNT steps up
2956    from the current frame, after the prologue.
2957    We punt for everything but the current frame by returning const0_rtx.  */
2958 
2959 rtx
2960 c6x_return_addr_rtx (int count)
2961 {
2962   if (count != 0)
2963     return const0_rtx;
2964 
2965   return get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNO);
2966 }
2967 
2968 /* Return true iff TYPE is one of the shadow types.  */
2969 static bool
2970 shadow_type_p (enum attr_type type)
2971 {
2972   return (type == TYPE_SHADOW || type == TYPE_LOAD_SHADOW
2973 	  || type == TYPE_MULT_SHADOW);
2974 }
2975 
2976 /* Return true iff INSN is a shadow pattern.  */
2977 static bool
2978 shadow_p (rtx_insn *insn)
2979 {
2980   if (!NONDEBUG_INSN_P (insn) || recog_memoized (insn) < 0)
2981     return false;
2982   return shadow_type_p (get_attr_type (insn));
2983 }
2984 
2985 /* Return true iff INSN is a shadow or blockage pattern.  */
2986 static bool
2987 shadow_or_blockage_p (rtx_insn *insn)
2988 {
2989   enum attr_type type;
2990   if (!NONDEBUG_INSN_P (insn) || recog_memoized (insn) < 0)
2991     return false;
2992   type = get_attr_type (insn);
2993   return shadow_type_p (type) || type == TYPE_BLOCKAGE;
2994 }
2995 
2996 /* Translate UNITS into a bitmask of units we can reserve for this
2997    insn.  */
2998 static int
2999 get_reservation_flags (enum attr_units units)
3000 {
3001   switch (units)
3002     {
3003     case UNITS_D:
3004     case UNITS_D_ADDR:
3005       return RESERVATION_FLAG_D;
3006     case UNITS_L:
3007       return RESERVATION_FLAG_L;
3008     case UNITS_S:
3009       return RESERVATION_FLAG_S;
3010     case UNITS_M:
3011       return RESERVATION_FLAG_M;
3012     case UNITS_LS:
3013       return RESERVATION_FLAG_LS;
3014     case UNITS_DL:
3015       return RESERVATION_FLAG_DL;
3016     case UNITS_DS:
3017       return RESERVATION_FLAG_DS;
3018     case UNITS_DLS:
3019       return RESERVATION_FLAG_DLS;
3020     default:
3021       return 0;
3022     }
3023 }
3024 
3025 /* Compute the side of the machine used by INSN, which reserves UNITS.
3026    This must match the reservations in the scheduling description.  */
3027 static int
3028 get_insn_side (rtx_insn *insn, enum attr_units units)
3029 {
3030   if (units == UNITS_D_ADDR)
3031     return (get_attr_addr_regfile (insn) == ADDR_REGFILE_A ? 0 : 1);
3032   else
3033     {
3034       enum attr_dest_regfile rf = get_attr_dest_regfile (insn);
3035       if (rf == DEST_REGFILE_ANY)
3036 	return get_attr_type (insn) == TYPE_BRANCH ? 0 : 1;
3037       else
3038 	return rf == DEST_REGFILE_A ? 0 : 1;
3039     }
3040 }
3041 
3042 /* After scheduling, walk the insns between HEAD and END and assign unit
3043    reservations.  */
3044 static void
3045 assign_reservations (rtx_insn *head, rtx_insn *end)
3046 {
3047   rtx_insn *insn;
3048   for (insn = head; insn != NEXT_INSN (end); insn = NEXT_INSN (insn))
3049     {
3050       unsigned int sched_mask, reserved;
3051       rtx_insn *within, *last;
3052       int pass;
3053       int rsrv[2];
3054       int rsrv_count[2][4];
3055       int i;
3056 
3057       if (GET_MODE (insn) != TImode)
3058 	continue;
3059 
3060       reserved = 0;
3061       last = NULL;
3062       /* Find the last insn in the packet.  It has a state recorded for it,
3063 	 which we can use to determine the units we should be using.  */
3064       for (within = insn;
3065 	   (within != NEXT_INSN (end)
3066 	    && (within == insn || GET_MODE (within) != TImode));
3067 	   within = NEXT_INSN (within))
3068 	{
3069 	  int icode;
3070 	  if (!NONDEBUG_INSN_P (within))
3071 	    continue;
3072 	  icode = recog_memoized (within);
3073 	  if (icode < 0)
3074 	    continue;
3075 	  if (shadow_p (within))
3076 	    continue;
3077 	  if (INSN_INFO_ENTRY (INSN_UID (within)).reservation != 0)
3078 	    reserved |= 1 << INSN_INFO_ENTRY (INSN_UID (within)).reservation;
3079 	  last = within;
3080 	}
3081       if (last == NULL_RTX)
3082 	continue;
3083 
3084       sched_mask = INSN_INFO_ENTRY (INSN_UID (last)).unit_mask;
3085       sched_mask &= ~reserved;
3086 
3087       memset (rsrv_count, 0, sizeof rsrv_count);
3088       rsrv[0] = rsrv[1] = ~0;
3089       for (i = 0; i < 8; i++)
3090 	{
3091 	  int side = i / 4;
3092 	  int unit = i & 3;
3093 	  unsigned unit_bit = 1 << (unit + side * UNIT_QID_SIDE_OFFSET);
3094 	  /* Clear the bits which we expect to reserve in the following loop,
3095 	     leaving the ones set which aren't present in the scheduler's
3096 	     state and shouldn't be reserved.  */
3097 	  if (sched_mask & unit_bit)
3098 	    rsrv[i / 4] &= ~(1 << unit);
3099 	}
3100 
3101       /* Walk through the insns that occur in the same cycle.  We use multiple
3102 	 passes to assign units, assigning for insns with the most specific
3103 	 requirements first.  */
3104       for (pass = 0; pass < 4; pass++)
3105 	for (within = insn;
3106 	     (within != NEXT_INSN (end)
3107 	      && (within == insn || GET_MODE (within) != TImode));
3108 	     within = NEXT_INSN (within))
3109 	  {
3110 	    int uid = INSN_UID (within);
3111 	    int this_rsrv, side;
3112 	    int icode;
3113 	    enum attr_units units;
3114 	    enum attr_type type;
3115 	    int j;
3116 
3117 	    if (!NONDEBUG_INSN_P (within))
3118 	      continue;
3119 	    icode = recog_memoized (within);
3120 	    if (icode < 0)
3121 	      continue;
3122 	    if (INSN_INFO_ENTRY (uid).reservation != 0)
3123 	      continue;
3124 	    units = get_attr_units (within);
3125 	    type = get_attr_type (within);
3126 	    this_rsrv = get_reservation_flags (units);
3127 	    if (this_rsrv == 0)
3128 	      continue;
3129 	    side = get_insn_side (within, units);
3130 
3131 	    /* Certain floating point instructions are treated specially.  If
3132 	       an insn can choose between units it can reserve, and its
3133 	       reservation spans more than one cycle, the reservation contains
3134 	       special markers in the first cycle to help us reconstruct what
3135 	       the automaton chose.  */
3136 	    if ((type == TYPE_ADDDP || type == TYPE_FP4)
3137 		&& units == UNITS_LS)
3138 	      {
3139 		int test1_code = ((type == TYPE_FP4 ? UNIT_QID_FPL1 : UNIT_QID_ADDDPL1)
3140 				  + side * UNIT_QID_SIDE_OFFSET);
3141 		int test2_code = ((type == TYPE_FP4 ? UNIT_QID_FPS1 : UNIT_QID_ADDDPS1)
3142 				  + side * UNIT_QID_SIDE_OFFSET);
3143 		if ((sched_mask & (1 << test1_code)) != 0)
3144 		  {
3145 		    this_rsrv = RESERVATION_FLAG_L;
3146 		    sched_mask &= ~(1 << test1_code);
3147 		  }
3148 		else if ((sched_mask & (1 << test2_code)) != 0)
3149 		  {
3150 		    this_rsrv = RESERVATION_FLAG_S;
3151 		    sched_mask &= ~(1 << test2_code);
3152 		  }
3153 	      }
3154 
3155 	    if ((this_rsrv & (this_rsrv - 1)) == 0)
3156 	      {
3157 		int t = exact_log2 (this_rsrv) + side * UNIT_QID_SIDE_OFFSET;
3158 		rsrv[side] |= this_rsrv;
3159 		INSN_INFO_ENTRY (uid).reservation = t;
3160 		continue;
3161 	      }
3162 
3163 	    if (pass == 1)
3164 	      {
3165 		for (j = 0; j < 4; j++)
3166 		  if (this_rsrv & (1 << j))
3167 		    rsrv_count[side][j]++;
3168 		continue;
3169 	      }
3170 	    if ((pass == 2 && this_rsrv != RESERVATION_FLAG_DLS)
3171 		|| (pass == 3 && this_rsrv == RESERVATION_FLAG_DLS))
3172 	      {
3173 		int best = -1, best_cost = INT_MAX;
3174 		for (j = 0; j < 4; j++)
3175 		  if ((this_rsrv & (1 << j))
3176 		      && !(rsrv[side] & (1 << j))
3177 		      && rsrv_count[side][j] < best_cost)
3178 		    {
3179 		      best_cost = rsrv_count[side][j];
3180 		      best = j;
3181 		    }
3182 		gcc_assert (best != -1);
3183 		rsrv[side] |= 1 << best;
3184 		for (j = 0; j < 4; j++)
3185 		  if ((this_rsrv & (1 << j)) && j != best)
3186 		    rsrv_count[side][j]--;
3187 
3188 		INSN_INFO_ENTRY (uid).reservation
3189 		  = best + side * UNIT_QID_SIDE_OFFSET;
3190 	      }
3191 	  }
3192     }
3193 }
3194 
3195 /* Return a factor by which to weight unit imbalances for a reservation
3196    R.  */
3197 static int
3198 unit_req_factor (enum unitreqs r)
3199 {
3200   switch (r)
3201     {
3202     case UNIT_REQ_D:
3203     case UNIT_REQ_L:
3204     case UNIT_REQ_S:
3205     case UNIT_REQ_M:
3206     case UNIT_REQ_X:
3207     case UNIT_REQ_T:
3208       return 1;
3209     case UNIT_REQ_DL:
3210     case UNIT_REQ_LS:
3211     case UNIT_REQ_DS:
3212       return 2;
3213     case UNIT_REQ_DLS:
3214       return 3;
3215     default:
3216       gcc_unreachable ();
3217     }
3218 }
3219 
3220 /* Examine INSN, and store in REQ1/SIDE1 and REQ2/SIDE2 the unit
3221    requirements.  Returns zero if INSN can't be handled, otherwise
3222    either one or two to show how many of the two pairs are in use.
3223    REQ1 is always used, it holds what is normally thought of as the
3224    instructions reservation, e.g. UNIT_REQ_DL.  REQ2 is used to either
3225    describe a cross path, or for loads/stores, the T unit.  */
3226 static int
3227 get_unit_reqs (rtx_insn *insn, int *req1, int *side1, int *req2, int *side2)
3228 {
3229   enum attr_units units;
3230   enum attr_cross cross;
3231   int side, req;
3232 
3233   if (!NONDEBUG_INSN_P (insn) || recog_memoized (insn) < 0)
3234     return 0;
3235   units = get_attr_units (insn);
3236   if (units == UNITS_UNKNOWN)
3237     return 0;
3238   side = get_insn_side (insn, units);
3239   cross = get_attr_cross (insn);
3240 
3241   req = (units == UNITS_D ? UNIT_REQ_D
3242 	 : units == UNITS_D_ADDR ? UNIT_REQ_D
3243 	 : units == UNITS_DL ? UNIT_REQ_DL
3244 	 : units == UNITS_DS ? UNIT_REQ_DS
3245 	 : units == UNITS_L ? UNIT_REQ_L
3246 	 : units == UNITS_LS ? UNIT_REQ_LS
3247 	 : units == UNITS_S ? UNIT_REQ_S
3248 	 : units == UNITS_M ? UNIT_REQ_M
3249 	 : units == UNITS_DLS ? UNIT_REQ_DLS
3250 	 : -1);
3251   gcc_assert (req != -1);
3252   *req1 = req;
3253   *side1 = side;
3254   if (units == UNITS_D_ADDR)
3255     {
3256       *req2 = UNIT_REQ_T;
3257       *side2 = side ^ (cross == CROSS_Y ? 1 : 0);
3258       return 2;
3259     }
3260   else if (cross == CROSS_Y)
3261     {
3262       *req2 = UNIT_REQ_X;
3263       *side2 = side;
3264       return 2;
3265     }
3266   return 1;
3267 }
3268 
3269 /* Walk the insns between and including HEAD and TAIL, and mark the
3270    resource requirements in the unit_reqs table.  */
3271 static void
3272 count_unit_reqs (unit_req_table reqs, rtx_insn *head, rtx_insn *tail)
3273 {
3274   rtx_insn *insn;
3275 
3276   memset (reqs, 0, sizeof (unit_req_table));
3277 
3278   for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
3279     {
3280       int side1, side2, req1, req2;
3281 
3282       switch (get_unit_reqs (insn, &req1, &side1, &req2, &side2))
3283 	{
3284 	case 2:
3285 	  reqs[side2][req2]++;
3286 	  /* fall through */
3287 	case 1:
3288 	  reqs[side1][req1]++;
3289 	  break;
3290 	}
3291     }
3292 }
3293 
3294 /* Update the table REQS by merging more specific unit reservations into
3295    more general ones, i.e. counting (for example) UNIT_REQ_D also in
3296    UNIT_REQ_DL, DS, and DLS.  */
3297 static void
3298 merge_unit_reqs (unit_req_table reqs)
3299 {
3300   int side;
3301   for (side = 0; side < 2; side++)
3302     {
3303       int d = reqs[side][UNIT_REQ_D];
3304       int l = reqs[side][UNIT_REQ_L];
3305       int s = reqs[side][UNIT_REQ_S];
3306       int dl = reqs[side][UNIT_REQ_DL];
3307       int ls = reqs[side][UNIT_REQ_LS];
3308       int ds = reqs[side][UNIT_REQ_DS];
3309 
3310       reqs[side][UNIT_REQ_DL] += d;
3311       reqs[side][UNIT_REQ_DL] += l;
3312       reqs[side][UNIT_REQ_DS] += d;
3313       reqs[side][UNIT_REQ_DS] += s;
3314       reqs[side][UNIT_REQ_LS] += l;
3315       reqs[side][UNIT_REQ_LS] += s;
3316       reqs[side][UNIT_REQ_DLS] += ds + dl + ls + d + l + s;
3317     }
3318 }
3319 
3320 /* Examine the table REQS and return a measure of unit imbalance by comparing
3321    the two sides of the machine.  If, for example, D1 is used twice and D2
3322    used not at all, the return value should be 1 in the absence of other
3323    imbalances.  */
3324 static int
3325 unit_req_imbalance (unit_req_table reqs)
3326 {
3327   int val = 0;
3328   int i;
3329 
3330   for (i = 0; i < UNIT_REQ_MAX; i++)
3331     {
3332       int factor = unit_req_factor ((enum unitreqs) i);
3333       int diff = abs (reqs[0][i] - reqs[1][i]);
3334       val += (diff + factor - 1) / factor / 2;
3335     }
3336   return val;
3337 }
3338 
3339 /* Return the resource-constrained minimum iteration interval given the
3340    data in the REQS table.  This must have been processed with
3341    merge_unit_reqs already.  */
3342 static int
3343 res_mii (unit_req_table reqs)
3344 {
3345   int side, req;
3346   int worst = 1;
3347   for (side = 0; side < 2; side++)
3348     for (req = 0; req < UNIT_REQ_MAX; req++)
3349       {
3350 	int factor = unit_req_factor ((enum unitreqs) req);
3351 	worst = MAX ((reqs[side][UNIT_REQ_D] + factor - 1) / factor, worst);
3352       }
3353 
3354   return worst;
3355 }
3356 
3357 /* Examine INSN, and store in PMASK1 and PMASK2 bitmasks that represent
3358    the operands that are involved in the (up to) two reservations, as
3359    found by get_unit_reqs.  Return true if we did this successfully, false
3360    if we couldn't identify what to do with INSN.  */
3361 static bool
3362 get_unit_operand_masks (rtx_insn *insn, unsigned int *pmask1,
3363 			unsigned int *pmask2)
3364 {
3365   enum attr_op_pattern op_pat;
3366 
3367   if (recog_memoized (insn) < 0)
3368     return 0;
3369   if (GET_CODE (PATTERN (insn)) == COND_EXEC)
3370     return false;
3371   extract_insn (insn);
3372   op_pat = get_attr_op_pattern (insn);
3373   if (op_pat == OP_PATTERN_DT)
3374     {
3375       gcc_assert (recog_data.n_operands == 2);
3376       *pmask1 = 1 << 0;
3377       *pmask2 = 1 << 1;
3378       return true;
3379     }
3380   else if (op_pat == OP_PATTERN_TD)
3381     {
3382       gcc_assert (recog_data.n_operands == 2);
3383       *pmask1 = 1 << 1;
3384       *pmask2 = 1 << 0;
3385       return true;
3386     }
3387   else if (op_pat == OP_PATTERN_SXS)
3388     {
3389       gcc_assert (recog_data.n_operands == 3);
3390       *pmask1 = (1 << 0) | (1 << 2);
3391       *pmask2 = 1 << 1;
3392       return true;
3393     }
3394   else if (op_pat == OP_PATTERN_SX)
3395     {
3396       gcc_assert (recog_data.n_operands == 2);
3397       *pmask1 = 1 << 0;
3398       *pmask2 = 1 << 1;
3399       return true;
3400     }
3401   else if (op_pat == OP_PATTERN_SSX)
3402     {
3403       gcc_assert (recog_data.n_operands == 3);
3404       *pmask1 = (1 << 0) | (1 << 1);
3405       *pmask2 = 1 << 2;
3406       return true;
3407     }
3408   return false;
3409 }
3410 
3411 /* Try to replace a register in INSN, which has corresponding rename info
3412    from regrename_analyze in INFO.  OP_MASK and ORIG_SIDE provide information
3413    about the operands that must be renamed and the side they are on.
3414    REQS is the table of unit reservations in the loop between HEAD and TAIL.
3415    We recompute this information locally after our transformation, and keep
3416    it only if we managed to improve the balance.  */
3417 static void
3418 try_rename_operands (rtx_insn *head, rtx_insn *tail, unit_req_table reqs,
3419 		     rtx insn,
3420 		     insn_rr_info *info, unsigned int op_mask, int orig_side)
3421 {
3422   enum reg_class super_class = orig_side == 0 ? B_REGS : A_REGS;
3423   HARD_REG_SET unavailable;
3424   du_head_p this_head;
3425   struct du_chain *chain;
3426   int i;
3427   unsigned tmp_mask;
3428   int best_reg, old_reg;
3429   vec<du_head_p> involved_chains = vNULL;
3430   unit_req_table new_reqs;
3431   bool ok;
3432 
3433   for (i = 0, tmp_mask = op_mask; tmp_mask; i++)
3434     {
3435       du_head_p op_chain;
3436       if ((tmp_mask & (1 << i)) == 0)
3437 	continue;
3438       if (info->op_info[i].n_chains != 1)
3439 	goto out_fail;
3440       op_chain = regrename_chain_from_id (info->op_info[i].heads[0]->id);
3441       involved_chains.safe_push (op_chain);
3442       tmp_mask &= ~(1 << i);
3443     }
3444 
3445   if (involved_chains.length () > 1)
3446     goto out_fail;
3447 
3448   this_head = involved_chains[0];
3449   if (this_head->cannot_rename)
3450     goto out_fail;
3451 
3452   for (chain = this_head->first; chain; chain = chain->next_use)
3453     {
3454       unsigned int mask1, mask2, mask_changed;
3455       int count, side1, side2, req1, req2;
3456       insn_rr_info *this_rr = &insn_rr[INSN_UID (chain->insn)];
3457 
3458       count = get_unit_reqs (chain->insn, &req1, &side1, &req2, &side2);
3459 
3460       if (count == 0)
3461 	goto out_fail;
3462 
3463       if (!get_unit_operand_masks (chain->insn, &mask1, &mask2))
3464 	goto out_fail;
3465 
3466       extract_insn (chain->insn);
3467 
3468       mask_changed = 0;
3469       for (i = 0; i < recog_data.n_operands; i++)
3470 	{
3471 	  int j;
3472 	  int n_this_op = this_rr->op_info[i].n_chains;
3473 	  for (j = 0; j < n_this_op; j++)
3474 	    {
3475 	      du_head_p other = this_rr->op_info[i].heads[j];
3476 	      if (regrename_chain_from_id (other->id) == this_head)
3477 		break;
3478 	    }
3479 	  if (j == n_this_op)
3480 	    continue;
3481 
3482 	  if (n_this_op != 1)
3483 	    goto out_fail;
3484 	  mask_changed |= 1 << i;
3485 	}
3486       gcc_assert (mask_changed != 0);
3487       if (mask_changed != mask1 && mask_changed != mask2)
3488 	goto out_fail;
3489     }
3490 
3491   /* If we get here, we can do the renaming.  */
3492   COMPL_HARD_REG_SET (unavailable, reg_class_contents[(int) super_class]);
3493 
3494   old_reg = this_head->regno;
3495   best_reg =
3496     find_rename_reg (this_head, super_class, &unavailable, old_reg, true);
3497 
3498   ok = regrename_do_replace (this_head, best_reg);
3499   gcc_assert (ok);
3500 
3501   count_unit_reqs (new_reqs, head, PREV_INSN (tail));
3502   merge_unit_reqs (new_reqs);
3503   if (dump_file)
3504     {
3505       fprintf (dump_file, "reshuffle for insn %d, op_mask %x, "
3506 	       "original side %d, new reg %d\n",
3507 	       INSN_UID (insn), op_mask, orig_side, best_reg);
3508       fprintf (dump_file, "  imbalance %d -> %d\n",
3509 	       unit_req_imbalance (reqs), unit_req_imbalance (new_reqs));
3510     }
3511   if (unit_req_imbalance (new_reqs) > unit_req_imbalance (reqs))
3512     {
3513       ok = regrename_do_replace (this_head, old_reg);
3514       gcc_assert (ok);
3515     }
3516   else
3517     memcpy (reqs, new_reqs, sizeof (unit_req_table));
3518 
3519  out_fail:
3520   involved_chains.release ();
3521 }
3522 
3523 /* Find insns in LOOP which would, if shifted to the other side
3524    of the machine, reduce an imbalance in the unit reservations.  */
3525 static void
3526 reshuffle_units (basic_block loop)
3527 {
3528   rtx_insn *head = BB_HEAD (loop);
3529   rtx_insn *tail = BB_END (loop);
3530   rtx_insn *insn;
3531   unit_req_table reqs;
3532   edge e;
3533   edge_iterator ei;
3534   bitmap_head bbs;
3535 
3536   count_unit_reqs (reqs, head, PREV_INSN (tail));
3537   merge_unit_reqs (reqs);
3538 
3539   regrename_init (true);
3540 
3541   bitmap_initialize (&bbs, &bitmap_default_obstack);
3542 
3543   FOR_EACH_EDGE (e, ei, loop->preds)
3544     bitmap_set_bit (&bbs, e->src->index);
3545 
3546   bitmap_set_bit (&bbs, loop->index);
3547   regrename_analyze (&bbs);
3548 
3549   for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
3550     {
3551       enum attr_units units;
3552       int count, side1, side2, req1, req2;
3553       unsigned int mask1, mask2;
3554       insn_rr_info *info;
3555 
3556       if (!NONDEBUG_INSN_P (insn))
3557 	continue;
3558 
3559       count = get_unit_reqs (insn, &req1, &side1, &req2, &side2);
3560 
3561       if (count == 0)
3562 	continue;
3563 
3564       if (!get_unit_operand_masks (insn, &mask1, &mask2))
3565 	continue;
3566 
3567       info = &insn_rr[INSN_UID (insn)];
3568       if (info->op_info == NULL)
3569 	continue;
3570 
3571       if (reqs[side1][req1] > 1
3572 	  && reqs[side1][req1] > 2 * reqs[side1 ^ 1][req1])
3573 	{
3574 	  try_rename_operands (head, tail, reqs, insn, info, mask1, side1);
3575 	}
3576 
3577       units = get_attr_units (insn);
3578       if (units == UNITS_D_ADDR)
3579 	{
3580 	  gcc_assert (count == 2);
3581 	  if (reqs[side2][req2] > 1
3582 	      && reqs[side2][req2] > 2 * reqs[side2 ^ 1][req2])
3583 	    {
3584 	      try_rename_operands (head, tail, reqs, insn, info, mask2, side2);
3585 	    }
3586 	}
3587     }
3588   regrename_finish ();
3589 }
3590 
3591 /* Backend scheduling state.  */
3592 typedef struct c6x_sched_context
3593 {
3594   /* The current scheduler clock, saved in the sched_reorder hook.  */
3595   int curr_sched_clock;
3596 
3597   /* Number of insns issued so far in this cycle.  */
3598   int issued_this_cycle;
3599 
3600   /* We record the time at which each jump occurs in JUMP_CYCLES.  The
3601      theoretical maximum for number of jumps in flight is 12: 2 every
3602      cycle, with a latency of 6 cycles each.  This is a circular
3603      buffer; JUMP_CYCLE_INDEX is the pointer to the start.  Earlier
3604      jumps have a higher index.  This array should be accessed through
3605      the jump_cycle function.  */
3606   int jump_cycles[12];
3607   int jump_cycle_index;
3608 
3609   /* In parallel with jump_cycles, this array records the opposite of
3610      the condition used in each pending jump.  This is used to
3611      predicate insns that are scheduled in the jump's delay slots.  If
3612      this is NULL_RTX no such predication happens.  */
3613   rtx jump_cond[12];
3614 
3615   /* Similar to the jump_cycles mechanism, but here we take into
3616      account all insns with delay slots, to avoid scheduling asms into
3617      the delay slots.  */
3618   int delays_finished_at;
3619 
3620   /* The following variable value is the last issued insn.  */
3621   rtx_insn *last_scheduled_insn;
3622   /* The last issued insn that isn't a shadow of another.  */
3623   rtx_insn *last_scheduled_iter0;
3624 
3625   /* The following variable value is DFA state before issuing the
3626      first insn in the current clock cycle.  We do not use this member
3627      of the structure directly; we copy the data in and out of
3628      prev_cycle_state.  */
3629   state_t prev_cycle_state_ctx;
3630 
3631   int reg_n_accesses[FIRST_PSEUDO_REGISTER];
3632   int reg_n_xaccesses[FIRST_PSEUDO_REGISTER];
3633   int reg_set_in_cycle[FIRST_PSEUDO_REGISTER];
3634 
3635   int tmp_reg_n_accesses[FIRST_PSEUDO_REGISTER];
3636   int tmp_reg_n_xaccesses[FIRST_PSEUDO_REGISTER];
3637 } *c6x_sched_context_t;
3638 
3639 /* The current scheduling state.  */
3640 static struct c6x_sched_context ss;
3641 
3642 /* The following variable value is DFA state before issuing the first insn
3643    in the current clock cycle.  This is used in c6x_variable_issue for
3644    comparison with the state after issuing the last insn in a cycle.  */
3645 static state_t prev_cycle_state;
3646 
3647 /* Set when we discover while processing an insn that it would lead to too
3648    many accesses of the same register.  */
3649 static bool reg_access_stall;
3650 
3651 /* The highest insn uid after delayed insns were split, but before loop bodies
3652    were copied by the modulo scheduling code.  */
3653 static int sploop_max_uid_iter0;
3654 
3655 /* Look up the jump cycle with index N.  For an out-of-bounds N, we return 0,
3656    so the caller does not specifically have to test for it.  */
3657 static int
3658 get_jump_cycle (int n)
3659 {
3660   if (n >= 12)
3661     return 0;
3662   n += ss.jump_cycle_index;
3663   if (n >= 12)
3664     n -= 12;
3665   return ss.jump_cycles[n];
3666 }
3667 
3668 /* Look up the jump condition with index N.  */
3669 static rtx
3670 get_jump_cond (int n)
3671 {
3672   if (n >= 12)
3673     return NULL_RTX;
3674   n += ss.jump_cycle_index;
3675   if (n >= 12)
3676     n -= 12;
3677   return ss.jump_cond[n];
3678 }
3679 
3680 /* Return the index of the first jump that occurs after CLOCK_VAR.  If no jump
3681    has delay slots beyond CLOCK_VAR, return -1.  */
3682 static int
3683 first_jump_index (int clock_var)
3684 {
3685   int retval = -1;
3686   int n = 0;
3687   for (;;)
3688     {
3689       int t = get_jump_cycle (n);
3690       if (t <= clock_var)
3691 	break;
3692       retval = n;
3693       n++;
3694     }
3695   return retval;
3696 }
3697 
3698 /* Add a new entry in our scheduling state for a jump that occurs in CYCLE
3699    and has the opposite condition of COND.  */
3700 static void
3701 record_jump (int cycle, rtx cond)
3702 {
3703   if (ss.jump_cycle_index == 0)
3704     ss.jump_cycle_index = 11;
3705   else
3706     ss.jump_cycle_index--;
3707   ss.jump_cycles[ss.jump_cycle_index] = cycle;
3708   ss.jump_cond[ss.jump_cycle_index] = cond;
3709 }
3710 
3711 /* Set the clock cycle of INSN to CYCLE.  Also clears the insn's entry in
3712    new_conditions.  */
3713 static void
3714 insn_set_clock (rtx insn, int cycle)
3715 {
3716   unsigned uid = INSN_UID (insn);
3717 
3718   if (uid >= INSN_INFO_LENGTH)
3719     insn_info.safe_grow (uid * 5 / 4 + 10);
3720 
3721   INSN_INFO_ENTRY (uid).clock = cycle;
3722   INSN_INFO_ENTRY (uid).new_cond = NULL;
3723   INSN_INFO_ENTRY (uid).reservation = 0;
3724   INSN_INFO_ENTRY (uid).ebb_start = false;
3725 }
3726 
3727 /* Return the clock cycle we set for the insn with uid UID.  */
3728 static int
3729 insn_uid_get_clock (int uid)
3730 {
3731   return INSN_INFO_ENTRY (uid).clock;
3732 }
3733 
3734 /* Return the clock cycle we set for INSN.  */
3735 static int
3736 insn_get_clock (rtx insn)
3737 {
3738   return insn_uid_get_clock (INSN_UID (insn));
3739 }
3740 
3741 /* Examine INSN, and if it is a conditional jump of any kind, return
3742    the opposite of the condition in which it branches.  Otherwise,
3743    return NULL_RTX.  */
3744 static rtx
3745 condjump_opposite_condition (rtx insn)
3746 {
3747   rtx pat = PATTERN (insn);
3748   int icode = INSN_CODE (insn);
3749   rtx x = NULL;
3750 
3751   if (icode == CODE_FOR_br_true || icode == CODE_FOR_br_false)
3752     {
3753       x = XEXP (SET_SRC (pat), 0);
3754       if (icode == CODE_FOR_br_false)
3755 	return x;
3756     }
3757   if (GET_CODE (pat) == COND_EXEC)
3758     {
3759       rtx t = COND_EXEC_CODE (pat);
3760       if ((GET_CODE (t) == PARALLEL
3761 	   && GET_CODE (XVECEXP (t, 0, 0)) == RETURN)
3762 	  || (GET_CODE (t) == UNSPEC && XINT (t, 1) == UNSPEC_REAL_JUMP)
3763 	  || (GET_CODE (t) == SET && SET_DEST (t) == pc_rtx))
3764 	x = COND_EXEC_TEST (pat);
3765     }
3766 
3767   if (x != NULL_RTX)
3768     {
3769       enum rtx_code code = GET_CODE (x);
3770       x = gen_rtx_fmt_ee (code == EQ ? NE : EQ,
3771 			  GET_MODE (x), XEXP (x, 0),
3772 			  XEXP (x, 1));
3773     }
3774   return x;
3775 }
3776 
3777 /* Return true iff COND1 and COND2 are exactly opposite conditions
3778    one of them NE and the other EQ.  */
3779 static bool
3780 conditions_opposite_p (rtx cond1, rtx cond2)
3781 {
3782   return (rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
3783 	  && rtx_equal_p (XEXP (cond1, 1), XEXP (cond2, 1))
3784 	  && GET_CODE (cond1) == reverse_condition (GET_CODE (cond2)));
3785 }
3786 
3787 /* Return true if we can add a predicate COND to INSN, or if INSN
3788    already has that predicate.  If DOIT is true, also perform the
3789    modification.  */
3790 static bool
3791 predicate_insn (rtx_insn *insn, rtx cond, bool doit)
3792 {
3793   int icode;
3794   if (cond == NULL_RTX)
3795     {
3796       gcc_assert (!doit);
3797       return false;
3798     }
3799 
3800   if (get_attr_predicable (insn) == PREDICABLE_YES
3801       && GET_CODE (PATTERN (insn)) != COND_EXEC)
3802     {
3803       if (doit)
3804 	{
3805 	  cond = copy_rtx (cond);
3806 	  rtx newpat = gen_rtx_COND_EXEC (VOIDmode, cond, PATTERN (insn));
3807 	  PATTERN (insn) = newpat;
3808 	  INSN_CODE (insn) = -1;
3809 	}
3810       return true;
3811     }
3812   if (GET_CODE (PATTERN (insn)) == COND_EXEC
3813       && rtx_equal_p (COND_EXEC_TEST (PATTERN (insn)), cond))
3814     return true;
3815   icode = INSN_CODE (insn);
3816   if (icode == CODE_FOR_real_jump
3817       || icode == CODE_FOR_jump
3818       || icode == CODE_FOR_indirect_jump)
3819     {
3820       rtx pat = PATTERN (insn);
3821       rtx dest = (icode == CODE_FOR_real_jump ? XVECEXP (pat, 0, 0)
3822 		  : icode == CODE_FOR_jump ? XEXP (SET_SRC (pat), 0)
3823 		  : SET_SRC (pat));
3824       if (doit)
3825 	{
3826 	  rtx newpat;
3827 	  if (REG_P (dest))
3828 	    newpat = gen_rtx_COND_EXEC (VOIDmode, cond, PATTERN (insn));
3829 	  else
3830 	    newpat = gen_br_true (cond, XEXP (cond, 0), dest);
3831 	  PATTERN (insn) = newpat;
3832 	  INSN_CODE (insn) = -1;
3833 	}
3834       return true;
3835     }
3836   if (INSN_CODE (insn) == CODE_FOR_br_true)
3837     {
3838       rtx br_cond = XEXP (SET_SRC (PATTERN (insn)), 0);
3839       return rtx_equal_p (br_cond, cond);
3840     }
3841   if (INSN_CODE (insn) == CODE_FOR_br_false)
3842     {
3843       rtx br_cond = XEXP (SET_SRC (PATTERN (insn)), 0);
3844       return conditions_opposite_p (br_cond, cond);
3845     }
3846   return false;
3847 }
3848 
3849 /* Initialize SC.  Used by c6x_init_sched_context and c6x_sched_init.  */
3850 static void
3851 init_sched_state (c6x_sched_context_t sc)
3852 {
3853   sc->last_scheduled_insn = NULL;
3854   sc->last_scheduled_iter0 = NULL;
3855   sc->issued_this_cycle = 0;
3856   memset (sc->jump_cycles, 0, sizeof sc->jump_cycles);
3857   memset (sc->jump_cond, 0, sizeof sc->jump_cond);
3858   sc->jump_cycle_index = 0;
3859   sc->delays_finished_at = 0;
3860   sc->curr_sched_clock = 0;
3861 
3862   sc->prev_cycle_state_ctx = xmalloc (dfa_state_size);
3863 
3864   memset (sc->reg_n_accesses, 0, sizeof sc->reg_n_accesses);
3865   memset (sc->reg_n_xaccesses, 0, sizeof sc->reg_n_xaccesses);
3866   memset (sc->reg_set_in_cycle, 0, sizeof sc->reg_set_in_cycle);
3867 
3868   state_reset (sc->prev_cycle_state_ctx);
3869 }
3870 
3871 /* Allocate store for new scheduling context.  */
3872 static void *
3873 c6x_alloc_sched_context (void)
3874 {
3875   return xmalloc (sizeof (struct c6x_sched_context));
3876 }
3877 
3878 /* If CLEAN_P is true then initializes _SC with clean data,
3879    and from the global context otherwise.  */
3880 static void
3881 c6x_init_sched_context (void *_sc, bool clean_p)
3882 {
3883   c6x_sched_context_t sc = (c6x_sched_context_t) _sc;
3884 
3885   if (clean_p)
3886     {
3887       init_sched_state (sc);
3888     }
3889   else
3890     {
3891       *sc = ss;
3892       sc->prev_cycle_state_ctx = xmalloc (dfa_state_size);
3893       memcpy (sc->prev_cycle_state_ctx, prev_cycle_state, dfa_state_size);
3894     }
3895 }
3896 
3897 /* Sets the global scheduling context to the one pointed to by _SC.  */
3898 static void
3899 c6x_set_sched_context (void *_sc)
3900 {
3901   c6x_sched_context_t sc = (c6x_sched_context_t) _sc;
3902 
3903   gcc_assert (sc != NULL);
3904   ss = *sc;
3905   memcpy (prev_cycle_state, sc->prev_cycle_state_ctx, dfa_state_size);
3906 }
3907 
3908 /* Clear data in _SC.  */
3909 static void
3910 c6x_clear_sched_context (void *_sc)
3911 {
3912   c6x_sched_context_t sc = (c6x_sched_context_t) _sc;
3913   gcc_assert (_sc != NULL);
3914 
3915   free (sc->prev_cycle_state_ctx);
3916 }
3917 
3918 /* Free _SC.  */
3919 static void
3920 c6x_free_sched_context (void *_sc)
3921 {
3922   free (_sc);
3923 }
3924 
3925 /* True if we are currently performing a preliminary scheduling
3926    pass before modulo scheduling; we can't allow the scheduler to
3927    modify instruction patterns using packetization assumptions,
3928    since there will be another scheduling pass later if modulo
3929    scheduling fails.  */
3930 static bool in_hwloop;
3931 
3932 /* Provide information about speculation capabilities, and set the
3933    DO_BACKTRACKING flag.  */
3934 static void
3935 c6x_set_sched_flags (spec_info_t spec_info)
3936 {
3937   unsigned int *flags = &(current_sched_info->flags);
3938 
3939   if (*flags & SCHED_EBB)
3940     {
3941       *flags |= DO_BACKTRACKING | DO_PREDICATION;
3942     }
3943   if (in_hwloop)
3944     *flags |= DONT_BREAK_DEPENDENCIES;
3945 
3946   spec_info->mask = 0;
3947 }
3948 
3949 /* Implement the TARGET_SCHED_ISSUE_RATE hook.  */
3950 
3951 static int
3952 c6x_issue_rate (void)
3953 {
3954   return 8;
3955 }
3956 
3957 /* Used together with the collapse_ndfa option, this ensures that we reach a
3958    deterministic automaton state before trying to advance a cycle.
3959    With collapse_ndfa, genautomata creates advance cycle arcs only for
3960    such deterministic states.  */
3961 
3962 static rtx
3963 c6x_sched_dfa_pre_cycle_insn (void)
3964 {
3965   return const0_rtx;
3966 }
3967 
3968 /* We're beginning a new block.  Initialize data structures as necessary.  */
3969 
3970 static void
3971 c6x_sched_init (FILE *dump ATTRIBUTE_UNUSED,
3972 		int sched_verbose ATTRIBUTE_UNUSED,
3973 		int max_ready ATTRIBUTE_UNUSED)
3974 {
3975   if (prev_cycle_state == NULL)
3976     {
3977       prev_cycle_state = xmalloc (dfa_state_size);
3978     }
3979   init_sched_state (&ss);
3980   state_reset (prev_cycle_state);
3981 }
3982 
3983 /* We are about to being issuing INSN.  Return nonzero if we cannot
3984    issue it on given cycle CLOCK and return zero if we should not sort
3985    the ready queue on the next clock start.
3986    For C6X, we use this function just to copy the previous DFA state
3987    for comparison purposes.  */
3988 
3989 static int
3990 c6x_dfa_new_cycle (FILE *dump ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
3991 		   rtx_insn *insn ATTRIBUTE_UNUSED,
3992 		   int last_clock ATTRIBUTE_UNUSED,
3993 		   int clock ATTRIBUTE_UNUSED, int *sort_p ATTRIBUTE_UNUSED)
3994 {
3995   if (clock != last_clock)
3996     memcpy (prev_cycle_state, curr_state, dfa_state_size);
3997   return 0;
3998 }
3999 
4000 static void
4001 c6x_mark_regno_read (int regno, bool cross)
4002 {
4003   int t = ++ss.tmp_reg_n_accesses[regno];
4004 
4005   if (t > 4)
4006     reg_access_stall = true;
4007 
4008   if (cross)
4009     {
4010       int set_cycle = ss.reg_set_in_cycle[regno];
4011       /* This must be done in this way rather than by tweaking things in
4012 	 adjust_cost, since the stall occurs even for insns with opposite
4013 	 predicates, and the scheduler may not even see a dependency.  */
4014       if (set_cycle > 0 && set_cycle == ss.curr_sched_clock)
4015 	reg_access_stall = true;
4016       /* This doesn't quite do anything yet as we're only modeling one
4017 	 x unit.  */
4018       ++ss.tmp_reg_n_xaccesses[regno];
4019     }
4020 }
4021 
4022 /* Note that REG is read in the insn being examined.  If CROSS, it
4023    means the access is through a cross path.  Update the temporary reg
4024    access arrays, and set REG_ACCESS_STALL if the insn can't be issued
4025    in the current cycle.  */
4026 
4027 static void
4028 c6x_mark_reg_read (rtx reg, bool cross)
4029 {
4030   unsigned regno = REGNO (reg);
4031   unsigned nregs = REG_NREGS (reg);
4032 
4033   while (nregs-- > 0)
4034     c6x_mark_regno_read (regno + nregs, cross);
4035 }
4036 
4037 /* Note that register REG is written in cycle CYCLES.  */
4038 
4039 static void
4040 c6x_mark_reg_written (rtx reg, int cycles)
4041 {
4042   unsigned regno = REGNO (reg);
4043   unsigned nregs = REG_NREGS (reg);
4044 
4045   while (nregs-- > 0)
4046     ss.reg_set_in_cycle[regno + nregs] = cycles;
4047 }
4048 
4049 /* Update the register state information for an instruction whose
4050    body is X.  Return true if the instruction has to be delayed until the
4051    next cycle.  */
4052 
4053 static bool
4054 c6x_registers_update (rtx_insn *insn)
4055 {
4056   enum attr_cross cross;
4057   enum attr_dest_regfile destrf;
4058   int i, nops;
4059   rtx x;
4060 
4061   if (!reload_completed || recog_memoized (insn) < 0)
4062     return false;
4063 
4064   reg_access_stall = false;
4065   memcpy (ss.tmp_reg_n_accesses, ss.reg_n_accesses,
4066 	  sizeof ss.tmp_reg_n_accesses);
4067   memcpy (ss.tmp_reg_n_xaccesses, ss.reg_n_xaccesses,
4068 	  sizeof ss.tmp_reg_n_xaccesses);
4069 
4070   extract_insn (insn);
4071 
4072   cross = get_attr_cross (insn);
4073   destrf = get_attr_dest_regfile (insn);
4074 
4075   nops = recog_data.n_operands;
4076   x = PATTERN (insn);
4077   if (GET_CODE (x) == COND_EXEC)
4078     {
4079       c6x_mark_reg_read (XEXP (XEXP (x, 0), 0), false);
4080       nops -= 2;
4081     }
4082 
4083   for (i = 0; i < nops; i++)
4084     {
4085       rtx op = recog_data.operand[i];
4086       if (recog_data.operand_type[i] == OP_OUT)
4087 	continue;
4088       if (REG_P (op))
4089 	{
4090 	  bool this_cross = cross;
4091 	  if (destrf == DEST_REGFILE_A && A_REGNO_P (REGNO (op)))
4092 	    this_cross = false;
4093 	  if (destrf == DEST_REGFILE_B && B_REGNO_P (REGNO (op)))
4094 	    this_cross = false;
4095 	  c6x_mark_reg_read (op, this_cross);
4096 	}
4097       else if (MEM_P (op))
4098 	{
4099 	  op = XEXP (op, 0);
4100 	  switch (GET_CODE (op))
4101 	    {
4102 	    case POST_INC:
4103 	    case PRE_INC:
4104 	    case POST_DEC:
4105 	    case PRE_DEC:
4106 	      op = XEXP (op, 0);
4107 	      /* fall through */
4108 	    case REG:
4109 	      c6x_mark_reg_read (op, false);
4110 	      break;
4111 	    case POST_MODIFY:
4112 	    case PRE_MODIFY:
4113 	      op = XEXP (op, 1);
4114 	      gcc_assert (GET_CODE (op) == PLUS);
4115 	      /* fall through */
4116 	    case PLUS:
4117 	      c6x_mark_reg_read (XEXP (op, 0), false);
4118 	      if (REG_P (XEXP (op, 1)))
4119 		c6x_mark_reg_read (XEXP (op, 1), false);
4120 	      break;
4121 	    case SYMBOL_REF:
4122 	    case LABEL_REF:
4123 	    case CONST:
4124 	      c6x_mark_regno_read (REG_B14, false);
4125 	      break;
4126 	    default:
4127 	      gcc_unreachable ();
4128 	    }
4129 	}
4130       else if (!CONSTANT_P (op) && strlen (recog_data.constraints[i]) > 0)
4131 	gcc_unreachable ();
4132     }
4133   return reg_access_stall;
4134 }
4135 
4136 /* Helper function for the TARGET_SCHED_REORDER and
4137    TARGET_SCHED_REORDER2 hooks.  If scheduling an insn would be unsafe
4138    in the current cycle, move it down in the ready list and return the
4139    number of non-unsafe insns.  */
4140 
4141 static int
4142 c6x_sched_reorder_1 (rtx_insn **ready, int *pn_ready, int clock_var)
4143 {
4144   int n_ready = *pn_ready;
4145   rtx_insn **e_ready = ready + n_ready;
4146   rtx_insn **insnp;
4147   int first_jump;
4148 
4149   /* Keep track of conflicts due to a limit number of register accesses,
4150      and due to stalls incurred by too early accesses of registers using
4151      cross paths.  */
4152 
4153   for (insnp = ready; insnp < e_ready; insnp++)
4154     {
4155       rtx_insn *insn = *insnp;
4156       int icode = recog_memoized (insn);
4157       bool is_asm = (icode < 0
4158 		     && (GET_CODE (PATTERN (insn)) == ASM_INPUT
4159 			 || asm_noperands (PATTERN (insn)) >= 0));
4160       bool no_parallel = (is_asm || icode == CODE_FOR_sploop
4161 			  || (icode >= 0
4162 			      && get_attr_type (insn) == TYPE_ATOMIC));
4163 
4164       /* We delay asm insns until all delay slots are exhausted.  We can't
4165 	 accurately tell how many cycles an asm takes, and the main scheduling
4166 	 code always assumes at least 1 cycle, which may be wrong.  */
4167       if ((no_parallel
4168 	   && (ss.issued_this_cycle > 0 || clock_var < ss.delays_finished_at))
4169 	  || c6x_registers_update (insn)
4170 	  || (ss.issued_this_cycle > 0 && icode == CODE_FOR_sploop))
4171 	{
4172 	  memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
4173 	  *ready = insn;
4174 	  n_ready--;
4175 	  ready++;
4176 	}
4177       else if (shadow_p (insn))
4178 	{
4179 	  memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
4180 	  *ready = insn;
4181 	}
4182     }
4183 
4184   /* Ensure that no other jump is scheduled in jump delay slots, since
4185      it would put the machine into the wrong state.  Also, we must
4186      avoid scheduling insns that have a latency longer than the
4187      remaining jump delay slots, as the code at the jump destination
4188      won't be prepared for it.
4189 
4190      However, we can relax this condition somewhat.  The rest of the
4191      scheduler will automatically avoid scheduling an insn on which
4192      the jump shadow depends so late that its side effect happens
4193      after the jump.  This means that if we see an insn with a longer
4194      latency here, it can safely be scheduled if we can ensure that it
4195      has a predicate opposite of the previous jump: the side effect
4196      will happen in what we think of as the same basic block.  In
4197      c6x_variable_issue, we will record the necessary predicate in
4198      new_conditions, and after scheduling is finished, we will modify
4199      the insn.
4200 
4201      Special care must be taken whenever there is more than one jump
4202      in flight.  */
4203 
4204   first_jump = first_jump_index (clock_var);
4205   if (first_jump != -1)
4206     {
4207       int first_cycle = get_jump_cycle (first_jump);
4208       rtx first_cond = get_jump_cond (first_jump);
4209       int second_cycle = 0;
4210 
4211       if (first_jump > 0)
4212 	second_cycle = get_jump_cycle (first_jump - 1);
4213 
4214       for (insnp = ready; insnp < e_ready; insnp++)
4215 	{
4216 	  rtx_insn *insn = *insnp;
4217 	  int icode = recog_memoized (insn);
4218 	  bool is_asm = (icode < 0
4219 			 && (GET_CODE (PATTERN (insn)) == ASM_INPUT
4220 			     || asm_noperands (PATTERN (insn)) >= 0));
4221 	  int this_cycles, rsrv_cycles;
4222 	  enum attr_type type;
4223 
4224 	  gcc_assert (!is_asm);
4225 	  if (icode < 0)
4226 	    continue;
4227 	  this_cycles = get_attr_cycles (insn);
4228 	  rsrv_cycles = get_attr_reserve_cycles (insn);
4229 	  type = get_attr_type (insn);
4230 	  /* Treat branches specially; there is also a hazard if two jumps
4231 	     end at the same cycle.  */
4232 	  if (type == TYPE_BRANCH || type == TYPE_CALL)
4233 	    this_cycles++;
4234 	  if (clock_var + this_cycles <= first_cycle)
4235 	    continue;
4236 	  if ((first_jump > 0 && clock_var + this_cycles > second_cycle)
4237 	      || clock_var + rsrv_cycles > first_cycle
4238 	      || !predicate_insn (insn, first_cond, false))
4239 	    {
4240 	      memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
4241 	      *ready = insn;
4242 	      n_ready--;
4243 	      ready++;
4244 	    }
4245 	}
4246     }
4247 
4248   return n_ready;
4249 }
4250 
4251 /* Implement the TARGET_SCHED_REORDER hook.  We save the current clock
4252    for later and clear the register access information for the new
4253    cycle.  We also move asm statements out of the way if they would be
4254    scheduled in a delay slot.  */
4255 
4256 static int
4257 c6x_sched_reorder (FILE *dump ATTRIBUTE_UNUSED,
4258 		   int sched_verbose ATTRIBUTE_UNUSED,
4259 		   rtx_insn **ready ATTRIBUTE_UNUSED,
4260 		   int *pn_ready ATTRIBUTE_UNUSED, int clock_var)
4261 {
4262   ss.curr_sched_clock = clock_var;
4263   ss.issued_this_cycle = 0;
4264   memset (ss.reg_n_accesses, 0, sizeof ss.reg_n_accesses);
4265   memset (ss.reg_n_xaccesses, 0, sizeof ss.reg_n_xaccesses);
4266 
4267   if (ready == NULL)
4268     return 0;
4269 
4270   return c6x_sched_reorder_1 (ready, pn_ready, clock_var);
4271 }
4272 
4273 /* Implement the TARGET_SCHED_REORDER2 hook.  We use this to record the clock
4274    cycle for every insn.  */
4275 
4276 static int
4277 c6x_sched_reorder2 (FILE *dump ATTRIBUTE_UNUSED,
4278 		    int sched_verbose ATTRIBUTE_UNUSED,
4279 		    rtx_insn **ready ATTRIBUTE_UNUSED,
4280 		    int *pn_ready ATTRIBUTE_UNUSED, int clock_var)
4281 {
4282   /* FIXME: the assembler rejects labels inside an execute packet.
4283      This can occur if prologue insns are scheduled in parallel with
4284      others, so we avoid this here.  Also make sure that nothing is
4285      scheduled in parallel with a TYPE_ATOMIC insn or after a jump.  */
4286   if (RTX_FRAME_RELATED_P (ss.last_scheduled_insn)
4287       || JUMP_P (ss.last_scheduled_insn)
4288       || (recog_memoized (ss.last_scheduled_insn) >= 0
4289 	  && get_attr_type (ss.last_scheduled_insn) == TYPE_ATOMIC))
4290     {
4291       int n_ready = *pn_ready;
4292       rtx_insn **e_ready = ready + n_ready;
4293       rtx_insn **insnp;
4294 
4295       for (insnp = ready; insnp < e_ready; insnp++)
4296 	{
4297 	  rtx_insn *insn = *insnp;
4298 	  if (!shadow_p (insn))
4299 	    {
4300 	      memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
4301 	      *ready = insn;
4302 	      n_ready--;
4303 	      ready++;
4304 	    }
4305 	}
4306       return n_ready;
4307     }
4308 
4309   return c6x_sched_reorder_1 (ready, pn_ready, clock_var);
4310 }
4311 
4312 /* Subroutine of maybe_clobber_cond, called through note_stores.  */
4313 
4314 static void
4315 clobber_cond_1 (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data1)
4316 {
4317   rtx *cond = (rtx *)data1;
4318   if (*cond != NULL_RTX && reg_overlap_mentioned_p (x, *cond))
4319     *cond = NULL_RTX;
4320 }
4321 
4322 /* Examine INSN, and if it destroys the conditions have recorded for
4323    any of the jumps in flight, clear that condition so that we don't
4324    predicate any more insns.  CLOCK_VAR helps us limit the search to
4325    only those jumps which are still in flight.  */
4326 
4327 static void
4328 maybe_clobber_cond (rtx insn, int clock_var)
4329 {
4330   int n, idx;
4331   idx = ss.jump_cycle_index;
4332   for (n = 0; n < 12; n++, idx++)
4333     {
4334       rtx cond, link;
4335       int cycle;
4336 
4337       if (idx >= 12)
4338 	idx -= 12;
4339       cycle = ss.jump_cycles[idx];
4340       if (cycle <= clock_var)
4341 	return;
4342 
4343       cond = ss.jump_cond[idx];
4344       if (cond == NULL_RTX)
4345 	continue;
4346 
4347       if (CALL_P (insn))
4348 	{
4349 	  ss.jump_cond[idx] = NULL_RTX;
4350 	  continue;
4351 	}
4352 
4353       note_stores (PATTERN (insn), clobber_cond_1, ss.jump_cond + idx);
4354       for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
4355 	if (REG_NOTE_KIND (link) == REG_INC)
4356 	  clobber_cond_1 (XEXP (link, 0), NULL_RTX, ss.jump_cond + idx);
4357     }
4358 }
4359 
4360 /* Implement the TARGET_SCHED_VARIABLE_ISSUE hook.  We are about to
4361    issue INSN.  Return the number of insns left on the ready queue
4362    that can be issued this cycle.
4363    We use this hook to record clock cycles and reservations for every insn.  */
4364 
4365 static int
4366 c6x_variable_issue (FILE *dump ATTRIBUTE_UNUSED,
4367 		    int sched_verbose ATTRIBUTE_UNUSED,
4368 		    rtx_insn *insn, int can_issue_more ATTRIBUTE_UNUSED)
4369 {
4370   ss.last_scheduled_insn = insn;
4371   if (INSN_UID (insn) < sploop_max_uid_iter0 && !JUMP_P (insn))
4372     ss.last_scheduled_iter0 = insn;
4373   if (GET_CODE (PATTERN (insn)) != USE && GET_CODE (PATTERN (insn)) != CLOBBER)
4374     ss.issued_this_cycle++;
4375   if (insn_info.exists ())
4376     {
4377       state_t st_after = alloca (dfa_state_size);
4378       int curr_clock = ss.curr_sched_clock;
4379       int uid = INSN_UID (insn);
4380       int icode = recog_memoized (insn);
4381       rtx first_cond;
4382       int first, first_cycle;
4383       unsigned int mask;
4384       int i;
4385 
4386       insn_set_clock (insn, curr_clock);
4387       INSN_INFO_ENTRY (uid).ebb_start
4388 	= curr_clock == 0 && ss.issued_this_cycle == 1;
4389 
4390       first = first_jump_index (ss.curr_sched_clock);
4391       if (first == -1)
4392 	{
4393 	  first_cycle = 0;
4394 	  first_cond = NULL_RTX;
4395 	}
4396       else
4397 	{
4398 	  first_cycle = get_jump_cycle (first);
4399 	  first_cond = get_jump_cond (first);
4400 	}
4401       if (icode >= 0
4402 	  && first_cycle > curr_clock
4403 	  && first_cond != NULL_RTX
4404 	  && (curr_clock + get_attr_cycles (insn) > first_cycle
4405 	      || get_attr_type (insn) == TYPE_BRANCH
4406 	      || get_attr_type (insn) == TYPE_CALL))
4407 	INSN_INFO_ENTRY (uid).new_cond = first_cond;
4408 
4409       memcpy (st_after, curr_state, dfa_state_size);
4410       state_transition (st_after, const0_rtx);
4411 
4412       mask = 0;
4413       for (i = 0; i < 2 * UNIT_QID_SIDE_OFFSET; i++)
4414 	if (cpu_unit_reservation_p (st_after, c6x_unit_codes[i])
4415 	    && !cpu_unit_reservation_p (prev_cycle_state, c6x_unit_codes[i]))
4416 	  mask |= 1 << i;
4417       INSN_INFO_ENTRY (uid).unit_mask = mask;
4418 
4419       maybe_clobber_cond (insn, curr_clock);
4420 
4421       if (icode >= 0)
4422 	{
4423 	  int i, cycles;
4424 
4425 	  c6x_registers_update (insn);
4426 	  memcpy (ss.reg_n_accesses, ss.tmp_reg_n_accesses,
4427 		  sizeof ss.reg_n_accesses);
4428 	  memcpy (ss.reg_n_xaccesses, ss.tmp_reg_n_accesses,
4429 		  sizeof ss.reg_n_xaccesses);
4430 
4431 	  cycles = get_attr_cycles (insn);
4432 	  if (ss.delays_finished_at < ss.curr_sched_clock + cycles)
4433 	    ss.delays_finished_at = ss.curr_sched_clock + cycles;
4434 	  if (get_attr_type (insn) == TYPE_BRANCH
4435 	      || get_attr_type (insn) == TYPE_CALL)
4436 	    {
4437 	      rtx opposite = condjump_opposite_condition (insn);
4438 	      record_jump (ss.curr_sched_clock + cycles, opposite);
4439 	    }
4440 
4441 	  /* Mark the cycles in which the destination registers are written.
4442 	     This is used for calculating stalls when using cross units.  */
4443 	  extract_insn (insn);
4444 	  /* Cross-path stalls don't apply to results of load insns.  */
4445 	  if (get_attr_type (insn) == TYPE_LOAD
4446 	      || get_attr_type (insn) == TYPE_LOADN
4447 	      || get_attr_type (insn) == TYPE_LOAD_SHADOW)
4448 	    cycles--;
4449 	  for (i = 0; i < recog_data.n_operands; i++)
4450 	    {
4451 	      rtx op = recog_data.operand[i];
4452 	      if (MEM_P (op))
4453 		{
4454 		  rtx addr = XEXP (op, 0);
4455 		  if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC)
4456 		    c6x_mark_reg_written (XEXP (addr, 0),
4457 					  insn_uid_get_clock (uid) + 1);
4458 		}
4459 	      if (recog_data.operand_type[i] != OP_IN
4460 		  && REG_P (op))
4461 		{
4462 		  c6x_mark_reg_written (op,
4463 					insn_uid_get_clock (uid) + cycles);
4464 		}
4465 	    }
4466 	}
4467     }
4468   return can_issue_more;
4469 }
4470 
4471 /* Implement the TARGET_SCHED_ADJUST_COST hook.  We need special handling for
4472    anti- and output dependencies.  */
4473 
4474 static int
4475 c6x_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
4476 		 unsigned int)
4477 {
4478   enum attr_type insn_type = TYPE_UNKNOWN, dep_insn_type = TYPE_UNKNOWN;
4479   int dep_insn_code_number, insn_code_number;
4480   int shadow_bonus = 0;
4481   enum reg_note kind;
4482   dep_insn_code_number = recog_memoized (dep_insn);
4483   insn_code_number = recog_memoized (insn);
4484 
4485   if (dep_insn_code_number >= 0)
4486     dep_insn_type = get_attr_type (dep_insn);
4487 
4488   if (insn_code_number >= 0)
4489     insn_type = get_attr_type (insn);
4490 
4491   kind = (reg_note) dep_type;
4492   if (kind == 0)
4493     {
4494       /* If we have a dependency on a load, and it's not for the result of
4495 	 the load, it must be for an autoincrement.  Reduce the cost in that
4496 	 case.  */
4497       if (dep_insn_type == TYPE_LOAD)
4498 	{
4499 	  rtx set = PATTERN (dep_insn);
4500 	  if (GET_CODE (set) == COND_EXEC)
4501 	    set = COND_EXEC_CODE (set);
4502 	  if (GET_CODE (set) == UNSPEC)
4503 	    cost = 1;
4504 	  else
4505 	    {
4506 	      gcc_assert (GET_CODE (set) == SET);
4507 	      if (!reg_overlap_mentioned_p (SET_DEST (set), PATTERN (insn)))
4508 		cost = 1;
4509 	    }
4510 	}
4511     }
4512 
4513   /* A jump shadow needs to have its latency decreased by one.  Conceptually,
4514      it occurs in between two cycles, but we schedule it at the end of the
4515      first cycle.  */
4516   if (shadow_type_p (insn_type))
4517     shadow_bonus = 1;
4518 
4519   /* Anti and output dependencies usually have zero cost, but we want
4520      to insert a stall after a jump, and after certain floating point
4521      insns that take more than one cycle to read their inputs.  In the
4522      future, we should try to find a better algorithm for scheduling
4523      jumps.  */
4524   if (kind != 0)
4525     {
4526       /* We can get anti-dependencies against shadow insns.  Treat these
4527 	 like output dependencies, so that the insn is entirely finished
4528 	 before the branch takes place.  */
4529       if (kind == REG_DEP_ANTI && insn_type == TYPE_SHADOW)
4530 	kind = REG_DEP_OUTPUT;
4531       switch (dep_insn_type)
4532 	{
4533 	case TYPE_CALLP:
4534 	  return 1;
4535 	case TYPE_BRANCH:
4536 	case TYPE_CALL:
4537 	  if (get_attr_has_shadow (dep_insn) == HAS_SHADOW_Y)
4538 	    /* This is a real_jump/real_call insn.  These don't have
4539 	       outputs, and ensuring the validity of scheduling things
4540 	       in the delay slot is the job of
4541 	       c6x_sched_reorder_1.  */
4542 	    return 0;
4543 	  /* Unsplit calls can happen - e.g. for divide insns.  */
4544 	  return 6;
4545 	case TYPE_LOAD:
4546 	case TYPE_LOADN:
4547 	case TYPE_INTDP:
4548 	  if (kind == REG_DEP_OUTPUT)
4549 	    return 5 - shadow_bonus;
4550 	  return 0;
4551 	case TYPE_MPY4:
4552 	case TYPE_FP4:
4553 	  if (kind == REG_DEP_OUTPUT)
4554 	    return 4 - shadow_bonus;
4555 	  return 0;
4556 	case TYPE_MPY2:
4557 	  if (kind == REG_DEP_OUTPUT)
4558 	    return 2 - shadow_bonus;
4559 	  return 0;
4560 	case TYPE_CMPDP:
4561 	  if (kind == REG_DEP_OUTPUT)
4562 	    return 2 - shadow_bonus;
4563 	  return 2;
4564 	case TYPE_ADDDP:
4565 	case TYPE_MPYSPDP:
4566 	  if (kind == REG_DEP_OUTPUT)
4567 	    return 7 - shadow_bonus;
4568 	  return 2;
4569 	case TYPE_MPYSP2DP:
4570 	  if (kind == REG_DEP_OUTPUT)
4571 	    return 5 - shadow_bonus;
4572 	  return 2;
4573 	case TYPE_MPYI:
4574 	  if (kind == REG_DEP_OUTPUT)
4575 	    return 9 - shadow_bonus;
4576 	  return 4;
4577 	case TYPE_MPYID:
4578 	case TYPE_MPYDP:
4579 	  if (kind == REG_DEP_OUTPUT)
4580 	    return 10 - shadow_bonus;
4581 	  return 4;
4582 
4583 	default:
4584 	  if (insn_type == TYPE_SPKERNEL)
4585 	    return 0;
4586 	  if (kind == REG_DEP_OUTPUT)
4587 	    return 1 - shadow_bonus;
4588 
4589 	  return 0;
4590 	}
4591     }
4592 
4593   return cost - shadow_bonus;
4594 }
4595 
4596 /* Create a SEQUENCE rtx to replace the instructions in SLOT, of which there
4597    are N_FILLED.  REAL_FIRST identifies the slot if the insn that appears
4598    first in the original stream.  */
4599 
4600 static void
4601 gen_one_bundle (rtx_insn **slot, int n_filled, int real_first)
4602 {
4603   rtx seq;
4604   rtx_insn *bundle;
4605   rtx_insn *t;
4606   int i;
4607 
4608   seq = gen_rtx_SEQUENCE (VOIDmode, gen_rtvec_v (n_filled, slot));
4609   bundle = make_insn_raw (seq);
4610   BLOCK_FOR_INSN (bundle) = BLOCK_FOR_INSN (slot[0]);
4611   INSN_LOCATION (bundle) = INSN_LOCATION (slot[0]);
4612   SET_PREV_INSN (bundle) = SET_PREV_INSN (slot[real_first]);
4613 
4614   t = NULL;
4615 
4616   for (i = 0; i < n_filled; i++)
4617     {
4618       rtx_insn *insn = slot[i];
4619       remove_insn (insn);
4620       SET_PREV_INSN (insn) = t ? t : PREV_INSN (bundle);
4621       if (t != NULL_RTX)
4622 	SET_NEXT_INSN (t) = insn;
4623       t = insn;
4624       if (i > 0)
4625 	INSN_LOCATION (slot[i]) = INSN_LOCATION (bundle);
4626     }
4627 
4628   SET_NEXT_INSN (bundle) = NEXT_INSN (PREV_INSN (bundle));
4629   SET_NEXT_INSN (t) = NEXT_INSN (bundle);
4630   SET_NEXT_INSN (PREV_INSN (bundle)) = bundle;
4631   SET_PREV_INSN (NEXT_INSN (bundle)) = bundle;
4632 }
4633 
4634 /* Move all parallel instructions into SEQUENCEs, so that no subsequent passes
4635    try to insert labels in the middle.  */
4636 
4637 static void
4638 c6x_gen_bundles (void)
4639 {
4640   basic_block bb;
4641 
4642   FOR_EACH_BB_FN (bb, cfun)
4643     {
4644       rtx_insn *insn, *next;
4645       /* The machine is eight insns wide.  We can have up to six shadow
4646 	 insns, plus an extra slot for merging the jump shadow.  */
4647       rtx_insn *slot[15];
4648       int n_filled = 0;
4649       int first_slot = 0;
4650 
4651       for (insn = BB_HEAD (bb);; insn = next)
4652 	{
4653 	  int at_end;
4654 	  rtx delete_this = NULL_RTX;
4655 
4656 	  if (NONDEBUG_INSN_P (insn))
4657 	    {
4658 	      /* Put calls at the start of the sequence.  */
4659 	      if (CALL_P (insn))
4660 		{
4661 		  first_slot++;
4662 		  if (n_filled)
4663 		    {
4664 		      memmove (&slot[1], &slot[0],
4665 			       n_filled * sizeof (slot[0]));
4666 		    }
4667 		  if (!shadow_p (insn))
4668 		    {
4669 		      PUT_MODE (insn, TImode);
4670 		      if (n_filled)
4671 			PUT_MODE (slot[1], VOIDmode);
4672 		    }
4673 		  n_filled++;
4674 		  slot[0] = insn;
4675 		}
4676 	      else
4677 		{
4678 		  slot[n_filled++] = insn;
4679 		}
4680 	    }
4681 
4682 	  next = NEXT_INSN (insn);
4683 	  while (next && insn != BB_END (bb)
4684 		 && !(NONDEBUG_INSN_P (next)
4685 		      && GET_CODE (PATTERN (next)) != USE
4686 		      && GET_CODE (PATTERN (next)) != CLOBBER))
4687 	    {
4688 	      insn = next;
4689 	      next = NEXT_INSN (insn);
4690 	    }
4691 
4692 	  at_end = insn == BB_END (bb);
4693 	  if (delete_this == NULL_RTX
4694 	      && (at_end || (GET_MODE (next) == TImode
4695 			     && !(shadow_p (next) && CALL_P (next)))))
4696 	    {
4697 	      if (n_filled >= 2)
4698 		gen_one_bundle (slot, n_filled, first_slot);
4699 
4700 	      n_filled = 0;
4701 	      first_slot = 0;
4702 	    }
4703 	  if (at_end)
4704 	    break;
4705 	}
4706     }
4707 }
4708 
4709 /* Emit a NOP instruction for CYCLES cycles after insn AFTER.  Return it.  */
4710 
4711 static rtx_insn *
4712 emit_nop_after (int cycles, rtx_insn *after)
4713 {
4714   rtx_insn *insn;
4715 
4716   /* mpydp has 9 delay slots, and we may schedule a stall for a cross-path
4717      operation.  We don't need the extra NOP since in this case, the hardware
4718      will automatically insert the required stall.  */
4719   if (cycles == 10)
4720     cycles--;
4721 
4722   gcc_assert (cycles < 10);
4723 
4724   insn = emit_insn_after (gen_nop_count (GEN_INT (cycles)), after);
4725   PUT_MODE (insn, TImode);
4726 
4727   return insn;
4728 }
4729 
4730 /* Determine whether INSN is a call that needs to have a return label
4731    placed.  */
4732 
4733 static bool
4734 returning_call_p (rtx_insn *insn)
4735 {
4736   if (CALL_P (insn))
4737     return (!SIBLING_CALL_P (insn)
4738 	    && get_attr_type (insn) != TYPE_CALLP
4739 	    && get_attr_type (insn) != TYPE_SHADOW);
4740   if (recog_memoized (insn) < 0)
4741     return false;
4742   if (get_attr_type (insn) == TYPE_CALL)
4743     return true;
4744   return false;
4745 }
4746 
4747 /* Determine whether INSN's pattern can be converted to use callp.  */
4748 static bool
4749 can_use_callp (rtx_insn *insn)
4750 {
4751   int icode = recog_memoized (insn);
4752   if (!TARGET_INSNS_64PLUS
4753       || icode < 0
4754       || GET_CODE (PATTERN (insn)) == COND_EXEC)
4755     return false;
4756 
4757   return ((icode == CODE_FOR_real_call
4758 	   || icode == CODE_FOR_call_internal
4759 	   || icode == CODE_FOR_call_value_internal)
4760 	  && get_attr_dest_regfile (insn) == DEST_REGFILE_ANY);
4761 }
4762 
4763 /* Convert the pattern of INSN, which must be a CALL_INSN, into a callp.  */
4764 static void
4765 convert_to_callp (rtx_insn *insn)
4766 {
4767   rtx lab;
4768   extract_insn (insn);
4769   if (GET_CODE (PATTERN (insn)) == SET)
4770     {
4771       rtx dest = recog_data.operand[0];
4772       lab = recog_data.operand[1];
4773       PATTERN (insn) = gen_callp_value (dest, lab);
4774       INSN_CODE (insn) = CODE_FOR_callp_value;
4775     }
4776   else
4777     {
4778       lab = recog_data.operand[0];
4779       PATTERN (insn) = gen_callp (lab);
4780       INSN_CODE (insn) = CODE_FOR_callp;
4781     }
4782 }
4783 
4784 /* Scan forwards from INSN until we find the next insn that has mode TImode
4785    (indicating it starts a new cycle), and occurs in cycle CLOCK.
4786    Return it if we find such an insn, NULL_RTX otherwise.  */
4787 static rtx_insn *
4788 find_next_cycle_insn (rtx_insn *insn, int clock)
4789 {
4790   rtx_insn *t = insn;
4791   if (GET_MODE (t) == TImode)
4792     t = next_real_insn (t);
4793   while (t && GET_MODE (t) != TImode)
4794     t = next_real_insn (t);
4795 
4796   if (t && insn_get_clock (t) == clock)
4797     return t;
4798   return NULL;
4799 }
4800 
4801 /* If COND_INSN has a COND_EXEC condition, wrap the same condition
4802    around PAT.  Return PAT either unchanged or modified in this
4803    way.  */
4804 static rtx
4805 duplicate_cond (rtx pat, rtx cond_insn)
4806 {
4807   rtx cond_pat = PATTERN (cond_insn);
4808   if (GET_CODE (cond_pat) == COND_EXEC)
4809     pat = gen_rtx_COND_EXEC (VOIDmode, copy_rtx (COND_EXEC_TEST (cond_pat)),
4810 			     pat);
4811   return pat;
4812 }
4813 
4814 /* Walk forward from INSN to find the last insn that issues in the same clock
4815    cycle.  */
4816 static rtx_insn *
4817 find_last_same_clock (rtx_insn *insn)
4818 {
4819   rtx_insn *retval = insn;
4820   rtx_insn *t = next_real_insn (insn);
4821 
4822   while (t && GET_MODE (t) != TImode)
4823     {
4824       if (!DEBUG_INSN_P (t) && recog_memoized (t) >= 0)
4825 	retval = t;
4826       t = next_real_insn (t);
4827     }
4828   return retval;
4829 }
4830 
4831 /* For every call insn in the function, emit code to load the return
4832    address.  For each call we create a return label and store it in
4833    CALL_LABELS.  If are not scheduling, we emit the labels here,
4834    otherwise the caller will do it later.
4835    This function is called after final insn scheduling, but before creating
4836    the SEQUENCEs that represent execute packets.  */
4837 
4838 static void
4839 reorg_split_calls (rtx_code_label **call_labels)
4840 {
4841   unsigned int reservation_mask = 0;
4842   rtx_insn *insn = get_insns ();
4843   gcc_assert (NOTE_P (insn));
4844   insn = next_real_insn (insn);
4845   while (insn)
4846     {
4847       int uid;
4848       rtx_insn *next = next_real_insn (insn);
4849 
4850       if (DEBUG_INSN_P (insn))
4851 	goto done;
4852 
4853       if (GET_MODE (insn) == TImode)
4854 	reservation_mask = 0;
4855       uid = INSN_UID (insn);
4856       if (c6x_flag_schedule_insns2 && recog_memoized (insn) >= 0)
4857 	reservation_mask |= 1 << INSN_INFO_ENTRY (uid).reservation;
4858 
4859       if (returning_call_p (insn))
4860 	{
4861 	  rtx_code_label *label = gen_label_rtx ();
4862 	  rtx labelref = gen_rtx_LABEL_REF (Pmode, label);
4863 	  rtx reg = gen_rtx_REG (SImode, RETURN_ADDR_REGNO);
4864 
4865 	  LABEL_NUSES (label) = 2;
4866 	  if (!c6x_flag_schedule_insns2)
4867 	    {
4868 	      if (can_use_callp (insn))
4869 		convert_to_callp (insn);
4870 	      else
4871 		{
4872 		  rtx t;
4873 		  rtx_insn *slot[4];
4874 		  emit_label_after (label, insn);
4875 
4876 		  /* Bundle the call and its delay slots into a single
4877 		     SEQUENCE.  While these do not issue in parallel
4878 		     we need to group them into a single EH region.  */
4879 		  slot[0] = insn;
4880 		  PUT_MODE (insn, TImode);
4881 		  if (TARGET_INSNS_64)
4882 		    {
4883 		      t = gen_addkpc (reg, labelref, GEN_INT (4));
4884 		      slot[1] = emit_insn_after (duplicate_cond (t, insn),
4885 						 insn);
4886 		      PUT_MODE (slot[1], TImode);
4887 		      gen_one_bundle (slot, 2, 0);
4888 		    }
4889 		  else
4890 		    {
4891 		      slot[3] = emit_insn_after (gen_nop_count (GEN_INT (3)),
4892 						 insn);
4893 		      PUT_MODE (slot[3], TImode);
4894 		      t = gen_movsi_lo_sum (reg, reg, labelref);
4895 		      slot[2] = emit_insn_after (duplicate_cond (t, insn),
4896 						  insn);
4897 		      PUT_MODE (slot[2], TImode);
4898 		      t = gen_movsi_high (reg, labelref);
4899 		      slot[1] = emit_insn_after (duplicate_cond (t, insn),
4900 						 insn);
4901 		      PUT_MODE (slot[1], TImode);
4902 		      gen_one_bundle (slot, 4, 0);
4903 		    }
4904 		}
4905 	    }
4906 	  else
4907 	    {
4908 	      /* If we scheduled, we reserved the .S2 unit for one or two
4909 		 cycles after the call.  Emit the insns in these slots,
4910 		 unless it's possible to create a CALLP insn.
4911 		 Note that this works because the dependencies ensure that
4912 		 no insn setting/using B3 is scheduled in the delay slots of
4913 		 a call.  */
4914 	      int this_clock = insn_get_clock (insn);
4915 	      rtx_insn *after1;
4916 
4917 	      call_labels[INSN_UID (insn)] = label;
4918 
4919 	      rtx_insn *last_same_clock = find_last_same_clock (insn);
4920 
4921 	      if (can_use_callp (insn))
4922 		{
4923 		  /* Find the first insn of the next execute packet.  If it
4924 		     is the shadow insn corresponding to this call, we may
4925 		     use a CALLP insn.  */
4926 		  rtx_insn *shadow =
4927 		    next_nonnote_nondebug_insn (last_same_clock);
4928 
4929 		  if (CALL_P (shadow)
4930 		      && insn_get_clock (shadow) == this_clock + 5)
4931 		    {
4932 		      convert_to_callp (shadow);
4933 		      insn_set_clock (shadow, this_clock);
4934 		      INSN_INFO_ENTRY (INSN_UID (shadow)).reservation
4935 			= RESERVATION_S2;
4936 		      INSN_INFO_ENTRY (INSN_UID (shadow)).unit_mask
4937 			= INSN_INFO_ENTRY (INSN_UID (last_same_clock)).unit_mask;
4938 		      if (GET_MODE (insn) == TImode)
4939 			{
4940 			  rtx_insn *new_cycle_first = NEXT_INSN (insn);
4941 			  while (!NONDEBUG_INSN_P (new_cycle_first)
4942 				 || GET_CODE (PATTERN (new_cycle_first)) == USE
4943 				 || GET_CODE (PATTERN (new_cycle_first)) == CLOBBER)
4944 			    new_cycle_first = NEXT_INSN (new_cycle_first);
4945 			  PUT_MODE (new_cycle_first, TImode);
4946 			  if (new_cycle_first != shadow)
4947 			    PUT_MODE (shadow, VOIDmode);
4948 			  INSN_INFO_ENTRY (INSN_UID (new_cycle_first)).ebb_start
4949 			    = INSN_INFO_ENTRY (INSN_UID (insn)).ebb_start;
4950 			}
4951 		      else
4952 			PUT_MODE (shadow, VOIDmode);
4953 		      delete_insn (insn);
4954 		      goto done;
4955 		    }
4956 		}
4957 	      after1 = find_next_cycle_insn (last_same_clock, this_clock + 1);
4958 	      if (after1 == NULL_RTX)
4959 		after1 = last_same_clock;
4960 	      else
4961 		after1 = find_last_same_clock (after1);
4962 	      if (TARGET_INSNS_64)
4963 		{
4964 		  rtx x1 = gen_addkpc (reg, labelref, const0_rtx);
4965 		  x1 = emit_insn_after (duplicate_cond (x1, insn), after1);
4966 		  insn_set_clock (x1, this_clock + 1);
4967 		  INSN_INFO_ENTRY (INSN_UID (x1)).reservation = RESERVATION_S2;
4968 		  if (after1 == last_same_clock)
4969 		    PUT_MODE (x1, TImode);
4970 		  else
4971 		    INSN_INFO_ENTRY (INSN_UID (x1)).unit_mask
4972 		      = INSN_INFO_ENTRY (INSN_UID (after1)).unit_mask;
4973 		}
4974 	      else
4975 		{
4976 		  rtx x1, x2;
4977 		  rtx_insn *after2 = find_next_cycle_insn (after1,
4978 							   this_clock + 2);
4979 		  if (after2 == NULL_RTX)
4980 		    after2 = after1;
4981 		  x2 = gen_movsi_lo_sum (reg, reg, labelref);
4982 		  x2 = emit_insn_after (duplicate_cond (x2, insn), after2);
4983 		  x1 = gen_movsi_high (reg, labelref);
4984 		  x1 = emit_insn_after (duplicate_cond (x1, insn), after1);
4985 		  insn_set_clock (x1, this_clock + 1);
4986 		  insn_set_clock (x2, this_clock + 2);
4987 		  INSN_INFO_ENTRY (INSN_UID (x1)).reservation = RESERVATION_S2;
4988 		  INSN_INFO_ENTRY (INSN_UID (x2)).reservation = RESERVATION_S2;
4989 		  if (after1 == last_same_clock)
4990 		    PUT_MODE (x1, TImode);
4991 		  else
4992 		    INSN_INFO_ENTRY (INSN_UID (x1)).unit_mask
4993 		      = INSN_INFO_ENTRY (INSN_UID (after1)).unit_mask;
4994 		  if (after1 == after2)
4995 		    PUT_MODE (x2, TImode);
4996 		  else
4997 		    INSN_INFO_ENTRY (INSN_UID (x2)).unit_mask
4998 		      = INSN_INFO_ENTRY (INSN_UID (after2)).unit_mask;
4999 		}
5000 	    }
5001 	}
5002     done:
5003       insn = next;
5004     }
5005 }
5006 
5007 /* Called as part of c6x_reorg.  This function emits multi-cycle NOP
5008    insns as required for correctness.  CALL_LABELS is the array that
5009    holds the return labels for call insns; we emit these here if
5010    scheduling was run earlier.  */
5011 
5012 static void
5013 reorg_emit_nops (rtx_code_label **call_labels)
5014 {
5015   bool first;
5016   rtx last_call;
5017   rtx_insn *prev;
5018   int prev_clock, earliest_bb_end;
5019   int prev_implicit_nops;
5020   rtx_insn *insn = get_insns ();
5021 
5022   /* We look at one insn (or bundle inside a sequence) in each iteration, storing
5023      its issue time in PREV_CLOCK for the next iteration.  If there is a gap in
5024      clocks, we must insert a NOP.
5025      EARLIEST_BB_END tracks in which cycle all insns that have been issued in the
5026      current basic block will finish.  We must not allow the next basic block to
5027      begin before this cycle.
5028      PREV_IMPLICIT_NOPS tells us whether we've seen an insn that implicitly contains
5029      a multi-cycle nop.  The code is scheduled such that subsequent insns will
5030      show the cycle gap, but we needn't insert a real NOP instruction.  */
5031   insn = next_real_insn (insn);
5032   last_call = prev = NULL;
5033   prev_clock = -1;
5034   earliest_bb_end = 0;
5035   prev_implicit_nops = 0;
5036   first = true;
5037   while (insn)
5038     {
5039       int this_clock = -1;
5040       rtx_insn *next;
5041       int max_cycles = 0;
5042 
5043       next = next_real_insn (insn);
5044 
5045       if (DEBUG_INSN_P (insn)
5046 	  || GET_CODE (PATTERN (insn)) == USE
5047 	  || GET_CODE (PATTERN (insn)) == CLOBBER
5048 	  || shadow_or_blockage_p (insn)
5049 	  || JUMP_TABLE_DATA_P (insn))
5050 	goto next_insn;
5051 
5052       if (!c6x_flag_schedule_insns2)
5053 	/* No scheduling; ensure that no parallel issue happens.  */
5054 	PUT_MODE (insn, TImode);
5055       else
5056 	{
5057 	  int cycles;
5058 
5059 	  this_clock = insn_get_clock (insn);
5060 	  if (this_clock != prev_clock)
5061 	    {
5062 	      PUT_MODE (insn, TImode);
5063 
5064 	      if (!first)
5065 		{
5066 		  cycles = this_clock - prev_clock;
5067 
5068 		  cycles -= prev_implicit_nops;
5069 		  if (cycles > 1)
5070 		    {
5071 		      rtx nop = emit_nop_after (cycles - 1, prev);
5072 		      insn_set_clock (nop, prev_clock + prev_implicit_nops + 1);
5073 		    }
5074 		}
5075 	      prev_clock = this_clock;
5076 
5077 	      if (last_call
5078 		  && insn_get_clock (last_call) + 6 <= this_clock)
5079 		{
5080 		  emit_label_before (call_labels[INSN_UID (last_call)], insn);
5081 		  last_call = NULL_RTX;
5082 		}
5083 	      prev_implicit_nops = 0;
5084 	    }
5085 	}
5086 
5087       /* Examine how many cycles the current insn takes, and adjust
5088 	 LAST_CALL, EARLIEST_BB_END and PREV_IMPLICIT_NOPS.  */
5089       if (recog_memoized (insn) >= 0
5090 	  /* If not scheduling, we've emitted NOPs after calls already.  */
5091 	  && (c6x_flag_schedule_insns2 || !returning_call_p (insn)))
5092 	{
5093 	  max_cycles = get_attr_cycles (insn);
5094 	  if (get_attr_type (insn) == TYPE_CALLP)
5095 	    prev_implicit_nops = 5;
5096 	}
5097       else
5098 	max_cycles = 1;
5099       if (returning_call_p (insn))
5100 	last_call = insn;
5101 
5102       if (c6x_flag_schedule_insns2)
5103 	{
5104 	  gcc_assert (this_clock >= 0);
5105 	  if (earliest_bb_end < this_clock + max_cycles)
5106 	    earliest_bb_end = this_clock + max_cycles;
5107 	}
5108       else if (max_cycles > 1)
5109 	emit_nop_after (max_cycles - 1, insn);
5110 
5111       prev = insn;
5112       first = false;
5113 
5114     next_insn:
5115       if (c6x_flag_schedule_insns2
5116 	  && (next == NULL_RTX
5117 	      || (GET_MODE (next) == TImode
5118 		  && INSN_INFO_ENTRY (INSN_UID (next)).ebb_start))
5119 	  && earliest_bb_end > 0)
5120 	{
5121 	  int cycles = earliest_bb_end - prev_clock;
5122 	  if (cycles > 1)
5123 	    {
5124 	      prev = emit_nop_after (cycles - 1, prev);
5125 	      insn_set_clock (prev, prev_clock + prev_implicit_nops + 1);
5126 	    }
5127 	  earliest_bb_end = 0;
5128 	  prev_clock = -1;
5129 	  first = true;
5130 
5131 	  if (last_call)
5132 	    emit_label_after (call_labels[INSN_UID (last_call)], prev);
5133 	  last_call = NULL_RTX;
5134 	}
5135       insn = next;
5136     }
5137 }
5138 
5139 /* If possible, split INSN, which we know is either a jump or a call, into a real
5140    insn and its shadow.  */
5141 static void
5142 split_delayed_branch (rtx_insn *insn)
5143 {
5144   int code = recog_memoized (insn);
5145   rtx_insn *i1;
5146   rtx newpat;
5147   rtx pat = PATTERN (insn);
5148 
5149   if (GET_CODE (pat) == COND_EXEC)
5150     pat = COND_EXEC_CODE (pat);
5151 
5152   if (CALL_P (insn))
5153     {
5154       rtx src = pat, dest = NULL_RTX;
5155       rtx callee;
5156       if (GET_CODE (pat) == SET)
5157 	{
5158 	  dest = SET_DEST (pat);
5159 	  src = SET_SRC (pat);
5160 	}
5161       callee = XEXP (XEXP (src, 0), 0);
5162       if (SIBLING_CALL_P (insn))
5163 	{
5164 	  if (REG_P (callee))
5165 	    newpat = gen_indirect_sibcall_shadow ();
5166 	  else
5167 	    newpat = gen_sibcall_shadow (callee);
5168 	  pat = gen_real_jump (callee);
5169 	}
5170       else if (dest != NULL_RTX)
5171 	{
5172 	  if (REG_P (callee))
5173 	    newpat = gen_indirect_call_value_shadow (dest);
5174 	  else
5175 	    newpat = gen_call_value_shadow (dest, callee);
5176 	  pat = gen_real_call (callee);
5177 	}
5178       else
5179 	{
5180 	  if (REG_P (callee))
5181 	    newpat = gen_indirect_call_shadow ();
5182 	  else
5183 	    newpat = gen_call_shadow (callee);
5184 	  pat = gen_real_call (callee);
5185 	}
5186       pat = duplicate_cond (pat, insn);
5187       newpat = duplicate_cond (newpat, insn);
5188     }
5189   else
5190     {
5191       rtx src, op;
5192       if (GET_CODE (pat) == PARALLEL
5193 	  && GET_CODE (XVECEXP (pat, 0, 0)) == RETURN)
5194 	{
5195 	  newpat = gen_return_shadow ();
5196 	  pat = gen_real_ret (XEXP (XVECEXP (pat, 0, 1), 0));
5197 	  newpat = duplicate_cond (newpat, insn);
5198 	}
5199       else
5200 	switch (code)
5201 	  {
5202 	  case CODE_FOR_br_true:
5203 	  case CODE_FOR_br_false:
5204 	    src = SET_SRC (pat);
5205 	    op = XEXP (src, code == CODE_FOR_br_true ? 1 : 2);
5206 	    newpat = gen_condjump_shadow (op);
5207 	    pat = gen_real_jump (op);
5208 	    if (code == CODE_FOR_br_true)
5209 	      pat = gen_rtx_COND_EXEC (VOIDmode, XEXP (src, 0), pat);
5210 	    else
5211 	      pat = gen_rtx_COND_EXEC (VOIDmode,
5212 				       reversed_comparison (XEXP (src, 0),
5213 							    VOIDmode),
5214 				       pat);
5215 	    break;
5216 
5217 	  case CODE_FOR_jump:
5218 	    op = SET_SRC (pat);
5219 	    newpat = gen_jump_shadow (op);
5220 	    break;
5221 
5222 	  case CODE_FOR_indirect_jump:
5223 	    newpat = gen_indirect_jump_shadow ();
5224 	    break;
5225 
5226 	  case CODE_FOR_return_internal:
5227 	    newpat = gen_return_shadow ();
5228 	    pat = gen_real_ret (XEXP (XVECEXP (pat, 0, 1), 0));
5229 	    break;
5230 
5231 	  default:
5232 	    return;
5233 	  }
5234     }
5235   i1 = emit_insn_before (pat, insn);
5236   PATTERN (insn) = newpat;
5237   INSN_CODE (insn) = -1;
5238   record_delay_slot_pair (i1, insn, 5, 0);
5239 }
5240 
5241 /* If INSN is a multi-cycle insn that should be handled properly in
5242    modulo-scheduling, split it into a real insn and a shadow.
5243    Return true if we made a change.
5244 
5245    It is valid for us to fail to split an insn; the caller has to deal
5246    with the possibility.  Currently we handle loads and most mpy2 and
5247    mpy4 insns.  */
5248 static bool
5249 split_delayed_nonbranch (rtx_insn *insn)
5250 {
5251   int code = recog_memoized (insn);
5252   enum attr_type type;
5253   rtx_insn *i1;
5254   rtx newpat, src, dest;
5255   rtx pat = PATTERN (insn);
5256   rtvec rtv;
5257   int delay;
5258 
5259   if (GET_CODE (pat) == COND_EXEC)
5260     pat = COND_EXEC_CODE (pat);
5261 
5262   if (code < 0 || GET_CODE (pat) != SET)
5263     return false;
5264   src = SET_SRC (pat);
5265   dest = SET_DEST (pat);
5266   if (!REG_P (dest))
5267     return false;
5268 
5269   type = get_attr_type (insn);
5270   if (code >= 0
5271       && (type == TYPE_LOAD
5272 	  || type == TYPE_LOADN))
5273     {
5274       if (!MEM_P (src)
5275 	  && (GET_CODE (src) != ZERO_EXTEND
5276 	      || !MEM_P (XEXP (src, 0))))
5277 	return false;
5278 
5279       if (GET_MODE_SIZE (GET_MODE (dest)) > 4
5280 	  && (GET_MODE_SIZE (GET_MODE (dest)) != 8 || !TARGET_LDDW))
5281 	return false;
5282 
5283       rtv = gen_rtvec (2, GEN_INT (REGNO (SET_DEST (pat))),
5284 		       SET_SRC (pat));
5285       newpat = gen_load_shadow (SET_DEST (pat));
5286       pat = gen_rtx_UNSPEC (VOIDmode, rtv, UNSPEC_REAL_LOAD);
5287       delay = 4;
5288     }
5289   else if (code >= 0
5290 	   && (type == TYPE_MPY2
5291 	       || type == TYPE_MPY4))
5292     {
5293       /* We don't handle floating point multiplies yet.  */
5294       if (GET_MODE (dest) == SFmode)
5295 	return false;
5296 
5297       rtv = gen_rtvec (2, GEN_INT (REGNO (SET_DEST (pat))),
5298 		       SET_SRC (pat));
5299       newpat = gen_mult_shadow (SET_DEST (pat));
5300       pat = gen_rtx_UNSPEC (VOIDmode, rtv, UNSPEC_REAL_MULT);
5301       delay = type == TYPE_MPY2 ? 1 : 3;
5302     }
5303   else
5304     return false;
5305 
5306   pat = duplicate_cond (pat, insn);
5307   newpat = duplicate_cond (newpat, insn);
5308   i1 = emit_insn_before (pat, insn);
5309   PATTERN (insn) = newpat;
5310   INSN_CODE (insn) = -1;
5311   recog_memoized (insn);
5312   recog_memoized (i1);
5313   record_delay_slot_pair (i1, insn, delay, 0);
5314   return true;
5315 }
5316 
5317 /* Examine if INSN is the result of splitting a load into a real load and a
5318    shadow, and if so, undo the transformation.  */
5319 static void
5320 undo_split_delayed_nonbranch (rtx_insn *insn)
5321 {
5322   int icode = recog_memoized (insn);
5323   enum attr_type type;
5324   rtx prev_pat, insn_pat;
5325   rtx_insn *prev;
5326 
5327   if (icode < 0)
5328     return;
5329   type = get_attr_type (insn);
5330   if (type != TYPE_LOAD_SHADOW && type != TYPE_MULT_SHADOW)
5331     return;
5332   prev = PREV_INSN (insn);
5333   prev_pat = PATTERN (prev);
5334   insn_pat = PATTERN (insn);
5335   if (GET_CODE (prev_pat) == COND_EXEC)
5336     {
5337       prev_pat = COND_EXEC_CODE (prev_pat);
5338       insn_pat = COND_EXEC_CODE (insn_pat);
5339     }
5340 
5341   gcc_assert (GET_CODE (prev_pat) == UNSPEC
5342 	      && ((XINT (prev_pat, 1) == UNSPEC_REAL_LOAD
5343 		   && type == TYPE_LOAD_SHADOW)
5344 		  || (XINT (prev_pat, 1) == UNSPEC_REAL_MULT
5345 		      && type == TYPE_MULT_SHADOW)));
5346   insn_pat = gen_rtx_SET (SET_DEST (insn_pat),
5347 			  XVECEXP (prev_pat, 0, 1));
5348   insn_pat = duplicate_cond (insn_pat, prev);
5349   PATTERN (insn) = insn_pat;
5350   INSN_CODE (insn) = -1;
5351   delete_insn (prev);
5352 }
5353 
5354 /* Split every insn (i.e. jumps and calls) which can have delay slots into
5355    two parts: the first one is scheduled normally and emits the instruction,
5356    while the second one is a shadow insn which shows the side effect taking
5357    place. The second one is placed in the right cycle by the scheduler, but
5358    not emitted as an assembly instruction.  */
5359 
5360 static void
5361 split_delayed_insns (void)
5362 {
5363   rtx_insn *insn;
5364   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5365     {
5366       if (JUMP_P (insn) || CALL_P (insn))
5367 	split_delayed_branch (insn);
5368     }
5369 }
5370 
5371 /* For every insn that has an entry in the new_conditions vector, give it
5372    the appropriate predicate.  */
5373 static void
5374 conditionalize_after_sched (void)
5375 {
5376   basic_block bb;
5377   rtx_insn *insn;
5378   FOR_EACH_BB_FN (bb, cfun)
5379     FOR_BB_INSNS (bb, insn)
5380       {
5381 	unsigned uid = INSN_UID (insn);
5382 	rtx cond;
5383 	if (!NONDEBUG_INSN_P (insn) || uid >= INSN_INFO_LENGTH)
5384 	  continue;
5385 	cond = INSN_INFO_ENTRY (uid).new_cond;
5386 	if (cond == NULL_RTX)
5387 	  continue;
5388 	if (dump_file)
5389 	  fprintf (dump_file, "Conditionalizing insn %d\n", uid);
5390 	predicate_insn (insn, cond, true);
5391       }
5392 }
5393 
5394 /* A callback for the hw-doloop pass.  This function examines INSN; if
5395    it is a loop_end pattern we recognize, return the reg rtx for the
5396    loop counter.  Otherwise, return NULL_RTX.  */
5397 
5398 static rtx
5399 hwloop_pattern_reg (rtx_insn *insn)
5400 {
5401   rtx pat, reg;
5402 
5403   if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end)
5404     return NULL_RTX;
5405 
5406   pat = PATTERN (insn);
5407   reg = SET_DEST (XVECEXP (pat, 0, 1));
5408   if (!REG_P (reg))
5409     return NULL_RTX;
5410   return reg;
5411 }
5412 
5413 /* Return the number of cycles taken by BB, as computed by scheduling,
5414    including the latencies of all insns with delay slots.  IGNORE is
5415    an insn we should ignore in the calculation, usually the final
5416    branch.  */
5417 static int
5418 bb_earliest_end_cycle (basic_block bb, rtx ignore)
5419 {
5420   int earliest = 0;
5421   rtx_insn *insn;
5422 
5423   FOR_BB_INSNS (bb, insn)
5424     {
5425       int cycles, this_clock;
5426 
5427       if (LABEL_P (insn) || NOTE_P (insn) || DEBUG_INSN_P (insn)
5428 	  || GET_CODE (PATTERN (insn)) == USE
5429 	  || GET_CODE (PATTERN (insn)) == CLOBBER
5430 	  || insn == ignore)
5431 	continue;
5432 
5433       this_clock = insn_get_clock (insn);
5434       cycles = get_attr_cycles (insn);
5435 
5436       if (earliest < this_clock + cycles)
5437 	earliest = this_clock + cycles;
5438     }
5439   return earliest;
5440 }
5441 
5442 /* Examine the insns in BB and remove all which have a uid greater or
5443    equal to MAX_UID.  */
5444 static void
5445 filter_insns_above (basic_block bb, int max_uid)
5446 {
5447   rtx_insn *insn, *next;
5448   bool prev_ti = false;
5449   int prev_cycle = -1;
5450 
5451   FOR_BB_INSNS_SAFE (bb, insn, next)
5452     {
5453       int this_cycle;
5454       if (!NONDEBUG_INSN_P (insn))
5455 	continue;
5456       if (insn == BB_END (bb))
5457 	return;
5458       this_cycle = insn_get_clock (insn);
5459       if (prev_ti && this_cycle == prev_cycle)
5460 	{
5461 	  gcc_assert (GET_MODE (insn) != TImode);
5462 	  PUT_MODE (insn, TImode);
5463 	}
5464       prev_ti = false;
5465       if (INSN_UID (insn) >= max_uid)
5466 	{
5467 	  if (GET_MODE (insn) == TImode)
5468 	    {
5469 	      prev_ti = true;
5470 	      prev_cycle = this_cycle;
5471 	    }
5472 	  delete_insn (insn);
5473 	}
5474     }
5475 }
5476 
5477 /* Implement TARGET_ASM_EMIT_EXCEPT_PERSONALITY.  */
5478 
5479 static void
5480 c6x_asm_emit_except_personality (rtx personality)
5481 {
5482   fputs ("\t.personality\t", asm_out_file);
5483   output_addr_const (asm_out_file, personality);
5484   fputc ('\n', asm_out_file);
5485 }
5486 
5487 /* Use a special assembly directive rather than a regular setion for
5488    unwind table data.  */
5489 
5490 static void
5491 c6x_asm_init_sections (void)
5492 {
5493   exception_section = get_unnamed_section (0, output_section_asm_op,
5494 					   "\t.handlerdata");
5495 }
5496 
5497 /* A callback for the hw-doloop pass.  Called to optimize LOOP in a
5498    machine-specific fashion; returns true if successful and false if
5499    the hwloop_fail function should be called.  */
5500 
5501 static bool
5502 hwloop_optimize (hwloop_info loop)
5503 {
5504   basic_block entry_bb, bb;
5505   rtx_insn *seq, *insn, *prev, *entry_after, *end_packet;
5506   rtx_insn *head_insn, *tail_insn, *new_insns, *last_insn;
5507   int loop_earliest;
5508   int n_execute_packets;
5509   edge entry_edge;
5510   unsigned ix;
5511   int max_uid_before, delayed_splits;
5512   int i, sp_ii, min_ii, max_ii, max_parallel, n_insns, n_real_insns, stages;
5513   rtx_insn **orig_vec;
5514   rtx_insn **copies;
5515   rtx_insn ***insn_copies;
5516 
5517   if (!c6x_flag_modulo_sched || !c6x_flag_schedule_insns2
5518       || !TARGET_INSNS_64PLUS)
5519     return false;
5520 
5521   if (loop->iter_reg_used || loop->depth > 1)
5522     return false;
5523   if (loop->has_call || loop->has_asm)
5524     return false;
5525 
5526   if (loop->head != loop->tail)
5527     return false;
5528 
5529   gcc_assert (loop->incoming_dest == loop->head);
5530 
5531   entry_edge = NULL;
5532   FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge)
5533     if (entry_edge->flags & EDGE_FALLTHRU)
5534       break;
5535   if (entry_edge == NULL)
5536     return false;
5537 
5538   reshuffle_units (loop->head);
5539 
5540   in_hwloop = true;
5541   schedule_ebbs_init ();
5542   schedule_ebb (BB_HEAD (loop->tail), loop->loop_end, true);
5543   schedule_ebbs_finish ();
5544   in_hwloop = false;
5545 
5546   bb = loop->head;
5547   loop_earliest = bb_earliest_end_cycle (bb, loop->loop_end) + 1;
5548 
5549   max_uid_before = get_max_uid ();
5550 
5551   /* Split all multi-cycle operations, such as loads.  For normal
5552      scheduling, we only do this for branches, as the generated code
5553      would otherwise not be interrupt-safe.  When using sploop, it is
5554      safe and beneficial to split them.  If any multi-cycle operations
5555      remain after splitting (because we don't handle them yet), we
5556      cannot pipeline the loop.  */
5557   delayed_splits = 0;
5558   FOR_BB_INSNS (bb, insn)
5559     {
5560       if (NONDEBUG_INSN_P (insn))
5561 	{
5562 	  recog_memoized (insn);
5563 	  if (split_delayed_nonbranch (insn))
5564 	    delayed_splits++;
5565 	  else if (INSN_CODE (insn) >= 0
5566 		   && get_attr_cycles (insn) > 1)
5567 	    goto undo_splits;
5568 	}
5569     }
5570 
5571   /* Count the number of insns as well as the number real insns, and save
5572      the original sequence of insns in case we must restore it later.  */
5573   n_insns = n_real_insns = 0;
5574   FOR_BB_INSNS (bb, insn)
5575     {
5576       n_insns++;
5577       if (NONDEBUG_INSN_P (insn) && insn != loop->loop_end)
5578 	n_real_insns++;
5579     }
5580   orig_vec = XNEWVEC (rtx_insn *, n_insns);
5581   n_insns = 0;
5582   FOR_BB_INSNS (bb, insn)
5583     orig_vec[n_insns++] = insn;
5584 
5585   /* Count the unit reservations, and compute a minimum II from that
5586      table.  */
5587   count_unit_reqs (unit_reqs, loop->start_label,
5588 		   PREV_INSN (loop->loop_end));
5589   merge_unit_reqs (unit_reqs);
5590 
5591   min_ii = res_mii (unit_reqs);
5592   max_ii = loop_earliest < 15 ? loop_earliest : 14;
5593 
5594   /* Make copies of the loop body, up to a maximum number of stages we want
5595      to handle.  */
5596   max_parallel = loop_earliest / min_ii + 1;
5597 
5598   copies = XCNEWVEC (rtx_insn *, (max_parallel + 1) * n_real_insns);
5599   insn_copies = XNEWVEC (rtx_insn **, max_parallel + 1);
5600   for (i = 0; i < max_parallel + 1; i++)
5601     insn_copies[i] = copies + i * n_real_insns;
5602 
5603   head_insn = next_nonnote_nondebug_insn (loop->start_label);
5604   tail_insn = prev_real_insn (BB_END (bb));
5605 
5606   i = 0;
5607   FOR_BB_INSNS (bb, insn)
5608     if (NONDEBUG_INSN_P (insn) && insn != loop->loop_end)
5609       insn_copies[0][i++] = insn;
5610 
5611   sploop_max_uid_iter0 = get_max_uid ();
5612 
5613   /* Generate the copies of the loop body, and save them in the
5614      INSN_COPIES array.  */
5615   start_sequence ();
5616   for (i = 0; i < max_parallel; i++)
5617     {
5618       int j;
5619       rtx_insn *this_iter;
5620 
5621       this_iter = duplicate_insn_chain (head_insn, tail_insn);
5622       j = 0;
5623       while (this_iter)
5624 	{
5625 	  rtx_insn *prev_stage_insn = insn_copies[i][j];
5626 	  gcc_assert (INSN_CODE (this_iter) == INSN_CODE (prev_stage_insn));
5627 
5628 	  if (INSN_CODE (this_iter) >= 0
5629 	      && (get_attr_type (this_iter) == TYPE_LOAD_SHADOW
5630 		  || get_attr_type (this_iter) == TYPE_MULT_SHADOW))
5631 	    {
5632 	      rtx_insn *prev = PREV_INSN (this_iter);
5633 	      record_delay_slot_pair (prev, this_iter,
5634 				      get_attr_cycles (prev) - 1, 0);
5635 	    }
5636 	  else
5637 	    record_delay_slot_pair (prev_stage_insn, this_iter, i, 1);
5638 
5639 	  insn_copies[i + 1][j] = this_iter;
5640 	  j++;
5641 	  this_iter = next_nonnote_nondebug_insn (this_iter);
5642 	}
5643     }
5644   new_insns = get_insns ();
5645   last_insn = insn_copies[max_parallel][n_real_insns - 1];
5646   end_sequence ();
5647   emit_insn_before (new_insns, BB_END (bb));
5648 
5649   /* Try to schedule the loop using varying initiation intervals,
5650      starting with the smallest possible and incrementing it
5651      on failure.  */
5652   for (sp_ii = min_ii; sp_ii <= max_ii; sp_ii++)
5653     {
5654       basic_block tmp_bb;
5655       if (dump_file)
5656 	fprintf (dump_file, "Trying to schedule for II %d\n", sp_ii);
5657 
5658       df_clear_flags (DF_LR_RUN_DCE);
5659 
5660       schedule_ebbs_init ();
5661       set_modulo_params (sp_ii, max_parallel, n_real_insns,
5662 			 sploop_max_uid_iter0);
5663       tmp_bb = schedule_ebb (BB_HEAD (bb), last_insn, true);
5664       schedule_ebbs_finish ();
5665 
5666       if (tmp_bb)
5667 	{
5668 	  if (dump_file)
5669 	    fprintf (dump_file, "Found schedule with II %d\n", sp_ii);
5670 	  break;
5671 	}
5672     }
5673 
5674   discard_delay_pairs_above (max_uid_before);
5675 
5676   if (sp_ii > max_ii)
5677     goto restore_loop;
5678 
5679   stages = insn_get_clock (ss.last_scheduled_iter0) / sp_ii + 1;
5680 
5681   if (stages == 1 && sp_ii > 5)
5682     goto restore_loop;
5683 
5684   /* At this point, we know we've been successful, unless we find later that
5685      there are too many execute packets for the loop buffer to hold.  */
5686 
5687   /* Assign reservations to the instructions in the loop.  We must find
5688      the stage that contains the full loop kernel, and transfer the
5689      reservations of the instructions contained in it to the corresponding
5690      instructions from iteration 0, which are the only ones we'll keep.  */
5691   assign_reservations (BB_HEAD (bb), ss.last_scheduled_insn);
5692   SET_PREV_INSN (BB_END (bb)) = ss.last_scheduled_iter0;
5693   SET_NEXT_INSN (ss.last_scheduled_iter0) = BB_END (bb);
5694   filter_insns_above (bb, sploop_max_uid_iter0);
5695 
5696   for (i = 0; i < n_real_insns; i++)
5697     {
5698       rtx insn = insn_copies[0][i];
5699       int uid = INSN_UID (insn);
5700       int stage = insn_uid_get_clock (uid) / sp_ii;
5701 
5702       if (stage + 1 < stages)
5703 	{
5704 	  int copy_uid;
5705 	  stage = stages - stage - 1;
5706 	  copy_uid = INSN_UID (insn_copies[stage][i]);
5707 	  INSN_INFO_ENTRY (uid).reservation
5708 	    = INSN_INFO_ENTRY (copy_uid).reservation;
5709 	}
5710     }
5711   if (stages == 1)
5712     stages++;
5713 
5714   /* Compute the number of execute packets the pipelined form of the loop will
5715      require.  */
5716   prev = NULL;
5717   n_execute_packets = 0;
5718   for (insn = loop->start_label;
5719        insn != loop->loop_end;
5720        insn = NEXT_INSN (insn))
5721     {
5722       if (NONDEBUG_INSN_P (insn) && GET_MODE (insn) == TImode
5723 	  && !shadow_p (insn))
5724 	{
5725 	  n_execute_packets++;
5726 	  if (prev && insn_get_clock (prev) + 1 != insn_get_clock (insn))
5727 	    /* We need an extra NOP instruction.  */
5728 	    n_execute_packets++;
5729 
5730 	  prev = insn;
5731 	}
5732     }
5733 
5734   end_packet = ss.last_scheduled_iter0;
5735   while (!NONDEBUG_INSN_P (end_packet) || GET_MODE (end_packet) != TImode)
5736     end_packet = PREV_INSN (end_packet);
5737 
5738   /* The earliest cycle in which we can emit the SPKERNEL instruction.  */
5739   loop_earliest = (stages - 1) * sp_ii;
5740   if (loop_earliest > insn_get_clock (end_packet))
5741     {
5742       n_execute_packets++;
5743       end_packet = loop->loop_end;
5744     }
5745   else
5746     loop_earliest = insn_get_clock (end_packet);
5747 
5748   if (n_execute_packets > 14)
5749     goto restore_loop;
5750 
5751   /* Generate the spkernel instruction, and place it at the appropriate
5752      spot.  */
5753   PUT_MODE (end_packet, VOIDmode);
5754 
5755   insn = emit_jump_insn_before (
5756 	   gen_spkernel (GEN_INT (stages - 1),
5757 			 const0_rtx, JUMP_LABEL (loop->loop_end)),
5758 	   end_packet);
5759   JUMP_LABEL (insn) = JUMP_LABEL (loop->loop_end);
5760   insn_set_clock (insn, loop_earliest);
5761   PUT_MODE (insn, TImode);
5762   INSN_INFO_ENTRY (INSN_UID (insn)).ebb_start = false;
5763   delete_insn (loop->loop_end);
5764 
5765   /* Place the mvc and sploop instructions before the loop.  */
5766   entry_bb = entry_edge->src;
5767 
5768   start_sequence ();
5769 
5770   insn = emit_insn (gen_mvilc (loop->iter_reg));
5771   if (loop->iter_reg_used_outside)
5772     insn = emit_move_insn (loop->iter_reg, const0_rtx);
5773   insn = emit_insn (gen_sploop (GEN_INT (sp_ii)));
5774   seq = get_insns ();
5775 
5776   if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1)
5777     {
5778       basic_block new_bb;
5779       edge e;
5780       edge_iterator ei;
5781 
5782       emit_insn_before (seq, BB_HEAD (loop->head));
5783       seq = emit_label_before (gen_label_rtx (), seq);
5784 
5785       new_bb = create_basic_block (seq, insn, entry_bb);
5786       FOR_EACH_EDGE (e, ei, loop->incoming)
5787 	{
5788 	  if (!(e->flags & EDGE_FALLTHRU))
5789 	    redirect_edge_and_branch_force (e, new_bb);
5790 	  else
5791 	    redirect_edge_succ (e, new_bb);
5792 	}
5793       make_edge (new_bb, loop->head, 0);
5794     }
5795   else
5796     {
5797       entry_after = BB_END (entry_bb);
5798       while (DEBUG_INSN_P (entry_after)
5799 	     || (NOTE_P (entry_after)
5800 		 && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK))
5801 	entry_after = PREV_INSN (entry_after);
5802       emit_insn_after (seq, entry_after);
5803     }
5804 
5805   end_sequence ();
5806 
5807   /* Make sure we don't try to schedule this loop again.  */
5808   for (ix = 0; loop->blocks.iterate (ix, &bb); ix++)
5809     bb->flags |= BB_DISABLE_SCHEDULE;
5810 
5811   return true;
5812 
5813  restore_loop:
5814   if (dump_file)
5815     fprintf (dump_file, "Unable to pipeline loop.\n");
5816 
5817   for (i = 1; i < n_insns; i++)
5818     {
5819       SET_NEXT_INSN (orig_vec[i - 1]) = orig_vec[i];
5820       SET_PREV_INSN (orig_vec[i]) = orig_vec[i - 1];
5821     }
5822   SET_PREV_INSN (orig_vec[0]) = PREV_INSN (BB_HEAD (bb));
5823   SET_NEXT_INSN (PREV_INSN (BB_HEAD (bb))) = orig_vec[0];
5824   SET_NEXT_INSN (orig_vec[n_insns - 1]) = NEXT_INSN (BB_END (bb));
5825   SET_PREV_INSN (NEXT_INSN (BB_END (bb))) = orig_vec[n_insns - 1];
5826   BB_HEAD (bb) = orig_vec[0];
5827   BB_END (bb) = orig_vec[n_insns - 1];
5828  undo_splits:
5829   free_delay_pairs ();
5830   FOR_BB_INSNS (bb, insn)
5831     if (NONDEBUG_INSN_P (insn))
5832       undo_split_delayed_nonbranch (insn);
5833   return false;
5834 }
5835 
5836 /* A callback for the hw-doloop pass.  Called when a loop we have discovered
5837    turns out not to be optimizable; we have to split the doloop_end pattern
5838    into a subtract and a test.  */
5839 static void
5840 hwloop_fail (hwloop_info loop)
5841 {
5842   rtx insn, test, testreg;
5843 
5844   if (dump_file)
5845     fprintf (dump_file, "splitting doloop insn %d\n",
5846 	     INSN_UID (loop->loop_end));
5847   insn = gen_addsi3 (loop->iter_reg, loop->iter_reg, constm1_rtx);
5848   /* See if we can emit the add at the head of the loop rather than at the
5849      end.  */
5850   if (loop->head == NULL
5851       || loop->iter_reg_used_outside
5852       || loop->iter_reg_used
5853       || TEST_HARD_REG_BIT (loop->regs_set_in_loop, REGNO (loop->iter_reg))
5854       || loop->incoming_dest != loop->head
5855       || EDGE_COUNT (loop->head->preds) != 2)
5856     emit_insn_before (insn, loop->loop_end);
5857   else
5858     {
5859       rtx_insn *t = loop->start_label;
5860       while (!NOTE_P (t) || NOTE_KIND (t) != NOTE_INSN_BASIC_BLOCK)
5861 	t = NEXT_INSN (t);
5862       emit_insn_after (insn, t);
5863     }
5864 
5865   testreg = SET_DEST (XVECEXP (PATTERN (loop->loop_end), 0, 2));
5866   if (GET_CODE (testreg) == SCRATCH)
5867     testreg = loop->iter_reg;
5868   else
5869     emit_insn_before (gen_movsi (testreg, loop->iter_reg), loop->loop_end);
5870 
5871   test = gen_rtx_NE (VOIDmode, testreg, const0_rtx);
5872   insn = emit_jump_insn_before (gen_cbranchsi4 (test, testreg, const0_rtx,
5873 						loop->start_label),
5874 				loop->loop_end);
5875 
5876   JUMP_LABEL (insn) = loop->start_label;
5877   LABEL_NUSES (loop->start_label)++;
5878   delete_insn (loop->loop_end);
5879 }
5880 
5881 static struct hw_doloop_hooks c6x_doloop_hooks =
5882 {
5883   hwloop_pattern_reg,
5884   hwloop_optimize,
5885   hwloop_fail
5886 };
5887 
5888 /* Run the hw-doloop pass to modulo-schedule hardware loops, or split the
5889    doloop_end patterns where such optimizations are impossible.  */
5890 static void
5891 c6x_hwloops (void)
5892 {
5893   if (optimize)
5894     reorg_loops (true, &c6x_doloop_hooks);
5895 }
5896 
5897 /* Implement the TARGET_MACHINE_DEPENDENT_REORG pass.  We split call insns here
5898    into a sequence that loads the return register and performs the call,
5899    and emit the return label.
5900    If scheduling after reload is requested, it happens here.  */
5901 
5902 static void
5903 c6x_reorg (void)
5904 {
5905   basic_block bb;
5906   bool do_selsched = (c6x_flag_schedule_insns2 && flag_selective_scheduling2
5907 		      && !maybe_skip_selective_scheduling ());
5908 
5909   /* We are freeing block_for_insn in the toplev to keep compatibility
5910      with old MDEP_REORGS that are not CFG based.  Recompute it now.  */
5911   compute_bb_for_insn ();
5912 
5913   df_clear_flags (DF_LR_RUN_DCE);
5914   df_note_add_problem ();
5915 
5916   /* If optimizing, we'll have split before scheduling.  */
5917   if (optimize == 0)
5918     split_all_insns ();
5919 
5920   df_analyze ();
5921 
5922   if (c6x_flag_schedule_insns2)
5923     {
5924       int sz = get_max_uid () * 3 / 2 + 1;
5925 
5926       insn_info.create (sz);
5927     }
5928 
5929   /* Make sure the real-jump insns we create are not deleted.  When modulo-
5930      scheduling, situations where a reg is only stored in a loop can also
5931      cause dead code when doing the initial unrolling.  */
5932   sched_no_dce = true;
5933 
5934   c6x_hwloops ();
5935 
5936   if (c6x_flag_schedule_insns2)
5937     {
5938       split_delayed_insns ();
5939       timevar_push (TV_SCHED2);
5940       if (do_selsched)
5941 	run_selective_scheduling ();
5942       else
5943 	schedule_ebbs ();
5944       conditionalize_after_sched ();
5945       timevar_pop (TV_SCHED2);
5946 
5947       free_delay_pairs ();
5948     }
5949   sched_no_dce = false;
5950 
5951   rtx_code_label **call_labels = XCNEWVEC (rtx_code_label *, get_max_uid () + 1);
5952 
5953   reorg_split_calls (call_labels);
5954 
5955   if (c6x_flag_schedule_insns2)
5956     {
5957       FOR_EACH_BB_FN (bb, cfun)
5958 	if ((bb->flags & BB_DISABLE_SCHEDULE) == 0)
5959 	  assign_reservations (BB_HEAD (bb), BB_END (bb));
5960     }
5961 
5962   if (c6x_flag_var_tracking)
5963     {
5964       timevar_push (TV_VAR_TRACKING);
5965       variable_tracking_main ();
5966       timevar_pop (TV_VAR_TRACKING);
5967     }
5968 
5969   reorg_emit_nops (call_labels);
5970 
5971   /* Post-process the schedule to move parallel insns into SEQUENCEs.  */
5972   if (c6x_flag_schedule_insns2)
5973     {
5974       free_delay_pairs ();
5975       c6x_gen_bundles ();
5976     }
5977 
5978   df_finish_pass (false);
5979 }
5980 
5981 /* Called when a function has been assembled.  It should perform all the
5982    tasks of ASM_DECLARE_FUNCTION_SIZE in elfos.h, plus target-specific
5983    tasks.
5984    We free the reservation (and other scheduling) information here now that
5985    all insns have been output.  */
5986 void
5987 c6x_function_end (FILE *file, const char *fname)
5988 {
5989   c6x_output_fn_unwind (file);
5990 
5991   insn_info.release ();
5992 
5993   if (!flag_inhibit_size_directive)
5994     ASM_OUTPUT_MEASURED_SIZE (file, fname);
5995 }
5996 
5997 /* Determine whether X is a shift with code CODE and an integer amount
5998    AMOUNT.  */
5999 static bool
6000 shift_p (rtx x, enum rtx_code code, int amount)
6001 {
6002   return (GET_CODE (x) == code && GET_CODE (XEXP (x, 1)) == CONST_INT
6003 	  && INTVAL (XEXP (x, 1)) == amount);
6004 }
6005 
6006 /* Compute a (partial) cost for rtx X.  Return true if the complete
6007    cost has been computed, and false if subexpressions should be
6008    scanned.  In either case, *TOTAL contains the cost result.  */
6009 
6010 static bool
6011 c6x_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total,
6012 	       bool speed)
6013 {
6014   int cost2 = COSTS_N_INSNS (1);
6015   rtx op0, op1;
6016   int code = GET_CODE (x);
6017 
6018   switch (code)
6019     {
6020     case CONST_INT:
6021       if (outer_code == SET || outer_code == PLUS)
6022         *total = satisfies_constraint_IsB (x) ? 0 : cost2;
6023       else if (outer_code == AND || outer_code == IOR || outer_code == XOR
6024 	       || outer_code == MINUS)
6025 	*total = satisfies_constraint_Is5 (x) ? 0 : cost2;
6026       else if (GET_RTX_CLASS (outer_code) == RTX_COMPARE
6027 	       || GET_RTX_CLASS (outer_code) == RTX_COMM_COMPARE)
6028 	*total = satisfies_constraint_Iu4 (x) ? 0 : cost2;
6029       else if (outer_code == ASHIFT || outer_code == ASHIFTRT
6030 	       || outer_code == LSHIFTRT)
6031 	*total = satisfies_constraint_Iu5 (x) ? 0 : cost2;
6032       else
6033 	*total = cost2;
6034       return true;
6035 
6036     case CONST:
6037     case LABEL_REF:
6038     case SYMBOL_REF:
6039     case CONST_DOUBLE:
6040       *total = COSTS_N_INSNS (2);
6041       return true;
6042 
6043     case TRUNCATE:
6044       /* Recognize a mult_highpart operation.  */
6045       if ((mode == HImode || mode == SImode)
6046 	  && GET_CODE (XEXP (x, 0)) == LSHIFTRT
6047 	  && GET_MODE (XEXP (x, 0)) == GET_MODE_2XWIDER_MODE (mode).require ()
6048 	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
6049 	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6050 	  && INTVAL (XEXP (XEXP (x, 0), 1)) == GET_MODE_BITSIZE (mode))
6051 	{
6052 	  rtx mul = XEXP (XEXP (x, 0), 0);
6053 	  rtx op0 = XEXP (mul, 0);
6054 	  rtx op1 = XEXP (mul, 1);
6055 	  enum rtx_code code0 = GET_CODE (op0);
6056 	  enum rtx_code code1 = GET_CODE (op1);
6057 
6058 	  if ((code0 == code1
6059 	       && (code0 == SIGN_EXTEND || code0 == ZERO_EXTEND))
6060 	      || (mode == HImode
6061 		  && code0 == ZERO_EXTEND && code1 == SIGN_EXTEND))
6062 	    {
6063 	      if (mode == HImode)
6064 		*total = COSTS_N_INSNS (2);
6065 	      else
6066 		*total = COSTS_N_INSNS (12);
6067 	      mode = GET_MODE (XEXP (op0, 0));
6068 	      *total += rtx_cost (XEXP (op0, 0), mode, code0, 0, speed);
6069 	      *total += rtx_cost (XEXP (op1, 0), mode, code1, 0, speed);
6070 	      return true;
6071 	    }
6072 	}
6073       return false;
6074 
6075     case ASHIFT:
6076     case ASHIFTRT:
6077     case LSHIFTRT:
6078       if (mode == DImode)
6079 	*total = COSTS_N_INSNS (CONSTANT_P (XEXP (x, 1)) ? 4 : 15);
6080       else
6081 	*total = COSTS_N_INSNS (1);
6082       return false;
6083 
6084     case PLUS:
6085     case MINUS:
6086       *total = COSTS_N_INSNS (1);
6087       op0 = code == PLUS ? XEXP (x, 0) : XEXP (x, 1);
6088       op1 = code == PLUS ? XEXP (x, 1) : XEXP (x, 0);
6089       if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
6090 	  && INTEGRAL_MODE_P (mode)
6091 	  && GET_CODE (op0) == MULT
6092 	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
6093 	  && (INTVAL (XEXP (op0, 1)) == 2
6094 	      || INTVAL (XEXP (op0, 1)) == 4
6095 	      || (code == PLUS && INTVAL (XEXP (op0, 1)) == 8)))
6096 	{
6097 	  *total += rtx_cost (XEXP (op0, 0), mode, ASHIFT, 0, speed);
6098 	  *total += rtx_cost (op1, mode, (enum rtx_code) code, 1, speed);
6099 	  return true;
6100 	}
6101       return false;
6102 
6103     case MULT:
6104       op0 = XEXP (x, 0);
6105       op1 = XEXP (x, 1);
6106       if (mode == DFmode)
6107 	{
6108 	  if (TARGET_FP)
6109 	    *total = COSTS_N_INSNS (speed ? 10 : 1);
6110 	  else
6111 	    *total = COSTS_N_INSNS (speed ? 200 : 4);
6112 	}
6113       else if (mode == SFmode)
6114 	{
6115 	  if (TARGET_FP)
6116 	    *total = COSTS_N_INSNS (speed ? 4 : 1);
6117 	  else
6118 	    *total = COSTS_N_INSNS (speed ? 100 : 4);
6119 	}
6120       else if (mode == DImode)
6121 	{
6122 	  if (TARGET_MPY32
6123 	      && GET_CODE (op0) == GET_CODE (op1)
6124 	      && (GET_CODE (op0) == ZERO_EXTEND
6125 		  || GET_CODE (op0) == SIGN_EXTEND))
6126 	    {
6127 	      *total = COSTS_N_INSNS (speed ? 2 : 1);
6128 	      op0 = XEXP (op0, 0);
6129 	      op1 = XEXP (op1, 0);
6130 	    }
6131 	  else
6132 	    /* Maybe improve this laster.  */
6133 	    *total = COSTS_N_INSNS (20);
6134 	}
6135       else if (mode == SImode)
6136 	{
6137 	  if (((GET_CODE (op0) == ZERO_EXTEND
6138 		|| GET_CODE (op0) == SIGN_EXTEND
6139 		|| shift_p (op0, LSHIFTRT, 16))
6140 	       && (GET_CODE (op1) == SIGN_EXTEND
6141 		   || GET_CODE (op1) == ZERO_EXTEND
6142 		   || scst5_operand (op1, SImode)
6143 		   || shift_p (op1, ASHIFTRT, 16)
6144 		   || shift_p (op1, LSHIFTRT, 16)))
6145 	      || (shift_p (op0, ASHIFTRT, 16)
6146 		  && (GET_CODE (op1) == SIGN_EXTEND
6147 		      || shift_p (op1, ASHIFTRT, 16))))
6148 	    {
6149 	      *total = COSTS_N_INSNS (speed ? 2 : 1);
6150 	      op0 = XEXP (op0, 0);
6151 	      if (scst5_operand (op1, SImode))
6152 		op1 = NULL_RTX;
6153 	      else
6154 		op1 = XEXP (op1, 0);
6155 	    }
6156 	  else if (!speed)
6157 	    *total = COSTS_N_INSNS (1);
6158 	  else if (TARGET_MPY32)
6159 	    *total = COSTS_N_INSNS (4);
6160 	  else
6161 	    *total = COSTS_N_INSNS (6);
6162 	}
6163       else if (mode == HImode)
6164 	*total = COSTS_N_INSNS (speed ? 2 : 1);
6165 
6166       if (GET_CODE (op0) != REG
6167 	  && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
6168 	*total += rtx_cost (op0, mode, MULT, 0, speed);
6169       if (op1 && GET_CODE (op1) != REG
6170 	  && (GET_CODE (op1) != SUBREG || GET_CODE (SUBREG_REG (op1)) != REG))
6171 	*total += rtx_cost (op1, mode, MULT, 1, speed);
6172       return true;
6173 
6174     case UDIV:
6175     case DIV:
6176       /* This is a bit random; assuming on average there'll be 16 leading
6177 	 zeros.  FIXME: estimate better for constant dividends.  */
6178       *total = COSTS_N_INSNS (6 + 3 * 16);
6179       return false;
6180 
6181     case IF_THEN_ELSE:
6182       /* Recognize the cmp_and/ior patterns.  */
6183       op0 = XEXP (x, 0);
6184       if ((GET_CODE (op0) == EQ || GET_CODE (op0) == NE)
6185 	  && REG_P (XEXP (op0, 0))
6186 	  && XEXP (op0, 1) == const0_rtx
6187 	  && rtx_equal_p (XEXP (x, 1), XEXP (op0, 0)))
6188 	{
6189 	  *total = rtx_cost (XEXP (x, 1), VOIDmode, (enum rtx_code) outer_code,
6190 			     opno, speed);
6191 	  return false;
6192 	}
6193       return false;
6194 
6195     default:
6196       return false;
6197     }
6198 }
6199 
6200 /* Implements target hook vector_mode_supported_p.  */
6201 
6202 static bool
6203 c6x_vector_mode_supported_p (machine_mode mode)
6204 {
6205   switch (mode)
6206     {
6207     case E_V2HImode:
6208     case E_V4QImode:
6209     case E_V2SImode:
6210     case E_V4HImode:
6211     case E_V8QImode:
6212       return true;
6213     default:
6214       return false;
6215     }
6216 }
6217 
6218 /* Implements TARGET_VECTORIZE_PREFERRED_SIMD_MODE.  */
6219 static machine_mode
6220 c6x_preferred_simd_mode (scalar_mode mode)
6221 {
6222   switch (mode)
6223     {
6224     case E_HImode:
6225       return V2HImode;
6226     case E_QImode:
6227       return V4QImode;
6228 
6229     default:
6230       return word_mode;
6231     }
6232 }
6233 
6234 /* Implement TARGET_SCALAR_MODE_SUPPORTED_P.  */
6235 
6236 static bool
6237 c6x_scalar_mode_supported_p (scalar_mode mode)
6238 {
6239   if (ALL_FIXED_POINT_MODE_P (mode)
6240       && GET_MODE_PRECISION (mode) <= 2 * BITS_PER_WORD)
6241     return true;
6242 
6243   return default_scalar_mode_supported_p (mode);
6244 }
6245 
6246 /* Output a reference from a function exception table to the type_info
6247    object X.  Output these via a special assembly directive.  */
6248 
6249 static bool
6250 c6x_output_ttype (rtx x)
6251 {
6252   /* Use special relocations for symbol references.  */
6253   if (GET_CODE (x) != CONST_INT)
6254     fputs ("\t.ehtype\t", asm_out_file);
6255   else
6256     fputs ("\t.word\t", asm_out_file);
6257   output_addr_const (asm_out_file, x);
6258   fputc ('\n', asm_out_file);
6259 
6260   return TRUE;
6261 }
6262 
6263 /* Modify the return address of the current function.  */
6264 
6265 void
6266 c6x_set_return_address (rtx source, rtx scratch)
6267 {
6268   struct c6x_frame frame;
6269   rtx addr;
6270   HOST_WIDE_INT offset;
6271 
6272   c6x_compute_frame_layout (&frame);
6273   if (! c6x_save_reg (RETURN_ADDR_REGNO))
6274     emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNO), source);
6275   else
6276     {
6277 
6278       if (frame_pointer_needed)
6279 	{
6280 	  addr = hard_frame_pointer_rtx;
6281 	  offset = frame.b3_offset;
6282 	}
6283       else
6284 	{
6285 	  addr = stack_pointer_rtx;
6286 	  offset = frame.to_allocate - frame.b3_offset;
6287 	}
6288 
6289       /* TODO: Use base+offset loads where possible.  */
6290       if (offset)
6291 	{
6292 	  HOST_WIDE_INT low = trunc_int_for_mode (offset, HImode);
6293 
6294 	  emit_insn (gen_movsi_high (scratch, GEN_INT (low)));
6295 	  if (low != offset)
6296 	    emit_insn (gen_movsi_lo_sum (scratch, scratch, GEN_INT(offset)));
6297 	  emit_insn (gen_addsi3 (scratch, addr, scratch));
6298 	  addr = scratch;
6299 	}
6300 
6301       emit_move_insn (gen_frame_mem (Pmode, addr), source);
6302     }
6303 }
6304 
6305 /* We save pairs of registers using a DImode store.  Describe the component
6306    registers for DWARF generation code.  */
6307 
6308 static rtx
6309 c6x_dwarf_register_span (rtx rtl)
6310 {
6311     unsigned regno;
6312     unsigned real_regno;
6313     int nregs;
6314     int i;
6315     rtx p;
6316 
6317     regno = REGNO (rtl);
6318     nregs = REG_NREGS (rtl);
6319     if (nregs == 1)
6320       return  NULL_RTX;
6321 
6322     p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc(nregs));
6323     for (i = 0; i < nregs; i++)
6324       {
6325 	if (TARGET_BIG_ENDIAN)
6326 	  real_regno = regno + nregs - (i + 1);
6327 	else
6328 	  real_regno = regno + i;
6329 
6330 	XVECEXP (p, 0, i) = gen_rtx_REG (SImode, real_regno);
6331       }
6332 
6333     return p;
6334 }
6335 
6336 /* Codes for all the C6X builtins.  */
6337 enum c6x_builtins
6338 {
6339   C6X_BUILTIN_SADD,
6340   C6X_BUILTIN_SSUB,
6341   C6X_BUILTIN_ADD2,
6342   C6X_BUILTIN_SUB2,
6343   C6X_BUILTIN_ADD4,
6344   C6X_BUILTIN_SUB4,
6345   C6X_BUILTIN_SADD2,
6346   C6X_BUILTIN_SSUB2,
6347   C6X_BUILTIN_SADDU4,
6348 
6349   C6X_BUILTIN_SMPY,
6350   C6X_BUILTIN_SMPYH,
6351   C6X_BUILTIN_SMPYHL,
6352   C6X_BUILTIN_SMPYLH,
6353   C6X_BUILTIN_MPY2,
6354   C6X_BUILTIN_SMPY2,
6355 
6356   C6X_BUILTIN_CLRR,
6357   C6X_BUILTIN_EXTR,
6358   C6X_BUILTIN_EXTRU,
6359 
6360   C6X_BUILTIN_SSHL,
6361   C6X_BUILTIN_SUBC,
6362   C6X_BUILTIN_ABS,
6363   C6X_BUILTIN_ABS2,
6364   C6X_BUILTIN_AVG2,
6365   C6X_BUILTIN_AVGU4,
6366 
6367   C6X_BUILTIN_MAX
6368 };
6369 
6370 
6371 static GTY(()) tree c6x_builtin_decls[C6X_BUILTIN_MAX];
6372 
6373 /* Return the C6X builtin for CODE.  */
6374 static tree
6375 c6x_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
6376 {
6377   if (code >= C6X_BUILTIN_MAX)
6378     return error_mark_node;
6379 
6380   return c6x_builtin_decls[code];
6381 }
6382 
6383 #define def_builtin(NAME, TYPE, CODE)					\
6384 do {									\
6385   tree bdecl;								\
6386   bdecl = add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD,	\
6387 				NULL, NULL_TREE);			\
6388   c6x_builtin_decls[CODE] = bdecl;					\
6389 } while (0)
6390 
6391 /* Set up all builtin functions for this target.  */
6392 static void
6393 c6x_init_builtins (void)
6394 {
6395   tree V4QI_type_node = build_vector_type (unsigned_intQI_type_node, 4);
6396   tree V2HI_type_node = build_vector_type (intHI_type_node, 2);
6397   tree V2SI_type_node = build_vector_type (intSI_type_node, 2);
6398   tree int_ftype_int
6399     = build_function_type_list (integer_type_node, integer_type_node,
6400 				NULL_TREE);
6401   tree int_ftype_int_int
6402     = build_function_type_list (integer_type_node, integer_type_node,
6403 				integer_type_node, NULL_TREE);
6404   tree v2hi_ftype_v2hi
6405     = build_function_type_list (V2HI_type_node, V2HI_type_node, NULL_TREE);
6406   tree v4qi_ftype_v4qi_v4qi
6407     = build_function_type_list (V4QI_type_node, V4QI_type_node,
6408 				V4QI_type_node, NULL_TREE);
6409   tree v2hi_ftype_v2hi_v2hi
6410     = build_function_type_list (V2HI_type_node, V2HI_type_node,
6411 				V2HI_type_node, NULL_TREE);
6412   tree v2si_ftype_v2hi_v2hi
6413     = build_function_type_list (V2SI_type_node, V2HI_type_node,
6414 				V2HI_type_node, NULL_TREE);
6415 
6416   def_builtin ("__builtin_c6x_sadd", int_ftype_int_int,
6417 	       C6X_BUILTIN_SADD);
6418   def_builtin ("__builtin_c6x_ssub", int_ftype_int_int,
6419 	       C6X_BUILTIN_SSUB);
6420   def_builtin ("__builtin_c6x_add2", v2hi_ftype_v2hi_v2hi,
6421 	       C6X_BUILTIN_ADD2);
6422   def_builtin ("__builtin_c6x_sub2", v2hi_ftype_v2hi_v2hi,
6423 	       C6X_BUILTIN_SUB2);
6424   def_builtin ("__builtin_c6x_add4", v4qi_ftype_v4qi_v4qi,
6425 	       C6X_BUILTIN_ADD4);
6426   def_builtin ("__builtin_c6x_sub4", v4qi_ftype_v4qi_v4qi,
6427 	       C6X_BUILTIN_SUB4);
6428   def_builtin ("__builtin_c6x_mpy2", v2si_ftype_v2hi_v2hi,
6429 	       C6X_BUILTIN_MPY2);
6430   def_builtin ("__builtin_c6x_sadd2", v2hi_ftype_v2hi_v2hi,
6431 	       C6X_BUILTIN_SADD2);
6432   def_builtin ("__builtin_c6x_ssub2", v2hi_ftype_v2hi_v2hi,
6433 	       C6X_BUILTIN_SSUB2);
6434   def_builtin ("__builtin_c6x_saddu4", v4qi_ftype_v4qi_v4qi,
6435 	       C6X_BUILTIN_SADDU4);
6436   def_builtin ("__builtin_c6x_smpy2", v2si_ftype_v2hi_v2hi,
6437 	       C6X_BUILTIN_SMPY2);
6438 
6439   def_builtin ("__builtin_c6x_smpy", int_ftype_int_int,
6440 	       C6X_BUILTIN_SMPY);
6441   def_builtin ("__builtin_c6x_smpyh", int_ftype_int_int,
6442 	       C6X_BUILTIN_SMPYH);
6443   def_builtin ("__builtin_c6x_smpyhl", int_ftype_int_int,
6444 	       C6X_BUILTIN_SMPYHL);
6445   def_builtin ("__builtin_c6x_smpylh", int_ftype_int_int,
6446 	       C6X_BUILTIN_SMPYLH);
6447 
6448   def_builtin ("__builtin_c6x_sshl", int_ftype_int_int,
6449 	       C6X_BUILTIN_SSHL);
6450   def_builtin ("__builtin_c6x_subc", int_ftype_int_int,
6451 	       C6X_BUILTIN_SUBC);
6452 
6453   def_builtin ("__builtin_c6x_avg2", v2hi_ftype_v2hi_v2hi,
6454 	       C6X_BUILTIN_AVG2);
6455   def_builtin ("__builtin_c6x_avgu4", v4qi_ftype_v4qi_v4qi,
6456 	       C6X_BUILTIN_AVGU4);
6457 
6458   def_builtin ("__builtin_c6x_clrr", int_ftype_int_int,
6459 	       C6X_BUILTIN_CLRR);
6460   def_builtin ("__builtin_c6x_extr", int_ftype_int_int,
6461 	       C6X_BUILTIN_EXTR);
6462   def_builtin ("__builtin_c6x_extru", int_ftype_int_int,
6463 	       C6X_BUILTIN_EXTRU);
6464 
6465   def_builtin ("__builtin_c6x_abs", int_ftype_int, C6X_BUILTIN_ABS);
6466   def_builtin ("__builtin_c6x_abs2", v2hi_ftype_v2hi, C6X_BUILTIN_ABS2);
6467 }
6468 
6469 
6470 struct builtin_description
6471 {
6472   const enum insn_code icode;
6473   const char *const name;
6474   const enum c6x_builtins code;
6475 };
6476 
6477 static const struct builtin_description bdesc_2arg[] =
6478 {
6479   { CODE_FOR_saddsi3, "__builtin_c6x_sadd", C6X_BUILTIN_SADD },
6480   { CODE_FOR_ssubsi3, "__builtin_c6x_ssub", C6X_BUILTIN_SSUB },
6481   { CODE_FOR_addv2hi3, "__builtin_c6x_add2", C6X_BUILTIN_ADD2 },
6482   { CODE_FOR_subv2hi3, "__builtin_c6x_sub2", C6X_BUILTIN_SUB2 },
6483   { CODE_FOR_addv4qi3, "__builtin_c6x_add4", C6X_BUILTIN_ADD4 },
6484   { CODE_FOR_subv4qi3, "__builtin_c6x_sub4", C6X_BUILTIN_SUB4 },
6485   { CODE_FOR_ss_addv2hi3, "__builtin_c6x_sadd2", C6X_BUILTIN_SADD2 },
6486   { CODE_FOR_ss_subv2hi3, "__builtin_c6x_ssub2", C6X_BUILTIN_SSUB2 },
6487   { CODE_FOR_us_addv4qi3, "__builtin_c6x_saddu4", C6X_BUILTIN_SADDU4 },
6488 
6489   { CODE_FOR_subcsi3, "__builtin_c6x_subc", C6X_BUILTIN_SUBC },
6490   { CODE_FOR_ss_ashlsi3, "__builtin_c6x_sshl", C6X_BUILTIN_SSHL },
6491 
6492   { CODE_FOR_avgv2hi3, "__builtin_c6x_avg2", C6X_BUILTIN_AVG2 },
6493   { CODE_FOR_uavgv4qi3, "__builtin_c6x_avgu4", C6X_BUILTIN_AVGU4 },
6494 
6495   { CODE_FOR_mulhqsq3, "__builtin_c6x_smpy", C6X_BUILTIN_SMPY },
6496   { CODE_FOR_mulhqsq3_hh, "__builtin_c6x_smpyh", C6X_BUILTIN_SMPYH },
6497   { CODE_FOR_mulhqsq3_lh, "__builtin_c6x_smpylh", C6X_BUILTIN_SMPYLH },
6498   { CODE_FOR_mulhqsq3_hl, "__builtin_c6x_smpyhl", C6X_BUILTIN_SMPYHL },
6499 
6500   { CODE_FOR_mulv2hqv2sq3, "__builtin_c6x_smpy2", C6X_BUILTIN_SMPY2 },
6501 
6502   { CODE_FOR_clrr, "__builtin_c6x_clrr", C6X_BUILTIN_CLRR },
6503   { CODE_FOR_extr, "__builtin_c6x_extr", C6X_BUILTIN_EXTR },
6504   { CODE_FOR_extru, "__builtin_c6x_extru", C6X_BUILTIN_EXTRU }
6505 };
6506 
6507 static const struct builtin_description bdesc_1arg[] =
6508 {
6509   { CODE_FOR_ssabssi2, "__builtin_c6x_abs", C6X_BUILTIN_ABS },
6510   { CODE_FOR_ssabsv2hi2, "__builtin_c6x_abs2", C6X_BUILTIN_ABS2 }
6511 };
6512 
6513 /* Errors in the source file can cause expand_expr to return const0_rtx
6514    where we expect a vector.  To avoid crashing, use one of the vector
6515    clear instructions.  */
6516 static rtx
6517 safe_vector_operand (rtx x, machine_mode mode)
6518 {
6519   if (x != const0_rtx)
6520     return x;
6521   x = gen_reg_rtx (SImode);
6522 
6523   emit_insn (gen_movsi (x, CONST0_RTX (SImode)));
6524   return gen_lowpart (mode, x);
6525 }
6526 
6527 /* Subroutine of c6x_expand_builtin to take care of binop insns.  MACFLAG is -1
6528    if this is a normal binary op, or one of the MACFLAG_xxx constants.  */
6529 
6530 static rtx
6531 c6x_expand_binop_builtin (enum insn_code icode, tree exp, rtx target,
6532 			  bool match_op)
6533 {
6534   int offs = match_op ? 1 : 0;
6535   rtx pat;
6536   tree arg0 = CALL_EXPR_ARG (exp, 0);
6537   tree arg1 = CALL_EXPR_ARG (exp, 1);
6538   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6539   rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6540   machine_mode op0mode = GET_MODE (op0);
6541   machine_mode op1mode = GET_MODE (op1);
6542   machine_mode tmode = insn_data[icode].operand[0].mode;
6543   machine_mode mode0 = insn_data[icode].operand[1 + offs].mode;
6544   machine_mode mode1 = insn_data[icode].operand[2 + offs].mode;
6545   rtx ret = target;
6546 
6547   if (VECTOR_MODE_P (mode0))
6548     op0 = safe_vector_operand (op0, mode0);
6549   if (VECTOR_MODE_P (mode1))
6550     op1 = safe_vector_operand (op1, mode1);
6551 
6552   if (! target
6553       || GET_MODE (target) != tmode
6554       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6555     {
6556       if (tmode == SQmode || tmode == V2SQmode)
6557 	{
6558 	  ret = gen_reg_rtx (tmode == SQmode ? SImode : V2SImode);
6559 	  target = gen_lowpart (tmode, ret);
6560 	}
6561       else
6562 	target = gen_reg_rtx (tmode);
6563     }
6564 
6565   if ((op0mode == V2HImode || op0mode == SImode || op0mode == VOIDmode)
6566       && (mode0 == V2HQmode || mode0 == HQmode || mode0 == SQmode))
6567     {
6568       op0mode = mode0;
6569       op0 = gen_lowpart (mode0, op0);
6570     }
6571   if ((op1mode == V2HImode || op1mode == SImode || op1mode == VOIDmode)
6572       && (mode1 == V2HQmode || mode1 == HQmode || mode1 == SQmode))
6573     {
6574       op1mode = mode1;
6575       op1 = gen_lowpart (mode1, op1);
6576     }
6577   /* In case the insn wants input operands in modes different from
6578      the result, abort.  */
6579   gcc_assert ((op0mode == mode0 || op0mode == VOIDmode)
6580 	      && (op1mode == mode1 || op1mode == VOIDmode));
6581 
6582   if (! (*insn_data[icode].operand[1 + offs].predicate) (op0, mode0))
6583     op0 = copy_to_mode_reg (mode0, op0);
6584   if (! (*insn_data[icode].operand[2 + offs].predicate) (op1, mode1))
6585     op1 = copy_to_mode_reg (mode1, op1);
6586 
6587   if (match_op)
6588     pat = GEN_FCN (icode) (target, target, op0, op1);
6589   else
6590     pat = GEN_FCN (icode) (target, op0, op1);
6591 
6592   if (! pat)
6593     return 0;
6594 
6595   emit_insn (pat);
6596 
6597   return ret;
6598 }
6599 
6600 /* Subroutine of c6x_expand_builtin to take care of unop insns.  */
6601 
6602 static rtx
6603 c6x_expand_unop_builtin (enum insn_code icode, tree exp,
6604 			  rtx target)
6605 {
6606   rtx pat;
6607   tree arg0 = CALL_EXPR_ARG (exp, 0);
6608   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6609   machine_mode op0mode = GET_MODE (op0);
6610   machine_mode tmode = insn_data[icode].operand[0].mode;
6611   machine_mode mode0 = insn_data[icode].operand[1].mode;
6612 
6613   if (! target
6614       || GET_MODE (target) != tmode
6615       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6616     target = gen_reg_rtx (tmode);
6617 
6618   if (VECTOR_MODE_P (mode0))
6619     op0 = safe_vector_operand (op0, mode0);
6620 
6621   if (op0mode == SImode && mode0 == HImode)
6622     {
6623       op0mode = HImode;
6624       op0 = gen_lowpart (HImode, op0);
6625     }
6626   gcc_assert (op0mode == mode0 || op0mode == VOIDmode);
6627 
6628   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6629     op0 = copy_to_mode_reg (mode0, op0);
6630 
6631   pat = GEN_FCN (icode) (target, op0);
6632   if (! pat)
6633     return 0;
6634   emit_insn (pat);
6635   return target;
6636 }
6637 
6638 /* Expand an expression EXP that calls a built-in function,
6639    with result going to TARGET if that's convenient
6640    (and in mode MODE if that's convenient).
6641    SUBTARGET may be used as the target for computing one of EXP's operands.
6642    IGNORE is nonzero if the value is to be ignored.  */
6643 
6644 static rtx
6645 c6x_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
6646 		     rtx subtarget ATTRIBUTE_UNUSED,
6647 		     machine_mode mode ATTRIBUTE_UNUSED,
6648 		     int ignore ATTRIBUTE_UNUSED)
6649 {
6650   size_t i;
6651   const struct builtin_description *d;
6652   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6653   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6654 
6655   for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
6656     if (d->code == fcode)
6657       return c6x_expand_binop_builtin (d->icode, exp, target,
6658 				       fcode == C6X_BUILTIN_CLRR);
6659 
6660   for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
6661     if (d->code == fcode)
6662       return c6x_expand_unop_builtin (d->icode, exp, target);
6663 
6664   gcc_unreachable ();
6665 }
6666 
6667 /* Target unwind frame info is generated from dwarf CFI directives, so
6668    always output dwarf2 unwind info.  */
6669 
6670 static enum unwind_info_type
6671 c6x_debug_unwind_info (void)
6672 {
6673   if (flag_unwind_tables || flag_exceptions)
6674     return UI_DWARF2;
6675 
6676   return default_debug_unwind_info ();
6677 }
6678 
6679 /* Implement TARGET_HARD_REGNO_MODE_OK.  */
6680 
6681 static bool
6682 c6x_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
6683 {
6684   return GET_MODE_SIZE (mode) <= UNITS_PER_WORD || (regno & 1) == 0;
6685 }
6686 
6687 /* Implement TARGET_MODES_TIEABLE_P.  */
6688 
6689 static bool
6690 c6x_modes_tieable_p (machine_mode mode1, machine_mode mode2)
6691 {
6692   return (mode1 == mode2
6693 	  || (GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
6694 	      && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD));
6695 }
6696 
6697 
6698 /* Target Structure.  */
6699 
6700 /* Initialize the GCC target structure.  */
6701 #undef TARGET_FUNCTION_ARG
6702 #define TARGET_FUNCTION_ARG c6x_function_arg
6703 #undef TARGET_FUNCTION_ARG_ADVANCE
6704 #define TARGET_FUNCTION_ARG_ADVANCE c6x_function_arg_advance
6705 #undef TARGET_FUNCTION_ARG_BOUNDARY
6706 #define TARGET_FUNCTION_ARG_BOUNDARY c6x_function_arg_boundary
6707 #undef TARGET_FUNCTION_ARG_ROUND_BOUNDARY
6708 #define TARGET_FUNCTION_ARG_ROUND_BOUNDARY \
6709   c6x_function_arg_round_boundary
6710 #undef TARGET_FUNCTION_VALUE_REGNO_P
6711 #define TARGET_FUNCTION_VALUE_REGNO_P c6x_function_value_regno_p
6712 #undef TARGET_FUNCTION_VALUE
6713 #define TARGET_FUNCTION_VALUE c6x_function_value
6714 #undef TARGET_LIBCALL_VALUE
6715 #define TARGET_LIBCALL_VALUE c6x_libcall_value
6716 #undef TARGET_RETURN_IN_MEMORY
6717 #define TARGET_RETURN_IN_MEMORY c6x_return_in_memory
6718 #undef TARGET_RETURN_IN_MSB
6719 #define TARGET_RETURN_IN_MSB c6x_return_in_msb
6720 #undef TARGET_PASS_BY_REFERENCE
6721 #define TARGET_PASS_BY_REFERENCE c6x_pass_by_reference
6722 #undef TARGET_CALLEE_COPIES
6723 #define TARGET_CALLEE_COPIES c6x_callee_copies
6724 #undef TARGET_STRUCT_VALUE_RTX
6725 #define TARGET_STRUCT_VALUE_RTX c6x_struct_value_rtx
6726 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
6727 #define TARGET_FUNCTION_OK_FOR_SIBCALL c6x_function_ok_for_sibcall
6728 
6729 #undef TARGET_ASM_OUTPUT_MI_THUNK
6730 #define TARGET_ASM_OUTPUT_MI_THUNK c6x_output_mi_thunk
6731 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
6732 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK c6x_can_output_mi_thunk
6733 
6734 #undef TARGET_BUILD_BUILTIN_VA_LIST
6735 #define TARGET_BUILD_BUILTIN_VA_LIST c6x_build_builtin_va_list
6736 
6737 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
6738 #define TARGET_ASM_TRAMPOLINE_TEMPLATE c6x_asm_trampoline_template
6739 #undef TARGET_TRAMPOLINE_INIT
6740 #define TARGET_TRAMPOLINE_INIT c6x_initialize_trampoline
6741 
6742 #undef TARGET_LEGITIMATE_CONSTANT_P
6743 #define TARGET_LEGITIMATE_CONSTANT_P c6x_legitimate_constant_p
6744 #undef TARGET_LEGITIMATE_ADDRESS_P
6745 #define TARGET_LEGITIMATE_ADDRESS_P c6x_legitimate_address_p
6746 
6747 #undef TARGET_LRA_P
6748 #define TARGET_LRA_P hook_bool_void_false
6749 
6750 #undef TARGET_IN_SMALL_DATA_P
6751 #define TARGET_IN_SMALL_DATA_P c6x_in_small_data_p
6752 #undef	TARGET_ASM_SELECT_RTX_SECTION
6753 #define TARGET_ASM_SELECT_RTX_SECTION  c6x_select_rtx_section
6754 #undef TARGET_ASM_SELECT_SECTION
6755 #define TARGET_ASM_SELECT_SECTION  c6x_elf_select_section
6756 #undef TARGET_ASM_UNIQUE_SECTION
6757 #define TARGET_ASM_UNIQUE_SECTION  c6x_elf_unique_section
6758 #undef TARGET_SECTION_TYPE_FLAGS
6759 #define TARGET_SECTION_TYPE_FLAGS  c6x_section_type_flags
6760 #undef TARGET_HAVE_SRODATA_SECTION
6761 #define TARGET_HAVE_SRODATA_SECTION true
6762 #undef TARGET_ASM_MERGEABLE_RODATA_PREFIX
6763 #define TARGET_ASM_MERGEABLE_RODATA_PREFIX ".const"
6764 
6765 #undef TARGET_OPTION_OVERRIDE
6766 #define TARGET_OPTION_OVERRIDE c6x_option_override
6767 #undef TARGET_CONDITIONAL_REGISTER_USAGE
6768 #define TARGET_CONDITIONAL_REGISTER_USAGE c6x_conditional_register_usage
6769 
6770 #undef TARGET_INIT_LIBFUNCS
6771 #define TARGET_INIT_LIBFUNCS c6x_init_libfuncs
6772 #undef TARGET_LIBFUNC_GNU_PREFIX
6773 #define TARGET_LIBFUNC_GNU_PREFIX true
6774 
6775 #undef TARGET_SCALAR_MODE_SUPPORTED_P
6776 #define TARGET_SCALAR_MODE_SUPPORTED_P c6x_scalar_mode_supported_p
6777 #undef TARGET_VECTOR_MODE_SUPPORTED_P
6778 #define TARGET_VECTOR_MODE_SUPPORTED_P c6x_vector_mode_supported_p
6779 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
6780 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE c6x_preferred_simd_mode
6781 
6782 #undef TARGET_RTX_COSTS
6783 #define TARGET_RTX_COSTS c6x_rtx_costs
6784 
6785 #undef TARGET_SCHED_INIT
6786 #define TARGET_SCHED_INIT c6x_sched_init
6787 #undef TARGET_SCHED_SET_SCHED_FLAGS
6788 #define TARGET_SCHED_SET_SCHED_FLAGS c6x_set_sched_flags
6789 #undef TARGET_SCHED_ADJUST_COST
6790 #define TARGET_SCHED_ADJUST_COST c6x_adjust_cost
6791 #undef TARGET_SCHED_ISSUE_RATE
6792 #define TARGET_SCHED_ISSUE_RATE c6x_issue_rate
6793 #undef TARGET_SCHED_VARIABLE_ISSUE
6794 #define TARGET_SCHED_VARIABLE_ISSUE c6x_variable_issue
6795 #undef TARGET_SCHED_REORDER
6796 #define TARGET_SCHED_REORDER c6x_sched_reorder
6797 #undef TARGET_SCHED_REORDER2
6798 #define TARGET_SCHED_REORDER2 c6x_sched_reorder2
6799 #undef TARGET_SCHED_DFA_NEW_CYCLE
6800 #define TARGET_SCHED_DFA_NEW_CYCLE c6x_dfa_new_cycle
6801 #undef TARGET_SCHED_DFA_PRE_CYCLE_INSN
6802 #define TARGET_SCHED_DFA_PRE_CYCLE_INSN c6x_sched_dfa_pre_cycle_insn
6803 #undef TARGET_SCHED_EXPOSED_PIPELINE
6804 #define TARGET_SCHED_EXPOSED_PIPELINE true
6805 
6806 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
6807 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT c6x_alloc_sched_context
6808 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
6809 #define TARGET_SCHED_INIT_SCHED_CONTEXT c6x_init_sched_context
6810 #undef TARGET_SCHED_SET_SCHED_CONTEXT
6811 #define TARGET_SCHED_SET_SCHED_CONTEXT c6x_set_sched_context
6812 #undef TARGET_SCHED_CLEAR_SCHED_CONTEXT
6813 #define TARGET_SCHED_CLEAR_SCHED_CONTEXT c6x_clear_sched_context
6814 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
6815 #define TARGET_SCHED_FREE_SCHED_CONTEXT c6x_free_sched_context
6816 
6817 #undef TARGET_CAN_ELIMINATE
6818 #define TARGET_CAN_ELIMINATE c6x_can_eliminate
6819 
6820 #undef TARGET_PREFERRED_RENAME_CLASS
6821 #define TARGET_PREFERRED_RENAME_CLASS c6x_preferred_rename_class
6822 
6823 #undef TARGET_MACHINE_DEPENDENT_REORG
6824 #define TARGET_MACHINE_DEPENDENT_REORG c6x_reorg
6825 
6826 #undef TARGET_ASM_FILE_START
6827 #define TARGET_ASM_FILE_START c6x_file_start
6828 
6829 #undef  TARGET_PRINT_OPERAND
6830 #define TARGET_PRINT_OPERAND c6x_print_operand
6831 #undef  TARGET_PRINT_OPERAND_ADDRESS
6832 #define TARGET_PRINT_OPERAND_ADDRESS c6x_print_operand_address
6833 #undef  TARGET_PRINT_OPERAND_PUNCT_VALID_P
6834 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P c6x_print_operand_punct_valid_p
6835 
6836 /* C6x unwinding tables use a different format for the typeinfo tables.  */
6837 #undef TARGET_ASM_TTYPE
6838 #define TARGET_ASM_TTYPE c6x_output_ttype
6839 
6840 /* The C6x ABI follows the ARM EABI exception handling rules.  */
6841 #undef TARGET_ARM_EABI_UNWINDER
6842 #define TARGET_ARM_EABI_UNWINDER true
6843 
6844 #undef TARGET_ASM_EMIT_EXCEPT_PERSONALITY
6845 #define TARGET_ASM_EMIT_EXCEPT_PERSONALITY c6x_asm_emit_except_personality
6846 
6847 #undef TARGET_ASM_INIT_SECTIONS
6848 #define TARGET_ASM_INIT_SECTIONS c6x_asm_init_sections
6849 
6850 #undef TARGET_DEBUG_UNWIND_INFO
6851 #define TARGET_DEBUG_UNWIND_INFO  c6x_debug_unwind_info
6852 
6853 #undef TARGET_DWARF_REGISTER_SPAN
6854 #define TARGET_DWARF_REGISTER_SPAN c6x_dwarf_register_span
6855 
6856 #undef TARGET_INIT_BUILTINS
6857 #define TARGET_INIT_BUILTINS c6x_init_builtins
6858 #undef TARGET_EXPAND_BUILTIN
6859 #define TARGET_EXPAND_BUILTIN c6x_expand_builtin
6860 #undef  TARGET_BUILTIN_DECL
6861 #define TARGET_BUILTIN_DECL c6x_builtin_decl
6862 
6863 #undef TARGET_HARD_REGNO_MODE_OK
6864 #define TARGET_HARD_REGNO_MODE_OK c6x_hard_regno_mode_ok
6865 #undef TARGET_MODES_TIEABLE_P
6866 #define TARGET_MODES_TIEABLE_P c6x_modes_tieable_p
6867 
6868 struct gcc_target targetm = TARGET_INITIALIZER;
6869 
6870 #include "gt-c6x.h"
6871