Skip to content
Open
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
4 changes: 4 additions & 0 deletions backends/cpp_hart_gen/lib/gen_cpp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ def gen_cpp(symtab, indent = 2, indent_spaces: 2)
if csr_obj.nil?
if function_name == "sw_read"
"#{' ' * indent}__UDB_CSR_BY_ADDR(#{csr.idx_expr.gen_cpp(symtab, 0, indent_spaces:)}).#{function_name}(__UDB_XLEN)"
elsif function_name == "address"
"#{' ' * indent}__UDB_CSR_BY_ADDR(#{csr.idx_expr.gen_cpp(symtab, 0, indent_spaces:)}).address_bits()"
else
"#{' ' * indent}__UDB_CSR_BY_ADDR(#{csr.idx_expr.gen_cpp(symtab, 0, indent_spaces:)}).#{function_name.gsub('?', '_Q_')}(#{args_cpp.join(', ')})"
end
Expand All @@ -280,6 +282,8 @@ def gen_cpp(symtab, indent = 2, indent_spaces: 2)
else
"#{' ' * indent}__UDB_CSR_BY_NAME(#{csr_obj.name})._#{function_name}()"
end
elsif function_name == "address"
"#{' ' * indent}__UDB_CSR_BY_NAME(#{csr_obj.name})._#{function_name}()"
else
"#{' ' * indent}__UDB_CSR_BY_NAME(#{csr_obj.name}).#{function_name.gsub('?', '_Q_')}(#{args_cpp.join(', ')})"
end
Expand Down
5 changes: 4 additions & 1 deletion backends/cpp_hart_gen/templates/csrs.hxx.erb
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,12 @@ namespace udb {

CsrAddressType address_type() const override { return <%= csr.indirect? ? 'CsrAddressType::Indirect' : 'CsrAddressType::Direct' -%>; }
unsigned address() const override { <%= !csr.indirect? ? "return #{csr.address};" : "throw CsrAddressTypeError(\"#{csr.name} is not direct addressible.\")" %>; }
_Bits<12, false> address_bits() const { <%= !csr.indirect? ? "return #{csr.address}_b;" : "throw CsrAddressTypeError(\"#{csr.name} is not direct addressible.\")" %>; }
uint64_t indirect_address() const override { <%= csr.indirect? ? "return #{csr.indirect_address};" : "throw CsrAddressTypeError(\"#{csr.name} is not indirect.\")" %>; }
uint8_t indirect_slot() const override { <%= csr.indirect? ? "return #{csr.indirect_slot};" : "throw CsrAddressTypeError(\"#{csr.name} is not indirect.\")" %>; }
static constexpr unsigned _address() { return <%= csr.address %>; }
<%- if !csr.indirect? -%>
static constexpr _Bits<12, false> _address() { return <%= csr.address %>_b; }
<%- end -%>
const std::string name() const override { return "<%= csr.name %>"; }
PrivilegeMode mode() const override { return PrivilegeMode::<%= csr.priv_mode %>; }
bool writable() const override { return <%= csr.writable %>; }
Expand Down
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 @@ -6310,6 +6310,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
64 changes: 64 additions & 0 deletions spec/std/isa/inst/Zcmt/cm.jalt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# 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
Csr csr_handle = direct_csr_lookup($bits(CSR[jvt].address()));
XReg jvt = csr_sw_read(csr_handle);

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(): |
59 changes: 59 additions & 0 deletions spec/std/isa/inst/Zcmt/cm.jt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# 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
Csr csr_handle = direct_csr_lookup(CSR[jvt].address());
XReg jvt = csr_sw_read(csr_handle);

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(): |
7 changes: 5 additions & 2 deletions tools/ruby-gems/idlc/lib/idlc/ast.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2463,7 +2463,7 @@ def type(symtab)
if symtab.mxlen == 64 && symtab.multi_xlen?
Type.new(:bits, width: [field(symtab).location(32).size, field(symtab).location(64).size].max)
else
Type.new(:bits, width: field(symtab).location(symtab.mxlen).size)
Type.new(:bits, width: field(symtab).location(symtab.mxlen.nil? ? 64 : symtab.mxlen).size)
end
elsif field(symtab).base64_only?
Type.new(:bits, width: field(symtab).location(64).size)
Expand Down Expand Up @@ -7445,8 +7445,11 @@ def initialize(input, interval, function_name, csr, args)
def type_check(symtab)
csr.type_check(symtab)

if ["sw_read", "address"].include?(function_name)
if function_name == "sw_read"
type_error "unexpected argument(s)" unless args.empty?
elsif function_name == "address"
type_error "unexpected argument(s)" unless args.empty?
type_error "csr is accessed indirectly, and has no address" if csr_def(symtab)&.indirect?
elsif ["implemented_without?"].include?(function_name)
type_error "Expecting one argument" unless args.size == 1
type_error "Expecting an ExtensionName" unless args[0].type(symtab).kind == :enum_ref && args[0].class_name == "ExtensionName"
Expand Down
6 changes: 2 additions & 4 deletions tools/ruby-gems/idlc/lib/idlc/idl.treetop
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,9 @@ grammar Idl
rule bits_cast
'$bits' space* '(' space*
expr:(
csr_register_access_expression
/
enum_ref
/
expression
/
csr_register_access_expression
)
space* ')' <Idl::BitsCastSyntaxNode>
end
Expand Down