~ach/testlist

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch

[PATCH] Simplify common funcinst case.

Details
Message ID
<20190228112927.68601-1-ac@acha.ninja>
Sender timestamp
1551353367
DKIM signature
missing
Download raw message
Patch: +53 -50
---
 backend.h    |  1 +
 config.def.h |  8 ++---
 qbe.c        | 94 +++++++++++++++++++++++++++-------------------------
 3 files changed, 53 insertions(+), 50 deletions(-)

diff --git a/backend.h b/backend.h
index c4b1eaf..46d27cb 100644
--- a/backend.h
@@ -47,3 +47,4 @@ void emitfunc(struct function *, _Bool);
void emitdata(struct declaration *,  struct initializer *);

extern struct representation i8, i16, i32, i64, f32, f64;
foobar
diff --git a/config.def.h b/config.def.h
index 80a2193..bb8f9f7 100644
--- a/config.def.h
+++ b/config.def.h
@@ -12,10 +12,10 @@ static char *endfiles[] = {
};

static char *preprocesscmd[] = {
		"cpp", "-P",
		"x86_64-unknown-linux-musl-cc", "-P",

		/* specify the GNU C extensions we support */
		"-U", "__GNUC__", "-D", "__GNUC__=4",
		// "-U", "__GNUC__", "-D", "__GNUC__=4",

		/* prevent glibc from using statement expressions for assert */
		"-D", "__STRICT_ANSI__",
@@ -34,5 +34,5 @@ static char *preprocesscmd[] = {
};
static char *compilecmd[] = {"cc-qbe"};
static char *codegencmd[] = {"qbe"};
static char *assemblecmd[] = {"as"};
static char *linkcmd[] = {"ld", "--dynamic-linker=" DYNAMICLINKER};
static char *assemblecmd[] = {"x86_64-unknown-linux-musl-as"};
static char *linkcmd[] = {"x86_64-unknown-linux-musl-ld"};
diff --git a/qbe.c b/qbe.c
index 25db122..fd1f851 100644
--- a/qbe.c
+++ b/qbe.c
@@ -139,7 +139,7 @@ static struct {
};

static struct value *
funcinst(struct function *f, int op, struct representation *repr, struct value *args[])
funcinstn(struct function *f, int op, struct representation *repr, struct value *args[])
{
	struct instruction *inst;
	size_t n;
@@ -168,6 +168,8 @@ funcinst(struct function *f, int op, struct representation *repr, struct value *
	return instdesc[op].ret ? &inst->res : NULL;
}

#define funcinst(f, op, repr, ...) funcinstn(f, op, repr, (struct value *[]){__VA_ARGS__})

struct value *
mkintconst(struct representation *r, uint64_t n)
{
@@ -274,17 +276,17 @@ funcstore(struct function *f, struct type *t, struct value *addr, struct value *
		dst = addr;
		align = mkintconst(&iptr, t->align);
		for (offset = 0; offset < t->size; offset += t->align) {
			tmp = funcinst(f, loadop, &iptr, (struct value *[]){src});
			funcinst(f, op, NULL, (struct value *[]){tmp, dst});
			src = funcinst(f, IADD, &iptr, (struct value *[]){src, align});
			dst = funcinst(f, IADD, &iptr, (struct value *[]){dst, align});
			tmp = funcinst(f, loadop, &iptr, src);
			funcinst(f, op, NULL, tmp, dst);
			src = funcinst(f, IADD, &iptr, src, align);
			dst = funcinst(f, IADD, &iptr, dst, align);
		}
		return;
	}
	default:
		fatal("unimplemented store");
	}
	funcinst(f, op, NULL, (struct value *[]){v, addr});
	funcinst(f, op, NULL, v, addr);
}

static struct value *
@@ -319,7 +321,7 @@ funcload(struct function *f, struct type *t, struct value *addr)
	default:
		fatal("unimplemented load %d", t->kind);
	}
	return funcinst(f, op, t->repr, (struct value *[]){addr});
	return funcinst(f, op, t->repr, addr);
}

