1 /* Output routines for CR16 processor.
2 Copyright (C) 2012-2015 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"
30 #include "fold-const.h"
31 #include "stor-layout.h"
35 #include "insn-config.h"
36 #include "conditions.h"
38 #include "insn-codes.h"
39 #include "insn-attr.h"
51 #include "diagnostic-core.h"
56 #include "cfgcleanup.h"
60 /* This file should be included last. */
61 #include "target-def.h"
65 /* Maximum number of register used for passing parameters. */
66 #define MAX_REG_FOR_PASSING_ARGS 6
68 /* Minimum number register used for passing parameters. */
69 #define MIN_REG_FOR_PASSING_ARGS 2
71 /* The maximum count of words supported in the assembly of the architecture in
72 a push/pop instruction. */
75 /* Predicate is true if the current function is a 'noreturn' function,
76 i.e. it is qualified as volatile. */
77 #define FUNC_IS_NORETURN_P(decl) (TREE_THIS_VOLATILE (decl))
79 /* Predicate that holds when we need to save registers even for 'noreturn'
80 functions, to accommodate for unwinding. */
81 #define MUST_SAVE_REGS_P() \
82 (flag_unwind_tables || (flag_exceptions && !UI_SJLJ))
84 /* Nonzero if the rtx X is a signed const int of n bits. */
85 #define RTX_SIGNED_INT_FITS_N_BITS(X, n) \
86 ((GET_CODE (X) == CONST_INT \
87 && SIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
89 /* Nonzero if the rtx X is an unsigned const int of n bits. */
90 #define RTX_UNSIGNED_INT_FITS_N_BITS(X, n) \
91 ((GET_CODE (X) == CONST_INT \
92 && UNSIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
94 /* Structure for stack computations. */
96 /* variable definitions in the struture
97 args_size Number of bytes saved on the stack for local
100 reg_size Number of bytes saved on the stack for
101 non-scratch registers
103 total_size The sum of 2 sizes: locals vars and padding byte
104 for saving the registers. Used in expand_prologue()
105 and expand_epilogue()
107 last_reg_to_save Will hold the number of the last register the
108 prologue saves, -1 if no register is saved
110 save_regs[16] Each object in the array is a register number.
111 Mark 1 for registers that need to be saved
113 num_regs Number of registers saved
115 initialized Non-zero if frame size already calculated, not
118 function_makes_calls Does the function make calls ? not used yet. */
120 struct cr16_frame_info
122 unsigned long var_size
;
123 unsigned long args_size
;
124 unsigned int reg_size
;
125 unsigned long total_size
;
126 long last_reg_to_save
;
127 long save_regs
[FIRST_PSEUDO_REGISTER
];
130 int function_makes_calls
;
133 /* Current frame information calculated by cr16_compute_frame_size. */
134 static struct cr16_frame_info current_frame_info
;
136 /* Static Variables. */
138 /* Data model that was supplied by user via command line option
139 This will be overridden in case of invalid combination
140 of core and data model options are supplied. */
141 static enum data_model_type data_model
= DM_DEFAULT
;
143 /* TARGETM Function Prototypes and forward declarations */
144 static void cr16_print_operand (FILE *, rtx
, int);
145 static void cr16_print_operand_address (FILE *, rtx
);
147 /* Stack layout and calling conventions. */
148 #undef TARGET_STRUCT_VALUE_RTX
149 #define TARGET_STRUCT_VALUE_RTX cr16_struct_value_rtx
150 #undef TARGET_RETURN_IN_MEMORY
151 #define TARGET_RETURN_IN_MEMORY cr16_return_in_memory
153 /* Target-specific uses of '__attribute__'. */
154 #undef TARGET_ATTRIBUTE_TABLE
155 #define TARGET_ATTRIBUTE_TABLE cr16_attribute_table
156 #undef TARGET_NARROW_VOLATILE_BITFIELD
157 #define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false
160 #undef TARGET_UNWIND_WORD_MODE
161 #define TARGET_UNWIND_WORD_MODE cr16_unwind_word_mode
163 /* Override Options. */
164 #undef TARGET_OPTION_OVERRIDE
165 #define TARGET_OPTION_OVERRIDE cr16_override_options
167 /* Conditional register usuage. */
168 #undef TARGET_CONDITIONAL_REGISTER_USAGE
169 #define TARGET_CONDITIONAL_REGISTER_USAGE cr16_conditional_register_usage
171 /* Controlling register spills. */
172 #undef TARGET_CLASS_LIKELY_SPILLED_P
173 #define TARGET_CLASS_LIKELY_SPILLED_P cr16_class_likely_spilled_p
175 /* Passing function arguments. */
176 #undef TARGET_FUNCTION_ARG
177 #define TARGET_FUNCTION_ARG cr16_function_arg
178 #undef TARGET_FUNCTION_ARG_ADVANCE
179 #define TARGET_FUNCTION_ARG_ADVANCE cr16_function_arg_advance
180 #undef TARGET_RETURN_POPS_ARGS
181 #define TARGET_RETURN_POPS_ARGS cr16_return_pops_args
183 /* Initialize the GCC target structure. */
184 #undef TARGET_FRAME_POINTER_REQUIRED
185 #define TARGET_FRAME_POINTER_REQUIRED cr16_frame_pointer_required
186 #undef TARGET_CAN_ELIMINATE
187 #define TARGET_CAN_ELIMINATE cr16_can_eliminate
188 #undef TARGET_LEGITIMIZE_ADDRESS
189 #define TARGET_LEGITIMIZE_ADDRESS cr16_legitimize_address
190 #undef TARGET_LEGITIMATE_CONSTANT_P
191 #define TARGET_LEGITIMATE_CONSTANT_P cr16_legitimate_constant_p
192 #undef TARGET_LEGITIMATE_ADDRESS_P
193 #define TARGET_LEGITIMATE_ADDRESS_P cr16_legitimate_address_p
195 /* Returning function value. */
196 #undef TARGET_FUNCTION_VALUE
197 #define TARGET_FUNCTION_VALUE cr16_function_value
198 #undef TARGET_LIBCALL_VALUE
199 #define TARGET_LIBCALL_VALUE cr16_libcall_value
200 #undef TARGET_FUNCTION_VALUE_REGNO_P
201 #define TARGET_FUNCTION_VALUE_REGNO_P cr16_function_value_regno_p
203 /* printing the values. */
204 #undef TARGET_PRINT_OPERAND
205 #define TARGET_PRINT_OPERAND cr16_print_operand
206 #undef TARGET_PRINT_OPERAND_ADDRESS
207 #define TARGET_PRINT_OPERAND_ADDRESS cr16_print_operand_address
209 /* Relative costs of operations. */
210 #undef TARGET_ADDRESS_COST
211 #define TARGET_ADDRESS_COST cr16_address_cost
212 #undef TARGET_REGISTER_MOVE_COST
213 #define TARGET_REGISTER_MOVE_COST cr16_register_move_cost
214 #undef TARGET_MEMORY_MOVE_COST
215 #define TARGET_MEMORY_MOVE_COST cr16_memory_move_cost
217 /* Table of machine attributes. */
218 static const struct attribute_spec cr16_attribute_table
[] = {
219 /* ISRs have special prologue and epilogue requirements. */
220 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
221 affects_type_identity }. */
222 {"interrupt", 0, 0, false, true, true, NULL
, false},
223 {NULL
, 0, 0, false, false, false, NULL
, false}
226 /* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive
227 .?byte directive along with @c is not understood by assembler.
228 Therefore, make all TARGET_ASM_UNALIGNED_xx_OP same
229 as TARGET_ASM_ALIGNED_xx_OP. */
230 #undef TARGET_ASM_UNALIGNED_HI_OP
231 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
232 #undef TARGET_ASM_UNALIGNED_SI_OP
233 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
234 #undef TARGET_ASM_UNALIGNED_DI_OP
235 #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
237 /* Target hook implementations. */
239 /* Implements hook TARGET_RETURN_IN_MEMORY. */
241 cr16_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
243 const HOST_WIDE_INT size
= int_size_in_bytes (type
);
244 return ((size
== -1) || (size
> 8));
247 /* Implement TARGET_CLASS_LIKELY_SPILLED_P. */
249 cr16_class_likely_spilled_p (reg_class_t rclass
)
251 if ((rclass
) == SHORT_REGS
|| (rclass
) == DOUBLE_BASE_REGS
252 || (rclass
) == LONG_REGS
|| (rclass
) == GENERAL_REGS
)
259 cr16_return_pops_args (tree fundecl ATTRIBUTE_UNUSED
,
260 tree funtype ATTRIBUTE_UNUSED
,
261 int size ATTRIBUTE_UNUSED
)
266 /* Returns true if data model selected via command line option
267 is same as function argument. */
269 cr16_is_data_model (enum data_model_type model
)
271 return (model
== data_model
);
274 /* Parse relevant options and override. */
276 cr16_override_options (void)
278 /* Disable -fdelete-null-pointer-checks option for CR16 target.
279 Programs which rely on NULL pointer dereferences _not_ halting the
280 program may not work properly with this option. So disable this
282 flag_delete_null_pointer_checks
= 0;
284 /* FIXME: To avoid spill_failure ICE during exception handling,
285 * disable cse_fllow_jumps. The spill error occurs when compiler
286 * can't find a suitable candidate in GENERAL_REGS class to reload
288 * Need to find a better way of avoiding this situation. */
290 flag_cse_follow_jumps
= 0;
292 /* If -fpic option, data_model == DM_FAR. */
293 if (flag_pic
== NEAR_PIC
)
298 /* The only option we want to examine is data model option. */
301 if (strcmp (cr16_data_model
, "medium") == 0)
302 data_model
= DM_DEFAULT
;
303 else if (strcmp (cr16_data_model
, "near") == 0)
304 data_model
= DM_NEAR
;
305 else if (strcmp (cr16_data_model
, "far") == 0)
310 error ("data-model=far not valid for cr16c architecture");
313 error ("invalid data model option -mdata-model=%s", cr16_data_model
);
316 data_model
= DM_DEFAULT
;
319 /* Implements the macro TARGET_CONDITIONAL_REGISTER_USAGE. */
321 cr16_conditional_register_usage (void)
325 fixed_regs
[12] = call_used_regs
[12] = 1;
329 /* Stack layout and calling conventions routines. */
331 /* Return nonzero if the current function being compiled is an interrupt
332 function as specified by the "interrupt" attribute. */
334 cr16_interrupt_function_p (void)
338 attributes
= TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl
));
339 return (lookup_attribute ("interrupt", attributes
) != NULL_TREE
);
342 /* Compute values for the array current_frame_info.save_regs and the variable
343 current_frame_info.reg_size. The index of current_frame_info.save_regs
344 is numbers of register, each will get 1 if we need to save it in the
345 current function, 0 if not. current_frame_info.reg_size is the total sum
346 of the registers being saved. */
348 cr16_compute_save_regs (void)
352 /* Initialize here so in case the function is no-return it will be -1. */
353 current_frame_info
.last_reg_to_save
= -1;
355 /* Initialize the number of bytes to be saved. */
356 current_frame_info
.reg_size
= 0;
358 /* No need to save any registers if the function never returns. */
359 if (FUNC_IS_NORETURN_P (current_function_decl
) && !MUST_SAVE_REGS_P ())
362 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
364 if (fixed_regs
[regno
])
366 current_frame_info
.save_regs
[regno
] = 0;
370 /* If this reg is used and not call-used (except RA), save it. */
371 if (cr16_interrupt_function_p ())
373 if (!crtl
->is_leaf
&& call_used_regs
[regno
])
374 /* This is a volatile reg in a non-leaf interrupt routine - save
375 it for the sake of its sons. */
376 current_frame_info
.save_regs
[regno
] = 1;
377 else if (df_regs_ever_live_p (regno
))
378 /* This reg is used - save it. */
379 current_frame_info
.save_regs
[regno
] = 1;
381 /* This reg is not used, and is not a volatile - don't save. */
382 current_frame_info
.save_regs
[regno
] = 0;
386 /* If this reg is used and not call-used (except RA), save it. */
387 if (df_regs_ever_live_p (regno
)
388 && (!call_used_regs
[regno
] || regno
== RETURN_ADDRESS_REGNUM
))
389 current_frame_info
.save_regs
[regno
] = 1;
391 current_frame_info
.save_regs
[regno
] = 0;
395 /* Save registers so the exception handler can modify them. */
396 if (crtl
->calls_eh_return
)
402 regno
= EH_RETURN_DATA_REGNO (i
);
403 if (INVALID_REGNUM
== regno
)
405 current_frame_info
.save_regs
[regno
] = 1;
409 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
410 if (current_frame_info
.save_regs
[regno
] == 1)
412 current_frame_info
.last_reg_to_save
= regno
;
413 if (regno
>= CR16_FIRST_DWORD_REGISTER
)
414 current_frame_info
.reg_size
+= CR16_UNITS_PER_DWORD
;
416 current_frame_info
.reg_size
+= UNITS_PER_WORD
;
420 /* Compute the size of the local area and the size to be adjusted by the
421 prologue and epilogue. */
423 cr16_compute_frame (void)
425 /* For aligning the local variables. */
426 int stack_alignment
= STACK_BOUNDARY
/ BITS_PER_UNIT
;
429 /* Padding needed for each element of the frame. */
430 current_frame_info
.var_size
= get_frame_size ();
432 /* Align to the stack alignment. */
433 padding_locals
= current_frame_info
.var_size
% stack_alignment
;
435 padding_locals
= stack_alignment
- padding_locals
;
437 current_frame_info
.var_size
+= padding_locals
;
438 current_frame_info
.total_size
= current_frame_info
.var_size
439 + (ACCUMULATE_OUTGOING_ARGS
440 ? crtl
->outgoing_args_size
: 0);
443 /* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */
445 cr16_initial_elimination_offset (int from
, int to
)
447 /* Compute this since we need to use current_frame_info.reg_size. */
448 cr16_compute_save_regs ();
450 /* Compute this since we need to use current_frame_info.var_size. */
451 cr16_compute_frame ();
453 if (((from
) == FRAME_POINTER_REGNUM
) && ((to
) == STACK_POINTER_REGNUM
))
454 return (ACCUMULATE_OUTGOING_ARGS
? crtl
->outgoing_args_size
: 0);
455 else if (((from
) == ARG_POINTER_REGNUM
) && ((to
) == FRAME_POINTER_REGNUM
))
456 return (current_frame_info
.reg_size
+ current_frame_info
.var_size
);
457 else if (((from
) == ARG_POINTER_REGNUM
) && ((to
) == STACK_POINTER_REGNUM
))
458 return (current_frame_info
.reg_size
+ current_frame_info
.var_size
459 + (ACCUMULATE_OUTGOING_ARGS
? crtl
->outgoing_args_size
: 0));
464 /* Register Usage. */
466 /* Return the class number of the smallest class containing reg number REGNO.
467 This could be a conditional expression or could index an array. */
469 cr16_regno_reg_class (int regno
)
471 if ((regno
>= 0) && (regno
< CR16_FIRST_DWORD_REGISTER
))
474 if ((regno
>= CR16_FIRST_DWORD_REGISTER
) && (regno
< FIRST_PSEUDO_REGISTER
))
480 /* Return 1 if hard register REGNO can hold a value of machine-mode MODE. */
482 cr16_hard_regno_mode_ok (int regno
, machine_mode mode
)
484 if ((GET_MODE_SIZE (mode
) >= 4) && (regno
== 11))
487 if (mode
== DImode
|| mode
== DFmode
)
489 if ((regno
> 8) || (regno
& 1))
495 && ((regno
>= 12) && (GET_MODE_SIZE (mode
) < 4 )))
498 /* CC can only hold CCmode values. */
499 if (GET_MODE_CLASS (mode
) == MODE_CC
)
504 /* Returns register number for function return value.*/
505 static inline unsigned int
506 cr16_ret_register (void)
511 /* Implements hook TARGET_STRUCT_VALUE_RTX. */
513 cr16_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED
,
514 int incoming ATTRIBUTE_UNUSED
)
516 return gen_rtx_REG (Pmode
, cr16_ret_register ());
519 /* Returning function value. */
521 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P. */
523 cr16_function_value_regno_p (const unsigned int regno
)
525 return (regno
== cr16_ret_register ());
528 /* Create an RTX representing the place where a
529 library function returns a value of mode MODE. */
531 cr16_libcall_value (machine_mode mode
,
532 const_rtx func ATTRIBUTE_UNUSED
)
534 return gen_rtx_REG (mode
, cr16_ret_register ());
537 /* Create an RTX representing the place where a
538 function returns a value of data type VALTYPE. */
540 cr16_function_value (const_tree type
,
541 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
542 bool outgoing ATTRIBUTE_UNUSED
)
544 return gen_rtx_REG (TYPE_MODE (type
), cr16_ret_register ());
547 /* Passing function arguments. */
549 /* If enough param regs are available for passing the param of type TYPE return
550 the number of registers needed else 0. */
552 enough_regs_for_param (CUMULATIVE_ARGS
* cum
, const_tree type
,
559 type_size
= GET_MODE_BITSIZE (mode
);
561 type_size
= int_size_in_bytes (type
) * BITS_PER_UNIT
;
563 remaining_size
= BITS_PER_WORD
* (MAX_REG_FOR_PASSING_ARGS
564 - (MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
) +
567 /* Any variable which is too big to pass in two registers, will pass on
569 if ((remaining_size
>= type_size
) && (type_size
<= 2 * BITS_PER_WORD
))
570 return (type_size
+ BITS_PER_WORD
- 1) / BITS_PER_WORD
;
575 /* Implements the macro FUNCTION_ARG defined in cr16.h. */
577 cr16_function_arg (cumulative_args_t cum_v
, machine_mode mode
,
578 const_tree type
, bool named ATTRIBUTE_UNUSED
)
580 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
581 cum
->last_parm_in_reg
= 0;
583 /* function_arg () is called with this type just after all the args have
584 had their registers assigned. The rtx that function_arg returns from
585 this type is supposed to pass to 'gen_call' but currently it is not
587 if (type
== void_type_node
)
590 if (targetm
.calls
.must_pass_in_stack (mode
, type
) || (cum
->ints
< 0))
595 /* Enable structures that need padding bytes at the end to pass to a
596 function in registers. */
597 if (enough_regs_for_param (cum
, type
, mode
) != 0)
599 cum
->last_parm_in_reg
= 1;
600 return gen_rtx_REG (mode
, MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
);
604 if ((MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
) > MAX_REG_FOR_PASSING_ARGS
)
608 if (enough_regs_for_param (cum
, type
, mode
) != 0)
610 cum
->last_parm_in_reg
= 1;
611 return gen_rtx_REG (mode
, MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
);
618 /* Implements the macro INIT_CUMULATIVE_ARGS defined in cr16.h. */
620 cr16_init_cumulative_args (CUMULATIVE_ARGS
* cum
, tree fntype
,
621 rtx libfunc ATTRIBUTE_UNUSED
)
623 tree param
, next_param
;
627 /* Determine if this function has variable arguments. This is indicated by
628 the last argument being 'void_type_mode' if there are no variable
629 arguments. Change here for a different vararg. */
630 for (param
= (fntype
) ? TYPE_ARG_TYPES (fntype
) : 0;
631 param
!= NULL_TREE
; param
= next_param
)
633 next_param
= TREE_CHAIN (param
);
634 if ((next_param
== NULL_TREE
) && (TREE_VALUE (param
) != void_type_node
))
642 /* Implements the macro FUNCTION_ARG_ADVANCE defined in cr16.h. */
644 cr16_function_arg_advance (cumulative_args_t cum_v
, machine_mode mode
,
645 const_tree type
, bool named ATTRIBUTE_UNUSED
)
647 CUMULATIVE_ARGS
* cum
= get_cumulative_args (cum_v
);
649 /* l holds the number of registers required. */
650 int l
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
652 /* If the parameter isn't passed on a register don't advance cum. */
653 if (!cum
->last_parm_in_reg
)
656 if (targetm
.calls
.must_pass_in_stack (mode
, type
) || (cum
->ints
< 0))
659 if ((mode
== SImode
) || (mode
== HImode
)
660 || (mode
== QImode
) || (mode
== DImode
))
667 else if ((mode
== SFmode
) || (mode
== DFmode
))
669 else if ((mode
) == BLKmode
)
671 if ((l
= enough_regs_for_param (cum
, type
, mode
)) != 0)
677 /* Implements the macro FUNCTION_ARG_REGNO_P defined in cr16.h.
678 Return nonzero if N is a register used for passing parameters. */
680 cr16_function_arg_regno_p (int n
)
682 return ((n
<= MAX_REG_FOR_PASSING_ARGS
) && (n
>= MIN_REG_FOR_PASSING_ARGS
));
686 Following set of function implement the macro GO_IF_LEGITIMATE_ADDRESS
687 defined in cr16.h. */
689 /* Helper function to check if is a valid base register that can
692 cr16_addr_reg_p (rtx addr_reg
)
696 if (REG_P (addr_reg
))
698 else if ((GET_CODE (addr_reg
) == SUBREG
)
699 && REG_P (SUBREG_REG (addr_reg
))
700 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg
)))
702 reg
= SUBREG_REG (addr_reg
);
706 if (GET_MODE (reg
) != Pmode
)
712 /* Helper functions: Created specifically for decomposing operand of CONST
713 Recursively look into expression x for code or data symbol.
714 The function expects the expression to contain combination of
715 SYMBOL_REF, CONST_INT, (PLUS or MINUS)
716 LABEL_REF, CONST_INT, (PLUS or MINUS)
719 All other combinations will result in code = -1 and data = ILLEGAL_DM
721 -1 ILLEGAL_DM The expression did not contain SYMBOL_REF or LABEL_REF
722 0 DM_FAR SYMBOL_REF was found and it was far data reference.
723 0 DM_DEFAULT SYMBOL_REF was found and it was medium data reference.
724 1 ILLEGAL_DM LABEL_REF was found.
725 2 ILLEGAL_DM SYMBOL_REF was found and it was function reference. */
727 cr16_decompose_const (rtx x
, int *code
, enum data_model_type
*data
,
732 switch (GET_CODE (x
))
735 *code
= SYMBOL_REF_FUNCTION_P (x
) ? 2 : 0;
736 /* 2 indicates func sym. */
739 if (CR16_TARGET_DATA_NEAR
)
741 else if (CR16_TARGET_DATA_MEDIUM
)
743 else if (CR16_TARGET_DATA_FAR
)
746 /* This will be used only for printing
747 the qualifier. This call is (may be)
748 made by cr16_print_operand_address. */
751 /* This call is (may be) made by
752 cr16_legitimate_address_p. */
759 /* 1 - indicates non-function symbol. */
765 /* Look into the tree nodes. */
766 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
767 cr16_decompose_const (XEXP (x
, 1), code
, data
, treat_as_const
);
768 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
769 cr16_decompose_const (XEXP (x
, 0), code
, data
, treat_as_const
);
777 This function decomposes the address returns the type of address
778 as defined in enum cr16_addrtype. It also fills the parameter *out.
779 The decomposed address can be used for two purposes. One to
780 check if the address is valid and second to print the address
783 Following tables list valid address supported in CR16C/C+ architectures.
785 aN : Absoulte address N-bit address
786 R : One 16-bit register
787 RP : Consecutive two 16-bit registers or one 32-bit register
788 I : One 32-bit register
789 dispN : Signed displacement of N-bits
791 ----Code addresses----
793 disp9 : CR16_ABSOLUTE (disp)
794 disp17 : CR16_ABSOLUTE (disp)
795 disp25 : CR16_ABSOLUTE (disp)
796 RP + disp25 : CR16_REGP_REL (base, disp)
799 RP : CR16_REGP_REL (base, disp=0)
800 a24 : CR16_ABSOLUTE (disp)
802 ----Data addresses----
803 a20 : CR16_ABSOLUTE (disp) near (1M)
804 a24 : CR16_ABSOLUTE (disp) medium (16M)
805 R + d20 : CR16_REG_REL (base, disp) near (1M+64K)
806 RP + d4 : CR16_REGP_REL (base, disp) far (4G)
807 RP + d16 : CR16_REGP_REL (base, disp) far (4G)
808 RP + d20 : CR16_REGP_REL (base, disp) far (4G)
809 I : *** Valid but port does not support this
810 I + a20 : *** Valid but port does not support this
811 I + RP + d14: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
812 I + RP + d20: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
814 Decomposing Data model in case of absolute address.
816 Target Option Address type Resultant Data ref type
817 ---------------------- ------------ -----------------------
818 CR16_TARGET_MODEL_NEAR ABS20 DM_DEFAULT
819 CR16_TARGET_MODEL_NEAR IMM20 DM_DEFAULT
820 CR16_TARGET_MODEL_NEAR ABS24 Invalid
821 CR16_TARGET_MODEL_NEAR IMM32 Invalid
823 CR16_TARGET_MODEL_MEDIUM ABS20 DM_DEFAULT
824 CR16_TARGET_MODEL_MEDIUM IMM20 DM_DEFAULT
825 CR16_TARGET_MODEL_MEDIUM ABS24 DM_FAR
826 CR16_TARGET_MODEL_MEDIUM IMM32 Invalid
828 CR16_TARGET_MODEL_FAR ABS20 DM_DEFAULT
829 CR16_TARGET_MODEL_FAR IMM20 DM_DEFAULT
830 CR16_TARGET_MODEL_FAR ABS24 DM_FAR
831 CR16_TARGET_MODEL_FAR IMM32 DM_FAR. */
833 cr16_decompose_address (rtx addr
, struct cr16_address
*out
,
834 bool debug_print
, bool treat_as_const
)
836 rtx base
= NULL_RTX
, disp
= NULL_RTX
, index
= NULL_RTX
;
837 enum data_model_type data
= ILLEGAL_DM
;
839 enum cr16_addrtype retval
= CR16_INVALID
;
841 switch (GET_CODE (addr
))
844 /* Absolute address (known at compile time). */
847 fprintf (stderr
, "\ncode:%d", code
);
852 fprintf (stderr
, "\ndisp:");
856 if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 20))
860 fprintf (stderr
, "\ndata:%d", data
);
861 retval
= CR16_ABSOLUTE
;
863 else if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 24))
865 if (!CR16_TARGET_DATA_NEAR
)
869 fprintf (stderr
, "\ndata:%d", data
);
870 retval
= CR16_ABSOLUTE
;
873 return CR16_INVALID
; /* ABS24 is not support in NEAR model. */
880 /* A CONST is an expression of PLUS or MINUS with
881 CONST_INT, SYMBOL_REF or LABEL_REF. This is the
882 result of assembly-time arithmetic computation. */
883 retval
= CR16_ABSOLUTE
;
885 /* Call the helper function to check the validity. */
886 cr16_decompose_const (XEXP (addr
, 0), &code
, &data
, treat_as_const
);
887 if ((code
== 0) && (data
== ILLEGAL_DM
))
888 /* CONST is not valid code or data address. */
892 fprintf (stderr
, "\ndisp:");
894 fprintf (stderr
, "\ncode:%d", code
);
895 fprintf (stderr
, "\ndata:%d", data
);
900 retval
= CR16_ABSOLUTE
;
902 /* 1 - indicates non-function symbol. */
906 fprintf (stderr
, "\ndisp:");
908 fprintf (stderr
, "\ncode:%d", code
);
913 /* Absolute address (known at link time). */
914 retval
= CR16_ABSOLUTE
;
916 /* This is a code address if symbol_ref is a function. */
917 /* 2 indicates func sym. */
918 code
= SYMBOL_REF_FUNCTION_P (addr
) ? 2 : 0;
921 fprintf (stderr
, "\ndisp:");
923 fprintf (stderr
, "\ncode:%d", code
);
925 /* If not function ref then check if valid data ref. */
928 if (CR16_TARGET_DATA_NEAR
)
930 else if (CR16_TARGET_DATA_MEDIUM
)
932 else if (CR16_TARGET_DATA_FAR
)
935 /* This will be used only for printing the
936 qualifier. This call is (may be) made
937 by cr16_print_operand_address. */
940 /* This call is (may be) made by
941 cr16_legitimate_address_p. */
948 fprintf (stderr
, "\ndata:%d", data
);
953 /* Register relative address. */
954 /* Assume REG fits in a single register. */
955 retval
= CR16_REG_REL
;
956 if (GET_MODE_BITSIZE (GET_MODE (addr
)) > BITS_PER_WORD
)
957 if (!LONG_REG_P (REGNO (addr
)))
958 /* REG will result in reg pair. */
959 retval
= CR16_REGP_REL
;
963 fprintf (stderr
, "\nbase:");
969 switch (GET_CODE (XEXP (addr
, 0)))
974 /* All Reg relative addresses having a displacement needs
975 to fit in 20-bits. */
976 disp
= XEXP (addr
, 1);
979 fprintf (stderr
, "\ndisp:");
982 switch (GET_CODE (XEXP (addr
, 1)))
985 /* Shall fit in 20-bits. */
986 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 20))
990 fprintf (stderr
, "\ncode:%d", code
);
994 switch (XINT (XEXP (addr
, 1), 1))
996 case UNSPEC_LIBRARY_OFFSET
:
1005 /* This is also a valid expression for address.
1006 However, we cannot ascertain if the resultant
1007 displacement will be valid 20-bit value. Therefore,
1008 lets not allow such an expression for now. This will
1009 be updated when we find a way to validate this
1010 expression as legitimate address.
1011 Till then fall through CR16_INVALID. */
1013 return CR16_INVALID
;
1016 /* Now check if REG can fit into single or pair regs. */
1017 retval
= CR16_REG_REL
;
1018 base
= XEXP (addr
, 0);
1021 fprintf (stderr
, "\nbase:");
1024 if (GET_MODE_BITSIZE (GET_MODE ((XEXP (addr
, 0)))) > BITS_PER_WORD
)
1026 if (!LONG_REG_P (REGNO ((XEXP (addr
, 0)))))
1027 /* REG will result in reg pair. */
1028 retval
= CR16_REGP_REL
;
1042 Check if the operand 1 is valid index register. */
1045 fprintf (stderr
, "\ndata:%d", data
);
1046 switch (GET_CODE (XEXP (addr
, 1)))
1050 if (!REG_OK_FOR_INDEX_P (XEXP (addr
, 1)))
1051 return CR16_INVALID
;
1052 /* OK. REG is a valid index register. */
1053 index
= XEXP (addr
, 1);
1056 fprintf (stderr
, "\nindex:");
1061 return CR16_INVALID
;
1063 /* Check if operand 0 of operand 0 is REGP. */
1064 switch (GET_CODE (XEXP (XEXP (addr
, 0), 0)))
1068 /* Now check if REG is a REGP and not in LONG regs. */
1069 if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (addr
, 0), 0)))
1072 if (REGNO (XEXP (XEXP (addr
, 0), 0))
1073 >= CR16_FIRST_DWORD_REGISTER
)
1074 return CR16_INVALID
;
1075 base
= XEXP (XEXP (addr
, 0), 0);
1078 fprintf (stderr
, "\nbase:");
1083 return CR16_INVALID
;
1086 return CR16_INVALID
;
1088 /* Now check if the operand 1 of operand 0 is const_int. */
1089 if (GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
1091 disp
= XEXP (XEXP (addr
, 0), 1);
1094 fprintf (stderr
, "\ndisp:");
1097 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 20))
1098 return CR16_INVALID
;
1101 return CR16_INVALID
;
1102 retval
= CR16_INDEX_REGP_REL
;
1105 return CR16_INVALID
;
1110 return CR16_INVALID
;
1113 /* Check if the base and index registers are valid. */
1114 if (base
&& !(cr16_addr_reg_p (base
)))
1115 return CR16_INVALID
;
1116 if (base
&& !(CR16_REG_OK_FOR_BASE_P (base
)))
1117 return CR16_INVALID
;
1118 if (index
&& !(REG_OK_FOR_INDEX_P (index
)))
1119 return CR16_INVALID
;
1121 /* Write the decomposition to out parameter. */
1131 /* Return non-zero value if 'x' is legitimate PIC operand
1132 when generating PIC code. */
1134 legitimate_pic_operand_p (rtx x
)
1136 switch (GET_CODE (x
))
1145 /* REVISIT: Use something like symbol_referenced_p. */
1146 if (GET_CODE (XEXP (x
, 0)) == PLUS
1147 && (GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
1148 || GET_CODE (XEXP (XEXP (x
, 0), 0)) == LABEL_REF
)
1149 && (GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
))
1153 return legitimate_pic_operand_p (XEXP (x
, 0));
1161 /* Convert a non-PIC address in `orig' to a PIC address in `reg'.
1163 Input Output (-f pic) Output (-f PIC)
1166 C1 symbol symbol@BRO (r12) symbol@GOT (r12)
1168 C2 symbol + offset symbol+offset@BRO (r12) symbol+offset@GOT (r12)
1170 NOTE: @BRO is added using unspec:BRO
1171 NOTE: @GOT is added using unspec:GOT. */
1173 legitimize_pic_address (rtx orig
, machine_mode mode ATTRIBUTE_UNUSED
,
1176 /* First handle a simple SYMBOL_REF or LABEL_REF. */
1177 if (GET_CODE (orig
) == SYMBOL_REF
|| GET_CODE (orig
) == LABEL_REF
)
1180 reg
= gen_reg_rtx (Pmode
);
1182 if (flag_pic
== NEAR_PIC
)
1184 /* Unspec to handle -fpic option. */
1185 emit_insn (gen_unspec_bro_addr (reg
, orig
));
1186 emit_insn (gen_addsi3 (reg
, reg
, pic_offset_table_rtx
));
1188 else if (flag_pic
== FAR_PIC
)
1190 /* Unspec to handle -fPIC option. */
1191 emit_insn (gen_unspec_got_addr (reg
, orig
));
1195 else if (GET_CODE (orig
) == CONST
)
1197 /* To handle (symbol + offset). */
1200 if (GET_CODE (XEXP (orig
, 0)) == PLUS
1201 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
1206 gcc_assert (can_create_pseudo_p ());
1207 reg
= gen_reg_rtx (Pmode
);
1210 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
1212 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
, reg
);
1213 offset
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
1214 base
== reg
? 0 : reg
);
1216 /* REVISIT: Optimize for const-offsets. */
1217 emit_insn (gen_addsi3 (reg
, base
, offset
));
1224 /* Implementation of TARGET_LEGITIMATE_ADDRESS_P. */
1226 cr16_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED
,
1227 rtx addr
, bool strict
)
1229 enum cr16_addrtype addrtype
;
1230 struct cr16_address address
;
1232 if (TARGET_DEBUG_ADDR
)
1235 "\n======\nTARGET_LEGITIMATE_ADDRESS_P, mode = %s, strict = %d",
1236 GET_MODE_NAME (mode
), strict
);
1239 addrtype
= cr16_decompose_address (addr
, &address
,
1240 (TARGET_DEBUG_ADDR
? 1 : 0), FALSE
);
1242 if (TARGET_DEBUG_ADDR
)
1244 const char *typestr
;
1249 typestr
= "invalid";
1252 typestr
= "absolute";
1255 typestr
= "register relative";
1258 typestr
= "register pair relative";
1260 case CR16_INDEX_REGP_REL
:
1261 typestr
= "index + register pair relative";
1266 fprintf (stderr
, "\ncr16 address type: %s\n", typestr
);
1269 if (addrtype
== CR16_INVALID
)
1275 && !REGNO_MODE_OK_FOR_BASE_P (REGNO (address
.base
), mode
))
1277 if (TARGET_DEBUG_ADDR
)
1278 fprintf (stderr
, "base register not strict\n");
1281 if (address
.index
&& !REGNO_OK_FOR_INDEX_P (REGNO (address
.index
)))
1283 if (TARGET_DEBUG_ADDR
)
1284 fprintf (stderr
, "index register not strict\n");
1289 /* Return true if addressing mode is register relative. */
1292 if (addrtype
== CR16_REG_REL
|| addrtype
== CR16_REGP_REL
)
1301 /* Routines to compute costs. */
1303 /* Return cost of the memory address x. */
1305 cr16_address_cost (rtx addr
, machine_mode mode ATTRIBUTE_UNUSED
,
1306 addr_space_t as ATTRIBUTE_UNUSED
,
1307 bool speed ATTRIBUTE_UNUSED
)
1309 enum cr16_addrtype addrtype
;
1310 struct cr16_address address
;
1313 addrtype
= cr16_decompose_address (addr
, &address
, 0, FALSE
);
1315 gcc_assert (addrtype
!= CR16_INVALID
);
1317 /* CR16_ABSOLUTE : 3
1318 CR16_REG_REL (disp !=0) : 4
1319 CR16_REG_REL (disp ==0) : 5
1320 CR16_REGP_REL (disp !=0) : 6
1321 CR16_REGP_REL (disp ==0) : 7
1322 CR16_INDEX_REGP_REL (disp !=0) : 8
1323 CR16_INDEX_REGP_REL (disp ==0) : 9. */
1337 case CR16_INDEX_REGP_REL
:
1345 if (TARGET_DEBUG_ADDR
)
1347 fprintf (stderr
, "\n======\nmacro TARGET_ADDRESS_COST = %d\n", cost
);
1355 /* Implement `TARGET_REGISTER_MOVE_COST'. */
1357 cr16_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
1358 reg_class_t from ATTRIBUTE_UNUSED
, reg_class_t to
)
1360 return (to
!= GENERAL_REGS
? 8 : 2);
1363 /* Implement `TARGET_MEMORY_MOVE_COST'. */
1365 /* Return the cost of moving data of mode MODE between a register of class
1366 CLASS and memory; IN is zero if the value is to be written to memory,
1367 nonzero if it is to be read in. This cost is relative to those in
1368 REGISTER_MOVE_COST. */
1370 cr16_memory_move_cost (machine_mode mode
,
1371 reg_class_t rclass ATTRIBUTE_UNUSED
,
1372 bool in ATTRIBUTE_UNUSED
)
1374 /* One LD or ST takes twice the time of a simple reg-reg move. */
1375 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
1376 return (4 * HARD_REGNO_NREGS (0, mode
));
1381 /* Instruction output. */
1383 /* Check if a const_double is ok for cr16 store-immediate instructions. */
1385 cr16_const_double_ok (rtx op
)
1387 if (GET_MODE (op
) == SFmode
)
1391 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
1392 REAL_VALUE_TO_TARGET_SINGLE (r
, l
);
1393 return UNSIGNED_INT_FITS_N_BITS (l
, 4) ? 1 : 0;
1396 return ((UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op
), 4)) &&
1397 (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op
), 4))) ? 1 : 0;
1400 /* Returns bit position of first 0 or 1 bit.
1401 It is safe to assume val as 16-bit wide. */
1403 cr16_operand_bit_pos (int val
, int bitval
)
1409 for (i
= 0; i
< 16; i
++)
1415 /* Implements the macro PRINT_OPERAND defined in cr16.h. */
1417 cr16_print_operand (FILE * file
, rtx x
, int code
)
1419 int ptr_dereference
= 0;
1425 const char *cr16_cmp_str
;
1426 switch (GET_CODE (x
))
1428 /* MD: compare (reg, reg or imm) but CR16: cmp (reg or imm, reg)
1429 -> swap all non symmetric ops. */
1431 cr16_cmp_str
= "eq";
1434 cr16_cmp_str
= "ne";
1437 cr16_cmp_str
= "lt";
1440 cr16_cmp_str
= "lo";
1443 cr16_cmp_str
= "gt";
1446 cr16_cmp_str
= "hi";
1449 cr16_cmp_str
= "le";
1452 cr16_cmp_str
= "ls";
1455 cr16_cmp_str
= "ge";
1458 cr16_cmp_str
= "hs";
1463 fprintf (file
, "%s", cr16_cmp_str
);
1471 if (GET_CODE (x
) == REG
)
1473 /* For Push instructions, we should not print register pairs. */
1474 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1480 /* Print the immediate address for bal
1481 'b' is used instead of 'a' to avoid compiler calling
1482 the GO_IF_LEGITIMATE_ADDRESS which cannot
1483 perform checks on const_int code addresses as it
1484 assumes all const_int are data addresses. */
1485 fprintf (file
, "0x%lx", INTVAL (x
));
1489 /* Print bit position of first 0. */
1490 fprintf (file
, "%d", cr16_operand_bit_pos (INTVAL (x
), 0));
1494 /* Print bit position of first 1. */
1495 fprintf (file
, "%d", cr16_operand_bit_pos (INTVAL (x
), 1));
1498 /* 'g' is used for implicit mem: dereference. */
1499 ptr_dereference
= 1;
1503 switch (GET_CODE (x
))
1506 if (GET_MODE_BITSIZE (GET_MODE (x
)) > BITS_PER_WORD
)
1508 if (LONG_REG_P (REGNO (x
)))
1509 fprintf (file
, "(%s)", reg_names
[REGNO (x
)]);
1511 fprintf (file
, "(%s,%s)", reg_names
[REGNO (x
) + 1],
1512 reg_names
[REGNO (x
)]);
1515 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1519 output_address (XEXP (x
, 0));
1527 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
1528 REAL_VALUE_TO_TARGET_SINGLE (r
, l
);
1530 fprintf (file
, "$0x%lx", l
);
1535 fprintf (file
, "$%ld", INTVAL (x
));
1539 switch (XINT (x
, 1))
1547 if (!ptr_dereference
)
1551 cr16_print_operand_address (file
, x
);
1555 output_operand_lossage ("invalid %%xn code");
1561 /* Implements the macro PRINT_OPERAND_ADDRESS defined in cr16.h. */
1564 cr16_print_operand_address (FILE * file
, rtx addr
)
1566 enum cr16_addrtype addrtype
;
1567 struct cr16_address address
;
1569 /* Decompose the address. Also ask it to treat address as constant. */
1570 addrtype
= cr16_decompose_address (addr
, &address
, 0, TRUE
);
1572 if (address
.disp
&& GET_CODE (address
.disp
) == UNSPEC
)
1582 if (GET_CODE (address
.disp
) == UNSPEC
)
1583 cr16_print_operand (file
, address
.disp
, 0);
1585 output_addr_const (file
, address
.disp
);
1588 fprintf (file
, "0");
1589 fprintf (file
, "(%s)", reg_names
[REGNO (address
.base
)]);
1594 output_addr_const (file
, address
.disp
);
1596 fprintf (file
, "0");
1599 case CR16_INDEX_REGP_REL
:
1600 fprintf (file
, "[%s]", reg_names
[REGNO (address
.index
)]);
1605 if (GET_CODE (address
.disp
) == UNSPEC
)
1606 cr16_print_operand (file
, address
.disp
, 0);
1608 output_addr_const (file
, address
.disp
);
1611 fprintf (file
, "0");
1612 fprintf (file
, "(%s,%s)", reg_names
[REGNO (address
.base
) + 1],
1613 reg_names
[REGNO (address
.base
)]);
1619 /* Add qualifiers to the address expression that was just printed. */
1620 if (flag_pic
< NEAR_PIC
&& address
.code
== 0)
1622 if (address
.data
== DM_FAR
)
1623 /* Addr contains SYMBOL_REF & far data ptr. */
1624 fprintf (file
, "@l");
1625 else if (address
.data
== DM_DEFAULT
)
1626 /* Addr contains SYMBOL_REF & medium data ptr. */
1627 fprintf (file
, "@m");
1628 /* Addr contains SYMBOL_REF & medium data ptr. */
1629 else if (address
.data
== DM_NEAR
)
1630 /* Addr contains SYMBOL_REF & near data ptr. */
1631 fprintf (file
, "@s");
1633 else if (flag_pic
== NEAR_PIC
1634 && (address
.code
== 0) && (address
.data
== DM_FAR
1635 || address
.data
== DM_DEFAULT
1636 || address
.data
== DM_NEAR
))
1638 fprintf (file
, "@l");
1640 else if (flag_pic
== NEAR_PIC
&& address
.code
== 2)
1642 fprintf (file
, "pic");
1644 else if (flag_pic
== NEAR_PIC
&& address
.code
== 1)
1646 fprintf (file
, "@cpic");
1649 else if (flag_pic
== FAR_PIC
&& address
.code
== 2)
1651 /* REVISIT: cr16 register indirect jump expects a 1-bit right shifted
1652 address ! GOTc tells assembler this symbol is a text-address
1653 This needs to be fixed in such a way that this offset is done
1654 only in the case where an address is being used for indirect jump
1655 or call. Determining the potential usage of loadd is of course not
1656 possible always. Eventually, this has to be fixed in the
1658 fprintf (file
, "GOT (%s)", reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
1660 else if (flag_pic
== FAR_PIC
&& address
.code
== 1)
1662 fprintf (file
, "@cGOT (%s)", reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
1665 else if (flag_pic
== FAR_PIC
&&
1666 (address
.data
== DM_FAR
|| address
.data
== DM_DEFAULT
1667 || address
.data
== DM_NEAR
))
1669 fprintf (file
, "@GOT (%s)", reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
1673 /* Machine description helper functions. */
1675 /* Called from cr16.md. The return value depends on the parameter push_or_pop:
1676 When push_or_pop is zero -> string for push instructions of prologue.
1677 When push_or_pop is nonzero -> string for pop/popret/retx in epilogue.
1678 Relies on the assumptions:
1679 1. RA is the last register to be saved.
1680 2. The maximal value of the counter is MAX_COUNT. */
1682 cr16_prepare_push_pop_string (int push_or_pop
)
1684 /* j is the number of registers being saved, takes care that there won't be
1685 more than 8 in one push/pop instruction. */
1687 /* For the register mask string. */
1688 static char one_inst_str
[50];
1690 /* i is the index of current_frame_info.save_regs[], going from 0 until
1691 current_frame_info.last_reg_to_save. */
1697 /* For reversing on the push instructions if there are more than one. */
1700 return_str
= (char *) xmalloc (160);
1701 temp_str
= (char *) xmalloc (160);
1704 memset (return_str
, 0, 3);
1707 while (i
<= current_frame_info
.last_reg_to_save
)
1709 /* Prepare mask for one instruction. */
1710 one_inst_str
[0] = 0;
1712 /* To count number of words in one instruction. */
1716 while ((word_cnt
< MAX_COUNT
)
1717 && (i
<= current_frame_info
.last_reg_to_save
))
1719 /* For each non consecutive save register,
1720 a new instruction shall be generated. */
1721 if (!current_frame_info
.save_regs
[i
])
1723 /* Move to next reg and break. */
1728 if (i
== RETURN_ADDRESS_REGNUM
)
1732 /* Check especially if adding 2 does not cross the MAX_COUNT. */
1733 if ((word_cnt
+ ((i
< CR16_FIRST_DWORD_REGISTER
) ? 1 : 2))
1736 /* Increase word count by 2 for long registers except RA. */
1737 word_cnt
+= ((i
< CR16_FIRST_DWORD_REGISTER
) ? 1 : 2);
1742 /* No need to generate any instruction as
1743 no register or RA needs to be saved. */
1744 if ((word_cnt
== 0) && (print_ra
== 0))
1747 /* Now prepare the instruction operands. */
1750 sprintf (one_inst_str
, "$%d, %s", word_cnt
, reg_names
[start_reg
]);
1752 strcat (one_inst_str
, ", ra");
1755 strcat (one_inst_str
, "ra");
1757 if (push_or_pop
== 1)
1759 /* Pop instruction. */
1760 if (print_ra
&& !cr16_interrupt_function_p ()
1761 && !crtl
->calls_eh_return
)
1762 /* Print popret if RA is saved and its not a interrupt
1764 strcpy (temp_str
, "\n\tpopret\t");
1766 strcpy (temp_str
, "\n\tpop\t");
1768 strcat (temp_str
, one_inst_str
);
1770 /* Add the pop instruction list. */
1771 strcat (return_str
, temp_str
);
1775 /* Push instruction. */
1776 strcpy (temp_str
, "\n\tpush\t");
1777 strcat (temp_str
, one_inst_str
);
1779 /* We need to reverse the order of the instructions if there
1780 are more than one. (since the pop will not be reversed in
1782 strcat (temp_str
, return_str
);
1783 strcpy (return_str
, temp_str
);
1787 if (push_or_pop
== 1)
1790 if (cr16_interrupt_function_p ())
1791 strcat (return_str
, "\n\tretx\n");
1792 else if (crtl
->calls_eh_return
)
1794 /* Add stack adjustment before returning to exception handler
1795 NOTE: EH_RETURN_STACKADJ_RTX must refer to (r5, r4). */
1796 strcat (return_str
, "\n\taddd\t (r5, r4), (sp)\t\n");
1797 strcat (return_str
, "\n\tjump\t (ra)\n");
1799 /* But before anything else, undo the adjustment addition done in
1800 cr16_expand_epilogue (). */
1801 strcpy (temp_str
, "\n\tsubd\t (r5, r4), (sp)\t\n");
1802 strcat (temp_str
, return_str
);
1803 strcpy (return_str
, temp_str
);
1805 else if (!FUNC_IS_NORETURN_P (current_function_decl
)
1806 && !(current_frame_info
.save_regs
[RETURN_ADDRESS_REGNUM
]))
1807 strcat (return_str
, "\n\tjump\t (ra)\n");
1810 /* Skip the newline and the tab in the start of return_str. */
1816 /* Generate DWARF2 annotation for multi-push instruction. */
1818 cr16_create_dwarf_for_multi_push (rtx insn
)
1820 rtx dwarf
, reg
, tmp
;
1821 int i
, j
, from
, to
, word_cnt
, dwarf_par_index
, inc
;
1823 int num_regs
= 0, offset
= 0, split_here
= 0, total_push_bytes
= 0;
1825 for (i
= 0; i
<= current_frame_info
.last_reg_to_save
; ++i
)
1827 if (current_frame_info
.save_regs
[i
])
1830 if (i
< CR16_FIRST_DWORD_REGISTER
)
1831 total_push_bytes
+= 2;
1833 total_push_bytes
+= 4;
1840 dwarf
= gen_rtx_SEQUENCE (VOIDmode
, rtvec_alloc (num_regs
+ 1));
1841 dwarf_par_index
= num_regs
;
1843 from
= current_frame_info
.last_reg_to_save
+ 1;
1844 to
= current_frame_info
.last_reg_to_save
;
1847 for (i
= current_frame_info
.last_reg_to_save
; i
>= 0;)
1849 if (!current_frame_info
.save_regs
[i
] || 0 == i
|| split_here
)
1851 /* This block of regs is pushed in one instruction. */
1852 if (0 == i
&& current_frame_info
.save_regs
[i
])
1855 for (j
= to
; j
>= from
; --j
)
1857 if (j
< CR16_FIRST_DWORD_REGISTER
)
1867 reg
= gen_rtx_REG (mode
, j
);
1869 tmp
= gen_rtx_SET (gen_frame_mem (mode
,
1871 (Pmode
, stack_pointer_rtx
,
1872 total_push_bytes
- offset
)),
1874 RTX_FRAME_RELATED_P (tmp
) = 1;
1875 XVECEXP (dwarf
, 0, dwarf_par_index
--) = tmp
;
1884 if (i
!= RETURN_ADDRESS_REGNUM
)
1886 inc
= (i
< CR16_FIRST_DWORD_REGISTER
) ? 1 : 2;
1887 if (word_cnt
+ inc
>= MAX_COUNT
|| FRAME_POINTER_REGNUM
== i
)
1899 tmp
= gen_rtx_SET (stack_pointer_rtx
,
1900 gen_rtx_PLUS (SImode
, stack_pointer_rtx
,
1901 GEN_INT (-offset
)));
1902 RTX_FRAME_RELATED_P (tmp
) = 1;
1903 XVECEXP (dwarf
, 0, 0) = tmp
;
1905 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, dwarf
);
1909 CompactRISC CR16 Architecture stack layout:
1911 0 +---------------------
1916 +==================== Sp (x) = Ap (x+1)
1917 A | Args for functions
1918 | | called by X and Dynamically
1919 | | Dynamic allocations allocated and
1920 | | (alloca, variable deallocated
1921 Stack | length arrays).
1922 grows +-------------------- Fp (x)
1923 down| | Local variables of X
1924 ward| +--------------------
1925 | | Regs saved for X-1
1926 | +==================== Sp (x-1) = Ap (x)
1929 +-------------------- Fp (x-1)
1935 cr16_expand_prologue (void)
1939 cr16_compute_frame ();
1940 cr16_compute_save_regs ();
1942 /* If there is no need in push and adjustment to sp, return. */
1943 if ((current_frame_info
.total_size
+ current_frame_info
.reg_size
) == 0)
1946 if (current_frame_info
.last_reg_to_save
!= -1)
1948 /* If there are registers to push. */
1949 insn
= emit_insn (gen_push_for_prologue
1950 (GEN_INT (current_frame_info
.reg_size
)));
1951 cr16_create_dwarf_for_multi_push (insn
);
1952 RTX_FRAME_RELATED_P (insn
) = 1;
1956 if (current_frame_info
.total_size
> 0)
1958 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
1959 GEN_INT (-current_frame_info
.total_size
)));
1960 RTX_FRAME_RELATED_P (insn
) = 1;
1963 if (frame_pointer_needed
)
1965 /* Initialize the frame pointer with the value of the stack pointer
1966 pointing now to the locals. */
1967 insn
= emit_move_insn (frame_pointer_rtx
, stack_pointer_rtx
);
1971 /* Generate insn that updates the stack for local variables and padding
1972 for registers we save. - Generate the appropriate return insn. */
1974 cr16_expand_epilogue (void)
1978 /* Nonzero if we need to return and pop only RA. This will generate a
1979 different insn. This differentiate is for the peepholes for call as
1980 last statement in function. */
1981 int only_popret_RA
= (current_frame_info
.save_regs
[RETURN_ADDRESS_REGNUM
]
1982 && (current_frame_info
.reg_size
1983 == CR16_UNITS_PER_DWORD
));
1985 if (frame_pointer_needed
)
1987 /* Restore the stack pointer with the frame pointers value. */
1988 insn
= emit_move_insn (stack_pointer_rtx
, frame_pointer_rtx
);
1991 if (current_frame_info
.total_size
> 0)
1993 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
1994 GEN_INT (current_frame_info
.total_size
)));
1995 RTX_FRAME_RELATED_P (insn
) = 1;
1998 if (crtl
->calls_eh_return
)
2000 /* Add this here so that (r5, r4) is actually loaded with the adjustment
2001 value; otherwise, the load might be optimized away...
2002 NOTE: remember to subtract the adjustment before popping the regs
2003 and add it back before returning. */
2004 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2005 EH_RETURN_STACKADJ_RTX
));
2008 if (cr16_interrupt_function_p ())
2010 insn
= emit_jump_insn (gen_interrupt_return ());
2011 RTX_FRAME_RELATED_P (insn
) = 1;
2013 else if (crtl
->calls_eh_return
)
2015 /* Special case, pop what's necessary, adjust SP and jump to (RA). */
2016 insn
= emit_jump_insn (gen_pop_and_popret_return
2017 (GEN_INT (current_frame_info
.reg_size
)));
2018 RTX_FRAME_RELATED_P (insn
) = 1;
2020 else if (current_frame_info
.last_reg_to_save
== -1)
2021 /* Nothing to pop. */
2022 /* Don't output jump for interrupt routine, only retx. */
2023 emit_jump_insn (gen_jump_return ());
2024 else if (only_popret_RA
)
2026 insn
= emit_jump_insn (gen_popret_RA_return ());
2027 RTX_FRAME_RELATED_P (insn
) = 1;
2031 insn
= emit_jump_insn (gen_pop_and_popret_return
2032 (GEN_INT (current_frame_info
.reg_size
)));
2033 RTX_FRAME_RELATED_P (insn
) = 1;
2037 /* Implements FRAME_POINTER_REQUIRED. */
2039 cr16_frame_pointer_required (void)
2041 return (cfun
->calls_alloca
|| crtl
->calls_eh_return
2042 || cfun
->has_nonlocal_label
|| crtl
->calls_eh_return
);
2046 cr16_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
2048 return (to
== STACK_POINTER_REGNUM
? !frame_pointer_needed
: true);
2052 /* A C compound statement that attempts to replace X with
2053 a valid memory address for an operand of mode MODE. WIN
2054 will be a C statement label elsewhere in the code.
2055 X will always be the result of a call to break_out_memory_refs (),
2056 and OLDX will be the operand that was given to that function to
2058 The code generated by this macro should not alter the
2059 substructure of X. If it transforms X into a more legitimate form,
2060 it should assign X (which will always be a C variable) a new value. */
2062 cr16_legitimize_address (rtx x
, rtx orig_x ATTRIBUTE_UNUSED
,
2063 machine_mode mode ATTRIBUTE_UNUSED
)
2066 return legitimize_pic_address (orig_x
, mode
, NULL_RTX
);
2071 /* Implement TARGET_LEGITIMATE_CONSTANT_P
2072 Nonzero if X is a legitimate constant for an immediate
2073 operand on the target machine. You can assume that X
2074 satisfies CONSTANT_P. In cr16c treat legitimize float
2075 constant as an immediate operand. */
2077 cr16_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
,
2078 rtx x ATTRIBUTE_UNUSED
)
2084 notice_update_cc (rtx exp
)
2086 if (GET_CODE (exp
) == SET
)
2088 /* Jumps do not alter the cc's. */
2089 if (SET_DEST (exp
) == pc_rtx
)
2092 /* Moving register or memory into a register:
2093 it doesn't alter the cc's, but it might invalidate
2094 the RTX's which we remember the cc's came from.
2095 (Note that moving a constant 0 or 1 MAY set the cc's). */
2096 if (REG_P (SET_DEST (exp
))
2097 && (REG_P (SET_SRC (exp
)) || GET_CODE (SET_SRC (exp
)) == MEM
))
2102 /* Moving register into memory doesn't alter the cc's.
2103 It may invalidate the RTX's which we remember the cc's came from. */
2104 if (GET_CODE (SET_DEST (exp
)) == MEM
&& REG_P (SET_SRC (exp
)))
2115 cr16_unwind_word_mode (void)
2120 /* Helper function for md file. This function is used to emit arithmetic
2121 DI instructions. The argument "num" decides which instruction to be
2124 cr16_emit_add_sub_di (rtx
*operands
, enum rtx_code code
)
2130 lo_op
[0] = gen_lowpart (SImode
, operands
[0]);
2131 hi0_op
[0] = simplify_gen_subreg (HImode
, operands
[0], DImode
, 4);
2132 hi1_op
[0] = simplify_gen_subreg (HImode
, operands
[0], DImode
, 6);
2134 lo_op
[1] = gen_lowpart (SImode
, operands
[2]);
2135 hi0_op
[1] = simplify_gen_subreg (HImode
, operands
[2], DImode
, 4);
2136 hi1_op
[1] = simplify_gen_subreg (HImode
, operands
[2], DImode
, 6);
2142 output_asm_insn ("addd\t%1, %0", lo_op
) ;
2143 output_asm_insn ("addcw\t%1, %0", hi0_op
) ;
2144 output_asm_insn ("addcw\t%1, %0", hi1_op
) ;
2149 output_asm_insn ("subd\t%1, %0", lo_op
) ;
2150 output_asm_insn ("subcw\t%1, %0", hi0_op
) ;
2151 output_asm_insn ("subcw\t%1, %0", hi1_op
) ;
2162 /* Helper function for md file. This function is used to emit logical
2163 DI instructions. The argument "num" decides which instruction to be
2166 cr16_emit_logical_di (rtx
*operands
, enum rtx_code code
)
2171 lo_op
[0] = gen_lowpart (SImode
, operands
[0]);
2172 hi_op
[0] = simplify_gen_subreg (SImode
, operands
[0], DImode
, 4);
2174 lo_op
[1] = gen_lowpart (SImode
, operands
[2]);
2175 hi_op
[1] = simplify_gen_subreg (SImode
, operands
[2], DImode
, 4);
2181 output_asm_insn ("andd\t%1, %0", lo_op
) ;
2182 output_asm_insn ("andd\t%1, %0", hi_op
) ;
2187 output_asm_insn ("ord\t%1, %0", lo_op
) ;
2188 output_asm_insn ("ord\t%1, %0", hi_op
) ;
2193 output_asm_insn ("xord\t%1, %0", lo_op
) ;
2194 output_asm_insn ("xord\t%1, %0", hi_op
) ;
2204 /* Initialize 'targetm' variable which contains pointers to functions
2205 and data relating to the target machine. */
2207 struct gcc_target targetm
= TARGET_INITIALIZER
;