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/>. */
21 #define IN_TARGET_CODE 1
25 #include "coretypes.h"
30 #include "stringpool.h"
37 #include "diagnostic-core.h"
38 #include "stor-layout.h"
40 #include "conditions.h"
45 /* This file should be included last. */
46 #include "target-def.h"
50 /* Maximum number of register used for passing parameters. */
51 #define MAX_REG_FOR_PASSING_ARGS 6
53 /* Minimum number register used for passing parameters. */
54 #define MIN_REG_FOR_PASSING_ARGS 2
56 /* The maximum count of words supported in the assembly of the architecture in
57 a push/pop instruction. */
60 /* Predicate is true if the current function is a 'noreturn' function,
61 i.e. it is qualified as volatile. */
62 #define FUNC_IS_NORETURN_P(decl) (TREE_THIS_VOLATILE (decl))
64 /* Predicate that holds when we need to save registers even for 'noreturn'
65 functions, to accommodate for unwinding. */
66 #define MUST_SAVE_REGS_P() \
67 (flag_unwind_tables || (flag_exceptions && !UI_SJLJ))
69 /* Nonzero if the rtx X is a signed const int of n bits. */
70 #define RTX_SIGNED_INT_FITS_N_BITS(X, n) \
71 ((GET_CODE (X) == CONST_INT \
72 && SIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
74 /* Nonzero if the rtx X is an unsigned const int of n bits. */
75 #define RTX_UNSIGNED_INT_FITS_N_BITS(X, n) \
76 ((GET_CODE (X) == CONST_INT \
77 && UNSIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
79 /* Structure for stack computations. */
81 /* variable definitions in the struture
82 args_size Number of bytes saved on the stack for local
85 reg_size Number of bytes saved on the stack for
88 total_size The sum of 2 sizes: locals vars and padding byte
89 for saving the registers. Used in expand_prologue()
92 last_reg_to_save Will hold the number of the last register the
93 prologue saves, -1 if no register is saved
95 save_regs[16] Each object in the array is a register number.
96 Mark 1 for registers that need to be saved
98 num_regs Number of registers saved
100 initialized Non-zero if frame size already calculated, not
103 function_makes_calls Does the function make calls ? not used yet. */
105 struct cr16_frame_info
107 unsigned long var_size
;
108 unsigned long args_size
;
109 unsigned int reg_size
;
110 unsigned long total_size
;
111 long last_reg_to_save
;
112 long save_regs
[FIRST_PSEUDO_REGISTER
];
115 int function_makes_calls
;
118 /* Current frame information calculated by cr16_compute_frame_size. */
119 static struct cr16_frame_info current_frame_info
;
121 /* Static Variables. */
123 /* Data model that was supplied by user via command line option
124 This will be overridden in case of invalid combination
125 of core and data model options are supplied. */
126 static enum data_model_type data_model
= DM_DEFAULT
;
128 /* TARGETM Function Prototypes and forward declarations */
129 static void cr16_print_operand (FILE *, rtx
, int);
130 static void cr16_print_operand_address (FILE *, machine_mode
, rtx
);
132 /* Stack layout and calling conventions. */
133 #undef TARGET_STRUCT_VALUE_RTX
134 #define TARGET_STRUCT_VALUE_RTX cr16_struct_value_rtx
135 #undef TARGET_RETURN_IN_MEMORY
136 #define TARGET_RETURN_IN_MEMORY cr16_return_in_memory
138 /* Target-specific uses of '__attribute__'. */
139 #undef TARGET_ATTRIBUTE_TABLE
140 #define TARGET_ATTRIBUTE_TABLE cr16_attribute_table
141 #undef TARGET_NARROW_VOLATILE_BITFIELD
142 #define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false
145 #undef TARGET_UNWIND_WORD_MODE
146 #define TARGET_UNWIND_WORD_MODE cr16_unwind_word_mode
148 /* Override Options. */
149 #undef TARGET_OPTION_OVERRIDE
150 #define TARGET_OPTION_OVERRIDE cr16_override_options
152 /* Conditional register usuage. */
153 #undef TARGET_CONDITIONAL_REGISTER_USAGE
154 #define TARGET_CONDITIONAL_REGISTER_USAGE cr16_conditional_register_usage
156 /* Controlling register spills. */
157 #undef TARGET_CLASS_LIKELY_SPILLED_P
158 #define TARGET_CLASS_LIKELY_SPILLED_P cr16_class_likely_spilled_p
160 /* Passing function arguments. */
161 #undef TARGET_FUNCTION_ARG
162 #define TARGET_FUNCTION_ARG cr16_function_arg
163 #undef TARGET_FUNCTION_ARG_ADVANCE
164 #define TARGET_FUNCTION_ARG_ADVANCE cr16_function_arg_advance
165 #undef TARGET_RETURN_POPS_ARGS
166 #define TARGET_RETURN_POPS_ARGS cr16_return_pops_args
168 /* Initialize the GCC target structure. */
169 #undef TARGET_FRAME_POINTER_REQUIRED
170 #define TARGET_FRAME_POINTER_REQUIRED cr16_frame_pointer_required
171 #undef TARGET_CAN_ELIMINATE
172 #define TARGET_CAN_ELIMINATE cr16_can_eliminate
173 #undef TARGET_LEGITIMIZE_ADDRESS
174 #define TARGET_LEGITIMIZE_ADDRESS cr16_legitimize_address
175 #undef TARGET_LEGITIMATE_CONSTANT_P
176 #define TARGET_LEGITIMATE_CONSTANT_P cr16_legitimate_constant_p
177 #undef TARGET_LEGITIMATE_ADDRESS_P
178 #define TARGET_LEGITIMATE_ADDRESS_P cr16_legitimate_address_p
181 #define TARGET_LRA_P hook_bool_void_false
183 /* Returning function value. */
184 #undef TARGET_FUNCTION_VALUE
185 #define TARGET_FUNCTION_VALUE cr16_function_value
186 #undef TARGET_LIBCALL_VALUE
187 #define TARGET_LIBCALL_VALUE cr16_libcall_value
188 #undef TARGET_FUNCTION_VALUE_REGNO_P
189 #define TARGET_FUNCTION_VALUE_REGNO_P cr16_function_value_regno_p
191 /* printing the values. */
192 #undef TARGET_PRINT_OPERAND
193 #define TARGET_PRINT_OPERAND cr16_print_operand
194 #undef TARGET_PRINT_OPERAND_ADDRESS
195 #define TARGET_PRINT_OPERAND_ADDRESS cr16_print_operand_address
197 /* Relative costs of operations. */
198 #undef TARGET_ADDRESS_COST
199 #define TARGET_ADDRESS_COST cr16_address_cost
200 #undef TARGET_REGISTER_MOVE_COST
201 #define TARGET_REGISTER_MOVE_COST cr16_register_move_cost
202 #undef TARGET_MEMORY_MOVE_COST
203 #define TARGET_MEMORY_MOVE_COST cr16_memory_move_cost
205 #undef TARGET_CONSTANT_ALIGNMENT
206 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
208 /* Table of machine attributes. */
209 static const struct attribute_spec cr16_attribute_table
[] = {
210 /* ISRs have special prologue and epilogue requirements. */
211 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
212 affects_type_identity, handler, exclude }. */
213 {"interrupt", 0, 0, false, true, true, false, NULL
, NULL
},
214 {NULL
, 0, 0, false, false, false, false, NULL
, NULL
}
217 /* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive
218 .?byte directive along with @c is not understood by assembler.
219 Therefore, make all TARGET_ASM_UNALIGNED_xx_OP same
220 as TARGET_ASM_ALIGNED_xx_OP. */
221 #undef TARGET_ASM_UNALIGNED_HI_OP
222 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
223 #undef TARGET_ASM_UNALIGNED_SI_OP
224 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
225 #undef TARGET_ASM_UNALIGNED_DI_OP
226 #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
228 #undef TARGET_HARD_REGNO_NREGS
229 #define TARGET_HARD_REGNO_NREGS cr16_hard_regno_nregs
230 #undef TARGET_HARD_REGNO_MODE_OK
231 #define TARGET_HARD_REGNO_MODE_OK cr16_hard_regno_mode_ok
232 #undef TARGET_MODES_TIEABLE_P
233 #define TARGET_MODES_TIEABLE_P cr16_modes_tieable_p
235 /* Target hook implementations. */
237 /* Implements hook TARGET_RETURN_IN_MEMORY. */
239 cr16_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
241 const HOST_WIDE_INT size
= int_size_in_bytes (type
);
242 return ((size
== -1) || (size
> 8));
245 /* Implement TARGET_CLASS_LIKELY_SPILLED_P. */
247 cr16_class_likely_spilled_p (reg_class_t rclass
)
249 if ((rclass
) == SHORT_REGS
|| (rclass
) == DOUBLE_BASE_REGS
250 || (rclass
) == LONG_REGS
|| (rclass
) == GENERAL_REGS
)
257 cr16_return_pops_args (tree
, tree
, poly_int64
)
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
435 = (current_frame_info
.var_size
436 + (ACCUMULATE_OUTGOING_ARGS
437 ? (HOST_WIDE_INT
) crtl
->outgoing_args_size
: 0));
440 /* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */
442 cr16_initial_elimination_offset (int from
, int to
)
444 /* Compute this since we need to use current_frame_info.reg_size. */
445 cr16_compute_save_regs ();
447 /* Compute this since we need to use current_frame_info.var_size. */
448 cr16_compute_frame ();
450 if (((from
) == FRAME_POINTER_REGNUM
) && ((to
) == STACK_POINTER_REGNUM
))
451 return (ACCUMULATE_OUTGOING_ARGS
452 ? (HOST_WIDE_INT
) crtl
->outgoing_args_size
: 0);
453 else if (((from
) == ARG_POINTER_REGNUM
) && ((to
) == FRAME_POINTER_REGNUM
))
454 return (current_frame_info
.reg_size
+ current_frame_info
.var_size
);
455 else if (((from
) == ARG_POINTER_REGNUM
) && ((to
) == STACK_POINTER_REGNUM
))
456 return (current_frame_info
.reg_size
+ current_frame_info
.var_size
457 + (ACCUMULATE_OUTGOING_ARGS
458 ? (HOST_WIDE_INT
) crtl
->outgoing_args_size
: 0));
463 /* Register Usage. */
465 /* Return the class number of the smallest class containing reg number REGNO.
466 This could be a conditional expression or could index an array. */
468 cr16_regno_reg_class (int regno
)
470 if ((regno
>= 0) && (regno
< CR16_FIRST_DWORD_REGISTER
))
473 if ((regno
>= CR16_FIRST_DWORD_REGISTER
) && (regno
< FIRST_PSEUDO_REGISTER
))
479 /* Implement TARGET_HARD_REGNO_NREGS. */
482 cr16_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
484 if (regno
>= CR16_FIRST_DWORD_REGISTER
)
485 return CEIL (GET_MODE_SIZE (mode
), CR16_UNITS_PER_DWORD
);
486 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_WORD
);
489 /* Implement TARGET_HARD_REGNO_MODE_OK. On the CR16 architecture, all
490 registers can hold all modes, except that double precision floats
491 (and double ints) must fall on even-register boundaries. */
494 cr16_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
496 if ((GET_MODE_SIZE (mode
) >= 4) && (regno
== 11))
499 if (mode
== DImode
|| mode
== DFmode
)
501 if ((regno
> 8) || (regno
& 1))
507 && ((regno
>= 12) && (GET_MODE_SIZE (mode
) < 4 )))
510 /* CC can only hold CCmode values. */
511 if (GET_MODE_CLASS (mode
) == MODE_CC
)
516 /* Implement TARGET_MODES_TIEABLE_P. */
518 cr16_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
520 return GET_MODE_CLASS (mode1
) == GET_MODE_CLASS (mode2
);
523 /* Returns register number for function return value.*/
524 static inline unsigned int
525 cr16_ret_register (void)
530 /* Implements hook TARGET_STRUCT_VALUE_RTX. */
532 cr16_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED
,
533 int incoming ATTRIBUTE_UNUSED
)
535 return gen_rtx_REG (Pmode
, cr16_ret_register ());
538 /* Returning function value. */
540 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P. */
542 cr16_function_value_regno_p (const unsigned int regno
)
544 return (regno
== cr16_ret_register ());
547 /* Create an RTX representing the place where a
548 library function returns a value of mode MODE. */
550 cr16_libcall_value (machine_mode mode
,
551 const_rtx func ATTRIBUTE_UNUSED
)
553 return gen_rtx_REG (mode
, cr16_ret_register ());
556 /* Create an RTX representing the place where a
557 function returns a value of data type VALTYPE. */
559 cr16_function_value (const_tree type
,
560 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
561 bool outgoing ATTRIBUTE_UNUSED
)
563 return gen_rtx_REG (TYPE_MODE (type
), cr16_ret_register ());
566 /* Passing function arguments. */
568 /* If enough param regs are available for passing the param of type TYPE return
569 the number of registers needed else 0. */
571 enough_regs_for_param (CUMULATIVE_ARGS
* cum
, const_tree type
,
578 type_size
= GET_MODE_BITSIZE (mode
);
580 type_size
= int_size_in_bytes (type
) * BITS_PER_UNIT
;
582 remaining_size
= BITS_PER_WORD
* (MAX_REG_FOR_PASSING_ARGS
583 - (MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
) +
586 /* Any variable which is too big to pass in two registers, will pass on
588 if ((remaining_size
>= type_size
) && (type_size
<= 2 * BITS_PER_WORD
))
589 return (type_size
+ BITS_PER_WORD
- 1) / BITS_PER_WORD
;
594 /* Implements the macro FUNCTION_ARG defined in cr16.h. */
596 cr16_function_arg (cumulative_args_t cum_v
, machine_mode mode
,
597 const_tree type
, bool named ATTRIBUTE_UNUSED
)
599 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
600 cum
->last_parm_in_reg
= 0;
602 /* function_arg () is called with this type just after all the args have
603 had their registers assigned. The rtx that function_arg returns from
604 this type is supposed to pass to 'gen_call' but currently it is not
606 if (type
== void_type_node
)
609 if (targetm
.calls
.must_pass_in_stack (mode
, type
) || (cum
->ints
< 0))
614 /* Enable structures that need padding bytes at the end to pass to a
615 function in registers. */
616 if (enough_regs_for_param (cum
, type
, mode
) != 0)
618 cum
->last_parm_in_reg
= 1;
619 return gen_rtx_REG (mode
, MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
);
623 if ((MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
) > MAX_REG_FOR_PASSING_ARGS
)
627 if (enough_regs_for_param (cum
, type
, mode
) != 0)
629 cum
->last_parm_in_reg
= 1;
630 return gen_rtx_REG (mode
, MIN_REG_FOR_PASSING_ARGS
+ cum
->ints
);
637 /* Implements the macro INIT_CUMULATIVE_ARGS defined in cr16.h. */
639 cr16_init_cumulative_args (CUMULATIVE_ARGS
* cum
, tree fntype
,
640 rtx libfunc ATTRIBUTE_UNUSED
)
642 tree param
, next_param
;
646 /* Determine if this function has variable arguments. This is indicated by
647 the last argument being 'void_type_mode' if there are no variable
648 arguments. Change here for a different vararg. */
649 for (param
= (fntype
) ? TYPE_ARG_TYPES (fntype
) : 0;
650 param
!= NULL_TREE
; param
= next_param
)
652 next_param
= TREE_CHAIN (param
);
653 if ((next_param
== NULL_TREE
) && (TREE_VALUE (param
) != void_type_node
))
661 /* Implements the macro FUNCTION_ARG_ADVANCE defined in cr16.h. */
663 cr16_function_arg_advance (cumulative_args_t cum_v
, machine_mode mode
,
664 const_tree type
, bool named ATTRIBUTE_UNUSED
)
666 CUMULATIVE_ARGS
* cum
= get_cumulative_args (cum_v
);
668 /* l holds the number of registers required. */
669 int l
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
671 /* If the parameter isn't passed on a register don't advance cum. */
672 if (!cum
->last_parm_in_reg
)
675 if (targetm
.calls
.must_pass_in_stack (mode
, type
) || (cum
->ints
< 0))
678 if ((mode
== SImode
) || (mode
== HImode
)
679 || (mode
== QImode
) || (mode
== DImode
))
686 else if ((mode
== SFmode
) || (mode
== DFmode
))
688 else if ((mode
) == BLKmode
)
690 if ((l
= enough_regs_for_param (cum
, type
, mode
)) != 0)
696 /* Implements the macro FUNCTION_ARG_REGNO_P defined in cr16.h.
697 Return nonzero if N is a register used for passing parameters. */
699 cr16_function_arg_regno_p (int n
)
701 return ((n
<= MAX_REG_FOR_PASSING_ARGS
) && (n
>= MIN_REG_FOR_PASSING_ARGS
));
705 Following set of function implement the macro GO_IF_LEGITIMATE_ADDRESS
706 defined in cr16.h. */
708 /* Helper function to check if is a valid base register that can
711 cr16_addr_reg_p (rtx addr_reg
)
715 if (REG_P (addr_reg
))
717 else if ((GET_CODE (addr_reg
) == SUBREG
)
718 && REG_P (SUBREG_REG (addr_reg
))
719 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg
)))
721 reg
= SUBREG_REG (addr_reg
);
725 if (GET_MODE (reg
) != Pmode
)
731 /* Helper functions: Created specifically for decomposing operand of CONST
732 Recursively look into expression x for code or data symbol.
733 The function expects the expression to contain combination of
734 SYMBOL_REF, CONST_INT, (PLUS or MINUS)
735 LABEL_REF, CONST_INT, (PLUS or MINUS)
738 All other combinations will result in code = -1 and data = ILLEGAL_DM
740 -1 ILLEGAL_DM The expression did not contain SYMBOL_REF or LABEL_REF
741 0 DM_FAR SYMBOL_REF was found and it was far data reference.
742 0 DM_DEFAULT SYMBOL_REF was found and it was medium data reference.
743 1 ILLEGAL_DM LABEL_REF was found.
744 2 ILLEGAL_DM SYMBOL_REF was found and it was function reference. */
746 cr16_decompose_const (rtx x
, int *code
, enum data_model_type
*data
,
751 switch (GET_CODE (x
))
754 *code
= SYMBOL_REF_FUNCTION_P (x
) ? 2 : 0;
755 /* 2 indicates func sym. */
758 if (CR16_TARGET_DATA_NEAR
)
760 else if (CR16_TARGET_DATA_MEDIUM
)
762 else if (CR16_TARGET_DATA_FAR
)
765 /* This will be used only for printing
766 the qualifier. This call is (may be)
767 made by cr16_print_operand_address. */
770 /* This call is (may be) made by
771 cr16_legitimate_address_p. */
778 /* 1 - indicates non-function symbol. */
784 /* Look into the tree nodes. */
785 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
786 cr16_decompose_const (XEXP (x
, 1), code
, data
, treat_as_const
);
787 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
788 cr16_decompose_const (XEXP (x
, 0), code
, data
, treat_as_const
);
796 This function decomposes the address returns the type of address
797 as defined in enum cr16_addrtype. It also fills the parameter *out.
798 The decomposed address can be used for two purposes. One to
799 check if the address is valid and second to print the address
802 Following tables list valid address supported in CR16C/C+ architectures.
804 aN : Absoulte address N-bit address
805 R : One 16-bit register
806 RP : Consecutive two 16-bit registers or one 32-bit register
807 I : One 32-bit register
808 dispN : Signed displacement of N-bits
810 ----Code addresses----
812 disp9 : CR16_ABSOLUTE (disp)
813 disp17 : CR16_ABSOLUTE (disp)
814 disp25 : CR16_ABSOLUTE (disp)
815 RP + disp25 : CR16_REGP_REL (base, disp)
818 RP : CR16_REGP_REL (base, disp=0)
819 a24 : CR16_ABSOLUTE (disp)
821 ----Data addresses----
822 a20 : CR16_ABSOLUTE (disp) near (1M)
823 a24 : CR16_ABSOLUTE (disp) medium (16M)
824 R + d20 : CR16_REG_REL (base, disp) near (1M+64K)
825 RP + d4 : CR16_REGP_REL (base, disp) far (4G)
826 RP + d16 : CR16_REGP_REL (base, disp) far (4G)
827 RP + d20 : CR16_REGP_REL (base, disp) far (4G)
828 I : *** Valid but port does not support this
829 I + a20 : *** Valid but port does not support this
830 I + RP + d14: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
831 I + RP + d20: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
833 Decomposing Data model in case of absolute address.
835 Target Option Address type Resultant Data ref type
836 ---------------------- ------------ -----------------------
837 CR16_TARGET_MODEL_NEAR ABS20 DM_DEFAULT
838 CR16_TARGET_MODEL_NEAR IMM20 DM_DEFAULT
839 CR16_TARGET_MODEL_NEAR ABS24 Invalid
840 CR16_TARGET_MODEL_NEAR IMM32 Invalid
842 CR16_TARGET_MODEL_MEDIUM ABS20 DM_DEFAULT
843 CR16_TARGET_MODEL_MEDIUM IMM20 DM_DEFAULT
844 CR16_TARGET_MODEL_MEDIUM ABS24 DM_FAR
845 CR16_TARGET_MODEL_MEDIUM IMM32 Invalid
847 CR16_TARGET_MODEL_FAR ABS20 DM_DEFAULT
848 CR16_TARGET_MODEL_FAR IMM20 DM_DEFAULT
849 CR16_TARGET_MODEL_FAR ABS24 DM_FAR
850 CR16_TARGET_MODEL_FAR IMM32 DM_FAR. */
852 cr16_decompose_address (rtx addr
, struct cr16_address
*out
,
853 bool debug_print
, bool treat_as_const
)
855 rtx base
= NULL_RTX
, disp
= NULL_RTX
, index
= NULL_RTX
;
856 enum data_model_type data
= ILLEGAL_DM
;
858 enum cr16_addrtype retval
= CR16_INVALID
;
860 switch (GET_CODE (addr
))
863 /* Absolute address (known at compile time). */
866 fprintf (stderr
, "\ncode:%d", code
);
871 fprintf (stderr
, "\ndisp:");
875 if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 20))
879 fprintf (stderr
, "\ndata:%d", data
);
880 retval
= CR16_ABSOLUTE
;
882 else if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 24))
884 if (!CR16_TARGET_DATA_NEAR
)
888 fprintf (stderr
, "\ndata:%d", data
);
889 retval
= CR16_ABSOLUTE
;
892 return CR16_INVALID
; /* ABS24 is not support in NEAR model. */
899 /* A CONST is an expression of PLUS or MINUS with
900 CONST_INT, SYMBOL_REF or LABEL_REF. This is the
901 result of assembly-time arithmetic computation. */
902 retval
= CR16_ABSOLUTE
;
904 /* Call the helper function to check the validity. */
905 cr16_decompose_const (XEXP (addr
, 0), &code
, &data
, treat_as_const
);
906 if ((code
== 0) && (data
== ILLEGAL_DM
))
907 /* CONST is not valid code or data address. */
911 fprintf (stderr
, "\ndisp:");
913 fprintf (stderr
, "\ncode:%d", code
);
914 fprintf (stderr
, "\ndata:%d", data
);
919 retval
= CR16_ABSOLUTE
;
921 /* 1 - indicates non-function symbol. */
925 fprintf (stderr
, "\ndisp:");
927 fprintf (stderr
, "\ncode:%d", code
);
932 /* Absolute address (known at link time). */
933 retval
= CR16_ABSOLUTE
;
935 /* This is a code address if symbol_ref is a function. */
936 /* 2 indicates func sym. */
937 code
= SYMBOL_REF_FUNCTION_P (addr
) ? 2 : 0;
940 fprintf (stderr
, "\ndisp:");
942 fprintf (stderr
, "\ncode:%d", code
);
944 /* If not function ref then check if valid data ref. */
947 if (CR16_TARGET_DATA_NEAR
)
949 else if (CR16_TARGET_DATA_MEDIUM
)
951 else if (CR16_TARGET_DATA_FAR
)
954 /* This will be used only for printing the
955 qualifier. This call is (may be) made
956 by cr16_print_operand_address. */
959 /* This call is (may be) made by
960 cr16_legitimate_address_p. */
967 fprintf (stderr
, "\ndata:%d", data
);
972 /* Register relative address. */
973 /* Assume REG fits in a single register. */
974 retval
= CR16_REG_REL
;
975 if (GET_MODE_BITSIZE (GET_MODE (addr
)) > BITS_PER_WORD
)
976 if (!LONG_REG_P (REGNO (addr
)))
977 /* REG will result in reg pair. */
978 retval
= CR16_REGP_REL
;
982 fprintf (stderr
, "\nbase:");
988 switch (GET_CODE (XEXP (addr
, 0)))
993 /* All Reg relative addresses having a displacement needs
994 to fit in 20-bits. */
995 disp
= XEXP (addr
, 1);
998 fprintf (stderr
, "\ndisp:");
1001 switch (GET_CODE (XEXP (addr
, 1)))
1004 /* Shall fit in 20-bits. */
1005 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 20))
1006 return CR16_INVALID
;
1009 fprintf (stderr
, "\ncode:%d", code
);
1013 switch (XINT (XEXP (addr
, 1), 1))
1015 case UNSPEC_LIBRARY_OFFSET
:
1024 /* This is also a valid expression for address.
1025 However, we cannot ascertain if the resultant
1026 displacement will be valid 20-bit value. Therefore,
1027 lets not allow such an expression for now. This will
1028 be updated when we find a way to validate this
1029 expression as legitimate address.
1030 Till then fall through CR16_INVALID. */
1032 return CR16_INVALID
;
1035 /* Now check if REG can fit into single or pair regs. */
1036 retval
= CR16_REG_REL
;
1037 base
= XEXP (addr
, 0);
1040 fprintf (stderr
, "\nbase:");
1043 if (GET_MODE_BITSIZE (GET_MODE ((XEXP (addr
, 0)))) > BITS_PER_WORD
)
1045 if (!LONG_REG_P (REGNO ((XEXP (addr
, 0)))))
1046 /* REG will result in reg pair. */
1047 retval
= CR16_REGP_REL
;
1061 Check if the operand 1 is valid index register. */
1064 fprintf (stderr
, "\ndata:%d", data
);
1065 switch (GET_CODE (XEXP (addr
, 1)))
1069 if (!REG_OK_FOR_INDEX_P (XEXP (addr
, 1)))
1070 return CR16_INVALID
;
1071 /* OK. REG is a valid index register. */
1072 index
= XEXP (addr
, 1);
1075 fprintf (stderr
, "\nindex:");
1080 return CR16_INVALID
;
1082 /* Check if operand 0 of operand 0 is REGP. */
1083 switch (GET_CODE (XEXP (XEXP (addr
, 0), 0)))
1087 /* Now check if REG is a REGP and not in LONG regs. */
1088 if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (addr
, 0), 0)))
1091 if (REGNO (XEXP (XEXP (addr
, 0), 0))
1092 >= CR16_FIRST_DWORD_REGISTER
)
1093 return CR16_INVALID
;
1094 base
= XEXP (XEXP (addr
, 0), 0);
1097 fprintf (stderr
, "\nbase:");
1102 return CR16_INVALID
;
1105 return CR16_INVALID
;
1107 /* Now check if the operand 1 of operand 0 is const_int. */
1108 if (GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
1110 disp
= XEXP (XEXP (addr
, 0), 1);
1113 fprintf (stderr
, "\ndisp:");
1116 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp
), 20))
1117 return CR16_INVALID
;
1120 return CR16_INVALID
;
1121 retval
= CR16_INDEX_REGP_REL
;
1124 return CR16_INVALID
;
1129 return CR16_INVALID
;
1132 /* Check if the base and index registers are valid. */
1133 if (base
&& !(cr16_addr_reg_p (base
)))
1134 return CR16_INVALID
;
1135 if (base
&& !(CR16_REG_OK_FOR_BASE_P (base
)))
1136 return CR16_INVALID
;
1137 if (index
&& !(REG_OK_FOR_INDEX_P (index
)))
1138 return CR16_INVALID
;
1140 /* Write the decomposition to out parameter. */
1150 /* Return non-zero value if 'x' is legitimate PIC operand
1151 when generating PIC code. */
1153 legitimate_pic_operand_p (rtx x
)
1155 switch (GET_CODE (x
))
1162 /* REVISIT: Use something like symbol_referenced_p. */
1163 if (GET_CODE (XEXP (x
, 0)) == PLUS
1164 && (GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
1165 || GET_CODE (XEXP (XEXP (x
, 0), 0)) == LABEL_REF
)
1166 && (GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
))
1170 return legitimate_pic_operand_p (XEXP (x
, 0));
1177 /* Convert a non-PIC address in `orig' to a PIC address in `reg'.
1179 Input Output (-f pic) Output (-f PIC)
1182 C1 symbol symbol@BRO (r12) symbol@GOT (r12)
1184 C2 symbol + offset symbol+offset@BRO (r12) symbol+offset@GOT (r12)
1186 NOTE: @BRO is added using unspec:BRO
1187 NOTE: @GOT is added using unspec:GOT. */
1189 legitimize_pic_address (rtx orig
, machine_mode mode ATTRIBUTE_UNUSED
,
1192 /* First handle a simple SYMBOL_REF or LABEL_REF. */
1193 if (GET_CODE (orig
) == SYMBOL_REF
|| GET_CODE (orig
) == LABEL_REF
)
1196 reg
= gen_reg_rtx (Pmode
);
1198 if (flag_pic
== NEAR_PIC
)
1200 /* Unspec to handle -fpic option. */
1201 emit_insn (gen_unspec_bro_addr (reg
, orig
));
1202 emit_insn (gen_addsi3 (reg
, reg
, pic_offset_table_rtx
));
1204 else if (flag_pic
== FAR_PIC
)
1206 /* Unspec to handle -fPIC option. */
1207 emit_insn (gen_unspec_got_addr (reg
, orig
));
1211 else if (GET_CODE (orig
) == CONST
)
1213 /* To handle (symbol + offset). */
1216 if (GET_CODE (XEXP (orig
, 0)) == PLUS
1217 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
1222 gcc_assert (can_create_pseudo_p ());
1223 reg
= gen_reg_rtx (Pmode
);
1226 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
1228 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
, reg
);
1229 offset
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
1230 base
== reg
? 0 : reg
);
1232 /* REVISIT: Optimize for const-offsets. */
1233 emit_insn (gen_addsi3 (reg
, base
, offset
));
1240 /* Implementation of TARGET_LEGITIMATE_ADDRESS_P. */
1242 cr16_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED
,
1243 rtx addr
, bool strict
)
1245 enum cr16_addrtype addrtype
;
1246 struct cr16_address address
;
1248 if (TARGET_DEBUG_ADDR
)
1251 "\n======\nTARGET_LEGITIMATE_ADDRESS_P, mode = %s, strict = %d",
1252 GET_MODE_NAME (mode
), strict
);
1255 addrtype
= cr16_decompose_address (addr
, &address
,
1256 (TARGET_DEBUG_ADDR
? 1 : 0), FALSE
);
1258 if (TARGET_DEBUG_ADDR
)
1260 const char *typestr
;
1265 typestr
= "invalid";
1268 typestr
= "absolute";
1271 typestr
= "register relative";
1274 typestr
= "register pair relative";
1276 case CR16_INDEX_REGP_REL
:
1277 typestr
= "index + register pair relative";
1282 fprintf (stderr
, "\ncr16 address type: %s\n", typestr
);
1285 if (addrtype
== CR16_INVALID
)
1291 && !REGNO_MODE_OK_FOR_BASE_P (REGNO (address
.base
), mode
))
1293 if (TARGET_DEBUG_ADDR
)
1294 fprintf (stderr
, "base register not strict\n");
1297 if (address
.index
&& !REGNO_OK_FOR_INDEX_P (REGNO (address
.index
)))
1299 if (TARGET_DEBUG_ADDR
)
1300 fprintf (stderr
, "index register not strict\n");
1305 /* Return true if addressing mode is register relative. */
1308 if (addrtype
== CR16_REG_REL
|| addrtype
== CR16_REGP_REL
)
1317 /* Routines to compute costs. */
1319 /* Return cost of the memory address x. */
1321 cr16_address_cost (rtx addr
, machine_mode mode ATTRIBUTE_UNUSED
,
1322 addr_space_t as ATTRIBUTE_UNUSED
,
1323 bool speed ATTRIBUTE_UNUSED
)
1325 enum cr16_addrtype addrtype
;
1326 struct cr16_address address
;
1329 addrtype
= cr16_decompose_address (addr
, &address
, 0, FALSE
);
1331 gcc_assert (addrtype
!= CR16_INVALID
);
1333 /* CR16_ABSOLUTE : 3
1334 CR16_REG_REL (disp !=0) : 4
1335 CR16_REG_REL (disp ==0) : 5
1336 CR16_REGP_REL (disp !=0) : 6
1337 CR16_REGP_REL (disp ==0) : 7
1338 CR16_INDEX_REGP_REL (disp !=0) : 8
1339 CR16_INDEX_REGP_REL (disp ==0) : 9. */
1353 case CR16_INDEX_REGP_REL
:
1361 if (TARGET_DEBUG_ADDR
)
1363 fprintf (stderr
, "\n======\nmacro TARGET_ADDRESS_COST = %d\n", cost
);
1371 /* Implement `TARGET_REGISTER_MOVE_COST'. */
1373 cr16_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
1374 reg_class_t from ATTRIBUTE_UNUSED
, reg_class_t to
)
1376 return (to
!= GENERAL_REGS
? 8 : 2);
1379 /* Implement `TARGET_MEMORY_MOVE_COST'. */
1381 /* Return the cost of moving data of mode MODE between a register of class
1382 CLASS and memory; IN is zero if the value is to be written to memory,
1383 nonzero if it is to be read in. This cost is relative to those in
1384 REGISTER_MOVE_COST. */
1386 cr16_memory_move_cost (machine_mode mode
,
1387 reg_class_t rclass ATTRIBUTE_UNUSED
,
1388 bool in ATTRIBUTE_UNUSED
)
1390 /* One LD or ST takes twice the time of a simple reg-reg move. */
1391 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
1392 return (4 * cr16_hard_regno_nregs (0, mode
));
1397 /* Instruction output. */
1399 /* Check if a const_double is ok for cr16 store-immediate instructions. */
1401 cr16_const_double_ok (rtx op
)
1403 if (GET_MODE (op
) == SFmode
)
1406 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op
), l
);
1407 return UNSIGNED_INT_FITS_N_BITS (l
, 4) ? 1 : 0;
1410 return ((UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op
), 4)) &&
1411 (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op
), 4))) ? 1 : 0;
1414 /* Returns bit position of first 0 or 1 bit.
1415 It is safe to assume val as 16-bit wide. */
1417 cr16_operand_bit_pos (int val
, int bitval
)
1423 for (i
= 0; i
< 16; i
++)
1429 /* Implements the macro PRINT_OPERAND defined in cr16.h. */
1431 cr16_print_operand (FILE * file
, rtx x
, int code
)
1433 int ptr_dereference
= 0;
1439 const char *cr16_cmp_str
;
1440 switch (GET_CODE (x
))
1442 /* MD: compare (reg, reg or imm) but CR16: cmp (reg or imm, reg)
1443 -> swap all non symmetric ops. */
1445 cr16_cmp_str
= "eq";
1448 cr16_cmp_str
= "ne";
1451 cr16_cmp_str
= "lt";
1454 cr16_cmp_str
= "lo";
1457 cr16_cmp_str
= "gt";
1460 cr16_cmp_str
= "hi";
1463 cr16_cmp_str
= "le";
1466 cr16_cmp_str
= "ls";
1469 cr16_cmp_str
= "ge";
1472 cr16_cmp_str
= "hs";
1477 fprintf (file
, "%s", cr16_cmp_str
);
1485 if (GET_CODE (x
) == REG
)
1487 /* For Push instructions, we should not print register pairs. */
1488 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1494 /* Print the immediate address for bal
1495 'b' is used instead of 'a' to avoid compiler calling
1496 the GO_IF_LEGITIMATE_ADDRESS which cannot
1497 perform checks on const_int code addresses as it
1498 assumes all const_int are data addresses. */
1499 fprintf (file
, "0x%lx", INTVAL (x
));
1503 /* Print bit position of first 0. */
1504 fprintf (file
, "%d", cr16_operand_bit_pos (INTVAL (x
), 0));
1508 /* Print bit position of first 1. */
1509 fprintf (file
, "%d", cr16_operand_bit_pos (INTVAL (x
), 1));
1512 /* 'g' is used for implicit mem: dereference. */
1513 ptr_dereference
= 1;
1518 switch (GET_CODE (x
))
1521 if (GET_MODE_BITSIZE (GET_MODE (x
)) > BITS_PER_WORD
)
1523 if (LONG_REG_P (REGNO (x
)))
1524 fprintf (file
, "(%s)", reg_names
[REGNO (x
)]);
1526 fprintf (file
, "(%s,%s)", reg_names
[REGNO (x
) + 1],
1527 reg_names
[REGNO (x
)]);
1530 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1534 output_address (GET_MODE (x
), XEXP (x
, 0));
1541 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
1543 fprintf (file
, "$0x%lx", l
);
1548 fprintf (file
, "$%ld", INTVAL (x
));
1552 switch (XINT (x
, 1))
1560 if (!ptr_dereference
)
1564 cr16_print_operand_address (file
, VOIDmode
, x
);
1569 output_operand_lossage ("invalid %%xn code");
1575 /* Implements the macro PRINT_OPERAND_ADDRESS defined in cr16.h. */
1578 cr16_print_operand_address (FILE * file
, machine_mode
/*mode*/, rtx addr
)
1580 enum cr16_addrtype addrtype
;
1581 struct cr16_address address
;
1583 /* Decompose the address. Also ask it to treat address as constant. */
1584 addrtype
= cr16_decompose_address (addr
, &address
, 0, TRUE
);
1586 if (address
.disp
&& GET_CODE (address
.disp
) == UNSPEC
)
1596 if (GET_CODE (address
.disp
) == UNSPEC
)
1597 cr16_print_operand (file
, address
.disp
, 0);
1599 output_addr_const (file
, address
.disp
);
1602 fprintf (file
, "0");
1603 fprintf (file
, "(%s)", reg_names
[REGNO (address
.base
)]);
1608 output_addr_const (file
, address
.disp
);
1610 fprintf (file
, "0");
1613 case CR16_INDEX_REGP_REL
:
1614 fprintf (file
, "[%s]", reg_names
[REGNO (address
.index
)]);
1619 if (GET_CODE (address
.disp
) == UNSPEC
)
1620 cr16_print_operand (file
, address
.disp
, 0);
1622 output_addr_const (file
, address
.disp
);
1625 fprintf (file
, "0");
1626 fprintf (file
, "(%s,%s)", reg_names
[REGNO (address
.base
) + 1],
1627 reg_names
[REGNO (address
.base
)]);
1633 /* Add qualifiers to the address expression that was just printed. */
1634 if (flag_pic
< NEAR_PIC
&& address
.code
== 0)
1636 if (address
.data
== DM_FAR
)
1637 /* Addr contains SYMBOL_REF & far data ptr. */
1638 fprintf (file
, "@l");
1639 else if (address
.data
== DM_DEFAULT
)
1640 /* Addr contains SYMBOL_REF & medium data ptr. */
1641 fprintf (file
, "@m");
1642 /* Addr contains SYMBOL_REF & medium data ptr. */
1643 else if (address
.data
== DM_NEAR
)
1644 /* Addr contains SYMBOL_REF & near data ptr. */
1645 fprintf (file
, "@s");
1647 else if (flag_pic
== NEAR_PIC
1648 && (address
.code
== 0) && (address
.data
== DM_FAR
1649 || address
.data
== DM_DEFAULT
1650 || address
.data
== DM_NEAR
))
1652 fprintf (file
, "@l");
1654 else if (flag_pic
== NEAR_PIC
&& address
.code
== 2)
1656 fprintf (file
, "pic");
1658 else if (flag_pic
== NEAR_PIC
&& address
.code
== 1)
1660 fprintf (file
, "@cpic");
1663 else if (flag_pic
== FAR_PIC
&& address
.code
== 2)
1665 /* REVISIT: cr16 register indirect jump expects a 1-bit right shifted
1666 address ! GOTc tells assembler this symbol is a text-address
1667 This needs to be fixed in such a way that this offset is done
1668 only in the case where an address is being used for indirect jump
1669 or call. Determining the potential usage of loadd is of course not
1670 possible always. Eventually, this has to be fixed in the
1672 fprintf (file
, "GOT (%s)", reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
1674 else if (flag_pic
== FAR_PIC
&& address
.code
== 1)
1676 fprintf (file
, "@cGOT (%s)", reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
1679 else if (flag_pic
== FAR_PIC
&&
1680 (address
.data
== DM_FAR
|| address
.data
== DM_DEFAULT
1681 || address
.data
== DM_NEAR
))
1683 fprintf (file
, "@GOT (%s)", reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
1687 /* Machine description helper functions. */
1689 /* Called from cr16.md. The return value depends on the parameter push_or_pop:
1690 When push_or_pop is zero -> string for push instructions of prologue.
1691 When push_or_pop is nonzero -> string for pop/popret/retx in epilogue.
1692 Relies on the assumptions:
1693 1. RA is the last register to be saved.
1694 2. The maximal value of the counter is MAX_COUNT. */
1696 cr16_prepare_push_pop_string (int push_or_pop
)
1698 /* j is the number of registers being saved, takes care that there won't be
1699 more than 8 in one push/pop instruction. */
1701 /* For the register mask string. */
1702 static char one_inst_str
[50];
1704 /* i is the index of current_frame_info.save_regs[], going from 0 until
1705 current_frame_info.last_reg_to_save. */
1711 /* For reversing on the push instructions if there are more than one. */
1714 return_str
= (char *) xmalloc (160);
1715 temp_str
= (char *) xmalloc (160);
1718 memset (return_str
, 0, 3);
1721 while (i
<= current_frame_info
.last_reg_to_save
)
1723 /* Prepare mask for one instruction. */
1724 one_inst_str
[0] = 0;
1726 /* To count number of words in one instruction. */
1730 while ((word_cnt
< MAX_COUNT
)
1731 && (i
<= current_frame_info
.last_reg_to_save
))
1733 /* For each non consecutive save register,
1734 a new instruction shall be generated. */
1735 if (!current_frame_info
.save_regs
[i
])
1737 /* Move to next reg and break. */
1742 if (i
== RETURN_ADDRESS_REGNUM
)
1746 /* Check especially if adding 2 does not cross the MAX_COUNT. */
1747 if ((word_cnt
+ ((i
< CR16_FIRST_DWORD_REGISTER
) ? 1 : 2))
1750 /* Increase word count by 2 for long registers except RA. */
1751 word_cnt
+= ((i
< CR16_FIRST_DWORD_REGISTER
) ? 1 : 2);
1756 /* No need to generate any instruction as
1757 no register or RA needs to be saved. */
1758 if ((word_cnt
== 0) && (print_ra
== 0))
1761 /* Now prepare the instruction operands. */
1764 sprintf (one_inst_str
, "$%d, %s", word_cnt
, reg_names
[start_reg
]);
1766 strcat (one_inst_str
, ", ra");
1769 strcat (one_inst_str
, "ra");
1771 if (push_or_pop
== 1)
1773 /* Pop instruction. */
1774 if (print_ra
&& !cr16_interrupt_function_p ()
1775 && !crtl
->calls_eh_return
)
1776 /* Print popret if RA is saved and its not a interrupt
1778 strcpy (temp_str
, "\n\tpopret\t");
1780 strcpy (temp_str
, "\n\tpop\t");
1782 strcat (temp_str
, one_inst_str
);
1784 /* Add the pop instruction list. */
1785 strcat (return_str
, temp_str
);
1789 /* Push instruction. */
1790 strcpy (temp_str
, "\n\tpush\t");
1791 strcat (temp_str
, one_inst_str
);
1793 /* We need to reverse the order of the instructions if there
1794 are more than one. (since the pop will not be reversed in
1796 strcat (temp_str
, return_str
);
1797 strcpy (return_str
, temp_str
);
1801 if (push_or_pop
== 1)
1804 if (cr16_interrupt_function_p ())
1805 strcat (return_str
, "\n\tretx\n");
1806 else if (crtl
->calls_eh_return
)
1808 /* Add stack adjustment before returning to exception handler
1809 NOTE: EH_RETURN_STACKADJ_RTX must refer to (r5, r4). */
1810 strcat (return_str
, "\n\taddd\t (r5, r4), (sp)\t\n");
1811 strcat (return_str
, "\n\tjump\t (ra)\n");
1813 /* But before anything else, undo the adjustment addition done in
1814 cr16_expand_epilogue (). */
1815 strcpy (temp_str
, "\n\tsubd\t (r5, r4), (sp)\t\n");
1816 strcat (temp_str
, return_str
);
1817 strcpy (return_str
, temp_str
);
1819 else if (!FUNC_IS_NORETURN_P (current_function_decl
)
1820 && !(current_frame_info
.save_regs
[RETURN_ADDRESS_REGNUM
]))
1821 strcat (return_str
, "\n\tjump\t (ra)\n");
1824 /* Skip the newline and the tab in the start of return_str. */
1830 /* Generate DWARF2 annotation for multi-push instruction. */
1832 cr16_create_dwarf_for_multi_push (rtx insn
)
1834 rtx dwarf
, reg
, tmp
;
1835 int i
, j
, from
, to
, word_cnt
, dwarf_par_index
, inc
;
1837 int num_regs
= 0, offset
= 0, split_here
= 0, total_push_bytes
= 0;
1839 for (i
= 0; i
<= current_frame_info
.last_reg_to_save
; ++i
)
1841 if (current_frame_info
.save_regs
[i
])
1844 if (i
< CR16_FIRST_DWORD_REGISTER
)
1845 total_push_bytes
+= 2;
1847 total_push_bytes
+= 4;
1854 dwarf
= gen_rtx_SEQUENCE (VOIDmode
, rtvec_alloc (num_regs
+ 1));
1855 dwarf_par_index
= num_regs
;
1857 from
= current_frame_info
.last_reg_to_save
+ 1;
1858 to
= current_frame_info
.last_reg_to_save
;
1861 for (i
= current_frame_info
.last_reg_to_save
; i
>= 0;)
1863 if (!current_frame_info
.save_regs
[i
] || i
== 0 || split_here
)
1865 /* This block of regs is pushed in one instruction. */
1866 if (i
== 0 && current_frame_info
.save_regs
[i
])
1869 for (j
= to
; j
>= from
; --j
)
1871 if (j
< CR16_FIRST_DWORD_REGISTER
)
1881 reg
= gen_rtx_REG (mode
, j
);
1883 tmp
= gen_rtx_SET (gen_frame_mem (mode
,
1885 (Pmode
, stack_pointer_rtx
,
1886 total_push_bytes
- offset
)),
1888 RTX_FRAME_RELATED_P (tmp
) = 1;
1889 XVECEXP (dwarf
, 0, dwarf_par_index
--) = tmp
;
1898 if (i
!= RETURN_ADDRESS_REGNUM
)
1900 inc
= (i
< CR16_FIRST_DWORD_REGISTER
) ? 1 : 2;
1901 if (word_cnt
+ inc
>= MAX_COUNT
|| FRAME_POINTER_REGNUM
== i
)
1913 tmp
= gen_rtx_SET (stack_pointer_rtx
,
1914 gen_rtx_PLUS (SImode
, stack_pointer_rtx
,
1915 GEN_INT (-offset
)));
1916 RTX_FRAME_RELATED_P (tmp
) = 1;
1917 XVECEXP (dwarf
, 0, 0) = tmp
;
1919 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, dwarf
);
1923 CompactRISC CR16 Architecture stack layout:
1925 0 +---------------------
1930 +==================== Sp (x) = Ap (x+1)
1931 A | Args for functions
1932 | | called by X and Dynamically
1933 | | Dynamic allocations allocated and
1934 | | (alloca, variable deallocated
1935 Stack | length arrays).
1936 grows +-------------------- Fp (x)
1937 down| | Local variables of X
1938 ward| +--------------------
1939 | | Regs saved for X-1
1940 | +==================== Sp (x-1) = Ap (x)
1943 +-------------------- Fp (x-1)
1949 cr16_expand_prologue (void)
1953 cr16_compute_frame ();
1954 cr16_compute_save_regs ();
1956 /* If there is no need in push and adjustment to sp, return. */
1957 if ((current_frame_info
.total_size
+ current_frame_info
.reg_size
) == 0)
1960 if (current_frame_info
.last_reg_to_save
!= -1)
1962 /* If there are registers to push. */
1963 insn
= emit_insn (gen_push_for_prologue
1964 (GEN_INT (current_frame_info
.reg_size
)));
1965 cr16_create_dwarf_for_multi_push (insn
);
1966 RTX_FRAME_RELATED_P (insn
) = 1;
1970 if (current_frame_info
.total_size
> 0)
1972 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
1973 GEN_INT (-current_frame_info
.total_size
)));
1974 RTX_FRAME_RELATED_P (insn
) = 1;
1977 if (frame_pointer_needed
)
1979 /* Initialize the frame pointer with the value of the stack pointer
1980 pointing now to the locals. */
1981 insn
= emit_move_insn (frame_pointer_rtx
, stack_pointer_rtx
);
1985 /* Generate insn that updates the stack for local variables and padding
1986 for registers we save. - Generate the appropriate return insn. */
1988 cr16_expand_epilogue (void)
1992 /* Nonzero if we need to return and pop only RA. This will generate a
1993 different insn. This differentiate is for the peepholes for call as
1994 last statement in function. */
1995 int only_popret_RA
= (current_frame_info
.save_regs
[RETURN_ADDRESS_REGNUM
]
1996 && (current_frame_info
.reg_size
1997 == CR16_UNITS_PER_DWORD
));
1999 if (frame_pointer_needed
)
2001 /* Restore the stack pointer with the frame pointers value. */
2002 insn
= emit_move_insn (stack_pointer_rtx
, frame_pointer_rtx
);
2005 if (current_frame_info
.total_size
> 0)
2007 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2008 GEN_INT (current_frame_info
.total_size
)));
2009 RTX_FRAME_RELATED_P (insn
) = 1;
2012 if (crtl
->calls_eh_return
)
2014 /* Add this here so that (r5, r4) is actually loaded with the adjustment
2015 value; otherwise, the load might be optimized away...
2016 NOTE: remember to subtract the adjustment before popping the regs
2017 and add it back before returning. */
2018 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2019 EH_RETURN_STACKADJ_RTX
));
2022 if (cr16_interrupt_function_p ())
2024 insn
= emit_jump_insn (gen_interrupt_return ());
2025 RTX_FRAME_RELATED_P (insn
) = 1;
2027 else if (crtl
->calls_eh_return
)
2029 /* Special case, pop what's necessary, adjust SP and jump to (RA). */
2030 insn
= emit_jump_insn (gen_pop_and_popret_return
2031 (GEN_INT (current_frame_info
.reg_size
)));
2032 RTX_FRAME_RELATED_P (insn
) = 1;
2034 else if (current_frame_info
.last_reg_to_save
== -1)
2035 /* Nothing to pop. */
2036 /* Don't output jump for interrupt routine, only retx. */
2037 emit_jump_insn (gen_jump_return ());
2038 else if (only_popret_RA
)
2040 insn
= emit_jump_insn (gen_popret_RA_return ());
2041 RTX_FRAME_RELATED_P (insn
) = 1;
2045 insn
= emit_jump_insn (gen_pop_and_popret_return
2046 (GEN_INT (current_frame_info
.reg_size
)));
2047 RTX_FRAME_RELATED_P (insn
) = 1;
2051 /* Implements FRAME_POINTER_REQUIRED. */
2053 cr16_frame_pointer_required (void)
2055 return (cfun
->calls_alloca
|| crtl
->calls_eh_return
2056 || cfun
->has_nonlocal_label
|| crtl
->calls_eh_return
);
2060 cr16_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
2062 return (to
== STACK_POINTER_REGNUM
? !frame_pointer_needed
: true);
2066 /* A C compound statement that attempts to replace X with
2067 a valid memory address for an operand of mode MODE. WIN
2068 will be a C statement label elsewhere in the code.
2069 X will always be the result of a call to break_out_memory_refs (),
2070 and OLDX will be the operand that was given to that function to
2072 The code generated by this macro should not alter the
2073 substructure of X. If it transforms X into a more legitimate form,
2074 it should assign X (which will always be a C variable) a new value. */
2076 cr16_legitimize_address (rtx x
, rtx orig_x ATTRIBUTE_UNUSED
,
2077 machine_mode mode ATTRIBUTE_UNUSED
)
2080 return legitimize_pic_address (orig_x
, mode
, NULL_RTX
);
2085 /* Implement TARGET_LEGITIMATE_CONSTANT_P
2086 Nonzero if X is a legitimate constant for an immediate
2087 operand on the target machine. You can assume that X
2088 satisfies CONSTANT_P. In cr16c treat legitimize float
2089 constant as an immediate operand. */
2091 cr16_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
,
2092 rtx x ATTRIBUTE_UNUSED
)
2098 notice_update_cc (rtx exp
)
2100 if (GET_CODE (exp
) == SET
)
2102 /* Jumps do not alter the cc's. */
2103 if (SET_DEST (exp
) == pc_rtx
)
2106 /* Moving register or memory into a register:
2107 it doesn't alter the cc's, but it might invalidate
2108 the RTX's which we remember the cc's came from.
2109 (Note that moving a constant 0 or 1 MAY set the cc's). */
2110 if (REG_P (SET_DEST (exp
))
2111 && (REG_P (SET_SRC (exp
)) || GET_CODE (SET_SRC (exp
)) == MEM
))
2116 /* Moving register into memory doesn't alter the cc's.
2117 It may invalidate the RTX's which we remember the cc's came from. */
2118 if (GET_CODE (SET_DEST (exp
)) == MEM
&& REG_P (SET_SRC (exp
)))
2128 static scalar_int_mode
2129 cr16_unwind_word_mode (void)
2134 /* Helper function for md file. This function is used to emit arithmetic
2135 DI instructions. The argument "num" decides which instruction to be
2138 cr16_emit_add_sub_di (rtx
*operands
, enum rtx_code code
)
2144 lo_op
[0] = gen_lowpart (SImode
, operands
[0]);
2145 hi0_op
[0] = simplify_gen_subreg (HImode
, operands
[0], DImode
, 4);
2146 hi1_op
[0] = simplify_gen_subreg (HImode
, operands
[0], DImode
, 6);
2148 lo_op
[1] = gen_lowpart (SImode
, operands
[2]);
2149 hi0_op
[1] = simplify_gen_subreg (HImode
, operands
[2], DImode
, 4);
2150 hi1_op
[1] = simplify_gen_subreg (HImode
, operands
[2], DImode
, 6);
2156 output_asm_insn ("addd\t%1, %0", lo_op
) ;
2157 output_asm_insn ("addcw\t%1, %0", hi0_op
) ;
2158 output_asm_insn ("addcw\t%1, %0", hi1_op
) ;
2163 output_asm_insn ("subd\t%1, %0", lo_op
) ;
2164 output_asm_insn ("subcw\t%1, %0", hi0_op
) ;
2165 output_asm_insn ("subcw\t%1, %0", hi1_op
) ;
2176 /* Helper function for md file. This function is used to emit logical
2177 DI instructions. The argument "num" decides which instruction to be
2180 cr16_emit_logical_di (rtx
*operands
, enum rtx_code code
)
2185 lo_op
[0] = gen_lowpart (SImode
, operands
[0]);
2186 hi_op
[0] = simplify_gen_subreg (SImode
, operands
[0], DImode
, 4);
2188 lo_op
[1] = gen_lowpart (SImode
, operands
[2]);
2189 hi_op
[1] = simplify_gen_subreg (SImode
, operands
[2], DImode
, 4);
2195 output_asm_insn ("andd\t%1, %0", lo_op
) ;
2196 output_asm_insn ("andd\t%1, %0", hi_op
) ;
2201 output_asm_insn ("ord\t%1, %0", lo_op
) ;
2202 output_asm_insn ("ord\t%1, %0", hi_op
) ;
2207 output_asm_insn ("xord\t%1, %0", lo_op
) ;
2208 output_asm_insn ("xord\t%1, %0", hi_op
) ;
2218 /* Initialize 'targetm' variable which contains pointers to functions
2219 and data relating to the target machine. */
2221 struct gcc_target targetm
= TARGET_INITIALIZER
;