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