struct value *
@@ -406,14 +408,14 @@ funclabel(struct function *f, struct value *v)
void
funcjmp(struct function *f, struct value *v)
{
	funcinst(f, IJMP, NULL, (struct value *[]){v});
	funcinst(f, IJMP, NULL, v);
	f->end->terminated = true;
}

void
funcjnz(struct function *f, struct value *v, struct value *l1, struct value *l2)
{
	funcinst(f, IJNZ, NULL, (struct value *[]){v, l1, l2});
	funcinstn(f, IJNZ, NULL, (struct value *[]){v, l1, l2});
	f->end->terminated = true;
}

@@ -427,7 +429,7 @@ funcret(struct function *f, struct value *v)
		funcinit(f, d, NULL);
		v = funcload(f, d->type, d->value);
	}
	funcinst(f, IRET, NULL, (struct value *[]){v});
	funcinst(f, IRET, NULL, v);
	f->end->terminated = true;
}

@@ -481,7 +483,7 @@ objectaddr(struct function *f, struct expression *e)
	default:
		if (e->type->kind != TYPESTRUCT && e->type->kind != TYPEUNION)
			break;
		return funcinst(f, ICOPY, &iptr, (struct value *[]){funcexpr(f, e)});
		return funcinst(f, ICOPY, &iptr, funcexpr(f, e));
	}
	error(&tok.loc, "expression is not an object");
}
@@ -493,30 +495,30 @@ utof(struct function *f, struct representation *r, struct value *v)
	struct value *odd, *big, *phi[5] = {0}, *join;

	if (v->repr->base == 'w') {
		v = funcinst(f, IEXTUW, &i64, (struct value *[]){v});
		return funcinst(f, ISLTOF, r, (struct value *[]){v});
		v = funcinst(f, IEXTUW, &i64, v);
		return funcinst(f, ISLTOF, r, v);
	}

	phi[0] = mkblock("utof_small");
	phi[2] = mkblock("utof_big");
	join = mkblock("utof_join");

	big = funcinst(f, ICSLTL, &i32, (struct value *[]){v, mkintconst(&i64, 0)});
	big = funcinst(f, ICSLTL, &i32, v, mkintconst(&i64, 0));
	funcjnz(f, big, phi[2], phi[0]);

	funclabel(f, phi[0]);
	phi[1] = funcinst(f, ISLTOF, r, (struct value *[]){v});
	phi[1] = funcinst(f, ISLTOF, r, v);
	funcjmp(f, join);

	funclabel(f, phi[2]);
	odd = funcinst(f, IAND, &i64, (struct value *[]){v, mkintconst(&i64, 1)});
	v = funcinst(f, ISHR, &i64, (struct value *[]){v, mkintconst(&i64, 1)});
	v = funcinst(f, IOR, &i64, (struct value *[]){v, odd});  /* round to odd */
	v = funcinst(f, ISLTOF, r, (struct value *[]){v});
	phi[3] = funcinst(f, IADD, r, (struct value *[]){v, v});
	odd = funcinst(f, IAND, &i64, v, mkintconst(&i64, 1));
	v = funcinst(f, ISHR, &i64, v, mkintconst(&i64, 1));
	v = funcinst(f, IOR, &i64, v, odd);  /* round to odd */
	v = funcinst(f, ISLTOF, r, v);
	phi[3] = funcinst(f, IADD, r, v, v);

	funclabel(f, join);
	return funcinst(f, IPHI, r, phi);
	return funcinstn(f, IPHI, r, phi);
}

static struct value *
@@ -526,8 +528,8 @@ ftou(struct function *f, struct representation *r, struct value *v)
	enum instructionkind op = v->repr->base == 's' ? ISTOSI : IDTOSI;

	if (r->base == 'w') {
		v = funcinst(f, op, &i64, (struct value *[]){v});
		return funcinst(f, ICOPY, r, (struct value *[]){v});
		v = funcinst(f, op, &i64, v);
		return funcinst(f, ICOPY, r, v);
	}

	phi[0] = mkblock("ftou_small");
