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