Skip to content

Commit

Permalink
Merge pull request #111 from tgtakaoka/devel
Browse files Browse the repository at this point in the history
Generate relevant binaries even when error
  • Loading branch information
tgtakaoka authored Nov 15, 2022
2 parents 38a773c + 941ee3d commit b20c6a7
Show file tree
Hide file tree
Showing 75 changed files with 2,774 additions and 2,782 deletions.
43 changes: 24 additions & 19 deletions src/asm_cdp1802.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,67 +30,72 @@ static Config::uintptr_t page(Config::uintptr_t addr) {
return addr & ~0xFF;
}

Error AsmCdp1802::encodePage(InsnCdp1802 &insn, AddrMode mode, const Operand &op) {
void AsmCdp1802::encodePage(InsnCdp1802 &insn, AddrMode mode, const Operand &op) {
const Config::uintptr_t base = insn.address() + 2;
const Config::uintptr_t target = op.getError() ? base : op.val16;
if (mode == M_PAGE) {
if (page(target) != page(base))
return setError(op, OVERWRAP_PAGE);
setErrorIf(op, OVERWRAP_PAGE);
insn.emitInsn();
insn.emitByte(target);
return OK;
return;
}
if (_smartBranch && page(target) == page(base)) {
const auto opc = insn.opCode();
insn.setOpCode(0x30 | (opc & 0xF)); // convert to in-page branch
insn.emitInsn();
insn.emitByte(target);
return OK;
return;
}
insn.emitInsn();
insn.emitUint16(op.val16);
return OK;
}

Error AsmCdp1802::emitOperand(InsnCdp1802 &insn, AddrMode mode, const Operand &op) {
uint16_t val16 = op.val16;
void AsmCdp1802::emitOperand(InsnCdp1802 &insn, AddrMode mode, const Operand &op) {
auto val16 = op.val16;
switch (mode) {
case M_REG1:
if (op.getError())
val16 = 7; // default work register.
if (val16 == 0)
return setError(op, REGISTER_NOT_ALLOWED);
if (val16 == 0) {
setErrorIf(op, REGISTER_NOT_ALLOWED);
val16 = 7;
}
/* Fall-through */
case M_REGN:
if (op.getError())
val16 = 7; // default work register.
if (val16 >= 16)
return setError(op, ILLEGAL_REGISTER);
if (val16 >= 16) {
setErrorIf(op, ILLEGAL_REGISTER);
val16 = 7;
}
insn.embed(val16);
insn.emitInsn();
break;
case M_IMM8:
if (overflowUint8(val16))
return setError(op, OVERFLOW_RANGE);
setErrorIf(op, OVERFLOW_RANGE);
insn.emitInsn();
insn.emitByte(val16);
break;
case M_PAGE:
case M_ADDR:
return encodePage(insn, mode, op);
encodePage(insn, mode, op);
break;
case M_IOAD:
if (op.getError())
val16 = 1; // default IO address
if (val16 == 0 || val16 >= 8)
return setError(op, OPERAND_NOT_ALLOWED);
if (val16 == 0 || val16 >= 8) {
setErrorIf(op, OPERAND_NOT_ALLOWED);
val16 = 1;
}
insn.embed(val16);
insn.emitInsn();
break;
default:
insn.emitInsn();
break;
}
return getError();
}

Error AsmCdp1802::parseOperand(StrScanner &scan, Operand &op) const {
Expand All @@ -100,7 +105,7 @@ Error AsmCdp1802::parseOperand(StrScanner &scan, Operand &op) const {
return OK;

if (_useReg) {
const RegName reg = RegCdp1802::parseRegName(p);
const auto reg = RegCdp1802::parseRegName(p);
if (reg != REG_UNDEF) {
op.val16 = int8_t(reg);
op.mode = M_REGN;
Expand All @@ -123,7 +128,7 @@ Error AsmCdp1802::encodeImpl(StrScanner &scan, Insn &_insn) {
Operand op1, op2;
if (parseOperand(scan, op1) && op1.hasError())
return setError(op1);
const StrScanner op1p(scan);
const auto op1p(scan);
if (scan.skipSpaces().expect(',')) {
if (parseOperand(scan, op2) && op2.hasError())
return setError(op2);
Expand All @@ -142,7 +147,7 @@ Error AsmCdp1802::encodeImpl(StrScanner &scan, Insn &_insn) {
emitOperand(insn, insn.mode1(), op1);
if (insn.mode2() == M_ADDR)
insn.emitUint16(op2.val16);
return getError();
return setErrorIf(insn);
}

} // namespace cdp1802
Expand Down
4 changes: 2 additions & 2 deletions src/asm_cdp1802.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ class AsmCdp1802 : public Assembler, public Config {

Error parseOperand(StrScanner &scan, Operand &op) const;

Error emitOperand(InsnCdp1802 &insn, AddrMode mode, const Operand &op);
Error encodePage(InsnCdp1802 &insn, AddrMode mode, const Operand &op);
void emitOperand(InsnCdp1802 &insn, AddrMode mode, const Operand &op);
void encodePage(InsnCdp1802 &insn, AddrMode mode, const Operand &op);
Error encodeImpl(StrScanner &scan, Insn &insn) override;

static const char OPT_BOOL_USE_REGISTER[] PROGMEM;
Expand Down
50 changes: 23 additions & 27 deletions src/asm_i8048.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ Error AsmI8048::parseOperand(StrScanner &scan, Operand &op) const {
return OK;
}

const bool indir = p.expect('@');
const auto indir = p.expect('@');
if (indir && isspace(*p))
return op.setError(UNKNOWN_OPERAND);

const StrScanner regp = p;
const auto regp = p;
op.reg = RegI8048::parseRegName(p);
if (op.reg != REG_UNDEF) {
if (indir) {
Expand Down Expand Up @@ -140,58 +140,58 @@ Error AsmI8048::parseOperand(StrScanner &scan, Operand &op) const {
return OK;
}

Error AsmI8048::encodeAddress(InsnI8048 &insn, const AddrMode mode, const Operand &op) {
void AsmI8048::encodeAddress(InsnI8048 &insn, const AddrMode mode, const Operand &op) {
if (mode == M_AD08) {
const Config::uintptr_t page = (insn.address() + 1) & ~0xFF;
if ((op.val16 & ~0xFF) != page)
return setError(op, OPERAND_TOO_FAR);
setErrorIf(op, OPERAND_TOO_FAR);
insn.emitOperand8(op.val16);
return setOK();
return;
}
const Config::uintptr_t max = 1UL << uint8_t(config().addressWidth());
if (op.val16 >= max)
return setError(op, OVERFLOW_RANGE);
setErrorIf(op, OVERFLOW_RANGE);
insn.embed((op.val16 >> 3) & 0xE0);
insn.emitOperand8(op.val16);
return setOK();
}

Error AsmI8048::encodeOperand(InsnI8048 &insn, const AddrMode mode, const Operand &op) {
void AsmI8048::encodeOperand(InsnI8048 &insn, const AddrMode mode, const Operand &op) {
switch (mode) {
case M_IR:
case M_IR3:
case M_R:
insn.embed(RegI8048::encodeRReg(op.reg));
return OK;
return;
case M_P12:
case M_PEXT:
insn.embed(RegI8048::encodePort(op.reg));
return OK;
return;
case M_AD08:
case M_AD11:
return encodeAddress(insn, mode, op);
encodeAddress(insn, mode, op);
return;
case M_IMM8:
case M_BIT8:
if (overflowUint8(op.val16))
return setError(op, OVERFLOW_RANGE);
setErrorIf(op, OVERFLOW_RANGE);
insn.emitOperand8(op.val16);
return OK;
return;
case M_BITN:
if (op.val16 >= 8)
return setError(op, ILLEGAL_BIT_NUMBER);
insn.embed(op.val16 << 5);
return OK;
setErrorIf(op, ILLEGAL_BIT_NUMBER);
insn.embed((op.val16 & 7) << 5);
return;
case M_F:
insn.embed(op.reg == REG_F1 ? 0x20 : 0);
return OK;
return;
case M_RB:
insn.embed(op.reg == REG_RB1 ? 0x10 : 0);
return OK;
return;
case M_MB:
insn.embed(op.reg == REG_MB1 ? 0x10 : 0);
return OK;
return;
default:
return OK;
return;
}
}

Expand All @@ -217,14 +217,10 @@ Error AsmI8048::encodeImpl(StrScanner &scan, Insn &_insn) {
if (error)
return setError(dstOp, error);

if (encodeOperand(insn, insn.dst(), dstOp))
return getError();
if (encodeOperand(insn, insn.src(), srcOp)) {
insn.reset();
return getError();
}
encodeOperand(insn, insn.dst(), dstOp);
encodeOperand(insn, insn.src(), srcOp);
insn.emitInsn();
return getError();
return setErrorIf(insn);
}

} // namespace i8048
Expand Down
4 changes: 2 additions & 2 deletions src/asm_i8048.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ class AsmI8048 : public Assembler, public Config {

Error parseOperand(StrScanner &scan, Operand &op) const;

Error encodeAddress(InsnI8048 &insn, const AddrMode mode, const Operand &op);
Error encodeOperand(InsnI8048 &insn, const AddrMode mode, const Operand &op);
void encodeAddress(InsnI8048 &insn, const AddrMode mode, const Operand &op);
void encodeOperand(InsnI8048 &insn, const AddrMode mode, const Operand &op);
Error encodeImpl(StrScanner &scan, Insn &insn) override;
};

Expand Down
70 changes: 30 additions & 40 deletions src/asm_i8051.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ Error AsmI8051::parseOperand(StrScanner &scan, Operand &op) const {
return OK;
}

const bool indir = p.expect('@');
const auto indir = p.expect('@');
if (indir && isspace(*p))
return op.setError(UNKNOWN_OPERAND);

const StrScanner regp = p;
const auto regp = p;
op.reg = RegI8051::parseRegName(p);
if (op.reg != REG_UNDEF) {
if (indir && op.reg == REG_A && p.expect('+')) {
const RegName base = RegI8051::parseRegName(p);
const auto base = RegI8051::parseRegName(p);
if (base == REG_DPTR || base == REG_PC) {
op.mode = (base == REG_DPTR) ? M_INDXD : M_INDXP;
scan = p;
Expand Down Expand Up @@ -88,21 +88,21 @@ Error AsmI8051::parseOperand(StrScanner &scan, Operand &op) const {
if (indir)
return op.setError(UNKNOWN_OPERAND);

const StrScanner addrp = p;
const bool bitNot = p.expect('/');
const auto addrp = p;
const auto bitNot = p.expect('/');
op.val16 = parseExpr16(p.skipSpaces(), op);
if (parserError())
return getError();
if (p.expect('.')) {
if (op.getError())
op.val16 = 0x20;
const StrScanner bitp = p;
uint16_t bitNo = parseExpr16(p, op);
const auto bitp = p;
auto bitNo = parseExpr16(p, op);
if (parserError())
return op.getError();
if (bitNo >= 8)
return op.setError(bitp, ILLEGAL_BIT_NUMBER);
uint16_t val16 = op.val16;
auto val16 = op.val16;
if ((val16 & ~0x0F) == 0x20 || (val16 & ~0x78) == 0x80) {
op.mode = bitNot ? M_NOTAD : M_BITAD;
if ((val16 & 0x80) == 0)
Expand All @@ -118,7 +118,7 @@ Error AsmI8051::parseOperand(StrScanner &scan, Operand &op) const {
return OK;
}

Error AsmI8051::encodeOperand(InsnI8051 &insn, const AddrMode mode, const Operand &op) {
void AsmI8051::encodeOperand(InsnI8051 &insn, const AddrMode mode, const Operand &op) {
switch (mode) {
case M_REL: {
uint8_t len = insn.length();
Expand All @@ -128,46 +128,46 @@ Error AsmI8051::encodeOperand(InsnI8051 &insn, const AddrMode mode, const Operan
const Config::uintptr_t target = op.getError() ? base : op.val16;
const Config::ptrdiff_t delta = target - base;
if (overflowRel8(delta))
return setError(op, OPERAND_TOO_FAR);
setErrorIf(op, OPERAND_TOO_FAR);
insn.emitOperand8(delta);
return OK;
return;
}
case M_RREG:
case M_IDIRR:
insn.embed(RegI8051::encodeRReg(op.reg));
return OK;
return;
case M_ADR8:
if (op.val16 >= 0x100)
return setError(op, OVERFLOW_RANGE);
setErrorIf(op, OVERFLOW_RANGE);
insn.emitOperand8(op.val16);
return OK;
return;
case M_IMM8: {
if (overflowUint8(op.val16))
return setError(op, OVERFLOW_RANGE);
setErrorIf(op, OVERFLOW_RANGE);
insn.emitOperand8(op.val16);
return OK;
return;
}
case M_ADR11: {
const Config::uintptr_t base = insn.address() + 2;
const Config::uintptr_t target = op.getError() ? (base & ~0x7FF) : op.val16;
if ((base & ~0x7FF) != (target & ~0x7FF))
return setError(op, OPERAND_TOO_FAR);
setErrorIf(op, OPERAND_TOO_FAR);
insn.embed((target & 0x700) >> 3);
insn.emitOperand8(target);
return OK;
return;
}
case M_ADR16:
case M_IMM16:
insn.emitOperand16(op.val16);
return OK;
return;
case M_BITAD:
case M_NOTAD:
if (op.val16 >= 0x100)
return setError(op, NOT_BIT_ADDRESSABLE);
setErrorIf(op, NOT_BIT_ADDRESSABLE);
insn.emitOperand8(op.val16);
return OK;
return;
default:
return OK;
return;
}
}

Expand Down Expand Up @@ -199,28 +199,18 @@ Error AsmI8051::encodeImpl(StrScanner &scan, Insn &_insn) {
if (error)
return setError(dstOp, error);

const AddrMode dst = insn.dst();
const AddrMode src = insn.src();
const AddrMode ext = insn.ext();
const auto dst = insn.dst();
const auto src = insn.src();
if (dst == M_ADR8 && src == M_ADR8) {
if (encodeOperand(insn, src, srcOp))
return getError();
if (encodeOperand(insn, dst, dstOp))
return getError();
encodeOperand(insn, src, srcOp);
encodeOperand(insn, dst, dstOp);
} else {
if (dst && encodeOperand(insn, dst, dstOp))
return getError();
if (src && encodeOperand(insn, src, srcOp)) {
insn.reset();
return getError();
}
if (ext && encodeOperand(insn, ext, extOp)) {
insn.reset();
return getError();
}
encodeOperand(insn, dst, dstOp);
encodeOperand(insn, src, srcOp);
encodeOperand(insn, insn.ext(), extOp);
}
insn.emitInsn();
return getError();
return setErrorIf(insn);
}

} // namespace i8051
Expand Down
Loading

0 comments on commit b20c6a7

Please sign in to comment.