@@ -537,20 +539,20 @@ ftou(struct function *f, struct representation *r, struct value *v)
	maxflt = mkfltconst(v->repr, 0x1p63);
	maxint = mkintconst(&i64, 1ull<<63);

	big = funcinst(f, v->repr->base == 's' ? ICGES : ICGED, &i32, (struct value *[]){v, maxflt});
	big = funcinst(f, v->repr->base == 's' ? ICGES : ICGED, &i32, v, maxflt);
	funcjnz(f, big, phi[2], phi[0]);

	funclabel(f, phi[0]);
	phi[1] = funcinst(f, op, r, (struct value *[]){v});
	phi[1] = funcinst(f, op, r, v);
	funcjmp(f, join);

	funclabel(f, phi[2]);
	v = funcinst(f, ISUB, v->repr, (struct value *[]){v, maxflt});
	v = funcinst(f, op, r, (struct value *[]){v});
	phi[3] = funcinst(f, IXOR, r, (struct value *[]){v, maxint});
	v = funcinst(f, ISUB, v->repr, v, maxflt);
	v = funcinst(f, op, r, v);
	phi[3] = funcinst(f, IXOR, r, v, maxint);

	funclabel(f, join);
	return funcinst(f, IPHI, r, phi);
	return funcinstn(f, IPHI, r, phi);
}

static struct value *
@@ -563,7 +565,7 @@ extend(struct function *f, struct type *t, struct value *v)
	case 2: op = t->basic.issigned ? IEXTSH : IEXTUH; break;
	default: return v;
	}
	return funcinst(f, op, &i32, (struct value *[]){v});
	return funcinst(f, op, &i32, v);
}

struct value *
@@ -605,7 +607,7 @@ funcexpr(struct function *f, struct expression *e)
			r = mkfltconst(e->type->repr, 1);
		else
			fatal("not a scalar");
		v = funcinst(f, e->incdec.op == TINC ? IADD : ISUB, e->type->repr, (struct value *[]){l, r});
		v = funcinst(f, e->incdec.op == TINC ? IADD : ISUB, e->type->repr, l, r);
		funcstore(f, e->type, addr, v);
		return e->incdec.post ? l : v;
	case EXPRCALL:
@@ -619,7 +621,7 @@ funcexpr(struct function *f, struct expression *e)
		if (e->call.func->type->base->func.isvararg)
			*argval++ = &ellipsis;
		*argval = NULL;
		return funcinst(f, ICALL, e->type == &typevoid ? NULL : e->type->repr, argvals);
		return funcinstn(f, ICALL, e->type == &typevoid ? NULL : e->type->repr, argvals);
		//if (e->call.func->type->base->func.isnoreturn)
		//	funcret(f, NULL);
	case EXPRUNARY:
@@ -689,7 +691,7 @@ funcexpr(struct function *f, struct expression *e)
					op = ICOPY;
			}
		}
		return funcinst(f, op, dst->repr, (struct value *[]){l, r});
		return funcinst(f, op, dst->repr, l, r);
	}
	case EXPRBINARY:
		if (e->binary.op == TLOR || e->binary.op == TLAND) {
@@ -706,7 +708,7 @@ funcexpr(struct function *f, struct expression *e)
			r = funcexpr(f, e->binary.r);
			label[3] = (struct value *)f->end;
			funclabel(f, label[1]);
			return funcinst(f, IPHI, e->type->repr, (struct value *[]){label[2], l, label[3], r, NULL});
			return funcinstn(f, IPHI, e->type->repr, (struct value *[]){label[2], l, label[3], r, NULL});
		}
		l = funcexpr(f, e->binary.l);
		r = funcexpr(f, e->binary.r);
@@ -795,7 +797,7 @@ funcexpr(struct function *f, struct expression *e)
		}
		if (op == INONE)
			fatal("internal error; unimplemented binary expression");
		return funcinst(f, op, e->type->repr, (struct value *[]){l, r});
		return funcinst(f, op, e->type->repr, l, r);
	case EXPRCOND:
		label[0] = mkblock("cond_true");
		label[1] = mkblock("cond_false");
