OSDN Git Service

* common/config/c6x/c6x-common.c (c6x_option_optimization_table):
[pf3gnuchains/gcc-fork.git] / gcc / config / c6x / c6x.c
1 /* Target Code for TI C6X
2    Copyright (C) 2010, 2011 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 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "insn-flags.h"
29 #include "output.h"
30 #include "insn-attr.h"
31 #include "insn-codes.h"
32 #include "expr.h"
33 #include "regs.h"
34 #include "optabs.h"
35 #include "recog.h"
36 #include "ggc.h"
37 #include "sched-int.h"
38 #include "timevar.h"
39 #include "tm_p.h"
40 #include "tm-preds.h"
41 #include "tm-constrs.h"
42 #include "df.h"
43 #include "integrate.h"
44 #include "diagnostic-core.h"
45 #include "cgraph.h"
46 #include "cfglayout.h"
47 #include "langhooks.h"
48 #include "target.h"
49 #include "target-def.h"
50 #include "sel-sched.h"
51 #include "debug.h"
52 #include "opts.h"
53 #include "hw-doloop.h"
54
55 /* Table of supported architecture variants.  */
56 typedef struct
57 {
58   const char *arch;
59   enum c6x_cpu_type type;
60   unsigned short features;
61 } c6x_arch_table;
62
63 /* A list of all ISAs, mapping each one to a representative device.
64    Used for -march selection.  */
65 static const c6x_arch_table all_isas[] =
66 {
67 #define C6X_ISA(NAME,DEVICE,FLAGS) \
68   { NAME, DEVICE, FLAGS },
69 #include "c6x-isas.def"
70 #undef C6X_ISA
71   { NULL, C6X_CPU_C62X, 0 }
72 };
73
74 /* This is the parsed result of the "-march=" option, if given.  */
75 enum c6x_cpu_type c6x_arch = C6X_DEFAULT_ARCH;
76
77 /* A mask of insn types that are allowed by the architecture selected by
78    the -march option.  */
79 unsigned long c6x_insn_mask = C6X_DEFAULT_INSN_MASK;
80
81 /* The instruction that is being output (as obtained from FINAL_PRESCAN_INSN).
82  */
83 static rtx c6x_current_insn = NULL_RTX;
84
85 /* A decl we build to access __c6xabi_DSBT_base.  */
86 static GTY(()) tree dsbt_decl;
87 \f
88 /* Determines whether we run our final scheduling pass or not.  We always
89    avoid the normal second scheduling pass.  */
90 static int c6x_flag_schedule_insns2;
91
92 /* Determines whether we run variable tracking in machine dependent
93    reorganization.  */
94 static int c6x_flag_var_tracking;
95
96 /* Determines whether we use modulo scheduling.  */
97 static int c6x_flag_modulo_sched;
98
99 /* Record the state of flag_pic before we set it to 1 for DSBT.  */
100 int c6x_initial_flag_pic;
101 \f
102 typedef struct
103 {
104   /* We record the clock cycle for every insn during scheduling.  */
105   int clock;
106   /* After scheduling, we run assign_reservations to choose unit
107      reservations for all insns.  These are recorded here.  */
108   int reservation;
109   /* Records the new condition for insns which must be made
110      conditional after scheduling.  An entry of NULL_RTX means no such
111      change is necessary.  */
112   rtx new_cond;
113   /* True for the first insn that was scheduled in an ebb.  */
114   bool ebb_start;
115   /* The scheduler state after the insn, transformed into a mask of UNIT_QID
116      bits rather than storing the state.  Meaningful only for the last
117      insn in a cycle.  */
118   unsigned int unit_mask;
119 } c6x_sched_insn_info;
120
121 DEF_VEC_O(c6x_sched_insn_info);
122 DEF_VEC_ALLOC_O(c6x_sched_insn_info, heap);
123
124 /* Record a c6x_sched_insn_info structure for every insn in the function.  */
125 static VEC(c6x_sched_insn_info, heap) *insn_info;
126
127 #define INSN_INFO_LENGTH (VEC_length (c6x_sched_insn_info, insn_info))
128 #define INSN_INFO_ENTRY(N) (*VEC_index (c6x_sched_insn_info, insn_info, (N)))
129
130 static bool done_cfi_sections;
131
132 #define RESERVATION_FLAG_D 1
133 #define RESERVATION_FLAG_L 2
134 #define RESERVATION_FLAG_S 4
135 #define RESERVATION_FLAG_M 8
136 #define RESERVATION_FLAG_DL (RESERVATION_FLAG_D | RESERVATION_FLAG_L)
137 #define RESERVATION_FLAG_DS (RESERVATION_FLAG_D | RESERVATION_FLAG_S)
138 #define RESERVATION_FLAG_LS (RESERVATION_FLAG_L | RESERVATION_FLAG_S)
139 #define RESERVATION_FLAG_DLS (RESERVATION_FLAG_D | RESERVATION_FLAG_LS)
140
141 /* The DFA names of the units.  */
142 static const char *const c6x_unit_names[] =
143 {
144   "d1", "l1", "s1", "m1", "fps1", "fpl1", "adddps1", "adddpl1",
145   "d2", "l2", "s2", "m2", "fps2", "fpl2", "adddps2", "adddpl2"
146 };
147
148 /* The DFA unit number for each unit in c6x_unit_names[].  */
149 static int c6x_unit_codes[ARRAY_SIZE (c6x_unit_names)];
150
151 /* Unit query IDs.  */
152 #define UNIT_QID_D1 0
153 #define UNIT_QID_L1 1
154 #define UNIT_QID_S1 2
155 #define UNIT_QID_M1 3
156 #define UNIT_QID_FPS1 4
157 #define UNIT_QID_FPL1 5
158 #define UNIT_QID_ADDDPS1 6
159 #define UNIT_QID_ADDDPL1 7
160 #define UNIT_QID_SIDE_OFFSET 8
161
162 #define RESERVATION_S1 2
163 #define RESERVATION_S2 10
164
165 /* An enum for the unit requirements we count in the UNIT_REQS table.  */
166 enum unitreqs
167 {
168   UNIT_REQ_D,
169   UNIT_REQ_L,
170   UNIT_REQ_S,
171   UNIT_REQ_M,
172   UNIT_REQ_DL,
173   UNIT_REQ_DS,
174   UNIT_REQ_LS,
175   UNIT_REQ_DLS,
176   UNIT_REQ_T,
177   UNIT_REQ_X,
178   UNIT_REQ_MAX
179 };
180
181 /* A table used to count unit requirements.  Used when computing minimum
182    iteration intervals.  */
183 typedef int unit_req_table[2][UNIT_REQ_MAX];
184 static unit_req_table unit_reqs;
185 \f
186 /* Register map for debugging.  */
187 int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
188 {
189   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* A0 - A15.  */
190   37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,   /* A16 - A32.  */
191   50, 51, 52,
192   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,   /* B0 - B15.  */
193   29, 30, 31,
194   53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,   /* B16 - B32.  */
195   66, 67, 68,
196   -1, -1, -1                                            /* FP, ARGP, ILC.  */
197 };
198 \f
199 /* Allocate a new, cleared machine_function structure.  */
200
201 static struct machine_function *
202 c6x_init_machine_status (void)
203 {
204   return ggc_alloc_cleared_machine_function ();
205 }
206
207 /* Implement TARGET_OPTION_OVERRIDE.  */
208
209 static void
210 c6x_option_override (void)
211 {
212   unsigned i;
213
214   if (global_options_set.x_c6x_arch_option)
215     {
216       c6x_arch = all_isas[c6x_arch_option].type;
217       c6x_insn_mask &= ~C6X_INSNS_ALL_CPU_BITS;
218       c6x_insn_mask |= all_isas[c6x_arch_option].features;
219     }
220
221   c6x_flag_schedule_insns2 = flag_schedule_insns_after_reload;
222   flag_schedule_insns_after_reload = 0;
223
224   c6x_flag_modulo_sched = flag_modulo_sched;
225   flag_modulo_sched = 0;
226
227   init_machine_status = c6x_init_machine_status;
228
229   for (i = 0; i < ARRAY_SIZE (c6x_unit_names); i++)
230     c6x_unit_codes[i] = get_cpu_unit_code (c6x_unit_names[i]);
231
232   if (flag_pic && !TARGET_DSBT)
233     {
234       error ("-fpic and -fPIC not supported without -mdsbt on this target");
235       flag_pic = 0;
236     }
237   c6x_initial_flag_pic = flag_pic;
238   if (TARGET_DSBT && !flag_pic)
239     flag_pic = 1;
240 }
241
242
243 /* Implement the TARGET_CONDITIONAL_REGISTER_USAGE hook.  */
244
245 static void
246 c6x_conditional_register_usage (void)
247 {
248   int i;
249   if (c6x_arch == C6X_CPU_C62X || c6x_arch == C6X_CPU_C67X)
250     for (i = 16; i < 32; i++)
251       {
252         fixed_regs[i] = 1;
253         fixed_regs[32 + i] = 1;
254       }
255   if (TARGET_INSNS_64)
256     {
257       SET_HARD_REG_BIT (reg_class_contents[(int)PREDICATE_A_REGS],
258                         REG_A0);
259       SET_HARD_REG_BIT (reg_class_contents[(int)PREDICATE_REGS],
260                         REG_A0);
261       CLEAR_HARD_REG_BIT (reg_class_contents[(int)NONPREDICATE_A_REGS],
262                           REG_A0);
263       CLEAR_HARD_REG_BIT (reg_class_contents[(int)NONPREDICATE_REGS],
264                           REG_A0);
265     }
266 }
267 \f
268 static GTY(()) rtx eqdf_libfunc;
269 static GTY(()) rtx nedf_libfunc;
270 static GTY(()) rtx ledf_libfunc;
271 static GTY(()) rtx ltdf_libfunc;
272 static GTY(()) rtx gedf_libfunc;
273 static GTY(()) rtx gtdf_libfunc;
274 static GTY(()) rtx eqsf_libfunc;
275 static GTY(()) rtx nesf_libfunc;
276 static GTY(()) rtx lesf_libfunc;
277 static GTY(()) rtx ltsf_libfunc;
278 static GTY(()) rtx gesf_libfunc;
279 static GTY(()) rtx gtsf_libfunc;
280 static GTY(()) rtx strasgi_libfunc;
281 static GTY(()) rtx strasgi64p_libfunc;
282
283 /* Implement the TARGET_INIT_LIBFUNCS macro.  We use this to rename library
284    functions to match the C6x ABI.  */
285
286 static void
287 c6x_init_libfuncs (void)
288 {
289   /* Double-precision floating-point arithmetic.  */
290   set_optab_libfunc (add_optab, DFmode, "__c6xabi_addd");
291   set_optab_libfunc (sdiv_optab, DFmode, "__c6xabi_divd");
292   set_optab_libfunc (smul_optab, DFmode, "__c6xabi_mpyd");
293   set_optab_libfunc (neg_optab, DFmode, "__c6xabi_negd");
294   set_optab_libfunc (sub_optab, DFmode, "__c6xabi_subd");
295
296   /* Single-precision floating-point arithmetic.  */
297   set_optab_libfunc (add_optab, SFmode, "__c6xabi_addf");
298   set_optab_libfunc (sdiv_optab, SFmode, "__c6xabi_divf");
299   set_optab_libfunc (smul_optab, SFmode, "__c6xabi_mpyf");
300   set_optab_libfunc (neg_optab, SFmode, "__c6xabi_negf");
301   set_optab_libfunc (sub_optab, SFmode, "__c6xabi_subf");
302
303   /* Floating-point comparisons.  */
304   eqsf_libfunc = init_one_libfunc ("__c6xabi_eqf");
305   nesf_libfunc = init_one_libfunc ("__c6xabi_neqf");
306   lesf_libfunc = init_one_libfunc ("__c6xabi_lef");
307   ltsf_libfunc = init_one_libfunc ("__c6xabi_ltf");
308   gesf_libfunc = init_one_libfunc ("__c6xabi_gef");
309   gtsf_libfunc = init_one_libfunc ("__c6xabi_gtf");
310   eqdf_libfunc = init_one_libfunc ("__c6xabi_eqd");
311   nedf_libfunc = init_one_libfunc ("__c6xabi_neqd");
312   ledf_libfunc = init_one_libfunc ("__c6xabi_led");
313   ltdf_libfunc = init_one_libfunc ("__c6xabi_ltd");
314   gedf_libfunc = init_one_libfunc ("__c6xabi_ged");
315   gtdf_libfunc = init_one_libfunc ("__c6xabi_gtd");
316
317   set_optab_libfunc (eq_optab, SFmode, NULL);
318   set_optab_libfunc (ne_optab, SFmode, "__c6xabi_neqf");
319   set_optab_libfunc (gt_optab, SFmode, NULL);
320   set_optab_libfunc (ge_optab, SFmode, NULL);
321   set_optab_libfunc (lt_optab, SFmode, NULL);
322   set_optab_libfunc (le_optab, SFmode, NULL);
323   set_optab_libfunc (unord_optab, SFmode, "__c6xabi_unordf");
324   set_optab_libfunc (eq_optab, DFmode, NULL);
325   set_optab_libfunc (ne_optab, DFmode, "__c6xabi_neqd");
326   set_optab_libfunc (gt_optab, DFmode, NULL);
327   set_optab_libfunc (ge_optab, DFmode, NULL);
328   set_optab_libfunc (lt_optab, DFmode, NULL);
329   set_optab_libfunc (le_optab, DFmode, NULL);
330   set_optab_libfunc (unord_optab, DFmode, "__c6xabi_unordd");
331
332   /* Floating-point to integer conversions.  */
333   set_conv_libfunc (sfix_optab, SImode, DFmode, "__c6xabi_fixdi");
334   set_conv_libfunc (ufix_optab, SImode, DFmode, "__c6xabi_fixdu");
335   set_conv_libfunc (sfix_optab, DImode, DFmode, "__c6xabi_fixdlli");
336   set_conv_libfunc (ufix_optab, DImode, DFmode, "__c6xabi_fixdull");
337   set_conv_libfunc (sfix_optab, SImode, SFmode, "__c6xabi_fixfi");
338   set_conv_libfunc (ufix_optab, SImode, SFmode, "__c6xabi_fixfu");
339   set_conv_libfunc (sfix_optab, DImode, SFmode, "__c6xabi_fixflli");
340   set_conv_libfunc (ufix_optab, DImode, SFmode, "__c6xabi_fixfull");
341
342   /* Conversions between floating types.  */
343   set_conv_libfunc (trunc_optab, SFmode, DFmode, "__c6xabi_cvtdf");
344   set_conv_libfunc (sext_optab, DFmode, SFmode, "__c6xabi_cvtfd");
345
346   /* Integer to floating-point conversions.  */
347   set_conv_libfunc (sfloat_optab, DFmode, SImode, "__c6xabi_fltid");
348   set_conv_libfunc (ufloat_optab, DFmode, SImode, "__c6xabi_fltud");
349   set_conv_libfunc (sfloat_optab, DFmode, DImode, "__c6xabi_fltllid");
350   set_conv_libfunc (ufloat_optab, DFmode, DImode, "__c6xabi_fltulld");
351   set_conv_libfunc (sfloat_optab, SFmode, SImode, "__c6xabi_fltif");
352   set_conv_libfunc (ufloat_optab, SFmode, SImode, "__c6xabi_fltuf");
353   set_conv_libfunc (sfloat_optab, SFmode, DImode, "__c6xabi_fltllif");
354   set_conv_libfunc (ufloat_optab, SFmode, DImode, "__c6xabi_fltullf");
355
356   /* Long long.  */
357   set_optab_libfunc (smul_optab, DImode, "__c6xabi_mpyll");
358   set_optab_libfunc (ashl_optab, DImode, "__c6xabi_llshl");
359   set_optab_libfunc (lshr_optab, DImode, "__c6xabi_llshru");
360   set_optab_libfunc (ashr_optab, DImode, "__c6xabi_llshr");
361
362   set_optab_libfunc (sdiv_optab, SImode, "__c6xabi_divi");
363   set_optab_libfunc (udiv_optab, SImode, "__c6xabi_divu");
364   set_optab_libfunc (smod_optab, SImode, "__c6xabi_remi");
365   set_optab_libfunc (umod_optab, SImode, "__c6xabi_remu");
366   set_optab_libfunc (sdivmod_optab, SImode, "__c6xabi_divremi");
367   set_optab_libfunc (udivmod_optab, SImode, "__c6xabi_divremu");
368   set_optab_libfunc (sdiv_optab, DImode, "__c6xabi_divlli");
369   set_optab_libfunc (udiv_optab, DImode, "__c6xabi_divull");
370   set_optab_libfunc (smod_optab, DImode, "__c6xabi_remlli");
371   set_optab_libfunc (umod_optab, DImode, "__c6xabi_remull");
372   set_optab_libfunc (udivmod_optab, DImode, "__c6xabi_divremull");
373
374   /* Block move.  */
375   strasgi_libfunc = init_one_libfunc ("__c6xabi_strasgi");
376   strasgi64p_libfunc = init_one_libfunc ("__c6xabi_strasgi_64plus");
377 }
378
379 /* Begin the assembly file.  */
380
381 static void
382 c6x_file_start (void)
383 {
384   /* Variable tracking should be run after all optimizations which change order
385      of insns.  It also needs a valid CFG.  This can't be done in
386      c6x_override_options, because flag_var_tracking is finalized after
387      that.  */
388   c6x_flag_var_tracking = flag_var_tracking;
389   flag_var_tracking = 0;
390
391   done_cfi_sections = false;
392   default_file_start ();
393
394   /* Arrays are aligned to 8-byte boundaries.  */
395   asm_fprintf (asm_out_file,
396                "\t.c6xabi_attribute Tag_ABI_array_object_alignment, 0\n");
397   asm_fprintf (asm_out_file,
398                "\t.c6xabi_attribute Tag_ABI_array_object_align_expected, 0\n");
399
400   /* Stack alignment is 8 bytes.  */
401   asm_fprintf (asm_out_file,
402                "\t.c6xabi_attribute Tag_ABI_stack_align_needed, 0\n");
403   asm_fprintf (asm_out_file,
404                "\t.c6xabi_attribute Tag_ABI_stack_align_preserved, 0\n");
405
406 #if 0 /* FIXME: Reenable when TI's tools are fixed.  */
407   /* ??? Ideally we'd check flag_short_wchar somehow.  */
408   asm_fprintf (asm_out_file, "\t.c6xabi_attribute Tag_ABI_wchar_t, %d\n", 2);
409 #endif
410
411   /* We conform to version 1.0 of the ABI.  */
412   asm_fprintf (asm_out_file,
413                "\t.c6xabi_attribute Tag_ABI_conformance, \"1.0\"\n");
414
415 }
416
417 /* The LTO frontend only enables exceptions when it sees a function that
418    uses it.  This changes the return value of dwarf2out_do_frame, so we
419    have to check before every function.  */
420
421 void
422 c6x_output_file_unwind (FILE * f)
423 {
424   if (done_cfi_sections)
425     return;
426
427   /* Output a .cfi_sections directive.  */
428   if (dwarf2out_do_frame ())
429     {
430       if (flag_unwind_tables || flag_exceptions)
431         {
432           if (write_symbols == DWARF2_DEBUG
433               || write_symbols == VMS_AND_DWARF2_DEBUG)
434             asm_fprintf (f, "\t.cfi_sections .debug_frame, .c6xabi.exidx\n");
435           else
436             asm_fprintf (f, "\t.cfi_sections .c6xabi.exidx\n");
437         }
438       else
439         asm_fprintf (f, "\t.cfi_sections .debug_frame\n");
440       done_cfi_sections = true;
441     }
442 }
443
444 /* Output unwind directives at the end of a function.  */
445
446 static void
447 c6x_output_fn_unwind (FILE * f)
448 {
449   /* Return immediately if we are not generating unwinding tables.  */
450   if (! (flag_unwind_tables || flag_exceptions))
451     return;
452
453   /* If this function will never be unwound, then mark it as such.  */
454   if (!(flag_unwind_tables || crtl->uses_eh_lsda)
455       && (TREE_NOTHROW (current_function_decl)
456           || crtl->all_throwers_are_sibcalls))
457     fputs("\t.cantunwind\n", f);
458
459   fputs ("\t.endp\n", f);
460 }
461
462 \f
463 /* Stack and Calling.  */
464
465 int argument_registers[10] =
466 {
467   REG_A4, REG_B4,
468   REG_A6, REG_B6,
469   REG_A8, REG_B8,
470   REG_A10, REG_B10,
471   REG_A12, REG_B12
472 };
473
474 /* Implements the macro INIT_CUMULATIVE_ARGS defined in c6x.h.  */
475
476 void
477 c6x_init_cumulative_args (CUMULATIVE_ARGS *cum, const_tree fntype, rtx libname,
478                           int n_named_args ATTRIBUTE_UNUSED)
479 {
480   cum->count = 0;
481   cum->nregs = 10;
482   if (!libname && fntype)
483     {
484       /* We need to find out the number of named arguments.  Unfortunately,
485          for incoming arguments, N_NAMED_ARGS is set to -1.  */
486       if (stdarg_p (fntype))
487         cum->nregs = type_num_arguments (fntype) - 1;
488       if (cum->nregs > 10)
489         cum->nregs = 10;
490     }
491 }
492
493 /* Implements the macro FUNCTION_ARG defined in c6x.h.  */
494
495 static rtx
496 c6x_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
497                   const_tree type, bool named ATTRIBUTE_UNUSED)
498 {
499   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
500   if (cum->count >= cum->nregs)
501     return NULL_RTX;
502   if (type)
503     {
504       HOST_WIDE_INT size = int_size_in_bytes (type);
505       if (TARGET_BIG_ENDIAN && AGGREGATE_TYPE_P (type))
506         {
507           if (size > 4)
508             {
509               rtx reg1 = gen_rtx_REG (SImode, argument_registers[cum->count] + 1);
510               rtx reg2 = gen_rtx_REG (SImode, argument_registers[cum->count]);
511               rtvec vec = gen_rtvec (2, gen_rtx_EXPR_LIST (VOIDmode, reg1, const0_rtx),
512                                      gen_rtx_EXPR_LIST (VOIDmode, reg2, GEN_INT (4)));
513               return gen_rtx_PARALLEL (mode, vec);
514             }
515         }
516     }
517   return gen_rtx_REG (mode, argument_registers[cum->count]);
518 }
519
520 static void
521 c6x_function_arg_advance (cumulative_args_t cum_v,
522                           enum machine_mode mode ATTRIBUTE_UNUSED,
523                           const_tree type ATTRIBUTE_UNUSED,
524                           bool named ATTRIBUTE_UNUSED)
525 {
526   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
527   cum->count++;
528 }
529
530
531 /* Return true if BLOCK_REG_PADDING (MODE, TYPE, FIRST) should return
532    upward rather than downward.  */
533
534 bool
535 c6x_block_reg_pad_upward (enum machine_mode mode ATTRIBUTE_UNUSED,
536                           const_tree type, bool first)
537 {
538   HOST_WIDE_INT size;
539
540   if (!TARGET_BIG_ENDIAN)
541     return true;
542   if (!first)
543     return true;
544   if (!type)
545     return true;
546   size = int_size_in_bytes (type);
547   return size == 3;
548 }
549
550 /* Implement TARGET_FUNCTION_ARG_BOUNDARY.  */
551
552 static unsigned int
553 c6x_function_arg_boundary (enum machine_mode mode, const_tree type)
554 {
555   unsigned int boundary = type ? TYPE_ALIGN (type) : GET_MODE_BITSIZE (mode);
556
557   if (boundary > BITS_PER_WORD)
558     return 2 * BITS_PER_WORD;
559
560   if (mode == BLKmode)
561     {
562       HOST_WIDE_INT size = int_size_in_bytes (type);
563       if (size > 4)
564         return 2 * BITS_PER_WORD;
565       if (boundary < BITS_PER_WORD)
566         {
567           if (size >= 3)
568             return BITS_PER_WORD;
569           if (size >= 2)
570             return 2 * BITS_PER_UNIT;
571         }
572     }
573   return boundary;
574 }
575
576 /* Implement TARGET_FUNCTION_ARG_ROUND_BOUNDARY.  */
577 static unsigned int
578 c6x_function_arg_round_boundary (enum machine_mode mode, const_tree type)
579 {
580   return c6x_function_arg_boundary (mode, type);
581 }
582
583 /* TARGET_FUNCTION_VALUE implementation.  Returns an RTX representing the place
584    where function FUNC returns or receives a value of data type TYPE.  */
585
586 static rtx
587 c6x_function_value (const_tree type, const_tree func ATTRIBUTE_UNUSED,
588                     bool outgoing ATTRIBUTE_UNUSED)
589 {
590   /* Functions return values in register A4.  When returning aggregates, we may
591      have to adjust for endianness.  */
592   if (TARGET_BIG_ENDIAN && type && AGGREGATE_TYPE_P (type))
593     {
594       HOST_WIDE_INT size = int_size_in_bytes (type);
595       if (size > 4)
596         {
597
598           rtx reg1 = gen_rtx_REG (SImode, REG_A4 + 1);
599           rtx reg2 = gen_rtx_REG (SImode, REG_A4);
600           rtvec vec = gen_rtvec (2, gen_rtx_EXPR_LIST (VOIDmode, reg1, const0_rtx),
601                                  gen_rtx_EXPR_LIST (VOIDmode, reg2, GEN_INT (4)));
602           return gen_rtx_PARALLEL (TYPE_MODE (type), vec);
603         }
604     }
605   return gen_rtx_REG (TYPE_MODE (type), REG_A4);
606 }
607
608 /* Implement TARGET_LIBCALL_VALUE.  */
609
610 static rtx
611 c6x_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
612 {
613   return gen_rtx_REG (mode, REG_A4);
614 }
615
616 /* TARGET_STRUCT_VALUE_RTX implementation.  */
617
618 static rtx
619 c6x_struct_value_rtx (tree type ATTRIBUTE_UNUSED, int incoming ATTRIBUTE_UNUSED)
620 {
621   return gen_rtx_REG (Pmode, REG_A3);
622 }
623
624 /* Implement TARGET_FUNCTION_VALUE_REGNO_P.  */
625
626 static bool
627 c6x_function_value_regno_p (const unsigned int regno)
628 {
629   return regno == REG_A4;
630 }
631
632 /* Types larger than 64 bit, and variable sized types, are passed by
633    reference.  The callee must copy them; see c6x_callee_copies.  */
634
635 static bool
636 c6x_pass_by_reference (cumulative_args_t cum_v ATTRIBUTE_UNUSED,
637                        enum machine_mode mode, const_tree type,
638                        bool named ATTRIBUTE_UNUSED)
639 {
640   int size = -1;
641   if (type)
642     size = int_size_in_bytes (type);
643   else if (mode != VOIDmode)
644     size = GET_MODE_SIZE (mode);
645   return size > 2 * UNITS_PER_WORD || size == -1;
646 }
647
648 /* Decide whether a type should be returned in memory (true)
649    or in a register (false).  This is called by the macro
650    TARGET_RETURN_IN_MEMORY.  */
651
652 static bool
653 c6x_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
654 {
655   int size = int_size_in_bytes (type);
656   return size > 2 * UNITS_PER_WORD || size == -1;
657 }
658
659 /* Values which must be returned in the most-significant end of the return
660    register.  */
661
662 static bool
663 c6x_return_in_msb (const_tree valtype)
664 {
665   HOST_WIDE_INT size = int_size_in_bytes (valtype);
666   return TARGET_BIG_ENDIAN && AGGREGATE_TYPE_P (valtype) && size == 3;
667 }
668
669 /* Implement TARGET_CALLEE_COPIES.  */
670
671 static bool
672 c6x_callee_copies (cumulative_args_t cum_v ATTRIBUTE_UNUSED,
673                    enum machine_mode mode ATTRIBUTE_UNUSED,
674                    const_tree type ATTRIBUTE_UNUSED,
675                    bool named ATTRIBUTE_UNUSED)
676 {
677   return true;
678 }
679
680 /* Return the type to use as __builtin_va_list.  */
681 static tree
682 c6x_build_builtin_va_list (void)
683 {
684   return build_pointer_type (char_type_node);
685 }
686 \f
687 static void
688 c6x_asm_trampoline_template (FILE *f)
689 {
690   fprintf (f, "\t.long\t0x0000002b\n"); /* mvkl .s2 fnlow,B0 */
691   fprintf (f, "\t.long\t0x01000028\n"); /* || mvkl .s1 sclow,A2 */
692   fprintf (f, "\t.long\t0x0000006b\n"); /* mvkh .s2 fnhigh,B0 */
693   fprintf (f, "\t.long\t0x01000068\n"); /* || mvkh .s1 schigh,A2 */
694   fprintf (f, "\t.long\t0x00000362\n"); /* b .s2 B0 */
695   fprintf (f, "\t.long\t0x00008000\n"); /* nop 5 */
696   fprintf (f, "\t.long\t0x00000000\n"); /* nop */
697   fprintf (f, "\t.long\t0x00000000\n"); /* nop */
698 }
699
700 /* Emit RTL insns to initialize the variable parts of a trampoline at
701    TRAMP. FNADDR is an RTX for the address of the function's pure
702    code.  CXT is an RTX for the static chain value for the function.  */
703
704 static void
705 c6x_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
706 {
707   rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
708   rtx t1 = copy_to_reg (fnaddr);
709   rtx t2 = copy_to_reg (cxt);
710   rtx mask = gen_reg_rtx (SImode);
711   int i;
712
713   emit_block_move (tramp, assemble_trampoline_template (),
714                    GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
715
716   emit_move_insn (mask, GEN_INT (0xffff << 7));
717
718   for (i = 0; i < 4; i++)
719     {
720       rtx mem = adjust_address (tramp, SImode, i * 4);
721       rtx t = (i & 1) ? t2 : t1;
722       rtx v1 = gen_reg_rtx (SImode);
723       rtx v2 = gen_reg_rtx (SImode);
724       emit_move_insn (v1, mem);
725       if (i < 2)
726         emit_insn (gen_ashlsi3 (v2, t, GEN_INT (7)));
727       else
728         emit_insn (gen_lshrsi3 (v2, t, GEN_INT (9)));
729       emit_insn (gen_andsi3 (v2, v2, mask));
730       emit_insn (gen_iorsi3 (v2, v2, v1));
731       emit_move_insn (mem, v2);
732     }
733 #ifdef CLEAR_INSN_CACHE
734   tramp = XEXP (tramp, 0);
735   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__gnu_clear_cache"),
736                      LCT_NORMAL, VOIDmode, 2, tramp, Pmode,
737                      plus_constant (tramp, TRAMPOLINE_SIZE), Pmode);
738 #endif
739 }
740 \f
741 /* Determine whether c6x_output_mi_thunk can succeed.  */
742
743 static bool
744 c6x_can_output_mi_thunk (const_tree thunk ATTRIBUTE_UNUSED,
745                          HOST_WIDE_INT delta ATTRIBUTE_UNUSED,
746                          HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
747                          const_tree function ATTRIBUTE_UNUSED)
748 {
749   return !TARGET_LONG_CALLS;
750 }
751
752 /* Output the assembler code for a thunk function.  THUNK is the
753    declaration for the thunk function itself, FUNCTION is the decl for
754    the target function.  DELTA is an immediate constant offset to be
755    added to THIS.  If VCALL_OFFSET is nonzero, the word at
756    *(*this + vcall_offset) should be added to THIS.  */
757
758 static void
759 c6x_output_mi_thunk (FILE *file ATTRIBUTE_UNUSED,
760                      tree thunk ATTRIBUTE_UNUSED, HOST_WIDE_INT delta,
761                      HOST_WIDE_INT vcall_offset, tree function)
762 {
763   rtx xops[5];
764   /* The this parameter is passed as the first argument.  */
765   rtx this_rtx = gen_rtx_REG (Pmode, REG_A4);
766
767   c6x_current_insn = NULL_RTX;
768
769   xops[4] = XEXP (DECL_RTL (function), 0);
770   if (!vcall_offset)
771     {
772       output_asm_insn ("b .s2 \t%4", xops);
773       if (!delta)
774         output_asm_insn ("nop 5", xops);
775     }
776
777   /* Adjust the this parameter by a fixed constant.  */
778   if (delta)
779     {
780       xops[0] = GEN_INT (delta);
781       xops[1] = this_rtx;
782       if (delta >= -16 && delta <= 15)
783         {
784           output_asm_insn ("add .s1 %0, %1, %1", xops);
785           if (!vcall_offset)
786             output_asm_insn ("nop 4", xops);
787         }
788       else if (delta >= 16 && delta < 32)
789         {
790           output_asm_insn ("add .d1 %0, %1, %1", xops);
791           if (!vcall_offset)
792             output_asm_insn ("nop 4", xops);
793         }
794       else if (delta >= -32768 && delta < 32768)
795         {
796           output_asm_insn ("mvk .s1 %0, A0", xops);
797           output_asm_insn ("add .d1 %1, A0, %1", xops);
798           if (!vcall_offset)
799             output_asm_insn ("nop 3", xops);
800         }
801       else
802         {
803           output_asm_insn ("mvkl .s1 %0, A0", xops);
804           output_asm_insn ("mvkh .s1 %0, A0", xops);
805           output_asm_insn ("add .d1 %1, A0, %1", xops);
806           if (!vcall_offset)
807             output_asm_insn ("nop 3", xops);
808         }
809     }
810
811   /* Adjust the this parameter by a value stored in the vtable.  */
812   if (vcall_offset)
813     {
814       rtx a0tmp = gen_rtx_REG (Pmode, REG_A0);
815       rtx a3tmp = gen_rtx_REG (Pmode, REG_A3);
816
817       xops[1] = a3tmp;
818       xops[2] = a0tmp;
819       xops[3] = gen_rtx_MEM (Pmode, a0tmp);
820       output_asm_insn ("mv .s1 a4, %2", xops);
821       output_asm_insn ("ldw .d1t1 %3, %2", xops);
822
823       /* Adjust the this parameter.  */
824       xops[0] = gen_rtx_MEM (Pmode, plus_constant (a0tmp, vcall_offset));
825       if (!memory_operand (xops[0], Pmode))
826         {
827           rtx tmp2 = gen_rtx_REG (Pmode, REG_A1);
828           xops[0] = GEN_INT (vcall_offset);
829           xops[1] = tmp2;
830           output_asm_insn ("mvkl .s1 %0, %1", xops);
831           output_asm_insn ("mvkh .s1 %0, %1", xops);
832           output_asm_insn ("nop 2", xops);
833           output_asm_insn ("add .d1 %2, %1, %2", xops);
834           xops[0] = gen_rtx_MEM (Pmode, a0tmp);
835         }
836       else
837         output_asm_insn ("nop 4", xops);
838       xops[2] = this_rtx;
839       output_asm_insn ("ldw .d1t1 %0, %1", xops);
840       output_asm_insn ("|| b .s2 \t%4", xops);
841       output_asm_insn ("nop 4", xops);
842       output_asm_insn ("add .d1 %2, %1, %2", xops);
843     }
844 }
845 \f
846 /* Return true if EXP goes in small data/bss.  */
847
848 static bool
849 c6x_in_small_data_p (const_tree exp)
850 {
851   /* We want to merge strings, so we never consider them small data.  */
852   if (TREE_CODE (exp) == STRING_CST)
853     return false;
854
855   /* Functions are never small data.  */
856   if (TREE_CODE (exp) == FUNCTION_DECL)
857     return false;
858
859   if (TREE_CODE (exp) == VAR_DECL && DECL_WEAK (exp))
860     return false;
861
862   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
863     {
864       const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
865
866       if (strcmp (section, ".neardata") == 0
867           || strncmp (section, ".neardata.", 10) == 0
868           || strncmp (section, ".gnu.linkonce.s.", 16) == 0
869           || strcmp (section, ".bss") == 0
870           || strncmp (section, ".bss.", 5) == 0
871           || strncmp (section, ".gnu.linkonce.sb.", 17) == 0
872           || strcmp (section, ".rodata") == 0
873           || strncmp (section, ".rodata.", 8) == 0
874           || strncmp (section, ".gnu.linkonce.s2.", 17) == 0)
875         return true;
876     }
877   else
878     return PLACE_IN_SDATA_P (exp);
879
880   return false;
881 }
882
883 /* Return a section for X.  The only special thing we do here is to
884    honor small data.  We don't have a tree type, so we can't use the
885    PLACE_IN_SDATA_P macro we use everywhere else; we choose to place
886    everything sized 8 bytes or smaller into small data.  */
887
888 static section *
889 c6x_select_rtx_section (enum machine_mode mode, rtx x,
890                         unsigned HOST_WIDE_INT align)
891 {
892   if (c6x_sdata_mode == C6X_SDATA_ALL
893       || (c6x_sdata_mode != C6X_SDATA_NONE && GET_MODE_SIZE (mode) <= 8))
894     /* ??? Consider using mergeable sdata sections.  */
895     return sdata_section;
896   else
897     return default_elf_select_rtx_section (mode, x, align);
898 }
899
900 static section *
901 c6x_elf_select_section (tree decl, int reloc,
902                         unsigned HOST_WIDE_INT align)
903 {
904   const char *sname = NULL;
905   unsigned int flags = SECTION_WRITE;
906   if (c6x_in_small_data_p (decl))
907     {
908       switch (categorize_decl_for_section (decl, reloc))
909         {
910         case SECCAT_SRODATA:
911           sname = ".rodata";
912           flags = 0;
913           break;
914         case SECCAT_SDATA:
915           sname = ".neardata";
916           break;
917         case SECCAT_SBSS:
918           sname = ".bss";
919           flags |= SECTION_BSS;
920         default:
921           break;
922         }
923     }
924   else
925     {
926       switch (categorize_decl_for_section (decl, reloc))
927         {
928         case SECCAT_DATA:
929           sname = ".fardata";
930           break;
931         case SECCAT_DATA_REL:
932           sname = ".fardata.rel";
933           break;
934         case SECCAT_DATA_REL_LOCAL:
935           sname = ".fardata.rel.local";
936           break;
937         case SECCAT_DATA_REL_RO:
938           sname = ".fardata.rel.ro";
939           break;
940         case SECCAT_DATA_REL_RO_LOCAL:
941           sname = ".fardata.rel.ro.local";
942           break;
943         case SECCAT_BSS:
944           sname = ".far";
945           flags |= SECTION_BSS;
946           break;
947         case SECCAT_RODATA:
948           sname = ".const";
949           flags = 0;
950           break;
951         case SECCAT_SRODATA:
952         case SECCAT_SDATA:
953         case SECCAT_SBSS:
954           gcc_unreachable ();
955         default:
956           break;
957         }
958     }
959   if (sname)
960     {
961       /* We might get called with string constants, but get_named_section
962          doesn't like them as they are not DECLs.  Also, we need to set
963          flags in that case.  */
964       if (!DECL_P (decl))
965         return get_section (sname, flags, NULL);
966       return get_named_section (decl, sname, reloc);
967     }
968
969   return default_elf_select_section (decl, reloc, align);
970 }
971
972 /* Build up a unique section name, expressed as a
973    STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
974    RELOC indicates whether the initial value of EXP requires
975    link-time relocations.  */
976
977 static void ATTRIBUTE_UNUSED
978 c6x_elf_unique_section (tree decl, int reloc)
979 {
980   const char *prefix = NULL;
981   /* We only need to use .gnu.linkonce if we don't have COMDAT groups.  */
982   bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP;
983
984   if (c6x_in_small_data_p (decl))
985     {
986       switch (categorize_decl_for_section (decl, reloc))
987         {
988         case SECCAT_SDATA:
989           prefix = one_only ? ".s" : ".neardata";
990           break;
991         case SECCAT_SBSS:
992           prefix = one_only ? ".sb" : ".bss";
993           break;
994         case SECCAT_SRODATA:
995           prefix = one_only ? ".s2" : ".rodata";
996           break;
997         case SECCAT_RODATA_MERGE_STR:
998         case SECCAT_RODATA_MERGE_STR_INIT:
999         case SECCAT_RODATA_MERGE_CONST:
1000         case SECCAT_RODATA:
1001         case SECCAT_DATA:
1002         case SECCAT_DATA_REL:
1003         case SECCAT_DATA_REL_LOCAL:
1004         case SECCAT_DATA_REL_RO:
1005         case SECCAT_DATA_REL_RO_LOCAL:
1006           gcc_unreachable ();
1007         default:
1008           /* Everything else we place into default sections and hope for the
1009              best.  */
1010           break;
1011         }
1012     }
1013   else
1014     {
1015       switch (categorize_decl_for_section (decl, reloc))
1016         {
1017         case SECCAT_DATA:
1018         case SECCAT_DATA_REL:
1019         case SECCAT_DATA_REL_LOCAL:
1020         case SECCAT_DATA_REL_RO:
1021         case SECCAT_DATA_REL_RO_LOCAL:
1022           prefix = one_only ? ".fd" : ".fardata";
1023           break;
1024         case SECCAT_BSS:
1025           prefix = one_only ? ".fb" : ".far";
1026           break;
1027         case SECCAT_RODATA:
1028         case SECCAT_RODATA_MERGE_STR:
1029         case SECCAT_RODATA_MERGE_STR_INIT:
1030         case SECCAT_RODATA_MERGE_CONST:
1031           prefix = one_only ? ".fr" : ".const";
1032           break;
1033         case SECCAT_SRODATA:
1034         case SECCAT_SDATA:
1035         case SECCAT_SBSS:
1036           gcc_unreachable ();
1037         default:
1038           break;
1039         }
1040     }
1041
1042   if (prefix)
1043     {
1044       const char *name, *linkonce;
1045       char *string;
1046
1047       name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
1048       name = targetm.strip_name_encoding (name);
1049
1050       /* If we're using one_only, then there needs to be a .gnu.linkonce
1051          prefix to the section name.  */
1052       linkonce = one_only ? ".gnu.linkonce" : "";
1053
1054       string = ACONCAT ((linkonce, prefix, ".", name, NULL));
1055
1056       DECL_SECTION_NAME (decl) = build_string (strlen (string), string);
1057       return;
1058     }
1059   default_unique_section (decl, reloc);
1060 }
1061
1062 static unsigned int
1063 c6x_section_type_flags (tree decl, const char *name, int reloc)
1064 {
1065   unsigned int flags = 0;
1066
1067   if (strcmp (name, ".far") == 0
1068       || strncmp (name, ".far.", 5) == 0)
1069     flags |= SECTION_BSS;
1070
1071   flags |= default_section_type_flags (decl, name, reloc);
1072
1073   return flags;
1074 }
1075 \f
1076 /* Checks whether the given CALL_EXPR would use a caller saved
1077    register.  This is used to decide whether sibling call optimization
1078    could be performed on the respective function call.  */
1079
1080 static bool
1081 c6x_call_saved_register_used (tree call_expr)
1082 {
1083   CUMULATIVE_ARGS cum_v;
1084   cumulative_args_t cum;
1085   HARD_REG_SET call_saved_regset;
1086   tree parameter;
1087   enum machine_mode mode;
1088   tree type;
1089   rtx parm_rtx;
1090   int i;
1091
1092   INIT_CUMULATIVE_ARGS (cum_v, NULL, NULL, 0, 0);
1093   cum = pack_cumulative_args (&cum_v);
1094
1095   COMPL_HARD_REG_SET (call_saved_regset, call_used_reg_set);
1096   for (i = 0; i < call_expr_nargs (call_expr); i++)
1097     {
1098       parameter = CALL_EXPR_ARG (call_expr, i);
1099       gcc_assert (parameter);
1100
1101       /* For an undeclared variable passed as parameter we will get
1102          an ERROR_MARK node here.  */
1103       if (TREE_CODE (parameter) == ERROR_MARK)
1104         return true;
1105
1106       type = TREE_TYPE (parameter);
1107       gcc_assert (type);
1108
1109       mode = TYPE_MODE (type);
1110       gcc_assert (mode);
1111
1112       if (pass_by_reference (&cum_v, mode, type, true))
1113         {
1114           mode = Pmode;
1115           type = build_pointer_type (type);
1116         }
1117
1118        parm_rtx = c6x_function_arg (cum, mode, type, 0);
1119
1120        c6x_function_arg_advance (cum, mode, type, 0);
1121
1122        if (!parm_rtx)
1123          continue;
1124
1125        if (REG_P (parm_rtx)
1126            && overlaps_hard_reg_set_p (call_saved_regset, GET_MODE (parm_rtx),
1127                                        REGNO (parm_rtx)))
1128          return true;
1129        if (GET_CODE (parm_rtx) == PARALLEL)
1130          {
1131            int n = XVECLEN (parm_rtx, 0);
1132            while (n-- > 0)
1133              {
1134                rtx x = XEXP (XVECEXP (parm_rtx, 0, n), 0);
1135                if (REG_P (x)
1136                    && overlaps_hard_reg_set_p (call_saved_regset,
1137                                                GET_MODE (x), REGNO (x)))
1138                  return true;
1139              }
1140          }
1141     }
1142   return false;
1143 }
1144
1145 /* Decide whether we can make a sibling call to a function.  DECL is the
1146    declaration of the function being targeted by the call and EXP is the
1147    CALL_EXPR representing the call.  */
1148
1149 static bool
1150 c6x_function_ok_for_sibcall (tree decl, tree exp)
1151 {
1152   /* Registers A10, A12, B10 and B12 are available as arguments
1153      register but unfortunately caller saved. This makes functions
1154      needing these registers for arguments not suitable for
1155      sibcalls.  */
1156   if (c6x_call_saved_register_used (exp))
1157     return false;
1158
1159   if (!flag_pic)
1160     return true;
1161
1162   if (TARGET_DSBT)
1163     {
1164       /* When compiling for DSBT, the calling function must be local,
1165          so that when we reload B14 in the sibcall epilogue, it will
1166          not change its value.  */
1167       struct cgraph_local_info *this_func;
1168
1169       if (!decl)
1170         /* Not enough information.  */
1171         return false;
1172
1173       this_func = cgraph_local_info (current_function_decl);
1174       return this_func->local;
1175     }
1176
1177   return true;
1178 }
1179
1180 /* Return true if DECL is known to be linked into section SECTION.  */
1181
1182 static bool
1183 c6x_function_in_section_p (tree decl, section *section)
1184 {
1185   /* We can only be certain about functions defined in the same
1186      compilation unit.  */
1187   if (!TREE_STATIC (decl))
1188     return false;
1189
1190   /* Make sure that SYMBOL always binds to the definition in this
1191      compilation unit.  */
1192   if (!targetm.binds_local_p (decl))
1193     return false;
1194
1195   /* If DECL_SECTION_NAME is set, assume it is trustworthy.  */
1196   if (!DECL_SECTION_NAME (decl))
1197     {
1198       /* Make sure that we will not create a unique section for DECL.  */
1199       if (flag_function_sections || DECL_ONE_ONLY (decl))
1200         return false;
1201     }
1202
1203   return function_section (decl) == section;
1204 }
1205
1206 /* Return true if a call to OP, which is a SYMBOL_REF, must be expanded
1207    as a long call.  */
1208 bool
1209 c6x_long_call_p (rtx op)
1210 {
1211   tree decl;
1212
1213   if (!TARGET_LONG_CALLS)
1214     return false;
1215
1216   decl = SYMBOL_REF_DECL (op);
1217
1218   /* Try to determine whether the symbol is in the same section as the current
1219      function.  Be conservative, and only cater for cases in which the
1220      whole of the current function is placed in the same section.  */
1221   if (decl != NULL_TREE
1222       && !flag_reorder_blocks_and_partition
1223       && TREE_CODE (decl) == FUNCTION_DECL
1224       && c6x_function_in_section_p (decl, current_function_section ()))
1225     return false;
1226
1227   return true;
1228 }
1229
1230 /* Emit the sequence for a call.  */
1231 void
1232 c6x_expand_call (rtx retval, rtx address, bool sibcall)
1233 {
1234   rtx callee = XEXP (address, 0);
1235   rtx call_insn;
1236
1237   if (!c6x_call_operand (callee, Pmode))
1238     {
1239       callee = force_reg (Pmode, callee);
1240       address = change_address (address, Pmode, callee);
1241     }
1242   call_insn = gen_rtx_CALL (VOIDmode, address, const0_rtx);
1243   if (sibcall)
1244     {
1245       call_insn = emit_call_insn (call_insn);
1246       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
1247                gen_rtx_REG (Pmode, REG_B3));
1248     }
1249   else
1250     {
1251       if (retval == NULL_RTX)
1252         call_insn = emit_call_insn (call_insn);
1253       else
1254         call_insn = emit_call_insn (gen_rtx_SET (GET_MODE (retval), retval,
1255                                                  call_insn));
1256     }
1257   if (flag_pic)
1258     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
1259 }
1260
1261 /* Legitimize PIC addresses.  If the address is already position-independent,
1262    we return ORIG.  Newly generated position-independent addresses go into a
1263    reg.  This is REG if nonzero, otherwise we allocate register(s) as
1264    necessary.  PICREG is the register holding the pointer to the PIC offset
1265    table.  */
1266
1267 static rtx
1268 legitimize_pic_address (rtx orig, rtx reg, rtx picreg)
1269 {
1270   rtx addr = orig;
1271   rtx new_rtx = orig;
1272
1273   if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
1274     {
1275       int unspec = UNSPEC_LOAD_GOT;
1276       rtx tmp;
1277
1278       if (reg == 0)
1279         {
1280           gcc_assert (can_create_pseudo_p ());
1281           reg = gen_reg_rtx (Pmode);
1282         }
1283       if (flag_pic == 2)
1284         {
1285           if (can_create_pseudo_p ())
1286             tmp = gen_reg_rtx (Pmode);
1287           else
1288             tmp = reg;
1289           emit_insn (gen_movsi_gotoff_high (tmp, addr));
1290           emit_insn (gen_movsi_gotoff_lo_sum (tmp, tmp, addr));
1291           emit_insn (gen_load_got_gotoff (reg, picreg, tmp));
1292         }
1293       else
1294         {
1295           tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), unspec);
1296           new_rtx = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, picreg, tmp));
1297
1298           emit_move_insn (reg, new_rtx);
1299         }
1300       if (picreg == pic_offset_table_rtx)
1301         crtl->uses_pic_offset_table = 1;
1302       return reg;
1303     }
1304
1305   else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
1306     {
1307       rtx base;
1308
1309       if (GET_CODE (addr) == CONST)
1310         {
1311           addr = XEXP (addr, 0);
1312           gcc_assert (GET_CODE (addr) == PLUS);
1313         }
1314
1315       if (XEXP (addr, 0) == picreg)
1316         return orig;
1317
1318       if (reg == 0)
1319         {
1320           gcc_assert (can_create_pseudo_p ());
1321           reg = gen_reg_rtx (Pmode);
1322         }
1323
1324       base = legitimize_pic_address (XEXP (addr, 0), reg, picreg);
1325       addr = legitimize_pic_address (XEXP (addr, 1),
1326                                      base == reg ? NULL_RTX : reg,
1327                                      picreg);
1328
1329       if (GET_CODE (addr) == CONST_INT)
1330         {
1331           gcc_assert (! reload_in_progress && ! reload_completed);
1332           addr = force_reg (Pmode, addr);
1333         }
1334
1335       if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
1336         {
1337           base = gen_rtx_PLUS (Pmode, base, XEXP (addr, 0));
1338           addr = XEXP (addr, 1);
1339         }
1340
1341       return gen_rtx_PLUS (Pmode, base, addr);
1342     }
1343
1344   return new_rtx;
1345 }
1346
1347 /* Expand a move operation in mode MODE.  The operands are in OPERANDS.
1348    Returns true if no further code must be generated, false if the caller
1349    should generate an insn to move OPERANDS[1] to OPERANDS[0].  */
1350
1351 bool
1352 expand_move (rtx *operands, enum machine_mode mode)
1353 {
1354   rtx dest = operands[0];
1355   rtx op = operands[1];
1356
1357   if ((reload_in_progress | reload_completed) == 0
1358       && GET_CODE (dest) == MEM && GET_CODE (op) != REG)
1359     operands[1] = force_reg (mode, op);
1360   else if (mode == SImode && symbolic_operand (op, SImode))
1361     {
1362       if (flag_pic)
1363         {
1364           if (sdata_symbolic_operand (op, SImode))
1365             {
1366               emit_insn (gen_load_sdata_pic (dest, pic_offset_table_rtx, op));
1367               crtl->uses_pic_offset_table = 1;
1368               return true;
1369             }
1370           else
1371             {
1372               rtx temp = (reload_completed || reload_in_progress
1373                           ? dest : gen_reg_rtx (Pmode));
1374
1375               operands[1] = legitimize_pic_address (op, temp,
1376                                                     pic_offset_table_rtx);
1377             }
1378         }
1379       else if (reload_completed
1380                && !sdata_symbolic_operand (op, SImode))
1381         {
1382           emit_insn (gen_movsi_high (dest, op));
1383           emit_insn (gen_movsi_lo_sum (dest, dest, op));
1384           return true;
1385         }
1386     }
1387   return false;
1388 }
1389
1390 /* This function is called when we're about to expand an integer compare
1391    operation which performs COMPARISON.  It examines the second operand,
1392    and if it is an integer constant that cannot be used directly on the
1393    current machine in a comparison insn, it returns true.  */
1394 bool
1395 c6x_force_op_for_comparison_p (enum rtx_code code, rtx op)
1396 {
1397   if (!CONST_INT_P (op) || satisfies_constraint_Iu4 (op))
1398     return false;
1399
1400   if ((code == EQ || code == LT || code == GT)
1401        && !satisfies_constraint_Is5 (op))
1402     return true;
1403   if ((code == GTU || code == LTU)
1404       && (!TARGET_INSNS_64 || !satisfies_constraint_Iu5 (op)))
1405     return true;
1406
1407   return false;
1408 }
1409
1410 /* Emit comparison instruction if necessary, returning the expression
1411    that holds the compare result in the proper mode.  Return the comparison
1412    that should be used in the jump insn.  */
1413
1414 rtx
1415 c6x_expand_compare (rtx comparison, enum machine_mode mode)
1416 {
1417   enum rtx_code code = GET_CODE (comparison);
1418   rtx op0 = XEXP (comparison, 0);
1419   rtx op1 = XEXP (comparison, 1);
1420   rtx cmp;
1421   enum rtx_code jump_code = code;
1422   enum machine_mode op_mode = GET_MODE (op0);
1423
1424   if (op_mode == DImode && (code == NE || code == EQ) && op1 == const0_rtx)
1425     {
1426       rtx t = gen_reg_rtx (SImode);
1427       emit_insn (gen_iorsi3 (t, gen_lowpart (SImode, op0),
1428                              gen_highpart (SImode, op0)));
1429       op_mode = SImode;
1430       cmp = t;
1431     }
1432   else if (op_mode == DImode)
1433     {
1434       rtx lo[2], high[2];
1435       rtx cmp1, cmp2;
1436
1437       if (code == NE || code == GEU || code == LEU || code == GE || code == LE)
1438         {
1439           code = reverse_condition (code);
1440           jump_code = EQ;
1441         }
1442       else
1443         jump_code = NE;
1444
1445       split_di (&op0, 1, lo, high);
1446       split_di (&op1, 1, lo + 1, high + 1);
1447
1448       if (c6x_force_op_for_comparison_p (code, high[1])
1449           || c6x_force_op_for_comparison_p (EQ, high[1]))
1450         high[1] = force_reg (SImode, high[1]);
1451
1452       cmp1 = gen_reg_rtx (SImode);
1453       cmp2 = gen_reg_rtx (SImode);
1454       emit_insn (gen_rtx_SET (VOIDmode, cmp1,
1455                               gen_rtx_fmt_ee (code, SImode, high[0], high[1])));
1456       if (code == EQ)
1457         {
1458           if (c6x_force_op_for_comparison_p (code, lo[1]))
1459             lo[1] = force_reg (SImode, lo[1]);
1460           emit_insn (gen_rtx_SET (VOIDmode, cmp2,
1461                                   gen_rtx_fmt_ee (code, SImode, lo[0], lo[1])));
1462           emit_insn (gen_andsi3 (cmp1, cmp1, cmp2));
1463         }
1464       else
1465         {
1466           emit_insn (gen_rtx_SET (VOIDmode, cmp2,
1467                                   gen_rtx_EQ (SImode, high[0], high[1])));
1468           if (code == GT)
1469             code = GTU;
1470           else if (code == LT)
1471             code = LTU;
1472           if (c6x_force_op_for_comparison_p (code, lo[1]))
1473             lo[1] = force_reg (SImode, lo[1]);
1474           emit_insn (gen_cmpsi_and (cmp2, gen_rtx_fmt_ee (code, SImode,
1475                                                           lo[0], lo[1]),
1476                                     lo[0], lo[1], cmp2));
1477           emit_insn (gen_iorsi3 (cmp1, cmp1, cmp2));
1478         }
1479       cmp = cmp1;
1480     }
1481   else if (TARGET_FP && !flag_finite_math_only
1482            && (op_mode == DFmode || op_mode == SFmode)
1483            && code != EQ && code != NE && code != LT && code != GT
1484            && code != UNLE && code != UNGE)
1485     {
1486       enum rtx_code code1, code2, code3;
1487       rtx (*fn) (rtx, rtx, rtx, rtx, rtx);
1488
1489       jump_code = NE;
1490       code3 = UNKNOWN;
1491       switch (code)
1492         {
1493         case UNLT:
1494         case UNGT:
1495           jump_code = EQ;
1496           /* fall through */
1497         case LE:
1498         case GE:
1499           code1 = code == LE || code == UNGT ? LT : GT;
1500           code2 = EQ;
1501           break;
1502
1503         case UNORDERED:
1504           jump_code = EQ;
1505           /* fall through */
1506         case ORDERED:
1507           code3 = EQ;
1508           /* fall through */
1509         case LTGT:
1510           code1 = LT;
1511           code2 = GT;
1512           break;
1513
1514         case UNEQ:
1515           code1 = LT;
1516           code2 = GT;
1517           jump_code = EQ;
1518           break;
1519
1520         default:
1521           gcc_unreachable ();
1522         }
1523
1524       cmp = gen_reg_rtx (SImode);
1525       emit_insn (gen_rtx_SET (VOIDmode, cmp,
1526                               gen_rtx_fmt_ee (code1, SImode, op0, op1)));
1527       fn = op_mode == DFmode ? gen_cmpdf_ior : gen_cmpsf_ior;
1528       emit_insn (fn (cmp, gen_rtx_fmt_ee (code2, SImode, op0, op1),
1529                      op0, op1, cmp));
1530       if (code3 != UNKNOWN)
1531         emit_insn (fn (cmp, gen_rtx_fmt_ee (code3, SImode, op0, op1),
1532                        op0, op1, cmp));
1533     }
1534   else if (op_mode == SImode && (code == NE || code == EQ) && op1 == const0_rtx)
1535     cmp = op0;
1536   else
1537     {
1538       bool is_fp_libfunc;
1539       is_fp_libfunc = !TARGET_FP && (op_mode == DFmode || op_mode == SFmode);
1540
1541       if ((code == NE || code == GEU || code == LEU || code == GE || code == LE)
1542           && !is_fp_libfunc)
1543         {
1544           code = reverse_condition (code);
1545           jump_code = EQ;
1546         }
1547       else if (code == UNGE)
1548         {
1549           code = LT;
1550           jump_code = EQ;
1551         }
1552       else if (code == UNLE)
1553         {
1554           code = GT;
1555           jump_code = EQ;
1556         }
1557       else
1558         jump_code = NE;
1559
1560       if (is_fp_libfunc)
1561         {
1562           rtx insns;
1563           rtx libfunc;
1564           switch (code)
1565             {
1566             case EQ:
1567               libfunc = op_mode == DFmode ? eqdf_libfunc : eqsf_libfunc;
1568               break;
1569             case NE:
1570               libfunc = op_mode == DFmode ? nedf_libfunc : nesf_libfunc;
1571               break;
1572             case GT:
1573               libfunc = op_mode == DFmode ? gtdf_libfunc : gtsf_libfunc;
1574               break;
1575             case GE:
1576               libfunc = op_mode == DFmode ? gedf_libfunc : gesf_libfunc;
1577               break;
1578             case LT:
1579               libfunc = op_mode == DFmode ? ltdf_libfunc : ltsf_libfunc;
1580               break;
1581             case LE:
1582               libfunc = op_mode == DFmode ? ledf_libfunc : lesf_libfunc;
1583               break;
1584             default:
1585               gcc_unreachable ();
1586             }
1587           start_sequence ();
1588
1589           cmp = emit_library_call_value (libfunc, 0, LCT_CONST, SImode, 2,
1590                                          op0, op_mode, op1, op_mode);
1591           insns = get_insns ();
1592           end_sequence ();
1593
1594           emit_libcall_block (insns, cmp, cmp,
1595                               gen_rtx_fmt_ee (code, SImode, op0, op1));
1596         }
1597       else
1598         {
1599           cmp = gen_reg_rtx (SImode);
1600           if (c6x_force_op_for_comparison_p (code, op1))
1601             op1 = force_reg (SImode, op1);
1602           emit_insn (gen_rtx_SET (VOIDmode, cmp,
1603                                   gen_rtx_fmt_ee (code, SImode, op0, op1)));
1604         }
1605     }
1606
1607   return gen_rtx_fmt_ee (jump_code, mode, cmp, const0_rtx);
1608 }
1609
1610 /* Return one word of double-word value OP.  HIGH_P is true to select the
1611    high part, false to select the low part.  When encountering auto-increment
1612    addressing, we make the assumption that the low part is going to be accessed
1613    first.  */
1614
1615 rtx
1616 c6x_subword (rtx op, bool high_p)
1617 {
1618   unsigned int byte;
1619   enum machine_mode mode;
1620
1621   mode = GET_MODE (op);
1622   if (mode == VOIDmode)
1623     mode = DImode;
1624
1625   if (TARGET_BIG_ENDIAN ? !high_p : high_p)
1626     byte = UNITS_PER_WORD;
1627   else
1628     byte = 0;
1629
1630   if (MEM_P (op))
1631     {
1632       rtx addr = XEXP (op, 0);
1633       if (GET_CODE (addr) == PLUS || REG_P (addr))
1634         return adjust_address (op, word_mode, byte);
1635       /* FIXME: should really support autoincrement addressing for
1636          multi-word modes.  */
1637       gcc_unreachable ();
1638     }
1639
1640   return simplify_gen_subreg (word_mode, op, mode, byte);
1641 }
1642
1643 /* Split one or more DImode RTL references into pairs of SImode
1644    references.  The RTL can be REG, offsettable MEM, integer constant, or
1645    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
1646    split and "num" is its length.  lo_half and hi_half are output arrays
1647    that parallel "operands".  */
1648
1649 void
1650 split_di (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
1651 {
1652   while (num--)
1653     {
1654       rtx op = operands[num];
1655
1656       lo_half[num] = c6x_subword (op, false);
1657       hi_half[num] = c6x_subword (op, true);
1658     }
1659 }
1660
1661 /* Return true if VAL is a mask valid for a clr instruction.  */
1662 bool
1663 c6x_valid_mask_p (HOST_WIDE_INT val)
1664 {
1665   int i;
1666   for (i = 0; i < 32; i++)
1667     if (!(val & ((unsigned HOST_WIDE_INT)1 << i)))
1668       break;
1669   for (; i < 32; i++)
1670     if (val & ((unsigned HOST_WIDE_INT)1 << i))
1671       break;
1672   for (; i < 32; i++)
1673     if (!(val & ((unsigned HOST_WIDE_INT)1 << i)))
1674       return false;
1675   return true;
1676 }
1677
1678 /* Expand a block move for a movmemM pattern.  */
1679
1680 bool
1681 c6x_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
1682                    rtx expected_align_exp ATTRIBUTE_UNUSED,
1683                    rtx expected_size_exp ATTRIBUTE_UNUSED)
1684 {
1685   unsigned HOST_WIDE_INT align = 1;
1686   unsigned HOST_WIDE_INT src_mem_align, dst_mem_align, min_mem_align;
1687   unsigned HOST_WIDE_INT count = 0, offset = 0;
1688   unsigned int biggest_move = TARGET_STDW ? 8 : 4;
1689
1690   if (CONST_INT_P (align_exp))
1691     align = INTVAL (align_exp);
1692
1693   src_mem_align = MEM_ALIGN (src) / BITS_PER_UNIT;
1694   dst_mem_align = MEM_ALIGN (dst) / BITS_PER_UNIT;
1695   min_mem_align = MIN (src_mem_align, dst_mem_align);
1696
1697   if (min_mem_align > align)
1698     align = min_mem_align / BITS_PER_UNIT;
1699   if (src_mem_align < align)
1700     src_mem_align = align;
1701   if (dst_mem_align < align)
1702     dst_mem_align = align;
1703
1704   if (CONST_INT_P (count_exp))
1705     count = INTVAL (count_exp);
1706   else
1707     return false;
1708
1709   /* Make sure we don't need to care about overflow later on.  */
1710   if (count > ((unsigned HOST_WIDE_INT) 1 << 30))
1711     return false;
1712
1713   if (count >= 28 && (count & 3) == 0 && align >= 4)
1714     {
1715       tree dst_expr = MEM_EXPR (dst);
1716       tree src_expr = MEM_EXPR (src);
1717       rtx fn = TARGET_INSNS_64PLUS ? strasgi64p_libfunc : strasgi_libfunc;
1718       rtx srcreg = force_reg (Pmode, XEXP (src, 0));
1719       rtx dstreg = force_reg (Pmode, XEXP (dst, 0));
1720
1721       if (src_expr)
1722         mark_addressable (src_expr);
1723       if (dst_expr)
1724         mark_addressable (dst_expr);
1725       emit_library_call (fn, LCT_NORMAL, VOIDmode, 3,
1726                          dstreg, Pmode, srcreg, Pmode, count_exp, SImode);
1727       return true;
1728     }
1729
1730   if (biggest_move > align && !TARGET_INSNS_64)
1731     biggest_move = align;
1732
1733   if (count / biggest_move > 7)
1734     return false;
1735
1736   while (count > 0)
1737     {
1738       rtx reg, reg_lowpart;
1739       enum machine_mode srcmode, dstmode;
1740       unsigned HOST_WIDE_INT src_size, dst_size, src_left;
1741       int shift;
1742       rtx srcmem, dstmem;
1743
1744       while (biggest_move > count)
1745         biggest_move /= 2;
1746
1747       src_size = dst_size = biggest_move;
1748       if (src_size > src_mem_align && src_size == 2)
1749         src_size = 1;
1750       if (dst_size > dst_mem_align && dst_size == 2)
1751         dst_size = 1;
1752
1753       if (dst_size > src_size)
1754         dst_size = src_size;
1755
1756       srcmode = mode_for_size (src_size * BITS_PER_UNIT, MODE_INT, 0);
1757       dstmode = mode_for_size (dst_size * BITS_PER_UNIT, MODE_INT, 0);
1758       if (src_size >= 4)
1759         reg_lowpart = reg = gen_reg_rtx (srcmode);
1760       else
1761         {
1762           reg = gen_reg_rtx (SImode);
1763           reg_lowpart = gen_lowpart (srcmode, reg);
1764         }
1765
1766       srcmem = adjust_address (copy_rtx (src), srcmode, offset);
1767
1768       if (src_size > src_mem_align)
1769         {
1770           enum insn_code icode = (srcmode == SImode ? CODE_FOR_movmisalignsi
1771                                   : CODE_FOR_movmisaligndi);
1772           emit_insn (GEN_FCN (icode) (reg_lowpart, srcmem));
1773         }
1774       else
1775         emit_move_insn (reg_lowpart, srcmem);
1776
1777       src_left = src_size;
1778       shift = TARGET_BIG_ENDIAN ? (src_size - dst_size) * BITS_PER_UNIT  : 0;
1779       while (src_left > 0)
1780         {
1781           rtx dstreg = reg_lowpart;
1782
1783           if (src_size > dst_size)
1784             {
1785               rtx srcword = reg;
1786               int shift_amount = shift & (BITS_PER_WORD - 1);
1787               if (src_size > 4)
1788                 srcword = operand_subword_force (srcword, src_left >= 4 ? 0 : 4,
1789                                                  SImode);
1790               if (shift_amount > 0)
1791                 {
1792                   dstreg = gen_reg_rtx (SImode);
1793                   emit_insn (gen_lshrsi3 (dstreg, srcword,
1794                                           GEN_INT (shift_amount)));
1795                 }
1796               else
1797                 dstreg = srcword;
1798               dstreg = gen_lowpart (dstmode, dstreg);
1799             }
1800
1801           dstmem = adjust_address (copy_rtx (dst), dstmode, offset);
1802           if (dst_size > dst_mem_align)
1803             {
1804               enum insn_code icode = (dstmode == SImode ? CODE_FOR_movmisalignsi
1805                                       : CODE_FOR_movmisaligndi);
1806               emit_insn (GEN_FCN (icode) (dstmem, dstreg));
1807             }
1808           else
1809             emit_move_insn (dstmem, dstreg);
1810
1811           if (TARGET_BIG_ENDIAN)
1812             shift -= dst_size * BITS_PER_UNIT;
1813           else
1814             shift += dst_size * BITS_PER_UNIT;
1815           offset += dst_size;
1816           src_left -= dst_size;
1817         }
1818       count -= src_size;
1819     }
1820   return true;
1821 }
1822 \f
1823 /* Subroutine of print_address_operand, print a single address offset OFF for
1824    a memory access of mode MEM_MODE, choosing between normal form and scaled
1825    form depending on the type of the insn.  Misaligned memory references must
1826    use the scaled form.  */
1827
1828 static void
1829 print_address_offset (FILE *file, rtx off, enum machine_mode mem_mode)
1830 {
1831   rtx pat;
1832
1833   if (c6x_current_insn != NULL_RTX)
1834     {
1835       pat = PATTERN (c6x_current_insn);
1836       if (GET_CODE (pat) == COND_EXEC)
1837         pat = COND_EXEC_CODE (pat);
1838       if (GET_CODE (pat) == PARALLEL)
1839         pat = XVECEXP (pat, 0, 0);
1840
1841       if (GET_CODE (pat) == SET
1842           && GET_CODE (SET_SRC (pat)) == UNSPEC
1843           && XINT (SET_SRC (pat), 1) == UNSPEC_MISALIGNED_ACCESS)
1844         {
1845           gcc_assert (CONST_INT_P (off)
1846                       && (INTVAL (off) & (GET_MODE_SIZE (mem_mode) - 1)) == 0);
1847           fprintf (file, "[" HOST_WIDE_INT_PRINT_DEC "]",
1848                    INTVAL (off) / GET_MODE_SIZE (mem_mode));
1849           return;
1850         }
1851     }
1852   fputs ("(", file);
1853   output_address (off);
1854   fputs (")", file);
1855 }
1856
1857 static bool
1858 c6x_print_operand_punct_valid_p (unsigned char c)
1859 {
1860   return c == '$' || c == '.' || c == '|';
1861 }
1862
1863 static void c6x_print_operand (FILE *, rtx, int);
1864
1865 /* Subroutine of c6x_print_operand; used to print a memory reference X to FILE.  */
1866
1867 static void
1868 c6x_print_address_operand (FILE *file, rtx x, enum machine_mode mem_mode)
1869 {
1870   rtx off;
1871   switch (GET_CODE (x))
1872     {
1873     case PRE_MODIFY:
1874     case POST_MODIFY:
1875       if (GET_CODE (x) == POST_MODIFY)
1876         output_address (XEXP (x, 0));
1877       off = XEXP (XEXP (x, 1), 1);
1878       if (XEXP (x, 0) == stack_pointer_rtx)
1879         {
1880           if (GET_CODE (x) == PRE_MODIFY)
1881             gcc_assert (INTVAL (off) > 0);
1882           else
1883             gcc_assert (INTVAL (off) < 0);
1884         }
1885       if (CONST_INT_P (off) && INTVAL (off) < 0)
1886         {
1887           fprintf (file, "--");
1888           off = GEN_INT (-INTVAL (off));
1889         }
1890       else
1891         fprintf (file, "++");
1892       if (GET_CODE (x) == PRE_MODIFY)
1893         output_address (XEXP (x, 0));
1894       print_address_offset (file, off, mem_mode);
1895       break;
1896
1897     case PLUS:
1898       off = XEXP (x, 1);
1899       if (CONST_INT_P (off) && INTVAL (off) < 0)
1900         {
1901           fprintf (file, "-");
1902           off = GEN_INT (-INTVAL (off));
1903         }
1904       else
1905         fprintf (file, "+");
1906       output_address (XEXP (x, 0));
1907       print_address_offset (file, off, mem_mode);
1908       break;
1909
1910     case PRE_DEC:
1911       gcc_assert (XEXP (x, 0) != stack_pointer_rtx);
1912       fprintf (file, "--");
1913       output_address (XEXP (x, 0));
1914       fprintf (file, "[1]");
1915       break;
1916     case PRE_INC:
1917       fprintf (file, "++");
1918       output_address (XEXP (x, 0));
1919       fprintf (file, "[1]");
1920       break;
1921     case POST_INC:
1922       gcc_assert (XEXP (x, 0) != stack_pointer_rtx);
1923       output_address (XEXP (x, 0));
1924       fprintf (file, "++[1]");
1925       break;
1926     case POST_DEC:
1927       output_address (XEXP (x, 0));
1928       fprintf (file, "--[1]");
1929       break;
1930
1931     case SYMBOL_REF:
1932     case CONST:
1933     case LABEL_REF:
1934       gcc_assert (sdata_symbolic_operand (x, Pmode));
1935       fprintf (file, "+B14(");
1936       output_addr_const (file, x);
1937       fprintf (file, ")");
1938       break;
1939
1940     case UNSPEC:
1941       switch (XINT (x, 1))
1942         {
1943         case UNSPEC_LOAD_GOT:
1944           fputs ("$GOT(", file);
1945           output_addr_const (file, XVECEXP (x, 0, 0));
1946           fputs (")", file);
1947           break;
1948         case UNSPEC_LOAD_SDATA:
1949           output_addr_const (file, XVECEXP (x, 0, 0));
1950           break;
1951         default:
1952           gcc_unreachable ();
1953         }
1954       break;
1955
1956     default:
1957       gcc_assert (GET_CODE (x) != MEM);
1958       c6x_print_operand (file, x, 0);
1959       break;
1960     }
1961 }
1962
1963 /* Return a single character, which is either 'l', 's', 'd' or 'm', which
1964    specifies the functional unit used by INSN.  */
1965
1966 char
1967 c6x_get_unit_specifier (rtx insn)
1968 {
1969   enum attr_units units;
1970
1971   if (insn_info)
1972     {
1973       int unit = INSN_INFO_ENTRY (INSN_UID (insn)).reservation;
1974       return c6x_unit_names[unit][0];
1975     }
1976
1977   units = get_attr_units (insn);
1978   switch (units)
1979     {
1980     case UNITS_D:
1981     case UNITS_DL:
1982     case UNITS_DS:
1983     case UNITS_DLS:
1984     case UNITS_D_ADDR:
1985       return 'd';
1986       break;
1987     case UNITS_L:
1988     case UNITS_LS:
1989       return 'l';
1990       break;
1991     case UNITS_S:
1992       return 's';
1993       break;
1994     case UNITS_M:
1995       return 'm';
1996       break;
1997     default:
1998       gcc_unreachable ();
1999     }
2000 }
2001
2002 /* Prints the unit specifier field.  */
2003 static void
2004 c6x_print_unit_specifier_field (FILE *file, rtx insn)
2005 {
2006   enum attr_units units = get_attr_units (insn);
2007   enum attr_cross cross = get_attr_cross (insn);
2008   enum attr_dest_regfile rf = get_attr_dest_regfile (insn);
2009   int half;
2010   char unitspec;
2011
2012   if (units == UNITS_D_ADDR)
2013     {
2014       enum attr_addr_regfile arf = get_attr_addr_regfile (insn);
2015       int t_half;
2016       gcc_assert (arf != ADDR_REGFILE_UNKNOWN);
2017       half = arf == ADDR_REGFILE_A ? 1 : 2;
2018       t_half = rf == DEST_REGFILE_A ? 1 : 2;
2019       fprintf (file, ".d%dt%d", half, t_half);
2020       return;
2021     }
2022
2023   if (insn_info)
2024     {
2025       int unit = INSN_INFO_ENTRY (INSN_UID (insn)).reservation;
2026       fputs (".", file);
2027       fputs (c6x_unit_names[unit], file);
2028       if (cross == CROSS_Y)
2029         fputs ("x", file);
2030       return;
2031     }
2032
2033   gcc_assert (rf != DEST_REGFILE_UNKNOWN);
2034   unitspec = c6x_get_unit_specifier (insn);
2035   half = rf == DEST_REGFILE_A ? 1 : 2;
2036   fprintf (file, ".%c%d%s", unitspec, half, cross == CROSS_Y ? "x" : "");
2037 }
2038
2039 /* Output assembly language output for the address ADDR to FILE.  */
2040 static void
2041 c6x_print_operand_address (FILE *file, rtx addr)
2042 {
2043   c6x_print_address_operand (file, addr, VOIDmode);
2044 }
2045
2046 /* Print an operand, X, to FILE, with an optional modifier in CODE.
2047
2048    Meaning of CODE:
2049    $ -- print the unit specifier field for the instruction.
2050    . -- print the predicate for the instruction or an emptry string for an
2051         unconditional one.
2052    | -- print "||" if the insn should be issued in parallel with the previous
2053         one.
2054
2055    C -- print an opcode suffix for a reversed condition
2056    d -- H, W or D as a suffix for ADDA, based on the factor given by the
2057         operand
2058    D -- print either B, H, W or D as a suffix for ADDA, based on the size of
2059         the operand
2060    J -- print a predicate
2061    j -- like J, but use reverse predicate
2062    k -- treat a CONST_INT as a register number and print it as a register
2063    k -- like k, but print out a doubleword register
2064    n -- print an integer operand, negated
2065    p -- print the low part of a DImode register
2066    P -- print the high part of a DImode register
2067    r -- print the absolute value of an integer operand, shifted right by 1
2068    R -- print the absolute value of an integer operand, shifted right by 2
2069    f -- the first clear bit in an integer operand assumed to be a mask for
2070         a clr instruction
2071    F -- the last clear bit in such a mask
2072    s -- the first set bit in an integer operand assumed to be a mask for
2073         a set instruction
2074    S -- the last set bit in such a mask
2075    U -- print either 1 or 2, depending on the side of the machine used by
2076         the operand  */
2077
2078 static void
2079 c6x_print_operand (FILE *file, rtx x, int code)
2080 {
2081   int i;
2082   HOST_WIDE_INT v;
2083   tree t;
2084   enum machine_mode mode;
2085
2086   if (code == '|')
2087     {
2088       if (GET_MODE (c6x_current_insn) != TImode)
2089         fputs ("||", file);
2090       return;
2091     }
2092   if (code == '$')
2093     {
2094       c6x_print_unit_specifier_field (file, c6x_current_insn);
2095       return;
2096     }
2097
2098   if (code == '.')
2099     {
2100       x = current_insn_predicate;
2101       if (x)
2102         {
2103           unsigned int regno = REGNO (XEXP (x, 0));
2104           fputs ("[", file);
2105           if (GET_CODE (x) == EQ)
2106             fputs ("!", file);
2107           fputs (reg_names [regno], file);
2108           fputs ("]", file);
2109         }
2110       return;
2111     }
2112
2113   mode = GET_MODE (x);
2114
2115   switch (code)
2116     {
2117     case 'C':
2118     case 'c':
2119       {
2120         enum rtx_code c = GET_CODE (x);
2121         if (code == 'C')
2122           c = swap_condition (c);
2123         fputs (GET_RTX_NAME (c), file);
2124       }
2125       return;
2126
2127     case 'J':
2128     case 'j':
2129       {
2130         unsigned int regno = REGNO (XEXP (x, 0));
2131         if ((GET_CODE (x) == EQ) == (code == 'J'))
2132           fputs ("!", file);
2133         fputs (reg_names [regno], file);
2134       }
2135       return;
2136
2137     case 'k':
2138       gcc_assert (GET_CODE (x) == CONST_INT);
2139       v = INTVAL (x);
2140       fprintf (file, "%s", reg_names[v]);
2141       return;
2142     case 'K':
2143       gcc_assert (GET_CODE (x) == CONST_INT);
2144       v = INTVAL (x);
2145       gcc_assert ((v & 1) == 0);
2146       fprintf (file, "%s:%s", reg_names[v + 1], reg_names[v]);
2147       return;
2148
2149     case 's':
2150     case 'S':
2151     case 'f':
2152     case 'F':
2153       gcc_assert (GET_CODE (x) == CONST_INT);
2154       v = INTVAL (x);
2155       for (i = 0; i < 32; i++)
2156         {
2157           HOST_WIDE_INT tst = v & 1;
2158           if (((code == 'f' || code == 'F') && !tst)
2159               || ((code == 's' || code == 'S') && tst))
2160             break;
2161           v >>= 1;
2162         }
2163       if (code == 'f' || code == 's')
2164         {
2165           fprintf (file, "%d", i);
2166           return;
2167         }
2168       for (;i < 32; i++)
2169         {
2170           HOST_WIDE_INT tst = v & 1;
2171           if ((code == 'F' && tst) || (code == 'S' && !tst))
2172             break;
2173           v >>= 1;
2174         }
2175       fprintf (file, "%d", i - 1);
2176       return;
2177
2178     case 'n':
2179       gcc_assert (GET_CODE (x) == CONST_INT);
2180       output_addr_const (file, GEN_INT (-INTVAL (x)));
2181       return;
2182
2183     case 'r':
2184       gcc_assert (GET_CODE (x) == CONST_INT);
2185       v = INTVAL (x);
2186       if (v < 0)
2187         v = -v;
2188       output_addr_const (file, GEN_INT (v >> 1));
2189       return;
2190
2191     case 'R':
2192       gcc_assert (GET_CODE (x) == CONST_INT);
2193       v = INTVAL (x);
2194       if (v < 0)
2195         v = -v;
2196       output_addr_const (file, GEN_INT (v >> 2));
2197       return;
2198
2199     case 'd':
2200       gcc_assert (GET_CODE (x) == CONST_INT);
2201       v = INTVAL (x);
2202       fputs (v == 2 ? "h" : v == 4 ? "w" : "d", file);
2203       return;
2204
2205     case 'p':
2206     case 'P':
2207       gcc_assert (GET_CODE (x) == REG);
2208       v = REGNO (x);
2209       if (code == 'P')
2210         v++;
2211       fputs (reg_names[v], file);
2212       return;
2213
2214     case 'D':
2215       v = 0;
2216       if (GET_CODE (x) == CONST)
2217         {
2218           x = XEXP (x, 0);
2219           gcc_assert (GET_CODE (x) == PLUS);
2220           gcc_assert (GET_CODE (XEXP (x, 1)) == CONST_INT);
2221           v = INTVAL (XEXP (x, 1));
2222           x = XEXP (x, 0);
2223
2224         }
2225       gcc_assert (GET_CODE (x) == SYMBOL_REF);
2226
2227       t = SYMBOL_REF_DECL (x);
2228       if (DECL_P (t))
2229         v |= DECL_ALIGN_UNIT (t);
2230       else
2231         v |= TYPE_ALIGN_UNIT (TREE_TYPE (t));
2232       if (v & 1)
2233         fputs ("b", file);
2234       else if (v & 2)
2235         fputs ("h", file);
2236       else
2237         fputs ("w", file);
2238       return;
2239
2240     case 'U':
2241       if (MEM_P (x))
2242         {
2243           x = XEXP (x, 0);
2244           if (GET_CODE (x) == PLUS
2245               || GET_RTX_CLASS (GET_CODE (x)) == RTX_AUTOINC)
2246             x = XEXP (x, 0);
2247           if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF)
2248             {
2249               gcc_assert (sdata_symbolic_operand (x, Pmode));
2250               fputs ("2", file);
2251               return;
2252             }
2253         }
2254       gcc_assert (REG_P (x));
2255       if (A_REGNO_P (REGNO (x)))
2256         fputs ("1", file);
2257       if (B_REGNO_P (REGNO (x)))
2258         fputs ("2", file);
2259       return;
2260
2261     default:
2262       switch (GET_CODE (x))
2263         {
2264         case REG:
2265           if (GET_MODE_SIZE (mode) == 8)
2266             fprintf (file, "%s:%s", reg_names[REGNO (x) + 1],
2267                      reg_names[REGNO (x)]);
2268           else
2269             fprintf (file, "%s", reg_names[REGNO (x)]);
2270           break;
2271
2272         case MEM:
2273           fputc ('*', file);
2274           gcc_assert (XEXP (x, 0) != stack_pointer_rtx);
2275           c6x_print_address_operand (file, XEXP (x, 0), GET_MODE (x));
2276           break;
2277
2278         case SYMBOL_REF:
2279           fputc ('(', file);
2280           output_addr_const (file, x);
2281           fputc (')', file);
2282           break;
2283
2284         case CONST_INT:
2285           output_addr_const (file, x);
2286           break;
2287
2288         case CONST_DOUBLE:
2289           output_operand_lossage ("invalid const_double operand");
2290           break;
2291
2292         default:
2293           output_addr_const (file, x);
2294         }
2295     }
2296 }
2297 \f
2298 /* Return TRUE if OP is a valid memory address with a base register of
2299    class C.  If SMALL_OFFSET is true, we disallow memory references which would
2300    require a long offset with B14/B15.  */
2301
2302 bool
2303 c6x_mem_operand (rtx op, enum reg_class c, bool small_offset)
2304 {
2305   enum machine_mode mode = GET_MODE (op);
2306   rtx base = XEXP (op, 0);
2307   switch (GET_CODE (base))
2308     {
2309     case REG:
2310       break;
2311     case PLUS:
2312       if (small_offset
2313           && (XEXP (base, 0) == stack_pointer_rtx
2314               || XEXP (base, 0) == pic_offset_table_rtx))
2315         {
2316           if (!c6x_legitimate_address_p_1 (mode, base, true, true))
2317             return false;
2318         }
2319
2320       /* fall through */
2321     case PRE_INC:
2322     case PRE_DEC:
2323     case PRE_MODIFY:
2324     case POST_INC:
2325     case POST_DEC:
2326     case POST_MODIFY:
2327       base = XEXP (base, 0);
2328       break;
2329
2330     case CONST:
2331     case LABEL_REF:
2332     case SYMBOL_REF:
2333       gcc_assert (sdata_symbolic_operand (base, Pmode));
2334       return !small_offset && c == B_REGS;
2335
2336     default:
2337       return false;
2338     }
2339   return TEST_HARD_REG_BIT (reg_class_contents[ (int) (c)], REGNO (base));
2340 }
2341
2342 /* Returns true if X is a valid address for use in a memory reference
2343    of mode MODE.  If STRICT is true, we do not allow pseudo registers
2344    in the address.  NO_LARGE_OFFSET is true if we are examining an
2345    address for use in a load or store misaligned instruction, or
2346    recursively examining an operand inside a PRE/POST_MODIFY.  */
2347
2348 bool
2349 c6x_legitimate_address_p_1 (enum machine_mode mode, rtx x, bool strict,
2350                             bool no_large_offset)
2351 {
2352   int size, size1;
2353   HOST_WIDE_INT off;
2354   enum rtx_code code = GET_CODE (x);
2355
2356   switch (code)
2357     {
2358     case PRE_MODIFY:
2359     case POST_MODIFY:
2360       /* We can't split these into word-sized pieces yet.  */
2361       if (!TARGET_STDW && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
2362         return false;
2363       if (GET_CODE (XEXP (x, 1)) != PLUS)
2364         return false;
2365       if (!c6x_legitimate_address_p_1 (mode, XEXP (x, 1), strict, true))
2366         return false;
2367       if (!rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0)))
2368         return false;
2369
2370       /* fall through */
2371     case PRE_INC:
2372     case PRE_DEC:
2373     case POST_INC:
2374     case POST_DEC:
2375       /* We can't split these into word-sized pieces yet.  */
2376       if (!TARGET_STDW && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
2377         return false;
2378       x = XEXP (x, 0);
2379       if (!REG_P (x))
2380         return false;
2381
2382       /* fall through */
2383     case REG:
2384       if (strict)
2385         return REGNO_OK_FOR_BASE_STRICT_P (REGNO (x));
2386       else
2387         return REGNO_OK_FOR_BASE_NONSTRICT_P (REGNO (x));
2388
2389     case PLUS:
2390       if (!REG_P (XEXP (x, 0))
2391           || !c6x_legitimate_address_p_1 (mode, XEXP (x, 0), strict, false))
2392         return false;
2393       /* We cannot ensure currently that both registers end up in the
2394          same register file.  */
2395       if (REG_P (XEXP (x, 1)))
2396         return false;
2397
2398       if (mode == BLKmode)
2399         size = 4;
2400       else if (mode == VOIDmode)
2401         /* ??? This can happen during ivopts.  */
2402         size = 1;
2403       else
2404         size = GET_MODE_SIZE (mode);
2405
2406       if (flag_pic
2407           && GET_CODE (XEXP (x, 1)) == UNSPEC
2408           && XINT (XEXP (x, 1), 1) == UNSPEC_LOAD_SDATA
2409           && XEXP (x, 0) == pic_offset_table_rtx
2410           && sdata_symbolic_operand (XVECEXP (XEXP (x, 1), 0, 0), SImode))
2411         return !no_large_offset && size <= 4;
2412       if (flag_pic == 1
2413           && mode == Pmode
2414           && GET_CODE (XEXP (x, 1)) == UNSPEC
2415           && XINT (XEXP (x, 1), 1) == UNSPEC_LOAD_GOT
2416           && XEXP (x, 0) == pic_offset_table_rtx
2417           && (GET_CODE (XVECEXP (XEXP (x, 1), 0, 0)) == SYMBOL_REF
2418               || GET_CODE (XVECEXP (XEXP (x, 1), 0, 0)) == LABEL_REF))
2419         return !no_large_offset;
2420       if (GET_CODE (XEXP (x, 1)) != CONST_INT)
2421         return false;
2422
2423       off = INTVAL (XEXP (x, 1));
2424
2425       /* If the machine does not have doubleword load/stores, we'll use
2426          word size accesses.  */
2427       size1 = size;
2428       if (size == 2 * UNITS_PER_WORD && !TARGET_STDW)
2429         size = UNITS_PER_WORD;
2430
2431       if (((HOST_WIDE_INT)size1 - 1) & off)
2432         return false;
2433       off /= size;
2434       if (off > -32 && off < (size1 == size ? 32 : 28))
2435         return true;
2436       if (no_large_offset || code != PLUS || XEXP (x, 0) != stack_pointer_rtx
2437           || size1 > UNITS_PER_WORD)
2438         return false;
2439       return off >= 0 && off < 32768;
2440
2441     case CONST:
2442     case SYMBOL_REF:
2443     case LABEL_REF:
2444       return (!no_large_offset
2445               /* With -fpic, we must wrap it in an unspec to show the B14
2446                  dependency.  */
2447               && !flag_pic
2448               && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
2449               && sdata_symbolic_operand (x, Pmode));
2450
2451     default:
2452       return false;
2453     }
2454 }
2455
2456 static bool
2457 c6x_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
2458 {
2459   return c6x_legitimate_address_p_1 (mode, x, strict, false);
2460 }
2461
2462 static bool
2463 c6x_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED,
2464                            rtx x ATTRIBUTE_UNUSED)
2465 {
2466   return true;
2467 }
2468 \f
2469 /* Implements TARGET_PREFERRED_RENAME_CLASS.  */
2470 static reg_class_t
2471 c6x_preferred_rename_class (reg_class_t cl)
2472 {
2473   if (cl == A_REGS)
2474     return NONPREDICATE_A_REGS;
2475   if (cl == B_REGS)
2476     return NONPREDICATE_B_REGS;
2477   if (cl == ALL_REGS || cl == GENERAL_REGS)
2478     return NONPREDICATE_REGS;
2479   return NO_REGS;
2480 }
2481 \f
2482 /* Implements FINAL_PRESCAN_INSN.  */
2483 void
2484 c6x_final_prescan_insn (rtx insn, rtx *opvec ATTRIBUTE_UNUSED,
2485                         int noperands ATTRIBUTE_UNUSED)
2486 {
2487   c6x_current_insn = insn;
2488 }
2489 \f
2490 /* A structure to describe the stack layout of a function.  The layout is
2491    as follows:
2492
2493    [saved frame pointer (or possibly padding0)]
2494    --> incoming stack pointer, new hard frame pointer
2495    [saved call-used regs]
2496    [optional padding1]
2497    --> soft frame pointer
2498    [frame]
2499    [outgoing arguments]
2500    [optional padding2]
2501
2502   The structure members are laid out in this order.  */
2503
2504 struct c6x_frame
2505 {
2506   int padding0;
2507   /* Number of registers to save.  */
2508   int nregs;
2509   int padding1;
2510   HOST_WIDE_INT frame;
2511   int outgoing_arguments_size;
2512   int padding2;
2513
2514   HOST_WIDE_INT to_allocate;
2515   /* The offsets relative to the incoming stack pointer (which
2516      becomes HARD_FRAME_POINTER).  */
2517   HOST_WIDE_INT frame_pointer_offset;
2518   HOST_WIDE_INT b3_offset;
2519
2520   /* True if we should call push_rts/pop_rts to save and restore
2521      registers.  */
2522   bool push_rts;
2523 };
2524
2525 /* Return true if we need to save and modify the PIC register in the
2526    prologue.  */
2527
2528 static bool
2529 must_reload_pic_reg_p (void)
2530 {
2531   struct cgraph_local_info *i = NULL;
2532
2533   if (!TARGET_DSBT)
2534     return false;
2535
2536   i = cgraph_local_info (current_function_decl);
2537
2538   if ((crtl->uses_pic_offset_table || !current_function_is_leaf) && !i->local)
2539     return true;
2540   return false;
2541 }
2542
2543 /* Return 1 if we need to save REGNO.  */
2544 static int
2545 c6x_save_reg (unsigned int regno)
2546 {
2547   return ((df_regs_ever_live_p (regno)
2548            && !call_used_regs[regno]
2549            && !fixed_regs[regno])
2550           || (regno == RETURN_ADDR_REGNO
2551               && (df_regs_ever_live_p (regno)
2552                   || !current_function_is_leaf))
2553           || (regno == PIC_OFFSET_TABLE_REGNUM && must_reload_pic_reg_p ()));
2554 }
2555
2556 /* Examine the number of regs NREGS we've determined we must save.
2557    Return true if we should use __c6xabi_push_rts/__c6xabi_pop_rts for
2558    prologue and epilogue.  */
2559
2560 static bool
2561 use_push_rts_p (int nregs)
2562 {
2563   if (TARGET_INSNS_64PLUS && optimize_function_for_size_p (cfun)
2564       && !cfun->machine->contains_sibcall
2565       && !cfun->returns_struct
2566       && !TARGET_LONG_CALLS
2567       && nregs >= 6 && !frame_pointer_needed)
2568     return true;
2569   return false;
2570 }
2571
2572 /* Return number of saved general prupose registers.  */
2573
2574 int
2575 c6x_nsaved_regs (void)
2576 {
2577   int nregs = 0;
2578   int regno;
2579
2580   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
2581     if (c6x_save_reg (regno))
2582       nregs++;
2583   return nregs;
2584 }
2585
2586 /* The safe debug order mandated by the ABI.  */
2587 static unsigned reg_save_order[] =
2588 {
2589   REG_A10, REG_A11, REG_A12, REG_A13,
2590   REG_A14, REG_B3,
2591   REG_B10, REG_B11, REG_B12, REG_B13,
2592   REG_B14, REG_A15
2593 };
2594
2595 #define N_SAVE_ORDER (sizeof reg_save_order / sizeof *reg_save_order)
2596
2597 /* Compute the layout of the stack frame and store it in FRAME.  */
2598
2599 static void
2600 c6x_compute_frame_layout (struct c6x_frame *frame)
2601 {
2602   HOST_WIDE_INT size = get_frame_size ();
2603   HOST_WIDE_INT offset;
2604   int nregs;
2605
2606   /* We use the four bytes which are technically inside the caller's frame,
2607      usually to save the frame pointer.  */
2608   offset = -4;
2609   frame->padding0 = 0;
2610   nregs = c6x_nsaved_regs ();
2611   frame->push_rts = false;
2612   frame->b3_offset = 0;
2613   if (use_push_rts_p (nregs))
2614     {
2615       frame->push_rts = true;
2616       frame->b3_offset = (TARGET_BIG_ENDIAN ? -12 : -13) * 4;
2617       nregs = 14;
2618     }
2619   else if (c6x_save_reg (REG_B3))
2620     {
2621       int idx;
2622       for (idx = N_SAVE_ORDER - 1; reg_save_order[idx] != REG_B3; idx--)
2623         {
2624           if (c6x_save_reg (reg_save_order[idx]))
2625             frame->b3_offset -= 4;
2626         }
2627     }
2628   frame->nregs = nregs;
2629
2630   if (size == 0 && nregs == 0)
2631     {
2632       frame->padding0 = 4;
2633       frame->padding1 = frame->padding2 = 0;
2634       frame->frame_pointer_offset = frame->to_allocate = 0;
2635       frame->outgoing_arguments_size = 0;
2636       return;
2637     }
2638
2639   if (!frame->push_rts)
2640     offset += frame->nregs * 4;
2641
2642   if (offset == 0 && size == 0 && crtl->outgoing_args_size == 0
2643       && !current_function_is_leaf)
2644     /* Don't use the bottom of the caller's frame if we have no
2645        allocation of our own and call other functions.  */
2646     frame->padding0 = frame->padding1 = 4;
2647   else if (offset & 4)
2648     frame->padding1 = 4;
2649   else
2650     frame->padding1 = 0;
2651
2652   offset += frame->padding0 + frame->padding1;
2653   frame->frame_pointer_offset = offset;
2654   offset += size;
2655
2656   frame->outgoing_arguments_size = crtl->outgoing_args_size;
2657   offset += frame->outgoing_arguments_size;
2658
2659   if ((offset & 4) == 0)
2660     frame->padding2 = 8;
2661   else
2662     frame->padding2 = 4;
2663   frame->to_allocate = offset + frame->padding2;
2664 }
2665
2666 /* Return the offset between two registers, one to be eliminated, and the other
2667    its replacement, at the start of a routine.  */
2668
2669 HOST_WIDE_INT
2670 c6x_initial_elimination_offset (int from, int to)
2671 {
2672   struct c6x_frame frame;
2673   c6x_compute_frame_layout (&frame);
2674
2675   if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
2676     return 0;
2677   else if (from == FRAME_POINTER_REGNUM
2678            && to == HARD_FRAME_POINTER_REGNUM)
2679     return -frame.frame_pointer_offset;
2680   else
2681     {
2682       gcc_assert (to == STACK_POINTER_REGNUM);
2683
2684       if (from == ARG_POINTER_REGNUM)
2685         return frame.to_allocate + (frame.push_rts ? 56 : 0);
2686
2687       gcc_assert (from == FRAME_POINTER_REGNUM);
2688       return frame.to_allocate - frame.frame_pointer_offset;
2689     }
2690 }
2691
2692 /* Given FROM and TO register numbers, say whether this elimination is
2693    allowed.  Frame pointer elimination is automatically handled.  */
2694
2695 static bool
2696 c6x_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
2697 {
2698   if (to == STACK_POINTER_REGNUM)
2699     return !frame_pointer_needed;
2700   return true;
2701 }
2702
2703 /* Emit insns to increment the stack pointer by OFFSET.  If
2704    FRAME_RELATED_P, set the RTX_FRAME_RELATED_P flag on the insns.
2705    Does nothing if the offset is zero.  */
2706
2707 static void
2708 emit_add_sp_const (HOST_WIDE_INT offset, bool frame_related_p)
2709 {
2710   rtx to_add = GEN_INT (offset);
2711   rtx orig_to_add = to_add;
2712   rtx insn;
2713
2714   if (offset == 0)
2715     return;
2716
2717   if (offset < -32768 || offset > 32767)
2718     {
2719       rtx reg = gen_rtx_REG (SImode, REG_A0);
2720       rtx low = GEN_INT (trunc_int_for_mode (offset, HImode));
2721
2722       insn = emit_insn (gen_movsi_high (reg, low));
2723       if (frame_related_p)
2724         RTX_FRAME_RELATED_P (insn) = 1;
2725       insn = emit_insn (gen_movsi_lo_sum (reg, reg, to_add));
2726       if (frame_related_p)
2727         RTX_FRAME_RELATED_P (insn) = 1;
2728       to_add = reg;
2729     }
2730   insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2731                                 to_add));
2732   if (frame_related_p)
2733     {
2734       if (REG_P (to_add))
2735         add_reg_note (insn, REG_FRAME_RELATED_EXPR,
2736                       gen_rtx_SET (VOIDmode, stack_pointer_rtx,
2737                                    gen_rtx_PLUS (Pmode, stack_pointer_rtx,
2738                                                  orig_to_add)));
2739
2740       RTX_FRAME_RELATED_P (insn) = 1;
2741     }
2742 }
2743
2744 /* Prologue and epilogue.  */
2745 void
2746 c6x_expand_prologue (void)
2747 {
2748   struct c6x_frame frame;
2749   rtx insn, mem;
2750   int nsaved = 0;
2751   HOST_WIDE_INT initial_offset, off, added_already;
2752
2753   c6x_compute_frame_layout (&frame);
2754
2755   if (flag_stack_usage_info)
2756     current_function_static_stack_size = frame.to_allocate;
2757
2758   initial_offset = -frame.to_allocate;
2759   if (frame.push_rts)
2760     {
2761       emit_insn (gen_push_rts ());
2762       nsaved = frame.nregs;
2763     }
2764
2765   /* If the offsets would be too large for the memory references we will
2766      create to save registers, do the stack allocation in two parts.
2767      Ensure by subtracting 8 that we don't store to the word pointed to
2768      by the stack pointer.  */
2769   if (initial_offset < -32768)
2770     initial_offset = -frame.frame_pointer_offset - 8;
2771
2772   if (frame.to_allocate > 0)
2773     gcc_assert (initial_offset != 0);
2774
2775   off = -initial_offset + 4 - frame.padding0;
2776
2777   mem = gen_frame_mem (Pmode, stack_pointer_rtx);
2778
2779   added_already = 0;
2780   if (frame_pointer_needed)
2781     {
2782       rtx fp_reg = gen_rtx_REG (SImode, REG_A15);
2783       /* We go through some contortions here to both follow the ABI's
2784          recommendation that FP == incoming SP, and to avoid writing or
2785          reading the word pointed to by the stack pointer.  */
2786       rtx addr = gen_rtx_POST_MODIFY (Pmode, stack_pointer_rtx,
2787                                       gen_rtx_PLUS (Pmode, stack_pointer_rtx,
2788                                                     GEN_INT (-8)));
2789       insn = emit_move_insn (gen_frame_mem (Pmode, addr), fp_reg);
2790       RTX_FRAME_RELATED_P (insn) = 1;
2791       nsaved++;
2792       insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, stack_pointer_rtx,
2793                                     GEN_INT (8)));
2794       RTX_FRAME_RELATED_P (insn) = 1;
2795       off -= 4;
2796       added_already = -8;
2797     }
2798
2799   emit_add_sp_const (initial_offset - added_already, true);
2800
2801   if (nsaved < frame.nregs)
2802     {
2803       unsigned i;
2804
2805       for (i = 0; i < N_SAVE_ORDER; i++)
2806         {
2807           int idx = N_SAVE_ORDER - i - 1;
2808           unsigned regno = reg_save_order[idx];
2809           rtx reg;
2810           enum machine_mode save_mode = SImode;
2811
2812           if (regno == REG_A15 && frame_pointer_needed)
2813             /* Already saved.  */
2814             continue;
2815           if (!c6x_save_reg (regno))
2816             continue;
2817
2818           if (TARGET_STDW && (off & 4) == 0 && off <= 256
2819               && (regno & 1) == 1
2820               && i + 1 < N_SAVE_ORDER
2821               && reg_save_order[idx - 1] == regno - 1
2822               && c6x_save_reg (regno - 1))
2823             {
2824               save_mode = DImode;
2825               regno--;
2826               i++;
2827             }
2828           reg = gen_rtx_REG (save_mode, regno);
2829           off -= GET_MODE_SIZE (save_mode);
2830
2831           insn = emit_move_insn (adjust_address (mem, save_mode, off),
2832                                  reg);
2833           RTX_FRAME_RELATED_P (insn) = 1;
2834
2835           nsaved += HARD_REGNO_NREGS (regno, save_mode);
2836         }
2837     }
2838   gcc_assert (nsaved == frame.nregs);
2839   emit_add_sp_const (-frame.to_allocate - initial_offset, true);
2840   if (must_reload_pic_reg_p ())
2841     {
2842       if (dsbt_decl == NULL)
2843         {
2844           tree t;
2845
2846           t = build_index_type (integer_one_node);
2847           t = build_array_type (integer_type_node, t);
2848           t = build_decl (BUILTINS_LOCATION, VAR_DECL,
2849                           get_identifier ("__c6xabi_DSBT_BASE"), t);
2850           DECL_ARTIFICIAL (t) = 1;
2851           DECL_IGNORED_P (t) = 1;
2852           DECL_EXTERNAL (t) = 1;
2853           TREE_STATIC (t) = 1;
2854           TREE_PUBLIC (t) = 1;
2855           TREE_USED (t) = 1;
2856
2857           dsbt_decl = t;
2858         }
2859       emit_insn (gen_setup_dsbt (pic_offset_table_rtx,
2860                                  XEXP (DECL_RTL (dsbt_decl), 0)));
2861     }
2862 }
2863
2864 void
2865 c6x_expand_epilogue (bool sibcall)
2866 {
2867   unsigned i;
2868   struct c6x_frame frame;
2869   rtx mem;
2870   HOST_WIDE_INT off;
2871   int nsaved = 0;
2872
2873   c6x_compute_frame_layout (&frame);
2874
2875   mem = gen_frame_mem (Pmode, stack_pointer_rtx);
2876
2877   /* Insert a dummy set/use of the stack pointer.  This creates a
2878      scheduler barrier between the prologue saves and epilogue restores. */
2879   emit_insn (gen_epilogue_barrier (stack_pointer_rtx, stack_pointer_rtx));
2880
2881   /* If the offsets would be too large for the memory references we will
2882      create to restore registers, do a preliminary stack adjustment here.  */
2883   off = frame.to_allocate - frame.frame_pointer_offset + frame.padding1;
2884   if (frame.push_rts)
2885     {
2886       nsaved = frame.nregs;
2887     }
2888   else
2889     {
2890       if (frame.to_allocate > 32768)
2891         {
2892           /* Don't add the entire offset so that we leave an unused word
2893              above the stack pointer.  */
2894           emit_add_sp_const ((off - 16) & ~7, false);
2895           off &= 7;
2896           off += 16;
2897         }
2898       for (i = 0; i < N_SAVE_ORDER; i++)
2899         {
2900           unsigned regno = reg_save_order[i];
2901           rtx reg;
2902           enum machine_mode save_mode = SImode;
2903
2904           if (!c6x_save_reg (regno))
2905             continue;
2906           if (regno == REG_A15 && frame_pointer_needed)
2907             continue;
2908
2909           if (TARGET_STDW && (off & 4) == 0 && off < 256
2910               && (regno & 1) == 0
2911               && i + 1 < N_SAVE_ORDER
2912               && reg_save_order[i + 1] == regno + 1
2913               && c6x_save_reg (regno + 1))
2914             {
2915               save_mode = DImode;
2916               i++;
2917             }
2918           reg = gen_rtx_REG (save_mode, regno);
2919
2920           emit_move_insn (reg, adjust_address (mem, save_mode, off));
2921
2922           off += GET_MODE_SIZE (save_mode);
2923           nsaved += HARD_REGNO_NREGS (regno, save_mode);
2924         }
2925     }
2926   if (!frame_pointer_needed)
2927     emit_add_sp_const (off + frame.padding0 - 4, false);
2928   else
2929     {
2930       rtx fp_reg = gen_rtx_REG (SImode, REG_A15);
2931       rtx addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
2932                                       gen_rtx_PLUS (Pmode, stack_pointer_rtx,
2933                                                     GEN_INT (8)));
2934       emit_insn (gen_addsi3 (stack_pointer_rtx, hard_frame_pointer_rtx,
2935                              GEN_INT (-8)));
2936       emit_move_insn (fp_reg, gen_frame_mem (Pmode, addr));
2937       nsaved++;
2938     }
2939   gcc_assert (nsaved == frame.nregs);
2940   if (!sibcall)
2941     {
2942       if (frame.push_rts)
2943         emit_jump_insn (gen_pop_rts ());
2944       else
2945         emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode,
2946                                                           RETURN_ADDR_REGNO)));
2947     }
2948 }
2949
2950 /* Return the value of the return address for the frame COUNT steps up
2951    from the current frame, after the prologue.
2952    We punt for everything but the current frame by returning const0_rtx.  */
2953
2954 rtx
2955 c6x_return_addr_rtx (int count)
2956 {
2957   if (count != 0)
2958     return const0_rtx;
2959
2960   return get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNO);
2961 }
2962 \f
2963 /* Return true iff TYPE is one of the shadow types.  */
2964 static bool
2965 shadow_type_p (enum attr_type type)
2966 {
2967   return (type == TYPE_SHADOW || type == TYPE_LOAD_SHADOW
2968           || type == TYPE_MULT_SHADOW);
2969 }
2970
2971 /* Return true iff INSN is a shadow pattern.  */
2972 static bool
2973 shadow_p (rtx insn)
2974 {
2975   if (!NONDEBUG_INSN_P (insn) || recog_memoized (insn) < 0)
2976     return false;
2977   return shadow_type_p (get_attr_type (insn));
2978 }
2979
2980 /* Return true iff INSN is a shadow or blockage pattern.  */
2981 static bool
2982 shadow_or_blockage_p (rtx insn)
2983 {
2984   enum attr_type type;
2985   if (!NONDEBUG_INSN_P (insn) || recog_memoized (insn) < 0)
2986     return false;
2987   type = get_attr_type (insn);
2988   return shadow_type_p (type) || type == TYPE_BLOCKAGE;
2989 }
2990 \f
2991 /* Translate UNITS into a bitmask of units we can reserve for this
2992    insn.  */
2993 static int
2994 get_reservation_flags (enum attr_units units)
2995 {
2996   switch (units)
2997     {
2998     case UNITS_D:
2999     case UNITS_D_ADDR:
3000       return RESERVATION_FLAG_D;
3001     case UNITS_L:
3002       return RESERVATION_FLAG_L;
3003     case UNITS_S:
3004       return RESERVATION_FLAG_S;
3005     case UNITS_M:
3006       return RESERVATION_FLAG_M;
3007     case UNITS_LS:
3008       return RESERVATION_FLAG_LS;
3009     case UNITS_DL:
3010       return RESERVATION_FLAG_DL;
3011     case UNITS_DS:
3012       return RESERVATION_FLAG_DS;
3013     case UNITS_DLS:
3014       return RESERVATION_FLAG_DLS;
3015     default:
3016       return 0;
3017     }
3018 }
3019
3020 /* Compute the side of the machine used by INSN, which reserves UNITS.
3021    This must match the reservations in the scheduling description.  */
3022 static int
3023 get_insn_side (rtx insn, enum attr_units units)
3024 {
3025   if (units == UNITS_D_ADDR)
3026     return (get_attr_addr_regfile (insn) == ADDR_REGFILE_A ? 0 : 1);
3027   else
3028     {
3029       enum attr_dest_regfile rf = get_attr_dest_regfile (insn);
3030       if (rf == DEST_REGFILE_ANY)
3031         return get_attr_type (insn) == TYPE_BRANCH ? 0 : 1;
3032       else
3033         return rf == DEST_REGFILE_A ? 0 : 1;
3034     }
3035 }
3036
3037 /* After scheduling, walk the insns between HEAD and END and assign unit
3038    reservations.  */
3039 static void
3040 assign_reservations (rtx head, rtx end)
3041 {
3042   rtx insn;
3043   for (insn = head; insn != NEXT_INSN (end); insn = NEXT_INSN (insn))
3044     {
3045       unsigned int sched_mask, reserved;
3046       rtx within, last;
3047       int pass;
3048       int rsrv[2];
3049       int rsrv_count[2][4];
3050       int i;
3051
3052       if (GET_MODE (insn) != TImode)
3053         continue;
3054
3055       reserved = 0;
3056       last = NULL_RTX;
3057       /* Find the last insn in the packet.  It has a state recorded for it,
3058          which we can use to determine the units we should be using.  */
3059       for (within = insn;
3060            (within != NEXT_INSN (end)
3061             && (within == insn || GET_MODE (within) != TImode));
3062            within = NEXT_INSN (within))
3063         {
3064           int icode;
3065           if (!NONDEBUG_INSN_P (within))
3066             continue;
3067           icode = recog_memoized (within);
3068           if (icode < 0)
3069             continue;
3070           if (shadow_p (within))
3071             continue;
3072           if (INSN_INFO_ENTRY (INSN_UID (within)).reservation != 0)
3073             reserved |= 1 << INSN_INFO_ENTRY (INSN_UID (within)).reservation;
3074           last = within;
3075         }
3076       if (last == NULL_RTX)
3077         continue;
3078
3079       sched_mask = INSN_INFO_ENTRY (INSN_UID (last)).unit_mask;
3080       sched_mask &= ~reserved;
3081
3082       memset (rsrv_count, 0, sizeof rsrv_count);
3083       rsrv[0] = rsrv[1] = ~0;
3084       for (i = 0; i < 8; i++)
3085         {
3086           int side = i / 4;
3087           int unit = i & 3;
3088           unsigned unit_bit = 1 << (unit + side * UNIT_QID_SIDE_OFFSET);
3089           /* Clear the bits which we expect to reserve in the following loop,
3090              leaving the ones set which aren't present in the scheduler's
3091              state and shouldn't be reserved.  */
3092           if (sched_mask & unit_bit)
3093             rsrv[i / 4] &= ~(1 << unit);
3094         }
3095
3096       /* Walk through the insns that occur in the same cycle.  We use multiple
3097          passes to assign units, assigning for insns with the most specific
3098          requirements first.  */
3099       for (pass = 0; pass < 4; pass++)
3100         for (within = insn;
3101              (within != NEXT_INSN (end)
3102               && (within == insn || GET_MODE (within) != TImode));
3103              within = NEXT_INSN (within))
3104           {
3105             int uid = INSN_UID (within);
3106             int this_rsrv, side;
3107             int icode;
3108             enum attr_units units;
3109             enum attr_type type;
3110             int j;
3111
3112             if (!NONDEBUG_INSN_P (within))
3113               continue;
3114             icode = recog_memoized (within);
3115             if (icode < 0)
3116               continue;
3117             if (INSN_INFO_ENTRY (uid).reservation != 0)
3118               continue;
3119             units = get_attr_units (within);
3120             type = get_attr_type (within);
3121             this_rsrv = get_reservation_flags (units);
3122             if (this_rsrv == 0)
3123               continue;
3124             side = get_insn_side (within, units);
3125
3126             /* Certain floating point instructions are treated specially.  If
3127                an insn can choose between units it can reserve, and its
3128                reservation spans more than one cycle, the reservation contains
3129                special markers in the first cycle to help us reconstruct what
3130                the automaton chose.  */
3131             if ((type == TYPE_ADDDP || type == TYPE_FP4)
3132                 && units == UNITS_LS)
3133               {
3134                 int test1_code = ((type == TYPE_FP4 ? UNIT_QID_FPL1 : UNIT_QID_ADDDPL1)
3135                                   + side * UNIT_QID_SIDE_OFFSET);
3136                 int test2_code = ((type == TYPE_FP4 ? UNIT_QID_FPS1 : UNIT_QID_ADDDPS1)
3137                                   + side * UNIT_QID_SIDE_OFFSET);
3138                 if ((sched_mask & (1 << test1_code)) != 0)
3139                   {
3140                     this_rsrv = RESERVATION_FLAG_L;
3141                     sched_mask &= ~(1 << test1_code);
3142                   }
3143                 else if ((sched_mask & (1 << test2_code)) != 0)
3144                   {
3145                     this_rsrv = RESERVATION_FLAG_S;
3146                     sched_mask &= ~(1 << test2_code);
3147                   }
3148               }
3149
3150             if ((this_rsrv & (this_rsrv - 1)) == 0)
3151               {
3152                 int t = exact_log2 (this_rsrv) + side * UNIT_QID_SIDE_OFFSET;
3153                 rsrv[side] |= this_rsrv;
3154                 INSN_INFO_ENTRY (uid).reservation = t;
3155                 continue;
3156               }
3157
3158             if (pass == 1)
3159               {
3160                 for (j = 0; j < 4; j++)
3161                   if (this_rsrv & (1 << j))
3162                     rsrv_count[side][j]++;
3163                 continue;
3164               }
3165             if ((pass == 2 && this_rsrv != RESERVATION_FLAG_DLS)
3166                 || (pass == 3 && this_rsrv == RESERVATION_FLAG_DLS))
3167               {
3168                 int best = -1, best_cost = INT_MAX;
3169                 for (j = 0; j < 4; j++)
3170                   if ((this_rsrv & (1 << j))
3171                       && !(rsrv[side] & (1 << j))
3172                       && rsrv_count[side][j] < best_cost)
3173                     {
3174                       best_cost = rsrv_count[side][j];
3175                       best = j;
3176                     }
3177                 gcc_assert (best != -1);
3178                 rsrv[side] |= 1 << best;
3179                 for (j = 0; j < 4; j++)
3180                   if ((this_rsrv & (1 << j)) && j != best)
3181                     rsrv_count[side][j]--;
3182
3183                 INSN_INFO_ENTRY (uid).reservation
3184                   = best + side * UNIT_QID_SIDE_OFFSET;
3185               }
3186           }
3187     }
3188 }
3189
3190 /* Return a factor by which to weight unit imbalances for a reservation
3191    R.  */
3192 static int
3193 unit_req_factor (enum unitreqs r)
3194 {
3195   switch (r)
3196     {
3197     case UNIT_REQ_D:
3198     case UNIT_REQ_L:
3199     case UNIT_REQ_S:
3200     case UNIT_REQ_M:
3201     case UNIT_REQ_X:
3202     case UNIT_REQ_T:
3203       return 1;
3204     case UNIT_REQ_DL:
3205     case UNIT_REQ_LS:
3206     case UNIT_REQ_DS:
3207       return 2;
3208     case UNIT_REQ_DLS:
3209       return 3;
3210     default:
3211       gcc_unreachable ();
3212     }
3213 }
3214
3215 /* Examine INSN, and store in REQ1/SIDE1 and REQ2/SIDE2 the unit
3216    requirements.  Returns zero if INSN can't be handled, otherwise
3217    either one or two to show how many of the two pairs are in use.
3218    REQ1 is always used, it holds what is normally thought of as the
3219    instructions reservation, e.g. UNIT_REQ_DL.  REQ2 is used to either
3220    describe a cross path, or for loads/stores, the T unit.  */
3221 static int
3222 get_unit_reqs (rtx insn, int *req1, int *side1, int *req2, int *side2)
3223 {
3224   enum attr_units units;
3225   enum attr_cross cross;
3226   int side, req;
3227
3228   if (!NONDEBUG_INSN_P (insn) || recog_memoized (insn) < 0)
3229     return 0;
3230   units = get_attr_units (insn);
3231   if (units == UNITS_UNKNOWN)
3232     return 0;
3233   side = get_insn_side (insn, units);
3234   cross = get_attr_cross (insn);
3235
3236   req = (units == UNITS_D ? UNIT_REQ_D
3237          : units == UNITS_D_ADDR ? UNIT_REQ_D
3238          : units == UNITS_DL ? UNIT_REQ_DL
3239          : units == UNITS_DS ? UNIT_REQ_DS
3240          : units == UNITS_L ? UNIT_REQ_L
3241          : units == UNITS_LS ? UNIT_REQ_LS
3242          : units == UNITS_S ? UNIT_REQ_S
3243          : units == UNITS_M ? UNIT_REQ_M
3244          : units == UNITS_DLS ? UNIT_REQ_DLS
3245          : -1);
3246   gcc_assert (req != -1);
3247   *req1 = req;
3248   *side1 = side;
3249   if (units == UNITS_D_ADDR)
3250     {
3251       *req2 = UNIT_REQ_T;
3252       *side2 = side ^ (cross == CROSS_Y ? 1 : 0);
3253       return 2;
3254     }
3255   else if (cross == CROSS_Y)
3256     {
3257       *req2 = UNIT_REQ_X;
3258       *side2 = side;
3259       return 2;
3260     }
3261   return 1;
3262 }
3263
3264 /* Walk the insns between and including HEAD and TAIL, and mark the
3265    resource requirements in the unit_reqs table.  */
3266 static void
3267 count_unit_reqs (unit_req_table reqs, rtx head, rtx tail)
3268 {
3269   rtx insn;
3270
3271   memset (reqs, 0, sizeof (unit_req_table));
3272
3273   for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
3274     {
3275       int side1, side2, req1, req2;
3276
3277       switch (get_unit_reqs (insn, &req1, &side1, &req2, &side2))
3278         {
3279         case 2:
3280           reqs[side2][req2]++;
3281           /* fall through */
3282         case 1:
3283           reqs[side1][req1]++;
3284           break;
3285         }
3286     }
3287 }
3288
3289 /* Update the table REQS by merging more specific unit reservations into
3290    more general ones, i.e. counting (for example) UNIT_REQ_D also in
3291    UNIT_REQ_DL, DS, and DLS.  */
3292 static void
3293 merge_unit_reqs (unit_req_table reqs)
3294 {
3295   int side;
3296   for (side = 0; side < 2; side++)
3297     {
3298       int d = reqs[side][UNIT_REQ_D];
3299       int l = reqs[side][UNIT_REQ_L];
3300       int s = reqs[side][UNIT_REQ_S];
3301       int dl = reqs[side][UNIT_REQ_DL];
3302       int ls = reqs[side][UNIT_REQ_LS];
3303       int ds = reqs[side][UNIT_REQ_DS];
3304
3305       reqs[side][UNIT_REQ_DL] += d;
3306       reqs[side][UNIT_REQ_DL] += l;
3307       reqs[side][UNIT_REQ_DS] += d;
3308       reqs[side][UNIT_REQ_DS] += s;
3309       reqs[side][UNIT_REQ_LS] += l;
3310       reqs[side][UNIT_REQ_LS] += s;
3311       reqs[side][UNIT_REQ_DLS] += ds + dl + ls + d + l + s;
3312     }
3313 }
3314
3315 /* Return the resource-constrained minimum iteration interval given the
3316    data in the REQS table.  This must have been processed with
3317    merge_unit_reqs already.  */
3318 static int
3319 res_mii (unit_req_table reqs)
3320 {
3321   int side, req;
3322   int worst = 1;
3323   for (side = 0; side < 2; side++)
3324     for (req = 0; req < UNIT_REQ_MAX; req++)
3325       {
3326         int factor = unit_req_factor (req);
3327         worst = MAX ((reqs[side][UNIT_REQ_D] + factor - 1) / factor, worst);
3328       }
3329
3330   return worst;
3331 }
3332 \f
3333 /* Backend scheduling state.  */
3334 typedef struct c6x_sched_context
3335 {
3336   /* The current scheduler clock, saved in the sched_reorder hook.  */
3337   int curr_sched_clock;
3338
3339   /* Number of insns issued so far in this cycle.  */
3340   int issued_this_cycle;
3341
3342   /* We record the time at which each jump occurs in JUMP_CYCLES.  The
3343      theoretical maximum for number of jumps in flight is 12: 2 every
3344      cycle, with a latency of 6 cycles each.  This is a circular
3345      buffer; JUMP_CYCLE_INDEX is the pointer to the start.  Earlier
3346      jumps have a higher index.  This array should be accessed through
3347      the jump_cycle function.  */
3348   int jump_cycles[12];
3349   int jump_cycle_index;
3350
3351   /* In parallel with jump_cycles, this array records the opposite of
3352      the condition used in each pending jump.  This is used to
3353      predicate insns that are scheduled in the jump's delay slots.  If
3354      this is NULL_RTX no such predication happens.  */
3355   rtx jump_cond[12];
3356
3357   /* Similar to the jump_cycles mechanism, but here we take into
3358      account all insns with delay slots, to avoid scheduling asms into
3359      the delay slots.  */
3360   int delays_finished_at;
3361
3362   /* The following variable value is the last issued insn.  */
3363   rtx last_scheduled_insn;
3364   /* The last issued insn that isn't a shadow of another.  */
3365   rtx last_scheduled_iter0;
3366
3367   /* The following variable value is DFA state before issuing the
3368      first insn in the current clock cycle.  We do not use this member
3369      of the structure directly; we copy the data in and out of
3370      prev_cycle_state.  */
3371   state_t prev_cycle_state_ctx;
3372
3373   int reg_n_accesses[FIRST_PSEUDO_REGISTER];
3374   int reg_n_xaccesses[FIRST_PSEUDO_REGISTER];
3375   int reg_set_in_cycle[FIRST_PSEUDO_REGISTER];
3376
3377   int tmp_reg_n_accesses[FIRST_PSEUDO_REGISTER];
3378   int tmp_reg_n_xaccesses[FIRST_PSEUDO_REGISTER];
3379 } *c6x_sched_context_t;
3380
3381 /* The current scheduling state.  */
3382 static struct c6x_sched_context ss;
3383
3384 /* The following variable value is DFA state before issueing the first insn
3385    in the current clock cycle.  This is used in c6x_variable_issue for
3386    comparison with the state after issuing the last insn in a cycle.  */
3387 static state_t prev_cycle_state;
3388
3389 /* Set when we discover while processing an insn that it would lead to too
3390    many accesses of the same register.  */
3391 static bool reg_access_stall;
3392
3393 /* The highest insn uid after delayed insns were split, but before loop bodies
3394    were copied by the modulo scheduling code.  */
3395 static int sploop_max_uid_iter0;
3396
3397 /* Look up the jump cycle with index N.  For an out-of-bounds N, we return 0,
3398    so the caller does not specifically have to test for it.  */
3399 static int
3400 get_jump_cycle (int n)
3401 {
3402   if (n >= 12)
3403     return 0;
3404   n += ss.jump_cycle_index;
3405   if (n >= 12)
3406     n -= 12;
3407   return ss.jump_cycles[n];
3408 }
3409
3410 /* Look up the jump condition with index N.  */
3411 static rtx
3412 get_jump_cond (int n)
3413 {
3414   if (n >= 12)
3415     return NULL_RTX;
3416   n += ss.jump_cycle_index;
3417   if (n >= 12)
3418     n -= 12;
3419   return ss.jump_cond[n];
3420 }
3421
3422 /* Return the index of the first jump that occurs after CLOCK_VAR.  If no jump
3423    has delay slots beyond CLOCK_VAR, return -1.  */
3424 static int
3425 first_jump_index (int clock_var)
3426 {
3427   int retval = -1;
3428   int n = 0;
3429   for (;;)
3430     {
3431       int t = get_jump_cycle (n);
3432       if (t <= clock_var)
3433         break;
3434       retval = n;
3435       n++;
3436     }
3437   return retval;
3438 }
3439
3440 /* Add a new entry in our scheduling state for a jump that occurs in CYCLE
3441    and has the opposite condition of COND.  */
3442 static void
3443 record_jump (int cycle, rtx cond)
3444 {
3445   if (ss.jump_cycle_index == 0)
3446     ss.jump_cycle_index = 11;
3447   else
3448     ss.jump_cycle_index--;
3449   ss.jump_cycles[ss.jump_cycle_index] = cycle;
3450   ss.jump_cond[ss.jump_cycle_index] = cond;
3451 }
3452
3453 /* Set the clock cycle of INSN to CYCLE.  Also clears the insn's entry in
3454    new_conditions.  */
3455 static void
3456 insn_set_clock (rtx insn, int cycle)
3457 {
3458   unsigned uid = INSN_UID (insn);
3459
3460   if (uid >= INSN_INFO_LENGTH)
3461     VEC_safe_grow (c6x_sched_insn_info, heap, insn_info, uid * 5 / 4 + 10);
3462
3463   INSN_INFO_ENTRY (uid).clock = cycle;
3464   INSN_INFO_ENTRY (uid).new_cond = NULL;
3465   INSN_INFO_ENTRY (uid).reservation = 0;
3466   INSN_INFO_ENTRY (uid).ebb_start = false;
3467 }
3468
3469 /* Return the clock cycle we set for the insn with uid UID.  */
3470 static int
3471 insn_uid_get_clock (int uid)
3472 {
3473   return INSN_INFO_ENTRY (uid).clock;
3474 }
3475
3476 /* Return the clock cycle we set for INSN.  */
3477 static int
3478 insn_get_clock (rtx insn)
3479 {
3480   return insn_uid_get_clock (INSN_UID (insn));
3481 }
3482
3483 /* Examine INSN, and if it is a conditional jump of any kind, return
3484    the opposite of the condition in which it branches.  Otherwise,
3485    return NULL_RTX.  */
3486 static rtx
3487 condjump_opposite_condition (rtx insn)
3488 {
3489   rtx pat = PATTERN (insn);
3490   int icode = INSN_CODE (insn);
3491   rtx x = NULL;
3492
3493   if (icode == CODE_FOR_br_true || icode == CODE_FOR_br_false)
3494     {
3495       x = XEXP (SET_SRC (pat), 0);
3496       if (icode == CODE_FOR_br_false)
3497         return x;
3498     }
3499   if (GET_CODE (pat) == COND_EXEC)
3500     {
3501       rtx t = COND_EXEC_CODE (pat);
3502       if ((GET_CODE (t) == PARALLEL
3503            && GET_CODE (XVECEXP (t, 0, 0)) == RETURN)
3504           || (GET_CODE (t) == UNSPEC && XINT (t, 1) == UNSPEC_REAL_JUMP)
3505           || (GET_CODE (t) == SET && SET_DEST (t) == pc_rtx))
3506         x = COND_EXEC_TEST (pat);
3507     }
3508
3509   if (x != NULL_RTX)
3510     {
3511       enum rtx_code code = GET_CODE (x);
3512       x = gen_rtx_fmt_ee (code == EQ ? NE : EQ,
3513                           GET_MODE (x), XEXP (x, 0),
3514                           XEXP (x, 1));
3515     }
3516   return x;
3517 }
3518
3519 /* Return true iff COND1 and COND2 are exactly opposite conditions
3520    one of them NE and the other EQ.  */
3521 static bool
3522 conditions_opposite_p (rtx cond1, rtx cond2)
3523 {
3524   return (rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
3525           && rtx_equal_p (XEXP (cond1, 1), XEXP (cond2, 1))
3526           && GET_CODE (cond1) == reverse_condition (GET_CODE (cond2)));
3527 }
3528
3529 /* Return true if we can add a predicate COND to INSN, or if INSN
3530    already has that predicate.  If DOIT is true, also perform the
3531    modification.  */
3532 static bool
3533 predicate_insn (rtx insn, rtx cond, bool doit)
3534 {
3535   int icode;
3536   if (cond == NULL_RTX)
3537     {
3538       gcc_assert (!doit);
3539       return false;
3540     }
3541
3542   if (get_attr_predicable (insn) == PREDICABLE_YES
3543       && GET_CODE (PATTERN (insn)) != COND_EXEC)
3544     {
3545       if (doit)
3546         {
3547           rtx newpat = gen_rtx_COND_EXEC (VOIDmode, cond, PATTERN (insn));
3548           PATTERN (insn) = newpat;
3549           INSN_CODE (insn) = -1;
3550         }
3551       return true;
3552     }
3553   if (GET_CODE (PATTERN (insn)) == COND_EXEC
3554       && rtx_equal_p (COND_EXEC_TEST (PATTERN (insn)), cond))