aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--io.c1
-rw-r--r--ir.c2
-rw-r--r--main.c4
-rw-r--r--op.def2
-rw-r--r--parse.c9
-rw-r--r--test.c5
6 files changed, 16 insertions, 7 deletions
diff --git a/io.c b/io.c
index 760dea3..d51e28d 100644
--- a/io.c
+++ b/io.c
@@ -171,6 +171,7 @@ pritypebefore(struct wbuf *buf, union type ty, int qual)
int n;
switch (ty.t) {
case TYVOID: s = "void"; Prim: n = bfmt(buf, "%s", s); return n + priquals(buf, qual);
+ case TYBOOL: s = "bool"; goto Prim;
case TYCHAR: s = "char"; goto Prim;
case TYSCHAR: s = "signed char"; goto Prim;
case TYUCHAR: s = "unsigned char"; goto Prim;
diff --git a/ir.c b/ir.c
index 9812f21..d0866ef 100644
--- a/ir.c
+++ b/ir.c
@@ -18,7 +18,7 @@ irinit(struct function *fn)
ninstr = 0;
vinit(&calls, callsbuf, arraylength(callsbuf));
if (!type2cls[TYINT]) {
- for (int i = TYCHAR; i <= TYUVLONG; ++i) {
+ for (int i = TYBOOL; i <= TYUVLONG; ++i) {
int siz = targ_primsizes[i];
type2cls[i] = siz < 8 ? KI4 : KI8;
}
diff --git a/main.c b/main.c
index edea3de..8f72dd9 100644
--- a/main.c
+++ b/main.c
@@ -49,11 +49,11 @@ main(int argc, char **argv)
const char *file, *targ;
atexit(flushstd);
- if (argc < 2) {
+ optparse(&file, &targ, argv);
+ if (!file) {
efmt("usage: %s [options] <file>\n", *argv);
return 1;
}
- optparse(&file, &targ, argv);
targ_init(targ ? targ : "amd64-sysv");
initparser(&pr, file);
diff --git a/op.def b/op.def
index 99df839..915d832 100644
--- a/op.def
+++ b/op.def
@@ -1,5 +1,5 @@
/* OP NARG */
-_(mov, 1)
+_(copy, 1)
_(neg, 1)
_(not, 1)
_(cvtf4s, 1)
diff --git a/parse.c b/parse.c
index d2ba738..4a59c32 100644
--- a/parse.c
+++ b/parse.c
@@ -918,7 +918,7 @@ cvt(struct function *fn, enum typetag to, enum typetag from, union irref ref)
{
enum irclass kto = type2cls[to], kfrom = type2cls[from];
struct instr ins = {0};
- if (kto == kfrom) return ref;
+ if (kto == kfrom && to != TYBOOL) return ref;
if (ref.t == RICON && kto < KF4) return ref;
ins.cls = kto;
@@ -927,6 +927,7 @@ cvt(struct function *fn, enum typetag to, enum typetag from, union irref ref)
if (kto == KPTR) kto = siz2intcls[cls2siz[kto]];
if (kfrom == KPTR) kfrom = siz2intcls[cls2siz[kfrom]];
if (kisflt(kto) && kfrom == KI4) ins.op = issignedt(from) ? Ocvts4f : Ocvtu4f;
+ else if (to == TYBOOL && kisflt(kfrom)) ins.op = Oneq, ins.r = mkfltcon(fn, kfrom, 0.0);
else if (kisflt(kto) && kfrom == KI8) ins.op = issignedt(from) ? Ocvts8f : Ocvtu8f;
else if (kto == KF8 && kfrom == KF4) ins.op = Ocvtf4f8;
else if (kto == KF4 && kfrom == KF8) ins.op = Ocvtf8f4;
@@ -934,9 +935,10 @@ cvt(struct function *fn, enum typetag to, enum typetag from, union irref ref)
else if (kfrom == KF8) ins.op = issignedt(to) ? Ocvtf8s : Ocvtf8u;
else assert(0);
} else {
- if (kfrom == KI4 && issignedt(from)) ins.op = Oexts4;
+ if (to == TYBOOL) ins.op = Oneq, ins.r = mkref(RICON, 0);
+ else if (kfrom == KI4 && issignedt(from)) ins.op = Oexts4;
else if (kfrom == KI4) ins.op = Oextu4;
- else ins.op = Omov;
+ else ins.op = Ocopy;
}
return addinstr(fn, ins);
}
@@ -1621,6 +1623,7 @@ declspec(struct declstate *st, struct parser *pr)
case TKWbool:
if (arith & KBOOL) goto Dup;
arith |= KBOOL;
+ break;
case TKWchar:
if (arith & KCHAR) {
Dup:
diff --git a/test.c b/test.c
index 2f2a39a..9832d1d 100644
--- a/test.c
+++ b/test.c
@@ -34,6 +34,11 @@ int diff(struct f *x, struct f *y)
return x - y;
}
+_Bool narrow(int x)
+{
+ return (float) x;
+}
+
#define xx 2
int waaa[xx == 0 ? 'Z'