1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-05 23:56:33 +00:00

Finally runs into the wall of trying to merge operands and offsets.

This commit is contained in:
Thomas Harte 2021-01-03 20:08:13 -05:00
parent a8738b533a
commit 38bca5f0f0
2 changed files with 25 additions and 14 deletions

View File

@ -16,8 +16,8 @@ using namespace CPU::Decoder::x86;
// Only 8086 is suppoted for now. // Only 8086 is suppoted for now.
Decoder::Decoder(Model) {} Decoder::Decoder(Model) {}
Instruction Decoder::decode(uint8_t *source, size_t length) { Instruction Decoder::decode(const uint8_t *source, size_t length) {
uint8_t *const end = source + length; const uint8_t *const end = source + length;
#define MapPartial(value, op, lrg, fmt, phs) \ #define MapPartial(value, op, lrg, fmt, phs) \
case value: \ case value: \
@ -49,10 +49,15 @@ Instruction Decoder::decode(uint8_t *source, size_t length) {
// Retain the instruction byte, in case additional decoding is deferred // Retain the instruction byte, in case additional decoding is deferred
// to the ModRM byte. // to the ModRM byte.
instr_ = *source; instr_ = *source;
++source;
++consumed_;
switch(instr_) { switch(instr_) {
default: default: {
const Instruction instruction(consumed_);
reset_parsing(); reset_parsing();
return Instruction(); return instruction;
}
#define PartialBlock(start, operation) \ #define PartialBlock(start, operation) \
MapPartial(start + 0x00, operation, false, MemReg_Reg, ModRM); \ MapPartial(start + 0x00, operation, false, MemReg_Reg, ModRM); \
@ -115,7 +120,7 @@ Instruction Decoder::decode(uint8_t *source, size_t length) {
/* 0x600x6f: not used. */ /* 0x600x6f: not used. */
#define MapJump(value, operation) MapPartial(value, operation, false, Disp, AwaitingOperands); #define MapJump(value, operation) MapPartial(value, operation, false, Immediate, AwaitingOperands);
MapJump(0x70, JO); MapJump(0x70, JO);
MapJump(0x71, JNO); MapJump(0x71, JNO);
MapJump(0x72, JB); MapJump(0x72, JB);
@ -164,7 +169,7 @@ Instruction Decoder::decode(uint8_t *source, size_t length) {
MapComplete(0x98, CBW, None, None); MapComplete(0x98, CBW, None, None);
MapComplete(0x99, CWD, None, None); MapComplete(0x99, CWD, None, None);
MapPartial(0x9a, CALL, true, Addr, AwaitingOperands); MapPartial(0x9a, CALL, true, Immediate, AwaitingOperands);
MapComplete(0x9b, WAIT, None, None); MapComplete(0x9b, WAIT, None, None);
MapComplete(0x9c, PUSHF, None, None); MapComplete(0x9c, PUSHF, None, None);
MapComplete(0x9d, POPF, None, None); MapComplete(0x9d, POPF, None, None);
@ -182,18 +187,24 @@ Instruction Decoder::decode(uint8_t *source, size_t length) {
MapRegData(0xbc, MOV, true, SP); MapRegData(0xbd, MOV, true, BP); MapRegData(0xbc, MOV, true, SP); MapRegData(0xbd, MOV, true, BP);
MapRegData(0xbe, MOV, true, SI); MapRegData(0xbf, MOV, true, DI); MapRegData(0xbe, MOV, true, SI); MapRegData(0xbf, MOV, true, DI);
MapPartial(0xc2, RETIntra, true, Disp, AwaitingOperands); MapPartial(0xc2, RETIntra, true, Immediate, AwaitingOperands);
MapComplete(0xc3, RETIntra, None, None); MapComplete(0xc3, RETIntra, None, None);
MapPartial(0xca, RETInter, true, Disp, AwaitingOperands); MapPartial(0xca, RETInter, true, Immediate, AwaitingOperands);
MapComplete(0xcb, RETInter, None, None); MapComplete(0xcb, RETInter, None, None);
MapPartial(0xd4, AAM, false, Immediate, AwaitingOperands);
MapPartial(0xd5, AAD, false, Immediate, AwaitingOperands);
// MapPartial(0xe4, IN, false, Immediate, AwaitingOperands);
MapComplete(0xec, IN, DX, AL); MapComplete(0xed, IN, DX, AX);
MapComplete(0xee, OUT, AL, DX); MapComplete(0xef, OUT, AX, DX);
// Other prefix bytes. // Other prefix bytes.
case 0xf0: lock_ = true; break; case 0xf0: lock_ = true; break;
case 0xf2: repetition_ = Repetition::RepNE; break; case 0xf2: repetition_ = Repetition::RepNE; break;
case 0xf3: repetition_ = Repetition::RepE; break; case 0xf3: repetition_ = Repetition::RepE; break;
} }
++source;
++consumed_;
} }
#undef MapInstr #undef MapInstr
@ -283,7 +294,7 @@ Instruction Decoder::decode(uint8_t *source, size_t length) {
result = Instruction(operation_, large_operand_ ? Size::Word : Size::Byte, source_, destination_, consumed_); result = Instruction(operation_, large_operand_ ? Size::Word : Size::Byte, source_, destination_, consumed_);
break; break;
case Format::Disp: case Format::Immediate:
result = Instruction(operation_, Size::Byte, Source::Immediate, Source::None, consumed_); result = Instruction(operation_, Size::Byte, Source::Immediate, Source::None, consumed_);
break; break;

View File

@ -114,7 +114,7 @@ struct Decoder {
instruction in response, and the decoder may still not be able to complete decoding instruction in response, and the decoder may still not be able to complete decoding
even if given that number of bytes. even if given that number of bytes.
*/ */
Instruction decode(uint8_t *source, size_t length); Instruction decode(const uint8_t *source, size_t length);
private: private:
enum class Phase { enum class Phase {
@ -151,8 +151,8 @@ struct Decoder {
Addr_Reg, Addr_Reg,
SegReg_MemReg, SegReg_MemReg,
Disp,
Addr Immediate,
} format_ = Format::MemReg_Reg; } format_ = Format::MemReg_Reg;
// TODO: figure out which Formats can be folded together, // TODO: figure out which Formats can be folded together,
// and which are improperly elided. // and which are improperly elided.