Skip to content

Commit af7566e

Browse files
committed
Add support for Zcmt extension
1 parent 3cdd27b commit af7566e

12 files changed

+144
-2
lines changed

c_emulator/riscv_platform.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,17 @@ bool sys_enable_zcb(unit)
3838
return rv_enable_zcb;
3939
}
4040

41-
bool sys_enable_zfinx(unit)
41+
bool sys_enable_zcd(unit u)
42+
{
43+
return rv_enable_zcd;
44+
}
45+
46+
bool sys_enable_zcmt(unit u)
47+
{
48+
return rv_enable_zcmt;
49+
}
50+
51+
bool sys_enable_zfinx(unit u)
4252
{
4353
return rv_enable_zfinx;
4454
}

c_emulator/riscv_platform.h

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ bool sys_enable_rvc(unit);
99
bool sys_enable_fdext(unit);
1010
bool sys_enable_svinval(unit);
1111
bool sys_enable_zcb(unit);
12+
bool sys_enable_zcd(unit);
13+
bool sys_enable_zcmt(unit);
1214
bool sys_enable_zfinx(unit);
1315
bool sys_enable_writable_misa(unit);
1416
bool sys_enable_writable_fiom(unit);

c_emulator/riscv_platform_impl.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ uint64_t rv_vector_elen_exp = 0x6;
1111

1212
bool rv_enable_svinval = false;
1313
bool rv_enable_zcb = false;
14+
bool rv_enable_zcd = true;
15+
bool rv_enable_zcmt = false;
1416
bool rv_enable_zfinx = false;
1517
bool rv_enable_rvc = true;
1618
bool rv_enable_writable_misa = true;

c_emulator/riscv_platform_impl.h

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ extern uint64_t rv_vector_elen_exp;
1616

1717
extern bool rv_enable_svinval;
1818
extern bool rv_enable_zcb;
19+
extern bool rv_enable_zcd;
20+
extern bool rv_enable_zcmt;
1921
extern bool rv_enable_zfinx;
2022
extern bool rv_enable_rvc;
2123
extern bool rv_enable_fdext;

