OSDN Git Service

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