[AArch64] Fix ICEs in aarch64_print_operand
[official-gcc.git] / gcc / config / cr16 / cr16.c
blobbd4e028f328ecdff2e57aca05cbcd5717e116e4d
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 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "target.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "stringpool.h"
29 #include "attribs.h"
30 #include "df.h"
31 #include "memmodel.h"
32 #include "tm_p.h"
33 #include "regs.h"
34 #include "emit-rtl.h"
35 #include "diagnostic-core.h"
36 #include "stor-layout.h"
37 #include "calls.h"
38 #include "conditions.h"
39 #include "output.h"
40 #include "expr.h"
41 #include "builtins.h"
43 /* This file should be included last. */
44 #include "target-def.h"
46 /* Definitions. */
48 /* Maximum number of register used for passing parameters. */
49 #define MAX_REG_FOR_PASSING_ARGS 6
51 /* Minimum number register used for passing parameters. */
52 #define MIN_REG_FOR_PASSING_ARGS 2
54 /* The maximum count of words supported in the assembly of the architecture in
55 a push/pop instruction. */
56 #define MAX_COUNT 8
58 /* Predicate is true if the current function is a 'noreturn' function,
59 i.e. it is qualified as volatile. */
60 #define FUNC_IS_NORETURN_P(decl) (TREE_THIS_VOLATILE (decl))
62 /* Predicate that holds when we need to save registers even for 'noreturn'
63 functions, to accommodate for unwinding. */
64 #define MUST_SAVE_REGS_P() \
65 (flag_unwind_tables || (flag_exceptions && !UI_SJLJ))
67 /* Nonzero if the rtx X is a signed const int of n bits. */
68 #define RTX_SIGNED_INT_FITS_N_BITS(X, n) \
69 ((GET_CODE (X) == CONST_INT \
70 && SIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
72 /* Nonzero if the rtx X is an unsigned const int of n bits. */
73 #define RTX_UNSIGNED_INT_FITS_N_BITS(X, n) \
74 ((GET_CODE (X) == CONST_INT \
75 && UNSIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
77 /* Structure for stack computations. */
79 /* variable definitions in the struture
80 args_size Number of bytes saved on the stack for local
81 variables
83 reg_size Number of bytes saved on the stack for
84 non-scratch registers
86 total_size The sum of 2 sizes: locals vars and padding byte
87 for saving the registers. Used in expand_prologue()
88 and expand_epilogue()
90 last_reg_to_save Will hold the number of the last register the
91 prologue saves, -1 if no register is saved
93 save_regs[16] Each object in the array is a register number.
94 Mark 1 for registers that need to be saved
96 num_regs Number of registers saved
98 initialized Non-zero if frame size already calculated, not
99 used yet
101 function_makes_calls Does the function make calls ? not used yet. */
103 struct cr16_frame_info
105 unsigned long var_size;
106 unsigned long args_size;
107 unsigned int reg_size;
108 unsigned long total_size;
109 long last_reg_to_save;
110 long save_regs[FIRST_PSEUDO_REGISTER];
111 int num_regs;
112 int initialized;
113 int function_makes_calls;
116 /* Current frame information calculated by cr16_compute_frame_size. */
117 static struct cr16_frame_info current_frame_info;
119 /* Static Variables. */
121 /* Data model that was supplied by user via command line option
122 This will be overridden in case of invalid combination
123 of core and data model options are supplied. */
124 static enum data_model_type data_model = DM_DEFAULT;
126 /* TARGETM Function Prototypes and forward declarations */
127 static void cr16_print_operand (FILE *, rtx, int);
128 static void cr16_print_operand_address (FILE *, machine_mode, rtx);
130 /* Stack layout and calling conventions. */
131 #undef TARGET_STRUCT_VALUE_RTX
132 #define TARGET_STRUCT_VALUE_RTX cr16_struct_value_rtx
133 #undef TARGET_RETURN_IN_MEMORY
134 #define TARGET_RETURN_IN_MEMORY cr16_return_in_memory
136 /* Target-specific uses of '__attribute__'. */
137 #undef TARGET_ATTRIBUTE_TABLE
138 #define TARGET_ATTRIBUTE_TABLE cr16_attribute_table
139 #undef TARGET_NARROW_VOLATILE_BITFIELD
140 #define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false
142 /* EH related. */
143 #undef TARGET_UNWIND_WORD_MODE
144 #define TARGET_UNWIND_WORD_MODE cr16_unwind_word_mode
146 /* Override Options. */
147 #undef TARGET_OPTION_OVERRIDE
148 #define TARGET_OPTION_OVERRIDE cr16_override_options
150 /* Conditional register usuage. */
151 #undef TARGET_CONDITIONAL_REGISTER_USAGE
152 #define TARGET_CONDITIONAL_REGISTER_USAGE cr16_conditional_register_usage
154 /* Controlling register spills. */
155 #undef TARGET_CLASS_LIKELY_SPILLED_P
156 #define TARGET_CLASS_LIKELY_SPILLED_P cr16_class_likely_spilled_p
158 /* Passing function arguments. */
159 #undef TARGET_FUNCTION_ARG
160 #define TARGET_FUNCTION_ARG cr16_function_arg
161 #undef TARGET_FUNCTION_ARG_ADVANCE
162 #define TARGET_FUNCTION_ARG_ADVANCE cr16_function_arg_advance
163 #undef TARGET_RETURN_POPS_ARGS
164 #define TARGET_RETURN_POPS_ARGS cr16_return_pops_args
166 /* Initialize the GCC target structure. */
167 #undef TARGET_FRAME_POINTER_REQUIRED
168 #define TARGET_FRAME_POINTER_REQUIRED cr16_frame_pointer_required
169 #undef TARGET_CAN_ELIMINATE
170 #define TARGET_CAN_ELIMINATE cr16_can_eliminate
171 #undef TARGET_LEGITIMIZE_ADDRESS
172 #define TARGET_LEGITIMIZE_ADDRESS cr16_legitimize_address
173 #undef TARGET_LEGITIMATE_CONSTANT_P
174 #define TARGET_LEGITIMATE_CONSTANT_P cr16_legitimate_constant_p
175 #undef TARGET_LEGITIMATE_ADDRESS_P
176 #define TARGET_LEGITIMATE_ADDRESS_P cr16_legitimate_address_p
178 #undef TARGET_LRA_P
179 #define TARGET_LRA_P hook_bool_void_false
181 /* Returning function value. */
182 #undef TARGET_FUNCTION_VALUE
183 #define TARGET_FUNCTION_VALUE cr16_function_value
184 #undef TARGET_LIBCALL_VALUE
185 #define TARGET_LIBCALL_VALUE cr16_libcall_value
186 #undef TARGET_FUNCTION_VALUE_REGNO_P
187 #define TARGET_FUNCTION_VALUE_REGNO_P cr16_function_value_regno_p
189 /* printing the values. */
190 #undef TARGET_PRINT_OPERAND
191 #define TARGET_PRINT_OPERAND cr16_print_operand
192 #undef TARGET_PRINT_OPERAND_ADDRESS
193 #define TARGET_PRINT_OPERAND_ADDRESS cr16_print_operand_address
195 /* Relative costs of operations. */
196 #undef TARGET_ADDRESS_COST
197 #define TARGET_ADDRESS_COST cr16_address_cost
198 #undef TARGET_REGISTER_MOVE_COST
199 #define TARGET_REGISTER_MOVE_COST cr16_register_move_cost
200 #undef TARGET_MEMORY_MOVE_COST
201 #define TARGET_MEMORY_MOVE_COST cr16_memory_move_cost
203 #undef TARGET_CONSTANT_ALIGNMENT
204 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
206 /* Table of machine attributes. */
207 static const struct attribute_spec cr16_attribute_table[] = {
208 /* ISRs have special prologue and epilogue requirements. */
209 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
210 affects_type_identity, exclusions }. */
211 {"interrupt", 0, 0, false, true, true, NULL, false, NULL},
212 {NULL, 0, 0, false, false, false, NULL, false, NULL}
215 /* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive
216 .?byte directive along with @c is not understood by assembler.
217 Therefore, make all TARGET_ASM_UNALIGNED_xx_OP same
218 as TARGET_ASM_ALIGNED_xx_OP. */
219 #undef TARGET_ASM_UNALIGNED_HI_OP
220 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
221 #undef TARGET_ASM_UNALIGNED_SI_OP
222 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
223 #undef TARGET_ASM_UNALIGNED_DI_OP
224 #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
226 #undef TARGET_HARD_REGNO_NREGS
227 #define TARGET_HARD_REGNO_NREGS cr16_hard_regno_nregs
228 #undef TARGET_HARD_REGNO_MODE_OK
229 #define TARGET_HARD_REGNO_MODE_OK cr16_hard_regno_mode_ok
230 #undef TARGET_MODES_TIEABLE_P
231 #define TARGET_MODES_TIEABLE_P cr16_modes_tieable_p
233 /* Target hook implementations. */
235 /* Implements hook TARGET_RETURN_IN_MEMORY. */
236 static bool
237 cr16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
239 const HOST_WIDE_INT size = int_size_in_bytes (type);
240 return ((size == -1) || (size > 8));
243 /* Implement TARGET_CLASS_LIKELY_SPILLED_P. */
244 static bool
245 cr16_class_likely_spilled_p (reg_class_t rclass)
247 if ((rclass) == SHORT_REGS || (rclass) == DOUBLE_BASE_REGS
248 || (rclass) == LONG_REGS || (rclass) == GENERAL_REGS)
249 return true;
251 return false;
254 static int
255 cr16_return_pops_args (tree fundecl ATTRIBUTE_UNUSED,
256 tree funtype ATTRIBUTE_UNUSED,
257 int size ATTRIBUTE_UNUSED)
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 = current_frame_info.var_size
435 + (ACCUMULATE_OUTGOING_ARGS
436 ? crtl->outgoing_args_size : 0);
439 /* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */
441 cr16_initial_elimination_offset (int from, int to)
443 /* Compute this since we need to use current_frame_info.reg_size. */
444 cr16_compute_save_regs ();
446 /* Compute this since we need to use current_frame_info.var_size. */
447 cr16_compute_frame ();
449 if (((from) == FRAME_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
450 return (ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0);
451 else if (((from) == ARG_POINTER_REGNUM) && ((to) == FRAME_POINTER_REGNUM))
452 return (current_frame_info.reg_size + current_frame_info.var_size);
453 else if (((from) == ARG_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
454 return (current_frame_info.reg_size + current_frame_info.var_size
455 + (ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0));
456 else
457 gcc_unreachable ();
460 /* Register Usage. */
462 /* Return the class number of the smallest class containing reg number REGNO.
463 This could be a conditional expression or could index an array. */
464 enum reg_class
465 cr16_regno_reg_class (int regno)
467 if ((regno >= 0) && (regno < CR16_FIRST_DWORD_REGISTER))
468 return SHORT_REGS;
470 if ((regno >= CR16_FIRST_DWORD_REGISTER) && (regno < FIRST_PSEUDO_REGISTER))
471 return LONG_REGS;
473 return NO_REGS;
476 /* Implement TARGET_HARD_REGNO_NREGS. */
478 static unsigned int
479 cr16_hard_regno_nregs (unsigned int regno, machine_mode mode)
481 if (regno >= CR16_FIRST_DWORD_REGISTER)
482 return CEIL (GET_MODE_SIZE (mode), CR16_UNITS_PER_DWORD);
483 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
486 /* Implement TARGET_HARD_REGNO_MODE_OK. On the CR16 architecture, all
487 registers can hold all modes, except that double precision floats
488 (and double ints) must fall on even-register boundaries. */
490 static bool
491 cr16_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
493 if ((GET_MODE_SIZE (mode) >= 4) && (regno == 11))
494 return false;
496 if (mode == DImode || mode == DFmode)
498 if ((regno > 8) || (regno & 1))
499 return false;
500 return true;
503 if ((TARGET_INT32)
504 && ((regno >= 12) && (GET_MODE_SIZE (mode) < 4 )))
505 return false;
507 /* CC can only hold CCmode values. */
508 if (GET_MODE_CLASS (mode) == MODE_CC)
509 return false;
510 return true;
513 /* Implement TARGET_MODES_TIEABLE_P. */
514 static bool
515 cr16_modes_tieable_p (machine_mode mode1, machine_mode mode2)
517 return GET_MODE_CLASS (mode1) == GET_MODE_CLASS (mode2);
520 /* Returns register number for function return value.*/
521 static inline unsigned int
522 cr16_ret_register (void)
524 return 0;
527 /* Implements hook TARGET_STRUCT_VALUE_RTX. */
528 static rtx
529 cr16_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
530 int incoming ATTRIBUTE_UNUSED)
532 return gen_rtx_REG (Pmode, cr16_ret_register ());
535 /* Returning function value. */
537 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P. */
538 static bool
539 cr16_function_value_regno_p (const unsigned int regno)
541 return (regno == cr16_ret_register ());
544 /* Create an RTX representing the place where a
545 library function returns a value of mode MODE. */
546 static rtx
547 cr16_libcall_value (machine_mode mode,
548 const_rtx func ATTRIBUTE_UNUSED)
550 return gen_rtx_REG (mode, cr16_ret_register ());
553 /* Create an RTX representing the place where a
554 function returns a value of data type VALTYPE. */
555 static rtx
556 cr16_function_value (const_tree type,
557 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
558 bool outgoing ATTRIBUTE_UNUSED)
560 return gen_rtx_REG (TYPE_MODE (type), cr16_ret_register ());
563 /* Passing function arguments. */
565 /* If enough param regs are available for passing the param of type TYPE return
566 the number of registers needed else 0. */
567 static int
568 enough_regs_for_param (CUMULATIVE_ARGS * cum, const_tree type,
569 machine_mode mode)
571 int type_size;
572 int remaining_size;
574 if (mode != BLKmode)
575 type_size = GET_MODE_BITSIZE (mode);
576 else
577 type_size = int_size_in_bytes (type) * BITS_PER_UNIT;
579 remaining_size = BITS_PER_WORD * (MAX_REG_FOR_PASSING_ARGS
580 - (MIN_REG_FOR_PASSING_ARGS + cum->ints) +
583 /* Any variable which is too big to pass in two registers, will pass on
584 stack. */
585 if ((remaining_size >= type_size) && (type_size <= 2 * BITS_PER_WORD))
586 return (type_size + BITS_PER_WORD - 1) / BITS_PER_WORD;
588 return 0;
591 /* Implements the macro FUNCTION_ARG defined in cr16.h. */
592 static rtx
593 cr16_function_arg (cumulative_args_t cum_v, machine_mode mode,
594 const_tree type, bool named ATTRIBUTE_UNUSED)
596 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
597 cum->last_parm_in_reg = 0;
599 /* function_arg () is called with this type just after all the args have
600 had their registers assigned. The rtx that function_arg returns from
601 this type is supposed to pass to 'gen_call' but currently it is not
602 implemented. */
603 if (type == void_type_node)
604 return NULL_RTX;
606 if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
607 return NULL_RTX;
609 if (mode == BLKmode)
611 /* Enable structures that need padding bytes at the end to pass to a
612 function in registers. */
613 if (enough_regs_for_param (cum, type, mode) != 0)
615 cum->last_parm_in_reg = 1;
616 return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
620 if ((MIN_REG_FOR_PASSING_ARGS + cum->ints) > MAX_REG_FOR_PASSING_ARGS)
621 return NULL_RTX;
622 else
624 if (enough_regs_for_param (cum, type, mode) != 0)
626 cum->last_parm_in_reg = 1;
627 return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
631 return NULL_RTX;
634 /* Implements the macro INIT_CUMULATIVE_ARGS defined in cr16.h. */
635 void
636 cr16_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype,
637 rtx libfunc ATTRIBUTE_UNUSED)
639 tree param, next_param;
641 cum->ints = 0;
643 /* Determine if this function has variable arguments. This is indicated by
644 the last argument being 'void_type_mode' if there are no variable
645 arguments. Change here for a different vararg. */
646 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
647 param != NULL_TREE; param = next_param)
649 next_param = TREE_CHAIN (param);
650 if ((next_param == NULL_TREE) && (TREE_VALUE (param) != void_type_node))
652 cum->ints = -1;
653 return;
658 /* Implements the macro FUNCTION_ARG_ADVANCE defined in cr16.h. */
659 static void
660 cr16_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
661 const_tree type, bool named ATTRIBUTE_UNUSED)
663 CUMULATIVE_ARGS * cum = get_cumulative_args (cum_v);
665 /* l holds the number of registers required. */
666 int l = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
668 /* If the parameter isn't passed on a register don't advance cum. */
669 if (!cum->last_parm_in_reg)
670 return;
672 if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
673 return;
675 if ((mode == SImode) || (mode == HImode)
676 || (mode == QImode) || (mode == DImode))
678 if (l <= 1)
679 cum->ints += 1;
680 else
681 cum->ints += l;
683 else if ((mode == SFmode) || (mode == DFmode))
684 cum->ints += l;
685 else if ((mode) == BLKmode)
687 if ((l = enough_regs_for_param (cum, type, mode)) != 0)
688 cum->ints += l;
690 return;
693 /* Implements the macro FUNCTION_ARG_REGNO_P defined in cr16.h.
694 Return nonzero if N is a register used for passing parameters. */
696 cr16_function_arg_regno_p (int n)
698 return ((n <= MAX_REG_FOR_PASSING_ARGS) && (n >= MIN_REG_FOR_PASSING_ARGS));
701 /* Addressing modes.
702 Following set of function implement the macro GO_IF_LEGITIMATE_ADDRESS
703 defined in cr16.h. */
705 /* Helper function to check if is a valid base register that can
706 hold address. */
707 static int
708 cr16_addr_reg_p (rtx addr_reg)
710 rtx reg;
712 if (REG_P (addr_reg))
713 reg = addr_reg;
714 else if ((GET_CODE (addr_reg) == SUBREG)
715 && REG_P (SUBREG_REG (addr_reg))
716 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg)))
717 <= UNITS_PER_WORD))
718 reg = SUBREG_REG (addr_reg);
719 else
720 return FALSE;
722 if (GET_MODE (reg) != Pmode)
723 return FALSE;
725 return TRUE;
728 /* Helper functions: Created specifically for decomposing operand of CONST
729 Recursively look into expression x for code or data symbol.
730 The function expects the expression to contain combination of
731 SYMBOL_REF, CONST_INT, (PLUS or MINUS)
732 LABEL_REF, CONST_INT, (PLUS or MINUS)
733 SYMBOL_REF
734 LABEL_REF
735 All other combinations will result in code = -1 and data = ILLEGAL_DM
736 code data
737 -1 ILLEGAL_DM The expression did not contain SYMBOL_REF or LABEL_REF
738 0 DM_FAR SYMBOL_REF was found and it was far data reference.
739 0 DM_DEFAULT SYMBOL_REF was found and it was medium data reference.
740 1 ILLEGAL_DM LABEL_REF was found.
741 2 ILLEGAL_DM SYMBOL_REF was found and it was function reference. */
742 void
743 cr16_decompose_const (rtx x, int *code, enum data_model_type *data,
744 bool treat_as_const)
746 *code = -1;
747 *data = ILLEGAL_DM;
748 switch (GET_CODE (x))
750 case SYMBOL_REF:
751 *code = SYMBOL_REF_FUNCTION_P (x) ? 2 : 0;
752 /* 2 indicates func sym. */
753 if (*code == 0)
755 if (CR16_TARGET_DATA_NEAR)
756 *data = DM_DEFAULT;
757 else if (CR16_TARGET_DATA_MEDIUM)
758 *data = DM_FAR;
759 else if (CR16_TARGET_DATA_FAR)
761 if (treat_as_const)
762 /* This will be used only for printing
763 the qualifier. This call is (may be)
764 made by cr16_print_operand_address. */
765 *data = DM_FAR;
766 else
767 /* This call is (may be) made by
768 cr16_legitimate_address_p. */
769 *data = ILLEGAL_DM;
772 return;
774 case LABEL_REF:
775 /* 1 - indicates non-function symbol. */
776 *code = 1;
777 return;
779 case PLUS:
780 case MINUS:
781 /* Look into the tree nodes. */
782 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
783 cr16_decompose_const (XEXP (x, 1), code, data, treat_as_const);
784 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
785 cr16_decompose_const (XEXP (x, 0), code, data, treat_as_const);
786 return;
787 default:
788 return;
792 /* Decompose Address
793 This function decomposes the address returns the type of address
794 as defined in enum cr16_addrtype. It also fills the parameter *out.
795 The decomposed address can be used for two purposes. One to
796 check if the address is valid and second to print the address
797 operand.
799 Following tables list valid address supported in CR16C/C+ architectures.
800 Legend:
801 aN : Absoulte address N-bit address
802 R : One 16-bit register
803 RP : Consecutive two 16-bit registers or one 32-bit register
804 I : One 32-bit register
805 dispN : Signed displacement of N-bits
807 ----Code addresses----
808 Branch operands:
809 disp9 : CR16_ABSOLUTE (disp)
810 disp17 : CR16_ABSOLUTE (disp)
811 disp25 : CR16_ABSOLUTE (disp)
812 RP + disp25 : CR16_REGP_REL (base, disp)
814 Jump operands:
815 RP : CR16_REGP_REL (base, disp=0)
816 a24 : CR16_ABSOLUTE (disp)
818 ----Data addresses----
819 a20 : CR16_ABSOLUTE (disp) near (1M)
820 a24 : CR16_ABSOLUTE (disp) medium (16M)
821 R + d20 : CR16_REG_REL (base, disp) near (1M+64K)
822 RP + d4 : CR16_REGP_REL (base, disp) far (4G)
823 RP + d16 : CR16_REGP_REL (base, disp) far (4G)
824 RP + d20 : CR16_REGP_REL (base, disp) far (4G)
825 I : *** Valid but port does not support this
826 I + a20 : *** Valid but port does not support this
827 I + RP + d14: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
828 I + RP + d20: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
830 Decomposing Data model in case of absolute address.
832 Target Option Address type Resultant Data ref type
833 ---------------------- ------------ -----------------------
834 CR16_TARGET_MODEL_NEAR ABS20 DM_DEFAULT
835 CR16_TARGET_MODEL_NEAR IMM20 DM_DEFAULT
836 CR16_TARGET_MODEL_NEAR ABS24 Invalid
837 CR16_TARGET_MODEL_NEAR IMM32 Invalid
839 CR16_TARGET_MODEL_MEDIUM ABS20 DM_DEFAULT
840 CR16_TARGET_MODEL_MEDIUM IMM20 DM_DEFAULT
841 CR16_TARGET_MODEL_MEDIUM ABS24 DM_FAR
842 CR16_TARGET_MODEL_MEDIUM IMM32 Invalid
844 CR16_TARGET_MODEL_FAR ABS20 DM_DEFAULT
845 CR16_TARGET_MODEL_FAR IMM20 DM_DEFAULT
846 CR16_TARGET_MODEL_FAR ABS24 DM_FAR
847 CR16_TARGET_MODEL_FAR IMM32 DM_FAR. */
848 enum cr16_addrtype
849 cr16_decompose_address (rtx addr, struct cr16_address *out,
850 bool debug_print, bool treat_as_const)
852 rtx base = NULL_RTX, disp = NULL_RTX, index = NULL_RTX;
853 enum data_model_type data = ILLEGAL_DM;
854 int code = -1;
855 enum cr16_addrtype retval = CR16_INVALID;
857 switch (GET_CODE (addr))
859 case CONST_INT:
860 /* Absolute address (known at compile time). */
861 code = 0;
862 if (debug_print)
863 fprintf (stderr, "\ncode:%d", code);
864 disp = addr;
866 if (debug_print)
868 fprintf (stderr, "\ndisp:");
869 debug_rtx (disp);
872 if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
874 data = DM_DEFAULT;
875 if (debug_print)
876 fprintf (stderr, "\ndata:%d", data);
877 retval = CR16_ABSOLUTE;
879 else if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 24))
881 if (!CR16_TARGET_DATA_NEAR)
883 data = DM_FAR;
884 if (debug_print)
885 fprintf (stderr, "\ndata:%d", data);
886 retval = CR16_ABSOLUTE;
888 else
889 return CR16_INVALID; /* ABS24 is not support in NEAR model. */
891 else
892 return CR16_INVALID;
893 break;
895 case CONST:
896 /* A CONST is an expression of PLUS or MINUS with
897 CONST_INT, SYMBOL_REF or LABEL_REF. This is the
898 result of assembly-time arithmetic computation. */
899 retval = CR16_ABSOLUTE;
900 disp = addr;
901 /* Call the helper function to check the validity. */
902 cr16_decompose_const (XEXP (addr, 0), &code, &data, treat_as_const);
903 if ((code == 0) && (data == ILLEGAL_DM))
904 /* CONST is not valid code or data address. */
905 return CR16_INVALID;
906 if (debug_print)
908 fprintf (stderr, "\ndisp:");
909 debug_rtx (disp);
910 fprintf (stderr, "\ncode:%d", code);
911 fprintf (stderr, "\ndata:%d", data);
913 break;
915 case LABEL_REF:
916 retval = CR16_ABSOLUTE;
917 disp = addr;
918 /* 1 - indicates non-function symbol. */
919 code = 1;
920 if (debug_print)
922 fprintf (stderr, "\ndisp:");
923 debug_rtx (disp);
924 fprintf (stderr, "\ncode:%d", code);
926 break;
928 case SYMBOL_REF:
929 /* Absolute address (known at link time). */
930 retval = CR16_ABSOLUTE;
931 disp = addr;
932 /* This is a code address if symbol_ref is a function. */
933 /* 2 indicates func sym. */
934 code = SYMBOL_REF_FUNCTION_P (addr) ? 2 : 0;
935 if (debug_print)
937 fprintf (stderr, "\ndisp:");
938 debug_rtx (disp);
939 fprintf (stderr, "\ncode:%d", code);
941 /* If not function ref then check if valid data ref. */
942 if (code == 0)
944 if (CR16_TARGET_DATA_NEAR)
945 data = DM_DEFAULT;
946 else if (CR16_TARGET_DATA_MEDIUM)
947 data = DM_FAR;
948 else if (CR16_TARGET_DATA_FAR)
950 if (treat_as_const)
951 /* This will be used only for printing the
952 qualifier. This call is (may be) made
953 by cr16_print_operand_address. */
954 data = DM_FAR;
955 else
956 /* This call is (may be) made by
957 cr16_legitimate_address_p. */
958 return CR16_INVALID;
960 else
961 data = DM_DEFAULT;
963 if (debug_print)
964 fprintf (stderr, "\ndata:%d", data);
965 break;
967 case REG:
968 case SUBREG:
969 /* Register relative address. */
970 /* Assume REG fits in a single register. */
971 retval = CR16_REG_REL;
972 if (GET_MODE_BITSIZE (GET_MODE (addr)) > BITS_PER_WORD)
973 if (!LONG_REG_P (REGNO (addr)))
974 /* REG will result in reg pair. */
975 retval = CR16_REGP_REL;
976 base = addr;
977 if (debug_print)
979 fprintf (stderr, "\nbase:");
980 debug_rtx (base);
982 break;
984 case PLUS:
985 switch (GET_CODE (XEXP (addr, 0)))
987 case REG:
988 case SUBREG:
989 /* REG + DISP20. */
990 /* All Reg relative addresses having a displacement needs
991 to fit in 20-bits. */
992 disp = XEXP (addr, 1);
993 if (debug_print)
995 fprintf (stderr, "\ndisp:");
996 debug_rtx (disp);
998 switch (GET_CODE (XEXP (addr, 1)))
1000 case CONST_INT:
1001 /* Shall fit in 20-bits. */
1002 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
1003 return CR16_INVALID;
1004 code = 0;
1005 if (debug_print)
1006 fprintf (stderr, "\ncode:%d", code);
1007 break;
1009 case UNSPEC:
1010 switch (XINT (XEXP (addr, 1), 1))
1012 case UNSPEC_LIBRARY_OFFSET:
1013 default:
1014 gcc_unreachable ();
1016 break;
1018 case LABEL_REF:
1019 case SYMBOL_REF:
1020 case CONST:
1021 /* This is also a valid expression for address.
1022 However, we cannot ascertain if the resultant
1023 displacement will be valid 20-bit value. Therefore,
1024 lets not allow such an expression for now. This will
1025 be updated when we find a way to validate this
1026 expression as legitimate address.
1027 Till then fall through CR16_INVALID. */
1028 default:
1029 return CR16_INVALID;
1032 /* Now check if REG can fit into single or pair regs. */
1033 retval = CR16_REG_REL;
1034 base = XEXP (addr, 0);
1035 if (debug_print)
1037 fprintf (stderr, "\nbase:");
1038 debug_rtx (base);
1040 if (GET_MODE_BITSIZE (GET_MODE ((XEXP (addr, 0)))) > BITS_PER_WORD)
1042 if (!LONG_REG_P (REGNO ((XEXP (addr, 0)))))
1043 /* REG will result in reg pair. */
1044 retval = CR16_REGP_REL;
1046 break;
1048 case PLUS:
1049 /* Valid expr:
1050 plus
1053 plus idx
1056 reg const_int
1058 Check if the operand 1 is valid index register. */
1059 data = ILLEGAL_DM;
1060 if (debug_print)
1061 fprintf (stderr, "\ndata:%d", data);
1062 switch (GET_CODE (XEXP (addr, 1)))
1064 case REG:
1065 case SUBREG:
1066 if (!REG_OK_FOR_INDEX_P (XEXP (addr, 1)))
1067 return CR16_INVALID;
1068 /* OK. REG is a valid index register. */
1069 index = XEXP (addr, 1);
1070 if (debug_print)
1072 fprintf (stderr, "\nindex:");
1073 debug_rtx (index);
1075 break;
1076 default:
1077 return CR16_INVALID;
1079 /* Check if operand 0 of operand 0 is REGP. */
1080 switch (GET_CODE (XEXP (XEXP (addr, 0), 0)))
1082 case REG:
1083 case SUBREG:
1084 /* Now check if REG is a REGP and not in LONG regs. */
1085 if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (addr, 0), 0)))
1086 > BITS_PER_WORD)
1088 if (REGNO (XEXP (XEXP (addr, 0), 0))
1089 >= CR16_FIRST_DWORD_REGISTER)
1090 return CR16_INVALID;
1091 base = XEXP (XEXP (addr, 0), 0);
1092 if (debug_print)
1094 fprintf (stderr, "\nbase:");
1095 debug_rtx (base);
1098 else
1099 return CR16_INVALID;
1100 break;
1101 default:
1102 return CR16_INVALID;
1104 /* Now check if the operand 1 of operand 0 is const_int. */
1105 if (GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
1107 disp = XEXP (XEXP (addr, 0), 1);
1108 if (debug_print)
1110 fprintf (stderr, "\ndisp:");
1111 debug_rtx (disp);
1113 if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
1114 return CR16_INVALID;
1116 else
1117 return CR16_INVALID;
1118 retval = CR16_INDEX_REGP_REL;
1119 break;
1120 default:
1121 return CR16_INVALID;
1123 break;
1125 default:
1126 return CR16_INVALID;
1129 /* Check if the base and index registers are valid. */
1130 if (base && !(cr16_addr_reg_p (base)))
1131 return CR16_INVALID;
1132 if (base && !(CR16_REG_OK_FOR_BASE_P (base)))
1133 return CR16_INVALID;
1134 if (index && !(REG_OK_FOR_INDEX_P (index)))
1135 return CR16_INVALID;
1137 /* Write the decomposition to out parameter. */
1138 out->base = base;
1139 out->disp = disp;
1140 out->index = index;
1141 out->data = data;
1142 out->code = code;
1144 return retval;
1147 /* Return non-zero value if 'x' is legitimate PIC operand
1148 when generating PIC code. */
1150 legitimate_pic_operand_p (rtx x)
1152 switch (GET_CODE (x))
1154 case SYMBOL_REF:
1155 return 0;
1156 case LABEL_REF:
1157 return 0;
1158 case CONST:
1159 /* REVISIT: Use something like symbol_referenced_p. */
1160 if (GET_CODE (XEXP (x, 0)) == PLUS
1161 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
1162 || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
1163 && (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
1164 return 0;
1165 break;
1166 case MEM:
1167 return legitimate_pic_operand_p (XEXP (x, 0));
1168 default:
1169 break;
1171 return 1;
1174 /* Convert a non-PIC address in `orig' to a PIC address in `reg'.
1176 Input Output (-f pic) Output (-f PIC)
1177 orig reg
1179 C1 symbol symbol@BRO (r12) symbol@GOT (r12)
1181 C2 symbol + offset symbol+offset@BRO (r12) symbol+offset@GOT (r12)
1183 NOTE: @BRO is added using unspec:BRO
1184 NOTE: @GOT is added using unspec:GOT. */
1186 legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
1187 rtx reg)
1189 /* First handle a simple SYMBOL_REF or LABEL_REF. */
1190 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
1192 if (reg == 0)
1193 reg = gen_reg_rtx (Pmode);
1195 if (flag_pic == NEAR_PIC)
1197 /* Unspec to handle -fpic option. */
1198 emit_insn (gen_unspec_bro_addr (reg, orig));
1199 emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx));
1201 else if (flag_pic == FAR_PIC)
1203 /* Unspec to handle -fPIC option. */
1204 emit_insn (gen_unspec_got_addr (reg, orig));
1206 return reg;
1208 else if (GET_CODE (orig) == CONST)
1210 /* To handle (symbol + offset). */
1211 rtx base, offset;
1213 if (GET_CODE (XEXP (orig, 0)) == PLUS
1214 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1215 return orig;
1217 if (reg == 0)
1219 gcc_assert (can_create_pseudo_p ());
1220 reg = gen_reg_rtx (Pmode);
1223 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
1225 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
1226 offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1227 base == reg ? 0 : reg);
1229 /* REVISIT: Optimize for const-offsets. */
1230 emit_insn (gen_addsi3 (reg, base, offset));
1232 return reg;
1234 return orig;
1237 /* Implementation of TARGET_LEGITIMATE_ADDRESS_P. */
1238 static bool
1239 cr16_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
1240 rtx addr, bool strict)
1242 enum cr16_addrtype addrtype;
1243 struct cr16_address address;
1245 if (TARGET_DEBUG_ADDR)
1247 fprintf (stderr,
1248 "\n======\nTARGET_LEGITIMATE_ADDRESS_P, mode = %s, strict = %d",
1249 GET_MODE_NAME (mode), strict);
1250 debug_rtx (addr);
1252 addrtype = cr16_decompose_address (addr, &address,
1253 (TARGET_DEBUG_ADDR ? 1 : 0), FALSE);
1255 if (TARGET_DEBUG_ADDR)
1257 const char *typestr;
1259 switch (addrtype)
1261 case CR16_INVALID:
1262 typestr = "invalid";
1263 break;
1264 case CR16_ABSOLUTE:
1265 typestr = "absolute";
1266 break;
1267 case CR16_REG_REL:
1268 typestr = "register relative";
1269 break;
1270 case CR16_REGP_REL:
1271 typestr = "register pair relative";
1272 break;
1273 case CR16_INDEX_REGP_REL:
1274 typestr = "index + register pair relative";
1275 break;
1276 default:
1277 gcc_unreachable ();
1279 fprintf (stderr, "\ncr16 address type: %s\n", typestr);
1282 if (addrtype == CR16_INVALID)
1283 return FALSE;
1285 if (strict)
1287 if (address.base
1288 && !REGNO_MODE_OK_FOR_BASE_P (REGNO (address.base), mode))
1290 if (TARGET_DEBUG_ADDR)
1291 fprintf (stderr, "base register not strict\n");
1292 return FALSE;
1294 if (address.index && !REGNO_OK_FOR_INDEX_P (REGNO (address.index)))
1296 if (TARGET_DEBUG_ADDR)
1297 fprintf (stderr, "index register not strict\n");
1298 return FALSE;
1302 /* Return true if addressing mode is register relative. */
1303 if (flag_pic)
1305 if (addrtype == CR16_REG_REL || addrtype == CR16_REGP_REL)
1306 return TRUE;
1307 else
1308 return FALSE;
1311 return TRUE;
1314 /* Routines to compute costs. */
1316 /* Return cost of the memory address x. */
1317 static int
1318 cr16_address_cost (rtx addr, machine_mode mode ATTRIBUTE_UNUSED,
1319 addr_space_t as ATTRIBUTE_UNUSED,
1320 bool speed ATTRIBUTE_UNUSED)
1322 enum cr16_addrtype addrtype;
1323 struct cr16_address address;
1324 int cost = 2;
1326 addrtype = cr16_decompose_address (addr, &address, 0, FALSE);
1328 gcc_assert (addrtype != CR16_INVALID);
1330 /* CR16_ABSOLUTE : 3
1331 CR16_REG_REL (disp !=0) : 4
1332 CR16_REG_REL (disp ==0) : 5
1333 CR16_REGP_REL (disp !=0) : 6
1334 CR16_REGP_REL (disp ==0) : 7
1335 CR16_INDEX_REGP_REL (disp !=0) : 8
1336 CR16_INDEX_REGP_REL (disp ==0) : 9. */
1337 switch (addrtype)
1339 case CR16_ABSOLUTE:
1340 cost += 1;
1341 break;
1342 case CR16_REGP_REL:
1343 cost += 2;
1344 /* Fall through. */
1345 case CR16_REG_REL:
1346 cost += 3;
1347 if (address.disp)
1348 cost -= 1;
1349 break;
1350 case CR16_INDEX_REGP_REL:
1351 cost += 7;
1352 if (address.disp)
1353 cost -= 1;
1354 default:
1355 break;
1358 if (TARGET_DEBUG_ADDR)
1360 fprintf (stderr, "\n======\nmacro TARGET_ADDRESS_COST = %d\n", cost);
1361 debug_rtx (addr);
1364 return cost;
1368 /* Implement `TARGET_REGISTER_MOVE_COST'. */
1369 static int
1370 cr16_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
1371 reg_class_t from ATTRIBUTE_UNUSED, reg_class_t to)
1373 return (to != GENERAL_REGS ? 8 : 2);
1376 /* Implement `TARGET_MEMORY_MOVE_COST'. */
1378 /* Return the cost of moving data of mode MODE between a register of class
1379 CLASS and memory; IN is zero if the value is to be written to memory,
1380 nonzero if it is to be read in. This cost is relative to those in
1381 REGISTER_MOVE_COST. */
1382 static int
1383 cr16_memory_move_cost (machine_mode mode,
1384 reg_class_t rclass ATTRIBUTE_UNUSED,
1385 bool in ATTRIBUTE_UNUSED)
1387 /* One LD or ST takes twice the time of a simple reg-reg move. */
1388 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
1389 return (4 * cr16_hard_regno_nregs (0, mode));
1390 else
1391 return (100);
1394 /* Instruction output. */
1396 /* Check if a const_double is ok for cr16 store-immediate instructions. */
1398 cr16_const_double_ok (rtx op)
1400 if (GET_MODE (op) == SFmode)
1402 long l;
1403 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op), l);
1404 return UNSIGNED_INT_FITS_N_BITS (l, 4) ? 1 : 0;
1407 return ((UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op), 4)) &&
1408 (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op), 4))) ? 1 : 0;
1411 /* Returns bit position of first 0 or 1 bit.
1412 It is safe to assume val as 16-bit wide. */
1414 cr16_operand_bit_pos (int val, int bitval)
1416 int i;
1417 if (bitval == 0)
1418 val = ~val;
1420 for (i = 0; i < 16; i++)
1421 if (val & (1 << i))
1422 break;
1423 return i;
1426 /* Implements the macro PRINT_OPERAND defined in cr16.h. */
1427 static void
1428 cr16_print_operand (FILE * file, rtx x, int code)
1430 int ptr_dereference = 0;
1432 switch (code)
1434 case 'd':
1436 const char *cr16_cmp_str;
1437 switch (GET_CODE (x))
1439 /* MD: compare (reg, reg or imm) but CR16: cmp (reg or imm, reg)
1440 -> swap all non symmetric ops. */
1441 case EQ:
1442 cr16_cmp_str = "eq";
1443 break;
1444 case NE:
1445 cr16_cmp_str = "ne";
1446 break;
1447 case GT:
1448 cr16_cmp_str = "lt";
1449 break;
1450 case GTU:
1451 cr16_cmp_str = "lo";
1452 break;
1453 case LT:
1454 cr16_cmp_str = "gt";
1455 break;
1456 case LTU:
1457 cr16_cmp_str = "hi";
1458 break;
1459 case GE:
1460 cr16_cmp_str = "le";
1461 break;
1462 case GEU:
1463 cr16_cmp_str = "ls";
1464 break;
1465 case LE:
1466 cr16_cmp_str = "ge";
1467 break;
1468 case LEU:
1469 cr16_cmp_str = "hs";
1470 break;
1471 default:
1472 gcc_unreachable ();
1474 fprintf (file, "%s", cr16_cmp_str);
1475 return;
1477 case '$':
1478 putc ('$', file);
1479 return;
1481 case 'p':
1482 if (GET_CODE (x) == REG)
1484 /* For Push instructions, we should not print register pairs. */
1485 fprintf (file, "%s", reg_names[REGNO (x)]);
1486 return;
1488 break;
1490 case 'b':
1491 /* Print the immediate address for bal
1492 'b' is used instead of 'a' to avoid compiler calling
1493 the GO_IF_LEGITIMATE_ADDRESS which cannot
1494 perform checks on const_int code addresses as it
1495 assumes all const_int are data addresses. */
1496 fprintf (file, "0x%lx", INTVAL (x));
1497 return;
1499 case 'r':
1500 /* Print bit position of first 0. */
1501 fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 0));
1502 return;
1504 case 's':
1505 /* Print bit position of first 1. */
1506 fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 1));
1507 return;
1508 case 'g':
1509 /* 'g' is used for implicit mem: dereference. */
1510 ptr_dereference = 1;
1511 /* FALLTHRU */
1512 case 'f':
1513 case 0:
1514 /* default. */
1515 switch (GET_CODE (x))
1517 case REG:
1518 if (GET_MODE_BITSIZE (GET_MODE (x)) > BITS_PER_WORD)
1520 if (LONG_REG_P (REGNO (x)))
1521 fprintf (file, "(%s)", reg_names[REGNO (x)]);
1522 else
1523 fprintf (file, "(%s,%s)", reg_names[REGNO (x) + 1],
1524 reg_names[REGNO (x)]);
1526 else
1527 fprintf (file, "%s", reg_names[REGNO (x)]);
1528 return;
1530 case MEM:
1531 output_address (GET_MODE (x), XEXP (x, 0));
1532 return;
1534 case CONST_DOUBLE:
1536 long l;
1538 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
1540 fprintf (file, "$0x%lx", l);
1541 return;
1543 case CONST_INT:
1545 fprintf (file, "$%ld", INTVAL (x));
1546 return;
1548 case UNSPEC:
1549 switch (XINT (x, 1))
1551 default:
1552 gcc_unreachable ();
1554 break;
1556 default:
1557 if (!ptr_dereference)
1559 putc ('$', file);
1561 cr16_print_operand_address (file, VOIDmode, x);
1562 return;
1564 gcc_unreachable ();
1565 default:
1566 output_operand_lossage ("invalid %%xn code");
1569 gcc_unreachable ();
1572 /* Implements the macro PRINT_OPERAND_ADDRESS defined in cr16.h. */
1574 static void
1575 cr16_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr)
1577 enum cr16_addrtype addrtype;
1578 struct cr16_address address;
1580 /* Decompose the address. Also ask it to treat address as constant. */
1581 addrtype = cr16_decompose_address (addr, &address, 0, TRUE);
1583 if (address.disp && GET_CODE (address.disp) == UNSPEC)
1585 debug_rtx (addr);
1588 switch (addrtype)
1590 case CR16_REG_REL:
1591 if (address.disp)
1593 if (GET_CODE (address.disp) == UNSPEC)
1594 cr16_print_operand (file, address.disp, 0);
1595 else
1596 output_addr_const (file, address.disp);
1598 else
1599 fprintf (file, "0");
1600 fprintf (file, "(%s)", reg_names[REGNO (address.base)]);
1601 break;
1603 case CR16_ABSOLUTE:
1604 if (address.disp)
1605 output_addr_const (file, address.disp);
1606 else
1607 fprintf (file, "0");
1608 break;
1610 case CR16_INDEX_REGP_REL:
1611 fprintf (file, "[%s]", reg_names[REGNO (address.index)]);
1612 /* Fall through. */
1613 case CR16_REGP_REL:
1614 if (address.disp)
1616 if (GET_CODE (address.disp) == UNSPEC)
1617 cr16_print_operand (file, address.disp, 0);
1618 else
1619 output_addr_const (file, address.disp);
1621 else
1622 fprintf (file, "0");
1623 fprintf (file, "(%s,%s)", reg_names[REGNO (address.base) + 1],
1624 reg_names[REGNO (address.base)]);
1625 break;
1626 default:
1627 debug_rtx (addr);
1628 gcc_unreachable ();
1630 /* Add qualifiers to the address expression that was just printed. */
1631 if (flag_pic < NEAR_PIC && address.code == 0)
1633 if (address.data == DM_FAR)
1634 /* Addr contains SYMBOL_REF & far data ptr. */
1635 fprintf (file, "@l");
1636 else if (address.data == DM_DEFAULT)
1637 /* Addr contains SYMBOL_REF & medium data ptr. */
1638 fprintf (file, "@m");
1639 /* Addr contains SYMBOL_REF & medium data ptr. */
1640 else if (address.data == DM_NEAR)
1641 /* Addr contains SYMBOL_REF & near data ptr. */
1642 fprintf (file, "@s");
1644 else if (flag_pic == NEAR_PIC
1645 && (address.code == 0) && (address.data == DM_FAR
1646 || address.data == DM_DEFAULT
1647 || address.data == DM_NEAR))
1649 fprintf (file, "@l");
1651 else if (flag_pic == NEAR_PIC && address.code == 2)
1653 fprintf (file, "pic");
1655 else if (flag_pic == NEAR_PIC && address.code == 1)
1657 fprintf (file, "@cpic");
1660 else if (flag_pic == FAR_PIC && address.code == 2)
1662 /* REVISIT: cr16 register indirect jump expects a 1-bit right shifted
1663 address ! GOTc tells assembler this symbol is a text-address
1664 This needs to be fixed in such a way that this offset is done
1665 only in the case where an address is being used for indirect jump
1666 or call. Determining the potential usage of loadd is of course not
1667 possible always. Eventually, this has to be fixed in the
1668 processor. */
1669 fprintf (file, "GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1671 else if (flag_pic == FAR_PIC && address.code == 1)
1673 fprintf (file, "@cGOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1676 else if (flag_pic == FAR_PIC &&
1677 (address.data == DM_FAR || address.data == DM_DEFAULT
1678 || address.data == DM_NEAR))
1680 fprintf (file, "@GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1684 /* Machine description helper functions. */
1686 /* Called from cr16.md. The return value depends on the parameter push_or_pop:
1687 When push_or_pop is zero -> string for push instructions of prologue.
1688 When push_or_pop is nonzero -> string for pop/popret/retx in epilogue.
1689 Relies on the assumptions:
1690 1. RA is the last register to be saved.
1691 2. The maximal value of the counter is MAX_COUNT. */
1692 char *
1693 cr16_prepare_push_pop_string (int push_or_pop)
1695 /* j is the number of registers being saved, takes care that there won't be
1696 more than 8 in one push/pop instruction. */
1698 /* For the register mask string. */
1699 static char one_inst_str[50];
1701 /* i is the index of current_frame_info.save_regs[], going from 0 until
1702 current_frame_info.last_reg_to_save. */
1703 int i, start_reg;
1704 int word_cnt;
1705 int print_ra;
1706 char *return_str;
1708 /* For reversing on the push instructions if there are more than one. */
1709 char *temp_str;
1711 return_str = (char *) xmalloc (160);
1712 temp_str = (char *) xmalloc (160);
1714 /* Initialize. */
1715 memset (return_str, 0, 3);
1717 i = 0;
1718 while (i <= current_frame_info.last_reg_to_save)
1720 /* Prepare mask for one instruction. */
1721 one_inst_str[0] = 0;
1723 /* To count number of words in one instruction. */
1724 word_cnt = 0;
1725 start_reg = i;
1726 print_ra = 0;
1727 while ((word_cnt < MAX_COUNT)
1728 && (i <= current_frame_info.last_reg_to_save))
1730 /* For each non consecutive save register,
1731 a new instruction shall be generated. */
1732 if (!current_frame_info.save_regs[i])
1734 /* Move to next reg and break. */
1735 ++i;
1736 break;
1739 if (i == RETURN_ADDRESS_REGNUM)
1740 print_ra = 1;
1741 else
1743 /* Check especially if adding 2 does not cross the MAX_COUNT. */
1744 if ((word_cnt + ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2))
1745 >= MAX_COUNT)
1746 break;
1747 /* Increase word count by 2 for long registers except RA. */
1748 word_cnt += ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2);
1750 ++i;
1753 /* No need to generate any instruction as
1754 no register or RA needs to be saved. */
1755 if ((word_cnt == 0) && (print_ra == 0))
1756 continue;
1758 /* Now prepare the instruction operands. */
1759 if (word_cnt > 0)
1761 sprintf (one_inst_str, "$%d, %s", word_cnt, reg_names[start_reg]);
1762 if (print_ra)
1763 strcat (one_inst_str, ", ra");
1765 else
1766 strcat (one_inst_str, "ra");
1768 if (push_or_pop == 1)
1770 /* Pop instruction. */
1771 if (print_ra && !cr16_interrupt_function_p ()
1772 && !crtl->calls_eh_return)
1773 /* Print popret if RA is saved and its not a interrupt
1774 function. */
1775 strcpy (temp_str, "\n\tpopret\t");
1776 else
1777 strcpy (temp_str, "\n\tpop\t");
1779 strcat (temp_str, one_inst_str);
1781 /* Add the pop instruction list. */
1782 strcat (return_str, temp_str);
1784 else
1786 /* Push instruction. */
1787 strcpy (temp_str, "\n\tpush\t");
1788 strcat (temp_str, one_inst_str);
1790 /* We need to reverse the order of the instructions if there
1791 are more than one. (since the pop will not be reversed in
1792 the epilogue. */
1793 strcat (temp_str, return_str);
1794 strcpy (return_str, temp_str);
1798 if (push_or_pop == 1)
1800 /* POP. */
1801 if (cr16_interrupt_function_p ())
1802 strcat (return_str, "\n\tretx\n");
1803 else if (crtl->calls_eh_return)
1805 /* Add stack adjustment before returning to exception handler
1806 NOTE: EH_RETURN_STACKADJ_RTX must refer to (r5, r4). */
1807 strcat (return_str, "\n\taddd\t (r5, r4), (sp)\t\n");
1808 strcat (return_str, "\n\tjump\t (ra)\n");
1810 /* But before anything else, undo the adjustment addition done in
1811 cr16_expand_epilogue (). */
1812 strcpy (temp_str, "\n\tsubd\t (r5, r4), (sp)\t\n");
1813 strcat (temp_str, return_str);
1814 strcpy (return_str, temp_str);
1816 else if (!FUNC_IS_NORETURN_P (current_function_decl)
1817 && !(current_frame_info.save_regs[RETURN_ADDRESS_REGNUM]))
1818 strcat (return_str, "\n\tjump\t (ra)\n");
1821 /* Skip the newline and the tab in the start of return_str. */
1822 return_str += 2;
1823 return return_str;
1827 /* Generate DWARF2 annotation for multi-push instruction. */
1828 static void
1829 cr16_create_dwarf_for_multi_push (rtx insn)
1831 rtx dwarf, reg, tmp;
1832 int i, j, from, to, word_cnt, dwarf_par_index, inc;
1833 machine_mode mode;
1834 int num_regs = 0, offset = 0, split_here = 0, total_push_bytes = 0;
1836 for (i = 0; i <= current_frame_info.last_reg_to_save; ++i)
1838 if (current_frame_info.save_regs[i])
1840 ++num_regs;
1841 if (i < CR16_FIRST_DWORD_REGISTER)
1842 total_push_bytes += 2;
1843 else
1844 total_push_bytes += 4;
1848 if (!num_regs)
1849 return;
1851 dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1));
1852 dwarf_par_index = num_regs;
1854 from = current_frame_info.last_reg_to_save + 1;
1855 to = current_frame_info.last_reg_to_save;
1856 word_cnt = 0;
1858 for (i = current_frame_info.last_reg_to_save; i >= 0;)
1860 if (!current_frame_info.save_regs[i] || 0 == i || split_here)
1862 /* This block of regs is pushed in one instruction. */
1863 if (0 == i && current_frame_info.save_regs[i])
1864 from = 0;
1866 for (j = to; j >= from; --j)
1868 if (j < CR16_FIRST_DWORD_REGISTER)
1870 mode = HImode;
1871 inc = 1;
1873 else
1875 mode = SImode;
1876 inc = 2;
1878 reg = gen_rtx_REG (mode, j);
1879 offset += 2 * inc;
1880 tmp = gen_rtx_SET (gen_frame_mem (mode,
1881 plus_constant
1882 (Pmode, stack_pointer_rtx,
1883 total_push_bytes - offset)),
1884 reg);
1885 RTX_FRAME_RELATED_P (tmp) = 1;
1886 XVECEXP (dwarf, 0, dwarf_par_index--) = tmp;
1888 from = i;
1889 to = --i;
1890 split_here = 0;
1891 word_cnt = 0;
1892 continue;
1895 if (i != RETURN_ADDRESS_REGNUM)
1897 inc = (i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2;
1898 if (word_cnt + inc >= MAX_COUNT || FRAME_POINTER_REGNUM == i)
1900 split_here = 1;
1901 from = i;
1902 continue;
1904 word_cnt += inc;
1907 from = i--;
1910 tmp = gen_rtx_SET (stack_pointer_rtx,
1911 gen_rtx_PLUS (SImode, stack_pointer_rtx,
1912 GEN_INT (-offset)));
1913 RTX_FRAME_RELATED_P (tmp) = 1;
1914 XVECEXP (dwarf, 0, 0) = tmp;
1916 add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
1920 CompactRISC CR16 Architecture stack layout:
1922 0 +---------------------
1927 +==================== Sp (x) = Ap (x+1)
1928 A | Args for functions
1929 | | called by X and Dynamically
1930 | | Dynamic allocations allocated and
1931 | | (alloca, variable deallocated
1932 Stack | length arrays).
1933 grows +-------------------- Fp (x)
1934 down| | Local variables of X
1935 ward| +--------------------
1936 | | Regs saved for X-1
1937 | +==================== Sp (x-1) = Ap (x)
1938 | Args for func X
1939 | pushed by X-1
1940 +-------------------- Fp (x-1)
1945 void
1946 cr16_expand_prologue (void)
1948 rtx insn;
1950 cr16_compute_frame ();
1951 cr16_compute_save_regs ();
1953 /* If there is no need in push and adjustment to sp, return. */
1954 if ((current_frame_info.total_size + current_frame_info.reg_size) == 0)
1955 return;
1957 if (current_frame_info.last_reg_to_save != -1)
1959 /* If there are registers to push. */
1960 insn = emit_insn (gen_push_for_prologue
1961 (GEN_INT (current_frame_info.reg_size)));
1962 cr16_create_dwarf_for_multi_push (insn);
1963 RTX_FRAME_RELATED_P (insn) = 1;
1967 if (current_frame_info.total_size > 0)
1969 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1970 GEN_INT (-current_frame_info.total_size)));
1971 RTX_FRAME_RELATED_P (insn) = 1;
1974 if (frame_pointer_needed)
1976 /* Initialize the frame pointer with the value of the stack pointer
1977 pointing now to the locals. */
1978 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1982 /* Generate insn that updates the stack for local variables and padding
1983 for registers we save. - Generate the appropriate return insn. */
1984 void
1985 cr16_expand_epilogue (void)
1987 rtx insn;
1989 /* Nonzero if we need to return and pop only RA. This will generate a
1990 different insn. This differentiate is for the peepholes for call as
1991 last statement in function. */
1992 int only_popret_RA = (current_frame_info.save_regs[RETURN_ADDRESS_REGNUM]
1993 && (current_frame_info.reg_size
1994 == CR16_UNITS_PER_DWORD));
1996 if (frame_pointer_needed)
1998 /* Restore the stack pointer with the frame pointers value. */
1999 insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
2002 if (current_frame_info.total_size > 0)
2004 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2005 GEN_INT (current_frame_info.total_size)));
2006 RTX_FRAME_RELATED_P (insn) = 1;
2009 if (crtl->calls_eh_return)
2011 /* Add this here so that (r5, r4) is actually loaded with the adjustment
2012 value; otherwise, the load might be optimized away...
2013 NOTE: remember to subtract the adjustment before popping the regs
2014 and add it back before returning. */
2015 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2016 EH_RETURN_STACKADJ_RTX));
2019 if (cr16_interrupt_function_p ())
2021 insn = emit_jump_insn (gen_interrupt_return ());
2022 RTX_FRAME_RELATED_P (insn) = 1;
2024 else if (crtl->calls_eh_return)
2026 /* Special case, pop what's necessary, adjust SP and jump to (RA). */
2027 insn = emit_jump_insn (gen_pop_and_popret_return
2028 (GEN_INT (current_frame_info.reg_size)));
2029 RTX_FRAME_RELATED_P (insn) = 1;
2031 else if (current_frame_info.last_reg_to_save == -1)
2032 /* Nothing to pop. */
2033 /* Don't output jump for interrupt routine, only retx. */
2034 emit_jump_insn (gen_jump_return ());
2035 else if (only_popret_RA)
2037 insn = emit_jump_insn (gen_popret_RA_return ());
2038 RTX_FRAME_RELATED_P (insn) = 1;
2040 else
2042 insn = emit_jump_insn (gen_pop_and_popret_return
2043 (GEN_INT (current_frame_info.reg_size)));
2044 RTX_FRAME_RELATED_P (insn) = 1;
2048 /* Implements FRAME_POINTER_REQUIRED. */
2049 static bool
2050 cr16_frame_pointer_required (void)
2052 return (cfun->calls_alloca || crtl->calls_eh_return
2053 || cfun->has_nonlocal_label || crtl->calls_eh_return);
2056 static bool
2057 cr16_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
2059 return (to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true);
2063 /* A C compound statement that attempts to replace X with
2064 a valid memory address for an operand of mode MODE. WIN
2065 will be a C statement label elsewhere in the code.
2066 X will always be the result of a call to break_out_memory_refs (),
2067 and OLDX will be the operand that was given to that function to
2068 produce X.
2069 The code generated by this macro should not alter the
2070 substructure of X. If it transforms X into a more legitimate form,
2071 it should assign X (which will always be a C variable) a new value. */
2072 static rtx
2073 cr16_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED,
2074 machine_mode mode ATTRIBUTE_UNUSED)
2076 if (flag_pic)
2077 return legitimize_pic_address (orig_x, mode, NULL_RTX);
2078 else
2079 return x;
2082 /* Implement TARGET_LEGITIMATE_CONSTANT_P
2083 Nonzero if X is a legitimate constant for an immediate
2084 operand on the target machine. You can assume that X
2085 satisfies CONSTANT_P. In cr16c treat legitimize float
2086 constant as an immediate operand. */
2087 static bool
2088 cr16_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED,
2089 rtx x ATTRIBUTE_UNUSED)
2091 return 1;
2094 void
2095 notice_update_cc (rtx exp)
2097 if (GET_CODE (exp) == SET)
2099 /* Jumps do not alter the cc's. */
2100 if (SET_DEST (exp) == pc_rtx)
2101 return;
2103 /* Moving register or memory into a register:
2104 it doesn't alter the cc's, but it might invalidate
2105 the RTX's which we remember the cc's came from.
2106 (Note that moving a constant 0 or 1 MAY set the cc's). */
2107 if (REG_P (SET_DEST (exp))
2108 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM))
2110 return;
2113 /* Moving register into memory doesn't alter the cc's.
2114 It may invalidate the RTX's which we remember the cc's came from. */
2115 if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp)))
2117 return;
2121 CC_STATUS_INIT;
2122 return;
2125 static scalar_int_mode
2126 cr16_unwind_word_mode (void)
2128 return SImode;
2131 /* Helper function for md file. This function is used to emit arithmetic
2132 DI instructions. The argument "num" decides which instruction to be
2133 printed. */
2134 const char *
2135 cr16_emit_add_sub_di (rtx *operands, enum rtx_code code)
2137 rtx lo_op[2] ;
2138 rtx hi0_op[2] ;
2139 rtx hi1_op[2] ;
2141 lo_op[0] = gen_lowpart (SImode, operands[0]);
2142 hi0_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 4);
2143 hi1_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 6);
2145 lo_op[1] = gen_lowpart (SImode, operands[2]);
2146 hi0_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 4);
2147 hi1_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 6);
2149 switch (code)
2151 case PLUS:
2153 output_asm_insn ("addd\t%1, %0", lo_op) ;
2154 output_asm_insn ("addcw\t%1, %0", hi0_op) ;
2155 output_asm_insn ("addcw\t%1, %0", hi1_op) ;
2156 break;
2158 case MINUS:
2160 output_asm_insn ("subd\t%1, %0", lo_op) ;
2161 output_asm_insn ("subcw\t%1, %0", hi0_op) ;
2162 output_asm_insn ("subcw\t%1, %0", hi1_op) ;
2163 break;
2165 default:
2166 break;
2169 return "";
2173 /* Helper function for md file. This function is used to emit logical
2174 DI instructions. The argument "num" decides which instruction to be
2175 printed. */
2176 const char *
2177 cr16_emit_logical_di (rtx *operands, enum rtx_code code)
2179 rtx lo_op[2] ;
2180 rtx hi_op[2] ;
2182 lo_op[0] = gen_lowpart (SImode, operands[0]);
2183 hi_op[0] = simplify_gen_subreg (SImode, operands[0], DImode, 4);
2185 lo_op[1] = gen_lowpart (SImode, operands[2]);
2186 hi_op[1] = simplify_gen_subreg (SImode, operands[2], DImode, 4);
2188 switch (code)
2190 case AND:
2192 output_asm_insn ("andd\t%1, %0", lo_op) ;
2193 output_asm_insn ("andd\t%1, %0", hi_op) ;
2194 return "";
2196 case IOR:
2198 output_asm_insn ("ord\t%1, %0", lo_op) ;
2199 output_asm_insn ("ord\t%1, %0", hi_op) ;
2200 return "";
2202 case XOR:
2204 output_asm_insn ("xord\t%1, %0", lo_op) ;
2205 output_asm_insn ("xord\t%1, %0", hi_op) ;
2206 return "";
2208 default:
2209 break;
2212 return "";
2215 /* Initialize 'targetm' variable which contains pointers to functions
2216 and data relating to the target machine. */
2218 struct gcc_target targetm = TARGET_INITIALIZER;