~sircmpwn/qbe

0f369cceaa0f1856d812b0814924be1d4d8113b7 — Drew DeVault 29 days ago 4620fc5 + 028534d
Merge remote-tracking branch 'upstream/master'
8 files changed, 37 insertions(+), 36 deletions(-)

M all.h
M amd64/emit.c
M amd64/isel.c
M gas.c
M parse.c
M rega.c
M test/isel2.ssa
M util.c
M all.h => all.h +1 -1
@@ 439,7 439,7 @@ int phicls(int, Tmp *);
Ref newtmp(char *, int, Fn *);
void chuse(Ref, int, Fn *);
Ref getcon(int64_t, Fn *);
void addcon(Con *, Con *);
int addcon(Con *, Con *);
void blit(Ref, uint, Ref, uint, Fn *);
void dumpts(BSet *, Tmp *, FILE *);


M amd64/emit.c => amd64/emit.c +2 -1
@@ 184,6 184,7 @@ regtoa(int reg, int sz)
{
	static char buf[6];

	assert(reg <= XMM15);
	if (reg >= XMM0) {
		sprintf(buf, "xmm%d", reg-XMM0);
		return buf;


@@ 407,7 408,7 @@ emitins(Ins i, Fn *fn, FILE *f)
	case Osub:
		/* we have to use the negation trick to handle
		 * some 3-address subtractions */
		if (req(i.arg[1], i.to) && !req(i.arg[0], i.to)) {
		if (req(i.to, i.arg[1]) && !req(i.arg[0], i.to)) {
			if (KBASE(i.cls) == 0)
				emitf("neg%k %=", &i, fn, f);
			else

M amd64/isel.c => amd64/isel.c +26 -26
@@ 147,7 147,7 @@ seladdr(Ref *r, ANum *an, Fn *fn)
			 * rewrite it or bail out if
			 * impossible
			 */
			if (!req(a.index, R))
			if (!req(a.index, R) || rtype(a.base) != RTmp)
				return;
			else {
				a.index = a.base;


@@ 256,13 256,18 @@ sel(Ins i, ANum *an, Fn *fn)
	case Osar:
	case Oshr:
	case Oshl:
		if (rtype(i.arg[1]) == RCon)
			goto Emit;
		r0 = i.arg[1];
		if (rtype(r0) == RCon)
			goto Emit;
		if (fn->tmp[r0.val].slot != -1)
			err("unlikely argument %%%s in %s",
				fn->tmp[r0.val].name, optab[i.op].name);
		i.arg[1] = TMP(RCX);
		emit(Ocopy, Kw, R, TMP(RCX), R);
		emiti(i);
		i1 = curi;
		emit(Ocopy, Kw, TMP(RCX), r0, R);
		fixarg(&i1->arg[0], argcls(&i, 0), i1, fn);
		break;
	case Onop:
		break;


@@ 339,11 344,12 @@ Emit:
		if (isload(i.op))
			goto case_Oload;
		if (iscmp(i.op, &kc, &x)) {
			/* ZF is set when operands are unordered, so we
			 * may have to check PF as well.
			 */
			switch (x) {
			case NCmpI+Cfeq:
				/* zf is set when operands are
				 * unordered, so we may have to
				 * check pf
				 */
				r0 = newtmp("isel", Kw, fn);
				r1 = newtmp("isel", Kw, fn);
				emit(Oand, Kw, i.to, r0, r1);


@@ 368,7 374,7 @@ Emit:
		die("unknown instruction %s", optab[i.op].name);
	}

	while (i0 > curi && --i0) {
	while (i0>curi && --i0) {
		assert(rslot(i0->arg[0], fn) == -1);
		assert(rslot(i0->arg[1], fn) == -1);
	}


@@ 402,7 408,7 @@ seljmp(Blk *b, Fn *fn)
	r = b->jmp.arg;
	t = &fn->tmp[r.val];
	b->jmp.arg = R;
	assert(!req(r, R) && rtype(r) != RCon);
	assert(rtype(r) == RTmp);
	if (b->s1 == b->s2) {
		chuse(r, -1, fn);
		b->jmp.type = Jjmp;


@@ 414,23 420,15 @@ seljmp(Blk *b, Fn *fn)
		selcmp((Ref[2]){r, CON_Z}, Kw, 0, fn); /* todo, long jnz */
		b->jmp.type = Jjf + Cine;
	}
	else if (iscmp(fi->op, &k, &c)) {
		switch (c) {
		case NCmpI+Cfeq:
		case NCmpI+Cfne:
			c = Cine;
			/* set jmp.jarg so rega() doesn't eliminate
			 * the instructions that set r and ZF */
			b->jmp.arg = r;
			break;
		default:
			swap = cmpswap(fi->arg, c);
			if (swap)
				c = cmpop(c);
			if (t->nuse == 1) {
				selcmp(fi->arg, k, swap, fn);
				*fi = (Ins){.op = Onop};
			}
	else if (iscmp(fi->op, &k, &c)
	     && c != NCmpI+Cfeq /* see sel() */
	     && c != NCmpI+Cfne) {
		swap = cmpswap(fi->arg, c);
		if (swap)
			c = cmpop(c);
		if (t->nuse == 1) {
			selcmp(fi->arg, k, swap, fn);
			*fi = (Ins){.op = Onop};
		}
		b->jmp.type = Jjf + c;
	}


@@ 550,7 548,9 @@ amatch(Addr *a, Ref r, int n, ANum *ai, Fn *fn)
	Ref al, ar;

	if (rtype(r) == RCon) {
		addcon(&a->offset, &fn->con[r.val]);
		if (!addcon(&a->offset, &fn->con[r.val]))
			err("unlikely sum of $%s and $%s",
				str(a->offset.label), str(fn->con[r.val].label));
		return 1;
	}
	assert(rtype(r) == RTmp);

M gas.c => gas.c +2 -1
@@ 100,6 100,8 @@ gasemitfin(FILE *f)
	int sz, i;
	double d;

	fprintf(f, ".section .note.GNU-stack,\"\",@progbits\n");

	if (!stash)
		return;
	fprintf(f, "/* floating point constants */\n.data\n");


@@ 128,5 130,4 @@ gasemitfin(FILE *f)
		stash = b->link;
		free(b);
	}
	fprintf(f, ".section .note.GNU-stack,\"\",@progbits\n");
}

M parse.c => parse.c +1 -1
@@ 827,7 827,7 @@ parsefn(int export)
		rcls = 5;
	if (next() != Tglo)
		err("function name expected");
	strcpy(curf->name, tokval.str);
	strncpy(curf->name, tokval.str, NString-1);
	curf->vararg = parserefl(0);
	if (nextnl() != Tlbrace)
		err("function body must start with {");

M rega.c => rega.c +1 -2
@@ 359,10 359,9 @@ doblk(Blk *b, RMap *cur)
	Mem *m;
	Ref *ra[4];

	assert(rtype(b->jmp.arg) != RTmp);
	for (r=0; bsiter(b->out, &r) && r<Tmp0; r++)
		radd(cur, r, r);
	if (rtype(b->jmp.arg) == RTmp)
		b->jmp.arg = ralloc(cur, b->jmp.arg.val);
	curi = &insb[NIns];
	for (i1=&b->ins[b->nins]; i1!=b->ins;) {
		emiti(*--i1);

M test/isel2.ssa => test/isel2.ssa +0 -2
@@ 1,7 1,5 @@
# tests that NaN is handled properly by
# floating point comparisons
#
# TODO: fix eq[123](NAN, NAN) on amd64

export function w $lt(d %x, d %y) {
@start

M util.c => util.c +4 -2
@@ 362,19 362,21 @@ getcon(int64_t val, Fn *fn)
	return CON(c);
}

void
int
addcon(Con *c0, Con *c1)
{
	if (c0->type == CUndef)
		*c0 = *c1;
	else {
		if (c1->type == CAddr) {
			assert(c0->type != CAddr && "adding two addresses");
			if (c0->type == CAddr)
				return 0;
			c0->type = CAddr;
			c0->label = c1->label;
		}
		c0->bits.i += c1->bits.i;
	}
	return 1;
}

void