xref: /netbsd-src/external/gpl3/gcc/dist/gcc/config/riscv/riscv-c.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 /* RISC-V-specific code for C family languages.
2    Copyright (C) 2011-2022 Free Software Foundation, Inc.
3    Contributed by Andrew Waterman (andrew@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
riscv_cpu_cpp_builtins(cpp_reader * pfile)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