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