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