1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-08 15:29:09 +00:00

Fills in 8f, c2, c3, ca and cb.

Also switches to RETN and RETF for near/far RET as this seems idiomatic.
This commit is contained in:
Thomas Harte 2021-01-06 21:18:24 -05:00
parent 17cbba85fc
commit 995904993d
2 changed files with 37 additions and 11 deletions

View File

@ -197,8 +197,7 @@ Instruction Decoder::decode(const uint8_t *source, size_t length) {
// 0x8c: not used.
MapMemRegReg(0x8d, LEA, Reg_MemReg, 2);
// MapMemRegReg(0x8e, MOV, SegReg_MemReg, 1); // TODO: SegReg_MemReg
// TODO: 0x8f, which requires further selection from the ModRegRM byte.
MapMemRegReg(0x8f, POP, MemRegPOP, 2);
MapComplete(0x90, NOP, None, None, 0); // Or XCHG AX, AX?
MapComplete(0x91, XCHG, AX, CX, 2);
@ -243,13 +242,15 @@ Instruction Decoder::decode(const uint8_t *source, size_t length) {
MapRegData(0xbc, MOV, SP, 2); MapRegData(0xbd, MOV, BP, 2);
MapRegData(0xbe, MOV, SI, 2); MapRegData(0xbf, MOV, DI, 2);
MapRegData(0xc2, RETIntra, None, 2);
MapComplete(0xc3, RETIntra, None, None, 2);
MapRegData(0xc2, RETN, None, 2);
MapComplete(0xc3, RETN, None, None, 2);
MapMemRegReg(0xc4, LES, Reg_MemReg, 4);
MapMemRegReg(0xc5, LDS, Reg_MemReg, 4);
MapMemRegReg(0xc6, MOV, MemRegMOV, 1);
MapMemRegReg(0xc7, MOV, MemRegMOV, 2);
MapRegData(0xca, RETInter, None, 2);
MapComplete(0xcb, RETInter, None, None, 4);
MapRegData(0xca, RETF, None, 2);
MapComplete(0xcb, RETF, None, None, 4);
MapComplete(0xcc, INT3, None, None, 0);
MapRegData(0xcd, INT, None, 1);
@ -299,8 +300,7 @@ Instruction Decoder::decode(const uint8_t *source, size_t length) {
/*
Unimplemented (but should be):
0x8e, 0x8f,
0xc6, 0xc7,
0x8e,
0xd0, 0xd1, 0xd2, 0xd3,
0xfe, 0xff
@ -384,7 +384,7 @@ Instruction Decoder::decode(const uint8_t *source, size_t length) {
switch(reg) {
default:
reset_parsing();
return Instruction();
return Instruction(consumed_);
case 0: operation_ = Operation::TEST; break;
case 2: operation_ = Operation::NOT; break;
@ -396,6 +396,21 @@ Instruction Decoder::decode(const uint8_t *source, size_t length) {
}
break;
case ModRegRMFormat::MemRegPOP:
source_ = destination_ = memreg;
if(reg != 0) {
reset_parsing();
return Instruction(consumed_);
}
break;
case ModRegRMFormat::MemRegMOV:
source_ = Source::Immediate;
destination_ = memreg;
operand_size_ = operation_size_;
break;
default: assert(false);
}

View File

@ -23,6 +23,7 @@ enum class Model {
enum class Operation: uint8_t {
Invalid,
/// ASCII adjust for addition;
AAA, AAD, AAM, AAS, ADC, ADD, AND, CALL, CBW, CLC, CLD, CLI, CMC,
CMP, CMPS, CWD, DAA, DAS, DEC, DIV, ESC, HLT, IDIV, IMUL, IN,
INC, INT, INT3, INTO, IRET,
@ -42,8 +43,8 @@ enum class Operation: uint8_t {
WAIT, XCHG, XLAT, XOR,
LES, LOOP, JPCX,
RETInter,
RETIntra,
RETF,
RETN,
};
enum class Size: uint8_t {
@ -156,6 +157,16 @@ struct Decoder {
// field to pick an operation from the TEST/NOT/NEG/MUL/IMUL/DIV/IDIV group.
MemRegTEST_to_IDIV,
// Parse for mode and register/memory fields, populating both
// source_ and destination_ fields with the result. Use the 'register'
// field to check for the POP operation.
MemRegPOP,
// Parse for mode and register/memory fields, populating both
// the destination_ field with the result and setting source_ to Immediate.
// Use the 'register' field to check for the MOV operation.
MemRegMOV,
} modregrm_format_ = ModRegRMFormat::MemReg_Reg;
// Ephemeral decoding state.