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