OSDN Git Service

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