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 }