Skip to content

Commit 7116249

Browse files
committed
Add Zicfiss extension from CFI extension, v0.4.0
1 parent c629231 commit 7116249

21 files changed

+365
-1
lines changed

disasm/disasm.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,18 @@ struct : public arg_t {
266266
}
267267
} rvc_sp;
268268

269+
struct : public arg_t {
270+
std::string to_string(insn_t UNUSED insn) const {
271+
return xpr_name[X_RA];
272+
}
273+
} rvc_ra;
274+
275+
struct : public arg_t {
276+
std::string to_string(insn_t UNUSED insn) const {
277+
return xpr_name[X_T0];
278+
}
279+
} rvc_t0;
280+
269281
struct : public arg_t {
270282
std::string to_string(insn_t insn) const {
271283
return std::to_string((int)insn.rvc_imm());
@@ -2381,6 +2393,23 @@ void disassembler_t::add_instructions(const isa_parser_t* isa)
23812393
DEFINE_XSTORE_BASE(sw_rl);
23822394
DEFINE_XSTORE_BASE(sd_rl);
23832395
}
2396+
2397+
if(isa->extension_enabled(EXT_ZICFISS)) {
2398+
DISASM_INSN("sspush", sspush_x1, 0, {&xrs2});
2399+
DISASM_INSN("sspush", sspush_x5, 0, {&xrs2});
2400+
DISASM_INSN("sspopchk", sspopchk_x1, 0, {&xrs1});
2401+
DISASM_INSN("sspopchk", sspopchk_x5, 0, {&xrs1});
2402+
DISASM_INSN("ssrdp", ssrdp, 0, {&xrd});
2403+
DEFINE_XAMO(ssamoswap_w);
2404+
2405+
if(isa->get_max_xlen() == 64)
2406+
DEFINE_XAMO(ssamoswap_d)
2407+
2408+
if (isa->extension_enabled(EXT_ZCA)) {
2409+
DISASM_INSN("c.sspush", c_sspush_x1, 0, {&rvc_ra});
2410+
DISASM_INSN("c.sspopchk", c_sspopchk_x5, 0, {&rvc_t0});
2411+
}
2412+
}
23842413
}
23852414

23862415
disassembler_t::disassembler_t(const isa_parser_t *isa)

