Mercurial > hg-old > index.cgi
annotate src/index.c @ 8:f1df096aa76f 1.1
Tagged 1.1 bugfix release
author | lost |
---|---|
date | Sun, 04 Jan 2009 05:46:07 +0000 |
parents | 34568fab6058 |
children |
rev | line source |
---|---|
0 | 1 /* |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
2 index.c, Copyright © 2008 William Astle |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
3 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
4 This file is part of LWASM. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
5 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
6 LWASM is free software: you can redistribute it and/or modify it under the |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
7 terms of the GNU General Public License as published by the Free Software |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
8 Foundation, either version 3 of the License, or (at your option) any later |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
9 version. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
10 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
11 This program is distributed in the hope that it will be useful, but WITHOUT |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
14 more details. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
15 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
16 You should have received a copy of the GNU General Public License along with |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
17 this program. If not, see <http://www.gnu.org/licenses/>. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
18 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
19 Contains code for parsing indexed addressing modes |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
20 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
21 */ |
0 | 22 |
23 #include <ctype.h> | |
24 //#include <errno.h> | |
25 //#include <stdio.h> | |
26 //#include <stdlib.h> | |
27 #include <string.h> | |
28 #define __index_c_seen__ | |
29 //#include "instab.h" | |
30 #include "lwasm.h" | |
31 #include "instab.h" | |
32 | |
33 | |
34 int parse_index_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *postbyte, int *opmode, int *v1) | |
35 { | |
36 static const char *regs = "X Y U S W PCRPC "; | |
37 static const struct { char *opstr; int pb; } simpleindex[] = | |
38 { | |
39 {",x", 0x84}, {",y", 0xa4}, {",u", 0xc4}, {",s", 0xe4}, | |
40 {",x+", 0x80}, {",y+", 0xa0}, {",u+", 0xc0}, {",s+", 0xe0}, | |
41 {",x++", 0x81}, {",y++", 0xa1}, {",u++", 0xc1}, {",s++", 0xe1}, | |
42 {",-x", 0x82}, {",-y", 0xa2}, {",-u", 0xc2}, {",-s", 0xe2}, | |
43 {",--x", 0x83}, {",--y", 0xa3}, {",--u", 0xc3}, {",--s", 0xe3}, | |
44 {"a,x", 0x86}, {"a,y", 0xa6}, {"a,u", 0xc6}, {"a,s", 0xe6}, | |
45 {"b,x", 0x85}, {"b,y", 0xa5}, {"b,u", 0xc5}, {"b,s", 0xe5}, | |
46 {"e,x", 0x87}, {"e,y", 0xa7}, {"e,u", 0xc7}, {"e,s", 0xe7}, | |
47 {"f,x", 0x8a}, {"f,y", 0xaa}, {"f,u", 0xca}, {"f,s", 0xea}, | |
48 {"d,x", 0x8b}, {"d,y", 0xab}, {"d,u", 0xcb}, {"d,s", 0xed}, | |
49 {"w,x", 0x8e}, {"w,y", 0xae}, {"w,u", 0xce}, {"w,s", 0xee}, | |
50 {",w", 0x8f}, {",w++", 0xcf}, {",--w", 0xef}, | |
51 | |
52 {"[,x]", 0x94}, {"[,y]", 0xb4}, {"[,u", 0xd4}, {"[,s]", 0xf4}, | |
53 {"[,x++]", 0x91}, {"[,y++]", 0xb1}, {"[,u++]", 0xd1}, {"[,s++]", 0xf1}, | |
54 {"[,--x]", 0x93}, {"[,--y]", 0xb3}, {"[,--u]", 0xd3}, {"[,--s]", 0xf3}, | |
55 {"[a,x]", 0x96}, {"[a,y]", 0xb6}, {"[a,u]", 0xd6}, {"[a,s]", 0xf6}, | |
56 {"[b,x]", 0x95}, {"[b,y]", 0xb5}, {"[b,u]", 0xd5}, {"[b,s]", 0xf5}, | |
57 {"[e,x]", 0x97}, {"[e,y]", 0xb7}, {"[e,u]", 0xd7}, {"[e,s]", 0xf7}, | |
58 {"[f,x]", 0x9a}, {"[f,y]", 0xba}, {"[f,u]", 0xda}, {"[f,s]", 0xfa}, | |
59 {"[d,x]", 0x9b}, {"[d,y]", 0xbb}, {"[d,u]", 0xdb}, {"[d,s]", 0xfd}, | |
60 {"[w,x]", 0x9e}, {"[w,y]", 0xbe}, {"[w,u]", 0xde}, {"[w,s]", 0xfe}, | |
61 {"[,w]", 0x90}, {"[,w++]", 0xd0}, {"[,--w]", 0xf0}, | |
62 | |
63 { "", -1 } | |
64 }; | |
65 char stbuf[25]; | |
66 int i; | |
67 int f8 = 0, f16 = 0; | |
68 int rn; | |
69 int indir = 0; | |
70 int rval; | |
71 int f0 = 0; | |
72 | |
73 for (i = 0; i < 24; i++) | |
74 { | |
75 if (*((*optr) + i) && !isspace(*((*optr) + i))) | |
76 stbuf[i] = *((*optr) + i); | |
77 else | |
78 break; | |
79 } | |
80 stbuf[i] = '\0'; | |
81 if (!*((*optr) + i) || isspace(*((*optr) + i))) | |
82 { | |
83 int j; | |
84 // do simple lookup | |
85 for (j = 0; simpleindex[j].opstr[0]; j++) | |
86 { | |
87 if (!strcasecmp(stbuf, simpleindex[j].opstr)) | |
88 break; | |
89 } | |
90 if (simpleindex[j].opstr[0]) | |
91 { | |
92 *postbyte = simpleindex[j].pb; | |
93 *opmode = OPER_INDEX; | |
94 (*optr) += i; | |
95 return 0; | |
96 } | |
97 } | |
98 | |
99 // now we have the hard ones to work out here | |
100 | |
101 if (**optr == '[') | |
102 { | |
103 indir = 1; | |
104 (*optr)++; | |
105 } | |
106 | |
107 rn = 0; | |
108 for (i = 0; (*optr)[i] && !isspace((*optr)[i]); i++) | |
109 { | |
110 if ((*optr)[i] == ',') | |
111 { | |
112 rn = 1; | |
113 break; | |
114 } | |
115 } | |
116 | |
117 if (!rn && indir) | |
118 { | |
119 // extended indir | |
120 *postbyte = 0x9f; | |
121 *opmode = OPER_EXTIND; | |
122 rval = eval_expr(as, cl, optr, v1); | |
123 if (**optr != ']') | |
124 { | |
125 errorp1(ERR_BADOPER); | |
126 } | |
127 (*optr)++; | |
128 return 0; | |
129 } | |
130 | |
131 if (cl -> p1f16) | |
132 f16 = 1; | |
133 if (**optr == '<') | |
134 { | |
135 f8 = 1; | |
136 (*optr)++; | |
137 } | |
138 else if (**optr == '>') | |
139 { | |
140 f16 = 1; | |
141 (*optr)++; | |
142 } | |
143 | |
144 if (**optr == '0' && *(*optr+1) == ',') | |
145 { | |
146 f0 = 1; | |
147 } | |
148 | |
149 // now we have to evaluate the expression | |
150 rval = eval_expr(as, cl, optr, v1); | |
151 | |
152 if (cl -> undef && as -> passnum == 1) | |
153 { | |
154 cl -> p1f16 = 1; | |
155 f16 = 1; | |
156 } | |
157 | |
158 // now look for a comma; if not present, explode | |
159 if (rval == -1 || *(*optr)++ != ',') | |
160 { | |
161 // syntax error; force 0 bit | |
162 *postbyte = -1; | |
163 *opmode = OPER_INDEX; | |
164 return -2; | |
165 } | |
166 | |
167 // now get the register | |
168 rn = lookupreg3(regs, optr); | |
169 if (rn < 0) | |
170 goto reterr; | |
171 | |
172 // debug("Reg: %d\n", rn); | |
173 | |
174 if (indir && **optr != ']') | |
175 goto reterr; | |
176 else | |
177 (*optr)++; | |
178 | |
179 // nnnn,W is only 16 bit | |
180 if (rn == 4) | |
181 { | |
182 if (f8) | |
183 goto reterr; | |
184 if (!f16 && !f0 && !(as -> pragmas & PRAGMA_NOINDEX0TONONE) && *v1 == 0) | |
185 { | |
186 *opmode = OPER_INDEX; | |
187 if (indir) | |
188 *postbyte = 0x90; | |
189 else | |
190 *postbyte = 0x8f; | |
191 return 0; | |
192 } | |
193 *opmode = OPER_INDEX16; | |
194 if (indir) | |
195 *postbyte = 0xb0; | |
196 else | |
197 *postbyte = 0xcf; | |
198 return 0; | |
199 } | |
200 | |
201 if (indir) indir = 0x10; | |
202 | |
203 // forward ref; we can't figure anything | |
204 if (cl -> undef) | |
205 { | |
206 f16 = 1; | |
207 } | |
208 | |
209 // PCR? redo v1, v2 relative to current address | |
210 if (rn == 5) | |
211 { | |
212 *v1 -= as -> addr; | |
213 | |
214 // we have a slight problem here | |
215 // PCR based on current insn loc is really | |
216 // -125 <= offset <= +130 (8 bit offset) | |
217 if (f8 || (!f16 && *v1 >= -125 && *v1 <= 130)) | |
218 { | |
219 *opmode = OPER_INDEX8; | |
220 *postbyte = indir | 0x8C; | |
221 *v1 -= 3; | |
222 if (*v1 < -128 || *v1 > 127) | |
223 errorp2(ERR_OVERFLOW); | |
224 return 0; | |
225 } | |
226 | |
227 // anything else is 16 bit offset | |
228 // need 16 bit | |
229 *opmode = OPER_INDEX16; | |
230 *postbyte = indir | 0x8D; | |
231 *v1 -= 4; | |
232 return 0; | |
233 } | |
234 | |
235 // constant offset from PC | |
236 if (rn == 6) | |
237 { | |
238 if (f8 || (!f16 && *v1 >= -128 && *v1 <= 127)) | |
239 { | |
240 *opmode = OPER_INDEX8; | |
241 *postbyte = indir | 0x8C; | |
242 if (*v1 < -128 || *v1 > 127) | |
243 errorp2(ERR_OVERFLOW); | |
244 return 0; | |
245 } | |
246 | |
247 // everything else must be 16 bit | |
248 // need 16 bit | |
249 *opmode = OPER_INDEX16; | |
250 *postbyte = indir | 0x8D; | |
251 return 0; | |
252 | |
253 } | |
254 | |
255 // we only have to deal with x,y,u,s here | |
256 if (!f8 && !f16 && *v1 >= -16 && *v1 <= 15) | |
257 { | |
258 if (*v1 == 0 && !f0 && !(as -> pragmas & PRAGMA_NOINDEX0TONONE)) | |
259 { | |
260 *postbyte = rn << 5 | indir | 0x80 | 0x04; | |
261 *opmode = OPER_INDEX; | |
262 return 0; | |
263 } | |
264 // we pick the smallest value here | |
265 if (indir) | |
266 { | |
267 f8 = 1; | |
268 goto no5bit; | |
269 } | |
270 *postbyte = rn << 5 | (*v1 & 0x1F); | |
271 *opmode = OPER_INDEX5; | |
272 return 0; | |
273 } | |
274 no5bit: | |
275 if (f16 || (!f8 && (*v1 < -128 || *v1 > 127))) | |
276 { | |
277 // must be a 16 bit offset here | |
278 *postbyte = rn << 5 | indir | 0x80 | 0x09; | |
279 *opmode = OPER_INDEX16; | |
280 return 0; | |
281 } | |
282 | |
283 // if we're here, we have an 8 bit offset | |
284 *postbyte = rn << 5 | indir | 0x80 | 0x08; | |
285 *opmode = OPER_INDEX8; | |
286 if (*v1 < -128 || *v1 > 127) | |
287 errorp2(ERR_OVERFLOW); | |
288 return 0; | |
289 reterr: | |
290 *postbyte = -1; | |
291 *opmode = OPER_INDEX; | |
292 return -2; | |
293 } | |
294 | |
295 void insn_indexed_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3) | |
296 { | |
297 int rval; | |
298 int v1, pb = -1; | |
299 | |
300 *b1 = *b2 = *b3 = -1; | |
301 | |
302 rval = parse_index_expr(as, cl, optr, &pb, &(cl -> addrmode), &v1); | |
303 if (rval < 0) | |
304 errorp1(ERR_BADOPER); | |
305 *b1 = pb; | |
306 | |
307 if (cl -> addrmode == OPER_INDEX8) | |
308 { | |
309 *b2 = v1 & 0xff; | |
310 } | |
311 else if (cl -> addrmode == OPER_INDEX16 || cl -> addrmode == OPER_EXTIND) | |
312 { | |
313 *b2 = (v1 & 0xffff) >> 8; | |
314 *b3 = v1 & 0xff; | |
315 } | |
316 } | |
317 | |
318 void insn_indexed(asmstate_t *as, sourceline_t *cl, char **optr) | |
319 { | |
320 int b1, b2, b3; | |
321 | |
322 emitop(instab[cl -> opcode].ops[0]); | |
323 insn_indexed_aux(as, cl, optr, &b1, &b2, &b3); | |
324 if (b1 != -1) | |
325 emit(b1); | |
326 if (b2 != -1) | |
327 emit(b2); | |
328 if (b3 != -1) | |
329 emit(b3); | |
330 } | |
331 |