Skip to content

Commit

Permalink
i#3544 RV64 vector part2: Add basic vector support to the core (Dynam…
Browse files Browse the repository at this point in the history
…oRIO#6848)

This is a follow-up patch of adding RISC-V vector (RVV) extension
support to the core, part1 in PR DynamoRIO#6810 (f1ce1bc).

This patch:
1. fixes several issues in the codec introduced in part1, codec unit
tests will be submitted separately in follow-up PRs;
2. rename and reuse SVE vector length getter/setter functions to be more
concise on APIs for vector extensions;
3. adds RISC-V vector support to drdisas;
4. support code cache and clean call context switch;

For now, we support RISC-V vector lengths up to 256 bits, longer vector
lengths will exceed the limit of DynamoRIO stack size and 12-bit signed
immediate range.

Issue: DynamoRIO#3544
  • Loading branch information
ksco authored Jun 27, 2024
1 parent 3d62fb6 commit 59d0360
Show file tree
Hide file tree
Showing 35 changed files with 782 additions and 129 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ jobs:
# We only use a non-zero build # when making multiple manual builds in one day.
run: |
if test -z "${{ github.event.inputs.version }}"; then
export VERSION_NUMBER=10.92.$((`git log -n 1 --format=%ct` / (60*60*24)))
export VERSION_NUMBER=10.93.$((`git log -n 1 --format=%ct` / (60*60*24)))
else
export VERSION_NUMBER=${{ github.event.inputs.version }}
fi
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/ci-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ jobs:
# We only use a non-zero build # when making multiple manual builds in one day.
run: |
if test -z "${{ github.event.inputs.version }}"; then
export VERSION_NUMBER=10.92.$((`git log -n 1 --format=%ct` / (60*60*24)))
export VERSION_NUMBER=10.93.$((`git log -n 1 --format=%ct` / (60*60*24)))
else
export VERSION_NUMBER=${{ github.event.inputs.version }}
fi
Expand Down Expand Up @@ -195,7 +195,7 @@ jobs:
# XXX: See x86 job comments on sharing the default ver# with CMakeLists.txt.
run: |
if test -z "${{ github.event.inputs.version }}"; then
export VERSION_NUMBER=10.92.$((`git log -n 1 --format=%ct` / (60*60*24)))
export VERSION_NUMBER=10.93.$((`git log -n 1 --format=%ct` / (60*60*24)))
else
export VERSION_NUMBER=${{ github.event.inputs.version }}
fi
Expand Down Expand Up @@ -283,7 +283,7 @@ jobs:
# XXX: See x86 job comments on sharing the default ver# with CMakeLists.txt.
run: |
if test -z "${{ github.event.inputs.version }}"; then
export VERSION_NUMBER=10.92.$((`git log -n 1 --format=%ct` / (60*60*24)))
export VERSION_NUMBER=10.93.$((`git log -n 1 --format=%ct` / (60*60*24)))
else
export VERSION_NUMBER=${{ github.event.inputs.version }}
fi
Expand Down Expand Up @@ -371,7 +371,7 @@ jobs:
# XXX: See x86 job comments on sharing the default ver# with CMakeLists.txt.
run: |
if test -z "${{ github.event.inputs.version }}"; then
export VERSION_NUMBER=10.92.$((`git log -n 1 --format=%ct` / (60*60*24)))
export VERSION_NUMBER=10.93.$((`git log -n 1 --format=%ct` / (60*60*24)))
else
export VERSION_NUMBER=${{ github.event.inputs.version }}
fi
Expand Down Expand Up @@ -451,7 +451,7 @@ jobs:
# XXX: See x86 job comments on sharing the default ver# with CMakeLists.txt.
run: |
if test -z "${{ github.event.inputs.version }}"; then
export VERSION_NUMBER=10.92.$((`git log -n 1 --format=%ct` / (60*60*24)))
export VERSION_NUMBER=10.93.$((`git log -n 1 --format=%ct` / (60*60*24)))
else
export VERSION_NUMBER=${{ github.event.inputs.version }}
fi
Expand Down Expand Up @@ -536,7 +536,7 @@ jobs:
# XXX: See x86 job comments on sharing the default ver# with CMakeLists.txt.
run: |
if test -z "${{ github.event.inputs.version }}"; then
export VERSION_NUMBER="10.92.$((`git log -n 1 --format=%ct` / (60*60*24)))"
export VERSION_NUMBER="10.93.$((`git log -n 1 --format=%ct` / (60*60*24)))"
export PREFIX="cronbuild-"
else
export VERSION_NUMBER=${{ github.event.inputs.version }}
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ endif (EXISTS "${PROJECT_SOURCE_DIR}/.svn")

