1  /* Target Definitions for TI C6X.
       2     Copyright (C) 2010-2023 Free Software Foundation, Inc.
       3     Contributed by Andrew Jenner <andrew@codesourcery.com>
       4     Contributed by Bernd Schmidt <bernds@codesourcery.com>
       5  
       6     This file is part of GCC.
       7  
       8     GCC is free software; you can redistribute it and/or modify it
       9     under the terms of the GNU General Public License as published
      10     by the Free Software Foundation; either version 3, or (at your
      11     option) any later version.
      12  
      13     GCC is distributed in the hope that it will be useful, but WITHOUT
      14     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      15     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
      16     License for more details.
      17  
      18     You should have received a copy of the GNU General Public License
      19     along with GCC; see the file COPYING3.  If not see
      20     <http://www.gnu.org/licenses/>.  */
      21  
      22  #ifndef GCC_C6X_H
      23  #define GCC_C6X_H
      24  
      25  /* Feature bit definitions that enable specific insns.  */
      26  #define C6X_INSNS_C62X		1
      27  #define C6X_INSNS_C64X		2
      28  #define C6X_INSNS_C64XP		4
      29  #define C6X_INSNS_C67X		8
      30  #define C6X_INSNS_C67XP		16
      31  #define C6X_INSNS_C674X		32
      32  #define C6X_INSNS_ATOMIC	64
      33  #define C6X_INSNS_ALL_CPU_BITS	127
      34  
      35  #define C6X_DEFAULT_INSN_MASK						\
      36    (C6X_INSNS_C62X | C6X_INSNS_C64X | C6X_INSNS_C64XP)
      37  
      38  /* A mask of allowed insn types, as defined above.  */
      39  extern unsigned long c6x_insn_mask;
      40  
      41  /* Value of -march= */
      42  extern c6x_cpu_t c6x_arch;
      43  #define C6X_DEFAULT_ARCH C6X_CPU_C64XP
      44  
      45  /* True if the target has C64x instructions.  */
      46  #define TARGET_INSNS_64		((c6x_insn_mask & C6X_INSNS_C64X) != 0)
      47  /* True if the target has C64x+ instructions.  */
      48  #define TARGET_INSNS_64PLUS	((c6x_insn_mask & C6X_INSNS_C64XP) != 0)
      49  /* True if the target has C67x instructions.  */
      50  #define TARGET_INSNS_67		((c6x_insn_mask & C6X_INSNS_C67X) != 0)
      51  /* True if the target has C67x+ instructions.  */
      52  #define TARGET_INSNS_67PLUS	((c6x_insn_mask & C6X_INSNS_C67XP) != 0)
      53  
      54  /* True if the target supports doubleword loads.  */
      55  #define TARGET_LDDW		(TARGET_INSNS_64 || TARGET_INSNS_67)
      56  /* True if the target supports doubleword loads.  */
      57  #define TARGET_STDW		TARGET_INSNS_64
      58  /* True if the target supports the MPY32 family of instructions.  */
      59  #define TARGET_MPY32		TARGET_INSNS_64PLUS
      60  /* True if the target has floating point hardware.  */
      61  #define TARGET_FP		TARGET_INSNS_67
      62  /* True if the target has C67x+ floating point extensions.  */
      63  #define TARGET_FP_EXT		TARGET_INSNS_67PLUS
      64  
      65  #define TARGET_DEFAULT 0
      66  
      67  /* Run-time Target.  */
      68  
      69  #define TARGET_CPU_CPP_BUILTINS()		\
      70    do						\
      71      {						\
      72        builtin_assert ("machine=tic6x");		\
      73        builtin_assert ("cpu=tic6x");		\
      74        builtin_define ("__TMS320C6X__");		\
      75        builtin_define ("_TMS320C6X");		\
      76  						\
      77        if (TARGET_DSBT)				\
      78  	builtin_define ("__DSBT__");		\
      79  						\
      80        if (TARGET_BIG_ENDIAN)			\
      81  	builtin_define ("_BIG_ENDIAN");		\
      82        else					\
      83  	builtin_define ("_LITTLE_ENDIAN");	\
      84  						\
      85        switch (c6x_arch)				\
      86  	{					\
      87  	case unk_isa:				\
      88  	  break;				\
      89  	case C6X_CPU_C62X:			\
      90  	  builtin_define ("_TMS320C6200");	\
      91  	  break;				\
      92  						\
      93  	case C6X_CPU_C64XP:			\
      94  	  builtin_define ("_TMS320C6400_PLUS");	\
      95  	  /* fall through */			\
      96  	case C6X_CPU_C64X:			\
      97  	  builtin_define ("_TMS320C6400");	\
      98  	  break;				\
      99  						\
     100  	case C6X_CPU_C67XP:			\
     101  	  builtin_define ("_TMS320C6700_PLUS");	\
     102  	  /* fall through */			\
     103  	case C6X_CPU_C67X:			\
     104  	  builtin_define ("_TMS320C6700");	\
     105  	  break;				\
     106  						\
     107  	case C6X_CPU_C674X:			\
     108  	  builtin_define ("_TMS320C6740");	\
     109  	  builtin_define ("_TMS320C6700_PLUS");	\
     110  	  builtin_define ("_TMS320C6700");	\
     111  	  builtin_define ("_TMS320C6400_PLUS");	\
     112  	  builtin_define ("_TMS320C6400");	\
     113  	  break;				\
     114  	}					\
     115      } while (0)
     116  
     117  #define OPTION_DEFAULT_SPECS \
     118    {"arch", "%{!march=*:-march=%(VALUE)}" }
     119  
     120  /* Storage Layout.  */
     121  
     122  #define BITS_BIG_ENDIAN 0
     123  #define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
     124  #define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
     125  
     126  #define REG_WORDS_BIG_ENDIAN 0
     127  
     128  #define UNITS_PER_WORD 4
     129  #define PARM_BOUNDARY 8
     130  #define STACK_BOUNDARY 64
     131  #define FUNCTION_BOUNDARY 32
     132  #define BIGGEST_ALIGNMENT 64
     133  #define STRICT_ALIGNMENT 1
     134  
     135  /* The ABI requires static arrays must be at least 8 byte aligned.
     136     Really only externally visible arrays must be aligned this way, as
     137     only those are directly visible from another compilation unit.  But
     138     we don't have that information available here.  */
     139  #define DATA_ABI_ALIGNMENT(TYPE, ALIGN)					\
     140    (((ALIGN) < BITS_PER_UNIT * 8 && TREE_CODE (TYPE) == ARRAY_TYPE)	\
     141     ? BITS_PER_UNIT * 8 : (ALIGN))
     142  
     143  /* Type Layout.  */
     144  
     145  #define DEFAULT_SIGNED_CHAR 1
     146  
     147  #undef SIZE_TYPE
     148  #define SIZE_TYPE "unsigned int"
     149  #undef PTRDIFF_TYPE
     150  #define PTRDIFF_TYPE "int"
     151  
     152  /* Registers.  */
     153  
     154  #define FIRST_PSEUDO_REGISTER 67
     155  #define FIXED_REGISTERS					\
     156    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	\
     157      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	\
     158      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,	\
     159      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	\
     160      1, 1, 1}
     161  #define CALL_USED_REGISTERS				\
     162    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,	\
     163      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	\
     164      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1,	\
     165      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	\
     166      1, 1, 1}
     167  
     168  /* This lists call-used non-predicate registers first, followed by call-used
     169     registers, followed by predicate registers.  We want to avoid allocating
     170     the predicate registers for other uses as much as possible.  */
     171  #define REG_ALLOC_ORDER							\
     172    {									\
     173      REG_A0, REG_A3, REG_A4, REG_A5, REG_A6, REG_A7, REG_A8, REG_A9,	\
     174      REG_A16, REG_A17, REG_A18, REG_A19, REG_A20, REG_A21, REG_A22, REG_A23, \
     175      REG_A24, REG_A25, REG_A26, REG_A27, REG_A28, REG_A29, REG_A30, REG_A31, \
     176      REG_B4, REG_B5, REG_B6, REG_B7, REG_B8, REG_B9, REG_B16,	\
     177      REG_B17, REG_B18, REG_B19, REG_B20, REG_B21, REG_B22, REG_B23, REG_B24, \
     178      REG_B25, REG_B26, REG_B27, REG_B28, REG_B29, REG_B30, REG_B31,	\
     179      REG_A10, REG_A11, REG_A12, REG_A13, REG_A14, REG_A15,		\
     180      REG_B3, REG_B10, REG_B11, REG_B12, REG_B13, REG_B14, REG_B15,	\
     181      REG_A1, REG_A2, REG_B0, REG_B1, REG_B2, REG_ILC			\
     182    }
     183  
     184  /* Register Classes.  */
     185  
     186  enum reg_class
     187    {
     188      NO_REGS,
     189      PREDICATE_A_REGS,
     190      PREDICATE_B_REGS,
     191      PREDICATE_REGS,
     192      PICREG,
     193      SPREG,
     194      CALL_USED_B_REGS,
     195      NONPREDICATE_A_REGS,
     196      NONPREDICATE_B_REGS,
     197      NONPREDICATE_REGS,
     198      A_REGS,
     199      B_REGS,
     200      GENERAL_REGS,
     201      ALL_REGS,
     202      LIM_REG_CLASSES
     203    };
     204  
     205  #define N_REG_CLASSES (int) LIM_REG_CLASSES
     206  
     207  #define REG_CLASS_NAMES {	  \
     208      "NO_REGS",			  \
     209      "PREDICATE_A_REGS",		  \
     210      "PREDICATE_B_REGS",		  \
     211      "PREDICATE_REGS",		  \
     212      "PICREG",			  \
     213      "SPREG",			  \
     214      "CALL_USED_B_REGS",		  \
     215      "NONPREDICATE_A_REGS",	  \
     216      "NONPREDICATE_B_REGS",	  \
     217      "NONPREDICATE_REGS",	  \
     218      "A_REGS",			  \
     219      "B_REGS",			  \
     220      "GENERAL_REGS",		  \
     221      "ALL_REGS" }
     222  
     223  #define REG_CLASS_CONTENTS			\
     224  {						\
     225    /* NO_REGS.  */				\
     226    { 0x00000000, 0x00000000, 0 },		\
     227    /* PREDICATE_A_REGS.  */			\
     228    { 0x00000006, 0x00000000, 0 },		\
     229    /* PREDICATE_B_REGS.  */			\
     230    { 0x00000000, 0x00000007, 0 },		\
     231    /* PREDICATE_REGS.  */			\
     232    { 0x00000006, 0x00000007, 0 },		\
     233    /* PICREG.  */				\
     234    { 0x00000000, 0x00004000, 0 },		\
     235    /* SPREG.  */					\
     236    { 0x00000000, 0x00008000, 0 },		\
     237    /* CALL_USED_B_REGS.  */			\
     238    { 0x00000000, 0xFFFF03FF, 0 },		\
     239    /* NONPREDICATE_A_REGS.  */			\
     240    { 0xFFFFFFF9, 0x00000000, 0 },		\
     241    /* NONPREDICATE_B_REGS.  */			\
     242    { 0x00000000, 0xFFFFFFF8, 0 },		\
     243    /* NONPREDICATE_REGS.  */			\
     244    { 0xFFFFFFF9, 0xFFFFFFF8, 0 },		\
     245    /* A_REGS.  */				\
     246    { 0xFFFFFFFF, 0x00000000, 3 },		\
     247    /* B_REGS.  */				\
     248    { 0x00000000, 0xFFFFFFFF, 3 },		\
     249    /* GENERAL_REGS.  */				\
     250    { 0xFFFFFFFF, 0xFFFFFFFF, 3 },		\
     251    /* ALL_REGS.  */				\
     252    { 0xFFFFFFFF, 0xFFFFFFFF, 7 },		\
     253  }
     254  
     255  #define A_REGNO_P(N) ((N) <= REG_A31)
     256  #define B_REGNO_P(N) ((N) >= REG_B0 && (N) <= REG_B31)
     257  
     258  #define A_REG_P(X) (REG_P (X) && A_REGNO_P (REGNO (X)))
     259  #define CROSS_OPERANDS(X0,X1) \
     260    (A_REG_P (X0) == A_REG_P (X1) ? CROSS_N : CROSS_Y)
     261  
     262  #define REGNO_REG_CLASS(reg) c6x_regno_reg_class (reg)
     263  
     264  #define BASE_REG_CLASS ALL_REGS
     265  #define INDEX_REG_CLASS ALL_REGS
     266  
     267  #define REGNO_OK_FOR_BASE_STRICT_P(X)				\
     268    ((X) < FIRST_PSEUDO_REGISTER					\
     269     || (reg_renumber[X] >= 0 && reg_renumber[X] < FIRST_PSEUDO_REGISTER))
     270  #define REGNO_OK_FOR_BASE_NONSTRICT_P(X) 1
     271  
     272  #define REGNO_OK_FOR_INDEX_STRICT_P(X)				\
     273    ((X) < FIRST_PSEUDO_REGISTER					\
     274     || (reg_renumber[X] >= 0 && reg_renumber[X] < FIRST_PSEUDO_REGISTER))
     275  #define REGNO_OK_FOR_INDEX_NONSTRICT_P(X) 1
     276  
     277  #ifdef REG_OK_STRICT
     278  #define REGNO_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_STRICT_P (X)
     279  #define REGNO_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_STRICT_P (X)
     280  #else
     281  #define REGNO_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_NONSTRICT_P (X)
     282  #define REGNO_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_NONSTRICT_P (X)
     283  #endif
     284  
     285  #define CLASS_MAX_NREGS(class, mode) \
     286    ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
     287  
     288  #define REGNO_OK_FOR_INDIRECT_JUMP_P(REGNO, MODE) B_REGNO_P (REGNO)
     289  
     290  /* Stack and Calling.  */
     291  
     292  /* SP points to 4 bytes below the first word of the frame.  */
     293  #define STACK_POINTER_OFFSET 4
     294  /* Likewise for AP (which is the incoming stack pointer).  */
     295  #define FIRST_PARM_OFFSET(fundecl) 4
     296  #define FRAME_GROWS_DOWNWARD 1
     297  #define STACK_GROWS_DOWNWARD 1
     298  
     299  #define STACK_POINTER_REGNUM REG_B15
     300  #define HARD_FRAME_POINTER_REGNUM REG_A15
     301  /* These two always get eliminated in favour of the stack pointer
     302     or the hard frame pointer.  */
     303  #define FRAME_POINTER_REGNUM REG_FRAME
     304  #define ARG_POINTER_REGNUM REG_ARGP
     305  
     306  #define PIC_OFFSET_TABLE_REGNUM REG_B14
     307  
     308  /* We keep the stack pointer constant rather than using push/pop
     309     instructions.  */
     310  #define ACCUMULATE_OUTGOING_ARGS 1
     311  
     312  /* Before the prologue, the return address is in the B3 register.  */
     313  #define RETURN_ADDR_REGNO REG_B3
     314  #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, RETURN_ADDR_REGNO)
     315  #define DWARF_FRAME_RETURN_COLUMN	DWARF_FRAME_REGNUM (RETURN_ADDR_REGNO)
     316  
     317  #define RETURN_ADDR_RTX(COUNT, FRAME) c6x_return_addr_rtx (COUNT)
     318  
     319  #define INCOMING_FRAME_SP_OFFSET 0
     320  #define ARG_POINTER_CFA_OFFSET(fundecl) 0
     321  
     322  #define STATIC_CHAIN_REGNUM REG_A2
     323  
     324  struct c6x_args {
     325    /* Number of arguments to pass in registers.  */
     326    int nregs;
     327    /* Number of arguments passed in registers so far.  */
     328    int count;
     329  };
     330  
     331  #define CUMULATIVE_ARGS struct c6x_args
     332  
     333  #define INIT_CUMULATIVE_ARGS(cum, fntype, libname, fndecl, n_named_args) \
     334    c6x_init_cumulative_args (&cum, fntype, libname, n_named_args)
     335  
     336  #define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
     337    (c6x_block_reg_pad_upward (MODE, TYPE, FIRST) ? PAD_UPWARD : PAD_DOWNWARD)
     338  
     339  #define FUNCTION_ARG_REGNO_P(r) \
     340      (((r) >= REG_A4 && (r) <= REG_A13) || ((r) >= REG_B4 && (r) <= REG_B13))
     341  
     342  #define DEFAULT_PCC_STRUCT_RETURN 0
     343  
     344  #define FUNCTION_PROFILER(file, labelno) \
     345    fatal_error (input_location, \
     346  	       "profiling is not yet implemented for this architecture")
     347  
     348  
     349  /* Trampolines.  */
     350  #define TRAMPOLINE_SIZE 32
     351  #define TRAMPOLINE_ALIGNMENT 256
     352  
     353  #define ELIMINABLE_REGS					\
     354  {{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},		\
     355   { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},	\
     356   { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},		\
     357   { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}	\
     358  
     359  /* Define the offset between two registers, one to be eliminated, and the other
     360     its replacement, at the start of a routine.  */
     361  
     362  #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
     363    ((OFFSET) = c6x_initial_elimination_offset ((FROM), (TO)))
     364  
     365  /* Addressing Modes.  */
     366  
     367  #define CONSTANT_ADDRESS_P(x) (CONSTANT_P(x) && GET_CODE(x) != CONST_DOUBLE)
     368  #define MAX_REGS_PER_ADDRESS 2
     369  
     370  #define HAVE_PRE_DECREMENT 1
     371  #define HAVE_POST_DECREMENT 1
     372  #define HAVE_PRE_INCREMENT 1
     373  #define HAVE_POST_INCREMENT 1
     374  
     375  /* Register forms are available, but due to scaling we currently don't
     376     support them.  */
     377  #define HAVE_PRE_MODIFY_DISP 1
     378  #define HAVE_POST_MODIFY_DISP 1
     379  
     380  #define LEGITIMATE_PIC_OPERAND_P(X) \
     381    (!symbolic_operand (X, SImode))
     382  
     383  struct GTY(()) machine_function
     384  {
     385    /* True if we expanded a sibling call.  */
     386    int contains_sibcall;
     387  };
     388  
     389  /* Costs.  */
     390  #define NO_FUNCTION_CSE 1
     391  
     392  #define SLOW_BYTE_ACCESS 0
     393  
     394  #define BRANCH_COST(speed_p, predictable_p) 6
     395  
     396  
     397  /* Model costs for the vectorizer.  */
     398  
     399  /* Cost of conditional branch.  */
     400  #ifndef TARG_COND_BRANCH_COST
     401  #define TARG_COND_BRANCH_COST        6
     402  #endif
     403  
     404  /* Cost of any scalar operation, excluding load and store.  */
     405  #ifndef TARG_SCALAR_STMT_COST
     406  #define TARG_SCALAR_STMT_COST        1
     407  #endif
     408  
     409  /* Cost of scalar load. */
     410  #undef TARG_SCALAR_LOAD_COST
     411  #define TARG_SCALAR_LOAD_COST        2 /* load + rotate */
     412  
     413  /* Cost of scalar store.  */
     414  #undef TARG_SCALAR_STORE_COST
     415  #define TARG_SCALAR_STORE_COST       10
     416  
     417  /* Cost of any vector operation, excluding load, store,
     418     or vector to scalar operation.  */
     419  #undef TARG_VEC_STMT_COST
     420  #define TARG_VEC_STMT_COST           1
     421  
     422  /* Cost of vector to scalar operation.  */
     423  #undef TARG_VEC_TO_SCALAR_COST
     424  #define TARG_VEC_TO_SCALAR_COST      1
     425  
     426  /* Cost of scalar to vector operation.  */
     427  #undef TARG_SCALAR_TO_VEC_COST
     428  #define TARG_SCALAR_TO_VEC_COST      1
     429  
     430  /* Cost of aligned vector load.  */
     431  #undef TARG_VEC_LOAD_COST
     432  #define TARG_VEC_LOAD_COST           1
     433  
     434  /* Cost of misaligned vector load.  */
     435  #undef TARG_VEC_UNALIGNED_LOAD_COST
     436  #define TARG_VEC_UNALIGNED_LOAD_COST 2
     437  
     438  /* Cost of vector store.  */
     439  #undef TARG_VEC_STORE_COST
     440  #define TARG_VEC_STORE_COST          1
     441  
     442  /* Cost of vector permutation.  */
     443  #ifndef TARG_VEC_PERMUTE_COST
     444  #define TARG_VEC_PERMUTE_COST        1
     445  #endif
     446  
     447  /* ttype entries (the only interesting data references used) are
     448     sb-relative got-indirect (aka .ehtype).  */
     449  #define ASM_PREFERRED_EH_DATA_FORMAT(code, data) \
     450    (((code) == 0 && (data) == 1) ? (DW_EH_PE_datarel | DW_EH_PE_indirect) \
     451  				: DW_EH_PE_absptr)
     452  
     453  /* This should be the same as the definition in elfos.h, plus the call
     454     to output special unwinding directives.  */
     455  #undef ASM_DECLARE_FUNCTION_NAME
     456  #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)		\
     457    do								\
     458      {								\
     459        c6x_output_file_unwind (FILE);				\
     460        ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function");	\
     461        ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL));		\
     462        ASM_OUTPUT_LABEL (FILE, NAME);				\
     463      }								\
     464    while (0)
     465  
     466  /* This should be the same as the definition in elfos.h, plus the call
     467     to output special unwinding directives.  */
     468  #undef ASM_DECLARE_FUNCTION_SIZE
     469  #define ASM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL) \
     470    c6x_function_end (STREAM, NAME)
     471  
     472  /* Arbitrarily choose A4/A5.  */
     473  #define EH_RETURN_DATA_REGNO(N) (((N) < 2) ? (N) + 4 : INVALID_REGNUM)
     474  
     475  /* The register that holds the return address in exception handlers.  */
     476  #define C6X_EH_STACKADJ_REGNUM  3
     477  #define EH_RETURN_STACKADJ_RTX  gen_rtx_REG (SImode, C6X_EH_STACKADJ_REGNUM)
     478  
     479  
     480  /* Assembler Format.  */
     481  
     482  #define DWARF2_ASM_LINE_DEBUG_INFO 1
     483  
     484  #undef ASM_APP_ON
     485  #define ASM_APP_ON "\t; #APP \n"
     486  #undef ASM_APP_OFF
     487  #define ASM_APP_OFF "\t; #NO_APP \n"
     488  
     489  #define ASM_OUTPUT_COMMON(stream, name, size, rounded)
     490  #define ASM_OUTPUT_LOCAL(stream, name, size, rounded)
     491  
     492  #define GLOBAL_ASM_OP "\t.global\t"
     493  
     494  #define REGISTER_NAMES						\
     495    {								\
     496      "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",		\
     497      "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15",	\
     498      "A16", "A17", "A18", "A19", "A20", "A21", "A22", "A23",	\
     499      "A24", "A25", "A26", "A27", "A28", "A29", "A30", "A31",     \
     500      "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7",             \
     501      "B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15",       \
     502      "B16", "B17", "B18", "B19", "B20", "B21", "B22", "B23",     \
     503      "B24", "B25", "B26", "B27", "B28", "B29", "B30", "B31",	\
     504      "FP", "ARGP", "ILC" }
     505  
     506  #define DEBUGGER_REGNO(N) (debugger_register_map[(N)])
     507  
     508  extern unsigned const debugger_register_map[FIRST_PSEUDO_REGISTER];
     509  
     510  #define FINAL_PRESCAN_INSN c6x_final_prescan_insn
     511  
     512  #define TEXT_SECTION_ASM_OP ".text;"
     513  #define DATA_SECTION_ASM_OP ".data;"
     514  
     515  #define ASM_OUTPUT_ALIGN(stream, power)			    \
     516    do							    \
     517      {							    \
     518        if (power)					    \
     519          fprintf ((stream), "\t.align\t%d\n", power);	    \
     520      }                                                       \
     521    while (0)
     522  
     523  #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)    	\
     524  do { char __buf[256];					\
     525       fprintf (FILE, "\t.long\t");				\
     526       ASM_GENERATE_INTERNAL_LABEL (__buf, "L", VALUE);	\
     527       assemble_name (FILE, __buf);			\
     528       fputc ('\n', FILE);				\
     529     } while (0)
     530  
     531  /* Determine whether to place EXP (an expression or a decl) should be
     532     placed into one of the small data sections.  */
     533  #define PLACE_IN_SDATA_P(EXP) \
     534    (c6x_sdata_mode == C6X_SDATA_NONE ? false	\
     535     : c6x_sdata_mode == C6X_SDATA_ALL ? true	\
     536     : !AGGREGATE_TYPE_P (TREE_TYPE (EXP)))
     537  
     538  #define SCOMMON_ASM_OP "\t.scomm\t"
     539  
     540  #undef  ASM_OUTPUT_ALIGNED_DECL_COMMON
     541  #define ASM_OUTPUT_ALIGNED_DECL_COMMON(FILE, DECL, NAME, SIZE, ALIGN)	\
     542    do									\
     543      {									\
     544        if (DECL != NULL && PLACE_IN_SDATA_P (DECL))			\
     545  	fprintf ((FILE), "%s", SCOMMON_ASM_OP);				\
     546        else								\
     547  	fprintf ((FILE), "%s", COMMON_ASM_OP);				\
     548        assemble_name ((FILE), (NAME));					\
     549        fprintf ((FILE), ",%u,%u\n", (int)(SIZE), (ALIGN) / BITS_PER_UNIT);\
     550      }									\
     551    while (0)
     552  
     553  /* This says how to output assembler code to declare an
     554     uninitialized internal linkage data object.  */
     555  
     556  #undef  ASM_OUTPUT_ALIGNED_DECL_LOCAL
     557  #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN)	\
     558  do {									\
     559    if (PLACE_IN_SDATA_P (DECL))						\
     560      switch_to_section (sbss_section);					\
     561    else									\
     562      switch_to_section (bss_section);					\
     563    ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
     564    if (!flag_inhibit_size_directive)					\
     565      ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
     566    ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT));	\
     567    ASM_OUTPUT_LABEL(FILE, NAME);						\
     568    ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1);				\
     569  } while (0)
     570  
     571  #define CASE_VECTOR_PC_RELATIVE flag_pic
     572  #define JUMP_TABLES_IN_TEXT_SECTION flag_pic
     573  
     574  #define ADDR_VEC_ALIGN(VEC) (JUMP_TABLES_IN_TEXT_SECTION ? 5 : 2)
     575  
     576  /* This is how to output an element of a case-vector that is relative.  */
     577  #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
     578    do { char buf[100];					\
     579         fputs ("\t.long ", FILE);			\
     580         ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE);	\
     581         assemble_name (FILE, buf);			\
     582         putc ('-', FILE);				\
     583         ASM_GENERATE_INTERNAL_LABEL (buf, "L", REL);	\
     584         assemble_name (FILE, buf);			\
     585         putc ('\n', FILE);				\
     586       } while (0)
     587  
     588  /* Misc.  */
     589  
     590  #define CASE_VECTOR_MODE SImode
     591  #define MOVE_MAX 4
     592  #define MOVE_RATIO(SPEED) 4
     593  #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
     594  #define Pmode SImode
     595  #define FUNCTION_MODE QImode
     596  
     597  #define CPU_UNITS_QUERY 1
     598  
     599  extern int c6x_initial_flag_pic;
     600  
     601  #endif /* GCC_C6X_H */