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