OSDN Git Service

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