1 /* Output routines for CR16 processor.
2 Copyright (C) 2012-2017 Free Software Foundation, Inc.
3 Contributed by KPIT Cummins Infosystems Limited.
5 This file is part of GCC.
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.
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.
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/>. */
23 #include "coretypes.h"
28 #include "stringpool.h"
35 #include "diagnostic-core.h"
36 #include "stor-layout.h"
38 #include "conditions.h"
43 /* This file should be included last. */
44 #include "target-def.h"
48 /* Maximum number of register used for passing parameters. */
49 #define MAX_REG_FOR_PASSING_ARGS 6
51 /* Minimum number register used for passing parameters. */
52 #define MIN_REG_FOR_PASSING_ARGS 2
54 /* The maximum count of words supported in the assembly of the architecture in
55 a push/pop instruction. */
58 /* Predicate is true if the current function is a 'noreturn' function,
59 i.e. it is qualified as volatile. */
60 #define FUNC_IS_NORETURN_P(decl) (TREE_THIS_VOLATILE (decl))
62 /* Predicate that holds when we need to save registers even for 'noreturn'
63 functions, to accommodate for unwinding. */
64 #define MUST_SAVE_REGS_P() \
65 (flag_unwind_tables || (flag_exceptions && !UI_SJLJ))
67 /* Nonzero if the rtx X is a signed const int of n bits. */
68 #define RTX_SIGNED_INT_FITS_N_BITS(X, n) \
69 ((GET_CODE (X) == CONST_INT \
70 && SIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
72 /* Nonzero if the rtx X is an unsigned const int of n bits. */
73 #define RTX_UNSIGNED_INT_FITS_N_BITS(X, n) \
74 ((GET_CODE (X) == CONST_INT \
75 && UNSIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
77 /* Structure for stack computations. */
79 /* variable definitions in the struture
80 args_size Number of bytes saved on the stack for local
83 reg_size Number of bytes saved on the stack for
86 total_size The sum of 2 sizes: locals vars and padding byte
87 for saving the registers. Used in expand_prologue()
90 last_reg_to_save Will hold the number of the last register the
91 prologue saves, -1 if no register is saved
93 save_regs[16] Each object in the array is a register number.
94 Mark 1 for registers that need to be saved
96 num_regs Number of registers saved
98 initialized Non-zero if frame size already calculated, not
101 function_makes_calls Does the function make calls ? not used yet. */
103 struct cr16_frame_info
105 unsigned long var_size
;
106 unsigned long args_size
;
107 unsigned int reg_size
;
108 unsigned long total_size
;
109 long last_reg_to_save
;
110 long save_regs
[FIRST_PSEUDO_REGISTER
];
113 int function_makes_calls
;
116 /* Current frame information calculated by cr16_compute_frame_size. */
117 static struct cr16_frame_info current_frame_info
;
119 /* Static Variables. */
121 /* Data model that was supplied by user via command line option
122 This will be overridden in case of invalid combination
123 of core and data model options are supplied. */
124 static enum data_model_type data_model
= DM_DEFAULT
;
126 /* TARGETM Function Prototypes and forward declarations */
127 static void cr16_print_operand (FILE *, rtx
, int);
128 static void cr16_print_operand_address (FILE *, machine_mode
, rtx
);
130 /* Stack layout and calling conventions. */
131 #undef TARGET_STRUCT_VALUE_RTX
132 #define TARGET_STRUCT_VALUE_RTX cr16_struct_value_rtx
133 #undef TARGET_RETURN_IN_MEMORY
134 #define TARGET_RETURN_IN_MEMORY cr16_return_in_memory
136 /* Target-specific uses of '__attribute__'. */
137 #undef TARGET_ATTRIBUTE_TABLE
138 #define TARGET_ATTRIBUTE_TABLE cr16_attribute_table
139 #undef TARGET_NARROW_VOLATILE_BITFIELD
140 #define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false
143 #undef TARGET_UNWIND_WORD_MODE
144 #define TARGET_UNWIND_WORD_MODE cr16_unwind_word_mode
146 /* Override Options. */
147 #undef TARGET_OPTION_OVERRIDE
148 #define TARGET_OPTION_OVERRIDE cr16_override_options
150 /* Conditional register usuage. */
151 #undef TARGET_CONDITIONAL_REGISTER_USAGE
152 #define TARGET_CONDITIONAL_REGISTER_USAGE cr16_conditional_register_usage
154 /* Controlling register spills. */
155 #undef TARGET_CLASS_LIKELY_SPILLED_P
156 #define TARGET_CLASS_LIKELY_SPILLED_P cr16_class_likely_spilled_p
158 /* Passing function arguments. */
159 #undef TARGET_FUNCTION_ARG
160 #define TARGET_FUNCTION_ARG cr16_function_arg
161 #undef TARGET_FUNCTION_ARG_ADVANCE
162 #define TARGET_FUNCTION_ARG_ADVANCE cr16_function_arg_advance
163 #undef TARGET_RETURN_POPS_ARGS
164 #define TARGET_RETURN_POPS_ARGS cr16_return_pops_args
166 /* Initialize the GCC target structure. */
167 #undef TARGET_FRAME_POINTER_REQUIRED
168 #define TARGET_FRAME_POINTER_REQUIRED cr16_frame_pointer_required
169 #undef TARGET_CAN_ELIMINATE
170 #define TARGET_CAN_ELIMINATE cr16_can_eliminate
171 #undef TARGET_LEGITIMIZE_ADDRESS
172 #define TARGET_LEGITIMIZE_ADDRESS cr16_legitimize_address
173 #undef TARGET_LEGITIMATE_CONSTANT_P
174 #define TARGET_LEGITIMATE_CONSTANT_P cr16_legitimate_constant_p
175 #undef TARGET_LEGITIMATE_ADDRESS_P
176 #define TARGET_LEGITIMATE_ADDRESS_P cr16_legitimate_address_p
179 #define TARGET_LRA_P hook_bool_void_false
181 /* Returning function value. */
182 #undef TARGET_FUNCTION_VALUE
183 #define TARGET_FUNCTION_VALUE cr16_function_value
184 #undef TARGET_LIBCALL_VALUE
185 #define TARGET_LIBCALL_VALUE cr16_libcall_value
186 #undef TARGET_FUNCTION_VALUE_REGNO_P
187 #define TARGET_FUNCTION_VALUE_REGNO_P cr16_function_value_regno_p
189 /* printing the values. */
190 #undef TARGET_PRINT_OPERAND
191 #define TARGET_PRINT_OPERAND cr16_print_operand
192 #undef TARGET_PRINT_OPERAND_ADDRESS
193 #define TARGET_PRINT_OPERAND_ADDRESS cr16_print_operand_address
195 /* Relative costs of operations. */
196 #undef TARGET_ADDRESS_COST
197 #define TARGET_ADDRESS_COST cr16_address_cost
198 #undef TARGET_REGISTER_MOVE_COST
199 #define TARGET_REGISTER_MOVE_COST cr16_register_move_cost
200 #undef TARGET_MEMORY_MOVE_COST
201 #define TARGET_MEMORY_MOVE_COST cr16_memory_move_cost
203 /* Table of machine attributes. */
204 static const struct attribute_spec cr16_attribute_table
[] = {
205 /* ISRs have special prologue and epilogue requirements. */
206 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
207 affects_type_identity }. */
208 {"interrupt", 0, 0, false, true, true, NULL
, false},
209 {NULL
, 0, 0, false, false, false, NULL
, false}
212 /* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive
213 .?byte directive along with @c is not understood by assembler.
214 Therefore, make all TARGET_ASM_UNALIGNED_xx_OP same
215 as TARGET_ASM_ALIGNED_xx_OP. */
216 #undef TARGET_ASM_UNALIGNED_HI_OP
217 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
218 #undef TARGET_ASM_UNALIGNED_SI_OP
219 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
220 #undef TARGET_ASM_UNALIGNED_DI_OP
221 #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
223 #undef TARGET_HARD_REGNO_NREGS
224 #define TARGET_HARD_REGNO_NREGS cr16_hard_regno_nregs
225 #undef TARGET_HARD_REGNO_MODE_OK
226 #define TARGET_HARD_REGNO_MODE_OK cr16_hard_regno_mode_ok
227 #undef TARGET_MODES_TIEABLE_P
228 #define TARGET_MODES_TIEABLE_P cr16_modes_tieable_p
230 /* Target hook implementations. */
232 /* Implements hook TARGET_RETURN_IN_MEMORY. */
234 cr16_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
236 const HOST_WIDE_INT size
= int_size_in_bytes (type
);
237 return ((size
== -1) || (size
> 8));
240 /* Implement TARGET_CLASS_LIKELY_SPILLED_P. */
242 cr16_class_likely_spilled_p (reg_class_t rclass
)
244 if ((rclass
) == SHORT_REGS
|| (rclass
) == DOUBLE_BASE_REGS
245 || (rclass
) == LONG_REGS
|| (rclass
) == GENERAL_REGS
)
252 cr16_return_pops_args (tree fundecl ATTRIBUTE_UNUSED
,
253 tree funtype ATTRIBUTE_UNUSED
,
254 int size ATTRIBUTE_UNUSED
)
259 /* Returns true if data model selected via command line option
260 is same as function argument. */
262 cr16_is_data_model (enum data_model_type model
)
264 return (model
== data_model
);
267 /* Parse relevant options and override. */
269 cr16_override_options (void)
271 /* Disable -fdelete-null-pointer-checks option for CR16 target.
272 Programs which rely on NULL pointer dereferences _not_ halting the
273 program may not work properly with this option. So disable this
275 flag_delete_null_pointer_checks
= 0;
277 /* FIXME: To avoid spill_failure ICE during exception handling,
278 * disable cse_fllow_jumps. The spill error occurs when compiler
279 * can't find a suitable candidate in GENERAL_REGS class to reload
281 * Need to find a better way of avoiding this situation. */
283 flag_cse_follow_jumps
= 0;
285 /* If -fpic option, data_model == DM_FAR. */
286 if (flag_pic
== NEAR_PIC
)
291 /* The only option we want to examine is data model option. */
294 if (strcmp (cr16_data_model
, "medium") == 0)
295 data_model
= DM_DEFAULT
;
296 else if (strcmp (cr16_data_model
, "near") == 0)
297 data_model
= DM_NEAR
;
298 else if (strcmp (cr16_data_model
, "far") == 0)
303 error ("data-model=far not valid for cr16c architecture");
306 error ("invalid data model option -mdata-model=%s", cr16_data_model
);
309 data_model
= DM_DEFAULT
;
312 /* Implements the macro TARGET_CONDITIONAL_REGISTER_USAGE. */
314 cr16_conditional_register_usage (void)
318 fixed_regs
[12] = call_used_regs
[12] = 1;
322 /* Stack layout and calling conventions routines. */
324 /* Return nonzero if the current function being compiled is an interrupt
325 function as specified by the "interrupt" attribute. */
327 cr16_interrupt_function_p (void)
331 attributes
= TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl
));
332 return (lookup_attribute ("interrupt", attributes
) != NULL_TREE
);
335 /* Compute values for the array current_frame_info.save_regs and the variable
336 current_frame_info.reg_size. The index of current_frame_info.save_regs
337 is numbers of register, each will get 1 if we need to save it in the
338 current function, 0 if not. current_frame_info.reg_size is the total sum
339 of the registers being saved. */
341 cr16_compute_save_regs (void)
345 /* Initialize here so in case the function is no-return it will be -1. */
346 current_frame_info
.last_reg_to_save
= -1;
348 /* Initialize the number of bytes to be saved. */
349 current_frame_info
.reg_size
= 0;
351 /* No need to save any registers if the function never returns. */
352 if (FUNC_IS_NORETURN_P (current_function_decl
) && !MUST_SAVE_REGS_P ())
355 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
357 if (fixed_regs
[regno
])
359 current_frame_info
.save_regs
[regno
] = 0;
363 /* If this reg is used and not call-used (except RA), save it. */
364 if (cr16_interrupt_function_p ())
366 if (!crtl
->is_leaf
&& call_used_regs
[regno
])
367 /* This is a volatile reg in a non-leaf interrupt routine - save
368 it for the sake of its sons. */
369 current_frame_info
.save_regs
[regno
] = 1;
370 else if (df_regs_ever_live_p (regno
))
371 /* This reg is used - save it. */
372 current_frame_info
.save_regs
[regno
] = 1;
374 /* This reg is not used, and is not a volatile - don't save. */
375 current_frame_info
.save_regs
[regno
] = 0;
379 /* If this reg is used and not call-used (except RA), save it. */
380 if (df_regs_ever_live_p (regno
)
381 && (!call_used_regs
[regno
] || regno
== RETURN_ADDRESS_REGNUM
))
382 current_frame_info
.save_regs
[regno
] = 1;
384 current_frame_info
.save_regs
[regno
] = 0;
388 /* Save registers so the exception handler can modify them. */
389 if (crtl
->calls_eh_return
)
395 regno
= EH_RETURN_DATA_REGNO (i
);
396 if (INVALID_REGNUM
== regno
)
398 current_frame_info
.save_regs
[regno
] = 1;
402 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
403 if (current_frame_info
.save_regs
[regno
] == 1)
405 current_frame_info
.last_reg_to_save
= regno
;
406 if (regno
>= CR16_FIRST_DWORD_REGISTER
)
407 current_frame_info
.reg_size
+= CR16_UNITS_PER_DWORD
;
409 current_frame_info
.reg_size
+= UNITS_PER_WORD
;
413 /* Compute the size of the local area and the size to be adjusted by the
414 prologue and epilogue. */
416 cr16_compute_frame (void)
418 /* For aligning the local variables. */
419 int stack_alignment
= STACK_BOUNDARY
/ BITS_PER_UNIT
;
422 /* Padding needed for each element of the frame. */
423 current_frame_info
.var_size
= get_frame_size ();
425 /* Align to the stack alignment. */
426 padding_locals
= current_frame_info
.var_size
% stack_alignment
;
428 padding_locals
= stack_alignment
- padding_locals
;
430 current_frame_info
.var_size
+= padding_locals
;
431 current_frame_info
.total_size
= current_frame_info
.var_size
432 + (ACCUMULATE_OUTGOING_ARGS
433 ? crtl
->outgoing_args_size
: 0);
436 /* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */
438 cr16_initial_elimination_offset (int from
, int to
)
440 /* Compute this since we need to use current_frame_info.reg_size. */
441 cr16_compute_save_regs ();
443 /* Compute this since we need to use current_frame_info.var_size. */
444 cr16_compute_frame ();
446 if (((from
) == FRAME_POINTER_REGNUM
) && ((to
) == STACK_POINTER_REGNUM
))
447 return (ACCUMULATE_OUTGOING_ARGS
? crtl
->outgoing_args_size
: 0);
448 else if (((from
) == ARG_POINTER_REGNUM
) && ((to
) == FRAME_POINTER_REGNUM
))
449 return (current_frame_info
.reg_size
+ current_frame_info
.var_size
);
450 else if (((from
) == ARG_POINTER_REGNUM
) && ((to
) == STACK_POINTER_REGNUM
))
451 return (current_frame_info
.reg_size
+ current_frame_info
.var_size
452 + (ACCUMULATE_OUTGOING_ARGS
? crtl
->outgoing_args_size
: 0));
457 /* Register Usage. */
459 /* Return the class number of the smallest class containing reg number REGNO.
460 This could be a conditional expression or could index an array. */
462 cr16_regno_reg_class (int regno
)
464 if ((regno
>= 0) && (regno
< CR16_FIRST_DWORD_REGISTER
))
467 if ((regno
>= CR16_FIRST_DWORD_REGISTER
) && (regno
< FIRST_PSEUDO_REGISTER
))
473 /* Implement TARGET_HARD_REGNO_NREGS. */
476 cr16_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
478 if (regno
>= CR16_FIRST_DWORD_REGISTER
)
479 return CEIL (GET_MODE_SIZE (mode
), CR16_UNITS_PER_DWORD
);
480 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_WORD
);
483 /* Implement TARGET_HARD_REGNO_MODE_OK. On the CR16 architecture, all
484 registers can hold all modes, except that double precision floats
485 (and double ints) must fall on even-register boundaries. */
488 cr16_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
490 if ((GET_MODE_SIZE (mode
) >= 4) && (regno
== 11))
493 if (mode
== DImode
|| mode
== DFmode
)
495 if ((regno
> 8) || (regno
& 1))
501 && ((regno
>= 12) && (GET_MODE_SIZE (mode
) < 4 )))
504 /* CC can only hold CCmode values. */
505 if (GET_MODE_CLASS (mode
) == MODE_CC
)
510 /* Implement TARGET_MODES_TIEABLE_P. */
512 cr16_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
514 return GET_MODE_CLASS (mode1
) == GET_MODE_CLASS (mode2
);
517 /* Returns register number for function return value.*/
518 static inline unsigned int
519 cr16_ret_register (void)
524 /* Implements hook TARGET_STRUCT_VALUE_RTX. */
526 cr16_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED
,
527 int incoming ATTRIBUTE_UNUSED
)
529 return gen_rtx_REG (Pmode
, cr16_ret_register ());
532 /* Returning function value. */
534 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P. */
536 cr16_function_value_regno_p (const unsigned int regno
)
538 return (regno
== cr16_ret_register ());
541 /* Create an RTX representing the place where a
542 library function returns a value of mode MODE. */
544 cr16_libcall_value (machine_mode mode
,
545 const_rtx func ATTRIBUTE_UNUSED
)
547 return gen_rtx_REG (mode
, cr16_ret_register ());
550 /* Create an RTX representing the place where a
551 function returns a value of data type VALTYPE. */
553 cr16_function_value (const_tree type
,
554 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
555 bool outgoing ATTRIBUTE_UNUSED
)
557 return gen_rtx_REG (TYPE_MODE (type
), cr16_ret_register ());
560 /* Passing function arguments. */
562 /* If enough param regs are available for passing the param of type TYPE return
563 the number of registers needed else 0. */
565 enough_regs_for_param (CUMULATIVE_ARGS
* cum
, const_tree type
,
572 type_size
= GET_MODE_BITSIZE (mode
);
574 type_size
= int_size_in_bytes (type
) * BITS_PER_UNIT
;
576 remaining_size
= BITS_PER_WORD
* (MAX_REG_FOR_PASSING_ARGS
577 - (MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
) +
580 /* Any variable which is too big to pass in two registers, will pass on
582 if ((remaining_size
>= type_size
) && (type_size
<= 2 * BITS_PER_WORD
))
583 return (type_size
+ BITS_PER_WORD
- 1) / BITS_PER_WORD
;
588 /* Implements the macro FUNCTION_ARG defined in cr16.h. */
590 cr16_function_arg (cumulative_args_t cum_v
, machine_mode mode
,
591 const_tree type
, bool named ATTRIBUTE_UNUSED
)
593 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
594 cum
->last_parm_in_reg
= 0;
596 /* function_arg () is called with this type just after all the args have
597 had their registers assigned. The rtx that function_arg returns from
598 this type is supposed to pass to 'gen_call' but currently it is not
600 if (type
== void_type_node
)
603 if (targetm
.calls
.must_pass_in_stack (mode
, type
) || (cum
->ints
< 0))
608 /* Enable structures that need padding bytes at the end to pass to a
609 function in registers. */
610 if (enough_regs_for_param (cum
, type
, mode
) != 0)
612 cum
->last_parm_in_reg
= 1;
613 return gen_rtx_REG (mode
, MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
);
617 if ((MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
) > MAX_REG_FOR_PASSING_ARGS
)
621 if (enough_regs_for_param (cum
, type
, mode
) != 0)
623 cum
->last_parm_in_reg
= 1;
624 return gen_rtx_REG (mode
, MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
);
631 /* Implements the macro INIT_CUMULATIVE_ARGS defined in cr16.h. */
633 cr16_init_cumulative_args (CUMULATIVE_ARGS
* cum
, tree fntype
,
634 rtx libfunc ATTRIBUTE_UNUSED
)
636 tree param
, next_param
;
640 /* Determine if this function has variable arguments. This is indicated by
641 the last argument being 'void_type_mode' if there are no variable
642 arguments. Change here for a different vararg. */
643 for (param
= (fntype
) ? TYPE_ARG_TYPES (fntype
) : 0;
644 param
!= NULL_TREE
; param
= next_param
)
646 next_param
= TREE_CHAIN (param
);
647 if ((next_param
== NULL_TREE
) && (TREE_VALUE (param
) != void_type_node
))
655 /* Implements the macro FUNCTION_ARG_ADVANCE defined in cr16.h. */
657 cr16_function_arg_advance (cumulative_args_t cum_v
, machine_mode mode
,
658 const_tree type
, bool named ATTRIBUTE_UNUSED
)
660 CUMULATIVE_ARGS
* cum
= get_cumulative_args (cum_v
);
662 /* l holds the number of registers required. */
663 int l
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
665 /* If the parameter isn't passed on a register don't advance cum. */
666 if (!cum
->last_parm_in_reg
)
669 if (targetm
.calls
.must_pass_in_stack (mode
, type
) || (cum
->ints
< 0))
672 if ((mode
== SImode
) || (mode
== HImode
)
673 || (mode
== QImode
) || (mode
== DImode
))
680 else if ((mode
== SFmode
) || (mode
== DFmode
))
682 else if ((mode
) == BLKmode
)
684 if ((l
= enough_regs_for_param (cum
, type
, mode
)) != 0)
690 /* Implements the macro FUNCTION_ARG_REGNO_P defined in cr16.h.
691 Return nonzero if N is a register used for passing parameters. */
693 cr16_function_arg_regno_p (int n
)
695 return ((n
<= MAX_REG_FOR_PASSING_ARGS
) && (n
>= MIN_REG_FOR_PASSING_ARGS
));
699 Following set of function implement the macro GO_IF_LEGITIMATE_ADDRESS
700 defined in cr16.h. */
702 /* Helper function to check if is a valid base register that can
705 cr16_addr_reg_p (rtx addr_reg
)
709 if (REG_P (addr_reg
))
711 else if ((GET_CODE (addr_reg
) == SUBREG
)
712 && REG_P (SUBREG_REG (addr_reg
))
713 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg
)))
715 reg
= SUBREG_REG (addr_reg
);
719 if (GET_MODE (reg
) != Pmode
)
725 /* Helper functions: Created specifically for decomposing operand of CONST
726 Recursively look into expression x for code or data symbol.
727 The function expects the expression to contain combination of
728 SYMBOL_REF, CONST_INT, (PLUS or MINUS)
729 LABEL_REF, CONST_INT, (PLUS or MINUS)
732 All other combinations will result in code = -1 and data = ILLEGAL_DM
734 -1 ILLEGAL_DM The expression did not contain SYMBOL_REF or LABEL_REF
735 0 DM_FAR SYMBOL_REF was found and it was far data reference.
736 0 DM_DEFAULT SYMBOL_REF was found and it was medium data reference.
737 1 ILLEGAL_DM LABEL_REF was found.
738 2 ILLEGAL_DM SYMBOL_REF was found and it was function reference. */
740 cr16_decompose_const (rtx x
, int *code
, enum data_model_type
*data
,
745 switch (GET_CODE (x
))
748 *code
= SYMBOL_REF_FUNCTION_P (x
) ? 2 : 0;
749 /* 2 indicates func sym. */
752 if (CR16_TARGET_DATA_NEAR
)
754 else if (CR16_TARGET_DATA_MEDIUM
)
756 else if (CR16_TARGET_DATA_FAR
)
759 /* This will be used only for printing
760 the qualifier. This call is (may be)
761 made by cr16_print_operand_address. */
764 /* This call is (may be) made by
765 cr16_legitimate_address_p. */
772 /* 1 - indicates non-function symbol. */
778 /* Look into the tree nodes. */
779 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
780 cr16_decompose_const (XEXP (x
, 1), code
, data
, treat_as_const
);
781 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
782 cr16_decompose_const (XEXP (x
, 0), code
, data
, treat_as_const
);
790 This function decomposes the address returns the type of address
791 as defined in enum cr16_addrtype. It also fills the parameter *out.
792 The decomposed address can be used for two purposes. One to
793 check if the address is valid and second to print the address
796 Following tables list valid address supported in CR16C/C+ architectures.
798 aN : Absoulte address N-bit address
799 R : One 16-bit register
800 RP : Consecutive two 16-bit registers or one 32-bit register
801 I : One 32-bit register
802 dispN : Signed displacement of N-bits
804 ----Code addresses----
806 disp9 : CR16_ABSOLUTE (disp)
807 disp17 : CR16_ABSOLUTE (disp)
808 disp25 : CR16_ABSOLUTE (disp)
809 RP + disp25 : CR16_REGP_REL (base, disp)
812 RP : CR16_REGP_REL (base, disp=0)
813 a24 : CR16_ABSOLUTE (disp)
815 ----Data addresses----
816 a20 : CR16_ABSOLUTE (disp) near (1M)
817 a24 : CR16_ABSOLUTE (disp) medium (16M)
818 R + d20 : CR16_REG_REL (base, disp) near (1M+64K)
819 RP + d4 : CR16_REGP_REL (base, disp) far (4G)
820 RP + d16 : CR16_REGP_REL (base, disp) far (4G)
821 RP + d20 : CR16_REGP_REL (base, disp) far (4G)
822 I : *** Valid but port does not support this
823 I + a20 : *** Valid but port does not support this
824 I + RP + d14: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
825 I + RP + d20: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
827 Decomposing Data model in case of absolute address.
829 Target Option Address type Resultant Data ref type
830 ---------------------- ------------ -----------------------
831 CR16_TARGET_MODEL_NEAR ABS20 DM_DEFAULT
832 CR16_TARGET_MODEL_NEAR IMM20 DM_DEFAULT
833 CR16_TARGET_MODEL_NEAR ABS24 Invalid
834 CR16_TARGET_MODEL_NEAR IMM32 Invalid
836 CR16_TARGET_MODEL_MEDIUM ABS20 DM_DEFAULT
837 CR16_TARGET_MODEL_MEDIUM IMM20 DM_DEFAULT
838 CR16_TARGET_MODEL_MEDIUM ABS24 DM_FAR
839 CR16_TARGET_MODEL_MEDIUM IMM32 Invalid
841 CR16_TARGET_MODEL_FAR ABS20 DM_DEFAULT
842 CR16_TARGET_MODEL_FAR IMM20 DM_DEFAULT
843 CR16_TARGET_MODEL_FAR ABS24 DM_FAR
844 CR16_TARGET_MODEL_FAR IMM32 DM_FAR. */
846 cr16_decompose_address (rtx addr
, struct cr16_address
*out
,
847 bool debug_print
, bool treat_as_const
)
849 rtx base
= NULL_RTX
, disp
= NULL_RTX
, index
= NULL_RTX
;
850 enum data_model_type data
= ILLEGAL_DM
;
852 enum cr16_addrtype retval
= CR16_INVALID
;
854 switch (GET_CODE (addr
))
857 /* Absolute address (known at compile time). */
860 fprintf (stderr
, "\ncode:%d", code
);
865 fprintf (stderr
, "\ndisp:");
869 if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 20))
873 fprintf (stderr
, "\ndata:%d", data
);
874 retval
= CR16_ABSOLUTE
;
876 else if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 24))
878 if (!CR16_TARGET_DATA_NEAR
)
882 fprintf (stderr
, "\ndata:%d", data
);
883 retval
= CR16_ABSOLUTE
;
886 return CR16_INVALID
; /* ABS24 is not support in NEAR model. */
893 /* A CONST is an expression of PLUS or MINUS with
894 CONST_INT, SYMBOL_REF or LABEL_REF. This is the
895 result of assembly-time arithmetic computation. */
896 retval
= CR16_ABSOLUTE
;
898 /* Call the helper function to check the validity. */
899 cr16_decompose_const (XEXP (addr
, 0), &code
, &data
, treat_as_const
);
900 if ((code
== 0) && (data
== ILLEGAL_DM
))
901 /* CONST is not valid code or data address. */
905 fprintf (stderr
, "\ndisp:");
907 fprintf (stderr
, "\ncode:%d", code
);
908 fprintf (stderr
, "\ndata:%d", data
);
913 retval
= CR16_ABSOLUTE
;
915 /* 1 - indicates non-function symbol. */
919 fprintf (stderr
, "\ndisp:");
921 fprintf (stderr
, "\ncode:%d", code
);
926 /* Absolute address (known at link time). */
927 retval
= CR16_ABSOLUTE
;
929 /* This is a code address if symbol_ref is a function. */
930 /* 2 indicates func sym. */
931 code
= SYMBOL_REF_FUNCTION_P (addr
) ? 2 : 0;
934 fprintf (stderr
, "\ndisp:");
936 fprintf (stderr
, "\ncode:%d", code
);
938 /* If not function ref then check if valid data ref. */
941 if (CR16_TARGET_DATA_NEAR
)
943 else if (CR16_TARGET_DATA_MEDIUM
)
945 else if (CR16_TARGET_DATA_FAR
)
948 /* This will be used only for printing the
949 qualifier. This call is (may be) made
950 by cr16_print_operand_address. */
953 /* This call is (may be) made by
954 cr16_legitimate_address_p. */
961 fprintf (stderr
, "\ndata:%d", data
);
966 /* Register relative address. */
967 /* Assume REG fits in a single register. */
968 retval
= CR16_REG_REL
;
969 if (GET_MODE_BITSIZE (GET_MODE (addr
)) > BITS_PER_WORD
)
970 if (!LONG_REG_P (REGNO (addr
)))
971 /* REG will result in reg pair. */
972 retval
= CR16_REGP_REL
;
976 fprintf (stderr
, "\nbase:");
982 switch (GET_CODE (XEXP (addr
, 0)))
987 /* All Reg relative addresses having a displacement needs
988 to fit in 20-bits. */
989 disp
= XEXP (addr
, 1);
992 fprintf (stderr
, "\ndisp:");
995 switch (GET_CODE (XEXP (addr
, 1)))
998 /* Shall fit in 20-bits. */
999 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 20))
1000 return CR16_INVALID
;
1003 fprintf (stderr
, "\ncode:%d", code
);
1007 switch (XINT (XEXP (addr
, 1), 1))
1009 case UNSPEC_LIBRARY_OFFSET
:
1018 /* This is also a valid expression for address.
1019 However, we cannot ascertain if the resultant
1020 displacement will be valid 20-bit value. Therefore,
1021 lets not allow such an expression for now. This will
1022 be updated when we find a way to validate this
1023 expression as legitimate address.
1024 Till then fall through CR16_INVALID. */
1026 return CR16_INVALID
;
1029 /* Now check if REG can fit into single or pair regs. */
1030 retval
= CR16_REG_REL
;
1031 base
= XEXP (addr
, 0);
1034 fprintf (stderr
, "\nbase:");
1037 if (GET_MODE_BITSIZE (GET_MODE ((XEXP (addr
, 0)))) > BITS_PER_WORD
)
1039 if (!LONG_REG_P (REGNO ((XEXP (addr
, 0)))))
1040 /* REG will result in reg pair. */
1041 retval
= CR16_REGP_REL
;
1055 Check if the operand 1 is valid index register. */
1058 fprintf (stderr
, "\ndata:%d", data
);
1059 switch (GET_CODE (XEXP (addr
, 1)))
1063 if (!REG_OK_FOR_INDEX_P (XEXP (addr
, 1)))
1064 return CR16_INVALID
;
1065 /* OK. REG is a valid index register. */
1066 index
= XEXP (addr
, 1);
1069 fprintf (stderr
, "\nindex:");
1074 return CR16_INVALID
;
1076 /* Check if operand 0 of operand 0 is REGP. */
1077 switch (GET_CODE (XEXP (XEXP (addr
, 0), 0)))
1081 /* Now check if REG is a REGP and not in LONG regs. */
1082 if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (addr
, 0), 0)))
1085 if (REGNO (XEXP (XEXP (addr
, 0), 0))
1086 >= CR16_FIRST_DWORD_REGISTER
)
1087 return CR16_INVALID
;
1088 base
= XEXP (XEXP (addr
, 0), 0);
1091 fprintf (stderr
, "\nbase:");
1096 return CR16_INVALID
;
1099 return CR16_INVALID
;
1101 /* Now check if the operand 1 of operand 0 is const_int. */
1102 if (GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
1104 disp
= XEXP (XEXP (addr
, 0), 1);
1107 fprintf (stderr
, "\ndisp:");
1110 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 20))
1111 return CR16_INVALID
;
1114 return CR16_INVALID
;
1115 retval
= CR16_INDEX_REGP_REL
;
1118 return CR16_INVALID
;
1123 return CR16_INVALID
;
1126 /* Check if the base and index registers are valid. */
1127 if (base
&& !(cr16_addr_reg_p (base
)))
1128 return CR16_INVALID
;
1129 if (base
&& !(CR16_REG_OK_FOR_BASE_P (base
)))
1130 return CR16_INVALID
;
1131 if (index
&& !(REG_OK_FOR_INDEX_P (index
)))
1132 return CR16_INVALID
;
1134 /* Write the decomposition to out parameter. */
1144 /* Return non-zero value if 'x' is legitimate PIC operand
1145 when generating PIC code. */
1147 legitimate_pic_operand_p (rtx x
)
1149 switch (GET_CODE (x
))
1156 /* REVISIT: Use something like symbol_referenced_p. */
1157 if (GET_CODE (XEXP (x
, 0)) == PLUS
1158 && (GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
1159 || GET_CODE (XEXP (XEXP (x
, 0), 0)) == LABEL_REF
)
1160 && (GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
))
1164 return legitimate_pic_operand_p (XEXP (x
, 0));
1171 /* Convert a non-PIC address in `orig' to a PIC address in `reg'.
1173 Input Output (-f pic) Output (-f PIC)
1176 C1 symbol symbol@BRO (r12) symbol@GOT (r12)
1178 C2 symbol + offset symbol+offset@BRO (r12) symbol+offset@GOT (r12)
1180 NOTE: @BRO is added using unspec:BRO
1181 NOTE: @GOT is added using unspec:GOT. */
1183 legitimize_pic_address (rtx orig
, machine_mode mode ATTRIBUTE_UNUSED
,
1186 /* First handle a simple SYMBOL_REF or LABEL_REF. */
1187 if (GET_CODE (orig
) == SYMBOL_REF
|| GET_CODE (orig
) == LABEL_REF
)
1190 reg
= gen_reg_rtx (Pmode
);
1192 if (flag_pic
== NEAR_PIC
)
1194 /* Unspec to handle -fpic option. */
1195 emit_insn (gen_unspec_bro_addr (reg
, orig
));
1196 emit_insn (gen_addsi3 (reg
, reg
, pic_offset_table_rtx
));
1198 else if (flag_pic
== FAR_PIC
)
1200 /* Unspec to handle -fPIC option. */
1201 emit_insn (gen_unspec_got_addr (reg
, orig
));
1205 else if (GET_CODE (orig
) == CONST
)
1207 /* To handle (symbol + offset). */
1210 if (GET_CODE (XEXP (orig
, 0)) == PLUS
1211 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
1216 gcc_assert (can_create_pseudo_p ());
1217 reg
= gen_reg_rtx (Pmode
);
1220 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
1222 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
, reg
);
1223 offset
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
1224 base
== reg
? 0 : reg
);
1226 /* REVISIT: Optimize for const-offsets. */
1227 emit_insn (gen_addsi3 (reg
, base
, offset
));
1234 /* Implementation of TARGET_LEGITIMATE_ADDRESS_P. */
1236 cr16_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED
,
1237 rtx addr
, bool strict
)
1239 enum cr16_addrtype addrtype
;
1240 struct cr16_address address
;
1242 if (TARGET_DEBUG_ADDR
)
1245 "\n======\nTARGET_LEGITIMATE_ADDRESS_P, mode = %s, strict = %d",
1246 GET_MODE_NAME (mode
), strict
);
1249 addrtype
= cr16_decompose_address (addr
, &address
,
1250 (TARGET_DEBUG_ADDR
? 1 : 0), FALSE
);
1252 if (TARGET_DEBUG_ADDR
)
1254 const char *typestr
;
1259 typestr
= "invalid";
1262 typestr
= "absolute";
1265 typestr
= "register relative";
1268 typestr
= "register pair relative";
1270 case CR16_INDEX_REGP_REL
:
1271 typestr
= "index + register pair relative";
1276 fprintf (stderr
, "\ncr16 address type: %s\n", typestr
);
1279 if (addrtype
== CR16_INVALID
)
1285 && !REGNO_MODE_OK_FOR_BASE_P (REGNO (address
.base
), mode
))
1287 if (TARGET_DEBUG_ADDR
)
1288 fprintf (stderr
, "base register not strict\n");
1291 if (address
.index
&& !REGNO_OK_FOR_INDEX_P (REGNO (address
.index
)))
1293 if (TARGET_DEBUG_ADDR
)
1294 fprintf (stderr
, "index register not strict\n");
1299 /* Return true if addressing mode is register relative. */
1302 if (addrtype
== CR16_REG_REL
|| addrtype
== CR16_REGP_REL
)
1311 /* Routines to compute costs. */
1313 /* Return cost of the memory address x. */
1315 cr16_address_cost (rtx addr
, machine_mode mode ATTRIBUTE_UNUSED
,
1316 addr_space_t as ATTRIBUTE_UNUSED
,
1317 bool speed ATTRIBUTE_UNUSED
)
1319 enum cr16_addrtype addrtype
;
1320 struct cr16_address address
;
1323 addrtype
= cr16_decompose_address (addr
, &address
, 0, FALSE
);
1325 gcc_assert (addrtype
!= CR16_INVALID
);
1327 /* CR16_ABSOLUTE : 3
1328 CR16_REG_REL (disp !=0) : 4
1329 CR16_REG_REL (disp ==0) : 5
1330 CR16_REGP_REL (disp !=0) : 6
1331 CR16_REGP_REL (disp ==0) : 7
1332 CR16_INDEX_REGP_REL (disp !=0) : 8
1333 CR16_INDEX_REGP_REL (disp ==0) : 9. */
1347 case CR16_INDEX_REGP_REL
:
1355 if (TARGET_DEBUG_ADDR
)
1357 fprintf (stderr
, "\n======\nmacro TARGET_ADDRESS_COST = %d\n", cost
);
1365 /* Implement `TARGET_REGISTER_MOVE_COST'. */
1367 cr16_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
1368 reg_class_t from ATTRIBUTE_UNUSED
, reg_class_t to
)
1370 return (to
!= GENERAL_REGS
? 8 : 2);
1373 /* Implement `TARGET_MEMORY_MOVE_COST'. */
1375 /* Return the cost of moving data of mode MODE between a register of class
1376 CLASS and memory; IN is zero if the value is to be written to memory,
1377 nonzero if it is to be read in. This cost is relative to those in
1378 REGISTER_MOVE_COST. */
1380 cr16_memory_move_cost (machine_mode mode
,
1381 reg_class_t rclass ATTRIBUTE_UNUSED
,
1382 bool in ATTRIBUTE_UNUSED
)
1384 /* One LD or ST takes twice the time of a simple reg-reg move. */
1385 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
1386 return (4 * cr16_hard_regno_nregs (0, mode
));
1391 /* Instruction output. */
1393 /* Check if a const_double is ok for cr16 store-immediate instructions. */
1395 cr16_const_double_ok (rtx op
)
1397 if (GET_MODE (op
) == SFmode
)
1400 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op
), l
);
1401 return UNSIGNED_INT_FITS_N_BITS (l
, 4) ? 1 : 0;
1404 return ((UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op
), 4)) &&
1405 (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op
), 4))) ? 1 : 0;
1408 /* Returns bit position of first 0 or 1 bit.
1409 It is safe to assume val as 16-bit wide. */
1411 cr16_operand_bit_pos (int val
, int bitval
)
1417 for (i
= 0; i
< 16; i
++)
1423 /* Implements the macro PRINT_OPERAND defined in cr16.h. */
1425 cr16_print_operand (FILE * file
, rtx x
, int code
)
1427 int ptr_dereference
= 0;
1433 const char *cr16_cmp_str
;
1434 switch (GET_CODE (x
))
1436 /* MD: compare (reg, reg or imm) but CR16: cmp (reg or imm, reg)
1437 -> swap all non symmetric ops. */
1439 cr16_cmp_str
= "eq";
1442 cr16_cmp_str
= "ne";
1445 cr16_cmp_str
= "lt";
1448 cr16_cmp_str
= "lo";
1451 cr16_cmp_str
= "gt";
1454 cr16_cmp_str
= "hi";
1457 cr16_cmp_str
= "le";
1460 cr16_cmp_str
= "ls";
1463 cr16_cmp_str
= "ge";
1466 cr16_cmp_str
= "hs";
1471 fprintf (file
, "%s", cr16_cmp_str
);
1479 if (GET_CODE (x
) == REG
)
1481 /* For Push instructions, we should not print register pairs. */
1482 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1488 /* Print the immediate address for bal
1489 'b' is used instead of 'a' to avoid compiler calling
1490 the GO_IF_LEGITIMATE_ADDRESS which cannot
1491 perform checks on const_int code addresses as it
1492 assumes all const_int are data addresses. */
1493 fprintf (file
, "0x%lx", INTVAL (x
));
1497 /* Print bit position of first 0. */
1498 fprintf (file
, "%d", cr16_operand_bit_pos (INTVAL (x
), 0));
1502 /* Print bit position of first 1. */
1503 fprintf (file
, "%d", cr16_operand_bit_pos (INTVAL (x
), 1));
1506 /* 'g' is used for implicit mem: dereference. */
1507 ptr_dereference
= 1;
1512 switch (GET_CODE (x
))
1515 if (GET_MODE_BITSIZE (GET_MODE (x
)) > BITS_PER_WORD
)
1517 if (LONG_REG_P (REGNO (x
)))
1518 fprintf (file
, "(%s)", reg_names
[REGNO (x
)]);
1520 fprintf (file
, "(%s,%s)", reg_names
[REGNO (x
) + 1],
1521 reg_names
[REGNO (x
)]);
1524 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1528 output_address (GET_MODE (x
), XEXP (x
, 0));
1535 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
1537 fprintf (file
, "$0x%lx", l
);
1542 fprintf (file
, "$%ld", INTVAL (x
));
1546 switch (XINT (x
, 1))
1554 if (!ptr_dereference
)
1558 cr16_print_operand_address (file
, VOIDmode
, x
);
1563 output_operand_lossage ("invalid %%xn code");
1569 /* Implements the macro PRINT_OPERAND_ADDRESS defined in cr16.h. */
1572 cr16_print_operand_address (FILE * file
, machine_mode
/*mode*/, rtx addr
)
1574 enum cr16_addrtype addrtype
;
1575 struct cr16_address address
;
1577 /* Decompose the address. Also ask it to treat address as constant. */
1578 addrtype
= cr16_decompose_address (addr
, &address
, 0, TRUE
);
1580 if (address
.disp
&& GET_CODE (address
.disp
) == UNSPEC
)
1590 if (GET_CODE (address
.disp
) == UNSPEC
)
1591 cr16_print_operand (file
, address
.disp
, 0);
1593 output_addr_const (file
, address
.disp
);
1596 fprintf (file
, "0");
1597 fprintf (file
, "(%s)", reg_names
[REGNO (address
.base
)]);
1602 output_addr_const (file
, address
.disp
);
1604 fprintf (file
, "0");
1607 case CR16_INDEX_REGP_REL
:
1608 fprintf (file
, "[%s]", reg_names
[REGNO (address
.index
)]);
1613 if (GET_CODE (address
.disp
) == UNSPEC
)
1614 cr16_print_operand (file
, address
.disp
, 0);
1616 output_addr_const (file
, address
.disp
);
1619 fprintf (file
, "0");
1620 fprintf (file
, "(%s,%s)", reg_names
[REGNO (address
.base
) + 1],
1621 reg_names
[REGNO (address
.base
)]);
1627 /* Add qualifiers to the address expression that was just printed. */
1628 if (flag_pic
< NEAR_PIC
&& address
.code
== 0)
1630 if (address
.data
== DM_FAR
)
1631 /* Addr contains SYMBOL_REF & far data ptr. */
1632 fprintf (file
, "@l");
1633 else if (address
.data
== DM_DEFAULT
)
1634 /* Addr contains SYMBOL_REF & medium data ptr. */
1635 fprintf (file
, "@m");
1636 /* Addr contains SYMBOL_REF & medium data ptr. */
1637 else if (address
.data
== DM_NEAR
)
1638 /* Addr contains SYMBOL_REF & near data ptr. */
1639 fprintf (file
, "@s");
1641 else if (flag_pic
== NEAR_PIC
1642 && (address
.code
== 0) && (address
.data
== DM_FAR
1643 || address
.data
== DM_DEFAULT
1644 || address
.data
== DM_NEAR
))
1646 fprintf (file
, "@l");
1648 else if (flag_pic
== NEAR_PIC
&& address
.code
== 2)
1650 fprintf (file
, "pic");
1652 else if (flag_pic
== NEAR_PIC
&& address
.code
== 1)
1654 fprintf (file
, "@cpic");
1657 else if (flag_pic
== FAR_PIC
&& address
.code
== 2)
1659 /* REVISIT: cr16 register indirect jump expects a 1-bit right shifted
1660 address ! GOTc tells assembler this symbol is a text-address
1661 This needs to be fixed in such a way that this offset is done
1662 only in the case where an address is being used for indirect jump
1663 or call. Determining the potential usage of loadd is of course not
1664 possible always. Eventually, this has to be fixed in the
1666 fprintf (file
, "GOT (%s)", reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
1668 else if (flag_pic
== FAR_PIC
&& address
.code
== 1)
1670 fprintf (file
, "@cGOT (%s)", reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
1673 else if (flag_pic
== FAR_PIC
&&
1674 (address
.data
== DM_FAR
|| address
.data
== DM_DEFAULT
1675 || address
.data
== DM_NEAR
))
1677 fprintf (file
, "@GOT (%s)", reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
1681 /* Machine description helper functions. */
1683 /* Called from cr16.md. The return value depends on the parameter push_or_pop:
1684 When push_or_pop is zero -> string for push instructions of prologue.
1685 When push_or_pop is nonzero -> string for pop/popret/retx in epilogue.
1686 Relies on the assumptions:
1687 1. RA is the last register to be saved.
1688 2. The maximal value of the counter is MAX_COUNT. */
1690 cr16_prepare_push_pop_string (int push_or_pop
)
1692 /* j is the number of registers being saved, takes care that there won't be
1693 more than 8 in one push/pop instruction. */
1695 /* For the register mask string. */
1696 static char one_inst_str
[50];
1698 /* i is the index of current_frame_info.save_regs[], going from 0 until
1699 current_frame_info.last_reg_to_save. */
1705 /* For reversing on the push instructions if there are more than one. */
1708 return_str
= (char *) xmalloc (160);
1709 temp_str
= (char *) xmalloc (160);
1712 memset (return_str
, 0, 3);
1715 while (i
<= current_frame_info
.last_reg_to_save
)
1717 /* Prepare mask for one instruction. */
1718 one_inst_str
[0] = 0;
1720 /* To count number of words in one instruction. */
1724 while ((word_cnt
< MAX_COUNT
)
1725 && (i
<= current_frame_info
.last_reg_to_save
))
1727 /* For each non consecutive save register,
1728 a new instruction shall be generated. */
1729 if (!current_frame_info
.save_regs
[i
])
1731 /* Move to next reg and break. */
1736 if (i
== RETURN_ADDRESS_REGNUM
)
1740 /* Check especially if adding 2 does not cross the MAX_COUNT. */
1741 if ((word_cnt
+ ((i
< CR16_FIRST_DWORD_REGISTER
) ? 1 : 2))
1744 /* Increase word count by 2 for long registers except RA. */
1745 word_cnt
+= ((i
< CR16_FIRST_DWORD_REGISTER
) ? 1 : 2);
1750 /* No need to generate any instruction as
1751 no register or RA needs to be saved. */
1752 if ((word_cnt
== 0) && (print_ra
== 0))
1755 /* Now prepare the instruction operands. */
1758 sprintf (one_inst_str
, "$%d, %s", word_cnt
, reg_names
[start_reg
]);
1760 strcat (one_inst_str
, ", ra");
1763 strcat (one_inst_str
, "ra");
1765 if (push_or_pop
== 1)
1767 /* Pop instruction. */
1768 if (print_ra
&& !cr16_interrupt_function_p ()
1769 && !crtl
->calls_eh_return
)
1770 /* Print popret if RA is saved and its not a interrupt
1772 strcpy (temp_str
, "\n\tpopret\t");
1774 strcpy (temp_str
, "\n\tpop\t");
1776 strcat (temp_str
, one_inst_str
);
1778 /* Add the pop instruction list. */
1779 strcat (return_str
, temp_str
);
1783 /* Push instruction. */
1784 strcpy (temp_str
, "\n\tpush\t");
1785 strcat (temp_str
, one_inst_str
);
1787 /* We need to reverse the order of the instructions if there
1788 are more than one. (since the pop will not be reversed in
1790 strcat (temp_str
, return_str
);
1791 strcpy (return_str
, temp_str
);
1795 if (push_or_pop
== 1)
1798 if (cr16_interrupt_function_p ())
1799 strcat (return_str
, "\n\tretx\n");
1800 else if (crtl
->calls_eh_return
)
1802 /* Add stack adjustment before returning to exception handler
1803 NOTE: EH_RETURN_STACKADJ_RTX must refer to (r5, r4). */
1804 strcat (return_str
, "\n\taddd\t (r5, r4), (sp)\t\n");
1805 strcat (return_str
, "\n\tjump\t (ra)\n");
1807 /* But before anything else, undo the adjustment addition done in
1808 cr16_expand_epilogue (). */
1809 strcpy (temp_str
, "\n\tsubd\t (r5, r4), (sp)\t\n");
1810 strcat (temp_str
, return_str
);
1811 strcpy (return_str
, temp_str
);
1813 else if (!FUNC_IS_NORETURN_P (current_function_decl
)
1814 && !(current_frame_info
.save_regs
[RETURN_ADDRESS_REGNUM
]))
1815 strcat (return_str
, "\n\tjump\t (ra)\n");
1818 /* Skip the newline and the tab in the start of return_str. */
1824 /* Generate DWARF2 annotation for multi-push instruction. */
1826 cr16_create_dwarf_for_multi_push (rtx insn
)
1828 rtx dwarf
, reg
, tmp
;
1829 int i
, j
, from
, to
, word_cnt
, dwarf_par_index
, inc
;
1831 int num_regs
= 0, offset
= 0, split_here
= 0, total_push_bytes
= 0;
1833 for (i
= 0; i
<= current_frame_info
.last_reg_to_save
; ++i
)
1835 if (current_frame_info
.save_regs
[i
])
1838 if (i
< CR16_FIRST_DWORD_REGISTER
)
1839 total_push_bytes
+= 2;
1841 total_push_bytes
+= 4;
1848 dwarf
= gen_rtx_SEQUENCE (VOIDmode
, rtvec_alloc (num_regs
+ 1));
1849 dwarf_par_index
= num_regs
;
1851 from
= current_frame_info
.last_reg_to_save
+ 1;
1852 to
= current_frame_info
.last_reg_to_save
;
1855 for (i
= current_frame_info
.last_reg_to_save
; i
>= 0;)
1857 if (!current_frame_info
.save_regs
[i
] || 0 == i
|| split_here
)
1859 /* This block of regs is pushed in one instruction. */
1860 if (0 == i
&& current_frame_info
.save_regs
[i
])
1863 for (j
= to
; j
>= from
; --j
)
1865 if (j
< CR16_FIRST_DWORD_REGISTER
)
1875 reg
= gen_rtx_REG (mode
, j
);
1877 tmp
= gen_rtx_SET (gen_frame_mem (mode
,
1879 (Pmode
, stack_pointer_rtx
,
1880 total_push_bytes
- offset
)),
1882 RTX_FRAME_RELATED_P (tmp
) = 1;
1883 XVECEXP (dwarf
, 0, dwarf_par_index
--) = tmp
;
1892 if (i
!= RETURN_ADDRESS_REGNUM
)
1894 inc
= (i
< CR16_FIRST_DWORD_REGISTER
) ? 1 : 2;
1895 if (word_cnt
+ inc
>= MAX_COUNT
|| FRAME_POINTER_REGNUM
== i
)
1907 tmp
= gen_rtx_SET (stack_pointer_rtx
,
1908 gen_rtx_PLUS (SImode
, stack_pointer_rtx
,
1909 GEN_INT (-offset
)));
1910 RTX_FRAME_RELATED_P (tmp
) = 1;
1911 XVECEXP (dwarf
, 0, 0) = tmp
;
1913 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, dwarf
);
1917 CompactRISC CR16 Architecture stack layout:
1919 0 +---------------------
1924 +==================== Sp (x) = Ap (x+1)
1925 A | Args for functions
1926 | | called by X and Dynamically
1927 | | Dynamic allocations allocated and
1928 | | (alloca, variable deallocated
1929 Stack | length arrays).
1930 grows +-------------------- Fp (x)
1931 down| | Local variables of X
1932 ward| +--------------------
1933 | | Regs saved for X-1
1934 | +==================== Sp (x-1) = Ap (x)
1937 +-------------------- Fp (x-1)
1943 cr16_expand_prologue (void)
1947 cr16_compute_frame ();
1948 cr16_compute_save_regs ();
1950 /* If there is no need in push and adjustment to sp, return. */
1951 if ((current_frame_info
.total_size
+ current_frame_info
.reg_size
) == 0)
1954 if (current_frame_info
.last_reg_to_save
!= -1)
1956 /* If there are registers to push. */
1957 insn
= emit_insn (gen_push_for_prologue
1958 (GEN_INT (current_frame_info
.reg_size
)));
1959 cr16_create_dwarf_for_multi_push (insn
);
1960 RTX_FRAME_RELATED_P (insn
) = 1;
1964 if (current_frame_info
.total_size
> 0)
1966 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
1967 GEN_INT (-current_frame_info
.total_size
)));
1968 RTX_FRAME_RELATED_P (insn
) = 1;
1971 if (frame_pointer_needed
)
1973 /* Initialize the frame pointer with the value of the stack pointer
1974 pointing now to the locals. */
1975 insn
= emit_move_insn (frame_pointer_rtx
, stack_pointer_rtx
);
1979 /* Generate insn that updates the stack for local variables and padding
1980 for registers we save. - Generate the appropriate return insn. */
1982 cr16_expand_epilogue (void)
1986 /* Nonzero if we need to return and pop only RA. This will generate a
1987 different insn. This differentiate is for the peepholes for call as
1988 last statement in function. */
1989 int only_popret_RA
= (current_frame_info
.save_regs
[RETURN_ADDRESS_REGNUM
]
1990 && (current_frame_info
.reg_size
1991 == CR16_UNITS_PER_DWORD
));
1993 if (frame_pointer_needed
)
1995 /* Restore the stack pointer with the frame pointers value. */
1996 insn
= emit_move_insn (stack_pointer_rtx
, frame_pointer_rtx
);
1999 if (current_frame_info
.total_size
> 0)
2001 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2002 GEN_INT (current_frame_info
.total_size
)));
2003 RTX_FRAME_RELATED_P (insn
) = 1;
2006 if (crtl
->calls_eh_return
)
2008 /* Add this here so that (r5, r4) is actually loaded with the adjustment
2009 value; otherwise, the load might be optimized away...
2010 NOTE: remember to subtract the adjustment before popping the regs
2011 and add it back before returning. */
2012 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2013 EH_RETURN_STACKADJ_RTX
));
2016 if (cr16_interrupt_function_p ())
2018 insn
= emit_jump_insn (gen_interrupt_return ());
2019 RTX_FRAME_RELATED_P (insn
) = 1;
2021 else if (crtl
->calls_eh_return
)
2023 /* Special case, pop what's necessary, adjust SP and jump to (RA). */
2024 insn
= emit_jump_insn (gen_pop_and_popret_return
2025 (GEN_INT (current_frame_info
.reg_size
)));
2026 RTX_FRAME_RELATED_P (insn
) = 1;
2028 else if (current_frame_info
.last_reg_to_save
== -1)
2029 /* Nothing to pop. */
2030 /* Don't output jump for interrupt routine, only retx. */
2031 emit_jump_insn (gen_jump_return ());
2032 else if (only_popret_RA
)
2034 insn
= emit_jump_insn (gen_popret_RA_return ());
2035 RTX_FRAME_RELATED_P (insn
) = 1;
2039 insn
= emit_jump_insn (gen_pop_and_popret_return
2040 (GEN_INT (current_frame_info
.reg_size
)));
2041 RTX_FRAME_RELATED_P (insn
) = 1;
2045 /* Implements FRAME_POINTER_REQUIRED. */
2047 cr16_frame_pointer_required (void)
2049 return (cfun
->calls_alloca
|| crtl
->calls_eh_return
2050 || cfun
->has_nonlocal_label
|| crtl
->calls_eh_return
);
2054 cr16_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
2056 return (to
== STACK_POINTER_REGNUM
? !frame_pointer_needed
: true);
2060 /* A C compound statement that attempts to replace X with
2061 a valid memory address for an operand of mode MODE. WIN
2062 will be a C statement label elsewhere in the code.
2063 X will always be the result of a call to break_out_memory_refs (),
2064 and OLDX will be the operand that was given to that function to
2066 The code generated by this macro should not alter the
2067 substructure of X. If it transforms X into a more legitimate form,
2068 it should assign X (which will always be a C variable) a new value. */
2070 cr16_legitimize_address (rtx x
, rtx orig_x ATTRIBUTE_UNUSED
,
2071 machine_mode mode ATTRIBUTE_UNUSED
)
2074 return legitimize_pic_address (orig_x
, mode
, NULL_RTX
);
2079 /* Implement TARGET_LEGITIMATE_CONSTANT_P
2080 Nonzero if X is a legitimate constant for an immediate
2081 operand on the target machine. You can assume that X
2082 satisfies CONSTANT_P. In cr16c treat legitimize float
2083 constant as an immediate operand. */
2085 cr16_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
,
2086 rtx x ATTRIBUTE_UNUSED
)
2092 notice_update_cc (rtx exp
)
2094 if (GET_CODE (exp
) == SET
)
2096 /* Jumps do not alter the cc's. */
2097 if (SET_DEST (exp
) == pc_rtx
)
2100 /* Moving register or memory into a register:
2101 it doesn't alter the cc's, but it might invalidate
2102 the RTX's which we remember the cc's came from.
2103 (Note that moving a constant 0 or 1 MAY set the cc's). */
2104 if (REG_P (SET_DEST (exp
))
2105 && (REG_P (SET_SRC (exp
)) || GET_CODE (SET_SRC (exp
)) == MEM
))
2110 /* Moving register into memory doesn't alter the cc's.
2111 It may invalidate the RTX's which we remember the cc's came from. */
2112 if (GET_CODE (SET_DEST (exp
)) == MEM
&& REG_P (SET_SRC (exp
)))
2122 static scalar_int_mode
2123 cr16_unwind_word_mode (void)
2128 /* Helper function for md file. This function is used to emit arithmetic
2129 DI instructions. The argument "num" decides which instruction to be
2132 cr16_emit_add_sub_di (rtx
*operands
, enum rtx_code code
)
2138 lo_op
[0] = gen_lowpart (SImode
, operands
[0]);
2139 hi0_op
[0] = simplify_gen_subreg (HImode
, operands
[0], DImode
, 4);
2140 hi1_op
[0] = simplify_gen_subreg (HImode
, operands
[0], DImode
, 6);
2142 lo_op
[1] = gen_lowpart (SImode
, operands
[2]);
2143 hi0_op
[1] = simplify_gen_subreg (HImode
, operands
[2], DImode
, 4);
2144 hi1_op
[1] = simplify_gen_subreg (HImode
, operands
[2], DImode
, 6);
2150 output_asm_insn ("addd\t%1, %0", lo_op
) ;
2151 output_asm_insn ("addcw\t%1, %0", hi0_op
) ;
2152 output_asm_insn ("addcw\t%1, %0", hi1_op
) ;
2157 output_asm_insn ("subd\t%1, %0", lo_op
) ;
2158 output_asm_insn ("subcw\t%1, %0", hi0_op
) ;
2159 output_asm_insn ("subcw\t%1, %0", hi1_op
) ;
2170 /* Helper function for md file. This function is used to emit logical
2171 DI instructions. The argument "num" decides which instruction to be
2174 cr16_emit_logical_di (rtx
*operands
, enum rtx_code code
)
2179 lo_op
[0] = gen_lowpart (SImode
, operands
[0]);
2180 hi_op
[0] = simplify_gen_subreg (SImode
, operands
[0], DImode
, 4);
2182 lo_op
[1] = gen_lowpart (SImode
, operands
[2]);
2183 hi_op
[1] = simplify_gen_subreg (SImode
, operands
[2], DImode
, 4);
2189 output_asm_insn ("andd\t%1, %0", lo_op
) ;
2190 output_asm_insn ("andd\t%1, %0", hi_op
) ;
2195 output_asm_insn ("ord\t%1, %0", lo_op
) ;
2196 output_asm_insn ("ord\t%1, %0", hi_op
) ;
2201 output_asm_insn ("xord\t%1, %0", lo_op
) ;
2202 output_asm_insn ("xord\t%1, %0", hi_op
) ;
2212 /* Initialize 'targetm' variable which contains pointers to functions
2213 and data relating to the target machine. */
2215 struct gcc_target targetm
= TARGET_INITIALIZER
;