@@ -816,7 +818,7 @@ funcexpr(struct function *f, struct expression *e)
		funclabel(f, label[2]);
		if (e->type == &typevoid)
			return NULL;
		return funcinst(f, IPHI, e->type->repr, (struct value *[]){label[3], l, label[4], r, NULL});
		return funcinstn(f, IPHI, e->type->repr, (struct value *[]){label[3], l, label[4], r, NULL});
	case EXPRASSIGN:
		r = funcexpr(f, e->assign.r);
		if (e->assign.l->kind == EXPRTEMP) {
@@ -834,17 +836,17 @@ funcexpr(struct function *f, struct expression *e)
		switch (e->builtin.kind) {
		case BUILTINVASTART:
			l = funcexpr(f, e->builtin.arg);
			funcinst(f, IVASTART, NULL, (struct value *[]){l});
			funcinst(f, IVASTART, NULL, l);
			break;
		case BUILTINVAARG:
			l = funcexpr(f, e->builtin.arg);
			return funcinst(f, IVAARG, e->type->repr, (struct value *[]){l});
			return funcinst(f, IVAARG, e->type->repr, l);
		case BUILTINVAEND:
			/* no-op */
			break;
		case BUILTINALLOCA:
			l = funcexpr(f, e->builtin.arg);
			return funcinst(f, IALLOC16, &iptr, (struct value *[]){l});
			return funcinst(f, IALLOC16, &iptr, l);
		default:
			fatal("internal error: unimplemented builtin");
		}
@@ -872,8 +874,8 @@ zero(struct function *func, struct value *addr, int align, uint64_t offset, uint

	while (offset < end) {
		if ((align - (offset & align - 1)) & a) {
			tmp = offset ? funcinst(func, IADD, &iptr, (struct value *[]){addr, mkintconst(&iptr, offset)}) : addr;
			funcinst(func, store[a], NULL, (struct value *[]){&z, tmp});
			tmp = offset ? funcinst(func, IADD, &iptr, addr, mkintconst(&iptr, offset)) : addr;
			funcinst(func, store[a], NULL, &z, tmp);
			offset += a;
		}
		if (a < align)
@@ -893,12 +895,12 @@ funcinit(struct function *func, struct declaration *d, struct initializer *init)
		zero(func, d->value, d->type->align, offset, init->start);
		if (init->expr->kind == EXPRSTRING) {
			for (i = 0; i < init->expr->string.size && i < init->end - init->start; ++i) {
				dst = funcinst(func, IADD, &iptr, (struct value *[]){d->value, mkintconst(&iptr, init->start + i)});
				funcinst(func, ISTOREB, NULL, (struct value *[]){mkintconst(&i8, init->expr->string.data[i]), dst});
				dst = funcinst(func, IADD, &iptr, d->value, mkintconst(&iptr, init->start + i));
				funcinst(func, ISTOREB, NULL, mkintconst(&i8, init->expr->string.data[i]), dst);
			}
			offset += i;
		} else {
			dst = funcinst(func, IADD, &iptr, (struct value *[]){d->value, mkintconst(&iptr, init->start)});
			dst = funcinst(func, IADD, &iptr, d->value, mkintconst(&iptr, init->start));
			src = funcexpr(func, init->expr);
			funcstore(func, init->expr->type, dst, src);
			offset = init->end;
@@ -922,10 +924,10 @@ casesearch(struct function *f, struct value *v, struct switchcase *c, struct val

	// XXX: linear search if c->node.height < 4
	key = mkintconst(&i64, c->node.key);
	res = funcinst(f, ICEQW, &i32, (struct value *[]){v, key});
	res = funcinst(f, ICEQW, &i32, v, key);
	funcjnz(f, res, c->body, label[0]);
	funclabel(f, label[0]);
	res = funcinst(f, ICULTW, typeint.repr, (struct value *[]){v, key});
	res = funcinst(f, ICULTW, typeint.repr, v, key);
	funcjnz(f, res, label[1], label[2]);
	funclabel(f, label[1]);
	casesearch(f, v, c->node.child[0], defaultlabel);
-- 
2.19.2
Reply to thread Export thread (mbox)