0
mirror of https://github.com/sampletext32/ParkanPlayground.git synced 2025-05-19 03:41:18 +03:00

Removed original floating point handlers that have been replaced by specialized handlers

This commit is contained in:
bird_egop 2025-04-18 00:23:21 +03:00
parent d216c29315
commit e6e3e886c8
6 changed files with 0 additions and 1031 deletions

View File

@ -1,123 +0,0 @@
using X86Disassembler.X86.Operands;
namespace X86Disassembler.X86.Handlers.FloatingPoint;
/// <summary>
/// Handler for floating-point operations on float32 (D8 opcode)
/// </summary>
public class Float32OperationHandler : InstructionHandler
{
// D8 opcode - operations on float32
private static readonly string[] Mnemonics =
[
"fadd",
"fmul",
"fcom",
"fcomp",
"fsub",
"fsubr",
"fdiv",
"fdivr"
];
// Corresponding instruction types for each mnemonic
private static readonly InstructionType[] InstructionTypes =
[
InstructionType.Fadd,
InstructionType.Fmul,
InstructionType.Fcom,
InstructionType.Fcomp,
InstructionType.Fsub,
InstructionType.Fsubr,
InstructionType.Fdiv,
InstructionType.Fdivr
];
/// <summary>
/// Initializes a new instance of the Float32OperationHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public Float32OperationHandler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
return opcode == 0xD8;
}
/// <summary>
/// Decodes a floating-point instruction for float32 operations
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type based on the reg field
instruction.Type = InstructionTypes[(int)reg];
// For memory operands, set the operand
if (mod != 3) // Memory operand
{
// Create a new memory operand with 32-bit size using the appropriate factory method
Operand operand;
if (rawOperand is DirectMemoryOperand directMemory)
{
operand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 32);
}
else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
{
operand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 32);
}
else if (rawOperand is DisplacementMemoryOperand dispMemory)
{
operand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 32);
}
else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
{
operand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 32);
}
else
{
operand = rawOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
operand
];
}
else // Register operand (ST(i))
{
// For register operands, we need to handle the stack registers
var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0); // ST(0)
var stiOperand = OperandFactory.CreateFPURegisterOperand((FpuRegisterIndex)rm); // ST(i)
// Set the structured operands
instruction.StructuredOperands =
[
st0Operand,
stiOperand
];
}
return true;
}
}

View File

@ -1,123 +0,0 @@
using X86Disassembler.X86.Operands;
namespace X86Disassembler.X86.Handlers.FloatingPoint;
/// <summary>
/// Handler for floating-point operations on float64 (DC opcode)
/// </summary>
public class Float64OperationHandler : InstructionHandler
{
// DC opcode - operations on float64
private static readonly string[] Mnemonics =
[
"fadd",
"fmul",
"fcom",
"fcomp",
"fsub",
"fsubr",
"fdiv",
"fdivr"
];
// Corresponding instruction types for each mnemonic
private static readonly InstructionType[] InstructionTypes =
[
InstructionType.Fadd,
InstructionType.Fmul,
InstructionType.Fcom,
InstructionType.Fcomp,
InstructionType.Fsub,
InstructionType.Fsubr,
InstructionType.Fdiv,
InstructionType.Fdivr
];
/// <summary>
/// Initializes a new instance of the Float64OperationHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public Float64OperationHandler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
return opcode == 0xDC;
}
/// <summary>
/// Decodes a floating-point instruction for float64 operations
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawOperand) = ModRMDecoder.ReadModRM64(); // Use the 64-bit version
// Set the instruction type based on the reg field
instruction.Type = InstructionTypes[(int)reg];
// For memory operands, set the operand
if (mod != 3) // Memory operand
{
// Create a new memory operand with 64-bit size using the appropriate factory method
Operand operand;
if (rawOperand is DirectMemoryOperand directMemory)
{
operand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 64);
}
else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
{
operand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 64);
}
else if (rawOperand is DisplacementMemoryOperand dispMemory)
{
operand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 64);
}
else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
{
operand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 64);
}
else
{
operand = rawOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
operand
];
}
else // Register operand (ST(i))
{
// For DC C0-DC FF, the operands are reversed: ST(i), ST(0)
var stiOperand = OperandFactory.CreateFPURegisterOperand((FpuRegisterIndex)rm); // ST(i)
var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0); // ST(0)
// Set the structured operands
instruction.StructuredOperands =
[
stiOperand,
st0Operand
];
}
return true;
}
}

View File

