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