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 }