# N.B.: When updating this, update all the default versions in ci-package.yml
# and ci-docs.yml. We should find a way to share (xref i#1565).
set(VERSION_NUMBER_DEFAULT "10.92.${VERSION_NUMBER_PATCHLEVEL}")
set(VERSION_NUMBER_DEFAULT "10.93.${VERSION_NUMBER_PATCHLEVEL}")
# do not store the default VERSION_NUMBER in the cache to prevent a stale one
# from preventing future version updates in a pre-existing build dir
set(VERSION_NUMBER "" CACHE STRING "Version number: leave empty for default")
Expand Down
4 changes: 4 additions & 0 deletions api/docs/release.dox
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ changes:
- Changed the way we cache the feature register values on AArch64. We now use an array of
uint64 values rather than individual variables for each feature register. This
allows the code to be more readable and easier to maintain.
- Renamed dr_set_sve_vector_length() to dr_set_vector_length() to share function
signature between AArch64 and RISC-V.
- Renamed dr_get_sve_vector_length() to dr_get_vector_length() to share function
signature between AArch64 and RISC-V.

Further non-compatibility-affecting changes include:
- Added DWARF-5 support to the drsyms library by linking in 4 static libraries
Expand Down
2 changes: 1 addition & 1 deletion clients/drcachesim/common/trace_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ typedef enum {
* length value is specific to the current thread.
* The vector length affects how some SVE instructions are decoded so any tools which
* decode instructions should clear any cached data and set the vector length used by
* the decoder using dr_set_sve_vector_length().
* the decoder using dr_set_vector_length().
*/
TRACE_MARKER_TYPE_VECTOR_LENGTH,

Expand Down
4 changes: 2 additions & 2 deletions clients/drcachesim/tools/invariant_checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,8 +438,8 @@ invariant_checker_t::parallel_shard_memref(void *shard_data, const memref_t &mem
"Vector length marker has invalid size");

const int new_vl_bits = memref.marker.marker_value * 8;
if (dr_get_sve_vector_length() != new_vl_bits) {
dr_set_sve_vector_length(new_vl_bits);
if (dr_get_vector_length() != new_vl_bits) {
dr_set_vector_length(new_vl_bits);
// Changing the vector length can change the IR representation of some SVE
// instructions but it doesn't effect any of the metadata that is stored
// in decode_cache_ so we don't need to flush the cache.
Expand Down
4 changes: 2 additions & 2 deletions clients/drcachesim/tools/opcode_mix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ opcode_mix_t::parallel_shard_memref(void *shard_data, const memref_t &memref)
memref.marker.marker_type == TRACE_MARKER_TYPE_VECTOR_LENGTH) {
#ifdef AARCH64
const int new_vl_bits = memref.marker.marker_value * 8;
if (dr_get_sve_vector_length() != new_vl_bits) {
dr_set_sve_vector_length(new_vl_bits);
if (dr_get_vector_length() != new_vl_bits) {
dr_set_vector_length(new_vl_bits);
// Changing the vector length can change the IR representation of some SVE
// instructions but it will never change the opcode so we don't need to
// flush the opcode cache.
Expand Down
4 changes: 2 additions & 2 deletions clients/drcachesim/tracer/raw2trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,8 +910,8 @@ raw2trace_t::process_marker(raw2trace_thread_data_t *tdata,
tdata->tid, marker_val);

const int new_vl_bits = marker_val * 8;
if (dr_get_sve_vector_length() != new_vl_bits) {
dr_set_sve_vector_length(new_vl_bits);
if (dr_get_vector_length() != new_vl_bits) {
dr_set_vector_length(new_vl_bits);
// Some SVE load/store instructions have an offset which is scaled by a value
// that depends on the vector length. These instructions will need to be
// re-decoded after the vector length changes.
Expand Down
19 changes: 12 additions & 7 deletions clients/drdisas/drdisas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,16 @@ droption_t<std::string> op_mode(DROPTION_SCOPE_FRONTEND, "mode", "arm",
"Decodes using the specified mode: 'arm' or 'thumb'.");
#elif defined(AARCH64)
droption_t<unsigned int>
op_sve_vl(DROPTION_SCOPE_FRONTEND, "vl", 128,
"Sets the SVE vector length to one of: 128 256 384 512 640 768 896 1024 "
"1152 1280 1408 1536 1664 1792 1920 2048.",
"Sets the SVE vector length to one of: 128 256 384 512 640 768 896 1024 "
"1152 1280 1408 1536 1664 1792 1920 2048.");
op_vl(DROPTION_SCOPE_FRONTEND, "vl", 128,
"Sets the SVE vector length to one of: 128 256 384 512 640 768 896 1024 "
"1152 1280 1408 1536 1664 1792 1920 2048.",
"Sets the SVE vector length to one of: 128 256 384 512 640 768 896 1024 "
"1152 1280 1408 1536 1664 1792 1920 2048.");
#elif defined(RISCV64)
droption_t<unsigned int>
op_vl(DROPTION_SCOPE_FRONTEND, "vl", 128,
"Sets the RVV vector length from 64 to 65536 in the power of 2.",
"Sets the RVV vector length from 64 to 65536 in the power of 2.");
#endif

droption_t<bool> op_show_bytes(DROPTION_SCOPE_FRONTEND, "show_bytes", true,
Expand Down Expand Up @@ -147,8 +152,8 @@ main(int argc, const char *argv[])
}
#endif

#ifdef AARCH64
dr_set_sve_vector_length(op_sve_vl.get_value());
#if defined(AARCH64) || defined(RISCV64)
dr_set_vector_length(op_vl.get_value());
#endif

// XXX i#4021: arm not yet supported.
Expand Down
2 changes: 1 addition & 1 deletion core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@ if (BUILD_TESTS AND
if (APPLE)
set_tests_properties(unit_tests PROPERTIES LABELS OSX)
endif ()
if (AARCHXX)
if (AARCHXX OR RISCV64)
set_tests_properties(unit_tests PROPERTIES LABELS RUNS_ON_QEMU)
endif ()
copy_target_to_device(unit_tests "${location_suffix}")
Expand Down
8 changes: 4 additions & 4 deletions core/arch/aarch64/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,14 @@ get_processor_specific_info(void)
:
: "x0");
cpu_info.sve_vector_length_bytes = vl;
dr_set_sve_vector_length(vl * 8);
dr_set_vector_length(vl * 8);
} else {
cpu_info.sve_vector_length_bytes = 32;
dr_set_sve_vector_length(256);
dr_set_vector_length(256);
}
# else
/* Set SVE vector length for unit testing the off-line decoder. */
dr_set_sve_vector_length(256);
dr_set_vector_length(256);
# endif
}
# endif
Expand Down Expand Up @@ -290,7 +290,7 @@ enable_all_test_cpu_features()
for (int i = 0; i < BUFFER_SIZE_ELEMENTS(features); ++i) {
proc_set_feature(features[i], true);
}
dr_set_sve_vector_length(256);
dr_set_vector_length(256);
}

#ifndef DR_HOST_NOT_TARGET
Expand Down
5 changes: 5 additions & 0 deletions core/arch/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ mixed_mode_enabled(void)
# define REG4_OFFSET ((MC_OFFS) + (offsetof(priv_mcontext_t, a4)))
# define REG5_OFFSET ((MC_OFFS) + (offsetof(priv_mcontext_t, a5)))
# define XFLAGS_OFFSET ((MC_OFFS) + (offsetof(priv_mcontext_t, fcsr)))
# define VSTART_OFFSET ((MC_OFFS) + (offsetof(priv_mcontext_t, vstart)))
# define VCSR_OFFSET ((MC_OFFS) + (offsetof(priv_mcontext_t, vcsr)))
# define SCRATCH_REG0 DR_REG_A0
# define SCRATCH_REG1 DR_REG_A1
# define SCRATCH_REG2 DR_REG_A2
Expand All @@ -188,6 +190,9 @@ mixed_mode_enabled(void)
# define SCRATCH_REG5_OFFS REG5_OFFSET
# define REG_OFFSET(reg) (X0_OFFSET + ((reg)-DR_REG_X0) * sizeof(reg_t))
# define FREG_OFFSET(reg) (F0_OFFSET + ((reg)-DR_REG_F0) * sizeof(reg_t))
# define VREG_OFFSET(reg) \
((MC_OFFS) + \
(offsetof(priv_mcontext_t, simd) + ((reg)-DR_REG_VR0) * sizeof(dr_simd_t)))
# define CALL_SCRATCH_REG DR_REG_T6
# define MC_IBL_REG a2
# define MC_RETVAL_REG a0
Expand Down
4 changes: 4 additions & 0 deletions core/arch/proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ typedef struct _cpu_info_t {
#ifdef AARCHXX
uint architecture;
uint sve_vector_length_bytes;
#endif
#ifdef RISCV64
/* Vector length in bytes. */
uint vlenb;
#endif
uint family;
uint type;
Expand Down
12 changes: 11 additions & 1 deletion core/arch/proc_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ DR_API
const char *
proc_get_cache_size_str(cache_size_t size);

#ifdef AARCHXX
#if defined(AARCHXX)
DR_API
/**
* Returns the size in bytes of the SVE registers' vector length set by the
Expand All @@ -576,6 +576,16 @@ DR_API
*/
uint
proc_get_vector_length_bytes(void);
#elif defined(RISCV64)
DR_API
/**
* Returns the size in bytes of the RVV registers' vector length which is a design-time
* constant set by the hardware implementor. Length can be from 64 to 65536 bits
* in the power of 2.
* Currently DynamoRIO supports implementations of up to 256 bits.
*/
uint
proc_get_vector_length_bytes(void);
#endif

DR_API
Expand Down
12 changes: 10 additions & 2 deletions core/arch/proc_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,10 @@ cpu_info_t cpu_info = {
#else
VENDOR_UNKNOWN,
#endif
#ifdef AARCHXX
#if defined(AARCHXX)
0,
0,
#elif defined(RISCV64)
0,
#endif
0,
Expand Down Expand Up @@ -200,7 +202,7 @@ proc_get_stepping(void)
return cpu_info.stepping;
}

#ifdef AARCHXX
#if defined(AARCHXX)
uint
proc_get_architecture(void)
{
Expand All @@ -212,6 +214,12 @@ proc_get_vector_length_bytes(void)
{
return cpu_info.sve_vector_length_bytes;
}
#elif defined(RISCV64)
uint
proc_get_vector_length_bytes(void)
{
return cpu_info.vlenb;
}
#endif

features_t *
Expand Down
Loading

0 comments on commit 59d0360

Please sign in to comment.