Mercurial > hg > index.cgi
changeset 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 | ad0efd5835c3 |
files | lwasm/insn_gen.c lwasm/insn_indexed.c lwasm/lwasm.c lwasm/lwasm.h |
diffstat | 4 files changed, 112 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/lwasm/insn_gen.c Sun Mar 04 10:24:58 2018 -0700 +++ b/lwasm/insn_gen.c Mon Jul 23 17:45:18 2018 -0600 @@ -65,6 +65,11 @@ { (*p)++; l -> lint2 = 0; + if (**p == '<') + { + *p = optr2; + goto indexed; + } } // for compatibility with asxxxx // * followed by a digit, alpha, or _, or ., or ?, or another * is "f8" @@ -175,7 +180,10 @@ } else if (l -> lint2 == 1 && l -> lint != -1) { - l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1 + elen; + if (l -> lint == 3) + l -> len = OPLEN(instab[l -> insn].ops[1]) + 1 + elen; + else + l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1 + elen; } } } @@ -261,7 +269,10 @@ } else if (l -> lint2 == 1 && l -> lint != -1) { - l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1 + elen; + if (l -> lint == 3) + l -> len = OPLEN(instab[l -> insn].ops[1]) + 1 + elen; + else + l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1 + elen; } } } @@ -278,6 +289,27 @@ if (l -> lint2 == 1) { + if (l -> lint == 3) + { + int offs; + if (lw_expr_istype(e, lw_expr_type_int)) + { + offs = lw_expr_intval(e); + if ((offs >= -16 && offs <= 15) || offs >= 0xFFF0) + { + l -> pb |= offs & 0x1f; + l -> lint = 0; + } + else + { + lwasm_register_error(as, l, E_BYTE_OVERFLOW); + } + } + else + { + lwasm_register_error(as, l, E_EXPRESSION_NOT_RESOLVED); + } + } lwasm_emit(l, l -> pb); if (l -> lint > 0) { @@ -375,7 +407,10 @@ } else if (l -> lint2 == 1 && l -> lint != -1) { - l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1; + if (l -> lint == 3) + l -> len = OPLEN(instab[l -> insn].ops[1]) + 1; + else + l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1; } } } @@ -447,7 +482,10 @@ } else if (l -> lint2 == 1 && l -> lint != -1) { - l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1; + if (l -> lint == 3) + l -> len = OPLEN(instab[l -> insn].ops[1]) + 1; + else + l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1; } } } @@ -509,7 +547,10 @@ } else if (l -> lint2 == 1 && l -> lint != -1) { - l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1; + if (l -> lint == 3) + l -> len = OPLEN(instab[l -> insn].ops[1]) + 1; + else + l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1; } } }
--- a/lwasm/insn_indexed.c Sun Mar 04 10:24:58 2018 -0700 +++ b/lwasm/insn_indexed.c Mon Jul 23 17:45:18 2018 -0600 @@ -286,6 +286,16 @@ { l -> lint = 1; (*p)++; + if (**p == '<') + { + l -> lint = 3; + (*p)++; + if (indir) + { + lwasm_register_error(as, l, E_ILL5); + return; + } + } } else if (**p == '>') { @@ -359,6 +369,10 @@ l -> pb = 0x89 | (rn << 5) | (indir ? 0x10 : 0); return; } + else if (l -> lint == 3) + { + l -> pb = (rn << 5); + } } // nnnn,W is only 16 bit (or 0 bit) @@ -369,6 +383,11 @@ lwasm_register_error(as, l, E_NW_8); return; } + else if (l -> lint == 3) + { + lwasm_register_error(as, l, E_ILL5); + return; + } if (l -> lint == 2) { @@ -409,11 +428,16 @@ l -> pb = indir ? 0x9C : 0x8C; return; } - if (l -> lint == 2) + else if (l -> lint == 2) { l -> pb = indir ? 0x9D : 0x8D; return; } + else if (l -> lint == 3) + { + lwasm_register_error(as, l, E_ILL5); + return; + } } if (rn == 6) @@ -423,14 +447,20 @@ l -> pb = indir ? 0x9C : 0x8C; return; } - if (l -> lint == 2) + else if (l -> lint == 2) { l -> pb = indir ? 0x9D : 0x8D; return; } + else if (l -> lint == 3) + { + lwasm_register_error(as, l, E_ILL5); + return; + } } - l -> pb = (indir * 0x80) | rn | (f0 * 0x40); + if (l -> lint != 3) + l -> pb = (indir * 0x80) | rn | (f0 * 0x40); } PARSEFUNC(insn_parse_indexed) @@ -440,7 +470,10 @@ if (l -> lint != -1) { - l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; + if (l -> lint == 3) + l -> len = OPLEN(instab[l -> insn].ops[0]) + 1; + else + l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; } } @@ -722,7 +755,10 @@ if (l -> lint != -1 && l -> pb != -1) { - l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; + if (l -> lint == 3) + l -> len = OPLEN(instab[l -> insn].ops[0]) + 1; + else + l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; } } @@ -742,7 +778,29 @@ } // exclude expr,W since that can only be 16 bits - if (l -> lint == 2 && CURPRAGMA(l, PRAGMA_OPERANDSIZE) && (l -> pb != 0xAF && l -> pb != 0xB0)) + if (l -> lint == 3) + { + int offs; + e = lwasm_fetch_expr(l, 0); + if (lw_expr_istype(e, lw_expr_type_int)) + { + offs = lw_expr_intval(e); + if ((offs >= -16 && offs <= 15) || offs >= 0xFFF0) + { + l -> pb |= offs & 0x1f; + l -> lint = 0; + } + else + { + lwasm_register_error(as, l, E_BYTE_OVERFLOW); + } + } + else + { + lwasm_register_error(as, l, E_EXPRESSION_NOT_RESOLVED); + } + } + else if (l -> lint == 2 && CURPRAGMA(l, PRAGMA_OPERANDSIZE) && (l -> pb != 0xAF && l -> pb != 0xB0)) { int offs; e = lwasm_fetch_expr(l, 0);
--- a/lwasm/lwasm.c Sun Mar 04 10:24:58 2018 -0700 +++ b/lwasm/lwasm.c Mon Jul 23 17:45:18 2018 -0600 @@ -283,6 +283,7 @@ case E_ORG_NOT_FOUND: return "Previous ORG not found"; case E_COMPLEX_INCOMPLETE: return "Incomplete expression too complex"; case E_USER_SPECIFIED: return "User Specified:"; + case E_ILL5: return "Illegal 5 bit offset"; case W_ENDSTRUCT_WITHOUT: return "ENDSTRUCT without STRUCT"; case W_DUPLICATE_SECTION: return "Section flags can only be specified the first time; ignoring duplicate definition";