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 ulong 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 ulong 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 lget8(Map *map, Regs *regs, Loc loc, u64int *u)
119 ulong ul;
121 if(locsimplify(map, regs, loc, &loc) < 0)
122 return -1;
123 if(loc.type == LADDR)
124 return get8(map, loc.addr, u);
125 if(loc.type == LCONST){
126 *u = loc.addr;
127 return 0;
129 if(loc.type == LREG){
130 if(rget(regs, loc.reg, &ul) < 0)
131 return -1;
132 *u = ul;
133 return 0;
135 werrstr("bad location for lget8");
136 return -1;
139 int
140 lput1(Map *map, Regs *regs, Loc loc, uchar *a, uint n)
142 if(locsimplify(map, regs, loc, &loc) < 0)
143 return -1;
144 if(loc.type == LADDR)
145 return put1(map, loc.addr, a, n);
146 /* could do more here - i'm lazy */
147 werrstr("bad location for lput1");
148 return -1;
151 int
152 lput2(Map *map, Regs *regs, Loc loc, u16int u)
154 if(locsimplify(map, regs, loc, &loc) < 0)
155 return -1;
156 if(loc.type == LADDR)
157 return put2(map, loc.addr, u);
158 if(loc.type == LREG)
159 return rput(regs, loc.reg, u);
160 werrstr("bad location for lput2");
161 return -1;
164 int
165 lput4(Map *map, Regs *regs, Loc loc, u32int u)
167 if(locsimplify(map, regs, loc, &loc) < 0)
168 return -1;
169 if(loc.type == LADDR)
170 return put4(map, loc.addr, u);
171 if(loc.type == LREG)
172 return rput(regs, loc.reg, u);
173 werrstr("bad location for lput4");
174 return -1;
177 int
178 lput8(Map *map, Regs *regs, Loc loc, u64int u)
180 if(locsimplify(map, regs, loc, &loc) < 0)
181 return -1;
182 if(loc.type == LADDR)
183 return put8(map, loc.addr, u);
184 if(loc.type == LREG)
185 return rput(regs, loc.reg, u);
186 werrstr("bad location for lput8");
187 return -1;
190 Loc
191 locaddr(ulong addr)
193 Loc l;
195 l.type = LADDR;
196 l.addr = addr;
197 return l;
200 Loc
201 locindir(char *reg, long offset)
203 Loc l;
205 l.type = LOFFSET;
206 l.reg = reg;
207 l.offset = offset;
208 l.addr = 0; /* SHUT UP GCC 4.0 */
209 return l;
212 Loc
213 locconst(ulong con)
215 Loc l;
217 l.type = LCONST;
218 l.addr = con;
219 return l;
222 Loc
223 locnone(void)
225 Loc l;
227 l.type = LNONE;
228 return l;
231 Loc
232 locreg(char *reg)
234 Loc l;
236 l.type = LREG;
237 l.reg = reg;
238 return l;
241 int
242 locsimplify(Map *map, Regs *regs, Loc loc, Loc *newloc)
244 ulong u;
246 if(loc.type == LOFFSET){
247 if(rget(regs, loc.reg, &u) < 0)
248 return -1;
249 *newloc = locaddr(u + loc.offset);
250 }else
251 *newloc = loc;
252 return 0;