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