Mercurial > hg > index.cgi
comparison lwasm/insn_indexed.c @ 402:b20f14edda5a
Completed initial conversion to new parser allowing spaces in operands
Converted the remaining addressing modes. This required a complete rewrite
of a large portion of the indexed addressing parser. Now the entire indexed
parsing system is programmatic without cheating with a lookup table.
This update also fixes the "force 0,r" by writing a literal 0,r which is
*supposed* to work.
There will likely be some pseudo ops that need tweaking for space handling,
specially those that take multiple operands of some description which are
not expressions. (The expression parser call eats the spaces both before and
after the expression, if appropriate.)
author | William Astle <lost@l-w.ca> |
---|---|
date | Wed, 14 Oct 2015 20:49:41 -0600 |
parents | 35d4213e6657 |
children | cad5937314cb |
comparison
equal
deleted
inserted
replaced
401:bbe5401a9bf3 | 402:b20f14edda5a |
---|---|
36 forward to the resolve stage (if l -> line is -1); 0x80 is indir | 36 forward to the resolve stage (if l -> line is -1); 0x80 is indir |
37 bits 0-2 are register number | 37 bits 0-2 are register number |
38 */ | 38 */ |
39 void insn_parse_indexed_aux(asmstate_t *as, line_t *l, char **p) | 39 void insn_parse_indexed_aux(asmstate_t *as, line_t *l, char **p) |
40 { | 40 { |
41 struct opvals { char *opstr; int pb; }; | |
42 | |
43 static const char *regs = "X Y U S W PCRPC "; | |
44 static const struct opvals simpleindex[] = | |
45 { | |
46 {",x", 0x84}, {",y", 0xa4}, {",u", 0xc4}, {",s", 0xe4}, | |
47 {",x+", 0x80}, {",y+", 0xa0}, {",u+", 0xc0}, {",s+", 0xe0}, | |
48 {",x++", 0x81}, {",y++", 0xa1}, {",u++", 0xc1}, {",s++", 0xe1}, | |
49 {",-x", 0x82}, {",-y", 0xa2}, {",-u", 0xc2}, {",-s", 0xe2}, | |
50 {",--x", 0x83}, {",--y", 0xa3}, {",--u", 0xc3}, {",--s", 0xe3}, | |
51 {"a,x", 0x86}, {"a,y", 0xa6}, {"a,u", 0xc6}, {"a,s", 0xe6}, | |
52 {"b,x", 0x85}, {"b,y", 0xa5}, {"b,u", 0xc5}, {"b,s", 0xe5}, | |
53 {"e,x", 0x87}, {"e,y", 0xa7}, {"e,u", 0xc7}, {"e,s", 0xe7}, | |
54 {"f,x", 0x8a}, {"f,y", 0xaa}, {"f,u", 0xca}, {"f,s", 0xea}, | |
55 {"d,x", 0x8b}, {"d,y", 0xab}, {"d,u", 0xcb}, {"d,s", 0xeb}, | |
56 {"w,x", 0x8e}, {"w,y", 0xae}, {"w,u", 0xce}, {"w,s", 0xee}, | |
57 {",w", 0x8f}, {",w++", 0xcf}, {",--w", 0xef}, | |
58 | |
59 {"[,x]", 0x94}, {"[,y]", 0xb4}, {"[,u]", 0xd4}, {"[,s]", 0xf4}, | |
60 {"[,x++]", 0x91}, {"[,y++]", 0xb1}, {"[,u++]", 0xd1}, {"[,s++]", 0xf1}, | |
61 {"[,--x]", 0x93}, {"[,--y]", 0xb3}, {"[,--u]", 0xd3}, {"[,--s]", 0xf3}, | |
62 {"[a,x]", 0x96}, {"[a,y]", 0xb6}, {"[a,u]", 0xd6}, {"[a,s]", 0xf6}, | |
63 {"[b,x]", 0x95}, {"[b,y]", 0xb5}, {"[b,u]", 0xd5}, {"[b,s]", 0xf5}, | |
64 {"[e,x]", 0x97}, {"[e,y]", 0xb7}, {"[e,u]", 0xd7}, {"[e,s]", 0xf7}, | |
65 {"[f,x]", 0x9a}, {"[f,y]", 0xba}, {"[f,u]", 0xda}, {"[f,s]", 0xfa}, | |
66 {"[d,x]", 0x9b}, {"[d,y]", 0xbb}, {"[d,u]", 0xdb}, {"[d,s]", 0xfb}, | |
67 {"[w,x]", 0x9e}, {"[w,y]", 0xbe}, {"[w,u]", 0xde}, {"[w,s]", 0xfe}, | |
68 {"[,w]", 0x90}, {"[,w++]", 0xd0}, {"[,--w]", 0xf0}, | |
69 | |
70 { "", -1 } | |
71 }; | |
72 | |
73 static const char *regs9 = "X Y U S PCRPC "; | 41 static const char *regs9 = "X Y U S PCRPC "; |
74 static const struct opvals simpleindex9[] = | 42 static const char *regs = "X Y U S W PCRPC "; |
75 { | 43 int i, rn; |
76 {",x", 0x84}, {",y", 0xa4}, {",u", 0xc4}, {",s", 0xe4}, | |
77 {",x+", 0x80}, {",y+", 0xa0}, {",u+", 0xc0}, {",s+", 0xe0}, | |
78 {",x++", 0x81}, {",y++", 0xa1}, {",u++", 0xc1}, {",s++", 0xe1}, | |
79 {",-x", 0x82}, {",-y", 0xa2}, {",-u", 0xc2}, {",-s", 0xe2}, | |
80 {",--x", 0x83}, {",--y", 0xa3}, {",--u", 0xc3}, {",--s", 0xe3}, | |
81 {"a,x", 0x86}, {"a,y", 0xa6}, {"a,u", 0xc6}, {"a,s", 0xe6}, | |
82 {"b,x", 0x85}, {"b,y", 0xa5}, {"b,u", 0xc5}, {"b,s", 0xe5}, | |
83 {"d,x", 0x8b}, {"d,y", 0xab}, {"d,u", 0xcb}, {"d,s", 0xeb}, | |
84 | |
85 {"[,x]", 0x94}, {"[,y]", 0xb4}, {"[,u]", 0xd4}, {"[,s]", 0xf4}, | |
86 {"[,x++]", 0x91}, {"[,y++]", 0xb1}, {"[,u++]", 0xd1}, {"[,s++]", 0xf1}, | |
87 {"[,--x]", 0x93}, {"[,--y]", 0xb3}, {"[,--u]", 0xd3}, {"[,--s]", 0xf3}, | |
88 {"[a,x]", 0x96}, {"[a,y]", 0xb6}, {"[a,u]", 0xd6}, {"[a,s]", 0xf6}, | |
89 {"[b,x]", 0x95}, {"[b,y]", 0xb5}, {"[b,u]", 0xd5}, {"[b,s]", 0xf5}, | |
90 {"[d,x]", 0x9b}, {"[d,y]", 0xbb}, {"[d,u]", 0xdb}, {"[d,s]", 0xfb}, | |
91 | |
92 { "", -1 } | |
93 }; | |
94 char stbuf[25]; | |
95 int i, j, rn; | |
96 int indir = 0; | 44 int indir = 0; |
97 int f0 = 1; | 45 int f0 = 0; |
98 const struct opvals *simples; | |
99 const char *reglist; | 46 const char *reglist; |
100 lw_expr_t e; | 47 lw_expr_t e; |
101 | 48 char *tstr; |
49 | |
50 | |
102 if (CURPRAGMA(l, PRAGMA_6809)) | 51 if (CURPRAGMA(l, PRAGMA_6809)) |
103 { | 52 { |
104 simples = simpleindex9; | |
105 reglist = regs9; | 53 reglist = regs9; |
106 } | 54 } |
107 else | 55 else |
108 { | 56 { |
109 simples = simpleindex; | |
110 reglist = regs; | 57 reglist = regs; |
111 } | 58 } |
112 | |
113 // fetch out operand for lookup | |
114 for (i = 0; i < 24; i++) | |
115 { | |
116 if (*((*p) + i) && !isspace(*((*p) + i))) | |
117 stbuf[i] = *((*p) + i); | |
118 else | |
119 break; | |
120 } | |
121 stbuf[i] = '\0'; | |
122 | |
123 // now look up operand in "simple" table | |
124 if (!*((*p) + i) || isspace(*((*p) + i))) | |
125 { | |
126 // do simple lookup | |
127 for (j = 0; simples[j].opstr[0]; j++) | |
128 { | |
129 if (!strcasecmp(stbuf, simples[j].opstr)) | |
130 break; | |
131 } | |
132 if (simples[j].opstr[0]) | |
133 { | |
134 l -> pb = simples[j].pb; | |
135 l -> lint = 0; | |
136 (*p) += i; | |
137 return; | |
138 } | |
139 } | |
140 | |
141 // now do the "hard" ones | |
142 | |
143 // is it indirect? | 59 // is it indirect? |
144 if (**p == '[') | 60 if (**p == '[') |
145 { | 61 { |
146 indir = 1; | 62 indir = 1; |
147 (*p)++; | 63 (*p)++; |
148 } | 64 } |
149 | 65 lwasm_skip_to_next_token(l, p); |
150 // look for a "," - all indexed modes have a "," except extended indir | 66 if (**p == ',') |
151 rn = 0; | 67 { |
152 for (i = 0; (*p)[i] && !isspace((*p)[i]); i++) | 68 int incdec = 0; |
153 { | 69 /* we have a pre-dec, post-inc, or no offset mode here */ |
154 if ((*p)[i] == ',') | 70 (*p)++; |
155 { | 71 lwasm_skip_to_next_token(l, p); |
72 if (**p == '-') | |
73 { | |
74 incdec = -1; | |
75 (*p)++; | |
76 if (**p == '-') | |
77 { | |
78 incdec = -2; | |
79 (*p)++; | |
80 } | |
81 lwasm_skip_to_next_token(l, p); | |
82 } | |
83 /* allowed registers: X, Y, U, S, or W (6309) */ | |
84 switch (**p) | |
85 { | |
86 case 'x': | |
87 case 'X': | |
88 rn = 0; | |
89 break; | |
90 | |
91 case 'y': | |
92 case 'Y': | |
156 rn = 1; | 93 rn = 1; |
157 break; | 94 break; |
158 } | 95 |
159 } | 96 case 'u': |
160 | 97 case 'U': |
161 // if no "," and indirect, do extended indir | 98 rn = 2; |
162 if (!rn && indir) | 99 break; |
163 { | 100 |
164 // eat the extended addressing indicator if present | 101 case 's': |
165 if (**p == '>') | 102 case 'S': |
103 rn = 3; | |
104 break; | |
105 | |
106 case 'w': | |
107 case 'W': | |
108 if (CURPRAGMA(l, PRAGMA_6809)) | |
109 { | |
110 lwasm_register_error(as, l, E_OPERAND_BAD); | |
111 return; | |
112 } | |
113 rn = 4; | |
114 break; | |
115 | |
116 default: | |
117 lwasm_register_error(as, l, E_OPERAND_BAD); | |
118 return; | |
119 } | |
120 (*p)++; | |
121 lwasm_skip_to_next_token(l, p); | |
122 if (**p == '+') | |
123 { | |
124 if (incdec != 0) | |
125 { | |
126 lwasm_register_error(as, l, E_OPERAND_BAD); | |
127 return; | |
128 } | |
129 incdec = 1; | |
166 (*p)++; | 130 (*p)++; |
167 // extended indir | 131 if (**p == '+') |
168 l -> pb = 0x9f; | 132 { |
169 e = lwasm_parse_expr(as, p); | 133 incdec = 2; |
170 if (!e || **p != ']') | 134 (*p)++; |
171 { | 135 } |
172 lwasm_register_error(as, l, E_OPERAND_BAD); | 136 lwasm_skip_to_next_token(l, p); |
173 return; | 137 } |
174 } | 138 if (indir) |
175 lwasm_save_expr(l, 0, e); | 139 { |
140 if (**p != ']') | |
141 { | |
142 lwasm_register_error(as, l, E_OPERAND_BAD); | |
143 return; | |
144 } | |
145 (*p)++; | |
146 } | |
147 if (indir || rn == 4) | |
148 { | |
149 if (incdec == 1 || incdec == -1) | |
150 { | |
151 lwasm_register_error(as, l, E_OPERAND_BAD); | |
152 return; | |
153 } | |
154 } | |
155 if (rn == 4) | |
156 { | |
157 if (indir) | |
158 { | |
159 if (incdec == 0) | |
160 i = 0x90; | |
161 else if (incdec == -2) | |
162 i = 0xF0; | |
163 else | |
164 i = 0xD0; | |
165 } | |
166 else | |
167 { | |
168 if (incdec == 0) | |
169 i = 0x8F; | |
170 else if (incdec == -2) | |
171 i = 0xEF; | |
172 else | |
173 i = 0xCF; | |
174 } | |
175 } | |
176 else | |
177 { | |
178 switch (incdec) | |
179 { | |
180 case 0: | |
181 i = 0x84; | |
182 break; | |
183 case 1: | |
184 i = 0x80; | |
185 break; | |
186 case 2: | |
187 i = 0x81; | |
188 break; | |
189 case -1: | |
190 i = 0x82; | |
191 break; | |
192 case -2: | |
193 i = 0x83; | |
194 break; | |
195 } | |
196 i = (rn << 5) | i | (indir << 4); | |
197 } | |
198 l -> pb = i; | |
199 l -> lint = 0; | |
200 return; | |
201 } | |
202 i = toupper(**p); | |
203 if ( | |
204 (i == 'A' || i == 'B' || i == 'D') || | |
205 (!CURPRAGMA(l, PRAGMA_6809) && (i == 'E' || i == 'F' || i == 'W')) | |
206 ) | |
207 { | |
208 tstr = *p + 1; | |
209 lwasm_skip_to_next_token(l, &tstr); | |
210 if (*tstr == ',') | |
211 { | |
212 *p = tstr + 1; | |
213 lwasm_skip_to_next_token(l, p); | |
214 switch (**p) | |
215 { | |
216 case 'x': | |
217 case 'X': | |
218 rn = 0; | |
219 break; | |
176 | 220 |
177 (*p)++; | 221 case 'y': |
178 l -> lint = 2; | 222 case 'Y': |
179 return; | 223 rn = 1; |
180 } | 224 break; |
181 | 225 |
226 case 'u': | |
227 case 'U': | |
228 rn = 2; | |
229 break; | |
230 | |
231 case 's': | |
232 case 'S': | |
233 rn = 3; | |
234 break; | |
235 | |
236 default: | |
237 lwasm_register_error(as, l, E_OPERAND_BAD); | |
238 return; | |
239 } | |
240 (*p)++; | |
241 lwasm_skip_to_next_token(l, p); | |
242 if (indir) | |
243 { | |
244 if (**p != ']') | |
245 { | |
246 lwasm_register_error(as, l, E_OPERAND_BAD); | |
247 return; | |
248 } | |
249 (*p)++; | |
250 } | |
251 | |
252 switch (i) | |
253 { | |
254 case 'A': | |
255 i = 0x86; | |
256 break; | |
257 | |
258 case 'B': | |
259 i = 0x85; | |
260 break; | |
261 | |
262 case 'D': | |
263 i = 0x8B; | |
264 break; | |
265 | |
266 case 'E': | |
267 i = 0x87; | |
268 break; | |
269 | |
270 case 'F': | |
271 i = 0x8A; | |
272 break; | |
273 | |
274 case 'W': | |
275 i = 0x8E; | |
276 break; | |
277 } | |
278 l -> pb = i | (indir << 4) | (rn << 5); | |
279 l -> lint = 0; | |
280 return; | |
281 } | |
282 } | |
283 | |
284 /* we have the "expression" types now */ | |
182 if (**p == '<') | 285 if (**p == '<') |
183 { | 286 { |
184 l -> lint = 1; | 287 l -> lint = 1; |
185 (*p)++; | 288 (*p)++; |
186 } | 289 } |
187 else if (**p == '>') | 290 else if (**p == '>') |
188 { | 291 { |
189 l -> lint = 2; | 292 l -> lint = 2; |
190 (*p)++; | 293 (*p)++; |
191 } | 294 } |
192 | 295 lwasm_skip_to_next_token(l, p); |
193 if (**p == '0' && *((*p)+1) == ',') | 296 if (**p == '0') |
194 { | 297 { |
195 f0 = 1; | 298 tstr = *p + 1; |
196 } | 299 lwasm_skip_to_next_token(l, &tstr); |
197 | 300 if (*tstr == ',') |
301 { | |
302 f0 = 1; | |
303 } | |
304 } | |
305 | |
198 // now we have to evaluate the expression | 306 // now we have to evaluate the expression |
199 e = lwasm_parse_expr(as, p); | 307 e = lwasm_parse_expr(as, p); |
200 if (!e) | 308 if (!e) |
201 { | 309 { |
202 lwasm_register_error(as, l, E_OPERAND_BAD); | 310 lwasm_register_error(as, l, E_OPERAND_BAD); |
203 return; | 311 return; |
204 } | 312 } |
205 lwasm_save_expr(l, 0, e); | 313 lwasm_save_expr(l, 0, e); |
206 | 314 |
207 // now look for a comma; if not present, explode | 315 if (**p != ',') |
208 if (*(*p)++ != ',') | 316 { |
209 { | 317 /* if no comma, we have extended indirect */ |
210 lwasm_register_error(as, l, E_OPERAND_BAD); | 318 if (l -> lint == 1 || **p != ']') |
319 { | |
320 lwasm_register_error(as, l, E_OPERAND_BAD); | |
321 return; | |
322 } | |
323 (*p)++; | |
324 l -> lint = 2; | |
325 l -> pb = 0x9F; | |
211 return; | 326 return; |
212 } | 327 } |
213 | 328 (*p)++; |
329 lwasm_skip_to_next_token(l, p); | |
214 // now get the register | 330 // now get the register |
215 rn = lwasm_lookupreg3(reglist, p); | 331 rn = lwasm_lookupreg3(reglist, p); |
216 if (rn < 0) | 332 if (rn < 0) |
217 { | 333 { |
218 lwasm_register_error(as, l, E_REGISTER_BAD); | 334 lwasm_register_error(as, l, E_REGISTER_BAD); |
460 | 576 |
461 if (lw_expr_istype(e, lw_expr_type_int)) | 577 if (lw_expr_istype(e, lw_expr_type_int)) |
462 { | 578 { |
463 // we know how big it is | 579 // we know how big it is |
464 v = lw_expr_intval(e); | 580 v = lw_expr_intval(e); |
465 if (v == 0 && !CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) && (l -> pb & 0x07) <= 4) | 581 |
582 if (v == 0 && !CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) && (l -> pb & 0x07) <= 4 && ((l -> pb & 0x40) == 0)) | |
466 { | 583 { |
467 if ((l -> pb & 0x07) < 4) | 584 if ((l -> pb & 0x07) < 4) |
468 { | 585 { |
469 pb = 0x84 | ((l -> pb & 0x03) << 5) | ((l -> pb & 0x80) ? 0x10 : 0); | 586 pb = 0x84 | ((l -> pb & 0x03) << 5) | ((l -> pb & 0x80) ? 0x10 : 0); |
470 } | 587 } |