Mercurial > hg-old > index.cgi
annotate src/pseudo.c @ 74:c8c772ef5df9
Checkpointing object target implementation
author | lost |
---|---|
date | Thu, 08 Jan 2009 01:18:40 +0000 |
parents | 31d8e85706e7 |
children | 121bf4a588ea |
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 pseudo.c |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
3 Copyright © 2009 William Astle |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
4 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
5 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
|
6 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
7 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
|
8 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
|
9 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
|
10 version. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
11 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
12 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
|
13 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
|
14 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
|
15 more details. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
16 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
17 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
|
18 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
|
19 |
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 This file implements the various pseudo operations. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
22 */ |
0 | 23 |
24 #include <stdlib.h> | |
50 | 25 #include <string.h> |
0 | 26 #include "lwasm.h" |
27 #include "instab.h" | |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
28 #include "expr.h" |
52 | 29 #include "util.h" |
0 | 30 |
52 | 31 extern int lwasm_read_file(asmstate_t *as, const char *filename); |
0 | 32 |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
33 OPFUNC(pseudo_org) |
0 | 34 { |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
35 int rval; |
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
36 lwasm_expr_stack_t *s; |
52 | 37 |
74 | 38 if (as -> csect) |
39 { | |
40 register_error(as, l, 1, "ORG not allowed within sections"); | |
41 return; | |
42 } | |
43 | |
52 | 44 if (as -> passnum != 1) |
45 { | |
46 // org is not needed to be processed on pass 2 | |
47 // this will prevent phasing errors for forward references that | |
48 // resolve on the second pass | |
49 // we saved the org address in l -> codeaddr on pass 1 | |
50 as -> addr = l -> codeaddr; | |
51 return; | |
52 } | |
0 | 53 |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
54 if (l -> sym) |
0 | 55 { |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
56 register_error(as, l, 1, "No symbol allowed with ORG"); |
0 | 57 } |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
58 s = lwasm_evaluate_expr(as, l, *p, NULL); |
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
59 if (!s) |
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
60 { |
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
61 register_error(as, l, 1, "Bad expression"); |
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
62 return; |
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
63 } |
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
64 if (!lwasm_expr_is_constant(s)) |
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
65 { |
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
66 register_error(as, l, 1, "Illegal incomplete reference (pass 1)"); |
50 | 67 lwasm_expr_stack_free(s); |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
68 return; |
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
69 } |
49
21ae0fab469b
Added needed infra for useful listing of EQU and ORG type statements
lost
parents:
47
diff
changeset
|
70 rval = lwasm_expr_get_value(s) & 0xffff; |
50 | 71 lwasm_expr_stack_free(s); |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
72 l -> codeaddr = rval; |
49
21ae0fab469b
Added needed infra for useful listing of EQU and ORG type statements
lost
parents:
47
diff
changeset
|
73 l -> addrset = 1; |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
74 as -> addr = rval; |
0 | 75 } |
76 | |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
77 /* |
52 | 78 The operand for include is a string optionally enclosed in " |
79 */ | |
80 OPFUNC(pseudo_include) | |
0 | 81 { |
82 int v1; | |
52 | 83 char *fn; |
57 | 84 |
52 | 85 // only include files on pass 1 |
86 // but make sure local include context is right | |
87 // for the next line... | |
0 | 88 if (as -> passnum != 1) |
52 | 89 { |
57 | 90 as -> context = lwasm_next_context(as); |
0 | 91 return; |
52 | 92 } |
93 | |
94 while (**p && isspace(**p)) | |
95 (*p)++; | |
96 | |
97 if (!**p) | |
0 | 98 { |
52 | 99 register_error(as, l, 1, "Bad file name"); |
0 | 100 return; |
101 } | |
52 | 102 |
103 if (**p == '"') | |
104 { | |
105 // search for ending " | |
106 (*p)++; | |
107 for (v1 = 0; *((*p)+v1) && *((*p)+v1) != '"'; v1++) | |
108 /* do nothing */ ; | |
109 if (*((*p)+v1) != '"') | |
110 { | |
111 register_error(as, l, 1, "Bad file name"); | |
112 return; | |
113 } | |
114 } | |
115 else | |
0 | 116 { |
52 | 117 // search for a space type character |
118 for (v1 = 0; *((*p)+v1) && !isspace(*((*p)+v1)); v1++) | |
119 ; | |
0 | 120 } |
52 | 121 |
122 fn = lwasm_alloc(v1 + 1); | |
123 memcpy(fn, *p, v1); | |
124 fn[v1] = '\0'; | |
125 | |
126 // end local label context on include | |
57 | 127 as -> context = lwasm_next_context(as); |
52 | 128 if (lwasm_read_file(as, fn) < 0) |
129 { | |
130 register_error(as, l, 1, "File include error (%s)", fn); | |
131 } | |
132 lwasm_free(fn); | |
0 | 133 } |
134 | |
50 | 135 OPFUNC(pseudo_rmb) |
0 | 136 { |
50 | 137 int rval; |
138 lwasm_expr_stack_t *s; | |
0 | 139 |
50 | 140 s = lwasm_evaluate_expr(as, l, *p, NULL); |
141 if (!s) | |
0 | 142 { |
50 | 143 register_error(as, l, 1, "Bad expression"); |
0 | 144 return; |
145 } | |
50 | 146 if (!lwasm_expr_is_constant(s)) |
0 | 147 { |
50 | 148 register_error(as, l, 1, "Illegal incomplete reference (pass 1)"); |
149 lwasm_expr_stack_free(s); | |
0 | 150 return; |
151 } | |
50 | 152 rval = lwasm_expr_get_value(s); |
153 lwasm_expr_stack_free(s); | |
154 l -> nocodelen = rval; | |
155 as -> addr += rval; | |
0 | 156 } |
53 | 157 |
158 OPFUNC(pseudo_rmd) | |
0 | 159 { |
53 | 160 int rval; |
161 lwasm_expr_stack_t *s; | |
0 | 162 |
53 | 163 s = lwasm_evaluate_expr(as, l, *p, NULL); |
164 if (!s) | |
0 | 165 { |
53 | 166 register_error(as, l, 1, "Bad expression"); |
0 | 167 return; |
168 } | |
53 | 169 if (!lwasm_expr_is_constant(s)) |
0 | 170 { |
53 | 171 register_error(as, l, 1, "Illegal incomplete reference (pass 1)"); |
172 lwasm_expr_stack_free(s); | |
0 | 173 return; |
174 } | |
53 | 175 rval = lwasm_expr_get_value(s) * 2; |
176 lwasm_expr_stack_free(s); | |
177 l -> nocodelen = rval; | |
178 as -> addr += rval; | |
0 | 179 } |
180 | |
53 | 181 OPFUNC(pseudo_rmq) |
0 | 182 { |
53 | 183 int rval; |
184 lwasm_expr_stack_t *s; | |
0 | 185 |
53 | 186 s = lwasm_evaluate_expr(as, l, *p, NULL); |
187 if (!s) | |
0 | 188 { |
53 | 189 register_error(as, l, 1, "Bad expression"); |
0 | 190 return; |
191 } | |
53 | 192 if (!lwasm_expr_is_constant(s)) |
0 | 193 { |
53 | 194 register_error(as, l, 1, "Illegal incomplete reference (pass 1)"); |
195 lwasm_expr_stack_free(s); | |
0 | 196 return; |
197 } | |
53 | 198 rval = lwasm_expr_get_value(s) * 4; |
199 lwasm_expr_stack_free(s); | |
200 l -> nocodelen = rval; | |
201 as -> addr += rval; | |
0 | 202 } |
203 | |
53 | 204 OPFUNC(pseudo_zmb) |
0 | 205 { |
53 | 206 int rval; |
207 lwasm_expr_stack_t *s; | |
0 | 208 |
53 | 209 s = lwasm_evaluate_expr(as, l, *p, NULL); |
210 if (!s) | |
0 | 211 { |
53 | 212 register_error(as, l, 1, "Bad expression"); |
0 | 213 return; |
214 } | |
53 | 215 if (!lwasm_expr_is_constant(s)) |
0 | 216 { |
53 | 217 register_error(as, l, 1, "Illegal incomplete reference (pass 1)"); |
218 lwasm_expr_stack_free(s); | |
0 | 219 return; |
220 } | |
53 | 221 rval = lwasm_expr_get_value(s); |
222 lwasm_expr_stack_free(s); | |
223 while (rval-- > 0) | |
0 | 224 { |
53 | 225 lwasm_emit(as, l, 0); |
0 | 226 } |
227 } | |
228 | |
53 | 229 OPFUNC(pseudo_zmd) |
0 | 230 { |
53 | 231 int rval; |
232 lwasm_expr_stack_t *s; | |
0 | 233 |
53 | 234 s = lwasm_evaluate_expr(as, l, *p, NULL); |
235 if (!s) | |
0 | 236 { |
53 | 237 register_error(as, l, 1, "Bad expression"); |
0 | 238 return; |
239 } | |
53 | 240 if (!lwasm_expr_is_constant(s)) |
0 | 241 { |
53 | 242 register_error(as, l, 1, "Illegal incomplete reference (pass 1)"); |
243 lwasm_expr_stack_free(s); | |
0 | 244 return; |
245 } | |
53 | 246 rval = lwasm_expr_get_value(s); |
247 lwasm_expr_stack_free(s); | |
248 while (rval-- > 0) | |
0 | 249 { |
53 | 250 lwasm_emit(as, l, 0); |
251 lwasm_emit(as, l, 0); | |
0 | 252 } |
253 } | |
254 | |
53 | 255 OPFUNC(pseudo_zmq) |
256 { | |
257 int rval; | |
258 lwasm_expr_stack_t *s; | |
259 | |
260 s = lwasm_evaluate_expr(as, l, *p, NULL); | |
261 if (!s) | |
262 { | |
263 register_error(as, l, 1, "Bad expression"); | |
264 return; | |
265 } | |
266 if (!lwasm_expr_is_constant(s)) | |
267 { | |
268 register_error(as, l, 1, "Illegal incomplete reference (pass 1)"); | |
269 lwasm_expr_stack_free(s); | |
270 return; | |
271 } | |
272 rval = lwasm_expr_get_value(s); | |
273 lwasm_expr_stack_free(s); | |
274 while (rval-- > 0) | |
275 { | |
276 lwasm_emit(as, l, 0); | |
277 lwasm_emit(as, l, 0); | |
278 lwasm_emit(as, l, 0); | |
279 lwasm_emit(as, l, 0); | |
280 } | |
281 } | |
282 | |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
283 OPFUNC(pseudo_end) |
0 | 284 { |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
285 int rval; |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
286 lwasm_expr_stack_t *s; |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
287 |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
288 |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
289 as -> endseen = 1; |
0 | 290 |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
291 // address only matters for DECB output |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
292 if (as -> outformat != OUTPUT_DECB) |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
293 return; |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
294 |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
295 s = lwasm_evaluate_expr(as, l, *p, NULL); |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
296 if (!s) |
0 | 297 { |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
298 register_error(as, l, 1, "Bad expression"); |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
299 return; |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
300 } |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
301 if (!lwasm_expr_is_constant(s)) |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
302 { |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
303 register_error(as, l, 2, "Incomplete reference"); |
0 | 304 } |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
305 rval = lwasm_expr_get_value(s); |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
306 lwasm_expr_stack_free(s); |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
307 |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
308 rval = rval & 0xffff; |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
309 if (as -> passnum == 2) |
0 | 310 { |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
311 as -> execaddr = rval; |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
312 l -> symaddr = rval; |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
313 l -> addrset = 2; |
0 | 314 } |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
315 } |
0 | 316 |
56 | 317 |
318 OPFUNC(pseudo_align) | |
0 | 319 { |
56 | 320 int rval; |
321 lwasm_expr_stack_t *s; | |
0 | 322 int cn; |
323 | |
56 | 324 if (as -> passnum == 2) |
0 | 325 { |
56 | 326 while (as -> addr < l -> symaddr) |
327 lwasm_emit(as, l, 0); | |
328 return; | |
329 } | |
330 | |
331 s = lwasm_evaluate_expr(as, l, *p, NULL); | |
332 if (!s) | |
333 { | |
334 register_error(as, l, 1, "Bad expression"); | |
0 | 335 return; |
336 } | |
56 | 337 if (!lwasm_expr_is_constant(s)) |
338 { | |
339 register_error(as, l, 1, "Illegal incomplete reference (pass 1)"); | |
340 } | |
341 rval = lwasm_expr_get_value(s); | |
342 lwasm_expr_stack_free(s); | |
0 | 343 |
56 | 344 if (rval < 1) |
0 | 345 { |
56 | 346 register_error(as, l, 1, "Illegal alignment %d", rval); |
347 return; | |
0 | 348 } |
56 | 349 |
350 cn = l -> codeaddr % rval; | |
351 if (cn) | |
352 cn = rval - cn; | |
353 | |
354 while (cn--) | |
355 { | |
356 lwasm_emit(as, l, 0); | |
357 } | |
358 l -> symaddr = as -> addr; | |
0 | 359 } |
56 | 360 |
50 | 361 OPFUNC(pseudo_equ) |
0 | 362 { |
50 | 363 int rval; |
52 | 364 |
365 // equ is not needed to be processed on pass 2 | |
366 if (as -> passnum != 1) | |
367 return; | |
368 | |
50 | 369 if (l -> sym == NULL) |
0 | 370 { |
50 | 371 register_error(as, l, 1, "No symbol specified"); |
0 | 372 return; |
373 } | |
50 | 374 |
63
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
375 if (lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &rval) < 0) |
50 | 376 rval = 0; |
63
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
377 |
50 | 378 l -> symaddr = rval & 0xFFFF; |
379 l -> addrset = 2; | |
63
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
380 |
64 | 381 lwasm_register_symbol(as, l, l -> sym, rval, SYMBOL_NORM); |
0 | 382 } |
63
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
383 |
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
384 OPFUNC(pseudo_set) |
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
385 { |
64 | 386 int rval; |
387 | |
388 // set MUST run on both passes as the symbol value changes! | |
389 | |
390 if (l -> sym == NULL) | |
391 { | |
392 register_error(as, l, 1, "No symbol specified"); | |
393 return; | |
394 } | |
395 | |
396 if (lwasm_expr_result(as, l, p, EXPR_PASS1CONST | EXPR_PASS2CONST, &rval) < 0) | |
397 rval = 0; | |
398 | |
399 l -> symaddr = rval & 0xFFFF; | |
400 l -> addrset = 2; | |
401 | |
402 lwasm_register_symbol(as, l, l -> sym, rval, SYMBOL_SET); | |
63
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
403 } |
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
404 |
65
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
405 OPFUNC(pseudo_setdp) |
0 | 406 { |
65
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
407 int rval; |
0 | 408 |
65
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
409 // setdp is needed on both passes |
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
410 if (lwasm_expr_result(as, l, p, EXPR_PASS1CONST | EXPR_PASS2CONST | EXPR_BYTE, &rval) < 0) |
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
411 rval = 0; |
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
412 |
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
413 l -> symaddr = rval & 0xFF; |
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
414 l -> addrset = 2; |
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
415 |
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
416 as -> dpval = rval & 0xFF; |
0 | 417 } |
418 | |
56 | 419 OPFUNC(pseudo_fcc) |
420 { | |
0 | 421 int delim = 0; |
422 | |
56 | 423 delim = **p; |
0 | 424 if (!delim) |
425 { | |
56 | 426 register_error(as, l, 1, "Bad operand"); |
427 return; | |
0 | 428 } |
56 | 429 *p += 1; |
430 while (**p && **p != delim) | |
0 | 431 { |
56 | 432 lwasm_emit(as, l, **p); |
433 (*p)++; | |
0 | 434 } |
56 | 435 if (**p) |
436 (*p)++; | |
0 | 437 } |
438 | |
56 | 439 |
440 OPFUNC(pseudo_fcs) | |
0 | 441 { |
442 int delim = 0; | |
56 | 443 |
444 delim = **p; | |
0 | 445 if (!delim) |
446 { | |
56 | 447 register_error(as, l, 1, "Bad operand"); |
448 return; | |
0 | 449 } |
56 | 450 *p += 1; |
451 while (**p && **p != delim) | |
0 | 452 { |
56 | 453 if (!*((*p) + 1) || *((*p) + 1) == delim) |
454 lwasm_emit(as, l, **p | 0x80); | |
455 else | |
456 lwasm_emit(as, l, **p); | |
457 (*p)++; | |
0 | 458 } |
56 | 459 if (**p) |
460 (*p)++; | |
0 | 461 } |
462 | |
56 | 463 OPFUNC(pseudo_fcn) |
0 | 464 { |
465 int delim = 0; | |
466 | |
56 | 467 delim = **p; |
0 | 468 if (!delim) |
469 { | |
56 | 470 register_error(as, l, 1, "Bad operand"); |
471 return; | |
0 | 472 } |
56 | 473 *p += 1; |
474 while (**p && **p != delim) | |
0 | 475 { |
56 | 476 lwasm_emit(as, l, **p); |
477 (*p)++; | |
0 | 478 } |
56 | 479 if (**p) |
480 (*p)++; | |
481 lwasm_emit(as, l, 0); | |
0 | 482 } |
56 | 483 |
484 OPFUNC(pseudo_fcb) | |
0 | 485 { |
56 | 486 int v1; |
0 | 487 |
488 fcb_again: | |
56 | 489 if (lwasm_expr_result(as, l, p, EXPR_PASS2CONST | EXPR_BYTE, &v1) < 0) |
490 return; | |
491 | |
492 lwasm_emit(as, l, v1); | |
493 if (**p == ',') | |
0 | 494 { |
56 | 495 (*p)++; |
0 | 496 goto fcb_again; |
497 } | |
498 } | |
499 | |
56 | 500 OPFUNC(pseudo_fdb) |
0 | 501 { |
56 | 502 int v1; |
0 | 503 |
504 fdb_again: | |
56 | 505 if (lwasm_expr_result(as, l, p, EXPR_PASS2CONST, &v1) < 0) |
506 return; | |
507 | |
508 lwasm_emit(as, l, v1 >> 8); | |
509 lwasm_emit(as, l, v1 & 0xff); | |
510 if (**p == ',') | |
0 | 511 { |
56 | 512 (*p)++; |
0 | 513 goto fdb_again; |
514 } | |
515 } | |
516 | |
56 | 517 OPFUNC(pseudo_fqb) |
0 | 518 { |
56 | 519 int v1; |
520 | |
0 | 521 fqb_again: |
56 | 522 if (lwasm_expr_result(as, l, p, EXPR_PASS2CONST, &v1) < 0) |
523 return; | |
524 | |
525 lwasm_emit(as, l, v1 >> 24); | |
526 lwasm_emit(as, l, v1 >> 16); | |
527 lwasm_emit(as, l, v1 >> 8); | |
528 lwasm_emit(as, l, v1 & 0xff); | |
529 if (**p == ',') | |
0 | 530 { |
56 | 531 (*p)++; |
0 | 532 goto fqb_again; |
533 } | |
534 } | |
535 | |
536 // don't need to do anything if we are executing one of these | |
57 | 537 OPFUNC(pseudo_endc) |
0 | 538 { |
57 | 539 if (as -> skipcond && !(as -> skipmacro)) |
540 { | |
541 as -> skipcount -= 1; | |
542 if (as -> skipcount <= 0) | |
543 { | |
544 as -> skipcond = 0; | |
545 } | |
546 } | |
0 | 547 return; |
548 } | |
549 | |
550 // if "else" executes, we must be going into an "ignore" state | |
57 | 551 OPFUNC(pseudo_else) |
0 | 552 { |
57 | 553 if (as -> skipmacro) |
554 return; | |
555 | |
556 if (as -> skipcond) | |
557 { | |
558 if (as -> skipcount == 1) | |
559 { | |
560 as -> skipcount = 0; | |
561 as -> skipcond = 0; | |
562 } | |
563 return; | |
564 } | |
565 | |
0 | 566 as -> skipcond = 1; |
567 as -> skipcount = 1; | |
568 } | |
569 | |
57 | 570 OPFUNC(pseudo_ifne) |
0 | 571 { |
572 int v1; | |
573 int rval; | |
57 | 574 |
575 if (as -> skipcond && !(as -> skipmacro)) | |
0 | 576 { |
57 | 577 as -> skipcount++; |
578 return; | |
579 } | |
580 | |
581 rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1); | |
582 if (rval < 0) | |
583 return; | |
584 if (!v1) | |
585 { | |
586 as -> skipcond = 1; | |
587 as -> skipcount = 1; | |
0 | 588 } |
589 } | |
57 | 590 |
591 OPFUNC(pseudo_ifeq) | |
0 | 592 { |
593 int v1; | |
594 int rval; | |
57 | 595 |
596 if (as -> skipcond && !(as -> skipmacro)) | |
0 | 597 { |
57 | 598 as -> skipcount++; |
599 return; | |
0 | 600 } |
57 | 601 |
602 rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1); | |
603 if (rval < 0) | |
604 return; | |
605 if (v1) | |
0 | 606 { |
57 | 607 as -> skipcond = 1; |
608 as -> skipcount = 1; | |
0 | 609 } |
610 } | |
57 | 611 |
612 OPFUNC(pseudo_iflt) | |
0 | 613 { |
614 int v1; | |
615 int rval; | |
57 | 616 |
617 if (as -> skipcond && !(as -> skipmacro)) | |
0 | 618 { |
57 | 619 as -> skipcount++; |
620 return; | |
0 | 621 } |
57 | 622 |
623 rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1); | |
624 if (rval < 0) | |
625 return; | |
626 if (v1 >= 0) | |
0 | 627 { |
57 | 628 as -> skipcond = 1; |
629 as -> skipcount = 1; | |
0 | 630 } |
631 } | |
57 | 632 |
633 OPFUNC(pseudo_ifle) | |
0 | 634 { |
635 int v1; | |
636 int rval; | |
57 | 637 |
638 if (as -> skipcond && !(as -> skipmacro)) | |
0 | 639 { |
57 | 640 as -> skipcount++; |
641 return; | |
0 | 642 } |
57 | 643 |
644 rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1); | |
645 if (rval < 0) | |
646 return; | |
647 if (v1 > 0) | |
0 | 648 { |
57 | 649 as -> skipcond = 1; |
650 as -> skipcount = 1; | |
0 | 651 } |
652 } | |
57 | 653 |
654 OPFUNC(pseudo_ifgt) | |
0 | 655 { |
656 int v1; | |
657 int rval; | |
57 | 658 |
659 if (as -> skipcond && !(as -> skipmacro)) | |
0 | 660 { |
57 | 661 as -> skipcount++; |
662 return; | |
0 | 663 } |
57 | 664 |
665 rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1); | |
666 if (rval < 0) | |
667 return; | |
668 if (v1 <= 0) | |
0 | 669 { |
57 | 670 as -> skipcond = 1; |
671 as -> skipcount = 1; | |
0 | 672 } |
673 } | |
57 | 674 |
675 OPFUNC(pseudo_ifge) | |
0 | 676 { |
677 int v1; | |
678 int rval; | |
57 | 679 |
680 if (as -> skipcond && !(as -> skipmacro)) | |
0 | 681 { |
57 | 682 as -> skipcount++; |
683 return; | |
0 | 684 } |
57 | 685 |
686 rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1); | |
687 if (rval < 0) | |
688 return; | |
689 if (v1 < 0) | |
0 | 690 { |
57 | 691 as -> skipcond = 1; |
692 as -> skipcount = 1; | |
0 | 693 } |
694 } | |
695 | |
56 | 696 OPFUNC(pseudo_error) |
0 | 697 { |
56 | 698 register_error(as, l, 1, "User error: %s", *p); |
0 | 699 } |
56 | 700 |
74 | 701 |
702 OPFUNC(pseudo_section) | |
703 { | |
704 sectiontab_t *s; | |
705 char *p2; | |
706 char *sn; | |
707 char *opts; | |
708 | |
709 | |
710 if (as -> outformat != OUTPUT_OBJ) | |
711 { | |
712 register_error(as, l, 1, "Sections only supported for obj target"); | |
713 return; | |
714 } | |
715 | |
716 if (as -> csect) | |
717 { | |
718 as -> csect -> offset = as -> addr; | |
719 as -> csect = NULL; | |
720 } | |
721 | |
722 if (!**p) | |
723 { | |
724 register_error(as, l, 1, "Need section name"); | |
725 return; | |
726 } | |
727 | |
728 for (p2 = *p; *p2 && !isspace(*p2); p2++) | |
729 /* do nothing */ ; | |
730 | |
731 sn = lwasm_alloc(p2 - *p + 1); | |
732 memcpy(sn, *p, p2 - *p); | |
733 sn[p2 - *p] = '\0'; | |
734 | |
735 *p = p2; | |
736 | |
737 opts = strchr(sn, ','); | |
738 if (opts) | |
739 { | |
740 *opts++ = '\0'; | |
741 } | |
742 | |
743 // have we seen the section name already? | |
744 for (s = as -> sections; s; s = s -> next) | |
745 { | |
746 if (!strcmp(s -> name, sn)) | |
747 break; | |
748 } | |
749 | |
750 if (s) | |
751 { | |
752 lwasm_free(sn); | |
753 if (opts) | |
754 { | |
755 register_error(as, l, 1, "Section options can only be specified the first time"); | |
756 return; | |
757 } | |
758 } | |
759 else if (!s) | |
760 { | |
761 s = lwasm_alloc(sizeof(sectiontab_t)); | |
762 s -> name = sn; | |
763 s -> offset = 0; | |
764 s -> flags = 0; | |
765 | |
766 // parse options; only one "bss" | |
767 if (opts && as -> passnum == 1) | |
768 { | |
769 if (!strcasecmp(opts, "bss")) | |
770 { | |
771 s -> flags = SECTION_BSS; | |
772 } | |
773 else | |
774 { | |
775 register_error(as, l, 1, "Unrecognized section option '%s'", opts); | |
776 lwasm_free(s -> name); | |
777 lwasm_free(s); | |
778 return; | |
779 } | |
780 } | |
781 | |
782 s -> next = as -> sections; | |
783 as -> sections = s; | |
784 } | |
785 as -> addr = s -> offset; | |
786 as -> csect = s; | |
787 as -> context = lwasm_next_context(as); | |
788 } | |
789 | |
790 OPFUNC(pseudo_endsection) | |
791 { | |
792 if (as -> outformat != OUTPUT_OBJ) | |
793 { | |
794 register_error(as, l, 1, "Sections only supported for obj target"); | |
795 return; | |
796 } | |
797 | |
798 if (!(as -> csect)) | |
799 { | |
800 register_error(as, l, 1, "ENDSECTION when not in a section"); | |
801 return; | |
802 } | |
803 | |
804 as -> csect -> offset = as -> addr; | |
805 as -> addr = 0; | |
806 as -> csect = 0; | |
807 as -> context = lwasm_next_context(as); | |
808 } |