#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>

int
locfmt(Fmt *fmt)
{
	Loc l;

	l = va_arg(fmt->args, Loc);
	switch(l.type){
	default:
		return fmtprint(fmt, "<loc%d>", l.type);
	case LCONST:
		return fmtprint(fmt, "0x%lux", l.addr);
	case LADDR:
		return fmtprint(fmt, "*0x%lux", l.addr);
	case LOFFSET:
		return fmtprint(fmt, "%ld(%s)", l.offset, l.reg);
	case LREG:
		return fmtprint(fmt, "%s", l.reg);
	}
}

int
loccmp(Loc *a, Loc *b)
{
	int i;

	if(a->type < b->type)
		return -1;
	if(a->type > b->type)
		return 1;
	switch(a->type){
	default:
		return 0;
	case LADDR:
		if(a->addr < b->addr)
			return -1;
		if(a->addr > b->addr)
			return 1;
		return 0;
	case LOFFSET:
		i = strcmp(a->reg, b->reg);
		if(i != 0)
			return i;
		if(a->offset < b->offset)
			return -1;
		if(a->offset > b->offset)
			return 1;
		return 0;
	case LREG:
		return strcmp(a->reg, b->reg);
	}
}

int
lget1(Map *map, Regs *regs, Loc loc, uchar *a, uint n)
{
	if(locsimplify(map, regs, loc, &loc) < 0)
		return -1;
	if(loc.type == LADDR)
		return get1(map, loc.addr, a, n);
	/* could do more here - i'm lazy */
	werrstr("bad location for lget1");
	return -1;
}

int
lget2(Map *map, Regs *regs, Loc loc, u16int *u)
{
	ulong ul;

	if(locsimplify(map, regs, loc, &loc) < 0)
		return -1;
	if(loc.type == LADDR)
		return get2(map, loc.addr, u);
	if(loc.type == LCONST){
		*u = loc.addr;
		return 0;
	}
	if(loc.type == LREG){
		if(rget(regs, loc.reg, &ul) < 0)
			return -1;
		*u = ul;
		return 0;
	}
	werrstr("bad location for lget2");
	return -1;
}

int
lget4(Map *map, Regs *regs, Loc loc, u32int *u)
{
	ulong ul;

	if(locsimplify(map, regs, loc, &loc) < 0)
		return -1;
	if(loc.type == LADDR)
		return get4(map, loc.addr, u);
	if(loc.type == LCONST){
		*u = loc.addr;
		return 0;
	}
	if(loc.type == LREG){
		if(rget(regs, loc.reg, &ul) < 0)
			return -1;
		*u = ul;
		return 0;
	}
	werrstr("bad location for lget4");
	return -1;
}

int
lget8(Map *map, Regs *regs, Loc loc, u64int *u)
{
	ulong ul;

	if(locsimplify(map, regs, loc, &loc) < 0)
		return -1;
	if(loc.type == LADDR)
		return get8(map, loc.addr, u);
	if(loc.type == LCONST){
		*u = loc.addr;
		return 0;
	}
	if(loc.type == LREG){
		if(rget(regs, loc.reg, &ul) < 0)
			return -1;
		*u = ul;
		return 0;
	}
	werrstr("bad location for lget8");
	return -1;
}

int
lput1(Map *map, Regs *regs, Loc loc, uchar *a, uint n)
{
	if(locsimplify(map, regs, loc, &loc) < 0)
		return -1;
	if(loc.type == LADDR)
		return put1(map, loc.addr, a, n);
	/* could do more here - i'm lazy */
	werrstr("bad location for lput1");
	return -1;
}

int
lput2(Map *map, Regs *regs, Loc loc, u16int u)
{
	if(locsimplify(map, regs, loc, &loc) < 0)
		return -1;
	if(loc.type == LADDR)
		return put2(map, loc.addr, u);
	if(loc.type == LREG)
		return rput(regs, loc.reg, u);
	werrstr("bad location for lput2");
	return -1;
}

int
lput4(Map *map, Regs *regs, Loc loc, u32int u)
{
	if(locsimplify(map, regs, loc, &loc) < 0)
		return -1;
	if(loc.type == LADDR)
		return put4(map, loc.addr, u);
	if(loc.type == LREG)
		return rput(regs, loc.reg, u);
	werrstr("bad location for lput4");
	return -1;
}

int
lput8(Map *map, Regs *regs, Loc loc, u64int u)
{
	if(locsimplify(map, regs, loc, &loc) < 0)
		return -1;
	if(loc.type == LADDR)
		return put8(map, loc.addr, u);
	if(loc.type == LREG)
		return rput(regs, loc.reg, u);
	werrstr("bad location for lput8");
	return -1;
}

Loc
locaddr(ulong addr)
{
	Loc l;

	l.type = LADDR;
	l.addr = addr;
	return l;
}

Loc
locindir(char *reg, long offset)
{
	Loc l;

	l.type = LOFFSET;
	l.reg = reg;
	l.offset = offset;
	l.addr = 0;	/* SHUT UP GCC 4.0 */
	return l;
}

Loc
locconst(ulong con)
{
	Loc l;

	l.type = LCONST;
	l.addr = con;
	return l;
}

Loc
locnone(void)
{
	Loc l;

	l.type = LNONE;
	return l;
}

Loc
locreg(char *reg)
{
	Loc l;

	l.type = LREG;
	l.reg = reg;
	return l;
}

int
locsimplify(Map *map, Regs *regs, Loc loc, Loc *newloc)
{
	ulong u;

	if(loc.type == LOFFSET){
		if(rget(regs, loc.reg, &u) < 0)
			return -1;
		*newloc = locaddr(u + loc.offset);
	}else
		*newloc = loc;
	return 0;
}

