OSDN Git Service

aeacecb50573156cdb0057eb3e353cc4da3a5875
[pf3gnuchains/gcc-fork.git] / gcc / config / c4x / c4x.c
1 /* Subroutines for assembler code output on the TMS320C[34]x
2    Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004
3    Free Software Foundation, Inc.
4
5    Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)
6               and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl).
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 GCC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING.  If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA.  */
24
25 /* Some output-actions in c4x.md need these.  */
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "tm.h"
30 #include "rtl.h"
31 #include "tree.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "basic-block.h"
35 #include "real.h"
36 #include "insn-config.h"
37 #include "insn-attr.h"
38 #include "conditions.h"
39 #include "output.h"
40 #include "function.h"
41 #include "expr.h"
42 #include "optabs.h"
43 #include "libfuncs.h"
44 #include "flags.h"
45 #include "recog.h"
46 #include "ggc.h"
47 #include "cpplib.h"
48 #include "toplev.h"
49 #include "tm_p.h"
50 #include "target.h"
51 #include "target-def.h"
52 #include "langhooks.h"
53
54 rtx smulhi3_libfunc;
55 rtx umulhi3_libfunc;
56 rtx fix_truncqfhi2_libfunc;
57 rtx fixuns_truncqfhi2_libfunc;
58 rtx fix_trunchfhi2_libfunc;
59 rtx fixuns_trunchfhi2_libfunc;
60 rtx floathiqf2_libfunc;
61 rtx floatunshiqf2_libfunc;
62 rtx floathihf2_libfunc;
63 rtx floatunshihf2_libfunc;
64
65 static int c4x_leaf_function;
66
67 static const char *const float_reg_names[] = FLOAT_REGISTER_NAMES;
68
69 /* Array of the smallest class containing reg number REGNO, indexed by
70    REGNO.  Used by REGNO_REG_CLASS in c4x.h.  We assume that all these
71    registers are available and set the class to NO_REGS for registers 
72    that the target switches say are unavailable.  */
73
74 enum reg_class c4x_regclass_map[FIRST_PSEUDO_REGISTER] =
75 {
76                                 /* Reg          Modes           Saved.  */
77   R0R1_REGS,                    /* R0           QI, QF, HF      No.  */
78   R0R1_REGS,                    /* R1           QI, QF, HF      No.  */
79   R2R3_REGS,                    /* R2           QI, QF, HF      No.  */
80   R2R3_REGS,                    /* R3           QI, QF, HF      No.  */
81   EXT_LOW_REGS,                 /* R4           QI, QF, HF      QI.  */
82   EXT_LOW_REGS,                 /* R5           QI, QF, HF      QI.  */
83   EXT_LOW_REGS,                 /* R6           QI, QF, HF      QF.  */
84   EXT_LOW_REGS,                 /* R7           QI, QF, HF      QF.  */
85   ADDR_REGS,                    /* AR0          QI              No.  */
86   ADDR_REGS,                    /* AR1          QI              No.  */
87   ADDR_REGS,                    /* AR2          QI              No.  */
88   ADDR_REGS,                    /* AR3          QI              QI.  */
89   ADDR_REGS,                    /* AR4          QI              QI.  */
90   ADDR_REGS,                    /* AR5          QI              QI.  */
91   ADDR_REGS,                    /* AR6          QI              QI.  */
92   ADDR_REGS,                    /* AR7          QI              QI.  */
93   DP_REG,                       /* DP           QI              No.  */
94   INDEX_REGS,                   /* IR0          QI              No.  */
95   INDEX_REGS,                   /* IR1          QI              No.  */
96   BK_REG,                       /* BK           QI              QI.  */
97   SP_REG,                       /* SP           QI              No.  */
98   ST_REG,                       /* ST           CC              No.  */
99   NO_REGS,                      /* DIE/IE                       No.  */
100   NO_REGS,                      /* IIE/IF                       No.  */
101   NO_REGS,                      /* IIF/IOF                      No.  */
102   INT_REGS,                     /* RS           QI              No.  */
103   INT_REGS,                     /* RE           QI              No.  */
104   RC_REG,                       /* RC           QI              No.  */
105   EXT_REGS,                     /* R8           QI, QF, HF      QI.  */
106   EXT_REGS,                     /* R9           QI, QF, HF      No.  */
107   EXT_REGS,                     /* R10          QI, QF, HF      No.  */
108   EXT_REGS,                     /* R11          QI, QF, HF      No.  */
109 };
110
111 enum machine_mode c4x_caller_save_map[FIRST_PSEUDO_REGISTER] =
112 {
113                                 /* Reg          Modes           Saved.  */
114   HFmode,                       /* R0           QI, QF, HF      No.  */
115   HFmode,                       /* R1           QI, QF, HF      No.  */
116   HFmode,                       /* R2           QI, QF, HF      No.  */
117   HFmode,                       /* R3           QI, QF, HF      No.  */
118   QFmode,                       /* R4           QI, QF, HF      QI.  */
119   QFmode,                       /* R5           QI, QF, HF      QI.  */
120   QImode,                       /* R6           QI, QF, HF      QF.  */
121   QImode,                       /* R7           QI, QF, HF      QF.  */
122   QImode,                       /* AR0          QI              No.  */
123   QImode,                       /* AR1          QI              No.  */
124   QImode,                       /* AR2          QI              No.  */
125   QImode,                       /* AR3          QI              QI.  */
126   QImode,                       /* AR4          QI              QI.  */
127   QImode,                       /* AR5          QI              QI.  */
128   QImode,                       /* AR6          QI              QI.  */
129   QImode,                       /* AR7          QI              QI.  */
130   VOIDmode,                     /* DP           QI              No.  */
131   QImode,                       /* IR0          QI              No.  */
132   QImode,                       /* IR1          QI              No.  */
133   QImode,                       /* BK           QI              QI.  */
134   VOIDmode,                     /* SP           QI              No.  */
135   VOIDmode,                     /* ST           CC              No.  */
136   VOIDmode,                     /* DIE/IE                       No.  */
137   VOIDmode,                     /* IIE/IF                       No.  */
138   VOIDmode,                     /* IIF/IOF                      No.  */
139   QImode,                       /* RS           QI              No.  */
140   QImode,                       /* RE           QI              No.  */
141   VOIDmode,                     /* RC           QI              No.  */
142   QFmode,                       /* R8           QI, QF, HF      QI.  */
143   HFmode,                       /* R9           QI, QF, HF      No.  */
144   HFmode,                       /* R10          QI, QF, HF      No.  */
145   HFmode,                       /* R11          QI, QF, HF      No.  */
146 };
147
148
149 /* Test and compare insns in c4x.md store the information needed to
150    generate branch and scc insns here.  */
151
152 rtx c4x_compare_op0;
153 rtx c4x_compare_op1;
154
155 const char *c4x_rpts_cycles_string;
156 int c4x_rpts_cycles = 0;        /* Max. cycles for RPTS.  */
157 const char *c4x_cpu_version_string;
158 int c4x_cpu_version = 40;       /* CPU version C30/31/32/33/40/44.  */
159
160 /* Pragma definitions.  */
161
162 tree code_tree = NULL_TREE;
163 tree data_tree = NULL_TREE;
164 tree pure_tree = NULL_TREE;
165 tree noreturn_tree = NULL_TREE;
166 tree interrupt_tree = NULL_TREE;
167 tree naked_tree = NULL_TREE;
168
169 /* Forward declarations */
170 static int c4x_isr_reg_used_p (unsigned int);
171 static int c4x_leaf_function_p (void);
172 static int c4x_naked_function_p (void);
173 static int c4x_immed_float_p (rtx);
174 static int c4x_a_register (rtx);
175 static int c4x_x_register (rtx);
176 static int c4x_immed_int_constant (rtx);
177 static int c4x_immed_float_constant (rtx);
178 static int c4x_K_constant (rtx);
179 static int c4x_N_constant (rtx);
180 static int c4x_O_constant (rtx);
181 static int c4x_R_indirect (rtx);
182 static int c4x_S_indirect (rtx);
183 static void c4x_S_address_parse (rtx , int *, int *, int *, int *);
184 static int c4x_valid_operands (enum rtx_code, rtx *, enum machine_mode, int);
185 static int c4x_arn_reg_operand (rtx, enum machine_mode, unsigned int);
186 static int c4x_arn_mem_operand (rtx, enum machine_mode, unsigned int);
187 static void c4x_file_start (void);
188 static void c4x_file_end (void);
189 static void c4x_check_attribute (const char *, tree, tree, tree *);
190 static int c4x_r11_set_p (rtx);
191 static int c4x_rptb_valid_p (rtx, rtx);
192 static void c4x_reorg (void);
193 static int c4x_label_ref_used_p (rtx, rtx);
194 static tree c4x_handle_fntype_attribute (tree *, tree, tree, int, bool *);
195 const struct attribute_spec c4x_attribute_table[];
196 static void c4x_insert_attributes (tree, tree *);
197 static void c4x_asm_named_section (const char *, unsigned int, tree);
198 static int c4x_adjust_cost (rtx, rtx, rtx, int);
199 static void c4x_globalize_label (FILE *, const char *);
200 static bool c4x_rtx_costs (rtx, int, int, int *);
201 static int c4x_address_cost (rtx);
202 static void c4x_init_libfuncs (void);
203 static void c4x_external_libcall (rtx);
204 static rtx c4x_struct_value_rtx (tree, int);
205 static tree c4x_gimplify_va_arg_expr (tree, tree, tree *, tree *);
206 \f
207 /* Initialize the GCC target structure.  */
208 #undef TARGET_ASM_BYTE_OP
209 #define TARGET_ASM_BYTE_OP "\t.word\t"
210 #undef TARGET_ASM_ALIGNED_HI_OP
211 #define TARGET_ASM_ALIGNED_HI_OP NULL
212 #undef TARGET_ASM_ALIGNED_SI_OP
213 #define TARGET_ASM_ALIGNED_SI_OP NULL
214 #undef TARGET_ASM_FILE_START
215 #define TARGET_ASM_FILE_START c4x_file_start
216 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
217 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
218 #undef TARGET_ASM_FILE_END
219 #define TARGET_ASM_FILE_END c4x_file_end
220
221 #undef TARGET_ASM_EXTERNAL_LIBCALL
222 #define TARGET_ASM_EXTERNAL_LIBCALL c4x_external_libcall
223
224 #undef TARGET_ATTRIBUTE_TABLE
225 #define TARGET_ATTRIBUTE_TABLE c4x_attribute_table
226
227 #undef TARGET_INSERT_ATTRIBUTES
228 #define TARGET_INSERT_ATTRIBUTES c4x_insert_attributes
229
230 #undef TARGET_INIT_BUILTINS
231 #define TARGET_INIT_BUILTINS c4x_init_builtins
232
233 #undef TARGET_EXPAND_BUILTIN
234 #define TARGET_EXPAND_BUILTIN c4x_expand_builtin
235
236 #undef TARGET_SCHED_ADJUST_COST
237 #define TARGET_SCHED_ADJUST_COST c4x_adjust_cost
238
239 #undef TARGET_ASM_GLOBALIZE_LABEL
240 #define TARGET_ASM_GLOBALIZE_LABEL c4x_globalize_label
241
242 #undef TARGET_RTX_COSTS
243 #define TARGET_RTX_COSTS c4x_rtx_costs
244 #undef TARGET_ADDRESS_COST
245 #define TARGET_ADDRESS_COST c4x_address_cost
246
247 #undef TARGET_MACHINE_DEPENDENT_REORG
248 #define TARGET_MACHINE_DEPENDENT_REORG c4x_reorg
249
250 #undef TARGET_INIT_LIBFUNCS
251 #define TARGET_INIT_LIBFUNCS c4x_init_libfuncs
252
253 #undef TARGET_STRUCT_VALUE_RTX
254 #define TARGET_STRUCT_VALUE_RTX c4x_struct_value_rtx
255
256 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
257 #define TARGET_GIMPLIFY_VA_ARG_EXPR c4x_gimplify_va_arg_expr
258
259 struct gcc_target targetm = TARGET_INITIALIZER;
260 \f
261 /* Override command line options.
262    Called once after all options have been parsed.
263    Mostly we process the processor
264    type and sometimes adjust other TARGET_ options.  */
265
266 void
267 c4x_override_options (void)
268 {
269   if (c4x_rpts_cycles_string)
270     c4x_rpts_cycles = atoi (c4x_rpts_cycles_string);
271   else
272     c4x_rpts_cycles = 0;
273
274   if (TARGET_C30)
275     c4x_cpu_version = 30;
276   else if (TARGET_C31)
277     c4x_cpu_version = 31;
278   else if (TARGET_C32)
279     c4x_cpu_version = 32;
280   else if (TARGET_C33)
281     c4x_cpu_version = 33;
282   else if (TARGET_C40)
283     c4x_cpu_version = 40;
284   else if (TARGET_C44)
285     c4x_cpu_version = 44;
286   else
287     c4x_cpu_version = 40;              
288
289   /* -mcpu=xx overrides -m40 etc.  */
290   if (c4x_cpu_version_string)
291     {
292       const char *p = c4x_cpu_version_string;
293       
294       /* Also allow -mcpu=c30 etc.  */
295       if (*p == 'c' || *p == 'C')
296         p++;
297       c4x_cpu_version = atoi (p);
298     }
299
300   target_flags &= ~(C30_FLAG | C31_FLAG | C32_FLAG | C33_FLAG |
301                     C40_FLAG | C44_FLAG);
302
303   switch (c4x_cpu_version)
304     {
305     case 30: target_flags |= C30_FLAG; break;
306     case 31: target_flags |= C31_FLAG; break;
307     case 32: target_flags |= C32_FLAG; break;
308     case 33: target_flags |= C33_FLAG; break;
309     case 40: target_flags |= C40_FLAG; break;
310     case 44: target_flags |= C44_FLAG; break;
311     default:
312       warning ("unknown CPU version %d, using 40.\n", c4x_cpu_version);
313       c4x_cpu_version = 40;
314       target_flags |= C40_FLAG;
315     }
316
317   if (TARGET_C30 || TARGET_C31 || TARGET_C32 || TARGET_C33)
318     target_flags |= C3X_FLAG;
319   else
320     target_flags &= ~C3X_FLAG;
321
322   /* Convert foo / 8.0 into foo * 0.125, etc.  */
323   set_fast_math_flags (1);
324
325   /* We should phase out the following at some stage.
326      This provides compatibility with the old -mno-aliases option.  */
327   if (! TARGET_ALIASES && ! flag_argument_noalias)
328     flag_argument_noalias = 1;
329 }
330
331
332 /* This is called before c4x_override_options.  */
333
334 void
335 c4x_optimization_options (int level ATTRIBUTE_UNUSED,
336                           int size ATTRIBUTE_UNUSED)
337 {
338   /* Scheduling before register allocation can screw up global
339      register allocation, especially for functions that use MPY||ADD
340      instructions.  The benefit we gain we get by scheduling before
341      register allocation is probably marginal anyhow.  */
342   flag_schedule_insns = 0;
343 }
344
345
346 /* Write an ASCII string.  */
347
348 #define C4X_ASCII_LIMIT 40
349
350 void
351 c4x_output_ascii (FILE *stream, const char *ptr, int len)
352 {
353   char sbuf[C4X_ASCII_LIMIT + 1];
354   int s, l, special, first = 1, onlys;
355
356   if (len)
357       fprintf (stream, "\t.byte\t");
358
359   for (s = l = 0; len > 0; --len, ++ptr)
360     {
361       onlys = 0;
362
363       /* Escape " and \ with a \".  */
364       special = *ptr == '\"' || *ptr == '\\';
365
366       /* If printable - add to buff.  */
367       if ((! TARGET_TI || ! special) && *ptr >= 0x20 && *ptr < 0x7f)
368         {
369           if (special)
370             sbuf[s++] = '\\';
371           sbuf[s++] = *ptr;
372           if (s < C4X_ASCII_LIMIT - 1)
373             continue;
374           onlys = 1;
375         }
376       if (s)
377         {
378           if (first)
379             first = 0;
380           else
381             {
382               fputc (',', stream);
383               l++;
384             }
385
386           sbuf[s] = 0;
387           fprintf (stream, "\"%s\"", sbuf);
388           l += s + 2;
389           if (TARGET_TI && l >= 80 && len > 1)
390             {
391               fprintf (stream, "\n\t.byte\t");
392               first = 1;
393               l = 0;
394             }
395         
396           s = 0;
397         }
398       if (onlys)
399         continue;
400
401       if (first)
402         first = 0;
403       else
404         {
405           fputc (',', stream);
406           l++;
407         }
408
409       fprintf (stream, "%d", *ptr);
410       l += 3;
411       if (TARGET_TI && l >= 80 && len > 1)
412         {
413           fprintf (stream, "\n\t.byte\t");
414           first = 1;
415           l = 0;
416         }
417     }
418   if (s)
419     {
420       if (! first)
421         fputc (',', stream);
422
423       sbuf[s] = 0;
424       fprintf (stream, "\"%s\"", sbuf);
425       s = 0;
426     }
427   fputc ('\n', stream);
428 }
429
430
431 int
432 c4x_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
433 {
434   switch (mode)
435     {
436 #if Pmode != QImode
437     case Pmode:                 /* Pointer (24/32 bits).  */
438 #endif
439     case QImode:                /* Integer (32 bits).  */
440       return IS_INT_REGNO (regno);
441
442     case QFmode:                /* Float, Double (32 bits).  */
443     case HFmode:                /* Long Double (40 bits).  */
444       return IS_EXT_REGNO (regno);
445
446     case CCmode:                /* Condition Codes.  */
447     case CC_NOOVmode:           /* Condition Codes.  */
448       return IS_ST_REGNO (regno);
449
450     case HImode:                /* Long Long (64 bits).  */
451       /* We need two registers to store long longs.  Note that 
452          it is much easier to constrain the first register
453          to start on an even boundary.  */
454       return IS_INT_REGNO (regno)
455         && IS_INT_REGNO (regno + 1)
456         && (regno & 1) == 0;
457
458     default:
459       return 0;                 /* We don't support these modes.  */
460     }
461
462   return 0;
463 }
464
465 /* Return nonzero if REGNO1 can be renamed to REGNO2.  */
466 int
467 c4x_hard_regno_rename_ok (unsigned int regno1, unsigned int regno2)
468 {
469   /* We cannot copy call saved registers from mode QI into QF or from
470      mode QF into QI.  */
471   if (IS_FLOAT_CALL_SAVED_REGNO (regno1) && IS_INT_CALL_SAVED_REGNO (regno2))
472     return 0;
473   if (IS_INT_CALL_SAVED_REGNO (regno1) && IS_FLOAT_CALL_SAVED_REGNO (regno2))
474     return 0;
475   /* We cannot copy from an extended (40 bit) register to a standard
476      (32 bit) register because we only set the condition codes for
477      extended registers.  */
478   if (IS_EXT_REGNO (regno1) && ! IS_EXT_REGNO (regno2))
479     return 0;
480   if (IS_EXT_REGNO (regno2) && ! IS_EXT_REGNO (regno1))
481     return 0;
482   return 1;
483 }
484
485 /* The TI C3x C compiler register argument runtime model uses 6 registers,
486    AR2, R2, R3, RC, RS, RE.
487
488    The first two floating point arguments (float, double, long double)
489    that are found scanning from left to right are assigned to R2 and R3.
490
491    The remaining integer (char, short, int, long) or pointer arguments
492    are assigned to the remaining registers in the order AR2, R2, R3,
493    RC, RS, RE when scanning left to right, except for the last named
494    argument prior to an ellipsis denoting variable number of
495    arguments.  We don't have to worry about the latter condition since
496    function.c treats the last named argument as anonymous (unnamed).
497
498    All arguments that cannot be passed in registers are pushed onto
499    the stack in reverse order (right to left).  GCC handles that for us.
500
501    c4x_init_cumulative_args() is called at the start, so we can parse
502    the args to see how many floating point arguments and how many
503    integer (or pointer) arguments there are.  c4x_function_arg() is
504    then called (sometimes repeatedly) for each argument (parsed left
505    to right) to obtain the register to pass the argument in, or zero
506    if the argument is to be passed on the stack.  Once the compiler is
507    happy, c4x_function_arg_advance() is called.
508
509    Don't use R0 to pass arguments in, we use 0 to indicate a stack
510    argument.  */
511
512 static const int c4x_int_reglist[3][6] =
513 {
514   {AR2_REGNO, R2_REGNO, R3_REGNO, RC_REGNO, RS_REGNO, RE_REGNO},
515   {AR2_REGNO, R3_REGNO, RC_REGNO, RS_REGNO, RE_REGNO, 0},
516   {AR2_REGNO, RC_REGNO, RS_REGNO, RE_REGNO, 0, 0}
517 };
518
519 static const int c4x_fp_reglist[2] = {R2_REGNO, R3_REGNO};
520
521
522 /* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a
523    function whose data type is FNTYPE.
524    For a library call, FNTYPE is  0.  */
525
526 void
527 c4x_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname)
528 {
529   tree param, next_param;
530
531   cum->floats = cum->ints = 0;
532   cum->init = 0;
533   cum->var = 0;
534   cum->args = 0;
535
536   if (TARGET_DEBUG)
537     {
538       fprintf (stderr, "\nc4x_init_cumulative_args (");
539       if (fntype)
540         {
541           tree ret_type = TREE_TYPE (fntype);
542
543           fprintf (stderr, "fntype code = %s, ret code = %s",
544                    tree_code_name[(int) TREE_CODE (fntype)],
545                    tree_code_name[(int) TREE_CODE (ret_type)]);
546         }
547       else
548         fprintf (stderr, "no fntype");
549
550       if (libname)
551         fprintf (stderr, ", libname = %s", XSTR (libname, 0));
552     }
553
554   cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
555
556   for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
557        param; param = next_param)
558     {
559       tree type;
560
561       next_param = TREE_CHAIN (param);
562
563       type = TREE_VALUE (param);
564       if (type && type != void_type_node)
565         {
566           enum machine_mode mode;
567
568           /* If the last arg doesn't have void type then we have
569              variable arguments.  */
570           if (! next_param)
571             cum->var = 1;
572
573           if ((mode = TYPE_MODE (type)))
574             {
575               if (! targetm.calls.must_pass_in_stack (mode, type))
576                 {
577                   /* Look for float, double, or long double argument.  */
578                   if (mode == QFmode || mode == HFmode)
579                     cum->floats++;
580                   /* Look for integer, enumeral, boolean, char, or pointer
581                      argument.  */
582                   else if (mode == QImode || mode == Pmode)
583                     cum->ints++;
584                 }
585             }
586           cum->args++;
587         }
588     }
589
590   if (TARGET_DEBUG)
591     fprintf (stderr, "%s%s, args = %d)\n",
592              cum->prototype ? ", prototype" : "",
593              cum->var ? ", variable args" : "",
594              cum->args);
595 }
596
597
598 /* Update the data in CUM to advance over an argument
599    of mode MODE and data type TYPE.
600    (TYPE is null for libcalls where that information may not be available.)  */
601
602 void
603 c4x_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
604                           tree type, int named)
605 {
606   if (TARGET_DEBUG)
607     fprintf (stderr, "c4x_function_adv(mode=%s, named=%d)\n\n",
608              GET_MODE_NAME (mode), named);
609   if (! TARGET_MEMPARM 
610       && named
611       && type
612       && ! targetm.calls.must_pass_in_stack (mode, type))
613     {
614       /* Look for float, double, or long double argument.  */
615       if (mode == QFmode || mode == HFmode)
616         cum->floats++;
617       /* Look for integer, enumeral, boolean, char, or pointer argument.  */
618       else if (mode == QImode || mode == Pmode)
619         cum->ints++;
620     }
621   else if (! TARGET_MEMPARM && ! type)
622     {
623       /* Handle libcall arguments.  */
624       if (mode == QFmode || mode == HFmode)
625         cum->floats++;
626       else if (mode == QImode || mode == Pmode)
627         cum->ints++;
628     }
629   return;
630 }
631
632
633 /* Define where to put the arguments to a function.  Value is zero to
634    push the argument on the stack, or a hard register in which to
635    store the argument.
636
637    MODE is the argument's machine mode.
638    TYPE is the data type of the argument (as a tree).
639    This is null for libcalls where that information may
640    not be available.
641    CUM is a variable of type CUMULATIVE_ARGS which gives info about
642    the preceding args and about the function being called.
643    NAMED is nonzero if this argument is a named parameter
644    (otherwise it is an extra parameter matching an ellipsis).  */
645
646 struct rtx_def *
647 c4x_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
648                   tree type, int named)
649 {
650   int reg = 0;                  /* Default to passing argument on stack.  */
651
652   if (! cum->init)
653     {
654       /* We can handle at most 2 floats in R2, R3.  */
655       cum->maxfloats = (cum->floats > 2) ? 2 : cum->floats;
656
657       /* We can handle at most 6 integers minus number of floats passed 
658          in registers.  */
659       cum->maxints = (cum->ints > 6 - cum->maxfloats) ? 
660         6 - cum->maxfloats : cum->ints;
661
662       /* If there is no prototype, assume all the arguments are integers.  */
663       if (! cum->prototype)
664         cum->maxints = 6;
665
666       cum->ints = cum->floats = 0;
667       cum->init = 1;
668     }
669
670   /* This marks the last argument.  We don't need to pass this through
671      to the call insn.  */
672   if (type == void_type_node)
673     return 0;
674
675   if (! TARGET_MEMPARM 
676       && named 
677       && type
678       && ! targetm.calls.must_pass_in_stack (mode, type))
679     {
680       /* Look for float, double, or long double argument.  */
681       if (mode == QFmode || mode == HFmode)
682         {
683           if (cum->floats < cum->maxfloats)
684             reg = c4x_fp_reglist[cum->floats];
685         }
686       /* Look for integer, enumeral, boolean, char, or pointer argument.  */
687       else if (mode == QImode || mode == Pmode)
688         {
689           if (cum->ints < cum->maxints)
690             reg = c4x_int_reglist[cum->maxfloats][cum->ints];
691         }
692     }
693   else if (! TARGET_MEMPARM && ! type)
694     {
695       /* We could use a different argument calling model for libcalls,
696          since we're only calling functions in libgcc.  Thus we could
697          pass arguments for long longs in registers rather than on the
698          stack.  In the meantime, use the odd TI format.  We make the
699          assumption that we won't have more than two floating point
700          args, six integer args, and that all the arguments are of the
701          same mode.  */
702       if (mode == QFmode || mode == HFmode)
703         reg = c4x_fp_reglist[cum->floats];
704       else if (mode == QImode || mode == Pmode)
705         reg = c4x_int_reglist[0][cum->ints];
706     }
707
708   if (TARGET_DEBUG)
709     {
710       fprintf (stderr, "c4x_function_arg(mode=%s, named=%d",
711                GET_MODE_NAME (mode), named);
712       if (reg)
713         fprintf (stderr, ", reg=%s", reg_names[reg]);
714       else
715         fprintf (stderr, ", stack");
716       fprintf (stderr, ")\n");
717     }
718   if (reg)
719     return gen_rtx_REG (mode, reg);
720   else
721     return NULL_RTX;
722 }
723
724 /* C[34]x arguments grow in weird ways (downwards) that the standard
725    varargs stuff can't handle..  */
726
727 static tree
728 c4x_gimplify_va_arg_expr (tree valist, tree type,
729                           tree *pre_p ATTRIBUTE_UNUSED,
730                           tree *post_p ATTRIBUTE_UNUSED)
731 {
732   tree t;
733   bool indirect;
734
735   indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
736   if (indirect)
737     type = build_pointer_type (type);
738
739   t = build (PREDECREMENT_EXPR, TREE_TYPE (valist), valist,
740              build_int_cst (NULL_TREE, int_size_in_bytes (type)));
741   t = fold_convert (build_pointer_type (type), t);
742   t = build_fold_indirect_ref (t);
743
744   if (indirect)
745     t = build_fold_indirect_ref (t);
746
747   return t;
748 }
749
750
751 static int
752 c4x_isr_reg_used_p (unsigned int regno)
753 {
754   /* Don't save/restore FP or ST, we handle them separately.  */
755   if (regno == FRAME_POINTER_REGNUM
756       || IS_ST_REGNO (regno))
757     return 0;
758
759   /* We could be a little smarter abut saving/restoring DP.
760      We'll only save if for the big memory model or if
761      we're paranoid. ;-)  */
762   if (IS_DP_REGNO (regno))
763     return ! TARGET_SMALL || TARGET_PARANOID;
764
765   /* Only save/restore regs in leaf function that are used.  */
766   if (c4x_leaf_function)
767     return regs_ever_live[regno] && fixed_regs[regno] == 0;
768
769   /* Only save/restore regs that are used by the ISR and regs
770      that are likely to be used by functions the ISR calls
771      if they are not fixed.  */
772   return IS_EXT_REGNO (regno)
773     || ((regs_ever_live[regno] || call_used_regs[regno]) 
774         && fixed_regs[regno] == 0);
775 }
776
777
778 static int
779 c4x_leaf_function_p (void)
780 {
781   /* A leaf function makes no calls, so we only need
782      to save/restore the registers we actually use.
783      For the global variable leaf_function to be set, we need
784      to define LEAF_REGISTERS and all that it entails.
785      Let's check ourselves....  */
786
787   if (lookup_attribute ("leaf_pretend",
788                         TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
789     return 1;
790
791   /* Use the leaf_pretend attribute at your own risk.  This is a hack
792      to speed up ISRs that call a function infrequently where the
793      overhead of saving and restoring the additional registers is not
794      warranted.  You must save and restore the additional registers
795      required by the called function.  Caveat emptor.  Here's enough
796      rope...  */
797
798   if (leaf_function_p ())
799     return 1;
800
801   return 0;
802 }
803
804
805 static int
806 c4x_naked_function_p (void)
807 {
808   tree type;
809
810   type = TREE_TYPE (current_function_decl);
811   return lookup_attribute ("naked", TYPE_ATTRIBUTES (type)) != NULL;
812 }
813
814
815 int
816 c4x_interrupt_function_p (void)
817 {
818   const char *cfun_name;
819   if (lookup_attribute ("interrupt",
820                         TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
821     return 1;
822
823   /* Look for TI style c_intnn.  */
824   cfun_name = current_function_name ();
825   return cfun_name[0] == 'c'
826     && cfun_name[1] == '_'
827     && cfun_name[2] == 'i'
828     && cfun_name[3] == 'n' 
829     && cfun_name[4] == 't'
830     && ISDIGIT (cfun_name[5])
831     && ISDIGIT (cfun_name[6]);
832 }
833
834 void
835 c4x_expand_prologue (void)
836 {
837   unsigned int regno;
838   int size = get_frame_size ();
839   rtx insn;
840
841   /* In functions where ar3 is not used but frame pointers are still
842      specified, frame pointers are not adjusted (if >= -O2) and this
843      is used so it won't needlessly push the frame pointer.  */
844   int dont_push_ar3;
845
846   /* For __naked__ function don't build a prologue.  */
847   if (c4x_naked_function_p ())
848     {
849       return;
850     }
851   
852   /* For __interrupt__ function build specific prologue.  */
853   if (c4x_interrupt_function_p ())
854     {
855       c4x_leaf_function = c4x_leaf_function_p ();
856       
857       insn = emit_insn (gen_push_st ());
858       RTX_FRAME_RELATED_P (insn) = 1;
859       if (size)
860         {
861           insn = emit_insn (gen_pushqi ( gen_rtx_REG (QImode, AR3_REGNO)));
862           RTX_FRAME_RELATED_P (insn) = 1;
863           insn = emit_insn (gen_movqi (gen_rtx_REG (QImode, AR3_REGNO),
864                                        gen_rtx_REG (QImode, SP_REGNO)));
865           RTX_FRAME_RELATED_P (insn) = 1;
866           /* We require that an ISR uses fewer than 32768 words of
867              local variables, otherwise we have to go to lots of
868              effort to save a register, load it with the desired size,
869              adjust the stack pointer, and then restore the modified
870              register.  Frankly, I think it is a poor ISR that
871              requires more than 32767 words of local temporary
872              storage!  */
873           if (size > 32767)
874             error ("ISR %s requires %d words of local vars, max is 32767",
875                    current_function_name (), size);
876
877           insn = emit_insn (gen_addqi3 (gen_rtx_REG (QImode, SP_REGNO),
878                                         gen_rtx_REG (QImode, SP_REGNO),
879                                         GEN_INT (size)));
880           RTX_FRAME_RELATED_P (insn) = 1;
881         }
882       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
883         {
884           if (c4x_isr_reg_used_p (regno))
885             {
886               if (regno == DP_REGNO)
887                 {
888                   insn = emit_insn (gen_push_dp ());
889                   RTX_FRAME_RELATED_P (insn) = 1;
890                 }
891               else
892                 {
893                   insn = emit_insn (gen_pushqi (gen_rtx_REG (QImode, regno)));
894                   RTX_FRAME_RELATED_P (insn) = 1;
895                   if (IS_EXT_REGNO (regno))
896                     {
897                       insn = emit_insn (gen_pushqf
898                                         (gen_rtx_REG (QFmode, regno)));
899                       RTX_FRAME_RELATED_P (insn) = 1;
900                     }
901                 }
902             }
903         }
904       /* We need to clear the repeat mode flag if the ISR is
905          going to use a RPTB instruction or uses the RC, RS, or RE
906          registers.  */
907       if (regs_ever_live[RC_REGNO] 
908           || regs_ever_live[RS_REGNO] 
909           || regs_ever_live[RE_REGNO])
910         {
911           insn = emit_insn (gen_andn_st (GEN_INT(~0x100)));
912           RTX_FRAME_RELATED_P (insn) = 1;
913         }
914
915       /* Reload DP reg if we are paranoid about some turkey
916          violating small memory model rules.  */
917       if (TARGET_SMALL && TARGET_PARANOID)
918         {
919           insn = emit_insn (gen_set_ldp_prologue
920                             (gen_rtx_REG (QImode, DP_REGNO),
921                              gen_rtx_SYMBOL_REF (QImode, "data_sec")));
922           RTX_FRAME_RELATED_P (insn) = 1;
923         }
924     }
925   else
926     {
927       if (frame_pointer_needed)
928         {
929           if ((size != 0)
930               || (current_function_args_size != 0)
931               || (optimize < 2))
932             {
933               insn = emit_insn (gen_pushqi ( gen_rtx_REG (QImode, AR3_REGNO)));
934               RTX_FRAME_RELATED_P (insn) = 1;
935               insn = emit_insn (gen_movqi (gen_rtx_REG (QImode, AR3_REGNO),
936                                            gen_rtx_REG (QImode, SP_REGNO)));
937               RTX_FRAME_RELATED_P (insn) = 1;
938               dont_push_ar3 = 1;
939             }
940           else
941             {
942               /* Since ar3 is not used, we don't need to push it.  */
943               dont_push_ar3 = 1;
944             }
945         }
946       else
947         {
948           /* If we use ar3, we need to push it.  */
949           dont_push_ar3 = 0;
950           if ((size != 0) || (current_function_args_size != 0))
951             {
952               /* If we are omitting the frame pointer, we still have
953                  to make space for it so the offsets are correct
954                  unless we don't use anything on the stack at all.  */
955               size += 1;
956             }
957         }
958       
959       if (size > 32767)
960         {
961           /* Local vars are too big, it will take multiple operations
962              to increment SP.  */
963           if (TARGET_C3X)
964             {
965               insn = emit_insn (gen_movqi (gen_rtx_REG (QImode, R1_REGNO),
966                                            GEN_INT(size >> 16)));
967               RTX_FRAME_RELATED_P (insn) = 1;
968               insn = emit_insn (gen_lshrqi3 (gen_rtx_REG (QImode, R1_REGNO),
969                                              gen_rtx_REG (QImode, R1_REGNO),
970                                              GEN_INT(-16)));
971               RTX_FRAME_RELATED_P (insn) = 1;
972             }
973           else
974             {
975               insn = emit_insn (gen_movqi (gen_rtx_REG (QImode, R1_REGNO),
976                                            GEN_INT(size & ~0xffff)));
977               RTX_FRAME_RELATED_P (insn) = 1;
978             }
979           insn = emit_insn (gen_iorqi3 (gen_rtx_REG (QImode, R1_REGNO),
980                                         gen_rtx_REG (QImode, R1_REGNO),
981                                         GEN_INT(size & 0xffff)));
982           RTX_FRAME_RELATED_P (insn) = 1;
983           insn = emit_insn (gen_addqi3 (gen_rtx_REG (QImode, SP_REGNO),
984                                         gen_rtx_REG (QImode, SP_REGNO),
985                                         gen_rtx_REG (QImode, R1_REGNO)));
986           RTX_FRAME_RELATED_P (insn) = 1;
987         }
988       else if (size != 0)
989         {
990           /* Local vars take up less than 32767 words, so we can directly
991              add the number.  */
992           insn = emit_insn (gen_addqi3 (gen_rtx_REG (QImode, SP_REGNO),
993                                         gen_rtx_REG (QImode, SP_REGNO),
994                                         GEN_INT (size)));
995           RTX_FRAME_RELATED_P (insn) = 1;
996         }
997       
998       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
999         {
1000           if (regs_ever_live[regno] && ! call_used_regs[regno])
1001             {
1002               if (IS_FLOAT_CALL_SAVED_REGNO (regno))
1003                 {
1004                   if (TARGET_PRESERVE_FLOAT)
1005                     {
1006                       insn = emit_insn (gen_pushqi
1007                                         (gen_rtx_REG (QImode, regno)));
1008                       RTX_FRAME_RELATED_P (insn) = 1;
1009                     }
1010                   insn = emit_insn (gen_pushqf (gen_rtx_REG (QFmode, regno)));
1011                   RTX_FRAME_RELATED_P (insn) = 1;
1012                 }
1013               else if ((! dont_push_ar3) || (regno != AR3_REGNO))
1014                 {
1015                   insn = emit_insn (gen_pushqi ( gen_rtx_REG (QImode, regno)));
1016                   RTX_FRAME_RELATED_P (insn) = 1;
1017                 }
1018             }
1019         }
1020     }
1021 }
1022
1023
1024 void
1025 c4x_expand_epilogue(void)
1026 {
1027   int regno;
1028   int jump = 0;
1029   int dont_pop_ar3;
1030   rtx insn;
1031   int size = get_frame_size ();
1032   
1033   /* For __naked__ function build no epilogue.  */
1034   if (c4x_naked_function_p ())
1035     {
1036       insn = emit_jump_insn (gen_return_from_epilogue ());
1037       RTX_FRAME_RELATED_P (insn) = 1;
1038       return;
1039     }
1040
1041   /* For __interrupt__ function build specific epilogue.  */
1042   if (c4x_interrupt_function_p ())
1043     {
1044       for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; --regno)
1045         {
1046           if (! c4x_isr_reg_used_p (regno))
1047             continue;
1048           if (regno == DP_REGNO)
1049             {
1050               insn = emit_insn (gen_pop_dp ());
1051               RTX_FRAME_RELATED_P (insn) = 1;
1052             }
1053           else
1054             {
1055               /* We have to use unspec because the compiler will delete insns
1056                  that are not call-saved.  */
1057               if (IS_EXT_REGNO (regno))
1058                 {
1059                   insn = emit_insn (gen_popqf_unspec
1060                                     (gen_rtx_REG (QFmode, regno)));
1061                   RTX_FRAME_RELATED_P (insn) = 1;
1062                 }
1063               insn = emit_insn (gen_popqi_unspec (gen_rtx_REG (QImode, regno)));
1064               RTX_FRAME_RELATED_P (insn) = 1;
1065             }
1066         }
1067       if (size)
1068         {
1069           insn = emit_insn (gen_subqi3 (gen_rtx_REG (QImode, SP_REGNO),
1070                                         gen_rtx_REG (QImode, SP_REGNO),
1071                                         GEN_INT(size)));
1072           RTX_FRAME_RELATED_P (insn) = 1;
1073           insn = emit_insn (gen_popqi
1074                             (gen_rtx_REG (QImode, AR3_REGNO)));
1075           RTX_FRAME_RELATED_P (insn) = 1;
1076         }
1077       insn = emit_insn (gen_pop_st ());
1078       RTX_FRAME_RELATED_P (insn) = 1;
1079       insn = emit_jump_insn (gen_return_from_interrupt_epilogue ());
1080       RTX_FRAME_RELATED_P (insn) = 1;
1081     }
1082   else
1083     {
1084       if (frame_pointer_needed)
1085         {
1086           if ((size != 0) 
1087               || (current_function_args_size != 0) 
1088               || (optimize < 2))
1089             {
1090               insn = emit_insn
1091                 (gen_movqi (gen_rtx_REG (QImode, R2_REGNO),
1092                             gen_rtx_MEM (QImode,
1093                                          gen_rtx_PLUS 
1094                                          (QImode, gen_rtx_REG (QImode,
1095                                                                AR3_REGNO),
1096                                           constm1_rtx))));
1097               RTX_FRAME_RELATED_P (insn) = 1;
1098               
1099               /* We already have the return value and the fp,
1100                  so we need to add those to the stack.  */
1101               size += 2;
1102               jump = 1;
1103               dont_pop_ar3 = 1;
1104             }
1105           else
1106             {
1107               /* Since ar3 is not used for anything, we don't need to
1108                  pop it.  */
1109               dont_pop_ar3 = 1;
1110             }
1111         }
1112       else
1113         {
1114           dont_pop_ar3 = 0;     /* If we use ar3, we need to pop it.  */
1115           if (size || current_function_args_size)
1116             {
1117               /* If we are omitting the frame pointer, we still have
1118                  to make space for it so the offsets are correct
1119                  unless we don't use anything on the stack at all.  */
1120               size += 1;
1121             }
1122         }
1123       
1124       /* Now restore the saved registers, putting in the delayed branch
1125          where required.  */
1126       for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
1127         {
1128           if (regs_ever_live[regno] && ! call_used_regs[regno])
1129             {
1130               if (regno == AR3_REGNO && dont_pop_ar3)
1131                 continue;
1132               
1133               if (IS_FLOAT_CALL_SAVED_REGNO (regno))
1134                 {
1135                   insn = emit_insn (gen_popqf_unspec
1136                                     (gen_rtx_REG (QFmode, regno)));
1137                   RTX_FRAME_RELATED_P (insn) = 1;
1138                   if (TARGET_PRESERVE_FLOAT)
1139                     {
1140                       insn = emit_insn (gen_popqi_unspec
1141                                         (gen_rtx_REG (QImode, regno)));
1142                       RTX_FRAME_RELATED_P (insn) = 1;
1143                     }
1144                 }
1145               else
1146                 {
1147                   insn = emit_insn (gen_popqi (gen_rtx_REG (QImode, regno)));
1148                   RTX_FRAME_RELATED_P (insn) = 1;
1149                 }
1150             }
1151         }
1152       
1153       if (frame_pointer_needed)
1154         {
1155           if ((size != 0)
1156               || (current_function_args_size != 0)
1157               || (optimize < 2))
1158             {
1159               /* Restore the old FP.  */
1160               insn = emit_insn 
1161                 (gen_movqi 
1162                  (gen_rtx_REG (QImode, AR3_REGNO),
1163                   gen_rtx_MEM (QImode, gen_rtx_REG (QImode, AR3_REGNO))));
1164               
1165               RTX_FRAME_RELATED_P (insn) = 1;
1166             }
1167         }
1168       
1169       if (size > 32767)
1170         {
1171           /* Local vars are too big, it will take multiple operations
1172              to decrement SP.  */
1173           if (TARGET_C3X)
1174             {
1175               insn = emit_insn (gen_movqi (gen_rtx_REG (QImode, R3_REGNO),
1176                                            GEN_INT(size >> 16)));
1177               RTX_FRAME_RELATED_P (insn) = 1;
1178               insn = emit_insn (gen_lshrqi3 (gen_rtx_REG (QImode, R3_REGNO),
1179                                              gen_rtx_REG (QImode, R3_REGNO),
1180                                              GEN_INT(-16)));
1181               RTX_FRAME_RELATED_P (insn) = 1;
1182             }
1183           else
1184             {
1185               insn = emit_insn (gen_movqi (gen_rtx_REG (QImode, R3_REGNO),
1186                                            GEN_INT(size & ~0xffff)));
1187               RTX_FRAME_RELATED_P (insn) = 1;
1188             }
1189           insn = emit_insn (gen_iorqi3 (gen_rtx_REG (QImode, R3_REGNO),
1190                                         gen_rtx_REG (QImode, R3_REGNO),
1191                                         GEN_INT(size & 0xffff)));
1192           RTX_FRAME_RELATED_P (insn) = 1;
1193           insn = emit_insn (gen_subqi3 (gen_rtx_REG (QImode, SP_REGNO),
1194                                         gen_rtx_REG (QImode, SP_REGNO),
1195                                         gen_rtx_REG (QImode, R3_REGNO)));
1196           RTX_FRAME_RELATED_P (insn) = 1;
1197         }
1198       else if (size != 0)
1199         {
1200           /* Local vars take up less than 32768 words, so we can directly
1201              subtract the number.  */
1202           insn = emit_insn (gen_subqi3 (gen_rtx_REG (QImode, SP_REGNO),
1203                                         gen_rtx_REG (QImode, SP_REGNO),
1204                                         GEN_INT(size)));
1205           RTX_FRAME_RELATED_P (insn) = 1;
1206         }
1207       
1208       if (jump)
1209         {
1210           insn = emit_jump_insn (gen_return_indirect_internal
1211                                  (gen_rtx_REG (QImode, R2_REGNO)));
1212           RTX_FRAME_RELATED_P (insn) = 1;
1213         }
1214       else
1215         {
1216           insn = emit_jump_insn (gen_return_from_epilogue ());
1217           RTX_FRAME_RELATED_P (insn) = 1;
1218         }
1219     }
1220 }
1221
1222
1223 int
1224 c4x_null_epilogue_p (void)
1225 {
1226   int regno;
1227
1228   if (reload_completed
1229       && ! c4x_naked_function_p ()
1230       && ! c4x_interrupt_function_p ()
1231       && ! current_function_calls_alloca
1232       && ! current_function_args_size
1233       && ! (optimize < 2)
1234       && ! get_frame_size ())
1235     {
1236       for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
1237         if (regs_ever_live[regno] && ! call_used_regs[regno]
1238             && (regno != AR3_REGNO))
1239           return 1;
1240       return 0;
1241     }
1242   return 1;
1243 }
1244
1245
1246 int
1247 c4x_emit_move_sequence (rtx *operands, enum machine_mode mode)
1248 {
1249   rtx op0 = operands[0];
1250   rtx op1 = operands[1];
1251
1252   if (! reload_in_progress
1253       && ! REG_P (op0) 
1254       && ! REG_P (op1)
1255       && ! (stik_const_operand (op1, mode) && ! push_operand (op0, mode)))
1256     op1 = force_reg (mode, op1);
1257
1258   if (GET_CODE (op1) == LO_SUM
1259       && GET_MODE (op1) == Pmode
1260       && dp_reg_operand (XEXP (op1, 0), mode))
1261     {
1262       /* expand_increment will sometimes create a LO_SUM immediate
1263          address.  Undo this silliness.  */
1264       op1 = XEXP (op1, 1);
1265     }
1266   
1267   if (symbolic_address_operand (op1, mode))
1268     {
1269       if (TARGET_LOAD_ADDRESS)
1270         {
1271           /* Alias analysis seems to do a better job if we force
1272              constant addresses to memory after reload.  */
1273           emit_insn (gen_load_immed_address (op0, op1));
1274           return 1;
1275         }
1276       else
1277         {
1278           /* Stick symbol or label address into the constant pool.  */
1279           op1 = force_const_mem (Pmode, op1);
1280         }
1281     }
1282   else if (mode == HFmode && CONSTANT_P (op1) && ! LEGITIMATE_CONSTANT_P (op1))
1283     {
1284       /* We could be a lot smarter about loading some of these
1285          constants...  */
1286       op1 = force_const_mem (mode, op1);
1287     }
1288
1289   /* Convert (MEM (SYMREF)) to a (MEM (LO_SUM (REG) (SYMREF)))
1290      and emit associated (HIGH (SYMREF)) if large memory model.  
1291      c4x_legitimize_address could be used to do this,
1292      perhaps by calling validize_address.  */
1293   if (TARGET_EXPOSE_LDP
1294       && ! (reload_in_progress || reload_completed)
1295       && GET_CODE (op1) == MEM
1296       && symbolic_address_operand (XEXP (op1, 0), Pmode))
1297     {
1298       rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
1299       if (! TARGET_SMALL)
1300         emit_insn (gen_set_ldp (dp_reg, XEXP (op1, 0)));
1301       op1 = change_address (op1, mode,
1302                             gen_rtx_LO_SUM (Pmode, dp_reg, XEXP (op1, 0)));
1303     }
1304
1305   if (TARGET_EXPOSE_LDP
1306       && ! (reload_in_progress || reload_completed)
1307       && GET_CODE (op0) == MEM 
1308       && symbolic_address_operand (XEXP (op0, 0), Pmode))
1309     {
1310       rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
1311       if (! TARGET_SMALL)
1312         emit_insn (gen_set_ldp (dp_reg, XEXP (op0, 0)));
1313       op0 = change_address (op0, mode,
1314                             gen_rtx_LO_SUM (Pmode, dp_reg, XEXP (op0, 0)));
1315     }
1316
1317   if (GET_CODE (op0) == SUBREG
1318       && mixed_subreg_operand (op0, mode))
1319     {
1320       /* We should only generate these mixed mode patterns
1321          during RTL generation.  If we need do it later on
1322          then we'll have to emit patterns that won't clobber CC.  */
1323       if (reload_in_progress || reload_completed)
1324         abort ();
1325       if (GET_MODE (SUBREG_REG (op0)) == QImode)
1326         op0 = SUBREG_REG (op0);
1327       else if (GET_MODE (SUBREG_REG (op0)) == HImode)
1328         {
1329           op0 = copy_rtx (op0);
1330           PUT_MODE (op0, QImode);
1331         }
1332       else
1333         abort ();
1334
1335       if (mode == QFmode)
1336         emit_insn (gen_storeqf_int_clobber (op0, op1));
1337       else
1338         abort ();
1339       return 1;
1340     }
1341
1342   if (GET_CODE (op1) == SUBREG
1343       && mixed_subreg_operand (op1, mode))
1344     {
1345       /* We should only generate these mixed mode patterns
1346          during RTL generation.  If we need do it later on
1347          then we'll have to emit patterns that won't clobber CC.  */
1348       if (reload_in_progress || reload_completed)
1349         abort ();
1350       if (GET_MODE (SUBREG_REG (op1)) == QImode)
1351         op1 = SUBREG_REG (op1);
1352       else if (GET_MODE (SUBREG_REG (op1)) == HImode)
1353         {
1354           op1 = copy_rtx (op1);
1355           PUT_MODE (op1, QImode);
1356         }
1357       else
1358         abort ();
1359
1360       if (mode == QFmode)
1361         emit_insn (gen_loadqf_int_clobber (op0, op1));
1362       else
1363         abort ();
1364       return 1;
1365     }
1366
1367   if (mode == QImode
1368       && reg_operand (op0, mode)
1369       && const_int_operand (op1, mode)
1370       && ! IS_INT16_CONST (INTVAL (op1))
1371       && ! IS_HIGH_CONST (INTVAL (op1)))
1372     {
1373       emit_insn (gen_loadqi_big_constant (op0, op1));
1374       return 1;
1375     }
1376
1377   if (mode == HImode
1378       && reg_operand (op0, mode)
1379       && const_int_operand (op1, mode))
1380     {
1381       emit_insn (gen_loadhi_big_constant (op0, op1));
1382       return 1;
1383     }
1384
1385   /* Adjust operands in case we have modified them.  */
1386   operands[0] = op0;
1387   operands[1] = op1;
1388
1389   /* Emit normal pattern.  */
1390   return 0;
1391 }
1392
1393
1394 void
1395 c4x_emit_libcall (rtx libcall, enum rtx_code code,
1396                   enum machine_mode dmode, enum machine_mode smode,
1397                   int noperands, rtx *operands)
1398 {
1399   rtx ret;
1400   rtx insns;
1401   rtx equiv;
1402
1403   start_sequence ();
1404   switch (noperands)
1405     {
1406     case 2:
1407       ret = emit_library_call_value (libcall, NULL_RTX, 1, dmode, 1,
1408                                      operands[1], smode);
1409       equiv = gen_rtx_fmt_e (code, dmode, operands[1]);
1410       break;
1411
1412     case 3:
1413       ret = emit_library_call_value (libcall, NULL_RTX, 1, dmode, 2,
1414                                      operands[1], smode, operands[2], smode);
1415       equiv = gen_rtx_fmt_ee (code, dmode, operands[1], operands[2]);
1416       break;
1417
1418     default:
1419       abort ();
1420     }
1421
1422   insns = get_insns ();
1423   end_sequence ();
1424   emit_libcall_block (insns, operands[0], ret, equiv);
1425 }
1426
1427
1428 void
1429 c4x_emit_libcall3 (rtx libcall, enum rtx_code code,
1430                    enum machine_mode mode, rtx *operands)
1431 {
1432   c4x_emit_libcall (libcall, code, mode, mode, 3, operands);
1433 }
1434
1435
1436 void
1437 c4x_emit_libcall_mulhi (rtx libcall, enum rtx_code code,
1438                         enum machine_mode mode, rtx *operands)
1439 {
1440   rtx ret;
1441   rtx insns;
1442   rtx equiv;
1443
1444   start_sequence ();
1445   ret = emit_library_call_value (libcall, NULL_RTX, 1, mode, 2,
1446                                  operands[1], mode, operands[2], mode);
1447   equiv = gen_rtx_TRUNCATE (mode,
1448                    gen_rtx_LSHIFTRT (HImode,
1449                             gen_rtx_MULT (HImode,
1450                                      gen_rtx_fmt_e (code, HImode, operands[1]),
1451                                      gen_rtx_fmt_e (code, HImode, operands[2])),
1452                                      GEN_INT (32)));
1453   insns = get_insns ();
1454   end_sequence ();
1455   emit_libcall_block (insns, operands[0], ret, equiv);
1456 }
1457
1458
1459 int
1460 c4x_legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
1461 {
1462   rtx base = NULL_RTX;          /* Base register (AR0-AR7).  */
1463   rtx indx = NULL_RTX;          /* Index register (IR0,IR1).  */
1464   rtx disp = NULL_RTX;          /* Displacement.  */
1465   enum rtx_code code;
1466
1467   code = GET_CODE (addr);
1468   switch (code)
1469     {
1470       /* Register indirect with auto increment/decrement.  We don't
1471          allow SP here---push_operand should recognize an operand
1472          being pushed on the stack.  */
1473
1474     case PRE_DEC:
1475     case PRE_INC:
1476     case POST_DEC:
1477       if (mode != QImode && mode != QFmode)
1478         return 0;
1479
1480     case POST_INC:
1481       base = XEXP (addr, 0);
1482       if (! REG_P (base))
1483         return 0;
1484       break;
1485
1486     case PRE_MODIFY:
1487     case POST_MODIFY:
1488       {
1489         rtx op0 = XEXP (addr, 0);
1490         rtx op1 = XEXP (addr, 1);
1491
1492         if (mode != QImode && mode != QFmode)
1493           return 0;
1494
1495         if (! REG_P (op0) 
1496             || (GET_CODE (op1) != PLUS && GET_CODE (op1) != MINUS))
1497           return 0;
1498         base = XEXP (op1, 0);
1499         if (! REG_P (base))
1500             return 0;
1501         if (REGNO (base) != REGNO (op0))
1502           return 0;
1503         if (REG_P (XEXP (op1, 1)))
1504           indx = XEXP (op1, 1);
1505         else
1506           disp = XEXP (op1, 1);
1507       }
1508       break;
1509         
1510       /* Register indirect.  */
1511     case REG:
1512       base = addr;
1513       break;
1514
1515       /* Register indirect with displacement or index.  */
1516     case PLUS:
1517       {
1518         rtx op0 = XEXP (addr, 0);
1519         rtx op1 = XEXP (addr, 1);
1520         enum rtx_code code0 = GET_CODE (op0);
1521
1522         switch (code0)
1523           {
1524           case REG:
1525             if (REG_P (op1))
1526               {
1527                 base = op0;     /* Base + index.  */
1528                 indx = op1;
1529                 if (IS_INDEX_REG (base) || IS_ADDR_REG (indx))
1530                   {
1531                     base = op1;
1532                     indx = op0;
1533                   }
1534               }
1535             else
1536               {
1537                 base = op0;     /* Base + displacement.  */
1538                 disp = op1;
1539               }
1540             break;
1541
1542           default:
1543             return 0;
1544           }
1545       }
1546       break;
1547
1548       /* Direct addressing with DP register.  */
1549     case LO_SUM:
1550       {
1551         rtx op0 = XEXP (addr, 0);
1552         rtx op1 = XEXP (addr, 1);
1553
1554         /* HImode and HFmode direct memory references aren't truly
1555            offsettable (consider case at end of data page).  We
1556            probably get better code by loading a pointer and using an
1557            indirect memory reference.  */
1558         if (mode == HImode || mode == HFmode)
1559           return 0;
1560
1561         if (!REG_P (op0) || REGNO (op0) != DP_REGNO)
1562           return 0;
1563
1564         if ((GET_CODE (op1) == SYMBOL_REF || GET_CODE (op1) == LABEL_REF))
1565           return 1;
1566
1567         if (GET_CODE (op1) == CONST)
1568           return 1;
1569         return 0;
1570       }
1571       break;
1572
1573       /* Direct addressing with some work for the assembler...  */
1574     case CONST:
1575       /* Direct addressing.  */
1576     case LABEL_REF:
1577     case SYMBOL_REF:
1578       if (! TARGET_EXPOSE_LDP && ! strict && mode != HFmode && mode != HImode)
1579         return 1;
1580       /* These need to be converted to a LO_SUM (...). 
1581          LEGITIMIZE_RELOAD_ADDRESS will do this during reload.  */
1582       return 0;
1583
1584       /* Do not allow direct memory access to absolute addresses.
1585          This is more pain than it's worth, especially for the
1586          small memory model where we can't guarantee that
1587          this address is within the data page---we don't want
1588          to modify the DP register in the small memory model,
1589          even temporarily, since an interrupt can sneak in....  */
1590     case CONST_INT:
1591       return 0;
1592
1593       /* Indirect indirect addressing.  */
1594     case MEM:
1595       return 0;
1596
1597     case CONST_DOUBLE:
1598       fatal_insn ("using CONST_DOUBLE for address", addr);
1599
1600     default:
1601       return 0;
1602     }
1603
1604   /* Validate the base register.  */
1605   if (base)
1606     {
1607       /* Check that the address is offsettable for HImode and HFmode.  */
1608       if (indx && (mode == HImode || mode == HFmode))
1609         return 0;
1610
1611       /* Handle DP based stuff.  */
1612       if (REGNO (base) == DP_REGNO)
1613         return 1;
1614       if (strict && ! REGNO_OK_FOR_BASE_P (REGNO (base)))
1615         return 0;
1616       else if (! strict && ! IS_ADDR_OR_PSEUDO_REG (base))
1617         return 0;
1618     }
1619
1620   /* Now validate the index register.  */
1621   if (indx)
1622     {
1623       if (GET_CODE (indx) != REG)
1624         return 0;
1625       if (strict && ! REGNO_OK_FOR_INDEX_P (REGNO (indx)))
1626         return 0;
1627       else if (! strict && ! IS_INDEX_OR_PSEUDO_REG (indx))
1628         return 0;
1629     }
1630
1631   /* Validate displacement.  */
1632   if (disp)
1633     {
1634       if (GET_CODE (disp) != CONST_INT)
1635         return 0;
1636       if (mode == HImode || mode == HFmode)
1637         {
1638           /* The offset displacement must be legitimate.  */
1639           if (! IS_DISP8_OFF_CONST (INTVAL (disp)))
1640             return 0;
1641         }
1642       else
1643         {
1644           if (! IS_DISP8_CONST (INTVAL (disp)))
1645             return 0;
1646         }
1647       /* Can't add an index with a disp.  */
1648       if (indx)
1649         return 0;               
1650     }
1651   return 1;
1652 }
1653
1654
1655 rtx
1656 c4x_legitimize_address (rtx orig ATTRIBUTE_UNUSED,
1657                         enum machine_mode mode ATTRIBUTE_UNUSED)
1658 {
1659   if (GET_CODE (orig) == SYMBOL_REF
1660       || GET_CODE (orig) == LABEL_REF)
1661     {
1662       if (mode == HImode || mode == HFmode)
1663         {
1664           /* We need to force the address into
1665              a register so that it is offsettable.  */
1666           rtx addr_reg = gen_reg_rtx (Pmode);
1667           emit_move_insn (addr_reg, orig);
1668           return addr_reg;
1669         }
1670       else
1671         {
1672           rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
1673           
1674           if (! TARGET_SMALL)
1675             emit_insn (gen_set_ldp (dp_reg, orig));
1676           
1677           return gen_rtx_LO_SUM (Pmode, dp_reg, orig);
1678         }
1679     }
1680
1681   return NULL_RTX;
1682 }
1683
1684
1685 /* Provide the costs of an addressing mode that contains ADDR.
1686    If ADDR is not a valid address, its cost is irrelevant.  
1687    This is used in cse and loop optimization to determine
1688    if it is worthwhile storing a common address into a register. 
1689    Unfortunately, the C4x address cost depends on other operands.  */
1690
1691 static int 
1692 c4x_address_cost (rtx addr)
1693 {
1694   switch (GET_CODE (addr))
1695     {
1696     case REG:
1697       return 1;
1698
1699     case POST_INC:
1700     case POST_DEC:
1701     case PRE_INC:
1702     case PRE_DEC:
1703       return 1;
1704       
1705       /* These shouldn't be directly generated.  */
1706     case SYMBOL_REF:
1707     case LABEL_REF:
1708     case CONST:
1709       return 10;
1710
1711     case LO_SUM:
1712       {
1713         rtx op1 = XEXP (addr, 1);
1714
1715         if (GET_CODE (op1) == LABEL_REF || GET_CODE (op1) == SYMBOL_REF)
1716           return TARGET_SMALL ? 3 : 4;
1717         
1718         if (GET_CODE (op1) == CONST)
1719           {
1720             rtx offset = const0_rtx;
1721             
1722             op1 = eliminate_constant_term (op1, &offset);
1723             
1724             /* ??? These costs need rethinking...  */
1725             if (GET_CODE (op1) == LABEL_REF)
1726               return 3;
1727             
1728             if (GET_CODE (op1) != SYMBOL_REF)
1729               return 4;
1730             
1731             if (INTVAL (offset) == 0)
1732               return 3;
1733
1734             return 4;
1735           }
1736         fatal_insn ("c4x_address_cost: Invalid addressing mode", addr);
1737       }
1738       break;
1739       
1740     case PLUS:
1741       {
1742         register rtx op0 = XEXP (addr, 0);
1743         register rtx op1 = XEXP (addr, 1);
1744         
1745         if (GET_CODE (op0) != REG)
1746           break;
1747         
1748         switch (GET_CODE (op1))
1749           {
1750           default:
1751             break;
1752
1753           case REG:
1754             /* This cost for REG+REG must be greater than the cost
1755                for REG if we want autoincrement addressing modes.  */
1756             return 2;
1757
1758           case CONST_INT:
1759             /* The following tries to improve GIV combination
1760                in strength reduce but appears not to help.  */
1761             if (TARGET_DEVEL && IS_UINT5_CONST (INTVAL (op1)))
1762               return 1;
1763
1764             if (IS_DISP1_CONST (INTVAL (op1)))
1765               return 1;
1766
1767             if (! TARGET_C3X && IS_UINT5_CONST (INTVAL (op1)))
1768               return 2;
1769
1770             return 3;
1771           }
1772       }
1773     default:
1774       break;
1775     }
1776   
1777   return 4;
1778 }
1779
1780
1781 rtx
1782 c4x_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
1783 {
1784   enum machine_mode mode = SELECT_CC_MODE (code, x, y);
1785   rtx cc_reg;
1786
1787   if (mode == CC_NOOVmode
1788       && (code == LE || code == GE || code == LT || code == GT))
1789     return NULL_RTX;
1790
1791   cc_reg = gen_rtx_REG (mode, ST_REGNO);
1792   emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
1793                           gen_rtx_COMPARE (mode, x, y)));
1794   return cc_reg;
1795 }
1796
1797 char *
1798 c4x_output_cbranch (const char *form, rtx seq)
1799 {
1800   int delayed = 0;
1801   int annultrue = 0;
1802   int annulfalse = 0;
1803   rtx delay;
1804   char *cp;
1805   static char str[100];
1806   
1807   if (final_sequence)
1808     {
1809       delay = XVECEXP (final_sequence, 0, 1);
1810       delayed = ! INSN_ANNULLED_BRANCH_P (seq);
1811       annultrue = INSN_ANNULLED_BRANCH_P (seq) && ! INSN_FROM_TARGET_P (delay);
1812       annulfalse = INSN_ANNULLED_BRANCH_P (seq) && INSN_FROM_TARGET_P (delay);
1813     }
1814   strcpy (str, form);
1815   cp = &str [strlen (str)];
1816   if (delayed)
1817     {
1818       *cp++ = '%';
1819       *cp++ = '#';
1820     }
1821   if (annultrue)
1822     {
1823       *cp++ = 'a';
1824       *cp++ = 't';
1825     }
1826   if (annulfalse)
1827     {
1828       *cp++ = 'a'; 
1829       *cp++ = 'f';
1830     }
1831   *cp++ = '\t';
1832   *cp++ = '%'; 
1833   *cp++ = 'l';
1834   *cp++ = '1';
1835   *cp = 0;
1836   return str;
1837 }
1838
1839 void
1840 c4x_print_operand (FILE *file, rtx op, int letter)
1841 {
1842   rtx op1;
1843   enum rtx_code code;
1844
1845   switch (letter)
1846     {
1847     case '#':                   /* Delayed.  */
1848       if (final_sequence)
1849         fprintf (file, "d");
1850       return;
1851     }
1852
1853   code = GET_CODE (op);
1854   switch (letter)
1855     {
1856     case 'A':                   /* Direct address.  */
1857       if (code == CONST_INT || code == SYMBOL_REF || code == CONST)
1858         fprintf (file, "@");
1859       break;
1860
1861     case 'H':                   /* Sethi.  */
1862       output_addr_const (file, op);
1863       return;
1864
1865     case 'I':                   /* Reversed condition.  */
1866       code = reverse_condition (code);
1867       break;
1868
1869     case 'L':                   /* Log 2 of constant.  */
1870       if (code != CONST_INT)
1871         fatal_insn ("c4x_print_operand: %%L inconsistency", op);
1872       fprintf (file, "%d", exact_log2 (INTVAL (op)));
1873       return;
1874
1875     case 'N':                   /* Ones complement of small constant.  */
1876       if (code != CONST_INT)
1877         fatal_insn ("c4x_print_operand: %%N inconsistency", op);
1878       fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~INTVAL (op));
1879       return;
1880
1881     case 'K':                   /* Generate ldp(k) if direct address.  */
1882       if (! TARGET_SMALL
1883           && code == MEM
1884           && GET_CODE (XEXP (op, 0)) == LO_SUM
1885           && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
1886           && REGNO (XEXP (XEXP (op, 0), 0)) == DP_REGNO)
1887         {
1888           op1 = XEXP (XEXP (op, 0), 1);
1889           if (GET_CODE(op1) == CONST_INT || GET_CODE(op1) == SYMBOL_REF)
1890             {
1891               fprintf (file, "\t%s\t@", TARGET_C3X ? "ldp" : "ldpk");
1892               output_address (XEXP (adjust_address (op, VOIDmode, 1), 0));
1893               fprintf (file, "\n");
1894             }
1895         }
1896       return;
1897
1898     case 'M':                   /* Generate ldp(k) if direct address.  */
1899       if (! TARGET_SMALL        /* Only used in asm statements.  */
1900           && code == MEM
1901           && (GET_CODE (XEXP (op, 0)) == CONST
1902               || GET_CODE (XEXP (op, 0)) == SYMBOL_REF))
1903         {
1904           fprintf (file, "%s\t@", TARGET_C3X ? "ldp" : "ldpk");
1905           output_address (XEXP (op, 0));
1906           fprintf (file, "\n\t");
1907         }
1908       return;
1909
1910     case 'O':                   /* Offset address.  */
1911       if (code == MEM && c4x_autoinc_operand (op, Pmode))
1912         break;
1913       else if (code == MEM)
1914         output_address (XEXP (adjust_address (op, VOIDmode, 1), 0));
1915       else if (code == REG)
1916         fprintf (file, "%s", reg_names[REGNO (op) + 1]);
1917       else
1918         fatal_insn ("c4x_print_operand: %%O inconsistency", op);
1919       return;
1920
1921     case 'C':                   /* Call.  */
1922       break;
1923
1924     case 'U':                   /* Call/callu.  */
1925       if (code != SYMBOL_REF)
1926         fprintf (file, "u");
1927       return;
1928
1929     default:
1930       break;
1931     }
1932   
1933   switch (code)
1934     {
1935     case REG:
1936       if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
1937           && ! TARGET_TI)
1938         fprintf (file, "%s", float_reg_names[REGNO (op)]);
1939       else
1940         fprintf (file, "%s", reg_names[REGNO (op)]);
1941       break;
1942       
1943     case MEM:
1944       output_address (XEXP (op, 0));
1945       break;
1946       
1947     case CONST_DOUBLE:
1948       {
1949         char str[64];
1950         
1951         real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (op),
1952                          sizeof (str), 0, 1);
1953         fprintf (file, "%s", str);
1954       }
1955       break;
1956       
1957     case CONST_INT:
1958       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op));
1959       break;
1960       
1961     case NE:
1962       fprintf (file, "ne");
1963       break;
1964       
1965     case EQ:
1966       fprintf (file, "eq");
1967       break;
1968       
1969     case GE:
1970       fprintf (file, "ge");
1971       break;
1972
1973     case GT:
1974       fprintf (file, "gt");
1975       break;
1976
1977     case LE:
1978       fprintf (file, "le");
1979       break;
1980
1981     case LT:
1982       fprintf (file, "lt");
1983       break;
1984
1985     case GEU:
1986       fprintf (file, "hs");
1987       break;
1988
1989     case GTU:
1990       fprintf (file, "hi");
1991       break;
1992
1993     case LEU:
1994       fprintf (file, "ls");
1995       break;
1996
1997     case LTU:
1998       fprintf (file, "lo");
1999       break;
2000
2001     case SYMBOL_REF:
2002       output_addr_const (file, op);
2003       break;
2004
2005     case CONST:
2006       output_addr_const (file, XEXP (op, 0));
2007       break;
2008
2009     case CODE_LABEL:
2010       break;
2011
2012     default:
2013       fatal_insn ("c4x_print_operand: Bad operand case", op);
2014       break;
2015     }
2016 }
2017
2018
2019 void
2020 c4x_print_operand_address (FILE *file, rtx addr)
2021 {
2022   switch (GET_CODE (addr))
2023     {
2024     case REG:
2025       fprintf (file, "*%s", reg_names[REGNO (addr)]);
2026       break;
2027
2028     case PRE_DEC:
2029       fprintf (file, "*--%s", reg_names[REGNO (XEXP (addr, 0))]);
2030       break;
2031
2032     case POST_INC:
2033       fprintf (file, "*%s++", reg_names[REGNO (XEXP (addr, 0))]);
2034       break;
2035
2036     case POST_MODIFY:
2037       {
2038         rtx op0 = XEXP (XEXP (addr, 1), 0);
2039         rtx op1 = XEXP (XEXP (addr, 1), 1);
2040         
2041         if (GET_CODE (XEXP (addr, 1)) == PLUS && REG_P (op1))
2042           fprintf (file, "*%s++(%s)", reg_names[REGNO (op0)],
2043                    reg_names[REGNO (op1)]);
2044         else if (GET_CODE (XEXP (addr, 1)) == PLUS && INTVAL (op1) > 0)
2045           fprintf (file, "*%s++(" HOST_WIDE_INT_PRINT_DEC ")",
2046                    reg_names[REGNO (op0)], INTVAL (op1));
2047         else if (GET_CODE (XEXP (addr, 1)) == PLUS && INTVAL (op1) < 0)
2048           fprintf (file, "*%s--(" HOST_WIDE_INT_PRINT_DEC ")",
2049                    reg_names[REGNO (op0)], -INTVAL (op1));
2050         else if (GET_CODE (XEXP (addr, 1)) == MINUS && REG_P (op1))
2051           fprintf (file, "*%s--(%s)", reg_names[REGNO (op0)],
2052                    reg_names[REGNO (op1)]);
2053         else
2054           fatal_insn ("c4x_print_operand_address: Bad post_modify", addr);
2055       }
2056       break;
2057       
2058     case PRE_MODIFY:
2059       {
2060         rtx op0 = XEXP (XEXP (addr, 1), 0);
2061         rtx op1 = XEXP (XEXP (addr, 1), 1);
2062         
2063         if (GET_CODE (XEXP (addr, 1)) == PLUS && REG_P (op1))
2064           fprintf (file, "*++%s(%s)", reg_names[REGNO (op0)],
2065                    reg_names[REGNO (op1)]);
2066         else if (GET_CODE (XEXP (addr, 1)) == PLUS && INTVAL (op1) > 0)
2067           fprintf (file, "*++%s(" HOST_WIDE_INT_PRINT_DEC ")",
2068                    reg_names[REGNO (op0)], INTVAL (op1));
2069         else if (GET_CODE (XEXP (addr, 1)) == PLUS && INTVAL (op1) < 0)
2070           fprintf (file, "*--%s(" HOST_WIDE_INT_PRINT_DEC ")",
2071                    reg_names[REGNO (op0)], -INTVAL (op1));
2072         else if (GET_CODE (XEXP (addr, 1)) == MINUS && REG_P (op1))
2073           fprintf (file, "*--%s(%s)", reg_names[REGNO (op0)],
2074                    reg_names[REGNO (op1)]);
2075         else
2076           fatal_insn ("c4x_print_operand_address: Bad pre_modify", addr);
2077       }
2078       break;
2079       
2080     case PRE_INC:
2081       fprintf (file, "*++%s", reg_names[REGNO (XEXP (addr, 0))]);
2082       break;
2083
2084     case POST_DEC:
2085       fprintf (file, "*%s--", reg_names[REGNO (XEXP (addr, 0))]);
2086       break;
2087
2088     case PLUS:                  /* Indirect with displacement.  */
2089       {
2090         rtx op0 = XEXP (addr, 0);
2091         rtx op1 = XEXP (addr, 1);
2092
2093         if (REG_P (op0))
2094           {
2095             if (REG_P (op1))
2096               {
2097                 if (IS_INDEX_REG (op0))
2098                   {
2099                     fprintf (file, "*+%s(%s)",
2100                              reg_names[REGNO (op1)],
2101                              reg_names[REGNO (op0)]);   /* Index + base.  */
2102                   }
2103                 else
2104                   {
2105                     fprintf (file, "*+%s(%s)",
2106                              reg_names[REGNO (op0)],
2107                              reg_names[REGNO (op1)]);   /* Base + index.  */
2108                   }
2109               }
2110             else if (INTVAL (op1) < 0)
2111               {
2112                 fprintf (file, "*-%s(" HOST_WIDE_INT_PRINT_DEC ")",
2113                          reg_names[REGNO (op0)],
2114                          -INTVAL (op1));        /* Base - displacement.  */
2115               }
2116             else
2117               {
2118                 fprintf (file, "*+%s(" HOST_WIDE_INT_PRINT_DEC ")",
2119                          reg_names[REGNO (op0)],
2120                          INTVAL (op1)); /* Base + displacement.  */
2121               }
2122           }
2123         else
2124           fatal_insn ("c4x_print_operand_address: Bad operand case", addr);
2125       }
2126       break;
2127
2128     case LO_SUM:
2129       {
2130         rtx op0 = XEXP (addr, 0);
2131         rtx op1 = XEXP (addr, 1);
2132           
2133         if (REG_P (op0) && REGNO (op0) == DP_REGNO)
2134           c4x_print_operand_address (file, op1);
2135         else
2136           fatal_insn ("c4x_print_operand_address: Bad operand case", addr);
2137       }
2138       break;
2139
2140     case CONST:
2141     case SYMBOL_REF:
2142     case LABEL_REF:
2143       fprintf (file, "@");
2144       output_addr_const (file, addr);
2145       break;
2146
2147       /* We shouldn't access CONST_INT addresses.  */
2148     case CONST_INT:
2149
2150     default:
2151       fatal_insn ("c4x_print_operand_address: Bad operand case", addr);
2152       break;
2153     }
2154 }
2155
2156
2157 /* Return nonzero if the floating point operand will fit
2158    in the immediate field.  */
2159
2160 static int
2161 c4x_immed_float_p (rtx op)
2162 {
2163   long convval[2];
2164   int exponent;
2165   REAL_VALUE_TYPE r;
2166
2167   REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2168   if (GET_MODE (op) == HFmode)
2169     REAL_VALUE_TO_TARGET_DOUBLE (r, convval);
2170   else
2171     {
2172       REAL_VALUE_TO_TARGET_SINGLE (r, convval[0]);
2173       convval[1] = 0;
2174     }
2175
2176   /* Sign extend exponent.  */
2177   exponent = (((convval[0] >> 24) & 0xff) ^ 0x80) - 0x80;
2178   if (exponent == -128)
2179     return 1;                   /* 0.0  */
2180   if ((convval[0] & 0x00000fff) != 0 || convval[1] != 0)
2181     return 0;                   /* Precision doesn't fit.  */
2182   return (exponent <= 7)        /* Positive exp.  */
2183     && (exponent >= -7);        /* Negative exp.  */
2184 }
2185
2186
2187 /* The last instruction in a repeat block cannot be a Bcond, DBcound,
2188    CALL, CALLCond, TRAPcond, RETIcond, RETScond, IDLE, RPTB or RPTS.
2189
2190    None of the last four instructions from the bottom of the block can
2191    be a BcondD, BRD, DBcondD, RPTBD, LAJ, LAJcond, LATcond, BcondAF,
2192    BcondAT or RETIcondD.
2193
2194    This routine scans the four previous insns for a jump insn, and if
2195    one is found, returns 1 so that we bung in a nop instruction.
2196    This simple minded strategy will add a nop, when it may not
2197    be required.  Say when there is a JUMP_INSN near the end of the
2198    block that doesn't get converted into a delayed branch.
2199
2200    Note that we cannot have a call insn, since we don't generate
2201    repeat loops with calls in them (although I suppose we could, but
2202    there's no benefit.)  
2203
2204    !!! FIXME.  The rptb_top insn may be sucked into a SEQUENCE.  */
2205
2206 int
2207 c4x_rptb_nop_p (rtx insn)
2208 {
2209   rtx start_label;
2210   int i;
2211
2212   /* Extract the start label from the jump pattern (rptb_end).  */
2213   start_label = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0);
2214
2215   /* If there is a label at the end of the loop we must insert
2216      a NOP.  */
2217   do {
2218     insn = previous_insn (insn);
2219   } while (GET_CODE (insn) == NOTE
2220            || GET_CODE (insn) == USE
2221            || GET_CODE (insn) == CLOBBER);
2222   if (GET_CODE (insn) == CODE_LABEL)
2223     return 1;
2224
2225   for (i = 0; i < 4; i++)
2226     {
2227       /* Search back for prev non-note and non-label insn.  */
2228       while (GET_CODE (insn) == NOTE || GET_CODE (insn) == CODE_LABEL
2229              || GET_CODE (insn) == USE || GET_CODE (insn) == CLOBBER)
2230         {
2231           if (insn == start_label)
2232             return i == 0;
2233
2234           insn = previous_insn (insn);
2235         };
2236
2237       /* If we have a jump instruction we should insert a NOP. If we
2238          hit repeat block top we should only insert a NOP if the loop
2239          is empty.  */
2240       if (GET_CODE (insn) == JUMP_INSN)
2241         return 1;
2242       insn = previous_insn (insn);
2243     }
2244   return 0;
2245 }
2246
2247
2248 /* The C4x looping instruction needs to be emitted at the top of the
2249   loop.  Emitting the true RTL for a looping instruction at the top of
2250   the loop can cause problems with flow analysis.  So instead, a dummy
2251   doloop insn is emitted at the end of the loop.  This routine checks
2252   for the presence of this doloop insn and then searches back to the
2253   top of the loop, where it inserts the true looping insn (provided
2254   there are no instructions in the loop which would cause problems).
2255   Any additional labels can be emitted at this point.  In addition, if
2256   the desired loop count register was not allocated, this routine does
2257   nothing. 
2258
2259   Before we can create a repeat block looping instruction we have to
2260   verify that there are no jumps outside the loop and no jumps outside
2261   the loop go into this loop. This can happen in the basic blocks reorder
2262   pass. The C4x cpu cannot handle this.  */
2263
2264 static int
2265 c4x_label_ref_used_p (rtx x, rtx code_label)
2266 {
2267   enum rtx_code code;
2268   int i, j;
2269   const char *fmt;
2270
2271   if (x == 0)
2272     return 0;
2273
2274   code = GET_CODE (x);
2275   if (code == LABEL_REF)
2276     return INSN_UID (XEXP (x,0)) == INSN_UID (code_label);
2277
2278   fmt = GET_RTX_FORMAT (code);
2279   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2280     {
2281       if (fmt[i] == 'e')
2282         {
2283           if (c4x_label_ref_used_p (XEXP (x, i), code_label))
2284             return 1;
2285         }
2286       else if (fmt[i] == 'E')
2287         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
2288           if (c4x_label_ref_used_p (XVECEXP (x, i, j), code_label))
2289             return 1;
2290     }
2291   return 0;
2292 }
2293
2294
2295 static int
2296 c4x_rptb_valid_p (rtx insn, rtx start_label)
2297 {
2298   rtx end = insn;
2299   rtx start;
2300   rtx tmp;
2301
2302   /* Find the start label.  */
2303   for (; insn; insn = PREV_INSN (insn))
2304     if (insn == start_label)
2305       break;
2306
2307   /* Note found then we cannot use a rptb or rpts.  The label was
2308      probably moved by the basic block reorder pass.  */
2309   if (! insn)
2310     return 0;
2311
2312   start = insn;
2313   /* If any jump jumps inside this block then we must fail.  */
2314   for (insn = PREV_INSN (start); insn; insn = PREV_INSN (insn))
2315     {
2316       if (GET_CODE (insn) == CODE_LABEL)
2317         {
2318           for (tmp = NEXT_INSN (start); tmp != end; tmp = NEXT_INSN(tmp))
2319             if (GET_CODE (tmp) == JUMP_INSN
2320                 && c4x_label_ref_used_p (tmp, insn))
2321               return 0;
2322         }
2323     }
2324   for (insn = NEXT_INSN (end); insn; insn = NEXT_INSN (insn))
2325     {
2326       if (GET_CODE (insn) == CODE_LABEL)
2327         {
2328           for (tmp = NEXT_INSN (start); tmp != end; tmp = NEXT_INSN(tmp))
2329             if (GET_CODE (tmp) == JUMP_INSN
2330                 && c4x_label_ref_used_p (tmp, insn))
2331               return 0;
2332         }
2333     }
2334   /* If any jump jumps outside this block then we must fail.  */
2335   for (insn = NEXT_INSN (start); insn != end; insn = NEXT_INSN (insn))
2336     {
2337       if (GET_CODE (insn) == CODE_LABEL)
2338         {
2339           for (tmp = NEXT_INSN (end); tmp; tmp = NEXT_INSN(tmp))
2340             if (GET_CODE (tmp) == JUMP_INSN
2341                 && c4x_label_ref_used_p (tmp, insn))
2342               return 0;
2343           for (tmp = PREV_INSN (start); tmp; tmp = PREV_INSN(tmp))
2344             if (GET_CODE (tmp) == JUMP_INSN
2345                 && c4x_label_ref_used_p (tmp, insn))
2346               return 0;
2347         }
2348     }
2349
2350   /* All checks OK.  */
2351   return 1;
2352 }
2353
2354
2355 void
2356 c4x_rptb_insert (rtx insn)
2357 {
2358   rtx end_label;
2359   rtx start_label;
2360   rtx new_start_label;
2361   rtx count_reg;
2362
2363   /* If the count register has not been allocated to RC, say if
2364      there is a movmem pattern in the loop, then do not insert a
2365      RPTB instruction.  Instead we emit a decrement and branch
2366      at the end of the loop.  */
2367   count_reg = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0), 0);
2368   if (REGNO (count_reg) != RC_REGNO)
2369     return;
2370
2371   /* Extract the start label from the jump pattern (rptb_end).  */
2372   start_label = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0);
2373   
2374   if (! c4x_rptb_valid_p (insn, start_label))
2375     {
2376       /* We cannot use the rptb insn.  Replace it so reorg can use
2377          the delay slots of the jump insn.  */
2378       emit_insn_before (gen_addqi3 (count_reg, count_reg, constm1_rtx), insn);
2379       emit_insn_before (gen_cmpqi (count_reg, const0_rtx), insn);
2380       emit_insn_before (gen_bge (start_label), insn);
2381       LABEL_NUSES (start_label)++;
2382       delete_insn (insn);
2383       return;
2384     }
2385
2386   end_label = gen_label_rtx ();
2387   LABEL_NUSES (end_label)++;
2388   emit_label_after (end_label, insn);
2389
2390   new_start_label = gen_label_rtx ();
2391   LABEL_NUSES (new_start_label)++;
2392
2393   for (; insn; insn = PREV_INSN (insn))
2394     {
2395       if (insn == start_label)
2396          break;
2397       if (GET_CODE (insn) == JUMP_INSN &&
2398           JUMP_LABEL (insn) == start_label)
2399         redirect_jump (insn, new_start_label, 0);
2400     }
2401   if (! insn)
2402     fatal_insn ("c4x_rptb_insert: Cannot find start label", start_label);
2403
2404   emit_label_after (new_start_label, insn);
2405
2406   if (TARGET_RPTS && c4x_rptb_rpts_p (PREV_INSN (insn), 0))
2407     emit_insn_after (gen_rpts_top (new_start_label, end_label), insn);
2408   else
2409     emit_insn_after (gen_rptb_top (new_start_label, end_label), insn);
2410   if (LABEL_NUSES (start_label) == 0)
2411     delete_insn (start_label);
2412 }
2413
2414
2415 /* We need to use direct addressing for large constants and addresses
2416    that cannot fit within an instruction.  We must check for these
2417    after after the final jump optimization pass, since this may
2418    introduce a local_move insn for a SYMBOL_REF.  This pass
2419    must come before delayed branch slot filling since it can generate
2420    additional instructions.
2421
2422    This function also fixes up RTPB style loops that didn't get RC
2423    allocated as the loop counter.  */
2424
2425 static void
2426 c4x_reorg (void)
2427 {
2428   rtx insn;
2429
2430   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2431     {
2432       /* Look for insn.  */
2433       if (INSN_P (insn))
2434         {
2435           int insn_code_number;
2436           rtx old;
2437
2438           insn_code_number = recog_memoized (insn);
2439
2440           if (insn_code_number < 0)
2441             continue;
2442
2443           /* Insert the RTX for RPTB at the top of the loop
2444              and a label at the end of the loop.  */
2445           if (insn_code_number == CODE_FOR_rptb_end)
2446             c4x_rptb_insert(insn);
2447
2448           /* We need to split the insn here. Otherwise the calls to
2449              force_const_mem will not work for load_immed_address.  */
2450           old = insn;
2451
2452           /* Don't split the insn if it has been deleted.  */
2453           if (! INSN_DELETED_P (old))
2454             insn = try_split (PATTERN(old), old, 1);
2455
2456           /* When not optimizing, the old insn will be still left around
2457              with only the 'deleted' bit set.  Transform it into a note
2458              to avoid confusion of subsequent processing.  */
2459           if (INSN_DELETED_P (old))
2460             {
2461               PUT_CODE (old, NOTE);
2462               NOTE_LINE_NUMBER (old) = NOTE_INSN_DELETED;
2463               NOTE_SOURCE_FILE (old) = 0;
2464             }
2465         }
2466     }
2467 }
2468
2469
2470 static int
2471 c4x_a_register (rtx op)
2472 {
2473   return REG_P (op) && IS_ADDR_OR_PSEUDO_REG (op);
2474 }
2475
2476
2477 static int
2478 c4x_x_register (rtx op)
2479 {
2480   return REG_P (op) && IS_INDEX_OR_PSEUDO_REG (op);
2481 }
2482
2483
2484 static int
2485 c4x_immed_int_constant (rtx op)
2486 {
2487   if (GET_CODE (op) != CONST_INT)
2488     return 0;
2489
2490   return GET_MODE (op) == VOIDmode
2491     || GET_MODE_CLASS (GET_MODE (op)) == MODE_INT
2492     || GET_MODE_CLASS (GET_MODE (op)) == MODE_PARTIAL_INT;
2493 }
2494
2495
2496 static int
2497 c4x_immed_float_constant (rtx op)
2498 {
2499   if (GET_CODE (op) != CONST_DOUBLE)
2500     return 0;
2501
2502   /* Do not check if the CONST_DOUBLE is in memory. If there is a MEM
2503      present this only means that a MEM rtx has been generated. It does
2504      not mean the rtx is really in memory.  */
2505
2506   return GET_MODE (op) == QFmode || GET_MODE (op) == HFmode;
2507 }
2508
2509
2510 int
2511 c4x_shiftable_constant (rtx op)
2512 {
2513   int i;
2514   int mask;
2515   int val = INTVAL (op);
2516
2517   for (i = 0; i < 16; i++)
2518     {
2519       if (val & (1 << i))
2520         break;
2521     }
2522   mask = ((0xffff >> i) << 16) | 0xffff;
2523   if (IS_INT16_CONST (val & (1 << 31) ? (val >> i) | ~mask
2524                                       : (val >> i) & mask))
2525     return i;
2526   return -1;
2527
2528
2529
2530 int
2531 c4x_H_constant (rtx op)
2532 {
2533   return c4x_immed_float_constant (op) && c4x_immed_float_p (op);
2534 }
2535
2536
2537 int
2538 c4x_I_constant (rtx op)
2539 {
2540   return c4x_immed_int_constant (op) && IS_INT16_CONST (INTVAL (op));
2541 }
2542
2543
2544 int
2545 c4x_J_constant (rtx op)
2546 {
2547   if (TARGET_C3X)
2548     return 0;
2549   return c4x_immed_int_constant (op) && IS_INT8_CONST (INTVAL (op));
2550 }
2551
2552
2553 static int
2554 c4x_K_constant (rtx op)
2555 {
2556   if (TARGET_C3X || ! c4x_immed_int_constant (op))
2557     return 0;
2558   return IS_INT5_CONST (INTVAL (op));
2559 }
2560
2561
2562 int
2563 c4x_L_constant (rtx op)
2564 {
2565   return c4x_immed_int_constant (op) && IS_UINT16_CONST (INTVAL (op));
2566 }
2567
2568
2569 static int
2570 c4x_N_constant (rtx op)
2571 {
2572   return c4x_immed_int_constant (op) && IS_NOT_UINT16_CONST (INTVAL (op));
2573 }
2574
2575
2576 static int
2577 c4x_O_constant (rtx op)
2578 {
2579   return c4x_immed_int_constant (op) && IS_HIGH_CONST (INTVAL (op));
2580 }
2581
2582
2583 /* The constraints do not have to check the register class,
2584    except when needed to discriminate between the constraints.
2585    The operand has been checked by the predicates to be valid.  */
2586
2587 /* ARx + 9-bit signed const or IRn
2588    *ARx, *+ARx(n), *-ARx(n), *+ARx(IRn), *-Arx(IRn) for -256 < n < 256
2589    We don't include the pre/post inc/dec forms here since
2590    they are handled by the <> constraints.  */
2591
2592 int
2593 c4x_Q_constraint (rtx op)
2594 {
2595   enum machine_mode mode = GET_MODE (op);
2596
2597   if (GET_CODE (op) != MEM)
2598     return 0;
2599   op = XEXP (op, 0);
2600   switch (GET_CODE (op))
2601     {
2602     case REG:
2603       return 1;
2604
2605     case PLUS:
2606       {
2607         rtx op0 = XEXP (op, 0);
2608         rtx op1 = XEXP (op, 1);
2609
2610         if (! REG_P (op0))
2611           return 0;
2612
2613         if (REG_P (op1))
2614           return 1;
2615
2616         if (GET_CODE (op1) != CONST_INT)
2617           return 0;
2618
2619         /* HImode and HFmode must be offsettable.  */
2620         if (mode == HImode || mode == HFmode)
2621           return IS_DISP8_OFF_CONST (INTVAL (op1));
2622         
2623         return IS_DISP8_CONST (INTVAL (op1));
2624       }
2625       break;
2626
2627     default:
2628       break;
2629     }
2630   return 0;
2631 }
2632
2633
2634 /* ARx + 5-bit unsigned const
2635    *ARx, *+ARx(n) for n < 32.  */
2636
2637 int
2638 c4x_R_constraint (rtx op)
2639 {
2640   enum machine_mode mode = GET_MODE (op);
2641
2642   if (TARGET_C3X)
2643     return 0;
2644   if (GET_CODE (op) != MEM)
2645     return 0;
2646   op = XEXP (op, 0);
2647   switch (GET_CODE (op))
2648     {
2649     case REG:
2650       return 1;
2651
2652     case PLUS:
2653       {
2654         rtx op0 = XEXP (op, 0);
2655         rtx op1 = XEXP (op, 1);
2656
2657         if (! REG_P (op0))
2658           return 0;
2659
2660         if (GET_CODE (op1) != CONST_INT)
2661           return 0;
2662
2663         /* HImode and HFmode must be offsettable.  */
2664         if (mode == HImode || mode == HFmode)
2665           return IS_UINT5_CONST (INTVAL (op1) + 1);
2666         
2667         return IS_UINT5_CONST (INTVAL (op1));
2668       }
2669       break;
2670
2671     default:
2672       break;
2673     }
2674   return 0;
2675 }
2676
2677
2678 static int
2679 c4x_R_indirect (rtx op)
2680 {
2681   enum machine_mode mode = GET_MODE (op);
2682
2683   if (TARGET_C3X || GET_CODE (op) != MEM)
2684     return 0;
2685
2686   op = XEXP (op, 0);
2687   switch (GET_CODE (op))
2688     {
2689     case REG:
2690       return IS_ADDR_OR_PSEUDO_REG (op);
2691
2692     case PLUS:
2693       {
2694         rtx op0 = XEXP (op, 0);
2695         rtx op1 = XEXP (op, 1);
2696
2697         /* HImode and HFmode must be offsettable.  */
2698         if (mode == HImode || mode == HFmode)
2699           return IS_ADDR_OR_PSEUDO_REG (op0)
2700             && GET_CODE (op1) == CONST_INT 
2701             && IS_UINT5_CONST (INTVAL (op1) + 1);
2702
2703         return REG_P (op0)
2704           && IS_ADDR_OR_PSEUDO_REG (op0)
2705           && GET_CODE (op1) == CONST_INT
2706           && IS_UINT5_CONST (INTVAL (op1));
2707       }
2708       break;
2709
2710     default:
2711       break;
2712     }
2713   return 0;
2714 }
2715
2716
2717 /* ARx + 1-bit unsigned const or IRn
2718    *ARx, *+ARx(1), *-ARx(1), *+ARx(IRn), *-Arx(IRn)
2719    We don't include the pre/post inc/dec forms here since
2720    they are handled by the <> constraints.  */
2721
2722 int
2723 c4x_S_constraint (rtx op)
2724 {
2725   enum machine_mode mode = GET_MODE (op);
2726   if (GET_CODE (op) != MEM)
2727     return 0;
2728   op = XEXP (op, 0);
2729   switch (GET_CODE (op))
2730     {
2731     case REG:
2732       return 1;
2733
2734     case PRE_MODIFY:
2735     case POST_MODIFY:
2736       {
2737         rtx op0 = XEXP (op, 0);
2738         rtx op1 = XEXP (op, 1);
2739         
2740         if ((GET_CODE (op1) != PLUS && GET_CODE (op1) != MINUS)
2741             || (op0 != XEXP (op1, 0)))
2742           return 0;
2743         
2744         op0 = XEXP (op1, 0);
2745         op1 = XEXP (op1, 1);
2746         return REG_P (op0) && REG_P (op1);
2747         /* Pre or post_modify with a displacement of 0 or 1 
2748            should not be generated.  */
2749       }
2750       break;
2751
2752     case PLUS:
2753       {
2754         rtx op0 = XEXP (op, 0);
2755         rtx op1 = XEXP (op, 1);
2756
2757         if (!REG_P (op0))
2758           return 0;
2759
2760         if (REG_P (op1))
2761           return 1;
2762
2763         if (GET_CODE (op1) != CONST_INT)
2764           return 0;
2765         
2766         /* HImode and HFmode must be offsettable.  */
2767         if (mode == HImode || mode == HFmode)
2768           return IS_DISP1_OFF_CONST (INTVAL (op1));
2769         
2770         return IS_DISP1_CONST (INTVAL (op1));
2771       }
2772       break;
2773
2774     default:
2775       break;
2776     }
2777   return 0;
2778 }
2779
2780
2781 static int
2782 c4x_S_indirect (rtx op)
2783 {
2784   enum machine_mode mode = GET_MODE (op);
2785   if (GET_CODE (op) != MEM)
2786     return 0;
2787
2788   op = XEXP (op, 0);
2789   switch (GET_CODE (op))
2790     {
2791     case PRE_DEC:
2792     case POST_DEC:
2793       if (mode != QImode && mode != QFmode)
2794         return 0;
2795     case PRE_INC:
2796     case POST_INC:
2797       op = XEXP (op, 0);
2798
2799     case REG:
2800       return IS_ADDR_OR_PSEUDO_REG (op);
2801
2802     case PRE_MODIFY:
2803     case POST_MODIFY:
2804       {
2805         rtx op0 = XEXP (op, 0);
2806         rtx op1 = XEXP (op, 1);
2807         
2808         if (mode != QImode && mode != QFmode)
2809           return 0;
2810
2811         if ((GET_CODE (op1) != PLUS && GET_CODE (op1) != MINUS)
2812             || (op0 != XEXP (op1, 0)))
2813           return 0;
2814         
2815         op0 = XEXP (op1, 0);
2816         op1 = XEXP (op1, 1);
2817         return REG_P (op0) && IS_ADDR_OR_PSEUDO_REG (op0)
2818           && REG_P (op1) && IS_INDEX_OR_PSEUDO_REG (op1);
2819         /* Pre or post_modify with a displacement of 0 or 1 
2820            should not be generated.  */
2821       }
2822
2823     case PLUS:
2824       {
2825         rtx op0 = XEXP (op, 0);
2826         rtx op1 = XEXP (op, 1);
2827
2828         if (REG_P (op0))
2829           {
2830             /* HImode and HFmode must be offsettable.  */
2831             if (mode == HImode || mode == HFmode)
2832               return IS_ADDR_OR_PSEUDO_REG (op0)
2833                 && GET_CODE (op1) == CONST_INT 
2834                 && IS_DISP1_OFF_CONST (INTVAL (op1));
2835
2836             if (REG_P (op1))
2837               return (IS_INDEX_OR_PSEUDO_REG (op1)
2838                       && IS_ADDR_OR_PSEUDO_REG (op0))
2839                 || (IS_ADDR_OR_PSEUDO_REG (op1)
2840                     && IS_INDEX_OR_PSEUDO_REG (op0));
2841             
2842             return IS_ADDR_OR_PSEUDO_REG (op0)
2843               && GET_CODE (op1) == CONST_INT 
2844               && IS_DISP1_CONST (INTVAL (op1));
2845           }
2846       }
2847       break;
2848
2849     default:
2850       break;
2851     }
2852   return 0;
2853 }
2854
2855
2856 /* Direct memory operand.  */
2857
2858 int
2859 c4x_T_constraint (rtx op)
2860 {
2861   if (GET_CODE (op) != MEM)
2862     return 0;
2863   op = XEXP (op, 0);
2864
2865   if (GET_CODE (op) != LO_SUM)
2866     {
2867       /* Allow call operands.  */
2868       return GET_CODE (op) == SYMBOL_REF
2869         && GET_MODE (op) == Pmode
2870         && SYMBOL_REF_FUNCTION_P (op);
2871     }
2872
2873   /* HImode and HFmode are not offsettable.  */
2874   if (GET_MODE (op) == HImode || GET_CODE (op) == HFmode)
2875     return 0;
2876
2877   if ((GET_CODE (XEXP (op, 0)) == REG)
2878       && (REGNO (XEXP (op, 0)) == DP_REGNO))
2879     return c4x_U_constraint (XEXP (op, 1));
2880   
2881   return 0;
2882 }
2883
2884
2885 /* Symbolic operand.  */
2886
2887 int
2888 c4x_U_constraint (rtx op)
2889 {
2890   /* Don't allow direct addressing to an arbitrary constant.  */
2891   return GET_CODE (op) == CONST
2892          || GET_CODE (op) == SYMBOL_REF
2893          || GET_CODE (op) == LABEL_REF;
2894 }
2895
2896
2897 int
2898 c4x_autoinc_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2899 {
2900   if (GET_CODE (op) == MEM)
2901     {
2902       enum rtx_code code = GET_CODE (XEXP (op, 0));
2903       
2904       if (code == PRE_INC
2905           || code == PRE_DEC
2906           || code == POST_INC
2907           || code == POST_DEC
2908           || code == PRE_MODIFY
2909           || code == POST_MODIFY
2910           )
2911         return 1;
2912     }
2913   return 0;
2914 }
2915
2916
2917 /* Match any operand.  */
2918
2919 int
2920 any_operand (register rtx op ATTRIBUTE_UNUSED,
2921              enum machine_mode mode ATTRIBUTE_UNUSED)
2922 {
2923   return 1;
2924 }
2925
2926
2927 /* Nonzero if OP is a floating point value with value 0.0.  */
2928
2929 int
2930 fp_zero_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2931 {
2932   REAL_VALUE_TYPE r;
2933
2934   if (GET_CODE (op) != CONST_DOUBLE)
2935     return 0;
2936   REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2937   return REAL_VALUES_EQUAL (r, dconst0);
2938 }
2939
2940
2941 int
2942 const_operand (register rtx op, register enum machine_mode mode)
2943 {
2944   switch (mode)
2945     {
2946     case QFmode:
2947     case HFmode:
2948       if (GET_CODE (op) != CONST_DOUBLE
2949           || GET_MODE (op) != mode
2950           || GET_MODE_CLASS (mode) != MODE_FLOAT)
2951         return 0;
2952
2953       return c4x_immed_float_p (op);
2954
2955 #if Pmode != QImode
2956     case Pmode:
2957 #endif
2958     case QImode:
2959       if (GET_CODE (op) != CONST_INT
2960           || (GET_MODE (op) != VOIDmode && GET_MODE (op) != mode)
2961           || GET_MODE_CLASS (mode) != MODE_INT)
2962         return 0;
2963
2964       return IS_HIGH_CONST (INTVAL (op)) || IS_INT16_CONST (INTVAL (op));
2965
2966     case HImode:
2967       return 0;
2968
2969     default:
2970       return 0;
2971     }
2972 }
2973
2974
2975 int
2976 stik_const_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2977 {
2978   return c4x_K_constant (op);
2979 }
2980
2981
2982 int
2983 not_const_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2984 {
2985   return c4x_N_constant (op);
2986 }
2987
2988
2989 int
2990 reg_operand (rtx op, enum machine_mode mode)
2991 {
2992   if (GET_CODE (op) == SUBREG
2993       && GET_MODE (op) == QFmode)
2994     return 0;
2995   return register_operand (op, mode);
2996 }
2997
2998
2999 int
3000 mixed_subreg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
3001 {
3002   /* Allow (subreg:HF (reg:HI)) that be generated for a union of an
3003      int and a long double.  */
3004   if (GET_CODE (op) == SUBREG
3005       && (GET_MODE (op) == QFmode)
3006       && (GET_MODE (SUBREG_REG (op)) == QImode
3007           || GET_MODE (SUBREG_REG (op)) == HImode))
3008     return 1;
3009   return 0;
3010 }
3011
3012
3013 int
3014 reg_imm_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
3015 {
3016   if (REG_P (op) || CONSTANT_P (op))
3017     return 1;
3018   return 0;
3019 }
3020
3021
3022 int
3023 not_modify_reg (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
3024 {
3025   if (REG_P (op) || CONSTANT_P (op))
3026     return 1;
3027   if (GET_CODE (op) != MEM)
3028     return 0;
3029   op = XEXP (op, 0);
3030   switch (GET_CODE (op))
3031     {
3032     case REG:
3033       return 1;
3034
3035     case PLUS:
3036       {
3037         rtx op0 = XEXP (op, 0);
3038         rtx op1 = XEXP (op, 1);
3039
3040         if (! REG_P (op0))
3041           return 0;
3042         
3043         if (REG_P (op1) || GET_CODE (op1) == CONST_INT)
3044           return 1;
3045       }
3046
3047     case LO_SUM:
3048       {
3049         rtx op0 = XEXP (op, 0);
3050           
3051         if (REG_P (op0) && REGNO (op0) == DP_REGNO)
3052           return 1;
3053       }
3054       break;
3055      
3056     case CONST:
3057     case SYMBOL_REF:
3058     case LABEL_REF:
3059       return 1;
3060
3061     default:
3062       break;
3063     }
3064   return 0;
3065 }
3066
3067
3068 int
3069 not_rc_reg (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
3070 {
3071   if (REG_P (op) && REGNO (op) == RC_REGNO)
3072     return 0;
3073   return 1;
3074 }
3075
3076
3077 /* Extended precision register R0-R1.  */
3078
3079 int
3080 r0r1_reg_operand (rtx op, enum machine_mode mode)
3081 {
3082   if (! reg_operand (op, mode))
3083     return 0;
3084   if (GET_CODE (op) == SUBREG)
3085     op = SUBREG_REG (op);
3086   return REG_P (op) && IS_R0R1_OR_PSEUDO_REG (op);
3087 }
3088
3089
3090 /* Extended precision register R2-R3.  */
3091
3092 int
3093 r2r3_reg_operand (rtx op, enum machine_mode mode)
3094 {
3095   if (! reg_operand (op, mode))
3096     return 0;
3097   if (GET_CODE (op) == SUBREG)
3098     op = SUBREG_REG (op);
3099   return REG_P (op) && IS_R2R3_OR_PSEUDO_REG (op);
3100 }
3101
3102
3103 /* Low extended precision register R0-R7.  */
3104
3105 int
3106 ext_low_reg_operand (rtx op, enum machine_mode mode)
3107 {
3108   if (! reg_operand (op, mode))
3109     return 0;
3110   if (GET_CODE (op) == SUBREG)
3111     op = SUBREG_REG (op);
3112   return REG_P (op) && IS_EXT_LOW_OR_PSEUDO_REG (op);
3113 }
3114
3115
3116 /* Extended precision register.  */
3117
3118 int
3119 ext_reg_operand (rtx op, enum machine_mode mode)
3120 {
3121   if (! reg_operand (op, mode))
3122     return 0;
3123   if (GET_CODE (op) == SUBREG)
3124     op = SUBREG_REG (op);
3125   if (! REG_P (op))
3126     return 0;
3127   return IS_EXT_OR_PSEUDO_REG (op);
3128 }
3129
3130
3131 /* Standard precision register.  */
3132
3133 int
3134 std_reg_operand (rtx op, enum machine_mode mode)
3135 {
3136   if (! reg_operand (op, mode))
3137     return 0;
3138   if (GET_CODE (op) == SUBREG)
3139     op = SUBREG_REG (op);
3140   return REG_P (op) && IS_STD_OR_PSEUDO_REG (op);
3141 }
3142
3143 /* Standard precision or normal register.  */
3144
3145 int
3146 std_or_reg_operand (rtx op, enum machine_mode mode)
3147 {
3148   if (reload_in_progress)
3149     return std_reg_operand (op, mode);
3150   return reg_operand (op, mode);
3151 }
3152
3153 /* Address register.  */
3154
3155 int
3156 addr_reg_operand (rtx op, enum machine_mode mode)
3157 {
3158   if (! reg_operand (op, mode))
3159     return 0;
3160   return c4x_a_register (op);
3161 }
3162
3163
3164 /* Index register.  */
3165
3166 int
3167 index_reg_operand (rtx op, enum machine_mode mode)
3168 {
3169   if (! reg_operand (op, mode))
3170     return 0;
3171   if (GET_CODE (op) == SUBREG)
3172     op = SUBREG_REG (op);
3173   return c4x_x_register (op);
3174 }
3175
3176
3177 /* DP register.  */
3178
3179 int
3180 dp_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
3181 {
3182   return REG_P (op) && IS_DP_OR_PSEUDO_REG (op);
3183 }
3184
3185
3186 /* SP register.  */
3187
3188 int
3189 sp_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
3190 {
3191   return REG_P (op) && IS_SP_OR_PSEUDO_REG (op);
3192 }
3193
3194
3195 /* ST register.  */
3196
3197 int
3198 st_reg_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
3199 {
3200   return REG_P (op) && IS_ST_OR_PSEUDO_REG (op);
3201 }
3202
3203
3204 /* RC register.  */
3205
3206 int
3207 rc_reg_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
3208 {
3209   return REG_P (op) && IS_RC_OR_PSEUDO_REG (op);
3210 }
3211
3212
3213 int
3214 call_address_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
3215 {
3216   return (REG_P (op) || symbolic_address_operand (op, mode));
3217 }
3218
3219
3220 /* Symbolic address operand.  */
3221
3222 int
3223 symbolic_address_operand (register rtx op,
3224                           enum machine_mode mode ATTRIBUTE_UNUSED)
3225 {
3226   switch (GET_CODE (op))
3227     {
3228     case CONST:
3229     case SYMBOL_REF:
3230     case LABEL_REF:
3231       return 1;
3232     default:
3233       return 0;
3234     }
3235 }
3236
3237
3238 /* Check dst operand of a move instruction.  */
3239
3240 int
3241 dst_operand (rtx op, enum machine_mode mode)
3242 {
3243   if (GET_CODE (op) == SUBREG
3244       && mixed_subreg_operand (op, mode))
3245     return 0;
3246
3247   if (REG_P (op))
3248     return reg_operand (op, mode);
3249
3250   return nonimmediate_operand (op, mode);
3251 }
3252
3253
3254 /* Check src operand of two operand arithmetic instructions.  */
3255
3256 int
3257 src_operand (rtx op, enum machine_mode mode)
3258 {
3259   if (GET_CODE (op) == SUBREG
3260       && mixed_subreg_operand (op, mode))
3261     return 0;
3262
3263   if (REG_P (op))
3264     return reg_operand (op, mode);
3265
3266   if (mode == VOIDmode)
3267     mode = GET_MODE (op);
3268
3269   if (GET_CODE (op) == CONST_INT)
3270     return (mode == QImode || mode == Pmode || mode == HImode)
3271       && c4x_I_constant (op);
3272
3273   /* We don't like CONST_DOUBLE integers.  */
3274   if (GET_CODE (op) == CONST_DOUBLE)
3275     return c4x_H_constant (op);
3276
3277   /* Disallow symbolic addresses.  Only the predicate
3278      symbolic_address_operand will match these.  */
3279   if (GET_CODE (op) == SYMBOL_REF
3280       || GET_CODE (op) == LABEL_REF
3281       || GET_CODE (op) == CONST)
3282     return 0;
3283
3284   /* If TARGET_LOAD_DIRECT_MEMS is nonzero, disallow direct memory
3285      access to symbolic addresses.  These operands will get forced
3286      into a register and the movqi expander will generate a
3287      HIGH/LO_SUM pair if TARGET_EXPOSE_LDP is nonzero.  */
3288   if (GET_CODE (op) == MEM
3289       && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3290            || GET_CODE (XEXP (op, 0)) == LABEL_REF
3291            || GET_CODE (XEXP (op, 0)) == CONST)))
3292     return !TARGET_EXPOSE_LDP && 
3293       ! TARGET_LOAD_DIRECT_MEMS && GET_MODE (op) == mode;
3294
3295   return general_operand (op, mode);
3296 }
3297
3298
3299 int
3300 src_hi_operand (rtx op, enum machine_mode mode)
3301 {
3302   if (c4x_O_constant (op))
3303     return 1;
3304   return src_operand (op, mode);
3305 }
3306
3307
3308 /* Check src operand of two operand logical instructions.  */
3309
3310 int
3311 lsrc_operand (rtx op, enum machine_mode mode)
3312 {
3313   if (mode == VOIDmode)
3314     mode = GET_MODE (op);
3315
3316   if (mode != QImode && mode != Pmode)
3317     fatal_insn ("mode not QImode", op);
3318
3319   if (GET_CODE (op) == CONST_INT)
3320     return c4x_L_constant (op) || c4x_J_constant (op);
3321
3322   return src_operand (op, mode);
3323 }
3324
3325
3326 /* Check src operand of two operand tricky instructions.  */
3327
3328 int
3329 tsrc_operand (rtx op, enum machine_mode mode)
3330 {
3331   if (mode == VOIDmode)
3332     mode = GET_MODE (op);
3333
3334   if (mode != QImode && mode != Pmode)
3335     fatal_insn ("mode not QImode", op);
3336
3337   if (GET_CODE (op) == CONST_INT)
3338     return c4x_L_constant (op) || c4x_N_constant (op) || c4x_J_constant (op);
3339
3340   return src_operand (op, mode);
3341 }
3342
3343
3344 /* Check src operand of two operand non immediate instructions.  */
3345
3346 int
3347 nonimmediate_src_operand (rtx op, enum machine_mode mode)
3348 {
3349   if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
3350     return 0;
3351
3352   return src_operand (op, mode);
3353 }
3354
3355
3356 /* Check logical src operand of two operand non immediate instructions.  */
3357
3358 int
3359 nonimmediate_lsrc_operand (rtx op, enum machine_mode mode)
3360 {
3361   if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
3362     return 0;
3363
3364   return lsrc_operand (op, mode);
3365 }
3366
3367
3368 int
3369 reg_or_const_operand (rtx op, enum machine_mode mode)
3370 {
3371   return reg_operand (op, mode) || const_operand (op, mode);
3372 }
3373
3374
3375 /* Check for indirect operands allowable in parallel instruction.  */
3376
3377 int
3378 par_ind_operand (rtx op, enum machine_mode mode)
3379 {
3380   if (mode != VOIDmode && mode != GET_MODE (op))
3381     return 0;
3382
3383   return c4x_S_indirect (op);
3384 }
3385
3386
3387 /* Check for operands allowable in parallel instruction.  */
3388
3389 int
3390 parallel_operand (rtx op, enum machine_mode mode)
3391 {
3392   return ext_low_reg_operand (op, mode) || par_ind_operand (op, mode);
3393 }
3394
3395
3396 static void 
3397 c4x_S_address_parse (rtx op, int *base, int *incdec, int *index, int *disp)
3398 {
3399   *base = 0;
3400   *incdec = 0;
3401   *index = 0;
3402   *disp = 0;
3403        
3404   if (GET_CODE (op) != MEM)
3405     fatal_insn ("invalid indirect memory address", op);
3406   
3407   op = XEXP (op, 0);
3408   switch (GET_CODE (op))
3409     {
3410     case PRE_DEC:
3411       *base = REGNO (XEXP (op, 0));
3412       *incdec = 1;
3413       *disp = -1;
3414       return;
3415
3416     case POST_DEC:
3417       *base = REGNO (XEXP (op, 0));
3418       *incdec = 1;
3419       *disp = 0;
3420       return;
3421
3422     case PRE_INC:
3423       *base = REGNO (XEXP (op, 0));
3424       *incdec = 1;
3425       *disp = 1;
3426       return;
3427
3428     case POST_INC:
3429       *base = REGNO (XEXP (op, 0));
3430       *incdec = 1;
3431       *disp = 0;
3432       return;
3433
3434     case POST_MODIFY:
3435       *base = REGNO (XEXP (op, 0));
3436       if (REG_P (XEXP (XEXP (op, 1), 1)))
3437         {
3438           *index = REGNO (XEXP (XEXP (op, 1), 1));
3439           *disp = 0;            /* ??? */
3440         }
3441       else
3442           *disp = INTVAL (XEXP (XEXP (op, 1), 1));
3443       *incdec = 1;
3444       return;
3445
3446     case PRE_MODIFY:
3447       *base = REGNO (XEXP (op, 0));
3448       if (REG_P (XEXP (XEXP (op, 1), 1)))
3449         {
3450           *index = REGNO (XEXP (XEXP (op, 1), 1));
3451           *disp = 1;            /* ??? */
3452         }
3453       else
3454           *disp = INTVAL (XEXP (XEXP (op, 1), 1));
3455       *incdec = 1;
3456
3457       return;
3458
3459     case REG:
3460       *base = REGNO (op);
3461       return;
3462
3463     case PLUS:
3464       {
3465         rtx op0 = XEXP (op, 0);
3466         rtx op1 = XEXP (op, 1);
3467
3468         if (c4x_a_register (op0))
3469           {
3470             if (c4x_x_register (op1))
3471               {
3472                 *base = REGNO (op0);
3473                 *index = REGNO (op1);
3474                 return;
3475               }
3476             else if ((GET_CODE (op1) == CONST_INT 
3477                       && IS_DISP1_CONST (INTVAL (op1))))
3478               {
3479                 *base = REGNO (op0);
3480                 *disp = INTVAL (op1);
3481                 return;
3482               }
3483           }
3484         else if (c4x_x_register (op0) && c4x_a_register (op1))
3485           {
3486             *base = REGNO (op1);
3487             *index = REGNO (op0);
3488             return;
3489           }
3490       }
3491       /* Fall through.  */
3492
3493     default:
3494       fatal_insn ("invalid indirect (S) memory address", op);
3495     }
3496 }
3497
3498
3499 int
3500 c4x_address_conflict (rtx op0, rtx op1, int store0, int store1)
3501 {
3502   int base0;
3503   int base1;
3504   int incdec0;
3505   int incdec1;
3506   int index0;
3507   int index1;
3508   int disp0;
3509   int disp1;
3510   
3511   if (MEM_VOLATILE_P (op0) && MEM_VOLATILE_P (op1))
3512     return 1;
3513
3514   c4x_S_address_parse (op0, &base0, &incdec0, &index0, &disp0);
3515   c4x_S_address_parse (op1, &base1, &incdec1, &index1, &disp1);
3516
3517   if (store0 && store1)
3518     {
3519       /* If we have two stores in parallel to the same address, then
3520          the C4x only executes one of the stores.  This is unlikely to
3521          cause problems except when writing to a hardware device such
3522          as a FIFO since the second write will be lost.  The user
3523          should flag the hardware location as being volatile so that
3524          we don't do this optimization.  While it is unlikely that we
3525          have an aliased address if both locations are not marked
3526          volatile, it is probably safer to flag a potential conflict
3527          if either location is volatile.  */
3528       if (! flag_argument_noalias)
3529         {
3530           if (MEM_VOLATILE_P (op0) || MEM_VOLATILE_P (op1))
3531             return 1;
3532         }
3533     }
3534
3535   /* If have a parallel load and a store to the same address, the load
3536      is performed first, so there is no conflict.  Similarly, there is
3537      no conflict if have parallel loads from the same address.  */
3538
3539   /* Cannot use auto increment or auto decrement twice for same
3540      base register.  */
3541   if (base0 == base1 && incdec0 && incdec0)
3542     return 1;
3543
3544   /* It might be too confusing for GCC if we have use a base register
3545      with a side effect and a memory reference using the same register
3546      in parallel.  */
3547   if (! TARGET_DEVEL && base0 == base1 && (incdec0 || incdec1))
3548     return 1;
3549
3550   /* We cannot optimize the case where op1 and op2 refer to the same
3551      address.  */
3552   if (base0 == base1 && disp0 == disp1 && index0 == index1)
3553     return 1;
3554
3555   /* No conflict.  */
3556   return 0;
3557 }
3558
3559
3560 /* Check for while loop inside a decrement and branch loop.  */
3561
3562 int
3563 c4x_label_conflict (rtx insn, rtx jump, rtx db)
3564 {
3565   while (insn)
3566     {
3567       if (GET_CODE (insn) == CODE_LABEL)
3568         {
3569           if (CODE_LABEL_NUMBER (jump) == CODE_LABEL_NUMBER (insn))
3570             return 1;
3571           if (CODE_LABEL_NUMBER (db) == CODE_LABEL_NUMBER (insn))
3572             return 0;
3573         }
3574       insn = PREV_INSN (insn);
3575     }
3576   return 1;
3577 }
3578
3579
3580 /* Validate combination of operands for parallel load/store instructions.  */
3581
3582 int
3583 valid_parallel_load_store (rtx *operands,
3584                            enum machine_mode mode ATTRIBUTE_UNUSED)
3585 {
3586   rtx op0 = operands[0];
3587   rtx op1 = operands[1];
3588   rtx op2 = operands[2];
3589   rtx op3 = operands[3];
3590
3591   if (GET_CODE (op0) == SUBREG)
3592     op0 = SUBREG_REG (op0);
3593   if (GET_CODE (op1) == SUBREG)
3594     op1 = SUBREG_REG (op1);
3595   if (GET_CODE (op2) == SUBREG)
3596     op2 = SUBREG_REG (op2);
3597   if (GET_CODE (op3) == SUBREG)
3598     op3 = SUBREG_REG (op3);
3599
3600   /* The patterns should only allow ext_low_reg_operand() or
3601      par_ind_operand() operands.  Thus of the 4 operands, only 2
3602      should be REGs and the other 2 should be MEMs.  */
3603
3604   /* This test prevents the multipack pass from using this pattern if
3605      op0 is used as an index or base register in op2 or op3, since
3606      this combination will require reloading.  */
3607   if (GET_CODE (op0) == REG
3608       && ((GET_CODE (op2) == MEM && reg_mentioned_p (op0, XEXP (op2, 0)))
3609           || (GET_CODE (op3) == MEM && reg_mentioned_p (op0, XEXP (op3, 0)))))
3610     return 0;
3611
3612   /* LDI||LDI.  */
3613   if (GET_CODE (op0) == REG && GET_CODE (op2) == REG)
3614     return (REGNO (op0) != REGNO (op2))
3615       && GET_CODE (op1) == MEM && GET_CODE (op3) == MEM
3616       && ! c4x_address_conflict (op1, op3, 0, 0);
3617
3618   /* STI||STI.  */
3619   if (GET_CODE (op1) == REG && GET_CODE (op3) == REG)
3620     return GET_CODE (op0) == MEM && GET_CODE (op2) == MEM
3621       && ! c4x_address_conflict (op0, op2, 1, 1);
3622
3623   /* LDI||STI.  */
3624   if (GET_CODE (op0) == REG && GET_CODE (op3) == REG)
3625     return GET_CODE (op1) == MEM && GET_CODE (op2) == MEM
3626       && ! c4x_address_conflict (op1, op2, 0, 1);
3627
3628   /* STI||LDI.  */
3629   if (GET_CODE (op1) == REG && GET_CODE (op2) == REG)
3630     return GET_CODE (op0) == MEM && GET_CODE (op3) == MEM
3631       && ! c4x_address_conflict (op0, op3, 1, 0);
3632
3633   return 0;
3634 }
3635
3636
3637 int
3638 valid_parallel_operands_4 (rtx *operands,
3639                            enum machine_mode mode ATTRIBUTE_UNUSED)
3640 {
3641   rtx op0 = operands[0];
3642   rtx op2 = operands[2];
3643
3644   if (GET_CODE (op0) == SUBREG)
3645     op0 = SUBREG_REG (op0);
3646   if (GET_CODE (op2) == SUBREG)
3647     op2 = SUBREG_REG (op2);
3648
3649   /* This test prevents the multipack pass from using this pattern if
3650      op0 is used as an index or base register in op2, since this combination
3651      will require reloading.  */
3652   if (GET_CODE (op0) == REG
3653       && GET_CODE (op2) == MEM
3654       && reg_mentioned_p (op0, XEXP (op2, 0)))
3655     return 0;
3656
3657   return 1;
3658 }
3659
3660
3661 int
3662 valid_parallel_operands_5 (rtx *operands,
3663                            enum machine_mode mode ATTRIBUTE_UNUSED)
3664 {
3665   int regs = 0;
3666   rtx op0 = operands[0];
3667   rtx op1 = operands[1];
3668   rtx op2 = operands[2];
3669   rtx op3 = operands[3];
3670
3671   if (GET_CODE (op0) == SUBREG)
3672     op0 = SUBREG_REG (op0);
3673   if (GET_CODE (op1) == SUBREG)
3674     op1 = SUBREG_REG (op1);
3675   if (GET_CODE (op2) == SUBREG)
3676     op2 = SUBREG_REG (op2);
3677
3678   /* The patterns should only allow ext_low_reg_operand() or
3679      par_ind_operand() operands.  Operands 1 and 2 may be commutative
3680      but only one of them can be a register.  */
3681   if (GET_CODE (op1) == REG)
3682     regs++;
3683   if (GET_CODE (op2) == REG)
3684     regs++;
3685
3686   if (regs != 1)
3687     return 0;
3688
3689   /* This test prevents the multipack pass from using this pattern if
3690      op0 is used as an index or base register in op3, since this combination
3691      will require reloading.  */
3692   if (GET_CODE (op0) == REG
3693       && GET_CODE (op3) == MEM
3694       && reg_mentioned_p (op0, XEXP (op3, 0)))
3695     return 0;
3696
3697   return 1;
3698 }
3699
3700
3701 int
3702 valid_parallel_operands_6 (rtx *operands,
3703                            enum machine_mode mode ATTRIBUTE_UNUSED)
3704 {
3705   int regs = 0;
3706   rtx op0 = operands[0];
3707   rtx op1 = operands[1];
3708   rtx op2 = operands[2];
3709   rtx op4 = operands[4];
3710   rtx op5 = operands[5];
3711
3712   if (GET_CODE (op1) == SUBREG)
3713     op1 = SUBREG_REG (op1);
3714   if (GET_CODE (op2) == SUBREG)
3715     op2 = SUBREG_REG (op2);
3716   if (GET_CODE (op4) == SUBREG)
3717     op4 = SUBREG_REG (op4);
3718   if (GET_CODE (op5) == SUBREG)
3719     op5 = SUBREG_REG (op5);
3720
3721   /* The patterns should only allow ext_low_reg_operand() or
3722      par_ind_operand() operands.  Thus of the 4 input operands, only 2
3723      should be REGs and the other 2 should be MEMs.  */
3724
3725   if (GET_CODE (op1) == REG)
3726     regs++;
3727   if (GET_CODE (op2) == REG)
3728     regs++;
3729   if (GET_CODE (op4) == REG)
3730     regs++;
3731   if (GET_CODE (op5) == REG)
3732     regs++;
3733
3734   /* The new C30/C40 silicon dies allow 3 regs of the 4 input operands. 
3735      Perhaps we should count the MEMs as well?  */
3736   if (regs != 2)
3737     return 0;
3738
3739   /* This test prevents the multipack pass from using this pattern if
3740      op0 is used as an index or base register in op4 or op5, since
3741      this combination will require reloading.  */
3742   if (GET_CODE (op0) == REG
3743       && ((GET_CODE (op4) == MEM && reg_mentioned_p (op0, XEXP (op4, 0)))
3744           || (GET_CODE (op5) == MEM && reg_mentioned_p (op0, XEXP (op5, 0)))))
3745     return 0;
3746
3747   return 1;
3748 }
3749
3750
3751 /* Validate combination of src operands.  Note that the operands have
3752    been screened by the src_operand predicate.  We just have to check
3753    that the combination of operands is valid.  If FORCE is set, ensure
3754    that the destination regno is valid if we have a 2 operand insn.  */
3755
3756 static int
3757 c4x_valid_operands (enum rtx_code code, rtx *operands,
3758                     enum machine_mode mode ATTRIBUTE_UNUSED,
3759                     int force)
3760 {
3761   rtx op0;
3762   rtx op1;
3763   rtx op2;
3764   enum rtx_code code1;
3765   enum rtx_code code2;
3766
3767
3768   /* FIXME, why can't we tighten the operands for IF_THEN_ELSE?  */
3769   if (code == IF_THEN_ELSE)
3770       return 1 || (operands[0] == operands[2] || operands[0] == operands[3]);
3771
3772   if (code == COMPARE)
3773     {
3774       op1 = operands[0];
3775       op2 = operands[1];
3776     }
3777   else
3778     {
3779       op1 = operands[1];
3780       op2 = operands[2];
3781     }
3782
3783   op0 = operands[0];
3784
3785   if (GET_CODE (op0) == SUBREG)
3786     op0 = SUBREG_REG (op0);
3787   if (GET_CODE (op1) == SUBREG)
3788     op1 = SUBREG_REG (op1);
3789   if (GET_CODE (op2) == SUBREG)
3790     op2 = SUBREG_REG (op2);
3791
3792   code1 = GET_CODE (op1);
3793   code2 = GET_CODE (op2);
3794
3795   
3796   if (code1 == REG && code2 == REG)
3797     return 1;
3798
3799   if (code1 == MEM && code2 == MEM)
3800     {
3801       if (c4x_S_indirect (op1) && c4x_S_indirect (op2))
3802         return 1;
3803       return c4x_R_indirect (op1) && c4x_R_indirect (op2);
3804     }
3805
3806   /* We cannot handle two MEMs or two CONSTS, etc.  */
3807   if (code1 == code2)
3808     return 0;
3809
3810   if (code1 == REG)
3811     {
3812       switch (code2)
3813         {
3814         case CONST_INT:
3815           if (c4x_J_constant (op2) && c4x_R_indirect (op1))
3816             return 1;
3817           break;
3818           
3819         case CONST_DOUBLE:
3820           if (! c4x_H_constant (op2))
3821             return 0;
3822           break;
3823
3824           /* Any valid memory operand screened by src_operand is OK.  */
3825         case MEM:
3826           break;
3827           
3828         default:
3829           fatal_insn ("c4x_valid_operands: Internal error", op2);
3830           break;
3831         }
3832       
3833       if (GET_CODE (op0) == SCRATCH)
3834           return 1;
3835
3836       if (!REG_P (op0))
3837           return 0;
3838
3839       /* Check that we have a valid destination register for a two operand
3840          instruction.  */
3841       return ! force || code == COMPARE || REGNO (op1) == REGNO (op0);
3842     }
3843
3844
3845   /* Check non-commutative operators.  */
3846   if (code == ASHIFTRT || code == LSHIFTRT
3847       || code == ASHIFT || code == COMPARE)
3848     return code2 == REG
3849       && (c4x_S_indirect (op1) || c4x_R_indirect (op1));
3850
3851
3852   /* Assume MINUS is commutative since the subtract patterns
3853      also support the reverse subtract instructions.  Since op1
3854      is not a register, and op2 is a register, op1 can only
3855      be a restricted memory operand for a shift instruction.  */
3856   if (code2 == REG)
3857     {
3858       switch (code1)
3859         {
3860         case CONST_INT:
3861           break;
3862       
3863         case CONST_DOUBLE:
3864           if (! c4x_H_constant (op1))
3865             return 0;
3866           break;
3867
3868           /* Any valid memory operand screened by src_operand is OK.  */      
3869         case MEM:
3870           break;
3871           
3872         default:
3873           abort ();
3874           break;
3875         }
3876
3877       if (GET_CODE (op0) == SCRATCH)
3878           return 1;
3879
3880       if (!REG_P (op0))
3881           return 0;
3882
3883       /* Check that we have a valid destination register for a two operand
3884          instruction.  */
3885       return ! force || REGNO (op1) == REGNO (op0);
3886     }
3887       
3888   if (c4x_J_constant (op1) && c4x_R_indirect (op2))
3889     return 1;
3890
3891   return 0;
3892 }
3893
3894
3895 int valid_operands (enum rtx_code code, rtx *operands, enum machine_mode mode)
3896 {
3897
3898   /* If we are not optimizing then we have to let anything go and let
3899      reload fix things up.  instantiate_decl in function.c can produce
3900      invalid insns by changing the offset of a memory operand from a
3901      valid one into an invalid one, when the second operand is also a
3902      memory operand.  The alternative is not to allow two memory
3903      operands for an insn when not optimizing.  The problem only rarely
3904      occurs, for example with the C-torture program DFcmp.c.  */
3905
3906   return ! optimize || c4x_valid_operands (code, operands, mode, 0);
3907 }
3908
3909
3910 int
3911 legitimize_operands (enum rtx_code code, rtx *operands, enum machine_mode mode)
3912 {
3913   /* Compare only has 2 operands.  */
3914   if (code == COMPARE)
3915     {
3916       /* During RTL generation, force constants into pseudos so that
3917          they can get hoisted out of loops.  This will tie up an extra
3918          register but can save an extra cycle.  Only do this if loop
3919          optimization enabled.  (We cannot pull this trick for add and
3920          sub instructions since the flow pass won't find
3921          autoincrements etc.)  This allows us to generate compare
3922          instructions like CMPI R0, *AR0++ where R0 = 42, say, instead
3923          of LDI *AR0++, R0; CMPI 42, R0. 
3924
3925          Note that expand_binops will try to load an expensive constant
3926          into a register if it is used within a loop.  Unfortunately,
3927          the cost mechanism doesn't allow us to look at the other
3928          operand to decide whether the constant is expensive.  */
3929       
3930       if (! reload_in_progress
3931           && TARGET_HOIST
3932           && optimize > 0
3933           && GET_CODE (operands[1]) == CONST_INT 
3934           && rtx_cost (operands[1], code) > 1)
3935         operands[1] = force_reg (mode, operands[1]);
3936       
3937       if (! reload_in_progress
3938           && ! c4x_valid_operands (code, operands, mode, 0))
3939         operands[0] = force_reg (mode, operands[0]);
3940       return 1;
3941     }
3942   
3943   /* We cannot do this for ADDI/SUBI insns since we will
3944      defeat the flow pass from finding autoincrement addressing
3945      opportunities.  */
3946   if (! reload_in_progress
3947       && ! ((code == PLUS || code == MINUS) && mode == Pmode)
3948       && TARGET_HOIST
3949       && optimize > 1
3950       && GET_CODE (operands[2]) == CONST_INT
3951       && rtx_cost (operands[2], code) > 1)
3952     operands[2] = force_reg (mode, operands[2]);
3953
3954   /* We can get better code on a C30 if we force constant shift counts
3955      into a register.  This way they can get hoisted out of loops,
3956      tying up a register but saving an instruction.  The downside is
3957      that they may get allocated to an address or index register, and
3958      thus we will get a pipeline conflict if there is a nearby
3959      indirect address using an address register. 
3960
3961      Note that expand_binops will not try to load an expensive constant
3962      into a register if it is used within a loop for a shift insn.  */
3963   
3964   if (! reload_in_progress
3965       && ! c4x_valid_operands (code, operands, mode, TARGET_FORCE))
3966     {
3967       /* If the operand combination is invalid, we force operand1 into a
3968          register, preventing reload from having doing to do this at a
3969          later stage.  */
3970       operands[1] = force_reg (mode, operands[1]);
3971       if (TARGET_FORCE)
3972         {
3973           emit_move_insn (operands[0], operands[1]);
3974           operands[1] = copy_rtx (operands[0]);
3975         }
3976       else
3977         {
3978           /* Just in case...  */
3979           if (! c4x_valid_operands (code, operands, mode, 0))
3980             operands[2] = force_reg (mode, operands[2]);
3981         }
3982     }
3983
3984   /* Right shifts require a negative shift count, but GCC expects
3985      a positive count, so we emit a NEG.  */
3986   if ((code == ASHIFTRT || code == LSHIFTRT)
3987       && (GET_CODE (operands[2]) != CONST_INT))
3988     operands[2] = gen_rtx_NEG (mode, negate_rtx (mode, operands[2]));
3989   
3990
3991   /* When the shift count is greater than 32 then the result 
3992      can be implementation dependent.  We truncate the result to
3993      fit in 5 bits so that we do not emit invalid code when
3994      optimizing---such as trying to generate lhu2 with 20021124-1.c.  */
3995   if (((code == ASHIFTRT || code == LSHIFTRT || code == ASHIFT)
3996       && (GET_CODE (operands[2]) == CONST_INT))
3997       && INTVAL (operands[2]) > (GET_MODE_BITSIZE (mode) - 1))
3998       operands[2]
3999           = GEN_INT (INTVAL (operands[2]) & (GET_MODE_BITSIZE (mode) - 1));
4000
4001   return 1;
4002 }
4003
4004
4005 /* The following predicates are used for instruction scheduling.  */
4006
4007 int
4008 group1_reg_operand (rtx op, enum machine_mode mode)
4009 {
4010   if (mode != VOIDmode && mode != GET_MODE (op))
4011     return 0;
4012   if (GET_CODE (op) == SUBREG)
4013     op = SUBREG_REG (op);
4014   return REG_P (op) && (! reload_completed || IS_GROUP1_REG (op));
4015 }
4016
4017
4018 int
4019 group1_mem_operand (rtx op, enum machine_mode mode)
4020 {
4021   if (mode != VOIDmode && mode != GET_MODE (op))
4022     return 0;
4023
4024   if (GET_CODE (op) == MEM)
4025     {
4026       op = XEXP (op, 0);
4027       if (GET_CODE (op) == PLUS)
4028         {
4029           rtx op0 = XEXP (op, 0);
4030           rtx op1 = XEXP (op, 1);
4031
4032           if ((REG_P (op0) && (! reload_completed || IS_GROUP1_REG (op0)))
4033               || (REG_P (op1) && (! reload_completed || IS_GROUP1_REG (op1))))
4034             return 1;
4035         }
4036       else if ((REG_P (op)) && (! reload_completed || IS_GROUP1_REG (op)))
4037         return 1;
4038     }
4039
4040   return 0;
4041 }
4042
4043
4044 /* Return true if any one of the address registers.  */
4045
4046 int
4047 arx_reg_operand (rtx op, enum machine_mode mode)
4048 {
4049   if (mode != VOIDmode && mode != GET_MODE (op))
4050     return 0;
4051   if (GET_CODE (op) == SUBREG)
4052     op = SUBREG_REG (op);
4053   return REG_P (op) && (! reload_completed || IS_ADDR_REG (op));
4054 }
4055
4056
4057 static int
4058 c4x_arn_reg_operand (rtx op, enum machine_mode mode, unsigned int regno)
4059 {
4060   if (mode != VOIDmode && mode != GET_MODE (op))
4061     return 0;
4062   if (GET_CODE (op) == SUBREG)
4063     op = SUBREG_REG (op);
4064   return REG_P (op) && (! reload_completed || (REGNO (op) == regno));
4065 }
4066
4067
4068 static int
4069 c4x_arn_mem_operand (rtx op, enum machine_mode mode, unsigned int regno)
4070 {
4071   if (mode != VOIDmode && mode != GET_MODE (op))
4072     return 0;
4073
4074   if (GET_CODE (op) == MEM)
4075     {
4076       op = XEXP (op, 0);
4077       switch (GET_CODE (op))
4078         {
4079         case PRE_DEC:
4080         case POST_DEC:
4081         case PRE_INC:
4082         case POST_INC:
4083           op = XEXP (op, 0);
4084
4085         case REG:
4086           return REG_P (op) && (! reload_completed || (REGNO (op) == regno));
4087
4088         case PRE_MODIFY:
4089         case POST_MODIFY:
4090           if (REG_P (XEXP (op, 0)) && (! reload_completed 
4091                                        || (REGNO (XEXP (op, 0)) == regno)))
4092             return 1;
4093           if (REG_P (XEXP (XEXP (op, 1), 1))
4094               && (! reload_completed
4095                   || (REGNO (XEXP (XEXP (op, 1), 1)) == regno)))
4096             return 1;
4097           break;
4098
4099         case PLUS:
4100           {
4101             rtx op0 = XEXP (op, 0);
4102             rtx op1 = XEXP (op, 1);
4103
4104             if ((REG_P (op0) && (! reload_completed
4105                                  || (REGNO (op0) == regno)))
4106                 || (REG_P (op1) && (! reload_completed
4107                                     || (REGNO (op1) == regno))))
4108               return 1;
4109           }
4110           break;
4111
4112         default:
4113           break;
4114         }
4115     }
4116   return 0;
4117 }
4118
4119
4120 int
4121 ar0_reg_operand (rtx op, enum machine_mode mode)
4122 {
4123   return c4x_arn_reg_operand (op, mode, AR0_REGNO);
4124 }
4125
4126
4127 int
4128 ar0_mem_operand (rtx op, enum machine_mode mode)
4129 {
4130   return c4x_arn_mem_operand (op, mode, AR0_REGNO);
4131 }
4132
4133
4134 int
4135 ar1_reg_operand (rtx op, enum machine_mode mode)
4136 {
4137   return c4x_arn_reg_operand (op, mode, AR1_REGNO);
4138 }
4139
4140
4141 int
4142 ar1_mem_operand (rtx op, enum machine_mode mode)
4143 {
4144   return c4x_arn_mem_operand (op, mode, AR1_REGNO);
4145 }
4146
4147
4148 int
4149 ar2_reg_operand (rtx op, enum machine_mode mode)
4150 {
4151   return c4x_arn_reg_operand (op, mode, AR2_REGNO);
4152 }
4153
4154
4155 int
4156 ar2_mem_operand (rtx op, enum machine_mode mode)
4157 {
4158   return c4x_arn_mem_operand (op, mode, AR2_REGNO);
4159 }
4160
4161
4162 int
4163 ar3_reg_operand (rtx op, enum machine_mode mode)
4164 {
4165   return c4x_arn_reg_operand (op, mode, AR3_REGNO);
4166 }
4167
4168
4169 int
4170 ar3_mem_operand (rtx op, enum machine_mode mode)
4171 {
4172   return c4x_arn_mem_operand (op, mode, AR3_REGNO);
4173 }
4174
4175
4176 int
4177 ar4_reg_operand (rtx op, enum machine_mode mode)
4178 {
4179   return c4x_arn_reg_operand (op, mode, AR4_REGNO);
4180 }
4181
4182
4183 int
4184 ar4_mem_operand (rtx op, enum machine_mode mode)
4185 {
4186   return c4x_arn_mem_operand (op, mode, AR4_REGNO);
4187 }
4188
4189
4190 int
4191 ar5_reg_operand (rtx op, enum machine_mode mode)
4192 {
4193   return c4x_arn_reg_operand (op, mode, AR5_REGNO);
4194 }
4195
4196
4197 int
4198 ar5_mem_operand (rtx op, enum machine_mode mode)
4199 {
4200   return c4x_arn_mem_operand (op, mode, AR5_REGNO);
4201 }
4202
4203
4204 int
4205 ar6_reg_operand (rtx op, enum machine_mode mode)
4206 {
4207   return c4x_arn_reg_operand (op, mode, AR6_REGNO);
4208 }
4209
4210
4211 int
4212 ar6_mem_operand (rtx op, enum machine_mode mode)
4213 {
4214   return c4x_arn_mem_operand (op, mode, AR6_REGNO);
4215 }
4216
4217
4218 int
4219 ar7_reg_operand (rtx op, enum machine_mode mode)
4220 {
4221   return c4x_arn_reg_operand (op, mode, AR7_REGNO);
4222 }
4223
4224
4225 int
4226 ar7_mem_operand (rtx op, enum machine_mode mode)
4227 {
4228   return c4x_arn_mem_operand (op, mode, AR7_REGNO);
4229 }
4230
4231
4232 int
4233 ir0_reg_operand (rtx op, enum machine_mode mode)
4234 {
4235   return c4x_arn_reg_operand (op, mode, IR0_REGNO);
4236 }
4237
4238
4239 int
4240 ir0_mem_operand (rtx op, enum machine_mode mode)
4241 {
4242   return c4x_arn_mem_operand (op, mode, IR0_REGNO);
4243 }
4244
4245
4246 int
4247 ir1_reg_operand (rtx op, enum machine_mode mode)
4248 {
4249   return c4x_arn_reg_operand (op, mode, IR1_REGNO);
4250 }
4251
4252
4253 int
4254 ir1_mem_operand (rtx op, enum machine_mode mode)
4255 {
4256   return c4x_arn_mem_operand (op, mode, IR1_REGNO);
4257 }
4258
4259
4260 /* This is similar to operand_subword but allows autoincrement
4261    addressing.  */
4262
4263 rtx
4264 c4x_operand_subword (rtx op, int i, int validate_address,
4265                      enum machine_mode  mode)
4266 {
4267   if (mode != HImode && mode != HFmode)
4268     fatal_insn ("c4x_operand_subword: invalid mode", op);
4269
4270   if (mode == HFmode && REG_P (op))
4271     fatal_insn ("c4x_operand_subword: invalid operand", op);
4272
4273   if (GET_CODE (op) == MEM)
4274     {
4275       enum rtx_code code = GET_CODE (XEXP (op, 0));
4276       enum machine_mode mode = GET_MODE (XEXP (op, 0));
4277       enum machine_mode submode;
4278
4279       submode = mode;
4280       if (mode == HImode)
4281         submode = QImode;
4282       else if (mode == HFmode)
4283         submode = QFmode;
4284
4285       switch (code)
4286         {
4287         case POST_INC:
4288         case PRE_INC:
4289           return gen_rtx_MEM (submode, XEXP (op, 0));
4290           
4291         case POST_DEC:
4292         case PRE_DEC:
4293         case PRE_MODIFY:
4294         case POST_MODIFY:
4295           /* We could handle these with some difficulty.
4296              e.g., *p-- => *(p-=2); *(p+1).  */
4297           fatal_insn ("c4x_operand_subword: invalid autoincrement", op);
4298
4299         case SYMBOL_REF:
4300         case LABEL_REF:
4301         case CONST:
4302         case CONST_INT:
4303           fatal_insn ("c4x_operand_subword: invalid address", op);
4304
4305           /* Even though offsettable_address_p considers (MEM
4306              (LO_SUM)) to be offsettable, it is not safe if the
4307              address is at the end of the data page since we also have
4308              to fix up the associated high PART.  In this case where
4309              we are trying to split a HImode or HFmode memory
4310              reference, we would have to emit another insn to reload a
4311              new HIGH value.  It's easier to disable LO_SUM memory references
4312              in HImode or HFmode and we probably get better code.  */
4313         case LO_SUM:
4314           fatal_insn ("c4x_operand_subword: address not offsettable", op);
4315   
4316         default:
4317           break;
4318         }
4319     }
4320   
4321   return operand_subword (op, i, validate_address, mode);
4322 }
4323
4324 struct name_list
4325 {
4326   struct name_list *next;
4327   const char *name;
4328 };
4329
4330 static struct name_list *global_head;
4331 static struct name_list *extern_head;
4332
4333
4334 /* Add NAME to list of global symbols and remove from external list if
4335    present on external list.  */
4336
4337 void
4338 c4x_global_label (const char *name)
4339 {
4340   struct name_list *p, *last;
4341
4342   /* Do not insert duplicate names, so linearly search through list of
4343      existing names.  */
4344   p = global_head;
4345   while (p)
4346     {
4347       if (strcmp (p->name, name) == 0)
4348         return;
4349       p = p->next;
4350     }
4351   p = (struct name_list *) xmalloc (sizeof *p);
4352   p->next = global_head;
4353   p->name = name;
4354   global_head = p;
4355
4356   /* Remove this name from ref list if present.  */
4357   last = NULL;
4358   p = extern_head;
4359   while (p)
4360     {
4361       if (strcmp (p->name, name) == 0)
4362         {
4363           if (last)
4364             last->next = p->next;
4365           else
4366             extern_head = p->next;
4367           break;
4368         }
4369       last = p;
4370       p = p->next;
4371     }
4372 }
4373
4374
4375 /* Add NAME to list of external symbols.  */
4376
4377 void
4378 c4x_external_ref (const char *name)
4379 {
4380   struct name_list *p;
4381
4382   /* Do not insert duplicate names.  */
4383   p = extern_head;
4384   while (p)
4385     {
4386       if (strcmp (p->name, name) == 0)
4387         return;
4388       p = p->next;
4389     }
4390   
4391   /* Do not insert ref if global found.  */
4392   p = global_head;
4393   while (p)
4394     {
4395       if (strcmp (p->name, name) == 0)
4396         return;
4397       p = p->next;
4398     }
4399   p = (struct name_list *) xmalloc (sizeof *p);
4400   p->next = extern_head;
4401   p->name = name;
4402   extern_head = p;
4403 }
4404
4405 /* We need to have a data section we can identify so that we can set
4406    the DP register back to a data pointer in the small memory model.
4407    This is only required for ISRs if we are paranoid that someone
4408    may have quietly changed this register on the sly.  */
4409 static void
4410 c4x_file_start (void)
4411 {
4412   int dspversion = 0;
4413   if (TARGET_C30) dspversion = 30;
4414   if (TARGET_C31) dspversion = 31;
4415   if (TARGET_C32) dspversion = 32;
4416   if (TARGET_C33) dspversion = 33;
4417   if (TARGET_C40) dspversion = 40;
4418   if (TARGET_C44) dspversion = 44;
4419
4420   default_file_start ();
4421   fprintf (asm_out_file, "\t.version\t%d\n", dspversion);
4422   fputs ("\n\t.data\ndata_sec:\n", asm_out_file);
4423 }
4424
4425
4426 static void
4427 c4x_file_end (void)
4428 {
4429   struct name_list *p;
4430   
4431   /* Output all external names that are not global.  */
4432   p = extern_head;
4433   while (p)
4434     {
4435       fprintf (asm_out_file, "\t.ref\t");
4436       assemble_name (asm_out_file, p->name);
4437       fprintf (asm_out_file, "\n");
4438       p = p->next;
4439     }
4440   fprintf (asm_out_file, "\t.end\n");
4441 }
4442
4443
4444 static void
4445 c4x_check_attribute (const char *attrib, tree list, tree decl, tree *attributes)
4446 {
4447   while (list != NULL_TREE
4448          && IDENTIFIER_POINTER (TREE_PURPOSE (list))
4449          != IDENTIFIER_POINTER (DECL_NAME (decl)))
4450     list = TREE_CHAIN (list);
4451   if (list)
4452     *attributes = tree_cons (get_identifier (attrib), TREE_VALUE (list),
4453                              *attributes);
4454 }
4455
4456
4457 static void
4458 c4x_insert_attributes (tree decl, tree *attributes)
4459 {
4460   switch (TREE_CODE (decl))
4461     {
4462     case FUNCTION_DECL:
4463       c4x_check_attribute ("section", code_tree, decl, attributes);
4464       c4x_check_attribute ("const", pure_tree, decl, attributes);
4465       c4x_check_attribute ("noreturn", noreturn_tree, decl, attributes);
4466       c4x_check_attribute ("interrupt", interrupt_tree, decl, attributes);
4467       c4x_check_attribute ("naked", naked_tree, decl, attributes);
4468       break;
4469
4470     case VAR_DECL:
4471       c4x_check_attribute ("section", data_tree, decl, attributes);
4472       break;
4473
4474     default:
4475       break;
4476     }
4477 }
4478
4479 /* Table of valid machine attributes.  */
4480 const struct attribute_spec c4x_attribute_table[] =
4481 {
4482   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4483   { "interrupt",    0, 0, false, true,  true,  c4x_handle_fntype_attribute },
4484   { "naked",    0, 0, false, true,  true,  c4x_handle_fntype_attribute },
4485   { "leaf_pretend", 0, 0, false, true,  true,  c4x_handle_fntype_attribute },
4486   { NULL,           0, 0, false, false, false, NULL }
4487 };
4488
4489 /* Handle an attribute requiring a FUNCTION_TYPE;
4490    arguments as in struct attribute_spec.handler.  */
4491 static tree
4492 c4x_handle_fntype_attribute (tree *node, tree name,
4493                              tree args ATTRIBUTE_UNUSED,
4494                              int flags ATTRIBUTE_UNUSED,
4495                              bool *no_add_attrs)
4496 {
4497   if (TREE_CODE (*node) != FUNCTION_TYPE)
4498     {
4499       warning ("`%s' attribute only applies to functions",
4500                IDENTIFIER_POINTER (name));
4501       *no_add_attrs = true;
4502     }
4503
4504   return NULL_TREE;
4505 }
4506
4507
4508 /* !!! FIXME to emit RPTS correctly.  */
4509
4510 int
4511 c4x_rptb_rpts_p (rtx insn, rtx op)
4512 {
4513   /* The next insn should be our label marking where the
4514      repeat block starts.  */
4515   insn = NEXT_INSN (insn);
4516   if (GET_CODE (insn) != CODE_LABEL)
4517     {
4518       /* Some insns may have been shifted between the RPTB insn
4519          and the top label... They were probably destined to
4520          be moved out of the loop.  For now, let's leave them
4521          where they are and print a warning.  We should
4522          probably move these insns before the repeat block insn.  */
4523       if (TARGET_DEBUG)
4524         fatal_insn("c4x_rptb_rpts_p: Repeat block top label moved\n",
4525                    insn);
4526       return 0;
4527     }
4528
4529   /* Skip any notes.  */
4530   insn = next_nonnote_insn (insn);
4531
4532   /* This should be our first insn in the loop.  */
4533   if (! INSN_P (insn))
4534     return 0;
4535
4536   /* Skip any notes.  */
4537   insn = next_nonnote_insn (insn);
4538
4539   if (! INSN_P (insn))
4540     return 0;
4541
4542   if (recog_memoized (insn) != CODE_FOR_rptb_end)
4543     return 0;
4544
4545   if (TARGET_RPTS)
4546     return 1;
4547
4548   return (GET_CODE (op) == CONST_INT) && TARGET_RPTS_CYCLES (INTVAL (op));
4549 }
4550
4551
4552 /* Check if register r11 is used as the destination of an insn.  */
4553
4554 static int
4555 c4x_r11_set_p(rtx x)
4556 {
4557   rtx set;
4558   int i, j;
4559   const char *fmt;
4560
4561   if (x == 0)
4562     return 0;
4563
4564   if (INSN_P (x) && GET_CODE (PATTERN (x)) == SEQUENCE)
4565     x = XVECEXP (PATTERN (x), 0, XVECLEN (PATTERN (x), 0) - 1);
4566
4567   if (INSN_P (x) && (set = single_set (x)))
4568     x = SET_DEST (set);
4569
4570   if (GET_CODE (x) == REG && REGNO (x) == R11_REGNO)
4571     return 1;
4572
4573   fmt = GET_RTX_FORMAT (GET_CODE (x));
4574   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4575     {
4576       if (fmt[i] == 'e')
4577         {
4578           if (c4x_r11_set_p (XEXP (x, i)))
4579             return 1;
4580         }
4581       else if (fmt[i] == 'E')
4582         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4583           if (c4x_r11_set_p (XVECEXP (x, i, j)))
4584             return 1;
4585     }
4586   return 0;
4587 }
4588
4589
4590 /* The c4x sometimes has a problem when the insn before the laj insn
4591    sets the r11 register.  Check for this situation.  */
4592
4593 int
4594 c4x_check_laj_p (rtx insn)
4595 {
4596   insn = prev_nonnote_insn (insn);
4597
4598   /* If this is the start of the function no nop is needed.  */
4599   if (insn == 0)
4600     return 0;
4601
4602   /* If the previous insn is a code label we have to insert a nop. This
4603      could be a jump or table jump. We can find the normal jumps by
4604      scanning the function but this will not find table jumps.  */
4605   if (GET_CODE (insn) == CODE_LABEL)
4606     return 1;
4607
4608   /* If the previous insn sets register r11 we have to insert a nop.  */
4609   if (c4x_r11_set_p (insn))
4610     return 1;
4611
4612   /* No nop needed.  */
4613   return 0;
4614 }
4615
4616
4617 /* Adjust the cost of a scheduling dependency.  Return the new cost of
4618    a dependency LINK or INSN on DEP_INSN.  COST is the current cost. 
4619    A set of an address register followed by a use occurs a 2 cycle
4620    stall (reduced to a single cycle on the c40 using LDA), while
4621    a read of an address register followed by a use occurs a single cycle.  */
4622
4623 #define SET_USE_COST    3
4624 #define SETLDA_USE_COST 2
4625 #define READ_USE_COST   2
4626
4627 static int
4628 c4x_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
4629 {
4630   /* Don't worry about this until we know what registers have been
4631      assigned.  */
4632   if (flag_schedule_insns == 0 && ! reload_completed)
4633     return 0;
4634
4635   /* How do we handle dependencies where a read followed by another
4636      read causes a pipeline stall?  For example, a read of ar0 followed
4637      by the use of ar0 for a memory reference.  It looks like we
4638      need to extend the scheduler to handle this case.  */
4639
4640   /* Reload sometimes generates a CLOBBER of a stack slot, e.g.,
4641      (clobber (mem:QI (plus:QI (reg:QI 11 ar3) (const_int 261)))),
4642      so only deal with insns we know about.  */
4643   if (recog_memoized (dep_insn) < 0)
4644     return 0;
4645
4646   if (REG_NOTE_KIND (link) == 0)
4647     {
4648       int max = 0;
4649
4650       /* Data dependency; DEP_INSN writes a register that INSN reads some
4651          cycles later.  */
4652       if (TARGET_C3X)
4653         {
4654           if (get_attr_setgroup1 (dep_insn) && get_attr_usegroup1 (insn))
4655             max = SET_USE_COST > max ? SET_USE_COST : max;
4656           if (get_attr_readarx (dep_insn) && get_attr_usegroup1 (insn))
4657             max = READ_USE_COST > max ? READ_USE_COST : max;
4658         }
4659       else
4660         {
4661           /* This could be significantly optimized. We should look
4662              to see if dep_insn sets ar0-ar7 or ir0-ir1 and if
4663              insn uses ar0-ar7.  We then test if the same register
4664              is used.  The tricky bit is that some operands will
4665              use several registers...  */
4666           if (get_attr_setar0 (dep_insn) && get_attr_usear0 (insn))
4667             max = SET_USE_COST > max ? SET_USE_COST : max;
4668           if (get_attr_setlda_ar0 (dep_insn) && get_attr_usear0 (insn))
4669             max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
4670           if (get_attr_readar0 (dep_insn) && get_attr_usear0 (insn))
4671             max = READ_USE_COST > max ? READ_USE_COST : max;
4672
4673           if (get_attr_setar1 (dep_insn) && get_attr_usear1 (insn))
4674             max = SET_USE_COST > max ? SET_USE_COST : max;
4675           if (get_attr_setlda_ar1 (dep_insn) && get_attr_usear1 (insn))
4676             max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
4677           if (get_attr_readar1 (dep_insn) && get_attr_usear1 (insn))
4678             max = READ_USE_COST > max ? READ_USE_COST : max;
4679
4680           if (get_attr_setar2 (dep_insn) && get_attr_usear2 (insn))
4681             max = SET_USE_COST > max ? SET_USE_COST : max;
4682           if (get_attr_setlda_ar2 (dep_insn) && get_attr_usear2 (insn))
4683             max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
4684           if (get_attr_readar2 (dep_insn) && get_attr_usear2 (insn))
4685             max = READ_USE_COST > max ? READ_USE_COST : max;
4686
4687           if (get_attr_setar3 (dep_insn) && get_attr_usear3 (insn))
4688             max = SET_USE_COST > max ? SET_USE_COST : max;
4689           if (get_attr_setlda_ar3 (dep_insn) && get_attr_usear3 (insn))
4690             max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
4691           if (get_attr_readar3 (dep_insn) && get_attr_usear3 (insn))
4692             max = READ_USE_COST > max ? READ_USE_COST : max;
4693
4694           if (get_attr_setar4 (dep_insn) && get_attr_usear4 (insn))
4695             max = SET_USE_COST > max ? SET_USE_COST : max;
4696           if (get_attr_setlda_ar4 (dep_insn) && get_attr_usear4 (insn))
4697             max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
4698           if (get_attr_readar4 (dep_insn) && get_attr_usear4 (insn))
4699             max = READ_USE_COST > max ? READ_USE_COST : max;
4700
4701           if (get_attr_setar5 (dep_insn) && get_attr_usear5 (insn))
4702             max = SET_USE_COST > max ? SET_USE_COST : max;
4703           if (get_attr_setlda_ar5 (dep_insn) && get_attr_usear5 (insn))
4704             max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
4705           if (get_attr_readar5 (dep_insn) && get_attr_usear5 (insn))
4706             max = READ_USE_COST > max ? READ_USE_COST : max;
4707
4708           if (get_attr_setar6 (dep_insn) && get_attr_usear6 (insn))
4709             max = SET_USE_COST > max ? SET_USE_COST : max;
4710           if (get_attr_setlda_ar6 (dep_insn) && get_attr_usear6 (insn))
4711             max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
4712           if (get_attr_readar6 (dep_insn) && get_attr_usear6 (insn))
4713             max = READ_USE_COST > max ? READ_USE_COST : max;
4714
4715           if (get_attr_setar7 (dep_insn) && get_attr_usear7 (insn))
4716             max = SET_USE_COST > max ? SET_USE_COST : max;
4717           if (get_attr_setlda_ar7 (dep_insn) && get_attr_usear7 (insn))
4718             max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
4719           if (get_attr_readar7 (dep_insn) && get_attr_usear7 (insn))
4720             max = READ_USE_COST > max ? READ_USE_COST : max;
4721
4722           if (get_attr_setir0 (dep_insn) && get_attr_useir0 (insn))
4723             max = SET_USE_COST > max ? SET_USE_COST : max;
4724           if (get_attr_setlda_ir0 (dep_insn) && get_attr_useir0 (insn))
4725             max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
4726
4727           if (get_attr_setir1 (dep_insn) && get_attr_useir1 (insn))
4728             max = SET_USE_COST > max ? SET_USE_COST : max;
4729           if (get_attr_setlda_ir1 (dep_insn) && get_attr_useir1 (insn))
4730             max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
4731         }
4732
4733       if (max)
4734         cost = max;
4735
4736       /* For other data dependencies, the default cost specified in the
4737          md is correct.  */
4738       return cost;
4739     }
4740   else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
4741     {
4742       /* Anti dependency; DEP_INSN reads a register that INSN writes some
4743          cycles later.  */
4744
4745       /* For c4x anti dependencies, the cost is 0.  */
4746       return 0;
4747     }
4748   else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
4749     {
4750       /* Output dependency; DEP_INSN writes a register that INSN writes some
4751          cycles later.  */
4752
4753       /* For c4x output dependencies, the cost is 0.  */
4754       return 0;
4755     }
4756   else
4757     abort ();
4758 }
4759
4760 void
4761 c4x_init_builtins (void)
4762 {
4763   tree endlink = void_list_node;
4764
4765   lang_hooks.builtin_function ("fast_ftoi",
4766                                build_function_type 
4767                                (integer_type_node,
4768                                 tree_cons (NULL_TREE, double_type_node,
4769                                            endlink)),
4770                                C4X_BUILTIN_FIX, BUILT_IN_MD, NULL, NULL_TREE);
4771   lang_hooks.builtin_function ("ansi_ftoi",
4772                                build_function_type 
4773                                (integer_type_node, 
4774                                 tree_cons (NULL_TREE, double_type_node,
4775                                            endlink)),
4776                                C4X_BUILTIN_FIX_ANSI, BUILT_IN_MD, NULL,
4777                                NULL_TREE);
4778   if (TARGET_C3X)
4779     lang_hooks.builtin_function ("fast_imult",
4780                                  build_function_type
4781                                  (integer_type_node, 
4782                                   tree_cons (NULL_TREE, integer_type_node,
4783                                              tree_cons (NULL_TREE,
4784                                                         integer_type_node,
4785                                                         endlink))),
4786                                  C4X_BUILTIN_MPYI, BUILT_IN_MD, NULL,
4787                                  NULL_TREE);
4788   else
4789     {
4790       lang_hooks.builtin_function ("toieee",
4791                                    build_function_type 
4792                                    (double_type_node,
4793                                     tree_cons (NULL_TREE, double_type_node,
4794                                                endlink)),
4795                                    C4X_BUILTIN_TOIEEE, BUILT_IN_MD, NULL,
4796                                    NULL_TREE);
4797       lang_hooks.builtin_function ("frieee",
4798                                    build_function_type
4799                                    (double_type_node, 
4800                                     tree_cons (NULL_TREE, double_type_node,
4801                                                endlink)),
4802                                    C4X_BUILTIN_FRIEEE, BUILT_IN_MD, NULL,
4803                                    NULL_TREE);
4804       lang_hooks.builtin_function ("fast_invf",
4805                                    build_function_type 
4806                                    (double_type_node, 
4807                                     tree_cons (NULL_TREE, double_type_node,
4808                                                endlink)),
4809                                    C4X_BUILTIN_RCPF, BUILT_IN_MD, NULL,
4810                                    NULL_TREE);
4811     }
4812 }
4813
4814
4815 rtx
4816 c4x_expand_builtin (tree exp, rtx target,
4817                     rtx subtarget ATTRIBUTE_UNUSED,
4818                     enum machine_mode mode ATTRIBUTE_UNUSED,
4819                     int ignore ATTRIBUTE_UNUSED)
4820 {
4821   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4822   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4823   tree arglist = TREE_OPERAND (exp, 1);
4824   tree arg0, arg1;
4825   rtx r0, r1;
4826
4827   switch (fcode)
4828     {
4829     case C4X_BUILTIN_FIX:
4830       arg0 = TREE_VALUE (arglist);
4831       r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
4832       if (! target || ! register_operand (target, QImode))
4833         target = gen_reg_rtx (QImode);
4834       emit_insn (gen_fixqfqi_clobber (target, r0));
4835       return target;
4836
4837     case C4X_BUILTIN_FIX_ANSI:
4838       arg0 = TREE_VALUE (arglist);
4839       r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
4840       if (! target || ! register_operand (target, QImode))
4841         target = gen_reg_rtx (QImode);
4842       emit_insn (gen_fix_truncqfqi2 (target, r0));
4843       return target;
4844
4845     case C4X_BUILTIN_MPYI:
4846       if (! TARGET_C3X)
4847         break;
4848       arg0 = TREE_VALUE (arglist);
4849       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4850       r0 = expand_expr (arg0, NULL_RTX, QImode, 0);
4851       r1 = expand_expr (arg1, NULL_RTX, QImode, 0);
4852       if (! target || ! register_operand (target, QImode))
4853         target = gen_reg_rtx (QImode);
4854       emit_insn (gen_mulqi3_24_clobber (target, r0, r1));
4855       return target;
4856
4857     case C4X_BUILTIN_TOIEEE:
4858       if (TARGET_C3X)
4859         break;
4860       arg0 = TREE_VALUE (arglist);
4861       r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
4862       if (! target || ! register_operand (target, QFmode))
4863         target = gen_reg_rtx (QFmode);
4864       emit_insn (gen_toieee (target, r0));
4865       return target;
4866
4867     case C4X_BUILTIN_FRIEEE:
4868       if (TARGET_C3X)
4869         break;
4870       arg0 = TREE_VALUE (arglist);
4871       r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
4872       if (register_operand (r0, QFmode))
4873         {
4874           r1 = assign_stack_local (QFmode, GET_MODE_SIZE (QFmode), 0);
4875           emit_move_insn (r1, r0);
4876           r0 = r1;
4877         }
4878       if (! target || ! register_operand (target, QFmode))
4879         target = gen_reg_rtx (QFmode);
4880       emit_insn (gen_frieee (target, r0));
4881       return target;
4882
4883     case C4X_BUILTIN_RCPF:
4884       if (TARGET_C3X)
4885         break;
4886       arg0 = TREE_VALUE (arglist);
4887       r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
4888       if (! target || ! register_operand (target, QFmode))
4889         target = gen_reg_rtx (QFmode);
4890       emit_insn (gen_rcpfqf_clobber (target, r0));
4891       return target;
4892     }
4893   return NULL_RTX;
4894 }
4895
4896 static void
4897 c4x_init_libfuncs (void)
4898 {
4899   set_optab_libfunc (smul_optab, QImode, "__mulqi3");
4900   set_optab_libfunc (sdiv_optab, QImode, "__divqi3");
4901   set_optab_libfunc (udiv_optab, QImode, "__udivqi3");
4902   set_optab_libfunc (smod_optab, QImode, "__modqi3");
4903   set_optab_libfunc (umod_optab, QImode, "__umodqi3");
4904   set_optab_libfunc (sdiv_optab, QFmode, "__divqf3");
4905   set_optab_libfunc (smul_optab, HFmode, "__mulhf3");
4906   set_optab_libfunc (sdiv_optab, HFmode, "__divhf3");
4907   set_optab_libfunc (smul_optab, HImode, "__mulhi3");
4908   set_optab_libfunc (sdiv_optab, HImode, "__divhi3");
4909   set_optab_libfunc (udiv_optab, HImode, "__udivhi3");
4910   set_optab_libfunc (smod_optab, HImode, "__modhi3");
4911   set_optab_libfunc (umod_optab, HImode, "__umodhi3");
4912   set_optab_libfunc (ffs_optab,  QImode, "__ffs");
4913   smulhi3_libfunc           = init_one_libfunc ("__smulhi3_high");
4914   umulhi3_libfunc           = init_one_libfunc ("__umulhi3_high");
4915   fix_truncqfhi2_libfunc    = init_one_libfunc ("__fix_truncqfhi2");
4916   fixuns_truncqfhi2_libfunc = init_one_libfunc ("__ufix_truncqfhi2");
4917   fix_trunchfhi2_libfunc    = init_one_libfunc ("__fix_trunchfhi2");
4918   fixuns_trunchfhi2_libfunc = init_one_libfunc ("__ufix_trunchfhi2");
4919   floathiqf2_libfunc        = init_one_libfunc ("__floathiqf2");
4920   floatunshiqf2_libfunc     = init_one_libfunc ("__ufloathiqf2");
4921   floathihf2_libfunc        = init_one_libfunc ("__floathihf2");
4922   floatunshihf2_libfunc     = init_one_libfunc ("__ufloathihf2");
4923 }
4924
4925 static void
4926 c4x_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED,
4927                        tree decl ATTRIBUTE_UNUSED)
4928 {
4929   fprintf (asm_out_file, "\t.sect\t\"%s\"\n", name);
4930 }
4931
4932 static void
4933 c4x_globalize_label (FILE *stream, const char *name)
4934 {
4935   default_globalize_label (stream, name);
4936   c4x_global_label (name);
4937 }
4938 \f
4939 #define SHIFT_CODE_P(C) \
4940   ((C) == ASHIFT || (C) == ASHIFTRT || (C) == LSHIFTRT)
4941 #define LOGICAL_CODE_P(C) \
4942   ((C) == NOT || (C) == AND || (C) == IOR || (C) == XOR)
4943
4944 /* Compute a (partial) cost for rtx X.  Return true if the complete
4945    cost has been computed, and false if subexpressions should be
4946    scanned.  In either case, *TOTAL contains the cost result.  */
4947
4948 static bool
4949 c4x_rtx_costs (rtx x, int code, int outer_code, int *total)
4950 {
4951   HOST_WIDE_INT val;
4952
4953   switch (code)
4954     {
4955       /* Some small integers are effectively free for the C40.  We should
4956          also consider if we are using the small memory model.  With
4957          the big memory model we require an extra insn for a constant
4958          loaded from memory.  */
4959
4960     case CONST_INT:
4961       val = INTVAL (x);
4962       if (c4x_J_constant (x))
4963         *total = 0;
4964       else if (! TARGET_C3X
4965                && outer_code == AND
4966                && (val == 255 || val == 65535))
4967         *total = 0;
4968       else if (! TARGET_C3X
4969                && (outer_code == ASHIFTRT || outer_code == LSHIFTRT)
4970                && (val == 16 || val == 24))
4971         *total = 0;
4972       else if (TARGET_C3X && SHIFT_CODE_P (outer_code))
4973         *total = 3;
4974       else if (LOGICAL_CODE_P (outer_code)
4975                ? c4x_L_constant (x) : c4x_I_constant (x))
4976         *total = 2;
4977       else
4978         *total = 4;
4979       return true;
4980
4981     case CONST:
4982     case LABEL_REF:
4983     case SYMBOL_REF:
4984       *total = 4;
4985       return true;
4986
4987     case CONST_DOUBLE:
4988       if (c4x_H_constant (x))
4989         *total = 2;
4990       else if (GET_MODE (x) == QFmode)
4991         *total = 4;
4992       else
4993         *total = 8;
4994       return true;
4995
4996     /* ??? Note that we return true, rather than false so that rtx_cost
4997        doesn't include the constant costs.  Otherwise expand_mult will
4998        think that it is cheaper to synthesize a multiply rather than to
4999        use a multiply instruction.  I think this is because the algorithm
5000        synth_mult doesn't take into account the loading of the operands,
5001        whereas the calculation of mult_cost does.  */
5002     case PLUS:
5003     case MINUS:
5004     case AND:
5005     case IOR:
5006     case XOR:
5007     case ASHIFT:
5008     case ASHIFTRT:
5009     case LSHIFTRT:
5010       *total = COSTS_N_INSNS (1);
5011       return true;
5012
5013     case MULT:
5014       *total = COSTS_N_INSNS (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
5015                               || TARGET_MPYI ? 1 : 14);
5016       return true;
5017
5018     case DIV:
5019     case UDIV:
5020     case MOD:
5021     case UMOD:
5022       *total = COSTS_N_INSNS (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
5023                               ? 15 : 50);
5024       return true;
5025
5026     default:
5027       return false;
5028     }
5029 }
5030 \f
5031 /* Worker function for TARGET_ASM_EXTERNAL_LIBCALL.  */
5032
5033 static void
5034 c4x_external_libcall (rtx fun)
5035 {
5036   /* This is only needed to keep asm30 happy for ___divqf3 etc.  */
5037   c4x_external_ref (XSTR (fun, 0));
5038 }
5039
5040 /* Worker function for TARGET_STRUCT_VALUE_RTX.  */
5041
5042 static rtx
5043 c4x_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
5044                       int incoming ATTRIBUTE_UNUSED)
5045 {
5046   return gen_rtx_REG (Pmode, AR0_REGNO);
5047 }