Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions backends/instructions_appendix/all_instructions.golden.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11513,6 +11513,78 @@ Included in::
|===


[#udb:doc:inst:cm_jalt]
== cm.jalt

Synopsis::
Jump Via Table with Optional Link

Assembly::
cm.jalt index

Encoding::
[wavedrom, ,svg,subs='attributes',width="100%"]
....
{"reg":[{"bits":2,"name": 0x2,"type":2},{"bits":8,"name": "index != {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}","type":4},{"bits":6,"name": 0x28,"type":2}]}
....

Description::
Read an address from the Jump Vector Table and jump to it, linking to `ra`.


Decode Variables::
[width="100%", cols="1,2", options="header"]
|===
|Variable Name |Location
|index |$encoding[9:2]
|===

Included in::
[options="autowrap,autowidth"]
|===
| Extension | Version

| *Zcmt* | ~> 1.0.0

|===


[#udb:doc:inst:cm_jt]
== cm.jt

Synopsis::
Jump Via Table

Assembly::
cm.jt index

Encoding::
[wavedrom, ,svg,subs='attributes',width="100%"]
....
{"reg":[{"bits":2,"name": 0x2,"type":2},{"bits":5,"name": "index","type":4},{"bits":9,"name": 0x140,"type":2}]}
....

Description::
Read an address from the Jump Vector Table and jump to it.


Decode Variables::
[width="100%", cols="1,2", options="header"]
|===
|Variable Name |Location
|index |$encoding[6:2]
|===

Included in::
[options="autowrap,autowidth"]
|===
| Extension | Version

| *Zcmt* | ~> 1.0.0

|===


[#udb:doc:inst:cm_mva01s]
== cm.mva01s

Expand Down
58 changes: 14 additions & 44 deletions spec/std/isa/csr/jvt.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,19 @@ fields:
}
reset_value: UNDEFINED_LEGAL
sw_write(csr_value): |
if ((mode() != PrivilegeMode::M) && implemented?(ExtensionName::Smstateen)) {
if (CSR[mstateen0].JVT == 1'b0) {
unimplemented_csr($encoding);
}
}
else if ((mode() == PrivilegeMode::U) && implemented?(ExtensionName::Ssstateen)) {
if (CSR[sstateen0].JVT == 1'b0) {
unimplemented_csr($encoding);
}
}
else if ((mode() == PrivilegeMode::VS) && implemented?(ExtensionName::Ssstateen)) {
if (CSR[hstateen0].JVT == 1'b0) {
unimplemented_csr($encoding);
}
}
else if ((mode() == PrivilegeMode::VU) && implemented?(ExtensionName::Ssstateen)) {
if ((CSR[sstateen0].JVT == 1'b0) || (CSR[hstateen0].JVT == 1'b0)) {
unimplemented_csr($encoding);
}
if (( mode() != PrivilegeMode::M && implemented?(ExtensionName::Smstateen)
&& CSR[mstateen0].JVT == 1'b0 )
||
( mode() == PrivilegeMode::U && implemented?(ExtensionName::Ssstateen)
&& CSR[sstateen0].JVT == 1'b0 )
||
( mode() == PrivilegeMode::VS && implemented?(ExtensionName::Ssstateen)
&& CSR[hstateen0].JVT == 1'b0 )
||
( mode() == PrivilegeMode::VU && implemented?(ExtensionName::Ssstateen)
&& (CSR[sstateen0].JVT == 1'b0 || CSR[hstateen0].JVT == 1'b0) )) {

unimplemented_csr($encoding);
}
else {
if (JVT_BASE_TYPE == "custom") {
Expand Down Expand Up @@ -94,28 +88,4 @@ fields:
}
return 0;
sw_read(): |
# If the Smstateen extension is implemented, then bit 2 in `mstateen0`, `sstateen0`, and `hstateen0` is
# implemented. If bit 2 of a controlling `stateen0` CSR is zero, then access to the `jvt` CSR and execution
# of a `cm.jalt` or `cm.jt` instruction by a lower privilege level results in an illegal-instruction trap (or, if
# appropriate, a virtual-instruction trap).

if ((mode() != PrivilegeMode::M) && implemented?(ExtensionName::Smstateen)) {
if (CSR[mstateen0].JVT == 1'b0) {
raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
}
}
else if ((mode() == PrivilegeMode::U) && implemented?(ExtensionName::Ssstateen)) {
if (CSR[sstateen0].JVT == 1'b0) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}
}
else if ((mode() == PrivilegeMode::VS) && implemented?(ExtensionName::Ssstateen)) {
if (CSR[hstateen0].JVT == 1'b0) {
raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
}
}
else if ((mode() == PrivilegeMode::VU) && implemented?(ExtensionName::Ssstateen)) {
if ((CSR[sstateen0].JVT == 1'b0) || (CSR[hstateen0].JVT == 1'b0)) {
raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
}
}
check_zcmt_enabled($encoding);
63 changes: 63 additions & 0 deletions spec/std/isa/inst/Zcmt/cm.jalt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Copyright (c) Ventana Micro Systems
# SPDX-License-Identifier: BSD-3-Clause-Clear

# yaml-language-server: $schema=../../../../schemas/inst_schema.json

$schema: "inst_schema.json#"
kind: instruction
name: cm.jalt
long_name: Jump Via Table with Optional Link
description: |
Read an address from the Jump Vector Table and jump to it, linking to `ra`.
definedBy: Zcmt
assembly: index
encoding:
match: 101000--------10
variables:
- name: index
location: 9-2
# prettier-ignore
not: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 ]
access:
s: always
u: always
vs: always
vu: always
operation(): |
# Ensure JVT readable
check_zcmt_enabled($encoding);

if (CSR[jvt].MODE != 0) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}

# Skip over _this_ 16-bit instruction
XReg return_addr = $pc + 2;
X[1] = return_addr;

XReg jump_table_base = { CSR[jvt].BASE, 6'b000000 };
XReg virtual_address = jump_table_base + index `* (xlen() / 8);
XReg addr;
TranslationResult result;

# TODO: Correct this check when we figure out what MISA can do
if (CSR[misa].S == 1) {
result = translate(virtual_address, MemoryOperation::Fetch, mode(), $encoding);
} else {
result.paddr = virtual_address;
}

# may raise an exception
access_check(result.paddr, xlen(), $pc, MemoryOperation::Fetch, ExceptionCode::InstructionAccessFault, mode());

if (xlen() == 32) {
addr = read_physical_memory<32>(result.paddr);
} else {
addr = read_physical_memory<64>(result.paddr);
} # Ensure low-order bit is clear

addr = addr & $signed(2'b10);

jump(addr);

sail(): |
58 changes: 58 additions & 0 deletions spec/std/isa/inst/Zcmt/cm.jt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Copyright (c) Ventana Micro Systems
# SPDX-License-Identifier: BSD-3-Clause-Clear

# yaml-language-server: $schema=../../../../schemas/inst_schema.json

$schema: "inst_schema.json#"
kind: instruction
name: cm.jt
long_name: Jump Via Table
description: |
Read an address from the Jump Vector Table and jump to it.
definedBy: Zcmt
assembly: index
encoding:
match: 101000000-----10
variables:
- name: index
location: 6-2
access:
s: always
u: always
vs: always
vu: always
operation(): |
# Ensure JVT readable
check_zcmt_enabled($encoding);

if (CSR[jvt].MODE != 0) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}

XReg jump_table_base = { CSR[jvt].BASE, 6'b000000 };
XReg virtual_address = jump_table_base + index `* (xlen() / 8);
XReg addr;
TranslationResult result;

# TODO: Correct this check when we figure out what MISA can do
if (CSR[misa].S == 1) {
result = translate(virtual_address, MemoryOperation::Fetch, mode(), $encoding);
} else {
result.paddr = virtual_address;
}

# may raise an exception
access_check(result.paddr, xlen(), $pc, MemoryOperation::Fetch, ExceptionCode::InstructionAccessFault, mode());

if (xlen() == 32) {
addr = read_physical_memory<32>(result.paddr);
} else {
addr = read_physical_memory<64>(result.paddr);
}

# Ensure low-order bit is clear
addr = addr & $signed(2'b10);

jump(addr);

sail(): |
30 changes: 30 additions & 0 deletions spec/std/isa/isa/globals.isa
Original file line number Diff line number Diff line change
Expand Up @@ -3062,3 +3062,33 @@ function mstatus_sd_reset_value
return ((fs_value == 3) || (vs_value == 3)) ? 1 : 0;
}
}

function check_zcmt_enabled {
arguments
Bits<INSTR_ENC_SIZE> encoding
description {
If the Smstateen extension is implemented, then bit 2 in `mstateen0`, `sstateen0`, and `hstateen0` is
implemented. If bit 2 of a controlling `stateen0` CSR is zero, then access to the `jvt` CSR and execution
of a `cm.jalt` or `cm.jt` instruction by a lower privilege level results in an illegal-instruction trap (or, if
appropriate, a virtual-instruction trap).
}
body {
if (( mode() != PrivilegeMode::M && implemented?(ExtensionName::Smstateen)
&& CSR[mstateen0].JVT == 1'b0 )
||
( mode() == PrivilegeMode::U && implemented?(ExtensionName::Ssstateen)
&& CSR[sstateen0].JVT == 1'b0 )) {

raise(ExceptionCode::IllegalInstruction, mode(), encoding);
}
else
if (( mode() == PrivilegeMode::VS && implemented?(ExtensionName::Ssstateen)
&& CSR[hstateen0].JVT == 1'b0 )
||
( mode() == PrivilegeMode::VU && implemented?(ExtensionName::Ssstateen)
&& (CSR[sstateen0].JVT == 1'b0 || CSR[hstateen0].JVT == 1'b0) )) {

raise(ExceptionCode::VirtualInstruction, mode(), encoding);
}
}
}
Loading