plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

loc.c (4331B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <bio.h>
      4 #include <mach.h>
      5 
      6 int
      7 locfmt(Fmt *fmt)
      8 {
      9 	Loc l;
     10 
     11 	l = va_arg(fmt->args, Loc);
     12 	switch(l.type){
     13 	default:
     14 		return fmtprint(fmt, "<loc%d>", l.type);
     15 	case LCONST:
     16 		return fmtprint(fmt, "0x%lux", l.addr);
     17 	case LADDR:
     18 		return fmtprint(fmt, "*0x%lux", l.addr);
     19 	case LOFFSET:
     20 		return fmtprint(fmt, "%ld(%s)", l.offset, l.reg);
     21 	case LREG:
     22 		return fmtprint(fmt, "%s", l.reg);
     23 	}
     24 }
     25 
     26 int
     27 loccmp(Loc *a, Loc *b)
     28 {
     29 	int i;
     30 
     31 	if(a->type < b->type)
     32 		return -1;
     33 	if(a->type > b->type)
     34 		return 1;
     35 	switch(a->type){
     36 	default:
     37 		return 0;
     38 	case LADDR:
     39 		if(a->addr < b->addr)
     40 			return -1;
     41 		if(a->addr > b->addr)
     42 			return 1;
     43 		return 0;
     44 	case LOFFSET:
     45 		i = strcmp(a->reg, b->reg);
     46 		if(i != 0)
     47 			return i;
     48 		if(a->offset < b->offset)
     49 			return -1;
     50 		if(a->offset > b->offset)
     51 			return 1;
     52 		return 0;
     53 	case LREG:
     54 		return strcmp(a->reg, b->reg);
     55 	}
     56 }
     57 
     58 int
     59 lget1(Map *map, Regs *regs, Loc loc, uchar *a, uint n)
     60 {
     61 	if(locsimplify(map, regs, loc, &loc) < 0)
     62 		return -1;
     63 	if(loc.type == LADDR)
     64 		return get1(map, loc.addr, a, n);
     65 	/* could do more here - i'm lazy */
     66 	werrstr("bad location for lget1");
     67 	return -1;
     68 }
     69 
     70 int
     71 lget2(Map *map, Regs *regs, Loc loc, u16int *u)
     72 {
     73 	u64int ul;
     74 
     75 	if(locsimplify(map, regs, loc, &loc) < 0)
     76 		return -1;
     77 	if(loc.type == LADDR)
     78 		return get2(map, loc.addr, u);
     79 	if(loc.type == LCONST){
     80 		*u = loc.addr;
     81 		return 0;
     82 	}
     83 	if(loc.type == LREG){
     84 		if(rget(regs, loc.reg, &ul) < 0)
     85 			return -1;
     86 		*u = ul;
     87 		return 0;
     88 	}
     89 	werrstr("bad location for lget2");
     90 	return -1;
     91 }
     92 
     93 int
     94 lget4(Map *map, Regs *regs, Loc loc, u32int *u)
     95 {
     96 	u64int ul;
     97 
     98 	if(locsimplify(map, regs, loc, &loc) < 0)
     99 		return -1;
    100 	if(loc.type == LADDR)
    101 		return get4(map, loc.addr, u);
    102 	if(loc.type == LCONST){
    103 		*u = loc.addr;
    104 		return 0;
    105 	}
    106 	if(loc.type == LREG){
    107 		if(rget(regs, loc.reg, &ul) < 0)
    108 			return -1;
    109 		*u = ul;
    110 		return 0;
    111 	}
    112 	werrstr("bad location for lget4");
    113 	return -1;
    114 }
    115 
    116 int
    117 lgeta(Map *map, Regs *regs, Loc loc, u64int *u)
    118 {
    119 	u32int v;
    120 
    121 	if(machcpu == &machamd64)
    122 		return lget8(map, regs, loc, u);
    123 	if(lget4(map, regs, loc, &v) < 0)
    124 		return -1;
    125 	*u = v;
    126 	return 4;
    127 }
    128 
    129 int
    130 lget8(Map *map, Regs *regs, Loc loc, u64int *u)
    131 {
    132 	u64int ul;
    133 
    134 	if(locsimplify(map, regs, loc, &loc) < 0)
    135 		return -1;
    136 	if(loc.type == LADDR)
    137 		return get8(map, loc.addr, u);
    138 	if(loc.type == LCONST){
    139 		*u = loc.addr;
    140 		return 0;
    141 	}
    142 	if(loc.type == LREG){
    143 		if(rget(regs, loc.reg, &ul) < 0)
    144 			return -1;
    145 		*u = ul;
    146 		return 0;
    147 	}
    148 	werrstr("bad location for lget8");
    149 	return -1;
    150 }
    151 
    152 int
    153 lput1(Map *map, Regs *regs, Loc loc, uchar *a, uint n)
    154 {
    155 	if(locsimplify(map, regs, loc, &loc) < 0)
    156 		return -1;
    157 	if(loc.type == LADDR)
    158 		return put1(map, loc.addr, a, n);
    159 	/* could do more here - i'm lazy */
    160 	werrstr("bad location for lput1");
    161 	return -1;
    162 }
    163 
    164 int
    165 lput2(Map *map, Regs *regs, Loc loc, u16int u)
    166 {
    167 	if(locsimplify(map, regs, loc, &loc) < 0)
    168 		return -1;
    169 	if(loc.type == LADDR)
    170 		return put2(map, loc.addr, u);
    171 	if(loc.type == LREG)
    172 		return rput(regs, loc.reg, u);
    173 	werrstr("bad location for lput2");
    174 	return -1;
    175 }
    176 
    177 int
    178 lput4(Map *map, Regs *regs, Loc loc, u32int u)
    179 {
    180 	if(locsimplify(map, regs, loc, &loc) < 0)
    181 		return -1;
    182 	if(loc.type == LADDR)
    183 		return put4(map, loc.addr, u);
    184 	if(loc.type == LREG)
    185 		return rput(regs, loc.reg, u);
    186 	werrstr("bad location for lput4");
    187 	return -1;
    188 }
    189 
    190 int
    191 lput8(Map *map, Regs *regs, Loc loc, u64int u)
    192 {
    193 	if(locsimplify(map, regs, loc, &loc) < 0)
    194 		return -1;
    195 	if(loc.type == LADDR)
    196 		return put8(map, loc.addr, u);
    197 	if(loc.type == LREG)
    198 		return rput(regs, loc.reg, u);
    199 	werrstr("bad location for lput8");
    200 	return -1;
    201 }
    202 
    203 static Loc zl;
    204 
    205 Loc
    206 locaddr(u64int addr)
    207 {
    208 	Loc l;
    209 
    210 	l = zl;
    211 	l.type = LADDR;
    212 	l.addr = addr;
    213 	return l;
    214 }
    215 
    216 Loc
    217 locindir(char *reg, long offset)
    218 {
    219 	Loc l;
    220 
    221 	l = zl;
    222 	l.type = LOFFSET;
    223 	l.reg = reg;
    224 	l.offset = offset;
    225 	l.addr = 0;	/* SHUT UP GCC 4.0 */
    226 	return l;
    227 }
    228 
    229 Loc
    230 locconst(u64int con)
    231 {
    232 	Loc l;
    233 
    234 	l = zl;
    235 	l.type = LCONST;
    236 	l.addr = con;
    237 	return l;
    238 }
    239 
    240 Loc
    241 locnone(void)
    242 {
    243 	Loc l;
    244 
    245 	l = zl;
    246 	l.type = LNONE;
    247 	return l;
    248 }
    249 
    250 Loc
    251 locreg(char *reg)
    252 {
    253 	Loc l;
    254 
    255 	l = zl;
    256 	l.type = LREG;
    257 	l.reg = reg;
    258 	return l;
    259 }
    260 
    261 int
    262 locsimplify(Map *map, Regs *regs, Loc loc, Loc *newloc)
    263 {
    264 	u64int u;
    265 
    266 	if(loc.type == LOFFSET){
    267 		if(rget(regs, loc.reg, &u) < 0)
    268 			return -1;
    269 		*newloc = locaddr(u + loc.offset);
    270 	}else
    271 		*newloc = loc;
    272 	return 0;
    273 }