OSDN Git Service

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