comparison lwasm/insn_indexed.c @ 382:eacdae8a1575

Various bugfixes
author lost@starbug
date Sat, 15 May 2010 13:39:21 -0600
parents 8f9d72cfb897
children 2d7255509130
comparison
equal deleted inserted replaced
381:1624a36f12a3 382:eacdae8a1575
169 if (!e || **p != ']') 169 if (!e || **p != ']')
170 { 170 {
171 lwasm_register_error(as, l, "Bad operand"); 171 lwasm_register_error(as, l, "Bad operand");
172 return; 172 return;
173 } 173 }
174 lwasm_save_expr(l, 0, e);
174 175
175 (*p)++; 176 (*p)++;
176 l -> lint = 2; 177 l -> lint = 2;
177 return; 178 return;
178 } 179 }
285 { 286 {
286 l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; 287 l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1;
287 } 288 }
288 } 289 }
289 290
290 void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force) 291 void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force, int elen)
291 { 292 {
292 // here, we have an expression which needs to be 293 // here, we have an expression which needs to be
293 // resolved; the post byte is determined here as well 294 // resolved; the post byte is determined here as well
294 lw_expr_t e; 295 lw_expr_t e, e2, e3;
295 int pb = -1; 296 int pb = -1;
296 int v; 297 int v;
298
299 if (l -> len != -1)
300 return;
301
297 e = lwasm_fetch_expr(l, 0); 302 e = lwasm_fetch_expr(l, 0);
303 if (!lw_expr_istype(e, lw_expr_type_int))
304 {
305 // temporarily set the instruction length to see if we get a
306 // constant for our expression; if so, we can select an instruction
307 // size
308 e2 = lw_expr_copy(e);
309 // magic 2 for 8 bit (post byte + offset)
310 l -> len = OPLEN(instab[l -> insn].ops[0]) + elen + 2;
311 lwasm_reduce_expr(as, e2);
312 // l -> len += 1;
313 // e3 = lw_expr_copy(e);
314 // lwasm_reduce_expr(as, e3);
315 l -> len = -1;
316 if (lw_expr_istype(e2, lw_expr_type_int))
317 {
318 v = lw_expr_intval(e2);
319 // we have a reducible expression here which depends on
320 // the size of this instruction
321 if (v < -128 || v > 127)
322 {
323 l -> lint = 2;
324 switch (l -> pb & 0x07)
325 {
326 case 0:
327 case 1:
328 case 2:
329 case 3:
330 pb = 0x89 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80));
331 break;
332
333 case 4: // W
334 pb = (l -> pb & 0x80) ? 0xD0 : 0xCF;
335 break;
336
337 case 5: // PCR
338 case 6: // PC
339 pb = (l -> pb & 0x80) ? 0x9D : 0x8D;
340 break;
341 }
342
343 l -> pb = pb;
344 lw_expr_destroy(e2);
345 // lw_expr_destroy(e3);
346 return;
347 }
348 else if ((l -> pb & 0x80) || ((l -> pb & 0x07) > 3) || v < -16 || v > 15)
349 {
350 // if not a 5 bit value, is indirect, or is not X,Y,U,S
351 l -> lint = 1;
352 switch (l -> pb & 0x07)
353 {
354 case 0:
355 case 1:
356 case 2:
357 case 3:
358 pb = 0x88 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80));
359 break;
360
361 case 4: // W
362 // use 16 bit because W doesn't have 8 bit, unless 0
363 if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40))
364 {
365 pb = (l -> pb & 0x80) ? 0x90 : 0x8F;
366 l -> lint = 0;
367 }
368 else
369 {
370 pb = (l -> pb & 0x80) ? 0xD0 : 0xCF;
371 l -> lint = 2;
372 }
373 break;
374
375 case 5: // PCR
376 case 6: // PC
377 pb = (l -> pb & 0x80) ? 0x9C : 0x8C;
378 break;
379 }
380
381 l -> pb = pb;
382 return;
383 }
384 else
385 {
386 // we have X,Y,U,S and a possible 16 bit here
387 l -> lint = 0;
388
389 if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40))
390 {
391 pb = (l -> pb & 0x03) << 5 | 0x84;
392 }
393 else
394 {
395 pb = (l -> pb & 0x03) << 5 | v & 0x1F;
396 }
397 l -> pb = pb;
398 return;
399 }
400 }
401 }
402
298 if (lw_expr_istype(e, lw_expr_type_int)) 403 if (lw_expr_istype(e, lw_expr_type_int))
299 { 404 {
300 // we know how big it is 405 // we know how big it is
301 v = lw_expr_intval(e); 406 v = lw_expr_intval(e);
302 if (v < -128 || v > 127) 407 if (v < -128 || v > 127)
361 l -> pb = pb; 466 l -> pb = pb;
362 return; 467 return;
363 } 468 }
364 else 469 else
365 { 470 {
366 // we have X,Y,U,S and a possible 15 bit here 471 // we have X,Y,U,S and a possible 16 bit here
367 l -> lint = 0; 472 l -> lint = 0;
368 473
369 if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40)) 474 if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40))
370 { 475 {
476 pb = (l -> pb & 0x03) << 5 | 0x84;
477 }
478 else
479 {
371 pb = (l -> pb & 0x03) << 5 | v & 0x1F; 480 pb = (l -> pb & 0x03) << 5 | v & 0x1F;
372 } 481 }
373 else
374 pb = (l -> pb & 0x03) << 5 | 0x84;
375 l -> pb = pb; 482 l -> pb = pb;
376 return; 483 return;
377 } 484 }
378 } 485 }
379 else 486 else
388 } 495 }
389 496
390 RESOLVEFUNC(insn_resolve_indexed) 497 RESOLVEFUNC(insn_resolve_indexed)
391 { 498 {
392 if (l -> lint == -1) 499 if (l -> lint == -1)
393 insn_resolve_indexed_aux(as, l, force); 500 insn_resolve_indexed_aux(as, l, force, 0);
394 501
395 if (l -> lint != -1 && l -> pb != -1) 502 if (l -> lint != -1 && l -> pb != -1)
396 { 503 {
397 l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; 504 l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1;
398 } 505 }