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