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