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 #undef TARGET_CONSTANT_ALIGNMENT
204 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
206 /* Table of machine attributes. */
207 static const struct attribute_spec cr16_attribute_table
[] = {
208 /* ISRs have special prologue and epilogue requirements. */
209 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
210 affects_type_identity, exclusions }. */
211 {"interrupt", 0, 0, false, true, true, NULL
, false, NULL
},
212 {NULL
, 0, 0, false, false, false, NULL
, false, NULL
}
215 /* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive
216 .?byte directive along with @c is not understood by assembler.
217 Therefore, make all TARGET_ASM_UNALIGNED_xx_OP same
218 as TARGET_ASM_ALIGNED_xx_OP. */
219 #undef TARGET_ASM_UNALIGNED_HI_OP
220 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
221 #undef TARGET_ASM_UNALIGNED_SI_OP
222 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
223 #undef TARGET_ASM_UNALIGNED_DI_OP
224 #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
226 #undef TARGET_HARD_REGNO_NREGS
227 #define TARGET_HARD_REGNO_NREGS cr16_hard_regno_nregs
228 #undef TARGET_HARD_REGNO_MODE_OK
229 #define TARGET_HARD_REGNO_MODE_OK cr16_hard_regno_mode_ok
230 #undef TARGET_MODES_TIEABLE_P
231 #define TARGET_MODES_TIEABLE_P cr16_modes_tieable_p
233 /* Target hook implementations. */
235 /* Implements hook TARGET_RETURN_IN_MEMORY. */
237 cr16_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
239 const HOST_WIDE_INT size
= int_size_in_bytes (type
);
240 return ((size
== -1) || (size
> 8));
243 /* Implement TARGET_CLASS_LIKELY_SPILLED_P. */
245 cr16_class_likely_spilled_p (reg_class_t rclass
)
247 if ((rclass
) == SHORT_REGS
|| (rclass
) == DOUBLE_BASE_REGS
248 || (rclass
) == LONG_REGS
|| (rclass
) == GENERAL_REGS
)
255 cr16_return_pops_args (tree fundecl ATTRIBUTE_UNUSED
,
256 tree funtype ATTRIBUTE_UNUSED
,
257 int size ATTRIBUTE_UNUSED
)
262 /* Returns true if data model selected via command line option
263 is same as function argument. */
265 cr16_is_data_model (enum data_model_type model
)
267 return (model
== data_model
);
270 /* Parse relevant options and override. */
272 cr16_override_options (void)
274 /* Disable -fdelete-null-pointer-checks option for CR16 target.
275 Programs which rely on NULL pointer dereferences _not_ halting the
276 program may not work properly with this option. So disable this
278 flag_delete_null_pointer_checks
= 0;
280 /* FIXME: To avoid spill_failure ICE during exception handling,
281 * disable cse_fllow_jumps. The spill error occurs when compiler
282 * can't find a suitable candidate in GENERAL_REGS class to reload
284 * Need to find a better way of avoiding this situation. */
286 flag_cse_follow_jumps
= 0;
288 /* If -fpic option, data_model == DM_FAR. */
289 if (flag_pic
== NEAR_PIC
)
294 /* The only option we want to examine is data model option. */
297 if (strcmp (cr16_data_model
, "medium") == 0)
298 data_model
= DM_DEFAULT
;
299 else if (strcmp (cr16_data_model
, "near") == 0)
300 data_model
= DM_NEAR
;
301 else if (strcmp (cr16_data_model
, "far") == 0)
306 error ("data-model=far not valid for cr16c architecture");
309 error ("invalid data model option -mdata-model=%s", cr16_data_model
);
312 data_model
= DM_DEFAULT
;
315 /* Implements the macro TARGET_CONDITIONAL_REGISTER_USAGE. */
317 cr16_conditional_register_usage (void)
321 fixed_regs
[12] = call_used_regs
[12] = 1;
325 /* Stack layout and calling conventions routines. */
327 /* Return nonzero if the current function being compiled is an interrupt
328 function as specified by the "interrupt" attribute. */
330 cr16_interrupt_function_p (void)
334 attributes
= TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl
));
335 return (lookup_attribute ("interrupt", attributes
) != NULL_TREE
);
338 /* Compute values for the array current_frame_info.save_regs and the variable
339 current_frame_info.reg_size. The index of current_frame_info.save_regs
340 is numbers of register, each will get 1 if we need to save it in the
341 current function, 0 if not. current_frame_info.reg_size is the total sum
342 of the registers being saved. */
344 cr16_compute_save_regs (void)
348 /* Initialize here so in case the function is no-return it will be -1. */
349 current_frame_info
.last_reg_to_save
= -1;
351 /* Initialize the number of bytes to be saved. */
352 current_frame_info
.reg_size
= 0;
354 /* No need to save any registers if the function never returns. */
355 if (FUNC_IS_NORETURN_P (current_function_decl
) && !MUST_SAVE_REGS_P ())
358 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
360 if (fixed_regs
[regno
])
362 current_frame_info
.save_regs
[regno
] = 0;
366 /* If this reg is used and not call-used (except RA), save it. */
367 if (cr16_interrupt_function_p ())
369 if (!crtl
->is_leaf
&& call_used_regs
[regno
])
370 /* This is a volatile reg in a non-leaf interrupt routine - save
371 it for the sake of its sons. */
372 current_frame_info
.save_regs
[regno
] = 1;
373 else if (df_regs_ever_live_p (regno
))
374 /* This reg is used - save it. */
375 current_frame_info
.save_regs
[regno
] = 1;
377 /* This reg is not used, and is not a volatile - don't save. */
378 current_frame_info
.save_regs
[regno
] = 0;
382 /* If this reg is used and not call-used (except RA), save it. */
383 if (df_regs_ever_live_p (regno
)
384 && (!call_used_regs
[regno
] || regno
== RETURN_ADDRESS_REGNUM
))
385 current_frame_info
.save_regs
[regno
] = 1;
387 current_frame_info
.save_regs
[regno
] = 0;
391 /* Save registers so the exception handler can modify them. */
392 if (crtl
->calls_eh_return
)
398 regno
= EH_RETURN_DATA_REGNO (i
);
399 if (INVALID_REGNUM
== regno
)
401 current_frame_info
.save_regs
[regno
] = 1;
405 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
406 if (current_frame_info
.save_regs
[regno
] == 1)
408 current_frame_info
.last_reg_to_save
= regno
;
409 if (regno
>= CR16_FIRST_DWORD_REGISTER
)
410 current_frame_info
.reg_size
+= CR16_UNITS_PER_DWORD
;
412 current_frame_info
.reg_size
+= UNITS_PER_WORD
;
416 /* Compute the size of the local area and the size to be adjusted by the
417 prologue and epilogue. */
419 cr16_compute_frame (void)
421 /* For aligning the local variables. */
422 int stack_alignment
= STACK_BOUNDARY
/ BITS_PER_UNIT
;
425 /* Padding needed for each element of the frame. */
426 current_frame_info
.var_size
= get_frame_size ();
428 /* Align to the stack alignment. */
429 padding_locals
= current_frame_info
.var_size
% stack_alignment
;
431 padding_locals
= stack_alignment
- padding_locals
;
433 current_frame_info
.var_size
+= padding_locals
;
434 current_frame_info
.total_size
= current_frame_info
.var_size
435 + (ACCUMULATE_OUTGOING_ARGS
436 ? crtl
->outgoing_args_size
: 0);
439 /* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */
441 cr16_initial_elimination_offset (int from
, int to
)
443 /* Compute this since we need to use current_frame_info.reg_size. */
444 cr16_compute_save_regs ();
446 /* Compute this since we need to use current_frame_info.var_size. */
447 cr16_compute_frame ();
449 if (((from
) == FRAME_POINTER_REGNUM
) && ((to
) == STACK_POINTER_REGNUM
))
450 return (ACCUMULATE_OUTGOING_ARGS
? crtl
->outgoing_args_size
: 0);
451 else if (((from
) == ARG_POINTER_REGNUM
) && ((to
) == FRAME_POINTER_REGNUM
))
452 return (current_frame_info
.reg_size
+ current_frame_info
.var_size
);
453 else if (((from
) == ARG_POINTER_REGNUM
) && ((to
) == STACK_POINTER_REGNUM
))
454 return (current_frame_info
.reg_size
+ current_frame_info
.var_size
455 + (ACCUMULATE_OUTGOING_ARGS
? crtl
->outgoing_args_size
: 0));
460 /* Register Usage. */
462 /* Return the class number of the smallest class containing reg number REGNO.
463 This could be a conditional expression or could index an array. */
465 cr16_regno_reg_class (int regno
)
467 if ((regno
>= 0) && (regno
< CR16_FIRST_DWORD_REGISTER
))
470 if ((regno
>= CR16_FIRST_DWORD_REGISTER
) && (regno
< FIRST_PSEUDO_REGISTER
))
476 /* Implement TARGET_HARD_REGNO_NREGS. */
479 cr16_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
481 if (regno
>= CR16_FIRST_DWORD_REGISTER
)
482 return CEIL (GET_MODE_SIZE (mode
), CR16_UNITS_PER_DWORD
);
483 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_WORD
);
486 /* Implement TARGET_HARD_REGNO_MODE_OK. On the CR16 architecture, all
487 registers can hold all modes, except that double precision floats
488 (and double ints) must fall on even-register boundaries. */
491 cr16_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
493 if ((GET_MODE_SIZE (mode
) >= 4) && (regno
== 11))
496 if (mode
== DImode
|| mode
== DFmode
)
498 if ((regno
> 8) || (regno
& 1))
504 && ((regno
>= 12) && (GET_MODE_SIZE (mode
) < 4 )))
507 /* CC can only hold CCmode values. */
508 if (GET_MODE_CLASS (mode
) == MODE_CC
)
513 /* Implement TARGET_MODES_TIEABLE_P. */
515 cr16_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
517 return GET_MODE_CLASS (mode1
) == GET_MODE_CLASS (mode2
);
520 /* Returns register number for function return value.*/
521 static inline unsigned int
522 cr16_ret_register (void)
527 /* Implements hook TARGET_STRUCT_VALUE_RTX. */
529 cr16_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED
,
530 int incoming ATTRIBUTE_UNUSED
)
532 return gen_rtx_REG (Pmode
, cr16_ret_register ());
535 /* Returning function value. */
537 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P. */
539 cr16_function_value_regno_p (const unsigned int regno
)
541 return (regno
== cr16_ret_register ());
544 /* Create an RTX representing the place where a
545 library function returns a value of mode MODE. */
547 cr16_libcall_value (machine_mode mode
,
548 const_rtx func ATTRIBUTE_UNUSED
)
550 return gen_rtx_REG (mode
, cr16_ret_register ());
553 /* Create an RTX representing the place where a
554 function returns a value of data type VALTYPE. */
556 cr16_function_value (const_tree type
,
557 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
558 bool outgoing ATTRIBUTE_UNUSED
)
560 return gen_rtx_REG (TYPE_MODE (type
), cr16_ret_register ());
563 /* Passing function arguments. */
565 /* If enough param regs are available for passing the param of type TYPE return
566 the number of registers needed else 0. */
568 enough_regs_for_param (CUMULATIVE_ARGS
* cum
, const_tree type
,
575 type_size
= GET_MODE_BITSIZE (mode
);
577 type_size
= int_size_in_bytes (type
) * BITS_PER_UNIT
;
579 remaining_size
= BITS_PER_WORD
* (MAX_REG_FOR_PASSING_ARGS
580 - (MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
) +
583 /* Any variable which is too big to pass in two registers, will pass on
585 if ((remaining_size
>= type_size
) && (type_size
<= 2 * BITS_PER_WORD
))
586 return (type_size
+ BITS_PER_WORD
- 1) / BITS_PER_WORD
;
591 /* Implements the macro FUNCTION_ARG defined in cr16.h. */
593 cr16_function_arg (cumulative_args_t cum_v
, machine_mode mode
,
594 const_tree type
, bool named ATTRIBUTE_UNUSED
)
596 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
597 cum
->last_parm_in_reg
= 0;
599 /* function_arg () is called with this type just after all the args have
600 had their registers assigned. The rtx that function_arg returns from
601 this type is supposed to pass to 'gen_call' but currently it is not
603 if (type
== void_type_node
)
606 if (targetm
.calls
.must_pass_in_stack (mode
, type
) || (cum
->ints
< 0))
611 /* Enable structures that need padding bytes at the end to pass to a
612 function in registers. */
613 if (enough_regs_for_param (cum
, type
, mode
) != 0)
615 cum
->last_parm_in_reg
= 1;
616 return gen_rtx_REG (mode
, MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
);
620 if ((MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
) > MAX_REG_FOR_PASSING_ARGS
)
624 if (enough_regs_for_param (cum
, type
, mode
) != 0)
626 cum
->last_parm_in_reg
= 1;
627 return gen_rtx_REG (mode
, MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
);
634 /* Implements the macro INIT_CUMULATIVE_ARGS defined in cr16.h. */
636 cr16_init_cumulative_args (CUMULATIVE_ARGS
* cum
, tree fntype
,
637 rtx libfunc ATTRIBUTE_UNUSED
)
639 tree param
, next_param
;
643 /* Determine if this function has variable arguments. This is indicated by
644 the last argument being 'void_type_mode' if there are no variable
645 arguments. Change here for a different vararg. */
646 for (param
= (fntype
) ? TYPE_ARG_TYPES (fntype
) : 0;
647 param
!= NULL_TREE
; param
= next_param
)
649 next_param
= TREE_CHAIN (param
);
650 if ((next_param
== NULL_TREE
) && (TREE_VALUE (param
) != void_type_node
))
658 /* Implements the macro FUNCTION_ARG_ADVANCE defined in cr16.h. */
660 cr16_function_arg_advance (cumulative_args_t cum_v
, machine_mode mode
,
661 const_tree type
, bool named ATTRIBUTE_UNUSED
)
663 CUMULATIVE_ARGS
* cum
= get_cumulative_args (cum_v
);
665 /* l holds the number of registers required. */
666 int l
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
668 /* If the parameter isn't passed on a register don't advance cum. */
669 if (!cum
->last_parm_in_reg
)
672 if (targetm
.calls
.must_pass_in_stack (mode
, type
) || (cum
->ints
< 0))
675 if ((mode
== SImode
) || (mode
== HImode
)
676 || (mode
== QImode
) || (mode
== DImode
))
683 else if ((mode
== SFmode
) || (mode
== DFmode
))
685 else if ((mode
) == BLKmode
)
687 if ((l
= enough_regs_for_param (cum
, type
, mode
)) != 0)
693 /* Implements the macro FUNCTION_ARG_REGNO_P defined in cr16.h.
694 Return nonzero if N is a register used for passing parameters. */
696 cr16_function_arg_regno_p (int n
)
698 return ((n
<= MAX_REG_FOR_PASSING_ARGS
) && (n
>= MIN_REG_FOR_PASSING_ARGS
));
702 Following set of function implement the macro GO_IF_LEGITIMATE_ADDRESS
703 defined in cr16.h. */
705 /* Helper function to check if is a valid base register that can
708 cr16_addr_reg_p (rtx addr_reg
)
712 if (REG_P (addr_reg
))
714 else if ((GET_CODE (addr_reg
) == SUBREG
)
715 && REG_P (SUBREG_REG (addr_reg
))
716 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg
)))
718 reg
= SUBREG_REG (addr_reg
);
722 if (GET_MODE (reg
) != Pmode
)
728 /* Helper functions: Created specifically for decomposing operand of CONST
729 Recursively look into expression x for code or data symbol.
730 The function expects the expression to contain combination of
731 SYMBOL_REF, CONST_INT, (PLUS or MINUS)
732 LABEL_REF, CONST_INT, (PLUS or MINUS)
735 All other combinations will result in code = -1 and data = ILLEGAL_DM
737 -1 ILLEGAL_DM The expression did not contain SYMBOL_REF or LABEL_REF
738 0 DM_FAR SYMBOL_REF was found and it was far data reference.
739 0 DM_DEFAULT SYMBOL_REF was found and it was medium data reference.
740 1 ILLEGAL_DM LABEL_REF was found.
741 2 ILLEGAL_DM SYMBOL_REF was found and it was function reference. */
743 cr16_decompose_const (rtx x
, int *code
, enum data_model_type
*data
,
748 switch (GET_CODE (x
))
751 *code
= SYMBOL_REF_FUNCTION_P (x
) ? 2 : 0;
752 /* 2 indicates func sym. */
755 if (CR16_TARGET_DATA_NEAR
)
757 else if (CR16_TARGET_DATA_MEDIUM
)
759 else if (CR16_TARGET_DATA_FAR
)
762 /* This will be used only for printing
763 the qualifier. This call is (may be)
764 made by cr16_print_operand_address. */
767 /* This call is (may be) made by
768 cr16_legitimate_address_p. */
775 /* 1 - indicates non-function symbol. */
781 /* Look into the tree nodes. */
782 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
783 cr16_decompose_const (XEXP (x
, 1), code
, data
, treat_as_const
);
784 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
785 cr16_decompose_const (XEXP (x
, 0), code
, data
, treat_as_const
);
793 This function decomposes the address returns the type of address
794 as defined in enum cr16_addrtype. It also fills the parameter *out.
795 The decomposed address can be used for two purposes. One to
796 check if the address is valid and second to print the address
799 Following tables list valid address supported in CR16C/C+ architectures.
801 aN : Absoulte address N-bit address
802 R : One 16-bit register
803 RP : Consecutive two 16-bit registers or one 32-bit register
804 I : One 32-bit register
805 dispN : Signed displacement of N-bits
807 ----Code addresses----
809 disp9 : CR16_ABSOLUTE (disp)
810 disp17 : CR16_ABSOLUTE (disp)
811 disp25 : CR16_ABSOLUTE (disp)
812 RP + disp25 : CR16_REGP_REL (base, disp)
815 RP : CR16_REGP_REL (base, disp=0)
816 a24 : CR16_ABSOLUTE (disp)
818 ----Data addresses----
819 a20 : CR16_ABSOLUTE (disp) near (1M)
820 a24 : CR16_ABSOLUTE (disp) medium (16M)
821 R + d20 : CR16_REG_REL (base, disp) near (1M+64K)
822 RP + d4 : CR16_REGP_REL (base, disp) far (4G)
823 RP + d16 : CR16_REGP_REL (base, disp) far (4G)
824 RP + d20 : CR16_REGP_REL (base, disp) far (4G)
825 I : *** Valid but port does not support this
826 I + a20 : *** Valid but port does not support this
827 I + RP + d14: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
828 I + RP + d20: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
830 Decomposing Data model in case of absolute address.
832 Target Option Address type Resultant Data ref type
833 ---------------------- ------------ -----------------------
834 CR16_TARGET_MODEL_NEAR ABS20 DM_DEFAULT
835 CR16_TARGET_MODEL_NEAR IMM20 DM_DEFAULT
836 CR16_TARGET_MODEL_NEAR ABS24 Invalid
837 CR16_TARGET_MODEL_NEAR IMM32 Invalid
839 CR16_TARGET_MODEL_MEDIUM ABS20 DM_DEFAULT
840 CR16_TARGET_MODEL_MEDIUM IMM20 DM_DEFAULT
841 CR16_TARGET_MODEL_MEDIUM ABS24 DM_FAR
842 CR16_TARGET_MODEL_MEDIUM IMM32 Invalid
844 CR16_TARGET_MODEL_FAR ABS20 DM_DEFAULT
845 CR16_TARGET_MODEL_FAR IMM20 DM_DEFAULT
846 CR16_TARGET_MODEL_FAR ABS24 DM_FAR
847 CR16_TARGET_MODEL_FAR IMM32 DM_FAR. */
849 cr16_decompose_address (rtx addr
, struct cr16_address
*out
,
850 bool debug_print
, bool treat_as_const
)
852 rtx base
= NULL_RTX
, disp
= NULL_RTX
, index
= NULL_RTX
;
853 enum data_model_type data
= ILLEGAL_DM
;
855 enum cr16_addrtype retval
= CR16_INVALID
;
857 switch (GET_CODE (addr
))
860 /* Absolute address (known at compile time). */
863 fprintf (stderr
, "\ncode:%d", code
);
868 fprintf (stderr
, "\ndisp:");
872 if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 20))
876 fprintf (stderr
, "\ndata:%d", data
);
877 retval
= CR16_ABSOLUTE
;
879 else if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 24))
881 if (!CR16_TARGET_DATA_NEAR
)
885 fprintf (stderr
, "\ndata:%d", data
);
886 retval
= CR16_ABSOLUTE
;
889 return CR16_INVALID
; /* ABS24 is not support in NEAR model. */
896 /* A CONST is an expression of PLUS or MINUS with
897 CONST_INT, SYMBOL_REF or LABEL_REF. This is the
898 result of assembly-time arithmetic computation. */
899 retval
= CR16_ABSOLUTE
;
901 /* Call the helper function to check the validity. */
902 cr16_decompose_const (XEXP (addr
, 0), &code
, &data
, treat_as_const
);
903 if ((code
== 0) && (data
== ILLEGAL_DM
))
904 /* CONST is not valid code or data address. */
908 fprintf (stderr
, "\ndisp:");
910 fprintf (stderr
, "\ncode:%d", code
);
911 fprintf (stderr
, "\ndata:%d", data
);
916 retval
= CR16_ABSOLUTE
;
918 /* 1 - indicates non-function symbol. */
922 fprintf (stderr
, "\ndisp:");
924 fprintf (stderr
, "\ncode:%d", code
);
929 /* Absolute address (known at link time). */
930 retval
= CR16_ABSOLUTE
;
932 /* This is a code address if symbol_ref is a function. */
933 /* 2 indicates func sym. */
934 code
= SYMBOL_REF_FUNCTION_P (addr
) ? 2 : 0;
937 fprintf (stderr
, "\ndisp:");
939 fprintf (stderr
, "\ncode:%d", code
);
941 /* If not function ref then check if valid data ref. */
944 if (CR16_TARGET_DATA_NEAR
)
946 else if (CR16_TARGET_DATA_MEDIUM
)
948 else if (CR16_TARGET_DATA_FAR
)
951 /* This will be used only for printing the
952 qualifier. This call is (may be) made
953 by cr16_print_operand_address. */
956 /* This call is (may be) made by
957 cr16_legitimate_address_p. */
964 fprintf (stderr
, "\ndata:%d", data
);
969 /* Register relative address. */
970 /* Assume REG fits in a single register. */
971 retval
= CR16_REG_REL
;
972 if (GET_MODE_BITSIZE (GET_MODE (addr
)) > BITS_PER_WORD
)
973 if (!LONG_REG_P (REGNO (addr
)))
974 /* REG will result in reg pair. */
975 retval
= CR16_REGP_REL
;
979 fprintf (stderr
, "\nbase:");
985 switch (GET_CODE (XEXP (addr
, 0)))
990 /* All Reg relative addresses having a displacement needs
991 to fit in 20-bits. */
992 disp
= XEXP (addr
, 1);
995 fprintf (stderr
, "\ndisp:");
998 switch (GET_CODE (XEXP (addr
, 1)))
1001 /* Shall fit in 20-bits. */
1002 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 20))
1003 return CR16_INVALID
;
1006 fprintf (stderr
, "\ncode:%d", code
);
1010 switch (XINT (XEXP (addr
, 1), 1))
1012 case UNSPEC_LIBRARY_OFFSET
:
1021 /* This is also a valid expression for address.
1022 However, we cannot ascertain if the resultant
1023 displacement will be valid 20-bit value. Therefore,
1024 lets not allow such an expression for now. This will
1025 be updated when we find a way to validate this
1026 expression as legitimate address.
1027 Till then fall through CR16_INVALID. */
1029 return CR16_INVALID
;
1032 /* Now check if REG can fit into single or pair regs. */
1033 retval
= CR16_REG_REL
;
1034 base
= XEXP (addr
, 0);
1037 fprintf (stderr
, "\nbase:");
1040 if (GET_MODE_BITSIZE (GET_MODE ((XEXP (addr
, 0)))) > BITS_PER_WORD
)
1042 if (!LONG_REG_P (REGNO ((XEXP (addr
, 0)))))
1043 /* REG will result in reg pair. */
1044 retval
= CR16_REGP_REL
;
1058 Check if the operand 1 is valid index register. */
1061 fprintf (stderr
, "\ndata:%d", data
);
1062 switch (GET_CODE (XEXP (addr
, 1)))
1066 if (!REG_OK_FOR_INDEX_P (XEXP (addr
, 1)))
1067 return CR16_INVALID
;
1068 /* OK. REG is a valid index register. */
1069 index
= XEXP (addr
, 1);
1072 fprintf (stderr
, "\nindex:");
1077 return CR16_INVALID
;
1079 /* Check if operand 0 of operand 0 is REGP. */
1080 switch (GET_CODE (XEXP (XEXP (addr
, 0), 0)))
1084 /* Now check if REG is a REGP and not in LONG regs. */
1085 if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (addr
, 0), 0)))
1088 if (REGNO (XEXP (XEXP (addr
, 0), 0))
1089 >= CR16_FIRST_DWORD_REGISTER
)
1090 return CR16_INVALID
;
1091 base
= XEXP (XEXP (addr
, 0), 0);
1094 fprintf (stderr
, "\nbase:");
1099 return CR16_INVALID
;
1102 return CR16_INVALID
;
1104 /* Now check if the operand 1 of operand 0 is const_int. */
1105 if (GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
1107 disp
= XEXP (XEXP (addr
, 0), 1);
1110 fprintf (stderr
, "\ndisp:");
1113 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 20))
1114 return CR16_INVALID
;
1117 return CR16_INVALID
;
1118 retval
= CR16_INDEX_REGP_REL
;
1121 return CR16_INVALID
;
1126 return CR16_INVALID
;
1129 /* Check if the base and index registers are valid. */
1130 if (base
&& !(cr16_addr_reg_p (base
)))
1131 return CR16_INVALID
;
1132 if (base
&& !(CR16_REG_OK_FOR_BASE_P (base
)))
1133 return CR16_INVALID
;
1134 if (index
&& !(REG_OK_FOR_INDEX_P (index
)))
1135 return CR16_INVALID
;
1137 /* Write the decomposition to out parameter. */
1147 /* Return non-zero value if 'x' is legitimate PIC operand
1148 when generating PIC code. */
1150 legitimate_pic_operand_p (rtx x
)
1152 switch (GET_CODE (x
))
1159 /* REVISIT: Use something like symbol_referenced_p. */
1160 if (GET_CODE (XEXP (x
, 0)) == PLUS
1161 && (GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
1162 || GET_CODE (XEXP (XEXP (x
, 0), 0)) == LABEL_REF
)
1163 && (GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
))
1167 return legitimate_pic_operand_p (XEXP (x
, 0));
1174 /* Convert a non-PIC address in `orig' to a PIC address in `reg'.
1176 Input Output (-f pic) Output (-f PIC)
1179 C1 symbol symbol@BRO (r12) symbol@GOT (r12)
1181 C2 symbol + offset symbol+offset@BRO (r12) symbol+offset@GOT (r12)
1183 NOTE: @BRO is added using unspec:BRO
1184 NOTE: @GOT is added using unspec:GOT. */
1186 legitimize_pic_address (rtx orig
, machine_mode mode ATTRIBUTE_UNUSED
,
1189 /* First handle a simple SYMBOL_REF or LABEL_REF. */
1190 if (GET_CODE (orig
) == SYMBOL_REF
|| GET_CODE (orig
) == LABEL_REF
)
1193 reg
= gen_reg_rtx (Pmode
);
1195 if (flag_pic
== NEAR_PIC
)
1197 /* Unspec to handle -fpic option. */
1198 emit_insn (gen_unspec_bro_addr (reg
, orig
));
1199 emit_insn (gen_addsi3 (reg
, reg
, pic_offset_table_rtx
));
1201 else if (flag_pic
== FAR_PIC
)
1203 /* Unspec to handle -fPIC option. */
1204 emit_insn (gen_unspec_got_addr (reg
, orig
));
1208 else if (GET_CODE (orig
) == CONST
)
1210 /* To handle (symbol + offset). */
1213 if (GET_CODE (XEXP (orig
, 0)) == PLUS
1214 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
1219 gcc_assert (can_create_pseudo_p ());
1220 reg
= gen_reg_rtx (Pmode
);
1223 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
1225 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
, reg
);
1226 offset
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
1227 base
== reg
? 0 : reg
);
1229 /* REVISIT: Optimize for const-offsets. */
1230 emit_insn (gen_addsi3 (reg
, base
, offset
));
1237 /* Implementation of TARGET_LEGITIMATE_ADDRESS_P. */
1239 cr16_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED
,
1240 rtx addr
, bool strict
)
1242 enum cr16_addrtype addrtype
;
1243 struct cr16_address address
;
1245 if (TARGET_DEBUG_ADDR
)
1248 "\n======\nTARGET_LEGITIMATE_ADDRESS_P, mode = %s, strict = %d",
1249 GET_MODE_NAME (mode
), strict
);
1252 addrtype
= cr16_decompose_address (addr
, &address
,
1253 (TARGET_DEBUG_ADDR
? 1 : 0), FALSE
);
1255 if (TARGET_DEBUG_ADDR
)
1257 const char *typestr
;
1262 typestr
= "invalid";
1265 typestr
= "absolute";
1268 typestr
= "register relative";
1271 typestr
= "register pair relative";
1273 case CR16_INDEX_REGP_REL
:
1274 typestr
= "index + register pair relative";
1279 fprintf (stderr
, "\ncr16 address type: %s\n", typestr
);
1282 if (addrtype
== CR16_INVALID
)
1288 && !REGNO_MODE_OK_FOR_BASE_P (REGNO (address
.base
), mode
))
1290 if (TARGET_DEBUG_ADDR
)
1291 fprintf (stderr
, "base register not strict\n");
1294 if (address
.index
&& !REGNO_OK_FOR_INDEX_P (REGNO (address
.index
)))
1296 if (TARGET_DEBUG_ADDR
)
1297 fprintf (stderr
, "index register not strict\n");
1302 /* Return true if addressing mode is register relative. */
1305 if (addrtype
== CR16_REG_REL
|| addrtype
== CR16_REGP_REL
)
1314 /* Routines to compute costs. */
1316 /* Return cost of the memory address x. */
1318 cr16_address_cost (rtx addr
, machine_mode mode ATTRIBUTE_UNUSED
,
1319 addr_space_t as ATTRIBUTE_UNUSED
,
1320 bool speed ATTRIBUTE_UNUSED
)
1322 enum cr16_addrtype addrtype
;
1323 struct cr16_address address
;
1326 addrtype
= cr16_decompose_address (addr
, &address
, 0, FALSE
);
1328 gcc_assert (addrtype
!= CR16_INVALID
);
1330 /* CR16_ABSOLUTE : 3
1331 CR16_REG_REL (disp !=0) : 4
1332 CR16_REG_REL (disp ==0) : 5
1333 CR16_REGP_REL (disp !=0) : 6
1334 CR16_REGP_REL (disp ==0) : 7
1335 CR16_INDEX_REGP_REL (disp !=0) : 8
1336 CR16_INDEX_REGP_REL (disp ==0) : 9. */
1350 case CR16_INDEX_REGP_REL
:
1358 if (TARGET_DEBUG_ADDR
)
1360 fprintf (stderr
, "\n======\nmacro TARGET_ADDRESS_COST = %d\n", cost
);
1368 /* Implement `TARGET_REGISTER_MOVE_COST'. */
1370 cr16_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
1371 reg_class_t from ATTRIBUTE_UNUSED
, reg_class_t to
)
1373 return (to
!= GENERAL_REGS
? 8 : 2);
1376 /* Implement `TARGET_MEMORY_MOVE_COST'. */
1378 /* Return the cost of moving data of mode MODE between a register of class
1379 CLASS and memory; IN is zero if the value is to be written to memory,
1380 nonzero if it is to be read in. This cost is relative to those in
1381 REGISTER_MOVE_COST. */
1383 cr16_memory_move_cost (machine_mode mode
,
1384 reg_class_t rclass ATTRIBUTE_UNUSED
,
1385 bool in ATTRIBUTE_UNUSED
)
1387 /* One LD or ST takes twice the time of a simple reg-reg move. */
1388 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
1389 return (4 * cr16_hard_regno_nregs (0, mode
));
1394 /* Instruction output. */
1396 /* Check if a const_double is ok for cr16 store-immediate instructions. */
1398 cr16_const_double_ok (rtx op
)
1400 if (GET_MODE (op
) == SFmode
)
1403 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op
), l
);
1404 return UNSIGNED_INT_FITS_N_BITS (l
, 4) ? 1 : 0;
1407 return ((UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op
), 4)) &&
1408 (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op
), 4))) ? 1 : 0;
1411 /* Returns bit position of first 0 or 1 bit.
1412 It is safe to assume val as 16-bit wide. */
1414 cr16_operand_bit_pos (int val
, int bitval
)
1420 for (i
= 0; i
< 16; i
++)
1426 /* Implements the macro PRINT_OPERAND defined in cr16.h. */
1428 cr16_print_operand (FILE * file
, rtx x
, int code
)
1430 int ptr_dereference
= 0;
1436 const char *cr16_cmp_str
;
1437 switch (GET_CODE (x
))
1439 /* MD: compare (reg, reg or imm) but CR16: cmp (reg or imm, reg)
1440 -> swap all non symmetric ops. */
1442 cr16_cmp_str
= "eq";
1445 cr16_cmp_str
= "ne";
1448 cr16_cmp_str
= "lt";
1451 cr16_cmp_str
= "lo";
1454 cr16_cmp_str
= "gt";
1457 cr16_cmp_str
= "hi";
1460 cr16_cmp_str
= "le";
1463 cr16_cmp_str
= "ls";
1466 cr16_cmp_str
= "ge";
1469 cr16_cmp_str
= "hs";
1474 fprintf (file
, "%s", cr16_cmp_str
);
1482 if (GET_CODE (x
) == REG
)
1484 /* For Push instructions, we should not print register pairs. */
1485 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1491 /* Print the immediate address for bal
1492 'b' is used instead of 'a' to avoid compiler calling
1493 the GO_IF_LEGITIMATE_ADDRESS which cannot
1494 perform checks on const_int code addresses as it
1495 assumes all const_int are data addresses. */
1496 fprintf (file
, "0x%lx", INTVAL (x
));
1500 /* Print bit position of first 0. */
1501 fprintf (file
, "%d", cr16_operand_bit_pos (INTVAL (x
), 0));
1505 /* Print bit position of first 1. */
1506 fprintf (file
, "%d", cr16_operand_bit_pos (INTVAL (x
), 1));
1509 /* 'g' is used for implicit mem: dereference. */
1510 ptr_dereference
= 1;
1515 switch (GET_CODE (x
))
1518 if (GET_MODE_BITSIZE (GET_MODE (x
)) > BITS_PER_WORD
)
1520 if (LONG_REG_P (REGNO (x
)))
1521 fprintf (file
, "(%s)", reg_names
[REGNO (x
)]);
1523 fprintf (file
, "(%s,%s)", reg_names
[REGNO (x
) + 1],
1524 reg_names
[REGNO (x
)]);
1527 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1531 output_address (GET_MODE (x
), XEXP (x
, 0));
1538 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
1540 fprintf (file
, "$0x%lx", l
);
1545 fprintf (file
, "$%ld", INTVAL (x
));
1549 switch (XINT (x
, 1))
1557 if (!ptr_dereference
)
1561 cr16_print_operand_address (file
, VOIDmode
, x
);
1566 output_operand_lossage ("invalid %%xn code");
1572 /* Implements the macro PRINT_OPERAND_ADDRESS defined in cr16.h. */
1575 cr16_print_operand_address (FILE * file
, machine_mode
/*mode*/, rtx addr
)
1577 enum cr16_addrtype addrtype
;
1578 struct cr16_address address
;
1580 /* Decompose the address. Also ask it to treat address as constant. */
1581 addrtype
= cr16_decompose_address (addr
, &address
, 0, TRUE
);
1583 if (address
.disp
&& GET_CODE (address
.disp
) == UNSPEC
)
1593 if (GET_CODE (address
.disp
) == UNSPEC
)
1594 cr16_print_operand (file
, address
.disp
, 0);
1596 output_addr_const (file
, address
.disp
);
1599 fprintf (file
, "0");
1600 fprintf (file
, "(%s)", reg_names
[REGNO (address
.base
)]);
1605 output_addr_const (file
, address
.disp
);
1607 fprintf (file
, "0");
1610 case CR16_INDEX_REGP_REL
:
1611 fprintf (file
, "[%s]", reg_names
[REGNO (address
.index
)]);
1616 if (GET_CODE (address
.disp
) == UNSPEC
)
1617 cr16_print_operand (file
, address
.disp
, 0);
1619 output_addr_const (file
, address
.disp
);
1622 fprintf (file
, "0");
1623 fprintf (file
, "(%s,%s)", reg_names
[REGNO (address
.base
) + 1],
1624 reg_names
[REGNO (address
.base
)]);
1630 /* Add qualifiers to the address expression that was just printed. */
1631 if (flag_pic
< NEAR_PIC
&& address
.code
== 0)
1633 if (address
.data
== DM_FAR
)
1634 /* Addr contains SYMBOL_REF & far data ptr. */
1635 fprintf (file
, "@l");
1636 else if (address
.data
== DM_DEFAULT
)
1637 /* Addr contains SYMBOL_REF & medium data ptr. */
1638 fprintf (file
, "@m");
1639 /* Addr contains SYMBOL_REF & medium data ptr. */
1640 else if (address
.data
== DM_NEAR
)
1641 /* Addr contains SYMBOL_REF & near data ptr. */
1642 fprintf (file
, "@s");
1644 else if (flag_pic
== NEAR_PIC
1645 && (address
.code
== 0) && (address
.data
== DM_FAR
1646 || address
.data
== DM_DEFAULT
1647 || address
.data
== DM_NEAR
))
1649 fprintf (file
, "@l");
1651 else if (flag_pic
== NEAR_PIC
&& address
.code
== 2)
1653 fprintf (file
, "pic");
1655 else if (flag_pic
== NEAR_PIC
&& address
.code
== 1)
1657 fprintf (file
, "@cpic");
1660 else if (flag_pic
== FAR_PIC
&& address
.code
== 2)
1662 /* REVISIT: cr16 register indirect jump expects a 1-bit right shifted
1663 address ! GOTc tells assembler this symbol is a text-address
1664 This needs to be fixed in such a way that this offset is done
1665 only in the case where an address is being used for indirect jump
1666 or call. Determining the potential usage of loadd is of course not
1667 possible always. Eventually, this has to be fixed in the
1669 fprintf (file
, "GOT (%s)", reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
1671 else if (flag_pic
== FAR_PIC
&& address
.code
== 1)
1673 fprintf (file
, "@cGOT (%s)", reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
1676 else if (flag_pic
== FAR_PIC
&&
1677 (address
.data
== DM_FAR
|| address
.data
== DM_DEFAULT
1678 || address
.data
== DM_NEAR
))
1680 fprintf (file
, "@GOT (%s)", reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
1684 /* Machine description helper functions. */
1686 /* Called from cr16.md. The return value depends on the parameter push_or_pop:
1687 When push_or_pop is zero -> string for push instructions of prologue.
1688 When push_or_pop is nonzero -> string for pop/popret/retx in epilogue.
1689 Relies on the assumptions:
1690 1. RA is the last register to be saved.
1691 2. The maximal value of the counter is MAX_COUNT. */
1693 cr16_prepare_push_pop_string (int push_or_pop
)
1695 /* j is the number of registers being saved, takes care that there won't be
1696 more than 8 in one push/pop instruction. */
1698 /* For the register mask string. */
1699 static char one_inst_str
[50];
1701 /* i is the index of current_frame_info.save_regs[], going from 0 until
1702 current_frame_info.last_reg_to_save. */
1708 /* For reversing on the push instructions if there are more than one. */
1711 return_str
= (char *) xmalloc (160);
1712 temp_str
= (char *) xmalloc (160);
1715 memset (return_str
, 0, 3);
1718 while (i
<= current_frame_info
.last_reg_to_save
)
1720 /* Prepare mask for one instruction. */
1721 one_inst_str
[0] = 0;
1723 /* To count number of words in one instruction. */
1727 while ((word_cnt
< MAX_COUNT
)
1728 && (i
<= current_frame_info
.last_reg_to_save
))
1730 /* For each non consecutive save register,
1731 a new instruction shall be generated. */
1732 if (!current_frame_info
.save_regs
[i
])
1734 /* Move to next reg and break. */
1739 if (i
== RETURN_ADDRESS_REGNUM
)
1743 /* Check especially if adding 2 does not cross the MAX_COUNT. */
1744 if ((word_cnt
+ ((i
< CR16_FIRST_DWORD_REGISTER
) ? 1 : 2))
1747 /* Increase word count by 2 for long registers except RA. */
1748 word_cnt
+= ((i
< CR16_FIRST_DWORD_REGISTER
) ? 1 : 2);
1753 /* No need to generate any instruction as
1754 no register or RA needs to be saved. */
1755 if ((word_cnt
== 0) && (print_ra
== 0))
1758 /* Now prepare the instruction operands. */
1761 sprintf (one_inst_str
, "$%d, %s", word_cnt
, reg_names
[start_reg
]);
1763 strcat (one_inst_str
, ", ra");
1766 strcat (one_inst_str
, "ra");
1768 if (push_or_pop
== 1)
1770 /* Pop instruction. */
1771 if (print_ra
&& !cr16_interrupt_function_p ()
1772 && !crtl
->calls_eh_return
)
1773 /* Print popret if RA is saved and its not a interrupt
1775 strcpy (temp_str
, "\n\tpopret\t");
1777 strcpy (temp_str
, "\n\tpop\t");
1779 strcat (temp_str
, one_inst_str
);
1781 /* Add the pop instruction list. */
1782 strcat (return_str
, temp_str
);
1786 /* Push instruction. */
1787 strcpy (temp_str
, "\n\tpush\t");
1788 strcat (temp_str
, one_inst_str
);
1790 /* We need to reverse the order of the instructions if there
1791 are more than one. (since the pop will not be reversed in
1793 strcat (temp_str
, return_str
);
1794 strcpy (return_str
, temp_str
);
1798 if (push_or_pop
== 1)
1801 if (cr16_interrupt_function_p ())
1802 strcat (return_str
, "\n\tretx\n");
1803 else if (crtl
->calls_eh_return
)
1805 /* Add stack adjustment before returning to exception handler
1806 NOTE: EH_RETURN_STACKADJ_RTX must refer to (r5, r4). */
1807 strcat (return_str
, "\n\taddd\t (r5, r4), (sp)\t\n");
1808 strcat (return_str
, "\n\tjump\t (ra)\n");
1810 /* But before anything else, undo the adjustment addition done in
1811 cr16_expand_epilogue (). */
1812 strcpy (temp_str
, "\n\tsubd\t (r5, r4), (sp)\t\n");
1813 strcat (temp_str
, return_str
);
1814 strcpy (return_str
, temp_str
);
1816 else if (!FUNC_IS_NORETURN_P (current_function_decl
)
1817 && !(current_frame_info
.save_regs
[RETURN_ADDRESS_REGNUM
]))
1818 strcat (return_str
, "\n\tjump\t (ra)\n");
1821 /* Skip the newline and the tab in the start of return_str. */
1827 /* Generate DWARF2 annotation for multi-push instruction. */
1829 cr16_create_dwarf_for_multi_push (rtx insn
)
1831 rtx dwarf
, reg
, tmp
;
1832 int i
, j
, from
, to
, word_cnt
, dwarf_par_index
, inc
;
1834 int num_regs
= 0, offset
= 0, split_here
= 0, total_push_bytes
= 0;
1836 for (i
= 0; i
<= current_frame_info
.last_reg_to_save
; ++i
)
1838 if (current_frame_info
.save_regs
[i
])
1841 if (i
< CR16_FIRST_DWORD_REGISTER
)
1842 total_push_bytes
+= 2;
1844 total_push_bytes
+= 4;
1851 dwarf
= gen_rtx_SEQUENCE (VOIDmode
, rtvec_alloc (num_regs
+ 1));
1852 dwarf_par_index
= num_regs
;
1854 from
= current_frame_info
.last_reg_to_save
+ 1;
1855 to
= current_frame_info
.last_reg_to_save
;
1858 for (i
= current_frame_info
.last_reg_to_save
; i
>= 0;)
1860 if (!current_frame_info
.save_regs
[i
] || 0 == i
|| split_here
)
1862 /* This block of regs is pushed in one instruction. */
1863 if (0 == i
&& current_frame_info
.save_regs
[i
])
1866 for (j
= to
; j
>= from
; --j
)
1868 if (j
< CR16_FIRST_DWORD_REGISTER
)
1878 reg
= gen_rtx_REG (mode
, j
);
1880 tmp
= gen_rtx_SET (gen_frame_mem (mode
,
1882 (Pmode
, stack_pointer_rtx
,
1883 total_push_bytes
- offset
)),
1885 RTX_FRAME_RELATED_P (tmp
) = 1;
1886 XVECEXP (dwarf
, 0, dwarf_par_index
--) = tmp
;
1895 if (i
!= RETURN_ADDRESS_REGNUM
)
1897 inc
= (i
< CR16_FIRST_DWORD_REGISTER
) ? 1 : 2;
1898 if (word_cnt
+ inc
>= MAX_COUNT
|| FRAME_POINTER_REGNUM
== i
)
1910 tmp
= gen_rtx_SET (stack_pointer_rtx
,
1911 gen_rtx_PLUS (SImode
, stack_pointer_rtx
,
1912 GEN_INT (-offset
)));
1913 RTX_FRAME_RELATED_P (tmp
) = 1;
1914 XVECEXP (dwarf
, 0, 0) = tmp
;
1916 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, dwarf
);
1920 CompactRISC CR16 Architecture stack layout:
1922 0 +---------------------
1927 +==================== Sp (x) = Ap (x+1)
1928 A | Args for functions
1929 | | called by X and Dynamically
1930 | | Dynamic allocations allocated and
1931 | | (alloca, variable deallocated
1932 Stack | length arrays).
1933 grows +-------------------- Fp (x)
1934 down| | Local variables of X
1935 ward| +--------------------
1936 | | Regs saved for X-1
1937 | +==================== Sp (x-1) = Ap (x)
1940 +-------------------- Fp (x-1)
1946 cr16_expand_prologue (void)
1950 cr16_compute_frame ();
1951 cr16_compute_save_regs ();
1953 /* If there is no need in push and adjustment to sp, return. */
1954 if ((current_frame_info
.total_size
+ current_frame_info
.reg_size
) == 0)
1957 if (current_frame_info
.last_reg_to_save
!= -1)
1959 /* If there are registers to push. */
1960 insn
= emit_insn (gen_push_for_prologue
1961 (GEN_INT (current_frame_info
.reg_size
)));
1962 cr16_create_dwarf_for_multi_push (insn
);
1963 RTX_FRAME_RELATED_P (insn
) = 1;
1967 if (current_frame_info
.total_size
> 0)
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;
1974 if (frame_pointer_needed
)
1976 /* Initialize the frame pointer with the value of the stack pointer
1977 pointing now to the locals. */
1978 insn
= emit_move_insn (frame_pointer_rtx
, stack_pointer_rtx
);
1982 /* Generate insn that updates the stack for local variables and padding
1983 for registers we save. - Generate the appropriate return insn. */
1985 cr16_expand_epilogue (void)
1989 /* Nonzero if we need to return and pop only RA. This will generate a
1990 different insn. This differentiate is for the peepholes for call as
1991 last statement in function. */
1992 int only_popret_RA
= (current_frame_info
.save_regs
[RETURN_ADDRESS_REGNUM
]
1993 && (current_frame_info
.reg_size
1994 == CR16_UNITS_PER_DWORD
));
1996 if (frame_pointer_needed
)
1998 /* Restore the stack pointer with the frame pointers value. */
1999 insn
= emit_move_insn (stack_pointer_rtx
, frame_pointer_rtx
);
2002 if (current_frame_info
.total_size
> 0)
2004 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2005 GEN_INT (current_frame_info
.total_size
)));
2006 RTX_FRAME_RELATED_P (insn
) = 1;
2009 if (crtl
->calls_eh_return
)
2011 /* Add this here so that (r5, r4) is actually loaded with the adjustment
2012 value; otherwise, the load might be optimized away...
2013 NOTE: remember to subtract the adjustment before popping the regs
2014 and add it back before returning. */
2015 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2016 EH_RETURN_STACKADJ_RTX
));
2019 if (cr16_interrupt_function_p ())
2021 insn
= emit_jump_insn (gen_interrupt_return ());
2022 RTX_FRAME_RELATED_P (insn
) = 1;
2024 else if (crtl
->calls_eh_return
)
2026 /* Special case, pop what's necessary, adjust SP and jump to (RA). */
2027 insn
= emit_jump_insn (gen_pop_and_popret_return
2028 (GEN_INT (current_frame_info
.reg_size
)));
2029 RTX_FRAME_RELATED_P (insn
) = 1;
2031 else if (current_frame_info
.last_reg_to_save
== -1)
2032 /* Nothing to pop. */
2033 /* Don't output jump for interrupt routine, only retx. */
2034 emit_jump_insn (gen_jump_return ());
2035 else if (only_popret_RA
)
2037 insn
= emit_jump_insn (gen_popret_RA_return ());
2038 RTX_FRAME_RELATED_P (insn
) = 1;
2042 insn
= emit_jump_insn (gen_pop_and_popret_return
2043 (GEN_INT (current_frame_info
.reg_size
)));
2044 RTX_FRAME_RELATED_P (insn
) = 1;
2048 /* Implements FRAME_POINTER_REQUIRED. */
2050 cr16_frame_pointer_required (void)
2052 return (cfun
->calls_alloca
|| crtl
->calls_eh_return
2053 || cfun
->has_nonlocal_label
|| crtl
->calls_eh_return
);
2057 cr16_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
2059 return (to
== STACK_POINTER_REGNUM
? !frame_pointer_needed
: true);
2063 /* A C compound statement that attempts to replace X with
2064 a valid memory address for an operand of mode MODE. WIN
2065 will be a C statement label elsewhere in the code.
2066 X will always be the result of a call to break_out_memory_refs (),
2067 and OLDX will be the operand that was given to that function to
2069 The code generated by this macro should not alter the
2070 substructure of X. If it transforms X into a more legitimate form,
2071 it should assign X (which will always be a C variable) a new value. */
2073 cr16_legitimize_address (rtx x
, rtx orig_x ATTRIBUTE_UNUSED
,
2074 machine_mode mode ATTRIBUTE_UNUSED
)
2077 return legitimize_pic_address (orig_x
, mode
, NULL_RTX
);
2082 /* Implement TARGET_LEGITIMATE_CONSTANT_P
2083 Nonzero if X is a legitimate constant for an immediate
2084 operand on the target machine. You can assume that X
2085 satisfies CONSTANT_P. In cr16c treat legitimize float
2086 constant as an immediate operand. */
2088 cr16_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
,
2089 rtx x ATTRIBUTE_UNUSED
)
2095 notice_update_cc (rtx exp
)
2097 if (GET_CODE (exp
) == SET
)
2099 /* Jumps do not alter the cc's. */
2100 if (SET_DEST (exp
) == pc_rtx
)
2103 /* Moving register or memory into a register:
2104 it doesn't alter the cc's, but it might invalidate
2105 the RTX's which we remember the cc's came from.
2106 (Note that moving a constant 0 or 1 MAY set the cc's). */
2107 if (REG_P (SET_DEST (exp
))
2108 && (REG_P (SET_SRC (exp
)) || GET_CODE (SET_SRC (exp
)) == MEM
))
2113 /* Moving register into memory doesn't alter the cc's.
2114 It may invalidate the RTX's which we remember the cc's came from. */
2115 if (GET_CODE (SET_DEST (exp
)) == MEM
&& REG_P (SET_SRC (exp
)))
2125 static scalar_int_mode
2126 cr16_unwind_word_mode (void)
2131 /* Helper function for md file. This function is used to emit arithmetic
2132 DI instructions. The argument "num" decides which instruction to be
2135 cr16_emit_add_sub_di (rtx
*operands
, enum rtx_code code
)
2141 lo_op
[0] = gen_lowpart (SImode
, operands
[0]);
2142 hi0_op
[0] = simplify_gen_subreg (HImode
, operands
[0], DImode
, 4);
2143 hi1_op
[0] = simplify_gen_subreg (HImode
, operands
[0], DImode
, 6);
2145 lo_op
[1] = gen_lowpart (SImode
, operands
[2]);
2146 hi0_op
[1] = simplify_gen_subreg (HImode
, operands
[2], DImode
, 4);
2147 hi1_op
[1] = simplify_gen_subreg (HImode
, operands
[2], DImode
, 6);
2153 output_asm_insn ("addd\t%1, %0", lo_op
) ;
2154 output_asm_insn ("addcw\t%1, %0", hi0_op
) ;
2155 output_asm_insn ("addcw\t%1, %0", hi1_op
) ;
2160 output_asm_insn ("subd\t%1, %0", lo_op
) ;
2161 output_asm_insn ("subcw\t%1, %0", hi0_op
) ;
2162 output_asm_insn ("subcw\t%1, %0", hi1_op
) ;
2173 /* Helper function for md file. This function is used to emit logical
2174 DI instructions. The argument "num" decides which instruction to be
2177 cr16_emit_logical_di (rtx
*operands
, enum rtx_code code
)
2182 lo_op
[0] = gen_lowpart (SImode
, operands
[0]);
2183 hi_op
[0] = simplify_gen_subreg (SImode
, operands
[0], DImode
, 4);
2185 lo_op
[1] = gen_lowpart (SImode
, operands
[2]);
2186 hi_op
[1] = simplify_gen_subreg (SImode
, operands
[2], DImode
, 4);
2192 output_asm_insn ("andd\t%1, %0", lo_op
) ;
2193 output_asm_insn ("andd\t%1, %0", hi_op
) ;
2198 output_asm_insn ("ord\t%1, %0", lo_op
) ;
2199 output_asm_insn ("ord\t%1, %0", hi_op
) ;
2204 output_asm_insn ("xord\t%1, %0", lo_op
) ;
2205 output_asm_insn ("xord\t%1, %0", hi_op
) ;
2215 /* Initialize 'targetm' variable which contains pointers to functions
2216 and data relating to the target machine. */
2218 struct gcc_target targetm
= TARGET_INITIALIZER
;