cr16.cc revision 1.1.1.1 1 1.1 mrg /* Output routines for CR16 processor.
2 1.1 mrg Copyright (C) 2012-2022 Free Software Foundation, Inc.
3 1.1 mrg Contributed by KPIT Cummins Infosystems Limited.
4 1.1 mrg
5 1.1 mrg This file is part of GCC.
6 1.1 mrg
7 1.1 mrg GCC is free software; you can redistribute it and/or modify it
8 1.1 mrg under the terms of the GNU General Public License as published
9 1.1 mrg by the Free Software Foundation; either version 3, or (at your
10 1.1 mrg option) any later version.
11 1.1 mrg
12 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT
13 1.1 mrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 1.1 mrg License for more details.
16 1.1 mrg
17 1.1 mrg You should have received a copy of the GNU General Public License
18 1.1 mrg along with GCC; see the file COPYING3. If not see
19 1.1 mrg <http://www.gnu.org/licenses/>. */
20 1.1 mrg
21 1.1 mrg #define IN_TARGET_CODE 1
22 1.1 mrg
23 1.1 mrg #include "config.h"
24 1.1 mrg #include "system.h"
25 1.1 mrg #include "coretypes.h"
26 1.1 mrg #include "backend.h"
27 1.1 mrg #include "target.h"
28 1.1 mrg #include "rtl.h"
29 1.1 mrg #include "tree.h"
30 1.1 mrg #include "stringpool.h"
31 1.1 mrg #include "attribs.h"
32 1.1 mrg #include "df.h"
33 1.1 mrg #include "memmodel.h"
34 1.1 mrg #include "tm_p.h"
35 1.1 mrg #include "regs.h"
36 1.1 mrg #include "emit-rtl.h"
37 1.1 mrg #include "diagnostic-core.h"
38 1.1 mrg #include "stor-layout.h"
39 1.1 mrg #include "calls.h"
40 1.1 mrg #include "conditions.h"
41 1.1 mrg #include "output.h"
42 1.1 mrg #include "expr.h"
43 1.1 mrg #include "builtins.h"
44 1.1 mrg
45 1.1 mrg /* This file should be included last. */
46 1.1 mrg #include "target-def.h"
47 1.1 mrg
48 1.1 mrg /* Definitions. */
49 1.1 mrg
50 1.1 mrg /* Maximum number of register used for passing parameters. */
51 1.1 mrg #define MAX_REG_FOR_PASSING_ARGS 6
52 1.1 mrg
53 1.1 mrg /* Minimum number register used for passing parameters. */
54 1.1 mrg #define MIN_REG_FOR_PASSING_ARGS 2
55 1.1 mrg
56 1.1 mrg /* The maximum count of words supported in the assembly of the architecture in
57 1.1 mrg a push/pop instruction. */
58 1.1 mrg #define MAX_COUNT 8
59 1.1 mrg
60 1.1 mrg /* Predicate is true if the current function is a 'noreturn' function,
61 1.1 mrg i.e. it is qualified as volatile. */
62 1.1 mrg #define FUNC_IS_NORETURN_P(decl) (TREE_THIS_VOLATILE (decl))
63 1.1 mrg
64 1.1 mrg /* Predicate that holds when we need to save registers even for 'noreturn'
65 1.1 mrg functions, to accommodate for unwinding. */
66 1.1 mrg #define MUST_SAVE_REGS_P() \
67 1.1 mrg (flag_unwind_tables || (flag_exceptions && !UI_SJLJ))
68 1.1 mrg
69 1.1 mrg /* Nonzero if the rtx X is a signed const int of n bits. */
70 1.1 mrg #define RTX_SIGNED_INT_FITS_N_BITS(X, n) \
71 1.1 mrg ((GET_CODE (X) == CONST_INT \
72 1.1 mrg && SIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
73 1.1 mrg
74 1.1 mrg /* Nonzero if the rtx X is an unsigned const int of n bits. */
75 1.1 mrg #define RTX_UNSIGNED_INT_FITS_N_BITS(X, n) \
76 1.1 mrg ((GET_CODE (X) == CONST_INT \
77 1.1 mrg && UNSIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
78 1.1 mrg
79 1.1 mrg /* Structure for stack computations. */
80 1.1 mrg
81 1.1 mrg /* variable definitions in the struture
82 1.1 mrg args_size Number of bytes saved on the stack for local
83 1.1 mrg variables
84 1.1 mrg
85 1.1 mrg reg_size Number of bytes saved on the stack for
86 1.1 mrg non-scratch registers
87 1.1 mrg
88 1.1 mrg total_size The sum of 2 sizes: locals vars and padding byte
89 1.1 mrg for saving the registers. Used in expand_prologue()
90 1.1 mrg and expand_epilogue()
91 1.1 mrg
92 1.1 mrg last_reg_to_save Will hold the number of the last register the
93 1.1 mrg prologue saves, -1 if no register is saved
94 1.1 mrg
95 1.1 mrg save_regs[16] Each object in the array is a register number.
96 1.1 mrg Mark 1 for registers that need to be saved
97 1.1 mrg
98 1.1 mrg num_regs Number of registers saved
99 1.1 mrg
100 1.1 mrg initialized Non-zero if frame size already calculated, not
101 1.1 mrg used yet
102 1.1 mrg
103 1.1 mrg function_makes_calls Does the function make calls ? not used yet. */
104 1.1 mrg
105 1.1 mrg struct cr16_frame_info
106 1.1 mrg {
107 1.1 mrg unsigned long var_size;
108 1.1 mrg unsigned long args_size;
109 1.1 mrg unsigned int reg_size;
110 1.1 mrg unsigned long total_size;
111 1.1 mrg long last_reg_to_save;
112 1.1 mrg long save_regs[FIRST_PSEUDO_REGISTER];
113 1.1 mrg int num_regs;
114 1.1 mrg int initialized;
115 1.1 mrg int function_makes_calls;
116 1.1 mrg };
117 1.1 mrg
118 1.1 mrg /* Current frame information calculated by cr16_compute_frame_size. */
119 1.1 mrg static struct cr16_frame_info current_frame_info;
120 1.1 mrg
121 1.1 mrg /* Static Variables. */
122 1.1 mrg
123 1.1 mrg /* Data model that was supplied by user via command line option
124 1.1 mrg This will be overridden in case of invalid combination
125 1.1 mrg of core and data model options are supplied. */
126 1.1 mrg static enum data_model_type data_model = DM_DEFAULT;
127 1.1 mrg
128 1.1 mrg /* TARGETM Function Prototypes and forward declarations */
129 1.1 mrg static void cr16_print_operand (FILE *, rtx, int);
130 1.1 mrg static void cr16_print_operand_address (FILE *, machine_mode, rtx);
131 1.1 mrg
132 1.1 mrg /* Stack layout and calling conventions. */
133 1.1 mrg #undef TARGET_STRUCT_VALUE_RTX
134 1.1 mrg #define TARGET_STRUCT_VALUE_RTX cr16_struct_value_rtx
135 1.1 mrg #undef TARGET_RETURN_IN_MEMORY
136 1.1 mrg #define TARGET_RETURN_IN_MEMORY cr16_return_in_memory
137 1.1 mrg
138 1.1 mrg /* Target-specific uses of '__attribute__'. */
139 1.1 mrg #undef TARGET_ATTRIBUTE_TABLE
140 1.1 mrg #define TARGET_ATTRIBUTE_TABLE cr16_attribute_table
141 1.1 mrg #undef TARGET_NARROW_VOLATILE_BITFIELD
142 1.1 mrg #define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false
143 1.1 mrg
144 1.1 mrg /* EH related. */
145 1.1 mrg #undef TARGET_UNWIND_WORD_MODE
146 1.1 mrg #define TARGET_UNWIND_WORD_MODE cr16_unwind_word_mode
147 1.1 mrg
148 1.1 mrg /* Override Options. */
149 1.1 mrg #undef TARGET_OPTION_OVERRIDE
150 1.1 mrg #define TARGET_OPTION_OVERRIDE cr16_override_options
151 1.1 mrg
152 1.1 mrg /* Conditional register usuage. */
153 1.1 mrg #undef TARGET_CONDITIONAL_REGISTER_USAGE
154 1.1 mrg #define TARGET_CONDITIONAL_REGISTER_USAGE cr16_conditional_register_usage
155 1.1 mrg
156 1.1 mrg /* Controlling register spills. */
157 1.1 mrg #undef TARGET_CLASS_LIKELY_SPILLED_P
158 1.1 mrg #define TARGET_CLASS_LIKELY_SPILLED_P cr16_class_likely_spilled_p
159 1.1 mrg
160 1.1 mrg /* Passing function arguments. */
161 1.1 mrg #undef TARGET_PUSH_ARGUMENT
162 1.1 mrg #define TARGET_PUSH_ARGUMENT hook_bool_uint_true
163 1.1 mrg #undef TARGET_FUNCTION_ARG
164 1.1 mrg #define TARGET_FUNCTION_ARG cr16_function_arg
165 1.1 mrg #undef TARGET_FUNCTION_ARG_ADVANCE
166 1.1 mrg #define TARGET_FUNCTION_ARG_ADVANCE cr16_function_arg_advance
167 1.1 mrg #undef TARGET_RETURN_POPS_ARGS
168 1.1 mrg #define TARGET_RETURN_POPS_ARGS cr16_return_pops_args
169 1.1 mrg
170 1.1 mrg /* Initialize the GCC target structure. */
171 1.1 mrg #undef TARGET_FRAME_POINTER_REQUIRED
172 1.1 mrg #define TARGET_FRAME_POINTER_REQUIRED cr16_frame_pointer_required
173 1.1 mrg #undef TARGET_CAN_ELIMINATE
174 1.1 mrg #define TARGET_CAN_ELIMINATE cr16_can_eliminate
175 1.1 mrg #undef TARGET_LEGITIMIZE_ADDRESS
176 1.1 mrg #define TARGET_LEGITIMIZE_ADDRESS cr16_legitimize_address
177 1.1 mrg #undef TARGET_LEGITIMATE_CONSTANT_P
178 1.1 mrg #define TARGET_LEGITIMATE_CONSTANT_P cr16_legitimate_constant_p
179 1.1 mrg #undef TARGET_LEGITIMATE_ADDRESS_P
180 1.1 mrg #define TARGET_LEGITIMATE_ADDRESS_P cr16_legitimate_address_p
181 1.1 mrg
182 1.1 mrg #undef TARGET_LRA_P
183 1.1 mrg #define TARGET_LRA_P hook_bool_void_false
184 1.1 mrg
185 1.1 mrg /* Returning function value. */
186 1.1 mrg #undef TARGET_FUNCTION_VALUE
187 1.1 mrg #define TARGET_FUNCTION_VALUE cr16_function_value
188 1.1 mrg #undef TARGET_LIBCALL_VALUE
189 1.1 mrg #define TARGET_LIBCALL_VALUE cr16_libcall_value
190 1.1 mrg #undef TARGET_FUNCTION_VALUE_REGNO_P
191 1.1 mrg #define TARGET_FUNCTION_VALUE_REGNO_P cr16_function_value_regno_p
192 1.1 mrg
193 1.1 mrg /* printing the values. */
194 1.1 mrg #undef TARGET_PRINT_OPERAND
195 1.1 mrg #define TARGET_PRINT_OPERAND cr16_print_operand
196 1.1 mrg #undef TARGET_PRINT_OPERAND_ADDRESS
197 1.1 mrg #define TARGET_PRINT_OPERAND_ADDRESS cr16_print_operand_address
198 1.1 mrg
199 1.1 mrg /* Relative costs of operations. */
200 1.1 mrg #undef TARGET_ADDRESS_COST
201 1.1 mrg #define TARGET_ADDRESS_COST cr16_address_cost
202 1.1 mrg #undef TARGET_REGISTER_MOVE_COST
203 1.1 mrg #define TARGET_REGISTER_MOVE_COST cr16_register_move_cost
204 1.1 mrg #undef TARGET_MEMORY_MOVE_COST
205 1.1 mrg #define TARGET_MEMORY_MOVE_COST cr16_memory_move_cost
206 1.1 mrg
207 1.1 mrg #undef TARGET_CONSTANT_ALIGNMENT
208 1.1 mrg #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
209 1.1 mrg
210 1.1 mrg /* Table of machine attributes. */
211 1.1 mrg static const struct attribute_spec cr16_attribute_table[] = {
212 1.1 mrg /* ISRs have special prologue and epilogue requirements. */
213 1.1 mrg /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
214 1.1 mrg affects_type_identity, handler, exclude }. */
215 1.1 mrg {"interrupt", 0, 0, false, true, true, false, NULL, NULL},
216 1.1 mrg {NULL, 0, 0, false, false, false, false, NULL, NULL}
217 1.1 mrg };
218 1.1 mrg
219 1.1 mrg /* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive
220 1.1 mrg .?byte directive along with @c is not understood by assembler.
221 1.1 mrg Therefore, make all TARGET_ASM_UNALIGNED_xx_OP same
222 1.1 mrg as TARGET_ASM_ALIGNED_xx_OP. */
223 1.1 mrg #undef TARGET_ASM_UNALIGNED_HI_OP
224 1.1 mrg #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
225 1.1 mrg #undef TARGET_ASM_UNALIGNED_SI_OP
226 1.1 mrg #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
227 1.1 mrg #undef TARGET_ASM_UNALIGNED_DI_OP
228 1.1 mrg #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
229 1.1 mrg
230 1.1 mrg #undef TARGET_HARD_REGNO_NREGS
231 1.1 mrg #define TARGET_HARD_REGNO_NREGS cr16_hard_regno_nregs
232 1.1 mrg #undef TARGET_HARD_REGNO_MODE_OK
233 1.1 mrg #define TARGET_HARD_REGNO_MODE_OK cr16_hard_regno_mode_ok
234 1.1 mrg #undef TARGET_MODES_TIEABLE_P
235 1.1 mrg #define TARGET_MODES_TIEABLE_P cr16_modes_tieable_p
236 1.1 mrg
237 1.1 mrg /* Target hook implementations. */
238 1.1 mrg
239 1.1 mrg /* Implements hook TARGET_RETURN_IN_MEMORY. */
240 1.1 mrg static bool
241 1.1 mrg cr16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
242 1.1 mrg {
243 1.1 mrg const HOST_WIDE_INT size = int_size_in_bytes (type);
244 1.1 mrg return ((size == -1) || (size > 8));
245 1.1 mrg }
246 1.1 mrg
247 1.1 mrg /* Implement TARGET_CLASS_LIKELY_SPILLED_P. */
248 1.1 mrg static bool
249 1.1 mrg cr16_class_likely_spilled_p (reg_class_t rclass)
250 1.1 mrg {
251 1.1 mrg if ((rclass) == SHORT_REGS || (rclass) == DOUBLE_BASE_REGS
252 1.1 mrg || (rclass) == LONG_REGS || (rclass) == GENERAL_REGS)
253 1.1 mrg return true;
254 1.1 mrg
255 1.1 mrg return false;
256 1.1 mrg }
257 1.1 mrg
258 1.1 mrg static poly_int64
259 1.1 mrg cr16_return_pops_args (tree, tree, poly_int64)
260 1.1 mrg {
261 1.1 mrg return 0;
262 1.1 mrg }
263 1.1 mrg
264 1.1 mrg /* Returns true if data model selected via command line option
265 1.1 mrg is same as function argument. */
266 1.1 mrg bool
267 1.1 mrg cr16_is_data_model (enum data_model_type model)
268 1.1 mrg {
269 1.1 mrg return (model == data_model);
270 1.1 mrg }
271 1.1 mrg
272 1.1 mrg /* Parse relevant options and override. */
273 1.1 mrg static void
274 1.1 mrg cr16_override_options (void)
275 1.1 mrg {
276 1.1 mrg /* Disable -fdelete-null-pointer-checks option for CR16 target.
277 1.1 mrg Programs which rely on NULL pointer dereferences _not_ halting the
278 1.1 mrg program may not work properly with this option. So disable this
279 1.1 mrg option. */
280 1.1 mrg flag_delete_null_pointer_checks = 0;
281 1.1 mrg
282 1.1 mrg /* FIXME: To avoid spill_failure ICE during exception handling,
283 1.1 mrg * disable cse_fllow_jumps. The spill error occurs when compiler
284 1.1 mrg * can't find a suitable candidate in GENERAL_REGS class to reload
285 1.1 mrg * a 32bit register.
286 1.1 mrg * Need to find a better way of avoiding this situation. */
287 1.1 mrg if (flag_exceptions)
288 1.1 mrg flag_cse_follow_jumps = 0;
289 1.1 mrg
290 1.1 mrg /* If -fpic option, data_model == DM_FAR. */
291 1.1 mrg if (flag_pic == NEAR_PIC)
292 1.1 mrg {
293 1.1 mrg data_model = DM_FAR;
294 1.1 mrg }
295 1.1 mrg
296 1.1 mrg /* The only option we want to examine is data model option. */
297 1.1 mrg if (cr16_data_model)
298 1.1 mrg {
299 1.1 mrg if (strcmp (cr16_data_model, "medium") == 0)
300 1.1 mrg data_model = DM_DEFAULT;
301 1.1 mrg else if (strcmp (cr16_data_model, "near") == 0)
302 1.1 mrg data_model = DM_NEAR;
303 1.1 mrg else if (strcmp (cr16_data_model, "far") == 0)
304 1.1 mrg {
305 1.1 mrg if (TARGET_CR16CP)
306 1.1 mrg data_model = DM_FAR;
307 1.1 mrg else
308 1.1 mrg error ("data-model=far not valid for cr16c architecture");
309 1.1 mrg }
310 1.1 mrg else
311 1.1 mrg error ("invalid data model option %<-mdata-model=%s%>",
312 1.1 mrg cr16_data_model);
313 1.1 mrg }
314 1.1 mrg else
315 1.1 mrg data_model = DM_DEFAULT;
316 1.1 mrg }
317 1.1 mrg
318 1.1 mrg /* Implements the macro TARGET_CONDITIONAL_REGISTER_USAGE. */
319 1.1 mrg static void
320 1.1 mrg cr16_conditional_register_usage (void)
321 1.1 mrg {
322 1.1 mrg if (flag_pic)
323 1.1 mrg {
324 1.1 mrg fixed_regs[12] = call_used_regs[12] = 1;
325 1.1 mrg }
326 1.1 mrg }
327 1.1 mrg
328 1.1 mrg /* Stack layout and calling conventions routines. */
329 1.1 mrg
330 1.1 mrg /* Return nonzero if the current function being compiled is an interrupt
331 1.1 mrg function as specified by the "interrupt" attribute. */
332 1.1 mrg int
333 1.1 mrg cr16_interrupt_function_p (void)
334 1.1 mrg {
335 1.1 mrg tree attributes;
336 1.1 mrg
337 1.1 mrg attributes = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
338 1.1 mrg return (lookup_attribute ("interrupt", attributes) != NULL_TREE);
339 1.1 mrg }
340 1.1 mrg
341 1.1 mrg /* Compute values for the array current_frame_info.save_regs and the variable
342 1.1 mrg current_frame_info.reg_size. The index of current_frame_info.save_regs
343 1.1 mrg is numbers of register, each will get 1 if we need to save it in the
344 1.1 mrg current function, 0 if not. current_frame_info.reg_size is the total sum
345 1.1 mrg of the registers being saved. */
346 1.1 mrg static void
347 1.1 mrg cr16_compute_save_regs (void)
348 1.1 mrg {
349 1.1 mrg unsigned int regno;
350 1.1 mrg
351 1.1 mrg /* Initialize here so in case the function is no-return it will be -1. */
352 1.1 mrg current_frame_info.last_reg_to_save = -1;
353 1.1 mrg
354 1.1 mrg /* Initialize the number of bytes to be saved. */
355 1.1 mrg current_frame_info.reg_size = 0;
356 1.1 mrg
357 1.1 mrg /* No need to save any registers if the function never returns. */
358 1.1 mrg if (FUNC_IS_NORETURN_P (current_function_decl) && !MUST_SAVE_REGS_P ())
359 1.1 mrg return;
360 1.1 mrg
361 1.1 mrg for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
362 1.1 mrg {
363 1.1 mrg if (fixed_regs[regno])
364 1.1 mrg {
365 1.1 mrg current_frame_info.save_regs[regno] = 0;
366 1.1 mrg continue;
367 1.1 mrg }
368 1.1 mrg
369 1.1 mrg /* If this reg is used and not call-used (except RA), save it. */
370 1.1 mrg if (cr16_interrupt_function_p ())
371 1.1 mrg {
372 1.1 mrg if (!crtl->is_leaf && call_used_or_fixed_reg_p (regno))
373 1.1 mrg /* This is a volatile reg in a non-leaf interrupt routine - save
374 1.1 mrg it for the sake of its sons. */
375 1.1 mrg current_frame_info.save_regs[regno] = 1;
376 1.1 mrg else if (df_regs_ever_live_p (regno))
377 1.1 mrg /* This reg is used - save it. */
378 1.1 mrg current_frame_info.save_regs[regno] = 1;
379 1.1 mrg else
380 1.1 mrg /* This reg is not used, and is not a volatile - don't save. */
381 1.1 mrg current_frame_info.save_regs[regno] = 0;
382 1.1 mrg }
383 1.1 mrg else
384 1.1 mrg {
385 1.1 mrg /* If this reg is used and not call-used (except RA), save it. */
386 1.1 mrg if (df_regs_ever_live_p (regno)
387 1.1 mrg && (!call_used_or_fixed_reg_p (regno)
388 1.1 mrg || regno == RETURN_ADDRESS_REGNUM))
389 1.1 mrg current_frame_info.save_regs[regno] = 1;
390 1.1 mrg else
391 1.1 mrg current_frame_info.save_regs[regno] = 0;
392 1.1 mrg }
393 1.1 mrg }
394 1.1 mrg
395 1.1 mrg /* Save registers so the exception handler can modify them. */
396 1.1 mrg if (crtl->calls_eh_return)
397 1.1 mrg {
398 1.1 mrg unsigned int i;
399 1.1 mrg
400 1.1 mrg for (i = 0;; ++i)
401 1.1 mrg {
402 1.1 mrg regno = EH_RETURN_DATA_REGNO (i);
403 1.1 mrg if (INVALID_REGNUM == regno)
404 1.1 mrg break;
405 1.1 mrg current_frame_info.save_regs[regno] = 1;
406 1.1 mrg }
407 1.1 mrg }
408 1.1 mrg
409 1.1 mrg for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
410 1.1 mrg if (current_frame_info.save_regs[regno] == 1)
411 1.1 mrg {
412 1.1 mrg current_frame_info.last_reg_to_save = regno;
413 1.1 mrg if (regno >= CR16_FIRST_DWORD_REGISTER)
414 1.1 mrg current_frame_info.reg_size += CR16_UNITS_PER_DWORD;
415 1.1 mrg else
416 1.1 mrg current_frame_info.reg_size += UNITS_PER_WORD;
417 1.1 mrg }
418 1.1 mrg }
419 1.1 mrg
420 1.1 mrg /* Compute the size of the local area and the size to be adjusted by the
421 1.1 mrg prologue and epilogue. */
422 1.1 mrg static void
423 1.1 mrg cr16_compute_frame (void)
424 1.1 mrg {
425 1.1 mrg /* For aligning the local variables. */
426 1.1 mrg int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
427 1.1 mrg int padding_locals;
428 1.1 mrg
429 1.1 mrg /* Padding needed for each element of the frame. */
430 1.1 mrg current_frame_info.var_size = get_frame_size ();
431 1.1 mrg
432 1.1 mrg /* Align to the stack alignment. */
433 1.1 mrg padding_locals = current_frame_info.var_size % stack_alignment;
434 1.1 mrg if (padding_locals)
435 1.1 mrg padding_locals = stack_alignment - padding_locals;
436 1.1 mrg
437 1.1 mrg current_frame_info.var_size += padding_locals;
438 1.1 mrg current_frame_info.total_size
439 1.1 mrg = (current_frame_info.var_size
440 1.1 mrg + (ACCUMULATE_OUTGOING_ARGS
441 1.1 mrg ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0));
442 1.1 mrg }
443 1.1 mrg
444 1.1 mrg /* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */
445 1.1 mrg int
446 1.1 mrg cr16_initial_elimination_offset (int from, int to)
447 1.1 mrg {
448 1.1 mrg /* Compute this since we need to use current_frame_info.reg_size. */
449 1.1 mrg cr16_compute_save_regs ();
450 1.1 mrg
451 1.1 mrg /* Compute this since we need to use current_frame_info.var_size. */
452 1.1 mrg cr16_compute_frame ();
453 1.1 mrg
454 1.1 mrg if (((from) == FRAME_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
455 1.1 mrg return (ACCUMULATE_OUTGOING_ARGS
456 1.1 mrg ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0);
457 1.1 mrg else if (((from) == ARG_POINTER_REGNUM) && ((to) == FRAME_POINTER_REGNUM))
458 1.1 mrg return (current_frame_info.reg_size + current_frame_info.var_size);
459 1.1 mrg else if (((from) == ARG_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
460 1.1 mrg return (current_frame_info.reg_size + current_frame_info.var_size
461 1.1 mrg + (ACCUMULATE_OUTGOING_ARGS
462 1.1 mrg ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0));
463 1.1 mrg else
464 1.1 mrg gcc_unreachable ();
465 1.1 mrg }
466 1.1 mrg
467 1.1 mrg /* Register Usage. */
468 1.1 mrg
469 1.1 mrg /* Return the class number of the smallest class containing reg number REGNO.
470 1.1 mrg This could be a conditional expression or could index an array. */
471 1.1 mrg enum reg_class
472 1.1 mrg cr16_regno_reg_class (int regno)
473 1.1 mrg {
474 1.1 mrg if ((regno >= 0) && (regno < CR16_FIRST_DWORD_REGISTER))
475 1.1 mrg return SHORT_REGS;
476 1.1 mrg
477 1.1 mrg if ((regno >= CR16_FIRST_DWORD_REGISTER) && (regno < FIRST_PSEUDO_REGISTER))
478 1.1 mrg return LONG_REGS;
479 1.1 mrg
480 1.1 mrg return NO_REGS;
481 1.1 mrg }
482 1.1 mrg
483 1.1 mrg /* Implement TARGET_HARD_REGNO_NREGS. */
484 1.1 mrg
485 1.1 mrg static unsigned int
486 1.1 mrg cr16_hard_regno_nregs (unsigned int regno, machine_mode mode)
487 1.1 mrg {
488 1.1 mrg if (regno >= CR16_FIRST_DWORD_REGISTER)
489 1.1 mrg return CEIL (GET_MODE_SIZE (mode), CR16_UNITS_PER_DWORD);
490 1.1 mrg return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
491 1.1 mrg }
492 1.1 mrg
493 1.1 mrg /* Implement TARGET_HARD_REGNO_MODE_OK. On the CR16 architecture, all
494 1.1 mrg registers can hold all modes, except that double precision floats
495 1.1 mrg (and double ints) must fall on even-register boundaries. */
496 1.1 mrg
497 1.1 mrg static bool
498 1.1 mrg cr16_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
499 1.1 mrg {
500 1.1 mrg if ((GET_MODE_SIZE (mode) >= 4) && (regno == 11))
501 1.1 mrg return false;
502 1.1 mrg
503 1.1 mrg if (mode == DImode || mode == DFmode)
504 1.1 mrg {
505 1.1 mrg if ((regno > 8) || (regno & 1))
506 1.1 mrg return false;
507 1.1 mrg return true;
508 1.1 mrg }
509 1.1 mrg
510 1.1 mrg if ((TARGET_INT32)
511 1.1 mrg && ((regno >= 12) && (GET_MODE_SIZE (mode) < 4 )))
512 1.1 mrg return false;
513 1.1 mrg
514 1.1 mrg /* CC can only hold CCmode values. */
515 1.1 mrg if (GET_MODE_CLASS (mode) == MODE_CC)
516 1.1 mrg return false;
517 1.1 mrg return true;
518 1.1 mrg }
519 1.1 mrg
520 1.1 mrg /* Implement TARGET_MODES_TIEABLE_P. */
521 1.1 mrg static bool
522 1.1 mrg cr16_modes_tieable_p (machine_mode mode1, machine_mode mode2)
523 1.1 mrg {
524 1.1 mrg return GET_MODE_CLASS (mode1) == GET_MODE_CLASS (mode2);
525 1.1 mrg }
526 1.1 mrg
527 1.1 mrg /* Returns register number for function return value.*/
528 1.1 mrg static inline unsigned int
529 1.1 mrg cr16_ret_register (void)
530 1.1 mrg {
531 1.1 mrg return 0;
532 1.1 mrg }
533 1.1 mrg
534 1.1 mrg /* Implements hook TARGET_STRUCT_VALUE_RTX. */
535 1.1 mrg static rtx
536 1.1 mrg cr16_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
537 1.1 mrg int incoming ATTRIBUTE_UNUSED)
538 1.1 mrg {
539 1.1 mrg return gen_rtx_REG (Pmode, cr16_ret_register ());
540 1.1 mrg }
541 1.1 mrg
542 1.1 mrg /* Returning function value. */
543 1.1 mrg
544 1.1 mrg /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P. */
545 1.1 mrg static bool
546 1.1 mrg cr16_function_value_regno_p (const unsigned int regno)
547 1.1 mrg {
548 1.1 mrg return (regno == cr16_ret_register ());
549 1.1 mrg }
550 1.1 mrg
551 1.1 mrg /* Create an RTX representing the place where a
552 1.1 mrg library function returns a value of mode MODE. */
553 1.1 mrg static rtx
554 1.1 mrg cr16_libcall_value (machine_mode mode,
555 1.1 mrg const_rtx func ATTRIBUTE_UNUSED)
556 1.1 mrg {
557 1.1 mrg return gen_rtx_REG (mode, cr16_ret_register ());
558 1.1 mrg }
559 1.1 mrg
560 1.1 mrg /* Create an RTX representing the place where a
561 1.1 mrg function returns a value of data type VALTYPE. */
562 1.1 mrg static rtx
563 1.1 mrg cr16_function_value (const_tree type,
564 1.1 mrg const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
565 1.1 mrg bool outgoing ATTRIBUTE_UNUSED)
566 1.1 mrg {
567 1.1 mrg return gen_rtx_REG (TYPE_MODE (type), cr16_ret_register ());
568 1.1 mrg }
569 1.1 mrg
570 1.1 mrg /* Passing function arguments. */
571 1.1 mrg
572 1.1 mrg /* If enough param regs are available for passing the param of type TYPE return
573 1.1 mrg the number of registers needed else 0. */
574 1.1 mrg static int
575 1.1 mrg enough_regs_for_param (CUMULATIVE_ARGS * cum, const_tree type,
576 1.1 mrg machine_mode mode)
577 1.1 mrg {
578 1.1 mrg int type_size;
579 1.1 mrg int remaining_size;
580 1.1 mrg
581 1.1 mrg if (mode != BLKmode)
582 1.1 mrg type_size = GET_MODE_BITSIZE (mode);
583 1.1 mrg else
584 1.1 mrg type_size = int_size_in_bytes (type) * BITS_PER_UNIT;
585 1.1 mrg
586 1.1 mrg remaining_size = BITS_PER_WORD * (MAX_REG_FOR_PASSING_ARGS
587 1.1 mrg - (MIN_REG_FOR_PASSING_ARGS + cum->ints) +
588 1.1 mrg 1);
589 1.1 mrg
590 1.1 mrg /* Any variable which is too big to pass in two registers, will pass on
591 1.1 mrg stack. */
592 1.1 mrg if ((remaining_size >= type_size) && (type_size <= 2 * BITS_PER_WORD))
593 1.1 mrg return (type_size + BITS_PER_WORD - 1) / BITS_PER_WORD;
594 1.1 mrg
595 1.1 mrg return 0;
596 1.1 mrg }
597 1.1 mrg
598 1.1 mrg /* Implement TARGET_FUNCTION_ARG. */
599 1.1 mrg static rtx
600 1.1 mrg cr16_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
601 1.1 mrg {
602 1.1 mrg CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
603 1.1 mrg cum->last_parm_in_reg = 0;
604 1.1 mrg
605 1.1 mrg /* function_arg () is called with this type just after all the args have
606 1.1 mrg had their registers assigned. The rtx that function_arg returns from
607 1.1 mrg this type is supposed to pass to 'gen_call' but currently it is not
608 1.1 mrg implemented. */
609 1.1 mrg if (arg.end_marker_p ())
610 1.1 mrg return NULL_RTX;
611 1.1 mrg
612 1.1 mrg if (targetm.calls.must_pass_in_stack (arg) || (cum->ints < 0))
613 1.1 mrg return NULL_RTX;
614 1.1 mrg
615 1.1 mrg if (arg.mode == BLKmode)
616 1.1 mrg {
617 1.1 mrg /* Enable structures that need padding bytes at the end to pass to a
618 1.1 mrg function in registers. */
619 1.1 mrg if (enough_regs_for_param (cum, arg.type, arg.mode) != 0)
620 1.1 mrg {
621 1.1 mrg cum->last_parm_in_reg = 1;
622 1.1 mrg return gen_rtx_REG (arg.mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
623 1.1 mrg }
624 1.1 mrg }
625 1.1 mrg
626 1.1 mrg if ((MIN_REG_FOR_PASSING_ARGS + cum->ints) > MAX_REG_FOR_PASSING_ARGS)
627 1.1 mrg return NULL_RTX;
628 1.1 mrg else
629 1.1 mrg {
630 1.1 mrg if (enough_regs_for_param (cum, arg.type, arg.mode) != 0)
631 1.1 mrg {
632 1.1 mrg cum->last_parm_in_reg = 1;
633 1.1 mrg return gen_rtx_REG (arg.mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
634 1.1 mrg }
635 1.1 mrg }
636 1.1 mrg
637 1.1 mrg return NULL_RTX;
638 1.1 mrg }
639 1.1 mrg
640 1.1 mrg /* Implements the macro INIT_CUMULATIVE_ARGS defined in cr16.h. */
641 1.1 mrg void
642 1.1 mrg cr16_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype,
643 1.1 mrg rtx libfunc ATTRIBUTE_UNUSED)
644 1.1 mrg {
645 1.1 mrg tree param, next_param;
646 1.1 mrg
647 1.1 mrg cum->ints = 0;
648 1.1 mrg
649 1.1 mrg /* Determine if this function has variable arguments. This is indicated by
650 1.1 mrg the last argument being 'void_type_mode' if there are no variable
651 1.1 mrg arguments. Change here for a different vararg. */
652 1.1 mrg for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
653 1.1 mrg param != NULL_TREE; param = next_param)
654 1.1 mrg {
655 1.1 mrg next_param = TREE_CHAIN (param);
656 1.1 mrg if ((next_param == NULL_TREE) && (TREE_VALUE (param) != void_type_node))
657 1.1 mrg {
658 1.1 mrg cum->ints = -1;
659 1.1 mrg return;
660 1.1 mrg }
661 1.1 mrg }
662 1.1 mrg }
663 1.1 mrg
664 1.1 mrg /* Implements the macro FUNCTION_ARG_ADVANCE defined in cr16.h. */
665 1.1 mrg static void
666 1.1 mrg cr16_function_arg_advance (cumulative_args_t cum_v,
667 1.1 mrg const function_arg_info &arg)
668 1.1 mrg {
669 1.1 mrg CUMULATIVE_ARGS * cum = get_cumulative_args (cum_v);
670 1.1 mrg
671 1.1 mrg /* l holds the number of registers required. */
672 1.1 mrg int l = GET_MODE_BITSIZE (arg.mode) / BITS_PER_WORD;
673 1.1 mrg
674 1.1 mrg /* If the parameter isn't passed on a register don't advance cum. */
675 1.1 mrg if (!cum->last_parm_in_reg)
676 1.1 mrg return;
677 1.1 mrg
678 1.1 mrg if (targetm.calls.must_pass_in_stack (arg) || (cum->ints < 0))
679 1.1 mrg return;
680 1.1 mrg
681 1.1 mrg if ((arg.mode == SImode) || (arg.mode == HImode)
682 1.1 mrg || (arg.mode == QImode) || (arg.mode == DImode))
683 1.1 mrg {
684 1.1 mrg if (l <= 1)
685 1.1 mrg cum->ints += 1;
686 1.1 mrg else
687 1.1 mrg cum->ints += l;
688 1.1 mrg }
689 1.1 mrg else if ((arg.mode == SFmode) || (arg.mode == DFmode))
690 1.1 mrg cum->ints += l;
691 1.1 mrg else if (arg.mode == BLKmode)
692 1.1 mrg {
693 1.1 mrg if ((l = enough_regs_for_param (cum, arg.type, arg.mode)) != 0)
694 1.1 mrg cum->ints += l;
695 1.1 mrg }
696 1.1 mrg return;
697 1.1 mrg }
698 1.1 mrg
699 1.1 mrg /* Implements the macro FUNCTION_ARG_REGNO_P defined in cr16.h.
700 1.1 mrg Return nonzero if N is a register used for passing parameters. */
701 1.1 mrg int
702 1.1 mrg cr16_function_arg_regno_p (int n)
703 1.1 mrg {
704 1.1 mrg return ((n <= MAX_REG_FOR_PASSING_ARGS) && (n >= MIN_REG_FOR_PASSING_ARGS));
705 1.1 mrg }
706 1.1 mrg
707 1.1 mrg /* Addressing modes.
708 1.1 mrg Following set of function implement the macro GO_IF_LEGITIMATE_ADDRESS
709 1.1 mrg defined in cr16.h. */
710 1.1 mrg
711 1.1 mrg /* Helper function to check if is a valid base register that can
712 1.1 mrg hold address. */
713 1.1 mrg static int
714 1.1 mrg cr16_addr_reg_p (rtx addr_reg)
715 1.1 mrg {
716 1.1 mrg rtx reg;
717 1.1 mrg
718 1.1 mrg if (REG_P (addr_reg))
719 1.1 mrg reg = addr_reg;
720 1.1 mrg else if ((GET_CODE (addr_reg) == SUBREG)
721 1.1 mrg && REG_P (SUBREG_REG (addr_reg))
722 1.1 mrg && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg)))
723 1.1 mrg <= UNITS_PER_WORD))
724 1.1 mrg reg = SUBREG_REG (addr_reg);
725 1.1 mrg else
726 1.1 mrg return FALSE;
727 1.1 mrg
728 1.1 mrg if (GET_MODE (reg) != Pmode)
729 1.1 mrg return FALSE;
730 1.1 mrg
731 1.1 mrg return TRUE;
732 1.1 mrg }
733 1.1 mrg
734 1.1 mrg /* Helper functions: Created specifically for decomposing operand of CONST
735 1.1 mrg Recursively look into expression x for code or data symbol.
736 1.1 mrg The function expects the expression to contain combination of
737 1.1 mrg SYMBOL_REF, CONST_INT, (PLUS or MINUS)
738 1.1 mrg LABEL_REF, CONST_INT, (PLUS or MINUS)
739 1.1 mrg SYMBOL_REF
740 1.1 mrg LABEL_REF
741 1.1 mrg All other combinations will result in code = -1 and data = ILLEGAL_DM
742 1.1 mrg code data
743 1.1 mrg -1 ILLEGAL_DM The expression did not contain SYMBOL_REF or LABEL_REF
744 1.1 mrg 0 DM_FAR SYMBOL_REF was found and it was far data reference.
745 1.1 mrg 0 DM_DEFAULT SYMBOL_REF was found and it was medium data reference.
746 1.1 mrg 1 ILLEGAL_DM LABEL_REF was found.
747 1.1 mrg 2 ILLEGAL_DM SYMBOL_REF was found and it was function reference. */
748 1.1 mrg void
749 1.1 mrg cr16_decompose_const (rtx x, int *code, enum data_model_type *data,
750 1.1 mrg bool treat_as_const)
751 1.1 mrg {
752 1.1 mrg *code = -1;
753 1.1 mrg *data = ILLEGAL_DM;
754 1.1 mrg switch (GET_CODE (x))
755 1.1 mrg {
756 1.1 mrg case SYMBOL_REF:
757 1.1 mrg *code = SYMBOL_REF_FUNCTION_P (x) ? 2 : 0;
758 1.1 mrg /* 2 indicates func sym. */
759 1.1 mrg if (*code == 0)
760 1.1 mrg {
761 1.1 mrg if (CR16_TARGET_DATA_NEAR)
762 1.1 mrg *data = DM_DEFAULT;
763 1.1 mrg else if (CR16_TARGET_DATA_MEDIUM)
764 1.1 mrg *data = DM_FAR;
765 1.1 mrg else if (CR16_TARGET_DATA_FAR)
766 1.1 mrg {
767 1.1 mrg if (treat_as_const)
768 1.1 mrg /* This will be used only for printing
769 1.1 mrg the qualifier. This call is (may be)
770 1.1 mrg made by cr16_print_operand_address. */
771 1.1 mrg *data = DM_FAR;
772 1.1 mrg else
773 1.1 mrg /* This call is (may be) made by
774 1.1 mrg cr16_legitimate_address_p. */
775 1.1 mrg *data = ILLEGAL_DM;
776 1.1 mrg }
777 1.1 mrg }
778 1.1 mrg return;
779 1.1 mrg
780 1.1 mrg case LABEL_REF:
781 1.1 mrg /* 1 - indicates non-function symbol. */
782 1.1 mrg *code = 1;
783 1.1 mrg return;
784 1.1 mrg
785 1.1 mrg case PLUS:
786 1.1 mrg case MINUS:
787 1.1 mrg /* Look into the tree nodes. */
788 1.1 mrg if (GET_CODE (XEXP (x, 0)) == CONST_INT)
789 1.1 mrg cr16_decompose_const (XEXP (x, 1), code, data, treat_as_const);
790 1.1 mrg else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
791 1.1 mrg cr16_decompose_const (XEXP (x, 0), code, data, treat_as_const);
792 1.1 mrg return;
793 1.1 mrg default:
794 1.1 mrg return;
795 1.1 mrg }
796 1.1 mrg }
797 1.1 mrg
798 1.1 mrg /* Decompose Address
799 1.1 mrg This function decomposes the address returns the type of address
800 1.1 mrg as defined in enum cr16_addrtype. It also fills the parameter *out.
801 1.1 mrg The decomposed address can be used for two purposes. One to
802 1.1 mrg check if the address is valid and second to print the address
803 1.1 mrg operand.
804 1.1 mrg
805 1.1 mrg Following tables list valid address supported in CR16C/C+ architectures.
806 1.1 mrg Legend:
807 1.1 mrg aN : Absoulte address N-bit address
808 1.1 mrg R : One 16-bit register
809 1.1 mrg RP : Consecutive two 16-bit registers or one 32-bit register
810 1.1 mrg I : One 32-bit register
811 1.1 mrg dispN : Signed displacement of N-bits
812 1.1 mrg
813 1.1 mrg ----Code addresses----
814 1.1 mrg Branch operands:
815 1.1 mrg disp9 : CR16_ABSOLUTE (disp)
816 1.1 mrg disp17 : CR16_ABSOLUTE (disp)
817 1.1 mrg disp25 : CR16_ABSOLUTE (disp)
818 1.1 mrg RP + disp25 : CR16_REGP_REL (base, disp)
819 1.1 mrg
820 1.1 mrg Jump operands:
821 1.1 mrg RP : CR16_REGP_REL (base, disp=0)
822 1.1 mrg a24 : CR16_ABSOLUTE (disp)
823 1.1 mrg
824 1.1 mrg ----Data addresses----
825 1.1 mrg a20 : CR16_ABSOLUTE (disp) near (1M)
826 1.1 mrg a24 : CR16_ABSOLUTE (disp) medium (16M)
827 1.1 mrg R + d20 : CR16_REG_REL (base, disp) near (1M+64K)
828 1.1 mrg RP + d4 : CR16_REGP_REL (base, disp) far (4G)
829 1.1 mrg RP + d16 : CR16_REGP_REL (base, disp) far (4G)
830 1.1 mrg RP + d20 : CR16_REGP_REL (base, disp) far (4G)
831 1.1 mrg I : *** Valid but port does not support this
832 1.1 mrg I + a20 : *** Valid but port does not support this
833 1.1 mrg I + RP + d14: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
834 1.1 mrg I + RP + d20: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
835 1.1 mrg
836 1.1 mrg Decomposing Data model in case of absolute address.
837 1.1 mrg
838 1.1 mrg Target Option Address type Resultant Data ref type
839 1.1 mrg ---------------------- ------------ -----------------------
840 1.1 mrg CR16_TARGET_MODEL_NEAR ABS20 DM_DEFAULT
841 1.1 mrg CR16_TARGET_MODEL_NEAR IMM20 DM_DEFAULT
842 1.1 mrg CR16_TARGET_MODEL_NEAR ABS24 Invalid
843 1.1 mrg CR16_TARGET_MODEL_NEAR IMM32 Invalid
844 1.1 mrg
845 1.1 mrg CR16_TARGET_MODEL_MEDIUM ABS20 DM_DEFAULT
846 1.1 mrg CR16_TARGET_MODEL_MEDIUM IMM20 DM_DEFAULT
847 1.1 mrg CR16_TARGET_MODEL_MEDIUM ABS24 DM_FAR
848 1.1 mrg CR16_TARGET_MODEL_MEDIUM IMM32 Invalid
849 1.1 mrg
850 1.1 mrg CR16_TARGET_MODEL_FAR ABS20 DM_DEFAULT
851 1.1 mrg CR16_TARGET_MODEL_FAR IMM20 DM_DEFAULT
852 1.1 mrg CR16_TARGET_MODEL_FAR ABS24 DM_FAR
853 1.1 mrg CR16_TARGET_MODEL_FAR IMM32 DM_FAR. */
854 1.1 mrg enum cr16_addrtype
855 1.1 mrg cr16_decompose_address (rtx addr, struct cr16_address *out,
856 1.1 mrg bool debug_print, bool treat_as_const)
857 1.1 mrg {
858 1.1 mrg rtx base = NULL_RTX, disp = NULL_RTX, index = NULL_RTX;
859 1.1 mrg enum data_model_type data = ILLEGAL_DM;
860 1.1 mrg int code = -1;
861 1.1 mrg enum cr16_addrtype retval = CR16_INVALID;
862 1.1 mrg
863 1.1 mrg switch (GET_CODE (addr))
864 1.1 mrg {
865 1.1 mrg case CONST_INT:
866 1.1 mrg /* Absolute address (known at compile time). */
867 1.1 mrg code = 0;
868 1.1 mrg if (debug_print)
869 1.1 mrg fprintf (stderr, "\ncode:%d", code);
870 1.1 mrg disp = addr;
871 1.1 mrg
872 1.1 mrg if (debug_print)
873 1.1 mrg {
874 1.1 mrg fprintf (stderr, "\ndisp:");
875 1.1 mrg debug_rtx (disp);
876 1.1 mrg }
877 1.1 mrg
878 1.1 mrg if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
879 1.1 mrg {
880 1.1 mrg data = DM_DEFAULT;
881 1.1 mrg if (debug_print)
882 1.1 mrg fprintf (stderr, "\ndata:%d", data);
883 1.1 mrg retval = CR16_ABSOLUTE;
884 1.1 mrg }
885 1.1 mrg else if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 24))
886 1.1 mrg {
887 1.1 mrg if (!CR16_TARGET_DATA_NEAR)
888 1.1 mrg {
889 1.1 mrg data = DM_FAR;
890 1.1 mrg if (debug_print)
891 1.1 mrg fprintf (stderr, "\ndata:%d", data);
892 1.1 mrg retval = CR16_ABSOLUTE;
893 1.1 mrg }
894 1.1 mrg else
895 1.1 mrg return CR16_INVALID; /* ABS24 is not support in NEAR model. */
896 1.1 mrg }
897 1.1 mrg else
898 1.1 mrg return CR16_INVALID;
899 1.1 mrg break;
900 1.1 mrg
901 1.1 mrg case CONST:
902 1.1 mrg /* A CONST is an expression of PLUS or MINUS with
903 1.1 mrg CONST_INT, SYMBOL_REF or LABEL_REF. This is the
904 1.1 mrg result of assembly-time arithmetic computation. */
905 1.1 mrg retval = CR16_ABSOLUTE;
906 1.1 mrg disp = addr;
907 1.1 mrg /* Call the helper function to check the validity. */
908 1.1 mrg cr16_decompose_const (XEXP (addr, 0), &code, &data, treat_as_const);
909 1.1 mrg if ((code == 0) && (data == ILLEGAL_DM))
910 1.1 mrg /* CONST is not valid code or data address. */
911 1.1 mrg return CR16_INVALID;
912 1.1 mrg if (debug_print)
913 1.1 mrg {
914 1.1 mrg fprintf (stderr, "\ndisp:");
915 1.1 mrg debug_rtx (disp);
916 1.1 mrg fprintf (stderr, "\ncode:%d", code);
917 1.1 mrg fprintf (stderr, "\ndata:%d", data);
918 1.1 mrg }
919 1.1 mrg break;
920 1.1 mrg
921 1.1 mrg case LABEL_REF:
922 1.1 mrg retval = CR16_ABSOLUTE;
923 1.1 mrg disp = addr;
924 1.1 mrg /* 1 - indicates non-function symbol. */
925 1.1 mrg code = 1;
926 1.1 mrg if (debug_print)
927 1.1 mrg {
928 1.1 mrg fprintf (stderr, "\ndisp:");
929 1.1 mrg debug_rtx (disp);
930 1.1 mrg fprintf (stderr, "\ncode:%d", code);
931 1.1 mrg }
932 1.1 mrg break;
933 1.1 mrg
934 1.1 mrg case SYMBOL_REF:
935 1.1 mrg /* Absolute address (known at link time). */
936 1.1 mrg retval = CR16_ABSOLUTE;
937 1.1 mrg disp = addr;
938 1.1 mrg /* This is a code address if symbol_ref is a function. */
939 1.1 mrg /* 2 indicates func sym. */
940 1.1 mrg code = SYMBOL_REF_FUNCTION_P (addr) ? 2 : 0;
941 1.1 mrg if (debug_print)
942 1.1 mrg {
943 1.1 mrg fprintf (stderr, "\ndisp:");
944 1.1 mrg debug_rtx (disp);
945 1.1 mrg fprintf (stderr, "\ncode:%d", code);
946 1.1 mrg }
947 1.1 mrg /* If not function ref then check if valid data ref. */
948 1.1 mrg if (code == 0)
949 1.1 mrg {
950 1.1 mrg if (CR16_TARGET_DATA_NEAR)
951 1.1 mrg data = DM_DEFAULT;
952 1.1 mrg else if (CR16_TARGET_DATA_MEDIUM)
953 1.1 mrg data = DM_FAR;
954 1.1 mrg else if (CR16_TARGET_DATA_FAR)
955 1.1 mrg {
956 1.1 mrg if (treat_as_const)
957 1.1 mrg /* This will be used only for printing the
958 1.1 mrg qualifier. This call is (may be) made
959 1.1 mrg by cr16_print_operand_address. */
960 1.1 mrg data = DM_FAR;
961 1.1 mrg else
962 1.1 mrg /* This call is (may be) made by
963 1.1 mrg cr16_legitimate_address_p. */
964 1.1 mrg return CR16_INVALID;
965 1.1 mrg }
966 1.1 mrg else
967 1.1 mrg data = DM_DEFAULT;
968 1.1 mrg }
969 1.1 mrg if (debug_print)
970 1.1 mrg fprintf (stderr, "\ndata:%d", data);
971 1.1 mrg break;
972 1.1 mrg
973 1.1 mrg case REG:
974 1.1 mrg case SUBREG:
975 1.1 mrg /* Register relative address. */
976 1.1 mrg /* Assume REG fits in a single register. */
977 1.1 mrg retval = CR16_REG_REL;
978 1.1 mrg if (GET_MODE_BITSIZE (GET_MODE (addr)) > BITS_PER_WORD)
979 1.1 mrg if (!LONG_REG_P (REGNO (addr)))
980 1.1 mrg /* REG will result in reg pair. */
981 1.1 mrg retval = CR16_REGP_REL;
982 1.1 mrg base = addr;
983 1.1 mrg if (debug_print)
984 1.1 mrg {
985 1.1 mrg fprintf (stderr, "\nbase:");
986 1.1 mrg debug_rtx (base);
987 1.1 mrg }
988 1.1 mrg break;
989 1.1 mrg
990 1.1 mrg case PLUS:
991 1.1 mrg switch (GET_CODE (XEXP (addr, 0)))
992 1.1 mrg {
993 1.1 mrg case REG:
994 1.1 mrg case SUBREG:
995 1.1 mrg /* REG + DISP20. */
996 1.1 mrg /* All Reg relative addresses having a displacement needs
997 1.1 mrg to fit in 20-bits. */
998 1.1 mrg disp = XEXP (addr, 1);
999 1.1 mrg if (debug_print)
1000 1.1 mrg {
1001 1.1 mrg fprintf (stderr, "\ndisp:");
1002 1.1 mrg debug_rtx (disp);
1003 1.1 mrg }
1004 1.1 mrg switch (GET_CODE (XEXP (addr, 1)))
1005 1.1 mrg {
1006 1.1 mrg case CONST_INT:
1007 1.1 mrg /* Shall fit in 20-bits. */
1008 1.1 mrg if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
1009 1.1 mrg return CR16_INVALID;
1010 1.1 mrg code = 0;
1011 1.1 mrg if (debug_print)
1012 1.1 mrg fprintf (stderr, "\ncode:%d", code);
1013 1.1 mrg break;
1014 1.1 mrg
1015 1.1 mrg case UNSPEC:
1016 1.1 mrg switch (XINT (XEXP (addr, 1), 1))
1017 1.1 mrg {
1018 1.1 mrg case UNSPEC_LIBRARY_OFFSET:
1019 1.1 mrg default:
1020 1.1 mrg gcc_unreachable ();
1021 1.1 mrg }
1022 1.1 mrg break;
1023 1.1 mrg
1024 1.1 mrg case LABEL_REF:
1025 1.1 mrg case SYMBOL_REF:
1026 1.1 mrg case CONST:
1027 1.1 mrg /* This is also a valid expression for address.
1028 1.1 mrg However, we cannot ascertain if the resultant
1029 1.1 mrg displacement will be valid 20-bit value. Therefore,
1030 1.1 mrg lets not allow such an expression for now. This will
1031 1.1 mrg be updated when we find a way to validate this
1032 1.1 mrg expression as legitimate address.
1033 1.1 mrg Till then fall through CR16_INVALID. */
1034 1.1 mrg default:
1035 1.1 mrg return CR16_INVALID;
1036 1.1 mrg }
1037 1.1 mrg
1038 1.1 mrg /* Now check if REG can fit into single or pair regs. */
1039 1.1 mrg retval = CR16_REG_REL;
1040 1.1 mrg base = XEXP (addr, 0);
1041 1.1 mrg if (debug_print)
1042 1.1 mrg {
1043 1.1 mrg fprintf (stderr, "\nbase:");
1044 1.1 mrg debug_rtx (base);
1045 1.1 mrg }
1046 1.1 mrg if (GET_MODE_BITSIZE (GET_MODE ((XEXP (addr, 0)))) > BITS_PER_WORD)
1047 1.1 mrg {
1048 1.1 mrg if (!LONG_REG_P (REGNO ((XEXP (addr, 0)))))
1049 1.1 mrg /* REG will result in reg pair. */
1050 1.1 mrg retval = CR16_REGP_REL;
1051 1.1 mrg }
1052 1.1 mrg break;
1053 1.1 mrg
1054 1.1 mrg case PLUS:
1055 1.1 mrg /* Valid expr:
1056 1.1 mrg plus
1057 1.1 mrg /\
1058 1.1 mrg / \
1059 1.1 mrg plus idx
1060 1.1 mrg /\
1061 1.1 mrg / \
1062 1.1 mrg reg const_int
1063 1.1 mrg
1064 1.1 mrg Check if the operand 1 is valid index register. */
1065 1.1 mrg data = ILLEGAL_DM;
1066 1.1 mrg if (debug_print)
1067 1.1 mrg fprintf (stderr, "\ndata:%d", data);
1068 1.1 mrg switch (GET_CODE (XEXP (addr, 1)))
1069 1.1 mrg {
1070 1.1 mrg case REG:
1071 1.1 mrg case SUBREG:
1072 1.1 mrg if (!REG_OK_FOR_INDEX_P (XEXP (addr, 1)))
1073 1.1 mrg return CR16_INVALID;
1074 1.1 mrg /* OK. REG is a valid index register. */
1075 1.1 mrg index = XEXP (addr, 1);
1076 1.1 mrg if (debug_print)
1077 1.1 mrg {
1078 1.1 mrg fprintf (stderr, "\nindex:");
1079 1.1 mrg debug_rtx (index);
1080 1.1 mrg }
1081 1.1 mrg break;
1082 1.1 mrg default:
1083 1.1 mrg return CR16_INVALID;
1084 1.1 mrg }
1085 1.1 mrg /* Check if operand 0 of operand 0 is REGP. */
1086 1.1 mrg switch (GET_CODE (XEXP (XEXP (addr, 0), 0)))
1087 1.1 mrg {
1088 1.1 mrg case REG:
1089 1.1 mrg case SUBREG:
1090 1.1 mrg /* Now check if REG is a REGP and not in LONG regs. */
1091 1.1 mrg if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (addr, 0), 0)))
1092 1.1 mrg > BITS_PER_WORD)
1093 1.1 mrg {
1094 1.1 mrg if (REGNO (XEXP (XEXP (addr, 0), 0))
1095 1.1 mrg >= CR16_FIRST_DWORD_REGISTER)
1096 1.1 mrg return CR16_INVALID;
1097 1.1 mrg base = XEXP (XEXP (addr, 0), 0);
1098 1.1 mrg if (debug_print)
1099 1.1 mrg {
1100 1.1 mrg fprintf (stderr, "\nbase:");
1101 1.1 mrg debug_rtx (base);
1102 1.1 mrg }
1103 1.1 mrg }
1104 1.1 mrg else
1105 1.1 mrg return CR16_INVALID;
1106 1.1 mrg break;
1107 1.1 mrg default:
1108 1.1 mrg return CR16_INVALID;
1109 1.1 mrg }
1110 1.1 mrg /* Now check if the operand 1 of operand 0 is const_int. */
1111 1.1 mrg if (GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
1112 1.1 mrg {
1113 1.1 mrg disp = XEXP (XEXP (addr, 0), 1);
1114 1.1 mrg if (debug_print)
1115 1.1 mrg {
1116 1.1 mrg fprintf (stderr, "\ndisp:");
1117 1.1 mrg debug_rtx (disp);
1118 1.1 mrg }
1119 1.1 mrg if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
1120 1.1 mrg return CR16_INVALID;
1121 1.1 mrg }
1122 1.1 mrg else
1123 1.1 mrg return CR16_INVALID;
1124 1.1 mrg retval = CR16_INDEX_REGP_REL;
1125 1.1 mrg break;
1126 1.1 mrg default:
1127 1.1 mrg return CR16_INVALID;
1128 1.1 mrg }
1129 1.1 mrg break;
1130 1.1 mrg
1131 1.1 mrg default:
1132 1.1 mrg return CR16_INVALID;
1133 1.1 mrg }
1134 1.1 mrg
1135 1.1 mrg /* Check if the base and index registers are valid. */
1136 1.1 mrg if (base && !(cr16_addr_reg_p (base)))
1137 1.1 mrg return CR16_INVALID;
1138 1.1 mrg if (base && !(CR16_REG_OK_FOR_BASE_P (base)))
1139 1.1 mrg return CR16_INVALID;
1140 1.1 mrg if (index && !(REG_OK_FOR_INDEX_P (index)))
1141 1.1 mrg return CR16_INVALID;
1142 1.1 mrg
1143 1.1 mrg /* Write the decomposition to out parameter. */
1144 1.1 mrg out->base = base;
1145 1.1 mrg out->disp = disp;
1146 1.1 mrg out->index = index;
1147 1.1 mrg out->data = data;
1148 1.1 mrg out->code = code;
1149 1.1 mrg
1150 1.1 mrg return retval;
1151 1.1 mrg }
1152 1.1 mrg
1153 1.1 mrg /* Return non-zero value if 'x' is legitimate PIC operand
1154 1.1 mrg when generating PIC code. */
1155 1.1 mrg int
1156 1.1 mrg legitimate_pic_operand_p (rtx x)
1157 1.1 mrg {
1158 1.1 mrg switch (GET_CODE (x))
1159 1.1 mrg {
1160 1.1 mrg case SYMBOL_REF:
1161 1.1 mrg return 0;
1162 1.1 mrg case LABEL_REF:
1163 1.1 mrg return 0;
1164 1.1 mrg case CONST:
1165 1.1 mrg /* REVISIT: Use something like symbol_referenced_p. */
1166 1.1 mrg if (GET_CODE (XEXP (x, 0)) == PLUS
1167 1.1 mrg && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
1168 1.1 mrg || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
1169 1.1 mrg && (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
1170 1.1 mrg return 0;
1171 1.1 mrg break;
1172 1.1 mrg case MEM:
1173 1.1 mrg return legitimate_pic_operand_p (XEXP (x, 0));
1174 1.1 mrg default:
1175 1.1 mrg break;
1176 1.1 mrg }
1177 1.1 mrg return 1;
1178 1.1 mrg }
1179 1.1 mrg
1180 1.1 mrg /* Convert a non-PIC address in `orig' to a PIC address in `reg'.
1181 1.1 mrg
1182 1.1 mrg Input Output (-f pic) Output (-f PIC)
1183 1.1 mrg orig reg
1184 1.1 mrg
1185 1.1 mrg C1 symbol symbol@BRO (r12) symbol@GOT (r12)
1186 1.1 mrg
1187 1.1 mrg C2 symbol + offset symbol+offset@BRO (r12) symbol+offset@GOT (r12)
1188 1.1 mrg
1189 1.1 mrg NOTE: @BRO is added using unspec:BRO
1190 1.1 mrg NOTE: @GOT is added using unspec:GOT. */
1191 1.1 mrg rtx
1192 1.1 mrg legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
1193 1.1 mrg rtx reg)
1194 1.1 mrg {
1195 1.1 mrg /* First handle a simple SYMBOL_REF or LABEL_REF. */
1196 1.1 mrg if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
1197 1.1 mrg {
1198 1.1 mrg if (reg == 0)
1199 1.1 mrg reg = gen_reg_rtx (Pmode);
1200 1.1 mrg
1201 1.1 mrg if (flag_pic == NEAR_PIC)
1202 1.1 mrg {
1203 1.1 mrg /* Unspec to handle -fpic option. */
1204 1.1 mrg emit_insn (gen_unspec_bro_addr (reg, orig));
1205 1.1 mrg emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx));
1206 1.1 mrg }
1207 1.1 mrg else if (flag_pic == FAR_PIC)
1208 1.1 mrg {
1209 1.1 mrg /* Unspec to handle -fPIC option. */
1210 1.1 mrg emit_insn (gen_unspec_got_addr (reg, orig));
1211 1.1 mrg }
1212 1.1 mrg return reg;
1213 1.1 mrg }
1214 1.1 mrg else if (GET_CODE (orig) == CONST)
1215 1.1 mrg {
1216 1.1 mrg /* To handle (symbol + offset). */
1217 1.1 mrg rtx base, offset;
1218 1.1 mrg
1219 1.1 mrg if (GET_CODE (XEXP (orig, 0)) == PLUS
1220 1.1 mrg && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1221 1.1 mrg return orig;
1222 1.1 mrg
1223 1.1 mrg if (reg == 0)
1224 1.1 mrg {
1225 1.1 mrg gcc_assert (can_create_pseudo_p ());
1226 1.1 mrg reg = gen_reg_rtx (Pmode);
1227 1.1 mrg }
1228 1.1 mrg
1229 1.1 mrg gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
1230 1.1 mrg
1231 1.1 mrg base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
1232 1.1 mrg offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1233 1.1 mrg base == reg ? 0 : reg);
1234 1.1 mrg
1235 1.1 mrg /* REVISIT: Optimize for const-offsets. */
1236 1.1 mrg emit_insn (gen_addsi3 (reg, base, offset));
1237 1.1 mrg
1238 1.1 mrg return reg;
1239 1.1 mrg }
1240 1.1 mrg return orig;
1241 1.1 mrg }
1242 1.1 mrg
1243 1.1 mrg /* Implementation of TARGET_LEGITIMATE_ADDRESS_P. */
1244 1.1 mrg static bool
1245 1.1 mrg cr16_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
1246 1.1 mrg rtx addr, bool strict)
1247 1.1 mrg {
1248 1.1 mrg enum cr16_addrtype addrtype;
1249 1.1 mrg struct cr16_address address;
1250 1.1 mrg
1251 1.1 mrg if (TARGET_DEBUG_ADDR)
1252 1.1 mrg {
1253 1.1 mrg fprintf (stderr,
1254 1.1 mrg "\n======\nTARGET_LEGITIMATE_ADDRESS_P, mode = %s, strict = %d",
1255 1.1 mrg GET_MODE_NAME (mode), strict);
1256 1.1 mrg debug_rtx (addr);
1257 1.1 mrg }
1258 1.1 mrg addrtype = cr16_decompose_address (addr, &address,
1259 1.1 mrg (TARGET_DEBUG_ADDR ? 1 : 0), FALSE);
1260 1.1 mrg
1261 1.1 mrg if (TARGET_DEBUG_ADDR)
1262 1.1 mrg {
1263 1.1 mrg const char *typestr;
1264 1.1 mrg
1265 1.1 mrg switch (addrtype)
1266 1.1 mrg {
1267 1.1 mrg case CR16_INVALID:
1268 1.1 mrg typestr = "invalid";
1269 1.1 mrg break;
1270 1.1 mrg case CR16_ABSOLUTE:
1271 1.1 mrg typestr = "absolute";
1272 1.1 mrg break;
1273 1.1 mrg case CR16_REG_REL:
1274 1.1 mrg typestr = "register relative";
1275 1.1 mrg break;
1276 1.1 mrg case CR16_REGP_REL:
1277 1.1 mrg typestr = "register pair relative";
1278 1.1 mrg break;
1279 1.1 mrg case CR16_INDEX_REGP_REL:
1280 1.1 mrg typestr = "index + register pair relative";
1281 1.1 mrg break;
1282 1.1 mrg default:
1283 1.1 mrg gcc_unreachable ();
1284 1.1 mrg }
1285 1.1 mrg fprintf (stderr, "\ncr16 address type: %s\n", typestr);
1286 1.1 mrg }
1287 1.1 mrg
1288 1.1 mrg if (addrtype == CR16_INVALID)
1289 1.1 mrg return FALSE;
1290 1.1 mrg
1291 1.1 mrg if (strict)
1292 1.1 mrg {
1293 1.1 mrg if (address.base
1294 1.1 mrg && !REGNO_MODE_OK_FOR_BASE_P (REGNO (address.base), mode))
1295 1.1 mrg {
1296 1.1 mrg if (TARGET_DEBUG_ADDR)
1297 1.1 mrg fprintf (stderr, "base register not strict\n");
1298 1.1 mrg return FALSE;
1299 1.1 mrg }
1300 1.1 mrg if (address.index && !REGNO_OK_FOR_INDEX_P (REGNO (address.index)))
1301 1.1 mrg {
1302 1.1 mrg if (TARGET_DEBUG_ADDR)
1303 1.1 mrg fprintf (stderr, "index register not strict\n");
1304 1.1 mrg return FALSE;
1305 1.1 mrg }
1306 1.1 mrg }
1307 1.1 mrg
1308 1.1 mrg /* Return true if addressing mode is register relative. */
1309 1.1 mrg if (flag_pic)
1310 1.1 mrg {
1311 1.1 mrg if (addrtype == CR16_REG_REL || addrtype == CR16_REGP_REL)
1312 1.1 mrg return TRUE;
1313 1.1 mrg else
1314 1.1 mrg return FALSE;
1315 1.1 mrg }
1316 1.1 mrg
1317 1.1 mrg return TRUE;
1318 1.1 mrg }
1319 1.1 mrg
1320 1.1 mrg /* Routines to compute costs. */
1321 1.1 mrg
1322 1.1 mrg /* Return cost of the memory address x. */
1323 1.1 mrg static int
1324 1.1 mrg cr16_address_cost (rtx addr, machine_mode mode ATTRIBUTE_UNUSED,
1325 1.1 mrg addr_space_t as ATTRIBUTE_UNUSED,
1326 1.1 mrg bool speed ATTRIBUTE_UNUSED)
1327 1.1 mrg {
1328 1.1 mrg enum cr16_addrtype addrtype;
1329 1.1 mrg struct cr16_address address;
1330 1.1 mrg int cost = 2;
1331 1.1 mrg
1332 1.1 mrg addrtype = cr16_decompose_address (addr, &address, 0, FALSE);
1333 1.1 mrg
1334 1.1 mrg gcc_assert (addrtype != CR16_INVALID);
1335 1.1 mrg
1336 1.1 mrg /* CR16_ABSOLUTE : 3
1337 1.1 mrg CR16_REG_REL (disp !=0) : 4
1338 1.1 mrg CR16_REG_REL (disp ==0) : 5
1339 1.1 mrg CR16_REGP_REL (disp !=0) : 6
1340 1.1 mrg CR16_REGP_REL (disp ==0) : 7
1341 1.1 mrg CR16_INDEX_REGP_REL (disp !=0) : 8
1342 1.1 mrg CR16_INDEX_REGP_REL (disp ==0) : 9. */
1343 1.1 mrg switch (addrtype)
1344 1.1 mrg {
1345 1.1 mrg case CR16_ABSOLUTE:
1346 1.1 mrg cost += 1;
1347 1.1 mrg break;
1348 1.1 mrg case CR16_REGP_REL:
1349 1.1 mrg cost += 2;
1350 1.1 mrg /* Fall through. */
1351 1.1 mrg case CR16_REG_REL:
1352 1.1 mrg cost += 3;
1353 1.1 mrg if (address.disp)
1354 1.1 mrg cost -= 1;
1355 1.1 mrg break;
1356 1.1 mrg case CR16_INDEX_REGP_REL:
1357 1.1 mrg cost += 7;
1358 1.1 mrg if (address.disp)
1359 1.1 mrg cost -= 1;
1360 1.1 mrg default:
1361 1.1 mrg break;
1362 1.1 mrg }
1363 1.1 mrg
1364 1.1 mrg if (TARGET_DEBUG_ADDR)
1365 1.1 mrg {
1366 1.1 mrg fprintf (stderr, "\n======\nmacro TARGET_ADDRESS_COST = %d\n", cost);
1367 1.1 mrg debug_rtx (addr);
1368 1.1 mrg }
1369 1.1 mrg
1370 1.1 mrg return cost;
1371 1.1 mrg }
1372 1.1 mrg
1373 1.1 mrg
1374 1.1 mrg /* Implement `TARGET_REGISTER_MOVE_COST'. */
1375 1.1 mrg static int
1376 1.1 mrg cr16_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
1377 1.1 mrg reg_class_t from ATTRIBUTE_UNUSED, reg_class_t to)
1378 1.1 mrg {
1379 1.1 mrg return (to != GENERAL_REGS ? 8 : 2);
1380 1.1 mrg }
1381 1.1 mrg
1382 1.1 mrg /* Implement `TARGET_MEMORY_MOVE_COST'. */
1383 1.1 mrg
1384 1.1 mrg /* Return the cost of moving data of mode MODE between a register of class
1385 1.1 mrg CLASS and memory; IN is zero if the value is to be written to memory,
1386 1.1 mrg nonzero if it is to be read in. This cost is relative to those in
1387 1.1 mrg REGISTER_MOVE_COST. */
1388 1.1 mrg static int
1389 1.1 mrg cr16_memory_move_cost (machine_mode mode,
1390 1.1 mrg reg_class_t rclass ATTRIBUTE_UNUSED,
1391 1.1 mrg bool in ATTRIBUTE_UNUSED)
1392 1.1 mrg {
1393 1.1 mrg /* One LD or ST takes twice the time of a simple reg-reg move. */
1394 1.1 mrg if (reg_classes_intersect_p (rclass, GENERAL_REGS))
1395 1.1 mrg return (4 * cr16_hard_regno_nregs (0, mode));
1396 1.1 mrg else
1397 1.1 mrg return (100);
1398 1.1 mrg }
1399 1.1 mrg
1400 1.1 mrg /* Instruction output. */
1401 1.1 mrg
1402 1.1 mrg /* Check if a const_double is ok for cr16 store-immediate instructions. */
1403 1.1 mrg int
1404 1.1 mrg cr16_const_double_ok (rtx op)
1405 1.1 mrg {
1406 1.1 mrg if (GET_MODE (op) == SFmode)
1407 1.1 mrg {
1408 1.1 mrg long l;
1409 1.1 mrg REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op), l);
1410 1.1 mrg return UNSIGNED_INT_FITS_N_BITS (l, 4) ? 1 : 0;
1411 1.1 mrg }
1412 1.1 mrg
1413 1.1 mrg return ((UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op), 4)) &&
1414 1.1 mrg (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op), 4))) ? 1 : 0;
1415 1.1 mrg }
1416 1.1 mrg
1417 1.1 mrg /* Returns bit position of first 0 or 1 bit.
1418 1.1 mrg It is safe to assume val as 16-bit wide. */
1419 1.1 mrg int
1420 1.1 mrg cr16_operand_bit_pos (int val, int bitval)
1421 1.1 mrg {
1422 1.1 mrg int i;
1423 1.1 mrg if (bitval == 0)
1424 1.1 mrg val = ~val;
1425 1.1 mrg
1426 1.1 mrg for (i = 0; i < 16; i++)
1427 1.1 mrg if (val & (1 << i))
1428 1.1 mrg break;
1429 1.1 mrg return i;
1430 1.1 mrg }
1431 1.1 mrg
1432 1.1 mrg /* Implements the macro PRINT_OPERAND defined in cr16.h. */
1433 1.1 mrg static void
1434 1.1 mrg cr16_print_operand (FILE * file, rtx x, int code)
1435 1.1 mrg {
1436 1.1 mrg int ptr_dereference = 0;
1437 1.1 mrg
1438 1.1 mrg switch (code)
1439 1.1 mrg {
1440 1.1 mrg case 'd':
1441 1.1 mrg {
1442 1.1 mrg const char *cr16_cmp_str;
1443 1.1 mrg switch (GET_CODE (x))
1444 1.1 mrg {
1445 1.1 mrg /* MD: compare (reg, reg or imm) but CR16: cmp (reg or imm, reg)
1446 1.1 mrg -> swap all non symmetric ops. */
1447 1.1 mrg case EQ:
1448 1.1 mrg cr16_cmp_str = "eq";
1449 1.1 mrg break;
1450 1.1 mrg case NE:
1451 1.1 mrg cr16_cmp_str = "ne";
1452 1.1 mrg break;
1453 1.1 mrg case GT:
1454 1.1 mrg cr16_cmp_str = "lt";
1455 1.1 mrg break;
1456 1.1 mrg case GTU:
1457 1.1 mrg cr16_cmp_str = "lo";
1458 1.1 mrg break;
1459 1.1 mrg case LT:
1460 1.1 mrg cr16_cmp_str = "gt";
1461 1.1 mrg break;
1462 1.1 mrg case LTU:
1463 1.1 mrg cr16_cmp_str = "hi";
1464 1.1 mrg break;
1465 1.1 mrg case GE:
1466 1.1 mrg cr16_cmp_str = "le";
1467 1.1 mrg break;
1468 1.1 mrg case GEU:
1469 1.1 mrg cr16_cmp_str = "ls";
1470 1.1 mrg break;
1471 1.1 mrg case LE:
1472 1.1 mrg cr16_cmp_str = "ge";
1473 1.1 mrg break;
1474 1.1 mrg case LEU:
1475 1.1 mrg cr16_cmp_str = "hs";
1476 1.1 mrg break;
1477 1.1 mrg default:
1478 1.1 mrg gcc_unreachable ();
1479 1.1 mrg }
1480 1.1 mrg fprintf (file, "%s", cr16_cmp_str);
1481 1.1 mrg return;
1482 1.1 mrg }
1483 1.1 mrg case '$':
1484 1.1 mrg putc ('$', file);
1485 1.1 mrg return;
1486 1.1 mrg
1487 1.1 mrg case 'p':
1488 1.1 mrg if (GET_CODE (x) == REG)
1489 1.1 mrg {
1490 1.1 mrg /* For Push instructions, we should not print register pairs. */
1491 1.1 mrg fprintf (file, "%s", reg_names[REGNO (x)]);
1492 1.1 mrg return;
1493 1.1 mrg }
1494 1.1 mrg break;
1495 1.1 mrg
1496 1.1 mrg case 'b':
1497 1.1 mrg /* Print the immediate address for bal
1498 1.1 mrg 'b' is used instead of 'a' to avoid compiler calling
1499 1.1 mrg the GO_IF_LEGITIMATE_ADDRESS which cannot
1500 1.1 mrg perform checks on const_int code addresses as it
1501 1.1 mrg assumes all const_int are data addresses. */
1502 1.1 mrg fprintf (file, "0x%lx", INTVAL (x));
1503 1.1 mrg return;
1504 1.1 mrg
1505 1.1 mrg case 'r':
1506 1.1 mrg /* Print bit position of first 0. */
1507 1.1 mrg fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 0));
1508 1.1 mrg return;
1509 1.1 mrg
1510 1.1 mrg case 's':
1511 1.1 mrg /* Print bit position of first 1. */
1512 1.1 mrg fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 1));
1513 1.1 mrg return;
1514 1.1 mrg case 'g':
1515 1.1 mrg /* 'g' is used for implicit mem: dereference. */
1516 1.1 mrg ptr_dereference = 1;
1517 1.1 mrg /* FALLTHRU */
1518 1.1 mrg case 'f':
1519 1.1 mrg case 0:
1520 1.1 mrg /* default. */
1521 1.1 mrg switch (GET_CODE (x))
1522 1.1 mrg {
1523 1.1 mrg case REG:
1524 1.1 mrg if (GET_MODE_BITSIZE (GET_MODE (x)) > BITS_PER_WORD)
1525 1.1 mrg {
1526 1.1 mrg if (LONG_REG_P (REGNO (x)))
1527 1.1 mrg fprintf (file, "(%s)", reg_names[REGNO (x)]);
1528 1.1 mrg else
1529 1.1 mrg fprintf (file, "(%s,%s)", reg_names[REGNO (x) + 1],
1530 1.1 mrg reg_names[REGNO (x)]);
1531 1.1 mrg }
1532 1.1 mrg else
1533 1.1 mrg fprintf (file, "%s", reg_names[REGNO (x)]);
1534 1.1 mrg return;
1535 1.1 mrg
1536 1.1 mrg case MEM:
1537 1.1 mrg output_address (GET_MODE (x), XEXP (x, 0));
1538 1.1 mrg return;
1539 1.1 mrg
1540 1.1 mrg case CONST_DOUBLE:
1541 1.1 mrg {
1542 1.1 mrg long l;
1543 1.1 mrg
1544 1.1 mrg REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
1545 1.1 mrg
1546 1.1 mrg fprintf (file, "$0x%lx", l);
1547 1.1 mrg return;
1548 1.1 mrg }
1549 1.1 mrg case CONST_INT:
1550 1.1 mrg {
1551 1.1 mrg fprintf (file, "$%ld", INTVAL (x));
1552 1.1 mrg return;
1553 1.1 mrg }
1554 1.1 mrg case UNSPEC:
1555 1.1 mrg switch (XINT (x, 1))
1556 1.1 mrg {
1557 1.1 mrg default:
1558 1.1 mrg gcc_unreachable ();
1559 1.1 mrg }
1560 1.1 mrg break;
1561 1.1 mrg
1562 1.1 mrg default:
1563 1.1 mrg if (!ptr_dereference)
1564 1.1 mrg {
1565 1.1 mrg putc ('$', file);
1566 1.1 mrg }
1567 1.1 mrg cr16_print_operand_address (file, VOIDmode, x);
1568 1.1 mrg return;
1569 1.1 mrg }
1570 1.1 mrg gcc_unreachable ();
1571 1.1 mrg default:
1572 1.1 mrg output_operand_lossage ("invalid %%xn code");
1573 1.1 mrg }
1574 1.1 mrg
1575 1.1 mrg gcc_unreachable ();
1576 1.1 mrg }
1577 1.1 mrg
1578 1.1 mrg /* Implements the macro PRINT_OPERAND_ADDRESS defined in cr16.h. */
1579 1.1 mrg
1580 1.1 mrg static void
1581 1.1 mrg cr16_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr)
1582 1.1 mrg {
1583 1.1 mrg enum cr16_addrtype addrtype;
1584 1.1 mrg struct cr16_address address;
1585 1.1 mrg
1586 1.1 mrg /* Decompose the address. Also ask it to treat address as constant. */
1587 1.1 mrg addrtype = cr16_decompose_address (addr, &address, 0, TRUE);
1588 1.1 mrg
1589 1.1 mrg if (address.disp && GET_CODE (address.disp) == UNSPEC)
1590 1.1 mrg {
1591 1.1 mrg debug_rtx (addr);
1592 1.1 mrg }
1593 1.1 mrg
1594 1.1 mrg switch (addrtype)
1595 1.1 mrg {
1596 1.1 mrg case CR16_REG_REL:
1597 1.1 mrg if (address.disp)
1598 1.1 mrg {
1599 1.1 mrg if (GET_CODE (address.disp) == UNSPEC)
1600 1.1 mrg cr16_print_operand (file, address.disp, 0);
1601 1.1 mrg else
1602 1.1 mrg output_addr_const (file, address.disp);
1603 1.1 mrg }
1604 1.1 mrg else
1605 1.1 mrg fprintf (file, "0");
1606 1.1 mrg fprintf (file, "(%s)", reg_names[REGNO (address.base)]);
1607 1.1 mrg break;
1608 1.1 mrg
1609 1.1 mrg case CR16_ABSOLUTE:
1610 1.1 mrg if (address.disp)
1611 1.1 mrg output_addr_const (file, address.disp);
1612 1.1 mrg else
1613 1.1 mrg fprintf (file, "0");
1614 1.1 mrg break;
1615 1.1 mrg
1616 1.1 mrg case CR16_INDEX_REGP_REL:
1617 1.1 mrg fprintf (file, "[%s]", reg_names[REGNO (address.index)]);
1618 1.1 mrg /* Fall through. */
1619 1.1 mrg case CR16_REGP_REL:
1620 1.1 mrg if (address.disp)
1621 1.1 mrg {
1622 1.1 mrg if (GET_CODE (address.disp) == UNSPEC)
1623 1.1 mrg cr16_print_operand (file, address.disp, 0);
1624 1.1 mrg else
1625 1.1 mrg output_addr_const (file, address.disp);
1626 1.1 mrg }
1627 1.1 mrg else
1628 1.1 mrg fprintf (file, "0");
1629 1.1 mrg fprintf (file, "(%s,%s)", reg_names[REGNO (address.base) + 1],
1630 1.1 mrg reg_names[REGNO (address.base)]);
1631 1.1 mrg break;
1632 1.1 mrg default:
1633 1.1 mrg debug_rtx (addr);
1634 1.1 mrg gcc_unreachable ();
1635 1.1 mrg }
1636 1.1 mrg /* Add qualifiers to the address expression that was just printed. */
1637 1.1 mrg if (flag_pic < NEAR_PIC && address.code == 0)
1638 1.1 mrg {
1639 1.1 mrg if (address.data == DM_FAR)
1640 1.1 mrg /* Addr contains SYMBOL_REF & far data ptr. */
1641 1.1 mrg fprintf (file, "@l");
1642 1.1 mrg else if (address.data == DM_DEFAULT)
1643 1.1 mrg /* Addr contains SYMBOL_REF & medium data ptr. */
1644 1.1 mrg fprintf (file, "@m");
1645 1.1 mrg /* Addr contains SYMBOL_REF & medium data ptr. */
1646 1.1 mrg else if (address.data == DM_NEAR)
1647 1.1 mrg /* Addr contains SYMBOL_REF & near data ptr. */
1648 1.1 mrg fprintf (file, "@s");
1649 1.1 mrg }
1650 1.1 mrg else if (flag_pic == NEAR_PIC
1651 1.1 mrg && (address.code == 0) && (address.data == DM_FAR
1652 1.1 mrg || address.data == DM_DEFAULT
1653 1.1 mrg || address.data == DM_NEAR))
1654 1.1 mrg {
1655 1.1 mrg fprintf (file, "@l");
1656 1.1 mrg }
1657 1.1 mrg else if (flag_pic == NEAR_PIC && address.code == 2)
1658 1.1 mrg {
1659 1.1 mrg fprintf (file, "pic");
1660 1.1 mrg }
1661 1.1 mrg else if (flag_pic == NEAR_PIC && address.code == 1)
1662 1.1 mrg {
1663 1.1 mrg fprintf (file, "@cpic");
1664 1.1 mrg }
1665 1.1 mrg
1666 1.1 mrg else if (flag_pic == FAR_PIC && address.code == 2)
1667 1.1 mrg {
1668 1.1 mrg /* REVISIT: cr16 register indirect jump expects a 1-bit right shifted
1669 1.1 mrg address ! GOTc tells assembler this symbol is a text-address
1670 1.1 mrg This needs to be fixed in such a way that this offset is done
1671 1.1 mrg only in the case where an address is being used for indirect jump
1672 1.1 mrg or call. Determining the potential usage of loadd is of course not
1673 1.1 mrg possible always. Eventually, this has to be fixed in the
1674 1.1 mrg processor. */
1675 1.1 mrg fprintf (file, "GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1676 1.1 mrg }
1677 1.1 mrg else if (flag_pic == FAR_PIC && address.code == 1)
1678 1.1 mrg {
1679 1.1 mrg fprintf (file, "@cGOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1680 1.1 mrg }
1681 1.1 mrg
1682 1.1 mrg else if (flag_pic == FAR_PIC &&
1683 1.1 mrg (address.data == DM_FAR || address.data == DM_DEFAULT
1684 1.1 mrg || address.data == DM_NEAR))
1685 1.1 mrg {
1686 1.1 mrg fprintf (file, "@GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1687 1.1 mrg }
1688 1.1 mrg }
1689 1.1 mrg
1690 1.1 mrg /* Machine description helper functions. */
1691 1.1 mrg
1692 1.1 mrg /* Called from cr16.md. The return value depends on the parameter push_or_pop:
1693 1.1 mrg When push_or_pop is zero -> string for push instructions of prologue.
1694 1.1 mrg When push_or_pop is nonzero -> string for pop/popret/retx in epilogue.
1695 1.1 mrg Relies on the assumptions:
1696 1.1 mrg 1. RA is the last register to be saved.
1697 1.1 mrg 2. The maximal value of the counter is MAX_COUNT. */
1698 1.1 mrg char *
1699 1.1 mrg cr16_prepare_push_pop_string (int push_or_pop)
1700 1.1 mrg {
1701 1.1 mrg /* j is the number of registers being saved, takes care that there won't be
1702 1.1 mrg more than 8 in one push/pop instruction. */
1703 1.1 mrg
1704 1.1 mrg /* For the register mask string. */
1705 1.1 mrg static char one_inst_str[50];
1706 1.1 mrg
1707 1.1 mrg /* i is the index of current_frame_info.save_regs[], going from 0 until
1708 1.1 mrg current_frame_info.last_reg_to_save. */
1709 1.1 mrg int i, start_reg;
1710 1.1 mrg int word_cnt;
1711 1.1 mrg int print_ra;
1712 1.1 mrg char *return_str;
1713 1.1 mrg
1714 1.1 mrg /* For reversing on the push instructions if there are more than one. */
1715 1.1 mrg char *temp_str;
1716 1.1 mrg
1717 1.1 mrg return_str = (char *) xmalloc (160);
1718 1.1 mrg temp_str = (char *) xmalloc (160);
1719 1.1 mrg
1720 1.1 mrg /* Initialize. */
1721 1.1 mrg memset (return_str, 0, 3);
1722 1.1 mrg
1723 1.1 mrg i = 0;
1724 1.1 mrg while (i <= current_frame_info.last_reg_to_save)
1725 1.1 mrg {
1726 1.1 mrg /* Prepare mask for one instruction. */
1727 1.1 mrg one_inst_str[0] = 0;
1728 1.1 mrg
1729 1.1 mrg /* To count number of words in one instruction. */
1730 1.1 mrg word_cnt = 0;
1731 1.1 mrg start_reg = i;
1732 1.1 mrg print_ra = 0;
1733 1.1 mrg while ((word_cnt < MAX_COUNT)
1734 1.1 mrg && (i <= current_frame_info.last_reg_to_save))
1735 1.1 mrg {
1736 1.1 mrg /* For each non consecutive save register,
1737 1.1 mrg a new instruction shall be generated. */
1738 1.1 mrg if (!current_frame_info.save_regs[i])
1739 1.1 mrg {
1740 1.1 mrg /* Move to next reg and break. */
1741 1.1 mrg ++i;
1742 1.1 mrg break;
1743 1.1 mrg }
1744 1.1 mrg
1745 1.1 mrg if (i == RETURN_ADDRESS_REGNUM)
1746 1.1 mrg print_ra = 1;
1747 1.1 mrg else
1748 1.1 mrg {
1749 1.1 mrg /* Check especially if adding 2 does not cross the MAX_COUNT. */
1750 1.1 mrg if ((word_cnt + ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2))
1751 1.1 mrg >= MAX_COUNT)
1752 1.1 mrg break;
1753 1.1 mrg /* Increase word count by 2 for long registers except RA. */
1754 1.1 mrg word_cnt += ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2);
1755 1.1 mrg }
1756 1.1 mrg ++i;
1757 1.1 mrg }
1758 1.1 mrg
1759 1.1 mrg /* No need to generate any instruction as
1760 1.1 mrg no register or RA needs to be saved. */
1761 1.1 mrg if ((word_cnt == 0) && (print_ra == 0))
1762 1.1 mrg continue;
1763 1.1 mrg
1764 1.1 mrg /* Now prepare the instruction operands. */
1765 1.1 mrg if (word_cnt > 0)
1766 1.1 mrg {
1767 1.1 mrg sprintf (one_inst_str, "$%d, %s", word_cnt, reg_names[start_reg]);
1768 1.1 mrg if (print_ra)
1769 1.1 mrg strcat (one_inst_str, ", ra");
1770 1.1 mrg }
1771 1.1 mrg else
1772 1.1 mrg strcat (one_inst_str, "ra");
1773 1.1 mrg
1774 1.1 mrg if (push_or_pop == 1)
1775 1.1 mrg {
1776 1.1 mrg /* Pop instruction. */
1777 1.1 mrg if (print_ra && !cr16_interrupt_function_p ()
1778 1.1 mrg && !crtl->calls_eh_return)
1779 1.1 mrg /* Print popret if RA is saved and its not a interrupt
1780 1.1 mrg function. */
1781 1.1 mrg strcpy (temp_str, "\n\tpopret\t");
1782 1.1 mrg else
1783 1.1 mrg strcpy (temp_str, "\n\tpop\t");
1784 1.1 mrg
1785 1.1 mrg strcat (temp_str, one_inst_str);
1786 1.1 mrg
1787 1.1 mrg /* Add the pop instruction list. */
1788 1.1 mrg strcat (return_str, temp_str);
1789 1.1 mrg }
1790 1.1 mrg else
1791 1.1 mrg {
1792 1.1 mrg /* Push instruction. */
1793 1.1 mrg strcpy (temp_str, "\n\tpush\t");
1794 1.1 mrg strcat (temp_str, one_inst_str);
1795 1.1 mrg
1796 1.1 mrg /* We need to reverse the order of the instructions if there
1797 1.1 mrg are more than one. (since the pop will not be reversed in
1798 1.1 mrg the epilogue. */
1799 1.1 mrg strcat (temp_str, return_str);
1800 1.1 mrg strcpy (return_str, temp_str);
1801 1.1 mrg }
1802 1.1 mrg }
1803 1.1 mrg
1804 1.1 mrg if (push_or_pop == 1)
1805 1.1 mrg {
1806 1.1 mrg /* POP. */
1807 1.1 mrg if (cr16_interrupt_function_p ())
1808 1.1 mrg strcat (return_str, "\n\tretx\n");
1809 1.1 mrg else if (crtl->calls_eh_return)
1810 1.1 mrg {
1811 1.1 mrg /* Add stack adjustment before returning to exception handler
1812 1.1 mrg NOTE: EH_RETURN_STACKADJ_RTX must refer to (r5, r4). */
1813 1.1 mrg strcat (return_str, "\n\taddd\t (r5, r4), (sp)\t\n");
1814 1.1 mrg strcat (return_str, "\n\tjump\t (ra)\n");
1815 1.1 mrg
1816 1.1 mrg /* But before anything else, undo the adjustment addition done in
1817 1.1 mrg cr16_expand_epilogue (). */
1818 1.1 mrg strcpy (temp_str, "\n\tsubd\t (r5, r4), (sp)\t\n");
1819 1.1 mrg strcat (temp_str, return_str);
1820 1.1 mrg strcpy (return_str, temp_str);
1821 1.1 mrg }
1822 1.1 mrg else if (!FUNC_IS_NORETURN_P (current_function_decl)
1823 1.1 mrg && !(current_frame_info.save_regs[RETURN_ADDRESS_REGNUM]))
1824 1.1 mrg strcat (return_str, "\n\tjump\t (ra)\n");
1825 1.1 mrg }
1826 1.1 mrg
1827 1.1 mrg /* Skip the newline and the tab in the start of return_str. */
1828 1.1 mrg return_str += 2;
1829 1.1 mrg return return_str;
1830 1.1 mrg }
1831 1.1 mrg
1832 1.1 mrg
1833 1.1 mrg /* Generate DWARF2 annotation for multi-push instruction. */
1834 1.1 mrg static void
1835 1.1 mrg cr16_create_dwarf_for_multi_push (rtx insn)
1836 1.1 mrg {
1837 1.1 mrg rtx dwarf, reg, tmp;
1838 1.1 mrg int i, j, from, to, word_cnt, dwarf_par_index, inc;
1839 1.1 mrg machine_mode mode;
1840 1.1 mrg int num_regs = 0, offset = 0, split_here = 0, total_push_bytes = 0;
1841 1.1 mrg
1842 1.1 mrg for (i = 0; i <= current_frame_info.last_reg_to_save; ++i)
1843 1.1 mrg {
1844 1.1 mrg if (current_frame_info.save_regs[i])
1845 1.1 mrg {
1846 1.1 mrg ++num_regs;
1847 1.1 mrg if (i < CR16_FIRST_DWORD_REGISTER)
1848 1.1 mrg total_push_bytes += 2;
1849 1.1 mrg else
1850 1.1 mrg total_push_bytes += 4;
1851 1.1 mrg }
1852 1.1 mrg }
1853 1.1 mrg
1854 1.1 mrg if (!num_regs)
1855 1.1 mrg return;
1856 1.1 mrg
1857 1.1 mrg dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1));
1858 1.1 mrg dwarf_par_index = num_regs;
1859 1.1 mrg
1860 1.1 mrg from = current_frame_info.last_reg_to_save + 1;
1861 1.1 mrg to = current_frame_info.last_reg_to_save;
1862 1.1 mrg word_cnt = 0;
1863 1.1 mrg
1864 1.1 mrg for (i = current_frame_info.last_reg_to_save; i >= 0;)
1865 1.1 mrg {
1866 1.1 mrg if (!current_frame_info.save_regs[i] || i == 0 || split_here)
1867 1.1 mrg {
1868 1.1 mrg /* This block of regs is pushed in one instruction. */
1869 1.1 mrg if (i == 0 && current_frame_info.save_regs[i])
1870 1.1 mrg from = 0;
1871 1.1 mrg
1872 1.1 mrg for (j = to; j >= from; --j)
1873 1.1 mrg {
1874 1.1 mrg if (j < CR16_FIRST_DWORD_REGISTER)
1875 1.1 mrg {
1876 1.1 mrg mode = HImode;
1877 1.1 mrg inc = 1;
1878 1.1 mrg }
1879 1.1 mrg else
1880 1.1 mrg {
1881 1.1 mrg mode = SImode;
1882 1.1 mrg inc = 2;
1883 1.1 mrg }
1884 1.1 mrg reg = gen_rtx_REG (mode, j);
1885 1.1 mrg offset += 2 * inc;
1886 1.1 mrg tmp = gen_rtx_SET (gen_frame_mem (mode,
1887 1.1 mrg plus_constant
1888 1.1 mrg (Pmode, stack_pointer_rtx,
1889 1.1 mrg total_push_bytes - offset)),
1890 1.1 mrg reg);
1891 1.1 mrg RTX_FRAME_RELATED_P (tmp) = 1;
1892 1.1 mrg XVECEXP (dwarf, 0, dwarf_par_index--) = tmp;
1893 1.1 mrg }
1894 1.1 mrg from = i;
1895 1.1 mrg to = --i;
1896 1.1 mrg split_here = 0;
1897 1.1 mrg word_cnt = 0;
1898 1.1 mrg continue;
1899 1.1 mrg }
1900 1.1 mrg
1901 1.1 mrg if (i != RETURN_ADDRESS_REGNUM)
1902 1.1 mrg {
1903 1.1 mrg inc = (i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2;
1904 1.1 mrg if (word_cnt + inc >= MAX_COUNT || FRAME_POINTER_REGNUM == i)
1905 1.1 mrg {
1906 1.1 mrg split_here = 1;
1907 1.1 mrg from = i;
1908 1.1 mrg continue;
1909 1.1 mrg }
1910 1.1 mrg word_cnt += inc;
1911 1.1 mrg }
1912 1.1 mrg
1913 1.1 mrg from = i--;
1914 1.1 mrg }
1915 1.1 mrg
1916 1.1 mrg tmp = gen_rtx_SET (stack_pointer_rtx,
1917 1.1 mrg gen_rtx_PLUS (SImode, stack_pointer_rtx,
1918 1.1 mrg GEN_INT (-offset)));
1919 1.1 mrg RTX_FRAME_RELATED_P (tmp) = 1;
1920 1.1 mrg XVECEXP (dwarf, 0, 0) = tmp;
1921 1.1 mrg
1922 1.1 mrg add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
1923 1.1 mrg }
1924 1.1 mrg
1925 1.1 mrg /*
1926 1.1 mrg CompactRISC CR16 Architecture stack layout:
1927 1.1 mrg
1928 1.1 mrg 0 +---------------------
1929 1.1 mrg |
1930 1.1 mrg .
1931 1.1 mrg .
1932 1.1 mrg |
1933 1.1 mrg +==================== Sp (x) = Ap (x+1)
1934 1.1 mrg A | Args for functions
1935 1.1 mrg | | called by X and Dynamically
1936 1.1 mrg | | Dynamic allocations allocated and
1937 1.1 mrg | | (alloca, variable deallocated
1938 1.1 mrg Stack | length arrays).
1939 1.1 mrg grows +-------------------- Fp (x)
1940 1.1 mrg down| | Local variables of X
1941 1.1 mrg ward| +--------------------
1942 1.1 mrg | | Regs saved for X-1
1943 1.1 mrg | +==================== Sp (x-1) = Ap (x)
1944 1.1 mrg | Args for func X
1945 1.1 mrg | pushed by X-1
1946 1.1 mrg +-------------------- Fp (x-1)
1947 1.1 mrg |
1948 1.1 mrg |
1949 1.1 mrg V
1950 1.1 mrg */
1951 1.1 mrg void
1952 1.1 mrg cr16_expand_prologue (void)
1953 1.1 mrg {
1954 1.1 mrg rtx insn;
1955 1.1 mrg
1956 1.1 mrg cr16_compute_frame ();
1957 1.1 mrg cr16_compute_save_regs ();
1958 1.1 mrg
1959 1.1 mrg /* If there is no need in push and adjustment to sp, return. */
1960 1.1 mrg if ((current_frame_info.total_size + current_frame_info.reg_size) == 0)
1961 1.1 mrg return;
1962 1.1 mrg
1963 1.1 mrg if (current_frame_info.last_reg_to_save != -1)
1964 1.1 mrg {
1965 1.1 mrg /* If there are registers to push. */
1966 1.1 mrg insn = emit_insn (gen_push_for_prologue
1967 1.1 mrg (GEN_INT (current_frame_info.reg_size)));
1968 1.1 mrg cr16_create_dwarf_for_multi_push (insn);
1969 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1;
1970 1.1 mrg }
1971 1.1 mrg
1972 1.1 mrg
1973 1.1 mrg if (current_frame_info.total_size > 0)
1974 1.1 mrg {
1975 1.1 mrg insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1976 1.1 mrg GEN_INT (-current_frame_info.total_size)));
1977 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1;
1978 1.1 mrg }
1979 1.1 mrg
1980 1.1 mrg if (frame_pointer_needed)
1981 1.1 mrg {
1982 1.1 mrg /* Initialize the frame pointer with the value of the stack pointer
1983 1.1 mrg pointing now to the locals. */
1984 1.1 mrg insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1985 1.1 mrg }
1986 1.1 mrg }
1987 1.1 mrg
1988 1.1 mrg /* Generate insn that updates the stack for local variables and padding
1989 1.1 mrg for registers we save. - Generate the appropriate return insn. */
1990 1.1 mrg void
1991 1.1 mrg cr16_expand_epilogue (void)
1992 1.1 mrg {
1993 1.1 mrg rtx insn;
1994 1.1 mrg
1995 1.1 mrg /* Nonzero if we need to return and pop only RA. This will generate a
1996 1.1 mrg different insn. This differentiate is for the peepholes for call as
1997 1.1 mrg last statement in function. */
1998 1.1 mrg int only_popret_RA = (current_frame_info.save_regs[RETURN_ADDRESS_REGNUM]
1999 1.1 mrg && (current_frame_info.reg_size
2000 1.1 mrg == CR16_UNITS_PER_DWORD));
2001 1.1 mrg
2002 1.1 mrg if (frame_pointer_needed)
2003 1.1 mrg {
2004 1.1 mrg /* Restore the stack pointer with the frame pointers value. */
2005 1.1 mrg insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
2006 1.1 mrg }
2007 1.1 mrg
2008 1.1 mrg if (current_frame_info.total_size > 0)
2009 1.1 mrg {
2010 1.1 mrg insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2011 1.1 mrg GEN_INT (current_frame_info.total_size)));
2012 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1;
2013 1.1 mrg }
2014 1.1 mrg
2015 1.1 mrg if (crtl->calls_eh_return)
2016 1.1 mrg {
2017 1.1 mrg /* Add this here so that (r5, r4) is actually loaded with the adjustment
2018 1.1 mrg value; otherwise, the load might be optimized away...
2019 1.1 mrg NOTE: remember to subtract the adjustment before popping the regs
2020 1.1 mrg and add it back before returning. */
2021 1.1 mrg insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2022 1.1 mrg EH_RETURN_STACKADJ_RTX));
2023 1.1 mrg }
2024 1.1 mrg
2025 1.1 mrg if (cr16_interrupt_function_p ())
2026 1.1 mrg {
2027 1.1 mrg insn = emit_jump_insn (gen_interrupt_return ());
2028 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1;
2029 1.1 mrg }
2030 1.1 mrg else if (crtl->calls_eh_return)
2031 1.1 mrg {
2032 1.1 mrg /* Special case, pop what's necessary, adjust SP and jump to (RA). */
2033 1.1 mrg insn = emit_jump_insn (gen_pop_and_popret_return
2034 1.1 mrg (GEN_INT (current_frame_info.reg_size)));
2035 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1;
2036 1.1 mrg }
2037 1.1 mrg else if (current_frame_info.last_reg_to_save == -1)
2038 1.1 mrg /* Nothing to pop. */
2039 1.1 mrg /* Don't output jump for interrupt routine, only retx. */
2040 1.1 mrg emit_jump_insn (gen_jump_return ());
2041 1.1 mrg else if (only_popret_RA)
2042 1.1 mrg {
2043 1.1 mrg insn = emit_jump_insn (gen_popret_RA_return ());
2044 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1;
2045 1.1 mrg }
2046 1.1 mrg else
2047 1.1 mrg {
2048 1.1 mrg insn = emit_jump_insn (gen_pop_and_popret_return
2049 1.1 mrg (GEN_INT (current_frame_info.reg_size)));
2050 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1;
2051 1.1 mrg }
2052 1.1 mrg }
2053 1.1 mrg
2054 1.1 mrg /* Implements FRAME_POINTER_REQUIRED. */
2055 1.1 mrg static bool
2056 1.1 mrg cr16_frame_pointer_required (void)
2057 1.1 mrg {
2058 1.1 mrg return (cfun->calls_alloca || crtl->calls_eh_return
2059 1.1 mrg || cfun->has_nonlocal_label || crtl->calls_eh_return);
2060 1.1 mrg }
2061 1.1 mrg
2062 1.1 mrg static bool
2063 1.1 mrg cr16_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
2064 1.1 mrg {
2065 1.1 mrg return (to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true);
2066 1.1 mrg }
2067 1.1 mrg
2068 1.1 mrg
2069 1.1 mrg /* A C compound statement that attempts to replace X with
2070 1.1 mrg a valid memory address for an operand of mode MODE. WIN
2071 1.1 mrg will be a C statement label elsewhere in the code.
2072 1.1 mrg X will always be the result of a call to break_out_memory_refs (),
2073 1.1 mrg and OLDX will be the operand that was given to that function to
2074 1.1 mrg produce X.
2075 1.1 mrg The code generated by this macro should not alter the
2076 1.1 mrg substructure of X. If it transforms X into a more legitimate form,
2077 1.1 mrg it should assign X (which will always be a C variable) a new value. */
2078 1.1 mrg static rtx
2079 1.1 mrg cr16_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED,
2080 1.1 mrg machine_mode mode ATTRIBUTE_UNUSED)
2081 1.1 mrg {
2082 1.1 mrg if (flag_pic)
2083 1.1 mrg return legitimize_pic_address (orig_x, mode, NULL_RTX);
2084 1.1 mrg else
2085 1.1 mrg return x;
2086 1.1 mrg }
2087 1.1 mrg
2088 1.1 mrg /* Implement TARGET_LEGITIMATE_CONSTANT_P
2089 1.1 mrg Nonzero if X is a legitimate constant for an immediate
2090 1.1 mrg operand on the target machine. You can assume that X
2091 1.1 mrg satisfies CONSTANT_P. In cr16c treat legitimize float
2092 1.1 mrg constant as an immediate operand. */
2093 1.1 mrg static bool
2094 1.1 mrg cr16_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED,
2095 1.1 mrg rtx x ATTRIBUTE_UNUSED)
2096 1.1 mrg {
2097 1.1 mrg return 1;
2098 1.1 mrg }
2099 1.1 mrg
2100 1.1 mrg static scalar_int_mode
2101 1.1 mrg cr16_unwind_word_mode (void)
2102 1.1 mrg {
2103 1.1 mrg return SImode;
2104 1.1 mrg }
2105 1.1 mrg
2106 1.1 mrg /* Helper function for md file. This function is used to emit arithmetic
2107 1.1 mrg DI instructions. The argument "num" decides which instruction to be
2108 1.1 mrg printed. */
2109 1.1 mrg const char *
2110 1.1 mrg cr16_emit_add_sub_di (rtx *operands, enum rtx_code code)
2111 1.1 mrg {
2112 1.1 mrg rtx lo_op[2] ;
2113 1.1 mrg rtx hi0_op[2] ;
2114 1.1 mrg rtx hi1_op[2] ;
2115 1.1 mrg
2116 1.1 mrg lo_op[0] = gen_lowpart (SImode, operands[0]);
2117 1.1 mrg hi0_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 4);
2118 1.1 mrg hi1_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 6);
2119 1.1 mrg
2120 1.1 mrg lo_op[1] = gen_lowpart (SImode, operands[2]);
2121 1.1 mrg hi0_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 4);
2122 1.1 mrg hi1_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 6);
2123 1.1 mrg
2124 1.1 mrg switch (code)
2125 1.1 mrg {
2126 1.1 mrg case PLUS:
2127 1.1 mrg {
2128 1.1 mrg output_asm_insn ("addd\t%1, %0", lo_op) ;
2129 1.1 mrg output_asm_insn ("addcw\t%1, %0", hi0_op) ;
2130 1.1 mrg output_asm_insn ("addcw\t%1, %0", hi1_op) ;
2131 1.1 mrg break;
2132 1.1 mrg }
2133 1.1 mrg case MINUS:
2134 1.1 mrg {
2135 1.1 mrg output_asm_insn ("subd\t%1, %0", lo_op) ;
2136 1.1 mrg output_asm_insn ("subcw\t%1, %0", hi0_op) ;
2137 1.1 mrg output_asm_insn ("subcw\t%1, %0", hi1_op) ;
2138 1.1 mrg break;
2139 1.1 mrg }
2140 1.1 mrg default:
2141 1.1 mrg break;
2142 1.1 mrg }
2143 1.1 mrg
2144 1.1 mrg return "";
2145 1.1 mrg }
2146 1.1 mrg
2147 1.1 mrg
2148 1.1 mrg /* Helper function for md file. This function is used to emit logical
2149 1.1 mrg DI instructions. The argument "num" decides which instruction to be
2150 1.1 mrg printed. */
2151 1.1 mrg const char *
2152 1.1 mrg cr16_emit_logical_di (rtx *operands, enum rtx_code code)
2153 1.1 mrg {
2154 1.1 mrg rtx lo_op[2] ;
2155 1.1 mrg rtx hi_op[2] ;
2156 1.1 mrg
2157 1.1 mrg lo_op[0] = gen_lowpart (SImode, operands[0]);
2158 1.1 mrg hi_op[0] = simplify_gen_subreg (SImode, operands[0], DImode, 4);
2159 1.1 mrg
2160 1.1 mrg lo_op[1] = gen_lowpart (SImode, operands[2]);
2161 1.1 mrg hi_op[1] = simplify_gen_subreg (SImode, operands[2], DImode, 4);
2162 1.1 mrg
2163 1.1 mrg switch (code)
2164 1.1 mrg {
2165 1.1 mrg case AND:
2166 1.1 mrg {
2167 1.1 mrg output_asm_insn ("andd\t%1, %0", lo_op) ;
2168 1.1 mrg output_asm_insn ("andd\t%1, %0", hi_op) ;
2169 1.1 mrg return "";
2170 1.1 mrg }
2171 1.1 mrg case IOR:
2172 1.1 mrg {
2173 1.1 mrg output_asm_insn ("ord\t%1, %0", lo_op) ;
2174 1.1 mrg output_asm_insn ("ord\t%1, %0", hi_op) ;
2175 1.1 mrg return "";
2176 1.1 mrg }
2177 1.1 mrg case XOR:
2178 1.1 mrg {
2179 1.1 mrg output_asm_insn ("xord\t%1, %0", lo_op) ;
2180 1.1 mrg output_asm_insn ("xord\t%1, %0", hi_op) ;
2181 1.1 mrg return "";
2182 1.1 mrg }
2183 1.1 mrg default:
2184 1.1 mrg break;
2185 1.1 mrg }
2186 1.1 mrg
2187 1.1 mrg return "";
2188 1.1 mrg }
2189 1.1 mrg
2190 1.1 mrg /* Implement PUSH_ROUNDING. */
2191 1.1 mrg
2192 1.1 mrg poly_int64
2193 1.1 mrg cr16_push_rounding (poly_int64 bytes)
2194 1.1 mrg {
2195 1.1 mrg return (bytes + 1) & ~1;
2196 1.1 mrg }
2197 1.1 mrg
2198 1.1 mrg /* Initialize 'targetm' variable which contains pointers to functions
2199 1.1 mrg and data relating to the target machine. */
2200 1.1 mrg
2201 1.1 mrg struct gcc_target targetm = TARGET_INITIALIZER;
2202