(root)/
gcc-13.2.0/
gcc/
config/
lm32/
lm32.h
       1  /* Definitions of target machine for GNU compiler, Lattice Mico32 architecture.
       2     Contributed by Jon Beniston <jon@beniston.com>
       3  
       4     Copyright (C) 2009-2023 Free Software Foundation, Inc.
       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  /*-------------------------------*/
      23  /* Run-time Target Specification */
      24  /*-------------------------------*/
      25  
      26  /* Target CPU builtins.  */
      27  #define TARGET_CPU_CPP_BUILTINS()                       \
      28    do                                                    \
      29      {                                                   \
      30        builtin_define ("__lm32__");                      \
      31        builtin_assert ("cpu=lm32");                      \
      32        builtin_assert ("machine=lm32");                  \
      33        if (TARGET_MULTIPLY_ENABLED)                      \
      34          builtin_define ("__multiply_enabled__");        \
      35        if (TARGET_DIVIDE_ENABLED)                        \
      36          builtin_define ("__divide_enabled__");          \
      37        if (TARGET_BARREL_SHIFT_ENABLED)                  \
      38          builtin_define ("__barrel_shift_enabled__");    \
      39        if (TARGET_SIGN_EXTEND_ENABLED)                   \
      40          builtin_define ("__sign_extend_enabled__");     \
      41        if (TARGET_USER_ENABLED)                          \
      42          builtin_define ("__user_enabled__");            \
      43      }                                                   \
      44    while (0)
      45  
      46  #undef  ASM_SPEC
      47  #define ASM_SPEC "\
      48  %{mmultiply-enabled} \
      49  %{mdivide-enabled} \
      50  %{mbarrel-shift-enabled} \
      51  %{msign-extend-enabled} \
      52  %{muser-enabled} \
      53  "
      54  
      55  /* Let link script define all link options. 
      56     Default to using simulator link script.  */
      57  
      58  #undef  STARTFILE_SPEC
      59  #define STARTFILE_SPEC ""
      60  #undef  ENDFILE_SPEC
      61  #define ENDFILE_SPEC ""
      62  #undef  LIB_SPEC
      63  #define LIB_SPEC "%{!T*:-T sim.ld}"
      64  
      65  #undef  CC1_SPEC
      66  #define CC1_SPEC "%{G*}"
      67  
      68  /*---------------------------------*/
      69  /* Target machine storage layout.  */
      70  /*---------------------------------*/
      71  
      72  #define BITS_BIG_ENDIAN 0
      73  #define BYTES_BIG_ENDIAN 1
      74  #define WORDS_BIG_ENDIAN 1
      75  
      76  #define BITS_PER_WORD 32
      77  #define UNITS_PER_WORD 4
      78  
      79  #define POINTER_SIZE 32
      80  
      81  #define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE)               \
      82  do {                                                    \
      83    if (GET_MODE_CLASS (MODE) == MODE_INT                 \
      84        && GET_MODE_SIZE (MODE) < UNITS_PER_WORD)         \
      85      (MODE) = word_mode;                                 \
      86  } while (0)
      87  
      88  #define PARM_BOUNDARY 32
      89  
      90  #define STACK_BOUNDARY 32
      91  
      92  #define BIGGEST_ALIGNMENT 64
      93  
      94  #define FUNCTION_BOUNDARY  32
      95  
      96  #define EMPTY_FIELD_BOUNDARY 32
      97  
      98  #define STRICT_ALIGNMENT 1
      99  
     100  #define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
     101  
     102  /* Make arrays and structures word-aligned to allow faster copying etc.  */
     103  #define DATA_ALIGNMENT(TYPE, ALIGN)					\
     104    ((((ALIGN) < BITS_PER_WORD)						\
     105      && (TREE_CODE (TYPE) == ARRAY_TYPE					\
     106  	|| TREE_CODE (TYPE) == UNION_TYPE				\
     107  	|| TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
     108  
     109  /* We need this for the same reason as DATA_ALIGNMENT, namely to cause
     110     character arrays to be word-aligned so that `strcpy' calls that copy
     111     constants to character arrays can be done inline, and 'strcmp' can be
     112     optimised to use word loads.  */
     113  #define LOCAL_ALIGNMENT(TYPE, ALIGN) \
     114    DATA_ALIGNMENT (TYPE, ALIGN)
     115  
     116  /*----------------------------------------*/
     117  /* Layout of source language data types.  */
     118  /*----------------------------------------*/
     119  
     120  #define INT_TYPE_SIZE		    32
     121  #define SHORT_TYPE_SIZE		    16
     122  #define LONG_TYPE_SIZE		    32
     123  #define LONG_LONG_TYPE_SIZE	    64
     124  
     125  #define FLOAT_TYPE_SIZE		    32
     126  #define DOUBLE_TYPE_SIZE	    64
     127  #define LONG_DOUBLE_TYPE_SIZE       64
     128  
     129  #define DEFAULT_SIGNED_CHAR         0
     130  
     131  #define SIZE_TYPE "unsigned int"
     132  
     133  #define PTRDIFF_TYPE "int"
     134  
     135  /*---------------------------*/
     136  /* Standard register usage.  */
     137  /*---------------------------*/
     138  
     139  #define FIRST_PSEUDO_REGISTER  32
     140  
     141  #define RV_REGNUM   1
     142  #define GP_REGNUM   26
     143  #define FP_REGNUM   27
     144  #define SP_REGNUM   28
     145  #define RA_REGNUM   29
     146  
     147  #define G_REG_P(X)      ((X)<32)
     148  
     149  #define FIXED_REGISTERS   \
     150  { 1, 0, 0, 0, 0, 0, 0, 0, \
     151    0, 0, 0, 0, 0, 0, 0, 0, \
     152    0, 0, 0, 0, 0, 0, 0, 0, \
     153    0, 0, 1, 0, 1, 0, 1, 1}
     154  
     155  #define CALL_USED_REGISTERS \
     156  { 1, 1, 1, 1, 1, 1, 1, 1,   \
     157    1, 1, 1, 0, 0, 0, 0, 0,   \
     158    0, 0, 0, 0, 0, 0, 0, 0,   \
     159    0, 0, 1, 0, 1, 0, 1, 1}
     160  
     161  #define AVOID_CCMODE_COPIES
     162  
     163  /*----------------------------------*/
     164  /* Register classes and constants.  */
     165  /*----------------------------------*/
     166  
     167  enum reg_class
     168  {
     169    NO_REGS,                                      
     170    GENERAL_REGS,
     171    ALL_REGS,
     172    LIM_REG_CLASSES
     173  };
     174  
     175  #define N_REG_CLASSES (int) LIM_REG_CLASSES
     176  
     177  #define REG_CLASS_NAMES { "NO_REGS", "GENERAL_REGS", "ALL_REGS" }
     178  
     179  #define REG_CLASS_CONTENTS      \
     180  { {0x00000000},                 \
     181    {0xffffffff},                 \
     182    {0xffffffff}                  \
     183  }
     184  
     185  #define REGNO_REG_CLASS(REGNO) \
     186      (G_REG_P(REGNO) ? GENERAL_REGS : NO_REGS)
     187  
     188  #define INDEX_REG_CLASS NO_REGS
     189  
     190  #define BASE_REG_CLASS GENERAL_REGS
     191  
     192  #define REGNO_OK_FOR_BASE_P(REGNO) \
     193      (G_REG_P (REGNO) || G_REG_P ((unsigned) reg_renumber[REGNO]))
     194  
     195  #define REGNO_OK_FOR_INDEX_P(REGNO) 0
     196  
     197  /*----------------------------------------*/
     198  /* Stack Layout and Calling Conventions.  */
     199  /*----------------------------------------*/
     200  
     201  #define STACK_GROWS_DOWNWARD 1
     202  
     203  #define FRAME_GROWS_DOWNWARD 1
     204  
     205  #define STACK_POINTER_OFFSET (UNITS_PER_WORD)
     206  
     207  #define FIRST_PARM_OFFSET(FNDECL) (UNITS_PER_WORD)
     208  
     209  #define STACK_POINTER_REGNUM SP_REGNUM
     210  
     211  #define FRAME_POINTER_REGNUM FP_REGNUM
     212  
     213  #define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
     214  
     215  #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (SImode, RA_REGNUM)
     216  
     217  #define RETURN_ADDR_RTX(count, frame)                                   \
     218    lm32_return_addr_rtx (count, frame)
     219  
     220  /* FIXME - This is not yet supported.  */
     221  #define STATIC_CHAIN_REGNUM 9
     222  
     223  #define ELIMINABLE_REGS \
     224  {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM },                        \
     225   { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM },                          \
     226  }
     227  
     228  #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                    \
     229    (OFFSET) = lm32_compute_initial_elimination_offset (FROM, TO)
     230  
     231  /*-----------------------------*/
     232  /* Function argument passing.  */
     233  /*-----------------------------*/
     234  
     235  #define ACCUMULATE_OUTGOING_ARGS 1
     236  
     237  /*--------------------------------*/
     238  /* Passing Arguments in Registers */
     239  /*--------------------------------*/
     240  
     241  /* The first argument register.  */
     242  #define LM32_FIRST_ARG_REG 1
     243  
     244  /* The number of (integer) argument register available.  */
     245  #define LM32_NUM_ARG_REGS 8
     246  
     247  #define CUMULATIVE_ARGS int
     248  
     249  #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT,N_NAMED_ARGS)  \
     250    (CUM) = 0
     251  
     252  #define FUNCTION_ARG_REGNO_P(r)                                         \
     253    (((r) >= LM32_FIRST_ARG_REG) && ((r) <= LM32_NUM_ARG_REGS))
     254  
     255  /*--------------------*/
     256  /* Function results.  */
     257  /*--------------------*/
     258  
     259  #define FUNCTION_VALUE(VALTYPE, FUNC)                                   \
     260     gen_rtx_REG ((INTEGRAL_TYPE_P (VALTYPE)                              \
     261                   && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)           \
     262  	            ? word_mode                                         \
     263  	            : TYPE_MODE (VALTYPE),				\
     264  	            RV_REGNUM)
     265  
     266  #define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, RV_REGNUM)
     267  
     268  #define FUNCTION_VALUE_REGNO_P(N) ((N) == RV_REGNUM)
     269  
     270  #define RETURN_IN_MEMORY(TYPE) lm32_return_in_memory (TYPE)
     271  
     272  #define DEFAULT_PCC_STRUCT_RETURN 0
     273  
     274  /* Convert from bytes to ints.  */
     275  #define LM32_NUM_INTS(X) (((X) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
     276  
     277  /* The number of (integer) registers required to hold a quantity of
     278     type MODE.  */
     279  #define LM32_NUM_REGS(MODE) LM32_NUM_INTS (GET_MODE_SIZE (MODE))
     280  
     281  /* The number of (integer) registers required to hold a quantity of
     282     TYPE MODE.  */
     283  #define LM32_NUM_REGS2(MODE, TYPE)                       \
     284    LM32_NUM_INTS ((MODE) == BLKmode ?                     \
     285    int_size_in_bytes (TYPE) : GET_MODE_SIZE (MODE))
     286  
     287  /*---------------------------*/
     288  /* Function entry and exit.  */
     289  /*---------------------------*/
     290  
     291  /*-------------*/
     292  /* Profiling.  */
     293  /*-------------*/
     294  
     295  #define FUNCTION_PROFILER(FILE, LABELNO)
     296  
     297  /*---------------*/
     298  /* Trampolines.  */
     299  /*---------------*/
     300  
     301  #define TRAMPOLINE_SIZE		0
     302  
     303  /*---------------------*/
     304  /*  Addressing Modes.  */
     305  /*---------------------*/
     306  
     307  #define CONSTANT_ADDRESS_P(X)						\
     308    ((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF		\
     309      || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH		\
     310      || (GET_CODE (X) == CONST)))
     311  
     312  #define MAX_REGS_PER_ADDRESS 1
     313  
     314  #define STRICT_REG_OK_FOR_BASE_P(X)                                     \
     315    (REGNO_OK_FOR_BASE_P (REGNO (X)))
     316  #define NONSTRICT_REG_OK_FOR_BASE_P(X)                                  \
     317    (G_REG_P (REGNO (X)) || !HARD_REGISTER_NUM_P (REGNO (X)))
     318  
     319  #ifdef REG_OK_STRICT
     320  #define REG_OK_FOR_BASE_P(X) STRICT_REG_OK_FOR_BASE_P(X)
     321  #else
     322  #define REG_OK_FOR_BASE_P(X) NONSTRICT_REG_OK_FOR_BASE_P(X)
     323  #endif
     324  
     325  /*-------------------------*/
     326  /* Condition Code Status.  */
     327  /*-------------------------*/
     328  
     329  #define REVERSIBLE_CC_MODE(MODE) 1
     330  
     331  /*---------*/
     332  /* Costs.  */
     333  /*---------*/
     334  
     335  #define SLOW_BYTE_ACCESS 1
     336  
     337  #define NO_FUNCTION_CSE 1
     338  
     339  #define BRANCH_COST(speed_p, predictable_p) 4
     340  
     341  #define MOVE_RATIO(speed) (speed ? 24 : 3)
     342  
     343  /*------------*/
     344  /* Sections.  */
     345  /*------------*/
     346  
     347  #define TEXT_SECTION_ASM_OP             "\t.section\t.text"
     348  #define DATA_SECTION_ASM_OP             "\t.section\t.data"
     349  #define SDATA_SECTION_ASM_OP            "\t.section\t.sdata,\"aw\""
     350  #define BSS_SECTION_ASM_OP              "\t.section\t.bss"
     351  #define SBSS_SECTION_ASM_OP             "\t.section\t.sbss,\"aw\""
     352  
     353  /*-------*/
     354  /* PIC.  */
     355  /*-------*/
     356  
     357  #define PIC_OFFSET_TABLE_REGNUM (flag_pic ? GP_REGNUM : INVALID_REGNUM)
     358  
     359  #define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
     360  
     361  #define LEGITIMATE_PIC_OPERAND_P(X)                                    \
     362  	(!(nonpic_symbol_mentioned_p (X)))
     363  
     364  /*-------------*/
     365  /* Assembler.  */
     366  /*-------------*/
     367  
     368  #define ASM_COMMENT_START "#"
     369  
     370  #define ASM_APP_ON "#APP\n"
     371  
     372  #define ASM_APP_OFF "#NO_APP\n"
     373  
     374  #define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2)				\
     375   do {									\
     376  	fputc ( '\t', FILE);						\
     377  	assemble_name (FILE, LABEL1);					\
     378  	fputs ( " = ", FILE);						\
     379  	assemble_name (FILE, LABEL2);					\
     380  	fputc ( '\n', FILE);						\
     381   } while (0)
     382  
     383  /* Override default implementation in elfos.h to support -G.  */
     384  #undef  ASM_OUTPUT_ALIGNED_LOCAL
     385  #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
     386  do {									\
     387    if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
     388      switch_to_section (sbss_section);					\
     389    else									\
     390      switch_to_section (bss_section);					\
     391    ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
     392    if (!flag_inhibit_size_directive)					\
     393      ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
     394    ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT));	\
     395    ASM_OUTPUT_LABEL(FILE, NAME);						\
     396    ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1);				\
     397  } while (0)
     398  
     399  /* Override default implementation in elfos.h to support -G.  */
     400  #undef  ASM_OUTPUT_ALIGNED_COMMON
     401  #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)		\
     402  do 									\
     403  {									\
     404    if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
     405      {									\
     406        switch_to_section (sbss_section);					\
     407        (*targetm.asm_out.globalize_label) (FILE, NAME);			\
     408        ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
     409        if (!flag_inhibit_size_directive)					\
     410  	ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
     411        ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT));	\
     412        ASM_OUTPUT_LABEL(FILE, NAME);					\
     413        ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1);			\
     414      }									\
     415    else									\
     416      {									\
     417        switch_to_section (bss_section);					\
     418        fprintf ((FILE), "%s", COMMON_ASM_OP);				\
     419        assemble_name ((FILE), (NAME));					\
     420        fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",          \
     421                 (SIZE), (ALIGN) / BITS_PER_UNIT);	                \
     422      }									\
     423  }									\
     424  while (0)
     425  
     426  #define ASM_OUTPUT_LABEL(FILE, NAME) \
     427    do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
     428  
     429  #define ASM_OUTPUT_LABELREF(FILE,NAME)	\
     430    do {					\
     431      const char *xname = (NAME);		\
     432      if (xname[0] == '@')		\
     433        xname += 1;			\
     434      if (xname[0] == '*')		\
     435        xname += 1;			\
     436      fputs (xname, FILE);		\
     437    } while (0)
     438  
     439  #define ASM_OUTPUT_SYMBOL_REF(STREAM, SYMBOL)				\
     440    do {									\
     441      assemble_name (STREAM, XSTR (SYMBOL, 0));				\
     442    } while (0)
     443  
     444  #define GLOBAL_ASM_OP "\t.global\t"
     445  
     446  #define REGISTER_NAMES                                          \
     447  {                                                               \
     448   "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",	        \
     449   "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",        \
     450   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",        \
     451   "r24", "r25",  "gp",  "fp",  "sp",  "ra",  "ea",  "ba"}
     452  
     453  #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
     454    (((CHAR) == '&') || ((CHAR) == '@') || ((CHAR) == '*'))
     455  
     456  #define PRINT_OPERAND(FILE, X, CODE)                            \
     457    lm32_print_operand (FILE, X, CODE)
     458  
     459  #define PRINT_OPERAND_ADDRESS(FILE, ADDR)                       \
     460    lm32_print_operand_address (FILE, ADDR)
     461  
     462  #ifndef LOCAL_LABEL_PREFIX
     463  #define LOCAL_LABEL_PREFIX	"."
     464  #endif
     465  
     466  #define ASM_OUTPUT_ALIGN(FILE,LOG)                              \
     467    do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", (1 << (LOG))); } while (0)
     468  
     469  #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)                    \
     470  do {                                                            \
     471    char label[64];                                               \
     472    ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE);              \
     473    fprintf (FILE, "\n\t.word\t");                                \
     474    assemble_name (FILE, label);                                  \
     475    fprintf (FILE, "\n");                                         \
     476  } while (0)
     477  
     478  #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)        \
     479  do {                                                            \
     480    char label[64];                                               \
     481    fprintf (FILE, "\t.word\t(");                                 \
     482    ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE);		\
     483    assemble_name (FILE, label);                                  \
     484    fprintf (FILE, "-");                                          \
     485    ASM_GENERATE_INTERNAL_LABEL (label, "L", REL);                \
     486    assemble_name (FILE, label);                                  \
     487    fprintf (FILE, ")\n");                                        \
     488  } while (0)
     489  
     490  /*-------------*/
     491  /* Debugging.  */
     492  /*-------------*/
     493  
     494  #define DEBUGGER_REGNO(REGNO) (REGNO)
     495  
     496  #define DEFAULT_GDB_EXTENSIONS 1
     497  
     498  /*--------*/
     499  /* Misc.  */
     500  /*--------*/
     501  
     502  #define CASE_VECTOR_MODE Pmode
     503  
     504  #define WORD_REGISTER_OPERATIONS 1
     505  
     506  #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
     507  
     508  #define SHORT_IMMEDIATES_SIGN_EXTEND 1
     509  
     510  #define MOVE_MAX        UNITS_PER_WORD
     511  #define MAX_MOVE_MAX    4
     512  
     513  #define SHIFT_COUNT_TRUNCATED 1
     514  
     515  #define Pmode SImode
     516  
     517  #define FUNCTION_MODE SImode
     518  
     519  #define STORE_FLAG_VALUE 1