Skip to content

Commit e79120c

Browse files
committed
iss: Generate pattern-based CPU register access functions
1 parent 965f334 commit e79120c

File tree

13 files changed

+384
-27
lines changed

13 files changed

+384
-27
lines changed

vadl/main/resources/templates/iss/target/gen-arch/cpu.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ const char * const [(${gen_arch_lower})]_cpu_[(${reg.name_lower})]_names[(${reg.
1919
};
2020
[/][/]
2121

22+
[# th:each="reg : ${register_tensors}"]
23+
[# th:each="access : ${reg.access_patterns}"]
24+
[(${access.signature})]
25+
{
26+
[(${access.body})] }
27+
[/][/]
28+
2229
[# th:each="reg : ${register_tensors}"]
2330
[(${reg.cpu_getter_signature})]
2431
{ [# th:each="dim : ${reg.index_dims}"]

vadl/main/resources/templates/iss/target/gen-arch/cpu.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ int [(${gen_arch_lower})]_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, in
7979

8080
// CPU register getters and setters
8181
[# th:each="reg : ${register_tensors}"]
82-
[(${reg.cpu_getter_signature})];
83-
[(${reg.cpu_setter_signature})];
84-
[/]
82+
[# th:each="access : ${reg.access_patterns}"]
83+
[(${access.signature})];
84+
[/][/]
8585

8686

8787
#include "exec/cpu-all.h"

vadl/main/vadl/ast/AnnotationTable.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText : © 2025 TU Wien <vadl@tuwien.ac.at>
1+
// SPDX-FileCopyrightText : © 2025-2026 TU Wien <vadl@tuwien.ac.at>
22
// SPDX-License-Identifier: GPL-3.0-or-later
33
//
44
// This program is free software: you can redistribute it and/or modify
@@ -1222,7 +1222,7 @@ public String usageString() {
12221222
}
12231223

12241224
public void verifyExprType(Type type) {
1225-
ensure(expr.type() == type, () -> error("Invalid annotation expression", expr)
1225+
Diagnostic.ensure(expr.type() == type, () -> error("Invalid annotation expression", expr)
12261226
.locationDescription(expr, "Expression must be a %s", type));
12271227
}
12281228
}
@@ -1330,11 +1330,11 @@ void resolveName(AnnotationDefinition definition, SymbolTable.SymbolResolver res
13301330
@Override
13311331
void typeCheck(AnnotationDefinition definition, TypeChecker typeChecker) {
13321332
for (var v : definition.values) {
1333-
ensure(v instanceof Identifier, () -> error("Invalid annotation value", v)
1333+
Diagnostic.ensure(v instanceof Identifier, () -> error("Invalid annotation value", v)
13341334
.description("A single identifier was expected.")
13351335
);
13361336
var target = ((Identifier) v).target();
1337-
ensure(target instanceof Definition, () -> error("Invalid annotation value", v)
1337+
Diagnostic.ensure(target instanceof Definition, () -> error("Invalid annotation value", v)
13381338
.description("The identifier must reference a definition."));
13391339
def.add((Definition) target);
13401340
}
@@ -1351,7 +1351,7 @@ public String usageString() {
13511351
* @return the casted definition.
13521352
*/
13531353
public <T extends Definition> T verifyDefinitionType(Class<T> defClass) {
1354-
ensure(defClass.isInstance(def), () -> error("Invalid annotation value", firstVal())
1354+
Diagnostic.ensure(defClass.isInstance(def), () -> error("Invalid annotation value", firstVal())
13551355
.locationDescription(firstVal(), "The identifier must reference a %s, but was %s",
13561356
defClass.getSimpleName(),
13571357
def));

vadl/main/vadl/iss/codegen/IssCMixins.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static vadl.iss.IssUtils.internalError;
2020

2121
import vadl.cppCodeGen.context.CGenContext;
22+
import vadl.iss.passes.extensions.RegInfo;
2223
import vadl.iss.passes.nodes.IssConstExtractNode;
2324
import vadl.iss.passes.nodes.IssGhostCastNode;
2425
import vadl.iss.passes.nodes.IssMoveNode;
@@ -206,7 +207,8 @@ interface CpuSourceWriteRegTensor {
206207
default void handle(CGenContext<Node> ctx,
207208
WriteRegTensorNode node) {
208209
var reg = node.regTensor();
209-
ctx.wr("set_cpu_" + reg.simpleName().toLowerCase() + "(env");
210+
var accessPattern = RegInfo.AccessPattern.of(node);
211+
ctx.wr(accessPattern.name() + "(env");
210212
for (var i : node.indices()) {
211213
ctx.wr(", ").gen(i);
212214
}
@@ -217,8 +219,8 @@ default void handle(CGenContext<Node> ctx,
217219
@SuppressWarnings("MissingJavadocMethod")
218220
default void handle(CGenContext<Node> ctx,
219221
ReadRegTensorNode node) {
220-
var reg = node.regTensor();
221-
ctx.wr("get_cpu_" + reg.simpleName().toLowerCase() + "(env");
222+
var accessPattern = RegInfo.AccessPattern.of(node);
223+
ctx.wr(accessPattern.name() + "(env");
222224
for (var i : node.indices()) {
223225
ctx.wr(", ").gen(i);
224226
}

vadl/main/vadl/iss/codegen/IssProcGen.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,9 @@ void initReadRegs(Graph graph) {
8888
void initSingleReadReg(ReadRegTensorNode read) {
8989
var info = read.regTensor().expectExtension(RegInfo.class);
9090
var name = readRegVariable(read);
91+
var accessPattern = RegInfo.AccessPattern.of(read);
9192
ctx.wr(info.valueCType() + " " + name + " = ")
92-
.wr("get_cpu_" + info.name().toLowerCase() + "(env");
93+
.wr(accessPattern.name() + "(env");
9394
for (var i : read.indices()) {
9495
ctx.wr(", ").gen(i);
9596
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// SPDX-FileCopyrightText : © 2026 TU Wien <vadl@tuwien.ac.at>
2+
// SPDX-License-Identifier: GPL-3.0-or-later
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
package vadl.iss.passes;
18+
19+
import static java.util.Objects.requireNonNull;
20+
import static vadl.iss.passes.TcgPassUtils.regInfo;
21+
22+
import java.io.IOException;
23+
import java.util.List;
24+
import java.util.Set;
25+
import javax.annotation.CheckForNull;
26+
import vadl.configuration.IssConfiguration;
27+
import vadl.iss.passes.extensions.RegInfo;
28+
import vadl.pass.PassName;
29+
import vadl.pass.PassResults;
30+
import vadl.utils.ViamUtils;
31+
import vadl.viam.Specification;
32+
import vadl.viam.graph.Graph;
33+
import vadl.viam.graph.dependency.ReadRegTensorNode;
34+
import vadl.viam.graph.dependency.WriteRegTensorNode;
35+
36+
public class IssRegisterAccessInfoRetrievalPass extends AbstractIssPass {
37+
public IssRegisterAccessInfoRetrievalPass(IssConfiguration config) {
38+
super(config);
39+
}
40+
41+
@Override
42+
public PassName getName() {
43+
return PassName.of("ISS Register Access Info Retrieval");
44+
}
45+
46+
@CheckForNull
47+
@Override
48+
public Object execute(PassResults passResults, Specification viam) throws IOException {
49+
ViamUtils.findAllBehaviors(viam).forEach(this::collectRegisterAccessPatterns);
50+
51+
// add custom one for program counter
52+
var pc = requireNonNull(viam.isa().get().pc());
53+
var info = regInfo(pc.registerTensor());
54+
info.accessPatterns.add(new RegInfo.AccessPattern(
55+
info, RegInfo.AccessType.READ, List.of(), pc.resultType().bitWidth(), pc
56+
));
57+
info.accessPatterns.add(new RegInfo.AccessPattern(
58+
info, RegInfo.AccessType.WRITE, List.of(), pc.resultType().bitWidth(), pc
59+
));
60+
61+
return null;
62+
}
63+
64+
private void collectRegisterAccessPatterns(Graph behavior) {
65+
behavior.getNodes(Set.of(ReadRegTensorNode.class, WriteRegTensorNode.class))
66+
.forEach((n) -> {
67+
if (n instanceof ReadRegTensorNode readRegTensorNode) {
68+
collectRegisterAccessPattern(readRegTensorNode);
69+
} else {
70+
collectRegisterAccessPattern((WriteRegTensorNode) n);
71+
}
72+
});
73+
}
74+
75+
private void collectRegisterAccessPattern(ReadRegTensorNode node) {
76+
var info = regInfo(node.regTensor());
77+
info.accessPatterns.add(RegInfo.AccessPattern.of(node));
78+
}
79+
80+
private void collectRegisterAccessPattern(WriteRegTensorNode node) {
81+
var info = regInfo(node.regTensor());
82+
info.accessPatterns.add(RegInfo.AccessPattern.of(node));
83+
}
84+
}

0 commit comments

Comments
 (0)