aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-08-25 10:21:20 +0200
committerMartin Liska <mliska@suse.cz>2022-08-26 08:19:38 +0200
commiteb6358247a9386db2828450477d86064f213e0a8 (patch)
tree5c1d8b419773c15e72127d25d461f20999336316 /gcc/config
parent388f1a8cf0851854cc4d2ee99ed85600f0822afc (diff)
downloadgcc-eb6358247a9386db2828450477d86064f213e0a8.zip
gcc-eb6358247a9386db2828450477d86064f213e0a8.tar.gz
gcc-eb6358247a9386db2828450477d86064f213e0a8.tar.bz2
cr16: remove obsoleted port
contrib/ChangeLog: * config-list.mk: Remove cr16. gcc/ChangeLog: * doc/extend.texi: Remove cr16 related stuff. * doc/install.texi: Likewise. * doc/invoke.texi: Likewise. * doc/md.texi: Likewise. * function-tests.cc (test_expansion_to_rtl): Likewise. * common/config/cr16/cr16-common.cc: Removed. * config/cr16/constraints.md: Removed. * config/cr16/cr16-protos.h: Removed. * config/cr16/cr16.cc: Removed. * config/cr16/cr16.h: Removed. * config/cr16/cr16.md: Removed. * config/cr16/cr16.opt: Removed. * config/cr16/predicates.md: Removed. * config/cr16/t-cr16: Removed. libgcc/ChangeLog: * config.host: Remove cr16 related stuff. * config/cr16/crti.S: Removed. * config/cr16/crtlibid.S: Removed. * config/cr16/crtn.S: Removed. * config/cr16/divmodhi3.c: Removed. * config/cr16/lib1funcs.S: Removed. * config/cr16/t-cr16: Removed. * config/cr16/t-crtlibid: Removed. * config/cr16/unwind-cr16.c: Removed. * config/cr16/unwind-dw2.h: Removed. gcc/testsuite/ChangeLog: * lib/target-supports.exp: Remove cr16 related stuff.
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/cr16/constraints.md81
-rw-r--r--gcc/config/cr16/cr16-protos.h98
-rw-r--r--gcc/config/cr16/cr16.cc2201
-rw-r--r--gcc/config/cr16/cr16.h556
-rw-r--r--gcc/config/cr16/cr16.md1084
-rw-r--r--gcc/config/cr16/cr16.opt51
-rw-r--r--gcc/config/cr16/predicates.md225
-rw-r--r--gcc/config/cr16/t-cr1625
8 files changed, 0 insertions, 4321 deletions
diff --git a/gcc/config/cr16/constraints.md b/gcc/config/cr16/constraints.md
deleted file mode 100644
index 708fe21..0000000
--- a/gcc/config/cr16/constraints.md
+++ /dev/null
@@ -1,81 +0,0 @@
-;; Predicates of machine description for CR16.
-;; Copyright (C) 2012-2022 Free Software Foundation, Inc.
-;; Contributed by KPIT Cummins Infosystems Limited.
-;;
-;; This file is part of GCC.
-;;
-;; GCC is free software; you can redistribute it and/or modify it
-;; under the terms of the GNU General Public License as published
-;; by the Free Software Foundation; either version 3, or (at your
-;; option) any later version.
-;;
-;; GCC is distributed in the hope that it will be useful, but WITHOUT
-;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-;; License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GCC; see the file COPYING3. If not see
-;; <http://www.gnu.org/licenses/>.
-
-;; Constraints
-;; Register constraints
-(define_register_constraint "b" "NOSP_REGS"
- "@no sp registers")
-
-(define_register_constraint "c" "SHORT_REGS"
- "@short registers")
-
-(define_register_constraint "d" "LONG_REGS"
- "@long registers")
-
-;; Integer constraints.
-(define_constraint "I"
- "A signed 4-bit immediate."
- (and (match_code "const_int")
- (match_test "SIGNED_INT_FITS_N_BITS (ival, 4)")))
-
-(define_constraint "J"
- "A signed 5-bit immediate."
- (and (match_code "const_int")
- (match_test "SIGNED_INT_FITS_N_BITS (ival, 5)")))
-
-(define_constraint "K"
- "A signed 6-bit immediate."
- (and (match_code "const_int")
- (match_test "SIGNED_INT_FITS_N_BITS (ival, 6)")))
-
-(define_constraint "L"
- "A unsigned 4-bit immediate."
- (and (match_code "const_int")
- (match_test "UNSIGNED_INT_FITS_N_BITS (ival, 4)")))
-
-(define_constraint "M"
- "A unsigned and customized 4-bit immediate."
- (and (match_code "const_int")
- (match_test "(IN_RANGE_P (ival, 0, 15) && ((ival != 9) && (ival != 11)))")))
-
-(define_constraint "N"
- "A signed 16-bit immediate."
- (and (match_code "const_int")
- (match_test "IN_RANGE_P (ival, -32768, 32767)")))
-
-(define_constraint "O"
- "A unsigned 20-bit immediate."
- (and (match_code "const_int")
- (match_test "IN_RANGE_P (ival, 0, 1048575)")))
-
-(define_constraint "Q"
- "A shift QI immediate."
- (and (match_code "const_int")
- (match_test "IN_RANGE_P (ival, 0, 7)")))
-
-(define_constraint "R"
- "A shift HI immediate."
- (and (match_code "const_int")
- (match_test "IN_RANGE_P (ival, 0, 15)")))
-
-(define_constraint "S"
- "A shift SI immediate."
- (and (match_code "const_int")
- (match_test "IN_RANGE_P (ival, 0, 31)")))
diff --git a/gcc/config/cr16/cr16-protos.h b/gcc/config/cr16/cr16-protos.h
deleted file mode 100644
index 300bb31..0000000
--- a/gcc/config/cr16/cr16-protos.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Prototypes for exported functions defined in cr16.cc
- Copyright (C) 2012-2022 Free Software Foundation, Inc.
- Contributed by KPIT Cummins Infosystems Limited.
-
- This file is part of GCC.
-
- GCC is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GCC is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
-
-#ifndef GCC_CR16_PROTOS_H
-#define GCC_CR16_PROTOS_H
-
-/* Register usage. */
-extern enum reg_class cr16_regno_reg_class (int);
-
-/* Passing function arguments. */
-extern int cr16_function_arg_regno_p (int);
-
-#ifdef TREE_CODE
-#ifdef RTX_CODE
-
-extern void cr16_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx);
-
-#endif /* RTX_CODE. */
-#endif /* TREE_CODE. */
-
-/* Enumeration giving the various data models we support. */
-enum data_model_type
-{
- DM_DEFAULT, /* Default data model (in CR16C/C+ - up to 16M). */
- DM_NEAR, /* Near data model (in CR16C/C+ - up to 1M). */
- DM_FAR, /* Far data model (in CR16C+ - up to 4G)
- (in CR16C - up to 16M). */
- ILLEGAL_DM /* Illegal data model. */
-};
-
-#ifdef RTX_CODE
-
-/* Addressing Modes. */
-struct cr16_address
-{
- rtx base; /* Base register: Any register or register pair. */
- rtx index; /* Index register: If one is present. */
- rtx disp; /* Displacement or Absolute address. */
- enum data_model_type data; /* data ref type. */
- int code; /* Whether the address is code address.
- 0 - data, 1 - code label, 2 - function label. */
-};
-
-enum cr16_addrtype
-{
- CR16_INVALID,
- CR16_REG_REL,
- CR16_REGP_REL,
- CR16_INDEX_REGP_REL,
- CR16_ABSOLUTE
-};
-
-extern int cr16_operand_bit_pos (int val, int bitval);
-extern void cr16_decompose_const (rtx x, int *code,
- enum data_model_type *data,
- bool treat_as_const);
-extern enum cr16_addrtype cr16_decompose_address (rtx addr,
- struct cr16_address *out,
- bool debug_print,
- bool treat_as_const);
-extern int cr16_const_double_ok (rtx op);
-extern int legitimate_pic_operand_p (rtx);
-extern rtx legitimize_pic_address (rtx, machine_mode, rtx);
-
-
-/* Prologue/Epilogue functions. */
-extern int cr16_initial_elimination_offset (int, int);
-extern char *cr16_prepare_push_pop_string (int);
-extern void cr16_expand_prologue (void);
-extern void cr16_expand_epilogue (void);
-extern const char *cr16_emit_add_sub_di (rtx *, enum rtx_code);
-extern const char *cr16_emit_logical_di (rtx *, enum rtx_code);
-
-#endif /* RTX_CODE. */
-
-/* Handling the "interrupt" attribute. */
-extern int cr16_interrupt_function_p (void);
-extern bool cr16_is_data_model (enum data_model_type);
-extern poly_int64 cr16_push_rounding (poly_int64);
-
-#endif /* Not GCC_CR16_PROTOS_H. */
diff --git a/gcc/config/cr16/cr16.cc b/gcc/config/cr16/cr16.cc
deleted file mode 100644
index 55dad99..0000000
--- a/gcc/config/cr16/cr16.cc
+++ /dev/null
@@ -1,2201 +0,0 @@
-/* Output routines for CR16 processor.
- Copyright (C) 2012-2022 Free Software Foundation, Inc.
- Contributed by KPIT Cummins Infosystems Limited.
-
- This file is part of GCC.
-
- GCC is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GCC is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
-
-#define IN_TARGET_CODE 1
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "backend.h"
-#include "target.h"
-#include "rtl.h"
-#include "tree.h"
-#include "stringpool.h"
-#include "attribs.h"
-#include "df.h"
-#include "memmodel.h"
-#include "tm_p.h"
-#include "regs.h"
-#include "emit-rtl.h"
-#include "diagnostic-core.h"
-#include "stor-layout.h"
-#include "calls.h"
-#include "conditions.h"
-#include "output.h"
-#include "expr.h"
-#include "builtins.h"
-
-/* This file should be included last. */
-#include "target-def.h"
-
-/* Definitions. */
-
-/* Maximum number of register used for passing parameters. */
-#define MAX_REG_FOR_PASSING_ARGS 6
-
-/* Minimum number register used for passing parameters. */
-#define MIN_REG_FOR_PASSING_ARGS 2
-
-/* The maximum count of words supported in the assembly of the architecture in
- a push/pop instruction. */
-#define MAX_COUNT 8
-
-/* Predicate is true if the current function is a 'noreturn' function,
- i.e. it is qualified as volatile. */
-#define FUNC_IS_NORETURN_P(decl) (TREE_THIS_VOLATILE (decl))
-
-/* Predicate that holds when we need to save registers even for 'noreturn'
- functions, to accommodate for unwinding. */
-#define MUST_SAVE_REGS_P() \
- (flag_unwind_tables || (flag_exceptions && !UI_SJLJ))
-
-/* Nonzero if the rtx X is a signed const int of n bits. */
-#define RTX_SIGNED_INT_FITS_N_BITS(X, n) \
- ((GET_CODE (X) == CONST_INT \
- && SIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
-
-/* Nonzero if the rtx X is an unsigned const int of n bits. */
-#define RTX_UNSIGNED_INT_FITS_N_BITS(X, n) \
- ((GET_CODE (X) == CONST_INT \
- && UNSIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
-
-/* Structure for stack computations. */
-
-/* variable definitions in the struture
- args_size Number of bytes saved on the stack for local
- variables
-
- reg_size Number of bytes saved on the stack for
- non-scratch registers
-
- total_size The sum of 2 sizes: locals vars and padding byte
- for saving the registers. Used in expand_prologue()
- and expand_epilogue()
-
- last_reg_to_save Will hold the number of the last register the
- prologue saves, -1 if no register is saved
-
- save_regs[16] Each object in the array is a register number.
- Mark 1 for registers that need to be saved
-
- num_regs Number of registers saved
-
- initialized Non-zero if frame size already calculated, not
- used yet
-
- function_makes_calls Does the function make calls ? not used yet. */
-
-struct cr16_frame_info
-{
- unsigned long var_size;
- unsigned long args_size;
- unsigned int reg_size;
- unsigned long total_size;
- long last_reg_to_save;
- long save_regs[FIRST_PSEUDO_REGISTER];
- int num_regs;
- int initialized;
- int function_makes_calls;
-};
-
-/* Current frame information calculated by cr16_compute_frame_size. */
-static struct cr16_frame_info current_frame_info;
-
-/* Static Variables. */
-
-/* Data model that was supplied by user via command line option
- This will be overridden in case of invalid combination
- of core and data model options are supplied. */
-static enum data_model_type data_model = DM_DEFAULT;
-
-/* TARGETM Function Prototypes and forward declarations */
-static void cr16_print_operand (FILE *, rtx, int);
-static void cr16_print_operand_address (FILE *, machine_mode, rtx);
-
-/* Stack layout and calling conventions. */
-#undef TARGET_STRUCT_VALUE_RTX
-#define TARGET_STRUCT_VALUE_RTX cr16_struct_value_rtx
-#undef TARGET_RETURN_IN_MEMORY
-#define TARGET_RETURN_IN_MEMORY cr16_return_in_memory
-
-/* Target-specific uses of '__attribute__'. */
-#undef TARGET_ATTRIBUTE_TABLE
-#define TARGET_ATTRIBUTE_TABLE cr16_attribute_table
-#undef TARGET_NARROW_VOLATILE_BITFIELD
-#define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false
-
-/* EH related. */
-#undef TARGET_UNWIND_WORD_MODE
-#define TARGET_UNWIND_WORD_MODE cr16_unwind_word_mode
-
-/* Override Options. */
-#undef TARGET_OPTION_OVERRIDE
-#define TARGET_OPTION_OVERRIDE cr16_override_options
-
-/* Conditional register usuage. */
-#undef TARGET_CONDITIONAL_REGISTER_USAGE
-#define TARGET_CONDITIONAL_REGISTER_USAGE cr16_conditional_register_usage
-
-/* Controlling register spills. */
-#undef TARGET_CLASS_LIKELY_SPILLED_P
-#define TARGET_CLASS_LIKELY_SPILLED_P cr16_class_likely_spilled_p
-
-/* Passing function arguments. */
-#undef TARGET_PUSH_ARGUMENT
-#define TARGET_PUSH_ARGUMENT hook_bool_uint_true
-#undef TARGET_FUNCTION_ARG
-#define TARGET_FUNCTION_ARG cr16_function_arg
-#undef TARGET_FUNCTION_ARG_ADVANCE
-#define TARGET_FUNCTION_ARG_ADVANCE cr16_function_arg_advance
-#undef TARGET_RETURN_POPS_ARGS
-#define TARGET_RETURN_POPS_ARGS cr16_return_pops_args
-
-/* Initialize the GCC target structure. */
-#undef TARGET_FRAME_POINTER_REQUIRED
-#define TARGET_FRAME_POINTER_REQUIRED cr16_frame_pointer_required
-#undef TARGET_CAN_ELIMINATE
-#define TARGET_CAN_ELIMINATE cr16_can_eliminate
-#undef TARGET_LEGITIMIZE_ADDRESS
-#define TARGET_LEGITIMIZE_ADDRESS cr16_legitimize_address
-#undef TARGET_LEGITIMATE_CONSTANT_P
-#define TARGET_LEGITIMATE_CONSTANT_P cr16_legitimate_constant_p
-#undef TARGET_LEGITIMATE_ADDRESS_P
-#define TARGET_LEGITIMATE_ADDRESS_P cr16_legitimate_address_p
-
-#undef TARGET_LRA_P
-#define TARGET_LRA_P hook_bool_void_false
-
-/* Returning function value. */
-#undef TARGET_FUNCTION_VALUE
-#define TARGET_FUNCTION_VALUE cr16_function_value
-#undef TARGET_LIBCALL_VALUE
-#define TARGET_LIBCALL_VALUE cr16_libcall_value
-#undef TARGET_FUNCTION_VALUE_REGNO_P
-#define TARGET_FUNCTION_VALUE_REGNO_P cr16_function_value_regno_p
-
-/* printing the values. */
-#undef TARGET_PRINT_OPERAND
-#define TARGET_PRINT_OPERAND cr16_print_operand
-#undef TARGET_PRINT_OPERAND_ADDRESS
-#define TARGET_PRINT_OPERAND_ADDRESS cr16_print_operand_address
-
-/* Relative costs of operations. */
-#undef TARGET_ADDRESS_COST
-#define TARGET_ADDRESS_COST cr16_address_cost
-#undef TARGET_REGISTER_MOVE_COST
-#define TARGET_REGISTER_MOVE_COST cr16_register_move_cost
-#undef TARGET_MEMORY_MOVE_COST
-#define TARGET_MEMORY_MOVE_COST cr16_memory_move_cost
-
-#undef TARGET_CONSTANT_ALIGNMENT
-#define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
-
-/* Table of machine attributes. */
-static const struct attribute_spec cr16_attribute_table[] = {
- /* ISRs have special prologue and epilogue requirements. */
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
- affects_type_identity, handler, exclude }. */
- {"interrupt", 0, 0, false, true, true, false, NULL, NULL},
- {NULL, 0, 0, false, false, false, false, NULL, NULL}
-};
-
-/* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive
- .?byte directive along with @c is not understood by assembler.
- Therefore, make all TARGET_ASM_UNALIGNED_xx_OP same
- as TARGET_ASM_ALIGNED_xx_OP. */
-#undef TARGET_ASM_UNALIGNED_HI_OP
-#define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
-#undef TARGET_ASM_UNALIGNED_SI_OP
-#define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
-#undef TARGET_ASM_UNALIGNED_DI_OP
-#define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
-
-#undef TARGET_HARD_REGNO_NREGS
-#define TARGET_HARD_REGNO_NREGS cr16_hard_regno_nregs
-#undef TARGET_HARD_REGNO_MODE_OK
-#define TARGET_HARD_REGNO_MODE_OK cr16_hard_regno_mode_ok
-#undef TARGET_MODES_TIEABLE_P
-#define TARGET_MODES_TIEABLE_P cr16_modes_tieable_p
-
-/* Target hook implementations. */
-
-/* Implements hook TARGET_RETURN_IN_MEMORY. */
-static bool
-cr16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
-{
- const HOST_WIDE_INT size = int_size_in_bytes (type);
- return ((size == -1) || (size > 8));
-}
-
-/* Implement TARGET_CLASS_LIKELY_SPILLED_P. */
-static bool
-cr16_class_likely_spilled_p (reg_class_t rclass)
-{
- if ((rclass) == SHORT_REGS || (rclass) == DOUBLE_BASE_REGS
- || (rclass) == LONG_REGS || (rclass) == GENERAL_REGS)
- return true;
-
- return false;
-}
-
-static poly_int64
-cr16_return_pops_args (tree, tree, poly_int64)
-{
- return 0;
-}
-
-/* Returns true if data model selected via command line option
- is same as function argument. */
-bool
-cr16_is_data_model (enum data_model_type model)
-{
- return (model == data_model);
-}
-
-/* Parse relevant options and override. */
-static void
-cr16_override_options (void)
-{
- /* Disable -fdelete-null-pointer-checks option for CR16 target.
- Programs which rely on NULL pointer dereferences _not_ halting the
- program may not work properly with this option. So disable this
- option. */
- flag_delete_null_pointer_checks = 0;
-
- /* FIXME: To avoid spill_failure ICE during exception handling,
- * disable cse_fllow_jumps. The spill error occurs when compiler
- * can't find a suitable candidate in GENERAL_REGS class to reload
- * a 32bit register.
- * Need to find a better way of avoiding this situation. */
- if (flag_exceptions)
- flag_cse_follow_jumps = 0;
-
- /* If -fpic option, data_model == DM_FAR. */
- if (flag_pic == NEAR_PIC)
- {
- data_model = DM_FAR;
- }
-
- /* The only option we want to examine is data model option. */
- if (cr16_data_model)
- {
- if (strcmp (cr16_data_model, "medium") == 0)
- data_model = DM_DEFAULT;
- else if (strcmp (cr16_data_model, "near") == 0)
- data_model = DM_NEAR;
- else if (strcmp (cr16_data_model, "far") == 0)
- {
- if (TARGET_CR16CP)
- data_model = DM_FAR;
- else
- error ("data-model=far not valid for cr16c architecture");
- }
- else
- error ("invalid data model option %<-mdata-model=%s%>",
- cr16_data_model);
- }
- else
- data_model = DM_DEFAULT;
-}
-
-/* Implements the macro TARGET_CONDITIONAL_REGISTER_USAGE. */
-static void
-cr16_conditional_register_usage (void)
-{
- if (flag_pic)
- {
- fixed_regs[12] = call_used_regs[12] = 1;
- }
-}
-
-/* Stack layout and calling conventions routines. */
-
-/* Return nonzero if the current function being compiled is an interrupt
- function as specified by the "interrupt" attribute. */
-int
-cr16_interrupt_function_p (void)
-{
- tree attributes;
-
- attributes = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
- return (lookup_attribute ("interrupt", attributes) != NULL_TREE);
-}
-
-/* Compute values for the array current_frame_info.save_regs and the variable
- current_frame_info.reg_size. The index of current_frame_info.save_regs
- is numbers of register, each will get 1 if we need to save it in the
- current function, 0 if not. current_frame_info.reg_size is the total sum
- of the registers being saved. */
-static void
-cr16_compute_save_regs (void)
-{
- unsigned int regno;
-
- /* Initialize here so in case the function is no-return it will be -1. */
- current_frame_info.last_reg_to_save = -1;
-
- /* Initialize the number of bytes to be saved. */
- current_frame_info.reg_size = 0;
-
- /* No need to save any registers if the function never returns. */
- if (FUNC_IS_NORETURN_P (current_function_decl) && !MUST_SAVE_REGS_P ())
- return;
-
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- {
- if (fixed_regs[regno])
- {
- current_frame_info.save_regs[regno] = 0;
- continue;
- }
-
- /* If this reg is used and not call-used (except RA), save it. */
- if (cr16_interrupt_function_p ())
- {
- if (!crtl->is_leaf && call_used_or_fixed_reg_p (regno))
- /* This is a volatile reg in a non-leaf interrupt routine - save
- it for the sake of its sons. */
- current_frame_info.save_regs[regno] = 1;
- else if (df_regs_ever_live_p (regno))
- /* This reg is used - save it. */
- current_frame_info.save_regs[regno] = 1;
- else
- /* This reg is not used, and is not a volatile - don't save. */
- current_frame_info.save_regs[regno] = 0;
- }
- else
- {
- /* If this reg is used and not call-used (except RA), save it. */
- if (df_regs_ever_live_p (regno)
- && (!call_used_or_fixed_reg_p (regno)
- || regno == RETURN_ADDRESS_REGNUM))
- current_frame_info.save_regs[regno] = 1;
- else
- current_frame_info.save_regs[regno] = 0;
- }
- }
-
- /* Save registers so the exception handler can modify them. */
- if (crtl->calls_eh_return)
- {
- unsigned int i;
-
- for (i = 0;; ++i)
- {
- regno = EH_RETURN_DATA_REGNO (i);
- if (INVALID_REGNUM == regno)
- break;
- current_frame_info.save_regs[regno] = 1;
- }
- }
-
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (current_frame_info.save_regs[regno] == 1)
- {
- current_frame_info.last_reg_to_save = regno;
- if (regno >= CR16_FIRST_DWORD_REGISTER)
- current_frame_info.reg_size += CR16_UNITS_PER_DWORD;
- else
- current_frame_info.reg_size += UNITS_PER_WORD;
- }
-}
-
-/* Compute the size of the local area and the size to be adjusted by the
- prologue and epilogue. */
-static void
-cr16_compute_frame (void)
-{
- /* For aligning the local variables. */
- int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
- int padding_locals;
-
- /* Padding needed for each element of the frame. */
- current_frame_info.var_size = get_frame_size ();
-
- /* Align to the stack alignment. */
- padding_locals = current_frame_info.var_size % stack_alignment;
- if (padding_locals)
- padding_locals = stack_alignment - padding_locals;
-
- current_frame_info.var_size += padding_locals;
- current_frame_info.total_size
- = (current_frame_info.var_size
- + (ACCUMULATE_OUTGOING_ARGS
- ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0));
-}
-
-/* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */
-int
-cr16_initial_elimination_offset (int from, int to)
-{
- /* Compute this since we need to use current_frame_info.reg_size. */
- cr16_compute_save_regs ();
-
- /* Compute this since we need to use current_frame_info.var_size. */
- cr16_compute_frame ();
-
- if (((from) == FRAME_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
- return (ACCUMULATE_OUTGOING_ARGS
- ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0);
- else if (((from) == ARG_POINTER_REGNUM) && ((to) == FRAME_POINTER_REGNUM))
- return (current_frame_info.reg_size + current_frame_info.var_size);
- else if (((from) == ARG_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
- return (current_frame_info.reg_size + current_frame_info.var_size
- + (ACCUMULATE_OUTGOING_ARGS
- ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0));
- else
- gcc_unreachable ();
-}
-
-/* Register Usage. */
-
-/* Return the class number of the smallest class containing reg number REGNO.
- This could be a conditional expression or could index an array. */
-enum reg_class
-cr16_regno_reg_class (int regno)
-{
- if ((regno >= 0) && (regno < CR16_FIRST_DWORD_REGISTER))
- return SHORT_REGS;
-
- if ((regno >= CR16_FIRST_DWORD_REGISTER) && (regno < FIRST_PSEUDO_REGISTER))
- return LONG_REGS;
-
- return NO_REGS;
-}
-
-/* Implement TARGET_HARD_REGNO_NREGS. */
-
-static unsigned int
-cr16_hard_regno_nregs (unsigned int regno, machine_mode mode)
-{
- if (regno >= CR16_FIRST_DWORD_REGISTER)
- return CEIL (GET_MODE_SIZE (mode), CR16_UNITS_PER_DWORD);
- return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
-}
-
-/* Implement TARGET_HARD_REGNO_MODE_OK. On the CR16 architecture, all
- registers can hold all modes, except that double precision floats
- (and double ints) must fall on even-register boundaries. */
-
-static bool
-cr16_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
-{
- if ((GET_MODE_SIZE (mode) >= 4) && (regno == 11))
- return false;
-
- if (mode == DImode || mode == DFmode)
- {
- if ((regno > 8) || (regno & 1))
- return false;
- return true;
- }
-
- if ((TARGET_INT32)
- && ((regno >= 12) && (GET_MODE_SIZE (mode) < 4 )))
- return false;
-
- /* CC can only hold CCmode values. */
- if (GET_MODE_CLASS (mode) == MODE_CC)
- return false;
- return true;
-}
-
-/* Implement TARGET_MODES_TIEABLE_P. */
-static bool
-cr16_modes_tieable_p (machine_mode mode1, machine_mode mode2)
-{
- return GET_MODE_CLASS (mode1) == GET_MODE_CLASS (mode2);
-}
-
-/* Returns register number for function return value.*/
-static inline unsigned int
-cr16_ret_register (void)
-{
- return 0;
-}
-
-/* Implements hook TARGET_STRUCT_VALUE_RTX. */
-static rtx
-cr16_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
- int incoming ATTRIBUTE_UNUSED)
-{
- return gen_rtx_REG (Pmode, cr16_ret_register ());
-}
-
-/* Returning function value. */
-
-/* Worker function for TARGET_FUNCTION_VALUE_REGNO_P. */
-static bool
-cr16_function_value_regno_p (const unsigned int regno)
-{
- return (regno == cr16_ret_register ());
-}
-
-/* Create an RTX representing the place where a
- library function returns a value of mode MODE. */
-static rtx
-cr16_libcall_value (machine_mode mode,
- const_rtx func ATTRIBUTE_UNUSED)
-{
- return gen_rtx_REG (mode, cr16_ret_register ());
-}
-
-/* Create an RTX representing the place where a
- function returns a value of data type VALTYPE. */
-static rtx
-cr16_function_value (const_tree type,
- const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
- bool outgoing ATTRIBUTE_UNUSED)
-{
- return gen_rtx_REG (TYPE_MODE (type), cr16_ret_register ());
-}
-
-/* Passing function arguments. */
-
-/* If enough param regs are available for passing the param of type TYPE return
- the number of registers needed else 0. */
-static int
-enough_regs_for_param (CUMULATIVE_ARGS * cum, const_tree type,
- machine_mode mode)
-{
- int type_size;
- int remaining_size;
-
- if (mode != BLKmode)
- type_size = GET_MODE_BITSIZE (mode);
- else
- type_size = int_size_in_bytes (type) * BITS_PER_UNIT;
-
- remaining_size = BITS_PER_WORD * (MAX_REG_FOR_PASSING_ARGS
- - (MIN_REG_FOR_PASSING_ARGS + cum->ints) +
- 1);
-
- /* Any variable which is too big to pass in two registers, will pass on
- stack. */
- if ((remaining_size >= type_size) && (type_size <= 2 * BITS_PER_WORD))
- return (type_size + BITS_PER_WORD - 1) / BITS_PER_WORD;
-
- return 0;
-}
-
-/* Implement TARGET_FUNCTION_ARG. */
-static rtx
-cr16_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
-{
- CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
- cum->last_parm_in_reg = 0;
-
- /* function_arg () is called with this type just after all the args have
- had their registers assigned. The rtx that function_arg returns from
- this type is supposed to pass to 'gen_call' but currently it is not
- implemented. */
- if (arg.end_marker_p ())
- return NULL_RTX;
-
- if (targetm.calls.must_pass_in_stack (arg) || (cum->ints < 0))
- return NULL_RTX;
-
- if (arg.mode == BLKmode)
- {
- /* Enable structures that need padding bytes at the end to pass to a
- function in registers. */
- if (enough_regs_for_param (cum, arg.type, arg.mode) != 0)
- {
- cum->last_parm_in_reg = 1;
- return gen_rtx_REG (arg.mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
- }
- }
-
- if ((MIN_REG_FOR_PASSING_ARGS + cum->ints) > MAX_REG_FOR_PASSING_ARGS)
- return NULL_RTX;
- else
- {
- if (enough_regs_for_param (cum, arg.type, arg.mode) != 0)
- {
- cum->last_parm_in_reg = 1;
- return gen_rtx_REG (arg.mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
- }
- }
-
- return NULL_RTX;
-}
-
-/* Implements the macro INIT_CUMULATIVE_ARGS defined in cr16.h. */
-void
-cr16_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype,
- rtx libfunc ATTRIBUTE_UNUSED)
-{
- tree param, next_param;
-
- cum->ints = 0;
-
- /* Determine if this function has variable arguments. This is indicated by
- the last argument being 'void_type_mode' if there are no variable
- arguments. Change here for a different vararg. */
- for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
- param != NULL_TREE; param = next_param)
- {
- next_param = TREE_CHAIN (param);
- if ((next_param == NULL_TREE) && (TREE_VALUE (param) != void_type_node))
- {
- cum->ints = -1;
- return;
- }
- }
-}
-
-/* Implements the macro FUNCTION_ARG_ADVANCE defined in cr16.h. */
-static void
-cr16_function_arg_advance (cumulative_args_t cum_v,
- const function_arg_info &arg)
-{
- CUMULATIVE_ARGS * cum = get_cumulative_args (cum_v);
-
- /* l holds the number of registers required. */
- int l = GET_MODE_BITSIZE (arg.mode) / BITS_PER_WORD;
-
- /* If the parameter isn't passed on a register don't advance cum. */
- if (!cum->last_parm_in_reg)
- return;
-
- if (targetm.calls.must_pass_in_stack (arg) || (cum->ints < 0))
- return;
-
- if ((arg.mode == SImode) || (arg.mode == HImode)
- || (arg.mode == QImode) || (arg.mode == DImode))
- {
- if (l <= 1)
- cum->ints += 1;
- else
- cum->ints += l;
- }
- else if ((arg.mode == SFmode) || (arg.mode == DFmode))
- cum->ints += l;
- else if (arg.mode == BLKmode)
- {
- if ((l = enough_regs_for_param (cum, arg.type, arg.mode)) != 0)
- cum->ints += l;
- }
- return;
-}
-
-/* Implements the macro FUNCTION_ARG_REGNO_P defined in cr16.h.
- Return nonzero if N is a register used for passing parameters. */
-int
-cr16_function_arg_regno_p (int n)
-{
- return ((n <= MAX_REG_FOR_PASSING_ARGS) && (n >= MIN_REG_FOR_PASSING_ARGS));
-}
-
-/* Addressing modes.
- Following set of function implement the macro GO_IF_LEGITIMATE_ADDRESS
- defined in cr16.h. */
-
-/* Helper function to check if is a valid base register that can
- hold address. */
-static int
-cr16_addr_reg_p (rtx addr_reg)
-{
- rtx reg;
-
- if (REG_P (addr_reg))
- reg = addr_reg;
- else if ((GET_CODE (addr_reg) == SUBREG)
- && REG_P (SUBREG_REG (addr_reg))
- && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg)))
- <= UNITS_PER_WORD))
- reg = SUBREG_REG (addr_reg);
- else
- return FALSE;
-
- if (GET_MODE (reg) != Pmode)
- return FALSE;
-
- return TRUE;
-}
-
-/* Helper functions: Created specifically for decomposing operand of CONST
- Recursively look into expression x for code or data symbol.
- The function expects the expression to contain combination of
- SYMBOL_REF, CONST_INT, (PLUS or MINUS)
- LABEL_REF, CONST_INT, (PLUS or MINUS)
- SYMBOL_REF
- LABEL_REF
- All other combinations will result in code = -1 and data = ILLEGAL_DM
- code data
- -1 ILLEGAL_DM The expression did not contain SYMBOL_REF or LABEL_REF
- 0 DM_FAR SYMBOL_REF was found and it was far data reference.
- 0 DM_DEFAULT SYMBOL_REF was found and it was medium data reference.
- 1 ILLEGAL_DM LABEL_REF was found.
- 2 ILLEGAL_DM SYMBOL_REF was found and it was function reference. */
-void
-cr16_decompose_const (rtx x, int *code, enum data_model_type *data,
- bool treat_as_const)
-{
- *code = -1;
- *data = ILLEGAL_DM;
- switch (GET_CODE (x))
- {
- case SYMBOL_REF:
- *code = SYMBOL_REF_FUNCTION_P (x) ? 2 : 0;
- /* 2 indicates func sym. */
- if (*code == 0)
- {
- if (CR16_TARGET_DATA_NEAR)
- *data = DM_DEFAULT;
- else if (CR16_TARGET_DATA_MEDIUM)
- *data = DM_FAR;
- else if (CR16_TARGET_DATA_FAR)
- {
- if (treat_as_const)
- /* This will be used only for printing
- the qualifier. This call is (may be)
- made by cr16_print_operand_address. */
- *data = DM_FAR;
- else
- /* This call is (may be) made by
- cr16_legitimate_address_p. */
- *data = ILLEGAL_DM;
- }
- }
- return;
-
- case LABEL_REF:
- /* 1 - indicates non-function symbol. */
- *code = 1;
- return;
-
- case PLUS:
- case MINUS:
- /* Look into the tree nodes. */
- if (GET_CODE (XEXP (x, 0)) == CONST_INT)
- cr16_decompose_const (XEXP (x, 1), code, data, treat_as_const);
- else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
- cr16_decompose_const (XEXP (x, 0), code, data, treat_as_const);
- return;
- default:
- return;
- }
-}
-
-/* Decompose Address
- This function decomposes the address returns the type of address
- as defined in enum cr16_addrtype. It also fills the parameter *out.
- The decomposed address can be used for two purposes. One to
- check if the address is valid and second to print the address
- operand.
-
- Following tables list valid address supported in CR16C/C+ architectures.
- Legend:
- aN : Absoulte address N-bit address
- R : One 16-bit register
- RP : Consecutive two 16-bit registers or one 32-bit register
- I : One 32-bit register
- dispN : Signed displacement of N-bits
-
- ----Code addresses----
- Branch operands:
- disp9 : CR16_ABSOLUTE (disp)
- disp17 : CR16_ABSOLUTE (disp)
- disp25 : CR16_ABSOLUTE (disp)
- RP + disp25 : CR16_REGP_REL (base, disp)
-
- Jump operands:
- RP : CR16_REGP_REL (base, disp=0)
- a24 : CR16_ABSOLUTE (disp)
-
- ----Data addresses----
- a20 : CR16_ABSOLUTE (disp) near (1M)
- a24 : CR16_ABSOLUTE (disp) medium (16M)
- R + d20 : CR16_REG_REL (base, disp) near (1M+64K)
- RP + d4 : CR16_REGP_REL (base, disp) far (4G)
- RP + d16 : CR16_REGP_REL (base, disp) far (4G)
- RP + d20 : CR16_REGP_REL (base, disp) far (4G)
- I : *** Valid but port does not support this
- I + a20 : *** Valid but port does not support this
- I + RP + d14: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
- I + RP + d20: CR16_INDEX_REGP_REL (base, index, disp) far (4G)
-
- Decomposing Data model in case of absolute address.
-
- Target Option Address type Resultant Data ref type
- ---------------------- ------------ -----------------------
- CR16_TARGET_MODEL_NEAR ABS20 DM_DEFAULT
- CR16_TARGET_MODEL_NEAR IMM20 DM_DEFAULT
- CR16_TARGET_MODEL_NEAR ABS24 Invalid
- CR16_TARGET_MODEL_NEAR IMM32 Invalid
-
- CR16_TARGET_MODEL_MEDIUM ABS20 DM_DEFAULT
- CR16_TARGET_MODEL_MEDIUM IMM20 DM_DEFAULT
- CR16_TARGET_MODEL_MEDIUM ABS24 DM_FAR
- CR16_TARGET_MODEL_MEDIUM IMM32 Invalid
-
- CR16_TARGET_MODEL_FAR ABS20 DM_DEFAULT
- CR16_TARGET_MODEL_FAR IMM20 DM_DEFAULT
- CR16_TARGET_MODEL_FAR ABS24 DM_FAR
- CR16_TARGET_MODEL_FAR IMM32 DM_FAR. */
-enum cr16_addrtype
-cr16_decompose_address (rtx addr, struct cr16_address *out,
- bool debug_print, bool treat_as_const)
-{
- rtx base = NULL_RTX, disp = NULL_RTX, index = NULL_RTX;
- enum data_model_type data = ILLEGAL_DM;
- int code = -1;
- enum cr16_addrtype retval = CR16_INVALID;
-
- switch (GET_CODE (addr))
- {
- case CONST_INT:
- /* Absolute address (known at compile time). */
- code = 0;
- if (debug_print)
- fprintf (stderr, "\ncode:%d", code);
- disp = addr;
-
- if (debug_print)
- {
- fprintf (stderr, "\ndisp:");
- debug_rtx (disp);
- }
-
- if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
- {
- data = DM_DEFAULT;
- if (debug_print)
- fprintf (stderr, "\ndata:%d", data);
- retval = CR16_ABSOLUTE;
- }
- else if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 24))
- {
- if (!CR16_TARGET_DATA_NEAR)
- {
- data = DM_FAR;
- if (debug_print)
- fprintf (stderr, "\ndata:%d", data);
- retval = CR16_ABSOLUTE;
- }
- else
- return CR16_INVALID; /* ABS24 is not support in NEAR model. */
- }
- else
- return CR16_INVALID;
- break;
-
- case CONST:
- /* A CONST is an expression of PLUS or MINUS with
- CONST_INT, SYMBOL_REF or LABEL_REF. This is the
- result of assembly-time arithmetic computation. */
- retval = CR16_ABSOLUTE;
- disp = addr;
- /* Call the helper function to check the validity. */
- cr16_decompose_const (XEXP (addr, 0), &code, &data, treat_as_const);
- if ((code == 0) && (data == ILLEGAL_DM))
- /* CONST is not valid code or data address. */
- return CR16_INVALID;
- if (debug_print)
- {
- fprintf (stderr, "\ndisp:");
- debug_rtx (disp);
- fprintf (stderr, "\ncode:%d", code);
- fprintf (stderr, "\ndata:%d", data);
- }
- break;
-
- case LABEL_REF:
- retval = CR16_ABSOLUTE;
- disp = addr;
- /* 1 - indicates non-function symbol. */
- code = 1;
- if (debug_print)
- {
- fprintf (stderr, "\ndisp:");
- debug_rtx (disp);
- fprintf (stderr, "\ncode:%d", code);
- }
- break;
-
- case SYMBOL_REF:
- /* Absolute address (known at link time). */
- retval = CR16_ABSOLUTE;
- disp = addr;
- /* This is a code address if symbol_ref is a function. */
- /* 2 indicates func sym. */
- code = SYMBOL_REF_FUNCTION_P (addr) ? 2 : 0;
- if (debug_print)
- {
- fprintf (stderr, "\ndisp:");
- debug_rtx (disp);
- fprintf (stderr, "\ncode:%d", code);
- }
- /* If not function ref then check if valid data ref. */
- if (code == 0)
- {
- if (CR16_TARGET_DATA_NEAR)
- data = DM_DEFAULT;
- else if (CR16_TARGET_DATA_MEDIUM)
- data = DM_FAR;
- else if (CR16_TARGET_DATA_FAR)
- {
- if (treat_as_const)
- /* This will be used only for printing the
- qualifier. This call is (may be) made
- by cr16_print_operand_address. */
- data = DM_FAR;
- else
- /* This call is (may be) made by
- cr16_legitimate_address_p. */
- return CR16_INVALID;
- }
- else
- data = DM_DEFAULT;
- }
- if (debug_print)
- fprintf (stderr, "\ndata:%d", data);
- break;
-
- case REG:
- case SUBREG:
- /* Register relative address. */
- /* Assume REG fits in a single register. */
- retval = CR16_REG_REL;
- if (GET_MODE_BITSIZE (GET_MODE (addr)) > BITS_PER_WORD)
- if (!LONG_REG_P (REGNO (addr)))
- /* REG will result in reg pair. */
- retval = CR16_REGP_REL;
- base = addr;
- if (debug_print)
- {
- fprintf (stderr, "\nbase:");
- debug_rtx (base);
- }
- break;
-
- case PLUS:
- switch (GET_CODE (XEXP (addr, 0)))
- {
- case REG:
- case SUBREG:
- /* REG + DISP20. */
- /* All Reg relative addresses having a displacement needs
- to fit in 20-bits. */
- disp = XEXP (addr, 1);
- if (debug_print)
- {
- fprintf (stderr, "\ndisp:");
- debug_rtx (disp);
- }
- switch (GET_CODE (XEXP (addr, 1)))
- {
- case CONST_INT:
- /* Shall fit in 20-bits. */
- if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
- return CR16_INVALID;
- code = 0;
- if (debug_print)
- fprintf (stderr, "\ncode:%d", code);
- break;
-
- case UNSPEC:
- switch (XINT (XEXP (addr, 1), 1))
- {
- case UNSPEC_LIBRARY_OFFSET:
- default:
- gcc_unreachable ();
- }
- break;
-
- case LABEL_REF:
- case SYMBOL_REF:
- case CONST:
- /* This is also a valid expression for address.
- However, we cannot ascertain if the resultant
- displacement will be valid 20-bit value. Therefore,
- lets not allow such an expression for now. This will
- be updated when we find a way to validate this
- expression as legitimate address.
- Till then fall through CR16_INVALID. */
- default:
- return CR16_INVALID;
- }
-
- /* Now check if REG can fit into single or pair regs. */
- retval = CR16_REG_REL;
- base = XEXP (addr, 0);
- if (debug_print)
- {
- fprintf (stderr, "\nbase:");
- debug_rtx (base);
- }
- if (GET_MODE_BITSIZE (GET_MODE ((XEXP (addr, 0)))) > BITS_PER_WORD)
- {
- if (!LONG_REG_P (REGNO ((XEXP (addr, 0)))))
- /* REG will result in reg pair. */
- retval = CR16_REGP_REL;
- }
- break;
-
- case PLUS:
- /* Valid expr:
- plus
- /\
- / \
- plus idx
- /\
- / \
- reg const_int
-
- Check if the operand 1 is valid index register. */
- data = ILLEGAL_DM;
- if (debug_print)
- fprintf (stderr, "\ndata:%d", data);
- switch (GET_CODE (XEXP (addr, 1)))
- {
- case REG:
- case SUBREG:
- if (!REG_OK_FOR_INDEX_P (XEXP (addr, 1)))
- return CR16_INVALID;
- /* OK. REG is a valid index register. */
- index = XEXP (addr, 1);
- if (debug_print)
- {
- fprintf (stderr, "\nindex:");
- debug_rtx (index);
- }
- break;
- default:
- return CR16_INVALID;
- }
- /* Check if operand 0 of operand 0 is REGP. */
- switch (GET_CODE (XEXP (XEXP (addr, 0), 0)))
- {
- case REG:
- case SUBREG:
- /* Now check if REG is a REGP and not in LONG regs. */
- if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (addr, 0), 0)))
- > BITS_PER_WORD)
- {
- if (REGNO (XEXP (XEXP (addr, 0), 0))
- >= CR16_FIRST_DWORD_REGISTER)
- return CR16_INVALID;
- base = XEXP (XEXP (addr, 0), 0);
- if (debug_print)
- {
- fprintf (stderr, "\nbase:");
- debug_rtx (base);
- }
- }
- else
- return CR16_INVALID;
- break;
- default:
- return CR16_INVALID;
- }
- /* Now check if the operand 1 of operand 0 is const_int. */
- if (GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
- {
- disp = XEXP (XEXP (addr, 0), 1);
- if (debug_print)
- {
- fprintf (stderr, "\ndisp:");
- debug_rtx (disp);
- }
- if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
- return CR16_INVALID;
- }
- else
- return CR16_INVALID;
- retval = CR16_INDEX_REGP_REL;
- break;
- default:
- return CR16_INVALID;
- }
- break;
-
- default:
- return CR16_INVALID;
- }
-
- /* Check if the base and index registers are valid. */
- if (base && !(cr16_addr_reg_p (base)))
- return CR16_INVALID;
- if (base && !(CR16_REG_OK_FOR_BASE_P (base)))
- return CR16_INVALID;
- if (index && !(REG_OK_FOR_INDEX_P (index)))
- return CR16_INVALID;
-
- /* Write the decomposition to out parameter. */
- out->base = base;
- out->disp = disp;
- out->index = index;
- out->data = data;
- out->code = code;
-
- return retval;
-}
-
-/* Return non-zero value if 'x' is legitimate PIC operand
- when generating PIC code. */
-int
-legitimate_pic_operand_p (rtx x)
-{
- switch (GET_CODE (x))
- {
- case SYMBOL_REF:
- return 0;
- case LABEL_REF:
- return 0;
- case CONST:
- /* REVISIT: Use something like symbol_referenced_p. */
- if (GET_CODE (XEXP (x, 0)) == PLUS
- && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
- || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
- && (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
- return 0;
- break;
- case MEM:
- return legitimate_pic_operand_p (XEXP (x, 0));
- default:
- break;
- }
- return 1;
-}
-
-/* Convert a non-PIC address in `orig' to a PIC address in `reg'.
-
- Input Output (-f pic) Output (-f PIC)
- orig reg
-
- C1 symbol symbol@BRO (r12) symbol@GOT (r12)
-
- C2 symbol + offset symbol+offset@BRO (r12) symbol+offset@GOT (r12)
-
- NOTE: @BRO is added using unspec:BRO
- NOTE: @GOT is added using unspec:GOT. */
-rtx
-legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
- rtx reg)
-{
- /* First handle a simple SYMBOL_REF or LABEL_REF. */
- if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
- {
- if (reg == 0)
- reg = gen_reg_rtx (Pmode);
-
- if (flag_pic == NEAR_PIC)
- {
- /* Unspec to handle -fpic option. */
- emit_insn (gen_unspec_bro_addr (reg, orig));
- emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx));
- }
- else if (flag_pic == FAR_PIC)
- {
- /* Unspec to handle -fPIC option. */
- emit_insn (gen_unspec_got_addr (reg, orig));
- }
- return reg;
- }
- else if (GET_CODE (orig) == CONST)
- {
- /* To handle (symbol + offset). */
- rtx base, offset;
-
- if (GET_CODE (XEXP (orig, 0)) == PLUS
- && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
- return orig;
-
- if (reg == 0)
- {
- gcc_assert (can_create_pseudo_p ());
- reg = gen_reg_rtx (Pmode);
- }
-
- gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
-
- base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
- offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
- base == reg ? 0 : reg);
-
- /* REVISIT: Optimize for const-offsets. */
- emit_insn (gen_addsi3 (reg, base, offset));
-
- return reg;
- }
- return orig;
-}
-
-/* Implementation of TARGET_LEGITIMATE_ADDRESS_P. */
-static bool
-cr16_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
- rtx addr, bool strict)
-{
- enum cr16_addrtype addrtype;
- struct cr16_address address;
-
- if (TARGET_DEBUG_ADDR)
- {
- fprintf (stderr,
- "\n======\nTARGET_LEGITIMATE_ADDRESS_P, mode = %s, strict = %d",
- GET_MODE_NAME (mode), strict);
- debug_rtx (addr);
- }
- addrtype = cr16_decompose_address (addr, &address,
- (TARGET_DEBUG_ADDR ? 1 : 0), FALSE);
-
- if (TARGET_DEBUG_ADDR)
- {
- const char *typestr;
-
- switch (addrtype)
- {
- case CR16_INVALID:
- typestr = "invalid";
- break;
- case CR16_ABSOLUTE:
- typestr = "absolute";
- break;
- case CR16_REG_REL:
- typestr = "register relative";
- break;
- case CR16_REGP_REL:
- typestr = "register pair relative";
- break;
- case CR16_INDEX_REGP_REL:
- typestr = "index + register pair relative";
- break;
- default:
- gcc_unreachable ();
- }
- fprintf (stderr, "\ncr16 address type: %s\n", typestr);
- }
-
- if (addrtype == CR16_INVALID)
- return FALSE;
-
- if (strict)
- {
- if (address.base
- && !REGNO_MODE_OK_FOR_BASE_P (REGNO (address.base), mode))
- {
- if (TARGET_DEBUG_ADDR)
- fprintf (stderr, "base register not strict\n");
- return FALSE;
- }
- if (address.index && !REGNO_OK_FOR_INDEX_P (REGNO (address.index)))
- {
- if (TARGET_DEBUG_ADDR)
- fprintf (stderr, "index register not strict\n");
- return FALSE;
- }
- }
-
- /* Return true if addressing mode is register relative. */
- if (flag_pic)
- {
- if (addrtype == CR16_REG_REL || addrtype == CR16_REGP_REL)
- return TRUE;
- else
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Routines to compute costs. */
-
-/* Return cost of the memory address x. */
-static int
-cr16_address_cost (rtx addr, machine_mode mode ATTRIBUTE_UNUSED,
- addr_space_t as ATTRIBUTE_UNUSED,
- bool speed ATTRIBUTE_UNUSED)
-{
- enum cr16_addrtype addrtype;
- struct cr16_address address;
- int cost = 2;
-
- addrtype = cr16_decompose_address (addr, &address, 0, FALSE);
-
- gcc_assert (addrtype != CR16_INVALID);
-
- /* CR16_ABSOLUTE : 3
- CR16_REG_REL (disp !=0) : 4
- CR16_REG_REL (disp ==0) : 5
- CR16_REGP_REL (disp !=0) : 6
- CR16_REGP_REL (disp ==0) : 7
- CR16_INDEX_REGP_REL (disp !=0) : 8
- CR16_INDEX_REGP_REL (disp ==0) : 9. */
- switch (addrtype)
- {
- case CR16_ABSOLUTE:
- cost += 1;
- break;
- case CR16_REGP_REL:
- cost += 2;
- /* Fall through. */
- case CR16_REG_REL:
- cost += 3;
- if (address.disp)
- cost -= 1;
- break;
- case CR16_INDEX_REGP_REL:
- cost += 7;
- if (address.disp)
- cost -= 1;
- default:
- break;
- }
-
- if (TARGET_DEBUG_ADDR)
- {
- fprintf (stderr, "\n======\nmacro TARGET_ADDRESS_COST = %d\n", cost);
- debug_rtx (addr);
- }
-
- return cost;
-}
-
-
-/* Implement `TARGET_REGISTER_MOVE_COST'. */
-static int
-cr16_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
- reg_class_t from ATTRIBUTE_UNUSED, reg_class_t to)
-{
- return (to != GENERAL_REGS ? 8 : 2);
-}
-
-/* Implement `TARGET_MEMORY_MOVE_COST'. */
-
-/* Return the cost of moving data of mode MODE between a register of class
- CLASS and memory; IN is zero if the value is to be written to memory,
- nonzero if it is to be read in. This cost is relative to those in
- REGISTER_MOVE_COST. */
-static int
-cr16_memory_move_cost (machine_mode mode,
- reg_class_t rclass ATTRIBUTE_UNUSED,
- bool in ATTRIBUTE_UNUSED)
-{
- /* One LD or ST takes twice the time of a simple reg-reg move. */
- if (reg_classes_intersect_p (rclass, GENERAL_REGS))
- return (4 * cr16_hard_regno_nregs (0, mode));
- else
- return (100);
-}
-
-/* Instruction output. */
-
-/* Check if a const_double is ok for cr16 store-immediate instructions. */
-int
-cr16_const_double_ok (rtx op)
-{
- if (GET_MODE (op) == SFmode)
- {
- long l;
- REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op), l);
- return UNSIGNED_INT_FITS_N_BITS (l, 4) ? 1 : 0;
- }
-
- return ((UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op), 4)) &&
- (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op), 4))) ? 1 : 0;
-}
-
-/* Returns bit position of first 0 or 1 bit.
- It is safe to assume val as 16-bit wide. */
-int
-cr16_operand_bit_pos (int val, int bitval)
-{
- int i;
- if (bitval == 0)
- val = ~val;
-
- for (i = 0; i < 16; i++)
- if (val & (1 << i))
- break;
- return i;
-}
-
-/* Implements the macro PRINT_OPERAND defined in cr16.h. */
-static void
-cr16_print_operand (FILE * file, rtx x, int code)
-{
- int ptr_dereference = 0;
-
- switch (code)
- {
- case 'd':
- {
- const char *cr16_cmp_str;
- switch (GET_CODE (x))
- {
- /* MD: compare (reg, reg or imm) but CR16: cmp (reg or imm, reg)
- -> swap all non symmetric ops. */
- case EQ:
- cr16_cmp_str = "eq";
- break;
- case NE:
- cr16_cmp_str = "ne";
- break;
- case GT:
- cr16_cmp_str = "lt";
- break;
- case GTU:
- cr16_cmp_str = "lo";
- break;
- case LT:
- cr16_cmp_str = "gt";
- break;
- case LTU:
- cr16_cmp_str = "hi";
- break;
- case GE:
- cr16_cmp_str = "le";
- break;
- case GEU:
- cr16_cmp_str = "ls";
- break;
- case LE:
- cr16_cmp_str = "ge";
- break;
- case LEU:
- cr16_cmp_str = "hs";
- break;
- default:
- gcc_unreachable ();
- }
- fprintf (file, "%s", cr16_cmp_str);
- return;
- }
- case '$':
- putc ('$', file);
- return;
-
- case 'p':
- if (GET_CODE (x) == REG)
- {
- /* For Push instructions, we should not print register pairs. */
- fprintf (file, "%s", reg_names[REGNO (x)]);
- return;
- }
- break;
-
- case 'b':
- /* Print the immediate address for bal
- 'b' is used instead of 'a' to avoid compiler calling
- the GO_IF_LEGITIMATE_ADDRESS which cannot
- perform checks on const_int code addresses as it
- assumes all const_int are data addresses. */
- fprintf (file, "0x%lx", INTVAL (x));
- return;
-
- case 'r':
- /* Print bit position of first 0. */
- fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 0));
- return;
-
- case 's':
- /* Print bit position of first 1. */
- fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 1));
- return;
- case 'g':
- /* 'g' is used for implicit mem: dereference. */
- ptr_dereference = 1;
- /* FALLTHRU */
- case 'f':
- case 0:
- /* default. */
- switch (GET_CODE (x))
- {
- case REG:
- if (GET_MODE_BITSIZE (GET_MODE (x)) > BITS_PER_WORD)
- {
- if (LONG_REG_P (REGNO (x)))
- fprintf (file, "(%s)", reg_names[REGNO (x)]);
- else
- fprintf (file, "(%s,%s)", reg_names[REGNO (x) + 1],
- reg_names[REGNO (x)]);
- }
- else
- fprintf (file, "%s", reg_names[REGNO (x)]);
- return;
-
- case MEM:
- output_address (GET_MODE (x), XEXP (x, 0));
- return;
-
- case CONST_DOUBLE:
- {
- long l;
-
- REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
-
- fprintf (file, "$0x%lx", l);
- return;
- }
- case CONST_INT:
- {
- fprintf (file, "$%ld", INTVAL (x));
- return;
- }
- case UNSPEC:
- switch (XINT (x, 1))
- {
- default:
- gcc_unreachable ();
- }
- break;
-
- default:
- if (!ptr_dereference)
- {
- putc ('$', file);
- }
- cr16_print_operand_address (file, VOIDmode, x);
- return;
- }
- gcc_unreachable ();
- default:
- output_operand_lossage ("invalid %%xn code");
- }
-
- gcc_unreachable ();
-}
-
-/* Implements the macro PRINT_OPERAND_ADDRESS defined in cr16.h. */
-
-static void
-cr16_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr)
-{
- enum cr16_addrtype addrtype;
- struct cr16_address address;
-
- /* Decompose the address. Also ask it to treat address as constant. */
- addrtype = cr16_decompose_address (addr, &address, 0, TRUE);
-
- if (address.disp && GET_CODE (address.disp) == UNSPEC)
- {
- debug_rtx (addr);
- }
-
- switch (addrtype)
- {
- case CR16_REG_REL:
- if (address.disp)
- {
- if (GET_CODE (address.disp) == UNSPEC)
- cr16_print_operand (file, address.disp, 0);
- else
- output_addr_const (file, address.disp);
- }
- else
- fprintf (file, "0");
- fprintf (file, "(%s)", reg_names[REGNO (address.base)]);
- break;
-
- case CR16_ABSOLUTE:
- if (address.disp)
- output_addr_const (file, address.disp);
- else
- fprintf (file, "0");
- break;
-
- case CR16_INDEX_REGP_REL:
- fprintf (file, "[%s]", reg_names[REGNO (address.index)]);
- /* Fall through. */
- case CR16_REGP_REL:
- if (address.disp)
- {
- if (GET_CODE (address.disp) == UNSPEC)
- cr16_print_operand (file, address.disp, 0);
- else
- output_addr_const (file, address.disp);
- }
- else
- fprintf (file, "0");
- fprintf (file, "(%s,%s)", reg_names[REGNO (address.base) + 1],
- reg_names[REGNO (address.base)]);
- break;
- default:
- debug_rtx (addr);
- gcc_unreachable ();
- }
- /* Add qualifiers to the address expression that was just printed. */
- if (flag_pic < NEAR_PIC && address.code == 0)
- {
- if (address.data == DM_FAR)
- /* Addr contains SYMBOL_REF & far data ptr. */
- fprintf (file, "@l");
- else if (address.data == DM_DEFAULT)
- /* Addr contains SYMBOL_REF & medium data ptr. */
- fprintf (file, "@m");
- /* Addr contains SYMBOL_REF & medium data ptr. */
- else if (address.data == DM_NEAR)
- /* Addr contains SYMBOL_REF & near data ptr. */
- fprintf (file, "@s");
- }
- else if (flag_pic == NEAR_PIC
- && (address.code == 0) && (address.data == DM_FAR
- || address.data == DM_DEFAULT
- || address.data == DM_NEAR))
- {
- fprintf (file, "@l");
- }
- else if (flag_pic == NEAR_PIC && address.code == 2)
- {
- fprintf (file, "pic");
- }
- else if (flag_pic == NEAR_PIC && address.code == 1)
- {
- fprintf (file, "@cpic");
- }
-
- else if (flag_pic == FAR_PIC && address.code == 2)
- {
- /* REVISIT: cr16 register indirect jump expects a 1-bit right shifted
- address ! GOTc tells assembler this symbol is a text-address
- This needs to be fixed in such a way that this offset is done
- only in the case where an address is being used for indirect jump
- or call. Determining the potential usage of loadd is of course not
- possible always. Eventually, this has to be fixed in the
- processor. */
- fprintf (file, "GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
- }
- else if (flag_pic == FAR_PIC && address.code == 1)
- {
- fprintf (file, "@cGOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
- }
-
- else if (flag_pic == FAR_PIC &&
- (address.data == DM_FAR || address.data == DM_DEFAULT
- || address.data == DM_NEAR))
- {
- fprintf (file, "@GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
- }
-}
-
-/* Machine description helper functions. */
-
-/* Called from cr16.md. The return value depends on the parameter push_or_pop:
- When push_or_pop is zero -> string for push instructions of prologue.
- When push_or_pop is nonzero -> string for pop/popret/retx in epilogue.
- Relies on the assumptions:
- 1. RA is the last register to be saved.
- 2. The maximal value of the counter is MAX_COUNT. */
-char *
-cr16_prepare_push_pop_string (int push_or_pop)
-{
- /* j is the number of registers being saved, takes care that there won't be
- more than 8 in one push/pop instruction. */
-
- /* For the register mask string. */
- static char one_inst_str[50];
-
- /* i is the index of current_frame_info.save_regs[], going from 0 until
- current_frame_info.last_reg_to_save. */
- int i, start_reg;
- int word_cnt;
- int print_ra;
- char *return_str;
-
- /* For reversing on the push instructions if there are more than one. */
- char *temp_str;
-
- return_str = (char *) xmalloc (160);
- temp_str = (char *) xmalloc (160);
-
- /* Initialize. */
- memset (return_str, 0, 3);
-
- i = 0;
- while (i <= current_frame_info.last_reg_to_save)
- {
- /* Prepare mask for one instruction. */
- one_inst_str[0] = 0;
-
- /* To count number of words in one instruction. */
- word_cnt = 0;
- start_reg = i;
- print_ra = 0;
- while ((word_cnt < MAX_COUNT)
- && (i <= current_frame_info.last_reg_to_save))
- {
- /* For each non consecutive save register,
- a new instruction shall be generated. */
- if (!current_frame_info.save_regs[i])
- {
- /* Move to next reg and break. */
- ++i;
- break;
- }
-
- if (i == RETURN_ADDRESS_REGNUM)
- print_ra = 1;
- else
- {
- /* Check especially if adding 2 does not cross the MAX_COUNT. */
- if ((word_cnt + ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2))
- >= MAX_COUNT)
- break;
- /* Increase word count by 2 for long registers except RA. */
- word_cnt += ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2);
- }
- ++i;
- }
-
- /* No need to generate any instruction as
- no register or RA needs to be saved. */
- if ((word_cnt == 0) && (print_ra == 0))
- continue;
-
- /* Now prepare the instruction operands. */
- if (word_cnt > 0)
- {
- sprintf (one_inst_str, "$%d, %s", word_cnt, reg_names[start_reg]);
- if (print_ra)
- strcat (one_inst_str, ", ra");
- }
- else
- strcat (one_inst_str, "ra");
-
- if (push_or_pop == 1)
- {
- /* Pop instruction. */
- if (print_ra && !cr16_interrupt_function_p ()
- && !crtl->calls_eh_return)
- /* Print popret if RA is saved and its not a interrupt
- function. */
- strcpy (temp_str, "\n\tpopret\t");
- else
- strcpy (temp_str, "\n\tpop\t");
-
- strcat (temp_str, one_inst_str);
-
- /* Add the pop instruction list. */
- strcat (return_str, temp_str);
- }
- else
- {
- /* Push instruction. */
- strcpy (temp_str, "\n\tpush\t");
- strcat (temp_str, one_inst_str);
-
- /* We need to reverse the order of the instructions if there
- are more than one. (since the pop will not be reversed in
- the epilogue. */
- strcat (temp_str, return_str);
- strcpy (return_str, temp_str);
- }
- }
-
- if (push_or_pop == 1)
- {
- /* POP. */
- if (cr16_interrupt_function_p ())
- strcat (return_str, "\n\tretx\n");
- else if (crtl->calls_eh_return)
- {
- /* Add stack adjustment before returning to exception handler
- NOTE: EH_RETURN_STACKADJ_RTX must refer to (r5, r4). */
- strcat (return_str, "\n\taddd\t (r5, r4), (sp)\t\n");
- strcat (return_str, "\n\tjump\t (ra)\n");
-
- /* But before anything else, undo the adjustment addition done in
- cr16_expand_epilogue (). */
- strcpy (temp_str, "\n\tsubd\t (r5, r4), (sp)\t\n");
- strcat (temp_str, return_str);
- strcpy (return_str, temp_str);
- }
- else if (!FUNC_IS_NORETURN_P (current_function_decl)
- && !(current_frame_info.save_regs[RETURN_ADDRESS_REGNUM]))
- strcat (return_str, "\n\tjump\t (ra)\n");
- }
-
- /* Skip the newline and the tab in the start of return_str. */
- return_str += 2;
- return return_str;
-}
-
-
-/* Generate DWARF2 annotation for multi-push instruction. */
-static void
-cr16_create_dwarf_for_multi_push (rtx insn)
-{
- rtx dwarf, reg, tmp;
- int i, j, from, to, word_cnt, dwarf_par_index, inc;
- machine_mode mode;
- int num_regs = 0, offset = 0, split_here = 0, total_push_bytes = 0;
-
- for (i = 0; i <= current_frame_info.last_reg_to_save; ++i)
- {
- if (current_frame_info.save_regs[i])
- {
- ++num_regs;
- if (i < CR16_FIRST_DWORD_REGISTER)
- total_push_bytes += 2;
- else
- total_push_bytes += 4;
- }
- }
-
- if (!num_regs)
- return;
-
- dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1));
- dwarf_par_index = num_regs;
-
- from = current_frame_info.last_reg_to_save + 1;
- to = current_frame_info.last_reg_to_save;
- word_cnt = 0;
-
- for (i = current_frame_info.last_reg_to_save; i >= 0;)
- {
- if (!current_frame_info.save_regs[i] || i == 0 || split_here)
- {
- /* This block of regs is pushed in one instruction. */
- if (i == 0 && current_frame_info.save_regs[i])
- from = 0;
-
- for (j = to; j >= from; --j)
- {
- if (j < CR16_FIRST_DWORD_REGISTER)
- {
- mode = HImode;
- inc = 1;
- }
- else
- {
- mode = SImode;
- inc = 2;
- }
- reg = gen_rtx_REG (mode, j);
- offset += 2 * inc;
- tmp = gen_rtx_SET (gen_frame_mem (mode,
- plus_constant
- (Pmode, stack_pointer_rtx,
- total_push_bytes - offset)),
- reg);
- RTX_FRAME_RELATED_P (tmp) = 1;
- XVECEXP (dwarf, 0, dwarf_par_index--) = tmp;
- }
- from = i;
- to = --i;
- split_here = 0;
- word_cnt = 0;
- continue;
- }
-
- if (i != RETURN_ADDRESS_REGNUM)
- {
- inc = (i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2;
- if (word_cnt + inc >= MAX_COUNT || FRAME_POINTER_REGNUM == i)
- {
- split_here = 1;
- from = i;
- continue;
- }
- word_cnt += inc;
- }
-
- from = i--;
- }
-
- tmp = gen_rtx_SET (stack_pointer_rtx,
- gen_rtx_PLUS (SImode, stack_pointer_rtx,
- GEN_INT (-offset)));
- RTX_FRAME_RELATED_P (tmp) = 1;
- XVECEXP (dwarf, 0, 0) = tmp;
-
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
-}
-
-/*
-CompactRISC CR16 Architecture stack layout:
-
- 0 +---------------------
- |
- .
- .
- |
- +==================== Sp (x) = Ap (x+1)
- A | Args for functions
- | | called by X and Dynamically
- | | Dynamic allocations allocated and
- | | (alloca, variable deallocated
- Stack | length arrays).
- grows +-------------------- Fp (x)
- down| | Local variables of X
- ward| +--------------------
- | | Regs saved for X-1
- | +==================== Sp (x-1) = Ap (x)
- | Args for func X
- | pushed by X-1
- +-------------------- Fp (x-1)
- |
- |
- V
-*/
-void
-cr16_expand_prologue (void)
-{
- rtx insn;
-
- cr16_compute_frame ();
- cr16_compute_save_regs ();
-
- /* If there is no need in push and adjustment to sp, return. */
- if ((current_frame_info.total_size + current_frame_info.reg_size) == 0)
- return;
-
- if (current_frame_info.last_reg_to_save != -1)
- {
- /* If there are registers to push. */
- insn = emit_insn (gen_push_for_prologue
- (GEN_INT (current_frame_info.reg_size)));
- cr16_create_dwarf_for_multi_push (insn);
- RTX_FRAME_RELATED_P (insn) = 1;
- }
-
-
- if (current_frame_info.total_size > 0)
- {
- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (-current_frame_info.total_size)));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
-
- if (frame_pointer_needed)
- {
- /* Initialize the frame pointer with the value of the stack pointer
- pointing now to the locals. */
- insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
- }
-}
-
-/* Generate insn that updates the stack for local variables and padding
- for registers we save. - Generate the appropriate return insn. */
-void
-cr16_expand_epilogue (void)
-{
- rtx insn;
-
- /* Nonzero if we need to return and pop only RA. This will generate a
- different insn. This differentiate is for the peepholes for call as
- last statement in function. */
- int only_popret_RA = (current_frame_info.save_regs[RETURN_ADDRESS_REGNUM]
- && (current_frame_info.reg_size
- == CR16_UNITS_PER_DWORD));
-
- if (frame_pointer_needed)
- {
- /* Restore the stack pointer with the frame pointers value. */
- insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
- }
-
- if (current_frame_info.total_size > 0)
- {
- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (current_frame_info.total_size)));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
-
- if (crtl->calls_eh_return)
- {
- /* Add this here so that (r5, r4) is actually loaded with the adjustment
- value; otherwise, the load might be optimized away...
- NOTE: remember to subtract the adjustment before popping the regs
- and add it back before returning. */
- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- EH_RETURN_STACKADJ_RTX));
- }
-
- if (cr16_interrupt_function_p ())
- {
- insn = emit_jump_insn (gen_interrupt_return ());
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- else if (crtl->calls_eh_return)
- {
- /* Special case, pop what's necessary, adjust SP and jump to (RA). */
- insn = emit_jump_insn (gen_pop_and_popret_return
- (GEN_INT (current_frame_info.reg_size)));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- else if (current_frame_info.last_reg_to_save == -1)
- /* Nothing to pop. */
- /* Don't output jump for interrupt routine, only retx. */
- emit_jump_insn (gen_jump_return ());
- else if (only_popret_RA)
- {
- insn = emit_jump_insn (gen_popret_RA_return ());
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- else
- {
- insn = emit_jump_insn (gen_pop_and_popret_return
- (GEN_INT (current_frame_info.reg_size)));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
-}
-
-/* Implements FRAME_POINTER_REQUIRED. */
-static bool
-cr16_frame_pointer_required (void)
-{
- return (cfun->calls_alloca || crtl->calls_eh_return
- || cfun->has_nonlocal_label || crtl->calls_eh_return);
-}
-
-static bool
-cr16_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
-{
- return (to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true);
-}
-
-
-/* A C compound statement that attempts to replace X with
- a valid memory address for an operand of mode MODE. WIN
- will be a C statement label elsewhere in the code.
- X will always be the result of a call to break_out_memory_refs (),
- and OLDX will be the operand that was given to that function to
- produce X.
- The code generated by this macro should not alter the
- substructure of X. If it transforms X into a more legitimate form,
- it should assign X (which will always be a C variable) a new value. */
-static rtx
-cr16_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED)
-{
- if (flag_pic)
- return legitimize_pic_address (orig_x, mode, NULL_RTX);
- else
- return x;
-}
-
-/* Implement TARGET_LEGITIMATE_CONSTANT_P
- Nonzero if X is a legitimate constant for an immediate
- operand on the target machine. You can assume that X
- satisfies CONSTANT_P. In cr16c treat legitimize float
- constant as an immediate operand. */
-static bool
-cr16_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED,
- rtx x ATTRIBUTE_UNUSED)
-{
- return 1;
-}
-
-static scalar_int_mode
-cr16_unwind_word_mode (void)
-{
- return SImode;
-}
-
-/* Helper function for md file. This function is used to emit arithmetic
- DI instructions. The argument "num" decides which instruction to be
- printed. */
-const char *
-cr16_emit_add_sub_di (rtx *operands, enum rtx_code code)
-{
- rtx lo_op[2] ;
- rtx hi0_op[2] ;
- rtx hi1_op[2] ;
-
- lo_op[0] = gen_lowpart (SImode, operands[0]);
- hi0_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 4);
- hi1_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 6);
-
- lo_op[1] = gen_lowpart (SImode, operands[2]);
- hi0_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 4);
- hi1_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 6);
-
- switch (code)
- {
- case PLUS:
- {
- output_asm_insn ("addd\t%1, %0", lo_op) ;
- output_asm_insn ("addcw\t%1, %0", hi0_op) ;
- output_asm_insn ("addcw\t%1, %0", hi1_op) ;
- break;
- }
- case MINUS:
- {
- output_asm_insn ("subd\t%1, %0", lo_op) ;
- output_asm_insn ("subcw\t%1, %0", hi0_op) ;
- output_asm_insn ("subcw\t%1, %0", hi1_op) ;
- break;
- }
- default:
- break;
- }
-
- return "";
-}
-
-
-/* Helper function for md file. This function is used to emit logical
- DI instructions. The argument "num" decides which instruction to be
- printed. */
-const char *
-cr16_emit_logical_di (rtx *operands, enum rtx_code code)
-{
- rtx lo_op[2] ;
- rtx hi_op[2] ;
-
- lo_op[0] = gen_lowpart (SImode, operands[0]);
- hi_op[0] = simplify_gen_subreg (SImode, operands[0], DImode, 4);
-
- lo_op[1] = gen_lowpart (SImode, operands[2]);
- hi_op[1] = simplify_gen_subreg (SImode, operands[2], DImode, 4);
-
- switch (code)
- {
- case AND:
- {
- output_asm_insn ("andd\t%1, %0", lo_op) ;
- output_asm_insn ("andd\t%1, %0", hi_op) ;
- return "";
- }
- case IOR:
- {
- output_asm_insn ("ord\t%1, %0", lo_op) ;
- output_asm_insn ("ord\t%1, %0", hi_op) ;
- return "";
- }
- case XOR:
- {
- output_asm_insn ("xord\t%1, %0", lo_op) ;
- output_asm_insn ("xord\t%1, %0", hi_op) ;
- return "";
- }
- default:
- break;
- }
-
- return "";
-}
-
-/* Implement PUSH_ROUNDING. */
-
-poly_int64
-cr16_push_rounding (poly_int64 bytes)
-{
- return (bytes + 1) & ~1;
-}
-
-/* Initialize 'targetm' variable which contains pointers to functions
- and data relating to the target machine. */
-
-struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/cr16/cr16.h b/gcc/config/cr16/cr16.h
deleted file mode 100644
index 100bb4f..0000000
--- a/gcc/config/cr16/cr16.h
+++ /dev/null
@@ -1,556 +0,0 @@
-/* Definitions of target machine for GNU compiler, for CR16.
- Copyright (C) 2012-2022 Free Software Foundation, Inc.
- Contributed by KPIT Cummins Infosystems Limited.
-
- This file is part of GCC.
-
- GCC is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GCC is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
-
-#ifndef GCC_CR16_H
-#define GCC_CR16_H
-
-#define OBJECT_FORMAT_ELF
-
-/* Controlling the driver. */
-
-/* The GNU C++ standard library requires that these macros be defined. */
-#undef CPLUSPLUS_CPP_SPEC
-#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC "crt1.o%s crti.o%s crtbegin.o%s crtlibid.o%s"
-
-#undef ENDFILE_SPEC
-#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
-
-#undef MATH_LIBRARY
-#define MATH_LIBRARY ""
-
-#undef LIB_SPEC
-#define LIB_SPEC "-( -lc %{msim*:-lsim}%{!msim*:-lnosys} -) \
-%{msim*:%{!T*:-Tsim.ld}} \
-%{!T*:%{!msim*: %{-Telf32cr16.x}}}"
-
-/* Run-time target specification. */
-#ifndef TARGET_CPU_CPP_BUILTINS
-#define TARGET_CPU_CPP_BUILTINS() \
-do \
- { \
- builtin_define ("__CR__"); \
- builtin_define ("__CR16__"); \
- builtin_define ("__CR16C__"); \
- if (TARGET_CR16CP) \
- builtin_define ("__CR16CP__"); \
- else \
- builtin_define ("__CR16CSTD__"); \
- if (CR16_TARGET_DATA_NEAR) \
- builtin_define ("__DATA_NEAR__"); \
- if (CR16_TARGET_DATA_MEDIUM) \
- builtin_define ("__DATA_MEDIUM__"); \
- if (CR16_TARGET_DATA_FAR) \
- builtin_define ("__DATA_FAR__"); \
- if (TARGET_INT32) \
- builtin_define ("__INT32__"); \
- } \
-while (0)
-#endif
-
-/* Force the generation of dwarf .debug_frame sections even if not
- compiling -g. This guarantees that we can unwind the stack. */
-#define DWARF2_FRAME_INFO 1
-
-#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-
-/* Generate .file/.loc directives, so that the assembler generates the
- line table. */
-#define DWARF2_ASM_LINE_DEBUG_INFO 1
-
-#define CR16_TARGET_DATA_NEAR cr16_is_data_model (DM_NEAR)
-#define CR16_TARGET_DATA_MEDIUM cr16_is_data_model (DM_DEFAULT)
-#define CR16_TARGET_DATA_FAR cr16_is_data_model (DM_FAR)
-
-/* Storage layout. */
-#define BITS_BIG_ENDIAN 0
-
-#define BYTES_BIG_ENDIAN 0
-
-#define WORDS_BIG_ENDIAN 0
-
-#define UNITS_PER_WORD 2
-
-/* Units per 32-bit (DWORD). */
-#define CR16_UNITS_PER_DWORD 4
-
-#define POINTER_SIZE 32
-
-#define PARM_BOUNDARY 16
-
-#define STACK_BOUNDARY (MAX (BIGGEST_ALIGNMENT, PARM_BOUNDARY))
-
-#define FUNCTION_BOUNDARY BIGGEST_ALIGNMENT
-
-/* Biggest alignment on CR16C+ is 32-bit as internal bus is AMBA based
- where as CR16C is proprietary internal bus architecture. */
-#define BIGGEST_ALIGNMENT ((TARGET_CR16CP) ? 32 : 16)
-
-#define MAX_FIXED_MODE_SIZE 64
-
-/* In CR16 arrays of chars are word-aligned, so strcpy () will be faster. */
-#define DATA_ALIGNMENT(TYPE, ALIGN) \
- (((TREE_CODE (TYPE) == ARRAY_TYPE) \
- && (TYPE_MODE (TREE_TYPE (TYPE)) == QImode) \
- && ((ALIGN) < BITS_PER_WORD)) \
- ? (BITS_PER_WORD) : (ALIGN))
-
-#define STRICT_ALIGNMENT 0
-
-#define PCC_BITFIELD_TYPE_MATTERS 1
-
-/* Layout of source language data types. */
-#define INT_TYPE_SIZE (TARGET_INT32 ? 32 : 16)
-
-#define SHORT_TYPE_SIZE 16
-
-#define LONG_TYPE_SIZE 32
-
-#define LONG_LONG_TYPE_SIZE 64
-
-#define FLOAT_TYPE_SIZE 32
-
-#define DOUBLE_TYPE_SIZE 64
-
-#define LONG_DOUBLE_TYPE_SIZE 64
-
-#define DEFAULT_SIGNED_CHAR 1
-
-#define SIZE_TYPE "long unsigned int"
-
-#define PTRDIFF_TYPE "long int"
-
-#define WCHAR_TYPE "short unsigned int"
-
-#define WCHAR_TYPE_SIZE 16
-
-/* By default, the C++ compiler will use the lowest bit of the pointer
- to function to indicate a pointer-to-member-function points to a
- virtual member function. However, in CR architecture FUNCTION_BOUNDARY
- indicates function addresses are always even, but function pointers can be
- odd (after right-shifting them when loading them into a register), and the
- default doesn't work. In that case, the lowest bit of the delta
- field will be used (the remainder of the field is shifted to the left). */
-#define TARGET_PTRMEMFUNC_VBIT_LOCATION ptrmemfunc_vbit_in_delta
-
-/* Define DEFAULT_PCC_STRUCT_RETURN to 1 if all structure and union return
- values must be in memory. */
-#define DEFAULT_PCC_STRUCT_RETURN 0
-
-/* Register usage. */
-
-/* First 32-bit register is R12. */
-#define CR16_FIRST_DWORD_REGISTER 12
-
-#define FIRST_PSEUDO_REGISTER 16
-
-/* 1 for registers that have pervasive standard uses
- and are not available for the register allocator.
- On the CR16, only the stack pointer (r15) is such. */
-#define FIXED_REGISTERS \
- { \
- /* r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10. */ \
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- /* r11 r12 r13 ra sp. */ \
- 0, 0, 0, 0, 1 \
- }
-
-/* 1 for registers not available across function calls.
- These must include the FIXED_REGISTERS and also any
- registers that can be used without being saved.
- The latter must include the registers where values are returned
- and the register where structure-value addresses are passed.
-
- On the CR16, calls clobbers r0-r6 (scratch registers),
- ra (the return address) and sp (the stack pointer). */
-#define CALL_USED_REGISTERS \
- { \
- /* r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10. */ \
- 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, \
- /* r11 r12 r13 ra sp. */ \
- 0, 0, 0, 1, 1 \
- }
-
-/* Returns 1 if the register is longer than word size, 0 otherwise. */
-#define LONG_REG_P(REGNO) \
- (targetm.hard_regno_nregs (REGNO, \
- GET_MODE_WIDER_MODE (word_mode).require ()) == 1)
-
-/* Interrupt functions can only use registers that have already been
- saved by the prologue, even if they would normally be call-clobbered
- Check if sizes are same and then check if it is possible to rename. */
-#define HARD_REGNO_RENAME_OK(SRC, DEST) \
- (!cr16_interrupt_function_p () || (df_regs_ever_live_p (DEST)))
-
-/* Exception handling stuff. */
-
-/*To ensure correct dwarf unwinding. */
-#define LIBGCC2_UNWIND_ATTRIBUTE __attribute__((optimize ("no-gcse","no-dse")))
-
-#define gen_rtx_RA gen_rtx_REG (Pmode, RETURN_ADDRESS_REGNUM)
-
-/* Use (r8,r7) and (r10,r9) to pass exception handling information. */
-#define EH_RETURN_DATA_REGNO(N) (((N) < 2) ? (N*2 + 7) : INVALID_REGNUM)
-
-#define DWARF2_UNWIND_INFO 1
-
-/* (r5,r4) holds a stack adjustment for returning to a handler. */
-#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 4)
-
-#define EH_RETURN_HANDLER_RTX \
- gen_rtx_MEM (Pmode, plus_constant (Pmode, arg_pointer_rtx, -4))
-
-#define INCOMING_RETURN_ADDR_RTX gen_rtx_RA
-
-#define DWARF_FRAME_RETURN_COLUMN \
- DWARF_FRAME_REGNUM (RETURN_ADDRESS_REGNUM)
-
-#define INCOMING_FRAME_SP_OFFSET 0
-#define FRAME_POINTER_CFA_OFFSET(FNDECL) 0
-
-/* A C expression whose value is RTL representing the value of the return
- address for the frame COUNT steps up from the current frame. */
-#define RETURN_ADDR_RTX(COUNT, FRAME) \
- (COUNT == 0) ? gen_rtx_PLUS (Pmode, gen_rtx_RA, gen_rtx_RA) \
- : const0_rtx
-
-enum reg_class
-{
- NO_REGS,
- SHORT_REGS,
- LONG_REGS,
- NOSP_REGS,
- DOUBLE_BASE_REGS,
- GENERAL_REGS,
- ALL_REGS,
- LIM_REG_CLASSES
-};
-
-#define N_REG_CLASSES (int) LIM_REG_CLASSES
-
-#define REG_CLASS_NAMES \
- { \
- "NO_REGS", \
- "SHORT_REGS", \
- "LONG_REGS", \
- "NOSP_REGS", \
- "DOUBLE_BASE_REGS", \
- "GENERAL_REGS", \
- "ALL_REGS" \
- }
-
-#define REG_CLASS_CONTENTS \
- { \
- {0x00000000}, /* NO_REGS */ \
- {0x00000FFF}, /* SHORT_REGS : 0 - 11 */ \
- {0x0000F000}, /* LONG_REGS : 12 - 15 */ \
- {0x00007FFF}, /* NOSP_REGS : 0 - 14 */ \
- {0x0000F555}, /* DOUBLE_BASE_REGS : 2,4,6,8,10 */ \
- {0x0000FFFF}, /* GENERAL_REGS : 0 - 15 */ \
- {0x0000FFFF} /* ALL_REGS : 0 - 15 */ \
- }
-
-#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
-
-#define REGNO_REG_CLASS(REGNO) cr16_regno_reg_class (REGNO)
-
-#define BASE_REG_CLASS GENERAL_REGS
-
-#define MODE_BASE_REG_CLASS(MODE) \
- (GET_MODE_SIZE (MODE) <= 4 ? (BASE_REG_CLASS) : (DOUBLE_BASE_REGS))
-
-#define INDEX_REG_CLASS LONG_REGS
-
-#define CR16_REGNO_OK_FOR_BASE_P(REGNO) \
- (((REGNO) < FIRST_PSEUDO_REGISTER) \
- || (reg_renumber && ((unsigned) reg_renumber[REGNO] \
- < FIRST_PSEUDO_REGISTER)))
-
-/* Use even-numbered reg for 64-bit accesses. */
-#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
- (CR16_REGNO_OK_FOR_BASE_P(REGNO) && \
- ((GET_MODE_SIZE (MODE) > 4 && \
- (REGNO) < CR16_FIRST_DWORD_REGISTER) \
- ? (((REGNO) & 1) == 0) \
- : 1))
-
-/* TODO: For now lets not support index addressing mode. */
-#define REGNO_OK_FOR_INDEX_P(REGNO) \
- (((REGNO >= CR16_FIRST_DWORD_REGISTER) \
- && ((REGNO) < FIRST_PSEUDO_REGISTER)) \
- || (reg_renumber \
- && (((unsigned) reg_renumber[REGNO] >= CR16_FIRST_DWORD_REGISTER) \
- && ((unsigned) reg_renumber[REGNO] < FIRST_PSEUDO_REGISTER))) \
- )
-
-#define PREFERRED_RELOAD_CLASS(X, CLASS) CLASS
-
-/* The maximum number of consecutive registers of class CLASS needed to
- hold a value of mode MODE.
- On the CompactRISC architecture, the size of MODE in words.
- The size of MODE in double words for the class LONG_REGS.
-
- The following check assumes if the class is not LONG_REGS, then
- all (NO_REGS, SHORT_REGS, NOSP_REGS and GENERAL_REGS) other classes are
- short. We may have to check if this can cause any degradation in
- performance. */
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- (CLASS == LONG_REGS \
- ? (GET_MODE_SIZE (MODE) + CR16_UNITS_PER_DWORD - 1) / CR16_UNITS_PER_DWORD\
- : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
-/* Macros to check the range of integers . These macros were used across
- the port, majorly in constraints.md, predicates.md files. */
-#define SIGNED_INT_FITS_N_BITS(imm, N) \
- ((((imm) < ((HOST_WIDE_INT) 1 << ((N) - 1))) \
- && ((imm) >= -((HOST_WIDE_INT) 1 << ((N) - 1)))) ? 1 : 0)
-
-#define UNSIGNED_INT_FITS_N_BITS(imm, N) \
- (((imm) < ((HOST_WIDE_INT) 1 << (N)) && (imm) >= (HOST_WIDE_INT) 0) ? 1 : 0)
-
-#define IN_RANGE_P(VALUE, LOW, HIGH) \
- ((((HOST_WIDE_INT)(VALUE)) >= (HOST_WIDE_INT)(LOW)) \
- && (((HOST_WIDE_INT)(VALUE)) <= ((HOST_WIDE_INT)(HIGH))))
-
-#define IN_RAN(VALUE, LOW, HIGH) \
- (((((HOST_WIDE_INT)(VALUE)) >= (HOST_WIDE_INT)(LOW)) \
- && (((HOST_WIDE_INT)(VALUE)) <= ((HOST_WIDE_INT)(HIGH)))) ? 1 : 0)
-
-/* This check is for sbit/cbit instruction. */
-#define OK_FOR_Z(OP) \
- ((GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == CONST_INT) \
- || (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG) \
- || (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == PLUS \
- && GET_CODE (XEXP ((XEXP (OP, 0)), 0)) == REG \
- && GET_CODE (XEXP ((XEXP (OP, 0)), 1)) == CONST_INT))
-
-/* Stack layout and calling conventions. */
-#define STACK_GROWS_DOWNWARD 1
-
-#define STACK_POINTER_REGNUM 15
-
-#define FRAME_POINTER_REGNUM 13
-
-#define ARG_POINTER_REGNUM 12
-
-#define STATIC_CHAIN_REGNUM 1
-
-#define RETURN_ADDRESS_REGNUM 14
-
-#define FIRST_PARM_OFFSET(FNDECL) 0
-
-#define ELIMINABLE_REGS \
- { \
- { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
- { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
- { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
- }
-
-#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
- do \
- { \
- (OFFSET) = cr16_initial_elimination_offset ((FROM), (TO)); \
- } \
- while (0)
-
-/* Passing function arguments. */
-
-#define ACCUMULATE_OUTGOING_ARGS 0
-
-#define PUSH_ROUNDING(BYTES) cr16_push_rounding (BYTES)
-
-#ifndef CUMULATIVE_ARGS
-struct cumulative_args
-{
- int ints;
- int last_parm_in_reg;
-};
-
-#define CUMULATIVE_ARGS struct cumulative_args
-#endif
-
-/* On the CR16 architecture, Varargs routines should receive their parameters
- on the stack. */
-
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
- cr16_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME))
-
-#define FUNCTION_ARG_REGNO_P(REGNO) cr16_function_arg_regno_p (REGNO)
-
-/* Generating code for profiling - NOT IMPLEMENTED. */
-#undef FUNCTION_PROFILER
-#define FUNCTION_PROFILER(STREAM, LABELNO) \
-{ \
- sorry ("profiler support for CR16"); \
-}
-
-/* Trampolines for nested functions - NOT SUPPORTED. */
-#define TRAMPOLINE_SIZE 16
-
-/* ADDRESSING MODES. */
-
-#define CONSTANT_ADDRESS_P(X) \
- (GET_CODE (X) == LABEL_REF \
- || GET_CODE (X) == SYMBOL_REF \
- || GET_CODE (X) == CONST \
- || GET_CODE (X) == CONST_INT)
-
-#define MAX_REGS_PER_ADDRESS 2
-
-#define HAVE_POST_INCREMENT 0
-#define HAVE_POST_DECREMENT 0
-#define HAVE_POST_MODIFY_DISP 0
-#define HAVE_POST_MODIFY_REG 0
-
-#ifdef REG_OK_STRICT
-#define CR16_REG_OK_FOR_BASE_P(X) CR16_REGNO_OK_FOR_BASE_P (REGNO (X))
-#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
- REGNO_MODE_OK_FOR_BASE_P (REGNO(X), MODE)
-#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
-#else /* not REG_OK_STRICT. */
-#define CR16_REG_OK_FOR_BASE_P(X) 1
-#define REG_MODE_OK_FOR_BASE_P(X, MODE) 1
-#define REG_OK_FOR_INDEX_P(X) 1
-#endif /* not REG_OK_STRICT. */
-
-/* Assume best case (branch predicted). */
-#define BRANCH_COST(speed_p, predictable_p) 2
-
-#define SLOW_BYTE_ACCESS 1
-
-/* It is as good or better to call a constant function address than to
- call an address kept in a register. */
-#define NO_FUNCTION_CSE 1
-
-/* Dividing the output into sections. */
-
-#define TEXT_SECTION_ASM_OP "\t.section\t.text"
-
-#define DATA_SECTION_ASM_OP "\t.section\t.data"
-
-#define BSS_SECTION_ASM_OP "\t.section\t.bss"
-
-/* Position independent code (PIC). */
-/* NEAR_PIC for -fpic option. */
-
-#define NEAR_PIC 1
-
-/* FAR_PIC for -fPIC option. */
-
-#define FAR_PIC 2
-
-#define PIC_OFFSET_TABLE_REGNUM 12
-
-#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
-
-/* Assembler format. */
-
-/* Character to start a comment. */
-#define ASM_COMMENT_START "#"
-
-#define GLOBAL_ASM_OP "\t.globl\t"
-
-#undef USER_LABEL_PREFIX
-#define USER_LABEL_PREFIX "_"
-
-#undef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
- asm_fprintf (STREAM, "%U%s", (*targetm.strip_name_encoding) (NAME))
-
-#define ASM_OUTPUT_SYMBOL_REF(STREAM, SYMBOL) \
- do \
- { \
- const char *rn = XSTR (SYMBOL, 0); \
- assemble_name (STREAM, rn); \
- if (SYMBOL_REF_FUNCTION_P (SYMBOL)) \
- { \
- fprintf ((STREAM), "@c"); \
- } \
- } \
- while (0)
-
-#undef ASM_APP_ON
-#define ASM_APP_ON "#APP\n"
-
-#undef ASM_APP_OFF
-#define ASM_APP_OFF "#NO_APP\n"
-
-/* Switch into a generic section. */
-#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
-
-#undef INIT_SECTION_ASM_OP
-#define INIT_SECTION_ASM_OP "\t.section\t.init"
-
-#undef FINI_SECTION_ASM_OP
-#define FINI_SECTION_ASM_OP "\t.section\t.fini"
-
-/* Instruction output. */
-
-#define REGISTER_NAMES \
- { \
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
- "r8", "r9", "r10", "r11", "r12", "r13", "ra", "sp" \
- }
-
-/* Output of dispatch tables. */
-
-/* Revisit. No PC relative case as label expressions are not
- properly supported in binutils else we could have done this:
- #define CASE_VECTOR_PC_RELATIVE (optimize_size ? 1 : 0). */
-#define CASE_VECTOR_PC_RELATIVE 0
-
-#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
- ((GET_MODE (BODY) == QImode) \
- ? fprintf ((FILE), "\t.byte (.L%d-.L%d) >> 1\n", \
- VALUE, REL) \
- : fprintf ((FILE), "\t.word (.L%d-.L%d) >> 1\n", \
- VALUE, REL))
-
-#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
- asm_fprintf ((STREAM), "\t.long\t.L%d@c\n", (VALUE))
-
-/* Alignment in assembler file. */
-
-#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
- asm_fprintf ((STREAM), "\t.align\t%d\n", 1 << (POWER))
-
-/* Miscellaneous parameters. */
-
-#define CASE_VECTOR_MODE Pmode
-
-#define MOVE_MAX 4
-
-#define STORE_FLAG_VALUE 1
-
-#define Pmode SImode
-
-#define FUNCTION_MODE QImode
-
-/* Define this boolean macro(s) to indicate whether or not your architecture
- has (un)conditional branches that can span all of memory. It is used in
- conjunction with an optimization that partitions hot and cold basic blocks
- into separate sections of the executable.
- CR16 contains branch instructions that span whole address space. */
-#define HAS_LONG_COND_BRANCH 1
-#define HAS_LONG_UNCOND_BRANCH 1
-
-#endif /* End of GCC_CR16_H. */
diff --git a/gcc/config/cr16/cr16.md b/gcc/config/cr16/cr16.md
deleted file mode 100644
index 7ec7468..0000000
--- a/gcc/config/cr16/cr16.md
+++ /dev/null
@@ -1,1084 +0,0 @@
-;; GCC machine description for CR16.
-;; Copyright (C) 2012-2022 Free Software Foundation, Inc.
-;; Contributed by KPIT Cummins Infosystems Limited.
-
-;; This file is part of GCC.
-
-;; GCC is free software; you can redistribute it and/or modify it
-;; under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-
-;; GCC is distributed in the hope that it will be useful, but WITHOUT
-;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-;; License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GCC; see the file COPYING3. If not see
-;; <http://www.gnu.org/licenses/>.
-
-;; Register numbers
-(define_constants
- [(SP_REGNUM 15); Stack pointer
- (RA_REGNUM 14); Return address
- ]
-)
-
-;; Predicates & Constraints
-(include "predicates.md")
-(include "constraints.md")
-
-;; UNSPEC usage
-(define_constants
- [(UNSPEC_PIC_ADDR 0)
- (UNSPEC_PIC_LOAD_ADDR 1)
- (UNSPEC_LIBRARY_OFFSET 2)
- (UNSPEC_SH_LIB_PUSH_R12 3)
- (UNSPEC_SH_LIB_POP_R12 4)
- (UNSPEC_RETURN_ADDR 5)
- ]
-)
-
-;; Attributes
-(define_attr "length" "" (const_int 2))
-
-(define_asm_attributes
- [(set_attr "length" "2")]
-)
-
-;; Mode Macro Definitions
-(define_mode_iterator CR16IM [QI HI SI])
-(define_mode_iterator LONG [SI SF])
-(define_mode_iterator ALLMTD [QI HI SI SF DI DF])
-(define_mode_iterator DOUBLE [DI DF])
-(define_mode_iterator SHORT [QI HI])
-(define_mode_attr tIsa [(QI "b") (HI "w") (SI "d") (SF "d")])
-(define_mode_attr lImmArith [(QI "4") (HI "4") (SI "6") (SF "6")])
-(define_mode_attr lImmArithD [(QI "4") (HI "4") (SI "6") (SF "6") (DI "12") (DF "12")])
-(define_mode_attr iF [(QI "i") (HI "i") (SI "i") (SF "F")])
-(define_mode_attr iFD [(DI "i") (DF "F")])
-(define_mode_attr LL [(QI "L") (HI "L")])
-(define_mode_attr shImmBits [(QI "3") (HI "4") (SI "5")])
-
-; In QI mode we push 2 bytes instead of 1 byte.
-(define_mode_attr pushCnstr [(QI "X") (HI "<") (SI "<") (SF "<") (DI "<") (DF "<")])
-
-; tpush will be used to generate the 'number of registers to push' in the
-; push instruction.
-(define_mode_attr tpush [(QI "1") (HI "1") (SI "2") (SF "2") (DI "4") (DF "4")])
-
-;; Code Macro Definitions
-(define_code_attr sIsa [(sign_extend "") (zero_extend "u")])
-(define_code_attr sPat [(sign_extend "s") (zero_extend "u")])
-(define_code_attr szPat [(sign_extend "") (zero_extend "zero_")])
-(define_code_attr szIsa [(sign_extend "x") (zero_extend "z")])
-
-(define_code_iterator sz_xtnd [ sign_extend zero_extend])
-(define_code_iterator any_cond [eq ne gt gtu lt ltu ge geu le leu])
-(define_code_iterator plusminus [plus minus])
-
-(define_code_attr plusminus_insn [(plus "add") (minus "sub")])
-(define_code_attr plusminus_flag [(plus "PLUS") (minus "MINUS")])
-(define_code_attr comm [(plus "%") (minus "")])
-
-(define_code_iterator any_logic [and ior xor])
-(define_code_attr logic [(and "and") (ior "or") (xor "xor")])
-(define_code_attr any_logic_insn [(and "and") (ior "ior") (xor "xor")])
-(define_code_attr any_logic_flag [(and "AND") (ior "IOR") (xor "XOR")])
-
-(define_mode_iterator QH [QI HI])
-(define_mode_attr qh [(QI "qi") (HI "hi")])
-(define_mode_attr QHsz [(QI "2,2,2") (HI "2,2,4")])
-(define_mode_attr QHsuffix [(QI "b") (HI "w")])
-
-
-;; Function Prologue and Epilogue
-(define_expand "prologue"
- [(const_int 0)]
- ""
- {
- cr16_expand_prologue ();
- DONE;
- }
-)
-
-(define_insn "push_for_prologue"
- [(set (reg:SI SP_REGNUM)
- (minus:SI (reg:SI SP_REGNUM)
- (match_operand:SI 0 "immediate_operand" "i")))]
- "reload_completed"
- {
- return cr16_prepare_push_pop_string (0);
- }
- [(set_attr "length" "4")]
-)
-
-(define_expand "epilogue"
- [(return)]
- ""
- {
- cr16_expand_epilogue ();
- DONE;
- }
-)
-
-(define_insn "pop_and_popret_return"
- [(set (reg:SI SP_REGNUM)
- (plus:SI (reg:SI SP_REGNUM)
- (match_operand:SI 0 "immediate_operand" "i")))
- (use (reg:SI RA_REGNUM))
- (return)]
- "reload_completed"
- {
- return cr16_prepare_push_pop_string (1);
- }
- [(set_attr "length" "4")]
-)
-
-(define_insn "popret_RA_return"
- [(use (reg:SI RA_REGNUM))
- (return)]
- "reload_completed"
- "popret\tra"
- [(set_attr "length" "2")]
-)
-
-;; Arithmetic Instruction Patterns
-
-;; Addition-Subtraction "adddi3/subdi3" insns.
-(define_insn "<plusminus_insn>di3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (plusminus:DI (match_operand:DI 1 "register_operand" "<comm>0")
- (match_operand:DI 2 "register_operand" "r")))]
- ""
- {
- return cr16_emit_add_sub_di (operands, <plusminus_flag>);
- })
-
-(define_insn "addsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
- (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0")
- (match_operand:SI 2 "reg_si_int_operand" "r,M,N,O,i")))]
- ""
- "addd\t%2, %0"
- [(set_attr "length" "2,2,4,4,6")]
-)
-
-;; Addition-Subtraction "addhi3/subhi3" insns.
-(define_insn "<plusminus_insn>hi3"
- [(set (match_operand:HI 0 "register_operand" "=c,c,c")
- (plusminus:HI (match_operand:HI 1 "register_operand" "<comm>0,0,0")
- (match_operand:HI 2 "reg_hi_int_operand" "c,M,N")))]
- ""
- "<plusminus_insn>w\t%2, %0"
- [(set_attr "length" "2,2,4")]
-)
-
-;; Addition-Subtraction "addqi3/subqi3" insns.
-(define_insn "<plusminus_insn>qi3"
- [(set (match_operand:QI 0 "register_operand" "=c,c")
- (plusminus:QI (match_operand:QI 1 "register_operand" "<comm>0,0")
- (match_operand:QI 2 "reg_qi_int_operand" "c,M")))]
- ""
- "<plusminus_insn>b\t%2, %0"
- [(set_attr "length" "2,2")]
-)
-
-;; Subtract Instruction
-(define_insn "subsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (minus:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "reg_si_int_operand" "r,i")))]
- ""
- "subd\t%2, %0"
- [(set_attr "length" "4,6")]
-)
-
-;; Multiply and Accumulate Instructions "smachisi3/umachisi3"
-(define_insn "<sPat>maddhisi4"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI
- (mult:SI (sz_xtnd:SI (match_operand:HI 1 "register_operand" "r"))
- (sz_xtnd:SI (match_operand:HI 2 "register_operand" "r")))
- (match_operand:SI 3 "register_operand" "0")))]
- "TARGET_MAC"
- "mac<sPat>w\t%1, %2, %0"
- [(set_attr "length" "2")]
-)
-
-;; Multiply Instructions
-(define_insn "mulhi3"
- [(set (match_operand:HI 0 "register_operand" "=c,c,c")
- (mult:HI (match_operand:HI 1 "register_operand" "%0,0,0")
- (match_operand:HI 2 "reg_or_int_operand" "c,M,N")))]
- ""
- "mulw\t%2, %0"
- [(set_attr "length" "2,2,4")]
-)
-
-(define_insn "mulqihi3"
- [(set (match_operand:HI 0 "register_operand" "=c")
- (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
- (sign_extend:HI (match_operand:QI 2 "register_operand" "c"))))]
- ""
- "mulsb\t%2, %0"
- [(set_attr "length" "2")]
-)
-
-;; Bit Set/Clear Instructions
-(define_expand "insv"
- [(set (zero_extract (match_operand 0 "memory_operand" "")
- (match_operand 1 "immediate_operand" "")
- (match_operand 2 "immediate_operand" ""))
- (match_operand 3 "immediate_operand" ""))]
- "TARGET_BIT_OPS"
- {
- if (INTVAL (operands[1]) != 1)
- FAIL;
- if (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 15)
- FAIL;
- if (INTVAL (operands[3]) == 1)
- {
- if (GET_MODE (operands[0]) == QImode)
- {
- emit_insn (gen_set_bitqi (operands[0], operands[2]));
- DONE;
- }
- else if (GET_MODE (operands[0]) == HImode)
- {
- emit_insn (gen_set_bithi (operands[0], operands[2]));
- DONE;
- }
- }
- if (INTVAL (operands[3]) == 0)
- {
- if (GET_MODE (operands[0]) == QImode)
- {
- emit_insn (gen_clr_bitqi (operands[0], operands[2]));
- DONE;
- }
- else if (GET_MODE (operands[0]) == HImode)
- {
- emit_insn (gen_clr_bithi (operands[0], operands[2]));
- DONE;
- }
- }
- }
-)
-
-(define_insn "set_bit<mode>"
- [(set (zero_extract:SHORT (match_operand:SHORT 0 "memory_operand" "+m")
- (const_int 1)
- (match_operand 1 "immediate_operand" "i"))
- (const_int 1))]
- "TARGET_BIT_OPS"
- "sbit<tIsa>\t%1,%0"
- [(set_attr "length" "2")]
-)
-
-(define_insn "clr_bit<mode>"
- [(set (zero_extract:SHORT (match_operand:SHORT 0 "memory_operand" "+m")
- (const_int 1)
- (match_operand 1 "immediate_operand" "i"))
- (const_int 0))]
- "TARGET_BIT_OPS"
- "cbit<tIsa>\t%1,%0"
- [(set_attr "length" "2")]
-)
-
-(define_insn "set_bit<mode>_mem"
- [(set (match_operand:SHORT 0 "bit_operand" "=m")
- (ior:SHORT (match_dup 0)
- (match_operand:SHORT 1 "one_bit_operand" "i"))
- )]
- "TARGET_BIT_OPS"
- "sbit<tIsa>\t$%s1,%0"
- [(set_attr "length" "2")]
-)
-
-(define_insn "clear_bit<mode>_mem"
- [(set (match_operand:SHORT 0 "bit_operand" "=m")
- (and:SHORT (match_dup 0)
- (match_operand:SHORT 1 "rev_one_bit_operand" "i"))
- )]
- "TARGET_BIT_OPS"
- "cbit<tIsa>\t$%r1,%0"
- [(set_attr "length" "2")]
-)
-
-;; Logical Instructions - and/ior/xor "anddi3/iordi3/xordi3"
-(define_insn "<any_logic_insn>di3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (any_logic:DI (match_operand:DI 1 "register_operand" "%0")
- (match_operand:DI 2 "register_operand" "r")))]
- ""
- {
- return cr16_emit_logical_di (operands, <any_logic_flag>);
- })
-
-; Logical and/ior/xor "andsi3/iorsi3/xorsi3"
-(define_insn "<any_logic_insn>si3"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
- (any_logic:SI (match_operand:SI 1 "register_operand" "%0,0,0,0")
- (match_operand:SI 2 "reg_si_int_operand" "r,M,N,i")))]
- ""
- "<logic>d\t%2, %0"
- [(set_attr "length" "2,2,4,6")]
-)
-
-; Logical and/ior/xor in HImode "andhi3/iorhi3/xorhi3"
-; Logical and/ior/xor in QImode "andqi3/iorqi3/xorqi3"
-(define_insn "<any_logic_insn><qh>3"
- [(set (match_operand:QH 0 "register_operand" "=c,c,c")
- (any_logic:QH (match_operand:QH 1 "register_operand" "%0,0,0")
- (match_operand:QH 2 "reg_hi_int_operand" "c,M,N")))]
- ""
- "<logic><QHsuffix>\t%2, %0"
- [(set_attr "length" "<QHsz>")]
-)
-
-;; Sign and Zero Extend Instructions
-(define_insn "<szPat>extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (sz_xtnd:SI (match_operand:HI 1 "register_operand" "r")))]
- ""
- "mov<szIsa>w\t%1, %0"
- [(set_attr "length" "4")]
-)
-
-(define_insn "<szPat>extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (sz_xtnd:HI (match_operand:QI 1 "register_operand" "r")))]
- ""
- "mov<szIsa>b\t%1, %0"
- [(set_attr "length" "4")]
-)
-
-;; One's Complement
-(define_insn "one_cmpldi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (not:DI (match_operand:DI 1 "register_operand" "0")))]
- ""
- {
- rtx xoperand ;
- int reg0 = REGNO (operands[0]);
-
- xoperand = gen_rtx_REG (SImode, reg0 + 2);
- output_asm_insn ("xord\t$-1, %0", operands);
- output_asm_insn ("xord\t$-1, %0", &xoperand);
- return "" ;
- }
- [(set_attr "length" "12")]
-)
-
-(define_insn "one_cmpl<mode>2"
- [(set (match_operand:CR16IM 0 "register_operand" "=r")
- (not:CR16IM (match_operand:CR16IM 1 "register_operand" "0")))]
- ""
- "xor<tIsa>\t$-1, %0"
- [(set_attr "length" "2")]
-)
-
-;; Arithmetic Left and Right Shift Instructions
-(define_insn "ashlqi3"
- [(set (match_operand:QI 0 "register_operand" "=c,c")
- (ashift:QI (match_operand:QI 1 "register_operand" "0,0")
- (match_operand:QI 2 "nonmemory_operand" "c,I")))]
- ""
- "ashub\t%2, %0"
- [(set_attr "length" "2,2")]
-)
-
-(define_insn "ashlhi3"
- [(set (match_operand:HI 0 "register_operand" "=c,c")
- (ashift:HI (match_operand:HI 1 "register_operand" "0,0")
- (match_operand:QI 2 "nonmemory_operand" "c,J")))]
- ""
- "ashuw\t%2, %0"
- [(set_attr "length" "2,2")]
-)
-
-(define_insn "ashlsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:QI 2 "nonmemory_operand" "r,K")))]
- ""
- "ashud\t%2, %0"
- [(set_attr "length" "2,2")]
-)
-
-(define_expand "ashr<mode>3"
- [(set (match_operand:CR16IM 0 "register_operand" "")
- (ashiftrt:CR16IM (match_operand:CR16IM 1 "register_operand" "")
- (match_operand:QI 2 "nonmemory_operand" "")))]
- ""
- {
- if (GET_CODE (operands[2]) == CONST_INT)
- {
- /* If the constant is not in range, try placing it in a reg */
- if (!UNSIGNED_INT_FITS_N_BITS(INTVAL (operands[2]),<shImmBits>))
- operands[2] = copy_to_mode_reg(QImode, operands[2]);
- }
-
- if (GET_CODE (operands[2]) != CONST_INT)
- operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
- }
-)
-
-(define_insn "ashrqi3_imm_insn"
- [(set (match_operand:QI 0 "register_operand" "=c")
- (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
- (match_operand:QI 2 "shift_qi_imm_operand" "i")))]
- ""
- "ashub\t$%n2, %0"
- [(set_attr "length" "2")]
-)
-
-(define_insn "ashrhi3_imm_insn"
- [(set (match_operand:HI 0 "register_operand" "=c")
- (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
- (match_operand:QI 2 "shift_hi_imm_operand" "i")))]
- ""
- "ashuw\t$%n2, %0"
- [(set_attr "length" "2")]
-)
-
-(define_insn "ashrsi3_imm_insn"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:QI 2 "shift_si_imm_operand" "i")))]
- ""
- "ashud\t$%n2, %0"
- [(set_attr "length" "2")]
-)
-
-(define_insn "ashrqi3_neg_insn"
- [(set (match_operand:QI 0 "register_operand" "=c")
- (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
- (neg:QI (match_operand:QI 2 "register_operand" "c"))))]
- ""
- "ashub\t%2,%0"
- [(set_attr "length" "2")]
-)
-
-(define_insn "ashrhi3_neg_insn"
- [(set (match_operand:HI 0 "register_operand" "=c")
- (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
- (neg:QI (match_operand:QI 2 "register_operand" "c"))))]
- ""
- "ashuw\t%2,%0"
- [(set_attr "length" "2")]
-)
-
-(define_insn "ashrdi3_neg_insn"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
- (neg:QI (match_operand:QI 2 "register_operand" "r"))))]
- ""
- "ashud\t%2,%0"
- [(set_attr "length" "2")]
-)
-
-(define_expand "lshr<mode>3"
- [(set (match_operand:CR16IM 0 "register_operand" "")
- (lshiftrt:CR16IM (match_operand:CR16IM 1 "register_operand" "")
- (match_operand:QI 2 "reg_or_int_operand" "")))]
- ""
- {
- if (GET_CODE (operands[2]) == CONST_INT)
- {
- /* If the constant is not in range, try placing it in a reg */
- if (!UNSIGNED_INT_FITS_N_BITS(INTVAL (operands[2]),<shImmBits>))
- operands[2] = copy_to_mode_reg(QImode, operands[2]);
- }
-
- if (GET_CODE (operands[2]) != CONST_INT)
- operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
- }
-)
-
-(define_insn "lshrqi3_imm_insn"
- [(set (match_operand:QI 0 "register_operand" "=c")
- (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
- (match_operand:QI 2 "shift_qi_operand" "Q")))]
- ""
- "lshb\t$%n2, %0"
- [(set_attr "length" "2")]
-)
-
-(define_insn "lshrhi3_imm_insn"
- [(set (match_operand:HI 0 "register_operand" "=c")
- (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
- (match_operand:QI 2 "shift_hi_operand" "R")))]
- ""
- "lshw\t$%n2, %0"
- [(set_attr "length" "2")]
-)
-
-(define_insn "lshrsi3_imm_insn"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:QI 2 "shift_si_operand" "S")))]
- ""
- "lshd\t$%n2, %0"
- [(set_attr "length" "2")]
-)
-
-(define_insn "lshrqi3_neg_insn"
- [(set (match_operand:QI 0 "register_operand" "=c")
- (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
- (neg:QI (match_operand:QI 2 "register_operand" "c"))))]
- ""
- "lshb\t%2,%0"
- [(set_attr "length" "2")]
-)
-
-(define_insn "lshrhi3_neg_insn"
- [(set (match_operand:HI 0 "register_operand" "=c")
- (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
- (neg:QI (match_operand:QI 2 "register_operand" "c"))))]
- ""
- "lshw\t%2,%0"
- [(set_attr "length" "2")]
-)
-
-(define_insn "lshrsi3_neg_insn"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
- (neg:QI (match_operand:QI 2 "register_operand" "r"))))]
- ""
- "lshd\t%2,%0"
- [(set_attr "length" "2")]
-)
-
-;; Move Instructions
-
-;; Move any non-immediate operand 0 to a general operand 1.
-;; This applies only before starting the reload process
-;; Operand 0 is not a register operand of type mode MODE
-;; If Operand 0 is a push operand of type mode MODE
-;; then, if Operand 1 is a non-SP register
-;; then, Operand 1 = copy_to_mode_reg (<MODE>mode, Operand 1)
-;; endif
-;; else
-;; if Operand 1 is either register or 4-bit immediate constant
-;; then, Operand 1 = copy_to_mode_reg (<MODE>mode, Operand 1)
-;; endif
-;; endif
-;;
-;; What does copy_to_mode_reg (mode, rtx val) do?
-;; Copy the value into new temp reg and return the reg where the
-;; mode of the new reg is always mode MODE when value is constant
-;;
-;; Why should copy_to_mode_reg be called?
-;; All sorts of move are nor supported by CR16. Therefore,
-;; when unsupported move is encountered, the additional instructions
-;; will be introduced for the purpose.
-;;
-;; A new move insn is inserted for Op 1 when one of the following
-;; conditions is met.
-;; Case 1: Op 0 is push_operand
-;; Op 1 is SP register
-;;
-;; Case 2: Op 0 is not push_operand
-;; Op 1 is neither register nor unsigned 4-bit immediate
-
-(define_expand "mov<mode>"
- [(set (match_operand:ALLMTD 0 "nonimmediate_operand" "")
- (match_operand:ALLMTD 1 "general_operand" ""))]
- ""
- {
- if (!(reload_in_progress || reload_completed))
- {
- /* Only if Op0 is a register operand. */
- if (!register_operand (operands[0], <MODE>mode))
- {
- if (push_operand (operands[0], <MODE>mode))
- {
- /* Use copy_to_mode_reg only if the register needs
- to be pushed is SP as CR16 does not support pushing SP. */
- if (!nosp_reg_operand (operands[1], <MODE>mode))
- operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]);
- }
- else
- {
- /* Use copy_to_mode_reg if op1 is not register operand
- subject to conditions inside. */
- if (!register_operand (operands[1], <MODE>mode))
- {
- /* CR16 does not support moving immediate to SI or SF
- type memory. */
- if (<MODE>mode == SImode || <MODE>mode == SFmode ||
- <MODE>mode == DImode || <MODE>mode == DFmode)
- operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]);
- else
- /* moving imm4 is supported by CR16 instruction. */
- if (!u4bits_operand (operands[1], <MODE>mode))
- operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]);
- }
- }
- }
-
- /* If operand-1 is a symbol, convert it into a BRO or GOT Format. */
- if (flag_pic && ! legitimate_pic_operand_p (operands[1]))
- {
- operands[1] = legitimize_pic_address (operands[1], <MODE>mode, 0);
- }
- }
- }
-)
-
-; ALLMT : QI,HI,SI,SF
-; pushCnstr : Push constraints
-; QI : X
-; HI,SI,SF,DI,DF : <
-; b : All non-sp registers
-; tpush : Push count
-; QI,HI : 1
-; SI,SF : 2
-; DI,DF : 4
-(define_insn "push<mode>_internal"
- [(set (match_operand:ALLMTD 0 "push_operand" "=<pushCnstr>")
- (match_operand:ALLMTD 1 "nosp_reg_operand" "b"))]
- ""
- "push\t$<tpush>,%p1"
- [(set_attr "length" "2")]
-)
-
-; (DI, DF) move
-(define_insn "*mov<mode>_double"
- [(set (match_operand:DOUBLE 0 "nonimmediate_operand" "=r, r, r, m")
- (match_operand:DOUBLE 1 "general_operand" "r, <iFD>, m, r"))]
- "register_operand (operands[0], DImode)
- || register_operand (operands[0], DFmode)
- || register_operand (operands[1], DImode)
- || register_operand (operands[1], DFmode)"
- {
- if (which_alternative == 0) {
- rtx xoperands[2];
- int reg0 = REGNO (operands[0]);
- int reg1 = REGNO (operands[1]);
-
- xoperands[0] = gen_rtx_REG (SImode, reg0 + 2);
- xoperands[1] = gen_rtx_REG (SImode, reg1 + 2);
- if ((reg1 + 2) != reg0)
- {
- output_asm_insn ("movd\t%1, %0", operands);
- output_asm_insn ("movd\t%1, %0", xoperands);
- }
- else
- {
- output_asm_insn ("movd\t%1, %0", xoperands);
- output_asm_insn ("movd\t%1, %0", operands);
- }}
-
- else if (which_alternative == 1) {
- rtx lo_operands[2];
- rtx hi_operands[2];
-
- lo_operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
- hi_operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
- lo_operands[1] = simplify_gen_subreg (SImode, operands[1],
- VOIDmode == GET_MODE (operands[1])
- ? DImode : GET_MODE (operands[1]), 0);
- hi_operands[1] = simplify_gen_subreg (SImode, operands[1],
- VOIDmode == GET_MODE (operands[1])
- ? DImode : GET_MODE (operands[1]), 4);
- output_asm_insn ("movd\t%1, %0", lo_operands);
- output_asm_insn ("movd\t%1, %0", hi_operands);}
-
- else if (which_alternative == 2) {
- rtx xoperands[2];
- int reg0 = REGNO (operands[0]), reg1 = -2;
- rtx addr;
-
- if (MEM_P (operands[1]))
- addr = XEXP (operands[1], 0);
- else
- addr = NULL_RTX;
- switch (GET_CODE (addr))
- {
- case REG:
- case SUBREG:
- reg1 = REGNO (addr);
- break;
- case PLUS:
- switch (GET_CODE (XEXP (addr, 0))) {
- case REG:
- case SUBREG:
- reg1 = REGNO (XEXP (addr, 0));
- break;
- case PLUS:
- reg1 = REGNO (XEXP (XEXP (addr, 0), 0));
- break;
- default:
- inform (DECL_SOURCE_LOCATION (cfun->decl), "unexpected expression; addr:");
- debug_rtx (addr);
- inform (DECL_SOURCE_LOCATION (cfun->decl), "operands[1]:");
- debug_rtx (operands[1]);
- inform (DECL_SOURCE_LOCATION (cfun->decl), "generated code might now work\n");
- break;}
- break;
- default:
- break;
- }
-
- xoperands[0] = gen_rtx_REG (SImode, reg0 + 2);
- xoperands[1] = offset_address (operands[1], GEN_INT (4), 2);
- gcc_assert ((reg0 + 1) != reg1);
- if (reg0 != reg1 && (reg1 + 1) != reg0)
- {
- output_asm_insn ("loadd\t%1, %0", operands);
- output_asm_insn ("loadd\t%1, %0", xoperands);
- }
- else
- {
- output_asm_insn ("loadd\t%1, %0", xoperands);
- output_asm_insn ("loadd\t%1, %0", operands);
- }}
- else
- {
- rtx xoperands[2];
- xoperands[0] = offset_address (operands[0], GEN_INT (4), 2);
- xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
- output_asm_insn ("stord\t%1, %0", operands);
- output_asm_insn ("stord\t%1, %0", xoperands);
- }
- return "";
- }
- [(set_attr "length" "4, <lImmArithD>, <lImmArithD>, <lImmArithD>")]
-)
-
-; All long (SI, SF) register move, load and store operations
-; The print_operand will take care of printing the register pair
-; when mode is SI/SF and register is in SHORT_REGS
-(define_insn "*mov<mode>_long"
- [(set (match_operand:LONG 0 "nonimmediate_operand" "=r, r, r, m")
- (match_operand:LONG 1 "general_operand" "r, <iF>, m, r"))]
- "register_operand (operands[0], <MODE>mode)
- || register_operand (operands[1], <MODE>mode)"
- "@
- mov<tIsa>\t%1, %0
- mov<tIsa>\t%1, %0
- load<tIsa>\t%1, %0
- stor<tIsa>\t%1, %0"
- [(set_attr "length" "2,<lImmArith>,<lImmArith>,<lImmArith>")]
-)
-
-;; All short (QI, HI) register move, load and store operations
-(define_insn "*mov<mode>_short"
- [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r, r, r, m, m")
- (match_operand:SHORT 1 "general_operand" "r, <iF>, m, r, <LL>"))]
- "(register_operand (operands[0], <MODE>mode))
- || (store_operand (operands[0], <MODE>mode)
- && (register_operand (operands[1], <MODE>mode)
- || u4bits_operand (operands[1], <MODE>mode)))"
- "@
- mov<tIsa>\t%1, %0
- mov<tIsa>\t%1, %0
- load<tIsa>\t%1, %0
- stor<tIsa>\t%1, %0
- stor<tIsa>\t%1, %0"
- [(set_attr "length" "2,<lImmArith>,<lImmArith>,<lImmArith>,<lImmArith>")]
-)
-
-;; Compare Instructions
-; Instruction generated compares the operands in reverse order
-; Therefore, while printing the asm, the reverse of the
-; compare condition shall be printed.
-(define_insn "cbranch<mode>4"
- [(set (pc)
- (if_then_else (match_operator 0 "ordered_comparison_operator"
- [(match_operand:CR16IM 1 "register_operand" "r,r")
- (match_operand:CR16IM 2 "nonmemory_operand" "r,n")])
- (label_ref (match_operand 3 "" ""))
- (pc)))
- (clobber (cc0))]
- ""
- "cmp<tIsa>\t%2, %1\;b%d0\t%l3"
- [(set_attr "length" "6,6")]
-)
-
-(define_expand "cmp<mode>"
- [(parallel [(set (cc0)
- (compare (match_operand:CR16IM 0 "register_operand" "")
- (match_operand:CR16IM 1 "nonmemory_operand" "")))
- (clobber (match_scratch:HI 2 "=r"))] ) ]
- ""
- "")
-
-;; Scond Instructions
-(define_expand "cstore<mode>4"
- [(set (cc0)
- (compare (match_operand:CR16IM 2 "register_operand" "")
- (match_operand:CR16IM 3 "nonmemory_operand" "")))
- (set (match_operand:HI 0 "register_operand")
- (match_operator:HI 1 "ordered_comparison_operator"
- [(cc0) (const_int 0)]))]
- ""
- ""
-)
-
-(define_insn "*cmp<mode>_insn"
- [(set (cc0)
- (compare (match_operand:CR16IM 0 "register_operand" "r,r")
- (match_operand:CR16IM 1 "nonmemory_operand" "r,n")))]
- ""
- "cmp<tIsa>\t%1, %0"
- [(set_attr "length" "2,4")]
-)
-
-(define_insn "sCOND_internal"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (match_operator:HI 1 "ordered_comparison_operator"
- [(cc0) (const_int 0)]))]
- ""
- "s%d1\t%0"
- [(set_attr "length" "2")]
-)
-
-;; Jumps and Branches
-(define_insn "indirect_jump_return"
- [(set (pc)
- (reg:SI RA_REGNUM))
- (return)]
- "reload_completed"
- "jump\t (ra)"
- [(set_attr "length" "2")]
-)
-
-(define_insn "jump_return"
- [(unspec:SI [(const_int 0)] UNSPEC_RETURN_ADDR)
- (return)]
- "reload_completed"
- "jump\t(ra)"
- [(set_attr "length" "2")]
-)
-
-(define_insn "indirect_jump"
- [(set (pc)
- (match_operand:SI 0 "reg_or_sym_operand" "r,i"))]
- ""
- "@
- jump\t%0
- br\t%a0"
- [(set_attr "length" "2,6")]
-)
-
-(define_insn "interrupt_return"
- [(unspec_volatile [(const_int 0)] 0)
- (return)]
- ""
- {
- return cr16_prepare_push_pop_string (1);
- }
- [(set_attr "length" "14")]
-)
-
-(define_insn "jump_to_imm"
- [(set (pc)
- (match_operand 0 "jump_imm_operand" "i"))]
- ""
- "br\t%c0"
- [(set_attr "length" "6")]
-)
-
-(define_insn "jump"
- [(set (pc)
- (label_ref (match_operand 0 "" "")))]
- ""
- "br\t%l0"
- [(set_attr "length" "6")]
-)
-
-;; Table Jump
-(define_insn "tablejump"
- [(set (pc)
- (match_operand:SI 0 "register_operand" "r"))
- (use (label_ref:SI (match_operand 1 "" "")))]
- "!flag_pic"
- "jump\t%0"
- [(set_attr "length" "2")]
-)
-
-;; Call Instructions
-(define_expand "call"
- [(call (match_operand:QI 0 "memory_operand" "")
- (match_operand 1 "" ""))]
- ""
- {
- if (flag_pic && ! legitimate_pic_operand_p (operands[0]))
- {
- operands[0] = gen_const_mem (QImode,
- legitimize_pic_address (XEXP (operands[0], 0), Pmode, 0));
- emit_call_insn (gen_cr16_call (operands[0], operands[1]));
- }
- else
- emit_call_insn (gen_cr16_call (operands[0], operands[1]));
- DONE;
- }
-)
-
-(define_expand "cr16_call"
- [(parallel
- [(call (match_operand:QI 0 "memory_operand" "")
- (match_operand 1 "" ""))
- (clobber (reg:SI RA_REGNUM))])]
- ""
- ""
-)
-
-(define_insn "cr16_call_insn_branch_pic"
- [(call (mem:QI (match_operand:SI 0 "call_imm_operand" "i"))
- (match_operand 1 "" ""))
- (clobber (match_operand:SI 2 "register_operand" "+r"))]
- "flag_pic == FAR_PIC"
- {
- if (GET_CODE (operands[0]) != CONST_INT)
- return "loadd\t%g0, %2 \n\tjal %2";
- else
- return "jal %2";
- }
- [(set_attr "length" "8")]
-)
-
-(define_insn "cr16_call_insn_branch"
- [(call (mem:QI (match_operand:SI 0 "call_imm_operand" "i"))
- (match_operand 1 "" ""))
- (clobber (match_operand:SI 2 "register_operand" "+r"))]
- "flag_pic == 0 || flag_pic == NEAR_PIC"
- {
- /* Print the immediate address for bal
- 'b' is used instead of 'a' to avoid compiler calling
- the GO_IF_LEGITIMATE_ADDRESS which cannot
- perform checks on const_int code addresses as it
- assumes all const_int are data addresses.
- */
- if (GET_CODE (operands[0]) != CONST_INT)
- return "bal (ra), %a0";
- else
- operands[4] = GEN_INT ((INTVAL (operands[0]))>>1);
- return "movd\t%g4,\t(r1,r0)\n\tjal\t(r1,r0)";
- }
- [(set_attr "length" "6")]
-)
-
-(define_insn "cr16_call_insn_jump"
- [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
- (match_operand 1 "" ""))
- (clobber (match_operand:SI 2 "register_operand" "+r"))]
- ""
- "jal\t%0"
- [(set_attr "length" "2")]
-)
-
-;; Call Value Instructions
-
-(define_expand "call_value"
- [(set (match_operand 0 "general_operand" "")
- (call (match_operand:QI 1 "memory_operand" "")
- (match_operand 2 "" "")))]
- ""
- {
- if (flag_pic && !legitimate_pic_operand_p (operands[1]))
- {
- operands[1] = gen_const_mem (QImode,
- legitimize_pic_address (XEXP (operands[1], 0), Pmode, 0));
- emit_call_insn (gen_cr16_call_value (operands[0], operands[1], operands[2]));
- }
- else
- emit_call_insn (gen_cr16_call_value (operands[0], operands[1], operands[2]));
- DONE;
- }
-)
-
-(define_expand "cr16_call_value"
- [(parallel
- [(set (match_operand 0 "general_operand" "")
- (call (match_operand 1 "memory_operand" "")
- (match_operand 2 "" "")))
- (clobber (reg:SI RA_REGNUM))])]
- ""
- ""
-)
-
-(define_insn "cr16_call_value_insn_branch_pic"
- [(set (match_operand 0 "" "=g")
- (call (mem:QI (match_operand:SI 1 "call_imm_operand" "i"))
- (match_operand 2 "" "")))
- (clobber (match_operand:SI 3 "register_operand" "+r"))]
- "flag_pic == FAR_PIC"
- {
- if (GET_CODE (operands[1]) != CONST_INT)
- return "loadd\t%g1, %3 \n\tjal %3";
- else
- return "jal %3";
- }
- [(set_attr "length" "8")]
-)
-
-(define_insn "cr16_call_value_insn_branch"
- [(set (match_operand 0 "" "=g")
- (call (mem:QI (match_operand:SI 1 "call_imm_operand" "i"))
- (match_operand 2 "" "")))
- (clobber (match_operand:SI 3 "register_operand" "+r"))]
- "flag_pic == 0 || flag_pic == NEAR_PIC"
- {
- /* Print the immediate address for bal
- 'b' is used instead of 'a' to avoid compiler calling
- the GO_IF_LEGITIMATE_ADDRESS which cannot
- perform checks on const_int code addresses as it
- assumes all const_int are data addresses.
- */
- if (GET_CODE (operands[1]) != CONST_INT)
- return "bal (ra), %a1";
- else
- {
- operands[4] = GEN_INT ((INTVAL (operands[1]))>>1);
- return "movd\t%g4,\t(r1,r0)\n\tjal\t(r1,r0)";
- }
- }
- [(set_attr "length" "6")]
-)
-
-
-(define_insn "cr16_call_value_insn_jump"
- [(set (match_operand 0 "" "=g")
- (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
- (match_operand 2 "" "")))
- (clobber (match_operand:SI 3 "register_operand" "+r"))]
- ""
- "jal\t%1"
- [(set_attr "length" "2")]
-)
-
-
-;; Nop
-(define_insn "nop"
- [(const_int 0)]
- ""
- "nop\t"
-)
-
-;; PIC
-/* When generating pic, we need to load the symbol offset into a register.
- So that the optimizer does not confuse this with a normal symbol load
- we use an unspec. The offset will be loaded from a constant pool entry,
- since that is the only type of relocation we can use. */
-
-(define_insn "unspec_bro_addr"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (unspec:SI [(match_operand 1 "" "")] UNSPEC_PIC_ADDR))]
- ""
- "movd \t%f1, %0"
- [(set_attr "length" "4")]
-)
-
-(define_insn "unspec_got_addr"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (unspec:SI [(match_operand 1 "" "")] UNSPEC_PIC_LOAD_ADDR))]
- ""
- "loadd \t%g1, %0"
- [(set_attr "length" "6")]
-)
diff --git a/gcc/config/cr16/cr16.opt b/gcc/config/cr16/cr16.opt
deleted file mode 100644
index 8d7da69..0000000
--- a/gcc/config/cr16/cr16.opt
+++ /dev/null
@@ -1,51 +0,0 @@
-; Options for the National Semiconductor CR16 port of the compiler.
-; Copyright (C) 2012-2022 Free Software Foundation, Inc.
-; Contributed by KPIT Cummins Infosystems Limited.
-;
-; This file is part of GCC.
-;
-; GCC is free software; you can redistribute it and/or modify it
-; under the terms of the GNU General Public License as published
-; by the Free Software Foundation; either version 3, or (at your
-; option) any later version.
-;
-; GCC is distributed in the hope that it will be useful, but WITHOUT
-; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-; License for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with GCC; see the file COPYING3. If not see
-; <http://www.gnu.org/licenses/>.
-
-msim
-Target
-Use simulator runtime.
-
-mbit-ops
-Target Mask(BIT_OPS)
-Generate SBIT, CBIT instructions.
-
-mmac
-Target Mask(MAC)
-Support multiply accumulate instructions.
-
-mdebug-addr
-Target RejectNegative Var(TARGET_DEBUG_ADDR) Undocumented
-
-mdata-model=
-Target RejectNegative JoinedOrMissing Var(cr16_data_model)
-Treat data references as near, far or medium. medium is default.
-
-mcr16c
-Target RejectNegative Mask(CR16C)
-Generate code for CR16C architecture.
-
-mcr16cplus
-Target RejectNegative InverseMask(CR16C,CR16CP)
-Generate code for CR16C+ architecture (Default).
-
-mint32
-Target RejectNegative Mask(INT32)
-Treat integers as 32-bit.
-
diff --git a/gcc/config/cr16/predicates.md b/gcc/config/cr16/predicates.md
deleted file mode 100644
index d8789f5a..0000000
--- a/gcc/config/cr16/predicates.md
+++ /dev/null
@@ -1,225 +0,0 @@
-;; Predicates of machine description for CR16.
-;; Copyright (C) 2012-2022 Free Software Foundation, Inc.
-;; Contributed by KPIT Cummins Infosystems Limited.
-;;
-;; This file is part of GCC.
-;;
-;; GCC is free software; you can redistribute it and/or modify it
-;; under the terms of the GNU General Public License as published
-;; by the Free Software Foundation; either version 3, or (at your
-;; option) any later version.
-;;
-;; GCC is distributed in the hope that it will be useful, but WITHOUT
-;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-;; License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GCC; see the file COPYING3. If not see
-;; <http://www.gnu.org/licenses/>.
-
-;; Predicates
-
-;; Predicates for sbit/cbit instructions
-;; bit operand used for the generation of bit insn generation
-(define_predicate "bit_operand"
- (match_code "mem")
-{
- return ((GET_CODE (op) == MEM && OK_FOR_Z (op)));
-})
-
-;; Unsigned 4-bits constant int or double value.
-(define_predicate "u4bits_operand"
- (match_code "const_int,const_double")
-{
- if (GET_CODE (op) == CONST_DOUBLE)
- return cr16_const_double_ok (op);
- return (UNSIGNED_INT_FITS_N_BITS(INTVAL (op), 4)) ? 1 : 0;
-})
-
-;; Operand is a constant integer where
-;; only one bit is set to 1.
-(define_predicate "one_bit_operand"
- (match_code "const_int")
-{
- unsigned int val;
-
- val = INTVAL (op);
- if (mode == QImode)
- val &= 0xff;
- else if (mode == HImode)
- val &= 0xffff;
- else
- gcc_unreachable();
-
- if (val != 0)
- return (val & (val - 1)) == 0; /* true if only one bit is set. */
- else
- return 0;
-})
-
-;; Operand is a constant integer where
-;; only one bit is set to 0.
-(define_predicate "rev_one_bit_operand"
- (match_code "const_int")
-{
- unsigned int val;
-
- val = ~INTVAL (op); /* Invert and use. */
- if (mode == QImode)
- val &= 0xff;
- else if (mode == HImode)
- val &= 0xffff;
- else
- gcc_unreachable();
-
- if (val != 0)
- return (val & (val - 1)) == 0; /* true if only one bit is set. */
- else
- return 0;
-})
-
-;; Predicates for shift instructions
-;; Immediate operand predicate for count in shift operations.
-;; Immediate shall be 3-bits in case operand to be operated on
-;; is a qi mode operand.
-(define_predicate "shift_qi_imm_operand"
- (match_code "const_int")
-{
- return (UNSIGNED_INT_FITS_N_BITS(INTVAL (op), 3)) ? 1 : 0;
-})
-
-;; Immediate shall be 4-bits in case operand to be operated on
-;; is a hi mode operand.
-(define_predicate "shift_hi_imm_operand"
- (match_code "const_int")
-{
- return (UNSIGNED_INT_FITS_N_BITS(INTVAL (op), 4)) ? 1 : 0;
-})
-
-;; Immediate shall be 3-bits in case operand to be operated on
-;; is a si mode operand.
-(define_predicate "shift_si_imm_operand"
- (match_code "const_int")
-{
- return (UNSIGNED_INT_FITS_N_BITS(INTVAL (op), 5)) ? 1 : 0;
-})
-
-;; Predicates for jump/call instructions
-;; Jump immediate cannot be more than 24-bits
-(define_predicate "jump_imm_operand"
- (match_code "const_int")
-{
- return (UNSIGNED_INT_FITS_N_BITS(INTVAL (op), 24)) ? 1 : 0;
-})
-
-;; Call immediate cannot be more than 24-bits
-(define_predicate "call_imm_operand"
- (match_operand 0 "immediate_operand")
-{
- if (GET_CODE (op) != CONST_INT) return 1;
- return (UNSIGNED_INT_FITS_N_BITS(INTVAL (op), 24)) ? 1 : 0;
-})
-
-;; Operand is register or 4-bit immediate operand
-(define_predicate "reg_or_u4bits_operand"
- (ior (match_operand 0 "u4bits_operand")
- (match_operand 0 "register_operand")))
-
-;; Operand is a register or symbol reference
-(define_predicate "reg_or_sym_operand"
- (ior (match_code "symbol_ref")
- (match_operand 0 "register_operand")))
-
-;; Operand is a non stack pointer register
-(define_predicate "nosp_reg_operand"
- (and (match_operand 0 "register_operand")
- (match_test "REGNO (op) != SP_REGNUM")))
-
-(define_predicate "hard_reg_operand"
- (and (match_operand 0 "register_operand")
- (match_test "REGNO (op) <= 15")))
-
-;; Operand is a memory reference and
-;; not a push operand.
-(define_predicate "store_operand"
- (and (match_operand 0 "memory_operand")
- (not (match_operand 0 "push_operand"))))
-
-;; Helper predicate
-(define_predicate "reg_or_int_operand"
- (ior (match_code "const_int")
- (match_operand 0 "register_operand")))
-
-;;
-;;
-;; Atithmetic/logical predicates
-
-;; QI Helper
-(define_predicate "arith_qi_operand"
- (match_code "const_int")
-{
- return (IN_RAN(INTVAL (op), 0, 15) && ((INTVAL (op) != 9)
- || (INTVAL (op) != 11))) ? 1 : 0 ;
-})
-
-;;QI Reg, subreg(reg) or const_int.
-(define_predicate "reg_qi_int_operand"
- (ior (match_operand 0 "arith_qi_operand")
- (match_operand 0 "register_operand")))
-
-;; HI Helper
-(define_predicate "arith_hi_operand"
- (match_code "const_int")
-{
- return (IN_RAN(INTVAL (op), -32768, 32768) ) ? 1 : 0 ;
-})
-
-;;HI Reg, subreg(reg) or const_int.
-(define_predicate "reg_hi_int_operand"
- (ior (match_operand 0 "arith_hi_operand")
- (match_operand 0 "register_operand")))
-
-;;SI Reg, subreg(reg) or const_int.
-(define_predicate "reg_si_int_operand"
- (ior (match_operand 0 "const_int_operand")
- (match_operand 0 "register_operand")))
-
-;;
-;; Shift predicates
-
-;; QI Helper
-(define_predicate "shift_qi_operand"
- (match_code "const_int")
-{
- return (IN_RAN(INTVAL (op), 0, 7) ) ? 1 : 0;
-})
-
-;;QI Reg, subreg(reg) or const_int.
-(define_predicate "shift_reg_qi_int_operand"
- (ior (match_operand 0 "shift_qi_operand")
- (match_operand 0 "register_operand")))
-
-;; HI Helper
-(define_predicate "shift_hi_operand"
- (match_code "const_int")
-{
- return (IN_RAN(INTVAL (op), 0, 15) ) ? 1 : 0 ;
-})
-
-;;HI Reg, subreg(reg) or const_int.
-(define_predicate "shift_reg_hi_int_operand"
- (ior (match_operand 0 "shift_hi_operand")
- (match_operand 0 "register_operand")))
-
-;; SI Helper
-(define_predicate "shift_si_operand"
- (match_code "const_int")
-{
- return (IN_RAN(INTVAL (op), 0, 31) ) ? 1 : 0;
-})
-
-;;SI Reg, subreg(reg) or const_int.
-(define_predicate "shift_reg_si_int_operand"
- (ior (match_operand 0 "shift_si_operand")
- (match_operand 0 "register_operand")))
diff --git a/gcc/config/cr16/t-cr16 b/gcc/config/cr16/t-cr16
deleted file mode 100644
index 928730f..0000000
--- a/gcc/config/cr16/t-cr16
+++ /dev/null
@@ -1,25 +0,0 @@
-# CR16 Target Makefile
-# Copyright (C) 2012-2022 Free Software Foundation, Inc.
-# Contributed by KPIT Cummins Infosystems Limited.
-#
-# This file is part of GCC.
-#
-# GCC is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published
-# by the Free Software Foundation; either version 3, or (at your
-# option) any later version.
-#
-# GCC is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-# License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3. If not see
-# <http://www.gnu.org/licenses/>.
-
-MULTILIB_OPTIONS = fPIC mint32
-MULTILIB_DIRNAMES = far-pic int32
-MULTILIB_MATCHES =
-MULTILIB_EXTRA_OPTS = mcr16cplus mdata-model=far
-