@ -1,179 +0,0 @@
using X86Disassembler.X86.Operands;
namespace X86Disassembler.X86.Handlers.FloatingPoint;
/// <summary>
/// Handler for floating-point operations on int16 (DE opcode)
/// </summary>
public class Int16OperationHandler : InstructionHandler
{
// Memory operand instruction types for DE opcode - operations on int16
private static readonly InstructionType[] MemoryInstructionTypes =
[
InstructionType.Fiadd, // fiadd word ptr [r/m]
InstructionType.Fmul, // fimul word ptr [r/m]
InstructionType.Fcom, // ficom word ptr [r/m]
InstructionType.Fcomp, // ficomp word ptr [r/m]
InstructionType.Fsub, // fisub word ptr [r/m]
InstructionType.Fsubr, // fisubr word ptr [r/m]
InstructionType.Fdiv, // fidiv word ptr [r/m]
InstructionType.Fdivr // fidivr word ptr [r/m]
];
// Register-register operations mapping (mod=3)
private static readonly Dictionary<(int Reg, int Rm), (InstructionType Type, FpuRegisterIndex DestIndex, FpuRegisterIndex? SrcIndex)> RegisterOperations = new()
{
// FADDP st(i), st(0)
{ (0, 0), (InstructionType.Fadd, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (0, 1), (InstructionType.Fadd, FpuRegisterIndex.ST1, FpuRegisterIndex.ST0) },
{ (0, 2), (InstructionType.Fadd, FpuRegisterIndex.ST2, FpuRegisterIndex.ST0) },
{ (0, 3), (InstructionType.Fadd, FpuRegisterIndex.ST3, FpuRegisterIndex.ST0) },
{ (0, 4), (InstructionType.Fadd, FpuRegisterIndex.ST4, FpuRegisterIndex.ST0) },
{ (0, 5), (InstructionType.Fadd, FpuRegisterIndex.ST5, FpuRegisterIndex.ST0) },
{ (0, 6), (InstructionType.Fadd, FpuRegisterIndex.ST6, FpuRegisterIndex.ST0) },
{ (0, 7), (InstructionType.Fadd, FpuRegisterIndex.ST7, FpuRegisterIndex.ST0) },
// FMULP st(i), st(0)
{ (1, 0), (InstructionType.Fmul, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (1, 1), (InstructionType.Fmul, FpuRegisterIndex.ST1, FpuRegisterIndex.ST0) },
{ (1, 2), (InstructionType.Fmul, FpuRegisterIndex.ST2, FpuRegisterIndex.ST0) },
{ (1, 3), (InstructionType.Fmul, FpuRegisterIndex.ST3, FpuRegisterIndex.ST0) },
{ (1, 4), (InstructionType.Fmul, FpuRegisterIndex.ST4, FpuRegisterIndex.ST0) },
{ (1, 5), (InstructionType.Fmul, FpuRegisterIndex.ST5, FpuRegisterIndex.ST0) },
{ (1, 6), (InstructionType.Fmul, FpuRegisterIndex.ST6, FpuRegisterIndex.ST0) },
{ (1, 7), (InstructionType.Fmul, FpuRegisterIndex.ST7, FpuRegisterIndex.ST0) },
// Special cases
{ (2, 3), (InstructionType.Fcomp, FpuRegisterIndex.ST0, null) },
{ (3, 3), (InstructionType.Fcompp, FpuRegisterIndex.ST0, null) },
// FSUBP st(i), st(0)
{ (6, 0), (InstructionType.Fsub, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (6, 1), (InstructionType.Fsub, FpuRegisterIndex.ST1, FpuRegisterIndex.ST0) },
{ (6, 2), (InstructionType.Fsub, FpuRegisterIndex.ST2, FpuRegisterIndex.ST0) },
{ (6, 3), (InstructionType.Fsub, FpuRegisterIndex.ST3, FpuRegisterIndex.ST0) },
{ (6, 4), (InstructionType.Fsub, FpuRegisterIndex.ST4, FpuRegisterIndex.ST0) },
{ (6, 5), (InstructionType.Fsub, FpuRegisterIndex.ST5, FpuRegisterIndex.ST0) },
{ (6, 6), (InstructionType.Fsub, FpuRegisterIndex.ST6, FpuRegisterIndex.ST0) },
{ (6, 7), (InstructionType.Fsub, FpuRegisterIndex.ST7, FpuRegisterIndex.ST0) },
// FSUBRP st(i), st(0)
{ (7, 0), (InstructionType.Fsubr, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (7, 1), (InstructionType.Fsubr, FpuRegisterIndex.ST1, FpuRegisterIndex.ST0) },
{ (7, 2), (InstructionType.Fsubr, FpuRegisterIndex.ST2, FpuRegisterIndex.ST0) },
{ (7, 3), (InstructionType.Fsubr, FpuRegisterIndex.ST3, FpuRegisterIndex.ST0) },
{ (7, 4), (InstructionType.Fsubr, FpuRegisterIndex.ST4, FpuRegisterIndex.ST0) },
{ (7, 5), (InstructionType.Fsubr, FpuRegisterIndex.ST5, FpuRegisterIndex.ST0) },
{ (7, 6), (InstructionType.Fsubr, FpuRegisterIndex.ST6, FpuRegisterIndex.ST0) },
{ (7, 7), (InstructionType.Fsubr, FpuRegisterIndex.ST7, FpuRegisterIndex.ST0) },
// FDIVP st(i), st(0)
{ (4, 0), (InstructionType.Fdiv, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (4, 1), (InstructionType.Fdiv, FpuRegisterIndex.ST1, FpuRegisterIndex.ST0) },
{ (4, 2), (InstructionType.Fdiv, FpuRegisterIndex.ST2, FpuRegisterIndex.ST0) },
{ (4, 3), (InstructionType.Fdiv, FpuRegisterIndex.ST3, FpuRegisterIndex.ST0) },
{ (4, 4), (InstructionType.Fdiv, FpuRegisterIndex.ST4, FpuRegisterIndex.ST0) },
{ (4, 5), (InstructionType.Fdiv, FpuRegisterIndex.ST5, FpuRegisterIndex.ST0) },
{ (4, 6), (InstructionType.Fdiv, FpuRegisterIndex.ST6, FpuRegisterIndex.ST0) },
{ (4, 7), (InstructionType.Fdiv, FpuRegisterIndex.ST7, FpuRegisterIndex.ST0) },
// FDIVRP st(i), st(0)
{ (5, 0), (InstructionType.Fdivr, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (5, 1), (InstructionType.Fdivr, FpuRegisterIndex.ST1, FpuRegisterIndex.ST0) },
{ (5, 2), (InstructionType.Fdivr, FpuRegisterIndex.ST2, FpuRegisterIndex.ST0) },
{ (5, 3), (InstructionType.Fdivr, FpuRegisterIndex.ST3, FpuRegisterIndex.ST0) },
{ (5, 4), (InstructionType.Fdivr, FpuRegisterIndex.ST4, FpuRegisterIndex.ST0) },
{ (5, 5), (InstructionType.Fdivr, FpuRegisterIndex.ST5, FpuRegisterIndex.ST0) },
{ (5, 6), (InstructionType.Fdivr, FpuRegisterIndex.ST6, FpuRegisterIndex.ST0) },
{ (5, 7), (InstructionType.Fdivr, FpuRegisterIndex.ST7, FpuRegisterIndex.ST0) }
};
/// <summary>
/// Initializes a new instance of the Int16OperationHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public Int16OperationHandler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
return opcode == 0xDE;
}
/// <summary>
/// Decodes a floating-point instruction for int16 operations
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte, specifying that we're dealing with 16-bit operands
var (mod, reg, rm, memoryOperand) = ModRMDecoder.ReadModRM16();
// Handle based on addressing mode
if (mod != 3) // Memory operand
{
// Set the instruction type based on the reg field
instruction.Type = MemoryInstructionTypes[(int)reg];
// Note: The operand size is already set to 16-bit by the ReadModRM16 method
var int16Operand = memoryOperand;
// Set the structured operands
instruction.StructuredOperands =
[
int16Operand
];
}
else // Register operand (ST(i))
{
// Look up the instruction type in the register operations dictionary
if (RegisterOperations.TryGetValue(((int)reg, (int)rm), out var operation))
{
instruction.Type = operation.Type;
// Create the FPU register operands
var destOperand = OperandFactory.CreateFPURegisterOperand(operation.DestIndex);
// Set the structured operands
if (operation.SrcIndex.HasValue)
{
var srcOperand = OperandFactory.CreateFPURegisterOperand(operation.SrcIndex.Value);
instruction.StructuredOperands =
[
destOperand,
srcOperand
];
}
else
{
instruction.StructuredOperands =
[
destOperand
];
}
}
else
{
// Unknown instruction
instruction.Type = InstructionType.Unknown;
instruction.StructuredOperands = [];
}
}
return true;
}
}

View File

@ -1,196 +0,0 @@
using X86Disassembler.X86.Operands;
namespace X86Disassembler.X86.Handlers.FloatingPoint;
/// <summary>
/// Handler for floating-point load/store float64 operations (DD opcode)
/// </summary>
public class LoadStoreFloat64Handler : InstructionHandler
{
// Memory operand mnemonics for DD opcode - load/store float64
private static readonly string[] MemoryMnemonics =
[
"fld", // 0
"??", // 1
"fst", // 2
"fstp", // 3
"frstor", // 4
"??", // 5
"fnsave", // 6
"fnstsw" // 7
];
// Memory operand instruction types for DD opcode
private static readonly InstructionType[] MemoryInstructionTypes =
[
InstructionType.Fld, // 0 - fld qword ptr [r/m]
InstructionType.Unknown, // 1 - (reserved)
InstructionType.Fst, // 2 - fst qword ptr [r/m]
InstructionType.Fstp, // 3 - fstp qword ptr [r/m]
InstructionType.Frstor, // 4 - frstor [r/m]
InstructionType.Unknown, // 5 - (reserved)
InstructionType.Fnsave, // 6 - fnsave [r/m]
InstructionType.Fnstsw // 7 - fnstsw [r/m]
];
// Register-register operations mapping (mod=3)
private static readonly Dictionary<(RegisterIndex Reg, RegisterIndex Rm), (InstructionType Type, FpuRegisterIndex OperandIndex)> RegisterOperations = new()
{
// FFREE ST(i)
{ (RegisterIndex.A, RegisterIndex.A), (InstructionType.Ffree, FpuRegisterIndex.ST0) },
{ (RegisterIndex.A, RegisterIndex.C), (InstructionType.Ffree, FpuRegisterIndex.ST1) },
{ (RegisterIndex.A, RegisterIndex.D), (InstructionType.Ffree, FpuRegisterIndex.ST2) },
{ (RegisterIndex.A, RegisterIndex.B), (InstructionType.Ffree, FpuRegisterIndex.ST3) },
{ (RegisterIndex.A, RegisterIndex.Sp), (InstructionType.Ffree, FpuRegisterIndex.ST4) },
{ (RegisterIndex.A, RegisterIndex.Bp), (InstructionType.Ffree, FpuRegisterIndex.ST5) },
{ (RegisterIndex.A, RegisterIndex.Si), (InstructionType.Ffree, FpuRegisterIndex.ST6) },
{ (RegisterIndex.A, RegisterIndex.Di), (InstructionType.Ffree, FpuRegisterIndex.ST7) },
// FST ST(i)
{ (RegisterIndex.C, RegisterIndex.A), (InstructionType.Fst, FpuRegisterIndex.ST0) },
{ (RegisterIndex.C, RegisterIndex.C), (InstructionType.Fst, FpuRegisterIndex.ST1) },
{ (RegisterIndex.C, RegisterIndex.D), (InstructionType.Fst, FpuRegisterIndex.ST2) },
{ (RegisterIndex.C, RegisterIndex.B), (InstructionType.Fst, FpuRegisterIndex.ST3) },
{ (RegisterIndex.C, RegisterIndex.Sp), (InstructionType.Fst, FpuRegisterIndex.ST4) },
{ (RegisterIndex.C, RegisterIndex.Bp), (InstructionType.Fst, FpuRegisterIndex.ST5) },
{ (RegisterIndex.C, RegisterIndex.Si), (InstructionType.Fst, FpuRegisterIndex.ST6) },
{ (RegisterIndex.C, RegisterIndex.Di), (InstructionType.Fst, FpuRegisterIndex.ST7) },
// FSTP ST(i)
{ (RegisterIndex.D, RegisterIndex.A), (InstructionType.Fstp, FpuRegisterIndex.ST0) },
{ (RegisterIndex.D, RegisterIndex.C), (InstructionType.Fstp, FpuRegisterIndex.ST1) },
{ (RegisterIndex.D, RegisterIndex.D), (InstructionType.Fstp, FpuRegisterIndex.ST2) },
{ (RegisterIndex.D, RegisterIndex.B), (InstructionType.Fstp, FpuRegisterIndex.ST3) },
{ (RegisterIndex.D, RegisterIndex.Sp), (InstructionType.Fstp, FpuRegisterIndex.ST4) },
{ (RegisterIndex.D, RegisterIndex.Bp), (InstructionType.Fstp, FpuRegisterIndex.ST5) },
{ (RegisterIndex.D, RegisterIndex.Si), (InstructionType.Fstp, FpuRegisterIndex.ST6) },
{ (RegisterIndex.D, RegisterIndex.Di), (InstructionType.Fstp, FpuRegisterIndex.ST7) },
// FUCOM ST(i)
{ (RegisterIndex.Si, RegisterIndex.A), (InstructionType.Fucom, FpuRegisterIndex.ST0) },
{ (RegisterIndex.Si, RegisterIndex.C), (InstructionType.Fucom, FpuRegisterIndex.ST1) },
{ (RegisterIndex.Si, RegisterIndex.D), (InstructionType.Fucom, FpuRegisterIndex.ST2) },
{ (RegisterIndex.Si, RegisterIndex.B), (InstructionType.Fucom, FpuRegisterIndex.ST3) },
{ (RegisterIndex.Si, RegisterIndex.Sp), (InstructionType.Fucom, FpuRegisterIndex.ST4) },
{ (RegisterIndex.Si, RegisterIndex.Bp), (InstructionType.Fucom, FpuRegisterIndex.ST5) },
{ (RegisterIndex.Si, RegisterIndex.Si), (InstructionType.Fucom, FpuRegisterIndex.ST6) },
{ (RegisterIndex.Si, RegisterIndex.Di), (InstructionType.Fucom, FpuRegisterIndex.ST7) },
// FUCOMP ST(i)
{ (RegisterIndex.Di, RegisterIndex.A), (InstructionType.Fucomp, FpuRegisterIndex.ST0) },
{ (RegisterIndex.Di, RegisterIndex.C), (InstructionType.Fucomp, FpuRegisterIndex.ST1) },
{ (RegisterIndex.Di, RegisterIndex.D), (InstructionType.Fucomp, FpuRegisterIndex.ST2) },
{ (RegisterIndex.Di, RegisterIndex.B), (InstructionType.Fucomp, FpuRegisterIndex.ST3) },
{ (RegisterIndex.Di, RegisterIndex.Sp), (InstructionType.Fucomp, FpuRegisterIndex.ST4) },
{ (RegisterIndex.Di, RegisterIndex.Bp), (InstructionType.Fucomp, FpuRegisterIndex.ST5) },
{ (RegisterIndex.Di, RegisterIndex.Si), (InstructionType.Fucomp, FpuRegisterIndex.ST6) },
{ (RegisterIndex.Di, RegisterIndex.Di), (InstructionType.Fucomp, FpuRegisterIndex.ST7) }
};
/// <summary>
/// Initializes a new instance of the LoadStoreFloat64Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public LoadStoreFloat64Handler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
return opcode == 0xDD;
}
/// <summary>
/// Decodes a floating point instruction with the DD opcode
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
// Check if we have enough bytes for the ModR/M byte
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type based on the mod and reg fields
if (mod != 3) // Memory operand
{
instruction.Type = MemoryInstructionTypes[(int)reg];
// For memory operands, the instruction depends on the reg field
switch (reg)
{
case RegisterIndex.A: // FLD m64real
case RegisterIndex.C: // FST m64real
case RegisterIndex.D: // FSTP m64real
// Create a new memory operand with 64-bit size using the appropriate factory method
Operand memoryOperand;
if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 64);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseRegMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 64);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 64);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 64);
}
else
{
memoryOperand = rawMemoryOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
default:
// For unsupported instructions, just set the type to Unknown
instruction.Type = InstructionType.Unknown;
return true;
}
}
else // Register operand (mod == 3)
{
// Look up the instruction type in the register operations dictionary
if (RegisterOperations.TryGetValue((reg, rm), out var operation))
{
instruction.Type = operation.Type;
// Create the FPU register operand
var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(operation.OperandIndex);
// Set the structured operands
instruction.StructuredOperands =
[
fpuRegisterOperand
];
return true;
}
}
return false;
}
}

