Skip to content

Commit

Permalink
Implement experimental riscv instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
Mingle Chen committed Apr 5, 2023
1 parent c27dd7d commit 03e9e72
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 2 deletions.
2 changes: 2 additions & 0 deletions target/riscv/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ DEF_HELPER_3(lr_c_cap, void, env, i32, i32)
DEF_HELPER_3(sc_c_modedep, tl, env, i32, i32)
DEF_HELPER_3(sc_c_ddc, tl, env, i32, i32)
DEF_HELPER_3(sc_c_cap, tl, env, i32, i32)
/* experimental instruction helpers*/
DEF_HELPER_2(ctestdereferenceable, tl, env, i32)
#endif

#ifdef CONFIG_TCG_LOG_INSTR
Expand Down
6 changes: 4 additions & 2 deletions target/riscv/insn32-cheri.decode
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ ccopytype 0011110 ..... ..... 000 ..... 1011011 @r
ccseal 0011111 ..... ..... 000 ..... 1011011 @r
ctestsubset 0100000 ..... ..... 000 ..... 1011011 @r
cseqx 0100001 ..... ..... 000 ..... 1011011 @r
candaddr 0100010 ..... ..... 000 ..... 1011011 @r

# 1111011 unused
# 1111100 Used for Stores (see below)
# 1111101 Used for Loads (see below)
Expand Down Expand Up @@ -85,9 +87,9 @@ cgetaddr 1111111 01111 ..... 000 ..... 1011011 @r2
# fpclear 1111111 10000 ..... 000 ..... 1011011 @r2
csealentry 1111111 10001 ..... 000 ..... 1011011 @r2
cloadtags 1111111 10010 ..... 000 ..... 1011011 @r2
ctestdereferenceable 1111111 10011 ..... 000 ..... 1011011 @r2
jalr_pcc 1111111 10100 ..... 000 ..... 1011011 @r2


candpermuserdata 1111111 10101 ..... 000 ..... 1011011 @r2

# There is an existing @sfence_vma format with rs1+rs2 fields, but let's define a new name
@r_2source ....... ..... ..... ... ..... ....... %rs2 %rs1
Expand Down
40 changes: 40 additions & 0 deletions target/riscv/insn_trans/trans_cheri.c.inc
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ TRANSLATE_INT_CAP(cgetsealed)

TRANSLATE_INT_CAP(cloadtags)

// experimental ctestdereferenceable
TRANSLATE_INT_CAP(ctestdereferenceable)

// Two operand (int int)
static inline bool trans_crrl(DisasContext *ctx, arg_crrl *a)
{
Expand All @@ -181,6 +184,40 @@ TRANSLATE_CAP_CAP(ccleartag)
TRANSLATE_CAP_CAP(cmove)
TRANSLATE_CAP_CAP(csealentry)

// experimental candpermuserdata

/* User-defined permission bits. */
#define CAP_PERM_SW0 (1 << 15) /* 0x00008000 */
#define CAP_PERM_SW1 (1 << 16) /* 0x00010000 */
#define CAP_PERM_SW2 (1 << 17) /* 0x00020000 */
#define CAP_PERM_SW3 (1 << 18) /* 0x00040000 */
#define CAP_PERM_SW_VMEM CAP_PERM_SW1

#define CAP_PERMS_SWALL \
(CAP_PERM_SW0 | CAP_PERM_SW1 | CAP_PERM_SW2 | CAP_PERM_SW3)

#define CAP_PERMS_USERSPACE \
(CAP_PERM_GLOBAL | CAP_PERM_LOAD | CAP_PERM_LOAD_CAP | CAP_PERM_CINVOKE | \
(CAP_PERMS_SWALL & ~CAP_PERM_SW_VMEM))

#define CAP_PERMS_USERSPACE_DATA \
(CAP_PERMS_USERSPACE | CAP_PERM_STORE | CAP_PERM_STORE_CAP | \
CAP_PERM_STORE_LOCAL)

static inline bool trans_candpermuserdata(DisasContext *ctx,
arg_candpermuserdata *a)
{
TCGv_i32 source_regnum = tcg_const_i32(a->rs1);
TCGv_i32 dest_regnum = tcg_const_i32(a->rd);
TCGv gpr = tcg_temp_new();
gen_set_gpr(gpr, CAP_PERMS_USERSPACE_DATA & ~CAP_PERM_SW_VMEM);
gen_helper_candperm(cpu_env, dest_regnum, source_regnum, gpr);
tcg_temp_free(gpr);
tcg_temp_free_i32(dest_regnum);
tcg_temp_free_i32(source_regnum);
return true;
}

// Three operand (cap cap cap)
TRANSLATE_CAP_CAP_CAP(cbuildcap)
TRANSLATE_CAP_CAP_CAP(ccopytype)
Expand Down Expand Up @@ -215,6 +252,9 @@ TRANSLATE_CAP_CAP_INT(csetboundsexact)
TRANSLATE_CAP_CAP_INT(csetflags)
TRANSLATE_CAP_CAP_INT(csetoffset)

// Add experimental CAndAddr instruction
TRANSLATE_CAP_CAP_INT(candaddr)

// Three operand (int cap cap)
TRANSLATE_INT_CAP_CAP(csub)
TRANSLATE_INT_CAP_CAP(ctestsubset)
Expand Down
8 changes: 8 additions & 0 deletions target/riscv/op_helper_cheri.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,3 +453,11 @@ target_ulong HELPER(sc_c_cap)(CPUArchState *env, uint32_t addr_reg, uint32_t val
{
return sc_c_impl(env, addr_reg, val_reg, /*offset=*/0, GETPC());
}

/* Helpers for experimental instructions. */
target_ulong HELPER(ctestdereferenceable)(CPUArchState *env, uint32_t addr_reg)
{
const cap_register_t *cbp = get_readonly_capreg(env, addr_reg);

return cbp->cr_tag && cap_is_unsealed(cbp) && cap_cursor_in_bounds(cbp);
}

0 comments on commit 03e9e72

Please sign in to comment.