Skip to content

Commit

Permalink
RISC-V: Introduce RVV header to enable builtin types
Browse files Browse the repository at this point in the history
gcc/ChangeLog:

	* config.gcc: Add riscv_vector.h.
	* config/riscv/riscv-builtins.cc: Add RVV builtin types support.
	* config/riscv/riscv-c.cc (riscv_pragma_intrinsic): New function.
	(riscv_register_pragmas): Ditto.
	* config/riscv/riscv-protos.h (riscv_register_pragmas): Ditto.
	(init_builtins): Move declaration from riscv-vector-builtins.h to riscv-protos.h.
	(mangle_builtin_type): Ditto.
	(verify_type_context): Ditto.
	(handle_pragma_vector): New function.
	* config/riscv/riscv-vector-builtins.cc (GTY): New variable.
	(register_vector_type): New function.
	(init_builtins): Add RVV builtin types support.
	(handle_pragma_vector): New function.
	* config/riscv/riscv-vector-builtins.h (GCC_RISCV_V_BUILTINS_H): Change
	name according to file name.
	(GCC_RISCV_VECTOR_BUILTINS_H): Ditto.
	(init_builtins): Remove declaration in riscv-vector-builtins.h.
	(mangle_builtin_type): Ditto.
	(verify_type_context): Ditto.
	* config/riscv/riscv.cc: Adjust for RVV builtin types support.
	* config/riscv/riscv.h (REGISTER_TARGET_PRAGMAS): New macro.
	* config/riscv/t-riscv: Remove redundant file including.
	* config/riscv/riscv_vector.h: New file.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/base/pragma-1.c: New test.
	* gcc.target/riscv/rvv/base/pragma-2.c: New test.
	* gcc.target/riscv/rvv/base/pragma-3.c: New test.
	* gcc.target/riscv/rvv/base/user-1.c: New test.
	* gcc.target/riscv/rvv/base/user-2.c: New test.
	* gcc.target/riscv/rvv/base/user-3.c: New test.
	* gcc.target/riscv/rvv/base/user-4.c: New test.
	* gcc.target/riscv/rvv/base/user-5.c: New test.
	* gcc.target/riscv/rvv/base/user-6.c: New test.
	* gcc.target/riscv/rvv/base/vread_csr.c: New test.
	* gcc.target/riscv/rvv/base/vwrite_csr.c: New test.
  • Loading branch information
zhongjuzhe authored and kito-cheng committed Oct 5, 2022
1 parent df4c584 commit 7d935cd
Show file tree
Hide file tree
Showing 21 changed files with 665 additions and 13 deletions.
1 change: 1 addition & 0 deletions gcc/config.gcc
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ riscv*)
extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o riscv-shorten-memrefs.o riscv-selftests.o"
extra_objs="${extra_objs} riscv-vector-builtins.o"
d_target_objs="riscv-d.o"
extra_headers="riscv_vector.h"
;;
rs6000*-*-*)
extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt"
Expand Down
2 changes: 1 addition & 1 deletion gcc/config/riscv/riscv-builtins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "expr.h"
#include "langhooks.h"
#include "riscv-vector-builtins.h"
#include "tm_p.h"

/* Macros to create an enumeration identifier for a function prototype. */
#define RISCV_FTYPE_NAME0(A) RISCV_##A##_FTYPE
Expand Down
41 changes: 41 additions & 0 deletions gcc/config/riscv/riscv-c.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "c-family/c-common.h"
#include "cpplib.h"
#include "c-family/c-pragma.h"
#include "target.h"
#include "tm_p.h"
#include "riscv-subset.h"

#define builtin_define(TXT) cpp_define (pfile, TXT)
Expand Down Expand Up @@ -150,3 +153,41 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
builtin_define_with_int_value (buf, version_value);
}
}

/* Implement "#pragma riscv intrinsic". */

static void
riscv_pragma_intrinsic (cpp_reader *)
{
tree x;

if (pragma_lex (&x) != CPP_STRING)
{
error ("%<#pragma riscv intrinsic%> requires a string parameter");
return;
}

const char *name = TREE_STRING_POINTER (x);

if (strcmp (name, "vector") == 0)
{
if (!TARGET_VECTOR)
{
error ("%<#pragma riscv intrinsic%> option %qs needs 'V' extension "
"enabled",
name);
return;
}
riscv_vector::handle_pragma_vector ();
}
else
error ("unknown %<#pragma riscv intrinsic%> option %qs", name);
}

/* Implement REGISTER_TARGET_PRAGMAS. */

void
riscv_register_pragmas (void)
{
c_register_pragma ("riscv", "intrinsic", riscv_pragma_intrinsic);
}
11 changes: 11 additions & 0 deletions gcc/config/riscv/riscv-protos.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ extern bool riscv_v_ext_enabled_vector_mode_p (machine_mode);

/* Routines implemented in riscv-c.cc. */
void riscv_cpu_cpp_builtins (cpp_reader *);
void riscv_register_pragmas (void);

