diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FaddRegisterHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FaddRegisterHandler.cs
new file mode 100644
index 0000000..dcdea09
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FaddRegisterHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FADD ST(i), ST(0) instruction (DC C0-C7)
+///
+public class FaddRegisterHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FaddRegisterHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FaddRegisterHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FADD ST(i), ST(0) is DC C0-C7
+ if (opcode != 0xDC) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 0 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 0
+ return reg == 0 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FADD ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fadd;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var stiOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ stiOperand,
+ st0Operand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FaddpHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FaddpHandler.cs
new file mode 100644
index 0000000..5c046e5
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FaddpHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FADDP ST(i), ST(0) instruction (DE C0-C7)
+///
+public class FaddpHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FaddpHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FaddpHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FADDP ST(i), ST(0) is DE C0-C7
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 0 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 0
+ return reg == 0 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FADDP ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Faddp;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivRegisterHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivRegisterHandler.cs
new file mode 100644
index 0000000..01cb4d8
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivRegisterHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FDIV ST(i), ST(0) instruction (DC F0-F7)
+///
+public class FdivRegisterHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FdivRegisterHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FdivRegisterHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FDIV ST(i), ST(0) is DC F0-F7
+ if (opcode != 0xDC) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 6 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 6
+ return reg == 6 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FDIV ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fdiv;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var stiOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ stiOperand,
+ st0Operand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivpHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivpHandler.cs
new file mode 100644
index 0000000..dfea862
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivpHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FDIVP ST(i), ST(0) instruction (DE F0-F7)
+///
+public class FdivpHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FdivpHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FdivpHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FDIVP ST(i), ST(0) is DE F0-F7
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 6 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 6
+ return reg == 6 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FDIVP ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fdivp;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivrRegisterHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivrRegisterHandler.cs
new file mode 100644
index 0000000..12459c1
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivrRegisterHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FDIVR ST(i), ST(0) instruction (DC F8-FF)
+///
+public class FdivrRegisterHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FdivrRegisterHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FdivrRegisterHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FDIVR ST(i), ST(0) is DC F8-FF
+ if (opcode != 0xDC) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 7 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 7
+ return reg == 7 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FDIVR ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fdivr;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var stiOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ stiOperand,
+ st0Operand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivrpHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivrpHandler.cs
new file mode 100644
index 0000000..6a31ffd
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivrpHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FDIVRP ST(i), ST(0) instruction (DE F8-FF)
+///
+public class FdivrpHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FdivrpHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FdivrpHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FDIVRP ST(i), ST(0) is DE F8-FF
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 7 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 7
+ return reg == 7 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FDIVRP ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fdivrp;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FiaddInt16Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FiaddInt16Handler.cs
new file mode 100644
index 0000000..0b8006a
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FiaddInt16Handler.cs
@@ -0,0 +1,70 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FIADD int16 instruction (DE /0)
+///
+public class FiaddInt16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FiaddInt16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FiaddInt16Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FIADD int16 is DE /0
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 0
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 0
+ return reg == 0 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FIADD int16 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fiadd;
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FidivInt16Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FidivInt16Handler.cs
new file mode 100644
index 0000000..d61fce3
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FidivInt16Handler.cs
@@ -0,0 +1,70 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FIDIV int16 instruction (DE /6)
+///
+public class FidivInt16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FidivInt16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FidivInt16Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FIDIV int16 is DE /6
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 6
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 6
+ return reg == 6 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FIDIV int16 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fidiv;
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FidivrInt16Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FidivrInt16Handler.cs
new file mode 100644
index 0000000..7011c34
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FidivrInt16Handler.cs
@@ -0,0 +1,70 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FIDIVR int16 instruction (DE /7)
+///
+public class FidivrInt16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FidivrInt16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FidivrInt16Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FIDIVR int16 is DE /7
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 7
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 7
+ return reg == 7 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FIDIVR int16 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fidivr;
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FimulInt16Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FimulInt16Handler.cs
new file mode 100644
index 0000000..b1ebd47
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FimulInt16Handler.cs
@@ -0,0 +1,70 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FIMUL int16 instruction (DE /1)
+///
+public class FimulInt16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FimulInt16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FimulInt16Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FIMUL int16 is DE /1
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 1
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 1
+ return reg == 1 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FIMUL int16 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fimul;
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FisubInt16Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FisubInt16Handler.cs
new file mode 100644
index 0000000..04d6f87
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FisubInt16Handler.cs
@@ -0,0 +1,70 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FISUB int16 instruction (DE /4)
+///
+public class FisubInt16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FisubInt16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FisubInt16Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FISUB int16 is DE /4
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 4
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 4
+ return reg == 4 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FISUB int16 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fisub;
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FisubrInt16Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FisubrInt16Handler.cs
new file mode 100644
index 0000000..aceb53e
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FisubrInt16Handler.cs
@@ -0,0 +1,70 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FISUBR int16 instruction (DE /5)
+///
+public class FisubrInt16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FisubrInt16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FisubrInt16Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FISUBR int16 is DE /5
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 5
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 5
+ return reg == 5 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FISUBR int16 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fisubr;
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FmulRegisterHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FmulRegisterHandler.cs
new file mode 100644
index 0000000..ccc8f12
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FmulRegisterHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FMUL ST(i), ST(0) instruction (DC C8-CF)
+///
+public class FmulRegisterHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FmulRegisterHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FmulRegisterHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FMUL ST(i), ST(0) is DC C8-CF
+ if (opcode != 0xDC) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 1 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 1
+ return reg == 1 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FMUL ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fmul;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var stiOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ stiOperand,
+ st0Operand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FmulpHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FmulpHandler.cs
new file mode 100644
index 0000000..e3a0825
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FmulpHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FMULP ST(i), ST(0) instruction (DE C8-CF)
+///
+public class FmulpHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FmulpHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FmulpHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FMULP ST(i), ST(0) is DE C8-CF
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 1 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 1
+ return reg == 1 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FMULP ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fmulp;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubRegisterHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubRegisterHandler.cs
new file mode 100644
index 0000000..2b6385c
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubRegisterHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FSUB ST(i), ST(0) instruction (DC E0-E7)
+///
+public class FsubRegisterHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FsubRegisterHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FsubRegisterHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FSUB ST(i), ST(0) is DC E0-E7
+ if (opcode != 0xDC) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 4 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 4
+ return reg == 4 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FSUB ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fsub;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var stiOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ stiOperand,
+ st0Operand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubpHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubpHandler.cs
new file mode 100644
index 0000000..f3b661c
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubpHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FSUBP ST(i), ST(0) instruction (DE E0-E7)
+///
+public class FsubpHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FsubpHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FsubpHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FSUBP ST(i), ST(0) is DE E0-E7
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 4 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 4
+ return reg == 4 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FSUBP ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fsubp;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubrRegisterHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubrRegisterHandler.cs
new file mode 100644
index 0000000..36fd43e
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubrRegisterHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FSUBR ST(i), ST(0) instruction (DC E8-EF)
+///
+public class FsubrRegisterHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FsubrRegisterHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FsubrRegisterHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FSUBR ST(i), ST(0) is DC E8-EF
+ if (opcode != 0xDC) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 5 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 5
+ return reg == 5 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FSUBR ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fsubr;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var stiOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ stiOperand,
+ st0Operand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubrpHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubrpHandler.cs
new file mode 100644
index 0000000..6f3c4cb
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubrpHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FSUBRP ST(i), ST(0) instruction (DE E8-EF)
+///
+public class FsubrpHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FsubrpHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FsubrpHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FSUBRP ST(i), ST(0) is DE E8-EF
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 5 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 5
+ return reg == 5 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FSUBRP ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fsubrp;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomRegisterHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomRegisterHandler.cs
new file mode 100644
index 0000000..03ba4bf
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomRegisterHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FCOM ST(i), ST(0) instruction (DC D0-D7)
+///
+public class FcomRegisterHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FcomRegisterHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FcomRegisterHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FCOM ST(i), ST(0) is DC D0-D7
+ if (opcode != 0xDC) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 2 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 2
+ return reg == 2 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FCOM ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fcom;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var stiOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ stiOperand,
+ st0Operand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomiHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomiHandler.cs
new file mode 100644
index 0000000..9b17a6c
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomiHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FCOMI instruction (DB F0-F7)
+///
+public class FcomiHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FcomiHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FcomiHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FCOMI is DB F0-F7
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 7 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 7
+ return reg == 7 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FCOMI instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fcomi;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomipHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomipHandler.cs
new file mode 100644
index 0000000..c6cbe3a
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomipHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FCOMIP ST(0), ST(i) instruction (DF F0-F7)
+///
+public class FcomipHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FcomipHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FcomipHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FCOMIP ST(0), ST(i) is DF F0-F7
+ if (opcode != 0xDF) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 6 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 6
+ return reg == 6 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FCOMIP ST(0), ST(i) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fcomip;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcompRegisterHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcompRegisterHandler.cs
new file mode 100644
index 0000000..e3a56ab
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcompRegisterHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FCOMP ST(i), ST(0) instruction (DC D8-DF)
+///
+public class FcompRegisterHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FcompRegisterHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FcompRegisterHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FCOMP ST(i), ST(0) is DC D8-DF
+ if (opcode != 0xDC) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 3 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 3
+ return reg == 3 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FCOMP ST(i), ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fcomp;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var stiOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+ var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ stiOperand,
+ st0Operand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcompStHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcompStHandler.cs
new file mode 100644
index 0000000..6fb400f
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcompStHandler.cs
@@ -0,0 +1,69 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FCOMP ST(0) instruction (DE D3)
+///
+public class FcompStHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FcompStHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FcompStHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FCOMP ST(0) is DE D3
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte is exactly D3 (reg = 2, rm = 3, mod = 3)
+ byte modRm = Decoder.PeakByte();
+ return modRm == 0xD3;
+ }
+
+ ///
+ /// Decodes a FCOMP ST(0) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fcomp;
+
+ // Create the FPU register operand
+ var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ fpuRegisterOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomppHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomppHandler.cs
new file mode 100644
index 0000000..c554133
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomppHandler.cs
@@ -0,0 +1,63 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FCOMPP instruction (DE D9)
+///
+public class FcomppHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FcomppHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FcomppHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FCOMPP is DE D9
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte is exactly D9 (reg = 3, rm = 1, mod = 3)
+ byte modRm = Decoder.PeakByte();
+ return modRm == 0xD9;
+ }
+
+ ///
+ /// Decodes a FCOMPP instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fcompp;
+
+ // FCOMPP has no operands
+ instruction.StructuredOperands = [];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FicomInt16Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FicomInt16Handler.cs
new file mode 100644
index 0000000..80ab210
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FicomInt16Handler.cs
@@ -0,0 +1,70 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FICOM int16 instruction (DE /2)
+///
+public class FicomInt16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FicomInt16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FicomInt16Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FICOM int16 is DE /2
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 2
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 2
+ return reg == 2 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FICOM int16 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Ficom;
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FicompInt16Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FicompInt16Handler.cs
new file mode 100644
index 0000000..ae1701c
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FicompInt16Handler.cs
@@ -0,0 +1,70 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FICOMP int16 instruction (DE /3)
+///
+public class FicompInt16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FicompInt16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FicompInt16Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FICOMP int16 is DE /3
+ if (opcode != 0xDE) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 3
+ return reg == 3 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FICOMP int16 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Ficomp;
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FucomHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FucomHandler.cs
new file mode 100644
index 0000000..e5ed053
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FucomHandler.cs
@@ -0,0 +1,87 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FUCOM ST(i) instruction (DD E0-E7)
+///
+public class FucomHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FucomHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FucomHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FUCOM ST(i) is DD E0-E7
+ if (opcode != 0xDD) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 4 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 4
+ return reg == 4 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FUCOM ST(i) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fucom;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operand
+ var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ fpuRegisterOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FucomiHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FucomiHandler.cs
new file mode 100644
index 0000000..bdd29fe
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FucomiHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FUCOMI instruction (DB E8-EF)
+///
+public class FucomiHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FucomiHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FucomiHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FUCOMI is DB E8-EF
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 6 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 6
+ return reg == 6 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FUCOMI instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fucomi;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FucomipHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FucomipHandler.cs
new file mode 100644
index 0000000..04a5c61
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FucomipHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FUCOMIP ST(0), ST(i) instruction (DF E8-EF)
+///
+public class FucomipHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FucomipHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FucomipHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FUCOMIP ST(0), ST(i) is DF E8-EF
+ if (opcode != 0xDF) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 5 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 5
+ return reg == 5 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FUCOMIP ST(0), ST(i) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fucomip;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FucompHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FucompHandler.cs
new file mode 100644
index 0000000..193ee74
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FucompHandler.cs
@@ -0,0 +1,87 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FUCOMP ST(i) instruction (DD E8-EF)
+///
+public class FucompHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FucompHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FucompHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FUCOMP ST(i) is DD E8-EF
+ if (opcode != 0xDD) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 5 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 5
+ return reg == 5 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FUCOMP ST(i) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fucomp;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operand
+ var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ fpuRegisterOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Conditional/FcmovnbHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Conditional/FcmovnbHandler.cs
new file mode 100644
index 0000000..85004fa
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Conditional/FcmovnbHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Conditional;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FCMOVNB instruction (DB C0-C7)
+///
+public class FcmovnbHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FcmovnbHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FcmovnbHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FCMOVNB is DB C0-C7
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 0 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 0
+ return reg == 0 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FCMOVNB instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fcmovnb;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Conditional/FcmovnbeHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Conditional/FcmovnbeHandler.cs
new file mode 100644
index 0000000..18dbf34
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Conditional/FcmovnbeHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Conditional;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FCMOVNBE instruction (DB D0-D7)
+///
+public class FcmovnbeHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FcmovnbeHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FcmovnbeHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FCMOVNBE is DB D0-D7
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 2 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 2
+ return reg == 2 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FCMOVNBE instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fcmovnbe;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Conditional/FcmovneHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Conditional/FcmovneHandler.cs
new file mode 100644
index 0000000..11b29d8
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Conditional/FcmovneHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Conditional;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FCMOVNE instruction (DB C8-CF)
+///
+public class FcmovneHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FcmovneHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FcmovneHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FCMOVNE is DB C8-CF
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 1 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 1
+ return reg == 1 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FCMOVNE instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fcmovne;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Conditional/FcmovnuHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Conditional/FcmovnuHandler.cs
new file mode 100644
index 0000000..ac228e5
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Conditional/FcmovnuHandler.cs
@@ -0,0 +1,89 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Conditional;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FCMOVNU instruction (DB D8-DF)
+///
+public class FcmovnuHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FcmovnuHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FcmovnuHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FCMOVNU is DB D8-DF
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 3 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 3
+ return reg == 3 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FCMOVNU instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fcmovnu;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operands
+ var destOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+ var srcOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destOperand,
+ srcOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Control/FclexHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FclexHandler.cs
new file mode 100644
index 0000000..bf04f46
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FclexHandler.cs
@@ -0,0 +1,63 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Control;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FCLEX instruction (DB E2)
+///
+public class FclexHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FclexHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FclexHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FCLEX is DB E2
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the next byte is E2
+ byte nextByte = Decoder.PeakByte();
+ return nextByte == 0xE2;
+ }
+
+ ///
+ /// Decodes a FCLEX instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the second byte of the opcode
+ byte secondByte = Decoder.ReadByte();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fclex;
+
+ // FCLEX has no operands
+ instruction.StructuredOperands = [];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Control/FfreeHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FfreeHandler.cs
new file mode 100644
index 0000000..d0c6e63
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FfreeHandler.cs
@@ -0,0 +1,87 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Control;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FFREE ST(i) instruction (DD C0-C7)
+///
+public class FfreeHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FfreeHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FfreeHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FFREE ST(i) is DD C0-C7
+ if (opcode != 0xDD) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 0 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 0
+ return reg == 0 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FFREE ST(i) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Ffree;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operand
+ var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ fpuRegisterOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Control/FfreepHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FfreepHandler.cs
new file mode 100644
index 0000000..b7c6288
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FfreepHandler.cs
@@ -0,0 +1,87 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Control;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FFREEP ST(i) instruction (DF C0-C7)
+///
+public class FfreepHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FfreepHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FfreepHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FFREEP ST(i) is DF C0-C7
+ if (opcode != 0xDF) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 0 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 0
+ return reg == 0 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FFREEP ST(i) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Ffreep;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operand
+ var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ fpuRegisterOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Control/FinitHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FinitHandler.cs
new file mode 100644
index 0000000..8200819
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FinitHandler.cs
@@ -0,0 +1,63 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Control;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FINIT instruction (DB E3)
+///
+public class FinitHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FinitHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FinitHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FINIT is DB E3
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the next byte is E3
+ byte nextByte = Decoder.PeakByte();
+ return nextByte == 0xE3;
+ }
+
+ ///
+ /// Decodes a FINIT instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the second byte of the opcode
+ byte secondByte = Decoder.ReadByte();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Finit;
+
+ // FINIT has no operands
+ instruction.StructuredOperands = [];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Control/FnsaveHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FnsaveHandler.cs
new file mode 100644
index 0000000..e2efae5
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FnsaveHandler.cs
@@ -0,0 +1,70 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Control;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FNSAVE instruction (DD /6)
+///
+public class FnsaveHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FnsaveHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FnsaveHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FNSAVE is DD /6
+ if (opcode != 0xDD) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 6
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3)
+ return reg == 6 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FNSAVE instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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
+ instruction.Type = InstructionType.Fnsave;
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ rawOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Control/FnstswMemoryHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FnstswMemoryHandler.cs
new file mode 100644
index 0000000..35990e5
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FnstswMemoryHandler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Control;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FNSTSW memory instruction (DD /7)
+///
+public class FnstswMemoryHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FnstswMemoryHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FnstswMemoryHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FNSTSW is DD /7
+ if (opcode != 0xDD) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 7
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3)
+ return reg == 7 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FNSTSW memory instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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
+ instruction.Type = InstructionType.Fnstsw;
+
+ // Create a 16-bit memory operand for status word
+ Operand memoryOperand;
+
+ if (rawOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand16(directMemory.Address);
+ }
+ else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand16(baseRegMemory.BaseRegister);
+ }
+ else if (rawOperand is DisplacementMemoryOperand dispMemory)
+ {
+ memoryOperand = OperandFactory.CreateDisplacementMemoryOperand16(dispMemory.BaseRegister, dispMemory.Displacement);
+ }
+ else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
+ {
+ memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand16(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement);
+ }
+ else
+ {
+ memoryOperand = rawOperand;
+ }
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Control/FrstorHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FrstorHandler.cs
new file mode 100644
index 0000000..1d40fc1
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FrstorHandler.cs
@@ -0,0 +1,70 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Control;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FRSTOR instruction (DD /4)
+///
+public class FrstorHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FrstorHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FrstorHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FRSTOR is DD /4
+ if (opcode != 0xDD) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 4
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3)
+ return reg == 4 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FRSTOR instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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
+ instruction.Type = InstructionType.Frstor;
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ rawOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Int32OperationHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Int32OperationHandler.cs
deleted file mode 100644
index 6539683..0000000
--- a/X86Disassembler/X86/Handlers/FloatingPoint/Int32OperationHandler.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-using X86Disassembler.X86.Operands;
-
-namespace X86Disassembler.X86.Handlers.FloatingPoint;
-
-///
-/// Handler for floating-point operations on int32 (DA opcode)
-///
-public class Int32OperationHandler : InstructionHandler
-{
- // Memory operand instruction types for DA opcode - operations on int32
- private static readonly InstructionType[] MemoryInstructionTypes =
- [
- InstructionType.Fiadd, // fiadd dword ptr [r/m]
- InstructionType.Fimul, // fimul dword ptr [r/m]
- InstructionType.Ficom, // ficom dword ptr [r/m]
- InstructionType.Ficomp, // ficomp dword ptr [r/m]
- InstructionType.Fisub, // fisub dword ptr [r/m]
- InstructionType.Fisubr, // fisubr dword ptr [r/m]
- InstructionType.Fidiv, // fidiv dword ptr [r/m]
- InstructionType.Fidivr // fidivr dword ptr [r/m]
- ];
-
- // Register-register operations mapping (mod=3)
- private static readonly Dictionary<(RegisterIndex Reg, RegisterIndex Rm), (InstructionType Type, FpuRegisterIndex DestIndex, FpuRegisterIndex SrcIndex)> RegisterOperations = new()
- {
- // FCMOVB st(0), st(i)
- { (RegisterIndex.A, RegisterIndex.A), (InstructionType.Fcmovb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
- { (RegisterIndex.A, RegisterIndex.C), (InstructionType.Fcmovb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST1) },
- { (RegisterIndex.A, RegisterIndex.D), (InstructionType.Fcmovb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST2) },
- { (RegisterIndex.A, RegisterIndex.B), (InstructionType.Fcmovb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST3) },
- { (RegisterIndex.A, RegisterIndex.Sp), (InstructionType.Fcmovb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST4) },
- { (RegisterIndex.A, RegisterIndex.Bp), (InstructionType.Fcmovb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST5) },
- { (RegisterIndex.A, RegisterIndex.Si), (InstructionType.Fcmovb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST6) },
- { (RegisterIndex.A, RegisterIndex.Di), (InstructionType.Fcmovb, FpuRegisterIndex.ST0, FpuRegisterIndex.ST7) },
-
- // FCMOVE st(0), st(i)
- { (RegisterIndex.B, RegisterIndex.A), (InstructionType.Fcmove, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
- { (RegisterIndex.B, RegisterIndex.C), (InstructionType.Fcmove, FpuRegisterIndex.ST0, FpuRegisterIndex.ST1) },
- { (RegisterIndex.B, RegisterIndex.D), (InstructionType.Fcmove, FpuRegisterIndex.ST0, FpuRegisterIndex.ST2) },
- { (RegisterIndex.B, RegisterIndex.B), (InstructionType.Fcmove, FpuRegisterIndex.ST0, FpuRegisterIndex.ST3) },
- { (RegisterIndex.B, RegisterIndex.Sp), (InstructionType.Fcmove, FpuRegisterIndex.ST0, FpuRegisterIndex.ST4) },
- { (RegisterIndex.B, RegisterIndex.Bp), (InstructionType.Fcmove, FpuRegisterIndex.ST0, FpuRegisterIndex.ST5) },
- { (RegisterIndex.B, RegisterIndex.Si), (InstructionType.Fcmove, FpuRegisterIndex.ST0, FpuRegisterIndex.ST6) },
- { (RegisterIndex.B, RegisterIndex.Di), (InstructionType.Fcmove, FpuRegisterIndex.ST0, FpuRegisterIndex.ST7) },
-
- // FCMOVBE st(0), st(i)
- { (RegisterIndex.C, RegisterIndex.A), (InstructionType.Fcmovbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
- { (RegisterIndex.C, RegisterIndex.C), (InstructionType.Fcmovbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST1) },
- { (RegisterIndex.C, RegisterIndex.D), (InstructionType.Fcmovbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST2) },
- { (RegisterIndex.C, RegisterIndex.B), (InstructionType.Fcmovbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST3) },
- { (RegisterIndex.C, RegisterIndex.Sp), (InstructionType.Fcmovbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST4) },
- { (RegisterIndex.C, RegisterIndex.Bp), (InstructionType.Fcmovbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST5) },
- { (RegisterIndex.C, RegisterIndex.Si), (InstructionType.Fcmovbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST6) },
- { (RegisterIndex.C, RegisterIndex.Di), (InstructionType.Fcmovbe, FpuRegisterIndex.ST0, FpuRegisterIndex.ST7) },
-
- // FCMOVU st(0), st(i)
- { (RegisterIndex.D, RegisterIndex.A), (InstructionType.Fcmovu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) },
- { (RegisterIndex.D, RegisterIndex.C), (InstructionType.Fcmovu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST1) },
- { (RegisterIndex.D, RegisterIndex.D), (InstructionType.Fcmovu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST2) },
- { (RegisterIndex.D, RegisterIndex.B), (InstructionType.Fcmovu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST3) },
- { (RegisterIndex.D, RegisterIndex.Sp), (InstructionType.Fcmovu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST4) },
- { (RegisterIndex.D, RegisterIndex.Bp), (InstructionType.Fcmovu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST5) },
- { (RegisterIndex.D, RegisterIndex.Si), (InstructionType.Fcmovu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST6) },
- { (RegisterIndex.D, RegisterIndex.Di), (InstructionType.Fcmovu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST7) },
-
- // Special case
- { (RegisterIndex.Di, RegisterIndex.B), (InstructionType.Fcmovu, FpuRegisterIndex.ST0, FpuRegisterIndex.ST0) }
- };
-
- ///
- /// Initializes a new instance of the Int32OperationHandler class
- ///
- /// The instruction decoder that owns this handler
- public Int32OperationHandler(InstructionDecoder decoder)
- : base(decoder)
- {
- }
-
- ///
- /// Checks if this handler can decode the given opcode
- ///
- /// The opcode to check
- /// True if this handler can decode the opcode
- public override bool CanHandle(byte opcode)
- {
- return opcode == 0xDA;
- }
-
- ///
- /// Decodes a floating-point instruction for int32 operations
- ///
- /// The opcode of the instruction
- /// The instruction object to populate
- /// True if the instruction was successfully decoded
- public override bool Decode(byte opcode, Instruction instruction)
- {
- if (!Decoder.CanReadByte())
- {
- return false;
- }
-
- // Read the ModR/M byte
- var (mod, reg, rm, memoryOperand) = 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];
-
- // 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);
- var srcOperand = OperandFactory.CreateFPURegisterOperand(operation.SrcIndex);
-
- // Set the structured operands
- instruction.StructuredOperands =
- [
- destOperand,
- srcOperand
- ];
- }
- else
- {
- // Unknown instruction
- instruction.Type = InstructionType.Unknown;
- instruction.StructuredOperands = [];
- }
- }
-
- return true;
- }
-}
\ No newline at end of file
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FbldHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FbldHandler.cs
new file mode 100644
index 0000000..a25ad22
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FbldHandler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FBLD packed BCD instruction (DF /4)
+///
+public class FbldHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FbldHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FbldHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FBLD is DF /4
+ if (opcode != 0xDF) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 4
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 4
+ return reg == 4 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FBLD packed BCD instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fbld;
+
+ // Create an 80-bit memory operand for packed BCD
+ Operand memoryOperand;
+
+ if (rawMemoryOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 80);
+ }
+ else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 80);
+ }
+ else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
+ {
+ memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 80);
+ }
+ else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
+ {
+ memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 80);
+ }
+ else
+ {
+ memoryOperand = rawMemoryOperand;
+ }
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FbstpHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FbstpHandler.cs
new file mode 100644
index 0000000..774d787
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FbstpHandler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FBSTP packed BCD instruction (DF /6)
+///
+public class FbstpHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FbstpHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FbstpHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FBSTP is DF /6
+ if (opcode != 0xDF) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 6
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 6
+ return reg == 6 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FBSTP packed BCD instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fbstp;
+
+ // Create an 80-bit memory operand for packed BCD
+ Operand memoryOperand;
+
+ if (rawMemoryOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 80);
+ }
+ else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 80);
+ }
+ else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
+ {
+ memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 80);
+ }
+ else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
+ {
+ memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 80);
+ }
+ else
+ {
+ memoryOperand = rawMemoryOperand;
+ }
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FildInt16Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FildInt16Handler.cs
new file mode 100644
index 0000000..fb166c3
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FildInt16Handler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FILD int16 instruction (DF /0)
+///
+public class FildInt16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FildInt16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FildInt16Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FILD int16 is DF /0
+ if (opcode != 0xDF) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 0
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 0
+ return reg == 0 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FILD int16 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fild;
+
+ // Create a 16-bit memory operand
+ Operand memoryOperand;
+
+ if (rawMemoryOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 16);
+ }
+ else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 16);
+ }
+ else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
+ {
+ memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 16);
+ }
+ else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
+ {
+ memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 16);
+ }
+ else
+ {
+ memoryOperand = rawMemoryOperand;
+ }
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FildInt32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FildInt32Handler.cs
new file mode 100644
index 0000000..b263c45
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FildInt32Handler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FILD int32 instruction (DB /0)
+///
+public class FildInt32Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FildInt32Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FildInt32Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FILD is DB /0
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 0
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3)
+ return reg == 0 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FILD int32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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
+ instruction.Type = InstructionType.Fild;
+
+ // Create a 32-bit memory operand for integer operations
+ Operand memoryOperand;
+
+ if (rawOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 32);
+ }
+ else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 32);
+ }
+ else if (rawOperand is DisplacementMemoryOperand dispMemory)
+ {
+ memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 32);
+ }
+ else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
+ {
+ memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 32);
+ }
+ else
+ {
+ memoryOperand = rawOperand;
+ }
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FildInt64Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FildInt64Handler.cs
new file mode 100644
index 0000000..1d14d08
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FildInt64Handler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FILD int64 instruction (DF /5)
+///
+public class FildInt64Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FildInt64Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FildInt64Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FILD int64 is DF /5
+ if (opcode != 0xDF) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 5
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 5
+ return reg == 5 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FILD int64 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fild;
+
+ // Create a 64-bit memory operand
+ Operand memoryOperand;
+
+ if (rawMemoryOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 64);
+ }
+ else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.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;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistInt16Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistInt16Handler.cs
new file mode 100644
index 0000000..84dae5d
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistInt16Handler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FIST int16 instruction (DF /2)
+///
+public class FistInt16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FistInt16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FistInt16Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FIST int16 is DF /2
+ if (opcode != 0xDF) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 2
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 2
+ return reg == 2 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FIST int16 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fist;
+
+ // Create a 16-bit memory operand
+ Operand memoryOperand;
+
+ if (rawMemoryOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 16);
+ }
+ else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 16);
+ }
+ else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
+ {
+ memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 16);
+ }
+ else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
+ {
+ memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 16);
+ }
+ else
+ {
+ memoryOperand = rawMemoryOperand;
+ }
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistInt32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistInt32Handler.cs
new file mode 100644
index 0000000..0a7bfab
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistInt32Handler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FIST int32 instruction (DB /2)
+///
+public class FistInt32Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FistInt32Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FistInt32Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FIST is DB /2
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 2
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3)
+ return reg == 2 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FIST int32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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
+ instruction.Type = InstructionType.Fist;
+
+ // Create a 32-bit memory operand for integer operations
+ Operand memoryOperand;
+
+ if (rawOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 32);
+ }
+ else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 32);
+ }
+ else if (rawOperand is DisplacementMemoryOperand dispMemory)
+ {
+ memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 32);
+ }
+ else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
+ {
+ memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 32);
+ }
+ else
+ {
+ memoryOperand = rawOperand;
+ }
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistpInt16Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistpInt16Handler.cs
new file mode 100644
index 0000000..8e3a659
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistpInt16Handler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FISTP int16 instruction (DF /3)
+///
+public class FistpInt16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FistpInt16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FistpInt16Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FISTP int16 is DF /3
+ if (opcode != 0xDF) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 3
+ return reg == 3 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FISTP int16 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fistp;
+
+ // Create a 16-bit memory operand
+ Operand memoryOperand;
+
+ if (rawMemoryOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 16);
+ }
+ else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 16);
+ }
+ else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
+ {
+ memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 16);
+ }
+ else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
+ {
+ memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 16);
+ }
+ else
+ {
+ memoryOperand = rawMemoryOperand;
+ }
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistpInt32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistpInt32Handler.cs
new file mode 100644
index 0000000..030d7a2
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistpInt32Handler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FISTP int32 instruction (DB /3)
+///
+public class FistpInt32Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FistpInt32Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FistpInt32Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FISTP is DB /3
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3)
+ return reg == 3 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FISTP int32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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
+ instruction.Type = InstructionType.Fistp;
+
+ // Create a 32-bit memory operand for integer operations
+ Operand memoryOperand;
+
+ if (rawOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 32);
+ }
+ else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 32);
+ }
+ else if (rawOperand is DisplacementMemoryOperand dispMemory)
+ {
+ memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 32);
+ }
+ else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
+ {
+ memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 32);
+ }
+ else
+ {
+ memoryOperand = rawOperand;
+ }
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistpInt64Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistpInt64Handler.cs
new file mode 100644
index 0000000..8643228
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FistpInt64Handler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FISTP int64 instruction (DF /7)
+///
+public class FistpInt64Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FistpInt64Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FistpInt64Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FISTP int64 is DF /7
+ if (opcode != 0xDF) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 7
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 7
+ return reg == 7 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FISTP int64 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fistp;
+
+ // Create a 64-bit memory operand
+ Operand memoryOperand;
+
+ if (rawMemoryOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 64);
+ }
+ else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.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;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FisttpInt16Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FisttpInt16Handler.cs
new file mode 100644
index 0000000..2226601
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FisttpInt16Handler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FISTTP int16 instruction (DF /1)
+///
+public class FisttpInt16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FisttpInt16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FisttpInt16Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FISTTP int16 is DF /1
+ if (opcode != 0xDF) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 1
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3) with reg = 1
+ return reg == 1 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FISTTP int16 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fisttp;
+
+ // Create a 16-bit memory operand
+ Operand memoryOperand;
+
+ if (rawMemoryOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 16);
+ }
+ else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 16);
+ }
+ else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
+ {
+ memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 16);
+ }
+ else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
+ {
+ memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 16);
+ }
+ else
+ {
+ memoryOperand = rawMemoryOperand;
+ }
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FldExtendedHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FldExtendedHandler.cs
new file mode 100644
index 0000000..ad0b422
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FldExtendedHandler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FLD extended-precision instruction (DB /5)
+///
+public class FldExtendedHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FldExtendedHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FldExtendedHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FLD extended-precision is DB /5
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 5
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3)
+ return reg == 5 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FLD extended-precision instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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
+ instruction.Type = InstructionType.Fld;
+
+ // Create an 80-bit memory operand for extended precision operations
+ Operand memoryOperand;
+
+ if (rawOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 80);
+ }
+ else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 80);
+ }
+ else if (rawOperand is DisplacementMemoryOperand dispMemory)
+ {
+ memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 80);
+ }
+ else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
+ {
+ memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 80);
+ }
+ else
+ {
+ memoryOperand = rawOperand;
+ }
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstRegisterHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstRegisterHandler.cs
new file mode 100644
index 0000000..ec5708e
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstRegisterHandler.cs
@@ -0,0 +1,87 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FST ST(i) instruction (DD D0-D7)
+///
+public class FstRegisterHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FstRegisterHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FstRegisterHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FST ST(i) is DD D0-D7
+ if (opcode != 0xDD) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 2 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 2
+ return reg == 2 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FST ST(i) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fst;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operand
+ var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ fpuRegisterOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpDfHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpDfHandler.cs
new file mode 100644
index 0000000..b933da3
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpDfHandler.cs
@@ -0,0 +1,70 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FSTP instruction with DF opcode (DF D0-D8)
+///
+public class FstpDfHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FstpDfHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FstpDfHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FSTP with DF opcode is DF D0 or DF D8
+ if (opcode != 0xDF) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte is D0 (reg = 2, rm = 0, mod = 3) or D8 (reg = 3, rm = 0, mod = 3)
+ byte modRm = Decoder.PeakByte();
+ return modRm == 0xD0 || modRm == 0xD8;
+ }
+
+ ///
+ /// Decodes a FSTP instruction with DF opcode
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fstp;
+
+ // Create the FPU register operand
+ // For both D0 and D8, the operand is ST1
+ var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST1);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ fpuRegisterOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpExtendedHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpExtendedHandler.cs
new file mode 100644
index 0000000..3e895c2
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpExtendedHandler.cs
@@ -0,0 +1,94 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FSTP extended-precision instruction (DB /7)
+///
+public class FstpExtendedHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FstpExtendedHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FstpExtendedHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FSTP extended-precision is DB /7
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 7
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle memory operands (mod != 3)
+ return reg == 7 && mod != 3;
+ }
+
+ ///
+ /// Decodes a FSTP extended-precision instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ 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
+ instruction.Type = InstructionType.Fstp;
+
+ // Create an 80-bit memory operand for extended precision operations
+ Operand memoryOperand;
+
+ if (rawOperand is DirectMemoryOperand directMemory)
+ {
+ memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 80);
+ }
+ else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
+ {
+ memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 80);
+ }
+ else if (rawOperand is DisplacementMemoryOperand dispMemory)
+ {
+ memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 80);
+ }
+ else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
+ {
+ memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 80);
+ }
+ else
+ {
+ memoryOperand = rawOperand;
+ }
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ memoryOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpRegisterHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpRegisterHandler.cs
new file mode 100644
index 0000000..3f8e958
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpRegisterHandler.cs
@@ -0,0 +1,87 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FSTP ST(i) instruction (DD D8-DF)
+///
+public class FstpRegisterHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FstpRegisterHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FstpRegisterHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FSTP ST(i) is DD D8-DF
+ if (opcode != 0xDD) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte has reg field = 3 and mod = 3
+ byte modRm = Decoder.PeakByte();
+ byte reg = (byte)((modRm >> 3) & 0x7);
+ byte mod = (byte)((modRm >> 6) & 0x3);
+
+ // Only handle register operands (mod = 3) with reg = 3
+ return reg == 3 && mod == 3;
+ }
+
+ ///
+ /// Decodes a FSTP ST(i) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fstp;
+
+ // Map rm field to FPU register index
+ FpuRegisterIndex stIndex = rm switch
+ {
+ RegisterIndex.A => FpuRegisterIndex.ST0,
+ RegisterIndex.C => FpuRegisterIndex.ST1,
+ RegisterIndex.D => FpuRegisterIndex.ST2,
+ RegisterIndex.B => FpuRegisterIndex.ST3,
+ RegisterIndex.Sp => FpuRegisterIndex.ST4,
+ RegisterIndex.Bp => FpuRegisterIndex.ST5,
+ RegisterIndex.Si => FpuRegisterIndex.ST6,
+ RegisterIndex.Di => FpuRegisterIndex.ST7,
+ _ => FpuRegisterIndex.ST0 // Default case, should not happen
+ };
+
+ // Create the FPU register operand
+ var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ fpuRegisterOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FxchDfHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FxchDfHandler.cs
new file mode 100644
index 0000000..f7ec688
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FxchDfHandler.cs
@@ -0,0 +1,69 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FXCH instruction with DF opcode (DF C8)
+///
+public class FxchDfHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FxchDfHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FxchDfHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FXCH with DF opcode is DF C8
+ if (opcode != 0xDF) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the ModR/M byte is exactly C8 (reg = 1, rm = 0, mod = 3)
+ byte modRm = Decoder.PeakByte();
+ return modRm == 0xC8;
+ }
+
+ ///
+ /// Decodes a FXCH instruction with DF opcode
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fxch;
+
+ // Create the FPU register operand
+ var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ fpuRegisterOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStoreControlHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStoreControlHandler.cs
deleted file mode 100644
index 8669f91..0000000
--- a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStoreControlHandler.cs
+++ /dev/null
@@ -1,212 +0,0 @@
-using X86Disassembler.X86.Operands;
-
-namespace X86Disassembler.X86.Handlers.FloatingPoint;
-
-///
-/// Handler for floating-point load, store, and control operations (D9 opcode)
-///
-public class LoadStoreControlHandler : InstructionHandler
-{
- // Memory operand instruction types for D9 opcode - load, store, and control operations
- private static readonly InstructionType[] MemoryInstructionTypes =
- [
- InstructionType.Fld, // 0 - fld dword ptr [r/m]
- InstructionType.Unknown, // 1 - (reserved)
- InstructionType.Fst, // 2 - fst dword ptr [r/m]
- InstructionType.Fstp, // 3 - fstp dword ptr [r/m]
- InstructionType.Fldenv, // 4 - fldenv [r/m]
- InstructionType.Fldcw, // 5 - fldcw [r/m]
- InstructionType.Fnstenv, // 6 - fnstenv [r/m]
- InstructionType.Fnstcw // 7 - fnstcw [r/m]
- ];
-
- // Register-register operations mapping (mod=3)
- private static readonly Dictionary<(RegisterIndex Reg, RegisterIndex Rm), (InstructionType Type, FpuRegisterIndex? OperandIndex)> RegisterOperations = new()
- {
- // FLD ST(i)
- { (RegisterIndex.A, RegisterIndex.A), (InstructionType.Fld, FpuRegisterIndex.ST0) },
- { (RegisterIndex.A, RegisterIndex.C), (InstructionType.Fld, FpuRegisterIndex.ST1) },
- { (RegisterIndex.A, RegisterIndex.D), (InstructionType.Fld, FpuRegisterIndex.ST2) },
- { (RegisterIndex.A, RegisterIndex.B), (InstructionType.Fld, FpuRegisterIndex.ST3) },
- { (RegisterIndex.A, RegisterIndex.Sp), (InstructionType.Fld, FpuRegisterIndex.ST4) },
- { (RegisterIndex.A, RegisterIndex.Bp), (InstructionType.Fld, FpuRegisterIndex.ST5) },
- { (RegisterIndex.A, RegisterIndex.Si), (InstructionType.Fld, FpuRegisterIndex.ST6) },
- { (RegisterIndex.A, RegisterIndex.Di), (InstructionType.Fld, FpuRegisterIndex.ST7) },
-
- // FXCH ST(i)
- { (RegisterIndex.B, RegisterIndex.A), (InstructionType.Fxch, FpuRegisterIndex.ST0) },
- { (RegisterIndex.B, RegisterIndex.C), (InstructionType.Fxch, FpuRegisterIndex.ST1) },
- { (RegisterIndex.B, RegisterIndex.D), (InstructionType.Fxch, FpuRegisterIndex.ST2) },
- { (RegisterIndex.B, RegisterIndex.B), (InstructionType.Fxch, FpuRegisterIndex.ST3) },
- { (RegisterIndex.B, RegisterIndex.Sp), (InstructionType.Fxch, FpuRegisterIndex.ST4) },
- { (RegisterIndex.B, RegisterIndex.Bp), (InstructionType.Fxch, FpuRegisterIndex.ST5) },
- { (RegisterIndex.B, RegisterIndex.Si), (InstructionType.Fxch, FpuRegisterIndex.ST6) },
- { (RegisterIndex.B, RegisterIndex.Di), (InstructionType.Fxch, FpuRegisterIndex.ST7) },
-
- // D9E0-D9EF special instructions (reg=6)
- { (RegisterIndex.Si, RegisterIndex.A), (InstructionType.Fchs, null) },
- { (RegisterIndex.Si, RegisterIndex.B), (InstructionType.Fabs, null) },
- { (RegisterIndex.Si, RegisterIndex.Si), (InstructionType.Ftst, null) },
- { (RegisterIndex.Si, RegisterIndex.Di), (InstructionType.Fxam, null) },
-
- // D9F0-D9FF special instructions (reg=7)
- { (RegisterIndex.Di, RegisterIndex.A), (InstructionType.F2xm1, null) },
- { (RegisterIndex.Di, RegisterIndex.B), (InstructionType.Fyl2x, null) },
- { (RegisterIndex.Di, RegisterIndex.C), (InstructionType.Fptan, null) },
- { (RegisterIndex.Di, RegisterIndex.D), (InstructionType.Fpatan, null) },
- { (RegisterIndex.Di, RegisterIndex.Si), (InstructionType.Fxtract, null) },
- { (RegisterIndex.Di, RegisterIndex.Di), (InstructionType.Fprem1, null) },
- { (RegisterIndex.Di, RegisterIndex.Sp), (InstructionType.Fdecstp, null) },
- { (RegisterIndex.Di, RegisterIndex.Bp), (InstructionType.Fincstp, null) },
-
- // D9D0-D9DF special instructions (reg=5)
- { (RegisterIndex.Sp, RegisterIndex.A), (InstructionType.Fprem, null) },
- { (RegisterIndex.Sp, RegisterIndex.B), (InstructionType.Fyl2xp1, null) },
- { (RegisterIndex.Sp, RegisterIndex.C), (InstructionType.Fsqrt, null) },
- { (RegisterIndex.Sp, RegisterIndex.D), (InstructionType.Fsincos, null) },
- { (RegisterIndex.Sp, RegisterIndex.Si), (InstructionType.Frndint, null) },
- { (RegisterIndex.Sp, RegisterIndex.Di), (InstructionType.Fscale, null) },
- { (RegisterIndex.Sp, RegisterIndex.Sp), (InstructionType.Fsin, null) },
- { (RegisterIndex.Sp, RegisterIndex.Bp), (InstructionType.Fcos, null) },
-
- // D9C8-D9CF special instructions (reg=4)
- { (RegisterIndex.Bp, RegisterIndex.A), (InstructionType.Fnop, null) },
- { (RegisterIndex.Bp, RegisterIndex.C), (InstructionType.Fwait, null) }
- };
-
- ///
- /// Initializes a new instance of the LoadStoreControlHandler class
- ///
- /// The instruction decoder that owns this handler
- public LoadStoreControlHandler(InstructionDecoder decoder)
- : base(decoder)
- {
- }
-
- ///
- /// Checks if this handler can decode the given opcode
- ///
- /// The opcode to check
- /// True if this handler can decode the opcode
- public override bool CanHandle(byte opcode)
- {
- return opcode == 0xD9;
- }
-
- ///
- /// Decodes a floating-point instruction for load, store, and control operations
- ///
- /// The opcode of the instruction
- /// The instruction object to populate
- /// True if the instruction was successfully decoded
- 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;
-
- if (reg == RegisterIndex.A || reg == RegisterIndex.C || reg == RegisterIndex.D) // fld, fst, fstp
- {
- // Create a 32-bit memory operand for floating point operations
- if (rawMemoryOperand is DirectMemoryOperand directMemory)
- {
- memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 32);
- }
- else if (rawMemoryOperand is BaseRegisterMemoryOperand baseRegMemory)
- {
- memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 32);
- }
- else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
- {
- memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 32);
- }
- else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
- {
- memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 32);
- }
- else
- {
- memoryOperand = rawMemoryOperand;
- }
- }
- else if (reg == RegisterIndex.Di || reg == RegisterIndex.Bp) // fldcw, fnstcw
- {
- // Create a 16-bit memory operand for control word operations
- if (rawMemoryOperand is DirectMemoryOperand directMemory)
- {
- memoryOperand = OperandFactory.CreateDirectMemoryOperand16(directMemory.Address);
- }
- else if (rawMemoryOperand is BaseRegisterMemoryOperand baseRegMemory)
- {
- memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand16(baseRegMemory.BaseRegister);
- }
- else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
- {
- memoryOperand = OperandFactory.CreateDisplacementMemoryOperand16(dispMemory.BaseRegister, dispMemory.Displacement);
- }
- else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
- {
- memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand16(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement);
- }
- else
- {
- memoryOperand = rawMemoryOperand;
- }
- }
- 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;
-
- // Set the structured operands
- if (operation.OperandIndex.HasValue)
- {
- var operand = OperandFactory.CreateFPURegisterOperand(operation.OperandIndex.Value);
- instruction.StructuredOperands =
- [
- operand
- ];
- }
- else
- {
- // No operands for instructions like fchs, fabs, etc.
- instruction.StructuredOperands = [];
- }
- }
- else
- {
- // Unknown instruction
- instruction.Type = InstructionType.Unknown;
- instruction.StructuredOperands = [];
- }
- }
-
- return true;
- }
-}
diff --git a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
index 1fbe786..3147715 100644
--- a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
+++ b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
@@ -437,12 +437,85 @@ public class InstructionHandlerFactory
// Other floating point handlers
_handlers.Add(new FloatingPoint.Control.FnstswHandler(_decoder)); // FNSTSW AX (DF E0)
- // Keep the existing handlers for operations not yet migrated to specialized handlers
- _handlers.Add(new LoadStoreInt32Handler(_decoder)); // Load and store 32-bit values
- _handlers.Add(new Float64OperationHandler(_decoder)); // Remaining float64 operations
- _handlers.Add(new LoadStoreFloat64Handler(_decoder)); // Load and store 64-bit values
- _handlers.Add(new Int16OperationHandler(_decoder)); // Integer operations on 16-bit values
- _handlers.Add(new LoadStoreInt16Handler(_decoder)); // Load and store 16-bit values
+ // DB opcode handlers (int32 operations and extended precision)
+ _handlers.Add(new FloatingPoint.LoadStore.FildInt32Handler(_decoder)); // FILD int32 (DB /0)
+ _handlers.Add(new FloatingPoint.LoadStore.FistInt32Handler(_decoder)); // FIST int32 (DB /2)
+ _handlers.Add(new FloatingPoint.LoadStore.FistpInt32Handler(_decoder)); // FISTP int32 (DB /3)
+ _handlers.Add(new FloatingPoint.LoadStore.FldExtendedHandler(_decoder)); // FLD extended-precision (DB /5)
+ _handlers.Add(new FloatingPoint.LoadStore.FstpExtendedHandler(_decoder)); // FSTP extended-precision (DB /7)
+
+ // DB opcode handlers (conditional move instructions)
+ _handlers.Add(new FloatingPoint.Conditional.FcmovnbHandler(_decoder)); // FCMOVNB (DB C0-C7)
+ _handlers.Add(new FloatingPoint.Conditional.FcmovneHandler(_decoder)); // FCMOVNE (DB C8-CF)
+ _handlers.Add(new FloatingPoint.Conditional.FcmovnbeHandler(_decoder)); // FCMOVNBE (DB D0-D7)
+ _handlers.Add(new FloatingPoint.Conditional.FcmovnuHandler(_decoder)); // FCMOVNU (DB D8-DF)
+
+ // DB opcode handlers (control instructions)
+ _handlers.Add(new FloatingPoint.Control.FclexHandler(_decoder)); // FCLEX (DB E2)
+ _handlers.Add(new FloatingPoint.Control.FinitHandler(_decoder)); // FINIT (DB E3)
+
+ // DB opcode handlers (comparison instructions)
+ _handlers.Add(new FloatingPoint.Comparison.FucomiHandler(_decoder)); // FUCOMI (DB E8-EF)
+ _handlers.Add(new FloatingPoint.Comparison.FcomiHandler(_decoder)); // FCOMI (DB F0-F7)
+
+ // DC opcode handlers (register-register operations)
+ _handlers.Add(new FloatingPoint.Arithmetic.FaddRegisterHandler(_decoder)); // FADD ST(i), ST(0) (DC C0-C7)
+ _handlers.Add(new FloatingPoint.Arithmetic.FmulRegisterHandler(_decoder)); // FMUL ST(i), ST(0) (DC C8-CF)
+ _handlers.Add(new FloatingPoint.Comparison.FcomRegisterHandler(_decoder)); // FCOM ST(i), ST(0) (DC D0-D7)
+ _handlers.Add(new FloatingPoint.Comparison.FcompRegisterHandler(_decoder)); // FCOMP ST(i), ST(0) (DC D8-DF)
+ _handlers.Add(new FloatingPoint.Arithmetic.FsubRegisterHandler(_decoder)); // FSUB ST(i), ST(0) (DC E0-E7)
+ _handlers.Add(new FloatingPoint.Arithmetic.FsubrRegisterHandler(_decoder)); // FSUBR ST(i), ST(0) (DC E8-EF)
+ _handlers.Add(new FloatingPoint.Arithmetic.FdivRegisterHandler(_decoder)); // FDIV ST(i), ST(0) (DC F0-F7)
+ _handlers.Add(new FloatingPoint.Arithmetic.FdivrRegisterHandler(_decoder)); // FDIVR ST(i), ST(0) (DC F8-FF)
+
+ // DD opcode handlers (register operations)
+ _handlers.Add(new FloatingPoint.Control.FfreeHandler(_decoder)); // FFREE ST(i) (DD C0-C7)
+ _handlers.Add(new FloatingPoint.LoadStore.FstRegisterHandler(_decoder)); // FST ST(i) (DD D0-D7)
+ _handlers.Add(new FloatingPoint.LoadStore.FstpRegisterHandler(_decoder)); // FSTP ST(i) (DD D8-DF)
+ _handlers.Add(new FloatingPoint.Comparison.FucomHandler(_decoder)); // FUCOM ST(i) (DD E0-E7)
+ _handlers.Add(new FloatingPoint.Comparison.FucompHandler(_decoder)); // FUCOMP ST(i) (DD E8-EF)
+
+ // DD opcode handlers (memory operations)
+ _handlers.Add(new FloatingPoint.Control.FrstorHandler(_decoder)); // FRSTOR (DD /4)
+ _handlers.Add(new FloatingPoint.Control.FnsaveHandler(_decoder)); // FNSAVE (DD /6)
+ _handlers.Add(new FloatingPoint.Control.FnstswMemoryHandler(_decoder)); // FNSTSW memory (DD /7)
+
+ // DE opcode handlers (memory operations)
+ _handlers.Add(new FloatingPoint.Arithmetic.FiaddInt16Handler(_decoder)); // FIADD int16 (DE /0)
+ _handlers.Add(new FloatingPoint.Arithmetic.FimulInt16Handler(_decoder)); // FIMUL int16 (DE /1)
+ _handlers.Add(new FloatingPoint.Comparison.FicomInt16Handler(_decoder)); // FICOM int16 (DE /2)
+ _handlers.Add(new FloatingPoint.Comparison.FicompInt16Handler(_decoder)); // FICOMP int16 (DE /3)
+ _handlers.Add(new FloatingPoint.Arithmetic.FisubInt16Handler(_decoder)); // FISUB int16 (DE /4)
+ _handlers.Add(new FloatingPoint.Arithmetic.FisubrInt16Handler(_decoder)); // FISUBR int16 (DE /5)
+ _handlers.Add(new FloatingPoint.Arithmetic.FidivInt16Handler(_decoder)); // FIDIV int16 (DE /6)
+ _handlers.Add(new FloatingPoint.Arithmetic.FidivrInt16Handler(_decoder)); // FIDIVR int16 (DE /7)
+
+ // DE opcode handlers (register operations)
+ _handlers.Add(new FloatingPoint.Arithmetic.FaddpHandler(_decoder)); // FADDP ST(i), ST(0) (DE C0-C7)
+ _handlers.Add(new FloatingPoint.Arithmetic.FmulpHandler(_decoder)); // FMULP ST(i), ST(0) (DE C8-CF)
+ _handlers.Add(new FloatingPoint.Comparison.FcompStHandler(_decoder)); // FCOMP ST(0) (DE D3)
+ _handlers.Add(new FloatingPoint.Comparison.FcomppHandler(_decoder)); // FCOMPP (DE D9)
+ _handlers.Add(new FloatingPoint.Arithmetic.FsubpHandler(_decoder)); // FSUBP ST(i), ST(0) (DE E0-E7)
+ _handlers.Add(new FloatingPoint.Arithmetic.FsubrpHandler(_decoder)); // FSUBRP ST(i), ST(0) (DE E8-EF)
+ _handlers.Add(new FloatingPoint.Arithmetic.FdivpHandler(_decoder)); // FDIVP ST(i), ST(0) (DE F0-F7)
+ _handlers.Add(new FloatingPoint.Arithmetic.FdivrpHandler(_decoder)); // FDIVRP ST(i), ST(0) (DE F8-FF)
+
+ // DF opcode handlers (memory operations)
+ _handlers.Add(new FloatingPoint.LoadStore.FildInt16Handler(_decoder)); // FILD int16 (DF /0)
+ _handlers.Add(new FloatingPoint.LoadStore.FisttpInt16Handler(_decoder)); // FISTTP int16 (DF /1)
+ _handlers.Add(new FloatingPoint.LoadStore.FistInt16Handler(_decoder)); // FIST int16 (DF /2)
+ _handlers.Add(new FloatingPoint.LoadStore.FistpInt16Handler(_decoder)); // FISTP int16 (DF /3)
+ _handlers.Add(new FloatingPoint.LoadStore.FbldHandler(_decoder)); // FBLD packed BCD (DF /4)
+ _handlers.Add(new FloatingPoint.LoadStore.FildInt64Handler(_decoder)); // FILD int64 (DF /5)
+ _handlers.Add(new FloatingPoint.LoadStore.FbstpHandler(_decoder)); // FBSTP packed BCD (DF /6)
+ _handlers.Add(new FloatingPoint.LoadStore.FistpInt64Handler(_decoder)); // FISTP int64 (DF /7)
+
+ // DF opcode handlers (register operations)
+ _handlers.Add(new FloatingPoint.Control.FfreepHandler(_decoder)); // FFREEP ST(i) (DF C0-C7)
+ _handlers.Add(new FloatingPoint.LoadStore.FxchDfHandler(_decoder)); // FXCH (DF C8)
+ _handlers.Add(new FloatingPoint.LoadStore.FstpDfHandler(_decoder)); // FSTP ST(1) (DF D0, DF D8)
+ _handlers.Add(new FloatingPoint.Comparison.FucomipHandler(_decoder)); // FUCOMIP ST(0), ST(i) (DF E8-EF)
+ _handlers.Add(new FloatingPoint.Comparison.FcomipHandler(_decoder)); // FCOMIP ST(0), ST(i) (DF F0-F7)
}
///
diff --git a/X86DisassemblerTests/TestData/string_tests.csv b/X86DisassemblerTests/TestData/string_tests.csv
index 57cf024..eb27ec9 100644
--- a/X86DisassemblerTests/TestData/string_tests.csv
+++ b/X86DisassemblerTests/TestData/string_tests.csv
@@ -5,12 +5,12 @@ RawBytes;Instructions
# MOVS - Move string
A4;[{ "Type": "MovsB", "Operands": ["byte ptr es:[edi]", "byte ptr ds:[esi]"] }]
A5;[{ "Type": "MovsD", "Operands": ["dword ptr es:[edi]", "dword ptr ds:[esi]"] }]
-66A5;[{ "Type": "MovsW", "Operands": ["word ptr es:[edi]", "byte ptr es:[esi]"] }]
+66A5;[{ "Type": "MovsW", "Operands": ["word ptr es:[edi]", "word ptr ds:[esi]"] }]
# CMPS - Compare string
-A6;[{ "Type": "CmpsB", "Operands": ["byte ptr es:[esi]", "byte ptr es:[edi]"] }]
-A7;[{ "Type": "CmpsD", "Operands": ["dword ptr es:[esi]", "dword ptr es:[edi]"] }]
-66A7;[{ "Type": "CmpsW", "Operands": ["word ptr es:[esi]", "word ptr es:[edi]"] }]
+A6;[{ "Type": "CmpsB", "Operands": ["byte ptr ds:[esi]", "byte ptr es:[edi]"] }]
+A7;[{ "Type": "CmpsD", "Operands": ["dword ptr ds:[esi]", "dword ptr es:[edi]"] }]
+66A7;[{ "Type": "CmpsW", "Operands": ["word ptr ds:[esi]", "word ptr es:[edi]"] }]
# SCAS - Scan string
AE;[{ "Type": "ScasB", "Operands": ["al", "byte ptr es:[edi]"] }]
@@ -20,7 +20,7 @@ AF;[{ "Type": "ScasD", "Operands": ["eax", "dword ptr es:[edi]"] }]
# LODS - Load string
AC;[{ "Type": "LodsB", "Operands": ["al", "byte ptr ds:[esi]"] }]
AD;[{ "Type": "LodsD", "Operands": ["eax", "dword ptr ds:[esi]"] }]
-66AD;[{ "Type": "LodsW", "Operands": ["ax", "byte ptr ds:[esi]"] }]
+66AD;[{ "Type": "LodsW", "Operands": ["ax", "word ptr ds:[esi]"] }]
# STOS - Store string
AA;[{ "Type": "StosB", "Operands": ["byte ptr es:[edi]", "al"] }]
@@ -36,17 +36,17 @@ F3AB;[{ "Type": "RepStosD", "Operands": ["dword ptr es:[edi]", "eax"] }]
F366AB;[{ "Type": "RepStosW", "Operands": ["word ptr es:[edi]", "ax"] }]
# REPE/REPZ prefix with string instructions
-F3A6;[{ "Type": "RepeCmpsB", "Operands": ["byte ptr es:[esi]", "byte ptr es:[edi]"] }]
-F3A7;[{ "Type": "RepeCmpsD", "Operands": ["dword ptr es:[esi]", "byte ptr es:[edi]"] }]
-F366A7;[{ "Type": "RepeCmpsW", "Operands": ["word ptr es:[esi]", "word ptr es:[edi]"] }]
+F3A6;[{ "Type": "RepeCmpsB", "Operands": ["byte ptr ds:[esi]", "byte ptr es:[edi]"] }]
+F3A7;[{ "Type": "RepeCmpsD", "Operands": ["dword ptr ds:[esi]", "dword ptr es:[edi]"] }]
+F366A7;[{ "Type": "RepeCmpsW", "Operands": ["word ptr ds:[esi]", "word ptr es:[edi]"] }]
F3AE;[{ "Type": "RepScasB", "Operands": ["al", "byte ptr es:[edi]"] }]
F3AF;[{ "Type": "RepScasD", "Operands": ["eax", "dword ptr es:[edi]"] }]
F366AF;[{ "Type": "RepScasW", "Operands": ["ax", "word ptr es:[edi]"] }]
# REPNE/REPNZ prefix with string instructions
-F2A6;[{ "Type": "RepneCmpsB", "Operands": ["byte ptr es:[esi]", "byte ptr es:[edi]"] }]
-F2A7;[{ "Type": "RepneCmpsD", "Operands": ["dword ptr es:[esi]", "dword ptr es:[edi]"] }]
-F266A7;[{ "Type": "RepneCmpsW", "Operands": ["word ptr es:[esi]", "word ptr es:[edi]"] }]
+F2A6;[{ "Type": "RepneCmpsB", "Operands": ["byte ptr ds:[esi]", "byte ptr es:[edi]"] }]
+F2A7;[{ "Type": "RepneCmpsD", "Operands": ["dword ptr ds:[esi]", "dword ptr es:[edi]"] }]
+F266A7;[{ "Type": "RepneCmpsW", "Operands": ["word ptr ds:[esi]", "word ptr es:[edi]"] }]
F2AE;[{ "Type": "RepneScasB", "Operands": ["al", "byte ptr es:[edi]"] }]
-F2AF;[{ "Type": "RepneScasD", "Operands": ["eax", "byte ptr es:[edi]"] }]
-F266AF;[{ "Type": "RepneScasW", "Operands": ["eax", "byte ptr es:[edi]"] }]
+F2AF;[{ "Type": "RepneScasD", "Operands": ["eax", "dword ptr es:[edi]"] }]
+F266AF;[{ "Type": "RepneScasW", "Operands": ["ax", "word ptr es:[edi]"] }]