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