[PATCH] cr16: remove obsoleted port
Andrew Pinski
pinskia@gmail.com
Thu Aug 25 17:06:50 GMT 2022
On Thu, Aug 25, 2022 at 1:39 AM Martin Liška <mliska@suse.cz> wrote:
>
> Remove the port that has been marked obsolete in GCC 12 change notes.
>
> Ready to be installed?
You missed the following one:
gcc/testsuite/lib/target-supports.exp: if { [istarget msp430-*-*]
|| [istarget cr16-*-*] } {
Thanks,
Andrew
> Thanks,
> Martin
>
> ChangeLog:
>
> * config.sub: Remove cr16.
>
> contrib/ChangeLog:
>
> * config-list.mk: Remove cr16.
>
> gcc/ChangeLog:
>
> * config.gcc: Remove cr16 related stuff.
> * doc/extend.texi: Likewise.
> * 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.
> ---
> config.sub | 3 -
> contrib/config-list.mk | 2 +-
> gcc/common/config/cr16/cr16-common.cc | 27 -
> gcc/config.gcc | 8 +-
> gcc/config/cr16/constraints.md | 81 -
> gcc/config/cr16/cr16-protos.h | 98 --
> gcc/config/cr16/cr16.cc | 2201 -------------------------
> gcc/config/cr16/cr16.h | 556 -------
> gcc/config/cr16/cr16.md | 1084 ------------
> gcc/config/cr16/cr16.opt | 51 -
> gcc/config/cr16/predicates.md | 225 ---
> gcc/config/cr16/t-cr16 | 25 -
> gcc/doc/extend.texi | 15 -
> gcc/doc/install.texi | 25 +-
> gcc/doc/invoke.texi | 49 +-
> gcc/doc/md.texi | 34 -
> gcc/function-tests.cc | 20 +-
> libgcc/config.host | 6 -
> libgcc/config/cr16/crti.S | 54 -
> libgcc/config/cr16/crtlibid.S | 28 -
> libgcc/config/cr16/crtn.S | 44 -
> libgcc/config/cr16/divmodhi3.c | 115 --
> libgcc/config/cr16/lib1funcs.S | 563 -------
> libgcc/config/cr16/t-cr16 | 29 -
> libgcc/config/cr16/t-crtlibid | 22 -
> libgcc/config/cr16/unwind-cr16.c | 1682 -------------------
> libgcc/config/cr16/unwind-dw2.h | 80 -
> 27 files changed, 5 insertions(+), 7122 deletions(-)
> delete mode 100644 gcc/common/config/cr16/cr16-common.cc
> delete mode 100644 gcc/config/cr16/constraints.md
> delete mode 100644 gcc/config/cr16/cr16-protos.h
> delete mode 100644 gcc/config/cr16/cr16.cc
> delete mode 100644 gcc/config/cr16/cr16.h
> delete mode 100644 gcc/config/cr16/cr16.md
> delete mode 100644 gcc/config/cr16/cr16.opt
> delete mode 100644 gcc/config/cr16/predicates.md
> delete mode 100644 gcc/config/cr16/t-cr16
> delete mode 100644 libgcc/config/cr16/crti.S
> delete mode 100644 libgcc/config/cr16/crtlibid.S
> delete mode 100644 libgcc/config/cr16/crtn.S
> delete mode 100644 libgcc/config/cr16/divmodhi3.c
> delete mode 100644 libgcc/config/cr16/lib1funcs.S
> delete mode 100644 libgcc/config/cr16/t-cr16
> delete mode 100644 libgcc/config/cr16/t-crtlibid
> delete mode 100644 libgcc/config/cr16/unwind-cr16.c
> delete mode 100644 libgcc/config/cr16/unwind-dw2.h
>
> diff --git a/config.sub b/config.sub
> index 38f3d037a78..b6275b57590 100755
> --- a/config.sub
> +++ b/config.sub
> @@ -1127,9 +1127,6 @@ case $cpu-$vendor in
>
> # Recognize the canonical CPU Types that limit and/or modify the
> # company names they are paired with.
> - cr16-*)
> - basic_os=${basic_os:-elf}
> - ;;
> crisv32-* | etraxfs*-*)
> cpu=crisv32
> vendor=axis
> diff --git a/contrib/config-list.mk b/contrib/config-list.mk
> index c4db8dc849a..dd22420f078 100644
> --- a/contrib/config-list.mk
> +++ b/contrib/config-list.mk
> @@ -40,7 +40,7 @@ LIST = aarch64-elf aarch64-linux-gnu aarch64-rtems \
> arm-symbianelf avr-elf \
> bfin-elf bfin-uclinux bfin-linux-uclibc bfin-rtems bfin-openbsd \
> bpf-unknown-none \
> - c6x-elf c6x-uclinux cr16-elfOPT-enable-obsolete cris-elf \
> + c6x-elf c6x-uclinux cris-elf \
> csky-elf csky-linux-gnu \
> epiphany-elf epiphany-elfOPT-with-stack-offset=16 fido-elf \
> fr30-elf frv-elf frv-linux ft32-elf h8300-elf hppa-linux-gnu \
> diff --git a/gcc/common/config/cr16/cr16-common.cc b/gcc/common/config/cr16/cr16-common.cc
> deleted file mode 100644
> index 6d0b2be52ed..00000000000
> --- a/gcc/common/config/cr16/cr16-common.cc
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -/* Common hooks for CR16.
> - Copyright (C) 2012-2022 Free Software Foundation, Inc.
> -
> - 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/>. */
> -
> -#include "config.h"
> -#include "system.h"
> -#include "coretypes.h"
> -#include "tm.h"
> -#include "common/common-target.h"
> -#include "common/common-target-def.h"
> -
> -struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index 02f58970db0..f19560264c8 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -248,8 +248,7 @@ md_file=
>
> # Obsolete configurations.
> case ${target} in
> - cr16-*-* \
> - | hppa[12]*-*-hpux10* \
> + hppa[12]*-*-hpux10* \
> | hppa[12]*-*-hpux11* \
> | m32c-*-rtems* \
> )
> @@ -1552,11 +1551,6 @@ bpf-*-*)
> extra_objs="coreout.o"
> target_gtfiles="$target_gtfiles \$(srcdir)/config/bpf/coreout.cc"
> ;;
> -cr16-*-elf)
> - tm_file="elfos.h ${tm_file} newlib-stdint.h"
> - tmake_file="${tmake_file} cr16/t-cr16 "
> - use_collect2=no
> - ;;
> cris-*-elf | cris-*-none)
> tm_file="elfos.h newlib-stdint.h ${tm_file}"
> tmake_file="cris/t-cris cris/t-elfmulti"
> diff --git a/gcc/config/cr16/constraints.md b/gcc/config/cr16/constraints.md
> deleted file mode 100644
> index 708fe21a7ab..00000000000
> --- 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 300bb31ad84..00000000000
> --- 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 55dad9994a5..00000000000
> --- 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 100bb4f123c..00000000000
> --- 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 7ec746802dc..00000000000
> --- 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 8d7da69509f..00000000000
> --- 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 d8789f5a50e..00000000000
> --- 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 928730f2dfd..00000000000
> --- 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
> -
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index 7fe7f8817cd..5f231721b33 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -2534,7 +2534,6 @@ GCC plugins may provide their own attributes.
> * AVR Function Attributes::
> * Blackfin Function Attributes::
> * BPF Function Attributes::
> -* CR16 Function Attributes::
> * C-SKY Function Attributes::
> * Epiphany Function Attributes::
> * H8/300 Function Attributes::
> @@ -5088,20 +5087,6 @@ int bpf_probe_read (void *dst, int size, const void *unsafe_ptr)
> @end smallexample
> @end table
>
> -@node CR16 Function Attributes
> -@subsection CR16 Function Attributes
> -
> -These function attributes are supported by the CR16 back end:
> -
> -@table @code
> -@item interrupt
> -@cindex @code{interrupt} function attribute, CR16
> -Use this attribute to indicate
> -that the specified function is an interrupt handler. The compiler generates
> -function entry and exit sequences suitable for use in an interrupt handler
> -when this attribute is present.
> -@end table
> -
> @node C-SKY Function Attributes
> @subsection C-SKY Function Attributes
>
> diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
> index b3bebdf125b..9c78476374b 100644
> --- a/gcc/doc/install.texi
> +++ b/gcc/doc/install.texi
> @@ -751,7 +751,7 @@ Here are the possible CPU types:
>
> @quotation
> aarch64, aarch64_be, alpha, alpha64, amdgcn, arc, arceb, arm, armeb, avr, bfin,
> -bpf, cr16, cris, csky, epiphany, fido, fr30, frv, ft32, h8300, hppa, hppa2.0,
> +bpf, cris, csky, epiphany, fido, fr30, frv, ft32, h8300, hppa, hppa2.0,
> hppa64, i486, i686, ia64, iq2000, lm32, loongarch64, m32c, m32r, m32rle, m68k,
> mcore, microblaze, microblazeel, mips, mips64, mips64el, mips64octeon,
> mips64orion, mips64vr, mipsel, mipsisa32, mipsisa32r2, mipsisa64, mipsisa64r2,
> @@ -3860,29 +3860,6 @@ See ``Blackfin Options'' in the main manual
> More information, and a version of binutils with support for this processor,
> are available at @uref{https://sourceforge.net/projects/adi-toolchain/}.
>
> -@html
> -<hr />
> -@end html
> -@anchor{cr16}
> -@heading CR16
> -The CR16 CompactRISC architecture is a 16-bit architecture. This
> -architecture is used in embedded applications.
> -
> -@ifnothtml
> -@xref{CR16 Options,, CR16 Options, gcc, Using and Porting the GNU Compiler
> -Collection (GCC)},
> -@end ifnothtml
> -
> -@ifhtml
> -See ``CR16 Options'' in the main manual for a list of CR16-specific options.
> -@end ifhtml
> -
> -Use @samp{configure --target=cr16-elf --enable-languages=c,c++} to configure
> -GCC@ for building a CR16 elf cross-compiler.
> -
> -Use @samp{configure --target=cr16-uclinux --enable-languages=c,c++} to
> -configure GCC@ for building a CR16 uclinux cross-compiler.
> -
> @html
> <hr />
> @end html
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 3359313d9c5..9ba83a6b1f3 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -879,12 +879,6 @@ Objective-C and Objective-C++ Dialects}.
> -melf -maout -sim -sim2 @gol
> -mmul-bug-workaround -mno-mul-bug-workaround}
>
> -@emph{CR16 Options}
> -@gccoptlist{-mmac @gol
> --mcr16cplus -mcr16c @gol
> --msim -mint32 -mbit-ops
> --mdata-model=@var{model}}
> -
> @emph{C-SKY Options}
> @gccoptlist{-march=@var{arch} -mcpu=@var{cpu} @gol
> -mbig-endian -EB -mlittle-endian -EL @gol
> @@ -11856,7 +11850,7 @@ Use @option{-fno-delete-null-pointer-checks} to disable this optimization
> for programs that depend on that behavior.
>
> This option is enabled by default on most targets. On Nios II ELF, it
> -defaults to off. On AVR, CR16, and MSP430, this option is completely disabled.
> +defaults to off. On AVR and MSP430, this option is completely disabled.
>
> Passes that use the dataflow information
> are enabled independently at different optimization levels.
> @@ -19403,7 +19397,6 @@ platform.
> * Blackfin Options::
> * C6X Options::
> * CRIS Options::
> -* CR16 Options::
> * C-SKY Options::
> * Darwin Options::
> * DEC Alpha Options::
> @@ -22984,46 +22977,6 @@ Like @option{-sim}, but pass linker options to locate initialized data at
> 0x40000000 and zero-initialized data at 0x80000000.
> @end table
>
> -@node CR16 Options
> -@subsection CR16 Options
> -@cindex CR16 Options
> -
> -These options are defined specifically for the CR16 ports.
> -
> -@table @gcctabopt
> -
> -@item -mmac
> -@opindex mmac
> -Enable the use of multiply-accumulate instructions. Disabled by default.
> -
> -@item -mcr16cplus
> -@itemx -mcr16c
> -@opindex mcr16cplus
> -@opindex mcr16c
> -Generate code for CR16C or CR16C+ architecture. CR16C+ architecture
> -is default.
> -
> -@item -msim
> -@opindex msim
> -Links the library libsim.a which is in compatible with simulator. Applicable
> -to ELF compiler only.
> -
> -@item -mint32
> -@opindex mint32
> -Choose integer type as 32-bit wide.
> -
> -@item -mbit-ops
> -@opindex mbit-ops
> -Generates @code{sbit}/@code{cbit} instructions for bit manipulations.
> -
> -@item -mdata-model=@var{model}
> -@opindex mdata-model
> -Choose a data model. The choices for @var{model} are @samp{near},
> -@samp{far} or @samp{medium}. @samp{medium} is default.
> -However, @samp{far} is not valid with @option{-mcr16c}, as the
> -CR16C architecture does not support the far data model.
> -@end table
> -
> @node C-SKY Options
> @subsection C-SKY Options
> @cindex C-SKY Options
> diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
> index 04aedfadbd1..b4dd4e7b5bd 100644
> --- a/gcc/doc/md.texi
> +++ b/gcc/doc/md.texi
> @@ -2198,40 +2198,6 @@ An integer constant with all bits set except exactly one.
> Any SYMBOL_REF.
> @end table
>
> -@item CR16 Architecture---@file{config/cr16/cr16.h}
> -@table @code
> -
> -@item b
> -Registers from r0 to r14 (registers without stack pointer)
> -
> -@item t
> -Register from r0 to r11 (all 16-bit registers)
> -
> -@item p
> -Register from r12 to r15 (all 32-bit registers)
> -
> -@item I
> -Signed constant that fits in 4 bits
> -
> -@item J
> -Signed constant that fits in 5 bits
> -
> -@item K
> -Signed constant that fits in 6 bits
> -
> -@item L
> -Unsigned constant that fits in 4 bits
> -
> -@item M
> -Signed constant that fits in 32 bits
> -
> -@item N
> -Check for 64 bits wide constants for add/sub instructions
> -
> -@item G
> -Floating point constant that is legal for store immediate
> -@end table
> -
> @item C-SKY---@file{config/csky/constraints.md}
> @table @code
>
> diff --git a/gcc/function-tests.cc b/gcc/function-tests.cc
> index 1f983e87032..68e8b97cd02 100644
> --- a/gcc/function-tests.cc
> +++ b/gcc/function-tests.cc
> @@ -627,25 +627,7 @@ test_expansion_to_rtl ()
> (reg:SI 87 [ D.59 ])) -1 (nil))
> (insn 10 6 11 2 (set (reg/i:SI 0 ax)
> (reg:SI 88 [ <retval> ])) -1 (nil))
> - (insn 11 10 0 2 (use (reg/i:SI 0 ax)) -1 (nil))
> -
> - On cr16-elf I get this:
> - (note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
> - (insn 2 4 3 2 (set (reg:SI 24)
> - (reg/f:SI 16 virtual-incoming-args)) -1
> - (nil))
> - (note 3 2 6 2 NOTE_INSN_FUNCTION_BEG)
> - (insn 6 3 7 2 (set (reg:HI 22 [ _1 ])
> - (const_int 42 [0x2a])) -1
> - (nil))
> - (insn 7 6 11 2 (set (reg:HI 23 [ <retval> ])
> - (reg:HI 22 [ _1 ])) -1
> - (nil))
> - (insn 11 7 12 2 (set (reg/i:HI 0 r0)
> - (reg:HI 23 [ <retval> ])) -1
> - (nil))
> - (insn 12 11 0 2 (use (reg/i:HI 0 r0)) -1
> - (nil)). */
> + (insn 11 10 0 2 (use (reg/i:SI 0 ax)) -1 (nil)). */
> verify_three_block_rtl_cfg (fun);
>
> /* Verify as much of the RTL as we can whilst avoiding
> diff --git a/libgcc/config.host b/libgcc/config.host
> index b2a0a8e1aa9..9a28b10ac7f 100644
> --- a/libgcc/config.host
> +++ b/libgcc/config.host
> @@ -110,8 +110,6 @@ bfin*-*)
> bpf-*-*)
> cpu_type=bpf
> ;;
> -cr16-*-*)
> - ;;
> csky*-*-*)
> cpu_type=csky
> ;;
> @@ -591,10 +589,6 @@ bpf-*-*)
> tmake_file="$tmake_file ${cpu_type}/t-${cpu_type}"
> extra_parts="crti.o crtn.o"
> ;;
> -cr16-*-elf)
> - tmake_file="${tmake_file} cr16/t-cr16 cr16/t-crtlibid t-fdpbit"
> - extra_parts="$extra_parts crti.o crtn.o crtlibid.o"
> - ;;
> cris-*-elf)
> tmake_file="$tmake_file cris/t-cris t-softfp-sfdf t-softfp cris/t-elfmulti"
> ;;
> diff --git a/libgcc/config/cr16/crti.S b/libgcc/config/cr16/crti.S
> deleted file mode 100644
> index 463d0e35c69..00000000000
> --- a/libgcc/config/cr16/crti.S
> +++ /dev/null
> @@ -1,54 +0,0 @@
> -# Specialized code needed to support construction and destruction of
> -# file-scope objects in C++ and Java code, and to support exception handling.
> -# Copyright (C) 2012-2022 Free Software Foundation, Inc.
> -# Contributed by KPIT Cummins Infosystems Limited.
> -
> -# This file 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.
> -#
> -# This file 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.
> -#
> -# Under Section 7 of GPL version 3, you are granted additional
> -# permissions described in the GCC Runtime Library Exception, version
> -# 3.1, as published by the Free Software Foundation.
> -#
> -# You should have received a copy of the GNU General Public License and
> -# a copy of the GCC Runtime Library Exception along with this program;
> -# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
> -# <http://www.gnu.org/licenses/>.
> -
> -
> -/* This file just supplies function prologues for the .init and .fini
> - sections. It is linked in before crtbegin.o. */
> -
> - .ident "GNU C crti.o"
> -
> - .section .init
> - .globl __init
> - .type __init,@function
> -__init:
> -#if defined (__ID_SHARED_LIB__)
> - push $2, r12, ra
> - movd $__current_shared_library_r12_offset_, (r1,r0)
> - loadd [r12]0(r1,r0), (r12)
> -#else
> - push ra
> -#endif
> -
> - .section .fini
> - .globl __fini
> - .type __fini,@function
> -__fini:
> -#if defined (__ID_SHARED_LIB__)
> - push $2, r12, ra
> - movd $__current_shared_library_r12_offset_, (r1,r0)
> - loadd [r12]0(r1,r0), (r12)
> -#else
> - push ra
> -#endif
> -
> diff --git a/libgcc/config/cr16/crtlibid.S b/libgcc/config/cr16/crtlibid.S
> deleted file mode 100644
> index f3b8f52484a..00000000000
> --- a/libgcc/config/cr16/crtlibid.S
> +++ /dev/null
> @@ -1,28 +0,0 @@
> -# Provide a weak definition of the library ID, for the benefit of certain
> -# configure scripts.
> -# Copyright (C) 2012-2022 Free Software Foundation, Inc.
> -# Contributed by KPIT Cummins Infosystems Limited.
> -
> -# This file 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.
> -#
> -# This file 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.
> -#
> -# Under Section 7 of GPL version 3, you are granted additional
> -# permissions described in the GCC Runtime Library Exception, version
> -# 3.1, as published by the Free Software Foundation.
> -#
> -# You should have received a copy of the GNU General Public License and
> -# a copy of the GCC Runtime Library Exception along with this program;
> -# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
> -# <http://www.gnu.org/licenses/>.
> -
> - .ident "GNU C crtlibid.o"
> -
> -.weak __current_shared_library_r12_offset_
> -.set __current_shared_library_r12_offset_, 0
> diff --git a/libgcc/config/cr16/crtn.S b/libgcc/config/cr16/crtn.S
> deleted file mode 100644
> index c0ef6a50144..00000000000
> --- a/libgcc/config/cr16/crtn.S
> +++ /dev/null
> @@ -1,44 +0,0 @@
> -# Specialized code needed to support construction and destruction of
> -# file-scope objects in C++ and Java code, and to support exception handling.
> -# Copyright (C) 2012-2022 Free Software Foundation, Inc.
> -# Contributed by KPIT Cummins Infosystems Limited.
> -
> -# This file 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.
> -#
> -# This file 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.
> -#
> -# Under Section 7 of GPL version 3, you are granted additional
> -# permissions described in the GCC Runtime Library Exception, version
> -# 3.1, as published by the Free Software Foundation.
> -#
> -# You should have received a copy of the GNU General Public License and
> -# a copy of the GCC Runtime Library Exception along with this program;
> -# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
> -# <http://www.gnu.org/licenses/>.
> -
> -
> -/* This file supplies function epilogues for the .init and .fini sections.
> - It is linked in after all other files. */
> -
> - .ident "GNU C crtn.o"
> -
> - .section .init
> -#if defined (__ID_SHARED_LIB__)
> - popret $2, r12, ra
> -#else
> - popret ra
> -#endif
> -
> - .section .fini
> -#if defined (__ID_SHARED_LIB__)
> - popret $2, r12, ra
> -#else
> - popret ra
> -#endif
> -
> diff --git a/libgcc/config/cr16/divmodhi3.c b/libgcc/config/cr16/divmodhi3.c
> deleted file mode 100644
> index 21265d09545..00000000000
> --- a/libgcc/config/cr16/divmodhi3.c
> +++ /dev/null
> @@ -1,115 +0,0 @@
> -/* Libgcc Target specific implementation - Emulating div and mod.
> - 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.
> -
> - Under Section 7 of GPL version 3, you are granted additional
> - permissions described in the GCC Runtime Library Exception, version
> - 3.1, as published by the Free Software Foundation.
> -
> - You should have received a copy of the GNU General Public License and
> - a copy of the GCC Runtime Library Exception along with this program;
> - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
> - <http://www.gnu.org/licenses/>. */
> -
> -
> -/* Emulate the division and modulus operation. */
> -
> -unsigned short
> -udivmodhi4 (unsigned short num, unsigned short den, short modwanted)
> -{
> - unsigned short bit = 1;
> - unsigned short res = 0;
> -
> - while (den < num && bit && !(den & (1 << 15)))
> - {
> - den <<= 1;
> - bit <<= 1;
> - }
> - while (bit)
> - {
> - if (num >= den)
> - {
> - num -= den;
> - res |= bit;
> - }
> - bit >>= 1;
> - den >>= 1;
> - }
> -
> - if (modwanted)
> - return num;
> - return res;
> -}
> -
> -short
> -__divhi3 (short a, short b)
> -{
> - short neg = 0;
> - short res;
> -
> - if (a < 0)
> - {
> - a = -a;
> - neg = !neg;
> - }
> -
> - if (b < 0)
> - {
> - b = -b;
> - neg = !neg;
> - }
> -
> - res = udivmodhi4 (a, b, 0);
> -
> - if (neg)
> - res = -res;
> -
> - return res;
> -}
> -
> -short
> -__modhi3 (short a, short b)
> -{
> - short neg = 0;
> - short res;
> -
> - if (a < 0)
> - {
> - a = -a;
> - neg = 1;
> - }
> -
> - if (b < 0)
> - b = -b;
> -
> - res = udivmodhi4 (a, b, 1);
> -
> - if (neg)
> - res = -res;
> -
> - return res;
> -}
> -
> -short
> -__udivhi3 (short a, short b)
> -{
> - return udivmodhi4 (a, b, 0);
> -}
> -
> -short
> -__umodhi3 (short a, short b)
> -{
> - return udivmodhi4 (a, b, 1);
> -}
> diff --git a/libgcc/config/cr16/lib1funcs.S b/libgcc/config/cr16/lib1funcs.S
> deleted file mode 100644
> index 502ec1a85a8..00000000000
> --- a/libgcc/config/cr16/lib1funcs.S
> +++ /dev/null
> @@ -1,563 +0,0 @@
> -/* Libgcc Target specific implementation.
> - 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.
> -
> - Under Section 7 of GPL version 3, you are granted additional
> - permissions described in the GCC Runtime Library Exception, version
> - 3.1, as published by the Free Software Foundation.
> -
> - You should have received a copy of the GNU General Public License and
> - a copy of the GCC Runtime Library Exception along with this program;
> - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
> - <http://www.gnu.org/licenses/>. */
> -
> -#ifdef L_mulsi3
> - .text
> - .align 4
> - .globl ___mulsi3
> -___mulsi3:
> - movw r4,r0
> - movw r2,r1
> - /* Extended multiplication between the 2 lower words */
> - muluw r1,(r1,r0)
> -
> - /* Multiply the lower word of each parameter */
> - mulw r2,r5
> -
> - /* With the higher word of the other */
> - mulw r3,r4
> -
> - /* Add products to the higher part of the final result */
> - addw r4,r1
> - addw r5,r1
> - jump (ra)
> -#endif
> -
> -#ifdef L_divdi3
> - .text
> - .align 4
> - .globl ___divdi3
> -
> -___divdi3:
> - push $4, r7, ra
> -
> - /* Param #1 Long Long low bit first */
> - loadd 12(sp), (r1, r0)
> - loadd 16(sp), (r3, r2)
> -
> - /* Param #2 Long Long low bit first */
> - loadd 20(sp), (r5, r4)
> - loadd 24(sp), (r7, r6)
> -
> - /* Set neg to 0 */
> - movw $0, r10
> -
> - subd $16, (sp)
> -
> - /* Compare if param1 is greater than 0 */
> - cmpw $0, r3
> - ble L4
> -
> - /* Invert param1 and neg */
> - movd $-1, (r9, r8) /* Temp set to FFFFFFFF */
> - xord (r9, r8), (r1, r0) /* Xor low bits of param 1 with temp */
> - xord (r9, r8), (r3, r2) /* Xor high bits of param 1 with temp */
> - addd $1, (r1, r0) /* Add 1 to low bits of param 1 */
> - xorw $1, r10 /* Invert neg */
> - bcc L4 /* If no carry occurred go to L4 */
> - addd $1, (r3, r2) /* Add 1 to high bits of param 1 */
> -
> -L4: stord (r1, r0), 0(sp)
> - stord (r3, r2), 4(sp)
> -
> - /* Compare if param2 is greater than 0 */
> - cmpw $0, r7
> - ble L5
> -
> - /* Invert param2 and neg */
> - movd $-1, (r9, r8) /* Temp set to FFFFFFFF */
> - xord (r9, r8), (r5, r4) /* Xor low bits of param 2 with temp */
> - xord (r9, r8), (r7, r6) /* Xor high bits of param 2 with temp */
> - addd $1, (r5, r4) /* Add 1 to low bits of param 2 */
> - xorw $1, r10 /* Invert neg */
> - bcc L5 /* If no carry occurred go to L5 */
> - addd $1, (r7, r6) /* Add 1 to high bits of param 2 */
> -
> -L5: stord (r5, r4), 8(sp)
> - stord (r7, r6), 12(sp)
> - movw $0, r2
> -
> - /* Call udivmoddi3 */
> -#ifdef __PIC__
> - loadd ___udivmoddi3@cGOT(r12), (r1,r0)
> - jal (r1,r0)
> -#else
> - bal (ra), ___udivmoddi3
> -#endif
> -
> - /* If (neg) */
> - addd $16, (sp)
> - cmpw $0, r10 /* Compare 0 with neg */
> - beq Lexit__
> -
> - /* Neg = -Neg */
> - xord (r9, r8), (r1, r0) /* Xor low bits of ures with temp */
> - xord (r9, r8), (r3, r2) /* Xor high bits of ures with temp */
> - addd $1, (r1, r0) /* Add 1 to low bits of ures */
> - bcc Lexit__
> - addd $1, (r3, r2) /* Add 1 to high bit of ures */
> -
> -Lexit__:
> -# ifdef __ID_SHARED_LIB__
> - pop $2, r12
> -# endif
> - popret $4, r7, ra
> -#endif
> -
> -#ifdef L_lshrdi3
> - .text
> - .align 4
> - .globl ___lshrdi3
> -
> -___lshrdi3:
> - push $3, r7
> -
> - /* Load parameters from stack in this order */
> - movw r2, r6 /* Number of shifts */
> - loadd 6(sp), (r1, r0) /* Low bits */
> - loadd 10(sp), (r3, r2)/* High bits */
> -
> - xorw $-1, r6 /* Invert number of shifts */
> - addw $1, r6 /* Add 1 by number of shifts */
> -
> - movw r6, r7 /* Copy number of shifts */
> -
> - tbit $15, r6 /* Test if number is negative */
> - bfs L2 /* If negative jump to L2 */
> -
> - movd (r1, r0), (r9, r8) /* Copy low bits */
> -
> - subw $32, r7 /* Calc how many bits will overflow */
> - /* Shift the temp low bit to the right to see the overflowing bits */
> - lshd r7, (r9, r8)
> -
> - cmpw $32, r6 /* If number of shifts is higher than 31 */
> - blt L1 /* Shift by moving */
> -
> - lshd r6, (r3, r2) /* Shift high bits */
> - lshd r6, (r1, r0) /* Shift low bits */
> - addd (r9, r8), (r3, r2) /* Add overflow to the high bits */
> - popret $3, r7 /* Return */
> -
> -L1: movd $0, (r1, r0) /* Reset low bit */
> - movd (r9, r8), (r3, r2) /* Add the overflow from the low bit */
> - popret $3, r7 /* Return */
> -
> -L2: movd (r3, r2), (r9, r8) /* Copy high bits */
> -
> - addw $32, r7 /* Calc how many bits will overflow */
> - /* Shift the temp low bit to the left to see the overflowing bits */
> - lshd r7, (r9, r8)
> -
> - cmpw $-32, r6 /* If number of shifts is lower than -31 */
> - bgt L3 /* Shift by moving */
> -
> - lshd r6, (r1, r0) /* Shift low bits */
> - lshd r6, (r3, r2) /* Shift high bits */
> - addd (r9, r8), (r1, r0) /* Add overflow to the low bits */
> - popret $3, r7 /* Return */
> -
> -L3: movd $0, (r3, r2) /* Reset the high bit */
> - movd (r9, r8), (r1, r0) /* Add the overflow from the high bit */
> - popret $3, r7 /* Return */
> -#endif
> -
> -#ifdef L_moddi3
> - .text
> - .align 4
> - .globl ___moddi3
> -
> -___moddi3:
> - push $4, r7, ra
> -
> - /* Param #1 Long Long low bit first */
> - loadd 12(sp), (r1, r0)
> - loadd 16(sp), (r3, r2)
> -
> - /* Param #2 Long Long low bit first */
> - loadd 20(sp), (r5, r4)
> - loadd 24(sp), (r7, r6)
> -
> - subd $18, (sp)
> -
> - /* Set neg to 0 */
> - storw $0, 16(sp)
> -
> - movd $-1, (r9, r8) /* Temp set to FFFFFFFF */
> -
> - /* Compare if param1 is greater than 0 */
> - cmpw $0, r3
> - ble L4
> -
> - /* Invert param1 and neg */
> - xord (r9, r8), (r1, r0) /* Xor low bits of param 1 with temp */
> - xord (r9, r8), (r3, r2) /* Xor high bits of param 1 with temp */
> - addd $1, (r1, r0) /* Add 1 to low bits of param 1 */
> - storw $1, 16(sp)
> - bcc L4 /* If no carry occurred go to L4 */
> - addd $1, (r3, r2) /* Add 1 to high bits of param 1 */
> -
> -L4: stord (r1, r0), 0(sp)
> - stord (r3, r2), 4(sp)
> -
> - /* Compare if param2 is greater than 0 */
> - cmpw $0, r7
> - ble L5
> -
> - /* Invert param2 and neg */
> - xord (r9, r8), (r5, r4) /* Xor low bits of param 2 with temp */
> - xord (r9, r8), (r7, r6) /* Xor high bits of param 2 with temp */
> - addd $1, (r5, r4) /* Add 1 to low bits of param 2 */
> - bcc L5 /* If no carry occurred go to L5 */
> - addd $1, (r7, r6) /* Add 1 to high bits of param 2 */
> -
> -L5: stord (r5, r4), 8(sp)
> - stord (r7, r6), 12(sp)
> - movw $1, r2
> -
> - /* Call udivmoddi3 */
> -#ifdef __PIC__
> - loadd ___udivmoddi3@cGOT(r12), (r1,r0)
> - jal (r1,r0)
> -#else
> - bal (ra), ___udivmoddi3
> -#endif
> -
> - /* If (neg) */
> - loadw 16(sp), r10 /* Load neg from stack */
> - addd $18, (sp)
> - cmpw $0, r10 /* Compare 0 with neg */
> - beq Lexit__
> -
> - /* Neg = -Neg */
> - xord (r9, r8), (r1, r0) /* Xor low bits of ures with temp */
> - xord (r9, r8), (r3, r2) /* Xor high bits of ures with temp */
> - addd $1, (r1, r0) /* Add 1 to low bits of ures */
> - bcc Lexit__
> - addd $1, (r3, r2) /* Add 1 to high bit of ures */
> -Lexit__:
> -# ifdef __ID_SHARED_LIB__
> - pop $2, r12
> -# endif
> - popret $4, r7, ra
> -#endif
> -
> -#ifdef L_muldi3
> - .text
> - .align 4
> - .globl ___muldi3
> -
> -___muldi3:
> - push $2, r13
> - push $7, r7
> -
> - /* Param #1 Long Long low bit first */
> - loadd 18(sp), (r1, r0)
> - loadd 22(sp), (r3, r2)
> -
> - /* Param #2 Long Long low bit first */
> - loadd 26(sp), (r5, r4)
> - loadd 30(sp), (r7, r6)
> -
> - /* Clear r13, r12 */
> - movd $0, (r12)
> - movd $0, (r13)
> -
> - /* Set neg */
> - movw $0, r10
> -
> - /* Compare if param1 is greater than 0 */
> - cmpw $0, r3
> - ble L1
> -
> - /* Invert param1 and neg */
> - movd $-1, (r9, r8) /* Temp set to FFFFFFFF */
> - xord (r9, r8), (r1, r0) /* Xor low bits of param 1 with temp */
> - xord (r9, r8), (r3, r2) /* Xor high bits of param 1 with temp */
> - addd $1, (r1, r0) /* Add 1 to low bits of param 1 */
> - xorw $1, r10 /* Invert neg */
> - bcc L1 /* If no carry occurred go to L1 */
> - addd $1, (r3, r2) /* Add 1 to high bits of param 1 */
> -
> -L1: /* Compare if param2 is greater than 0 */
> - cmpw $0, r7
> - ble L2
> -
> - /* Invert param2 and neg */
> - movd $-1, (r9, r8) /* Temp set to FFFFFFFF */
> - xord (r9, r8), (r5, r4) /* Xor low bits of param 2 with temp */
> - xord (r9, r8), (r7, r6) /* Xor high bits of param 2 with temp */
> - addd $1, (r5, r4) /* Add 1 to low bits of param 2 */
> - xorw $1, r10 /* Invert neg */
> - bcc L2 /* If no carry occurred go to L2 */
> - addd $1, (r7, r6) /* Add 1 to high bits of param 2 */
> -
> -L2: storw r10, 18(sp) /* Store neg to stack so we can use r10 */
> -
> - /* B*D */
> - /* Bl*Dl */
> - macuw r0, r4, (r12) /* Multiply r0 and r4 and add to r12 */
> -
> - /* Bh*Dl */
> - movd $0, (r9, r8) /* Clear r9, r8 */
> - macuw r1, r4, (r9, r8) /* Multiply Bh*Dl and add result to (r9, r8) */
> - movw r9, r10 /* Shift left: r9 to r10 */
> - lshd $16, (r9, r8) /* Shift left: r8 to r9 */
> - movw $0, r11 /* Clear r11 */
> - addd (r9, r8), (r12) /* Add (r9, r8) to r12 */
> - bcc L3 /* If no carry occurred go to L3 */
> - addd $1, (r13) /* If carry occurred add 1 to r13 */
> -
> -L3: addd (r11, r10), (r13) /* Add (r11, r10) to r13 */
> -
> - /* Bl*Dh */
> - movd $0, (r9, r8) /* Clear (r9, r8) */
> - macuw r0, r5, (r9, r8) /* Multiply r0 and r5 and stor in (r9, r8) */
> - movw r9, r10 /* Shift left: r9 to r10 */
> - lshd $16, (r9, r8) /* Shift left: r8 to r9 */
> - addd (r9, r8), (r12) /* Add (r9, r8) to r12 */
> - bcc L4 /* If no carry occurred go to L4 */
> - addd $1, (r13) /* If carry occurred add 1 to r13 */
> -
> -L4: addd (r11, r10), (r13) /* Add (r11, r10) to r13 */
> -
> - /* Bh*Dh */
> - movd $0, (r9, r8) /* Clear (r9, r8) */
> - macuw r1, r5, (r9, r8) /* Multiply r1 and r5 and add to r13 */
> - addd (r9, r8), (r13) /* Add (r9, r8) to result */
> -
> - /* A*D */
> - /* Al*Dl */
> - movd $0, (r11, r10) /* Clear (r11, r10) */
> - macuw r2, r4, (r11, r10)/* Multiply r2 and r4 and add to (r11, r10) */
> -
> - addd (r13), (r11, r10) /* Copy r13 to (r11, r10) */
> -
> - /* Al*Dh */
> - movd $0, (r9, r8) /* Clear (r9, r8) */
> - macuw r2, r5, (r9, r8) /* Multiply r2 and r5 and add to (r9, r8) */
> - addw r8, r11 /* Add r8 to r11 */
> -
> - /* Ah*Dl */
> - muluw r3, (r5, r4) /* Multiply r3 and r4 and stor in (r5, r4) */
> - addw r4, r11 /* Add r4 to r11 */
> -
> - /* B*C */
> - /* Bl*Cl */
> - movd $0, (r9, r8) /* Clear (r9, r8) */
> - macuw r0, r6, (r9, r8) /* Multiply r0 and r6 and add to (r9, r8) */
> - addd (r9, r8), (r11, r10)/* Add (r9, r8) to result */
> -
> - /* Bl*Ch */
> - movd $0, (r9, r8) /* Clear (r9, r8) */
> - macuw r0, r7, (r9, r8) /* Multiply r0 and r7 and add to (r9, r8) */
> - addw r8, r11 /* Add r8 to r11 */
> -
> - loadw 18(sp), r8 /* Load neg from stack */
> -
> - /* Bh*Cl */
> - muluw r1, (r7, r6) /* Multiply r1 and r6 and stor in (r7, r6) */
> - addw r6, r11 /* Add r6 to r11 */
> -
> -E1: movd (r11, r10), (r3, r2)
> - movd (r12), (r1, r0)
> -
> - /* If (neg) */
> - cmpw $0, r8 /* Compare 0 with neg */
> - beq Lexit__
> -
> - /* Neg = -Neg */
> - movd $-1, (r9, r8) /* Temp set to FFFFFFFF */
> - xord (r9, r8), (r1, r0) /* Xor low bits of result with temp */
> - xord (r9, r8), (r3, r2) /* Xor high bits of result with temp */
> - addd $1, (r1, r0) /* Add 1 to low bits of result */
> - bcc Lexit__
> - addd $1, (r3, r2) /* Add 1 to high bit of result */
> -Lexit__:
> - pop $7, r7
> - popret $2, r13
> -#endif
> -
> -#ifdef L_negdi2
> - .text
> - .align 4
> - .globl ___negdi2
> -
> -___negdi2:
> - /* Load parameter from the registers in this order */
> - loadd 0(sp), (r1, r0)
> - loadd 4(sp), (r3, r2)
> -
> - movd $-1, (r6, r5) /* Set temp to FFFFFFFF */
> - xord (r6, r5), (r1, r0) /* Xor low bits with temp */
> - xord (r6, r5), (r3, r2) /* Xor high bits with temp */
> - addd $1, (r1, r0) /* Add one */
> - jcc (ra)
> - addd $1, (r3, r2) /* Add the carry to the high bits */
> - jump (ra)
> -#endif
> -
> -#ifdef L_udivdi3
> - .text
> - .align 4
> - .globl ___udivdi3
> -
> -___udivdi3:
> - movw $0, r2
> - br ___udivmoddi3
> -#endif
> -
> -#ifdef L_udivmoddi3
> - .text
> - .align 4
> - .globl ___udivmoddi3
> -
> -___udivmoddi3:
> - push $2, r13
> - push $7, r7
> -
> - /* Param #1 Long Long low bit first */
> - loadd 18(sp), (r1, r0)
> - storw r2, 18(sp) /* Store modulo on stack */
> - loadd 22(sp), (r3, r2)
> -
> - /* Param #2 Long Long low bit first */
> - loadd 26(sp), (r5, r4)
> - loadd 30(sp), (r7, r6)
> -
> - /* Set ures to 0 */
> - movd $0, (r13)
> - movd $0, (r12)
> -
> - cmpd (r12), (r5, r4)
> - beq LE
> -
> -L5: movd $1, (r9, r8) /* Store 1 in low bits from bit */
> - movd $0, (r11, r10) /* Store 0 in high bits from bit */
> -
> -L6: /* While (den < num && (!den & (1LL<<63))) */
> - /* Compare high bits from param 1 and param 2 */
> - cmpd (r7, r6), (r3, r2)
> - bhi L10 /* If param 2 is greater go to L10 */
> - bne L8 /* If param 1 is greater go to L8 */
> - cmpd (r5, r4), (r1, r0) /* Compare low bits from param 1 and param 2 */
> - /* If param 2 is greater or the same go to L1 */
> - bhs L10
> -
> -L8: /* Check if most significant bit of param 2 is set */
> - tbit $15, r7
> - bfs L10 /* If PSR is set go to L10 */
> -
> - /* Shift bit */
> - lshd $1, (r11, r10) /* Shift left: high bits of bit */
> - /* Check if most significant bit of bit is set */
> - tbit $15, r9
> - lshd $1, (r9, r8) /* Shift left: low bits of bit */
> - bfs L28 /* If PSR is set go to L28 */
> -
> -L9: /* Shift b */
> - lshd $1, (r7, r6) /* Shift left: high bits of param 2 */
> - /* Check if most significant bit of param 2 is set */
> - tbit $15, r5
> - lshd $1, (r5, r4) /* Shift left: low bits of param 2 */
> - bfc L6 /* If PSR is set go to L6 */
> - addw $1, r6 /* Add 1 to the highest bits of b */
> - br L6 /* Go to L6 */
> -
> -L10: /* While (bit) */
> - cmpd $0, (r11, r10)
> - bne L11
> - cmpd $0, (r9, r8)
> - beq E1
> -
> -L11: /* If (num >= den) */
> - cmpd (r3, r2), (r7, r6) /* Compare high bits of param 1 and param 2 */
> - blo L15 /* If param 1 lower than param 2 go to L15 */
> - bne L12 /* If not equal go to L12 */
> - cmpd (r1, r0), (r5, r4) /* Compare low bits of param 1 and param 2 */
> - blo L15 /* If param 1 lower than param 2 go to L15 */
> -
> -L12: /* Ures |= bit */
> - ord (r11, r10), (r13)
> - ord (r9, r8), (r12)
> -
> - /* Num -= den */
> - subd (r7, r6), (r3, r2) /* Subtract highest 32 bits from each other */
> - subd (r5, r4), (r1, r0) /* Subtract lowest 32 bits from each other */
> - bcc L15 /* If no carry occurred go to L15 */
> - subd $1, (r3, r2) /* Subtract the carry */
> -
> -L15: /* Shift bit to the right */
> - lshd $-1, (r9, r8) /* Shift right: low bits of bit */
> - /* Check if least significant bit of high bits is set */
> - tbit $0, r10
> - lshd $-1, (r11, r10) /* Shift right: high bits of bit */
> - bfs L18 /* If PSR is set go to L18 */
> -
> -L17: /* Shift param#2 to the right */
> - lshd $-1, (r5, r4) /* Shift right: low bits of param 2 */
> - /* Check if least significant bit of high bits is set */
> - tbit $0, r6
> - lshd $-1, (r7, r6) /* Shift right: high bits of param 2 */
> - bfc L10 /* If PSR is not set go to L10 */
> - /* Or with 0x8000 to set most significant bit */
> - orw $32768, r5
> - br L10 /* Go to L10 */
> -
> -L18: /* Or with 0x8000 to set most significant bit */
> - orw $32768, r9
> - br L17
> -
> -L28: /* Left shift bit */
> - addw $1, r10 /* Add 1 to highest bits of bit */
> - br L9 /* Go to L9 */
> -
> -LE: cmpd (r12), (r7, r6)
> - bne L5
> - excp dvz
> - br Lexit__
> -
> -E1: loadw 18(sp), r4
> - cmpw $0, r4
> - bne Lexit__
> -
> - /* Return result */
> - movd (r12), (r1, r0)
> - movd (r13), (r3, r2)
> -Lexit__:
> - pop $7, r7
> - popret $2, r13
> -#endif
> -
> -#ifdef L_umoddi3
> - .text
> - .align 4
> - .globl ___umoddi3
> -
> -___umoddi3:
> - movw $1, r2
> - br ___udivmoddi3
> -#endif
> -
> diff --git a/libgcc/config/cr16/t-cr16 b/libgcc/config/cr16/t-cr16
> deleted file mode 100644
> index 1e375d28100..00000000000
> --- a/libgcc/config/cr16/t-cr16
> +++ /dev/null
> @@ -1,29 +0,0 @@
> -# Makefile fragment for building LIBGCC for the Renesas CR16 target.
> -# Copyright (C) 2012-2022 Free Software Foundation, Inc.
> -#
> -# 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/>.
> -
> -LIB1ASMSRC = cr16/lib1funcs.S
> -LIB1ASMFUNCS = _mulsi3 _lshrdi3 _muldi3 _divdi3 _udivdi3 _udivmoddi3 \
> - _umoddi3 _moddi3
> -
> -LIB2ADD = $(srcdir)/config/cr16/divmodhi3.c \
> - $(srcdir)/udivmodsi4.c \
> - $(srcdir)/udivmod.c \
> - $(srcdir)/divmod.c
> -
> -LIB2ADDEH = $(srcdir)/config/cr16/unwind-cr16.c
> diff --git a/libgcc/config/cr16/t-crtlibid b/libgcc/config/cr16/t-crtlibid
> deleted file mode 100644
> index 86cc5c6340f..00000000000
> --- a/libgcc/config/cr16/t-crtlibid
> +++ /dev/null
> @@ -1,22 +0,0 @@
> -# Makefile fragment for building LIBGCC for the Renesas CR16 target.
> -# Copyright (C) 2012-2022 Free Software Foundation, Inc.
> -#
> -# 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/>.
> -
> -# Assemble startup files.
> -crtlibid.o: $(srcdir)/config/cr16/crtlibid.S
> - $(gcc_compile) -c -x assembler-with-cpp $<
> diff --git a/libgcc/config/cr16/unwind-cr16.c b/libgcc/config/cr16/unwind-cr16.c
> deleted file mode 100644
> index 8625da837b1..00000000000
> --- a/libgcc/config/cr16/unwind-cr16.c
> +++ /dev/null
> @@ -1,1682 +0,0 @@
> -/* DWARF2 exception handling and frame unwind runtime interface routines.
> - Copyright (C) 1997-2022 Free Software Foundation, Inc.
> -
> - 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.
> -
> - Under Section 7 of GPL version 3, you are granted additional
> - permissions described in the GCC Runtime Library Exception, version
> - 3.1, as published by the Free Software Foundation.
> -
> - You should have received a copy of the GNU General Public License and
> - a copy of the GCC Runtime Library Exception along with this program;
> - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
> - <http://www.gnu.org/licenses/>. */
> -
> -#include "tconfig.h"
> -#include "tsystem.h"
> -#include "coretypes.h"
> -#include "tm.h"
> -#include "dwarf2.h"
> -#include "unwind.h"
> -#ifdef __USING_SJLJ_EXCEPTIONS__
> -# define NO_SIZE_OF_ENCODED_VALUE
> -#endif
> -#include "unwind-pe.h"
> -#include "unwind-dw2-fde.h"
> -#include "gthr.h"
> -#include "unwind-dw2.h"
> -
> -#ifdef HAVE_SYS_SDT_H
> -#include <sys/sdt.h>
> -#endif
> -
> -#ifndef __USING_SJLJ_EXCEPTIONS__
> -
> -#ifndef __LIBGCC_STACK_GROWS_DOWNWARD__
> -#define __LIBGCC_STACK_GROWS_DOWNWARD__ 0
> -#else
> -#undef __LIBGCC_STACK_GROWS_DOWNWARD__
> -#define __LIBGCC_STACK_GROWS_DOWNWARD__ 1
> -#endif
> -
> -/* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
> -#ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
> -#define PRE_GCC3_DWARF_FRAME_REGISTERS __LIBGCC_DWARF_FRAME_REGISTERS__
> -#endif
> -
> -#ifndef DWARF_REG_TO_UNWIND_COLUMN
> -#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
> -#endif
> -
> -#ifdef REG_VALUE_IN_UNWIND_CONTEXT
> -typedef _Unwind_Word _Unwind_Context_Reg_Val;
> -
> -#ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
> -#define ASSUME_EXTENDED_UNWIND_CONTEXT 1
> -#endif
> -
> -static inline _Unwind_Word
> -_Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val)
> -{
> - return val;
> -}
> -
> -static inline _Unwind_Context_Reg_Val
> -_Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val)
> -{
> - return val;
> -}
> -#else
> -typedef void *_Unwind_Context_Reg_Val;
> -
> -static inline _Unwind_Word
> -_Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val)
> -{
> - return (_Unwind_Word) (_Unwind_Internal_Ptr) val;
> -}
> -
> -static inline _Unwind_Context_Reg_Val
> -_Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val)
> -{
> - return (_Unwind_Context_Reg_Val) (_Unwind_Internal_Ptr) val;
> -}
> -#endif
> -
> -#ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
> -#define ASSUME_EXTENDED_UNWIND_CONTEXT 0
> -#endif
> -
> -/* This is the register and unwind state for a particular frame. This
> - provides the information necessary to unwind up past a frame and return
> - to its caller. */
> -struct _Unwind_Context
> -{
> - _Unwind_Context_Reg_Val reg[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
> - void *cfa;
> - void *ra;
> - void *lsda;
> - struct dwarf_eh_bases bases;
> - /* Signal frame context. */
> -#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
> - /* Context which has version/args_size/by_value fields. */
> -#define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
> - _Unwind_Word flags;
> - /* 0 for now, can be increased when further fields are added to
> - struct _Unwind_Context. */
> - _Unwind_Word version;
> - _Unwind_Word args_size;
> - char by_value[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
> -};
> -
> -/* Byte size of every register managed by these routines. */
> -static unsigned char dwarf_reg_size_table[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
> -
> -
> -/* Read unaligned data from the instruction buffer. */
> -
> -union unaligned
> -{
> - void *p;
> - unsigned u2 __attribute__ ((mode (HI)));
> - unsigned u4 __attribute__ ((mode (SI)));
> - unsigned u8 __attribute__ ((mode (DI)));
> - signed s2 __attribute__ ((mode (HI)));
> - signed s4 __attribute__ ((mode (SI)));
> - signed s8 __attribute__ ((mode (DI)));
> -} __attribute__ ((packed));
> -
> -static void uw_update_context (struct _Unwind_Context *, _Unwind_FrameState *);
> -static _Unwind_Reason_Code uw_frame_state_for (struct _Unwind_Context *,
> - _Unwind_FrameState *);
> -
> -static inline void *
> -read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
> -
> -static inline int
> -read_1u (const void *p) { return *(const unsigned char *) p; }
> -
> -static inline int
> -read_1s (const void *p) { return *(const signed char *) p; }
> -
> -static inline int
> -read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
> -
> -static inline int
> -read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
> -
> -static inline unsigned int
> -read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
> -
> -static inline int
> -read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
> -
> -static inline unsigned long
> -read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
> -
> -static inline unsigned long
> -read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
> -
> -static inline _Unwind_Word
> -_Unwind_IsSignalFrame (struct _Unwind_Context *context)
> -{
> - return (context->flags & SIGNAL_FRAME_BIT) ? 1 : 0;
> -}
> -
> -static inline void
> -_Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
> -{
> - if (val)
> - context->flags |= SIGNAL_FRAME_BIT;
> - else
> - context->flags &= ~SIGNAL_FRAME_BIT;
> -}
> -
> -static inline _Unwind_Word
> -_Unwind_IsExtendedContext (struct _Unwind_Context *context)
> -{
> - return (ASSUME_EXTENDED_UNWIND_CONTEXT
> - || (context->flags & EXTENDED_CONTEXT_BIT));
> -}
> -
> -/* Get the value of register INDEX as saved in CONTEXT. */
> -
> -inline _Unwind_Word
> -_Unwind_GetGR (struct _Unwind_Context *context, int index)
> -{
> - int size;
> - _Unwind_Context_Reg_Val val;
> -
> -#ifdef DWARF_ZERO_REG
> - if (index == DWARF_ZERO_REG)
> - return 0;
> -#endif
> -
> - index = DWARF_REG_TO_UNWIND_COLUMN (index);
> - gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
> - size = dwarf_reg_size_table[index];
> - val = context->reg[index];
> -
> - if (_Unwind_IsExtendedContext (context) && context->by_value[index])
> - return _Unwind_Get_Unwind_Word (val);
> -
> - /* This will segfault if the register hasn't been saved. */
> - if (size == sizeof(_Unwind_Ptr))
> - return * (_Unwind_Ptr *) (_Unwind_Internal_Ptr) val;
> - else
> - {
> - gcc_assert (size == sizeof(_Unwind_Word));
> - return * (_Unwind_Word *) (_Unwind_Internal_Ptr) val;
> - }
> -}
> -
> -static inline void *
> -_Unwind_GetPtr (struct _Unwind_Context *context, int index)
> -{
> - return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
> -}
> -
> -/* Get the value of the CFA as saved in CONTEXT. */
> -
> -_Unwind_Word
> -_Unwind_GetCFA (struct _Unwind_Context *context)
> -{
> - return (_Unwind_Ptr) context->cfa;
> -}
> -
> -/* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
> -
> -inline void
> -_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
> -{
> - int size;
> - void *ptr;
> -
> - index = DWARF_REG_TO_UNWIND_COLUMN (index);
> - gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
> - size = dwarf_reg_size_table[index];
> -
> - if (_Unwind_IsExtendedContext (context) && context->by_value[index])
> - {
> - context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
> - return;
> - }
> -
> - ptr = (void *) (_Unwind_Internal_Ptr) context->reg[index];
> -
> - if (size == sizeof(_Unwind_Ptr))
> - * (_Unwind_Ptr *) ptr = val;
> - else
> - {
> -#if defined( __CR16C__ )
> - if (size == sizeof(_Unwind_Word))
> - * (_Unwind_Word *) ptr = val;
> - else
> - {
> - typedef unsigned _CR16_Unwind_Word __attribute__((__mode__(__word__)));
> - gcc_assert (index + 1 < (int) sizeof(dwarf_reg_size_table));
> - * (_CR16_Unwind_Word *) ptr = val & 0xffff ; /* low 16-bit */
> - ptr = context->reg[index + 1];
> - * (_CR16_Unwind_Word *) ptr = val >> 16 ; /* high 16-bit */
> - }
> -#else
> - gcc_assert (size == sizeof(_Unwind_Word));
> - * (_Unwind_Word *) ptr = val;
> -#endif
> - }
> -}
> -
> -/* Get the pointer to a register INDEX as saved in CONTEXT. */
> -
> -static inline void *
> -_Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
> -{
> - index = DWARF_REG_TO_UNWIND_COLUMN (index);
> - if (_Unwind_IsExtendedContext (context) && context->by_value[index])
> - return &context->reg[index];
> - return (void *) (_Unwind_Internal_Ptr) context->reg[index];
> -}
> -
> -/* Set the pointer to a register INDEX as saved in CONTEXT. */
> -
> -static inline void
> -_Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
> -{
> - index = DWARF_REG_TO_UNWIND_COLUMN (index);
> - if (_Unwind_IsExtendedContext (context))
> - context->by_value[index] = 0;
> - context->reg[index] = (_Unwind_Context_Reg_Val) (_Unwind_Internal_Ptr) p;
> -}
> -
> -/* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
> -
> -static inline void
> -_Unwind_SetGRValue (struct _Unwind_Context *context, int index,
> - _Unwind_Word val)
> -{
> - index = DWARF_REG_TO_UNWIND_COLUMN (index);
> - gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
> - gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Context_Reg_Val));
> -
> - context->by_value[index] = 1;
> - context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
> -}
> -
> -/* Return nonzero if register INDEX is stored by value rather than
> - by reference. */
> -
> -static inline int
> -_Unwind_GRByValue (struct _Unwind_Context *context, int index)
> -{
> - index = DWARF_REG_TO_UNWIND_COLUMN (index);
> - return context->by_value[index];
> -}
> -
> -/* Retrieve the return address for CONTEXT. */
> -
> -inline _Unwind_Ptr
> -_Unwind_GetIP (struct _Unwind_Context *context)
> -{
> - return (_Unwind_Ptr) context->ra;
> -}
> -
> -/* Retrieve the return address and flag whether that IP is before
> - or after first not yet fully executed instruction. */
> -
> -inline _Unwind_Ptr
> -_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
> -{
> - *ip_before_insn = _Unwind_IsSignalFrame (context);
> - return (_Unwind_Ptr) context->ra;
> -}
> -
> -/* Overwrite the return address for CONTEXT with VAL. */
> -
> -inline void
> -_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
> -{
> - context->ra = (void *) val;
> -}
> -
> -void *
> -_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
> -{
> - return context->lsda;
> -}
> -
> -_Unwind_Ptr
> -_Unwind_GetRegionStart (struct _Unwind_Context *context)
> -{
> - return (_Unwind_Ptr) context->bases.func;
> -}
> -
> -void *
> -_Unwind_FindEnclosingFunction (void *pc)
> -{
> - struct dwarf_eh_bases bases;
> - const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
> - if (fde)
> - return bases.func;
> - else
> - return NULL;
> -}
> -
> -_Unwind_Ptr
> -_Unwind_GetDataRelBase (struct _Unwind_Context *context)
> -{
> - return (_Unwind_Ptr) context->bases.dbase;
> -}
> -
> -_Unwind_Ptr
> -_Unwind_GetTextRelBase (struct _Unwind_Context *context)
> -{
> - return (_Unwind_Ptr) context->bases.tbase;
> -}
> -
> -#include "md-unwind-support.h"
> -
> -/* Extract any interesting information from the CIE for the translation
> - unit F belongs to. Return a pointer to the byte after the augmentation,
> - or NULL if we encountered an undecipherable augmentation. */
> -
> -static const unsigned char *
> -extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
> - _Unwind_FrameState *fs)
> -{
> - const unsigned char *aug = cie->augmentation;
> - const unsigned char *p = aug + strlen ((const char *)aug) + 1;
> - const unsigned char *ret = NULL;
> - _uleb128_t utmp;
> - _sleb128_t stmp;
> -
> - /* g++ v2 "eh" has pointer immediately following augmentation string,
> - so it must be handled first. */
> - if (aug[0] == 'e' && aug[1] == 'h')
> - {
> - fs->eh_ptr = read_pointer (p);
> - p += sizeof (void *);
> - aug += 2;
> - }
> -
> - /* After the augmentation resp. pointer for "eh" augmentation
> - follows for CIE version >= 4 address size byte and
> - segment size byte. */
> - if (__builtin_expect (cie->version >= 4, 0))
> - {
> - if (p[0] != sizeof (void *) || p[1] != 0)
> - return NULL;
> - p += 2;
> - }
> - /* Immediately following this are the code and
> - data alignment and return address column. */
> - p = read_uleb128 (p, &utmp);
> - fs->code_align = (_Unwind_Word)utmp;
> - p = read_sleb128 (p, &stmp);
> - fs->data_align = (_Unwind_Sword)stmp;
> - if (cie->version == 1)
> - fs->retaddr_column = *p++;
> - else
> - {
> - p = read_uleb128 (p, &utmp);
> - fs->retaddr_column = (_Unwind_Word)utmp;
> - }
> - fs->lsda_encoding = DW_EH_PE_omit;
> -
> - /* If the augmentation starts with 'z', then a uleb128 immediately
> - follows containing the length of the augmentation field following
> - the size. */
> - if (*aug == 'z')
> - {
> - p = read_uleb128 (p, &utmp);
> - ret = p + utmp;
> -
> - fs->saw_z = 1;
> - ++aug;
> - }
> -
> - /* Iterate over recognized augmentation subsequences. */
> - while (*aug != '\0')
> - {
> - /* "L" indicates a byte showing how the LSDA pointer is encoded. */
> - if (aug[0] == 'L')
> - {
> - fs->lsda_encoding = *p++;
> - aug += 1;
> - }
> -
> - /* "R" indicates a byte indicating how FDE addresses are encoded. */
> - else if (aug[0] == 'R')
> - {
> - fs->fde_encoding = *p++;
> - aug += 1;
> - }
> -
> - /* "P" indicates a personality routine in the CIE augmentation. */
> - else if (aug[0] == 'P')
> - {
> - _Unwind_Ptr personality;
> -
> - p = read_encoded_value (context, *p, p + 1, &personality);
> - fs->personality = (_Unwind_Personality_Fn) personality;
> - aug += 1;
> - }
> -
> - /* "S" indicates a signal frame. */
> - else if (aug[0] == 'S')
> - {
> - fs->signal_frame = 1;
> - aug += 1;
> - }
> -
> - /* Otherwise we have an unknown augmentation string.
> - Bail unless we saw a 'z' prefix. */
> - else
> - return ret;
> - }
> -
> - return ret ? ret : p;
> -}
> -
> -
> -/* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
> - onto the stack to start. */
> -
> -static _Unwind_Word
> -execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
> - struct _Unwind_Context *context, _Unwind_Word initial)
> -{
> - _Unwind_Word stack[64]; /* ??? Assume this is enough. */
> - int stack_elt;
> -
> - stack[0] = initial;
> - stack_elt = 1;
> -
> - while (op_ptr < op_end)
> - {
> - enum dwarf_location_atom op = *op_ptr++;
> - _Unwind_Word result;
> - _uleb128_t reg, utmp;
> - _sleb128_t offset, stmp;
> -
> - switch (op)
> - {
> - case DW_OP_lit0:
> - case DW_OP_lit1:
> - case DW_OP_lit2:
> - case DW_OP_lit3:
> - case DW_OP_lit4:
> - case DW_OP_lit5:
> - case DW_OP_lit6:
> - case DW_OP_lit7:
> - case DW_OP_lit8:
> - case DW_OP_lit9:
> - case DW_OP_lit10:
> - case DW_OP_lit11:
> - case DW_OP_lit12:
> - case DW_OP_lit13:
> - case DW_OP_lit14:
> - case DW_OP_lit15:
> - case DW_OP_lit16:
> - case DW_OP_lit17:
> - case DW_OP_lit18:
> - case DW_OP_lit19:
> - case DW_OP_lit20:
> - case DW_OP_lit21:
> - case DW_OP_lit22:
> - case DW_OP_lit23:
> - case DW_OP_lit24:
> - case DW_OP_lit25:
> - case DW_OP_lit26:
> - case DW_OP_lit27:
> - case DW_OP_lit28:
> - case DW_OP_lit29:
> - case DW_OP_lit30:
> - case DW_OP_lit31:
> - result = op - DW_OP_lit0;
> - break;
> -
> - case DW_OP_addr:
> - result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
> - op_ptr += sizeof (void *);
> - break;
> -
> - case DW_OP_GNU_encoded_addr:
> - {
> - _Unwind_Ptr presult;
> - op_ptr = read_encoded_value (context, *op_ptr, op_ptr+1, &presult);
> - result = presult;
> - }
> - break;
> -
> - case DW_OP_const1u:
> - result = read_1u (op_ptr);
> - op_ptr += 1;
> - break;
> - case DW_OP_const1s:
> - result = read_1s (op_ptr);
> - op_ptr += 1;
> - break;
> - case DW_OP_const2u:
> - result = read_2u (op_ptr);
> - op_ptr += 2;
> - break;
> - case DW_OP_const2s:
> - result = read_2s (op_ptr);
> - op_ptr += 2;
> - break;
> - case DW_OP_const4u:
> - result = read_4u (op_ptr);
> - op_ptr += 4;
> - break;
> - case DW_OP_const4s:
> - result = read_4s (op_ptr);
> - op_ptr += 4;
> - break;
> - case DW_OP_const8u:
> - result = read_8u (op_ptr);
> - op_ptr += 8;
> - break;
> - case DW_OP_const8s:
> - result = read_8s (op_ptr);
> - op_ptr += 8;
> - break;
> - case DW_OP_constu:
> - op_ptr = read_uleb128 (op_ptr, &utmp);
> - result = (_Unwind_Word)utmp;
> - break;
> - case DW_OP_consts:
> - op_ptr = read_sleb128 (op_ptr, &stmp);
> - result = (_Unwind_Sword)stmp;
> - break;
> -
> - case DW_OP_reg0:
> - case DW_OP_reg1:
> - case DW_OP_reg2:
> - case DW_OP_reg3:
> - case DW_OP_reg4:
> - case DW_OP_reg5:
> - case DW_OP_reg6:
> - case DW_OP_reg7:
> - case DW_OP_reg8:
> - case DW_OP_reg9:
> - case DW_OP_reg10:
> - case DW_OP_reg11:
> - case DW_OP_reg12:
> - case DW_OP_reg13:
> - case DW_OP_reg14:
> - case DW_OP_reg15:
> - case DW_OP_reg16:
> - case DW_OP_reg17:
> - case DW_OP_reg18:
> - case DW_OP_reg19:
> - case DW_OP_reg20:
> - case DW_OP_reg21:
> - case DW_OP_reg22:
> - case DW_OP_reg23:
> - case DW_OP_reg24:
> - case DW_OP_reg25:
> - case DW_OP_reg26:
> - case DW_OP_reg27:
> - case DW_OP_reg28:
> - case DW_OP_reg29:
> - case DW_OP_reg30:
> - case DW_OP_reg31:
> - result = _Unwind_GetGR (context, op - DW_OP_reg0);
> - break;
> - case DW_OP_regx:
> - op_ptr = read_uleb128 (op_ptr, ®);
> - result = _Unwind_GetGR (context, reg);
> - break;
> -
> - case DW_OP_breg0:
> - case DW_OP_breg1:
> - case DW_OP_breg2:
> - case DW_OP_breg3:
> - case DW_OP_breg4:
> - case DW_OP_breg5:
> - case DW_OP_breg6:
> - case DW_OP_breg7:
> - case DW_OP_breg8:
> - case DW_OP_breg9:
> - case DW_OP_breg10:
> - case DW_OP_breg11:
> - case DW_OP_breg12:
> - case DW_OP_breg13:
> - case DW_OP_breg14:
> - case DW_OP_breg15:
> - case DW_OP_breg16:
> - case DW_OP_breg17:
> - case DW_OP_breg18:
> - case DW_OP_breg19:
> - case DW_OP_breg20:
> - case DW_OP_breg21:
> - case DW_OP_breg22:
> - case DW_OP_breg23:
> - case DW_OP_breg24:
> - case DW_OP_breg25:
> - case DW_OP_breg26:
> - case DW_OP_breg27:
> - case DW_OP_breg28:
> - case DW_OP_breg29:
> - case DW_OP_breg30:
> - case DW_OP_breg31:
> - op_ptr = read_sleb128 (op_ptr, &offset);
> - result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
> - break;
> - case DW_OP_bregx:
> - op_ptr = read_uleb128 (op_ptr, ®);
> - op_ptr = read_sleb128 (op_ptr, &offset);
> - result = _Unwind_GetGR (context, reg) + (_Unwind_Word)offset;
> - break;
> -
> - case DW_OP_dup:
> - gcc_assert (stack_elt);
> - result = stack[stack_elt - 1];
> - break;
> -
> - case DW_OP_drop:
> - gcc_assert (stack_elt);
> - stack_elt -= 1;
> - goto no_push;
> -
> - case DW_OP_pick:
> - offset = *op_ptr++;
> - gcc_assert (offset < stack_elt - 1);
> - result = stack[stack_elt - 1 - offset];
> - break;
> -
> - case DW_OP_over:
> - gcc_assert (stack_elt >= 2);
> - result = stack[stack_elt - 2];
> - break;
> -
> - case DW_OP_swap:
> - {
> - _Unwind_Word t;
> - gcc_assert (stack_elt >= 2);
> - t = stack[stack_elt - 1];
> - stack[stack_elt - 1] = stack[stack_elt - 2];
> - stack[stack_elt - 2] = t;
> - goto no_push;
> - }
> -
> - case DW_OP_rot:
> - {
> - _Unwind_Word t1, t2, t3;
> -
> - gcc_assert (stack_elt >= 3);
> - t1 = stack[stack_elt - 1];
> - t2 = stack[stack_elt - 2];
> - t3 = stack[stack_elt - 3];
> - stack[stack_elt - 1] = t2;
> - stack[stack_elt - 2] = t3;
> - stack[stack_elt - 3] = t1;
> - goto no_push;
> - }
> -
> - case DW_OP_deref:
> - case DW_OP_deref_size:
> - case DW_OP_abs:
> - case DW_OP_neg:
> - case DW_OP_not:
> - case DW_OP_plus_uconst:
> - /* Unary operations. */
> - gcc_assert (stack_elt);
> - stack_elt -= 1;
> -
> - result = stack[stack_elt];
> -
> - switch (op)
> - {
> - case DW_OP_deref:
> - {
> - void *ptr = (void *) (_Unwind_Ptr) result;
> - result = (_Unwind_Ptr) read_pointer (ptr);
> - }
> - break;
> -
> - case DW_OP_deref_size:
> - {
> - void *ptr = (void *) (_Unwind_Ptr) result;
> - switch (*op_ptr++)
> - {
> - case 1:
> - result = read_1u (ptr);
> - break;
> - case 2:
> - result = read_2u (ptr);
> - break;
> - case 4:
> - result = read_4u (ptr);
> - break;
> - case 8:
> - result = read_8u (ptr);
> - break;
> - default:
> - gcc_unreachable ();
> - }
> - }
> - break;
> -
> - case DW_OP_abs:
> - if ((_Unwind_Sword) result < 0)
> - result = -result;
> - break;
> - case DW_OP_neg:
> - result = -result;
> - break;
> - case DW_OP_not:
> - result = ~result;
> - break;
> - case DW_OP_plus_uconst:
> - op_ptr = read_uleb128 (op_ptr, &utmp);
> - result += (_Unwind_Word)utmp;
> - break;
> -
> - default:
> - gcc_unreachable ();
> - }
> - break;
> -
> - case DW_OP_and:
> - case DW_OP_div:
> - case DW_OP_minus:
> - case DW_OP_mod:
> - case DW_OP_mul:
> - case DW_OP_or:
> - case DW_OP_plus:
> - case DW_OP_shl:
> - case DW_OP_shr:
> - case DW_OP_shra:
> - case DW_OP_xor:
> - case DW_OP_le:
> - case DW_OP_ge:
> - case DW_OP_eq:
> - case DW_OP_lt:
> - case DW_OP_gt:
> - case DW_OP_ne:
> - {
> - /* Binary operations. */
> - _Unwind_Word first, second;
> - gcc_assert (stack_elt >= 2);
> - stack_elt -= 2;
> -
> - second = stack[stack_elt];
> - first = stack[stack_elt + 1];
> -
> - switch (op)
> - {
> - case DW_OP_and:
> - result = second & first;
> - break;
> - case DW_OP_div:
> - result = (_Unwind_Sword) second / (_Unwind_Sword) first;
> - break;
> - case DW_OP_minus:
> - result = second - first;
> - break;
> - case DW_OP_mod:
> - result = second % first;
> - break;
> - case DW_OP_mul:
> - result = second * first;
> - break;
> - case DW_OP_or:
> - result = second | first;
> - break;
> - case DW_OP_plus:
> - result = second + first;
> - break;
> - case DW_OP_shl:
> - result = second << first;
> - break;
> - case DW_OP_shr:
> - result = second >> first;
> - break;
> - case DW_OP_shra:
> - result = (_Unwind_Sword) second >> first;
> - break;
> - case DW_OP_xor:
> - result = second ^ first;
> - break;
> - case DW_OP_le:
> - result = (_Unwind_Sword) second <= (_Unwind_Sword) first;
> - break;
> - case DW_OP_ge:
> - result = (_Unwind_Sword) second >= (_Unwind_Sword) first;
> - break;
> - case DW_OP_eq:
> - result = (_Unwind_Sword) second == (_Unwind_Sword) first;
> - break;
> - case DW_OP_lt:
> - result = (_Unwind_Sword) second < (_Unwind_Sword) first;
> - break;
> - case DW_OP_gt:
> - result = (_Unwind_Sword) second > (_Unwind_Sword) first;
> - break;
> - case DW_OP_ne:
> - result = (_Unwind_Sword) second != (_Unwind_Sword) first;
> - break;
> -
> - default:
> - gcc_unreachable ();
> - }
> - }
> - break;
> -
> - case DW_OP_skip:
> - offset = read_2s (op_ptr);
> - op_ptr += 2;
> - op_ptr += offset;
> - goto no_push;
> -
> - case DW_OP_bra:
> - gcc_assert (stack_elt);
> - stack_elt -= 1;
> -
> - offset = read_2s (op_ptr);
> - op_ptr += 2;
> - if (stack[stack_elt] != 0)
> - op_ptr += offset;
> - goto no_push;
> -
> - case DW_OP_nop:
> - goto no_push;
> -
> - default:
> - gcc_unreachable ();
> - }
> -
> - /* Most things push a result value. */
> - gcc_assert ((size_t) stack_elt < sizeof(stack)/sizeof(*stack));
> - stack[stack_elt++] = result;
> - no_push:;
> - }
> -
> - /* We were executing this program to get a value. It should be
> - at top of stack. */
> - gcc_assert (stack_elt);
> - stack_elt -= 1;
> - return stack[stack_elt];
> -}
> -
> -
> -/* Decode DWARF 2 call frame information. Takes pointers the
> - instruction sequence to decode, current register information and
> - CIE info, and the PC range to evaluate. */
> -
> -static void
> -execute_cfa_program (const unsigned char *insn_ptr,
> - const unsigned char *insn_end,
> - struct _Unwind_Context *context,
> - _Unwind_FrameState *fs)
> -{
> - struct frame_state_reg_info *unused_rs = NULL;
> -
> - /* Don't allow remember/restore between CIE and FDE programs. */
> - fs->regs.prev = NULL;
> -
> - /* The comparison with the return address uses < rather than <= because
> - we are only interested in the effects of code before the call; for a
> - noreturn function, the return address may point to unrelated code with
> - a different stack configuration that we are not interested in. We
> - assume that the call itself is unwind info-neutral; if not, or if
> - there are delay instructions that adjust the stack, these must be
> - reflected at the point immediately before the call insn.
> - In signal frames, return address is after last completed instruction,
> - so we add 1 to return address to make the comparison <=. */
> - while (insn_ptr < insn_end
> - && fs->pc < context->ra + _Unwind_IsSignalFrame (context))
> - {
> - unsigned char insn = *insn_ptr++;
> - _uleb128_t reg, utmp;
> - _sleb128_t offset, stmp;
> -
> - if ((insn & 0xc0) == DW_CFA_advance_loc)
> - fs->pc += (insn & 0x3f) * fs->code_align;
> - else if ((insn & 0xc0) == DW_CFA_offset)
> - {
> - reg = insn & 0x3f;
> - insn_ptr = read_uleb128 (insn_ptr, &utmp);
> - offset = (_Unwind_Sword) utmp * fs->data_align;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
> - = REG_SAVED_OFFSET;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
> - }
> - else if ((insn & 0xc0) == DW_CFA_restore)
> - {
> - reg = insn & 0x3f;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
> - }
> - else switch (insn)
> - {
> - case DW_CFA_set_loc:
> - {
> - _Unwind_Ptr pc;
> -
> - insn_ptr = read_encoded_value (context, fs->fde_encoding,
> - insn_ptr, &pc);
> - fs->pc = (void *) pc;
> - }
> - break;
> -
> - case DW_CFA_advance_loc1:
> - fs->pc += read_1u (insn_ptr) * fs->code_align;
> - insn_ptr += 1;
> - break;
> - case DW_CFA_advance_loc2:
> - fs->pc += read_2u (insn_ptr) * fs->code_align;
> - insn_ptr += 2;
> - break;
> - case DW_CFA_advance_loc4:
> - fs->pc += read_4u (insn_ptr) * fs->code_align;
> - insn_ptr += 4;
> - break;
> -
> - case DW_CFA_offset_extended:
> - insn_ptr = read_uleb128 (insn_ptr, ®);
> - insn_ptr = read_uleb128 (insn_ptr, &utmp);
> - offset = (_Unwind_Sword) utmp * fs->data_align;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
> - = REG_SAVED_OFFSET;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
> - break;
> -
> - case DW_CFA_restore_extended:
> - insn_ptr = read_uleb128 (insn_ptr, ®);
> - /* FIXME, this is wrong; the CIE might have said that the
> - register was saved somewhere. */
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
> - break;
> -
> - case DW_CFA_same_value:
> - insn_ptr = read_uleb128 (insn_ptr, ®);
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
> - break;
> -
> - case DW_CFA_undefined:
> - insn_ptr = read_uleb128 (insn_ptr, ®);
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNDEFINED;
> - break;
> -
> - case DW_CFA_nop:
> - break;
> -
> - case DW_CFA_register:
> - {
> - _uleb128_t reg2;
> - insn_ptr = read_uleb128 (insn_ptr, ®);
> - insn_ptr = read_uleb128 (insn_ptr, ®2);
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg =
> - (_Unwind_Word)reg2;
> - }
> - break;
> -
> - case DW_CFA_remember_state:
> - {
> - struct frame_state_reg_info *new_rs;
> - if (unused_rs)
> - {
> - new_rs = unused_rs;
> - unused_rs = unused_rs->prev;
> - }
> - else
> - new_rs = alloca (sizeof (struct frame_state_reg_info));
> -
> - *new_rs = fs->regs;
> - fs->regs.prev = new_rs;
> - }
> - break;
> -
> - case DW_CFA_restore_state:
> - {
> - struct frame_state_reg_info *old_rs = fs->regs.prev;
> - fs->regs = *old_rs;
> - old_rs->prev = unused_rs;
> - unused_rs = old_rs;
> - }
> - break;
> -
> - case DW_CFA_def_cfa:
> - insn_ptr = read_uleb128 (insn_ptr, &utmp);
> - fs->regs.cfa_reg = (_Unwind_Word)utmp;
> - insn_ptr = read_uleb128 (insn_ptr, &utmp);
> - fs->regs.cfa_offset = (_Unwind_Word)utmp;
> - fs->regs.cfa_how = CFA_REG_OFFSET;
> - break;
> -
> - case DW_CFA_def_cfa_register:
> - insn_ptr = read_uleb128 (insn_ptr, &utmp);
> - fs->regs.cfa_reg = (_Unwind_Word)utmp;
> - fs->regs.cfa_how = CFA_REG_OFFSET;
> - break;
> -
> - case DW_CFA_def_cfa_offset:
> - insn_ptr = read_uleb128 (insn_ptr, &utmp);
> - fs->regs.cfa_offset = utmp;
> - /* cfa_how deliberately not set. */
> - break;
> -
> - case DW_CFA_def_cfa_expression:
> - fs->regs.cfa_exp = insn_ptr;
> - fs->regs.cfa_how = CFA_EXP;
> - insn_ptr = read_uleb128 (insn_ptr, &utmp);
> - insn_ptr += utmp;
> - break;
> -
> - case DW_CFA_expression:
> - insn_ptr = read_uleb128 (insn_ptr, ®);
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
> - insn_ptr = read_uleb128 (insn_ptr, &utmp);
> - insn_ptr += utmp;
> - break;
> -
> - /* Dwarf3. */
> - case DW_CFA_offset_extended_sf:
> - insn_ptr = read_uleb128 (insn_ptr, ®);
> - insn_ptr = read_sleb128 (insn_ptr, &stmp);
> - offset = stmp * fs->data_align;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
> - = REG_SAVED_OFFSET;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
> - break;
> -
> - case DW_CFA_def_cfa_sf:
> - insn_ptr = read_uleb128 (insn_ptr, &utmp);
> - fs->regs.cfa_reg = (_Unwind_Word)utmp;
> - insn_ptr = read_sleb128 (insn_ptr, &stmp);
> - fs->regs.cfa_offset = (_Unwind_Sword)stmp;
> - fs->regs.cfa_how = CFA_REG_OFFSET;
> - fs->regs.cfa_offset *= fs->data_align;
> - break;
> -
> - case DW_CFA_def_cfa_offset_sf:
> - insn_ptr = read_sleb128 (insn_ptr, &stmp);
> - fs->regs.cfa_offset = (_Unwind_Sword)stmp;
> - fs->regs.cfa_offset *= fs->data_align;
> - /* cfa_how deliberately not set. */
> - break;
> -
> - case DW_CFA_val_offset:
> - insn_ptr = read_uleb128 (insn_ptr, ®);
> - insn_ptr = read_uleb128 (insn_ptr, &utmp);
> - offset = (_Unwind_Sword) utmp * fs->data_align;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
> - = REG_SAVED_VAL_OFFSET;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
> - break;
> -
> - case DW_CFA_val_offset_sf:
> - insn_ptr = read_uleb128 (insn_ptr, ®);
> - insn_ptr = read_sleb128 (insn_ptr, &stmp);
> - offset = stmp * fs->data_align;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
> - = REG_SAVED_VAL_OFFSET;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
> - break;
> -
> - case DW_CFA_val_expression:
> - insn_ptr = read_uleb128 (insn_ptr, ®);
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
> - = REG_SAVED_VAL_EXP;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
> - insn_ptr = read_uleb128 (insn_ptr, &utmp);
> - insn_ptr += utmp;
> - break;
> -
> - case DW_CFA_GNU_window_save:
> - /* ??? Hardcoded for SPARC register window configuration. */
> - for (reg = 16; reg < 32; ++reg)
> - {
> - fs->regs.reg[reg].how = REG_SAVED_OFFSET;
> - fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
> - }
> - break;
> -
> - case DW_CFA_GNU_args_size:
> - insn_ptr = read_uleb128 (insn_ptr, &utmp);
> - context->args_size = (_Unwind_Word)utmp;
> - break;
> -
> - case DW_CFA_GNU_negative_offset_extended:
> - /* Obsoleted by DW_CFA_offset_extended_sf, but used by
> - older PowerPC code. */
> - insn_ptr = read_uleb128 (insn_ptr, ®);
> - insn_ptr = read_uleb128 (insn_ptr, &utmp);
> - offset = (_Unwind_Word) utmp * fs->data_align;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
> - = REG_SAVED_OFFSET;
> - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
> - break;
> -
> - default:
> - gcc_unreachable ();
> - }
> - }
> -}
> -
> -/* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
> - its caller and decode it into FS. This function also sets the
> - args_size and lsda members of CONTEXT, as they are really information
> - about the caller's frame. */
> -
> -static _Unwind_Reason_Code
> -uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
> -{
> - const struct dwarf_fde *fde;
> - const struct dwarf_cie *cie;
> - const unsigned char *aug, *insn, *end;
> -
> - memset (fs, 0, sizeof (*fs));
> - context->args_size = 0;
> - context->lsda = 0;
> -
> - if (context->ra == 0)
> - return _URC_END_OF_STACK;
> -
> - fde = _Unwind_Find_FDE (context->ra + _Unwind_IsSignalFrame (context) - 1,
> - &context->bases);
> - if (fde == NULL)
> - {
> -#ifdef MD_FALLBACK_FRAME_STATE_FOR
> - /* Couldn't find frame unwind info for this function. Try a
> - target-specific fallback mechanism. This will necessarily
> - not provide a personality routine or LSDA. */
> - return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
> -#else
> - return _URC_END_OF_STACK;
> -#endif
> - }
> -
> - fs->pc = context->bases.func;
> -
> - cie = get_cie (fde);
> - insn = extract_cie_info (cie, context, fs);
> - if (insn == NULL)
> - /* CIE contained unknown augmentation. */
> - return _URC_FATAL_PHASE1_ERROR;
> -
> - /* First decode all the insns in the CIE. */
> - end = (const unsigned char *) next_fde ((const struct dwarf_fde *) cie);
> - execute_cfa_program (insn, end, context, fs);
> -
> - /* Locate augmentation for the fde. */
> - aug = (const unsigned char *) fde + sizeof (*fde);
> - aug += 2 * size_of_encoded_value (fs->fde_encoding);
> - insn = NULL;
> - if (fs->saw_z)
> - {
> - _uleb128_t i;
> - aug = read_uleb128 (aug, &i);
> - insn = aug + i;
> - }
> - if (fs->lsda_encoding != DW_EH_PE_omit)
> - {
> - _Unwind_Ptr lsda;
> -
> - aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
> - context->lsda = (void *) lsda;
> - }
> -
> - /* Then the insns in the FDE up to our target PC. */
> - if (insn == NULL)
> - insn = aug;
> - end = (const unsigned char *) next_fde (fde);
> - execute_cfa_program (insn, end, context, fs);
> -
> - return _URC_NO_REASON;
> -}
> -
> -typedef struct frame_state
> -{
> - void *cfa;
> - void *eh_ptr;
> - long cfa_offset;
> - long args_size;
> - long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
> - unsigned short cfa_reg;
> - unsigned short retaddr_column;
> - char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
> -} frame_state;
> -
> -struct frame_state * __frame_state_for (void *, struct frame_state *);
> -
> -/* Called from pre-G++ 3.0 __throw to find the registers to restore for
> - a given PC_TARGET. The caller should allocate a local variable of
> - `struct frame_state' and pass its address to STATE_IN. */
> -
> -struct frame_state *
> -__frame_state_for (void *pc_target, struct frame_state *state_in)
> -{
> - struct _Unwind_Context context;
> - _Unwind_FrameState fs;
> - int reg;
> -
> - memset (&context, 0, sizeof (struct _Unwind_Context));
> - if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
> - context.flags = EXTENDED_CONTEXT_BIT;
> - context.ra = pc_target + 1;
> -
> - if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
> - return 0;
> -
> - /* We have no way to pass a location expression for the CFA to our
> - caller. It wouldn't understand it anyway. */
> - if (fs.regs.cfa_how == CFA_EXP)
> - return 0;
> -
> - for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
> - {
> - state_in->saved[reg] = fs.regs.reg[reg].how;
> - switch (state_in->saved[reg])
> - {
> - case REG_SAVED_REG:
> - state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
> - break;
> - case REG_SAVED_OFFSET:
> - state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
> - break;
> - default:
> - state_in->reg_or_offset[reg] = 0;
> - break;
> - }
> - }
> -
> - state_in->cfa_offset = fs.regs.cfa_offset;
> - state_in->cfa_reg = fs.regs.cfa_reg;
> - state_in->retaddr_column = fs.retaddr_column;
> - state_in->args_size = context.args_size;
> - state_in->eh_ptr = fs.eh_ptr;
> -
> - return state_in;
> -}
> -
> -typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
> -
> -static inline void
> -_Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
> - _Unwind_SpTmp *tmp_sp)
> -{
> - int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
> -
> - if (size == sizeof(_Unwind_Ptr))
> - tmp_sp->ptr = (_Unwind_Ptr) cfa;
> - else
> - {
> - gcc_assert (size == sizeof(_Unwind_Word));
> - tmp_sp->word = (_Unwind_Ptr) cfa;
> - }
> - _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
> -}
> -
> -static void
> -uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
> -{
> - struct _Unwind_Context orig_context = *context;
> - void *cfa;
> - long i;
> -
> -#ifdef __LIBGCC_EH_RETURN_STACKADJ_RTX__
> - /* Special handling here: Many machines do not use a frame pointer,
> - and track the CFA only through offsets from the stack pointer from
> - one frame to the next. In this case, the stack pointer is never
> - stored, so it has no saved address in the context. What we do
> - have is the CFA from the previous stack frame.
> -
> - In very special situations (such as unwind info for signal return),
> - there may be location expressions that use the stack pointer as well.
> -
> - Do this conditionally for one frame. This allows the unwind info
> - for one frame to save a copy of the stack pointer from the previous
> - frame, and be able to use much easier CFA mechanisms to do it.
> - Always zap the saved stack pointer value for the next frame; carrying
> - the value over from one frame to another doesn't make sense. */
> -
> - _Unwind_SpTmp tmp_sp;
> -
> - if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
> - _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
> - _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
> -#endif
> -
> - /* Compute this frame's CFA. */
> - switch (fs->regs.cfa_how)
> - {
> - case CFA_REG_OFFSET:
> - cfa = _Unwind_GetPtr (&orig_context, fs->regs.cfa_reg);
> - cfa += fs->regs.cfa_offset;
> - break;
> -
> - case CFA_EXP:
> - {
> - const unsigned char *exp = fs->regs.cfa_exp;
> - _uleb128_t len;
> -
> - exp = read_uleb128 (exp, &len);
> - cfa = (void *) (_Unwind_Ptr)
> - execute_stack_op (exp, exp + len, &orig_context, 0);
> - break;
> - }
> -
> - default:
> - gcc_unreachable ();
> - }
> - context->cfa = cfa;
> -
> - /* Compute the addresses of all registers saved in this frame. */
> - for (i = 0; i < __LIBGCC_DWARF_FRAME_REGISTERS__ + 1; ++i)
> - switch (fs->regs.reg[i].how)
> - {
> - case REG_UNSAVED:
> - case REG_UNDEFINED:
> - break;
> -
> - case REG_SAVED_OFFSET:
> - _Unwind_SetGRPtr (context, i,
> - (void *) (cfa + fs->regs.reg[i].loc.offset));
> - break;
> -
> - case REG_SAVED_REG:
> - if (_Unwind_GRByValue (&orig_context, fs->regs.reg[i].loc.reg))
> - _Unwind_SetGRValue (context, i,
> - _Unwind_GetGR (&orig_context,
> - fs->regs.reg[i].loc.reg));
> - else
> - _Unwind_SetGRPtr (context, i,
> - _Unwind_GetGRPtr (&orig_context,
> - fs->regs.reg[i].loc.reg));
> - break;
> -
> - case REG_SAVED_EXP:
> - {
> - const unsigned char *exp = fs->regs.reg[i].loc.exp;
> - _uleb128_t len;
> - _Unwind_Ptr val;
> -
> - exp = read_uleb128 (exp, &len);
> - val = execute_stack_op (exp, exp + len, &orig_context,
> - (_Unwind_Ptr) cfa);
> - _Unwind_SetGRPtr (context, i, (void *) val);
> - }
> - break;
> -
> - case REG_SAVED_VAL_OFFSET:
> - _Unwind_SetGRValue (context, i,
> - (_Unwind_Internal_Ptr)
> - (cfa + fs->regs.reg[i].loc.offset));
> - break;
> -
> - case REG_SAVED_VAL_EXP:
> - {
> - const unsigned char *exp = fs->regs.reg[i].loc.exp;
> - _uleb128_t len;
> - _Unwind_Ptr val;
> -
> - exp = read_uleb128 (exp, &len);
> - val = execute_stack_op (exp, exp + len, &orig_context,
> - (_Unwind_Ptr) cfa);
> - _Unwind_SetGRValue (context, i, val);
> - }
> - break;
> - }
> -
> - _Unwind_SetSignalFrame (context, fs->signal_frame);
> -
> -#ifdef MD_FROB_UPDATE_CONTEXT
> - MD_FROB_UPDATE_CONTEXT (context, fs);
> -#endif
> -}
> -
> -/* CONTEXT describes the unwind state for a frame, and FS describes the FDE
> - of its caller. Update CONTEXT to refer to the caller as well. Note
> - that the args_size and lsda members are not updated here, but later in
> - uw_frame_state_for. */
> -
> -static void
> -uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
> -{
> - uw_update_context_1 (context, fs);
> -
> - /* In general this unwinder doesn't make any distinction between
> - undefined and same_value rule. Call-saved registers are assumed
> - to have same_value rule by default and explicit undefined
> - rule is handled like same_value. The only exception is
> - DW_CFA_undefined on retaddr_column which is supposed to
> - mark outermost frame in DWARF 3. */
> - if (fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (fs->retaddr_column)].how
> - == REG_UNDEFINED)
> - /* uw_frame_state_for uses context->ra == 0 check to find outermost
> - stack frame. */
> - context->ra = 0;
> - else
> - /* Compute the return address now, since the return address column
> - can change from frame to frame. */
> - context->ra = __builtin_extract_return_addr
> - (_Unwind_GetPtr (context, fs->retaddr_column));
> -#if defined( __CR16C__ )
> - context->ra = (void*)( ( (unsigned)context->ra ) << 1 ) ;
> -#endif
> -}
> -
> -static void
> -uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
> -{
> - uw_update_context (context, fs);
> -}
> -
> -/* Fill in CONTEXT for top-of-stack. The only valid registers at this
> - level will be the return address and the CFA. */
> -
> -#define uw_init_context(CONTEXT) \
> - do \
> - { \
> - /* Do any necessary initialization to access arbitrary stack frames. \
> - On the SPARC, this means flushing the register windows. */ \
> - __builtin_unwind_init (); \
> - uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
> - __builtin_return_address (0)); \
> - } \
> - while (0)
> -
> -static inline void
> -init_dwarf_reg_size_table (void)
> -{
> - __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
> -}
> -
> -static void __attribute__((noinline))
> -uw_init_context_1 (struct _Unwind_Context *context,
> - void *outer_cfa, void *outer_ra)
> -{
> - void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
> - _Unwind_FrameState fs;
> - _Unwind_SpTmp sp_slot;
> - _Unwind_Reason_Code code;
> -
> - memset (context, 0, sizeof (struct _Unwind_Context));
> - context->ra = ra;
> - if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
> - context->flags = EXTENDED_CONTEXT_BIT;
> -
> - code = uw_frame_state_for (context, &fs);
> - gcc_assert (code == _URC_NO_REASON);
> -
> -#if __GTHREADS
> - {
> - static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
> - if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
> - && dwarf_reg_size_table[0] == 0)
> - init_dwarf_reg_size_table ();
> - }
> -#else
> - if (dwarf_reg_size_table[0] == 0)
> - init_dwarf_reg_size_table ();
> -#endif
> -
> - /* Force the frame state to use the known cfa value. */
> - _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
> - fs.regs.cfa_how = CFA_REG_OFFSET;
> - fs.regs.cfa_reg = __builtin_dwarf_sp_column ();
> -#if !defined( __CR16C__ )
> - fs.regs.cfa_offset = 0;
> -#else
> - fs.regs.cfa_offset -= context->args_size ;
> -#endif
> -
> - uw_update_context_1 (context, &fs);
> -
> - /* If the return address column was saved in a register in the
> - initialization context, then we can't see it in the given
> - call frame data. So have the initialization context tell us. */
> - context->ra = __builtin_extract_return_addr (outer_ra);
> -}
> -
> -static void _Unwind_DebugHook (void *, void *)
> - __attribute__ ((__noinline__, __used__, __noclone__));
> -
> -/* This function is called during unwinding. It is intended as a hook
> - for a debugger to intercept exceptions. CFA is the CFA of the
> - target frame. HANDLER is the PC to which control will be
> - transferred. */
> -static void
> -_Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
> - void *handler __attribute__ ((__unused__)))
> -{
> - /* We only want to use stap probes starting with v3. Earlier
> - versions added too much startup cost. */
> -#if defined (HAVE_SYS_SDT_H) && defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
> - STAP_PROBE2 (libgcc, unwind, cfa, handler);
> -#else
> - asm ("");
> -#endif
> -}
> -
> -/* Install TARGET into CURRENT so that we can return to it. This is a
> - macro because __builtin_eh_return must be invoked in the context of
> - our caller. */
> -#if defined( __CR16C__ )
> -
> -#define uw_install_context(CURRENT, TARGET, FRAMES) \
> - do \
> - { \
> - long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
> - void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
> - handler = (void*)( ( (unsigned)handler ) >> 1 ) ; \
> - _Unwind_DebugHook ((TARGET)->cfa, handler); \
> - __builtin_eh_return (offset, handler); \
> - } \
> - while (0)
> -#else
> -#define uw_install_context(CURRENT, TARGET, FRAMES) \
> - do \
> - { \
> - long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
> - void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
> - _Unwind_DebugHook ((TARGET)->cfa, handler); \
> - __builtin_eh_return (offset, handler); \
> - } \
> - while (0)
> -#endif /* __CR16C__ */
> -
> -static long
> -uw_install_context_1 (struct _Unwind_Context *current,
> - struct _Unwind_Context *target)
> -{
> - long i;
> - _Unwind_SpTmp sp_slot;
> -
> - /* If the target frame does not have a saved stack pointer,
> - then set up the target's CFA. */
> - if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
> - _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
> -
> - for (i = 0; i < __LIBGCC_DWARF_FRAME_REGISTERS__; ++i)
> - {
> - void *c = (void *) (_Unwind_Internal_Ptr) current->reg[i];
> - void *t = (void *) (_Unwind_Internal_Ptr)target->reg[i];
> -
> - gcc_assert (current->by_value[i] == 0);
> - if (target->by_value[i] && c)
> - {
> - _Unwind_Word w;
> - _Unwind_Ptr p;
> - if (dwarf_reg_size_table[i] == sizeof (_Unwind_Word))
> - {
> - w = (_Unwind_Internal_Ptr) t;
> - memcpy (c, &w, sizeof (_Unwind_Word));
> - }
> - else
> - {
> - gcc_assert (dwarf_reg_size_table[i] == sizeof (_Unwind_Ptr));
> - p = (_Unwind_Internal_Ptr) t;
> - memcpy (c, &p, sizeof (_Unwind_Ptr));
> - }
> - }
> - else if (t && c && t != c)
> - memcpy (c, t, dwarf_reg_size_table[i]);
> - }
> -
> - /* If the current frame doesn't have a saved stack pointer, then we
> - need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
> - pointer value reloaded. */
> - if (!_Unwind_GetGRPtr (current, __builtin_dwarf_sp_column ()))
> - {
> - void *target_cfa;
> -
> - target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
> -
> - /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
> - if (__LIBGCC_STACK_GROWS_DOWNWARD__)
> - return target_cfa - current->cfa + target->args_size;
> - else
> - return current->cfa - target_cfa - target->args_size;
> - }
> - return 0;
> -}
> -
> -static inline _Unwind_Ptr
> -uw_identify_context (struct _Unwind_Context *context)
> -{
> - /* The CFA is not sufficient to disambiguate the context of a function
> - interrupted by a signal before establishing its frame and the context
> - of the signal itself. */
> - if (__LIBGCC_STACK_GROWS_DOWNWARD__)
> - return _Unwind_GetCFA (context) - _Unwind_IsSignalFrame (context);
> - else
> - return _Unwind_GetCFA (context) + _Unwind_IsSignalFrame (context);
> -}
> -
> -
> -#include "unwind.inc"
> -
> -#if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
> -alias (_Unwind_Backtrace);
> -alias (_Unwind_DeleteException);
> -alias (_Unwind_FindEnclosingFunction);
> -alias (_Unwind_ForcedUnwind);
> -alias (_Unwind_GetDataRelBase);
> -alias (_Unwind_GetTextRelBase);
> -alias (_Unwind_GetCFA);
> -alias (_Unwind_GetGR);
> -alias (_Unwind_GetIP);
> -alias (_Unwind_GetLanguageSpecificData);
> -alias (_Unwind_GetRegionStart);
> -alias (_Unwind_RaiseException);
> -alias (_Unwind_Resume);
> -alias (_Unwind_Resume_or_Rethrow);
> -alias (_Unwind_SetGR);
> -alias (_Unwind_SetIP);
> -#endif
> -
> -#endif /* !USING_SJLJ_EXCEPTIONS */
> diff --git a/libgcc/config/cr16/unwind-dw2.h b/libgcc/config/cr16/unwind-dw2.h
> deleted file mode 100644
> index 0c478e56c02..00000000000
> --- a/libgcc/config/cr16/unwind-dw2.h
> +++ /dev/null
> @@ -1,80 +0,0 @@
> -/* DWARF2 frame unwind data structure.
> - Copyright (C) 1997-2022 Free Software Foundation, Inc.
> -
> - 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.
> -
> - Under Section 7 of GPL version 3, you are granted additional
> - permissions described in the GCC Runtime Library Exception, version
> - 3.1, as published by the Free Software Foundation.
> -
> - You should have received a copy of the GNU General Public License and
> - a copy of the GCC Runtime Library Exception along with this program;
> - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
> - <http://www.gnu.org/licenses/>. */
> -
> -/* The result of interpreting the frame unwind info for a frame.
> - This is all symbolic at this point, as none of the values can
> - be resolved until the target pc is located. */
> -typedef struct
> -{
> - /* Each register save state can be described in terms of a CFA slot,
> - another register, or a location expression. */
> - struct frame_state_reg_info
> - {
> - struct {
> - union {
> - _Unwind_Word reg;
> - _Unwind_Sword offset;
> - const unsigned char *exp;
> - } loc;
> - enum {
> - REG_UNSAVED,
> - REG_SAVED_OFFSET,
> - REG_SAVED_REG,
> - REG_SAVED_EXP,
> - REG_SAVED_VAL_OFFSET,
> - REG_SAVED_VAL_EXP,
> - REG_UNDEFINED
> - } how;
> - } reg[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
> -
> - /* Used to implement DW_CFA_remember_state. */
> - struct frame_state_reg_info *prev;
> -
> - /* The CFA can be described in terms of a reg+offset or a
> - location expression. */
> - _Unwind_Sword cfa_offset;
> - _Unwind_Word cfa_reg;
> - const unsigned char *cfa_exp;
> - enum {
> - CFA_UNSET,
> - CFA_REG_OFFSET,
> - CFA_EXP
> - } cfa_how;
> - } regs;
> -
> - /* The PC described by the current frame state. */
> - void *pc;
> -
> - /* The information we care about from the CIE/FDE. */
> - _Unwind_Personality_Fn personality;
> - _Unwind_Sword data_align;
> - _Unwind_Word code_align;
> - _Unwind_Word retaddr_column;
> - unsigned char fde_encoding;
> - unsigned char lsda_encoding;
> - unsigned char saw_z;
> - unsigned char signal_frame;
> - void *eh_ptr;
> -} _Unwind_FrameState;
> -
> --
> 2.37.2
>
More information about the Gcc-patches
mailing list