View File

@ -1,192 +0,0 @@
using X86Disassembler.X86.Operands;
namespace X86Disassembler.X86.Handlers.FloatingPoint;
/// <summary>
/// Handler for floating-point load/store int16 and miscellaneous operations (DF opcode)
/// </summary>
public class LoadStoreInt16Handler : InstructionHandler
{
// Memory operand instruction types for DF opcode - load/store int16, misc
private static readonly InstructionType[] MemoryInstructionTypes =
[
InstructionType.Fild, // fild word ptr [r/m]
InstructionType.Fisttp, // fistt word ptr [r/m]
InstructionType.Fist, // fist word ptr [r/m]
InstructionType.Fistp, // fistp word ptr [r/m]
InstructionType.Fbld, // fbld packed BCD [r/m]
InstructionType.Fild, // fild qword ptr [r/m] (64-bit integer)
InstructionType.Fbstp, // fbstp packed BCD [r/m]
InstructionType.Fistp // fistp qword ptr [r/m] (64-bit integer)
];
// Register-register operations mapping (mod=3)
private static readonly Dictionary<(RegisterIndex Reg, RegisterIndex Rm), (InstructionType Type, FpuRegisterIndex OperandIndex, FpuRegisterIndex? SrcIndex)> RegisterOperations = new()
{
// FFREEP ST(i)
{ (RegisterIndex.A, RegisterIndex.A), (InstructionType.Ffreep, FpuRegisterIndex.ST0, null) },
{ (RegisterIndex.A, RegisterIndex.C), (InstructionType.Ffreep, FpuRegisterIndex.ST1, null) },
{ (RegisterIndex.A, RegisterIndex.D), (InstructionType.Ffreep, FpuRegisterIndex.ST2, null) },
{ (RegisterIndex.A, RegisterIndex.B), (InstructionType.Ffreep, FpuRegisterIndex.ST3, null) },
{ (RegisterIndex.A, RegisterIndex.Sp), (InstructionType.Ffreep, FpuRegisterIndex.ST4, null) },
{ (RegisterIndex.A, RegisterIndex.Bp), (InstructionType.Ffreep, FpuRegisterIndex.ST5, null) },
{ (RegisterIndex.A, RegisterIndex.Si), (InstructionType.Ffreep, FpuRegisterIndex.ST6, null) },
{ (RegisterIndex.A, RegisterIndex.Di), (InstructionType.Ffreep, FpuRegisterIndex.ST7, null) },
// Special cases
{ (RegisterIndex.B, RegisterIndex.A), (InstructionType.Fxch, FpuRegisterIndex.ST0, null) },
{ (RegisterIndex.C, RegisterIndex.A), (InstructionType.Fstp, FpuRegisterIndex.ST1, null) },
{ (RegisterIndex.D, RegisterIndex.A), (InstructionType.Fstp, FpuRegisterIndex.ST1, null) },
// FUCOMIP ST(0), ST(i)
{ (RegisterIndex.Di, RegisterIndex.A), (InstructionType.Fucomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (RegisterIndex.Di, RegisterIndex.C), (InstructionType.Fucomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST1) },
{ (RegisterIndex.Di, RegisterIndex.D), (InstructionType.Fucomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST2) },
{ (RegisterIndex.Di, RegisterIndex.B), (InstructionType.Fucomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST3) },
{ (RegisterIndex.Di, RegisterIndex.Sp), (InstructionType.Fucomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST4) },
{ (RegisterIndex.Di, RegisterIndex.Bp), (InstructionType.Fucomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST5) },
{ (RegisterIndex.Di, RegisterIndex.Si), (InstructionType.Fucomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST6) },
{ (RegisterIndex.Di, RegisterIndex.Di), (InstructionType.Fucomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST7) },
// FCOMIP ST(0), ST(i)
{ (RegisterIndex.Sp, RegisterIndex.A), (InstructionType.Fcomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (RegisterIndex.Sp, RegisterIndex.C), (InstructionType.Fcomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST1) },
{ (RegisterIndex.Sp, RegisterIndex.D), (InstructionType.Fcomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST2) },
{ (RegisterIndex.Sp, RegisterIndex.B), (InstructionType.Fcomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST3) },
{ (RegisterIndex.Sp, RegisterIndex.Sp), (InstructionType.Fcomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST4) },
{ (RegisterIndex.Sp, RegisterIndex.Bp), (InstructionType.Fcomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST5) },
{ (RegisterIndex.Sp, RegisterIndex.Si), (InstructionType.Fcomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST6) },
{ (RegisterIndex.Sp, RegisterIndex.Di), (InstructionType.Fcomip, FpuRegisterIndex.ST0, FpuRegisterIndex.ST7) }
};
/// <summary>
/// Initializes a new instance of the LoadStoreInt16Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public LoadStoreInt16Handler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
return opcode == 0xDF;
}
/// <summary>
/// Decodes a floating-point instruction for load/store int16 and miscellaneous operations
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Handle based on addressing mode
if (mod != 3) // Memory operand
{
// Set the instruction type based on the reg field
instruction.Type = MemoryInstructionTypes[(int)reg];
// Create the appropriate memory operand based on the operation type and original operand type
Operand memoryOperand;
int operandSize;
// Determine the operand size based on the operation
if (reg == RegisterIndex.A || reg == RegisterIndex.C || reg == RegisterIndex.D) // 16-bit integer operations
{
operandSize = 16;
}
else if (reg == RegisterIndex.Di || reg == RegisterIndex.Bp) // 64-bit integer operations
{
operandSize = 64;
}
else if (reg == RegisterIndex.Si || reg == RegisterIndex.Sp) // 80-bit packed BCD operations
{
operandSize = 80;
}
else
{
// Default to 32-bit for other operations
operandSize = 32;
}
// Create the appropriate memory operand based on the type of the raw operand
if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, operandSize);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, operandSize);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, operandSize);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, operandSize);
}
else
{
memoryOperand = rawMemoryOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
}
else // Register operand (ST(i))
{
// Look up the instruction type in the register operations dictionary
if (RegisterOperations.TryGetValue((reg, rm), out var operation))
{
instruction.Type = operation.Type;
// Create the FPU register operands
var destOperand = OperandFactory.CreateFPURegisterOperand(operation.OperandIndex);
// Set the structured operands
if (operation.SrcIndex.HasValue)
{
var srcOperand = OperandFactory.CreateFPURegisterOperand(operation.SrcIndex.Value);
instruction.StructuredOperands =
[
destOperand,
srcOperand
];
}
else
{
instruction.StructuredOperands =
[
destOperand
];
}
}
else
{
// Unknown instruction
instruction.Type = InstructionType.Unknown;
instruction.StructuredOperands = [];
}
}
return true;
}
}

