File:  [Plan 9 NeXT] / lucent / sys / src / alef / k / reg.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:01:04 2018 UTC (8 years, 1 month ago) by root
Branches: lucent, MAIN
CVS tags: plan9, HEAD
Plan 9 NeXT

#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ctype.h>
#define Extern extern
#include "parl.h"
#include "globl.h"

int regmap[65];

void
reginit(void)
{
	regmap[Retfreg]++;
	regmap[Retireg]++;
	regmap[Reglink]++;
	regmap[Regtmp]++;

	privreg = Pregs;
}

void
regcheck(void)
{
	int r, e;

	e = 0;
	for(r = Ireg; r < Maxireg; r++)
		if(regmap[r]) {
			switch(r) {
			default:
				print("R%d still used\n", r);
				e++;
				break;
			case Retfreg:
			case Retireg:
			case Reglink:
			case Regtmp:
				break;
			}
		}

	for(r = Freg; r < Maxfreg; r++)
		if(regmap[r] && (r != Retfreg || regmap[Retfreg] != 1)) {
			print("F%d still used\n", r);
			e++;
		}
	if(e)
		fatal("regcheck %P", curfunc);
}

void
reg(Node *n, Type *t, Node *use)
{
	int r, j;
	static int ireg;

	switch(t->type) {
	default:
		fatal("reg: bad type %T", t);

	case TINT:
	case TUINT:
	case TSINT:
	case TSUINT:
	case TCHAR:
	case TIND:
	case TCHANNEL:
		if(use && use->type == OREGISTER && use->reg < Freg) {
			r = use->reg;
			break;
		}
		j = ireg+Ireg;
		for(r = Ireg; r < Maxireg; r++) {
			if(j >= Maxireg)
				j = Ireg;
			if(regmap[j] == 0) {
				r = j;
				break;
			}
			j++;
		}
		if(r >= Maxireg)
			fatal("No int registers");
		break;

	case TFLOAT:
		if(use && use->type == OREGISTER && use->reg >= Freg) {
			r = use->reg;
			break;
		}

		j = ireg*2+Freg;
		for(r = Freg; r < Maxfreg; r += 2) {
			if(j >= Maxfreg)
				j = Ireg;
			if(regmap[j] == 0) {
				r = j;
				break;
			}
			j += 2;
		}
		if(r >= Maxfreg)
			fatal("No float registers");
		break;
	}
	ireg++;
	if(ireg > 5)
		ireg = 0;
	regmap[r]++;
	n->reg = r;
	n->type = OREGISTER;
	n->islval = 11;
	n->sun = 0;
	n->t = t;
}

Node*
regtmp(void)
{
	Node *n;
	int r;

	n = an(OREGISTER, ZeroN, ZeroN);
	n->t = builtype[TINT];
	n->islval = 11;
	n->sun = 0;

	for(r = Ireg; r < Maxireg; r++)
		if(regmap[r] == 0) {
			n->reg = r;
			regmap[r]++;
			return n;
		}
	fatal("No int registers");
	return ZeroN;	
}

Node*
regn(int nr)
{
	Node *n;

	n = an(OREGISTER, ZeroN, ZeroN);
	if(nr >= Freg)
		n->t = builtype[TFLOAT];
	else
		n->t = builtype[TINT];
	n->islval = 11;
	n->sun = 0;
	n->reg = nr;
	return n;
}

void
regret(Node *n, Type*t)
{
	int r;

	switch(t->type) {
	default:
		fatal("regret: bad type %T", t);

	case TINT:
	case TUINT:
	case TSINT:
	case TSUINT:
	case TCHAR:
	case TIND:
	case TCHANNEL:
		r = Retireg;
		break;

	case TFLOAT:
		r = Retfreg;
		break;
	}
	regmap[r]++;
	n->reg = r;
	n->type = OREGISTER;
	n->t = t;
}

void
regfree(Node *n)
{
	if(regmap[n->reg] <= 0)
		fatal("regfree");

	regmap[n->reg]--;
}

/*
 * look for a constant which fits in a sparc immediate
 */
int
immed(Node *n)
{
	long ival;

	if(n->type != OCONST || n->t->type == TFLOAT)
		return 0;

	ival = n->ival;
	if(ival >= -(1<<12) && ival < (1<<12))
		return 1;

	return 0;
}

/*
 * Return the name of an activation argument
 */
Node*
atvnode(Type *t)
{
	int o;
	Node *n;

	n = an(OREGISTER, ZeroN, ZeroN);
	n->reg = ratv.reg;
	n->ival = 0;
	n->t = at(TIND, t);

	o = align(ratv.ival, builtype[TINT]);
	ratv.ival = o+t->size;
	if(ratv.ival > maxframe)
		maxframe = ratv.ival;

	/* Adjust offset within int for smaller types */
	switch(t->type) {
	case TSINT:
	case TSUINT:
		o += Shortfoff;
		break;

	case TCHAR:
		o += Charfoff;
		break;
	}

	n = an(OADD, n, con(o));
	n->t = n->left->t;
	n = an(OIND, n, ZeroN);
	n->t = t;

	sucalc(n);
	return n;
}

/*
 * Make a node to alias an argument
 */
Node*
argnode(Type *t)
{
	Node *n;
	int o;

	if(atv)
		return atvnode(t);

	n = an(ONAME, ZeroN, ZeroN);
	n->t = t;
	n->ti = ati(t, Argument);
	args = align(args, builtype[TINT]);
	o = args;

	/* Adjust offset within int for smaller types */
	switch(t->type) {
	case TSINT:
	case TSUINT:
		o += Shortfoff;
		break;

	case TCHAR:
		o += Charfoff;
		break;
	}

	n->ti->offset = o;
	args += t->size;

	sucalc(n);
	return n;
}

Node*
paramnode(Type *t)
{
	Node *n;

	USED(t);

	while(tip->class != Parameter)
		tip = tip->dcllist;

	n = an(ONAME, ZeroN, ZeroN);
	n->sym = tip->s;
	n->ti = tip;
	n->t = tip->t;

	/* for next time */
	tip = tip->dcllist;

	sucalc(n);
	return n;
}

/*
 * Make a stack temporary node and allocate space in the frame
 */
Node*
stknode(Type *o)
{
	Node *n;
	char buf[10];

	n = an(ONAME, ZeroN, ZeroN);
	n->sym = malloc(sizeof(Sym));
	n->ti = ati(o, Automatic);
	n->t = o;

	sprint(buf, ".t%d", stmp++);
	n->sym->name = strdup(buf);

	/* Allocate the space */
	frame = align(frame, o);
	frame += o->size;

	n->ti->offset = -frame;
	sucalc(n);
	return n;
}

Node*
internnode(Type *o)
{
	Node *n;
	char buf[10];

	n = an(ONAME, ZeroN, ZeroN);
	n->sym = malloc(sizeof(Sym));
	n->t = at(o->type, 0);
	n->t->class = Internal;
	n->ti = ati(n->t, Internal);

	sprint(buf, ".i%d", stmp++);
	n->sym->name = strdup(buf);

	n->ti->offset = 0;
	sucalc(n);

	n->init = ZeroN;
	gendata(n);

	return n;
}

Node*
con(int i)
{
	Node *c;

	c = an(OCONST, ZeroN, ZeroN);
	c->t = builtype[TINT];
	c->ival = i;

	return c;
}

Node*
conf(double d)
{
	Node *c;

	c = an(OCONST, ZeroN, ZeroN);
	c->t = builtype[TFLOAT];
	c->fval = d;

	return c;
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.