~mcf/cproc

b38f2d82a80ea203f37c88746639a0efa8b66fbf — Michael Forney 1 year, 7 months ago b95f69c
Use a common member for expression op
4 files changed, 19 insertions(+), 21 deletions(-)

M cc.h
M eval.c
M expr.c
M qbe.c
M cc.h => cc.h +1 -3
@@ 305,6 305,7 @@ struct expr {
	struct type *type;
	/* the type qualifiers of the object this expression refers to (ignored for non-lvalues) */
	enum typequal qual;
	enum tokenkind op;
	struct expr *next;
	union {
		struct {


@@ 330,19 331,16 @@ struct expr {
			struct init *init;
		} compound;
		struct {
			enum tokenkind op;
			_Bool post;
			struct expr *base;
		} incdec;
		struct {
			enum tokenkind op;
			struct expr *base;
		} unary;
		struct {
			struct expr *e;
		} cast;
		struct {
			enum tokenkind op;
			struct expr *l, *r;
		} binary;
		struct {

M eval.c => eval.c +7 -7
@@ 108,11 108,11 @@ eval(struct expr *expr)
		break;
	case EXPRUNARY:
		l = eval(expr->unary.base);
		if (expr->unary.op != TBAND)
		if (expr->op != TBAND)
			break;
		switch (l->kind) {
		case EXPRUNARY:
			if (l->unary.op == TMUL)
			if (l->op == TMUL)
				expr = eval(l->unary.base);
			break;
		case EXPRSTRING:


@@ 142,19 142,19 @@ eval(struct expr *expr)
		r = eval(expr->binary.r);
		expr->binary.l = l;
		expr->binary.r = r;
		switch (expr->binary.op) {
		switch (expr->op) {
		case TADD:
			if (r->kind == EXPRBINARY)
				c = l, l = r, r = c;
			if (r->kind != EXPRCONST)
				break;
			if (l->kind == EXPRCONST) {
				binary(expr, expr->binary.op, l, r);
				binary(expr, expr->op, l, r);
			} else if (l->kind == EXPRBINARY && l->type->kind == TYPEPOINTER && l->binary.r->kind == EXPRCONST) {
				if (l->binary.op == TADD || l->binary.op == TSUB) {
				if (l->op == TADD || l->op == TSUB) {
					/* (P ± C1) + C2  ->  P + (C2 ± C1) */
					expr->binary.l = l->binary.l;
					binary(expr->binary.r, l->binary.op, r, l->binary.r);
					binary(expr->binary.r, l->op, r, l->binary.r);
				}
			}
			break;


@@ 170,7 170,7 @@ eval(struct expr *expr)
		default:
			if (l->kind != EXPRCONST || r->kind != EXPRCONST)
				break;
			binary(expr, expr->binary.op, l, r);
			binary(expr, expr->op, l, r);
		}
		break;
	case EXPRCOND:

M expr.c => expr.c +4 -4
@@ 137,7 137,7 @@ mkunaryexpr(enum tokenkind op, struct expr *base)
		if (base->kind == EXPRBITFIELD)
			error(&tok.loc, "cannot take address of bit-field");
		expr = mkexpr(EXPRUNARY, mkpointertype(base->type, base->qual));
		expr->unary.op = op;
		expr->op = op;
		expr->unary.base = base;
		return expr;
	case TMUL:


@@ 146,7 146,7 @@ mkunaryexpr(enum tokenkind op, struct expr *base)
		expr = mkexpr(EXPRUNARY, base->type->base);
		expr->qual = base->type->qual;
		expr->lvalue = true;
		expr->unary.op = op;
		expr->op = op;
		expr->unary.base = base;
		return decay(expr);
	}


@@ 280,7 280,7 @@ mkbinaryexpr(struct location *loc, enum tokenkind op, struct expr *l, struct exp
		fatal("internal error: unknown binary operator %d", op);
	}
	e = mkexpr(EXPRBINARY, t);
	e->binary.op = op;
	e->op = op;
	e->binary.l = l;
	e->binary.r = r;



@@ 643,7 643,7 @@ mkincdecexpr(enum tokenkind op, struct expr *base, bool post)
	if (base->qual & QUALCONST)
		error(&tok.loc, "operand of '%s' operator is const qualified", tokstr[op]);
	e = mkexpr(EXPRINCDEC, base->type);
	e->incdec.op = op;
	e->op = op;
	e->incdec.base = base;
	e->incdec.post = post;
	return e;

M qbe.c => qbe.c +7 -7
@@ 518,7 518,7 @@ funclval(struct func *f, struct expr *e)
		lval.addr = d->value;
		break;
	case EXPRUNARY:
		if (e->unary.op != TMUL)
		if (e->op != TMUL)
			break;
		lval.addr = funcexpr(f, e->unary.base);
		break;


@@ 652,7 652,7 @@ funcexpr(struct func *f, struct expr *e)
			r = mkfltconst(e->type->repr, 1);
		else
			fatal("not a scalar");
		v = funcinst(f, e->incdec.op == TINC ? IADD : ISUB, e->type->repr, l, r);
		v = funcinst(f, e->op == TINC ? IADD : ISUB, e->type->repr, l, r);
		funcstore(f, e->type, e->qual, lval, v);
		return e->incdec.post ? l : v;
	case EXPRCALL:


@@ 671,7 671,7 @@ funcexpr(struct func *f, struct expr *e)
		//	funcret(f, NULL);
		return v;
	case EXPRUNARY:
		switch (e->unary.op) {
		switch (e->op) {
		case TBAND:
			lval = funclval(f, e->unary.base);
			return lval.addr;


@@ 738,13 738,13 @@ funcexpr(struct func *f, struct expr *e)
		return funcinst(f, op, dst->repr, l, r);
	}
	case EXPRBINARY:
		if (e->binary.op == TLOR || e->binary.op == TLAND) {
		if (e->op == TLOR || e->op == TLAND) {
			label[0] = mkblock("logic_right");
			label[1] = mkblock("logic_join");

			l = funcexpr(f, e->binary.l);
			label[2] = (struct value *)f->end;
			if (e->binary.op == TLOR)
			if (e->op == TLOR)
				funcjnz(f, l, label[1], label[0]);
			else
				funcjnz(f, l, label[0], label[1]);


@@ 759,7 759,7 @@ funcexpr(struct func *f, struct expr *e)
		t = e->binary.l->type;
		if (t->kind == TYPEPOINTER)
			t = &typeulong;
		switch (e->binary.op) {
		switch (e->op) {
		case TMUL:
			op = IMUL;
			break;


@@ 1191,7 1191,7 @@ dataitem(struct expr *expr, uint64_t size)

	switch (expr->kind) {
	case EXPRUNARY:
		if (expr->unary.op != TBAND)
		if (expr->op != TBAND)
			fatal("not a address expr");
		expr = expr->unary.base;
		if (expr->kind != EXPRIDENT)