Mercurial > hg-old > index.cgi
annotate lwasm/lwasm.c @ 448:5cccf90bf838 3.0 tip
Fixed bug with complex external references generating invalid relocations in the object file
author | lost@l-w.ca |
---|---|
date | Fri, 05 Nov 2010 22:27:00 -0600 |
parents | 00924eeb2ec8 |
children |
rev | line source |
---|---|
337 | 1 /* |
2 lwasm.c | |
3 | |
4 Copyright © 2010 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
22 #define ___lwasm_c_seen___ |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
23 |
337 | 24 #include <config.h> |
25 | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
26 #include <stdio.h> |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
27 #include <stdarg.h> |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
28 #include <string.h> |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
29 |
337 | 30 #include <lw_expr.h> |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
31 #include <lw_alloc.h> |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
32 #include <lw_string.h> |
337 | 33 |
34 #include "lwasm.h" | |
35 | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
36 void lwasm_register_error(asmstate_t *as, line_t *l, const char *msg, ...); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
37 |
375 | 38 int lwasm_expr_exportable(asmstate_t *as, lw_expr_t expr) |
39 { | |
40 return 0; | |
41 } | |
42 | |
43 int lwasm_expr_exportval(asmstate_t *as, lw_expr_t expr) | |
44 { | |
45 return 0; | |
46 } | |
47 | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
48 lw_expr_t lwasm_evaluate_var(char *var, void *priv) |
337 | 49 { |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
50 asmstate_t *as = (asmstate_t *)priv; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
51 lw_expr_t e; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
52 importlist_t *im; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
53 struct symtabe *s; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
54 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
55 s = lookup_symbol(as, as -> cl, var); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
56 if (s) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
57 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
58 e = lw_expr_build(lw_expr_type_special, lwasm_expr_syment, s); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
59 return e; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
60 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
61 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
62 // undefined here is undefied unless output is object |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
63 if (as -> output_format != OUTPUT_OBJ) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
64 goto nomatch; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
65 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
66 // check for import |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
67 for (im = as -> importlist; im; im = im -> next) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
68 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
69 if (!strcmp(im -> symbol, var)) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
70 break; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
71 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
72 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
73 // check for "undefined" to import automatically |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
74 if (!im && CURPRAGMA(as -> cl, PRAGMA_UNDEFEXTERN)) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
75 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
76 im = lw_alloc(sizeof(importlist_t)); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
77 im -> symbol = lw_strdup(var); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
78 im -> next = as -> importlist; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
79 as -> importlist = im; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
80 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
81 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
82 if (!im) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
83 goto nomatch; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
84 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
85 e = lw_expr_build(lw_expr_type_special, lwasm_expr_import, im); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
86 return e; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
87 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
88 nomatch: |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
89 if (as -> badsymerr) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
90 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
91 lwasm_register_error(as, as -> cl, "Undefined symbol %s", var); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
92 } |
337 | 93 return NULL; |
94 } | |
95 | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
96 lw_expr_t lwasm_evaluate_special(int t, void *ptr, void *priv) |
337 | 97 { |
98 switch (t) | |
99 { | |
375 | 100 case lwasm_expr_secbase: |
101 { | |
385 | 102 // sectiontab_t *s = priv; |
103 asmstate_t *as = priv; | |
104 if (as -> exportcheck && ptr == as -> csect) | |
375 | 105 return lw_expr_build(lw_expr_type_int, 0); |
106 return NULL; | |
107 } | |
108 | |
337 | 109 case lwasm_expr_linelen: |
110 { | |
111 line_t *cl = ptr; | |
112 if (cl -> len == -1) | |
113 return NULL; | |
114 return lw_expr_build(lw_expr_type_int, cl -> len); | |
115 } | |
116 break; | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
117 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
118 case lwasm_expr_lineaddr: |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
119 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
120 line_t *cl = ptr; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
121 if (cl -> addr) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
122 return lw_expr_copy(cl -> addr); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
123 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
124 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
125 } |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
126 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
127 case lwasm_expr_syment: |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
128 { |
371 | 129 struct symtabe *sym = ptr; |
130 return lw_expr_copy(sym -> value); | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
131 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
132 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
133 case lwasm_expr_import: |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
134 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
135 return NULL; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
136 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
137 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
138 case lwasm_expr_nextbp: |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
139 { |
418 | 140 line_t *cl = ptr; |
141 for (cl = cl -> next; cl; cl = cl -> next) | |
142 { | |
143 if (cl -> isbrpt) | |
144 break; | |
145 } | |
146 if (cl) | |
147 { | |
148 return lw_expr_copy(cl -> addr); | |
149 } | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
150 return NULL; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
151 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
152 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
153 case lwasm_expr_prevbp: |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
154 { |
418 | 155 line_t *cl = ptr; |
156 for (cl = cl -> prev; cl; cl = cl -> prev) | |
157 { | |
158 if (cl -> isbrpt) | |
159 break; | |
160 } | |
161 if (cl) | |
162 { | |
163 return lw_expr_copy(cl -> addr); | |
164 } | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
165 return NULL; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
166 } |
337 | 167 } |
168 return NULL; | |
169 } | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
170 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
171 void lwasm_register_error(asmstate_t *as, line_t *l, const char *msg, ...) |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
172 { |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
173 lwasm_error_t *e; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
174 va_list args; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
175 char errbuff[1024]; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
176 int r; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
177 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
178 if (!l) |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
179 return; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
180 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
181 va_start(args, msg); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
182 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
183 e = lw_alloc(sizeof(lwasm_error_t)); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
184 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
185 e -> next = l -> err; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
186 l -> err = e; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
187 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
188 as -> errorcount++; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
189 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
190 r = vsnprintf(errbuff, 1024, msg, args); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
191 e -> mess = lw_strdup(errbuff); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
192 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
193 va_end(args); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
194 } |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
195 |
351 | 196 void lwasm_register_warning(asmstate_t *as, line_t *l, const char *msg, ...) |
197 { | |
198 lwasm_error_t *e; | |
199 va_list args; | |
200 char errbuff[1024]; | |
201 int r; | |
202 | |
203 if (!l) | |
204 return; | |
205 | |
206 va_start(args, msg); | |
207 | |
208 e = lw_alloc(sizeof(lwasm_error_t)); | |
209 | |
210 e -> next = l -> err; | |
211 l -> err = e; | |
212 | |
213 as -> errorcount++; | |
214 | |
215 r = vsnprintf(errbuff, 1024, msg, args); | |
216 e -> mess = lw_strdup(errbuff); | |
217 | |
218 va_end(args); | |
219 } | |
220 | |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
221 int lwasm_next_context(asmstate_t *as) |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
222 { |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
223 int r; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
224 r = as -> nextcontext; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
225 as -> nextcontext++; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
226 return r; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
227 } |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
228 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
229 void lwasm_emit(line_t *cl, int byte) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
230 { |
447
00924eeb2ec8
Fixed segfault with output outside of a section
lost@l-w.ca
parents:
418
diff
changeset
|
231 if (cl -> as -> output_format == OUTPUT_OBJ && cl -> csect == NULL) |
00924eeb2ec8
Fixed segfault with output outside of a section
lost@l-w.ca
parents:
418
diff
changeset
|
232 { |
00924eeb2ec8
Fixed segfault with output outside of a section
lost@l-w.ca
parents:
418
diff
changeset
|
233 lwasm_register_error(cl -> as, cl, "Instruction generating output outside of a section"); |
00924eeb2ec8
Fixed segfault with output outside of a section
lost@l-w.ca
parents:
418
diff
changeset
|
234 return; |
00924eeb2ec8
Fixed segfault with output outside of a section
lost@l-w.ca
parents:
418
diff
changeset
|
235 } |
374 | 236 if (cl -> outputl < 0) |
237 cl -> outputl = 0; | |
238 | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
239 if (cl -> outputl == cl -> outputbl) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
240 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
241 cl -> output = lw_realloc(cl -> output, cl -> outputbl + 8); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
242 cl -> outputbl += 8; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
243 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
244 cl -> output[cl -> outputl++] = byte & 0xff; |
354 | 245 |
246 if (cl -> inmod) | |
247 { | |
248 asmstate_t *as = cl -> as; | |
249 // update module CRC | |
250 // this is a direct transliteration from the nitros9 asm source | |
251 // to C; it can, no doubt, be optimized for 32 bit processing | |
252 byte &= 0xff; | |
253 | |
254 byte ^= (as -> crc)[0]; | |
255 (as -> crc)[0] = (as -> crc)[1]; | |
256 (as -> crc)[1] = (as -> crc)[2]; | |
257 (as -> crc)[1] ^= (byte >> 7); | |
258 (as -> crc)[2] = (byte << 1); | |
259 (as -> crc)[1] ^= (byte >> 2); | |
260 (as -> crc)[2] ^= (byte << 6); | |
261 byte ^= (byte << 1); | |
262 byte ^= (byte << 2); | |
263 byte ^= (byte << 4); | |
264 if (byte & 0x80) | |
265 { | |
266 (as -> crc)[0] ^= 0x80; | |
267 (as -> crc)[2] ^= 0x21; | |
268 } | |
269 } | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
270 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
271 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
272 void lwasm_emitop(line_t *cl, int opc) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
273 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
274 if (opc > 0x100) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
275 lwasm_emit(cl, opc >> 8); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
276 lwasm_emit(cl, opc); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
277 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
278 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
279 lw_expr_t lwasm_parse_term(char **p, void *priv) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
280 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
281 asmstate_t *as = priv; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
282 int val; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
283 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
284 if (!**p) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
285 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
286 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
287 if (**p == '*' || ( |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
288 **p == '.' |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
289 && !((*p)[1] >= 'A' && (*p)[1] <= 'Z') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
290 && !((*p)[1] >= 'a' && (*p)[1] <= 'z') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
291 && !((*p)[1] >= '0' && (*p)[1] <= '9') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
292 )) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
293 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
294 // special "symbol" for current line addr (*, .) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
295 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
296 return lw_expr_build(lw_expr_type_special, lwasm_expr_lineaddr, as -> cl); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
297 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
298 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
299 // branch points |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
300 if (**p == '<') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
301 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
302 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
303 return lw_expr_build(lw_expr_type_special, lwasm_expr_prevbp, as -> cl); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
304 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
305 if (**p == '>') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
306 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
307 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
308 return lw_expr_build(lw_expr_type_special, lwasm_expr_nextbp, as -> cl); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
309 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
310 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
311 // double ascii constant |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
312 if (**p == '"') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
313 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
314 int v; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
315 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
316 if (!**p) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
317 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
318 if (!*((*p)+1)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
319 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
320 v = (unsigned char)**p << 8 | (unsigned char)*((*p)+1); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
321 (*p) += 2; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
322 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
323 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
324 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
325 if (**p == '\'') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
326 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
327 int v; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
328 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
329 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
330 if (!**p) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
331 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
332 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
333 v = (unsigned char)**p; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
334 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
335 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
336 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
337 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
338 if (**p == '&') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
339 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
340 // decimal constant |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
341 int v = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
342 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
343 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
344 if (!strchr("0123456789", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
345 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
346 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
347 while (**p && strchr("0123456789", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
348 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
349 val = val * 10 + (**p - '0'); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
350 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
351 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
352 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
353 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
354 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
355 if (**p == '%') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
356 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
357 // binary constant |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
358 int v = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
359 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
360 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
361 if (**p != '0' && **p != '1') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
362 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
363 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
364 while (**p && (**p == '0' || **p == '1')) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
365 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
366 val = val * 2 + (**p - '0'); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
367 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
368 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
369 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
370 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
371 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
372 if (**p == '$') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
373 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
374 // hexadecimal constant |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
375 int v = 0, v2; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
376 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
377 if (!strchr("0123456789abcdefABCDEF", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
378 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
379 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
380 while (**p && strchr("0123456789abcdefABCDEF", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
381 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
382 v2 = toupper(**p) - '0'; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
383 if (v2 > 9) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
384 v2 -= 7; |
382 | 385 v = v * 16 + v2; |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
386 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
387 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
388 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
389 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
390 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
391 if (**p == '0' && (*((*p)+1) == 'x' || *((*p)+1) == 'X')) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
392 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
393 // hexadecimal constant, C style |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
394 int v = 0, v2; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
395 (*p)+=2; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
396 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
397 if (!strchr("0123456789abcdefABCDEF", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
398 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
399 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
400 while (**p && strchr("0123456789abcdefABCDEF", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
401 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
402 v2 = toupper(**p) - '0'; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
403 if (v2 > 9) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
404 v2 -= 7; |
382 | 405 v = v * 16 + v2; |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
406 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
407 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
408 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
409 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
410 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
411 if (**p == '@' && (*((*p)+1) >= '0' && *((*p)+1) <= '7')) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
412 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
413 // octal constant |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
414 int v = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
415 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
416 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
417 if (!strchr("01234567", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
418 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
419 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
420 while (**p && strchr("01234567", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
421 { |
382 | 422 v = v * 8 + (**p - '0'); |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
423 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
424 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
425 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
426 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
427 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
428 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
429 // symbol or bare decimal or suffix constant here |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
430 do |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
431 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
432 int havedol = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
433 int l = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
434 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
435 while ((*p)[l] && strchr(SYMCHARS, (*p)[l])) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
436 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
437 if ((*p)[l] == '$') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
438 havedol = 1; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
439 l++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
440 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
441 if (l == 0) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
442 return NULL; |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
443 |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
444 if ((*p)[l] == '{') |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
445 { |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
446 while ((*p)[l] && (*p)[l] != '}') |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
447 l++; |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
448 l++; |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
449 } |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
450 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
451 if (havedol || **p < '0' || **p > '9') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
452 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
453 // have a symbol here |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
454 char *sym; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
455 lw_expr_t term; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
456 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
457 sym = lw_strndup(*p, l); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
458 (*p) += l; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
459 term = lw_expr_build(lw_expr_type_var, sym); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
460 lw_free(sym); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
461 return term; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
462 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
463 } while (0); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
464 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
465 if (!**p) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
466 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
467 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
468 // we have a numeric constant here, either decimal or postfix base notation |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
469 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
470 int decval = 0, binval = 0, hexval = 0, octval = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
471 int valtype = 15; // 1 = bin, 2 = oct, 4 = dec, 8 = hex |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
472 int bindone = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
473 int val; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
474 int dval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
475 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
476 while (1) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
477 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
478 if (!**p || !strchr("0123456789ABCDEFabcdefqhoQHO", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
479 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
480 // we can legally be bin or decimal here |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
481 if (bindone) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
482 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
483 // just finished a binary value |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
484 val = binval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
485 break; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
486 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
487 else if (valtype & 4) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
488 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
489 val = decval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
490 break; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
491 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
492 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
493 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
494 // bad value |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
495 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
496 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
497 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
498 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
499 dval = toupper(**p); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
500 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
501 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
502 if (bindone) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
503 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
504 // any characters past "B" means it is not binary |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
505 bindone = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
506 valtype &= 14; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
507 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
508 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
509 switch (dval) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
510 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
511 case 'Q': |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
512 case 'O': |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
513 if (valtype & 2) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
514 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
515 val = octval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
516 valtype = -1; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
517 break; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
518 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
519 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
520 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
521 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
522 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
523 /* can't get here */ |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
524 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
525 case 'H': |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
526 if (valtype & 8) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
527 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
528 val = hexval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
529 valtype = -1; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
530 break; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
531 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
532 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
533 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
534 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
535 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
536 /* can't get here */ |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
537 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
538 case 'B': |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
539 // this is a bit of a sticky one since B may be a |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
540 // hex number instead of the end of a binary number |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
541 // so it falls through to the digit case |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
542 if (valtype & 1) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
543 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
544 // could still be binary of hex |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
545 bindone = 1; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
546 valtype = 9; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
547 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
548 /* fall through intented */ |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
549 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
550 default: |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
551 // digit |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
552 dval -= '0'; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
553 if (dval > 9) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
554 dval -= 7; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
555 if (valtype & 8) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
556 hexval = hexval * 16 + dval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
557 if (valtype & 4) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
558 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
559 if (dval > 9) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
560 valtype &= 11; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
561 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
562 decval = decval * 10 + dval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
563 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
564 if (valtype & 2) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
565 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
566 if (dval > 7) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
567 valtype &= 13; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
568 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
569 octval = octval * 8 + dval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
570 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
571 if (valtype & 1) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
572 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
573 if (dval > 1) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
574 valtype &= 14; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
575 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
576 binval = binval * 2 + dval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
577 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
578 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
579 if (valtype == -1) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
580 break; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
581 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
582 // return if no more valid types |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
583 if (valtype == 0) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
584 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
585 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
586 val = decval; // in case we fall through |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
587 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
588 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
589 // get here if we have a value |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
590 return lw_expr_build(lw_expr_type_int, val); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
591 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
592 // can't get here |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
593 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
594 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
595 lw_expr_t lwasm_parse_expr(asmstate_t *as, char **p) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
596 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
597 lw_expr_t e; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
598 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
599 e = lw_expr_parse(p, as); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
600 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
601 return e; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
602 } |
347 | 603 |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
604 int lwasm_reduce_expr(asmstate_t *as, lw_expr_t expr) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
605 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
606 lw_expr_simplify(expr, as); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
607 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
608 |
347 | 609 void lwasm_save_expr(line_t *cl, int id, lw_expr_t expr) |
610 { | |
611 struct line_expr_s *e; | |
612 | |
613 for (e = cl -> exprs; e; e = e -> next) | |
614 { | |
615 if (e -> id == id) | |
616 { | |
617 lw_expr_destroy(e -> expr); | |
618 e -> expr = expr; | |
619 return; | |
620 } | |
621 } | |
622 | |
623 e = lw_alloc(sizeof(struct line_expr_s)); | |
624 e -> expr = expr; | |
625 e -> id = id; | |
626 e -> next = cl -> exprs; | |
627 cl -> exprs = e; | |
628 } | |
629 | |
630 lw_expr_t lwasm_fetch_expr(line_t *cl, int id) | |
631 { | |
632 struct line_expr_s *e; | |
633 | |
634 for (e = cl -> exprs; e; e = e -> next) | |
635 { | |
636 if (e -> id == id) | |
637 { | |
638 return e -> expr; | |
639 } | |
640 } | |
641 return NULL; | |
642 } | |
643 | |
644 void skip_operand(char **p) | |
645 { | |
646 for (; **p && !isspace(**p); (*p)++) | |
647 /* do nothing */ ; | |
648 } | |
649 | |
650 int lwasm_emitexpr(line_t *l, lw_expr_t expr, int size) | |
651 { | |
416
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
652 int v = 0; |
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
653 int ol; |
347 | 654 |
416
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
655 ol = l -> outputl; |
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
656 if (ol == -1) |
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
657 ol = 0; |
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
658 |
347 | 659 if (lw_expr_istype(expr, lw_expr_type_int)) |
660 { | |
661 v = lw_expr_intval(expr); | |
662 } | |
348
11a95c6414b4
Added third func to instab to split resolve and emit logic
lost@starbug
parents:
347
diff
changeset
|
663 // handle external/cross-section/incomplete references here |
347 | 664 else |
665 { | |
374 | 666 if (l -> as -> output_format == OUTPUT_OBJ) |
667 { | |
668 reloctab_t *re; | |
376 | 669 lw_expr_t te; |
447
00924eeb2ec8
Fixed segfault with output outside of a section
lost@l-w.ca
parents:
418
diff
changeset
|
670 |
00924eeb2ec8
Fixed segfault with output outside of a section
lost@l-w.ca
parents:
418
diff
changeset
|
671 if (l->csect == NULL) |
00924eeb2ec8
Fixed segfault with output outside of a section
lost@l-w.ca
parents:
418
diff
changeset
|
672 { |
00924eeb2ec8
Fixed segfault with output outside of a section
lost@l-w.ca
parents:
418
diff
changeset
|
673 lwasm_register_error(l -> as, l, "Instruction generating output outside of a section"); |
00924eeb2ec8
Fixed segfault with output outside of a section
lost@l-w.ca
parents:
418
diff
changeset
|
674 return -1; |
00924eeb2ec8
Fixed segfault with output outside of a section
lost@l-w.ca
parents:
418
diff
changeset
|
675 } |
374 | 676 |
381 | 677 if (size == 4) |
678 { | |
679 // create a two part reference because lwlink doesn't | |
680 // support 32 bit references | |
681 lw_expr_t te2; | |
682 te = lw_expr_build(lw_expr_type_int, 0x10000); | |
683 te2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_divide, expr, te); | |
684 lw_expr_destroy(te); | |
685 | |
686 re = lw_alloc(sizeof(reloctab_t)); | |
687 re -> next = l -> csect -> reloctab; | |
688 l -> csect -> reloctab = re; | |
416
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
689 te = lw_expr_build(lw_expr_type_int, ol); |
381 | 690 re -> offset = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, l -> addr, te); |
691 lw_expr_destroy(te); | |
692 lwasm_reduce_expr(l -> as, re -> offset); | |
693 re -> expr = te2; | |
694 re -> size = 2; | |
695 | |
696 te = lw_expr_build(lw_expr_type_int, 0xFFFF); | |
697 te2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_bwand, expr, te); | |
698 lw_expr_destroy(te); | |
699 | |
700 re = lw_alloc(sizeof(reloctab_t)); | |
701 re -> next = l -> csect -> reloctab; | |
702 l -> csect -> reloctab = re; | |
416
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
703 te = lw_expr_build(lw_expr_type_int, ol + 2); |
381 | 704 re -> offset = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, l -> addr, te); |
705 lw_expr_destroy(te); | |
706 lwasm_reduce_expr(l -> as, re -> offset); | |
707 re -> expr = te2; | |
708 re -> size = 2; | |
709 } | |
710 else | |
711 { | |
712 // add "expression" record to section table | |
713 re = lw_alloc(sizeof(reloctab_t)); | |
714 re -> next = l -> csect -> reloctab; | |
715 l -> csect -> reloctab = re; | |
416
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
716 te = lw_expr_build(lw_expr_type_int, ol); |
381 | 717 re -> offset = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, l -> addr, te); |
718 lw_expr_destroy(te); | |
719 lwasm_reduce_expr(l -> as, re -> offset); | |
720 re -> size = size; | |
721 re -> expr = lw_expr_copy(expr); | |
722 } | |
374 | 723 for (v = 0; v < size; v++) |
724 lwasm_emit(l, 0); | |
725 return 0; | |
726 } | |
347 | 727 lwasm_register_error(l -> as, l, "Expression not fully resolved"); |
728 return -1; | |
729 } | |
730 | |
731 switch (size) | |
732 { | |
733 case 4: | |
734 lwasm_emit(l, v >> 24); | |
735 lwasm_emit(l, v >> 16); | |
736 /* fallthrough intended */ | |
737 | |
738 case 2: | |
739 lwasm_emit(l, v >> 8); | |
740 /* fallthrough intended */ | |
741 | |
742 case 1: | |
743 lwasm_emit(l, v); | |
744 } | |
745 | |
746 return 0; | |
747 } | |
357 | 748 |
749 int lwasm_lookupreg2(const char *regs, char **p) | |
750 { | |
751 int rval = 0; | |
752 | |
753 while (*regs) | |
754 { | |
755 if (toupper(**p) == *regs) | |
756 { | |
757 if (regs[1] == ' ' && !isalpha(*(*p + 1))) | |
758 break; | |
759 if (toupper(*(*p + 1)) == regs[1]) | |
760 break; | |
761 } | |
762 regs += 2; | |
763 rval++; | |
764 } | |
765 if (!*regs) | |
766 return -1; | |
767 if (regs[1] == ' ') | |
768 (*p)++; | |
769 else | |
770 (*p) += 2; | |
771 return rval; | |
772 } | |
359 | 773 |
774 int lwasm_lookupreg3(const char *regs, char **p) | |
775 { | |
776 int rval = 0; | |
777 | |
778 while (*regs) | |
779 { | |
780 if (toupper(**p) == *regs) | |
781 { | |
782 if (regs[1] == ' ' && !isalpha(*(*p + 1))) | |
783 break; | |
784 if (toupper(*(*p + 1)) == regs[1]) | |
785 { | |
786 if (regs[2] == ' ' && !isalpha(*(*p + 2))) | |
787 break; | |
788 if (toupper(*(*p + 2)) == regs[2]) | |
789 break; | |
790 } | |
791 } | |
792 regs += 3; | |
793 rval++; | |
794 } | |
795 if (!*regs) | |
796 return -1; | |
797 if (regs[1] == ' ') | |
798 (*p)++; | |
799 else if (regs[2] == ' ') | |
800 (*p) += 2; | |
801 else | |
802 (*p) += 3; | |
803 return rval; | |
804 } | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
805 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
806 void lwasm_show_errors(asmstate_t *as) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
807 { |
382 | 808 line_t *cl; |
809 lwasm_error_t *e; | |
810 | |
811 for (cl = as -> line_head; cl; cl = cl -> next) | |
812 { | |
813 if (!(cl -> err) && !(cl -> warn)) | |
814 continue; | |
815 for (e = cl -> err; e; e = e -> next) | |
816 { | |
817 fprintf(stderr, "ERROR: %s\n", e -> mess); | |
818 } | |
819 for (e = cl -> warn; e; e = e -> next) | |
820 { | |
821 fprintf(stderr, "WARNING: %s\n", e -> mess); | |
822 } | |
394
a2f52e97b454
Actually show name of file and line number where error occurred
lost@l-w.ca
parents:
391
diff
changeset
|
823 fprintf(stderr, "%s:%05d %s\n\n", cl -> linespec, cl -> lineno, cl -> ltext); |
382 | 824 } |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
825 } |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
826 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
827 /* |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
828 this does any passes and other gymnastics that might be useful |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
829 to see if an expression reduces early |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
830 */ |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
831 extern void do_pass3(asmstate_t *as); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
832 extern void do_pass4_aux(asmstate_t *as, int force); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
833 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
834 void lwasm_interim_reduce(asmstate_t *as) |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
835 { |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
836 do_pass3(as); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
837 // do_pass4_aux(as, 0); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
838 } |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
839 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
840 lw_expr_t lwasm_parse_cond(asmstate_t *as, char **p) |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
841 { |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
842 lw_expr_t e; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
843 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
844 debug_message(as, 250, "Parsing condition"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
845 e = lwasm_parse_expr(as, p); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
846 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e)); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
847 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
848 if (!e) |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
849 { |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
850 lwasm_register_error(as, as -> cl, "Bad expression"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
851 return NULL; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
852 } |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
853 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
854 /* we need to simplify the expression here */ |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
855 debug_message(as, 250, "Doing interim reductions"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
856 lwasm_interim_reduce(as); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
857 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e)); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
858 debug_message(as, 250, "Reducing expression"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
859 lwasm_reduce_expr(as, e); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
860 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e)); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
861 /* lwasm_reduce_expr(as, e); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
862 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e)); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
863 lwasm_reduce_expr(as, e); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
864 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e)); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
865 lwasm_reduce_expr(as, e); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
866 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e)); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
867 */ |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
868 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
869 lwasm_save_expr(as -> cl, 4242, e); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
870 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
871 if (!lw_expr_istype(e, lw_expr_type_int)) |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
872 { |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
873 debug_message(as, 250, "Non-constant expression"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
874 lwasm_register_error(as, as -> cl, "Conditions must be constant on pass 1"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
875 return NULL; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
876 } |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
877 debug_message(as, 250, "Returning expression"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
878 return e; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
879 } |