1 /* Output routines for CR16 processor.
2    Copyright (C) 2012-2013 Free Software Foundation, Inc.
3    Contributed by KPIT Cummins Infosystems Limited.
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 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "tm_p.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "output.h"
33 #include "insn-codes.h"
34 #include "insn-attr.h"
35 #include "flags.h"
36 #include "except.h"
37 #include "function.h"
38 #include "recog.h"
39 #include "expr.h"
40 #include "optabs.h"
41 #include "diagnostic-core.h"
42 #include "basic-block.h"
43 #include "target.h"
44 #include "target-def.h"
45 #include "df.h"
46 
47 /* Definitions.  */
48 
49 /* Maximum number of register used for passing parameters.  */
50 #define MAX_REG_FOR_PASSING_ARGS  6
51 
52 /* Minimum number register used for passing parameters.  */
53 #define MIN_REG_FOR_PASSING_ARGS  2
54 
55 /* The maximum count of words supported in the assembly of the architecture in
56    a push/pop instruction.  */
57 #define MAX_COUNT  8
58 
59 /* Predicate is true if the current function is a 'noreturn' function,
60    i.e. it is qualified as volatile.  */
61 #define FUNC_IS_NORETURN_P(decl) (TREE_THIS_VOLATILE (decl))
62 
63 /* Predicate that holds when we need to save registers even for 'noreturn'
64    functions, to accommodate for unwinding.  */
65 #define MUST_SAVE_REGS_P() \
66   (flag_unwind_tables || (flag_exceptions && !UI_SJLJ))
67 
68 /* Nonzero if the rtx X is a signed const int of n bits.  */
69 #define RTX_SIGNED_INT_FITS_N_BITS(X, n)                \
70   ((GET_CODE (X) == CONST_INT                          \
71    && SIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
72 
73 /* Nonzero if the rtx X is an unsigned const int of n bits.  */
74 #define RTX_UNSIGNED_INT_FITS_N_BITS(X, n)               \
75   ((GET_CODE (X) == CONST_INT                            \
76    && UNSIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
77 
78 /* Structure for stack computations.  */
79 
80 /* variable definitions in the struture
81    args_size             Number of bytes saved on the stack for local
82 			 variables
83 
84    reg_size		 Number of bytes saved on the stack for
85 			 non-scratch registers
86 
87    total_size 		 The sum of 2 sizes: locals vars and padding byte
88 			 for saving the registers. Used in expand_prologue()
89 			 and expand_epilogue()
90 
91    last_reg_to_save      Will hold the number of the last register the
92 			 prologue saves, -1 if no register is saved
93 
94    save_regs[16]	 Each object in the array is a register number.
95 			 Mark 1 for registers that need to be saved
96 
97    num_regs		 Number of registers saved
98 
99    initialized		 Non-zero if frame size already calculated, not
100 			 used yet
101 
102    function_makes_calls  Does the function make calls ? not used yet.  */
103 
104 struct cr16_frame_info
105 {
106   unsigned long var_size;
107   unsigned long args_size;
108   unsigned int  reg_size;
109   unsigned long total_size;
110   long          last_reg_to_save;
111   long          save_regs[FIRST_PSEUDO_REGISTER];
112   int           num_regs;
113   int           initialized;
114   int           function_makes_calls;
115 };
116 
117 /* Current frame information calculated by cr16_compute_frame_size.  */
118 static struct cr16_frame_info current_frame_info;
119 
120 /* Static Variables.  */
121 
122 /* Data model that was supplied by user via command line option
123    This will be overridden in case of invalid combination
124    of core and data model options are supplied.  */
125 static enum data_model_type data_model = DM_DEFAULT;
126 
127 /* TARGETM Function Prototypes and forward declarations  */
128 static void cr16_print_operand (FILE *, rtx, int);
129 static void cr16_print_operand_address (FILE *, rtx);
130 
131 /* Stack layout and calling conventions.  */
132 #undef  TARGET_STRUCT_VALUE_RTX
133 #define TARGET_STRUCT_VALUE_RTX		cr16_struct_value_rtx
134 #undef  TARGET_RETURN_IN_MEMORY
135 #define TARGET_RETURN_IN_MEMORY		cr16_return_in_memory
136 
137 /* Target-specific uses of '__attribute__'.  */
138 #undef  TARGET_ATTRIBUTE_TABLE
139 #define TARGET_ATTRIBUTE_TABLE 		cr16_attribute_table
140 #undef TARGET_NARROW_VOLATILE_BITFIELD
141 #define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false
142 
143 /* EH related.  */
144 #undef TARGET_UNWIND_WORD_MODE
145 #define TARGET_UNWIND_WORD_MODE		cr16_unwind_word_mode
146 
147 /* Override Options.  */
148 #undef TARGET_OPTION_OVERRIDE
149 #define TARGET_OPTION_OVERRIDE  	cr16_override_options
150 
151 /* Conditional register usuage.  */
152 #undef TARGET_CONDITIONAL_REGISTER_USAGE
153 #define TARGET_CONDITIONAL_REGISTER_USAGE cr16_conditional_register_usage
154 
155 /* Controlling register spills.  */
156 #undef TARGET_CLASS_LIKELY_SPILLED_P
157 #define TARGET_CLASS_LIKELY_SPILLED_P	cr16_class_likely_spilled_p
158 
159 /* Passing function arguments.  */
160 #undef TARGET_FUNCTION_ARG
161 #define TARGET_FUNCTION_ARG 		cr16_function_arg
162 #undef TARGET_FUNCTION_ARG_ADVANCE
163 #define TARGET_FUNCTION_ARG_ADVANCE 	cr16_function_arg_advance
164 #undef TARGET_RETURN_POPS_ARGS
165 #define TARGET_RETURN_POPS_ARGS 	cr16_return_pops_args
166 
167 /* Initialize the GCC target structure.  */
168 #undef TARGET_FRAME_POINTER_REQUIRED
169 #define TARGET_FRAME_POINTER_REQUIRED	cr16_frame_pointer_required
170 #undef TARGET_CAN_ELIMINATE
171 #define TARGET_CAN_ELIMINATE 		cr16_can_eliminate
172 #undef TARGET_LEGITIMIZE_ADDRESS
173 #define TARGET_LEGITIMIZE_ADDRESS 	cr16_legitimize_address
174 #undef TARGET_LEGITIMATE_CONSTANT_P
175 #define TARGET_LEGITIMATE_CONSTANT_P    cr16_legitimate_constant_p
176 #undef TARGET_LEGITIMATE_ADDRESS_P
177 #define TARGET_LEGITIMATE_ADDRESS_P     cr16_legitimate_address_p
178 
179 /* Returning function value.  */
180 #undef TARGET_FUNCTION_VALUE
181 #define TARGET_FUNCTION_VALUE 		cr16_function_value
182 #undef TARGET_LIBCALL_VALUE
183 #define TARGET_LIBCALL_VALUE 		cr16_libcall_value
184 #undef TARGET_FUNCTION_VALUE_REGNO_P
185 #define TARGET_FUNCTION_VALUE_REGNO_P 	cr16_function_value_regno_p
186 
187 /* printing the values.  */
188 #undef TARGET_PRINT_OPERAND
189 #define TARGET_PRINT_OPERAND 		cr16_print_operand
190 #undef TARGET_PRINT_OPERAND_ADDRESS
191 #define TARGET_PRINT_OPERAND_ADDRESS 	cr16_print_operand_address
192 
193 /* Relative costs of operations.  */
194 #undef  TARGET_ADDRESS_COST
195 #define TARGET_ADDRESS_COST 		cr16_address_cost
196 #undef TARGET_REGISTER_MOVE_COST
197 #define TARGET_REGISTER_MOVE_COST 	cr16_register_move_cost
198 #undef TARGET_MEMORY_MOVE_COST
199 #define TARGET_MEMORY_MOVE_COST 	cr16_memory_move_cost
200 
201 /* Table of machine attributes.  */
202 static const struct attribute_spec cr16_attribute_table[] = {
203   /* ISRs have special prologue and epilogue requirements.  */
204   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
205        affects_type_identity }.  */
206   {"interrupt", 0, 0, false, true, true, NULL, false},
207   {NULL, 0, 0, false, false, false, NULL, false}
208 };
209 
210 /* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive
211    .?byte directive along with @c is not understood by assembler.
212    Therefore, make all TARGET_ASM_UNALIGNED_xx_OP same
213    as TARGET_ASM_ALIGNED_xx_OP.  */
214 #undef TARGET_ASM_UNALIGNED_HI_OP
215 #define TARGET_ASM_UNALIGNED_HI_OP 	TARGET_ASM_ALIGNED_HI_OP
216 #undef TARGET_ASM_UNALIGNED_SI_OP
217 #define TARGET_ASM_UNALIGNED_SI_OP 	TARGET_ASM_ALIGNED_SI_OP
218 #undef TARGET_ASM_UNALIGNED_DI_OP
219 #define TARGET_ASM_UNALIGNED_DI_OP 	TARGET_ASM_ALIGNED_DI_OP
220 
221 /* Target hook implementations.  */
222 
223 /* Implements hook TARGET_RETURN_IN_MEMORY.  */
224 static bool
cr16_return_in_memory(const_tree type,const_tree fntype ATTRIBUTE_UNUSED)225 cr16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
226 {
227   const HOST_WIDE_INT size = int_size_in_bytes (type);
228   return ((size == -1) || (size > 8));
229 }
230 
231 /* Implement TARGET_CLASS_LIKELY_SPILLED_P.  */
232 static bool
cr16_class_likely_spilled_p(reg_class_t rclass)233 cr16_class_likely_spilled_p (reg_class_t rclass)
234 {
235   if ((rclass) == SHORT_REGS || (rclass) == DOUBLE_BASE_REGS
236       || (rclass) == LONG_REGS || (rclass) == GENERAL_REGS)
237     return true;
238 
239   return false;
240 }
241 
242 static int
cr16_return_pops_args(tree fundecl ATTRIBUTE_UNUSED,tree funtype ATTRIBUTE_UNUSED,int size ATTRIBUTE_UNUSED)243 cr16_return_pops_args (tree fundecl ATTRIBUTE_UNUSED,
244                        tree funtype ATTRIBUTE_UNUSED,
245 		       int size ATTRIBUTE_UNUSED)
246 {
247   return 0;
248 }
249 
250 /* Returns true if data model selected via command line option
251    is same as function argument.  */
252 bool
cr16_is_data_model(enum data_model_type model)253 cr16_is_data_model (enum data_model_type model)
254 {
255   return (model == data_model);
256 }
257 
258 /* Parse relevant options and override.  */
259 static void
cr16_override_options(void)260 cr16_override_options (void)
261 {
262   /* Disable -fdelete-null-pointer-checks option for CR16 target.
263      Programs which rely on NULL pointer dereferences _not_ halting the
264      program may not work properly with this option. So disable this
265      option.  */
266   flag_delete_null_pointer_checks = 0;
267 
268   /* FIXME: To avoid spill_failure ICE during exception handling,
269    * disable cse_fllow_jumps. The spill error occurs when compiler
270    * can't find a suitable candidate in GENERAL_REGS class to reload
271    * a 32bit register.
272    * Need to find a better way of avoiding this situation. */
273   if (flag_exceptions)
274     flag_cse_follow_jumps = 0;
275 
276   /* If -fpic option, data_model == DM_FAR.  */
277   if (flag_pic == NEAR_PIC)
278     {
279       data_model = DM_FAR;
280     }
281 
282   /* The only option we want to examine is data model option.  */
283   if (cr16_data_model)
284     {
285       if (strcmp (cr16_data_model, "medium") == 0)
286 	data_model = DM_DEFAULT;
287       else if (strcmp (cr16_data_model, "near") == 0)
288 	data_model = DM_NEAR;
289       else if (strcmp (cr16_data_model, "far") == 0)
290 	{
291 	  if (TARGET_CR16CP)
292 	    data_model = DM_FAR;
293 	  else
294 	    error ("data-model=far not valid for cr16c architecture");
295 	}
296       else
297 	error ("invalid data model option -mdata-model=%s", cr16_data_model);
298     }
299   else
300     data_model = DM_DEFAULT;
301 }
302 
303 /* Implements the macro  TARGET_CONDITIONAL_REGISTER_USAGE.  */
304 static void
cr16_conditional_register_usage(void)305 cr16_conditional_register_usage (void)
306 {
307   if (flag_pic)
308     {
309       fixed_regs[12] = call_used_regs[12] = 1;
310     }
311 }
312 
313 /* Stack layout and calling conventions routines.  */
314 
315 /* Return nonzero if the current function being compiled is an interrupt
316    function as specified by the "interrupt" attribute.  */
317 int
cr16_interrupt_function_p(void)318 cr16_interrupt_function_p (void)
319 {
320   tree attributes;
321 
322   attributes = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
323   return (lookup_attribute ("interrupt", attributes) != NULL_TREE);
324 }
325 
326 /* Compute values for the array current_frame_info.save_regs and the variable
327    current_frame_info.reg_size. The index of current_frame_info.save_regs
328    is numbers of register, each will get 1 if we need to save it in the
329    current function, 0 if not. current_frame_info.reg_size is the total sum
330    of the registers being saved.  */
331 static void
cr16_compute_save_regs(void)332 cr16_compute_save_regs (void)
333 {
334   unsigned int regno;
335 
336   /* Initialize here so in case the function is no-return it will be -1.  */
337   current_frame_info.last_reg_to_save = -1;
338 
339   /* Initialize the number of bytes to be saved. */
340   current_frame_info.reg_size = 0;
341 
342   /* No need to save any registers if the function never returns.  */
343   if (FUNC_IS_NORETURN_P (current_function_decl) && !MUST_SAVE_REGS_P ())
344     return;
345 
346   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
347     {
348       if (fixed_regs[regno])
349 	{
350 	  current_frame_info.save_regs[regno] = 0;
351 	  continue;
352 	}
353 
354       /* If this reg is used and not call-used (except RA), save it.  */
355       if (cr16_interrupt_function_p ())
356 	{
357 	  if (!crtl->is_leaf && call_used_regs[regno])
358 	    /* This is a volatile reg in a non-leaf interrupt routine - save
359 	       it for the sake of its sons.  */
360 	    current_frame_info.save_regs[regno] = 1;
361 	  else if (df_regs_ever_live_p (regno))
362 	    /* This reg is used - save it.  */
363 	    current_frame_info.save_regs[regno] = 1;
364 	  else
365 	    /* This reg is not used, and is not a volatile - don't save.  */
366 	    current_frame_info.save_regs[regno] = 0;
367 	}
368       else
369 	{
370 	  /* If this reg is used and not call-used (except RA), save it.  */
371 	  if (df_regs_ever_live_p (regno)
372 	      && (!call_used_regs[regno] || regno == RETURN_ADDRESS_REGNUM))
373 	    current_frame_info.save_regs[regno] = 1;
374 	  else
375 	    current_frame_info.save_regs[regno] = 0;
376 	}
377     }
378 
379   /* Save registers so the exception handler can modify them.  */
380   if (crtl->calls_eh_return)
381     {
382       unsigned int i;
383 
384       for (i = 0;; ++i)
385 	{
386 	  regno = EH_RETURN_DATA_REGNO (i);
387 	  if (INVALID_REGNUM == regno)
388 	    break;
389 	  current_frame_info.save_regs[regno] = 1;
390 	}
391     }
392 
393   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
394     if (current_frame_info.save_regs[regno] == 1)
395       {
396 	current_frame_info.last_reg_to_save = regno;
397 	if (regno >= CR16_FIRST_DWORD_REGISTER)
398 	  current_frame_info.reg_size += CR16_UNITS_PER_DWORD;
399 	else
400 	  current_frame_info.reg_size += UNITS_PER_WORD;
401       }
402 }
403 
404 /* Compute the size of the local area and the size to be adjusted by the
405    prologue and epilogue.  */
406 static void
cr16_compute_frame(void)407 cr16_compute_frame (void)
408 {
409   /* For aligning the local variables.  */
410   int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
411   int padding_locals;
412 
413   /* Padding needed for each element of the frame.  */
414   current_frame_info.var_size = get_frame_size ();
415 
416   /* Align to the stack alignment.  */
417   padding_locals = current_frame_info.var_size % stack_alignment;
418   if (padding_locals)
419     padding_locals = stack_alignment - padding_locals;
420 
421   current_frame_info.var_size += padding_locals;
422   current_frame_info.total_size = current_frame_info.var_size
423 			          + (ACCUMULATE_OUTGOING_ARGS
424 			             ? crtl->outgoing_args_size : 0);
425 }
426 
427 /* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET.  */
428 int
cr16_initial_elimination_offset(int from,int to)429 cr16_initial_elimination_offset (int from, int to)
430 {
431   /* Compute this since we need to use current_frame_info.reg_size.  */
432   cr16_compute_save_regs ();
433 
434   /* Compute this since we need to use current_frame_info.var_size.  */
435   cr16_compute_frame ();
436 
437   if (((from) == FRAME_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
438     return (ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0);
439   else if (((from) == ARG_POINTER_REGNUM) && ((to) == FRAME_POINTER_REGNUM))
440     return (current_frame_info.reg_size + current_frame_info.var_size);
441   else if (((from) == ARG_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
442     return (current_frame_info.reg_size + current_frame_info.var_size
443 	    + (ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0));
444   else
445     gcc_unreachable ();
446 }
447 
448 /* Register Usage.  */
449 
450 /* Return the class number of the smallest class containing reg number REGNO.
451    This could be a conditional expression or could index an array.  */
452 enum reg_class
cr16_regno_reg_class(int regno)453 cr16_regno_reg_class (int regno)
454 {
455   if ((regno >= 0) && (regno < CR16_FIRST_DWORD_REGISTER))
456     return SHORT_REGS;
457 
458   if ((regno >= CR16_FIRST_DWORD_REGISTER) && (regno < FIRST_PSEUDO_REGISTER))
459     return LONG_REGS;
460 
461   return NO_REGS;
462 }
463 
464 /* Return 1 if hard register REGNO can hold a value of machine-mode MODE.  */
465 int
cr16_hard_regno_mode_ok(int regno,enum machine_mode mode)466 cr16_hard_regno_mode_ok (int regno, enum machine_mode mode)
467 {
468   if ((GET_MODE_SIZE (mode) >= 4) && (regno == 11))
469     return 0;
470 
471   if (mode == DImode || mode == DFmode)
472     {
473       if ((regno > 8) || (regno & 1))
474 	return 0;
475       return 1;
476     }
477 
478   if ((TARGET_INT32)
479        && ((regno >= 12) && (GET_MODE_SIZE (mode) < 4 )))
480      return 0;
481 
482   /* CC can only hold CCmode values.  */
483   if (GET_MODE_CLASS (mode) == MODE_CC)
484     return 0;
485   return 1;
486 }
487 
488 /* Returns register number for function return value.*/
489 static inline unsigned int
cr16_ret_register(void)490 cr16_ret_register (void)
491 {
492   return 0;
493 }
494 
495 /* Implements hook TARGET_STRUCT_VALUE_RTX.  */
496 static rtx
cr16_struct_value_rtx(tree fntype ATTRIBUTE_UNUSED,int incoming ATTRIBUTE_UNUSED)497 cr16_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
498                        int incoming ATTRIBUTE_UNUSED)
499 {
500   return gen_rtx_REG (Pmode, cr16_ret_register ());
501 }
502 
503 /* Returning function value.  */
504 
505 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.  */
506 static bool
cr16_function_value_regno_p(const unsigned int regno)507 cr16_function_value_regno_p (const unsigned int regno)
508 {
509   return (regno == cr16_ret_register ());
510 }
511 
512 /* Create an RTX representing the place where a
513    library function returns a value of mode MODE.  */
514 static rtx
cr16_libcall_value(enum machine_mode mode,const_rtx func ATTRIBUTE_UNUSED)515 cr16_libcall_value (enum machine_mode mode,
516 		    const_rtx func ATTRIBUTE_UNUSED)
517 {
518   return gen_rtx_REG (mode, cr16_ret_register ());
519 }
520 
521 /* Create an RTX representing the place where a
522    function returns a value of data type VALTYPE.  */
523 static rtx
cr16_function_value(const_tree type,const_tree fn_decl_or_type ATTRIBUTE_UNUSED,bool outgoing ATTRIBUTE_UNUSED)524 cr16_function_value (const_tree type,
525 		     const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
526 		     bool outgoing ATTRIBUTE_UNUSED)
527 {
528   return gen_rtx_REG (TYPE_MODE (type), cr16_ret_register ());
529 }
530 
531 /* Passing function arguments.  */
532 
533 /* If enough param regs are available for passing the param of type TYPE return
534    the number of registers needed else 0.  */
535 static int
enough_regs_for_param(CUMULATIVE_ARGS * cum,const_tree type,enum machine_mode mode)536 enough_regs_for_param (CUMULATIVE_ARGS * cum, const_tree type,
537 		       enum machine_mode mode)
538 {
539   int type_size;
540   int remaining_size;
541 
542   if (mode != BLKmode)
543     type_size = GET_MODE_BITSIZE (mode);
544   else
545     type_size = int_size_in_bytes (type) * BITS_PER_UNIT;
546 
547   remaining_size = BITS_PER_WORD * (MAX_REG_FOR_PASSING_ARGS
548 				    - (MIN_REG_FOR_PASSING_ARGS + cum->ints) +
549 				    1);
550 
551   /* Any variable which is too big to pass in two registers, will pass on
552      stack.  */
553   if ((remaining_size >= type_size) && (type_size <= 2 * BITS_PER_WORD))
554     return (type_size + BITS_PER_WORD - 1) / BITS_PER_WORD;
555 
556   return 0;
557 }
558 
559 /* Implements the macro FUNCTION_ARG defined in cr16.h.  */
560 static rtx
cr16_function_arg(cumulative_args_t cum_v,enum machine_mode mode,const_tree type,bool named ATTRIBUTE_UNUSED)561 cr16_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
562 		   const_tree type, bool named ATTRIBUTE_UNUSED)
563 {
564   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
565   cum->last_parm_in_reg = 0;
566 
567   /* function_arg () is called with this type just after all the args have
568      had their registers assigned. The rtx that function_arg returns from
569      this type is supposed to pass to 'gen_call' but currently it is not
570      implemented (see macro GEN_CALL).  */
571   if (type == void_type_node)
572     return NULL_RTX;
573 
574   if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
575     return NULL_RTX;
576 
577   if (mode == BLKmode)
578     {
579       /* Enable structures that need padding bytes at the end to pass to a
580          function in registers.  */
581       if (enough_regs_for_param (cum, type, mode) != 0)
582 	{
583 	  cum->last_parm_in_reg = 1;
584 	  return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
585 	}
586     }
587 
588   if ((MIN_REG_FOR_PASSING_ARGS + cum->ints) > MAX_REG_FOR_PASSING_ARGS)
589     return NULL_RTX;
590   else
591     {
592       if (enough_regs_for_param (cum, type, mode) != 0)
593 	{
594 	  cum->last_parm_in_reg = 1;
595 	  return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
596 	}
597     }
598 
599   return NULL_RTX;
600 }
601 
602 /* Implements the macro INIT_CUMULATIVE_ARGS defined in cr16.h.  */
603 void
cr16_init_cumulative_args(CUMULATIVE_ARGS * cum,tree fntype,rtx libfunc ATTRIBUTE_UNUSED)604 cr16_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype,
605 			   rtx libfunc ATTRIBUTE_UNUSED)
606 {
607   tree param, next_param;
608 
609   cum->ints = 0;
610 
611   /* Determine if this function has variable arguments.  This is indicated by
612      the last argument being 'void_type_mode' if there are no variable
613      arguments.  Change here for a different vararg.  */
614   for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
615        param != NULL_TREE; param = next_param)
616     {
617       next_param = TREE_CHAIN (param);
618       if ((next_param == NULL_TREE) && (TREE_VALUE (param) != void_type_node))
619 	{
620 	  cum->ints = -1;
621 	  return;
622 	}
623     }
624 }
625 
626 /* Implements the macro FUNCTION_ARG_ADVANCE defined in cr16.h.  */
627 static void
cr16_function_arg_advance(cumulative_args_t cum_v,enum machine_mode mode,const_tree type,bool named ATTRIBUTE_UNUSED)628 cr16_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
629 			   const_tree type, bool named ATTRIBUTE_UNUSED)
630 {
631   CUMULATIVE_ARGS * cum = get_cumulative_args (cum_v);
632 
633   /* l holds the number of registers required.  */
634   int l = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
635 
636   /* If the parameter isn't passed on a register don't advance cum.  */
637   if (!cum->last_parm_in_reg)
638     return;
639 
640   if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
641     return;
642 
643   if ((mode == SImode) || (mode == HImode)
644       || (mode == QImode) || (mode == DImode))
645     {
646       if (l <= 1)
647 	cum->ints += 1;
648       else
649 	cum->ints += l;
650     }
651   else if ((mode == SFmode) || (mode == DFmode))
652     cum->ints += l;
653   else if ((mode) == BLKmode)
654     {
655       if ((l = enough_regs_for_param (cum, type, mode)) != 0)
656 	cum->ints += l;
657     }
658   return;
659 }
660 
661 /* Implements the macro FUNCTION_ARG_REGNO_P defined in cr16.h.
662    Return nonzero if N is a register used for passing parameters.  */
663 int
cr16_function_arg_regno_p(int n)664 cr16_function_arg_regno_p (int n)
665 {
666   return ((n <= MAX_REG_FOR_PASSING_ARGS) && (n >= MIN_REG_FOR_PASSING_ARGS));
667 }
668 
669 /* Addressing modes.
670    Following set of function implement the macro GO_IF_LEGITIMATE_ADDRESS
671    defined in cr16.h.  */
672 
673 /* Helper function to check if is a valid base register that can
674    hold address.  */
675 static int
cr16_addr_reg_p(rtx addr_reg)676 cr16_addr_reg_p (rtx addr_reg)
677 {
678   rtx reg;
679 
680   if (REG_P (addr_reg))
681     reg = addr_reg;
682   else if ((GET_CODE (addr_reg) == SUBREG)
683 	   && REG_P (SUBREG_REG (addr_reg))
684 	   && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg)))
685 	       <= UNITS_PER_WORD))
686     reg = SUBREG_REG (addr_reg);
687   else
688     return FALSE;
689 
690   if (GET_MODE (reg) != Pmode)
691     return FALSE;
692 
693   return TRUE;
694 }
695 
696 /* Helper functions: Created specifically for decomposing operand of CONST
697    Recursively look into expression x for code or data symbol.
698    The function expects the expression to contain combination of
699    SYMBOL_REF, CONST_INT, (PLUS or MINUS)
700    LABEL_REF, CONST_INT, (PLUS or MINUS)
701    SYMBOL_REF
702    LABEL_REF
703    All other combinations will result in code = -1 and data = ILLEGAL_DM
704    code data
705    -1   ILLEGAL_DM   The expression did not contain SYMBOL_REF or LABEL_REF
706     0   DM_FAR       SYMBOL_REF was found and it was far data reference.
707     0   DM_DEFAULT   SYMBOL_REF was found and it was medium data reference.
708     1   ILLEGAL_DM   LABEL_REF was found.
709     2   ILLEGAL_DM   SYMBOL_REF was found and it was function reference.  */
710 void
cr16_decompose_const(rtx x,int * code,enum data_model_type * data,bool treat_as_const)711 cr16_decompose_const (rtx x, int *code, enum data_model_type *data,
712 		      bool treat_as_const)
713 {
714   *code = -1;
715   *data = ILLEGAL_DM;
716   switch (GET_CODE (x))
717     {
718     case SYMBOL_REF:
719       *code = SYMBOL_REF_FUNCTION_P (x) ? 2 : 0;
720       /* 2 indicates func sym.  */
721       if (*code == 0)
722 	{
723 	  if (CR16_TARGET_DATA_NEAR)
724 	    *data = DM_DEFAULT;
725 	  else if (CR16_TARGET_DATA_MEDIUM)
726 	    *data = DM_FAR;
727 	  else if (CR16_TARGET_DATA_FAR)
728 	    {
729 	      if (treat_as_const)
730 		/* This will be used only for printing
731 		   the qualifier. This call is (may be)
732 		   made by cr16_print_operand_address.  */
733 		*data = DM_FAR;
734 	      else
735 		/* This call is (may be) made by
736 		   cr16_legitimate_address_p.  */
737 		*data = ILLEGAL_DM;
738 	    }
739 	}
740       return;
741 
742     case LABEL_REF:
743       /* 1 - indicates non-function symbol.  */
744       *code = 1;
745       return;
746 
747     case PLUS:
748     case MINUS:
749       /* Look into the tree nodes.  */
750       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
751 	cr16_decompose_const (XEXP (x, 1), code, data, treat_as_const);
752       else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
753 	cr16_decompose_const (XEXP (x, 0), code, data, treat_as_const);
754       return;
755     default:
756       return;
757     }
758 }
759 
760 /* Decompose Address
761    This function decomposes the address returns the type of address
762    as defined in enum cr16_addrtype.  It also fills the parameter *out.
763    The decomposed address can be used for two purposes.  One to
764    check if the address is valid and second to print the address
765    operand.
766 
767    Following tables list valid address supported in CR16C/C+ architectures.
768    Legend:
769    aN : Absoulte address N-bit address
770    R  : One 16-bit register
771    RP : Consecutive two 16-bit registers or one 32-bit register
772    I  : One 32-bit register
773    dispN : Signed displacement of N-bits
774 
775    ----Code addresses----
776    Branch operands:
777    disp9        : CR16_ABSOLUTE       (disp)
778    disp17       : CR16_ABSOLUTE       (disp)
779    disp25       : CR16_ABSOLUTE       (disp)
780    RP + disp25  : CR16_REGP_REL       (base, disp)
781 
782    Jump operands:
783    RP           : CR16_REGP_REL       (base, disp=0)
784    a24          : CR16_ABSOLUTE       (disp)
785 
786    ----Data addresses----
787    a20          : CR16_ABSOLUTE       (disp)                near (1M)
788    a24          : CR16_ABSOLUTE       (disp)                medium  (16M)
789    R  + d20     : CR16_REG_REL        (base,  disp)         near (1M+64K)
790    RP + d4      : CR16_REGP_REL       (base,  disp)         far  (4G)
791    RP + d16     : CR16_REGP_REL       (base,  disp)         far  (4G)
792    RP + d20     : CR16_REGP_REL       (base,  disp)         far  (4G)
793    I            : *** Valid but port does not support this
794    I  + a20     : *** Valid but port does not support this
795    I  + RP + d14: CR16_INDEX_REGP_REL (base,  index, disp)  far  (4G)
796    I  + RP + d20: CR16_INDEX_REGP_REL (base,  index, disp)  far  (4G)
797 
798    Decomposing Data model in case of absolute address.
799 
800    Target Option             Address type Resultant Data ref type
801    ----------------------    ------------ -----------------------
802    CR16_TARGET_MODEL_NEAR    ABS20        DM_DEFAULT
803    CR16_TARGET_MODEL_NEAR    IMM20        DM_DEFAULT
804    CR16_TARGET_MODEL_NEAR    ABS24        Invalid
805    CR16_TARGET_MODEL_NEAR    IMM32        Invalid
806 
807    CR16_TARGET_MODEL_MEDIUM  ABS20        DM_DEFAULT
808    CR16_TARGET_MODEL_MEDIUM  IMM20        DM_DEFAULT
809    CR16_TARGET_MODEL_MEDIUM  ABS24        DM_FAR
810    CR16_TARGET_MODEL_MEDIUM  IMM32        Invalid
811 
812    CR16_TARGET_MODEL_FAR     ABS20        DM_DEFAULT
813    CR16_TARGET_MODEL_FAR     IMM20        DM_DEFAULT
814    CR16_TARGET_MODEL_FAR     ABS24        DM_FAR
815    CR16_TARGET_MODEL_FAR     IMM32        DM_FAR.  */
816 enum cr16_addrtype
cr16_decompose_address(rtx addr,struct cr16_address * out,bool debug_print,bool treat_as_const)817 cr16_decompose_address (rtx addr, struct cr16_address *out,
818 			bool debug_print, bool treat_as_const)
819 {
820   rtx base = NULL_RTX, disp = NULL_RTX, index = NULL_RTX;
821   enum data_model_type data = ILLEGAL_DM;
822   int code = -1;
823   enum cr16_addrtype retval = CR16_INVALID;
824 
825   switch (GET_CODE (addr))
826     {
827     case CONST_INT:
828       /* Absolute address (known at compile time).  */
829       code = 0;
830       if (debug_print)
831 	fprintf (stderr, "\ncode:%d", code);
832       disp = addr;
833 
834       if (debug_print)
835 	{
836 	  fprintf (stderr, "\ndisp:");
837 	  debug_rtx (disp);
838 	}
839 
840       if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
841 	{
842 	  data = DM_DEFAULT;
843 	  if (debug_print)
844 	    fprintf (stderr, "\ndata:%d", data);
845 	  retval = CR16_ABSOLUTE;
846 	}
847       else if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 24))
848 	{
849 	  if (!CR16_TARGET_DATA_NEAR)
850 	    {
851 	      data = DM_FAR;
852 	      if (debug_print)
853 		fprintf (stderr, "\ndata:%d", data);
854 	      retval = CR16_ABSOLUTE;
855 	    }
856 	  else
857 	    return CR16_INVALID;	/* ABS24 is not support in NEAR model.  */
858 	}
859       else
860 	return CR16_INVALID;
861       break;
862 
863     case CONST:
864       /* A CONST is an expression of PLUS or MINUS with
865 	 CONST_INT, SYMBOL_REF or LABEL_REF. This is the
866 	 result of assembly-time arithmetic computation.  */
867       retval = CR16_ABSOLUTE;
868       disp = addr;
869       /* Call the helper function to check the validity.  */
870       cr16_decompose_const (XEXP (addr, 0), &code, &data, treat_as_const);
871       if ((code == 0) && (data == ILLEGAL_DM))
872 	/* CONST is not valid code or data address.  */
873 	return CR16_INVALID;
874       if (debug_print)
875 	{
876 	  fprintf (stderr, "\ndisp:");
877 	  debug_rtx (disp);
878 	  fprintf (stderr, "\ncode:%d", code);
879 	  fprintf (stderr, "\ndata:%d", data);
880 	}
881       break;
882 
883     case LABEL_REF:
884       retval = CR16_ABSOLUTE;
885       disp = addr;
886       /* 1 - indicates non-function symbol.  */
887       code = 1;
888       if (debug_print)
889 	{
890 	  fprintf (stderr, "\ndisp:");
891 	  debug_rtx (disp);
892 	  fprintf (stderr, "\ncode:%d", code);
893 	}
894       break;
895 
896     case SYMBOL_REF:
897       /* Absolute address (known at link time).  */
898       retval = CR16_ABSOLUTE;
899       disp = addr;
900       /* This is a code address if symbol_ref is a function.  */
901       /* 2 indicates func sym.  */
902       code = SYMBOL_REF_FUNCTION_P (addr) ? 2 : 0;
903       if (debug_print)
904 	{
905 	  fprintf (stderr, "\ndisp:");
906 	  debug_rtx (disp);
907 	  fprintf (stderr, "\ncode:%d", code);
908 	}
909       /* If not function ref then check if valid data ref.  */
910       if (code == 0)
911 	{
912 	  if (CR16_TARGET_DATA_NEAR)
913 	    data = DM_DEFAULT;
914 	  else if (CR16_TARGET_DATA_MEDIUM)
915 	    data = DM_FAR;
916 	  else if (CR16_TARGET_DATA_FAR)
917 	    {
918 	      if (treat_as_const)
919 		/* This will be used only for printing the
920 		   qualifier. This call is (may be) made
921 		   by cr16_print_operand_address.  */
922 		data = DM_FAR;
923 	      else
924 		/* This call is (may be) made by
925 		   cr16_legitimate_address_p.  */
926 		return CR16_INVALID;
927 	    }
928 	  else
929 	    data = DM_DEFAULT;
930 	}
931       if (debug_print)
932 	fprintf (stderr, "\ndata:%d", data);
933       break;
934 
935     case REG:
936     case SUBREG:
937       /* Register relative address.  */
938       /* Assume REG fits in a single register.  */
939       retval = CR16_REG_REL;
940       if (GET_MODE_BITSIZE (GET_MODE (addr)) > BITS_PER_WORD)
941 	if (!LONG_REG_P (REGNO (addr)))
942 	  /* REG will result in reg pair.  */
943 	  retval = CR16_REGP_REL;
944       base = addr;
945       if (debug_print)
946 	{
947 	  fprintf (stderr, "\nbase:");
948 	  debug_rtx (base);
949 	}
950       break;
951 
952     case PLUS:
953       switch (GET_CODE (XEXP (addr, 0)))
954 	{
955 	case REG:
956 	case SUBREG:
957 	  /* REG + DISP20.  */
958 	  /* All Reg relative addresses having a displacement needs
959 	     to fit in 20-bits.  */
960 	  disp = XEXP (addr, 1);
961 	  if (debug_print)
962 	    {
963 	      fprintf (stderr, "\ndisp:");
964 	      debug_rtx (disp);
965 	    }
966 	  switch (GET_CODE (XEXP (addr, 1)))
967 	    {
968 	    case CONST_INT:
969 	      /* Shall fit in 20-bits.  */
970 	      if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
971 		return CR16_INVALID;
972 	      code = 0;
973 	      if (debug_print)
974 		fprintf (stderr, "\ncode:%d", code);
975 	      break;
976 
977 	    case UNSPEC:
978 	      switch (XINT (XEXP (addr, 1), 1))
979 		{
980 		case UNSPEC_LIBRARY_OFFSET:
981 		default:
982 		  gcc_unreachable ();
983 		}
984 	      break;
985 
986 	    case LABEL_REF:
987 	    case SYMBOL_REF:
988 	    case CONST:
989 	      /* This is also a valid expression for address.
990 	         However, we cannot ascertain if the resultant
991 	         displacement will be valid 20-bit value.  Therefore,
992 	         lets not allow such an expression for now.  This will
993 	         be updated when  we find a way to validate this
994 	         expression as legitimate address.
995 	         Till then fall through CR16_INVALID.  */
996 	    default:
997 	      return CR16_INVALID;
998 	    }
999 
1000 	  /* Now check if REG can fit into single or pair regs.  */
1001 	  retval = CR16_REG_REL;
1002 	  base = XEXP (addr, 0);
1003 	  if (debug_print)
1004 	    {
1005 	      fprintf (stderr, "\nbase:");
1006 	      debug_rtx (base);
1007 	    }
1008 	  if (GET_MODE_BITSIZE (GET_MODE ((XEXP (addr, 0)))) > BITS_PER_WORD)
1009 	    {
1010 	      if (!LONG_REG_P (REGNO ((XEXP (addr, 0)))))
1011 		/* REG will result in reg pair.  */
1012 		retval = CR16_REGP_REL;
1013 	    }
1014 	  break;
1015 
1016 	case PLUS:
1017 	  /* Valid expr:
1018 	     plus
1019 	      /\
1020 	     /  \
1021 	     plus idx
1022 	      /\
1023 	     /  \
1024 	     reg  const_int
1025 
1026 	     Check if the operand 1 is valid index register.  */
1027 	  data = ILLEGAL_DM;
1028 	  if (debug_print)
1029 	    fprintf (stderr, "\ndata:%d", data);
1030 	  switch (GET_CODE (XEXP (addr, 1)))
1031 	    {
1032 	    case REG:
1033 	    case SUBREG:
1034 	      if (!REG_OK_FOR_INDEX_P (XEXP (addr, 1)))
1035 		return CR16_INVALID;
1036 	      /* OK. REG is a valid index register.  */
1037 	      index = XEXP (addr, 1);
1038 	      if (debug_print)
1039 		{
1040 		  fprintf (stderr, "\nindex:");
1041 		  debug_rtx (index);
1042 		}
1043 	      break;
1044 	    default:
1045 	      return CR16_INVALID;
1046 	    }
1047 	  /* Check if operand 0 of operand 0 is REGP.  */
1048 	  switch (GET_CODE (XEXP (XEXP (addr, 0), 0)))
1049 	    {
1050 	    case REG:
1051 	    case SUBREG:
1052 	      /* Now check if REG is a REGP and not in LONG regs.  */
1053 	      if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (addr, 0), 0)))
1054 		  > BITS_PER_WORD)
1055 		{
1056 		  if (REGNO (XEXP (XEXP (addr, 0), 0))
1057 		      >= CR16_FIRST_DWORD_REGISTER)
1058 		    return CR16_INVALID;
1059 		  base = XEXP (XEXP (addr, 0), 0);
1060 		  if (debug_print)
1061 		    {
1062 		      fprintf (stderr, "\nbase:");
1063 		      debug_rtx (base);
1064 		    }
1065 		}
1066 	      else
1067 		return CR16_INVALID;
1068 	      break;
1069 	    default:
1070 	      return CR16_INVALID;
1071 	    }
1072 	  /* Now check if the operand 1 of operand 0 is const_int.  */
1073 	  if (GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
1074 	    {
1075 	      disp = XEXP (XEXP (addr, 0), 1);
1076 	      if (debug_print)
1077 		{
1078 		  fprintf (stderr, "\ndisp:");
1079 		  debug_rtx (disp);
1080 		}
1081 	      if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
1082 		return CR16_INVALID;
1083 	    }
1084 	  else
1085 	    return CR16_INVALID;
1086 	  retval = CR16_INDEX_REGP_REL;
1087 	  break;
1088 	default:
1089 	  return CR16_INVALID;
1090 	}
1091       break;
1092 
1093     default:
1094       return CR16_INVALID;
1095     }
1096 
1097   /* Check if the base and index registers are valid.  */
1098   if (base && !(cr16_addr_reg_p (base)))
1099     return CR16_INVALID;
1100   if (base && !(CR16_REG_OK_FOR_BASE_P (base)))
1101     return CR16_INVALID;
1102   if (index && !(REG_OK_FOR_INDEX_P (index)))
1103     return CR16_INVALID;
1104 
1105   /* Write the decomposition to out parameter.  */
1106   out->base = base;
1107   out->disp = disp;
1108   out->index = index;
1109   out->data = data;
1110   out->code = code;
1111 
1112   return retval;
1113 }
1114 
1115 /* Return non-zero value if 'x' is legitimate PIC operand
1116    when generating PIC code.  */
1117 int
legitimate_pic_operand_p(rtx x)1118 legitimate_pic_operand_p (rtx x)
1119 {
1120   switch (GET_CODE (x))
1121     {
1122     case SYMBOL_REF:
1123       return 0;
1124       break;
1125     case LABEL_REF:
1126       return 0;
1127       break;
1128     case CONST:
1129       /* REVISIT: Use something like symbol_referenced_p.  */
1130       if (GET_CODE (XEXP (x, 0)) == PLUS
1131 	  && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
1132 	      || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
1133 	  && (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
1134 	return 0;
1135       break;
1136     case MEM:
1137       return legitimate_pic_operand_p (XEXP (x, 0));
1138       break;
1139     default:
1140       break;
1141     }
1142   return 1;
1143 }
1144 
1145 /* Convert a non-PIC address in `orig' to a PIC address in `reg'.
1146 
1147      Input            Output (-f pic)        Output (-f PIC)
1148      orig             reg
1149 
1150      C1   symbol           symbol@BRO (r12)        symbol@GOT (r12)
1151 
1152      C2   symbol + offset  symbol+offset@BRO (r12) symbol+offset@GOT (r12)
1153 
1154      NOTE: @BRO is added using unspec:BRO
1155      NOTE: @GOT is added using unspec:GOT.  */
1156 rtx
legitimize_pic_address(rtx orig,enum machine_mode mode ATTRIBUTE_UNUSED,rtx reg)1157 legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
1158 			rtx reg)
1159 {
1160   /* First handle a simple SYMBOL_REF or LABEL_REF.  */
1161   if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
1162     {
1163       if (reg == 0)
1164 	reg = gen_reg_rtx (Pmode);
1165 
1166       if (flag_pic == NEAR_PIC)
1167 	{
1168 	  /* Unspec to handle -fpic option.  */
1169 	  emit_insn (gen_unspec_bro_addr (reg, orig));
1170 	  emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx));
1171 	}
1172       else if (flag_pic == FAR_PIC)
1173 	{
1174 	  /* Unspec to handle -fPIC option.  */
1175 	  emit_insn (gen_unspec_got_addr (reg, orig));
1176 	}
1177       return reg;
1178     }
1179   else if (GET_CODE (orig) == CONST)
1180     {
1181       /* To handle (symbol + offset).  */
1182       rtx base, offset;
1183 
1184       if (GET_CODE (XEXP (orig, 0)) == PLUS
1185 	  && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1186 	return orig;
1187 
1188       if (reg == 0)
1189 	{
1190 	  gcc_assert (can_create_pseudo_p ());
1191 	  reg = gen_reg_rtx (Pmode);
1192 	}
1193 
1194       gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
1195 
1196       base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
1197       offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1198 				       base == reg ? 0 : reg);
1199 
1200       /* REVISIT: Optimize for const-offsets.  */
1201       emit_insn (gen_addsi3 (reg, base, offset));
1202 
1203       return reg;
1204     }
1205   return orig;
1206 }
1207 
1208 /* Implementation of TARGET_LEGITIMATE_ADDRESS_P.  */
1209 static bool
cr16_legitimate_address_p(enum machine_mode mode ATTRIBUTE_UNUSED,rtx addr,bool strict)1210 cr16_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
1211 			   rtx addr, bool strict)
1212 {
1213   enum cr16_addrtype addrtype;
1214   struct cr16_address address;
1215 
1216   if (TARGET_DEBUG_ADDR)
1217     {
1218       fprintf (stderr,
1219 	       "\n======\nTARGET_LEGITIMATE_ADDRESS_P, mode = %s, strict = %d",
1220 	       GET_MODE_NAME (mode), strict);
1221       debug_rtx (addr);
1222     }
1223   addrtype = cr16_decompose_address (addr, &address,
1224 				     (TARGET_DEBUG_ADDR ? 1 : 0), FALSE);
1225 
1226   if (TARGET_DEBUG_ADDR)
1227     {
1228       const char *typestr;
1229 
1230       switch (addrtype)
1231 	{
1232 	case CR16_INVALID:
1233 	  typestr = "invalid";
1234 	  break;
1235 	case CR16_ABSOLUTE:
1236 	  typestr = "absolute";
1237 	  break;
1238 	case CR16_REG_REL:
1239 	  typestr = "register relative";
1240 	  break;
1241 	case CR16_REGP_REL:
1242 	  typestr = "register pair relative";
1243 	  break;
1244 	case CR16_INDEX_REGP_REL:
1245 	  typestr = "index + register pair relative";
1246 	  break;
1247 	default:
1248 	  gcc_unreachable ();
1249 	}
1250       fprintf (stderr, "\ncr16 address type: %s\n", typestr);
1251     }
1252 
1253   if (addrtype == CR16_INVALID)
1254     return FALSE;
1255 
1256   if (strict)
1257     {
1258       if (address.base
1259 	  && !REGNO_MODE_OK_FOR_BASE_P (REGNO (address.base), mode))
1260 	{
1261 	  if (TARGET_DEBUG_ADDR)
1262 	    fprintf (stderr, "base register not strict\n");
1263 	  return FALSE;
1264 	}
1265       if (address.index && !REGNO_OK_FOR_INDEX_P (REGNO (address.index)))
1266 	{
1267 	  if (TARGET_DEBUG_ADDR)
1268 	    fprintf (stderr, "index register not strict\n");
1269 	  return FALSE;
1270 	}
1271     }
1272 
1273   /* Return true if addressing mode is register relative.  */
1274   if (flag_pic)
1275     {
1276       if (addrtype == CR16_REG_REL || addrtype == CR16_REGP_REL)
1277 	return TRUE;
1278       else
1279 	return FALSE;
1280     }
1281 
1282   return TRUE;
1283 }
1284 
1285 /* Routines to compute costs.  */
1286 
1287 /* Return cost of the memory address x.  */
1288 static int
cr16_address_cost(rtx addr,enum machine_mode mode ATTRIBUTE_UNUSED,addr_space_t as ATTRIBUTE_UNUSED,bool speed ATTRIBUTE_UNUSED)1289 cr16_address_cost (rtx addr, enum machine_mode mode ATTRIBUTE_UNUSED,
1290 		   addr_space_t as ATTRIBUTE_UNUSED,
1291 		   bool speed ATTRIBUTE_UNUSED)
1292 {
1293   enum cr16_addrtype addrtype;
1294   struct cr16_address address;
1295   int cost = 2;
1296 
1297   addrtype = cr16_decompose_address (addr, &address, 0, FALSE);
1298 
1299   gcc_assert (addrtype != CR16_INVALID);
1300 
1301   /* CR16_ABSOLUTE            : 3
1302      CR16_REG_REL  (disp !=0) : 4
1303      CR16_REG_REL  (disp ==0) : 5
1304      CR16_REGP_REL (disp !=0) : 6
1305      CR16_REGP_REL (disp ==0) : 7
1306      CR16_INDEX_REGP_REL (disp !=0) : 8
1307      CR16_INDEX_REGP_REL (disp ==0) : 9.  */
1308   switch (addrtype)
1309     {
1310     case CR16_ABSOLUTE:
1311       cost += 1;
1312       break;
1313     case CR16_REGP_REL:
1314       cost += 2;
1315       /* Fall through.  */
1316     case CR16_REG_REL:
1317       cost += 3;
1318       if (address.disp)
1319 	cost -= 1;
1320       break;
1321     case CR16_INDEX_REGP_REL:
1322       cost += 7;
1323       if (address.disp)
1324 	cost -= 1;
1325     default:
1326       break;
1327     }
1328 
1329   if (TARGET_DEBUG_ADDR)
1330     {
1331       fprintf (stderr, "\n======\nmacro TARGET_ADDRESS_COST = %d\n", cost);
1332       debug_rtx (addr);
1333     }
1334 
1335   return cost;
1336 }
1337 
1338 
1339 /* Implement `TARGET_REGISTER_MOVE_COST'.  */
1340 static int
cr16_register_move_cost(enum machine_mode mode ATTRIBUTE_UNUSED,reg_class_t from ATTRIBUTE_UNUSED,reg_class_t to)1341 cr16_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1342 			 reg_class_t from ATTRIBUTE_UNUSED, reg_class_t to)
1343 {
1344   return (to != GENERAL_REGS ? 8 : 2);
1345 }
1346 
1347 /* Implement `TARGET_MEMORY_MOVE_COST'.  */
1348 
1349 /* Return the cost of moving data of mode MODE between a register of class
1350    CLASS and memory; IN is zero if the value is to be written to memory,
1351    nonzero if it is to be read in. This cost is relative to those in
1352    REGISTER_MOVE_COST.  */
1353 static int
cr16_memory_move_cost(enum machine_mode mode,reg_class_t rclass ATTRIBUTE_UNUSED,bool in ATTRIBUTE_UNUSED)1354 cr16_memory_move_cost (enum machine_mode mode,
1355 		       reg_class_t rclass ATTRIBUTE_UNUSED,
1356 		       bool in ATTRIBUTE_UNUSED)
1357 {
1358   /* One LD or ST takes twice the time of a simple reg-reg move.  */
1359   if (reg_classes_intersect_p (rclass, GENERAL_REGS))
1360     return (4 * HARD_REGNO_NREGS (0, mode));
1361   else
1362     return (100);
1363 }
1364 
1365 /* Instruction output.  */
1366 
1367 /* Check if a const_double is ok for cr16 store-immediate instructions.  */
1368 int
cr16_const_double_ok(rtx op)1369 cr16_const_double_ok (rtx op)
1370 {
1371   if (GET_MODE (op) == SFmode)
1372     {
1373       REAL_VALUE_TYPE r;
1374       long l;
1375       REAL_VALUE_FROM_CONST_DOUBLE (r, op);
1376       REAL_VALUE_TO_TARGET_SINGLE (r, l);
1377       return UNSIGNED_INT_FITS_N_BITS (l, 4) ? 1 : 0;
1378     }
1379 
1380   return ((UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op), 4)) &&
1381 	  (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op), 4))) ? 1 : 0;
1382 }
1383 
1384 /* Returns bit position of first 0 or 1 bit.
1385    It is safe to assume val as 16-bit wide.  */
1386 int
cr16_operand_bit_pos(int val,int bitval)1387 cr16_operand_bit_pos (int val, int bitval)
1388 {
1389   int i;
1390   if (bitval == 0)
1391     val = ~val;
1392 
1393   for (i = 0; i < 16; i++)
1394     if (val & (1 << i))
1395       break;
1396   return i;
1397 }
1398 
1399 /* Implements the macro PRINT_OPERAND defined in cr16.h.  */
1400 static void
cr16_print_operand(FILE * file,rtx x,int code)1401 cr16_print_operand (FILE * file, rtx x, int code)
1402 {
1403   int ptr_dereference = 0;
1404 
1405   switch (code)
1406     {
1407     case 'd':
1408       {
1409 	const char *cr16_cmp_str;
1410 	switch (GET_CODE (x))
1411 	  {
1412 	    /* MD: compare (reg, reg or imm) but CR16: cmp (reg or imm, reg)
1413 	       -> swap all non symmetric ops.  */
1414 	  case EQ:
1415 	    cr16_cmp_str = "eq";
1416 	    break;
1417 	  case NE:
1418 	    cr16_cmp_str = "ne";
1419 	    break;
1420 	  case GT:
1421 	    cr16_cmp_str = "lt";
1422 	    break;
1423 	  case GTU:
1424 	    cr16_cmp_str = "lo";
1425 	    break;
1426 	  case LT:
1427 	    cr16_cmp_str = "gt";
1428 	    break;
1429 	  case LTU:
1430 	    cr16_cmp_str = "hi";
1431 	    break;
1432 	  case GE:
1433 	    cr16_cmp_str = "le";
1434 	    break;
1435 	  case GEU:
1436 	    cr16_cmp_str = "ls";
1437 	    break;
1438 	  case LE:
1439 	    cr16_cmp_str = "ge";
1440 	    break;
1441 	  case LEU:
1442 	    cr16_cmp_str = "hs";
1443 	    break;
1444 	  default:
1445 	    gcc_unreachable ();
1446 	  }
1447 	fprintf (file, "%s", cr16_cmp_str);
1448 	return;
1449       }
1450     case '$':
1451       putc ('$', file);
1452       return;
1453 
1454     case 'p':
1455       if (GET_CODE (x) == REG)
1456 	{
1457 	  /* For Push instructions, we should not print register pairs.  */
1458 	  fprintf (file, "%s", reg_names[REGNO (x)]);
1459 	  return;
1460 	}
1461       break;
1462 
1463     case 'b':
1464       /* Print the immediate address for bal
1465          'b' is used instead of 'a' to avoid compiler calling
1466          the GO_IF_LEGITIMATE_ADDRESS which cannot
1467          perform checks on const_int code addresses as it
1468          assumes all const_int are data addresses.  */
1469       fprintf (file, "0x%lx", INTVAL (x));
1470       return;
1471 
1472     case 'r':
1473       /* Print bit position of first 0.  */
1474       fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 0));
1475       return;
1476 
1477     case 's':
1478       /* Print bit position of first 1.  */
1479       fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 1));
1480       return;
1481     case 'g':
1482       /* 'g' is used for implicit mem: dereference.  */
1483       ptr_dereference = 1;
1484     case 'f':
1485     case 0:
1486       /* default.  */
1487       switch (GET_CODE (x))
1488 	{
1489 	case REG:
1490 	  if (GET_MODE_BITSIZE (GET_MODE (x)) > BITS_PER_WORD)
1491 	    {
1492 	      if (LONG_REG_P (REGNO (x)))
1493 		fprintf (file, "(%s)", reg_names[REGNO (x)]);
1494 	      else
1495 		fprintf (file, "(%s,%s)", reg_names[REGNO (x) + 1],
1496 			 reg_names[REGNO (x)]);
1497 	    }
1498 	  else
1499 	    fprintf (file, "%s", reg_names[REGNO (x)]);
1500 	  return;
1501 
1502 	case MEM:
1503 	  output_address (XEXP (x, 0));
1504 	  return;
1505 
1506 	case CONST_DOUBLE:
1507 	  {
1508 	    REAL_VALUE_TYPE r;
1509 	    long l;
1510 
1511 	    REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1512 	    REAL_VALUE_TO_TARGET_SINGLE (r, l);
1513 
1514 	    fprintf (file, "$0x%lx", l);
1515 	    return;
1516 	  }
1517 	case CONST_INT:
1518 	  {
1519 	    fprintf (file, "$%ld", INTVAL (x));
1520 	    return;
1521 	  }
1522 	case UNSPEC:
1523 	  switch (XINT (x, 1))
1524 	    {
1525 	    default:
1526 	      gcc_unreachable ();
1527 	    }
1528 	  break;
1529 
1530 	default:
1531 	  if (!ptr_dereference)
1532 	    {
1533 	      putc ('$', file);
1534 	    }
1535 	  cr16_print_operand_address (file, x);
1536 	  return;
1537 	}
1538     default:
1539       output_operand_lossage ("invalid %%xn code");
1540     }
1541 
1542   gcc_unreachable ();
1543 }
1544 
1545 /* Implements the macro PRINT_OPERAND_ADDRESS defined in cr16.h.  */
1546 
1547 static void
cr16_print_operand_address(FILE * file,rtx addr)1548 cr16_print_operand_address (FILE * file, rtx addr)
1549 {
1550   enum cr16_addrtype addrtype;
1551   struct cr16_address address;
1552 
1553   /* Decompose the address. Also ask it to treat address as constant.  */
1554   addrtype = cr16_decompose_address (addr, &address, 0, TRUE);
1555 
1556   if (address.disp && GET_CODE (address.disp) == UNSPEC)
1557     {
1558       debug_rtx (addr);
1559     }
1560 
1561   switch (addrtype)
1562     {
1563     case CR16_REG_REL:
1564       if (address.disp)
1565 	{
1566 	  if (GET_CODE (address.disp) == UNSPEC)
1567 	    cr16_print_operand (file, address.disp, 0);
1568 	  else
1569 	    output_addr_const (file, address.disp);
1570 	}
1571       else
1572 	fprintf (file, "0");
1573       fprintf (file, "(%s)", reg_names[REGNO (address.base)]);
1574       break;
1575 
1576     case CR16_ABSOLUTE:
1577       if (address.disp)
1578 	output_addr_const (file, address.disp);
1579       else
1580 	fprintf (file, "0");
1581       break;
1582 
1583     case CR16_INDEX_REGP_REL:
1584       fprintf (file, "[%s]", reg_names[REGNO (address.index)]);
1585       /* Fall through.  */
1586     case CR16_REGP_REL:
1587       if (address.disp)
1588 	{
1589 	  if (GET_CODE (address.disp) == UNSPEC)
1590 	    cr16_print_operand (file, address.disp, 0);
1591 	  else
1592 	    output_addr_const (file, address.disp);
1593 	}
1594       else
1595 	fprintf (file, "0");
1596       fprintf (file, "(%s,%s)", reg_names[REGNO (address.base) + 1],
1597 	       reg_names[REGNO (address.base)]);
1598       break;
1599     default:
1600       debug_rtx (addr);
1601       gcc_unreachable ();
1602     }
1603   /* Add qualifiers to the address expression that was just printed.  */
1604   if (flag_pic < NEAR_PIC && address.code == 0)
1605     {
1606       if (address.data == DM_FAR)
1607 	/* Addr contains SYMBOL_REF & far data ptr.  */
1608 	fprintf (file, "@l");
1609       else if (address.data == DM_DEFAULT)
1610 	/* Addr contains SYMBOL_REF & medium data ptr.  */
1611 	fprintf (file, "@m");
1612       /* Addr contains SYMBOL_REF & medium data ptr.  */
1613       else if (address.data == DM_NEAR)
1614 	/* Addr contains SYMBOL_REF & near data ptr.  */
1615 	fprintf (file, "@s");
1616     }
1617   else if (flag_pic == NEAR_PIC
1618 	   && (address.code == 0) && (address.data == DM_FAR
1619 				      || address.data == DM_DEFAULT
1620 				      || address.data == DM_NEAR))
1621     {
1622       fprintf (file, "@l");
1623     }
1624   else if (flag_pic == NEAR_PIC && address.code == 2)
1625     {
1626       fprintf (file, "pic");
1627     }
1628   else if (flag_pic == NEAR_PIC && address.code == 1)
1629     {
1630       fprintf (file, "@cpic");
1631     }
1632 
1633   else if (flag_pic == FAR_PIC && address.code == 2)
1634     {
1635       /* REVISIT: cr16 register indirect jump expects a 1-bit right shifted
1636          address ! GOTc tells assembler this symbol is a text-address
1637          This needs to be fixed in such a way that this offset is done
1638          only in the case where an address is being used for indirect jump
1639          or call. Determining the potential usage of loadd is of course not
1640          possible always. Eventually, this has to be fixed in the
1641          processor.  */
1642       fprintf (file, "GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1643     }
1644   else if (flag_pic == FAR_PIC && address.code == 1)
1645     {
1646       fprintf (file, "@cGOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1647     }
1648 
1649   else if (flag_pic == FAR_PIC &&
1650 	   (address.data == DM_FAR || address.data == DM_DEFAULT
1651 	    || address.data == DM_NEAR))
1652     {
1653       fprintf (file, "@GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1654     }
1655 }
1656 
1657 /* Machine description helper functions.  */
1658 
1659 /* Called from cr16.md. The return value depends on the parameter push_or_pop:
1660    When push_or_pop is zero -> string for push instructions of prologue.
1661    When push_or_pop is nonzero -> string for pop/popret/retx in epilogue.
1662    Relies on the assumptions:
1663    1. RA is the last register to be saved.
1664    2. The maximal value of the counter is MAX_COUNT.  */
1665 char *
cr16_prepare_push_pop_string(int push_or_pop)1666 cr16_prepare_push_pop_string (int push_or_pop)
1667 {
1668   /* j is the number of registers being saved, takes care that there won't be
1669      more than 8 in one push/pop instruction.  */
1670 
1671   /* For the register mask string.  */
1672   static char one_inst_str[50];
1673 
1674   /* i is the index of current_frame_info.save_regs[], going from 0 until
1675      current_frame_info.last_reg_to_save.  */
1676   int i, start_reg;
1677   int word_cnt;
1678   int print_ra;
1679   char *return_str;
1680 
1681   /* For reversing on the push instructions if there are more than one.  */
1682   char *temp_str;
1683 
1684   return_str = (char *) xmalloc (160);
1685   temp_str = (char *) xmalloc (160);
1686 
1687   /* Initialize.  */
1688   memset (return_str, 0, 3);
1689 
1690   i = 0;
1691   while (i <= current_frame_info.last_reg_to_save)
1692     {
1693       /* Prepare mask for one instruction.  */
1694       one_inst_str[0] = 0;
1695 
1696       /* To count number of words in one instruction.  */
1697       word_cnt = 0;
1698       start_reg = i;
1699       print_ra = 0;
1700       while ((word_cnt < MAX_COUNT)
1701 	     && (i <= current_frame_info.last_reg_to_save))
1702 	{
1703 	  /* For each non consecutive save register,
1704 	     a new instruction shall be generated.  */
1705 	  if (!current_frame_info.save_regs[i])
1706 	    {
1707 	      /* Move to next reg and break.  */
1708 	      ++i;
1709 	      break;
1710 	    }
1711 
1712 	  if (i == RETURN_ADDRESS_REGNUM)
1713 	    print_ra = 1;
1714 	  else
1715 	    {
1716 	      /* Check especially if adding 2 does not cross the MAX_COUNT.  */
1717 	      if ((word_cnt + ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2))
1718 		  >= MAX_COUNT)
1719 		break;
1720 	      /* Increase word count by 2 for long registers except RA.   */
1721 	      word_cnt += ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2);
1722 	    }
1723 	  ++i;
1724 	}
1725 
1726       /* No need to generate any instruction as
1727          no register or RA needs to be saved.  */
1728       if ((word_cnt == 0) && (print_ra == 0))
1729 	continue;
1730 
1731       /* Now prepare the instruction operands.  */
1732       if (word_cnt > 0)
1733 	{
1734 	  sprintf (one_inst_str, "$%d, %s", word_cnt, reg_names[start_reg]);
1735 	  if (print_ra)
1736 	    strcat (one_inst_str, ", ra");
1737 	}
1738       else
1739 	strcat (one_inst_str, "ra");
1740 
1741       if (push_or_pop == 1)
1742 	{
1743 	  /* Pop instruction.  */
1744 	  if (print_ra && !cr16_interrupt_function_p ()
1745 	      && !crtl->calls_eh_return)
1746 	    /* Print popret if RA is saved and its not a interrupt
1747 	       function.  */
1748 	    strcpy (temp_str, "\n\tpopret\t");
1749 	  else
1750 	    strcpy (temp_str, "\n\tpop\t");
1751 
1752 	  strcat (temp_str, one_inst_str);
1753 
1754 	  /* Add the pop instruction list.  */
1755 	  strcat (return_str, temp_str);
1756 	}
1757       else
1758 	{
1759 	  /* Push instruction.  */
1760 	  strcpy (temp_str, "\n\tpush\t");
1761 	  strcat (temp_str, one_inst_str);
1762 
1763 	  /* We need to reverse the order of the instructions if there
1764 	     are more than one. (since the pop will not be reversed in
1765 	     the epilogue.  */
1766 	  strcat (temp_str, return_str);
1767 	  strcpy (return_str, temp_str);
1768 	}
1769     }
1770 
1771   if (push_or_pop == 1)
1772     {
1773       /* POP.  */
1774       if (cr16_interrupt_function_p ())
1775 	strcat (return_str, "\n\tretx\n");
1776       else if (crtl->calls_eh_return)
1777 	{
1778 	  /* Add stack adjustment before returning to exception handler
1779 	     NOTE: EH_RETURN_STACKADJ_RTX must refer to (r5, r4).  */
1780 	  strcat (return_str, "\n\taddd\t (r5, r4), (sp)\t\n");
1781 	  strcat (return_str, "\n\tjump\t (ra)\n");
1782 
1783 	  /* But before anything else, undo the adjustment addition done in
1784 	     cr16_expand_epilogue ().  */
1785 	  strcpy (temp_str, "\n\tsubd\t (r5, r4), (sp)\t\n");
1786 	  strcat (temp_str, return_str);
1787 	  strcpy (return_str, temp_str);
1788 	}
1789       else if (!FUNC_IS_NORETURN_P (current_function_decl)
1790 	       && !(current_frame_info.save_regs[RETURN_ADDRESS_REGNUM]))
1791 	strcat (return_str, "\n\tjump\t (ra)\n");
1792     }
1793 
1794   /* Skip the newline and the tab in the start of return_str.  */
1795   return_str += 2;
1796   return return_str;
1797 }
1798 
1799 
1800 /* Generate DWARF2 annotation for multi-push instruction.  */
1801 static void
cr16_create_dwarf_for_multi_push(rtx insn)1802 cr16_create_dwarf_for_multi_push (rtx insn)
1803 {
1804   rtx dwarf, reg, tmp;
1805   int i, j, from, to, word_cnt, dwarf_par_index, inc;
1806   enum machine_mode mode;
1807   int num_regs = 0, offset = 0, split_here = 0, total_push_bytes = 0;
1808 
1809   for (i = 0; i <= current_frame_info.last_reg_to_save; ++i)
1810     {
1811       if (current_frame_info.save_regs[i])
1812 	{
1813 	  ++num_regs;
1814 	  if (i < CR16_FIRST_DWORD_REGISTER)
1815 	    total_push_bytes += 2;
1816 	  else
1817 	    total_push_bytes += 4;
1818 	}
1819     }
1820 
1821   if (!num_regs)
1822     return;
1823 
1824   dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1));
1825   dwarf_par_index = num_regs;
1826 
1827   from = current_frame_info.last_reg_to_save + 1;
1828   to = current_frame_info.last_reg_to_save;
1829   word_cnt = 0;
1830 
1831   for (i = current_frame_info.last_reg_to_save; i >= 0;)
1832     {
1833       if (!current_frame_info.save_regs[i] || 0 == i || split_here)
1834 	{
1835 	  /* This block of regs is pushed in one instruction.  */
1836 	  if (0 == i && current_frame_info.save_regs[i])
1837 	    from = 0;
1838 
1839 	  for (j = to; j >= from; --j)
1840 	    {
1841 	      if (j < CR16_FIRST_DWORD_REGISTER)
1842 		{
1843 		  mode = HImode;
1844 		  inc = 1;
1845 		}
1846 	      else
1847 		{
1848 		  mode = SImode;
1849 		  inc = 2;
1850 		}
1851 	      reg = gen_rtx_REG (mode, j);
1852 	      offset += 2 * inc;
1853 	      tmp = gen_rtx_SET (VOIDmode,
1854 				 gen_frame_mem (mode,
1855 						plus_constant
1856 						(Pmode, stack_pointer_rtx,
1857 						 total_push_bytes - offset)),
1858 				 reg);
1859 	      RTX_FRAME_RELATED_P (tmp) = 1;
1860 	      XVECEXP (dwarf, 0, dwarf_par_index--) = tmp;
1861 	    }
1862 	  from = i;
1863 	  to = --i;
1864 	  split_here = 0;
1865 	  word_cnt = 0;
1866 	  continue;
1867 	}
1868 
1869       if (i != RETURN_ADDRESS_REGNUM)
1870 	{
1871 	  inc = (i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2;
1872 	  if (word_cnt + inc >= MAX_COUNT || FRAME_POINTER_REGNUM == i)
1873 	    {
1874 	      split_here = 1;
1875 	      from = i;
1876 	      continue;
1877 	    }
1878 	  word_cnt += inc;
1879 	}
1880 
1881       from = i--;
1882     }
1883 
1884   tmp = gen_rtx_SET (SImode, stack_pointer_rtx,
1885 		     gen_rtx_PLUS (SImode, stack_pointer_rtx,
1886 				   GEN_INT (-offset)));
1887   RTX_FRAME_RELATED_P (tmp) = 1;
1888   XVECEXP (dwarf, 0, 0) = tmp;
1889 
1890   add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
1891 }
1892 
1893 /*
1894 CompactRISC CR16 Architecture stack layout:
1895 
1896      0 +---------------------
1897     |
1898     .
1899     .
1900     |
1901     +==================== Sp (x) = Ap (x+1)
1902       A | Args for functions
1903       | | called by X and      Dynamically
1904       | | Dynamic allocations  allocated and
1905       | | (alloca, variable    deallocated
1906   Stack | length arrays).
1907   grows +-------------------- Fp (x)
1908   down| | Local variables of X
1909   ward| +--------------------
1910       | | Regs saved for X-1
1911       | +==================== Sp (x-1) = Ap (x)
1912     | Args for func X
1913     | pushed by X-1
1914     +-------------------- Fp (x-1)
1915     |
1916     |
1917     V
1918 */
1919 void
cr16_expand_prologue(void)1920 cr16_expand_prologue (void)
1921 {
1922   rtx insn;
1923 
1924   cr16_compute_frame ();
1925   cr16_compute_save_regs ();
1926 
1927   /* If there is no need in push and adjustment to sp, return.  */
1928   if ((current_frame_info.total_size + current_frame_info.reg_size) == 0)
1929     return;
1930 
1931   if (current_frame_info.last_reg_to_save != -1)
1932     {
1933       /* If there are registers to push.  */
1934       insn = emit_insn (gen_push_for_prologue
1935 			(GEN_INT (current_frame_info.reg_size)));
1936       cr16_create_dwarf_for_multi_push (insn);
1937       RTX_FRAME_RELATED_P (insn) = 1;
1938     }
1939 
1940 
1941   if (current_frame_info.total_size > 0)
1942     {
1943       insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1944 				    GEN_INT (-current_frame_info.total_size)));
1945       RTX_FRAME_RELATED_P (insn) = 1;
1946     }
1947 
1948   if (frame_pointer_needed)
1949     {
1950       /* Initialize the frame pointer with the value of the stack pointer
1951          pointing now to the locals.  */
1952       insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1953     }
1954 }
1955 
1956 /* Generate insn that updates the stack for local variables and padding
1957    for registers we save.   - Generate the appropriate return insn.  */
1958 void
cr16_expand_epilogue(void)1959 cr16_expand_epilogue (void)
1960 {
1961   rtx insn;
1962 
1963   /* Nonzero if we need to return and pop only RA. This will generate a
1964      different insn. This differentiate is for the peepholes for call as
1965      last statement in function.  */
1966   int only_popret_RA = (current_frame_info.save_regs[RETURN_ADDRESS_REGNUM]
1967 			&& (current_frame_info.reg_size
1968 			    == CR16_UNITS_PER_DWORD));
1969 
1970   if (frame_pointer_needed)
1971     {
1972       /* Restore the stack pointer with the frame pointers value.  */
1973       insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1974     }
1975 
1976   if (current_frame_info.total_size > 0)
1977     {
1978       insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1979 				    GEN_INT (current_frame_info.total_size)));
1980       RTX_FRAME_RELATED_P (insn) = 1;
1981     }
1982 
1983   if (crtl->calls_eh_return)
1984     {
1985       /* Add this here so that (r5, r4) is actually loaded with the adjustment
1986          value; otherwise, the load might be optimized away...
1987          NOTE: remember to subtract the adjustment before popping the regs
1988          and add it back before returning.  */
1989       insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1990 				    EH_RETURN_STACKADJ_RTX));
1991     }
1992 
1993   if (cr16_interrupt_function_p ())
1994     {
1995       insn = emit_jump_insn (gen_interrupt_return ());
1996       RTX_FRAME_RELATED_P (insn) = 1;
1997     }
1998   else if (crtl->calls_eh_return)
1999     {
2000       /* Special case, pop what's necessary, adjust SP and jump to (RA).  */
2001       insn = emit_jump_insn (gen_pop_and_popret_return
2002 			     (GEN_INT (current_frame_info.reg_size)));
2003       RTX_FRAME_RELATED_P (insn) = 1;
2004     }
2005   else if (current_frame_info.last_reg_to_save == -1)
2006     /* Nothing to pop.  */
2007     /* Don't output jump for interrupt routine, only retx.  */
2008     emit_jump_insn (gen_jump_return ());
2009   else if (only_popret_RA)
2010     {
2011       insn = emit_jump_insn (gen_popret_RA_return ());
2012       RTX_FRAME_RELATED_P (insn) = 1;
2013     }
2014   else
2015     {
2016       insn = emit_jump_insn (gen_pop_and_popret_return
2017 			     (GEN_INT (current_frame_info.reg_size)));
2018       RTX_FRAME_RELATED_P (insn) = 1;
2019     }
2020 }
2021 
2022 /* Implements FRAME_POINTER_REQUIRED.  */
2023 static bool
cr16_frame_pointer_required(void)2024 cr16_frame_pointer_required (void)
2025 {
2026   return (cfun->calls_alloca || crtl->calls_eh_return
2027 	  || cfun->has_nonlocal_label || crtl->calls_eh_return);
2028 }
2029 
2030 static bool
cr16_can_eliminate(const int from ATTRIBUTE_UNUSED,const int to)2031 cr16_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
2032 {
2033   return (to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true);
2034 }
2035 
2036 
2037 /* A C compound statement that attempts to replace X with
2038    a valid memory address for an operand of mode MODE. WIN
2039    will be a C statement label elsewhere in the code.
2040    X will always be the result of a call to break_out_memory_refs (),
2041    and OLDX will be the operand that was given to that function to
2042    produce X.
2043    The code generated by this macro should not alter the
2044    substructure of X.  If it transforms X into a more legitimate form,
2045    it should assign X (which will always be a C variable) a new value.  */
2046 static rtx
cr16_legitimize_address(rtx x,rtx orig_x ATTRIBUTE_UNUSED,enum machine_mode mode ATTRIBUTE_UNUSED)2047 cr16_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED,
2048 			 enum machine_mode mode ATTRIBUTE_UNUSED)
2049 {
2050   if (flag_pic)
2051     return legitimize_pic_address (orig_x, mode, NULL_RTX);
2052   else
2053     return x;
2054 }
2055 
2056 /* Implement TARGET_LEGITIMATE_CONSTANT_P
2057    Nonzero if X is a legitimate constant for an immediate
2058    operand on the target machine.  You can assume that X
2059    satisfies CONSTANT_P. In cr16c treat legitimize float
2060    constant as an immediate operand.  */
2061 static bool
cr16_legitimate_constant_p(enum machine_mode mode ATTRIBUTE_UNUSED,rtx x ATTRIBUTE_UNUSED)2062 cr16_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED,
2063 			    rtx x ATTRIBUTE_UNUSED)
2064 {
2065   return 1;
2066 }
2067 
2068 void
notice_update_cc(rtx exp)2069 notice_update_cc (rtx exp)
2070 {
2071   if (GET_CODE (exp) == SET)
2072     {
2073       /* Jumps do not alter the cc's.  */
2074       if (SET_DEST (exp) == pc_rtx)
2075 	return;
2076 
2077       /* Moving register or memory into a register:
2078          it doesn't alter the cc's, but it might invalidate
2079          the RTX's which we remember the cc's came from.
2080          (Note that moving a constant 0 or 1 MAY set the cc's).  */
2081       if (REG_P (SET_DEST (exp))
2082 	  && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM))
2083 	{
2084 	  return;
2085 	}
2086 
2087       /* Moving register into memory doesn't alter the cc's.
2088          It may invalidate the RTX's which we remember the cc's came from.  */
2089       if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp)))
2090 	{
2091 	  return;
2092 	}
2093     }
2094 
2095   CC_STATUS_INIT;
2096   return;
2097 }
2098 
2099 static enum machine_mode
cr16_unwind_word_mode(void)2100 cr16_unwind_word_mode (void)
2101 {
2102   return SImode;
2103 }
2104 
2105 /* Helper function for md file. This function is used to emit arithmetic
2106    DI instructions. The argument "num" decides which instruction to be
2107    printed.  */
2108 const char *
cr16_emit_add_sub_di(rtx * operands,enum rtx_code code)2109 cr16_emit_add_sub_di (rtx *operands, enum rtx_code code)
2110 {
2111   rtx lo_op[2] ;
2112   rtx hi0_op[2] ;
2113   rtx hi1_op[2] ;
2114 
2115   lo_op[0] = gen_lowpart (SImode, operands[0]);
2116   hi0_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 4);
2117   hi1_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 6);
2118 
2119   lo_op[1] = gen_lowpart (SImode, operands[2]);
2120   hi0_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 4);
2121   hi1_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 6);
2122 
2123   switch (code)
2124   {
2125     case PLUS:
2126       {
2127 	output_asm_insn ("addd\t%1, %0", lo_op) ;
2128 	output_asm_insn ("addcw\t%1, %0", hi0_op) ;
2129 	output_asm_insn ("addcw\t%1, %0", hi1_op) ;
2130 	break;
2131       }
2132     case MINUS:
2133       {
2134 	output_asm_insn ("subd\t%1, %0", lo_op) ;
2135 	output_asm_insn ("subcw\t%1, %0", hi0_op) ;
2136 	output_asm_insn ("subcw\t%1, %0", hi1_op) ;
2137 	break;
2138       }
2139    default:
2140      break;
2141   }
2142 
2143   return "";
2144 }
2145 
2146 
2147 /* Helper function for md file. This function is used to emit logical
2148    DI instructions. The argument "num" decides which instruction to be
2149    printed.  */
2150 const char *
cr16_emit_logical_di(rtx * operands,enum rtx_code code)2151 cr16_emit_logical_di (rtx *operands, enum rtx_code code)
2152 {
2153   rtx lo_op[2] ;
2154   rtx hi_op[2] ;
2155 
2156   lo_op[0] = gen_lowpart (SImode, operands[0]);
2157   hi_op[0] = simplify_gen_subreg (SImode, operands[0], DImode, 4);
2158 
2159   lo_op[1] = gen_lowpart (SImode, operands[2]);
2160   hi_op[1] = simplify_gen_subreg (SImode, operands[2], DImode, 4);
2161 
2162   switch (code)
2163   {
2164     case AND:
2165       {
2166 	output_asm_insn ("andd\t%1, %0", lo_op) ;
2167 	output_asm_insn ("andd\t%1, %0", hi_op) ;
2168 	return "";
2169       }
2170     case IOR:
2171       {
2172 	output_asm_insn ("ord\t%1, %0", lo_op) ;
2173 	output_asm_insn ("ord\t%1, %0", hi_op) ;
2174 	return "";
2175       }
2176     case XOR:
2177       {
2178 	output_asm_insn ("xord\t%1, %0", lo_op) ;
2179 	output_asm_insn ("xord\t%1, %0", hi_op) ;
2180 	return "";
2181       }
2182     default:
2183       break;
2184   }
2185 
2186   return "";
2187 }
2188 
2189 /* Initialize 'targetm' variable which contains pointers to functions
2190    and data relating to the target machine.  */
2191 
2192 struct gcc_target targetm = TARGET_INITIALIZER;
2193