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 {