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