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