Mercurial > hg-old > index.cgi
annotate lwasm/pseudo.c @ 257:e27279180a73 2.x
Added support for include path to LWASM
author | lost |
---|---|
date | Tue, 22 Dec 2009 04:53:20 +0000 |
parents | c7a41b4c89b3 |
children | c79b3c88adbc |
rev | line source |
---|---|
0 | 1 /* |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
2 pseudo.c |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
3 Copyright © 2009 William Astle |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
4 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
5 This file is part of LWASM. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
6 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
7 LWASM is free software: you can redistribute it and/or modify it under the |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
8 terms of the GNU General Public License as published by the Free Software |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
9 Foundation, either version 3 of the License, or (at your option) any later |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
10 version. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
11 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
12 This program is distributed in the hope that it will be useful, but WITHOUT |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
15 more details. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
16 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
17 You should have received a copy of the GNU General Public License along with |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
18 this program. If not, see <http://www.gnu.org/licenses/>. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
19 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
20 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
21 This file implements the various pseudo operations. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
22 */ |
212 | 23 #include <config.h> |
225
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
24 #include <errno.h> |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
25 #include <stdio.h> |
0 | 26 #include <stdlib.h> |
50 | 27 #include <string.h> |
0 | 28 #include "lwasm.h" |
29 #include "instab.h" | |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
30 #include "expr.h" |
52 | 31 #include "util.h" |
0 | 32 |
52 | 33 extern int lwasm_read_file(asmstate_t *as, const char *filename); |
0 | 34 |
158
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
35 OPFUNC(pseudo_noop) |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
36 { |
229 | 37 skip_operand(p); |
158
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
38 } |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
39 |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
40 OPFUNC(pseudo_org) |
0 | 41 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
42 int v, r; |
52 | 43 |
74 | 44 if (as -> csect) |
45 { | |
46 register_error(as, l, 1, "ORG not allowed within sections"); | |
47 return; | |
48 } | |
241 | 49 if (as -> inmod) |
50 { | |
51 register_error(as, l, 1, "ORG not allowed within modules"); | |
52 return; | |
53 } | |
74 | 54 |
52 | 55 if (as -> passnum != 1) |
56 { | |
57 // org is not needed to be processed on pass 2 | |
58 // this will prevent phasing errors for forward references that | |
59 // resolve on the second pass | |
60 // we saved the org address in l -> codeaddr on pass 1 | |
61 as -> addr = l -> codeaddr; | |
229 | 62 skip_operand(p); |
52 | 63 return; |
64 } | |
0 | 65 |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
66 if (l -> sym) |
0 | 67 { |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
68 register_error(as, l, 1, "No symbol allowed with ORG"); |
0 | 69 } |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
70 |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
71 r = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v, 0); |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
72 if (r != 0) |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
73 return; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
74 l -> codeaddr = v; |
49
21ae0fab469b
Added needed infra for useful listing of EQU and ORG type statements
lost
parents:
47
diff
changeset
|
75 l -> addrset = 1; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
76 as -> addr = v; |
0 | 77 } |
78 | |
47
804d7465e0f9
Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents:
4
diff
changeset
|
79 /* |
52 | 80 The operand for include is a string optionally enclosed in " |
81 */ | |
82 OPFUNC(pseudo_include) | |
0 | 83 { |
84 int v1; | |
52 | 85 char *fn; |
57 | 86 |
52 | 87 // only include files on pass 1 |
88 // but make sure local include context is right | |
89 // for the next line... | |
0 | 90 if (as -> passnum != 1) |
52 | 91 { |
57 | 92 as -> context = lwasm_next_context(as); |
229 | 93 skip_operand(p); |
0 | 94 return; |
52 | 95 } |
96 | |
97 while (**p && isspace(**p)) | |
98 (*p)++; | |
99 | |
100 if (!**p) | |
0 | 101 { |
52 | 102 register_error(as, l, 1, "Bad file name"); |
0 | 103 return; |
104 } | |
52 | 105 |
106 if (**p == '"') | |
107 { | |
108 // search for ending " | |
109 (*p)++; | |
110 for (v1 = 0; *((*p)+v1) && *((*p)+v1) != '"'; v1++) | |
111 /* do nothing */ ; | |
112 if (*((*p)+v1) != '"') | |
113 { | |
114 register_error(as, l, 1, "Bad file name"); | |
115 return; | |
116 } | |
117 } | |
118 else | |
0 | 119 { |
52 | 120 // search for a space type character |
121 for (v1 = 0; *((*p)+v1) && !isspace(*((*p)+v1)); v1++) | |
122 ; | |
0 | 123 } |
52 | 124 |
125 fn = lwasm_alloc(v1 + 1); | |
126 memcpy(fn, *p, v1); | |
127 fn[v1] = '\0'; | |
128 | |
225
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
129 (*p) += v1; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
130 if (**p == '"') |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
131 (*p)++; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
132 |
257 | 133 // resolve file name |
134 if (*fn != '/') | |
135 { | |
136 char *path; | |
137 int i; | |
138 FILE *fp; | |
139 | |
140 fp = fopen(fn, "r"); | |
141 if (!fp) | |
142 { | |
143 | |
144 | |
145 for (i = 0; i < as -> nincludedirs; i++) | |
146 { | |
147 0 == asprintf(&path, "%s/%s", as -> includedirs[i], fn); | |
148 fp = fopen(path, "r"); | |
149 if (fp) | |
150 { | |
151 fclose(fp); | |
152 lwasm_free(fn); | |
153 fn = path; | |
154 break; | |
155 } | |
156 lwasm_free(path); | |
157 } | |
158 } | |
159 else | |
160 { | |
161 fclose(fp); | |
162 } | |
163 } | |
164 | |
52 | 165 // end local label context on include |
57 | 166 as -> context = lwasm_next_context(as); |
52 | 167 if (lwasm_read_file(as, fn) < 0) |
168 { | |
169 register_error(as, l, 1, "File include error (%s)", fn); | |
170 } | |
171 lwasm_free(fn); | |
0 | 172 } |
173 | |
225
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
174 /* |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
175 The operand for includebin is a string optionally enclosed in " |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
176 */ |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
177 OPFUNC(pseudo_includebin) |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
178 { |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
179 int v1; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
180 char *fn; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
181 FILE *f; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
182 |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
183 // only include files on pass 1 |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
184 while (**p && isspace(**p)) |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
185 (*p)++; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
186 |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
187 if (!**p) |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
188 { |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
189 register_error(as, l, 1, "Bad file name"); |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
190 return; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
191 } |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
192 |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
193 if (**p == '"') |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
194 { |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
195 // search for ending " |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
196 (*p)++; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
197 for (v1 = 0; *((*p)+v1) && *((*p)+v1) != '"'; v1++) |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
198 /* do nothing */ ; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
199 if (*((*p)+v1) != '"') |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
200 { |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
201 register_error(as, l, 1, "Bad file name"); |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
202 return; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
203 } |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
204 } |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
205 else |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
206 { |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
207 // search for a space type character |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
208 for (v1 = 0; *((*p)+v1) && !isspace(*((*p)+v1)); v1++) |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
209 ; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
210 } |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
211 |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
212 fn = lwasm_alloc(v1 + 1); |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
213 memcpy(fn, *p, v1); |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
214 fn[v1] = '\0'; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
215 |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
216 (*p) += v1; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
217 if (**p == '"') |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
218 (*p)++; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
219 |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
220 // open the file |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
221 f = fopen(fn, "rb"); |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
222 if (!f) |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
223 { |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
224 register_error(as, l, 1, "Cannot open file: %s", strerror(errno)); |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
225 register_error(as, l, 2, "Cannot open file: %s", strerror(errno)); |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
226 } |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
227 |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
228 // don't need fn any more |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
229 lwasm_free(fn); |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
230 |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
231 // read the contents of the file and "emit()" it |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
232 while (!feof(f) && !ferror(f)) |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
233 { |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
234 v1 = fgetc(f); |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
235 if (v1 == EOF) |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
236 break; |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
237 lwasm_emit(as, l, v1); |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
238 } |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
239 // close file |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
240 fclose(f); |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
241 } |
058f18119025
Fixed filename parsing bug in include directive and added includebin directive
lost
parents:
221
diff
changeset
|
242 |
50 | 243 OPFUNC(pseudo_rmb) |
0 | 244 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
245 int r, v; |
0 | 246 |
95 | 247 if (as -> passnum == 2) |
0 | 248 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
249 as -> addr += l -> nocodelen; |
229 | 250 skip_operand(p); |
0 | 251 return; |
252 } | |
103 | 253 r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v, -1); |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
254 if (r != 0) |
0 | 255 return; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
256 l -> nocodelen = v; |
254 | 257 if (as -> instruct) |
258 return; | |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
259 as -> addr += v; |
0 | 260 } |
53 | 261 |
262 OPFUNC(pseudo_rmd) | |
0 | 263 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
264 int r, v; |
0 | 265 |
95 | 266 if (as -> passnum == 2) |
0 | 267 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
268 as -> addr += l -> nocodelen; |
229 | 269 skip_operand(p); |
0 | 270 return; |
271 } | |
103 | 272 r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v, 0); |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
273 if (r != 0) |
0 | 274 return; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
275 v *= 2; |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
276 l -> nocodelen = v; |
254 | 277 if (as -> instruct) |
278 return; | |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
279 as -> addr += v; |
0 | 280 } |
281 | |
53 | 282 OPFUNC(pseudo_rmq) |
0 | 283 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
284 int r, v; |
0 | 285 |
95 | 286 if (as -> passnum == 2) |
0 | 287 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
288 as -> addr += l -> nocodelen; |
229 | 289 skip_operand(p); |
0 | 290 return; |
291 } | |
103 | 292 r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v, 0); |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
293 if (r != 0) |
0 | 294 return; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
295 v *= 4; |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
296 l -> nocodelen = v; |
254 | 297 if (as -> instruct) |
298 return; | |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
299 as -> addr += v; |
0 | 300 } |
301 | |
53 | 302 OPFUNC(pseudo_zmb) |
0 | 303 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
304 int r, v; |
0 | 305 |
103 | 306 r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v, 0); |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
307 if (r != 0) |
0 | 308 return; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
309 while (v--) |
53 | 310 lwasm_emit(as, l, 0); |
0 | 311 } |
312 | |
53 | 313 OPFUNC(pseudo_zmd) |
0 | 314 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
315 int r, v; |
0 | 316 |
103 | 317 r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v, 0); |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
318 if (r != 0) |
0 | 319 return; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
320 v *= 2; |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
321 while (v--) |
53 | 322 lwasm_emit(as, l, 0); |
0 | 323 } |
324 | |
53 | 325 OPFUNC(pseudo_zmq) |
326 { | |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
327 int r, v; |
53 | 328 |
103 | 329 r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v, 0); |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
330 if (r != 0) |
53 | 331 return; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
332 v *= 4; |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
333 while (v--) |
53 | 334 lwasm_emit(as, l, 0); |
335 } | |
336 | |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
337 OPFUNC(pseudo_end) |
0 | 338 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
339 int r, v; |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
340 lwasm_expr_stack_t *s; |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
341 |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
342 |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
343 as -> endseen = 1; |
0 | 344 |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
345 // address only matters for DECB output |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
346 if (as -> outformat != OUTPUT_DECB) |
229 | 347 { |
348 skip_operand(p); | |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
349 return; |
229 | 350 } |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
351 |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
352 r = lwasm_expr_result2(as, l, p, 0, &v, 0); |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
353 if (r != 0) |
0 | 354 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
355 register_error(as, l, 2, "Bad operand"); |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
356 } |
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
357 |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
358 v = v & 0xffff; |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
359 if (as -> passnum == 2) |
0 | 360 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
361 as -> execaddr = v; |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
362 l -> symaddr = v; |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
363 l -> addrset = 2; |
0 | 364 } |
54
360d53062bb9
Fixed typo in instruction table and added END directive
lost
parents:
53
diff
changeset
|
365 } |
0 | 366 |
56 | 367 |
368 OPFUNC(pseudo_align) | |
0 | 369 { |
370 int cn; | |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
371 int r, v; |
235 | 372 int pad = 0; |
373 // we have to parse this on pass 2 so that we get the pad value | |
374 // if (as -> passnum == 2) | |
375 // { | |
376 // skip_operand(p); | |
377 // while (as -> addr < l -> symaddr) | |
378 // lwasm_emit(as, l, 0); | |
379 // return; | |
380 // } | |
56 | 381 |
103 | 382 r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v, 0); |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
383 if (r != 0) |
56 | 384 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
385 l -> symaddr = as -> addr; |
0 | 386 return; |
387 } | |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
388 |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
389 if (v < 1) |
56 | 390 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
391 register_error(as, l, 1, "Illegal alignment %d", v); |
56 | 392 return; |
0 | 393 } |
56 | 394 |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
395 cn = l -> codeaddr % v; |
56 | 396 if (cn) |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
397 cn = v - cn; |
56 | 398 |
235 | 399 if (**p == ',') |
400 { | |
401 // we have a padding value specified | |
402 (*p)++; | |
403 r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST, &pad, 1); | |
404 if (r != 0 && as -> passnum == 2) | |
405 { | |
406 register_error(as, l, 2, "Illegal padding value - must be constant on pass 2"); | |
407 return; | |
408 } | |
409 } | |
410 | |
56 | 411 while (cn--) |
412 { | |
235 | 413 lwasm_emit(as, l, pad); |
56 | 414 } |
415 l -> symaddr = as -> addr; | |
0 | 416 } |
56 | 417 |
50 | 418 OPFUNC(pseudo_equ) |
0 | 419 { |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
420 int r, v; |
52 | 421 |
50 | 422 if (l -> sym == NULL) |
0 | 423 { |
50 | 424 register_error(as, l, 1, "No symbol specified"); |
0 | 425 return; |
426 } | |
50 | 427 |
103 | 428 r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v, 0); |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
429 if (r < 0) |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
430 v = 0; |
63
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
431 |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
74
diff
changeset
|
432 l -> symaddr = v & 0xFFFF; |
50 | 433 l -> addrset = 2; |
63
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
434 |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
435 // note: we need to do this because the symbol might have resolved |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
436 // to a constant! |
190 | 437 lwasm_register_symbol(as, l, l -> sym, v, (r > 0 ? SYMBOL_COMPLEX: SYMBOL_NORM) | SYMBOL_FORCE | (l -> forceglobal ? SYMBOL_GLOBAL : SYMBOL_NORM)); |
0 | 438 } |
63
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
439 |
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
440 OPFUNC(pseudo_set) |
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
441 { |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
442 int r, v; |
64 | 443 |
444 // set MUST run on both passes as the symbol value changes! | |
445 | |
446 if (l -> sym == NULL) | |
447 { | |
448 register_error(as, l, 1, "No symbol specified"); | |
449 return; | |
450 } | |
451 | |
103 | 452 r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v, 0); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
453 if (r < 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
454 v = 0; |
64 | 455 |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
456 l -> symaddr = v & 0xFFFF; |
64 | 457 l -> addrset = 2; |
458 | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
459 lwasm_register_symbol(as, l, l -> sym, v, (r > 0 ? SYMBOL_COMPLEX: SYMBOL_NORM) | SYMBOL_SET); |
63
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
460 } |
d85ba47b1e8f
Moved symbol registration so symbols that are in skipped code do not get registered and so EQU/SET can do their own registration
lost
parents:
57
diff
changeset
|
461 |
65
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
462 OPFUNC(pseudo_setdp) |
0 | 463 { |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
464 int r, v; |
0 | 465 |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
466 if (as -> outformat == OUTPUT_OBJ) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
467 { |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
468 register_error(as, l, 1, "SETDP not permitted with OBJ target"); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
469 return; |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
470 } |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
471 |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
472 // setdp is needed on both passes; must resolve to a constant on pass 1 |
103 | 473 r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v, 0); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
474 if (r != 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
475 return; |
65
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
476 |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
477 if (v < -127 || v > 255) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
478 { |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
479 register_error(as, l, 1, "Byte overflow"); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
480 return; |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
481 } |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
482 |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
483 l -> symaddr = v & 0xFF; |
65
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
484 l -> addrset = 2; |
31d8e85706e7
Implemented setdp and corrected handling of direct page detection in insn_gen_aux()
lost
parents:
64
diff
changeset
|
485 |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
486 as -> dpval = v & 0xFF; |
0 | 487 } |
488 | |
160
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
489 // used to get a byte from a string |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
490 // -1 is end of line |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
491 int pseudo_fcc_fetchchar(asmstate_t *as, char **p) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
492 { |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
493 int c; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
494 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
495 // - |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
496 if (!**p) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
497 return -1; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
498 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
499 c = (unsigned char)(**p); |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
500 (*p)++; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
501 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
502 if (as -> pragmas & PRAGMA_CESCAPES && c == '\\') |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
503 { |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
504 // decode escapes if needed |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
505 if (!**p) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
506 return c; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
507 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
508 c = **p; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
509 (*p)++; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
510 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
511 switch (c) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
512 { |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
513 // octal value |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
514 // 1, 2, or 3 digits |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
515 // NOTE: \0 for NUL is included in this... |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
516 case '0': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
517 case '1': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
518 case '2': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
519 case '3': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
520 case '4': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
521 case '5': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
522 case '6': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
523 case '7': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
524 c -= '0'; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
525 if (**p < '0' || **p > '9') |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
526 return c; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
527 c = c << 3; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
528 c |= **p - '0'; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
529 (*p)++; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
530 if (**p < '0' || **p > '9') |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
531 return c; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
532 c = c << 3; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
533 c |= **p - '0'; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
534 (*p)++; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
535 return c; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
536 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
537 // LF |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
538 case 'n': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
539 return 10; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
540 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
541 // CR |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
542 case 'r': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
543 return 13; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
544 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
545 // TAB |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
546 case 't': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
547 return 9; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
548 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
549 // VT |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
550 case 'v': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
551 return 11; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
552 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
553 // BS |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
554 case 'b': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
555 return 8; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
556 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
557 // FF |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
558 case 'f': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
559 return 12; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
560 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
561 // BEL |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
562 case 'a': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
563 return 7; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
564 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
565 // hex char code (2 chars) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
566 case 'x': |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
567 { |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
568 int c2; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
569 if (!**p) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
570 return 'x'; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
571 c = toupper(**p); |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
572 (*p)++; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
573 if (c < '0' || (c > '9' && c < 'A') || c > 'F') |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
574 return 0; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
575 c -= '0'; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
576 if (c > 9) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
577 c -= 7; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
578 c2 = c << 4; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
579 if (!**p) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
580 return 0; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
581 c = toupper(**p); |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
582 (*p)++; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
583 if (c < '0' || (c > '9' && c < 'A') || c > 'F') |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
584 return 0; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
585 c -= '0'; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
586 if (c > 9) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
587 c -= 7; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
588 c2 |= c; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
589 return c2; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
590 } |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
591 // everything else stands for itself as a fall back or legit |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
592 default: |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
593 return c; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
594 } |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
595 } |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
596 return c; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
597 } |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
598 |
56 | 599 OPFUNC(pseudo_fcc) |
600 { | |
0 | 601 int delim = 0; |
160
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
602 int c; |
0 | 603 |
56 | 604 delim = **p; |
0 | 605 if (!delim) |
606 { | |
56 | 607 register_error(as, l, 1, "Bad operand"); |
608 return; | |
0 | 609 } |
56 | 610 *p += 1; |
160
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
611 for (;;) |
0 | 612 { |
160
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
613 c = pseudo_fcc_fetchchar(as, p); |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
614 if (c == delim || c < 0) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
615 break; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
616 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
617 lwasm_emit(as, l, c); |
0 | 618 } |
619 } | |
620 | |
56 | 621 |
622 OPFUNC(pseudo_fcs) | |
0 | 623 { |
624 int delim = 0; | |
160
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
625 int c, lc = -1; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
626 |
56 | 627 delim = **p; |
0 | 628 if (!delim) |
629 { | |
56 | 630 register_error(as, l, 1, "Bad operand"); |
631 return; | |
0 | 632 } |
56 | 633 *p += 1; |
160
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
634 for (;;) |
0 | 635 { |
160
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
636 c = pseudo_fcc_fetchchar(as, p); |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
637 if (c == delim || c < 0) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
638 { |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
639 if (lc >= 0) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
640 lwasm_emit(as, l, lc | 0x80); |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
641 break; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
642 } |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
643 if (lc >= 0) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
644 lwasm_emit(as, l, lc); |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
645 lc = c; |
0 | 646 } |
647 } | |
648 | |
56 | 649 OPFUNC(pseudo_fcn) |
0 | 650 { |
651 int delim = 0; | |
160
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
652 int c; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
653 |
56 | 654 delim = **p; |
0 | 655 if (!delim) |
656 { | |
56 | 657 register_error(as, l, 1, "Bad operand"); |
658 return; | |
0 | 659 } |
56 | 660 *p += 1; |
160
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
661 for (;;) |
0 | 662 { |
160
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
663 c = pseudo_fcc_fetchchar(as, p); |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
664 if (c == delim || c < 0) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
665 break; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
666 |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
667 lwasm_emit(as, l, c); |
0 | 668 } |
56 | 669 lwasm_emit(as, l, 0); |
0 | 670 } |
56 | 671 |
672 OPFUNC(pseudo_fcb) | |
0 | 673 { |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
674 int r, v; |
0 | 675 |
676 fcb_again: | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
677 r = lwasm_expr_result2(as, l, p, 0, &v, -1); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
678 if (r < 0) |
56 | 679 return; |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
680 |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
681 if (r > 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
682 { |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
683 register_error(as, l, 2, "Illegal external or inter-segment reference"); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
684 v = 0; |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
685 } |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
686 |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
687 if (v < -127 || v > 255) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
688 { |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
689 register_error(as, l, 1, "Byte overflow"); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
690 } |
56 | 691 |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
692 lwasm_emit(as, l, v); |
56 | 693 if (**p == ',') |
0 | 694 { |
56 | 695 (*p)++; |
0 | 696 goto fcb_again; |
697 } | |
698 } | |
699 | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
700 // FIXME: handle external references in an intelligent way |
56 | 701 OPFUNC(pseudo_fdb) |
0 | 702 { |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
703 int r, v; |
103 | 704 int extseen = 0; |
705 char *p1; | |
0 | 706 |
707 fdb_again: | |
103 | 708 p1 = *p; |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
709 r = lwasm_expr_result2(as, l, p, 0, &v, -1); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
710 if (r < 0) |
56 | 711 return; |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
712 |
103 | 713 if (r > 0 && extseen == 1) |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
714 { |
103 | 715 register_error(as, l, 2, "Illegal external or inter-segment reference (only 1 per FDB line)"); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
716 v = 0; |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
717 } |
103 | 718 else if (r > 0) |
719 { | |
720 l -> relocoff = as -> addr - l -> codeaddr; | |
721 *p = p1; | |
722 r = lwasm_expr_result2(as, l, p, 0, &v, 0); | |
723 } | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
724 |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
725 lwasm_emit(as, l, v >> 8); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
726 lwasm_emit(as, l, v & 0xff); |
56 | 727 if (**p == ',') |
0 | 728 { |
56 | 729 (*p)++; |
0 | 730 goto fdb_again; |
731 } | |
732 } | |
733 | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
734 // FIXME: handle external references in a sensible way |
56 | 735 OPFUNC(pseudo_fqb) |
0 | 736 { |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
737 int r, v; |
56 | 738 |
0 | 739 fqb_again: |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
740 r = lwasm_expr_result2(as, l, p, 0, &v, -1); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
741 if (r < 0) |
56 | 742 return; |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
743 |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
744 if (r > 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
745 { |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
746 register_error(as, l, 2, "Illegal external or inter-segment reference"); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
747 v = 0; |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
748 } |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
749 |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
750 lwasm_emit(as, l, v >> 24); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
751 lwasm_emit(as, l, v >> 16); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
752 lwasm_emit(as, l, v >> 8); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
753 lwasm_emit(as, l, v & 0xff); |
56 | 754 if (**p == ',') |
0 | 755 { |
56 | 756 (*p)++; |
0 | 757 goto fqb_again; |
758 } | |
759 } | |
760 | |
761 // don't need to do anything if we are executing one of these | |
57 | 762 OPFUNC(pseudo_endc) |
0 | 763 { |
57 | 764 if (as -> skipcond && !(as -> skipmacro)) |
765 { | |
766 as -> skipcount -= 1; | |
767 if (as -> skipcount <= 0) | |
768 { | |
769 as -> skipcond = 0; | |
770 } | |
771 } | |
0 | 772 return; |
773 } | |
774 | |
775 // if "else" executes, we must be going into an "ignore" state | |
57 | 776 OPFUNC(pseudo_else) |
0 | 777 { |
57 | 778 if (as -> skipmacro) |
779 return; | |
780 | |
781 if (as -> skipcond) | |
782 { | |
783 if (as -> skipcount == 1) | |
784 { | |
785 as -> skipcount = 0; | |
786 as -> skipcond = 0; | |
787 } | |
788 return; | |
789 } | |
790 | |
0 | 791 as -> skipcond = 1; |
792 as -> skipcount = 1; | |
793 } | |
794 | |
57 | 795 OPFUNC(pseudo_ifne) |
0 | 796 { |
797 int v1; | |
798 int rval; | |
57 | 799 |
800 if (as -> skipcond && !(as -> skipmacro)) | |
0 | 801 { |
57 | 802 as -> skipcount++; |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
803 skip_operand(p); |
57 | 804 return; |
805 } | |
806 | |
103 | 807 rval = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v1, 0); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
808 if (rval != 0) |
57 | 809 return; |
810 if (!v1) | |
811 { | |
812 as -> skipcond = 1; | |
813 as -> skipcount = 1; | |
0 | 814 } |
815 } | |
57 | 816 |
104 | 817 OPFUNC(pseudo_ifdef) |
818 { | |
819 lwasm_symbol_ent_t *se; | |
820 char *sym; | |
821 char *p2; | |
822 | |
823 if (as -> skipcond && !(as -> skipmacro)) | |
824 { | |
825 as -> skipcount++; | |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
826 skip_operand(p); |
104 | 827 return; |
828 } | |
829 | |
830 if (as -> passnum != 1) | |
831 { | |
229 | 832 skip_operand(p); |
104 | 833 if (!(l -> fsize)) |
834 { | |
835 as -> skipcond = 1; | |
836 as -> skipcount = 1; | |
837 } | |
838 return; | |
839 } | |
840 | |
841 if (!**p) | |
842 { | |
843 register_error(as, l, 1, "Need symbol name"); | |
844 return; | |
845 } | |
846 | |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
847 for (p2 = *p; **p && !isspace(**p); (*p)++) |
104 | 848 /* do nothing */ ; |
849 | |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
850 sym = lwasm_alloc(*p - p2 + 1); |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
851 memcpy(sym, p2, *p - p2); |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
852 sym[*p - p2] = '\0'; |
104 | 853 |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
854 // fprintf(stderr, "STUFF: %s; '%s'; '%s' (%d)\n", p2, *p, sym, as -> passnum); |
104 | 855 se = lwasm_find_symbol(as, sym, l -> context); |
856 if (!se) | |
857 se = lwasm_find_symbol(as, sym, -1); | |
858 | |
859 lwasm_free(sym); | |
860 | |
861 if (!se) | |
862 { | |
863 as -> skipcond = 1; | |
864 as -> skipcount = 1; | |
865 l -> fsize = 0; | |
866 } | |
867 else | |
868 { | |
869 l -> fsize = 1; | |
870 } | |
871 } | |
872 | |
873 OPFUNC(pseudo_ifndef) | |
874 { | |
875 lwasm_symbol_ent_t *se; | |
876 char *sym; | |
877 char *p2; | |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
878 |
104 | 879 if (as -> skipcond && !(as -> skipmacro)) |
880 { | |
881 as -> skipcount++; | |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
882 skip_operand(p); |
104 | 883 return; |
884 } | |
885 | |
886 if (as -> passnum != 1) | |
887 { | |
229 | 888 skip_operand(p); |
104 | 889 if (l -> fsize) |
890 { | |
891 as -> skipcond = 1; | |
892 as -> skipcount = 1; | |
893 } | |
894 return; | |
895 } | |
896 | |
897 if (!**p) | |
898 { | |
899 register_error(as, l, 1, "Need symbol name"); | |
900 return; | |
901 } | |
902 | |
903 for (p2 = *p; *p2 && !isspace(*p2); p2++) | |
904 /* do nothing */ ; | |
905 | |
906 sym = lwasm_alloc(p2 - *p + 1); | |
907 memcpy(sym, *p, p2 - *p); | |
908 sym[p2 - *p] = '\0'; | |
909 | |
910 *p = p2; | |
911 | |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
912 // fprintf(stderr, "STUFF2: %s; '%s'; '%s' (%d)\n", *p, p2, sym, as -> passnum); |
104 | 913 se = lwasm_find_symbol(as, sym, l -> context); |
914 if (!se) | |
915 se = lwasm_find_symbol(as, sym, -1); | |
916 | |
917 lwasm_free(sym); | |
918 | |
919 if (se) | |
920 { | |
921 as -> skipcond = 1; | |
922 as -> skipcount = 1; | |
923 l -> fsize = 0; | |
924 } | |
925 else | |
926 { | |
927 l -> fsize = 1; | |
928 } | |
929 } | |
930 | |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
931 OPFUNC(pseudo_ifp1) |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
932 { |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
933 if (as -> skipcond && !(as -> skipmacro)) |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
934 { |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
935 as -> skipcount++; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
936 skip_operand(p); |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
937 return; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
938 } |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
939 |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
940 if (as -> passnum != 1) |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
941 { |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
942 as -> skipcond = 1; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
943 as -> skipcount = 1; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
944 } |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
945 } |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
946 |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
947 OPFUNC(pseudo_ifp2) |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
948 { |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
949 if (as -> skipcond && !(as -> skipmacro)) |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
950 { |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
951 as -> skipcount++; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
952 skip_operand(p); |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
953 return; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
954 } |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
955 |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
956 if (as -> passnum != 2) |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
957 { |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
958 as -> skipcond = 1; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
959 as -> skipcount = 1; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
960 } |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
961 } |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
962 |
57 | 963 OPFUNC(pseudo_ifeq) |
0 | 964 { |
965 int v1; | |
966 int rval; | |
57 | 967 |
968 if (as -> skipcond && !(as -> skipmacro)) | |
0 | 969 { |
57 | 970 as -> skipcount++; |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
971 skip_operand(p); |
57 | 972 return; |
0 | 973 } |
57 | 974 |
103 | 975 rval = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v1, 0); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
976 if (rval != 0) |
57 | 977 return; |
978 if (v1) | |
0 | 979 { |
57 | 980 as -> skipcond = 1; |
981 as -> skipcount = 1; | |
0 | 982 } |
983 } | |
57 | 984 |
985 OPFUNC(pseudo_iflt) | |
0 | 986 { |
987 int v1; | |
988 int rval; | |
57 | 989 |
990 if (as -> skipcond && !(as -> skipmacro)) | |
0 | 991 { |
57 | 992 as -> skipcount++; |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
993 skip_operand(p); |
57 | 994 return; |
0 | 995 } |
57 | 996 |
103 | 997 rval = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v1, 0); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
998 if (rval != 0) |
57 | 999 return; |
1000 if (v1 >= 0) | |
0 | 1001 { |
57 | 1002 as -> skipcond = 1; |
1003 as -> skipcount = 1; | |
0 | 1004 } |
1005 } | |
57 | 1006 |
1007 OPFUNC(pseudo_ifle) | |
0 | 1008 { |
1009 int v1; | |
1010 int rval; | |
57 | 1011 |
1012 if (as -> skipcond && !(as -> skipmacro)) | |
0 | 1013 { |
57 | 1014 as -> skipcount++; |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
1015 skip_operand(p); |
57 | 1016 return; |
0 | 1017 } |
57 | 1018 |
103 | 1019 rval = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v1, 0); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
1020 if (rval != 0) |
57 | 1021 return; |
1022 if (v1 > 0) | |
0 | 1023 { |
57 | 1024 as -> skipcond = 1; |
1025 as -> skipcount = 1; | |
0 | 1026 } |
1027 } | |
57 | 1028 |
1029 OPFUNC(pseudo_ifgt) | |
0 | 1030 { |
1031 int v1; | |
1032 int rval; | |
57 | 1033 |
1034 if (as -> skipcond && !(as -> skipmacro)) | |
0 | 1035 { |
57 | 1036 as -> skipcount++; |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
1037 skip_operand(p); |
57 | 1038 return; |
0 | 1039 } |
57 | 1040 |
103 | 1041 rval = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v1, 0); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
1042 if (rval != 0) |
57 | 1043 return; |
1044 if (v1 <= 0) | |
0 | 1045 { |
57 | 1046 as -> skipcond = 1; |
1047 as -> skipcount = 1; | |
0 | 1048 } |
1049 } | |
57 | 1050 |
1051 OPFUNC(pseudo_ifge) | |
0 | 1052 { |
1053 int v1; | |
1054 int rval; | |
57 | 1055 |
1056 if (as -> skipcond && !(as -> skipmacro)) | |
0 | 1057 { |
57 | 1058 as -> skipcount++; |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
235
diff
changeset
|
1059 skip_operand(p); |
57 | 1060 return; |
0 | 1061 } |
57 | 1062 |
103 | 1063 rval = lwasm_expr_result2(as, l, p, EXPR_SECTCONST | EXPR_PASS1CONST, &v1, 0); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
1064 if (rval != 0) |
57 | 1065 return; |
1066 if (v1 < 0) | |
0 | 1067 { |
57 | 1068 as -> skipcond = 1; |
1069 as -> skipcount = 1; | |
0 | 1070 } |
1071 } | |
1072 | |
56 | 1073 OPFUNC(pseudo_error) |
0 | 1074 { |
56 | 1075 register_error(as, l, 1, "User error: %s", *p); |
0 | 1076 } |
56 | 1077 |
74 | 1078 |
1079 OPFUNC(pseudo_section) | |
1080 { | |
1081 sectiontab_t *s; | |
1082 char *p2; | |
1083 char *sn; | |
1084 char *opts; | |
1085 | |
99 | 1086 |
74 | 1087 if (as -> outformat != OUTPUT_OBJ) |
1088 { | |
1089 register_error(as, l, 1, "Sections only supported for obj target"); | |
1090 return; | |
1091 } | |
1092 | |
1093 if (as -> csect) | |
1094 { | |
1095 as -> csect -> offset = as -> addr; | |
1096 as -> csect = NULL; | |
1097 } | |
1098 | |
1099 if (!**p) | |
1100 { | |
1101 register_error(as, l, 1, "Need section name"); | |
1102 return; | |
1103 } | |
1104 | |
1105 for (p2 = *p; *p2 && !isspace(*p2); p2++) | |
1106 /* do nothing */ ; | |
1107 | |
1108 sn = lwasm_alloc(p2 - *p + 1); | |
1109 memcpy(sn, *p, p2 - *p); | |
1110 sn[p2 - *p] = '\0'; | |
1111 | |
1112 *p = p2; | |
1113 | |
1114 opts = strchr(sn, ','); | |
1115 if (opts) | |
1116 { | |
1117 *opts++ = '\0'; | |
1118 } | |
1119 | |
1120 // have we seen the section name already? | |
1121 for (s = as -> sections; s; s = s -> next) | |
1122 { | |
1123 if (!strcmp(s -> name, sn)) | |
1124 break; | |
1125 } | |
1126 | |
99 | 1127 if (s && as -> passnum == 1) |
74 | 1128 { |
1129 lwasm_free(sn); | |
1130 if (opts) | |
1131 { | |
1132 register_error(as, l, 1, "Section options can only be specified the first time"); | |
1133 return; | |
1134 } | |
1135 } | |
1136 else if (!s) | |
1137 { | |
1138 s = lwasm_alloc(sizeof(sectiontab_t)); | |
1139 s -> name = sn; | |
1140 s -> offset = 0; | |
1141 s -> flags = 0; | |
85 | 1142 s -> obytes = NULL; |
1143 s -> oblen = 0; | |
1144 s -> obsize = 0; | |
86 | 1145 s -> rl = NULL; |
90 | 1146 s -> exports = NULL; |
160
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
1147 // if name of section is "bss" or ".bss", assume bss flag |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
1148 // which can be overridden with !bss flag |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
1149 if (!strcasecmp(sn, "bss") || !strcasecmp(sn, ".bss")) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
1150 s -> flags = SECTION_BSS; |
74 | 1151 // parse options; only one "bss" |
1152 if (opts && as -> passnum == 1) | |
1153 { | |
1154 if (!strcasecmp(opts, "bss")) | |
1155 { | |
160
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
1156 s -> flags |= SECTION_BSS; |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
1157 } |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
1158 else if (!strcasecmp(opts, "!bss")) |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
1159 { |
b061350c17e4
Added cescapes pragma and a few other compatibility pseudo ops
lost
parents:
158
diff
changeset
|
1160 s -> flags &= ~SECTION_BSS; |
74 | 1161 } |
1162 else | |
1163 { | |
1164 register_error(as, l, 1, "Unrecognized section option '%s'", opts); | |
1165 lwasm_free(s -> name); | |
1166 lwasm_free(s); | |
1167 return; | |
1168 } | |
1169 } | |
1170 | |
1171 s -> next = as -> sections; | |
1172 as -> sections = s; | |
1173 } | |
1174 as -> addr = s -> offset; | |
1175 as -> csect = s; | |
1176 as -> context = lwasm_next_context(as); | |
1177 } | |
1178 | |
1179 OPFUNC(pseudo_endsection) | |
1180 { | |
1181 if (as -> outformat != OUTPUT_OBJ) | |
1182 { | |
1183 register_error(as, l, 1, "Sections only supported for obj target"); | |
1184 return; | |
1185 } | |
1186 | |
1187 if (!(as -> csect)) | |
1188 { | |
1189 register_error(as, l, 1, "ENDSECTION when not in a section"); | |
1190 return; | |
1191 } | |
1192 | |
1193 as -> csect -> offset = as -> addr; | |
1194 as -> addr = 0; | |
1195 as -> csect = 0; | |
1196 as -> context = lwasm_next_context(as); | |
229 | 1197 skip_operand(p); |
74 | 1198 } |
82 | 1199 |
1200 OPFUNC(pseudo_extern) | |
1201 { | |
1202 if (as -> passnum != 1) | |
1203 return; | |
1204 | |
1205 if (as -> outformat != OUTPUT_OBJ) | |
1206 { | |
1207 register_error(as, l, 1, "External references only supported for obj target"); | |
1208 return; | |
1209 } | |
1210 | |
1211 if (as -> csect) | |
1212 { | |
1213 register_error(as, l, 1, "Cannot declare external symbols within a section"); | |
1214 return; | |
1215 } | |
1216 | |
221 | 1217 if (l -> sym) |
1218 { | |
1219 lwasm_register_symbol(as, l, l -> sym, 0, SYMBOL_EXTERN); | |
229 | 1220 for ( ; **p; (*p)++) ; |
221 | 1221 return; |
1222 } | |
1223 | |
1224 while (**p) | |
1225 { | |
1226 char *sym2, *sym3; | |
1227 for (sym2 = *p; **p && !isspace(**p) && **p != ','; (*p)++) | |
1228 /* do nothing */ ; | |
1229 | |
1230 if (l -> sym) | |
1231 lwasm_free(l -> sym); | |
1232 | |
1233 sym3 = lwasm_alloc(*p - sym2 + 1); | |
1234 memcpy(sym3, sym2, *p - sym2); | |
1235 sym3[*p - sym2] = '\0'; | |
1236 | |
1237 l -> sym = sym3; | |
1238 debug_message(2, "import symbol: '%s'", sym3); | |
1239 lwasm_register_symbol(as, l, l -> sym, 0, SYMBOL_EXTERN); | |
1240 if (**p && (**p != ',')) | |
1241 { | |
1242 register_error(as, l, 1, "Bad import list"); | |
1243 return; | |
1244 } | |
1245 if (**p == ',') | |
1246 (*p)++; | |
1247 } | |
1248 if (!(l -> sym)) | |
1249 register_error(as, l, 1, "Bad import list"); | |
82 | 1250 } |
90 | 1251 |
243 | 1252 OPFUNC(pseudo_extdep) |
1253 { | |
1254 if (as -> passnum != 1) | |
1255 return; | |
1256 | |
1257 if (as -> outformat != OUTPUT_OBJ) | |
1258 { | |
1259 register_error(as, l, 1, "External references only supported for obj target"); | |
1260 return; | |
1261 } | |
1262 | |
1263 if (l -> sym) | |
1264 { | |
1265 // add symbol to the "ext dep" list | |
1266 as -> extdeps = lwasm_realloc(as -> extdeps, sizeof(char *) * (as -> nextdeps + 1)); | |
1267 as -> extdeps[as -> nextdeps++] = lwasm_strdup(l -> sym); | |
1268 return; | |
1269 } | |
1270 } | |
1271 | |
90 | 1272 OPFUNC(pseudo_export) |
1273 { | |
1274 lwasm_symbol_ent_t *se; | |
1275 export_list_t *ex; | |
158
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1276 char *sym2, *sym3; |
192
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1277 int after = 0; |
158
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1278 |
90 | 1279 if (as -> outformat != OUTPUT_OBJ) |
1280 { | |
1281 register_error(as, l, 1, "Symbol exports only supported for obj target"); | |
1282 return; | |
1283 } | |
158
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1284 |
90 | 1285 if (as -> passnum == 1) |
229 | 1286 { |
1287 skip_operand(p); | |
90 | 1288 return; |
229 | 1289 } |
1290 | |
1291 if (l -> sym) | |
1292 { | |
1293 for ( ; **p; (*p)++) ; | |
1294 } | |
90 | 1295 |
192
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1296 again: |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1297 if (!(l -> sym) || after == 1) |
158
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1298 { |
192
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1299 |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1300 after = 1; |
158
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1301 // look for symbol after op |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1302 if (**p) |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1303 { |
192
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1304 for (sym2 = *p; **p && !isspace(**p) && **p != ','; (*p)++) |
162 | 1305 /* do nothing */ ; |
192
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1306 |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1307 debug_message(2, "export expression: %s", sym2); |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1308 if (l -> sym) |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1309 lwasm_free(l -> sym); |
158
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1310 sym3 = lwasm_alloc(*p - sym2 + 1); |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1311 memcpy(sym3, sym2, *p - sym2); |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1312 sym3[*p - sym2] = '\0'; |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1313 |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1314 l -> sym = sym3; |
192
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1315 debug_message(2, "export symbol: '%s'", sym3); |
158
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1316 } |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1317 } |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1318 if (!(l -> sym)) |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1319 { |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1320 register_error(as, l, 2, "No symbol"); |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1321 return; |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1322 } |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1323 |
f0527dc3804d
Added support for .globl <sym>, .area <section>, .word, .byte, .blkb, and a .module directive that does nothing
lost
parents:
151
diff
changeset
|
1324 |
90 | 1325 // the symbol better be defined at this point (pass 2) |
1326 // local symbols cannot be exported nor can "global" symbols | |
1327 se = lwasm_find_symbol(as, l -> sym, -1); | |
202
1a75121c3c3f
Yet again try to get importing undefined exports working
lost
parents:
201
diff
changeset
|
1328 if ((!se || (se -> flags & SYMBOL_EXTERN)) && (as -> pragmas & PRAGMA_IMPORTUNDEFEXPORT)) |
198 | 1329 { |
201 | 1330 void *p; |
1331 p = as -> csect; | |
1332 as -> csect = NULL; | |
198 | 1333 lwasm_register_symbol(as, l, l -> sym, 0, SYMBOL_EXTERN); |
201 | 1334 as -> csect = p; |
198 | 1335 } |
199 | 1336 else |
90 | 1337 { |
201 | 1338 if (!se) |
199 | 1339 { |
1340 register_error(as, l, 2, "Exported symbols must be fully defined within a section"); | |
1341 return; | |
1342 } | |
1343 if (se -> sect == NULL) | |
1344 { | |
1345 register_error(as, l, 2, "Only non-local symbols within a section can be exported"); | |
1346 return; | |
1347 } | |
90 | 1348 |
199 | 1349 if (se -> flags & SYMBOL_SET) |
1350 { | |
1351 register_error(as, l, 2, "You cannot export symbols defined with SET"); | |
1352 return; | |
1353 } | |
90 | 1354 |
199 | 1355 // if the symbol is not already a simple value, re-evaluate it |
1356 // and see if it becomes simple | |
90 | 1357 |
1358 | |
199 | 1359 if (se -> flags & SYMBOL_COMPLEX) |
1360 { | |
1361 register_error(as, l, 2, "Exported symbols must be fully resolved on pass 2"); | |
1362 return; | |
1363 } | |
90 | 1364 |
199 | 1365 // search for existing export |
1366 for (ex = se -> sect -> exports; ex; ex = ex -> next) | |
1367 if (!strcmp(l -> sym, ex -> sym)) | |
1368 break; | |
1369 if (ex) | |
1370 { | |
1371 register_error(as, l, 2, "Symbol %s already exported", l -> sym); | |
1372 return; | |
1373 } | |
1374 | |
1375 // add an external reference | |
1376 ex = lwasm_alloc(sizeof(export_list_t)); | |
1377 ex -> next = se -> sect -> exports; | |
1378 se -> sect -> exports = ex; | |
1379 ex -> offset = se -> value; | |
1380 ex -> sym = lwasm_strdup(se -> sym); | |
90 | 1381 } |
202
1a75121c3c3f
Yet again try to get importing undefined exports working
lost
parents:
201
diff
changeset
|
1382 next: |
192
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1383 if (after == 1) |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1384 { |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1385 if (**p == ',') |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1386 { |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1387 debug_message(2, "Export another symbol: %s", *p); |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1388 (*p)++; |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1389 for ( ; **p && isspace(**p); (*p)++) |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1390 /* do nothing */ ; |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1391 goto again; |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1392 } |
bfd0fb0a85c2
Allow exporting multiple symbols on a single directive
lost
parents:
190
diff
changeset
|
1393 } |
90 | 1394 } |