/* Routines implemented in riscv-builtins.cc. */
extern void riscv_atomic_assign_expand_fenv (tree *, tree *, tree *);
Expand Down Expand Up @@ -115,4 +116,14 @@ extern void riscv_run_selftests (void);
} // namespace selftest
#endif

namespace riscv_vector {
/* Routines implemented in riscv-vector-builtins.cc. */
extern void init_builtins (void);
extern const char *mangle_builtin_type (const_tree);
#ifdef GCC_TARGET_H
extern bool verify_type_context (location_t, type_context_kind, const_tree, bool);
#endif
extern void handle_pragma_vector (void);
}

#endif /* ! GCC_RISCV_PROTOS_H */
45 changes: 45 additions & 0 deletions gcc/config/riscv/riscv-vector-builtins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
#include "regs.h"
#include "riscv-vector-builtins.h"

using namespace riscv_vector;

namespace riscv_vector {

/* Information about each RVV type. */
Expand All @@ -64,6 +66,10 @@ static GTY (()) machine_mode vector_modes[NUM_VECTOR_TYPES];
yields a null tree. */
static GTY(()) tree abi_vector_types[NUM_VECTOR_TYPES + 1];

/* Same, but with the riscv_vector.h "v..._t" name. */
extern GTY(()) tree builtin_vector_types[MAX_TUPLE_SIZE][NUM_VECTOR_TYPES + 1];
tree builtin_vector_types[MAX_TUPLE_SIZE][NUM_VECTOR_TYPES + 1];

rvv_switcher::rvv_switcher ()
{
/* Set have_regs_of_mode before targetm.init_builtins (). */
Expand Down Expand Up @@ -183,6 +189,32 @@ register_builtin_types ()
}
}

/* Register vector type TYPE under its risv_vector.h name. */
static void
register_vector_type (vector_type_index type)
{
tree vectype = abi_vector_types[type];
/* When vectype is NULL, the corresponding builtin type
is disabled according to '-march'. */
if (!vectype)
return;
tree id = get_identifier (vector_types[type].user_name);
tree decl = build_decl (input_location, TYPE_DECL, id, vectype);
decl = lang_hooks.decls.pushdecl (decl);

/* Record the new RVV type if pushdecl succeeded without error. Use
the ABI type otherwise, so that the type we record at least has the
right form, even if it doesn't have the right name. This should give
better error recovery behavior than installing error_mark_node or
installing an incorrect type. */
if (decl && TREE_CODE (decl) == TYPE_DECL
&& TREE_TYPE (decl) != error_mark_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == vectype)
vectype = TREE_TYPE (decl);

builtin_vector_types[0][type] = vectype;
}

/* Initialize all compiler built-ins related to RVV that should be
defined at start-up. */
void
Expand All @@ -192,6 +224,8 @@ init_builtins ()
if (!TARGET_VECTOR)
return;
register_builtin_types ();
if (in_lto_p)
handle_pragma_vector ();
}

/* Implement TARGET_VERIFY_TYPE_CONTEXT for RVV types. */
Expand Down Expand Up @@ -276,4 +310,15 @@ verify_type_context (location_t loc, type_context_kind context, const_tree type,
gcc_unreachable ();
}

/* Implement #pragma riscv intrinsic vector. */
void
handle_pragma_vector ()
{
rvv_switcher rvv;

/* Define the vector and tuple types. */
for (unsigned int type_i = 0; type_i < NUM_VECTOR_TYPES; ++type_i)
register_vector_type ((enum vector_type_index) type_i);
}

} // end namespace riscv_vector
13 changes: 5 additions & 8 deletions gcc/config/riscv/riscv-vector-builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */

#ifndef GCC_RISCV_V_BUILTINS_H
#define GCC_RISCV_V_BUILTINS_H
#ifndef GCC_RISCV_VECTOR_BUILTINS_H
#define GCC_RISCV_VECTOR_BUILTINS_H

namespace riscv_vector {

/* This is for segment instructions. */
const unsigned int MAX_TUPLE_SIZE = 8;

/* Static information about each vector type. */
struct vector_type_info
{
Expand Down Expand Up @@ -68,12 +71,6 @@ class rvv_switcher
bool m_old_have_regs_of_mode[MAX_MACHINE_MODE];
};

void init_builtins ();
const char *mangle_builtin_type (const_tree);
#ifdef GCC_TARGET_H
bool verify_type_context (location_t, type_context_kind, const_tree, bool);
#endif

} // end namespace riscv_vector

#endif
7 changes: 4 additions & 3 deletions gcc/config/riscv/riscv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "tm.h"
#include "rtl.h"
#include "regs.h"
Expand All @@ -45,8 +46,6 @@ along with GCC; see the file COPYING3. If not see
#include "emit-rtl.h"
#include "reload.h"
#include "tm_p.h"
#include "target.h"
#include "target-def.h"
#include "basic-block.h"
#include "expr.h"
#include "optabs.h"
Expand All @@ -59,7 +58,9 @@ along with GCC; see the file COPYING3. If not see
#include "opts.h"
#include "tm-constrs.h"
#include "rtl-iter.h"
#include "riscv-vector-builtins.h"

