]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/cr16/cr16.c
Add a "compact" mode to print_rtx_function
[thirdparty/gcc.git] / gcc / config / cr16 / cr16.c
CommitLineData
b25364a0 1/* Output routines for CR16 processor.
818ab71a 2 Copyright (C) 2012-2016 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"
c7131fb2 24#include "backend.h"
e11c4407 25#include "target.h"
b25364a0 26#include "rtl.h"
e11c4407 27#include "tree.h"
c7131fb2 28#include "df.h"
b25364a0
S
29#include "tm_p.h"
30#include "regs.h"
e11c4407
AM
31#include "emit-rtl.h"
32#include "diagnostic-core.h"
33#include "stor-layout.h"
34#include "calls.h"
b25364a0
S
35#include "conditions.h"
36#include "output.h"
b25364a0 37#include "expr.h"
9b2b7279 38#include "builtins.h"
b25364a0 39
994c5d85 40/* This file should be included last. */
d58627a0
RS
41#include "target-def.h"
42
b25364a0
S
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'
073a8998 60 functions, to accommodate for unwinding. */
b25364a0
S
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
100struct 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. */
114static 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. */
121static enum data_model_type data_model = DM_DEFAULT;
122
123/* TARGETM Function Prototypes and forward declarations */
124static void cr16_print_operand (FILE *, rtx, int);
cc8ca59e 125static void cr16_print_operand_address (FILE *, machine_mode, rtx);
b25364a0
S
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
d81db636
SB
175#undef TARGET_LRA_P
176#define TARGET_LRA_P hook_bool_void_false
177
b25364a0
S
178/* Returning function value. */
179#undef TARGET_FUNCTION_VALUE
180#define TARGET_FUNCTION_VALUE cr16_function_value
181#undef TARGET_LIBCALL_VALUE
182#define TARGET_LIBCALL_VALUE cr16_libcall_value
183#undef TARGET_FUNCTION_VALUE_REGNO_P
184#define TARGET_FUNCTION_VALUE_REGNO_P cr16_function_value_regno_p
185
186/* printing the values. */
187#undef TARGET_PRINT_OPERAND
188#define TARGET_PRINT_OPERAND cr16_print_operand
189#undef TARGET_PRINT_OPERAND_ADDRESS
190#define TARGET_PRINT_OPERAND_ADDRESS cr16_print_operand_address
191
192/* Relative costs of operations. */
193#undef TARGET_ADDRESS_COST
194#define TARGET_ADDRESS_COST cr16_address_cost
195#undef TARGET_REGISTER_MOVE_COST
196#define TARGET_REGISTER_MOVE_COST cr16_register_move_cost
197#undef TARGET_MEMORY_MOVE_COST
198#define TARGET_MEMORY_MOVE_COST cr16_memory_move_cost
199
200/* Table of machine attributes. */
201static const struct attribute_spec cr16_attribute_table[] = {
202 /* ISRs have special prologue and epilogue requirements. */
203 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
204 affects_type_identity }. */
205 {"interrupt", 0, 0, false, true, true, NULL, false},
206 {NULL, 0, 0, false, false, false, NULL, false}
207};
208
209/* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive
210 .?byte directive along with @c is not understood by assembler.
211 Therefore, make all TARGET_ASM_UNALIGNED_xx_OP same
212 as TARGET_ASM_ALIGNED_xx_OP. */
213#undef TARGET_ASM_UNALIGNED_HI_OP
214#define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
215#undef TARGET_ASM_UNALIGNED_SI_OP
216#define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
217#undef TARGET_ASM_UNALIGNED_DI_OP
218#define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
219
220/* Target hook implementations. */
221
222/* Implements hook TARGET_RETURN_IN_MEMORY. */
223static bool
224cr16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
225{
226 const HOST_WIDE_INT size = int_size_in_bytes (type);
227 return ((size == -1) || (size > 8));
228}
229
230/* Implement TARGET_CLASS_LIKELY_SPILLED_P. */
231static bool
232cr16_class_likely_spilled_p (reg_class_t rclass)
233{
234 if ((rclass) == SHORT_REGS || (rclass) == DOUBLE_BASE_REGS
235 || (rclass) == LONG_REGS || (rclass) == GENERAL_REGS)
236 return true;
237
238 return false;
239}
240
241static int
242cr16_return_pops_args (tree fundecl ATTRIBUTE_UNUSED,
243 tree funtype ATTRIBUTE_UNUSED,
244 int size ATTRIBUTE_UNUSED)
245{
246 return 0;
247}
248
249/* Returns true if data model selected via command line option
250 is same as function argument. */
251bool
252cr16_is_data_model (enum data_model_type model)
253{
254 return (model == data_model);
255}
256
257/* Parse relevant options and override. */
258static void
259cr16_override_options (void)
260{
261 /* Disable -fdelete-null-pointer-checks option for CR16 target.
262 Programs which rely on NULL pointer dereferences _not_ halting the
263 program may not work properly with this option. So disable this
264 option. */
265 flag_delete_null_pointer_checks = 0;
266
267 /* FIXME: To avoid spill_failure ICE during exception handling,
268 * disable cse_fllow_jumps. The spill error occurs when compiler
269 * can't find a suitable candidate in GENERAL_REGS class to reload
270 * a 32bit register.
271 * Need to find a better way of avoiding this situation. */
272 if (flag_exceptions)
273 flag_cse_follow_jumps = 0;
274
275 /* If -fpic option, data_model == DM_FAR. */
276 if (flag_pic == NEAR_PIC)
277 {
278 data_model = DM_FAR;
279 }
280
281 /* The only option we want to examine is data model option. */
282 if (cr16_data_model)
283 {
284 if (strcmp (cr16_data_model, "medium") == 0)
285 data_model = DM_DEFAULT;
286 else if (strcmp (cr16_data_model, "near") == 0)
287 data_model = DM_NEAR;
288 else if (strcmp (cr16_data_model, "far") == 0)
289 {
290 if (TARGET_CR16CP)
291 data_model = DM_FAR;
292 else
293 error ("data-model=far not valid for cr16c architecture");
294 }
295 else
296 error ("invalid data model option -mdata-model=%s", cr16_data_model);
297 }
298 else
299 data_model = DM_DEFAULT;
300}
301
302/* Implements the macro TARGET_CONDITIONAL_REGISTER_USAGE. */
303static void
304cr16_conditional_register_usage (void)
305{
306 if (flag_pic)
307 {
308 fixed_regs[12] = call_used_regs[12] = 1;
309 }
310}
311
312/* Stack layout and calling conventions routines. */
313
314/* Return nonzero if the current function being compiled is an interrupt
315 function as specified by the "interrupt" attribute. */
316int
317cr16_interrupt_function_p (void)
318{
319 tree attributes;
320
321 attributes = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
322 return (lookup_attribute ("interrupt", attributes) != NULL_TREE);
323}
324
325/* Compute values for the array current_frame_info.save_regs and the variable
326 current_frame_info.reg_size. The index of current_frame_info.save_regs
327 is numbers of register, each will get 1 if we need to save it in the
328 current function, 0 if not. current_frame_info.reg_size is the total sum
329 of the registers being saved. */
330static void
331cr16_compute_save_regs (void)
332{
333 unsigned int regno;
334
335 /* Initialize here so in case the function is no-return it will be -1. */
336 current_frame_info.last_reg_to_save = -1;
337
338 /* Initialize the number of bytes to be saved. */
339 current_frame_info.reg_size = 0;
340
341 /* No need to save any registers if the function never returns. */
342 if (FUNC_IS_NORETURN_P (current_function_decl) && !MUST_SAVE_REGS_P ())
343 return;
344
345 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
346 {
347 if (fixed_regs[regno])
348 {
349 current_frame_info.save_regs[regno] = 0;
350 continue;
351 }
352
353 /* If this reg is used and not call-used (except RA), save it. */
354 if (cr16_interrupt_function_p ())
355 {
416ff32e 356 if (!crtl->is_leaf && call_used_regs[regno])
b25364a0
S
357 /* This is a volatile reg in a non-leaf interrupt routine - save
358 it for the sake of its sons. */
359 current_frame_info.save_regs[regno] = 1;
360 else if (df_regs_ever_live_p (regno))
361 /* This reg is used - save it. */
362 current_frame_info.save_regs[regno] = 1;
363 else
364 /* This reg is not used, and is not a volatile - don't save. */
365 current_frame_info.save_regs[regno] = 0;
366 }
367 else
368 {
369 /* If this reg is used and not call-used (except RA), save it. */
370 if (df_regs_ever_live_p (regno)
371 && (!call_used_regs[regno] || regno == RETURN_ADDRESS_REGNUM))
372 current_frame_info.save_regs[regno] = 1;
373 else
374 current_frame_info.save_regs[regno] = 0;
375 }
376 }
377
378 /* Save registers so the exception handler can modify them. */
379 if (crtl->calls_eh_return)
380 {
381 unsigned int i;
382
383 for (i = 0;; ++i)
384 {
385 regno = EH_RETURN_DATA_REGNO (i);
386 if (INVALID_REGNUM == regno)
387 break;
388 current_frame_info.save_regs[regno] = 1;
389 }
390 }
391
392 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
393 if (current_frame_info.save_regs[regno] == 1)
394 {
395 current_frame_info.last_reg_to_save = regno;
396 if (regno >= CR16_FIRST_DWORD_REGISTER)
397 current_frame_info.reg_size += CR16_UNITS_PER_DWORD;
398 else
399 current_frame_info.reg_size += UNITS_PER_WORD;
400 }
401}
402
403/* Compute the size of the local area and the size to be adjusted by the
404 prologue and epilogue. */
405static void
406cr16_compute_frame (void)
407{
408 /* For aligning the local variables. */
409 int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
410 int padding_locals;
411
412 /* Padding needed for each element of the frame. */
413 current_frame_info.var_size = get_frame_size ();
414
415 /* Align to the stack alignment. */
416 padding_locals = current_frame_info.var_size % stack_alignment;
417 if (padding_locals)
418 padding_locals = stack_alignment - padding_locals;
419
420 current_frame_info.var_size += padding_locals;
421 current_frame_info.total_size = current_frame_info.var_size
422 + (ACCUMULATE_OUTGOING_ARGS
423 ? crtl->outgoing_args_size : 0);
424}
425
426/* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */
427int
428cr16_initial_elimination_offset (int from, int to)
429{
430 /* Compute this since we need to use current_frame_info.reg_size. */
431 cr16_compute_save_regs ();
432
433 /* Compute this since we need to use current_frame_info.var_size. */
434 cr16_compute_frame ();
435
436 if (((from) == FRAME_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
437 return (ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0);
438 else if (((from) == ARG_POINTER_REGNUM) && ((to) == FRAME_POINTER_REGNUM))
439 return (current_frame_info.reg_size + current_frame_info.var_size);
440 else if (((from) == ARG_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
441 return (current_frame_info.reg_size + current_frame_info.var_size
442 + (ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0));
443 else
444 gcc_unreachable ();
445}
446
447/* Register Usage. */
448
449/* Return the class number of the smallest class containing reg number REGNO.
450 This could be a conditional expression or could index an array. */
451enum reg_class
452cr16_regno_reg_class (int regno)
453{
454 if ((regno >= 0) && (regno < CR16_FIRST_DWORD_REGISTER))
455 return SHORT_REGS;
456
457 if ((regno >= CR16_FIRST_DWORD_REGISTER) && (regno < FIRST_PSEUDO_REGISTER))
458 return LONG_REGS;
459
460 return NO_REGS;
461}
462
463/* Return 1 if hard register REGNO can hold a value of machine-mode MODE. */
464int
ef4bddc2 465cr16_hard_regno_mode_ok (int regno, machine_mode mode)
b25364a0
S
466{
467 if ((GET_MODE_SIZE (mode) >= 4) && (regno == 11))
468 return 0;
469
470 if (mode == DImode || mode == DFmode)
471 {
472 if ((regno > 8) || (regno & 1))
473 return 0;
474 return 1;
475 }
476
477 if ((TARGET_INT32)
478 && ((regno >= 12) && (GET_MODE_SIZE (mode) < 4 )))
479 return 0;
480
481 /* CC can only hold CCmode values. */
482 if (GET_MODE_CLASS (mode) == MODE_CC)
483 return 0;
484 return 1;
485}
486
487/* Returns register number for function return value.*/
488static inline unsigned int
489cr16_ret_register (void)
490{
491 return 0;
492}
493
494/* Implements hook TARGET_STRUCT_VALUE_RTX. */
495static rtx
496cr16_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
497 int incoming ATTRIBUTE_UNUSED)
498{
499 return gen_rtx_REG (Pmode, cr16_ret_register ());
500}
501
502/* Returning function value. */
503
504/* Worker function for TARGET_FUNCTION_VALUE_REGNO_P. */
505static bool
506cr16_function_value_regno_p (const unsigned int regno)
507{
508 return (regno == cr16_ret_register ());
509}
510
511/* Create an RTX representing the place where a
512 library function returns a value of mode MODE. */
513static rtx
ef4bddc2 514cr16_libcall_value (machine_mode mode,
b25364a0
S
515 const_rtx func ATTRIBUTE_UNUSED)
516{
517 return gen_rtx_REG (mode, cr16_ret_register ());
518}
519
520/* Create an RTX representing the place where a
521 function returns a value of data type VALTYPE. */
522static rtx
523cr16_function_value (const_tree type,
524 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
525 bool outgoing ATTRIBUTE_UNUSED)
526{
527 return gen_rtx_REG (TYPE_MODE (type), cr16_ret_register ());
528}
529
530/* Passing function arguments. */
531
532/* If enough param regs are available for passing the param of type TYPE return
533 the number of registers needed else 0. */
534static int
535enough_regs_for_param (CUMULATIVE_ARGS * cum, const_tree type,
ef4bddc2 536 machine_mode mode)
b25364a0
S
537{
538 int type_size;
539 int remaining_size;
540
541 if (mode != BLKmode)
542 type_size = GET_MODE_BITSIZE (mode);
543 else
544 type_size = int_size_in_bytes (type) * BITS_PER_UNIT;
545
546 remaining_size = BITS_PER_WORD * (MAX_REG_FOR_PASSING_ARGS
547 - (MIN_REG_FOR_PASSING_ARGS + cum->ints) +
548 1);
549
550 /* Any variable which is too big to pass in two registers, will pass on
551 stack. */
552 if ((remaining_size >= type_size) && (type_size <= 2 * BITS_PER_WORD))
553 return (type_size + BITS_PER_WORD - 1) / BITS_PER_WORD;
554
555 return 0;
556}
557
558/* Implements the macro FUNCTION_ARG defined in cr16.h. */
559static rtx
ef4bddc2 560cr16_function_arg (cumulative_args_t cum_v, machine_mode mode,
b25364a0
S
561 const_tree type, bool named ATTRIBUTE_UNUSED)
562{
563 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
564 cum->last_parm_in_reg = 0;
565
566 /* function_arg () is called with this type just after all the args have
567 had their registers assigned. The rtx that function_arg returns from
568 this type is supposed to pass to 'gen_call' but currently it is not
58d745ec 569 implemented. */
b25364a0
S
570 if (type == void_type_node)
571 return NULL_RTX;
572
573 if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
574 return NULL_RTX;
575
576 if (mode == BLKmode)
577 {
578 /* Enable structures that need padding bytes at the end to pass to a
579 function in registers. */
580 if (enough_regs_for_param (cum, type, mode) != 0)
581 {
582 cum->last_parm_in_reg = 1;
583 return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
584 }
585 }
586
587 if ((MIN_REG_FOR_PASSING_ARGS + cum->ints) > MAX_REG_FOR_PASSING_ARGS)
588 return NULL_RTX;
589 else
590 {
591 if (enough_regs_for_param (cum, type, mode) != 0)
592 {
593 cum->last_parm_in_reg = 1;
594 return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
595 }
596 }
597
598 return NULL_RTX;
599}
600
601/* Implements the macro INIT_CUMULATIVE_ARGS defined in cr16.h. */
602void
603cr16_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype,
604 rtx libfunc ATTRIBUTE_UNUSED)
605{
606 tree param, next_param;
607
608 cum->ints = 0;
609
610 /* Determine if this function has variable arguments. This is indicated by
611 the last argument being 'void_type_mode' if there are no variable
612 arguments. Change here for a different vararg. */
613 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
614 param != NULL_TREE; param = next_param)
615 {
616 next_param = TREE_CHAIN (param);
617 if ((next_param == NULL_TREE) && (TREE_VALUE (param) != void_type_node))
618 {
619 cum->ints = -1;
620 return;
621 }
622 }
623}
624
625/* Implements the macro FUNCTION_ARG_ADVANCE defined in cr16.h. */
626static void
ef4bddc2 627cr16_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
b25364a0
S
628 const_tree type, bool named ATTRIBUTE_UNUSED)
629{
630 CUMULATIVE_ARGS * cum = get_cumulative_args (cum_v);
631
632 /* l holds the number of registers required. */
633 int l = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
634
635 /* If the parameter isn't passed on a register don't advance cum. */
636 if (!cum->last_parm_in_reg)
637 return;
638
639 if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
640 return;
641
642 if ((mode == SImode) || (mode == HImode)
643 || (mode == QImode) || (mode == DImode))
644 {
645 if (l <= 1)
646 cum->ints += 1;
647 else
648 cum->ints += l;
649 }
650 else if ((mode == SFmode) || (mode == DFmode))
651 cum->ints += l;
652 else if ((mode) == BLKmode)
653 {
654 if ((l = enough_regs_for_param (cum, type, mode)) != 0)
655 cum->ints += l;
656 }
657 return;
658}
659
660/* Implements the macro FUNCTION_ARG_REGNO_P defined in cr16.h.
661 Return nonzero if N is a register used for passing parameters. */
662int
663cr16_function_arg_regno_p (int n)
664{
665 return ((n <= MAX_REG_FOR_PASSING_ARGS) && (n >= MIN_REG_FOR_PASSING_ARGS));
666}
667
668/* Addressing modes.
669 Following set of function implement the macro GO_IF_LEGITIMATE_ADDRESS
670 defined in cr16.h. */
671
672/* Helper function to check if is a valid base register that can
673 hold address. */
674static int
675cr16_addr_reg_p (rtx addr_reg)
676{
677 rtx reg;
678
679 if (REG_P (addr_reg))
680 reg = addr_reg;
681 else if ((GET_CODE (addr_reg) == SUBREG)
682 && REG_P (SUBREG_REG (addr_reg))
683 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg)))
684 <= UNITS_PER_WORD))
685 reg = SUBREG_REG (addr_reg);
686 else
687 return FALSE;
688
689 if (GET_MODE (reg) != Pmode)
690 return FALSE;
691
692 return TRUE;
693}
694
695/* Helper functions: Created specifically for decomposing operand of CONST
696 Recursively look into expression x for code or data symbol.
697 The function expects the expression to contain combination of
698 SYMBOL_REF, CONST_INT, (PLUS or MINUS)
699 LABEL_REF, CONST_INT, (PLUS or MINUS)
700 SYMBOL_REF
701 LABEL_REF
702 All other combinations will result in code = -1 and data = ILLEGAL_DM
703 code data
704 -1 ILLEGAL_DM The expression did not contain SYMBOL_REF or LABEL_REF
705 0 DM_FAR SYMBOL_REF was found and it was far data reference.
706 0 DM_DEFAULT SYMBOL_REF was found and it was medium data reference.
707 1 ILLEGAL_DM LABEL_REF was found.
708 2 ILLEGAL_DM SYMBOL_REF was found and it was function reference. */
709void
710cr16_decompose_const (rtx x, int *code, enum data_model_type *data,
711 bool treat_as_const)
712{
713 *code = -1;
714 *data = ILLEGAL_DM;
715 switch (GET_CODE (x))
716 {
717 case SYMBOL_REF:
718 *code = SYMBOL_REF_FUNCTION_P (x) ? 2 : 0;
719 /* 2 indicates func sym. */
720 if (*code == 0)
721 {
722 if (CR16_TARGET_DATA_NEAR)
723 *data = DM_DEFAULT;
724 else if (CR16_TARGET_DATA_MEDIUM)
725 *data = DM_FAR;
726 else if (CR16_TARGET_DATA_FAR)
727 {
728 if (treat_as_const)
729 /* This will be used only for printing
730 the qualifier. This call is (may be)
731 made by cr16_print_operand_address. */
732 *data = DM_FAR;
733 else
734 /* This call is (may be) made by
735 cr16_legitimate_address_p. */
736 *data = ILLEGAL_DM;
737 }
738 }
739 return;
740
741 case LABEL_REF:
742 /* 1 - indicates non-function symbol. */
743 *code = 1;
744 return;
745
746 case PLUS:
747 case MINUS:
748 /* Look into the tree nodes. */
749 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
750 cr16_decompose_const (XEXP (x, 1), code, data, treat_as_const);
751 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
752 cr16_decompose_const (XEXP (x, 0), code, data, treat_as_const);
753 return;
754 default:
755 return;
756 }
757}
758
759/* Decompose Address
760 This function decomposes the address returns the type of address
761 as defined in enum cr16_addrtype. It also fills the parameter *out.
762 The decomposed address can be used for two purposes. One to
763 check if the address is valid and second to print the address
764 operand.
765
766 Following tables list valid address supported in CR16C/C+ architectures.
767 Legend:
768 aN : Absoulte address N-bit address
769 R : One 16-bit register
770 RP : Consecutive two 16-bit registers or one 32-bit register
771 I : One 32-bit register
772 dispN : Signed displacement of N-bits
773
774 ----Code addresses----
775 Branch operands:
776 disp9 : CR16_ABSOLUTE (disp)
777 disp17 : CR16_ABSOLUTE (disp)
778 disp25 : CR16_ABSOLUTE (disp)
779 RP + disp25 : CR16_REGP_REL (base, disp)
780
781 Jump operands:
782 RP : CR16_REGP_REL (base, disp=0)
783 a24 : CR16_ABSOLUTE (disp)
784
785 ----Data addresses----
786 a20 : CR16_ABSOLUTE (disp) near (1M)
787 a24 : CR16_ABSOLUTE (disp) medium (16M)
788 R + d20 : CR16_REG_REL (base, disp) near (1M+64K)
789 RP + d4 : CR16_REGP_REL (base, disp) far (4G)
790 RP + d16 : CR16_REGP_REL (base, disp) far (4G)
791 RP + d20 : CR16_REGP_REL (base, disp) far (4G)
792 I : *** Valid but port does not support this
793 I + a20 : *** Valid but port does not support this
794 I + RP + d14: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
795 I + RP + d20: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
796
797 Decomposing Data model in case of absolute address.
798
799 Target Option Address type Resultant Data ref type
800 ---------------------- ------------ -----------------------
801 CR16_TARGET_MODEL_NEAR ABS20 DM_DEFAULT
802 CR16_TARGET_MODEL_NEAR IMM20 DM_DEFAULT
803 CR16_TARGET_MODEL_NEAR ABS24 Invalid
804 CR16_TARGET_MODEL_NEAR IMM32 Invalid
805
806 CR16_TARGET_MODEL_MEDIUM ABS20 DM_DEFAULT
807 CR16_TARGET_MODEL_MEDIUM IMM20 DM_DEFAULT
808 CR16_TARGET_MODEL_MEDIUM ABS24 DM_FAR
809 CR16_TARGET_MODEL_MEDIUM IMM32 Invalid
810
811 CR16_TARGET_MODEL_FAR ABS20 DM_DEFAULT
812 CR16_TARGET_MODEL_FAR IMM20 DM_DEFAULT
813 CR16_TARGET_MODEL_FAR ABS24 DM_FAR
814 CR16_TARGET_MODEL_FAR IMM32 DM_FAR. */
815enum cr16_addrtype
816cr16_decompose_address (rtx addr, struct cr16_address *out,
817 bool debug_print, bool treat_as_const)
818{
819 rtx base = NULL_RTX, disp = NULL_RTX, index = NULL_RTX;
820 enum data_model_type data = ILLEGAL_DM;
821 int code = -1;
822 enum cr16_addrtype retval = CR16_INVALID;
823
824 switch (GET_CODE (addr))
825 {
826 case CONST_INT:
827 /* Absolute address (known at compile time). */
828 code = 0;
829 if (debug_print)
830 fprintf (stderr, "\ncode:%d", code);
831 disp = addr;
832
833 if (debug_print)
834 {
835 fprintf (stderr, "\ndisp:");
836 debug_rtx (disp);
837 }
838
839 if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
840 {
841 data = DM_DEFAULT;
842 if (debug_print)
843 fprintf (stderr, "\ndata:%d", data);
844 retval = CR16_ABSOLUTE;
845 }
846 else if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 24))
847 {
848 if (!CR16_TARGET_DATA_NEAR)
849 {
850 data = DM_FAR;
851 if (debug_print)
852 fprintf (stderr, "\ndata:%d", data);
853 retval = CR16_ABSOLUTE;
854 }
855 else
856 return CR16_INVALID; /* ABS24 is not support in NEAR model. */
857 }
858 else
859 return CR16_INVALID;
860 break;
861
862 case CONST:
863 /* A CONST is an expression of PLUS or MINUS with
864 CONST_INT, SYMBOL_REF or LABEL_REF. This is the
865 result of assembly-time arithmetic computation. */
866 retval = CR16_ABSOLUTE;
867 disp = addr;
868 /* Call the helper function to check the validity. */
869 cr16_decompose_const (XEXP (addr, 0), &code, &data, treat_as_const);
870 if ((code == 0) && (data == ILLEGAL_DM))
871 /* CONST is not valid code or data address. */
872 return CR16_INVALID;
873 if (debug_print)
874 {
875 fprintf (stderr, "\ndisp:");
876 debug_rtx (disp);
877 fprintf (stderr, "\ncode:%d", code);
878 fprintf (stderr, "\ndata:%d", data);
879 }
880 break;
881
882 case LABEL_REF:
883 retval = CR16_ABSOLUTE;
884 disp = addr;
885 /* 1 - indicates non-function symbol. */
886 code = 1;
887 if (debug_print)
888 {
889 fprintf (stderr, "\ndisp:");
890 debug_rtx (disp);
891 fprintf (stderr, "\ncode:%d", code);
892 }
893 break;
894
895 case SYMBOL_REF:
896 /* Absolute address (known at link time). */
897 retval = CR16_ABSOLUTE;
898 disp = addr;
899 /* This is a code address if symbol_ref is a function. */
900 /* 2 indicates func sym. */
901 code = SYMBOL_REF_FUNCTION_P (addr) ? 2 : 0;
902 if (debug_print)
903 {
904 fprintf (stderr, "\ndisp:");
905 debug_rtx (disp);
906 fprintf (stderr, "\ncode:%d", code);
907 }
908 /* If not function ref then check if valid data ref. */
909 if (code == 0)
910 {
911 if (CR16_TARGET_DATA_NEAR)
912 data = DM_DEFAULT;
913 else if (CR16_TARGET_DATA_MEDIUM)
914 data = DM_FAR;
915 else if (CR16_TARGET_DATA_FAR)
916 {
917 if (treat_as_const)
918 /* This will be used only for printing the
919 qualifier. This call is (may be) made
920 by cr16_print_operand_address. */
921 data = DM_FAR;
922 else
923 /* This call is (may be) made by
924 cr16_legitimate_address_p. */
925 return CR16_INVALID;
926 }
927 else
928 data = DM_DEFAULT;
929 }
930 if (debug_print)
931 fprintf (stderr, "\ndata:%d", data);
932 break;
933
934 case REG:
935 case SUBREG:
936 /* Register relative address. */
937 /* Assume REG fits in a single register. */
938 retval = CR16_REG_REL;
939 if (GET_MODE_BITSIZE (GET_MODE (addr)) > BITS_PER_WORD)
940 if (!LONG_REG_P (REGNO (addr)))
941 /* REG will result in reg pair. */
942 retval = CR16_REGP_REL;
943 base = addr;
944 if (debug_print)
945 {
946 fprintf (stderr, "\nbase:");
947 debug_rtx (base);
948 }
949 break;
950
951 case PLUS:
952 switch (GET_CODE (XEXP (addr, 0)))
953 {
954 case REG:
955 case SUBREG:
956 /* REG + DISP20. */
957 /* All Reg relative addresses having a displacement needs
958 to fit in 20-bits. */
959 disp = XEXP (addr, 1);
960 if (debug_print)
961 {
962 fprintf (stderr, "\ndisp:");
963 debug_rtx (disp);
964 }
965 switch (GET_CODE (XEXP (addr, 1)))
966 {
967 case CONST_INT:
968 /* Shall fit in 20-bits. */
969 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
970 return CR16_INVALID;
971 code = 0;
972 if (debug_print)
973 fprintf (stderr, "\ncode:%d", code);
974 break;
975
976 case UNSPEC:
977 switch (XINT (XEXP (addr, 1), 1))
978 {
979 case UNSPEC_LIBRARY_OFFSET:
980 default:
981 gcc_unreachable ();
982 }
983 break;
984
985 case LABEL_REF:
986 case SYMBOL_REF:
987 case CONST:
988 /* This is also a valid expression for address.
989 However, we cannot ascertain if the resultant
990 displacement will be valid 20-bit value. Therefore,
991 lets not allow such an expression for now. This will
992 be updated when we find a way to validate this
993 expression as legitimate address.
994 Till then fall through CR16_INVALID. */
995 default:
996 return CR16_INVALID;
997 }
998
999 /* Now check if REG can fit into single or pair regs. */
1000 retval = CR16_REG_REL;
1001 base = XEXP (addr, 0);
1002 if (debug_print)
1003 {
1004 fprintf (stderr, "\nbase:");
1005 debug_rtx (base);
1006 }
1007 if (GET_MODE_BITSIZE (GET_MODE ((XEXP (addr, 0)))) > BITS_PER_WORD)
1008 {
1009 if (!LONG_REG_P (REGNO ((XEXP (addr, 0)))))
1010 /* REG will result in reg pair. */
1011 retval = CR16_REGP_REL;
1012 }
1013 break;
1014
1015 case PLUS:
1016 /* Valid expr:
1017 plus
1018 /\
1019 / \
1020 plus idx
1021 /\
1022 / \
1023 reg const_int
1024
1025 Check if the operand 1 is valid index register. */
1026 data = ILLEGAL_DM;
1027 if (debug_print)
1028 fprintf (stderr, "\ndata:%d", data);
1029 switch (GET_CODE (XEXP (addr, 1)))
1030 {
1031 case REG:
1032 case SUBREG:
1033 if (!REG_OK_FOR_INDEX_P (XEXP (addr, 1)))
1034 return CR16_INVALID;
1035 /* OK. REG is a valid index register. */
1036 index = XEXP (addr, 1);
1037 if (debug_print)
1038 {
1039 fprintf (stderr, "\nindex:");
1040 debug_rtx (index);
1041 }
1042 break;
1043 default:
1044 return CR16_INVALID;
1045 }
1046 /* Check if operand 0 of operand 0 is REGP. */
1047 switch (GET_CODE (XEXP (XEXP (addr, 0), 0)))
1048 {
1049 case REG:
1050 case SUBREG:
1051 /* Now check if REG is a REGP and not in LONG regs. */
1052 if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (addr, 0), 0)))
1053 > BITS_PER_WORD)
1054 {
1055 if (REGNO (XEXP (XEXP (addr, 0), 0))
1056 >= CR16_FIRST_DWORD_REGISTER)
1057 return CR16_INVALID;
1058 base = XEXP (XEXP (addr, 0), 0);
1059 if (debug_print)
1060 {
1061 fprintf (stderr, "\nbase:");
1062 debug_rtx (base);
1063 }
1064 }
1065 else
1066 return CR16_INVALID;
1067 break;
1068 default:
1069 return CR16_INVALID;
1070 }
1071 /* Now check if the operand 1 of operand 0 is const_int. */
1072 if (GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
1073 {
1074 disp = XEXP (XEXP (addr, 0), 1);
1075 if (debug_print)
1076 {
1077 fprintf (stderr, "\ndisp:");
1078 debug_rtx (disp);
1079 }
1080 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
1081 return CR16_INVALID;
1082 }
1083 else
1084 return CR16_INVALID;
1085 retval = CR16_INDEX_REGP_REL;
1086 break;
1087 default:
1088 return CR16_INVALID;
1089 }
1090 break;
1091
1092 default:
1093 return CR16_INVALID;
1094 }
1095
1096 /* Check if the base and index registers are valid. */
1097 if (base && !(cr16_addr_reg_p (base)))
1098 return CR16_INVALID;
1099 if (base && !(CR16_REG_OK_FOR_BASE_P (base)))
1100 return CR16_INVALID;
1101 if (index && !(REG_OK_FOR_INDEX_P (index)))
1102 return CR16_INVALID;
1103
1104 /* Write the decomposition to out parameter. */
1105 out->base = base;
1106 out->disp = disp;
1107 out->index = index;
1108 out->data = data;
1109 out->code = code;
1110
1111 return retval;
1112}
1113
1114/* Return non-zero value if 'x' is legitimate PIC operand
1115 when generating PIC code. */
1116int
1117legitimate_pic_operand_p (rtx x)
1118{
1119 switch (GET_CODE (x))
1120 {
1121 case SYMBOL_REF:
1122 return 0;
b25364a0
S
1123 case LABEL_REF:
1124 return 0;
b25364a0
S
1125 case CONST:
1126 /* REVISIT: Use something like symbol_referenced_p. */
1127 if (GET_CODE (XEXP (x, 0)) == PLUS
1128 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
1129 || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
1130 && (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
1131 return 0;
1132 break;
1133 case MEM:
1134 return legitimate_pic_operand_p (XEXP (x, 0));
b25364a0
S
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. */
1152rtx
ef4bddc2 1153legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
b25364a0
S
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. */
1205static bool
ef4bddc2 1206cr16_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
b25364a0
S
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. */
1284static int
ef4bddc2 1285cr16_address_cost (rtx addr, machine_mode mode ATTRIBUTE_UNUSED,
b413068c
OE
1286 addr_space_t as ATTRIBUTE_UNUSED,
1287 bool speed ATTRIBUTE_UNUSED)
b25364a0
S
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'. */
1336static int
ef4bddc2 1337cr16_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
b25364a0
S
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. */
1349static int
ef4bddc2 1350cr16_memory_move_cost (machine_mode mode,
b25364a0
S
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. */
1364int
1365cr16_const_double_ok (rtx op)
1366{
1367 if (GET_MODE (op) == SFmode)
1368 {
b25364a0 1369 long l;
34a72c33 1370 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op), l);
b25364a0
S
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. */
1380int
1381cr16_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. */
1394static void
1395cr16_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:
cc8ca59e 1497 output_address (GET_MODE (x), XEXP (x, 0));
b25364a0
S
1498 return;
1499
1500 case CONST_DOUBLE:
1501 {
b25364a0
S
1502 long l;
1503
34a72c33 1504 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
b25364a0
S
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 }
cc8ca59e 1527 cr16_print_operand_address (file, VOIDmode, x);
b25364a0
S
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
1539static void
cc8ca59e 1540cr16_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr)
b25364a0
S
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. */
1657char *
1658cr16_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. */
1793static void
1794cr16_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;
ef4bddc2 1798 machine_mode mode;
b25364a0
S
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;
f7df4a84 1845 tmp = gen_rtx_SET (gen_frame_mem (mode,
b25364a0 1846 plus_constant
0a81f074 1847 (Pmode, stack_pointer_rtx,
b25364a0
S
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
f7df4a84 1875 tmp = gen_rtx_SET (stack_pointer_rtx,
b25364a0
S
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/*
1885CompactRISC 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*/
1910void
1911cr16_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. */
1949void
1950cr16_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. */
2014static bool
2015cr16_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
2021static bool
2022cr16_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. */
2037static rtx
2038cr16_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED,
ef4bddc2 2039 machine_mode mode ATTRIBUTE_UNUSED)
b25364a0
S
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. */
2052static bool
ef4bddc2 2053cr16_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED,
b25364a0
S
2054 rtx x ATTRIBUTE_UNUSED)
2055{
2056 return 1;
2057}
2058
2059void
2060notice_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
ef4bddc2 2090static machine_mode
b25364a0
S
2091cr16_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. */
2099const char *
2100cr16_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. */
2141const char *
2142cr16_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
2183struct gcc_target targetm = TARGET_INITIALIZER;