mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-06 13:31:55 +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:
parent
17cbba85fc
commit
995904993d
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user