|
4 | 4 | import com.dat3m.dartagnan.exception.ParsingException;
|
5 | 5 | import com.dat3m.dartagnan.expression.Expression;
|
6 | 6 | import com.dat3m.dartagnan.expression.ExpressionFactory;
|
| 7 | +import com.dat3m.dartagnan.expression.ExpressionVisitor; |
7 | 8 | import com.dat3m.dartagnan.expression.integers.IntLiteral;
|
| 9 | +import com.dat3m.dartagnan.expression.processing.ExprTransformer; |
8 | 10 | import com.dat3m.dartagnan.expression.type.IntegerType;
|
9 | 11 | import com.dat3m.dartagnan.expression.type.TypeFactory;
|
10 | 12 | import com.dat3m.dartagnan.parsers.LitmusAArch64BaseVisitor;
|
|
13 | 15 | import com.dat3m.dartagnan.program.Program;
|
14 | 16 | import com.dat3m.dartagnan.program.Register;
|
15 | 17 | import com.dat3m.dartagnan.program.event.EventFactory;
|
| 18 | +import com.dat3m.dartagnan.program.event.RegReader; |
16 | 19 | import com.dat3m.dartagnan.program.event.arch.StoreExclusive;
|
17 | 20 | import com.dat3m.dartagnan.program.event.core.Label;
|
18 | 21 | import com.dat3m.dartagnan.program.event.core.Load;
|
19 | 22 |
|
| 23 | +import java.math.BigInteger; |
20 | 24 | import java.util.HashMap;
|
21 | 25 | import java.util.Map;
|
22 | 26 |
|
@@ -53,9 +57,32 @@ public Object visitMain(LitmusAArch64Parser.MainContext ctx) {
|
53 | 57 | visitVariableDeclaratorList(ctx.variableDeclaratorList());
|
54 | 58 | visitInstructionList(ctx.program().instructionList());
|
55 | 59 | VisitorLitmusAssertions.parseAssertions(programBuilder, ctx.assertionList(), ctx.assertionFilter());
|
56 |
| - return programBuilder.build(); |
| 60 | + Program prog = programBuilder.build(); |
| 61 | + replaceXZRRegister(prog); |
| 62 | + |
| 63 | + return prog; |
| 64 | + |
57 | 65 | }
|
58 | 66 |
|
| 67 | + /* |
| 68 | + The "xzr" register plays a special role in AArhc64: |
| 69 | + 1. Reading accesses always return the value 0. |
| 70 | + 2. Discards data when written. |
| 71 | + TODO: The below code is a simple fix to guarantee point 1. above. |
| 72 | + Point 2. might also be resolved: although we do not prevent writing to xzr, |
| 73 | + the value of xzr is never read after the transformation so its value is effectively 0. |
| 74 | + However, the exists/forall clauses could still refer to that register and observe a non-zero value. |
| 75 | + */ |
| 76 | + private void replaceXZRRegister(Program program) { |
| 77 | + final ExpressionVisitor<Expression> xzrReplacer = new ExprTransformer() { |
| 78 | + @Override |
| 79 | + public Expression visitRegister(Register reg) { |
| 80 | + return reg.getName().equals("xzr") ? expressions.makeGeneralZero(reg.getType()) : reg; |
| 81 | + } |
| 82 | + }; |
| 83 | + program.getThreadEvents(RegReader.class) |
| 84 | + .forEach(e -> e.transformExpressions(xzrReplacer)); |
| 85 | + } |
59 | 86 |
|
60 | 87 | // ----------------------------------------------------------------------------------------------------------------
|
61 | 88 | // Variable declarator list, e.g., { 0:EAX=0; 1:EAX=1; x=2; }
|
@@ -211,6 +238,12 @@ public Object visitFence(LitmusAArch64Parser.FenceContext ctx) {
|
211 | 238 | return programBuilder.addChild(mainThread, EventFactory.newFenceOpt(ctx.Fence().getText(), ctx.opt));
|
212 | 239 | }
|
213 | 240 |
|
| 241 | + @Override |
| 242 | + public Object visitReturn(LitmusAArch64Parser.ReturnContext ctx) { |
| 243 | + Label end = programBuilder.getEndOfThreadLabel(mainThread); |
| 244 | + return programBuilder.addChild(mainThread, EventFactory.newGoto(end)); |
| 245 | + } |
| 246 | + |
214 | 247 | @Override
|
215 | 248 | public Expression visitExpressionRegister64(LitmusAArch64Parser.ExpressionRegister64Context ctx) {
|
216 | 249 | Expression expr = programBuilder.getOrNewRegister(mainThread, ctx.register64().id, archType);
|
@@ -255,4 +288,12 @@ private Register visitOffset(LitmusAArch64Parser.OffsetContext ctx, Register reg
|
255 | 288 | programBuilder.addChild(mainThread, EventFactory.newLocal(result, expressions.makeAdd(register, expr)));
|
256 | 289 | return result;
|
257 | 290 | }
|
| 291 | + |
| 292 | + @Override |
| 293 | + public Expression visitImmediate(LitmusAArch64Parser.ImmediateContext ctx) { |
| 294 | + final int radix = ctx.Hexa() != null ? 16 : 10; |
| 295 | + BigInteger value = new BigInteger(ctx.constant().getText(), radix); |
| 296 | + return expressions.makeValue(value, archType); |
| 297 | + } |
| 298 | + |
258 | 299 | }
|
0 commit comments