blob: eb7ef09297e9dd0fc3ee9c15b0aa5c6cadadad00 [file] [log] [blame]
/* RISC-V-specific code for C family languages.
Copyright (C) 2011-2022 Free Software Foundation, Inc.
Contributed by Andrew Waterman (andrew@sifive.com).
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#define IN_TARGET_CODE 1
#define INCLUDE_STRING
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "c-family/c-common.h"
#include "cpplib.h"
#include "riscv-subset.h"
#define builtin_define(TXT) cpp_define (pfile, TXT)
/* Implement TARGET_CPU_CPP_BUILTINS. */
void
riscv_cpu_cpp_builtins (cpp_reader *pfile)
{
builtin_define ("__riscv");
if (TARGET_RVC)
builtin_define ("__riscv_compressed");
if (TARGET_RVE)
builtin_define ("__riscv_32e");
if (TARGET_ATOMIC)
builtin_define ("__riscv_atomic");
if (TARGET_MUL)
builtin_define ("__riscv_mul");
if (TARGET_DIV)
builtin_define ("__riscv_div");
if (TARGET_DIV && TARGET_MUL)
builtin_define ("__riscv_muldiv");
builtin_define_with_int_value ("__riscv_xlen", UNITS_PER_WORD * 8);
if (TARGET_HARD_FLOAT)
builtin_define_with_int_value ("__riscv_flen", UNITS_PER_FP_REG * 8);
if (TARGET_HARD_FLOAT && TARGET_FDIV)
{
builtin_define ("__riscv_fdiv");
builtin_define ("__riscv_fsqrt");
}
switch (riscv_abi)
{
case ABI_ILP32E:
builtin_define ("__riscv_abi_rve");
gcc_fallthrough ();
case ABI_ILP32:
case ABI_LP64:
builtin_define ("__riscv_float_abi_soft");
break;
case ABI_ILP32F:
case ABI_LP64F:
builtin_define ("__riscv_float_abi_single");
break;
case ABI_ILP32D:
case ABI_LP64D:
builtin_define ("__riscv_float_abi_double");
break;
}
switch (riscv_cmodel)
{
case CM_MEDLOW:
builtin_define ("__riscv_cmodel_medlow");
break;
case CM_PIC:
/* __riscv_cmodel_pic is deprecated, and will removed in next GCC release.
see https://github.com/riscv/riscv-c-api-doc/pull/11 */
builtin_define ("__riscv_cmodel_pic");
/* FALLTHROUGH. */
case CM_MEDANY:
builtin_define ("__riscv_cmodel_medany");
break;
}
if (TARGET_MIN_VLEN != 0)
builtin_define_with_int_value ("__riscv_v_min_vlen", TARGET_MIN_VLEN);
if (TARGET_VECTOR_ELEN_64)
builtin_define_with_int_value ("__riscv_v_elen", 64);
else if (TARGET_VECTOR_ELEN_32)
builtin_define_with_int_value ("__riscv_v_elen", 32);
if (TARGET_VECTOR_ELEN_FP_64)
builtin_define_with_int_value ("__riscv_v_elen_fp", 64);
else if (TARGET_VECTOR_ELEN_FP_32)
builtin_define_with_int_value ("__riscv_v_elen_fp", 32);
else if (TARGET_MIN_VLEN != 0)
builtin_define_with_int_value ("__riscv_v_elen_fp", 0);
if (TARGET_MIN_VLEN)
builtin_define ("__riscv_vector");
/* Define architecture extension test macros. */
builtin_define_with_int_value ("__riscv_arch_test", 1);
const riscv_subset_list *subset_list = riscv_current_subset_list ();
if (!subset_list)
return;
size_t max_ext_len = 0;
/* Figure out the max length of extension name for reserving buffer. */
for (const riscv_subset_t *subset = subset_list->begin ();
subset != subset_list->end ();
subset = subset->next)
max_ext_len = MAX (max_ext_len, subset->name.length ());
char *buf = (char *)alloca (max_ext_len + 10 /* For __riscv_ and '\0'. */);
for (const riscv_subset_t *subset = subset_list->begin ();
subset != subset_list->end ();
subset = subset->next)
{
int version_value = (subset->major_version * 1000000)
+ (subset->minor_version * 1000);
/* Special rule for zicsr and zifencei, it's used for ISA spec 2.2 or
earlier. */
if ((subset->name == "zicsr" || subset->name == "zifencei")
&& version_value == 0)
version_value = 2000000;
sprintf (buf, "__riscv_%s", subset->name.c_str ());
builtin_define_with_int_value (buf, version_value);
}
}