/* This file should be included last. */
#include "target-def.h"

/* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
#define UNSPEC_ADDRESS_P(X) \
Expand Down
2 changes: 2 additions & 0 deletions gcc/config/riscv/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1078,4 +1078,6 @@ extern void riscv_remove_unneeded_save_restore_calls (void);

#define TARGET_SUPPORTS_WIDE_INT 1

#define REGISTER_TARGET_PRAGMAS() riscv_register_pragmas ()

#endif /* ! GCC_RISCV_H */
100 changes: 100 additions & 0 deletions gcc/config/riscv/riscv_vector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* RISC-V 'V' Extension intrinsics include file.
Copyright (C) 2022-2022 Free Software Foundation, Inc.
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.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */

#ifndef __RISCV_VECTOR_H
#define __RISCV_VECTOR_H

#include <stdint.h>
#include <stddef.h>

#ifndef __riscv_vector
#error "Vector intrinsics require the vector extension."
#else
#ifdef __cplusplus
extern "C" {
#endif

enum RVV_CSR {
RVV_VSTART = 0,
RVV_VXSAT,
RVV_VXRM,
RVV_VCSR,
};

__extension__ extern __inline unsigned long
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vread_csr(enum RVV_CSR csr)
{
unsigned long rv = 0;
switch (csr)
{
case RVV_VSTART:
__asm__ __volatile__ ("csrr\t%0,vstart" : "=r"(rv) : : "memory");
break;
case RVV_VXSAT:
__asm__ __volatile__ ("csrr\t%0,vxsat" : "=r"(rv) : : "memory");
break;
case RVV_VXRM:
__asm__ __volatile__ ("csrr\t%0,vxrm" : "=r"(rv) : : "memory");
break;
case RVV_VCSR:
__asm__ __volatile__ ("csrr\t%0,vcsr" : "=r"(rv) : : "memory");
break;
}
return rv;
}

__extension__ extern __inline void
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vwrite_csr(enum RVV_CSR csr, unsigned long value)
{
switch (csr)
{
case RVV_VSTART:
__asm__ __volatile__ ("csrw\tvstart,%z0" : : "rJ"(value) : "memory");
break;
case RVV_VXSAT:
__asm__ __volatile__ ("csrw\tvxsat,%z0" : : "rJ"(value) : "memory");
break;
case RVV_VXRM:
__asm__ __volatile__ ("csrw\tvxrm,%z0" : : "rJ"(value) : "memory");
break;
case RVV_VCSR:
__asm__ __volatile__ ("csrw\tvcsr,%z0" : : "rJ"(value) : "memory");
break;
}
}

/* NOTE: This implementation of riscv_vector.h is intentionally short. It does
not define the RVV types and intrinsic functions directly in C and C++
code, but instead uses the following pragma to tell GCC to insert the
necessary type and function definitions itself. The net effect is the
same, and the file is a complete implementation of riscv_vector.h. */
#pragma riscv intrinsic "vector"

#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __riscv_vector
#endif // __RISCV_VECTOR_H
2 changes: 1 addition & 1 deletion gcc/config/riscv/t-riscv
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ riscv-vector-builtins.o: $(srcdir)/config/riscv/riscv-vector-builtins.cc \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) $(TM_P_H) \
memmodel.h insn-codes.h $(OPTABS_H) $(RECOG_H) $(DIAGNOSTIC_H) $(EXPR_H) \
$(FUNCTION_H) fold-const.h gimplify.h explow.h stor-layout.h $(REGS_H) \
alias.h langhooks.h attribs.h stringpool.h $(REGS_H) \
alias.h langhooks.h attribs.h stringpool.h \
$(srcdir)/config/riscv/riscv-vector-builtins.h \
$(srcdir)/config/riscv/riscv-vector-builtins.def
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
Expand Down
4 changes: 4 additions & 0 deletions gcc/testsuite/gcc.target/riscv/rvv/base/pragma-1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* { dg-do compile } */
/* { dg-options "-O3 -march=rv32gc -mabi=ilp32d" } */

#pragma riscv intrinsic "vector" /* { dg-error {#pragma riscv intrinsic' option 'vector' needs 'V' extension enabled} } */
4 changes: 4 additions & 0 deletions gcc/testsuite/gcc.target/riscv/rvv/base/pragma-2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* { dg-do compile } */
/* { dg-skip-if "test rvv intrinsic" { *-*-* } { "*" } { "-march=rv*v*" } } */

#pragma riscv intrinsic "vector"
4 changes: 4 additions & 0 deletions gcc/testsuite/gcc.target/riscv/rvv/base/pragma-3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* { dg-do compile } */
/* { dg-skip-if "test rvv intrinsic" { *-*-* } { "*" } { "-march=rv*v*" } } */

#pragma riscv intrinsic "report-error" /* { dg-error {unknown '#pragma riscv intrinsic' option 'report-error'} } */
Loading

0 comments on commit 7d935cd

Please sign in to comment.