|
24 | 24 | import static vadl.utils.GraphUtils.neq; |
25 | 25 | import static vadl.utils.GraphUtils.or; |
26 | 26 | import static vadl.utils.GraphUtils.select; |
27 | | -import static vadl.utils.GraphUtils.truncate; |
| 27 | +import static vadl.utils.GraphUtils.signExtend; |
28 | 28 | import static vadl.utils.GraphUtils.zeroExtend; |
29 | 29 |
|
30 | 30 | import com.google.common.collect.Lists; |
|
37 | 37 | import java.util.stream.Collectors; |
38 | 38 | import javax.annotation.Nullable; |
39 | 39 | import vadl.types.BitsType; |
| 40 | +import vadl.types.BoolType; |
40 | 41 | import vadl.types.BuiltInTable; |
41 | 42 | import vadl.types.ConcreteRelationType; |
42 | 43 | import vadl.types.DataType; |
@@ -312,8 +313,9 @@ Function getRegisterAliasReadFunc(AliasDefinition definition) { |
312 | 313 | ); |
313 | 314 | } |
314 | 315 |
|
315 | | - if (definition.slice != null) { |
316 | | - regAccess = truncate(regAccess, Type.bits(definition.slice.bitSize())); |
| 316 | + var slice = definition.slice; |
| 317 | + if (slice != null) { |
| 318 | + regAccess = new SliceNode(regAccess, slice, Type.bits(slice.bitSize())); |
317 | 319 | } |
318 | 320 |
|
319 | 321 | var returnNode = graph.addWithInputs(new ReturnNode(regAccess)); |
@@ -375,11 +377,28 @@ Procedure getRegisterAliasWriteProc(AliasDefinition definition) { |
375 | 377 |
|
376 | 378 | var regFile = (RegisterTensor) viamLowering.fetch(regFileDef).orElseThrow(); |
377 | 379 |
|
378 | | - if (definition.slice != null) { |
379 | | - ensure(definition.slice.lsb() == 0, |
| 380 | + var slice = definition.slice; |
| 381 | + if (slice != null) { |
| 382 | + ensure(slice.lsb() == 0, |
380 | 383 | () -> error("Unsupported alias slice", definition) |
381 | 384 | .description("Currently, the alias slice MSB must be 0.")); |
382 | | - writeValue = zeroExtend(writeValue, regFile.resultType(indices.size())); |
| 385 | + |
| 386 | + var sourceRegType = regFile.resultType(indices.size()); |
| 387 | + var overwriteAnno = definition.findAnnotation("overwrite source", EnumAnnotation.class); |
| 388 | + var overwriteMode = overwriteAnno == null ? null : overwriteAnno.value; |
| 389 | + |
| 390 | + // If we have a slice, we must adjust the write values accordingly. |
| 391 | + // By default, we prepare the write values to be sliced by reading the original content. |
| 392 | + // If the [overwrite source:] annotation is set, we instead either zero or sign extend the |
| 393 | + // write value to overwrite the whole source register. |
| 394 | + writeValue = switch (overwriteMode) { |
| 395 | + case null -> sliceWriteValue(writeValue, |
| 396 | + new ReadRegTensorNode(regFile, indices, sourceRegType, null), List.of(slice)); |
| 397 | + case "zero" -> zeroExtend(writeValue, sourceRegType); |
| 398 | + case "sign" -> signExtend(writeValue, sourceRegType); |
| 399 | + default -> throw new IllegalStateException( |
| 400 | + "Unexpected value: " + overwriteMode); |
| 401 | + }; |
383 | 402 | } |
384 | 403 |
|
385 | 404 | // FIXME: Support pre-indexed registers, for example: |
@@ -684,7 +703,8 @@ public ExpressionNode visit(GroupedExpr expr) { |
684 | 703 | @Override |
685 | 704 | public ExpressionNode visit(IntegerLiteral expr) { |
686 | 705 | // IntegerLiteral should never be reached as it should always be substituted by the typechecker. |
687 | | - throw new IllegalStateException("IntegerLiteral should never be reached in the VIAM lowering."); |
| 706 | + throw new IllegalStateException( |
| 707 | + "IntegerLiteral should never be reached in the VIAM lowering."); |
688 | 708 | } |
689 | 709 |
|
690 | 710 | @Override |
@@ -771,7 +791,8 @@ private ExpressionNode visitSubCall(CallIndexExpr expr, ExpressionNode exprBefor |
771 | 791 | (DataType) getViamType(Objects.requireNonNull(subCall.formatFieldType))); |
772 | 792 | resultExpr = visitSliceIndexCall(slice, subCall.argsIndices); |
773 | 793 | } else if (subCall.computedStatusIndex != null) { |
774 | | - var indexing = new TupleGetFieldNode(subCall.computedStatusIndex, resultExpr, Type.bool()); |
| 794 | + var indexing = |
| 795 | + new TupleGetFieldNode(subCall.computedStatusIndex, resultExpr, Type.bool()); |
775 | 796 | resultExpr = visitSliceIndexCall(indexing, subCall.argsIndices); |
776 | 797 | } else if (exprBeforeSubcall instanceof ReadResourceNode resRead) { |
777 | 798 | var computedTarget = expr.target.path().target(); |
@@ -923,7 +944,7 @@ public ExpressionNode visit(CastExpr expr) { |
923 | 944 | var sourceDataType = (DataType) sourceType; |
924 | 945 | var targetDataType = (DataType) targetType; |
925 | 946 |
|
926 | | - if (targetType.getClass() == vadl.types.BoolType.class) { |
| 947 | + if (targetType.getClass() == BoolType.class) { |
927 | 948 | // match 2. rule: target type is bool |
928 | 949 | // -> produce != 0 call |
929 | 950 | //return new BuiltInCall |
@@ -1136,7 +1157,7 @@ yield new WriteMemNode( |
1136 | 1157 | * Method that prepares the value so it can be written to a subset region of a resource. |
1137 | 1158 | * The entire resource before writing the value is given by the entireRead node. |
1138 | 1159 | * The subset region of the resource is given by the slices list, that |
1139 | | - * holds a list of {@link vadl.viam.Constant.BitSlice}. |
| 1160 | + * holds a list of {@link Constant.BitSlice}. |
1140 | 1161 | * E.g. {@code A(3, 15..11) := 0b101111} writes the value's msb `1` at position 3 in the |
1141 | 1162 | * resource, |
1142 | 1163 | * and the rest (0b01111) is written to position 15 to 11 (inclusive) in the resource. |
@@ -1266,7 +1287,8 @@ public SubgraphContext visit(InstructionCallStatement statement) { |
1266 | 1287 | } |
1267 | 1288 |
|
1268 | 1289 | var target = |
1269 | | - (Instruction) viamLowering.fetch(Objects.requireNonNull(statement.instrDef)).orElseThrow(); |
| 1290 | + (Instruction) viamLowering.fetch(Objects.requireNonNull(statement.instrDef)) |
| 1291 | + .orElseThrow(); |
1270 | 1292 | var fieldMap = Arrays.stream(target.encoding().nonEncodedFormatFields()) |
1271 | 1293 | .collect(Collectors.toMap(Definition::simpleName, f -> f)); |
1272 | 1294 |
|
@@ -1492,7 +1514,8 @@ static SubgraphContext of(Node root, List<vadl.viam.graph.Node> nodes) { |
1492 | 1514 |
|
1493 | 1515 | SubgraphContext setSideEffects(NodeList<SideEffectNode> sideEffects) { |
1494 | 1516 | if (this.sideEffects != null) { |
1495 | | - throw new IllegalStateException("SideEffects already set to: %s".formatted(this.sideEffects)); |
| 1517 | + throw new IllegalStateException( |
| 1518 | + "SideEffects already set to: %s".formatted(this.sideEffects)); |
1496 | 1519 | } |
1497 | 1520 | this.sideEffects = sideEffects; |
1498 | 1521 | return this; |
|
0 commit comments