Home | History | Annotate | Line # | Download | only in riscv
riscv-c.cc revision 1.1.1.1
      1 /* RISC-V-specific code for C family languages.
      2    Copyright (C) 2011-2022 Free Software Foundation, Inc.
      3    Contributed by Andrew Waterman (andrew (at) sifive.com).
      4 
      5 This file is part of GCC.
      6 
      7 GCC is free software; you can redistribute it and/or modify
      8 it under the terms of the GNU General Public License as published by
      9 the Free Software Foundation; either version 3, or (at your option)
     10 any later version.
     11 
     12 GCC is distributed in the hope that it will be useful,
     13 but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with GCC; see the file COPYING3.  If not see
     19 <http://www.gnu.org/licenses/>.  */
     20 
     21 #define IN_TARGET_CODE 1
     22 
     23 #define INCLUDE_STRING
     24 #include "config.h"
     25 #include "system.h"
     26 #include "coretypes.h"
     27 #include "tm.h"
     28 #include "c-family/c-common.h"
     29 #include "cpplib.h"
     30 #include "riscv-subset.h"
     31 
     32 #define builtin_define(TXT) cpp_define (pfile, TXT)
     33 
     34 /* Implement TARGET_CPU_CPP_BUILTINS.  */
     35 
     36 void
     37 riscv_cpu_cpp_builtins (cpp_reader *pfile)
     38 {
     39   builtin_define ("__riscv");
     40 
     41   if (TARGET_RVC)
     42     builtin_define ("__riscv_compressed");
     43 
     44   if (TARGET_RVE)
     45     builtin_define ("__riscv_32e");
     46 
     47   if (TARGET_ATOMIC)
     48     builtin_define ("__riscv_atomic");
     49 
     50   if (TARGET_MUL)
     51     builtin_define ("__riscv_mul");
     52   if (TARGET_DIV)
     53     builtin_define ("__riscv_div");
     54   if (TARGET_DIV && TARGET_MUL)
     55     builtin_define ("__riscv_muldiv");
     56 
     57   builtin_define_with_int_value ("__riscv_xlen", UNITS_PER_WORD * 8);
     58   if (TARGET_HARD_FLOAT)
     59     builtin_define_with_int_value ("__riscv_flen", UNITS_PER_FP_REG * 8);
     60 
     61   if (TARGET_HARD_FLOAT && TARGET_FDIV)
     62     {
     63       builtin_define ("__riscv_fdiv");
     64       builtin_define ("__riscv_fsqrt");
     65     }
     66 
     67   switch (riscv_abi)
     68     {
     69     case ABI_ILP32E:
     70       builtin_define ("__riscv_abi_rve");
     71       gcc_fallthrough ();
     72 
     73     case ABI_ILP32:
     74     case ABI_LP64:
     75       builtin_define ("__riscv_float_abi_soft");
     76       break;
     77 
     78     case ABI_ILP32F:
     79     case ABI_LP64F:
     80       builtin_define ("__riscv_float_abi_single");
     81       break;
     82 
     83     case ABI_ILP32D:
     84     case ABI_LP64D:
     85       builtin_define ("__riscv_float_abi_double");
     86       break;
     87     }
     88 
     89   switch (riscv_cmodel)
     90     {
     91     case CM_MEDLOW:
     92       builtin_define ("__riscv_cmodel_medlow");
     93       break;
     94 
     95     case CM_PIC:
     96       /* __riscv_cmodel_pic is deprecated, and will removed in next GCC release.
     97 	 see https://github.com/riscv/riscv-c-api-doc/pull/11  */
     98       builtin_define ("__riscv_cmodel_pic");
     99       /* FALLTHROUGH. */
    100 
    101     case CM_MEDANY:
    102       builtin_define ("__riscv_cmodel_medany");
    103       break;
    104 
    105     }
    106 
    107   if (TARGET_MIN_VLEN != 0)
    108     builtin_define_with_int_value ("__riscv_v_min_vlen", TARGET_MIN_VLEN);
    109 
    110   if (TARGET_VECTOR_ELEN_64)
    111     builtin_define_with_int_value ("__riscv_v_elen", 64);
    112   else if (TARGET_VECTOR_ELEN_32)
    113     builtin_define_with_int_value ("__riscv_v_elen", 32);
    114 
    115   if (TARGET_VECTOR_ELEN_FP_64)
    116     builtin_define_with_int_value ("__riscv_v_elen_fp", 64);
    117   else if (TARGET_VECTOR_ELEN_FP_32)
    118     builtin_define_with_int_value ("__riscv_v_elen_fp", 32);
    119   else if (TARGET_MIN_VLEN != 0)
    120     builtin_define_with_int_value ("__riscv_v_elen_fp", 0);
    121 
    122   if (TARGET_MIN_VLEN)
    123     builtin_define ("__riscv_vector");
    124 
    125   /* Define architecture extension test macros.  */
    126   builtin_define_with_int_value ("__riscv_arch_test", 1);
    127 
    128   const riscv_subset_list *subset_list = riscv_current_subset_list ();
    129   if (!subset_list)
    130     return;
    131 
    132   size_t max_ext_len = 0;
    133 
    134   /* Figure out the max length of extension name for reserving buffer.   */
    135   for (const riscv_subset_t *subset = subset_list->begin ();
    136        subset != subset_list->end ();
    137        subset = subset->next)
    138     max_ext_len = MAX (max_ext_len, subset->name.length ());
    139 
    140   char *buf = (char *)alloca (max_ext_len + 10 /* For __riscv_ and '\0'.  */);
    141 
    142   for (const riscv_subset_t *subset = subset_list->begin ();
    143        subset != subset_list->end ();
    144        subset = subset->next)
    145     {
    146       int version_value = (subset->major_version * 1000000)
    147 			   + (subset->minor_version * 1000);
    148       /* Special rule for zicsr and zifencei, it's used for ISA spec 2.2 or
    149 	 earlier.  */
    150       if ((subset->name == "zicsr" || subset->name == "zifencei")
    151 	  && version_value == 0)
    152 	version_value = 2000000;
    153 
    154       sprintf (buf, "__riscv_%s", subset->name.c_str ());
    155       builtin_define_with_int_value (buf, version_value);
    156     }
    157 }
    158