poly_int: PUSH_ROUNDING
[official-gcc.git] / gcc / config / cr16 / cr16.c
blob9ea02a967ff4e3db932541b6696a251f4cf49110
1 /* Output routines for CR16 processor.
2 Copyright (C) 2012-2017 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_FUNCTION_ARG
162 #define TARGET_FUNCTION_ARG cr16_function_arg
163 #undef TARGET_FUNCTION_ARG_ADVANCE
164 #define TARGET_FUNCTION_ARG_ADVANCE cr16_function_arg_advance
165 #undef TARGET_RETURN_POPS_ARGS
166 #define TARGET_RETURN_POPS_ARGS cr16_return_pops_args
168 /* Initialize the GCC target structure. */
169 #undef TARGET_FRAME_POINTER_REQUIRED
170 #define TARGET_FRAME_POINTER_REQUIRED cr16_frame_pointer_required
171 #undef TARGET_CAN_ELIMINATE
172 #define TARGET_CAN_ELIMINATE cr16_can_eliminate
173 #undef TARGET_LEGITIMIZE_ADDRESS
174 #define TARGET_LEGITIMIZE_ADDRESS cr16_legitimize_address
175 #undef TARGET_LEGITIMATE_CONSTANT_P
176 #define TARGET_LEGITIMATE_CONSTANT_P cr16_legitimate_constant_p
177 #undef TARGET_LEGITIMATE_ADDRESS_P
178 #define TARGET_LEGITIMATE_ADDRESS_P cr16_legitimate_address_p
180 #undef TARGET_LRA_P
181 #define TARGET_LRA_P hook_bool_void_false
183 /* Returning function value. */
184 #undef TARGET_FUNCTION_VALUE
185 #define TARGET_FUNCTION_VALUE cr16_function_value
186 #undef TARGET_LIBCALL_VALUE
187 #define TARGET_LIBCALL_VALUE cr16_libcall_value
188 #undef TARGET_FUNCTION_VALUE_REGNO_P
189 #define TARGET_FUNCTION_VALUE_REGNO_P cr16_function_value_regno_p
191 /* printing the values. */
192 #undef TARGET_PRINT_OPERAND
193 #define TARGET_PRINT_OPERAND cr16_print_operand
194 #undef TARGET_PRINT_OPERAND_ADDRESS
195 #define TARGET_PRINT_OPERAND_ADDRESS cr16_print_operand_address
197 /* Relative costs of operations. */
198 #undef TARGET_ADDRESS_COST
199 #define TARGET_ADDRESS_COST cr16_address_cost
200 #undef TARGET_REGISTER_MOVE_COST
201 #define TARGET_REGISTER_MOVE_COST cr16_register_move_cost
202 #undef TARGET_MEMORY_MOVE_COST
203 #define TARGET_MEMORY_MOVE_COST cr16_memory_move_cost
205 #undef TARGET_CONSTANT_ALIGNMENT
206 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
208 /* Table of machine attributes. */
209 static const struct attribute_spec cr16_attribute_table[] = {
210 /* ISRs have special prologue and epilogue requirements. */
211 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
212 affects_type_identity, handler, exclude }. */
213 {"interrupt", 0, 0, false, true, true, false, NULL, NULL},
214 {NULL, 0, 0, false, false, false, false, NULL, NULL}
217 /* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive
218 .?byte directive along with @c is not understood by assembler.
219 Therefore, make all TARGET_ASM_UNALIGNED_xx_OP same
220 as TARGET_ASM_ALIGNED_xx_OP. */
221 #undef TARGET_ASM_UNALIGNED_HI_OP
222 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
223 #undef TARGET_ASM_UNALIGNED_SI_OP
224 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
225 #undef TARGET_ASM_UNALIGNED_DI_OP
226 #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
228 #undef TARGET_HARD_REGNO_NREGS
229 #define TARGET_HARD_REGNO_NREGS cr16_hard_regno_nregs
230 #undef TARGET_HARD_REGNO_MODE_OK
231 #define TARGET_HARD_REGNO_MODE_OK cr16_hard_regno_mode_ok
232 #undef TARGET_MODES_TIEABLE_P
233 #define TARGET_MODES_TIEABLE_P cr16_modes_tieable_p
235 /* Target hook implementations. */
237 /* Implements hook TARGET_RETURN_IN_MEMORY. */
238 static bool
239 cr16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
241 const HOST_WIDE_INT size = int_size_in_bytes (type);
242 return ((size == -1) || (size > 8));
245 /* Implement TARGET_CLASS_LIKELY_SPILLED_P. */
246 static bool
247 cr16_class_likely_spilled_p (reg_class_t rclass)
249 if ((rclass) == SHORT_REGS || (rclass) == DOUBLE_BASE_REGS
250 || (rclass) == LONG_REGS || (rclass) == GENERAL_REGS)
251 return true;
253 return false;
256 static poly_int64
257 cr16_return_pops_args (tree, tree, poly_int64)
259 return 0;
262 /* Returns true if data model selected via command line option
263 is same as function argument. */
264 bool
265 cr16_is_data_model (enum data_model_type model)
267 return (model == data_model);
270 /* Parse relevant options and override. */
271 static void
272 cr16_override_options (void)
274 /* Disable -fdelete-null-pointer-checks option for CR16 target.
275 Programs which rely on NULL pointer dereferences _not_ halting the
276 program may not work properly with this option. So disable this
277 option. */
278 flag_delete_null_pointer_checks = 0;
280 /* FIXME: To avoid spill_failure ICE during exception handling,
281 * disable cse_fllow_jumps. The spill error occurs when compiler
282 * can't find a suitable candidate in GENERAL_REGS class to reload
283 * a 32bit register.
284 * Need to find a better way of avoiding this situation. */
285 if (flag_exceptions)
286 flag_cse_follow_jumps = 0;
288 /* If -fpic option, data_model == DM_FAR. */
289 if (flag_pic == NEAR_PIC)
291 data_model = DM_FAR;
294 /* The only option we want to examine is data model option. */
295 if (cr16_data_model)
297 if (strcmp (cr16_data_model, "medium") == 0)
298 data_model = DM_DEFAULT;
299 else if (strcmp (cr16_data_model, "near") == 0)
300 data_model = DM_NEAR;
301 else if (strcmp (cr16_data_model, "far") == 0)
303 if (TARGET_CR16CP)
304 data_model = DM_FAR;
305 else
306 error ("data-model=far not valid for cr16c architecture");
308 else
309 error ("invalid data model option -mdata-model=%s", cr16_data_model);
311 else
312 data_model = DM_DEFAULT;
315 /* Implements the macro TARGET_CONDITIONAL_REGISTER_USAGE. */
316 static void
317 cr16_conditional_register_usage (void)
319 if (flag_pic)
321 fixed_regs[12] = call_used_regs[12] = 1;
325 /* Stack layout and calling conventions routines. */
327 /* Return nonzero if the current function being compiled is an interrupt
328 function as specified by the "interrupt" attribute. */
330 cr16_interrupt_function_p (void)
332 tree attributes;
334 attributes = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
335 return (lookup_attribute ("interrupt", attributes) != NULL_TREE);
338 /* Compute values for the array current_frame_info.save_regs and the variable
339 current_frame_info.reg_size. The index of current_frame_info.save_regs
340 is numbers of register, each will get 1 if we need to save it in the
341 current function, 0 if not. current_frame_info.reg_size is the total sum
342 of the registers being saved. */
343 static void
344 cr16_compute_save_regs (void)
346 unsigned int regno;
348 /* Initialize here so in case the function is no-return it will be -1. */
349 current_frame_info.last_reg_to_save = -1;
351 /* Initialize the number of bytes to be saved. */
352 current_frame_info.reg_size = 0;
354 /* No need to save any registers if the function never returns. */
355 if (FUNC_IS_NORETURN_P (current_function_decl) && !MUST_SAVE_REGS_P ())
356 return;
358 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
360 if (fixed_regs[regno])
362 current_frame_info.save_regs[regno] = 0;
363 continue;
366 /* If this reg is used and not call-used (except RA), save it. */
367 if (cr16_interrupt_function_p ())
369 if (!crtl->is_leaf && call_used_regs[regno])
370 /* This is a volatile reg in a non-leaf interrupt routine - save
371 it for the sake of its sons. */
372 current_frame_info.save_regs[regno] = 1;
373 else if (df_regs_ever_live_p (regno))
374 /* This reg is used - save it. */
375 current_frame_info.save_regs[regno] = 1;
376 else
377 /* This reg is not used, and is not a volatile - don't save. */
378 current_frame_info.save_regs[regno] = 0;
380 else
382 /* If this reg is used and not call-used (except RA), save it. */
383 if (df_regs_ever_live_p (regno)
384 && (!call_used_regs[regno] || regno == RETURN_ADDRESS_REGNUM))
385 current_frame_info.save_regs[regno] = 1;
386 else
387 current_frame_info.save_regs[regno] = 0;
391 /* Save registers so the exception handler can modify them. */
392 if (crtl->calls_eh_return)
394 unsigned int i;
396 for (i = 0;; ++i)
398 regno = EH_RETURN_DATA_REGNO (i);
399 if (INVALID_REGNUM == regno)
400 break;
401 current_frame_info.save_regs[regno] = 1;
405 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
406 if (current_frame_info.save_regs[regno] == 1)
408 current_frame_info.last_reg_to_save = regno;
409 if (regno >= CR16_FIRST_DWORD_REGISTER)
410 current_frame_info.reg_size += CR16_UNITS_PER_DWORD;
411 else
412 current_frame_info.reg_size += UNITS_PER_WORD;
416 /* Compute the size of the local area and the size to be adjusted by the
417 prologue and epilogue. */
418 static void
419 cr16_compute_frame (void)
421 /* For aligning the local variables. */
422 int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
423 int padding_locals;
425 /* Padding needed for each element of the frame. */
426 current_frame_info.var_size = get_frame_size ();
428 /* Align to the stack alignment. */
429 padding_locals = current_frame_info.var_size % stack_alignment;
430 if (padding_locals)
431 padding_locals = stack_alignment - padding_locals;
433 current_frame_info.var_size += padding_locals;
434 current_frame_info.total_size
435 = (current_frame_info.var_size
436 + (ACCUMULATE_OUTGOING_ARGS
437 ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0));
440 /* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */
442 cr16_initial_elimination_offset (int from, int to)
444 /* Compute this since we need to use current_frame_info.reg_size. */
445 cr16_compute_save_regs ();
447 /* Compute this since we need to use current_frame_info.var_size. */
448 cr16_compute_frame ();
450 if (((from) == FRAME_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
451 return (ACCUMULATE_OUTGOING_ARGS
452 ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0);
453 else if (((from) == ARG_POINTER_REGNUM) && ((to) == FRAME_POINTER_REGNUM))
454 return (current_frame_info.reg_size + current_frame_info.var_size);
455 else if (((from) == ARG_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
456 return (current_frame_info.reg_size + current_frame_info.var_size
457 + (ACCUMULATE_OUTGOING_ARGS
458 ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0));
459 else
460 gcc_unreachable ();
463 /* Register Usage. */
465 /* Return the class number of the smallest class containing reg number REGNO.
466 This could be a conditional expression or could index an array. */
467 enum reg_class
468 cr16_regno_reg_class (int regno)
470 if ((regno >= 0) && (regno < CR16_FIRST_DWORD_REGISTER))
471 return SHORT_REGS;
473 if ((regno >= CR16_FIRST_DWORD_REGISTER) && (regno < FIRST_PSEUDO_REGISTER))
474 return LONG_REGS;
476 return NO_REGS;
479 /* Implement TARGET_HARD_REGNO_NREGS. */
481 static unsigned int
482 cr16_hard_regno_nregs (unsigned int regno, machine_mode mode)
484 if (regno >= CR16_FIRST_DWORD_REGISTER)
485 return CEIL (GET_MODE_SIZE (mode), CR16_UNITS_PER_DWORD);
486 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
489 /* Implement TARGET_HARD_REGNO_MODE_OK. On the CR16 architecture, all
490 registers can hold all modes, except that double precision floats
491 (and double ints) must fall on even-register boundaries. */
493 static bool
494 cr16_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
496 if ((GET_MODE_SIZE (mode) >= 4) && (regno == 11))
497 return false;
499 if (mode == DImode || mode == DFmode)
501 if ((regno > 8) || (regno & 1))
502 return false;
503 return true;
506 if ((TARGET_INT32)
507 && ((regno >= 12) && (GET_MODE_SIZE (mode) < 4 )))
508 return false;
510 /* CC can only hold CCmode values. */
511 if (GET_MODE_CLASS (mode) == MODE_CC)
512 return false;
513 return true;
516 /* Implement TARGET_MODES_TIEABLE_P. */
517 static bool
518 cr16_modes_tieable_p (machine_mode mode1, machine_mode mode2)
520 return GET_MODE_CLASS (mode1) == GET_MODE_CLASS (mode2);
523 /* Returns register number for function return value.*/
524 static inline unsigned int
525 cr16_ret_register (void)
527 return 0;
530 /* Implements hook TARGET_STRUCT_VALUE_RTX. */
531 static rtx
532 cr16_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
533 int incoming ATTRIBUTE_UNUSED)
535 return gen_rtx_REG (Pmode, cr16_ret_register ());
538 /* Returning function value. */
540 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P. */
541 static bool
542 cr16_function_value_regno_p (const unsigned int regno)
544 return (regno == cr16_ret_register ());
547 /* Create an RTX representing the place where a
548 library function returns a value of mode MODE. */
549 static rtx
550 cr16_libcall_value (machine_mode mode,
551 const_rtx func ATTRIBUTE_UNUSED)
553 return gen_rtx_REG (mode, cr16_ret_register ());
556 /* Create an RTX representing the place where a
557 function returns a value of data type VALTYPE. */
558 static rtx
559 cr16_function_value (const_tree type,
560 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
561 bool outgoing ATTRIBUTE_UNUSED)
563 return gen_rtx_REG (TYPE_MODE (type), cr16_ret_register ());
566 /* Passing function arguments. */
568 /* If enough param regs are available for passing the param of type TYPE return
569 the number of registers needed else 0. */
570 static int
571 enough_regs_for_param (CUMULATIVE_ARGS * cum, const_tree type,
572 machine_mode mode)
574 int type_size;
575 int remaining_size;
577 if (mode != BLKmode)
578 type_size = GET_MODE_BITSIZE (mode);
579 else
580 type_size = int_size_in_bytes (type) * BITS_PER_UNIT;
582 remaining_size = BITS_PER_WORD * (MAX_REG_FOR_PASSING_ARGS
583 - (MIN_REG_FOR_PASSING_ARGS + cum->ints) +
586 /* Any variable which is too big to pass in two registers, will pass on
587 stack. */
588 if ((remaining_size >= type_size) && (type_size <= 2 * BITS_PER_WORD))
589 return (type_size + BITS_PER_WORD - 1) / BITS_PER_WORD;
591 return 0;
594 /* Implements the macro FUNCTION_ARG defined in cr16.h. */
595 static rtx
596 cr16_function_arg (cumulative_args_t cum_v, machine_mode mode,
597 const_tree type, bool named ATTRIBUTE_UNUSED)
599 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
600 cum->last_parm_in_reg = 0;
602 /* function_arg () is called with this type just after all the args have
603 had their registers assigned. The rtx that function_arg returns from
604 this type is supposed to pass to 'gen_call' but currently it is not
605 implemented. */
606 if (type == void_type_node)
607 return NULL_RTX;
609 if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
610 return NULL_RTX;
612 if (mode == BLKmode)
614 /* Enable structures that need padding bytes at the end to pass to a
615 function in registers. */
616 if (enough_regs_for_param (cum, type, mode) != 0)
618 cum->last_parm_in_reg = 1;
619 return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
623 if ((MIN_REG_FOR_PASSING_ARGS + cum->ints) > MAX_REG_FOR_PASSING_ARGS)
624 return NULL_RTX;
625 else
627 if (enough_regs_for_param (cum, type, mode) != 0)
629 cum->last_parm_in_reg = 1;
630 return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
634 return NULL_RTX;
637 /* Implements the macro INIT_CUMULATIVE_ARGS defined in cr16.h. */
638 void
639 cr16_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype,
640 rtx libfunc ATTRIBUTE_UNUSED)
642 tree param, next_param;
644 cum->ints = 0;
646 /* Determine if this function has variable arguments. This is indicated by
647 the last argument being 'void_type_mode' if there are no variable
648 arguments. Change here for a different vararg. */
649 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
650 param != NULL_TREE; param = next_param)
652 next_param = TREE_CHAIN (param);
653 if ((next_param == NULL_TREE) && (TREE_VALUE (param) != void_type_node))
655 cum->ints = -1;
656 return;
661 /* Implements the macro FUNCTION_ARG_ADVANCE defined in cr16.h. */
662 static void
663 cr16_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
664 const_tree type, bool named ATTRIBUTE_UNUSED)
666 CUMULATIVE_ARGS * cum = get_cumulative_args (cum_v);
668 /* l holds the number of registers required. */
669 int l = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
671 /* If the parameter isn't passed on a register don't advance cum. */
672 if (!cum->last_parm_in_reg)
673 return;
675 if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
676 return;
678 if ((mode == SImode) || (mode == HImode)
679 || (mode == QImode) || (mode == DImode))
681 if (l <= 1)
682 cum->ints += 1;
683 else
684 cum->ints += l;
686 else if ((mode == SFmode) || (mode == DFmode))
687 cum->ints += l;
688 else if ((mode) == BLKmode)
690 if ((l = enough_regs_for_param (cum, type, mode)) != 0)
691 cum->ints += l;
693 return;
696 /* Implements the macro FUNCTION_ARG_REGNO_P defined in cr16.h.
697 Return nonzero if N is a register used for passing parameters. */
699 cr16_function_arg_regno_p (int n)
701 return ((n <= MAX_REG_FOR_PASSING_ARGS) && (n >= MIN_REG_FOR_PASSING_ARGS));
704 /* Addressing modes.
705 Following set of function implement the macro GO_IF_LEGITIMATE_ADDRESS
706 defined in cr16.h. */
708 /* Helper function to check if is a valid base register that can
709 hold address. */
710 static int
711 cr16_addr_reg_p (rtx addr_reg)
713 rtx reg;
715 if (REG_P (addr_reg))
716 reg = addr_reg;
717 else if ((GET_CODE (addr_reg) == SUBREG)
718 && REG_P (SUBREG_REG (addr_reg))
719 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg)))
720 <= UNITS_PER_WORD))
721 reg = SUBREG_REG (addr_reg);
722 else
723 return FALSE;
725 if (GET_MODE (reg) != Pmode)
726 return FALSE;
728 return TRUE;
731 /* Helper functions: Created specifically for decomposing operand of CONST
732 Recursively look into expression x for code or data symbol.
733 The function expects the expression to contain combination of
734 SYMBOL_REF, CONST_INT, (PLUS or MINUS)
735 LABEL_REF, CONST_INT, (PLUS or MINUS)
736 SYMBOL_REF
737 LABEL_REF
738 All other combinations will result in code = -1 and data = ILLEGAL_DM
739 code data
740 -1 ILLEGAL_DM The expression did not contain SYMBOL_REF or LABEL_REF
741 0 DM_FAR SYMBOL_REF was found and it was far data reference.
742 0 DM_DEFAULT SYMBOL_REF was found and it was medium data reference.
743 1 ILLEGAL_DM LABEL_REF was found.
744 2 ILLEGAL_DM SYMBOL_REF was found and it was function reference. */
745 void
746 cr16_decompose_const (rtx x, int *code, enum data_model_type *data,
747 bool treat_as_const)
749 *code = -1;
750 *data = ILLEGAL_DM;
751 switch (GET_CODE (x))
753 case SYMBOL_REF:
754 *code = SYMBOL_REF_FUNCTION_P (x) ? 2 : 0;
755 /* 2 indicates func sym. */
756 if (*code == 0)
758 if (CR16_TARGET_DATA_NEAR)
759 *data = DM_DEFAULT;
760 else if (CR16_TARGET_DATA_MEDIUM)
761 *data = DM_FAR;
762 else if (CR16_TARGET_DATA_FAR)
764 if (treat_as_const)
765 /* This will be used only for printing
766 the qualifier. This call is (may be)
767 made by cr16_print_operand_address. */
768 *data = DM_FAR;
769 else
770 /* This call is (may be) made by
771 cr16_legitimate_address_p. */
772 *data = ILLEGAL_DM;
775 return;
777 case LABEL_REF:
778 /* 1 - indicates non-function symbol. */
779 *code = 1;
780 return;
782 case PLUS:
783 case MINUS:
784 /* Look into the tree nodes. */
785 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
786 cr16_decompose_const (XEXP (x, 1), code, data, treat_as_const);
787 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
788 cr16_decompose_const (XEXP (x, 0), code, data, treat_as_const);
789 return;
790 default:
791 return;
795 /* Decompose Address
796 This function decomposes the address returns the type of address
797 as defined in enum cr16_addrtype. It also fills the parameter *out.
798 The decomposed address can be used for two purposes. One to
799 check if the address is valid and second to print the address
800 operand.
802 Following tables list valid address supported in CR16C/C+ architectures.
803 Legend:
804 aN : Absoulte address N-bit address
805 R : One 16-bit register
806 RP : Consecutive two 16-bit registers or one 32-bit register
807 I : One 32-bit register
808 dispN : Signed displacement of N-bits
810 ----Code addresses----
811 Branch operands:
812 disp9 : CR16_ABSOLUTE (disp)
813 disp17 : CR16_ABSOLUTE (disp)
814 disp25 : CR16_ABSOLUTE (disp)
815 RP + disp25 : CR16_REGP_REL (base, disp)
817 Jump operands:
818 RP : CR16_REGP_REL (base, disp=0)
819 a24 : CR16_ABSOLUTE (disp)
821 ----Data addresses----
822 a20 : CR16_ABSOLUTE (disp) near (1M)
823 a24 : CR16_ABSOLUTE (disp) medium (16M)
824 R + d20 : CR16_REG_REL (base, disp) near (1M+64K)
825 RP + d4 : CR16_REGP_REL (base, disp) far (4G)
826 RP + d16 : CR16_REGP_REL (base, disp) far (4G)
827 RP + d20 : CR16_REGP_REL (base, disp) far (4G)
828 I : *** Valid but port does not support this
829 I + a20 : *** Valid but port does not support this
830 I + RP + d14: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
831 I + RP + d20: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
833 Decomposing Data model in case of absolute address.
835 Target Option Address type Resultant Data ref type
836 ---------------------- ------------ -----------------------
837 CR16_TARGET_MODEL_NEAR ABS20 DM_DEFAULT
838 CR16_TARGET_MODEL_NEAR IMM20 DM_DEFAULT
839 CR16_TARGET_MODEL_NEAR ABS24 Invalid
840 CR16_TARGET_MODEL_NEAR IMM32 Invalid
842 CR16_TARGET_MODEL_MEDIUM ABS20 DM_DEFAULT
843 CR16_TARGET_MODEL_MEDIUM IMM20 DM_DEFAULT
844 CR16_TARGET_MODEL_MEDIUM ABS24 DM_FAR
845 CR16_TARGET_MODEL_MEDIUM IMM32 Invalid
847 CR16_TARGET_MODEL_FAR ABS20 DM_DEFAULT
848 CR16_TARGET_MODEL_FAR IMM20 DM_DEFAULT
849 CR16_TARGET_MODEL_FAR ABS24 DM_FAR
850 CR16_TARGET_MODEL_FAR IMM32 DM_FAR. */
851 enum cr16_addrtype
852 cr16_decompose_address (rtx addr, struct cr16_address *out,
853 bool debug_print, bool treat_as_const)
855 rtx base = NULL_RTX, disp = NULL_RTX, index = NULL_RTX;
856 enum data_model_type data = ILLEGAL_DM;
857 int code = -1;
858 enum cr16_addrtype retval = CR16_INVALID;
860 switch (GET_CODE (addr))
862 case CONST_INT:
863 /* Absolute address (known at compile time). */
864 code = 0;
865 if (debug_print)
866 fprintf (stderr, "\ncode:%d", code);
867 disp = addr;
869 if (debug_print)
871 fprintf (stderr, "\ndisp:");
872 debug_rtx (disp);
875 if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
877 data = DM_DEFAULT;
878 if (debug_print)
879 fprintf (stderr, "\ndata:%d", data);
880 retval = CR16_ABSOLUTE;
882 else if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 24))
884 if (!CR16_TARGET_DATA_NEAR)
886 data = DM_FAR;
887 if (debug_print)
888 fprintf (stderr, "\ndata:%d", data);
889 retval = CR16_ABSOLUTE;
891 else
892 return CR16_INVALID; /* ABS24 is not support in NEAR model. */
894 else
895 return CR16_INVALID;
896 break;
898 case CONST:
899 /* A CONST is an expression of PLUS or MINUS with
900 CONST_INT, SYMBOL_REF or LABEL_REF. This is the
901 result of assembly-time arithmetic computation. */
902 retval = CR16_ABSOLUTE;
903 disp = addr;
904 /* Call the helper function to check the validity. */
905 cr16_decompose_const (XEXP (addr, 0), &code, &data, treat_as_const);
906 if ((code == 0) && (data == ILLEGAL_DM))
907 /* CONST is not valid code or data address. */
908 return CR16_INVALID;
909 if (debug_print)
911 fprintf (stderr, "\ndisp:");
912 debug_rtx (disp);
913 fprintf (stderr, "\ncode:%d", code);
914 fprintf (stderr, "\ndata:%d", data);
916 break;
918 case LABEL_REF:
919 retval = CR16_ABSOLUTE;
920 disp = addr;
921 /* 1 - indicates non-function symbol. */
922 code = 1;
923 if (debug_print)
925 fprintf (stderr, "\ndisp:");
926 debug_rtx (disp);
927 fprintf (stderr, "\ncode:%d", code);
929 break;
931 case SYMBOL_REF:
932 /* Absolute address (known at link time). */
933 retval = CR16_ABSOLUTE;
934 disp = addr;
935 /* This is a code address if symbol_ref is a function. */
936 /* 2 indicates func sym. */
937 code = SYMBOL_REF_FUNCTION_P (addr) ? 2 : 0;
938 if (debug_print)
940 fprintf (stderr, "\ndisp:");
941 debug_rtx (disp);
942 fprintf (stderr, "\ncode:%d", code);
944 /* If not function ref then check if valid data ref. */
945 if (code == 0)
947 if (CR16_TARGET_DATA_NEAR)
948 data = DM_DEFAULT;
949 else if (CR16_TARGET_DATA_MEDIUM)
950 data = DM_FAR;
951 else if (CR16_TARGET_DATA_FAR)
953 if (treat_as_const)
954 /* This will be used only for printing the
955 qualifier. This call is (may be) made
956 by cr16_print_operand_address. */
957 data = DM_FAR;
958 else
959 /* This call is (may be) made by
960 cr16_legitimate_address_p. */
961 return CR16_INVALID;
963 else
964 data = DM_DEFAULT;
966 if (debug_print)
967 fprintf (stderr, "\ndata:%d", data);
968 break;
970 case REG:
971 case SUBREG:
972 /* Register relative address. */
973 /* Assume REG fits in a single register. */
974 retval = CR16_REG_REL;
975 if (GET_MODE_BITSIZE (GET_MODE (addr)) > BITS_PER_WORD)
976 if (!LONG_REG_P (REGNO (addr)))
977 /* REG will result in reg pair. */
978 retval = CR16_REGP_REL;
979 base = addr;
980 if (debug_print)
982 fprintf (stderr, "\nbase:");
983 debug_rtx (base);
985 break;
987 case PLUS:
988 switch (GET_CODE (XEXP (addr, 0)))
990 case REG:
991 case SUBREG:
992 /* REG + DISP20. */
993 /* All Reg relative addresses having a displacement needs
994 to fit in 20-bits. */
995 disp = XEXP (addr, 1);
996 if (debug_print)
998 fprintf (stderr, "\ndisp:");
999 debug_rtx (disp);
1001 switch (GET_CODE (XEXP (addr, 1)))
1003 case CONST_INT:
1004 /* Shall fit in 20-bits. */
1005 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
1006 return CR16_INVALID;
1007 code = 0;
1008 if (debug_print)
1009 fprintf (stderr, "\ncode:%d", code);
1010 break;
1012 case UNSPEC:
1013 switch (XINT (XEXP (addr, 1), 1))
1015 case UNSPEC_LIBRARY_OFFSET:
1016 default:
1017 gcc_unreachable ();
1019 break;
1021 case LABEL_REF:
1022 case SYMBOL_REF:
1023 case CONST:
1024 /* This is also a valid expression for address.
1025 However, we cannot ascertain if the resultant
1026 displacement will be valid 20-bit value. Therefore,
1027 lets not allow such an expression for now. This will
1028 be updated when we find a way to validate this
1029 expression as legitimate address.
1030 Till then fall through CR16_INVALID. */
1031 default:
1032 return CR16_INVALID;
1035 /* Now check if REG can fit into single or pair regs. */
1036 retval = CR16_REG_REL;
1037 base = XEXP (addr, 0);
1038 if (debug_print)
1040 fprintf (stderr, "\nbase:");
1041 debug_rtx (base);
1043 if (GET_MODE_BITSIZE (GET_MODE ((XEXP (addr, 0)))) > BITS_PER_WORD)
1045 if (!LONG_REG_P (REGNO ((XEXP (addr, 0)))))
1046 /* REG will result in reg pair. */
1047 retval = CR16_REGP_REL;
1049 break;
1051 case PLUS:
1052 /* Valid expr:
1053 plus
1056 plus idx
1059 reg const_int
1061 Check if the operand 1 is valid index register. */
1062 data = ILLEGAL_DM;
1063 if (debug_print)
1064 fprintf (stderr, "\ndata:%d", data);
1065 switch (GET_CODE (XEXP (addr, 1)))
1067 case REG:
1068 case SUBREG:
1069 if (!REG_OK_FOR_INDEX_P (XEXP (addr, 1)))
1070 return CR16_INVALID;
1071 /* OK. REG is a valid index register. */
1072 index = XEXP (addr, 1);
1073 if (debug_print)
1075 fprintf (stderr, "\nindex:");
1076 debug_rtx (index);
1078 break;
1079 default:
1080 return CR16_INVALID;
1082 /* Check if operand 0 of operand 0 is REGP. */
1083 switch (GET_CODE (XEXP (XEXP (addr, 0), 0)))
1085 case REG:
1086 case SUBREG:
1087 /* Now check if REG is a REGP and not in LONG regs. */
1088 if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (addr, 0), 0)))
1089 > BITS_PER_WORD)
1091 if (REGNO (XEXP (XEXP (addr, 0), 0))
1092 >= CR16_FIRST_DWORD_REGISTER)
1093 return CR16_INVALID;
1094 base = XEXP (XEXP (addr, 0), 0);
1095 if (debug_print)
1097 fprintf (stderr, "\nbase:");
1098 debug_rtx (base);
1101 else
1102 return CR16_INVALID;
1103 break;
1104 default:
1105 return CR16_INVALID;
1107 /* Now check if the operand 1 of operand 0 is const_int. */
1108 if (GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
1110 disp = XEXP (XEXP (addr, 0), 1);
1111 if (debug_print)
1113 fprintf (stderr, "\ndisp:");
1114 debug_rtx (disp);
1116 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
1117 return CR16_INVALID;
1119 else
1120 return CR16_INVALID;
1121 retval = CR16_INDEX_REGP_REL;
1122 break;
1123 default:
1124 return CR16_INVALID;
1126 break;
1128 default:
1129 return CR16_INVALID;
1132 /* Check if the base and index registers are valid. */
1133 if (base && !(cr16_addr_reg_p (base)))
1134 return CR16_INVALID;
1135 if (base && !(CR16_REG_OK_FOR_BASE_P (base)))
1136 return CR16_INVALID;
1137 if (index && !(REG_OK_FOR_INDEX_P (index)))
1138 return CR16_INVALID;
1140 /* Write the decomposition to out parameter. */
1141 out->base = base;
1142 out->disp = disp;
1143 out->index = index;
1144 out->data = data;
1145 out->code = code;
1147 return retval;
1150 /* Return non-zero value if 'x' is legitimate PIC operand
1151 when generating PIC code. */
1153 legitimate_pic_operand_p (rtx x)
1155 switch (GET_CODE (x))
1157 case SYMBOL_REF:
1158 return 0;
1159 case LABEL_REF:
1160 return 0;
1161 case CONST:
1162 /* REVISIT: Use something like symbol_referenced_p. */
1163 if (GET_CODE (XEXP (x, 0)) == PLUS
1164 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
1165 || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
1166 && (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
1167 return 0;
1168 break;
1169 case MEM:
1170 return legitimate_pic_operand_p (XEXP (x, 0));
1171 default:
1172 break;
1174 return 1;
1177 /* Convert a non-PIC address in `orig' to a PIC address in `reg'.
1179 Input Output (-f pic) Output (-f PIC)
1180 orig reg
1182 C1 symbol symbol@BRO (r12) symbol@GOT (r12)
1184 C2 symbol + offset symbol+offset@BRO (r12) symbol+offset@GOT (r12)
1186 NOTE: @BRO is added using unspec:BRO
1187 NOTE: @GOT is added using unspec:GOT. */
1189 legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
1190 rtx reg)
1192 /* First handle a simple SYMBOL_REF or LABEL_REF. */
1193 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
1195 if (reg == 0)
1196 reg = gen_reg_rtx (Pmode);
1198 if (flag_pic == NEAR_PIC)
1200 /* Unspec to handle -fpic option. */
1201 emit_insn (gen_unspec_bro_addr (reg, orig));
1202 emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx));
1204 else if (flag_pic == FAR_PIC)
1206 /* Unspec to handle -fPIC option. */
1207 emit_insn (gen_unspec_got_addr (reg, orig));
1209 return reg;
1211 else if (GET_CODE (orig) == CONST)
1213 /* To handle (symbol + offset). */
1214 rtx base, offset;
1216 if (GET_CODE (XEXP (orig, 0)) == PLUS
1217 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1218 return orig;
1220 if (reg == 0)
1222 gcc_assert (can_create_pseudo_p ());
1223 reg = gen_reg_rtx (Pmode);
1226 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
1228 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
1229 offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1230 base == reg ? 0 : reg);
1232 /* REVISIT: Optimize for const-offsets. */
1233 emit_insn (gen_addsi3 (reg, base, offset));
1235 return reg;
1237 return orig;
1240 /* Implementation of TARGET_LEGITIMATE_ADDRESS_P. */
1241 static bool
1242 cr16_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
1243 rtx addr, bool strict)
1245 enum cr16_addrtype addrtype;
1246 struct cr16_address address;
1248 if (TARGET_DEBUG_ADDR)
1250 fprintf (stderr,
1251 "\n======\nTARGET_LEGITIMATE_ADDRESS_P, mode = %s, strict = %d",
1252 GET_MODE_NAME (mode), strict);
1253 debug_rtx (addr);
1255 addrtype = cr16_decompose_address (addr, &address,
1256 (TARGET_DEBUG_ADDR ? 1 : 0), FALSE);
1258 if (TARGET_DEBUG_ADDR)
1260 const char *typestr;
1262 switch (addrtype)
1264 case CR16_INVALID:
1265 typestr = "invalid";
1266 break;
1267 case CR16_ABSOLUTE:
1268 typestr = "absolute";
1269 break;
1270 case CR16_REG_REL:
1271 typestr = "register relative";
1272 break;
1273 case CR16_REGP_REL:
1274 typestr = "register pair relative";
1275 break;
1276 case CR16_INDEX_REGP_REL:
1277 typestr = "index + register pair relative";
1278 break;
1279 default:
1280 gcc_unreachable ();
1282 fprintf (stderr, "\ncr16 address type: %s\n", typestr);
1285 if (addrtype == CR16_INVALID)
1286 return FALSE;
1288 if (strict)
1290 if (address.base
1291 && !REGNO_MODE_OK_FOR_BASE_P (REGNO (address.base), mode))
1293 if (TARGET_DEBUG_ADDR)
1294 fprintf (stderr, "base register not strict\n");
1295 return FALSE;
1297 if (address.index && !REGNO_OK_FOR_INDEX_P (REGNO (address.index)))
1299 if (TARGET_DEBUG_ADDR)
1300 fprintf (stderr, "index register not strict\n");
1301 return FALSE;
1305 /* Return true if addressing mode is register relative. */
1306 if (flag_pic)
1308 if (addrtype == CR16_REG_REL || addrtype == CR16_REGP_REL)
1309 return TRUE;
1310 else
1311 return FALSE;
1314 return TRUE;
1317 /* Routines to compute costs. */
1319 /* Return cost of the memory address x. */
1320 static int
1321 cr16_address_cost (rtx addr, machine_mode mode ATTRIBUTE_UNUSED,
1322 addr_space_t as ATTRIBUTE_UNUSED,
1323 bool speed ATTRIBUTE_UNUSED)
1325 enum cr16_addrtype addrtype;
1326 struct cr16_address address;
1327 int cost = 2;
1329 addrtype = cr16_decompose_address (addr, &address, 0, FALSE);
1331 gcc_assert (addrtype != CR16_INVALID);
1333 /* CR16_ABSOLUTE : 3
1334 CR16_REG_REL (disp !=0) : 4
1335 CR16_REG_REL (disp ==0) : 5
1336 CR16_REGP_REL (disp !=0) : 6
1337 CR16_REGP_REL (disp ==0) : 7
1338 CR16_INDEX_REGP_REL (disp !=0) : 8
1339 CR16_INDEX_REGP_REL (disp ==0) : 9. */
1340 switch (addrtype)
1342 case CR16_ABSOLUTE:
1343 cost += 1;
1344 break;
1345 case CR16_REGP_REL:
1346 cost += 2;
1347 /* Fall through. */
1348 case CR16_REG_REL:
1349 cost += 3;
1350 if (address.disp)
1351 cost -= 1;
1352 break;
1353 case CR16_INDEX_REGP_REL:
1354 cost += 7;
1355 if (address.disp)
1356 cost -= 1;
1357 default:
1358 break;
1361 if (TARGET_DEBUG_ADDR)
1363 fprintf (stderr, "\n======\nmacro TARGET_ADDRESS_COST = %d\n", cost);
1364 debug_rtx (addr);
1367 return cost;
1371 /* Implement `TARGET_REGISTER_MOVE_COST'. */
1372 static int
1373 cr16_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
1374 reg_class_t from ATTRIBUTE_UNUSED, reg_class_t to)
1376 return (to != GENERAL_REGS ? 8 : 2);
1379 /* Implement `TARGET_MEMORY_MOVE_COST'. */
1381 /* Return the cost of moving data of mode MODE between a register of class
1382 CLASS and memory; IN is zero if the value is to be written to memory,
1383 nonzero if it is to be read in. This cost is relative to those in
1384 REGISTER_MOVE_COST. */
1385 static int
1386 cr16_memory_move_cost (machine_mode mode,
1387 reg_class_t rclass ATTRIBUTE_UNUSED,
1388 bool in ATTRIBUTE_UNUSED)
1390 /* One LD or ST takes twice the time of a simple reg-reg move. */
1391 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
1392 return (4 * cr16_hard_regno_nregs (0, mode));
1393 else
1394 return (100);
1397 /* Instruction output. */
1399 /* Check if a const_double is ok for cr16 store-immediate instructions. */
1401 cr16_const_double_ok (rtx op)
1403 if (GET_MODE (op) == SFmode)
1405 long l;
1406 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op), l);
1407 return UNSIGNED_INT_FITS_N_BITS (l, 4) ? 1 : 0;
1410 return ((UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op), 4)) &&
1411 (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op), 4))) ? 1 : 0;
1414 /* Returns bit position of first 0 or 1 bit.
1415 It is safe to assume val as 16-bit wide. */
1417 cr16_operand_bit_pos (int val, int bitval)
1419 int i;
1420 if (bitval == 0)
1421 val = ~val;
1423 for (i = 0; i < 16; i++)
1424 if (val & (1 << i))
1425 break;
1426 return i;
1429 /* Implements the macro PRINT_OPERAND defined in cr16.h. */
1430 static void
1431 cr16_print_operand (FILE * file, rtx x, int code)
1433 int ptr_dereference = 0;
1435 switch (code)
1437 case 'd':
1439 const char *cr16_cmp_str;
1440 switch (GET_CODE (x))
1442 /* MD: compare (reg, reg or imm) but CR16: cmp (reg or imm, reg)
1443 -> swap all non symmetric ops. */
1444 case EQ:
1445 cr16_cmp_str = "eq";
1446 break;
1447 case NE:
1448 cr16_cmp_str = "ne";
1449 break;
1450 case GT:
1451 cr16_cmp_str = "lt";
1452 break;
1453 case GTU:
1454 cr16_cmp_str = "lo";
1455 break;
1456 case LT:
1457 cr16_cmp_str = "gt";
1458 break;
1459 case LTU:
1460 cr16_cmp_str = "hi";
1461 break;
1462 case GE:
1463 cr16_cmp_str = "le";
1464 break;
1465 case GEU:
1466 cr16_cmp_str = "ls";
1467 break;
1468 case LE:
1469 cr16_cmp_str = "ge";
1470 break;
1471 case LEU:
1472 cr16_cmp_str = "hs";
1473 break;
1474 default:
1475 gcc_unreachable ();
1477 fprintf (file, "%s", cr16_cmp_str);
1478 return;
1480 case '$':
1481 putc ('$', file);
1482 return;
1484 case 'p':
1485 if (GET_CODE (x) == REG)
1487 /* For Push instructions, we should not print register pairs. */
1488 fprintf (file, "%s", reg_names[REGNO (x)]);
1489 return;
1491 break;
1493 case 'b':
1494 /* Print the immediate address for bal
1495 'b' is used instead of 'a' to avoid compiler calling
1496 the GO_IF_LEGITIMATE_ADDRESS which cannot
1497 perform checks on const_int code addresses as it
1498 assumes all const_int are data addresses. */
1499 fprintf (file, "0x%lx", INTVAL (x));
1500 return;
1502 case 'r':
1503 /* Print bit position of first 0. */
1504 fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 0));
1505 return;
1507 case 's':
1508 /* Print bit position of first 1. */
1509 fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 1));
1510 return;
1511 case 'g':
1512 /* 'g' is used for implicit mem: dereference. */
1513 ptr_dereference = 1;
1514 /* FALLTHRU */
1515 case 'f':
1516 case 0:
1517 /* default. */
1518 switch (GET_CODE (x))
1520 case REG:
1521 if (GET_MODE_BITSIZE (GET_MODE (x)) > BITS_PER_WORD)
1523 if (LONG_REG_P (REGNO (x)))
1524 fprintf (file, "(%s)", reg_names[REGNO (x)]);
1525 else
1526 fprintf (file, "(%s,%s)", reg_names[REGNO (x) + 1],
1527 reg_names[REGNO (x)]);
1529 else
1530 fprintf (file, "%s", reg_names[REGNO (x)]);
1531 return;
1533 case MEM:
1534 output_address (GET_MODE (x), XEXP (x, 0));
1535 return;
1537 case CONST_DOUBLE:
1539 long l;
1541 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
1543 fprintf (file, "$0x%lx", l);
1544 return;
1546 case CONST_INT:
1548 fprintf (file, "$%ld", INTVAL (x));
1549 return;
1551 case UNSPEC:
1552 switch (XINT (x, 1))
1554 default:
1555 gcc_unreachable ();
1557 break;
1559 default:
1560 if (!ptr_dereference)
1562 putc ('$', file);
1564 cr16_print_operand_address (file, VOIDmode, x);
1565 return;
1567 gcc_unreachable ();
1568 default:
1569 output_operand_lossage ("invalid %%xn code");
1572 gcc_unreachable ();
1575 /* Implements the macro PRINT_OPERAND_ADDRESS defined in cr16.h. */
1577 static void
1578 cr16_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr)
1580 enum cr16_addrtype addrtype;
1581 struct cr16_address address;
1583 /* Decompose the address. Also ask it to treat address as constant. */
1584 addrtype = cr16_decompose_address (addr, &address, 0, TRUE);
1586 if (address.disp && GET_CODE (address.disp) == UNSPEC)
1588 debug_rtx (addr);
1591 switch (addrtype)
1593 case CR16_REG_REL:
1594 if (address.disp)
1596 if (GET_CODE (address.disp) == UNSPEC)
1597 cr16_print_operand (file, address.disp, 0);
1598 else
1599 output_addr_const (file, address.disp);
1601 else
1602 fprintf (file, "0");
1603 fprintf (file, "(%s)", reg_names[REGNO (address.base)]);
1604 break;
1606 case CR16_ABSOLUTE:
1607 if (address.disp)
1608 output_addr_const (file, address.disp);
1609 else
1610 fprintf (file, "0");
1611 break;
1613 case CR16_INDEX_REGP_REL:
1614 fprintf (file, "[%s]", reg_names[REGNO (address.index)]);
1615 /* Fall through. */
1616 case CR16_REGP_REL:
1617 if (address.disp)
1619 if (GET_CODE (address.disp) == UNSPEC)
1620 cr16_print_operand (file, address.disp, 0);
1621 else
1622 output_addr_const (file, address.disp);
1624 else
1625 fprintf (file, "0");
1626 fprintf (file, "(%s,%s)", reg_names[REGNO (address.base) + 1],
1627 reg_names[REGNO (address.base)]);
1628 break;
1629 default:
1630 debug_rtx (addr);
1631 gcc_unreachable ();
1633 /* Add qualifiers to the address expression that was just printed. */
1634 if (flag_pic < NEAR_PIC && address.code == 0)
1636 if (address.data == DM_FAR)
1637 /* Addr contains SYMBOL_REF & far data ptr. */
1638 fprintf (file, "@l");
1639 else if (address.data == DM_DEFAULT)
1640 /* Addr contains SYMBOL_REF & medium data ptr. */
1641 fprintf (file, "@m");
1642 /* Addr contains SYMBOL_REF & medium data ptr. */
1643 else if (address.data == DM_NEAR)
1644 /* Addr contains SYMBOL_REF & near data ptr. */
1645 fprintf (file, "@s");
1647 else if (flag_pic == NEAR_PIC
1648 && (address.code == 0) && (address.data == DM_FAR
1649 || address.data == DM_DEFAULT
1650 || address.data == DM_NEAR))
1652 fprintf (file, "@l");
1654 else if (flag_pic == NEAR_PIC && address.code == 2)
1656 fprintf (file, "pic");
1658 else if (flag_pic == NEAR_PIC && address.code == 1)
1660 fprintf (file, "@cpic");
1663 else if (flag_pic == FAR_PIC && address.code == 2)
1665 /* REVISIT: cr16 register indirect jump expects a 1-bit right shifted
1666 address ! GOTc tells assembler this symbol is a text-address
1667 This needs to be fixed in such a way that this offset is done
1668 only in the case where an address is being used for indirect jump
1669 or call. Determining the potential usage of loadd is of course not
1670 possible always. Eventually, this has to be fixed in the
1671 processor. */
1672 fprintf (file, "GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1674 else if (flag_pic == FAR_PIC && address.code == 1)
1676 fprintf (file, "@cGOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1679 else if (flag_pic == FAR_PIC &&
1680 (address.data == DM_FAR || address.data == DM_DEFAULT
1681 || address.data == DM_NEAR))
1683 fprintf (file, "@GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1687 /* Machine description helper functions. */
1689 /* Called from cr16.md. The return value depends on the parameter push_or_pop:
1690 When push_or_pop is zero -> string for push instructions of prologue.
1691 When push_or_pop is nonzero -> string for pop/popret/retx in epilogue.
1692 Relies on the assumptions:
1693 1. RA is the last register to be saved.
1694 2. The maximal value of the counter is MAX_COUNT. */
1695 char *
1696 cr16_prepare_push_pop_string (int push_or_pop)
1698 /* j is the number of registers being saved, takes care that there won't be
1699 more than 8 in one push/pop instruction. */
1701 /* For the register mask string. */
1702 static char one_inst_str[50];
1704 /* i is the index of current_frame_info.save_regs[], going from 0 until
1705 current_frame_info.last_reg_to_save. */
1706 int i, start_reg;
1707 int word_cnt;
1708 int print_ra;
1709 char *return_str;
1711 /* For reversing on the push instructions if there are more than one. */
1712 char *temp_str;
1714 return_str = (char *) xmalloc (160);
1715 temp_str = (char *) xmalloc (160);
1717 /* Initialize. */
1718 memset (return_str, 0, 3);
1720 i = 0;
1721 while (i <= current_frame_info.last_reg_to_save)
1723 /* Prepare mask for one instruction. */
1724 one_inst_str[0] = 0;
1726 /* To count number of words in one instruction. */
1727 word_cnt = 0;
1728 start_reg = i;
1729 print_ra = 0;
1730 while ((word_cnt < MAX_COUNT)
1731 && (i <= current_frame_info.last_reg_to_save))
1733 /* For each non consecutive save register,
1734 a new instruction shall be generated. */
1735 if (!current_frame_info.save_regs[i])
1737 /* Move to next reg and break. */
1738 ++i;
1739 break;
1742 if (i == RETURN_ADDRESS_REGNUM)
1743 print_ra = 1;
1744 else
1746 /* Check especially if adding 2 does not cross the MAX_COUNT. */
1747 if ((word_cnt + ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2))
1748 >= MAX_COUNT)
1749 break;
1750 /* Increase word count by 2 for long registers except RA. */
1751 word_cnt += ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2);
1753 ++i;
1756 /* No need to generate any instruction as
1757 no register or RA needs to be saved. */
1758 if ((word_cnt == 0) && (print_ra == 0))
1759 continue;
1761 /* Now prepare the instruction operands. */
1762 if (word_cnt > 0)
1764 sprintf (one_inst_str, "$%d, %s", word_cnt, reg_names[start_reg]);
1765 if (print_ra)
1766 strcat (one_inst_str, ", ra");
1768 else
1769 strcat (one_inst_str, "ra");
1771 if (push_or_pop == 1)
1773 /* Pop instruction. */
1774 if (print_ra && !cr16_interrupt_function_p ()
1775 && !crtl->calls_eh_return)
1776 /* Print popret if RA is saved and its not a interrupt
1777 function. */
1778 strcpy (temp_str, "\n\tpopret\t");
1779 else
1780 strcpy (temp_str, "\n\tpop\t");
1782 strcat (temp_str, one_inst_str);
1784 /* Add the pop instruction list. */
1785 strcat (return_str, temp_str);
1787 else
1789 /* Push instruction. */
1790 strcpy (temp_str, "\n\tpush\t");
1791 strcat (temp_str, one_inst_str);
1793 /* We need to reverse the order of the instructions if there
1794 are more than one. (since the pop will not be reversed in
1795 the epilogue. */
1796 strcat (temp_str, return_str);
1797 strcpy (return_str, temp_str);
1801 if (push_or_pop == 1)
1803 /* POP. */
1804 if (cr16_interrupt_function_p ())
1805 strcat (return_str, "\n\tretx\n");
1806 else if (crtl->calls_eh_return)
1808 /* Add stack adjustment before returning to exception handler
1809 NOTE: EH_RETURN_STACKADJ_RTX must refer to (r5, r4). */
1810 strcat (return_str, "\n\taddd\t (r5, r4), (sp)\t\n");
1811 strcat (return_str, "\n\tjump\t (ra)\n");
1813 /* But before anything else, undo the adjustment addition done in
1814 cr16_expand_epilogue (). */
1815 strcpy (temp_str, "\n\tsubd\t (r5, r4), (sp)\t\n");
1816 strcat (temp_str, return_str);
1817 strcpy (return_str, temp_str);
1819 else if (!FUNC_IS_NORETURN_P (current_function_decl)
1820 && !(current_frame_info.save_regs[RETURN_ADDRESS_REGNUM]))
1821 strcat (return_str, "\n\tjump\t (ra)\n");
1824 /* Skip the newline and the tab in the start of return_str. */
1825 return_str += 2;
1826 return return_str;
1830 /* Generate DWARF2 annotation for multi-push instruction. */
1831 static void
1832 cr16_create_dwarf_for_multi_push (rtx insn)
1834 rtx dwarf, reg, tmp;
1835 int i, j, from, to, word_cnt, dwarf_par_index, inc;
1836 machine_mode mode;
1837 int num_regs = 0, offset = 0, split_here = 0, total_push_bytes = 0;
1839 for (i = 0; i <= current_frame_info.last_reg_to_save; ++i)
1841 if (current_frame_info.save_regs[i])
1843 ++num_regs;
1844 if (i < CR16_FIRST_DWORD_REGISTER)
1845 total_push_bytes += 2;
1846 else
1847 total_push_bytes += 4;
1851 if (!num_regs)
1852 return;
1854 dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1));
1855 dwarf_par_index = num_regs;
1857 from = current_frame_info.last_reg_to_save + 1;
1858 to = current_frame_info.last_reg_to_save;
1859 word_cnt = 0;
1861 for (i = current_frame_info.last_reg_to_save; i >= 0;)
1863 if (!current_frame_info.save_regs[i] || i == 0 || split_here)
1865 /* This block of regs is pushed in one instruction. */
1866 if (i == 0 && current_frame_info.save_regs[i])
1867 from = 0;
1869 for (j = to; j >= from; --j)
1871 if (j < CR16_FIRST_DWORD_REGISTER)
1873 mode = HImode;
1874 inc = 1;
1876 else
1878 mode = SImode;
1879 inc = 2;
1881 reg = gen_rtx_REG (mode, j);
1882 offset += 2 * inc;
1883 tmp = gen_rtx_SET (gen_frame_mem (mode,
1884 plus_constant
1885 (Pmode, stack_pointer_rtx,
1886 total_push_bytes - offset)),
1887 reg);
1888 RTX_FRAME_RELATED_P (tmp) = 1;
1889 XVECEXP (dwarf, 0, dwarf_par_index--) = tmp;
1891 from = i;
1892 to = --i;
1893 split_here = 0;
1894 word_cnt = 0;
1895 continue;
1898 if (i != RETURN_ADDRESS_REGNUM)
1900 inc = (i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2;
1901 if (word_cnt + inc >= MAX_COUNT || FRAME_POINTER_REGNUM == i)
1903 split_here = 1;
1904 from = i;
1905 continue;
1907 word_cnt += inc;
1910 from = i--;
1913 tmp = gen_rtx_SET (stack_pointer_rtx,
1914 gen_rtx_PLUS (SImode, stack_pointer_rtx,
1915 GEN_INT (-offset)));
1916 RTX_FRAME_RELATED_P (tmp) = 1;
1917 XVECEXP (dwarf, 0, 0) = tmp;
1919 add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
1923 CompactRISC CR16 Architecture stack layout:
1925 0 +---------------------
1930 +==================== Sp (x) = Ap (x+1)
1931 A | Args for functions
1932 | | called by X and Dynamically
1933 | | Dynamic allocations allocated and
1934 | | (alloca, variable deallocated
1935 Stack | length arrays).
1936 grows +-------------------- Fp (x)
1937 down| | Local variables of X
1938 ward| +--------------------
1939 | | Regs saved for X-1
1940 | +==================== Sp (x-1) = Ap (x)
1941 | Args for func X
1942 | pushed by X-1
1943 +-------------------- Fp (x-1)
1948 void
1949 cr16_expand_prologue (void)
1951 rtx insn;
1953 cr16_compute_frame ();
1954 cr16_compute_save_regs ();
1956 /* If there is no need in push and adjustment to sp, return. */
1957 if ((current_frame_info.total_size + current_frame_info.reg_size) == 0)
1958 return;
1960 if (current_frame_info.last_reg_to_save != -1)
1962 /* If there are registers to push. */
1963 insn = emit_insn (gen_push_for_prologue
1964 (GEN_INT (current_frame_info.reg_size)));
1965 cr16_create_dwarf_for_multi_push (insn);
1966 RTX_FRAME_RELATED_P (insn) = 1;
1970 if (current_frame_info.total_size > 0)
1972 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1973 GEN_INT (-current_frame_info.total_size)));
1974 RTX_FRAME_RELATED_P (insn) = 1;
1977 if (frame_pointer_needed)
1979 /* Initialize the frame pointer with the value of the stack pointer
1980 pointing now to the locals. */
1981 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1985 /* Generate insn that updates the stack for local variables and padding
1986 for registers we save. - Generate the appropriate return insn. */
1987 void
1988 cr16_expand_epilogue (void)
1990 rtx insn;
1992 /* Nonzero if we need to return and pop only RA. This will generate a
1993 different insn. This differentiate is for the peepholes for call as
1994 last statement in function. */
1995 int only_popret_RA = (current_frame_info.save_regs[RETURN_ADDRESS_REGNUM]
1996 && (current_frame_info.reg_size
1997 == CR16_UNITS_PER_DWORD));
1999 if (frame_pointer_needed)
2001 /* Restore the stack pointer with the frame pointers value. */
2002 insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
2005 if (current_frame_info.total_size > 0)
2007 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2008 GEN_INT (current_frame_info.total_size)));
2009 RTX_FRAME_RELATED_P (insn) = 1;
2012 if (crtl->calls_eh_return)
2014 /* Add this here so that (r5, r4) is actually loaded with the adjustment
2015 value; otherwise, the load might be optimized away...
2016 NOTE: remember to subtract the adjustment before popping the regs
2017 and add it back before returning. */
2018 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2019 EH_RETURN_STACKADJ_RTX));
2022 if (cr16_interrupt_function_p ())
2024 insn = emit_jump_insn (gen_interrupt_return ());
2025 RTX_FRAME_RELATED_P (insn) = 1;
2027 else if (crtl->calls_eh_return)
2029 /* Special case, pop what's necessary, adjust SP and jump to (RA). */
2030 insn = emit_jump_insn (gen_pop_and_popret_return
2031 (GEN_INT (current_frame_info.reg_size)));
2032 RTX_FRAME_RELATED_P (insn) = 1;
2034 else if (current_frame_info.last_reg_to_save == -1)
2035 /* Nothing to pop. */
2036 /* Don't output jump for interrupt routine, only retx. */
2037 emit_jump_insn (gen_jump_return ());
2038 else if (only_popret_RA)
2040 insn = emit_jump_insn (gen_popret_RA_return ());
2041 RTX_FRAME_RELATED_P (insn) = 1;
2043 else
2045 insn = emit_jump_insn (gen_pop_and_popret_return
2046 (GEN_INT (current_frame_info.reg_size)));
2047 RTX_FRAME_RELATED_P (insn) = 1;
2051 /* Implements FRAME_POINTER_REQUIRED. */
2052 static bool
2053 cr16_frame_pointer_required (void)
2055 return (cfun->calls_alloca || crtl->calls_eh_return
2056 || cfun->has_nonlocal_label || crtl->calls_eh_return);
2059 static bool
2060 cr16_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
2062 return (to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true);
2066 /* A C compound statement that attempts to replace X with
2067 a valid memory address for an operand of mode MODE. WIN
2068 will be a C statement label elsewhere in the code.
2069 X will always be the result of a call to break_out_memory_refs (),
2070 and OLDX will be the operand that was given to that function to
2071 produce X.
2072 The code generated by this macro should not alter the
2073 substructure of X. If it transforms X into a more legitimate form,
2074 it should assign X (which will always be a C variable) a new value. */
2075 static rtx
2076 cr16_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED,
2077 machine_mode mode ATTRIBUTE_UNUSED)
2079 if (flag_pic)
2080 return legitimize_pic_address (orig_x, mode, NULL_RTX);
2081 else
2082 return x;
2085 /* Implement TARGET_LEGITIMATE_CONSTANT_P
2086 Nonzero if X is a legitimate constant for an immediate
2087 operand on the target machine. You can assume that X
2088 satisfies CONSTANT_P. In cr16c treat legitimize float
2089 constant as an immediate operand. */
2090 static bool
2091 cr16_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED,
2092 rtx x ATTRIBUTE_UNUSED)
2094 return 1;
2097 void
2098 notice_update_cc (rtx exp)
2100 if (GET_CODE (exp) == SET)
2102 /* Jumps do not alter the cc's. */
2103 if (SET_DEST (exp) == pc_rtx)
2104 return;
2106 /* Moving register or memory into a register:
2107 it doesn't alter the cc's, but it might invalidate
2108 the RTX's which we remember the cc's came from.
2109 (Note that moving a constant 0 or 1 MAY set the cc's). */
2110 if (REG_P (SET_DEST (exp))
2111 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM))
2113 return;
2116 /* Moving register into memory doesn't alter the cc's.
2117 It may invalidate the RTX's which we remember the cc's came from. */
2118 if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp)))
2120 return;
2124 CC_STATUS_INIT;
2125 return;
2128 static scalar_int_mode
2129 cr16_unwind_word_mode (void)
2131 return SImode;
2134 /* Helper function for md file. This function is used to emit arithmetic
2135 DI instructions. The argument "num" decides which instruction to be
2136 printed. */
2137 const char *
2138 cr16_emit_add_sub_di (rtx *operands, enum rtx_code code)
2140 rtx lo_op[2] ;
2141 rtx hi0_op[2] ;
2142 rtx hi1_op[2] ;
2144 lo_op[0] = gen_lowpart (SImode, operands[0]);
2145 hi0_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 4);
2146 hi1_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 6);
2148 lo_op[1] = gen_lowpart (SImode, operands[2]);
2149 hi0_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 4);
2150 hi1_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 6);
2152 switch (code)
2154 case PLUS:
2156 output_asm_insn ("addd\t%1, %0", lo_op) ;
2157 output_asm_insn ("addcw\t%1, %0", hi0_op) ;
2158 output_asm_insn ("addcw\t%1, %0", hi1_op) ;
2159 break;
2161 case MINUS:
2163 output_asm_insn ("subd\t%1, %0", lo_op) ;
2164 output_asm_insn ("subcw\t%1, %0", hi0_op) ;
2165 output_asm_insn ("subcw\t%1, %0", hi1_op) ;
2166 break;
2168 default:
2169 break;
2172 return "";
2176 /* Helper function for md file. This function is used to emit logical
2177 DI instructions. The argument "num" decides which instruction to be
2178 printed. */
2179 const char *
2180 cr16_emit_logical_di (rtx *operands, enum rtx_code code)
2182 rtx lo_op[2] ;
2183 rtx hi_op[2] ;
2185 lo_op[0] = gen_lowpart (SImode, operands[0]);
2186 hi_op[0] = simplify_gen_subreg (SImode, operands[0], DImode, 4);
2188 lo_op[1] = gen_lowpart (SImode, operands[2]);
2189 hi_op[1] = simplify_gen_subreg (SImode, operands[2], DImode, 4);
2191 switch (code)
2193 case AND:
2195 output_asm_insn ("andd\t%1, %0", lo_op) ;
2196 output_asm_insn ("andd\t%1, %0", hi_op) ;
2197 return "";
2199 case IOR:
2201 output_asm_insn ("ord\t%1, %0", lo_op) ;
2202 output_asm_insn ("ord\t%1, %0", hi_op) ;
2203 return "";
2205 case XOR:
2207 output_asm_insn ("xord\t%1, %0", lo_op) ;
2208 output_asm_insn ("xord\t%1, %0", hi_op) ;
2209 return "";
2211 default:
2212 break;
2215 return "";
2218 /* Implement PUSH_ROUNDING. */
2220 poly_int64
2221 cr16_push_rounding (poly_int64 bytes)
2223 return (bytes + 1) & ~1;
2226 /* Initialize 'targetm' variable which contains pointers to functions
2227 and data relating to the target machine. */
2229 struct gcc_target targetm = TARGET_INITIALIZER;