Mercurial > hg > index.cgi
comparison lwasm/insn_indexed.c @ 470:2c1c5dd84024
Add << prefix to force 5 bit offsets in indexed modes
Rounding out the compliment of operand size prefixes, we now have "<<" to
mean "force 5 bits". According to Steve Bjork, this was the "official" way
to do this since 1980. However, I have no official Motorola source for
that. It does suggest that the choice of "<<" is consistent with other
(historical) assemblers, though.
Either way, it seems the most logical choice while avoiding any conflicts
with legal source code, so "<<" it is.
author | William Astle <lost@l-w.ca> |
---|---|
date | Mon, 23 Jul 2018 17:45:18 -0600 |
parents | 9393a6b8886c |
children | 62720ac9e28d |
comparison
equal
deleted
inserted
replaced
469:9393a6b8886c | 470:2c1c5dd84024 |
---|---|
284 /* we have the "expression" types now */ | 284 /* we have the "expression" types now */ |
285 if (**p == '<') | 285 if (**p == '<') |
286 { | 286 { |
287 l -> lint = 1; | 287 l -> lint = 1; |
288 (*p)++; | 288 (*p)++; |
289 if (**p == '<') | |
290 { | |
291 l -> lint = 3; | |
292 (*p)++; | |
293 if (indir) | |
294 { | |
295 lwasm_register_error(as, l, E_ILL5); | |
296 return; | |
297 } | |
298 } | |
289 } | 299 } |
290 else if (**p == '>') | 300 else if (**p == '>') |
291 { | 301 { |
292 l -> lint = 2; | 302 l -> lint = 2; |
293 (*p)++; | 303 (*p)++; |
357 else if (l -> lint == 2) | 367 else if (l -> lint == 2) |
358 { | 368 { |
359 l -> pb = 0x89 | (rn << 5) | (indir ? 0x10 : 0); | 369 l -> pb = 0x89 | (rn << 5) | (indir ? 0x10 : 0); |
360 return; | 370 return; |
361 } | 371 } |
372 else if (l -> lint == 3) | |
373 { | |
374 l -> pb = (rn << 5); | |
375 } | |
362 } | 376 } |
363 | 377 |
364 // nnnn,W is only 16 bit (or 0 bit) | 378 // nnnn,W is only 16 bit (or 0 bit) |
365 if (rn == 4) | 379 if (rn == 4) |
366 { | 380 { |
367 if (l -> lint == 1) | 381 if (l -> lint == 1) |
368 { | 382 { |
369 lwasm_register_error(as, l, E_NW_8); | 383 lwasm_register_error(as, l, E_NW_8); |
384 return; | |
385 } | |
386 else if (l -> lint == 3) | |
387 { | |
388 lwasm_register_error(as, l, E_ILL5); | |
370 return; | 389 return; |
371 } | 390 } |
372 | 391 |
373 if (l -> lint == 2) | 392 if (l -> lint == 2) |
374 { | 393 { |
407 if (l -> lint == 1) | 426 if (l -> lint == 1) |
408 { | 427 { |
409 l -> pb = indir ? 0x9C : 0x8C; | 428 l -> pb = indir ? 0x9C : 0x8C; |
410 return; | 429 return; |
411 } | 430 } |
412 if (l -> lint == 2) | 431 else if (l -> lint == 2) |
413 { | 432 { |
414 l -> pb = indir ? 0x9D : 0x8D; | 433 l -> pb = indir ? 0x9D : 0x8D; |
415 return; | 434 return; |
416 } | 435 } |
436 else if (l -> lint == 3) | |
437 { | |
438 lwasm_register_error(as, l, E_ILL5); | |
439 return; | |
440 } | |
417 } | 441 } |
418 | 442 |
419 if (rn == 6) | 443 if (rn == 6) |
420 { | 444 { |
421 if (l -> lint == 1) | 445 if (l -> lint == 1) |
422 { | 446 { |
423 l -> pb = indir ? 0x9C : 0x8C; | 447 l -> pb = indir ? 0x9C : 0x8C; |
424 return; | 448 return; |
425 } | 449 } |
426 if (l -> lint == 2) | 450 else if (l -> lint == 2) |
427 { | 451 { |
428 l -> pb = indir ? 0x9D : 0x8D; | 452 l -> pb = indir ? 0x9D : 0x8D; |
429 return; | 453 return; |
430 } | 454 } |
431 } | 455 else if (l -> lint == 3) |
432 | 456 { |
433 l -> pb = (indir * 0x80) | rn | (f0 * 0x40); | 457 lwasm_register_error(as, l, E_ILL5); |
458 return; | |
459 } | |
460 } | |
461 | |
462 if (l -> lint != 3) | |
463 l -> pb = (indir * 0x80) | rn | (f0 * 0x40); | |
434 } | 464 } |
435 | 465 |
436 PARSEFUNC(insn_parse_indexed) | 466 PARSEFUNC(insn_parse_indexed) |
437 { | 467 { |
438 l -> lint = -1; | 468 l -> lint = -1; |
439 insn_parse_indexed_aux(as, l, p); | 469 insn_parse_indexed_aux(as, l, p); |
440 | 470 |
441 if (l -> lint != -1) | 471 if (l -> lint != -1) |
442 { | 472 { |
443 l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; | 473 if (l -> lint == 3) |
474 l -> len = OPLEN(instab[l -> insn].ops[0]) + 1; | |
475 else | |
476 l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; | |
444 } | 477 } |
445 } | 478 } |
446 | 479 |
447 void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force, int elen) | 480 void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force, int elen) |
448 { | 481 { |
720 if (l -> lint == -1) | 753 if (l -> lint == -1) |
721 insn_resolve_indexed_aux(as, l, force, 0); | 754 insn_resolve_indexed_aux(as, l, force, 0); |
722 | 755 |
723 if (l -> lint != -1 && l -> pb != -1) | 756 if (l -> lint != -1 && l -> pb != -1) |
724 { | 757 { |
725 l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; | 758 if (l -> lint == 3) |
759 l -> len = OPLEN(instab[l -> insn].ops[0]) + 1; | |
760 else | |
761 l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; | |
726 } | 762 } |
727 } | 763 } |
728 | 764 |
729 void insn_emit_indexed_aux(asmstate_t *as, line_t *l) | 765 void insn_emit_indexed_aux(asmstate_t *as, line_t *l) |
730 { | 766 { |
740 lwasm_register_error(as, l, E_BYTE_OVERFLOW); | 776 lwasm_register_error(as, l, E_BYTE_OVERFLOW); |
741 } | 777 } |
742 } | 778 } |
743 | 779 |
744 // exclude expr,W since that can only be 16 bits | 780 // exclude expr,W since that can only be 16 bits |
745 if (l -> lint == 2 && CURPRAGMA(l, PRAGMA_OPERANDSIZE) && (l -> pb != 0xAF && l -> pb != 0xB0)) | 781 if (l -> lint == 3) |
782 { | |
783 int offs; | |
784 e = lwasm_fetch_expr(l, 0); | |
785 if (lw_expr_istype(e, lw_expr_type_int)) | |
786 { | |
787 offs = lw_expr_intval(e); | |
788 if ((offs >= -16 && offs <= 15) || offs >= 0xFFF0) | |
789 { | |
790 l -> pb |= offs & 0x1f; | |
791 l -> lint = 0; | |
792 } | |
793 else | |
794 { | |
795 lwasm_register_error(as, l, E_BYTE_OVERFLOW); | |
796 } | |
797 } | |
798 else | |
799 { | |
800 lwasm_register_error(as, l, E_EXPRESSION_NOT_RESOLVED); | |
801 } | |
802 } | |
803 else if (l -> lint == 2 && CURPRAGMA(l, PRAGMA_OPERANDSIZE) && (l -> pb != 0xAF && l -> pb != 0xB0)) | |
746 { | 804 { |
747 int offs; | 805 int offs; |
748 e = lwasm_fetch_expr(l, 0); | 806 e = lwasm_fetch_expr(l, 0); |
749 if (lw_expr_istype(e, lw_expr_type_int)) | 807 if (lw_expr_istype(e, lw_expr_type_int)) |
750 { | 808 { |