mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 23:52:26 +00:00
Takes a run at 0x82 and 0x83, completing the set.
This commit is contained in:
parent
5058a8b96a
commit
a24ae727a7
@ -165,13 +165,10 @@ std::pair<int, Instruction> Decoder::decode(const uint8_t *source, size_t length
|
||||
case 0x7e: Jump(JLE); break;
|
||||
case 0x7f: Jump(JNLE); break;
|
||||
|
||||
// TODO:
|
||||
//
|
||||
// 0x82, 0x83, which will require me to do something
|
||||
// re: word-sign extended.
|
||||
|
||||
case 0x80: MemRegReg(Invalid, MemRegADD_to_CMP, 1); break;
|
||||
case 0x81: MemRegReg(Invalid, MemRegADD_to_CMP, 2); break;
|
||||
case 0x82: MemRegReg(Invalid, MemRegADC_to_CMP, 1); break;
|
||||
case 0x83: MemRegReg(Invalid, MemRegADC_to_CMP, 2); break;
|
||||
|
||||
case 0x84: MemRegReg(TEST, MemReg_Reg, 1); break;
|
||||
case 0x85: MemRegReg(TEST, MemReg_Reg, 2); break;
|
||||
@ -531,6 +528,27 @@ std::pair<int, Instruction> Decoder::decode(const uint8_t *source, size_t length
|
||||
}
|
||||
break;
|
||||
|
||||
case ModRegRMFormat::MemRegADC_to_CMP:
|
||||
destination_ = memreg;
|
||||
source_ = Source::Immediate;
|
||||
operand_size_ = 1; // ... and always 1; it'll be sign extended if
|
||||
// the operation requires it.
|
||||
|
||||
switch(reg) {
|
||||
default: {
|
||||
const auto result = std::make_pair(consumed_, Instruction());
|
||||
reset_parsing();
|
||||
return result;
|
||||
}
|
||||
|
||||
case 0: operation_ = Operation::ADD; break;
|
||||
case 2: operation_ = Operation::ADC; break;
|
||||
case 3: operation_ = Operation::SBB; break;
|
||||
case 5: operation_ = Operation::SUB; break;
|
||||
case 7: operation_ = Operation::CMP; break;
|
||||
}
|
||||
break;
|
||||
|
||||
default: assert(false);
|
||||
}
|
||||
|
||||
@ -562,7 +580,14 @@ std::pair<int, Instruction> Decoder::decode(const uint8_t *source, size_t length
|
||||
|
||||
switch(operand_size_) {
|
||||
default: operand_ = 0; break;
|
||||
case 1: operand_ = inward_data_ >> 56; inward_data_ <<= 8; break;
|
||||
case 1:
|
||||
operand_ = inward_data_ >> 56; inward_data_ <<= 8;
|
||||
|
||||
// Sign extend if a single byte operand is feeding a two-byte instruction.
|
||||
if(operation_size_ == 2) {
|
||||
operand_ |= (operand_ & 0x80) ? 0xff : 0x00;
|
||||
}
|
||||
break;
|
||||
case 2: operand_ = inward_data_ >> 48; inward_data_ <<= 16; break;
|
||||
}
|
||||
switch(displacement_size_) {
|
||||
|
@ -259,6 +259,12 @@ struct Decoder {
|
||||
// 'register' field to pick from INC/DEC/CALL/JMP/PUSH, altering
|
||||
// the source to ::Immediate and setting an operand size if necessary.
|
||||
MemRegINC_to_PUSH,
|
||||
|
||||
// Parse for mode and register/memory fields, populating the
|
||||
// source_ and destination_ fields with the result. Uses the
|
||||
// 'register' field to pick from ADD/ADC/SBB/SUB/CMP, altering
|
||||
// the source to ::Immediate and setting an appropriate operand size.
|
||||
MemRegADC_to_CMP,
|
||||
} modregrm_format_ = ModRegRMFormat::MemReg_Reg;
|
||||
|
||||
// Ephemeral decoding state.
|
||||
|
Loading…
Reference in New Issue
Block a user