blob: 596c681629a1fc841a290bb9b6c0be1f28d939b2 [file] [log] [blame]
rsca84cbb22004-04-19 19:29:25 +00001#include <u.h>
2#include <libc.h>
3#include <bio.h>
4#include <mach.h>
5
6int
7locfmt(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
26int
27loccmp(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
58int
59lget1(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
70int
71lget2(Map *map, Regs *regs, Loc loc, u16int *u)
72{
rsc4f0073f2004-06-11 12:52:08 +000073 ulong ul;
rsca84cbb22004-04-19 19:29:25 +000074
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
93int
94lget4(Map *map, Regs *regs, Loc loc, u32int *u)
95{
rsc4f0073f2004-06-11 12:52:08 +000096 ulong ul;
rsca84cbb22004-04-19 19:29:25 +000097
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
116int
117lget8(Map *map, Regs *regs, Loc loc, u64int *u)
118{
rsc4f0073f2004-06-11 12:52:08 +0000119 ulong ul;
rsca84cbb22004-04-19 19:29:25 +0000120
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;
128 }
129 if(loc.type == LREG){
130 if(rget(regs, loc.reg, &ul) < 0)
131 return -1;
132 *u = ul;
133 return 0;
134 }
135 werrstr("bad location for lget8");
136 return -1;
137}
138
139int
140lput1(Map *map, Regs *regs, Loc loc, uchar *a, uint n)
141{
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;
149}
150
151int
152lput2(Map *map, Regs *regs, Loc loc, u16int u)
153{
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;
162}
163
164int
165lput4(Map *map, Regs *regs, Loc loc, u32int u)
166{
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;
175}
176
177int
178lput8(Map *map, Regs *regs, Loc loc, u64int u)
179{
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;
188}
189
190Loc
rsc4f0073f2004-06-11 12:52:08 +0000191locaddr(ulong addr)
rsca84cbb22004-04-19 19:29:25 +0000192{
193 Loc l;
194
195 l.type = LADDR;
196 l.addr = addr;
197 return l;
198}
199
200Loc
rsc4f0073f2004-06-11 12:52:08 +0000201locindir(char *reg, long offset)
rsca84cbb22004-04-19 19:29:25 +0000202{
203 Loc l;
204
205 l.type = LOFFSET;
206 l.reg = reg;
207 l.offset = offset;
rsc3c47d762005-07-13 23:01:04 +0000208 l.addr = 0; /* SHUT UP GCC 4.0 */
rsca84cbb22004-04-19 19:29:25 +0000209 return l;
210}
211
212Loc
rsc4f0073f2004-06-11 12:52:08 +0000213locconst(ulong con)
rsca84cbb22004-04-19 19:29:25 +0000214{
215 Loc l;
216
217 l.type = LCONST;
218 l.addr = con;
219 return l;
220}
221
222Loc
223locnone(void)
224{
225 Loc l;
226
227 l.type = LNONE;
228 return l;
229}
230
231Loc
232locreg(char *reg)
233{
234 Loc l;
235
236 l.type = LREG;
237 l.reg = reg;
238 return l;
239}
240
241int
242locsimplify(Map *map, Regs *regs, Loc loc, Loc *newloc)
243{
244 ulong u;
245
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;
253}
254