diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2022-11-24 11:08:33 +0100 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2022-11-27 21:48:21 +0100 |
commit | 9126afa2da0e1635d78429075cc44ca576f68169 (patch) | |
tree | 0836f3da0fdfee9af24ca5dabb8244af61e5283e | |
parent | b5da3f3d64c857baf808220e202dc37c5c039eb8 (diff) | |
download | roux-9126afa2da0e1635d78429075cc44ca576f68169.tar.gz |
new hlt block terminator
It is handy to express when the end of a block cannot be reached. If a hlt terminator is executed, it traps the program. We don't go the llvm way and specify execution semantics as undefined behavior.
-rw-r--r-- | all.h | 2 | ||||
-rw-r--r-- | amd64/emit.c | 3 | ||||
-rw-r--r-- | amd64/isel.c | 4 | ||||
-rw-r--r-- | arm64/emit.c | 3 | ||||
-rw-r--r-- | arm64/isel.c | 13 | ||||
-rw-r--r-- | fold.c | 2 | ||||
-rw-r--r-- | parse.c | 11 | ||||
-rw-r--r-- | rv64/emit.c | 3 | ||||
-rw-r--r-- | tools/lexh.c | 2 |
9 files changed, 30 insertions, 13 deletions
diff --git a/all.h b/all.h index d852609..3ddb944 100644 --- a/all.h +++ b/all.h @@ -154,7 +154,7 @@ enum J { X(jfisle) X(jfislt) X(jfiuge) X(jfiugt) \ X(jfiule) X(jfiult) X(jffeq) X(jffge) \ X(jffgt) X(jffle) X(jfflt) X(jffne) \ - X(jffo) X(jffuo) + X(jffo) X(jffuo) X(hlt) #define X(j) J##j, JMPS(X) #undef X diff --git a/amd64/emit.c b/amd64/emit.c index a034a66..9e5996b 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -582,6 +582,9 @@ amd64_emitfn(Fn *fn, FILE *f) emitins(*i, fn, f); lbl = 1; switch (b->jmp.type) { + case Jhlt: + fprintf(f, "\tud2\n"); + break; case Jret0: if (fn->dynalloc) fprintf(f, diff --git a/amd64/isel.c b/amd64/isel.c index 63c304a..6d62275 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -465,7 +465,9 @@ seljmp(Blk *b, Fn *fn) Ins *fi; Tmp *t; - if (b->jmp.type == Jret0 || b->jmp.type == Jjmp) + if (b->jmp.type == Jret0 + || b->jmp.type == Jjmp + || b->jmp.type == Jhlt) return; assert(b->jmp.type == Jjnz); r = b->jmp.arg; diff --git a/arm64/emit.c b/arm64/emit.c index 38b7e1a..4a0316c 100644 --- a/arm64/emit.c +++ b/arm64/emit.c @@ -561,6 +561,9 @@ arm64_emitfn(Fn *fn, FILE *out) emitins(i, e); lbl = 1; switch (b->jmp.type) { + case Jhlt: + fprintf(e->f, "\tbrk\t#1000\n"); + break; case Jret0: s = (e->frame - e->padding) / 4; for (r=arm64_rclob; *r>=0; r++) diff --git a/arm64/isel.c b/arm64/isel.c index 9b062d8..062beb3 100644 --- a/arm64/isel.c +++ b/arm64/isel.c @@ -239,16 +239,11 @@ seljmp(Blk *b, Fn *fn) Ins *i, *ir; int ck, cc, use; - switch (b->jmp.type) { - default: - assert(0 && "TODO 2"); - break; - case Jret0: - case Jjmp: + if (b->jmp.type == Jret0 + || b->jmp.type == Jjmp + || b->jmp.type == Jhlt) return; - case Jjnz: - break; - } + assert(b->jmp.type == Jjnz); r = b->jmp.arg; use = -1; b->jmp.arg = R; diff --git a/fold.c b/fold.c index 75554bf..4b4a811 100644 --- a/fold.c +++ b/fold.c @@ -147,6 +147,8 @@ visitjmp(Blk *b, int n, Fn *fn) edge[n][0].work = flowrk; flowrk = &edge[n][0]; break; + case Jhlt: + break; default: if (isret(b->jmp.type)) break; diff --git a/parse.c b/parse.c index 04ef8be..849c81d 100644 --- a/parse.c +++ b/parse.c @@ -44,6 +44,7 @@ enum { Tjmp, Tjnz, Tret, + Thlt, Texport, Tthread, Tfunc, @@ -99,6 +100,7 @@ static char *kwmap[Ntok] = { [Tjmp] = "jmp", [Tjnz] = "jnz", [Tret] = "ret", + [Thlt] = "hlt", [Texport] = "export", [Tthread] = "thread", [Tfunc] = "function", @@ -641,7 +643,10 @@ parseline(PState ps) curb->s2 = findblk(tokval.str); } if (curb->s1 == curf->start || curb->s2 == curf->start) - err("invalid jump to the start node"); + err("invalid jump to the start block"); + goto Close; + case Thlt: + curb->jmp.type = Jhlt; Close: expect(Tnl); closeblk(); @@ -1322,6 +1327,9 @@ printfn(Fn *fn, FILE *f) fprintf(f, ", :%s", typ[fn->retty].name); fprintf(f, "\n"); break; + case Jhlt: + fprintf(f, "\thlt\n"); + break; case Jjmp: if (b->s1 != b->link) fprintf(f, "\tjmp @%s\n", b->s1->name); @@ -1332,6 +1340,7 @@ printfn(Fn *fn, FILE *f) printref(b->jmp.arg, fn, f); fprintf(f, ", "); } + assert(b->s1 && b->s2); fprintf(f, "@%s, @%s\n", b->s1->name, b->s2->name); break; } diff --git a/rv64/emit.c b/rv64/emit.c index 4ce6555..f9e58da 100644 --- a/rv64/emit.c +++ b/rv64/emit.c @@ -494,6 +494,9 @@ rv64_emitfn(Fn *fn, FILE *f) emitins(i, fn, f); lbl = 1; switch (b->jmp.type) { + case Jhlt: + fprintf(f, "\tebreak\n"); + break; case Jret0: if (fn->dynalloc) { if (frame - 16 <= 2048) diff --git a/tools/lexh.c b/tools/lexh.c index 1aea3e0..a07514e 100644 --- a/tools/lexh.c +++ b/tools/lexh.c @@ -25,7 +25,7 @@ char *tok[] = { "cgtd", "cged", "cned", "ceqd", "cod", "cuod", "vaarg", "vastart", "...", "env", - "call", "phi", "jmp", "jnz", "ret", "export", + "call", "phi", "jmp", "jnz", "ret", "hlt", "export", "function", "type", "data", "section", "align", "l", "w", "sh", "uh", "h", "sb", "ub", "b", "d", "s", "z", "loadw", "loadl", "loads", "loadd", |