View File

@ -1,218 +0,0 @@
using X86Disassembler.X86.Operands;
namespace X86Disassembler.X86.Handlers.FloatingPoint;
/// <summary>
/// Handler for floating-point load/store int32 and miscellaneous operations (DB opcode)
/// </summary>
public class LoadStoreInt32Handler : InstructionHandler
{
// Memory operand instruction types for DB opcode - load/store int32, misc
private static readonly InstructionType[] MemoryInstructionTypes =
[
InstructionType.Fild, // fild dword ptr [r/m]
InstructionType.Unknown, // fisttp dword ptr [r/m] (not implemented)
InstructionType.Fist, // fist dword ptr [r/m]
InstructionType.Fistp, // fistp dword ptr [r/m]
InstructionType.Unknown, // (reserved)
InstructionType.Fld, // fld extended-precision [r/m]
InstructionType.Unknown, // (reserved)
InstructionType.Fstp // fstp extended-precision [r/m]
];
// Register-register operations mapping (mod=3)
private static readonly Dictionary<(RegisterIndex Reg, RegisterIndex Rm), (InstructionType Type, FpuRegisterIndex DestIndex, FpuRegisterIndex? SrcIndex)> RegisterOperations = new()
{
// FCMOVNB ST(0), ST(i)
{ (RegisterIndex.A, RegisterIndex.A), (InstructionType.Fcmovnb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (RegisterIndex.A, RegisterIndex.C), (InstructionType.Fcmovnb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST1) },
{ (RegisterIndex.A, RegisterIndex.D), (InstructionType.Fcmovnb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST2) },
{ (RegisterIndex.A, RegisterIndex.B), (InstructionType.Fcmovnb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST3) },
{ (RegisterIndex.A, RegisterIndex.Sp), (InstructionType.Fcmovnb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST4) },
{ (RegisterIndex.A, RegisterIndex.Bp), (InstructionType.Fcmovnb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST5) },
{ (RegisterIndex.A, RegisterIndex.Si), (InstructionType.Fcmovnb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST6) },
{ (RegisterIndex.A, RegisterIndex.Di), (InstructionType.Fcmovnb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST7) },
// FCMOVNE ST(0), ST(i)
{ (RegisterIndex.B, RegisterIndex.A), (InstructionType.Fcmovne, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (RegisterIndex.B, RegisterIndex.C), (InstructionType.Fcmovne, FpuRegisterIndex.ST0, FpuRegisterIndex.ST1) },
{ (RegisterIndex.B, RegisterIndex.D), (InstructionType.Fcmovne, FpuRegisterIndex.ST0, FpuRegisterIndex.ST2) },
{ (RegisterIndex.B, RegisterIndex.B), (InstructionType.Fcmovne, FpuRegisterIndex.ST0, FpuRegisterIndex.ST3) },
{ (RegisterIndex.B, RegisterIndex.Sp), (InstructionType.Fcmovne, FpuRegisterIndex.ST0, FpuRegisterIndex.ST4) },
{ (RegisterIndex.B, RegisterIndex.Bp), (InstructionType.Fcmovne, FpuRegisterIndex.ST0, FpuRegisterIndex.ST5) },
{ (RegisterIndex.B, RegisterIndex.Si), (InstructionType.Fcmovne, FpuRegisterIndex.ST0, FpuRegisterIndex.ST6) },
{ (RegisterIndex.B, RegisterIndex.Di), (InstructionType.Fcmovne, FpuRegisterIndex.ST0, FpuRegisterIndex.ST7) },
// FCMOVNBE ST(0), ST(i)
{ (RegisterIndex.C, RegisterIndex.A), (InstructionType.Fcmovnbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (RegisterIndex.C, RegisterIndex.C), (InstructionType.Fcmovnbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST1) },
{ (RegisterIndex.C, RegisterIndex.D), (InstructionType.Fcmovnbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST2) },
{ (RegisterIndex.C, RegisterIndex.B), (InstructionType.Fcmovnbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST3) },
{ (RegisterIndex.C, RegisterIndex.Sp), (InstructionType.Fcmovnbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST4) },
{ (RegisterIndex.C, RegisterIndex.Bp), (InstructionType.Fcmovnbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST5) },
{ (RegisterIndex.C, RegisterIndex.Si), (InstructionType.Fcmovnbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST6) },
{ (RegisterIndex.C, RegisterIndex.Di), (InstructionType.Fcmovnbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST7) },
// FCMOVNU ST(0), ST(i)
{ (RegisterIndex.D, RegisterIndex.A), (InstructionType.Fcmovnu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (RegisterIndex.D, RegisterIndex.C), (InstructionType.Fcmovnu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST1) },
{ (RegisterIndex.D, RegisterIndex.D), (InstructionType.Fcmovnu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST2) },
{ (RegisterIndex.D, RegisterIndex.B), (InstructionType.Fcmovnu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST3) },
{ (RegisterIndex.D, RegisterIndex.Sp), (InstructionType.Fcmovnu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST4) },
{ (RegisterIndex.D, RegisterIndex.Bp), (InstructionType.Fcmovnu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST5) },
{ (RegisterIndex.D, RegisterIndex.Si), (InstructionType.Fcmovnu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST6) },
{ (RegisterIndex.D, RegisterIndex.Di), (InstructionType.Fcmovnu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST7) },
// Special cases
{ (RegisterIndex.Si, RegisterIndex.C), (InstructionType.Fclex, FpuRegisterIndex.ST0, null) }, // fclex
{ (RegisterIndex.Si, RegisterIndex.D), (InstructionType.Finit, FpuRegisterIndex.ST0, null) }, // finit
// FUCOMI ST(0), ST(i)
{ (RegisterIndex.Di, RegisterIndex.A), (InstructionType.Fucomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (RegisterIndex.Di, RegisterIndex.C), (InstructionType.Fucomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST1) },
{ (RegisterIndex.Di, RegisterIndex.D), (InstructionType.Fucomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST2) },
{ (RegisterIndex.Di, RegisterIndex.B), (InstructionType.Fucomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST3) },
{ (RegisterIndex.Di, RegisterIndex.Sp), (InstructionType.Fucomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST4) },
{ (RegisterIndex.Di, RegisterIndex.Bp), (InstructionType.Fucomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST5) },
{ (RegisterIndex.Di, RegisterIndex.Si), (InstructionType.Fucomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST6) },
{ (RegisterIndex.Di, RegisterIndex.Di), (InstructionType.Fucomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST7) },
// FCOMI ST(0), ST(i)
{ (RegisterIndex.Sp, RegisterIndex.A), (InstructionType.Fcomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
{ (RegisterIndex.Sp, RegisterIndex.C), (InstructionType.Fcomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST1) },
{ (RegisterIndex.Sp, RegisterIndex.D), (InstructionType.Fcomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST2) },
{ (RegisterIndex.Sp, RegisterIndex.B), (InstructionType.Fcomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST3) },
{ (RegisterIndex.Sp, RegisterIndex.Sp), (InstructionType.Fcomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST4) },
{ (RegisterIndex.Sp, RegisterIndex.Bp), (InstructionType.Fcomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST5) },
{ (RegisterIndex.Sp, RegisterIndex.Si), (InstructionType.Fcomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST6) },
{ (RegisterIndex.Sp, RegisterIndex.Di), (InstructionType.Fcomi, FpuRegisterIndex.ST0, FpuRegisterIndex.ST7) }
};
/// <summary>
/// Initializes a new instance of the LoadStoreInt32Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public LoadStoreInt32Handler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
return opcode == 0xDB;
}
/// <summary>
/// Decodes a floating-point instruction for load/store int32 and miscellaneous operations
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Handle based on addressing mode
if (mod != 3) // Memory operand
{
// Set the instruction type based on the reg field
instruction.Type = MemoryInstructionTypes[(int)reg];
// Create a new memory operand with the appropriate size based on the operation
Operand memoryOperand;
int operandSize;
if (reg == RegisterIndex.A || reg == RegisterIndex.C || reg == RegisterIndex.D) // 32-bit integer operations
{
// Use 32-bit size for integer operations
operandSize = 32;
}
else if (reg == RegisterIndex.Di || reg == RegisterIndex.Bp) // 80-bit extended precision operations
{
// Use 80-bit size for extended precision operations
operandSize = 80;
}
else
{
// Default size
operandSize = 32;
}
// Create the appropriate memory operand with the correct size
if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, operandSize);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseRegMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, operandSize);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, operandSize);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, operandSize);
}
else
{
memoryOperand = rawMemoryOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
}
else // Register operand (ST(i))
{
// Look up the instruction type in the register operations dictionary
if (RegisterOperations.TryGetValue((reg, rm), out var operation))
{
instruction.Type = operation.Type;
// Create the FPU register operands
var destOperand = OperandFactory.CreateFPURegisterOperand(operation.DestIndex);
// Set the structured operands
if (operation.SrcIndex.HasValue)
{
var srcOperand = OperandFactory.CreateFPURegisterOperand(operation.SrcIndex.Value);
instruction.StructuredOperands =
[
destOperand,
srcOperand
];
}
else
{
instruction.StructuredOperands =
[
destOperand
];
}
}
else
{
// Unknown instruction
instruction.Type = InstructionType.Unknown;
instruction.StructuredOperands = [];
}
}
return true;
}
}