Mercurial > hg-old > index.cgi
annotate lwasm/lwasm.c @ 238:a9a14e6b4bc8
Fixed os9 module CRC calculation
author | lost |
---|---|
date | Sat, 15 Aug 2009 05:26:02 +0000 |
parents | a58f49a77441 |
children | 1106ec189e4f |
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 lwasm.c |
55 | 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 |
26 | 20 |
21 Contains random functions used by the assembler | |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
22 */ |
0 | 23 |
26 | 24 #define __lwasm_c_seen__ |
212 | 25 #include <config.h> |
26 | 26 |
27 #include <stdarg.h> | |
0 | 28 #include <stdlib.h> |
26 | 29 #include <stdio.h> |
30 | |
0 | 31 #include "lwasm.h" |
26 | 32 #include "util.h" |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
33 #include "expr.h" |
0 | 34 |
38 | 35 int debug_level = 0; |
36 | |
26 | 37 int register_error(asmstate_t *as, lwasm_line_t *l, int pass, const char *fmt, ...) |
0 | 38 { |
26 | 39 lwasm_error_t *e; |
40 va_list args; | |
41 char errbuff[1024]; | |
42 int r; | |
0 | 43 |
143
0ee5f65bccf9
Added pragma to allow all undefined symbols to be considered external and also added a --pragma command line option
lost
parents:
101
diff
changeset
|
44 if (!l) |
0ee5f65bccf9
Added pragma to allow all undefined symbols to be considered external and also added a --pragma command line option
lost
parents:
101
diff
changeset
|
45 return; |
0ee5f65bccf9
Added pragma to allow all undefined symbols to be considered external and also added a --pragma command line option
lost
parents:
101
diff
changeset
|
46 |
26 | 47 if (as -> passnum != pass) |
48 return; | |
49 | |
50 va_start(args, fmt); | |
0 | 51 |
26 | 52 e = lwasm_alloc(sizeof(lwasm_error_t)); |
53 | |
54 e -> next = l -> err; | |
55 l -> err = e; | |
0 | 56 |
57 as -> errorcount++; | |
58 | |
26 | 59 r = vsnprintf(errbuff, 1024, fmt, args); |
60 e -> mess = lwasm_strdup(errbuff); | |
0 | 61 |
26 | 62 va_end(args); |
0 | 63 |
26 | 64 return r; |
0 | 65 } |
27
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
66 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
67 void lwasm_emit(asmstate_t *as, lwasm_line_t *l, int b) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
68 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
69 as -> addr += 1; |
58 | 70 as -> addr &= 0xffff; |
71 | |
74 | 72 if (as -> outformat == OUTPUT_OBJ && !(as -> csect)) |
73 { | |
74 register_error(as, l, 1, "Output not allowed outside sections with obj target"); | |
75 return; | |
76 } | |
77 if (as -> outformat == OUTPUT_OBJ && as -> csect -> flags & SECTION_BSS) | |
78 { | |
79 register_error(as, l, 1, "Output not allowed inside BSS sections"); | |
80 return; | |
81 } | |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
82 |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
83 if (as -> outformat == OUTPUT_OS9 && as -> inmod == 0) |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
84 { |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
85 register_error(as, l, 1, "Output not allowed outside of module in OS9 mode"); |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
86 return; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
87 } |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
88 |
27
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
89 if (as -> passnum == 1) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
90 return; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
91 |
42 | 92 |
93 if (l -> codelen >= l -> codesize) | |
94 { | |
95 l -> bytes = realloc(l -> bytes, l -> codesize + 16); | |
96 l -> codesize += 16; | |
97 } | |
98 l -> bytes[l -> codelen] = b & 0xff; | |
99 l -> codelen += 1; | |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
100 |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
101 if (as -> outformat == OUTPUT_OS9 && as -> inmod) |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
102 { |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
103 // calc the CRC |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
104 b &= 0xff; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
105 |
238 | 106 b ^= (as -> crc)[0]; |
107 (as -> crc)[0] = (as -> crc)[1]; | |
108 (as -> crc)[1] = (as -> crc)[2]; | |
109 (as -> crc)[1] ^= (b >> 7); | |
110 (as -> crc)[2] = (b << 1); | |
111 (as -> crc)[1] ^= (b >> 2); | |
112 (as -> crc)[2] ^= (b << 6); | |
113 b ^= (b << 1); | |
114 b ^= (b << 2); | |
115 b ^= (b << 4); | |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
116 if (b & 0x80) |
238 | 117 { |
118 (as -> crc)[0] ^= 0x80; | |
119 (as -> crc)[2] ^= 0x21; | |
120 } | |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
121 } |
27
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
122 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
123 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
124 void lwasm_emitop(asmstate_t *as, lwasm_line_t *l, int o) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
125 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
126 if (o >= 0x100) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
127 lwasm_emit(as, l, o >> 8); |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
128 lwasm_emit(as, l, o & 0xff); |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
129 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
130 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
131 int lwasm_lookupreg2(const char *reglist, char **str) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
132 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
133 int rval = 0; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
134 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
135 while (*reglist) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
136 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
137 if (toupper(**str) == *reglist) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
138 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
139 // first char matches |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
140 if (reglist[1] == ' ' && !isalpha(*(*str + 1))) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
141 break; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
142 if (toupper(*(*str + 1)) == reglist[1]) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
143 break; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
144 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
145 reglist += 2; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
146 rval++; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
147 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
148 if (!*reglist) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
149 return -1; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
150 if (reglist[1] == ' ') |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
151 (*str)++; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
152 else |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
153 (*str) += 2; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
154 return rval; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
155 } |
32 | 156 |
157 int lwasm_lookupreg3(const char *rlist, const char **str) | |
158 { | |
159 int rval = 0; | |
160 int f = 0; | |
161 const char *reglist = rlist; | |
162 | |
163 while (*reglist) | |
164 { | |
165 if (toupper(**str) == *reglist) | |
166 { | |
167 // first char matches | |
168 if (reglist[1] == ' ') | |
169 { | |
170 f = 1; | |
171 break; | |
172 } | |
173 if (toupper(*(*str + 1)) == reglist[1]) | |
174 { | |
175 // second char matches | |
176 if (reglist[2] == ' ') | |
177 { | |
178 f = 1; | |
179 break; | |
180 } | |
181 if (toupper(*(*str + 2)) == reglist[2]) | |
182 { | |
183 f = 1; | |
184 break; | |
185 } | |
186 } | |
187 } | |
188 reglist += 3; | |
189 rval++; | |
190 } | |
191 if (f == 0) | |
192 return -1; | |
193 | |
194 | |
195 reglist = rval * 3 + rlist; | |
196 if (reglist[1] == ' ') | |
197 (*str) += 1; | |
198 else if (reglist[2] == ' ') | |
199 (*str) += 2; | |
200 else | |
201 (*str)+=3; | |
202 return rval; | |
203 } | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
204 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
205 struct symstateinfo |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
206 { |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
207 asmstate_t *as; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
208 lwasm_line_t *l; |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
209 int flags; |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
210 }; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
211 |
76 | 212 lwasm_expr_stack_t *lwasm_expr_lookup_symbol(char *sym, void *state) |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
213 { |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
214 lwasm_symbol_ent_t *se; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
215 struct symstateinfo *st; |
76 | 216 lwasm_expr_stack_t *rs; |
217 lwasm_expr_term_t *t; | |
218 lwasm_expr_stack_node_t *n; | |
219 | |
220 int val; | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
221 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
222 st = state; |
52 | 223 debug_message(3, "lwasm_expr_lookup_symbol(): find '%s' (context=%d)", sym, st -> as -> context); |
224 | |
60 | 225 // check for special symbols first... |
226 if (sym[1] == '\0') | |
227 { | |
228 switch (sym[0]) | |
229 { | |
230 // current line address | |
231 case '*': | |
232 case '.': | |
76 | 233 val = st -> l -> codeaddr; |
234 goto retconst; | |
60 | 235 |
236 case '<': | |
237 // previous branch point | |
238 // not implemented | |
239 break; | |
240 case '>': | |
241 // next branch point | |
242 // not implemented | |
243 break; | |
244 } | |
245 } | |
246 | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
247 // look for local symbol first then global symbol |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
248 se = lwasm_find_symbol(st -> as, sym, st -> as -> context); |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
249 if (!se) |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
250 se = lwasm_find_symbol(st -> as, sym, -1); |
52 | 251 debug_message(3, "lwasm_expr_lookup_symbol(): got '%p'", se); |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
252 if (!se) |
77 | 253 { |
254 register_error(st -> as, st -> l, 2, "Undefined symbol '%s'", sym); | |
76 | 255 return NULL; |
77 | 256 } |
92
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
257 // external reference - can not resolve it |
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
258 if (se -> flags & SYMBOL_EXTERN) |
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
259 { |
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
260 return NULL; |
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
261 } |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
262 if (st -> flags & EXPR_SECTCONST) |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
263 { |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
264 if (se -> sect == st -> l -> sect) |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
265 { |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
266 if (se -> expr) |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
267 goto retsym; |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
268 val = se -> value; |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
269 goto retconst; |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
270 } |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
271 } |
93
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
272 if (st -> as -> outformat == OUTPUT_OBJ && se -> sect != NULL) |
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
273 { |
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
274 return NULL; |
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
275 } |
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
276 if (st -> as -> outformat != OUTPUT_OBJ || se -> sect == NULL) |
76 | 277 { |
278 // global symbol, intrasegment reference, or not an object target | |
279 val = se -> value; | |
280 goto retconst; | |
281 } | |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
282 |
76 | 283 // an intersegment reference will return as NULL (to be resolved at output/link time) |
284 // if se -> expr is NULL, it has to be an intersegment reference here | |
285 if (se -> expr == NULL) | |
286 { | |
287 return NULL; | |
288 } | |
289 | |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
290 retsym: |
76 | 291 // duplicate the expression for return |
292 rs = lwasm_expr_stack_create(); | |
293 for (n = se -> expr -> head; n; n = n -> next) | |
294 { | |
295 lwasm_expr_stack_push(rs, n -> term); | |
296 } | |
297 return rs; | |
298 | |
299 retconst: | |
300 rs = lwasm_expr_stack_create(); | |
301 t = lwasm_expr_term_create_int(val); | |
302 lwasm_expr_stack_push(rs, t); | |
303 lwasm_expr_term_free(t); | |
304 return rs; | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
305 } |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
306 |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
307 lwasm_expr_stack_t *lwasm_evaluate_expr(asmstate_t *as, lwasm_line_t *l, const char *inp, const char **outp, int flags) |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
308 { |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
309 struct symstateinfo st; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
310 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
311 st.as = as; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
312 st.l = l; |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
313 st.flags = flags; |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
314 |
38 | 315 debug_message(2, "Evaluate expression: %s", inp); |
316 | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
317 return(lwasm_expr_eval(inp, outp, lwasm_expr_lookup_symbol, &st)); |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
318 } |
38 | 319 |
77 | 320 |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
321 int lwasm_reevaluate_expr(asmstate_t *as, lwasm_line_t *l, lwasm_expr_stack_t *s, int flags) |
77 | 322 { |
323 struct symstateinfo st; | |
324 | |
325 st.as = as; | |
326 st.l = l; | |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
327 st.flags = flags; |
77 | 328 return(lwasm_expr_reval(s, lwasm_expr_lookup_symbol, &st)); |
329 } | |
330 | |
76 | 331 // return 1 if no undefined symbols (externals and incompletes are okay) |
332 // return 0 if there are undefined symbols | |
333 int lwasm_expr_result_ckconst(asmstate_t *as, lwasm_expr_stack_t *s) | |
334 { | |
335 lwasm_expr_stack_node_t *n; | |
336 lwasm_symbol_ent_t *se; | |
337 | |
77 | 338 if (as -> outformat != OUTPUT_OBJ) |
339 { | |
340 if (lwasm_expr_is_constant(s)) | |
341 return 1; | |
342 else | |
343 return 0; | |
344 } | |
345 | |
76 | 346 for (n = s -> head; n; n = n -> next) |
347 { | |
348 if (n -> term -> term_type == LWASM_TERM_SYM) | |
349 { | |
350 se = lwasm_find_symbol(as, n -> term -> symbol, as -> context); | |
351 if (!se) | |
352 se = lwasm_find_symbol(as, n -> term -> symbol, -1); | |
353 if (!se) | |
354 return 0; | |
355 } | |
356 } | |
357 return 1; | |
358 } | |
359 | |
360 /* | |
361 Evaluate an expression according to the flag value. Return 0 if a constant result was | |
362 obtained, 1 if an incomplete result was obtained, and -1 if an error was flagged. | |
363 | |
77 | 364 */ |
365 int lwasm_expr_result2(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val, int slot) | |
366 { | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
367 lwasm_expr_stack_t *s = NULL; |
77 | 368 const char *ep; |
369 int rval; | |
370 | |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
371 if ((as -> passnum == 1 && !(flag & EXPR_REEVAL)) || slot < 0) |
77 | 372 { |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
373 s = lwasm_evaluate_expr(as, l, *inp, &ep, flag); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
374 if (slot >= 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
375 l -> exprs[slot] = s; |
77 | 376 if (!s) |
377 { | |
378 register_error(as, l, 1, "Bad expression"); | |
379 *val = 0; | |
380 return -1; | |
381 } | |
382 *inp = (char *)ep; | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
383 if (slot >= 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
384 { |
94
83ba34ed11b3
Fixed problem with constant expressions evaluating to 0 when they shouldn't
lost
parents:
93
diff
changeset
|
385 l -> exprends[slot] = (char *)ep; |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
386 l -> exprvals[slot] = lwasm_expr_get_value(s); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
387 } |
77 | 388 } |
389 else if (l -> exprs[slot]) | |
390 { | |
391 s = l -> exprs[slot]; | |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
392 lwasm_reevaluate_expr(as, l, s, flag); |
77 | 393 l -> exprvals[slot] = lwasm_expr_get_value(s); |
394 } | |
84
e12edcfbebd5
Fixed problem with expression evaluation infrastructure not advancing input pointer on pass 2
lost
parents:
79
diff
changeset
|
395 if (as -> passnum == 2 && slot >= 0) |
e12edcfbebd5
Fixed problem with expression evaluation infrastructure not advancing input pointer on pass 2
lost
parents:
79
diff
changeset
|
396 *inp = l -> exprends[slot]; |
77 | 397 |
398 if (s && lwasm_expr_is_constant(s)) | |
399 { | |
94
83ba34ed11b3
Fixed problem with constant expressions evaluating to 0 when they shouldn't
lost
parents:
93
diff
changeset
|
400 *val = lwasm_expr_get_value(s); |
77 | 401 lwasm_expr_stack_free(s); |
402 l -> exprs[slot] = NULL; | |
403 s = NULL; | |
94
83ba34ed11b3
Fixed problem with constant expressions evaluating to 0 when they shouldn't
lost
parents:
93
diff
changeset
|
404 return 0; |
77 | 405 } |
406 | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
407 if (!s && slot >= 0) |
77 | 408 { |
409 *val = l -> exprvals[slot]; | |
410 return 0; | |
411 } | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
412 else if (!s) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
413 { |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
414 *val = 0; |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
415 return 0; |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
416 } |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
417 |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
418 // was a constant result on pass 1 requested? |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
419 // that means we must have a constant on either pass |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
420 if (flag & EXPR_PASS1CONST) |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
421 { |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
422 *val = 0; |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
423 if (slot >= 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
424 l -> exprvals[slot] = 0; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
425 register_error(as, l, 1, "Illegal forward, external, or inter-section reference"); |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
426 lwasm_expr_stack_free(s); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
427 if (slot >= 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
428 l -> exprs[slot] = NULL; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
429 return -1; |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
430 } |
77 | 431 |
432 return 1; | |
433 } | |
55 | 434 |
38 | 435 void debug_message(int level, const char *fmt, ...) |
436 { | |
437 va_list args; | |
438 | |
439 va_start(args, fmt); | |
440 if (debug_level >= level) | |
441 { | |
39 | 442 if (level > 0) |
443 fprintf(stderr, "DEBUG %d: ", level); | |
38 | 444 vfprintf(stderr, fmt, args); |
445 fputc('\n', stderr); | |
446 } | |
447 va_end(args); | |
448 } | |
57 | 449 |
450 int lwasm_next_context(asmstate_t *as) | |
451 { | |
58 | 452 int r; |
453 r = as -> nextcontext; | |
454 as -> nextcontext += 1; | |
455 debug_message(3, "lwasm_next_context(): %d (%d) pass %d", r, as -> nextcontext, as -> passnum); | |
456 return r; | |
57 | 457 } |
458 |