c_emulator/riscv_sim.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ enum {
4949
OPT_PMP_GRAIN,
5050
OPT_ENABLE_SVINVAL,
5151
OPT_ENABLE_ZCB,
52+
OPT_ENABLE_ZCMT,
5253
OPT_ENABLE_ZICBOM,
5354
OPT_ENABLE_ZICBOZ,
5455
OPT_ENABLE_ZVKB,
@@ -141,6 +142,7 @@ static struct option options[] = {
141142
{"enable-writable-fiom", no_argument, 0, OPT_ENABLE_WRITABLE_FIOM},
142143
{"enable-svinval", no_argument, 0, OPT_ENABLE_SVINVAL },
143144
{"enable-zcb", no_argument, 0, OPT_ENABLE_ZCB },
145+
{"enable-zcmt", no_argument, 0, OPT_ENABLE_ZCMT },
144146
{"enable-zicbom", no_argument, 0, OPT_ENABLE_ZICBOM },
145147
{"enable-zicboz", no_argument, 0, OPT_ENABLE_ZICBOZ },
146148
{"enable-zvkb", no_argument, 0, OPT_ENABLE_ZVKB },
@@ -391,6 +393,10 @@ static int process_args(int argc, char **argv)
391393
case OPT_ENABLE_ZCB:
392394
fprintf(stderr, "enabling Zcb extension.\n");
393395
rv_enable_zcb = true;
396+
case OPT_ENABLE_ZCMT:
397+
fprintf(stderr, "enabling Zcmt extension.\n");
398+
rv_enable_zcd = false;
399+
rv_enable_zcmt = true;
394400
break;
395401
case OPT_ENABLE_ZICBOM:
396402
fprintf(stderr, "enabling Zicbom extension.\n");

model/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ foreach (xlen IN ITEMS 32 64)
6666
"riscv_insts_zbc.sail"
6767
"riscv_insts_zbs.sail"
6868
"riscv_insts_zcb.sail"
69+
"riscv_insts_zcmt.sail"
6970
"riscv_insts_zfh.sail"
7071
# Zfa needs to be added after fext, dext and Zfh (as it needs
7172
# definitions from those)

model/riscv_addr_checks.sail

+5
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ function ext_data_get_addr(base : regidx, offset : xlenbits, acc : AccessType(ex
5959
let addr = virtaddr(X(base) + offset) in
6060
Ext_DataAddr_OK(addr)
6161

62+
function ext_data_get_addr_from_bits(addr_ext : xlenbits, acc : AccessType(ext_access_type), width : mem_access_width)
63+
-> Ext_DataAddr_Check(ext_data_addr_error) =
64+
let addr = virtaddr(addr_ext) in
65+
Ext_DataAddr_OK(addr)
66+
6267
function ext_handle_data_check_error(err : ext_data_addr_error) -> unit =
6368
()
6469

model/riscv_extensions.sail

+2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ enum clause extension = Ext_Zdinx
6767
enum clause extension = Ext_Zca
6868
// Code Size Reduction: additional 16-bit aliases
6969
enum clause extension = Ext_Zcb
70+
// Code Size Reduction: compressed table jump instructions
71+
enum clause extension = Ext_Zcmt
7072
// Code Size Reduction: compressed double precision floating point loads and stores
7173
enum clause extension = Ext_Zcd
7274
// Code Size Reduction: compressed single precision floating point loads and stores

model/riscv_insts_zcd.sail

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* SPDX-License-Identifier: BSD-2-Clause */
77
/*=======================================================================================*/
88

9-
function clause extensionEnabled(Ext_Zcd) = extensionEnabled(Ext_Zca) & extensionEnabled(Ext_D) & (xlen == 32 | xlen == 64)
9+
function clause extensionEnabled(Ext_Zcd) = extensionEnabled(Ext_Zca) & extensionEnabled(Ext_D) & sys_enable_zcd() & not(sys_enable_zcmt()) & (xlen == 32 | xlen == 64)
1010

1111
union clause ast = C_FLDSP : (bits(6), fregidx)
1212

model/riscv_insts_zcmt.sail

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*=======================================================================================*/
2+
/* This Sail RISC-V architecture model, comprising all files and */
3+
/* directories except where otherwise noted is subject the BSD */
4+
/* two-clause license in the LICENSE file. */
5+
/* */
6+
/* SPDX-License-Identifier: BSD-2-Clause */
7+
/*=======================================================================================*/
8+
9+
function clause extensionEnabled(Ext_Zcmt) = extensionEnabled(Ext_Zca) & sys_enable_zcmt() & not(sys_enable_zcd()) & (xlen == 32 | xlen == 64)
10+
11+
type target_address = xlenbits
12+
13+
function fetch_jump_table(table_address : xlenbits) -> result(target_address, unit) = {
14+
/* Executable permission required to fetch jump table address */
15+
match ext_data_get_addr_from_bits(table_address, Execute(), xlen_bytes) {
16+
Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); Err() },
17+
Ext_DataAddr_OK(vaddr) => {
18+
if check_misaligned(vaddr, size_bytes(xlen_bytes))
19+
then { handle_mem_exception(vaddr, E_Load_Addr_Align()); Err() }
20+
else match translateAddr(vaddr, Execute()) {
21+
TR_Failure(e, _) => { handle_mem_exception(vaddr, e); Err() },
22+
TR_Address(paddr, _) =>
23+
match mem_read(Execute(), paddr, xlen_bytes, false, false, false) {
24+
Ok(result) => { Ok(result) },
25+
Err(e) => { handle_mem_exception(vaddr, e); Err() },
26+
}
27+
}
28+
}
29+
}
30+
}
31+
32+
union clause ast = CM_JALT : (bits(8))
33+
34+
mapping clause encdec_compressed = CM_JALT(index)
35+
<-> 0b101 @ 0b000 @ index : bits(8) @ 0b10
36+
when extensionEnabled(Ext_Zcmt) & 32 <= unsigned(index)
37+
38+
function clause execute (CM_JALT(index)) = {
39+
let base : bits(xlen) = jvt[base] @ 0b000000;
40+
let index : bits(xlen) = zero_extend(index);
41+
if jvt[mode] == 0b000000 then {
42+
let table_address = base + (index << log2_xlen_bytes);
43+
match fetch_jump_table(table_address) {
44+
Err(_) => { RETIRE_FAIL },
45+
Ok(target_address) => {
46+
X(ra) = get_next_pc();
47+
set_next_pc([target_address with 0 = bitzero]);
48+
RETIRE_SUCCESS
49+
}
50+
};
51+
} else {
52+
handle_illegal();
53+
RETIRE_FAIL
54+
};
55+
}
56+
57+
mapping clause assembly = CM_JALT(index)
58+
<-> "cm.jalt" ^ spc() ^ hex_bits_8(index)
59+
60+
/* ****************************************************************** */
61+
union clause ast = CM_JT : (bits(8))
62+
63+
mapping clause encdec_compressed = CM_JT(index)
64+
<-> 0b101 @ 0b000 @ index : bits(8) @ 0b10
65+
when extensionEnabled(Ext_Zcmt) & unsigned(index) < 32
66+
67+
function clause execute (CM_JT(index)) = {
68+
let base : bits(xlen) = jvt[base] @ 0b000000;
69+
let index : bits(xlen) = zero_extend(index);
70+
if jvt[mode] == 0b000000 then {
71+
let table_address = base + (index << log2_xlen_bytes);
72+
match fetch_jump_table(table_address) {
73+
Err(_) => { RETIRE_FAIL },
74+
Ok(target_address) => {
75+
set_next_pc([target_address with 0 = bitzero]);
76+
RETIRE_SUCCESS
77+
}
78+
};
79+
} else {
80+
handle_illegal();
81+
RETIRE_FAIL
82+
};
83+
}
84+
85+
mapping clause assembly = CM_JT(index)
86+
<-> "cm.jt" ^ spc() ^ hex_bits_8(index)

model/riscv_sys_regs.sail

+25
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ val sys_enable_fdext = pure "sys_enable_fdext" : unit -> bool
9292
val sys_enable_svinval = pure "sys_enable_svinval" : unit -> bool
9393
/* whether Zcb was enabled at boot */
9494
val sys_enable_zcb = pure "sys_enable_zcb" : unit -> bool
95+
/* whether Zcd was enabled at boot */
96+
val sys_enable_zcd = pure "sys_enable_zcd" : unit -> bool
97+
/* whether Zcmt was enabled at boot */
98+
val sys_enable_zcmt = pure "sys_enable_zcmt" : unit -> bool
9599
/* whether zfinx was enabled at boot */
96100
val sys_enable_zfinx = pure "sys_enable_zfinx" : unit -> bool
97101
/* Whether FIOM bit of menvcfg/senvcfg is enabled. It must be enabled if
@@ -511,6 +515,27 @@ function clause write_CSR((0x302, value) if xlen == 32) = { medeleg = legalize_m
511515
function clause write_CSR((0x312, value) if xlen == 32) = { medeleg = legalize_medeleg(medeleg, value @ medeleg.bits[31 .. 0]); medeleg.bits[63 .. 32] }
512516
function clause write_CSR(0x303, value) = { mideleg = legalize_mideleg(mideleg, value); mideleg.bits }
513517

518+
/* Zcmt extension */
519+
520+
bitfield Jvt : xlenbits = {
521+
base : xlen - 1 .. 6,
522+
mode : 5 .. 0
523+
}
524+
register jvt : Jvt
525+
526+
function legalize_jvt(o : Jvt, v : xlenbits) -> Jvt = {
527+
let v = Mk_Jvt(v);
528+
[o with
529+
base = v[base],
530+
mode = 0b000000
531+
]
532+
}
533+
534+
mapping clause csr_name_map = 0x017 <-> "jvt"
535+
function clause is_CSR_defined (0x017) = sys_enable_zcmt()
536+
function clause write_CSR(0x017, value) = { jvt = legalize_jvt(jvt, value); jvt.bits }
537+
function clause read_CSR(0x017) = jvt.bits
538+
514539
/* registers for trap handling */
515540

516541
bitfield Mtvec : xlenbits = {

model/riscv_termination.sail

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ function extensionEnabled_measure(ext : extension) -> int =
5656
Ext_Zcb => 2, // Ext_Zca
5757
Ext_Zcd => 2, // Ext_Zca, (Ext_D)
5858
Ext_Zcf => 2, // Ext_Zca, (Ext_F)
59+
Ext_Zcmt => 2, // Ext_Zcmt
5960
_ => 0
6061
}
6162
termination_measure extensionEnabled(ext) = extensionEnabled_measure(ext)

0 commit comments

Comments
 (0)