mirror of
https://github.com/TomHarte/CLK.git
synced 2025-03-25 21:34:05 +00:00
Allow for non-sign-extended offsets/displacements.
This commit is contained in:
parent
d36f785428
commit
d2b9c435e5
InstructionSets/x86
@ -238,7 +238,7 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
||||
RequiresMin(i80286);
|
||||
MemRegReg(IMUL_3, Reg_MemReg, data_size_);
|
||||
operand_size_ = DataSize::Byte;
|
||||
sign_extend_ = true;
|
||||
sign_extend_operand_ = true;
|
||||
break;
|
||||
case 0x6c: // INSB
|
||||
RequiresMin(i80186);
|
||||
@ -795,7 +795,7 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
||||
source_ = Source::Immediate;
|
||||
destination_ = memreg;
|
||||
operand_size_ = (modregrm_format_ == ModRegRMFormat::MemRegADD_to_CMP_SignExtend) ? DataSize::Byte : operation_size_;
|
||||
sign_extend_ = true; // Will be effective only if modregrm_format_ == ModRegRMFormat::MemRegADD_to_CMP_SignExtend.
|
||||
sign_extend_operand_ = true; // Will be effective only if modregrm_format_ == ModRegRMFormat::MemRegADD_to_CMP_SignExtend.
|
||||
|
||||
switch(reg) {
|
||||
default: operation_ = Operation::ADD; break;
|
||||
@ -905,16 +905,25 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
||||
// TODO: whether the displacement is signed appears to depend on the opcode.
|
||||
// Find an appropriate table.
|
||||
|
||||
switch(displacement_size_) {
|
||||
case DataSize::None: displacement_ = 0; break;
|
||||
case DataSize::Byte: displacement_ = int8_t(inward_data_); break;
|
||||
case DataSize::Word: displacement_ = int16_t(inward_data_); break;
|
||||
case DataSize::DWord: displacement_ = int32_t(inward_data_); break;
|
||||
if(!sign_extend_displacement_) {
|
||||
switch(displacement_size_) {
|
||||
case DataSize::None: displacement_ = 0; break;
|
||||
case DataSize::Byte: displacement_ = decltype(operand_)(uint8_t(inward_data_)); break;
|
||||
case DataSize::Word: displacement_ = decltype(operand_)(uint16_t(inward_data_)); break;
|
||||
case DataSize::DWord: displacement_ = decltype(operand_)(uint32_t(inward_data_)); break;
|
||||
}
|
||||
} else {
|
||||
switch(displacement_size_) {
|
||||
case DataSize::None: displacement_ = 0; break;
|
||||
case DataSize::Byte: displacement_ = int8_t(inward_data_); break;
|
||||
case DataSize::Word: displacement_ = int16_t(inward_data_); break;
|
||||
case DataSize::DWord: displacement_ = int32_t(inward_data_); break;
|
||||
}
|
||||
}
|
||||
inward_data_ >>= bit_size(displacement_size_);
|
||||
|
||||
// Use inequality of sizes as a test for necessary sign extension.
|
||||
if(operand_size_ == data_size_ || !sign_extend_) {
|
||||
if(operand_size_ == data_size_ || !sign_extend_operand_) {
|
||||
operand_ = decltype(operand_)(inward_data_);
|
||||
} else {
|
||||
switch(operand_size_) {
|
||||
|
@ -193,8 +193,10 @@ template <Model model> class Decoder {
|
||||
DataSize operand_size_ = DataSize::None; // i.e. size of in-stream operand, if any.
|
||||
DataSize operation_size_ = DataSize::None; // i.e. size of data manipulated by the operation.
|
||||
|
||||
bool sign_extend_ = false; // If set then sign extend the operand up to the operation size;
|
||||
bool sign_extend_operand_ = false; // If set then sign extend the operand up to the operation size;
|
||||
// otherwise it'll be zero-padded.
|
||||
bool sign_extend_displacement_ = false; // Much as above; 'displacement' is used internally for both
|
||||
// displacements and offsets, so signage will vary.
|
||||
|
||||
// Prefix capture fields.
|
||||
Repetition repetition_ = Repetition::None;
|
||||
@ -222,7 +224,8 @@ template <Model model> class Decoder {
|
||||
sib_ = ScaleIndexBase();
|
||||
next_inward_data_shift_ = 0;
|
||||
inward_data_ = 0;
|
||||
sign_extend_ = false;
|
||||
sign_extend_operand_ = false;
|
||||
sign_extend_displacement_ = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user