OSDN Git Service

cc3248fb5eee1ccb3c5fd26e29bf7e58ad9a91cb
[pf3gnuchains/gcc-fork.git] / gcc / config / crx / crx.c
1 /* Output routines for GCC for CRX.
2    Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3    2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
4
5    This file is part of GCC.
6
7    GCC is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published
9    by the Free Software Foundation; either version 3, or (at your
10    option) any later version.
11
12    GCC is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GCC; see the file COPYING3.  If not see
19    <http://www.gnu.org/licenses/>.  */
20
21 /*****************************************************************************/
22 /* HEADER INCLUDES                                                           */
23 /*****************************************************************************/
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h"
29 #include "rtl.h"
30 #include "tree.h"
31 #include "tm_p.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "real.h"
35 #include "insn-config.h"
36 #include "conditions.h"
37 #include "output.h"
38 #include "insn-codes.h"
39 #include "insn-attr.h"
40 #include "flags.h"
41 #include "except.h"
42 #include "function.h"
43 #include "recog.h"
44 #include "expr.h"
45 #include "optabs.h"
46 #include "toplev.h"
47 #include "basic-block.h"
48 #include "target.h"
49 #include "target-def.h"
50
51 /*****************************************************************************/
52 /* DEFINITIONS                                                               */
53 /*****************************************************************************/
54
55 /* Maximum number of register used for passing parameters.  */
56 #define MAX_REG_FOR_PASSING_ARGS 6
57
58 /* Minimum number register used for passing parameters.  */
59 #define MIN_REG_FOR_PASSING_ARGS 2
60
61 /* The maximum count of words supported in the assembly of the architecture in
62  * a push/pop instruction.  */
63 #define MAX_COUNT               8
64
65 /* Predicate is true if the current function is a 'noreturn' function, i.e. it
66  * is qualified as volatile.  */
67 #define FUNC_IS_NORETURN_P(decl) (TREE_THIS_VOLATILE (decl))
68
69 /* The following macros are used in crx_decompose_address () */
70
71 /* Returns the factor of a scaled index address or -1 if invalid. */
72 #define SCALE_FOR_INDEX_P(X)    \
73  (GET_CODE (X) == CONST_INT ?   \
74   (INTVAL (X) == 1 ? 1 :        \
75    INTVAL (X) == 2 ? 2 :        \
76    INTVAL (X) == 4 ? 4 :        \
77    INTVAL (X) == 8 ? 8 :        \
78    -1) :                        \
79   -1)
80
81 /* Nonzero if the rtx X is a signed const int of n bits */
82 #define RTX_SIGNED_INT_FITS_N_BITS(X,n)                 \
83  ((GET_CODE (X) == CONST_INT                            \
84    && SIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
85
86 /* Nonzero if the rtx X is an unsigned const int of n bits.  */
87 #define RTX_UNSIGNED_INT_FITS_N_BITS(X, n)              \
88  ((GET_CODE (X) == CONST_INT                            \
89    && UNSIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
90
91 /*****************************************************************************/
92 /* STATIC VARIABLES                                                          */
93 /*****************************************************************************/
94
95 /* Nonzero if the last param processed is passed in a register.  */
96 static int last_parm_in_reg;
97
98 /* Will hold the number of the last register the prologue saves, -1 if no
99  * register is saved. */
100 static int last_reg_to_save;
101
102 /* Each object in the array is a register number. Mark 1 for registers that
103  * need to be saved.  */
104 static int save_regs[FIRST_PSEUDO_REGISTER];
105
106 /* Number of bytes saved on the stack for non-scratch registers */
107 static int sum_regs = 0;
108
109 /* Number of bytes saved on the stack for local variables. */
110 static int local_vars_size;
111
112 /* The sum of 2 sizes: locals vars and padding byte for saving the registers.
113  * Used in expand_prologue () and expand_epilogue ().  */
114 static int size_for_adjusting_sp;
115
116 /* In case of a POST_INC or POST_DEC memory reference, we must report the mode
117  * of the memory reference from PRINT_OPERAND to PRINT_OPERAND_ADDRESS. */
118 static enum machine_mode output_memory_reference_mode;
119
120 /*****************************************************************************/
121 /* GLOBAL VARIABLES                                                          */
122 /*****************************************************************************/
123
124 /* Table of machine attributes.  */
125 const struct attribute_spec crx_attribute_table[];
126
127 /*****************************************************************************/
128 /* TARGETM FUNCTION PROTOTYPES                                               */
129 /*****************************************************************************/
130
131 static bool crx_fixed_condition_code_regs (unsigned int *, unsigned int *);
132 static rtx crx_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
133                                  int incoming ATTRIBUTE_UNUSED);
134 static bool crx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED);
135 static int crx_address_cost (rtx, bool);
136
137 /*****************************************************************************/
138 /* STACK LAYOUT AND CALLING CONVENTIONS                                      */
139 /*****************************************************************************/
140
141 #undef  TARGET_FIXED_CONDITION_CODE_REGS
142 #define TARGET_FIXED_CONDITION_CODE_REGS crx_fixed_condition_code_regs
143
144 #undef  TARGET_STRUCT_VALUE_RTX
145 #define TARGET_STRUCT_VALUE_RTX         crx_struct_value_rtx
146
147 #undef  TARGET_RETURN_IN_MEMORY
148 #define TARGET_RETURN_IN_MEMORY         crx_return_in_memory
149
150 /*****************************************************************************/
151 /* RELATIVE COSTS OF OPERATIONS                                              */
152 /*****************************************************************************/
153
154 #undef  TARGET_ADDRESS_COST
155 #define TARGET_ADDRESS_COST             crx_address_cost
156
157 /*****************************************************************************/
158 /* TARGET-SPECIFIC USES OF `__attribute__'                                   */
159 /*****************************************************************************/
160
161 #undef  TARGET_ATTRIBUTE_TABLE
162 #define TARGET_ATTRIBUTE_TABLE          crx_attribute_table
163
164 const struct attribute_spec crx_attribute_table[] = {
165   /* ISRs have special prologue and epilogue requirements. */
166   {"interrupt", 0, 0, false, true, true, NULL},
167   {NULL, 0, 0, false, false, false, NULL}
168 };
169
170
171 /* Initialize 'targetm' variable which contains pointers to functions and data
172  * relating to the target machine.  */
173
174 struct gcc_target targetm = TARGET_INITIALIZER;
175
176
177 /*****************************************************************************/
178 /* TARGET HOOK IMPLEMENTATIONS                                               */
179 /*****************************************************************************/
180
181 /* Return the fixed registers used for condition codes.  */
182
183 static bool
184 crx_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
185 {
186     *p1 = CC_REGNUM;
187     *p2 = INVALID_REGNUM;
188     return true;
189 }
190
191 /* Implements hook TARGET_STRUCT_VALUE_RTX.  */
192
193 static rtx
194 crx_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
195                       int incoming ATTRIBUTE_UNUSED)
196 {
197   return gen_rtx_REG (Pmode, CRX_STRUCT_VALUE_REGNUM);
198 }
199
200 /* Implements hook TARGET_RETURN_IN_MEMORY.  */
201
202 static bool
203 crx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
204 {
205   if (TYPE_MODE (type) == BLKmode)
206     {
207       HOST_WIDE_INT size = int_size_in_bytes (type);
208       return (size == -1 || size > 8);
209     }
210   else
211     return false;
212 }
213
214
215 /*****************************************************************************/
216 /* MACRO IMPLEMENTATIONS                                                     */
217 /*****************************************************************************/
218
219 /* STACK LAYOUT AND CALLING CONVENTIONS ROUTINES */
220 /* --------------------------------------------- */
221
222 /* Return nonzero if the current function being compiled is an interrupt
223  * function as specified by the "interrupt" attribute.  */
224
225 int
226 crx_interrupt_function_p (void)
227 {
228   tree attributes;
229
230   attributes = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
231   return lookup_attribute ("interrupt", attributes) != NULL_TREE;
232 }
233
234 /* Compute values for the array save_regs and the variable sum_regs.  The index
235  * of save_regs is numbers of register, each will get 1 if we need to save it
236  * in the current function, 0 if not. sum_regs is the total sum of the
237  * registers being saved. */
238
239 static void
240 crx_compute_save_regs (void)
241 {
242   unsigned int regno;
243
244   /* initialize here so in case the function is no-return it will be -1. */
245   last_reg_to_save = -1;
246
247   /* No need to save any registers if the function never returns.  */
248   if (FUNC_IS_NORETURN_P (current_function_decl))
249     return;
250
251   /* Initialize the number of bytes to be saved. */
252   sum_regs = 0;
253
254   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
255     {
256       if (fixed_regs[regno])
257         {
258           save_regs[regno] = 0;
259           continue;
260         }
261
262       /* If this reg is used and not call-used (except RA), save it. */
263       if (crx_interrupt_function_p ())
264         {
265           if (!current_function_is_leaf && call_used_regs[regno])
266             /* this is a volatile reg in a non-leaf interrupt routine - save it
267              * for the sake of its sons.  */
268             save_regs[regno] = 1;
269
270           else if (df_regs_ever_live_p (regno))
271             /* This reg is used - save it.  */
272             save_regs[regno] = 1;
273           else
274             /* This reg is not used, and is not a volatile - don't save. */
275             save_regs[regno] = 0;
276         }
277       else
278         {
279           /* If this reg is used and not call-used (except RA), save it. */
280           if (df_regs_ever_live_p (regno)
281               && (!call_used_regs[regno] || regno == RETURN_ADDRESS_REGNUM))
282             save_regs[regno] = 1;
283           else
284             save_regs[regno] = 0;
285         }
286     }
287
288   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
289     if (save_regs[regno] == 1)
290       {
291         last_reg_to_save = regno;
292         sum_regs += UNITS_PER_WORD;
293       }
294 }
295
296 /* Compute the size of the local area and the size to be adjusted by the
297  * prologue and epilogue. */
298
299 static void
300 crx_compute_frame (void)
301 {
302   /* For aligning the local variables. */
303   int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
304   int padding_locals;
305
306   /* Padding needed for each element of the frame.  */
307   local_vars_size = get_frame_size ();
308
309   /* Align to the stack alignment. */
310   padding_locals = local_vars_size % stack_alignment;
311   if (padding_locals)
312     padding_locals = stack_alignment - padding_locals;
313
314   local_vars_size += padding_locals;
315
316   size_for_adjusting_sp = local_vars_size + (ACCUMULATE_OUTGOING_ARGS ?
317                                      crtl->outgoing_args_size : 0);
318 }
319
320 /* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */
321
322 int
323 crx_initial_elimination_offset (int from, int to)
324 {
325   /* Compute this since we need to use sum_regs.  */
326   crx_compute_save_regs ();
327
328   /* Compute this since we need to use local_vars_size.  */
329   crx_compute_frame ();
330
331   if ((from) == FRAME_POINTER_REGNUM && (to) == STACK_POINTER_REGNUM)
332     return (ACCUMULATE_OUTGOING_ARGS ?
333             crtl->outgoing_args_size : 0);
334   else if ((from) == ARG_POINTER_REGNUM && (to) == FRAME_POINTER_REGNUM)
335     return (sum_regs + local_vars_size);
336   else if ((from) == ARG_POINTER_REGNUM && (to) == STACK_POINTER_REGNUM)
337     return (sum_regs + local_vars_size +
338             (ACCUMULATE_OUTGOING_ARGS ?
339              crtl->outgoing_args_size : 0));
340   else
341     abort ();
342 }
343
344 /* REGISTER USAGE */
345 /* -------------- */
346
347 /* Return the class number of the smallest class containing reg number REGNO.
348  * This could be a conditional expression or could index an array. */
349
350 enum reg_class
351 crx_regno_reg_class (int regno)
352 {
353   if (regno >= 0 && regno < SP_REGNUM)
354     return NOSP_REGS;
355
356   if (regno == SP_REGNUM)
357     return GENERAL_REGS;
358
359   if (regno == LO_REGNUM)
360     return LO_REGS;
361   if (regno == HI_REGNUM)
362     return HI_REGS;
363
364   return NO_REGS;
365 }
366
367 /* Transfer between HILO_REGS and memory via secondary reloading. */
368
369 enum reg_class
370 crx_secondary_reload_class (enum reg_class rclass,
371                             enum machine_mode mode ATTRIBUTE_UNUSED,
372                             rtx x ATTRIBUTE_UNUSED)
373 {
374   if (reg_classes_intersect_p (rclass, HILO_REGS)
375       && true_regnum (x) == -1)
376     return GENERAL_REGS;
377
378   return NO_REGS;
379 }
380
381 /* Return 1 if hard register REGNO can hold a value of machine-mode MODE. */
382
383 int
384 crx_hard_regno_mode_ok (int regno, enum machine_mode mode)
385 {
386   /* CC can only hold CCmode values.  */
387   if (regno == CC_REGNUM)
388     return GET_MODE_CLASS (mode) == MODE_CC;
389   if (GET_MODE_CLASS (mode) == MODE_CC)
390     return 0;
391   /* HILO registers can only hold SImode and DImode */
392   if (HILO_REGNO_P (regno))
393     return mode == SImode || mode == DImode;
394   return 1;
395 }
396
397 /* PASSING FUNCTION ARGUMENTS */
398 /* -------------------------- */
399
400 /* If enough param regs are available for passing the param of type TYPE return
401  * the number of registers needed else 0.  */
402
403 static int
404 enough_regs_for_param (CUMULATIVE_ARGS * cum, tree type,
405                        enum machine_mode mode)
406 {
407   int type_size;
408   int remaining_size;
409
410   if (mode != BLKmode)
411     type_size = GET_MODE_BITSIZE (mode);
412   else
413     type_size = int_size_in_bytes (type) * BITS_PER_UNIT;
414
415   remaining_size =
416     BITS_PER_WORD * (MAX_REG_FOR_PASSING_ARGS -
417     (MIN_REG_FOR_PASSING_ARGS + cum->ints) + 1);
418
419   /* Any variable which is too big to pass in two registers, will pass on
420    * stack. */
421   if ((remaining_size >= type_size) && (type_size <= 2 * BITS_PER_WORD))
422     return (type_size + BITS_PER_WORD - 1) / BITS_PER_WORD;
423
424   return 0;
425 }
426
427 /* Implements the macro FUNCTION_ARG defined in crx.h.  */
428
429 rtx
430 crx_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, tree type,
431               int named ATTRIBUTE_UNUSED)
432 {
433   last_parm_in_reg = 0;
434
435   /* Function_arg () is called with this type just after all the args have had
436    * their registers assigned. The rtx that function_arg returns from this type
437    * is supposed to pass to 'gen_call' but currently it is not implemented (see
438    * macro GEN_CALL).  */
439   if (type == void_type_node)
440     return NULL_RTX;
441
442   if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
443     return NULL_RTX;
444
445   if (mode == BLKmode)
446     {
447       /* Enable structures that need padding bytes at the end to pass to a
448        * function in registers. */
449       if (enough_regs_for_param (cum, type, mode) != 0)
450         {
451           last_parm_in_reg = 1;
452           return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
453         }
454     }
455
456   if (MIN_REG_FOR_PASSING_ARGS + cum->ints > MAX_REG_FOR_PASSING_ARGS)
457     return NULL_RTX;
458   else
459     {
460       if (enough_regs_for_param (cum, type, mode) != 0)
461         {
462           last_parm_in_reg = 1;
463           return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
464         }
465     }
466
467   return NULL_RTX;
468 }
469
470 /* Implements the macro INIT_CUMULATIVE_ARGS defined in crx.h.  */
471
472 void
473 crx_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype,
474                       rtx libfunc ATTRIBUTE_UNUSED)
475 {
476   tree param, next_param;
477
478   cum->ints = 0;
479
480   /* Determine if this function has variable arguments.  This is indicated by
481    * the last argument being 'void_type_mode' if there are no variable
482    * arguments.  Change here for a different vararg.  */
483   for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
484        param != (tree) 0; param = next_param)
485     {
486       next_param = TREE_CHAIN (param);
487       if (next_param == (tree) 0 && TREE_VALUE (param) != void_type_node)
488         {
489           cum->ints = -1;
490           return;
491         }
492     }
493 }
494
495 /* Implements the macro FUNCTION_ARG_ADVANCE defined in crx.h.  */
496
497 void
498 crx_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode,
499                       tree type, int named ATTRIBUTE_UNUSED)
500 {
501   /* l holds the number of registers required */
502   int l = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
503
504   /* If the parameter isn't passed on a register don't advance cum.  */
505   if (!last_parm_in_reg)
506     return;
507
508   if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
509     return;
510
511   if (mode == SImode || mode == HImode || mode == QImode || mode == DImode)
512     {
513       if (l <= 1)
514         cum->ints += 1;
515       else
516         cum->ints += l;
517     }
518   else if (mode == SFmode || mode == DFmode)
519     cum->ints += l;
520   else if ((mode) == BLKmode)
521     {
522       if ((l = enough_regs_for_param (cum, type, mode)) != 0)
523         cum->ints += l;
524     }
525
526 }
527
528 /* Implements the macro FUNCTION_ARG_REGNO_P defined in crx.h.  Return nonzero
529  * if N is a register used for passing parameters.  */
530
531 int
532 crx_function_arg_regno_p (int n)
533 {
534   return (n <= MAX_REG_FOR_PASSING_ARGS && n >= MIN_REG_FOR_PASSING_ARGS);
535 }
536
537 /* ADDRESSING MODES */
538 /* ---------------- */
539
540 /* Implements the macro GO_IF_LEGITIMATE_ADDRESS defined in crx.h.
541  * The following addressing modes are supported on CRX:
542  *
543  * Relocations          --> const | symbol_ref | label_ref
544  * Absolute address     --> 32-bit absolute
545  * Post increment       --> reg + 12-bit disp.
546  * Post modify          --> reg + 12-bit disp.
547  * Register relative    --> reg | 32-bit disp. + reg | 4 bit + reg
548  * Scaled index         --> reg + reg | 22-bit disp. + reg + reg |
549  *                          22-disp. + reg + reg + (2 | 4 | 8) */
550
551 static int crx_addr_reg_p (rtx addr_reg)
552 {
553   rtx reg;
554
555   if (REG_P (addr_reg))
556     {
557       reg = addr_reg;
558     }
559   else if ((GET_CODE (addr_reg) == SUBREG
560            && REG_P (SUBREG_REG (addr_reg))
561            && GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg)))
562            <= UNITS_PER_WORD))
563     {
564       reg = SUBREG_REG (addr_reg);
565     }
566   else
567     return FALSE;
568
569   if (GET_MODE (addr_reg) != Pmode)
570     {
571       return FALSE;
572     }
573
574   return TRUE;
575 }
576
577 enum crx_addrtype
578 crx_decompose_address (rtx addr, struct crx_address *out)
579 {
580   rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
581   rtx scale_rtx = NULL_RTX, side_effect = NULL_RTX;
582   int scale = -1;
583   
584   enum crx_addrtype retval = CRX_INVALID;
585
586   switch (GET_CODE (addr))
587     {
588     case CONST_INT:
589       /* Absolute address (known at compile time) */
590       retval = CRX_ABSOLUTE;
591       disp = addr;
592       if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), GET_MODE_BITSIZE (Pmode)))
593         return CRX_INVALID;
594       break;
595       
596     case CONST:
597     case SYMBOL_REF:
598     case LABEL_REF:
599       /* Absolute address (known at link time) */
600       retval = CRX_ABSOLUTE;
601       disp = addr;
602       break;
603
604     case REG:
605     case SUBREG:
606       /* Register relative address */
607       retval = CRX_REG_REL;
608       base = addr;
609       break;
610
611     case PLUS:
612       switch (GET_CODE (XEXP (addr, 0)))
613         {
614         case REG:
615         case SUBREG:
616           if (REG_P (XEXP (addr, 1)))
617             {
618               /* Scaled index with scale = 1 and disp. = 0 */
619               retval = CRX_SCALED_INDX;
620               base = XEXP (addr, 1);
621               index = XEXP (addr, 0); 
622               scale = 1;
623             }
624           else if (RTX_SIGNED_INT_FITS_N_BITS (XEXP (addr, 1), 28))
625             {
626               /* Register relative address and <= 28-bit disp. */
627               retval = CRX_REG_REL;
628               base = XEXP (addr, 0);
629               disp = XEXP (addr, 1);
630             }
631           else
632             return CRX_INVALID;
633           break;
634
635         case PLUS:
636           /* Scaled index and <= 22-bit disp. */
637           retval = CRX_SCALED_INDX;
638           base = XEXP (XEXP (addr, 0), 1); 
639           disp = XEXP (addr, 1);
640           if (!RTX_SIGNED_INT_FITS_N_BITS (disp, 22))
641             return CRX_INVALID;
642           switch (GET_CODE (XEXP (XEXP (addr, 0), 0)))
643             {
644             case REG:
645               /* Scaled index with scale = 0 and <= 22-bit disp. */
646               index = XEXP (XEXP (addr, 0), 0); 
647               scale = 1;
648               break;
649               
650             case MULT:
651               /* Scaled index with scale >= 0 and <= 22-bit disp. */
652               index = XEXP (XEXP (XEXP (addr, 0), 0), 0); 
653               scale_rtx = XEXP (XEXP (XEXP (addr, 0), 0), 1); 
654               if ((scale = SCALE_FOR_INDEX_P (scale_rtx)) == -1)
655                 return CRX_INVALID;
656               break;
657
658             default:
659               return CRX_INVALID;
660             }
661           break;
662           
663         case MULT:
664           /* Scaled index with scale >= 0 */
665           retval = CRX_SCALED_INDX;
666           base = XEXP (addr, 1); 
667           index = XEXP (XEXP (addr, 0), 0); 
668           scale_rtx = XEXP (XEXP (addr, 0), 1); 
669           /* Scaled index with scale >= 0 and <= 22-bit disp. */
670           if ((scale = SCALE_FOR_INDEX_P (scale_rtx)) == -1)
671             return CRX_INVALID;
672           break;
673
674         default:
675           return CRX_INVALID;
676         }
677       break;
678
679     case POST_INC:
680     case POST_DEC:
681       /* Simple post-increment */
682       retval = CRX_POST_INC;
683       base = XEXP (addr, 0);
684       side_effect = addr;
685       break;
686
687     case POST_MODIFY:
688       /* Generic post-increment with <= 12-bit disp. */
689       retval = CRX_POST_INC;
690       base = XEXP (addr, 0);
691       side_effect = XEXP (addr, 1);
692       if (base != XEXP (side_effect, 0))
693         return CRX_INVALID;
694       switch (GET_CODE (side_effect))
695         {
696         case PLUS:
697         case MINUS:
698           disp = XEXP (side_effect, 1);
699           if (!RTX_SIGNED_INT_FITS_N_BITS (disp, 12))
700             return CRX_INVALID;
701           break;
702
703         default:
704           /* CRX only supports PLUS and MINUS */
705           return CRX_INVALID;
706         }
707       break;
708
709     default:
710       return CRX_INVALID;
711     }
712
713   if (base && !crx_addr_reg_p (base)) return CRX_INVALID;
714   if (index && !crx_addr_reg_p (index)) return CRX_INVALID;
715   
716   out->base = base;
717   out->index = index;
718   out->disp = disp;
719   out->scale = scale;
720   out->side_effect = side_effect;
721
722   return retval;
723 }
724
725 int
726 crx_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
727                           rtx addr, int strict)
728 {
729   enum crx_addrtype addrtype;
730   struct crx_address address;
731                                                  
732   if (TARGET_DEBUG_ADDR)
733     {
734       fprintf (stderr,
735                "\n======\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
736                GET_MODE_NAME (mode), strict);
737       debug_rtx (addr);
738     }
739   
740   addrtype = crx_decompose_address (addr, &address);
741
742   if (addrtype == CRX_POST_INC && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
743     return FALSE;
744
745   if (TARGET_DEBUG_ADDR)
746     {
747       const char *typestr;
748       switch (addrtype)
749         {
750         case CRX_INVALID:
751           typestr = "Invalid";
752           break;
753         case CRX_REG_REL:
754           typestr = "Register relative";
755           break;
756         case CRX_POST_INC:
757           typestr = "Post-increment";
758           break;
759         case CRX_SCALED_INDX:
760           typestr = "Scaled index";
761           break;
762         case CRX_ABSOLUTE:
763           typestr = "Absolute";
764           break;
765         default:
766           abort ();
767         }
768       fprintf (stderr, "CRX Address type: %s\n", typestr);
769     }
770   
771   if (addrtype == CRX_INVALID)
772     return FALSE;
773
774   if (strict)
775     {
776       if (address.base && !REGNO_OK_FOR_BASE_P (REGNO (address.base)))
777         {
778           if (TARGET_DEBUG_ADDR)
779             fprintf (stderr, "Base register not strict\n");
780           return FALSE;
781         }
782       if (address.index && !REGNO_OK_FOR_INDEX_P (REGNO (address.index)))
783         {
784           if (TARGET_DEBUG_ADDR)
785             fprintf (stderr, "Index register not strict\n");
786           return FALSE;
787         }
788     }
789
790   return TRUE;
791 }
792
793 /* ROUTINES TO COMPUTE COSTS */
794 /* ------------------------- */
795
796 /* Return cost of the memory address x. */
797
798 static int
799 crx_address_cost (rtx addr, bool speed ATTRIBUTE_UNUSED)
800 {
801   enum crx_addrtype addrtype;
802   struct crx_address address;
803                                                  
804   int cost = 2;
805   
806   addrtype = crx_decompose_address (addr, &address);
807   
808   gcc_assert (addrtype != CRX_INVALID);
809
810   /* An absolute address causes a 3-word instruction */
811   if (addrtype == CRX_ABSOLUTE)
812     cost+=2;
813   
814   /* Post-modifying addresses are more powerful.  */
815   if (addrtype == CRX_POST_INC)
816     cost-=2;
817
818   /* Attempt to minimize number of registers in the address. */
819   if (address.base)
820     cost++;
821   
822   if (address.index && address.scale == 1)
823     cost+=5;
824
825   if (address.disp && !INT_CST4 (INTVAL (address.disp)))
826     cost+=2;
827
828   if (TARGET_DEBUG_ADDR)
829     {
830       fprintf (stderr, "\n======\nTARGET_ADDRESS_COST = %d\n", cost);
831       debug_rtx (addr);
832     }
833   
834   return cost;
835 }
836
837 /* Return the cost of moving data of mode MODE between a register of class
838  * RCLASS and memory; IN is zero if the value is to be written to memory,
839  * nonzero if it is to be read in. This cost is relative to those in
840  * REGISTER_MOVE_COST.  */
841
842 int
843 crx_memory_move_cost (enum machine_mode mode,
844                   enum reg_class rclass ATTRIBUTE_UNUSED,
845                   int in ATTRIBUTE_UNUSED)
846 {
847   /* One LD or ST takes twice the time of a simple reg-reg move */
848   if (reg_classes_intersect_p (rclass, GENERAL_REGS))
849     {
850       /* printf ("GENERAL_REGS LD/ST = %d\n", 4 * HARD_REGNO_NREGS (0, mode));*/
851       return 4 * HARD_REGNO_NREGS (0, mode);
852     }   
853   else if (reg_classes_intersect_p (rclass, HILO_REGS))
854     {
855       /* HILO to memory and vice versa */
856       /* printf ("HILO_REGS %s = %d\n", in ? "LD" : "ST",
857              (REGISTER_MOVE_COST (mode,
858                                  in ? GENERAL_REGS : HILO_REGS,
859                                  in ? HILO_REGS : GENERAL_REGS) + 4)
860         * HARD_REGNO_NREGS (0, mode)); */
861       return (REGISTER_MOVE_COST (mode,
862                                  in ? GENERAL_REGS : HILO_REGS,
863                                  in ? HILO_REGS : GENERAL_REGS) + 4)
864         * HARD_REGNO_NREGS (0, mode);
865     }
866   else /* default (like in i386) */
867     {
868       /* printf ("ANYREGS = 100\n"); */
869       return 100;
870     }
871 }
872
873 /* INSTRUCTION OUTPUT */
874 /* ------------------ */
875
876 /* Check if a const_double is ok for crx store-immediate instructions */
877
878 int
879 crx_const_double_ok (rtx op)
880 {
881   if (GET_MODE (op) == DFmode)
882   {
883     REAL_VALUE_TYPE r;
884     long l[2];
885     REAL_VALUE_FROM_CONST_DOUBLE (r, op);
886     REAL_VALUE_TO_TARGET_DOUBLE (r, l);
887     return (UNSIGNED_INT_FITS_N_BITS (l[0], 4) &&
888             UNSIGNED_INT_FITS_N_BITS (l[1], 4)) ? 1 : 0;
889   }
890
891   if (GET_MODE (op) == SFmode)
892   {
893     REAL_VALUE_TYPE r;
894     long l;
895     REAL_VALUE_FROM_CONST_DOUBLE (r, op);
896     REAL_VALUE_TO_TARGET_SINGLE (r, l);
897     return UNSIGNED_INT_FITS_N_BITS (l, 4) ? 1 : 0;
898   }
899
900   return (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op), 4) &&
901           UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op), 4)) ? 1 : 0;
902 }
903
904 /* Implements the macro PRINT_OPERAND defined in crx.h.  */
905
906 void
907 crx_print_operand (FILE * file, rtx x, int code)
908 {
909   switch (code)
910     {
911     case 'p' :
912       if (GET_CODE (x) == REG) {
913         if (GET_MODE (x) == DImode || GET_MODE (x) == DFmode)
914           {
915             int regno = REGNO (x);
916             if (regno + 1 >= SP_REGNUM) abort ();
917             fprintf (file, "{%s, %s}", reg_names[regno], reg_names[regno + 1]);
918             return;
919           }
920         else
921           {
922             if (REGNO (x) >= SP_REGNUM) abort ();
923             fprintf (file, "%s", reg_names[REGNO (x)]);
924             return;
925           }
926       }
927
928     case 'd' :
929         {
930           const char *crx_cmp_str;
931           switch (GET_CODE (x))
932             { /* MD: compare (reg, reg or imm) but CRX: cmp (reg or imm, reg)
933                * -> swap all non symmetric ops */
934             case EQ  : crx_cmp_str = "eq"; break;
935             case NE  : crx_cmp_str = "ne"; break;
936             case GT  : crx_cmp_str = "lt"; break;
937             case GTU : crx_cmp_str = "lo"; break;
938             case LT  : crx_cmp_str = "gt"; break;
939             case LTU : crx_cmp_str = "hi"; break;
940             case GE  : crx_cmp_str = "le"; break;
941             case GEU : crx_cmp_str = "ls"; break;
942             case LE  : crx_cmp_str = "ge"; break;
943             case LEU : crx_cmp_str = "hs"; break;
944             default : abort ();
945             }
946           fprintf (file, "%s", crx_cmp_str);
947           return;
948         }
949
950     case 'H':
951       /* Print high part of a double precision value. */
952       switch (GET_CODE (x))
953         {
954         case CONST_DOUBLE:
955           if (GET_MODE (x) == SFmode) abort ();
956           if (GET_MODE (x) == DFmode)
957             {
958               /* High part of a DF const. */
959               REAL_VALUE_TYPE r;
960               long l[2];
961
962               REAL_VALUE_FROM_CONST_DOUBLE (r, x);
963               REAL_VALUE_TO_TARGET_DOUBLE (r, l);
964
965               fprintf (file, "$0x%lx", l[1]);
966               return;
967             }
968
969           /* -- Fallthrough to handle DI consts -- */
970
971         case CONST_INT:
972             {
973               rtx high, low;
974               split_double (x, &low, &high);
975               putc ('$', file);
976               output_addr_const (file, high);
977               return;
978             }
979
980         case REG:
981           if (REGNO (x) + 1 >= FIRST_PSEUDO_REGISTER) abort ();
982           fprintf (file, "%s", reg_names[REGNO (x) + 1]);
983           return;
984
985         case MEM:
986           /* Adjust memory address to high part.  */
987             {
988               rtx adj_mem = x;
989               adj_mem = adjust_address (adj_mem, GET_MODE (adj_mem), 4);
990
991               output_memory_reference_mode = GET_MODE (adj_mem);
992               output_address (XEXP (adj_mem, 0));
993               return;
994             }
995
996         default:
997           abort ();
998         }
999
1000     case 'L':
1001       /* Print low part of a double precision value. */
1002       switch (GET_CODE (x))
1003         {
1004         case CONST_DOUBLE:
1005           if (GET_MODE (x) == SFmode) abort ();
1006           if (GET_MODE (x) == DFmode)
1007             {
1008               /* High part of a DF const. */
1009               REAL_VALUE_TYPE r;
1010               long l[2];
1011
1012               REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1013               REAL_VALUE_TO_TARGET_DOUBLE (r, l);
1014
1015               fprintf (file, "$0x%lx", l[0]);
1016               return;
1017             }
1018
1019           /* -- Fallthrough to handle DI consts -- */
1020
1021         case CONST_INT:
1022             {
1023               rtx high, low;
1024               split_double (x, &low, &high);
1025               putc ('$', file);
1026               output_addr_const (file, low);
1027               return;
1028             }
1029
1030         case REG:
1031           fprintf (file, "%s", reg_names[REGNO (x)]);
1032           return;
1033
1034         case MEM:
1035           output_memory_reference_mode = GET_MODE (x);
1036           output_address (XEXP (x, 0));
1037           return;
1038
1039         default:
1040           abort ();
1041         }
1042
1043     case 0 : /* default */
1044       switch (GET_CODE (x))
1045         {
1046         case REG:
1047           fprintf (file, "%s", reg_names[REGNO (x)]);
1048           return;
1049
1050         case MEM:
1051           output_memory_reference_mode = GET_MODE (x);
1052           output_address (XEXP (x, 0));
1053           return;
1054
1055         case CONST_DOUBLE:
1056             {
1057               REAL_VALUE_TYPE r;
1058               long l;
1059
1060               /* Always use H and L for double precision - see above */
1061               gcc_assert (GET_MODE (x) == SFmode);
1062
1063               REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1064               REAL_VALUE_TO_TARGET_SINGLE (r, l);
1065
1066               fprintf (file, "$0x%lx", l);
1067               return;
1068             }
1069
1070         default:
1071           putc ('$', file);
1072           output_addr_const (file, x);
1073           return;
1074         }
1075
1076     default:
1077       output_operand_lossage ("invalid %%xn code");
1078     }
1079
1080   abort ();
1081 }
1082
1083 /* Implements the macro PRINT_OPERAND_ADDRESS defined in crx.h.  */
1084
1085 void
1086 crx_print_operand_address (FILE * file, rtx addr)
1087 {
1088   enum crx_addrtype addrtype;
1089   struct crx_address address;
1090
1091   int offset;
1092   
1093   addrtype = crx_decompose_address (addr, &address);
1094   
1095   if (address.disp)
1096     offset = INTVAL (address.disp);
1097   else
1098     offset = 0;
1099
1100   switch (addrtype)
1101     {
1102     case CRX_REG_REL:
1103       fprintf (file, "%d(%s)", offset, reg_names[REGNO (address.base)]);
1104       return;
1105       
1106     case CRX_POST_INC:
1107       switch (GET_CODE (address.side_effect))
1108         {
1109         case PLUS:
1110           break;
1111         case MINUS:
1112           offset = -offset;
1113           break;
1114         case POST_INC:
1115           offset = GET_MODE_SIZE (output_memory_reference_mode);
1116           break;
1117         case POST_DEC:
1118           offset = -GET_MODE_SIZE (output_memory_reference_mode);
1119           break;
1120         default:
1121           abort ();
1122         }
1123         fprintf (file, "%d(%s)+", offset, reg_names[REGNO (address.base)]);
1124       return;
1125       
1126     case CRX_SCALED_INDX:
1127       fprintf (file, "%d(%s, %s, %d)", offset, reg_names[REGNO (address.base)],
1128                reg_names[REGNO (address.index)], address.scale);
1129       return;
1130       
1131     case CRX_ABSOLUTE:
1132       output_addr_const (file, address.disp);
1133       return;
1134       
1135     default:
1136       abort ();
1137     }
1138 }
1139
1140
1141 /*****************************************************************************/
1142 /* MACHINE DESCRIPTION HELPER-FUNCTIONS                                      */
1143 /*****************************************************************************/
1144
1145 void crx_expand_movmem_single (rtx src, rtx srcbase, rtx dst, rtx dstbase,
1146                                rtx tmp_reg, unsigned HOST_WIDE_INT *offset_p)
1147 {
1148   rtx addr, mem;
1149   unsigned HOST_WIDE_INT offset = *offset_p;
1150
1151   /* Load */
1152   addr = plus_constant (src, offset);
1153   mem = adjust_automodify_address (srcbase, SImode, addr, offset);
1154   emit_move_insn (tmp_reg, mem);
1155
1156   /* Store */
1157   addr = plus_constant (dst, offset);
1158   mem = adjust_automodify_address (dstbase, SImode, addr, offset);
1159   emit_move_insn (mem, tmp_reg);
1160
1161   *offset_p = offset + 4;
1162 }
1163
1164 int
1165 crx_expand_movmem (rtx dstbase, rtx srcbase, rtx count_exp, rtx align_exp)
1166 {
1167   unsigned HOST_WIDE_INT count = 0, offset, si_moves, i;
1168   HOST_WIDE_INT align = 0;
1169
1170   rtx src, dst;
1171   rtx tmp_reg;
1172
1173   if (GET_CODE (align_exp) == CONST_INT)
1174     { /* Only if aligned */
1175       align = INTVAL (align_exp);
1176       if (align & 3)
1177         return 0;
1178     }
1179
1180   if (GET_CODE (count_exp) == CONST_INT)
1181     { /* No more than 16 SImode moves */
1182       count = INTVAL (count_exp);
1183       if (count > 64)
1184         return 0;
1185     }
1186
1187   tmp_reg = gen_reg_rtx (SImode);
1188
1189   /* Create psrs for the src and dest pointers */
1190   dst = copy_to_mode_reg (Pmode, XEXP (dstbase, 0));
1191   if (dst != XEXP (dstbase, 0))
1192     dstbase = replace_equiv_address_nv (dstbase, dst);
1193   src = copy_to_mode_reg (Pmode, XEXP (srcbase, 0));
1194   if (src != XEXP (srcbase, 0))
1195     srcbase = replace_equiv_address_nv (srcbase, src);
1196
1197   offset = 0;
1198
1199   /* Emit SImode moves */
1200   si_moves = count >> 2;
1201   for (i = 0; i < si_moves; i++)
1202     crx_expand_movmem_single (src, srcbase, dst, dstbase, tmp_reg, &offset);
1203
1204   /* Special cases */
1205   if (count & 3)
1206     {
1207       offset = count - 4;
1208       crx_expand_movmem_single (src, srcbase, dst, dstbase, tmp_reg, &offset);
1209     }
1210
1211   gcc_assert (offset == count);
1212
1213   return 1;
1214 }
1215
1216 static void
1217 mpushpop_str (char *stringbuffer, const char *mnemonic, char *mask)
1218 {
1219   if (strlen (mask) > 2 || crx_interrupt_function_p ()) /* needs 2-word instr. */
1220     sprintf (stringbuffer, "\n\t%s\tsp, {%s}", mnemonic, mask);
1221   else /* single word instruction */
1222     sprintf (stringbuffer, "\n\t%s\t%s", mnemonic, mask);
1223 }
1224
1225 /* Called from crx.md. The return value depends on the parameter push_or_pop:
1226  * When push_or_pop is zero -> string for push instructions of prologue.
1227  * When push_or_pop is nonzero -> string for pop/popret/retx in epilogue.
1228  * Relies on the assumptions:
1229  * 1. RA is the last register to be saved.
1230  * 2. The maximal value of the counter is MAX_COUNT. */
1231
1232 char *
1233 crx_prepare_push_pop_string (int push_or_pop)
1234 {
1235   /* j is the number of registers being saved, takes care that there won't be
1236    * more than 8 in one push/pop instruction */
1237
1238   /* For the register mask string */
1239   static char mask_str[50];
1240
1241   /* i is the index of save_regs[], going from 0 until last_reg_to_save */
1242   int i = 0;
1243
1244   int ra_in_bitmask = 0;
1245
1246   char *return_str;
1247
1248   /* For reversing on the push instructions if there are more than one. */
1249   char *temp_str;
1250
1251   return_str = (char *) xmalloc (120);
1252   temp_str = (char *) xmalloc (120);
1253
1254   /* Initialize */
1255   memset (return_str, 0, 3);
1256
1257   while (i <= last_reg_to_save)
1258     {
1259       /* Prepare mask for one instruction. */
1260       mask_str[0] = 0;
1261
1262       if (i <= SP_REGNUM)
1263         { /* Add regs unit full or SP register reached */
1264           int j = 0;
1265           while (j < MAX_COUNT && i <= SP_REGNUM)
1266             {
1267               if (save_regs[i])
1268                 {
1269                   /* TODO to use ra_in_bitmask for detecting last pop is not
1270                    * smart it prevents things like:  popret r5 */
1271                   if (i == RETURN_ADDRESS_REGNUM) ra_in_bitmask = 1;
1272                   if (j > 0) strcat (mask_str, ", ");
1273                   strcat (mask_str, reg_names[i]);
1274                   ++j;
1275                 }
1276               ++i;
1277             }
1278         }
1279       else
1280         {
1281           /* Handle hi/lo savings */
1282           while (i <= last_reg_to_save)
1283             {
1284               if (save_regs[i])
1285                 {
1286                   strcat (mask_str, "lo, hi");
1287                   i = last_reg_to_save + 1;
1288                   break;
1289                 }
1290               ++i;
1291             }
1292         }
1293
1294       if (strlen (mask_str) == 0) continue;
1295         
1296       if (push_or_pop == 1)
1297         {
1298           if (crx_interrupt_function_p ())
1299             mpushpop_str (temp_str, "popx", mask_str);
1300           else
1301             {
1302               if (ra_in_bitmask)
1303                 {
1304                   mpushpop_str (temp_str, "popret", mask_str);
1305                   ra_in_bitmask = 0;
1306                 }
1307               else mpushpop_str (temp_str, "pop", mask_str);
1308             }
1309
1310           strcat (return_str, temp_str);
1311         }
1312       else
1313         {
1314           /* push - We need to reverse the order of the instructions if there
1315            * are more than one. (since the pop will not be reversed in the
1316            * epilogue */
1317           if (crx_interrupt_function_p ())
1318             mpushpop_str (temp_str, "pushx", mask_str);
1319           else
1320             mpushpop_str (temp_str, "push", mask_str);
1321           strcat (temp_str, return_str);
1322           strcpy (strcat (return_str, "\t"), temp_str);
1323         }
1324
1325     }
1326
1327   if (push_or_pop == 1)
1328     {
1329       /* pop */
1330       if (crx_interrupt_function_p ())
1331         strcat (return_str, "\n\tretx\n");
1332
1333       else if (!FUNC_IS_NORETURN_P (current_function_decl)
1334                && !save_regs[RETURN_ADDRESS_REGNUM])
1335         strcat (return_str, "\n\tjump\tra\n");
1336     }
1337
1338   /* Skip the newline and the tab in the start of return_str. */
1339   return_str += 2;
1340   return return_str;
1341 }
1342
1343 /*  CompactRISC CRX Architecture stack layout:
1344
1345      0 +---------------------
1346         |
1347         .
1348         .
1349         |
1350         +==================== Sp(x)=Ap(x+1)
1351       A | Args for functions
1352       | | called by X and      Dynamically
1353       | | Dynamic allocations  allocated and
1354       | | (alloca, variable    deallocated
1355   Stack | length arrays).
1356   grows +-------------------- Fp(x)
1357   down| | Local variables of X
1358   ward| +--------------------
1359       | | Regs saved for X-1
1360       | +==================== Sp(x-1)=Ap(x)
1361         | Args for func X
1362         | pushed by X-1
1363         +-------------------- Fp(x-1)
1364         |
1365         |
1366         V
1367
1368 */
1369
1370 void
1371 crx_expand_prologue (void)
1372 {
1373   crx_compute_frame ();
1374   crx_compute_save_regs ();
1375
1376   /* If there is no need in push and adjustment to sp, return. */
1377   if (size_for_adjusting_sp + sum_regs == 0)
1378     return;
1379
1380   if (last_reg_to_save != -1)
1381     /* If there are registers to push.  */
1382     emit_insn (gen_push_for_prologue (GEN_INT (sum_regs)));
1383
1384   if (size_for_adjusting_sp > 0)
1385     emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1386                            GEN_INT (-size_for_adjusting_sp)));
1387
1388   if (frame_pointer_needed)
1389     /* Initialize the frame pointer with the value of the stack pointer
1390      * pointing now to the locals. */
1391     emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1392 }
1393
1394 /* Generate insn that updates the stack for local variables and padding for
1395  * registers we save. - Generate the appropriate return insn. */
1396
1397 void
1398 crx_expand_epilogue (void)
1399 {
1400   rtx return_reg;
1401
1402   /* Nonzero if we need to return and pop only RA. This will generate a
1403    * different insn. This differentiate is for the peepholes for call as last
1404    * statement in function. */
1405   int only_popret_RA = (save_regs[RETURN_ADDRESS_REGNUM]
1406                         && (sum_regs == UNITS_PER_WORD));
1407
1408   /* Return register.  */
1409   return_reg = gen_rtx_REG (Pmode, RETURN_ADDRESS_REGNUM);
1410
1411   if (frame_pointer_needed)
1412     /* Restore the stack pointer with the frame pointers value */
1413     emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1414
1415   if (size_for_adjusting_sp > 0)
1416     emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1417                            GEN_INT (size_for_adjusting_sp)));
1418
1419   if (crx_interrupt_function_p ())
1420     emit_jump_insn (gen_interrupt_return ());
1421   else if (last_reg_to_save == -1)
1422     /* Nothing to pop */
1423     /* Don't output jump for interrupt routine, only retx.  */
1424     emit_jump_insn (gen_indirect_jump_return ());
1425   else if (only_popret_RA)
1426     emit_jump_insn (gen_popret_RA_return ());
1427   else
1428     emit_jump_insn (gen_pop_and_popret_return (GEN_INT (sum_regs)));
1429 }
1430