disasm/isa_parser.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
302302
extension_table[EXT_ZALASR] = true;
303303
} else if (ext_str == "ssqosid") {
304304
extension_table[EXT_SSQOSID] = true;
305+
} else if (ext_str == "zicfiss") {
306+
extension_table[EXT_ZICFISS] = true;
305307
} else if (ext_str[0] == 'x') {
306308
extension_table['X'] = true;
307309
if (ext_str.size() == 1) {

riscv/decode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const int NCSR = 4096;
2626

2727
#define X_RA 1
2828
#define X_SP 2
29+
#define X_T0 5
2930
#define X_S0 8
3031
#define X_A0 10
3132
#define X_A1 11

riscv/decode_macros.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#define RVC_R2S (Sn(insn.rvc_r2sc()))
6060
#define SP READ_REG(X_SP)
6161
#define RA READ_REG(X_RA)
62+
#define T0 READ_REG(X_T0)
6263

6364
// FPU macros
6465
#define READ_ZDINX_REG(reg) (xlen == 32 ? f64(READ_REG_PAIR(reg)) : f64(STATE.XPR[reg] & (uint64_t)-1))

riscv/insn_macros.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@
66

77
#define require(x) (unlikely(!(x)) ? throw trap_illegal_instruction(insn.bits()) : (void) 0)
88

9+
#define software_check(x, tval) (unlikely(!(x)) ? throw trap_software_check_fault(tval) : (void) 0)
10+
911
#endif

riscv/insns/c_lui.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ if (insn.rvc_rd() == 2) { // c.addi16sp
55
} else if (insn.rvc_imm() != 0) { // c.lui
66
WRITE_RD(insn.rvc_imm() << 12);
77
} else if ((insn.rvc_rd() & 1) != 0) { // c.mop.N
8-
#include "c_mop_N.h"
8+
if (insn.rvc_rd() == 5 && p->extension_enabled(EXT_ZICFISS)) {
9+
#include "c_sspopchk_x5.h"
10+
} else if (insn.rvc_rd() == 1 && p->extension_enabled(EXT_ZICFISS)) {
11+
#include "c_sspush_x1.h"
12+
} else {
13+
#include "c_mop_N.h"
14+
}
915
} else {
1016
require(false);
1117
}

riscv/insns/c_sspopchk_x5.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
reg_t prv = STATE.prv;
2+
reg_t xSSE = 0;
3+
4+
if (prv == PRV_M)
5+
xSSE = 0;
6+
else if (prv == PRV_S || prv == PRV_HS)
7+
xSSE = get_field(STATE.menvcfg->read(), MENVCFG_SSE);
8+
else if (p->extension_enabled('S'))
9+
xSSE = get_field(STATE.senvcfg->read(), SENVCFG_SSE);
10+
else
11+
xSSE = false;
12+
13+
// For VS-mode
14+
if (prv == PRV_S && STATE.v)
15+
xSSE &= get_field(STATE.henvcfg->read(), HENVCFG_SSE);
16+
17+
if (!xSSE) {
18+
#include "c_mop_N.h"
19+
} else {
20+
reg_t ssp = STATE.ssp->read();
21+
const auto new_sp = ssp + xlen / 8;
22+
uint64_t ss_addr;
23+
24+
if (xlen == 32)
25+
ss_addr = MMU.load<uint32_t>(ssp);
26+
else
27+
ss_addr = MMU.load<uint64_t>(ssp);
28+
29+
software_check(T0 == ss_addr, SHADOW_STACK_FAULT);
30+
31+
STATE.ssp->write(new_sp);
32+
}

riscv/insns/c_sspush_x1.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
reg_t prv = STATE.prv;
2+
reg_t xSSE = 0;
3+
4+
if (prv == PRV_M)
5+
xSSE = 0;
6+
else if (prv == PRV_S || prv == PRV_HS)
7+
xSSE = get_field(STATE.menvcfg->read(), MENVCFG_SSE);
8+
else if (p->extension_enabled('S'))
9+
xSSE = get_field(STATE.senvcfg->read(), SENVCFG_SSE);
10+
else
11+
xSSE = false;
12+
13+
// For VS-mode
14+
if (prv == PRV_S && STATE.v)
15+
xSSE &= get_field(STATE.henvcfg->read(), HENVCFG_SSE);
16+
17+
if (!xSSE) {
18+
#include "c_mop_N.h"
19+
} else {
20+
reg_t ssp = STATE.ssp->read();
21+
const auto new_sp = ssp - xlen / 8;
22+
23+
if (xlen == 32)
24+
MMU.store<uint32_t>(new_sp, RA);
25+
else
26+
MMU.store<uint64_t>(new_sp, RA);
27+
28+
STATE.ssp->write(new_sp);
29+
}

riscv/insns/ssamoswap_d.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
require_extension(EXT_ZICFISS);
2+
require_extension('A');
3+
require_rv64;
4+
5+
reg_t prv = STATE.prv;
6+
7+
if (prv != PRV_M && !get_field(STATE.menvcfg->read(), MENVCFG_SSE))
8+
throw trap_illegal_instruction(insn.bits());
9+
if (!p->extension_enabled('S'))
10+
throw trap_illegal_instruction(insn.bits());
11+
else if (prv == PRV_U && !get_field(STATE.senvcfg->read(), SENVCFG_SSE))
12+
throw trap_illegal_instruction(insn.bits());
13+
else if (prv == PRV_S && STATE.v && !get_field(STATE.henvcfg->read(), HENVCFG_SSE))
14+
throw trap_virtual_instruction(insn.bits());
15+
else if (prv == PRV_U && STATE.v && !get_field(STATE.senvcfg->read(), SENVCFG_SSE))
16+
throw trap_virtual_instruction(insn.bits());
17+
else
18+
WRITE_RD(MMU.amo<uint64_t>(RS1, [&](uint64_t UNUSED lhs) { return RS2; }));

riscv/insns/ssamoswap_w.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
require_extension(EXT_ZICFISS);
2+
require_extension('A');
3+
4+
reg_t prv = STATE.prv;
5+
6+
if (prv != PRV_M && !get_field(STATE.menvcfg->read(), MENVCFG_SSE))
7+
throw trap_illegal_instruction(insn.bits());
8+
if (!p->extension_enabled('S'))
9+
throw trap_illegal_instruction(insn.bits());
10+
else if (prv == PRV_U && !get_field(STATE.senvcfg->read(), SENVCFG_SSE))
11+
throw trap_illegal_instruction(insn.bits());
12+
else if (prv == PRV_S && STATE.v && !get_field(STATE.henvcfg->read(), HENVCFG_SSE))
13+
throw trap_virtual_instruction(insn.bits());
14+
else if (prv == PRV_U && STATE.v && !get_field(STATE.senvcfg->read(), SENVCFG_SSE))
15+
throw trap_virtual_instruction(insn.bits());
16+
else
17+
WRITE_RD(sext32(MMU.amo<uint32_t>(RS1, [&](uint32_t UNUSED lhs) { return RS2; })));
18+

0 commit comments

Comments
 (0)