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