Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
6 int
7 locfmt(Fmt *fmt)
8 {
9 Loc l;
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 }
26 int
27 loccmp(Loc *a, Loc *b)
28 {
29 int i;
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 }
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 }
70 int
71 lget2(Map *map, Regs *regs, Loc loc, u16int *u)
72 {
73 u64int ul;
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 }
93 int
94 lget4(Map *map, Regs *regs, Loc loc, u32int *u)
95 {
96 u64int ul;
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;
106 if(loc.type == LREG){
107 if(rget(regs, loc.reg, &ul) < 0)
108 return -1;
109 *u = ul;
110 return 0;
112 werrstr("bad location for lget4");
113 return -1;
116 int
117 lgeta(Map *map, Regs *regs, Loc loc, u64int *u)
119 u32int v;
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;
129 int
130 lget8(Map *map, Regs *regs, Loc loc, u64int *u)
132 u64int ul;
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;
142 if(loc.type == LREG){
143 if(rget(regs, loc.reg, &ul) < 0)
144 return -1;
145 *u = ul;
146 return 0;
148 werrstr("bad location for lget8");
149 return -1;
152 int
153 lput1(Map *map, Regs *regs, Loc loc, uchar *a, uint n)
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;
164 int
165 lput2(Map *map, Regs *regs, Loc loc, u16int u)
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;
177 int
178 lput4(Map *map, Regs *regs, Loc loc, u32int u)
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;
190 int
191 lput8(Map *map, Regs *regs, Loc loc, u64int u)
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;
203 static Loc zl;
205 Loc
206 locaddr(u64int addr)
208 Loc l;
210 l = zl;
211 l.type = LADDR;
212 l.addr = addr;
213 return l;
216 Loc
217 locindir(char *reg, long offset)
219 Loc l;
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;
229 Loc
230 locconst(u64int con)
232 Loc l;
234 l = zl;
235 l.type = LCONST;
236 l.addr = con;
237 return l;
240 Loc
241 locnone(void)
243 Loc l;
245 l = zl;
246 l.type = LNONE;
247 return l;
250 Loc
251 locreg(char *reg)
253 Loc l;
255 l = zl;
256 l.type = LREG;
257 l.reg = reg;
258 return l;
261 int
262 locsimplify(Map *map, Regs *regs, Loc loc, Loc *newloc)
264 u64int u;
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;