diff gcc/config/csky/csky.h @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents
children 1830386684a0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/config/csky/csky.h	Thu Oct 25 07:37:49 2018 +0900
@@ -0,0 +1,1054 @@
+/* Declarations for the C-SKY back end.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   Contributed by C-SKY Microsystems and Mentor Graphics.
+
+   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_CSKY_H
+#define GCC_CSKY_H
+
+/* In some places e.g. csky_secondary_reload, we use -1 to indicate an
+   invalid register.  In other places where N is unsigned the comparison
+   to zero would give an error, so explicitly cast to int here.  */
+#define CSKY_GENERAL_REGNO_P(N)			\
+  ((N) < CSKY_NGPR_REGS && (int)(N) >= 0)
+
+#define CSKY_VREG_P(N)		     \
+  ((N) >= CSKY_FIRST_VFP_REGNUM && (N) <= CSKY_LAST_VFP_REGNUM)
+
+#define CSKY_HILO_REG_P(N)   \
+  ((N) == CSKY_HI_REGNUM || (N) == CSKY_LO_REGNUM)
+
+/* Helper macros for constant constraints and predicates.  */
+#define CSKY_VALUE_BETWEEN(VALUE, LOW, HIGH)	\
+  ((VALUE) >= (LOW) && (VALUE) <= (HIGH))
+
+#define CSKY_CONST_OK_FOR_I(VALUE)  \
+  CSKY_VALUE_BETWEEN (VALUE, 0, 65535)
+
+#define CSKY_CONST_OK_FOR_J(VALUE)  \
+  CSKY_VALUE_BETWEEN (VALUE, 1, 32)
+
+#define CSKY_CONST_OK_FOR_K(VALUE)  \
+  CSKY_VALUE_BETWEEN (VALUE, 0, 31)
+
+#define CSKY_CONST_OK_FOR_L(VALUE)  \
+  CSKY_VALUE_BETWEEN (VALUE, 1, 8)
+
+#define CSKY_CONST_OK_FOR_M(VALUE)  \
+  CSKY_VALUE_BETWEEN (VALUE, 1, 4096)
+
+#define CSKY_CONST_OK_FOR_N(VALUE)  \
+  CSKY_VALUE_BETWEEN (VALUE, 1, 256)
+
+#define CSKY_CONST_OK_FOR_O(VALUE)  \
+  CSKY_VALUE_BETWEEN (VALUE, 0, 4095)
+
+#define CSKY_CONST_OK_FOR_P(VALUE)  \
+  (((VALUE) & 0x3) == 0 && CSKY_VALUE_BETWEEN (VALUE, 4, 508))
+
+#define CSKY_CONST_OK_FOR_T(VALUE)  \
+  CSKY_VALUE_BETWEEN (VALUE, -256, -1)
+
+#define CSKY_CONST_OK_FOR_Ub(VALUE)  \
+  (exact_log2 (VALUE & 0xFFFFFFFF) >= 0)
+
+#define CSKY_CONST_OK_FOR_Uc(VALUE)	     \
+  ((VALUE) == (HOST_WIDE_INT) -1	     \
+   || (exact_log2 ((VALUE) + 1) >= 0	     \
+       && exact_log2 ((VALUE) + 1) <= 31))
+
+#define CSKY_CONST_OK_FOR_Ud(VALUE)				\
+  ((CSKY_CONST_OK_FOR_I ((VALUE) & 0xffffffff)			\
+    || CSKY_CONST_OK_FOR_Ub ((VALUE))				\
+    || CSKY_CONST_OK_FOR_Uc (((VALUE) << 32) >> 32))		\
+   && (CSKY_CONST_OK_FOR_I ((VALUE) >> 32)			\
+       || CSKY_CONST_OK_FOR_Ub ((VALUE) >> 32)			\
+       || CSKY_CONST_OK_FOR_Uc ((VALUE) >> 32)))		\
+
+#define CSKY_CONST_OK_FOR_Ug(VALUE)  \
+  (((VALUE) & 0x3) == 0 && CSKY_VALUE_BETWEEN (VALUE, -508, -4))
+
+#define CSKY_CONST_OK_FOR_Uh(VALUE)  \
+  CSKY_VALUE_BETWEEN (VALUE, -31, 0)
+
+#define CSKY_CONST_OK_FOR_Uj(VALUE)  \
+  (((VALUE) & 0x3) == 0 && CSKY_VALUE_BETWEEN (VALUE, 1, 1024))
+
+#define CSKY_CONST_OK_FOR_Uk(VALUE)  \
+  CSKY_VALUE_BETWEEN (VALUE, 1, 65536)
+
+#define CSKY_CONST_OK_FOR_Ul(VALUE)  \
+  (((VALUE) & 0x3) == 0 && CSKY_VALUE_BETWEEN (VALUE, -1024, -4))
+
+#define CSKY_CONST_OK_FOR_Um(VALUE)  \
+  CSKY_VALUE_BETWEEN (VALUE, -4096, -1)
+
+#define CSKY_CONST_OK_FOR_US(VALUE) \
+  CSKY_VALUE_BETWEEN (VALUE, -8, -1)
+
+#define CSKY_CONST_OK_FOR_MOVIH(VALUE)		\
+  (((VALUE) & 0xFFFF) == 0)
+
+#ifndef TARGET_CPU_DEFAULT
+#define TARGET_CPU_DEFAULT CSKY_TARGET_CORE_GET(ck810f)
+#endif
+
+/* Options that are enabled by default are specified as such in the
+   .opt file.  */
+#define TARGET_DEFAULT 0
+
+/* The highest CSKY architecture version supported by the target.  */
+#define CSKY_TARGET_ARCH(arch) \
+  (csky_base_arch == CSKY_TARGET_ARCH_GET (arch))
+
+/* Define some macros for target code generation options.  */
+#define TARGET_SOFT_FPU \
+  (csky_fpu_index == TARGET_FPU_fpv2_sf)
+#define TARGET_CASESI \
+  (optimize_size && TARGET_CONSTANT_POOL \
+   && (CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802)))
+#define TARGET_TLS \
+  (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810))
+
+/* Number of loads/stores handled by ldm/stm.  */
+#define CSKY_MIN_MULTIPLE_STLD	3
+#define CSKY_MAX_MULTIPLE_STLD	12
+
+/* Pull in enums and defines for processor/arch variants.  This makes
+   it possible to use CSKY_TARGET_ARCH in macros defined in this file.  */
+#include "csky_opts.h"
+extern enum csky_base_architecture csky_base_arch;
+
+/* Pull in enums and defines for ISA features.  Likewise required to
+   support use of CSKY_ISA_FEATURE in this file.
+   Note that the CSKY_ISA_FEATURE macro tests properties of the
+   particular processor we're compiling for, not code generation
+   options that may have dependencies on those features.  The latter
+   are handled by TARGET_xxxx macros/variables instead.  See csky.opt.  */
+#include "csky_isa.h"
+extern int csky_arch_isa_features[];
+#define CSKY_ISA_FEATURE(IDENT) \
+  csky_arch_isa_features[CSKY_ISA_FEATURE_GET (IDENT)]
+
+/******************************************************************
+ *			   Storage Layout			  *
+ ******************************************************************/
+
+
+/* Define this if most significant bit is lowest numbered
+   in instructions that operate on numbered bit-fields.  */
+#define BITS_BIG_ENDIAN	 0
+
+/* If the most significant byte of a word is the lowest numbered.  */
+#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
+
+/* If the most significant word of a multiword number is the lowest.  */
+#define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN)
+
+/* Width of a word, in units (bytes).  */
+#define UNITS_PER_WORD 4
+
+/* Define this macro if it is advisable to hold scalars in registers
+   in a wider mode than that declared by the program.  In such cases,
+   the value is constrained to be within the bounds of the declared
+   type, but kept valid in the wider mode.  The signedness of the
+   extension may differ from that of the type.  */
+#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)	\
+  if (GET_MODE_CLASS (MODE) == MODE_INT		\
+      && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
+    (MODE) = SImode;
+
+
+/* Allocation boundary (in *bits*) for storing arguments in argument list.  */
+#define PARM_BOUNDARY	32
+
+/* Boundary (in *bits*) on which stack pointer should be aligned.
+   Per C-SKY, the published V2 ABI document is incorrect and the proper
+   alignment is on a 4-byte boundary rather than 8 bytes.  */
+#define STACK_BOUNDARY	32
+
+/* Align definitions of arrays, unions and structures so that
+   initializations and copies can be made more efficient.  This is not
+   ABI-changing, so it only affects places where we can see the
+   definition. Increasing the alignment tends to introduce padding,
+   so don't do this when optimizing for size/conserving stack space. */
+#define CSKY_EXPAND_ALIGNMENT(COND, EXP, ALIGN) \
+  (((COND) && ((ALIGN) < BITS_PER_WORD)		 \
+    && (TREE_CODE (EXP) == ARRAY_TYPE		 \
+	|| TREE_CODE (EXP) == UNION_TYPE	 \
+	|| TREE_CODE (EXP) == RECORD_TYPE))	 \
+   ? BITS_PER_WORD : (ALIGN))
+
+/* Align global data. */
+#define DATA_ALIGNMENT(EXP, ALIGN)	\
+  CSKY_EXPAND_ALIGNMENT (!optimize_size, EXP, ALIGN)
+
+/* Similarly, make sure that objects on the stack are sensibly aligned.  */
+#define LOCAL_ALIGNMENT(EXP, ALIGN)	  \
+  CSKY_EXPAND_ALIGNMENT (!flag_conserve_stack, EXP, ALIGN)
+
+/* No data type wants to be aligned rounder than this.  */
+#define BIGGEST_ALIGNMENT 32
+
+/* Every structures size must be a multiple of 8 bits.  */
+#define STRUCTURE_SIZE_BOUNDARY 8
+
+/* Look at the fundamental type that is used for a bit-field and use
+   that to impose alignment on the enclosing structure.
+   struct s {int a:8}; should have same alignment as "int", not "char".  */
+#define PCC_BITFIELD_TYPE_MATTERS 1
+
+/* Largest integer machine mode for structures.  If undefined, the default
+   is GET_MODE_SIZE(DImode).  */
+#define MAX_FIXED_MODE_SIZE 64
+
+/* Allocation boundary (in *bits*) for the code of a function.
+   Optimize ck801 and ck802 a little harder for size.  */
+#define FUNCTION_BOUNDARY					\
+  (((CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802))	\
+    && optimize_size)						\
+   ? 16 : 32)
+
+/* C-SKY does not support unaligned access.  */
+#define STRICT_ALIGNMENT    1
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "int"
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "long int"
+
+#undef UINT_LEAST32_TYPE
+#define UINT_LEAST32_TYPE "unsigned int"
+
+#undef INT_LEAST32_TYPE
+#define INT_LEAST32_TYPE "int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+/******************************************************************
+ *		Layout of Source Language Data Types		  *
+ ******************************************************************/
+
+
+/* 'char' is unsigned by default for backward compatibility.  */
+#define DEFAULT_SIGNED_CHAR    0
+
+
+/******************************************************************
+ *		Stack Layout and Calling Conventions		  *
+ ******************************************************************/
+
+
+/* Basic Stack Layout  */
+
+
+/* Define this if pushing a word on the stack
+   makes the stack pointer a smaller address.  */
+#define STACK_GROWS_DOWNWARD	1
+
+/* Define this to nonzero if the nominal address of the stack frame
+   is at the high-address end of the local variables;
+   that is, each additional local variable allocated
+   goes at a more negative offset in the frame.  */
+#define FRAME_GROWS_DOWNWARD	1
+
+/* Offset of first parameter from the argument pointer register value.  */
+#define FIRST_PARM_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) \
+  csky_return_addr (COUNT, FRAME)
+
+/* Pick up the return address upon entry to a procedure. Used for
+   dwarf2 unwind information.  This also enables the table driven
+   mechanism.  */
+#define INCOMING_RETURN_ADDR_RTX  gen_rtx_REG (Pmode, CSKY_LR_REGNUM)
+
+
+/* Exception Handling Support  */
+
+/* The register that holds the return address in exception handlers.  */
+#define EH_RETURN_STACKADJ_RTX	gen_rtx_REG (SImode, CSKY_EH_STACKADJ_REGNUM)
+
+
+/* Registers That Address the Stack Frame  */
+
+
+/* Register to use for pushing function arguments.  */
+#define STACK_POINTER_REGNUM  CSKY_SP_REGNUM
+
+/* Base register for access to local variables of the function.  */
+#define FRAME_POINTER_REGNUM  8
+
+/* Base register for access to arguments of the function.  This is a fake
+   register that is always eliminated.  */
+#define ARG_POINTER_REGNUM    32
+
+/* Static chain register.
+   Register use is more restricted on CK801.  */
+#define STATIC_CHAIN_REGNUM   (CSKY_TARGET_ARCH (CK801) ? 13 : 12)
+
+
+/* Eliminating Frame Pointer and Arg Pointer  */
+
+
+/* Definitions for register eliminations.
+
+   This is an array of structures.  Each structure initializes one pair
+   of eliminable registers.  The "from" register number is given first,
+   followed by "to".  Eliminations of the same "from" register are listed
+   in order of preference.
+
+   We have two registers that can be eliminated on the CSKY.  First, the
+   arg pointer register can often be eliminated in favor of the stack
+   pointer register.  Secondly, the pseudo frame pointer register can always
+   be eliminated; it is replaced with the stack pointer.  */
+#define ELIMINABLE_REGS		  \
+{{ ARG_POINTER_REGNUM,	      STACK_POINTER_REGNUM	      },\
+ { ARG_POINTER_REGNUM,	      FRAME_POINTER_REGNUM	      },\
+ { FRAME_POINTER_REGNUM,      STACK_POINTER_REGNUM	      }}
+
+/* Define the offset between two registers, one to be eliminated, and the
+   other its replacement, at the start of a routine.  */
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)	  \
+  (OFFSET) = csky_initial_elimination_offset (FROM, TO)
+
+
+/* Passing Function Arguments on the Stack  */
+
+
+/* Define this if the maximum size of all the outgoing args is to be
+   accumulated and pushed during the prologue.  The amount can be
+   found in the variable crtl->outgoing_args_size.  */
+#define ACCUMULATE_OUTGOING_ARGS 1
+
+
+/* Passing Arguments in Registers  */
+
+
+/* A C type for declaring a variable that is used as the first argument of
+   TARGET_ FUNCTION_ARG and other related values.  */
+#define CUMULATIVE_ARGS	 int
+
+/* Initialize a variable CUM of type CUMULATIVE_ARGS
+   for a call to a function whose data type is FNTYPE.
+   For a library call, FNTYPE is 0.
+
+   On CSKY, the offset always starts at 0: the first parm reg is always
+   the same reg.  */
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
+  ((CUM) = 0)
+
+/* True if N is a possible register number for function argument passing.
+   On the CSKY, r0-r3 are used to pass args.
+   The int cast is to prevent a complaint about unsigned comparison to
+   zero, since CSKY_FIRST_PARM_REGNUM is zero.  */
+#define FUNCTION_ARG_REGNO_P(REGNO)	    \
+  (((int)(REGNO) >= CSKY_FIRST_PARM_REGNUM) &&		\
+   ((REGNO) < (CSKY_NPARM_REGS + CSKY_FIRST_PARM_REGNUM)))
+
+/* How Large Values Are Returned  */
+
+
+/* Define DEFAULT_PCC_STRUCT_RETURN to 1 if all structure and union return
+   values must be in memory.  On the CSKY, small
+   structures (eight bytes or fewer) are returned in
+   the register pair r0/r1.  */
+#define DEFAULT_PCC_STRUCT_RETURN 0
+
+/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
+   the stack pointer does not matter.  The value is tested only in
+   functions that have frame pointers.
+   No definition is equivalent to always zero.
+
+   On the CSKY, the function epilogue recovers the stack pointer from the
+   frame.  */
+#define EXIT_IGNORE_STACK 1
+
+
+/******************************************************************
+ *		Register Usage & Register Classes		  *
+ ******************************************************************/
+
+
+#define FIRST_PSEUDO_REGISTER 71
+
+/* 1 for registers that have pervasive standard uses
+   and are not available for the register allocator.
+   On C-SKY, r14 is SP, r26 is used by linker,
+   r27 is used by assembler, r28 is data base address,
+   r29 is GOT base address, r30 is handler base address,
+   r31 is TLS register.  */
+#define FIXED_REGISTERS							\
+ /*  r0	   r1	 r2    r3    r4	   r5	 r6    r7  */			\
+{    0,	   0,	 0,    0,    0,	   0,	 0,    0,			\
+ /*  r8	   r9	 r10   r11   r12   r13	 r14   r15 */			\
+     0,	   0,	 0,    0,    0,	   0,	 1,    0,			\
+ /*  r16   r17	 r18   r19   r20   r21	 r22   r23 */			\
+     0,	   0,	 0,    0,    0,	   0,	 0,    0,			\
+ /*  r24   r25	 r26   r27   r28   r29	 r30   tls */			\
+     0,	   0,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  reserved	 c     hi    lo	 */					\
+     1,		 1,    0,    0,						\
+ /*  reserved */							\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  vr0   vr1	 vr2   vr3   vr4   vr5	 vr6   vr7  */			\
+     0,	   0,	 0,    0,    0,	   0,	 0,    0,			\
+ /*  vr8   vr9	 vr10  vr11  vr12  vr13	 vr14  vr15 */			\
+     0,	   0,	 0,    0,    0,	   0,	 0,    0 ,			\
+ /*  reserved */							\
+     1,	   1,								\
+ /*  epc */								\
+     1									\
+}
+
+/* 1 for registers that is clobbered (in general) by function calls.
+   If a register has 0, the compiler automatically saves it on
+   function entry and restores it on function exit, if the register
+   is used within the function.  */
+#define CALL_USED_REGISTERS \
+ /*  r0	   r1	 r2    r3    r4	   r5	 r6    r7  */			\
+{    1,	   1,	 1,    1,    0,	   0,	 0,    0,			\
+ /*  r8	   r9	 r10   r11   r12   r13	 r14   r15 */			\
+     0,	   0,	 0,    0,    1,	   1,	 1,    0,			\
+ /*  r16   r17	 r18   r19   r20   r21	 r22   r23 */			\
+     0,	   0,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  r24   r25	 r26   r27   r28   r29	 r30   r31 */			\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  reserved	 c     hi    lo */					\
+     1,		 1,    1,    1,						\
+ /*  reserved */							\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  vr0   vr1	 vr2   vr3   vr4   vr5	 vr6   vr7 */			\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  vr8   vr9	 vr10  vr11  vr12  vr13	 vr14  vr15 */			\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  reserved */							\
+     1,	   1,								\
+ /*  epc */								\
+     1									\
+}
+
+/* Like `CALL_USED_REGISTERS' but used to overcome a historical
+   problem which makes CALL_USED_REGISTERS *always* include
+   all the FIXED_REGISTERS.  Until this problem has been
+   resolved this macro can be used to overcome this situation.
+   In particular, block_propagate() requires this list
+   be accurate, or we can remove registers which should be live.
+   This macro is used in get_csky_live_regs().  */
+#define CALL_REALLY_USED_REGISTERS \
+ /*  r0	   r1	 r2    r3    r4	   r5	 r6    r7  */			\
+{    1,	   1,	 1,    1,    0,	   0,	 0,    0,			\
+ /*  r8	   r9	 r10   r11   r12   r13	 r14   r15 */			\
+     0,	   0,	 0,    0,    1,	   1,	 1,    0,			\
+ /*  r16   r17	 r18   r19   r20   r21	 r22   r23 */			\
+     0,	   0,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  r24   r25	 r26   r27   r28   r29	 r30   r31 */			\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  reserved	 c     hi    lo */					\
+     1,		 1,    1,    1,						\
+ /*  reserved */							\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  vr0   vr1	 vr2   vr3   vr4   vr5	 vr6   vr7 */			\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  vr8   vr9	 vr10  vr11  vr12  vr13	 vr14  vr15 */			\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  reserved */							\
+     1,	   1,								\
+ /*  epc */								\
+     1									\
+}
+
+#define REGISTER_NAMES							\
+{									\
+  "a0",	 "a1",	"a2",  "a3",  "l0",  "l1",  "l2",  "l3",		\
+  "l4",	 "l5",	"l6",  "l7",  "t0",  "t1",  "sp",  "lr",		\
+  "l8",	 "l9",	"t2",  "t3",  "t4",  "t5",  "t6",  "t7",		\
+  "t8",	 "t9",	"r26", "r27", "gb",  "r29", "svbr", "r31",		\
+  /* reserved */							\
+  "reserved",								\
+  /* CC register: 33 */							\
+  "c",									\
+  /* DSP instruction register: 34, 35 */				\
+  "hi", "lo",								\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved",								\
+  /* V registers: 52~67 */						\
+  "vr0", "vr1", "vr2",	"vr3",	"vr4",	"vr5",	"vr6",	"vr7",		\
+  "vr8", "vr9", "vr10", "vr11", "vr12", "vr13", "vr14", "vr15",		\
+  "reserved", "reserved",						\
+  "epc"									\
+}
+
+/* Table of additional register names to use in user input.  */
+#define ADDITIONAL_REGISTER_NAMES   \
+{				    \
+  {"r0",  0},			    \
+  {"r1",  1},			    \
+  {"r2",  2},			    \
+  {"r3",  3},			    \
+  {"r4",  4},			    \
+  {"r5",  5},			    \
+  {"r6",  6},			    \
+  {"r7",  7},			    \
+  {"r8",  8},			    \
+  {"r9",  9},			    \
+  {"r10", 10},			    \
+  {"r11", 11},			    \
+  {"r12", 12},			    \
+  {"r13", 13},			    \
+  {"r14", 14},			    \
+  {"r15", 15},			    \
+  {"r16", 16},			    \
+  {"r17", 17},			    \
+  {"r18", 18},			    \
+  {"r19", 19},			    \
+  {"r20", 20},			    \
+  {"r21", 21},			    \
+  {"r22", 22},			    \
+  {"r23", 23},			    \
+  {"r24", 24},			    \
+  {"r25", 25},			    \
+  {"r26", 26},			    \
+  {"r27", 27},			    \
+  {"r28", 28},			    \
+  {"r29", 29},			    \
+  {"r30", 30},			    \
+  {"r31", 31},			    \
+}
+
+/* The order in which registers should be allocated.
+   It is better to use the registers the caller need not save.
+   Allocate r0 through r3 in reverse order since r3 is least likely
+   to contain a function parameter; in addition results are returned
+   in r0.  It is quite good to use lr since other calls may clobber
+   it anyway.  */
+#define REG_ALLOC_ORDER						\
+/*   r3	   r2	 r1    r0   r12	  r13	r18   r19 */		\
+  {   3,    2,	  1,	0,   12,   13,	 18,   19,		\
+/*  r20	  r21	r22   r23   r24	  r25 */			\
+     20,   21,	 22,   23,   24,   25,				\
+/*   r15   r4	 r5   r6     r7	   r8	 r9   r10   r11 */	\
+     15,    4,	  5,   6,     7,    8,	  9,   10,   11,	\
+/*  r16	  r17	r26   r27   r28	  r29	r30    hi    lo	 */	\
+     16,   17,	 26,   27,   28,   29,	 30,   34,   35,	\
+/*  vr0	  vr1	vr2   vr3   vr4	  vr5	vr6   vr7  */		\
+     52,   53,	 54,   55,   56,   57,	 58,   59,		\
+/*  vr8	  vr9	vr10  vr11  vr12  vr13	vr14  vr15 */		\
+     60,   61,	 62,   63,   64,   65,	 66,   67,		\
+/*  reserved  */						\
+     36,   37,	 38,   39,   40,   41,	 42,   43,		\
+     44,   45,	 46,   47,   48,   49,	 50,   51,		\
+/*  sp	  tls	reserved     c	   reserved	    epc */	\
+     14,   31,	 32,	     33,   68,	 69,	     70	 }
+
+/*  Register classes.  */
+enum reg_class
+{
+  NO_REGS,
+  MINI_REGS,
+  SP_REGS,
+  LOW_REGS,
+  GENERAL_REGS,
+  C_REGS,
+  HI_REGS,
+  LO_REGS,
+  HILO_REGS,
+  V_REGS,
+  OTHER_REGS,
+  RESERVE_REGS,
+  ALL_REGS,
+  LIM_REG_CLASSES
+};
+
+#define N_REG_CLASSES  (int) LIM_REG_CLASSES
+
+/* Give names of register classes as strings for dump file.  */
+#define REG_CLASS_NAMES \
+{			\
+  "NO_REGS",		\
+  "MINI_REGS",		\
+  "SP_REGS",		\
+  "LOW_REGS",		\
+  "GENERAL_REGS",	\
+  "C_REGS",		\
+  "HI_REGS",		\
+  "LO_REGS",		\
+  "HILO_REGS",		\
+  "V_REGS",		\
+  "OTHER_REGS",		\
+  "RESERVE_REGS",	\
+  "ALL_REGS",		\
+}
+
+/* Define which registers fit in which classes.  This is an initializer
+   for a vector of HARD_REG_SET of length N_REG_CLASSES.  */
+#define REG_CLASS_CONTENTS					     \
+{								     \
+  {0x00000000, 0x00000000, 0x00000000 },  /* NO_REGS	       */    \
+  {0x000000FF, 0x00000000, 0x00000000 },  /* MINI_REGS	       */    \
+  {0x00004000, 0x00000000, 0x00000000 },  /* SP_REGS	       */    \
+  {0x0000FFFF, 0x00000000, 0x00000000 },  /* LOW_REGS	       */    \
+  {0xFFFFFFFF, 0x00000000, 0x00000000 },  /* GENERAL_REGS      */    \
+  {0x00000000, 0x00000002, 0x00000000 },  /* C_REGS	       */    \
+  {0x00000000, 0x00000004, 0x00000000 },  /* HI_REG	       */    \
+  {0x00000000, 0x00000008, 0x00000000 },  /* LO_REG	       */    \
+  {0x00000000, 0x0000000c, 0x00000000 },  /* HILO_REGS	       */    \
+  {0x00000000, 0xFFF00000, 0x0000000F },  /* V_REGS	       */    \
+  {0x00000000, 0x00000000, 0x00000040 },  /* OTHER_REGS	       */    \
+  {0x00000000, 0x0FF00001, 0x00000030 },  /* RESERVE_REGS      */    \
+  {0xFFFFFFFF, 0xFFFFFFFF, 0x0000007F },  /* ALL_REGS	       */    \
+}
+
+/* Return register class from regno.  */
+extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
+#define REGNO_REG_CLASS(REGNO) regno_reg_class[REGNO]
+
+/* The class value for index registers, and the one for base regs.  */
+#define INDEX_REG_CLASS	 (CSKY_ISA_FEATURE (2E3) ? GENERAL_REGS : NO_REGS)
+#define BASE_REG_CLASS	GENERAL_REGS
+
+/* TODO is it necessary to set it to MINI_REGS to emit more 16-bit
+   instructions?  */
+#define MODE_BASE_REG_CLASS(MODE) GENERAL_REGS
+
+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
+   and check its validity for a certain class.
+   We have two alternate definitions for each of them.
+   The usual definition accepts all pseudo regs; the other rejects
+   them unless they have been allocated suitable hard regs.
+   The symbol REG_OK_STRICT causes the latter definition to be used.
+
+   Most source files want to accept pseudo regs in the hope that
+   they will get allocated to the class that the insn wants them to be in.
+   Source files for reload pass need to be strict.
+   After reload, it makes no difference, since pseudo regs have
+   been eliminated by then.
+
+   The reg_renumber is used to map pseudo regs into hardware
+   regs, it is set up as a result of register allocation.  */
+#ifdef REG_OK_STRICT
+#define REGNO_OK_FOR_BASE_P(REGNO)		       \
+  (CSKY_GENERAL_REGNO_P (REGNO)			       \
+   || CSKY_GENERAL_REGNO_P (reg_renumber[(REGNO)]) )
+#else
+#define REGNO_OK_FOR_BASE_P(REGNO)		       \
+  (CSKY_GENERAL_REGNO_P (REGNO)			       \
+   || (REGNO) >= FIRST_PSEUDO_REGISTER)
+#endif
+
+
+#ifdef REG_OK_STRICT
+#define REGNO_OK_FOR_INDEX_P(REGNO)			\
+  (CSKY_GENERAL_REGNO_P (REGNO)				\
+   || CSKY_GENERAL_REGNO_P (reg_renumber[(REGNO)]) )
+#else
+#define REGNO_OK_FOR_INDEX_P(REGNO)		      \
+  (CSKY_GENERAL_REGNO_P (REGNO)			      \
+   || (REGNO) >= FIRST_PSEUDO_REGISTER)
+#endif
+
+
+/******************************************************************
+ *			  Addressing Modes			  *
+ ******************************************************************/
+
+
+/* Recognize any constant value that is a valid address.  */
+#define CONSTANT_ADDRESS_P(X) \
+  (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF)
+
+/* Maximum number of registers that can appear in a valid memory address.
+   Shifts in addresses can't be by a register.  */
+#define MAX_REGS_PER_ADDRESS 2
+
+
+/******************************************************************
+ *			  Run-time Target			  *
+ ******************************************************************/
+
+
+#define TARGET_CPU_CPP_BUILTINS()		      \
+  csky_cpu_cpp_builtins (pfile)
+
+/******************************************************************
+ *			Per-function Data			  *
+ ******************************************************************/
+
+
+/* Initialize data used by insn expanders.  This is called from insn_emit,
+   once for every function before code is generated.  */
+#define INIT_EXPANDERS	csky_init_expanders ()
+
+
+/******************************************************************
+ *    Dividing the Output into Sections (Texts, Data, . . . )	  *
+ ******************************************************************/
+
+
+/* Switch to the text or data segment.  */
+#define TEXT_SECTION_ASM_OP  "\t.text"
+#define DATA_SECTION_ASM_OP  "\t.data"
+
+/* The subroutine calls in the .init and .fini sections create literal
+   pools which must be jumped around...  */
+#define FORCE_CODE_SECTION_ALIGN    \
+  asm ("br 1f ; .literals ; .align 2 ; 1:");
+
+/* Define this macro to be an expression with a nonzero value if
+   jump tables (for tablejump insns) should be output in the text section,
+   along with the assembler instructions.  */
+#define JUMP_TABLES_IN_TEXT_SECTION TARGET_CASESI
+
+
+/******************************************************************
+ *			Assembler Format			  *
+ ******************************************************************/
+
+
+/* A C string constant for text to be output before(after) each asm
+   statement or group of consecutive ones.  */
+#undef	ASM_APP_ON
+#define ASM_APP_ON    "// inline asm begin\n"
+#undef	ASM_APP_OFF
+#define ASM_APP_OFF   "// inline asm end\n"
+
+/* A C string constant describing how to begin a comment in the target
+   assembler language.  */
+#define ASM_COMMENT_START "\t//"
+
+/* This says how to output an assembler line
+   to define a global common symbol, with alignment information.  */
+#undef	ASM_OUTPUT_ALIGNED_COMMON
+#define ASM_OUTPUT_ALIGNED_COMMON(STREAM, NAME, SIZE, ALIGN)	\
+  do								\
+    {								\
+      fputs ("\t.comm\t", STREAM);				\
+      assemble_name (STREAM, NAME);				\
+      fprintf (STREAM, ",%lu, %u\n", (unsigned long)(SIZE),	\
+	       (ALIGN) / BITS_PER_UNIT);			\
+    }								\
+while (0)
+
+/* Define a local common symbol whose alignment we wish to specify.
+   ALIGN comes in as bits, we have to turn it into bytes.  */
+#undef	ASM_OUTPUT_ALIGNED_LOCAL
+#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN)	\
+  do								\
+{								\
+  fputs ("\t.bss\t", (STREAM));					\
+  assemble_name ((STREAM), (NAME));				\
+  fprintf ((STREAM), ",%d, %d\n", (int)(SIZE),			\
+	   (ALIGN) / BITS_PER_UNIT);				\
+}								\
+while (0)
+
+/* Globalizing directive for a label.  */
+#define GLOBAL_ASM_OP "\t.global\t"
+
+/* Output a reference to a label.  */
+#undef	ASM_OUTPUT_LABELREF
+#define ASM_OUTPUT_LABELREF(STREAM, NAME)     \
+  fprintf (STREAM, "%s%s", user_label_prefix, \
+	   (* targetm.strip_name_encoding) (NAME))
+
+/* Make an internal label into a string.  */
+#undef	ASM_GENERATE_INTERNAL_LABEL
+#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM)  \
+  sprintf (STRING, "*.%s%ld", PREFIX, (long) NUM)
+
+/* This is how to output an insn to push a register on the stack.
+   It need not be very fast code.  */
+#define ASM_OUTPUT_REG_PUSH(STREAM,REGNO)		    \
+  fprintf (STREAM, "\tsubi\t %s,%d\n\tst.w\t %s,(%s)\n",    \
+	   reg_names[STACK_POINTER_REGNUM],		    \
+	   (STACK_BOUNDARY / BITS_PER_UNIT),		    \
+	   reg_names[REGNO],				    \
+	   reg_names[STACK_POINTER_REGNUM])
+
+/* This is how to output an insn to pop a register from the stack.  */
+#define ASM_OUTPUT_REG_POP(STREAM,REGNO)		    \
+  fprintf (STREAM, "\tld.w\t %s,(%s)\n\taddi\t %s,%d\n",    \
+	   reg_names[REGNO],				    \
+	   reg_names[STACK_POINTER_REGNUM],		    \
+	   reg_names[STACK_POINTER_REGNUM],		    \
+	   (STACK_BOUNDARY / BITS_PER_UNIT))
+
+/* Output an element of a dispatch table.  */
+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE)  \
+  fprintf (STREAM, "\t.long\t.L%d\n", VALUE)
+
+/* This is how to output an assembler line
+   that says to advance the location counter by SIZE bytes.  */
+#undef	ASM_OUTPUT_SKIP
+#define ASM_OUTPUT_SKIP(STREAM,SIZE)  \
+  fprintf (STREAM, "\t.fill %d, 1\n", (int)(SIZE))
+
+/* Align output to a power of two.  Note ".align 0" is redundant,
+   and also GAS will treat it as ".align 2" which we do not want.  */
+#define ASM_OUTPUT_ALIGN(STREAM, POWER)			\
+  do							\
+    {							\
+      if ((POWER) > 0)					\
+	fprintf (STREAM, "\t.align\t%d\n", POWER);	\
+    }							\
+  while (0)
+
+
+/******************************************************************
+ *		Controlling the Compilation Driver		  *
+ ******************************************************************/
+
+
+/* Define this macro as a C expression for the initializer of an
+   array of string to tell the driver program which options are
+   defaults for this target and thus do not need to be handled
+   specially when using MULTILIB_OPTIONS.  */
+#undef MULTILIB_DEFAULTS
+#define MULTILIB_DEFAULTS    \
+    {"mlittle-endian", "mcpu=ck810f", "msoft-float"}
+
+/* Support for a compile-time default CPU, et cetera.  The rules are:
+   --with-arch is ignored if -march or -mcpu are specified.
+   --with-cpu is ignored if -march or -mcpu are specified, and is overridden
+    by --with-arch. */
+#define OPTION_DEFAULT_SPECS \
+  {"arch", "%{!march=*:%{!mcpu=*:-march=%(VALUE)}}" }, \
+  {"cpu", "%{!march=*:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
+  {"endian", "%{!mbig-endian:%{!mlittle-endian:-m%(VALUE)-endian}}" }, \
+  {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" },
+
+
+/******************************************************************
+ *		      Position Independent Code			  *
+ ******************************************************************/
+
+/* Define the global table register.  */
+#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? CSKY_GB_REGNUM : INVALID_REGNUM)
+
+/* Nonzero if x is a legitimate immediate operand on the target machine
+   when generating position-independent code.  */
+#define LEGITIMATE_PIC_OPERAND_P(X) \
+  csky_legitimate_pic_operand_p (X)
+
+
+/******************************************************************
+ *	      Controlling Debugging Information Format		  *
+ ******************************************************************/
+
+
+/* Define this macro if GCC should produce dwarf version 2 format debugging
+   output in response to the `-g' option.  */
+#define DWARF2_DEBUGGING_INFO 1
+
+/* Define this macro to 0 if your target supports DWARF 2 frame unwind
+   information, but it does not yet work with exception handling.  */
+#define DWARF2_UNWIND_INFO 1
+
+/* Define this if you have arranged for GCC to support
+   more than one format of debugging output.
+   The value of this macro only affects the default debugging output.  */
+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+
+/* Define this macro if the target’s representation
+   for dwarf registers used in .eh_frame or .debug_frame
+   is different from that used in other debug info sections.
+   Given a GCC hard register number,
+   this macro should return the .eh_frame register number.*/
+#define DWARF_FRAME_REGNUM(REG)	 DBX_REGISTER_NUMBER (REG)
+
+/* If INCOMING_RETURN_ADDR_RTX is defined & the RTL is REG,
+   define DWARF_FRAME_RETURN_COLUMN to DWARF_FRAME_REGNUM.  */
+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (CSKY_LR_REGNUM)
+
+/* Use r0 and r1 to pass exception handling information.  */
+#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? N : INVALID_REGNUM)
+
+/* How to renumber registers for dbx and gdb.  */
+extern const int csky_dbx_regno[];
+#define DBX_REGISTER_NUMBER(REGNO) ((unsigned int) csky_dbx_regno[REGNO])
+
+
+/******************************************************************
+ *		      Miscellaneous Parameters			  *
+ ******************************************************************/
+
+
+/* Specify the machine mode that this machine uses
+   for the index in the tablejump instruction.  */
+#define CASE_VECTOR_MODE SImode
+
+/* Define if operations between registers always perform the operation
+   on the full register even if a narrower mode is specified.  */
+#define WORD_REGISTER_OPERATIONS 1
+
+/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
+   will either zero-extend or sign-extend.  The value of this macro should
+   be the code that says which one of the two operations is implicitly
+   done, UNKNOWN if none.  */
+#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
+
+/* Max number of bytes we can move from memory to memory
+   in one reasonably fast instruction.  */
+#define MOVE_MAX 4
+
+/* Shift counts are truncated to 6-bits (0 to 63) instead of the expected
+   5-bits, so we can not define SHIFT_COUNT_TRUNCATED to true for this
+   target.  */
+#define SHIFT_COUNT_TRUNCATED 0
+
+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
+
+/* The machine modes of pointers and functions.  */
+#define Pmode  SImode
+#define FUNCTION_MODE  Pmode
+
+/* Define this macro to be a C expression to indicate when jump-tables
+   should contain relative addresses.  */
+#define CASE_VECTOR_PC_RELATIVE \
+  (optimize_size && TARGET_CONSTANT_POOL \
+   && (CSKY_TARGET_ARCH (CK802) || CSKY_TARGET_ARCH (CK801)))
+
+/* Return the preferred mode for an addr_diff_vec when the minimum
+   and maximum offset are known.  */
+#define CASE_VECTOR_SHORTEN_MODE(min, max, body)		    \
+  (min >= 0 && max < 512					    \
+   ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 1, QImode)	    \
+   : min >= -256 && max < 256					    \
+     ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 0, QImode)	    \
+     : min >= 0 && max < 8192					    \
+       ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 1, HImode)   \
+       : min >= -4096 && max < 4096				    \
+	 ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 0, HImode) \
+	 : SImode)
+
+/* This is how to output an element of a case-vector that is relative.  */
+#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL)	    \
+  do								    \
+    {								    \
+      if (optimize_size && TARGET_CONSTANT_POOL			    \
+	  && (CSKY_TARGET_ARCH (CK802) || CSKY_TARGET_ARCH (CK801)))  \
+	{							    \
+	  switch (GET_MODE (BODY))				    \
+	    {							    \
+	    case E_QImode:					    \
+	      asm_fprintf (STREAM, "\t.byte\t(.L%d-.L%d)/2\n",	    \
+			   VALUE, REL);				    \
+	      break;						    \
+	    case E_HImode: /* TBH */				    \
+	      asm_fprintf (STREAM, "\t.short\t(.L%d-.L%d)/2\n",	    \
+			   VALUE, REL);				    \
+	      break;						    \
+	    case E_SImode:					    \
+	      asm_fprintf (STREAM, "\t.long\t.L%d-.L%d\n",	    \
+			   VALUE, REL);				    \
+	      break;						    \
+	    default:						    \
+	      gcc_unreachable ();				    \
+	    }							    \
+	}							    \
+      else							    \
+	asm_fprintf (STREAM, "\t.long\t.L%d@GOTOFF\n", VALUE);	    \
+    } while (0)
+
+/* This macro is not documented yet.
+   But we do need it to make jump table vector aligned.  */
+#define ADDR_VEC_ALIGN(JUMPTABLE) 0
+
+/* We have to undef this first to override the version from elfos.h.  */
+#undef	ASM_OUTPUT_CASE_LABEL
+#define ASM_OUTPUT_CASE_LABEL(stream, prefix, num, table)	\
+  do								\
+    {								\
+      if (GET_MODE (PATTERN (table)) == SImode)			\
+	ASM_OUTPUT_ALIGN (stream, 2);				\
+      (*targetm.asm_out.internal_label) (stream, prefix, num);	\
+    } while (0)
+
+/* Make sure subsequent insns are aligned after a byte-sized jump offset
+   table.  */
+#define ASM_OUTPUT_CASE_END(stream, num, table)	  \
+  do						  \
+    {						  \
+      if (GET_MODE (PATTERN (table)) == QImode)	  \
+	ASM_OUTPUT_ALIGN (stream, 1);		  \
+    } while (0)
+
+
+
+
+/******************************************************************
+ *		  Trampolines for Nested Functions		  *
+ ******************************************************************/
+
+
+/* Length in units of the trampoline for entering a nested function.  */
+#define TRAMPOLINE_SIZE	 (CSKY_ISA_FEATURE (2E3) ? 16 : 20)
+
+/* Alignment required for a trampoline in bits.  */
+#define TRAMPOLINE_ALIGNMENT  32
+
+
+/******************************************************************
+ *	      Describing Relative Costs of Operations		  *
+ ******************************************************************/
+
+
+/* Nonzero if access to memory by bytes is slow and undesirable.
+   For RISC chips, it means that access to memory by bytes is no
+   better than access by words when possible, so grab a whole word
+   and maybe make use of that.  */
+#define SLOW_BYTE_ACCESS  0
+
+/* On C-SKY, function CSE would allow use of 16-bit jsr instructions
+   instead of normal 32-bit calls.  But it also needs a separate constant
+   pool entry for the function address and an instruction to load it, and
+   may cause additional spills due to increased register pressure, etc.
+   It doesn't seem like a good idea overall.  */
+#define NO_FUNCTION_CSE 1
+
+/* Try to generate sequences that don't involve branches, we can then use
+   conditional instructions.  */
+#define BRANCH_COST(speed_p, predictable_p)			\
+  csky_default_branch_cost (speed_p, predictable_p)
+
+/* False if short circuit operation is preferred.  */
+#define LOGICAL_OP_NON_SHORT_CIRCUIT \
+  (csky_default_logical_op_non_short_circuit ())
+
+
+/******************************************************************
+ *		   Generating Code for Profiling		  *
+ ******************************************************************/
+
+
+#define FUNCTION_PROFILER(FILE, LABELNO)
+
+#endif /* GCC_CSKY_H */