Exemplo n.º 1
0
Arquivo: tree.c Projeto: UraKn0x/gbdk
char *opname(int op) {
	static char *opnames[] = {
	"",
	"CNST",
	"ARG",
	"ASGN",
	"INDIR",
	"CVC",
	"CVD",
	"CVF",
	"CVI",
	"CVP",
	"CVS",
	"CVU",
	"NEG",
	"CALL",
	"*LOAD*",
	"RET",
	"ADDRG",
	"ADDRF",
	"ADDRL",
	"ADD",
	"SUB",
	"LSH",
	"MOD",
	"RSH",
	"BAND",
	"BCOM",
	"BOR",
	"BXOR",
	"DIV",
	"MUL",
	"EQ",
	"GE",
	"GT",
	"LE",
	"LT",
	"NE",
	"JUMP",
	"LABEL",
	"AND",
	"NOT",
	"OR",
	"COND",
	"RIGHT",
	"FIELD"
	}, *suffixes[] = {
		"0", "F", "D", "C", "S", "I", "U", "P", "V", "B",
		"10","11","12","13","14","15"
	};

	if (generic(op) >= AND && generic(op) <= FIELD && opsize(op) == 0)
		return opnames[opindex(op)];
	return stringf("%s%s%s",
		opindex(op) > 0 && opindex(op) < NELEMS(opnames) ?
			opnames[opindex(op)] : stringd(opindex(op)),
		suffixes[optype(op)], opsize(op) > 0 ? stringd(opsize(op)) : "");
}
Exemplo n.º 2
0
static void prelabel(Node p) {
	if (p == NULL)
		return;
	prelabel(p->kids[0]);
	prelabel(p->kids[1]);
	if (NeedsReg[opindex(p->op)])
		setreg(p, (*IR->x.rmap)(opkind(p->op)));
	switch (generic(p->op)) {
	case ADDRF: case ADDRL:
		if (p->syms[0]->sclass == REGISTER)
			p->op = VREG+P;
		break;
	case INDIR:
		if (p->kids[0]->op == VREG+P)
			setreg(p, p->kids[0]->syms[0]);
		break;
	case ASGN:
		if (p->kids[0]->op == VREG+P)
			rtarget(p, 1, p->kids[0]->syms[0]);
		break;
	case CVI: case CVU: case CVP:
		if (optype(p->op) != F
		&&  opsize(p->op) <= p->syms[0]->u.c.v.i)
			p->op = LOAD + opkind(p->op);
		break;
	}
	(IR->x.target)(p);
}
Exemplo n.º 3
0
/*
static void I(asmcode)(char * s , Symbol ss[] ) {
  
  write(2, "EMIT ASM", strlen("EMIT ASM"));
  
  print("asm\n");
}
*/
static void I(emit)(Node p) {
	for (; p; p = p->link) {
		dumptree(p);
		if (generic(p->op) == CALL) {
			print("DISCARD%s%d\n", " "/*suffixes[optype(p->op)]*/, opsize(p->op));
		}
	}
}
Exemplo n.º 4
0
static void spillr(Symbol r, Node here) {
	int i;
	Symbol tmp;
	Node p = r->x.lastuse;
	assert(p);
	while (p->x.prevuse)
		assert(r == p->syms[RX]),
		p = p->x.prevuse;
	assert(p->x.registered && !readsreg(p));
	tmp = newtemp(AUTO, optype(p->op), opsize(p->op));
	genspill(r, p, tmp);
	for (p = here->x.next; p; p = p->x.next)
		for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) {
			Node k = p->x.kids[i];
			if (k->x.registered && k->syms[RX] == r)
				genreload(p, tmp, i);
		}
	putreg(r);
}
Exemplo n.º 5
0
static void emit2(Node p)
{
    char* name;
    char* offset;
    int localoffset;
    int argoffset;
    long intval;
    long double fltval;
    int op = specific(p->op);
    int opsz = opsize(p->op);
    int i, j, k;
    Symbol s;

    switch (op)
    {
        case CNST + F:
            fltval = p->syms[0]->u.c.v.d;
            if (fltval < 0)
                emithex((short) (fltval * 256));
            else
                printf("%d", (short) (fltval * 256));
            break;
        case CNST + I:
            intval = p->syms[0]->u.c.v.i;
            if (intval < 0)
                emithex((short) intval);
            else
                print("%d", intval);
            break;
        case ARG + F:
        case ARG + I:
        case ARG + U:
        case ARG + P:
            if (p->x.argno > 2)
            {
                assert(maxargoffset);
                if (p->x.argno == 3)
                    print("SET PEEK, ");
                else
                    print("SET I, SP\nSET [%d+I], ", p->x.argno - 3);
                emitasm(p->kids[0], _bval_NT);
                print("\n");
            }
            break;
        case CALL + F:
        case CALL + I:
        case CALL + U:
        case CALL + P:
        case CALL + V:
            assert(p->kids[0]);
            argoffset = p->syms[0]->u.c.v.i;

            print("JSR ");
            emitasm(p->kids[0], _addr_NT);
            print("\n");
            if (argoffset > 3)
                popstack(argoffset - 3, "popping arguments from stack");
            break;
        case ADDRL + P:
            localoffset = p->syms[0]->x.offset + maxoffset;
            if (p->x.inst)
            {
                if (localoffset)
                    print("SET %s, %d\nADD %s, J\n", p->syms[RX]->name,
                            localoffset, p->syms[RX]->name);
                else
                    print("SET %s, J\n", p->syms[RX]->name);
            }
            else
            {
                if (localoffset)
                    print("%d+J", localoffset);
                else
                    print("J");
            }
            break;
        case ADDRF + P:
            if (p->syms[0]->x.offset)
                print("%d+J", p->syms[0]->x.offset);
            else
                print("J");
            break;
        case ASGN + B:
            assert(p->kids[0]);
            assert(p->kids[1]);
            assert(p->kids[1]->kids[0]);

            print(";starting block copy (%s %s %d)\n",
                    p->kids[0]->syms[RX]->x.name,
                    p->kids[1]->kids[0]->syms[RX]->x.name, p->syms[0]->u.c.v.i);

            for (i = 0; i < p->syms[0]->u.c.v.i; i++)
            {
                if (i == 0)
                    print("SET [%s], [%s]\n", p->kids[0]->syms[RX]->x.name,
                            p->kids[1]->kids[0]->syms[RX]->x.name);
                else
                    print("SET [%d+%s], [%d+%s]\n", i,
                            p->kids[0]->syms[RX]->x.name, i,
                            p->kids[1]->kids[0]->syms[RX]->x.name);
            }

            break;
            /*
             case INDIR+P:
             if (p->kids[0]) {
             s = p->kids[0]->syms[0];
             }
             else {
             s = p->syms[0];
             }

             assert(s->x.name);
             debug(fprintf(stderr, "addrg emit2 %s->%s\n", s->x.name, p->syms[RX]->name));

             name = (char*)malloc(strlen(s->x.name));
             offset = (char*)malloc(strlen(s->x.name));
             for( i = 0; s->x.name[i]; i++ ) {
             if ( s->x.name[i] == '+' )
             break;
             name[i] = s->x.name[i];
             }
             name[i+1] = 0;
             if (s->x.name[i] == '+') {
             i++;
             for( j = 0; s->x.name[i+j]; j++ ) {
             offset[j] = s->x.name[i+j];
             }
             offset[i+j+1] = 0;

             print("SET %s, %s\nADD %s, %s\nSET %s, [%s]\n", p->syms[RX]->name, name, p->syms[RX]->name, offset, p->syms[RX]->name, p->syms[RX]->name);
             }
             else {
             print("SET %s, [", p->syms[RX]->name);
             emithex(atoi(s->x.name));
             print("]\n");
             }

             break;
             */
    }
}
Exemplo n.º 6
0
static rcc_node_ty visit(Node p) {
	Symbol q;
	rcc_node_ty left = NULL, right = NULL;
	int suffix = optype(p->op), size = opsize(p->op);

	assert(p);
	for (q = temps; q; q = q->u.t.next)
		if (q->u.t.cse == p) {
			q->u.t.cse = NULL;
			return rcc_CSE(0, 0, symboluid(q), visit(p));
		}
	if (p->kids[0] != NULL)
		left = visit(p->kids[0]);
	if (p->kids[1] != NULL)
		right = visit(p->kids[1]);
	switch (specific(p->op)) {
	case CNST+F:
		assert(p->syms[0]);
		return rcc_CNSTF(suffix, size, mk_real(size, p->syms[0]->u.c.v));
	case CALL+B:
		assert(p->syms[0]);
		assert(p->syms[0]->type);
		return rcc_CALLB(suffix, size, left, right, typeuid(p->syms[0]->type));
	case RET+V:
		return rcc_RET(suffix, size);
	case LABEL+V:
		assert(p->syms[0]);
		return rcc_LABEL(suffix, size, p->syms[0]->u.l.label);
	}
	switch (generic(p->op)) {
	case CNST:
		assert(p->syms[0]);
		return rcc_CNST(suffix, size, p->syms[0]->u.c.v.i);	/* FIXME */
	case ARG:
		assert(p->syms[0]);
		return rcc_ARG(suffix, size, left, p->syms[0]->u.c.v.i, p->syms[1]->u.c.v.i);
	case ASGN:
		assert(p->syms[0]);
		assert(p->syms[1]);
		return rcc_ASGN(suffix, size, left, right, p->syms[0]->u.c.v.i, p->syms[1]->u.c.v.i);
	case CVF: case CVI: case CVP: case CVU:
		assert(p->syms[0]);
		return rcc_CVT(suffix, size, generic(p->op), left, p->syms[0]->u.c.v.i);
	case CALL:
		assert(p->syms[0]);
		assert(p->syms[0]->type);
		return rcc_CALL(suffix, size, left, typeuid(p->syms[0]->type));
#define xx(op) case op: return rcc_##op(suffix, size, symboluid(p->syms[0]))
	xx(ADDRG);
	xx(ADDRF);
#undef xx
	case ADDRL:
		if (!p->syms[0]->defined)
			(*IR->local)(p->syms[0]);
		p->syms[0]->defined = 1;
		return rcc_ADDRL(suffix, size, symboluid(p->syms[0]));
	case JUMP:
		if (p->syms[0] != NULL)
			return rcc_BRANCH(suffix, size, p->syms[0]->u.l.label);
		return rcc_Unary(suffix, size, generic(p->op), left);
	case INDIR: case RET: case NEG: case BCOM: 
		return rcc_Unary(suffix, size, generic(p->op), left);
	case BOR: case BAND: case BXOR: case RSH: case LSH:
	case ADD: case SUB: case DIV: case MUL: case MOD:
		return rcc_Binary(suffix, size, generic(p->op), left, right);
	case EQ: case NE: case GT: case GE: case LE: case LT:
		assert(p->syms[0]);
		return rcc_Compare(suffix, size, generic(p->op), left, right, p->syms[0]->u.l.label);
	}
	assert(0);
	return NULL;
}