Skip to content

Commit

Permalink
i#3544 RV64: Implement tp, stolen reg and lr/sc sequence mangling (#6419
Browse files Browse the repository at this point in the history
)

This patch implements several mangling procedures for tp, stolen reg,
and lr/sc sequences.

1. For any instruction using tp or stolen register, we use a scratch
register to hold the app value and mangle the instr to use that scratch
register.
2. For the lr/sc sequence, a similar approach to AARCHXX's exclusive
monitor is adopted: mangling LR to a normal load, and SC to a
compare-and-swap. The function name (mangle_exclusive_monitor_op) is
kept unchanged for simplicity.

Note there are several places that are left unimplemented, they are
rarely used in practice, so it should be okay to implement it later.

Issue: #3544
  • Loading branch information
ksco committed Nov 11, 2023
1 parent c6f7b74 commit e8f554f
Show file tree
Hide file tree
Showing 8 changed files with 560 additions and 20 deletions.
7 changes: 5 additions & 2 deletions core/arch/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -595,8 +595,11 @@ instr_t *
mangle_rel_addr(dcontext_t *dcontext, instrlist_t *ilist, instr_t *instr,
instr_t *next_instr);
#endif
#ifdef AARCHXX
/* mangle instructions that use pc or dr_reg_stolen */
#if defined(AARCHXX) || defined(RISCV64)
/* For ARM, mangle app instr accessing registers pc and dr_reg_stolen;
* for AArch64, mangle app instr accessing register dr_reg_stolen;
* for RISC-V, mangle app instr accessing registers tp and dr_reg_stolen.
*/
instr_t *
mangle_special_registers(dcontext_t *dcontext, instrlist_t *ilist, instr_t *instr,
instr_t *next_instr);
Expand Down
11 changes: 11 additions & 0 deletions core/arch/arch_exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ typedef struct _spill_state_t {
reg_t ldstex_flags;
# endif
/* TODO i#1575: coarse-grain NYI on ARM */
#elif defined(RISCV64)
/* State for converting LR/SC pair into compare-and-swap (-ldstex2cas). */
ptr_uint_t lrsc_addr;
ptr_uint_t lrsc_value;
ptr_uint_t lrsc_size;
#endif
} spill_state_t;

Expand Down Expand Up @@ -233,11 +238,14 @@ typedef struct _local_state_extended_t {
# define TLS_REG1_SLOT ((ushort)offsetof(spill_state_t, a1))
# define TLS_REG2_SLOT ((ushort)offsetof(spill_state_t, a2))
# define TLS_REG3_SLOT ((ushort)offsetof(spill_state_t, a3))
# define TLS_REG4_SLOT ((ushort)offsetof(spill_state_t, a4))
# define TLS_REG_STOLEN_SLOT ((ushort)offsetof(spill_state_t, reg_stolen))
# define SCRATCH_REG0 DR_REG_A0
# define SCRATCH_REG1 DR_REG_A1
# define SCRATCH_REG2 DR_REG_A2
# define SCRATCH_REG3 DR_REG_A3
# define SCRATCH_REG4 DR_REG_A4
# define SCRATCH_REG_LAST DR_REG_A4
#endif /* X86/ARM */
#define IBL_TARGET_REG SCRATCH_REG2
#define IBL_TARGET_SLOT TLS_REG2_SLOT
Expand All @@ -253,6 +261,9 @@ typedef struct _local_state_extended_t {
# endif
#elif defined(RISCV64)
# define TLS_FCACHE_RETURN_SLOT ((ushort)offsetof(spill_state_t, fcache_return))
# define TLS_LRSC_ADDR_SLOT ((ushort)offsetof(spill_state_t, lrsc_addr))
# define TLS_LRSC_VALUE_SLOT ((ushort)offsetof(spill_state_t, lrsc_value))
# define TLS_LRSC_SIZE_SLOT ((ushort)offsetof(spill_state_t, lrsc_size))
#endif

#define TABLE_OFFSET (offsetof(local_state_extended_t, table_space))
Expand Down
18 changes: 11 additions & 7 deletions core/arch/mangle_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -1692,10 +1692,11 @@ d_r_mangle(dcontext_t *dcontext, instrlist_t *ilist, uint *flags INOUT, bool man
continue;
}
#endif
#ifdef AARCHXX
#if defined(AARCHXX) || defined(RISCV64)
if (instr_is_app(instr) &&
(instr_is_exclusive_load(instr) || instr_is_exclusive_store(instr) ||
instr_get_opcode(instr) == OP_clrex)) {
(instr_is_exclusive_load(instr) ||
instr_is_exclusive_store(instr)
IF_AARCHXX(|| instr_get_opcode(instr) == OP_clrex))) {
instr_t *res =
mangle_exclusive_monitor_op(dcontext, ilist, instr, next_instr);
if (res != NULL) {
Expand All @@ -1704,18 +1705,21 @@ d_r_mangle(dcontext_t *dcontext, instrlist_t *ilist, uint *flags INOUT, bool man
} /* Else, fall through. */
}
#endif
#ifdef AARCH64
#if defined(AARCH64)
if (!instr_is_meta(instr) && instr_uses_reg(instr, dr_reg_stolen))
next_instr = mangle_special_registers(dcontext, ilist, instr, next_instr);
#endif
#ifdef ARM
#elif defined(ARM)
/* Our stolen reg model is to expose to the client. We assume that any
* meta instrs using it are using it as TLS. Ditto w/ use of PC.
*/
if (!instr_is_meta(instr) &&
(instr_uses_reg(instr, DR_REG_PC) || instr_uses_reg(instr, dr_reg_stolen)))
next_instr = mangle_special_registers(dcontext, ilist, instr, next_instr);
#endif /* ARM */
#elif defined(RISCV64)
if (!instr_is_meta(instr) &&
(instr_uses_reg(instr, dr_reg_stolen) || instr_uses_reg(instr, DR_REG_TP)))
next_instr = mangle_special_registers(dcontext, ilist, instr, next_instr);
#endif /* AARCH64/ARM/RISCV64 */

if (instr_is_exit_cti(instr)) {
#ifdef X86
Expand Down
Loading

0 comments on commit e8f554f

Please sign in to comment.