From 5916d139954f46b05c0d94888d93cca332c1cfb4 Mon Sep 17 00:00:00 2001 From: bird_egop Date: Thu, 17 Apr 2025 23:48:09 +0300 Subject: [PATCH] Reorganize floating point handlers into logical subfolders --- .../{ => Arithmetic}/FaddFloat32Handler.cs | 4 +- .../{ => Arithmetic}/FaddFloat64Handler.cs | 4 +- .../{ => Arithmetic}/FdivFloat32Handler.cs | 4 +- .../Arithmetic/FdivFloat64Handler.cs | 85 ++++++++++++++++++ .../{ => Arithmetic}/FdivrFloat32Handler.cs | 4 +- .../Arithmetic/FdivrFloat64Handler.cs | 85 ++++++++++++++++++ .../{ => Arithmetic}/FmulFloat32Handler.cs | 4 +- .../{ => Arithmetic}/FmulFloat64Handler.cs | 4 +- .../{ => Arithmetic}/FsubFloat32Handler.cs | 4 +- .../Arithmetic/FsubFloat64Handler.cs | 85 ++++++++++++++++++ .../{ => Arithmetic}/FsubrFloat32Handler.cs | 4 +- .../Arithmetic/FsubrFloat64Handler.cs | 85 ++++++++++++++++++ .../{ => Comparison}/FcomFloat32Handler.cs | 4 +- .../Comparison/FcomFloat64Handler.cs | 85 ++++++++++++++++++ .../{ => Comparison}/FcompFloat32Handler.cs | 4 +- .../Comparison/FcompFloat64Handler.cs | 85 ++++++++++++++++++ .../{ => Control}/FnstswHandler.cs | 4 +- .../{ => LoadStore}/FldFloat32Handler.cs | 4 +- .../LoadStore/FldFloat64Handler.cs | 89 +++++++++++++++++++ .../{ => LoadStore}/FstFloat32Handler.cs | 4 +- .../LoadStore/FstFloat64Handler.cs | 83 +++++++++++++++++ .../{ => LoadStore}/FstpFloat32Handler.cs | 4 +- .../LoadStore/FstpFloat64Handler.cs | 83 +++++++++++++++++ .../X86/Handlers/InstructionHandlerFactory.cs | 39 +++++--- 24 files changed, 818 insertions(+), 42 deletions(-) rename X86Disassembler/X86/Handlers/FloatingPoint/{ => Arithmetic}/FaddFloat32Handler.cs (96%) rename X86Disassembler/X86/Handlers/FloatingPoint/{ => Arithmetic}/FaddFloat64Handler.cs (96%) rename X86Disassembler/X86/Handlers/FloatingPoint/{ => Arithmetic}/FdivFloat32Handler.cs (96%) create mode 100644 X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivFloat64Handler.cs rename X86Disassembler/X86/Handlers/FloatingPoint/{ => Arithmetic}/FdivrFloat32Handler.cs (96%) create mode 100644 X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivrFloat64Handler.cs rename X86Disassembler/X86/Handlers/FloatingPoint/{ => Arithmetic}/FmulFloat32Handler.cs (96%) rename X86Disassembler/X86/Handlers/FloatingPoint/{ => Arithmetic}/FmulFloat64Handler.cs (96%) rename X86Disassembler/X86/Handlers/FloatingPoint/{ => Arithmetic}/FsubFloat32Handler.cs (96%) create mode 100644 X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubFloat64Handler.cs rename X86Disassembler/X86/Handlers/FloatingPoint/{ => Arithmetic}/FsubrFloat32Handler.cs (96%) create mode 100644 X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubrFloat64Handler.cs rename X86Disassembler/X86/Handlers/FloatingPoint/{ => Comparison}/FcomFloat32Handler.cs (96%) create mode 100644 X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomFloat64Handler.cs rename X86Disassembler/X86/Handlers/FloatingPoint/{ => Comparison}/FcompFloat32Handler.cs (96%) create mode 100644 X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcompFloat64Handler.cs rename X86Disassembler/X86/Handlers/FloatingPoint/{ => Control}/FnstswHandler.cs (95%) rename X86Disassembler/X86/Handlers/FloatingPoint/{ => LoadStore}/FldFloat32Handler.cs (96%) create mode 100644 X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FldFloat64Handler.cs rename X86Disassembler/X86/Handlers/FloatingPoint/{ => LoadStore}/FstFloat32Handler.cs (96%) create mode 100644 X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstFloat64Handler.cs rename X86Disassembler/X86/Handlers/FloatingPoint/{ => LoadStore}/FstpFloat32Handler.cs (96%) create mode 100644 X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpFloat64Handler.cs diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FaddFloat32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FaddFloat32Handler.cs similarity index 96% rename from X86Disassembler/X86/Handlers/FloatingPoint/FaddFloat32Handler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FaddFloat32Handler.cs index cb8e4bf..f06c842 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FaddFloat32Handler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FaddFloat32Handler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic; -using Operands; +using X86Disassembler.X86.Operands; /// /// Handler for FADD float32 instruction (D8 /0) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FaddFloat64Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FaddFloat64Handler.cs similarity index 96% rename from X86Disassembler/X86/Handlers/FloatingPoint/FaddFloat64Handler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FaddFloat64Handler.cs index 1b76431..83e0c95 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FaddFloat64Handler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FaddFloat64Handler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic; -using Operands; +using X86Disassembler.X86.Operands; /// /// Handler for FADD float64 instruction (DC /0) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FdivFloat32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivFloat32Handler.cs similarity index 96% rename from X86Disassembler/X86/Handlers/FloatingPoint/FdivFloat32Handler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivFloat32Handler.cs index f8580a0..70385c8 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FdivFloat32Handler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivFloat32Handler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +using X86Disassembler.X86.Operands; -using Operands; +namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic; /// /// Handler for FDIV float32 instruction (D8 /6) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivFloat64Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivFloat64Handler.cs new file mode 100644 index 0000000..7a5e304 --- /dev/null +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivFloat64Handler.cs @@ -0,0 +1,85 @@ +namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic; + +using X86Disassembler.X86.Operands; + +/// +/// Handler for FDIV float64 instruction (DC /6) +/// +public class FdivFloat64Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the FdivFloat64Handler class + /// + /// The instruction decoder that owns this handler + public FdivFloat64Handler(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 is DC /6 + if (opcode != 0xDC) 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); + + return reg == 6; + } + + /// + /// Decodes a FDIV float64 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 using the specialized FPU method + var (mod, reg, fpuRm, rawOperand) = ModRMDecoder.ReadModRMFpu(); + + // Set the instruction type + instruction.Type = InstructionType.Fdiv; + + // For memory operands, set the operand + if (mod != 3) // Memory operand + { + // Set the structured operands - the operand already has the correct size from ReadModRM + instruction.StructuredOperands = + [ + rawOperand + ]; + } + else // Register operand (ST(i)) + { + // For DC F0-DC F7, the operands are reversed: ST(i), ST(0) + var stiOperand = OperandFactory.CreateFPURegisterOperand(fpuRm); // ST(i) + var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0); // ST(0) + + // Set the structured operands + instruction.StructuredOperands = + [ + stiOperand, + st0Operand + ]; + } + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FdivrFloat32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivrFloat32Handler.cs similarity index 96% rename from X86Disassembler/X86/Handlers/FloatingPoint/FdivrFloat32Handler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivrFloat32Handler.cs index 7c77ca1..4885fc3 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FdivrFloat32Handler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivrFloat32Handler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +using X86Disassembler.X86.Operands; -using Operands; +namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic; /// /// Handler for FDIVR float32 instruction (D8 /7) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivrFloat64Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivrFloat64Handler.cs new file mode 100644 index 0000000..9619587 --- /dev/null +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FdivrFloat64Handler.cs @@ -0,0 +1,85 @@ +namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic; + +using X86Disassembler.X86.Operands; + +/// +/// Handler for FDIVR float64 instruction (DC /7) +/// +public class FdivrFloat64Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the FdivrFloat64Handler class + /// + /// The instruction decoder that owns this handler + public FdivrFloat64Handler(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 is DC /7 + if (opcode != 0xDC) 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); + + return reg == 7; + } + + /// + /// Decodes a FDIVR float64 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 using the specialized FPU method + var (mod, reg, fpuRm, rawOperand) = ModRMDecoder.ReadModRMFpu(); + + // Set the instruction type + instruction.Type = InstructionType.Fdivr; + + // For memory operands, set the operand + if (mod != 3) // Memory operand + { + // Set the structured operands - the operand already has the correct size from ReadModRM + instruction.StructuredOperands = + [ + rawOperand + ]; + } + else // Register operand (ST(i)) + { + // For DC F8-DC FF, the operands are reversed: ST(i), ST(0) + var stiOperand = OperandFactory.CreateFPURegisterOperand(fpuRm); // ST(i) + var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0); // ST(0) + + // Set the structured operands + instruction.StructuredOperands = + [ + stiOperand, + st0Operand + ]; + } + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FmulFloat32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FmulFloat32Handler.cs similarity index 96% rename from X86Disassembler/X86/Handlers/FloatingPoint/FmulFloat32Handler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FmulFloat32Handler.cs index f41225d..fe6ef8b 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FmulFloat32Handler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FmulFloat32Handler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +using X86Disassembler.X86.Operands; -using Operands; +namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic; /// /// Handler for FMUL float32 instruction (D8 /1) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FmulFloat64Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FmulFloat64Handler.cs similarity index 96% rename from X86Disassembler/X86/Handlers/FloatingPoint/FmulFloat64Handler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FmulFloat64Handler.cs index 47dd396..b9b8306 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FmulFloat64Handler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FmulFloat64Handler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +using X86Disassembler.X86.Operands; -using Operands; +namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic; /// /// Handler for FMUL float64 instruction (DC /1) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FsubFloat32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubFloat32Handler.cs similarity index 96% rename from X86Disassembler/X86/Handlers/FloatingPoint/FsubFloat32Handler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubFloat32Handler.cs index 1ba621e..27b40bf 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FsubFloat32Handler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubFloat32Handler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +using X86Disassembler.X86.Operands; -using Operands; +namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic; /// /// Handler for FSUB float32 instruction (D8 /4) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubFloat64Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubFloat64Handler.cs new file mode 100644 index 0000000..36960d6 --- /dev/null +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubFloat64Handler.cs @@ -0,0 +1,85 @@ +namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic; + +using X86Disassembler.X86.Operands; + +/// +/// Handler for FSUB float64 instruction (DC /4) +/// +public class FsubFloat64Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the FsubFloat64Handler class + /// + /// The instruction decoder that owns this handler + public FsubFloat64Handler(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 is DC /4 + if (opcode != 0xDC) 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); + + return reg == 4; + } + + /// + /// Decodes a FSUB float64 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 using the specialized FPU method + var (mod, reg, fpuRm, rawOperand) = ModRMDecoder.ReadModRMFpu(); + + // Set the instruction type + instruction.Type = InstructionType.Fsub; + + // For memory operands, set the operand + if (mod != 3) // Memory operand + { + // Set the structured operands - the operand already has the correct size from ReadModRM + instruction.StructuredOperands = + [ + rawOperand + ]; + } + else // Register operand (ST(i)) + { + // For DC E0-DC E7, the operands are reversed: ST(i), ST(0) + var stiOperand = OperandFactory.CreateFPURegisterOperand(fpuRm); // ST(i) + var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0); // ST(0) + + // Set the structured operands + instruction.StructuredOperands = + [ + stiOperand, + st0Operand + ]; + } + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FsubrFloat32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubrFloat32Handler.cs similarity index 96% rename from X86Disassembler/X86/Handlers/FloatingPoint/FsubrFloat32Handler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubrFloat32Handler.cs index 3b348b8..19dfbd8 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FsubrFloat32Handler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubrFloat32Handler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +using X86Disassembler.X86.Operands; -using Operands; +namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic; /// /// Handler for FSUBR float32 instruction (D8 /5) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubrFloat64Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubrFloat64Handler.cs new file mode 100644 index 0000000..6efedc8 --- /dev/null +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Arithmetic/FsubrFloat64Handler.cs @@ -0,0 +1,85 @@ +namespace X86Disassembler.X86.Handlers.FloatingPoint.Arithmetic; + +using X86Disassembler.X86.Operands; + +/// +/// Handler for FSUBR float64 instruction (DC /5) +/// +public class FsubrFloat64Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the FsubrFloat64Handler class + /// + /// The instruction decoder that owns this handler + public FsubrFloat64Handler(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 is DC /5 + if (opcode != 0xDC) 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); + + return reg == 5; + } + + /// + /// Decodes a FSUBR float64 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 using the specialized FPU method + var (mod, reg, fpuRm, rawOperand) = ModRMDecoder.ReadModRMFpu(); + + // Set the instruction type + instruction.Type = InstructionType.Fsubr; + + // For memory operands, set the operand + if (mod != 3) // Memory operand + { + // Set the structured operands - the operand already has the correct size from ReadModRM + instruction.StructuredOperands = + [ + rawOperand + ]; + } + else // Register operand (ST(i)) + { + // For DC E8-DC EF, the operands are reversed: ST(i), ST(0) + var stiOperand = OperandFactory.CreateFPURegisterOperand(fpuRm); // ST(i) + var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0); // ST(0) + + // Set the structured operands + instruction.StructuredOperands = + [ + stiOperand, + st0Operand + ]; + } + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FcomFloat32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomFloat32Handler.cs similarity index 96% rename from X86Disassembler/X86/Handlers/FloatingPoint/FcomFloat32Handler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomFloat32Handler.cs index f3da079..8a541b7 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FcomFloat32Handler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomFloat32Handler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +using X86Disassembler.X86.Operands; -using Operands; +namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison; /// /// Handler for FCOM float32 instruction (D8 /2) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomFloat64Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomFloat64Handler.cs new file mode 100644 index 0000000..5835869 --- /dev/null +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcomFloat64Handler.cs @@ -0,0 +1,85 @@ +namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison; + +using X86Disassembler.X86.Operands; + +/// +/// Handler for FCOM float64 instruction (DC /2) +/// +public class FcomFloat64Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the FcomFloat64Handler class + /// + /// The instruction decoder that owns this handler + public FcomFloat64Handler(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 is DC /2 + if (opcode != 0xDC) 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); + + return reg == 2; + } + + /// + /// Decodes a FCOM float64 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 using the specialized FPU method + var (mod, reg, fpuRm, rawOperand) = ModRMDecoder.ReadModRMFpu(); + + // Set the instruction type + instruction.Type = InstructionType.Fcom; + + // For memory operands, set the operand + if (mod != 3) // Memory operand + { + // Set the structured operands - the operand already has the correct size from ReadModRM + instruction.StructuredOperands = + [ + rawOperand + ]; + } + else // Register operand (ST(i)) + { + // For register operands, we need to handle the stack registers + var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0); // ST(0) + var stiOperand = OperandFactory.CreateFPURegisterOperand(fpuRm); // ST(i) + + // Set the structured operands + instruction.StructuredOperands = + [ + st0Operand, + stiOperand + ]; + } + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FcompFloat32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcompFloat32Handler.cs similarity index 96% rename from X86Disassembler/X86/Handlers/FloatingPoint/FcompFloat32Handler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcompFloat32Handler.cs index 8108dbf..0be84e5 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FcompFloat32Handler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcompFloat32Handler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +using X86Disassembler.X86.Operands; -using Operands; +namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison; /// /// Handler for FCOMP float32 instruction (D8 /3) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcompFloat64Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcompFloat64Handler.cs new file mode 100644 index 0000000..ea62835 --- /dev/null +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Comparison/FcompFloat64Handler.cs @@ -0,0 +1,85 @@ +namespace X86Disassembler.X86.Handlers.FloatingPoint.Comparison; + +using X86Disassembler.X86.Operands; + +/// +/// Handler for FCOMP float64 instruction (DC /3) +/// +public class FcompFloat64Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the FcompFloat64Handler class + /// + /// The instruction decoder that owns this handler + public FcompFloat64Handler(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 is DC /3 + if (opcode != 0xDC) 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); + + return reg == 3; + } + + /// + /// Decodes a FCOMP float64 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 using the specialized FPU method + var (mod, reg, fpuRm, rawOperand) = ModRMDecoder.ReadModRMFpu(); + + // Set the instruction type + instruction.Type = InstructionType.Fcomp; + + // For memory operands, set the operand + if (mod != 3) // Memory operand + { + // Set the structured operands - the operand already has the correct size from ReadModRM + instruction.StructuredOperands = + [ + rawOperand + ]; + } + else // Register operand (ST(i)) + { + // For register operands, we need to handle the stack registers + var st0Operand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0); // ST(0) + var stiOperand = OperandFactory.CreateFPURegisterOperand(fpuRm); // ST(i) + + // Set the structured operands + instruction.StructuredOperands = + [ + st0Operand, + stiOperand + ]; + } + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FnstswHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FnstswHandler.cs similarity index 95% rename from X86Disassembler/X86/Handlers/FloatingPoint/FnstswHandler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/Control/FnstswHandler.cs index ed628cd..31b8cdc 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FnstswHandler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FnstswHandler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +using X86Disassembler.X86.Operands; -using Operands; +namespace X86Disassembler.X86.Handlers.FloatingPoint.Control; /// /// Handler for FNSTSW AX instruction (0xDF 0xE0) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FldFloat32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FldFloat32Handler.cs similarity index 96% rename from X86Disassembler/X86/Handlers/FloatingPoint/FldFloat32Handler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FldFloat32Handler.cs index 5cf7279..0682e8c 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FldFloat32Handler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FldFloat32Handler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +using X86Disassembler.X86.Operands; -using Operands; +namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore; /// /// Handler for FLD float32 instruction (D9 /0) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FldFloat64Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FldFloat64Handler.cs new file mode 100644 index 0000000..30ca0da --- /dev/null +++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FldFloat64Handler.cs @@ -0,0 +1,89 @@ +namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore; + +using X86Disassembler.X86.Operands; + +/// +/// Handler for FLD float64 instruction (DD /0) +/// +public class FldFloat64Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the FldFloat64Handler class + /// + /// The instruction decoder that owns this handler + public FldFloat64Handler(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 is DD /0 + if (opcode != 0xDD) 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); + + return reg == 0; + } + + /// + /// Decodes a FLD float64 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 using the specialized FPU method + var (mod, reg, fpuRm, rawOperand) = ModRMDecoder.ReadModRMFpu(); + + // Verify reg field is 0 (FLD) + if (reg != 0) + { + return false; + } + + // Set the instruction type + instruction.Type = InstructionType.Fld; + + // Handle based on addressing mode + if (mod != 3) // Memory operand + { + // Set the structured operands - the operand already has the correct size from ReadModRM + instruction.StructuredOperands = + [ + rawOperand + ]; + } + else // Register operand (ST(i)) + { + // For register operands with mod=3, this is FLD ST(i) + var stiOperand = OperandFactory.CreateFPURegisterOperand(fpuRm); // ST(i) + + // Set the structured operands + instruction.StructuredOperands = + [ + stiOperand + ]; + } + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FstFloat32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstFloat32Handler.cs similarity index 96% rename from X86Disassembler/X86/Handlers/FloatingPoint/FstFloat32Handler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstFloat32Handler.cs index a8a29f6..7bbc209 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FstFloat32Handler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstFloat32Handler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +using X86Disassembler.X86.Operands; -using Operands; +namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore; /// /// Handler for FST float32 instruction (D9 /2) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstFloat64Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstFloat64Handler.cs new file mode 100644 index 0000000..3e33a44 --- /dev/null +++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstFloat64Handler.cs @@ -0,0 +1,83 @@ +namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore; + +using X86Disassembler.X86.Operands; + +/// +/// Handler for FST float64 instruction (DD /2) +/// +public class FstFloat64Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the FstFloat64Handler class + /// + /// The instruction decoder that owns this handler + public FstFloat64Handler(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 is DD /2 + if (opcode != 0xDD) 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); + + return reg == 2; + } + + /// + /// Decodes a FST float64 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 using the specialized FPU method + var (mod, reg, fpuRm, rawOperand) = ModRMDecoder.ReadModRMFpu(); + + // Set the instruction type + instruction.Type = InstructionType.Fst; + + // Handle based on addressing mode + if (mod != 3) // Memory operand + { + // Set the structured operands - the operand already has the correct size from ReadModRM + instruction.StructuredOperands = + [ + rawOperand + ]; + } + else // Register operand (ST(i)) + { + // For register operands with mod=3, this is FST ST(i) + var stiOperand = OperandFactory.CreateFPURegisterOperand(fpuRm); // ST(i) + + // Set the structured operands + instruction.StructuredOperands = + [ + stiOperand + ]; + } + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/FstpFloat32Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpFloat32Handler.cs similarity index 96% rename from X86Disassembler/X86/Handlers/FloatingPoint/FstpFloat32Handler.cs rename to X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpFloat32Handler.cs index 36604f9..e796067 100644 --- a/X86Disassembler/X86/Handlers/FloatingPoint/FstpFloat32Handler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpFloat32Handler.cs @@ -1,6 +1,6 @@ -namespace X86Disassembler.X86.Handlers.FloatingPoint; +using X86Disassembler.X86.Operands; -using Operands; +namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore; /// /// Handler for FSTP float32 instruction (D9 /3) diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpFloat64Handler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpFloat64Handler.cs new file mode 100644 index 0000000..73b7b1e --- /dev/null +++ b/X86Disassembler/X86/Handlers/FloatingPoint/LoadStore/FstpFloat64Handler.cs @@ -0,0 +1,83 @@ +namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore; + +using X86Disassembler.X86.Operands; + +/// +/// Handler for FSTP float64 instruction (DD /3) +/// +public class FstpFloat64Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the FstpFloat64Handler class + /// + /// The instruction decoder that owns this handler + public FstpFloat64Handler(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 is DD /3 + if (opcode != 0xDD) 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); + + return reg == 3; + } + + /// + /// Decodes a FSTP float64 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 using the specialized FPU method + var (mod, reg, fpuRm, rawOperand) = ModRMDecoder.ReadModRMFpu(); + + // Set the instruction type + instruction.Type = InstructionType.Fstp; + + // Handle based on addressing mode + if (mod != 3) // Memory operand + { + // Set the structured operands - the operand already has the correct size from ReadModRM + instruction.StructuredOperands = + [ + rawOperand + ]; + } + else // Register operand (ST(i)) + { + // For register operands with mod=3, this is FSTP ST(i) + var stiOperand = OperandFactory.CreateFPURegisterOperand(fpuRm); // ST(i) + + // Set the structured operands + instruction.StructuredOperands = + [ + stiOperand + ]; + } + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs index e5aa28a..16437ac 100644 --- a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs +++ b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs @@ -376,26 +376,37 @@ public class InstructionHandlerFactory // Add specialized Floating Point handlers // D8 opcode handlers (float32 operations) - _handlers.Add(new FaddFloat32Handler(_decoder)); // FADD float32 (D8 /0) - _handlers.Add(new FmulFloat32Handler(_decoder)); // FMUL float32 (D8 /1) - _handlers.Add(new FcomFloat32Handler(_decoder)); // FCOM float32 (D8 /2) - _handlers.Add(new FcompFloat32Handler(_decoder)); // FCOMP float32 (D8 /3) - _handlers.Add(new FsubFloat32Handler(_decoder)); // FSUB float32 (D8 /4) - _handlers.Add(new FsubrFloat32Handler(_decoder)); // FSUBR float32 (D8 /5) - _handlers.Add(new FdivFloat32Handler(_decoder)); // FDIV float32 (D8 /6) - _handlers.Add(new FdivrFloat32Handler(_decoder)); // FDIVR float32 (D8 /7) + _handlers.Add(new FloatingPoint.Arithmetic.FaddFloat32Handler(_decoder)); // FADD float32 (D8 /0) + _handlers.Add(new FloatingPoint.Arithmetic.FmulFloat32Handler(_decoder)); // FMUL float32 (D8 /1) + _handlers.Add(new FloatingPoint.Comparison.FcomFloat32Handler(_decoder)); // FCOM float32 (D8 /2) + _handlers.Add(new FloatingPoint.Comparison.FcompFloat32Handler(_decoder)); // FCOMP float32 (D8 /3) + _handlers.Add(new FloatingPoint.Arithmetic.FsubFloat32Handler(_decoder)); // FSUB float32 (D8 /4) + _handlers.Add(new FloatingPoint.Arithmetic.FsubrFloat32Handler(_decoder)); // FSUBR float32 (D8 /5) + _handlers.Add(new FloatingPoint.Arithmetic.FdivFloat32Handler(_decoder)); // FDIV float32 (D8 /6) + _handlers.Add(new FloatingPoint.Arithmetic.FdivrFloat32Handler(_decoder)); // FDIVR float32 (D8 /7) // D9 opcode handlers (load/store float32 and control operations) - _handlers.Add(new FldFloat32Handler(_decoder)); // FLD float32 (D9 /0) - _handlers.Add(new FstFloat32Handler(_decoder)); // FST float32 (D9 /2) - _handlers.Add(new FstpFloat32Handler(_decoder)); // FSTP float32 (D9 /3) + _handlers.Add(new FloatingPoint.LoadStore.FldFloat32Handler(_decoder)); // FLD float32 (D9 /0) + _handlers.Add(new FloatingPoint.LoadStore.FstFloat32Handler(_decoder)); // FST float32 (D9 /2) + _handlers.Add(new FloatingPoint.LoadStore.FstpFloat32Handler(_decoder)); // FSTP float32 (D9 /3) // DC opcode handlers (float64 operations) - _handlers.Add(new FaddFloat64Handler(_decoder)); // FADD float64 (DC /0) - _handlers.Add(new FmulFloat64Handler(_decoder)); // FMUL float64 (DC /1) + _handlers.Add(new FloatingPoint.Arithmetic.FaddFloat64Handler(_decoder)); // FADD float64 (DC /0) + _handlers.Add(new FloatingPoint.Arithmetic.FmulFloat64Handler(_decoder)); // FMUL float64 (DC /1) + _handlers.Add(new FloatingPoint.Comparison.FcomFloat64Handler(_decoder)); // FCOM float64 (DC /2) + _handlers.Add(new FloatingPoint.Comparison.FcompFloat64Handler(_decoder)); // FCOMP float64 (DC /3) + _handlers.Add(new FloatingPoint.Arithmetic.FsubFloat64Handler(_decoder)); // FSUB float64 (DC /4) + _handlers.Add(new FloatingPoint.Arithmetic.FsubrFloat64Handler(_decoder)); // FSUBR float64 (DC /5) + _handlers.Add(new FloatingPoint.Arithmetic.FdivFloat64Handler(_decoder)); // FDIV float64 (DC /6) + _handlers.Add(new FloatingPoint.Arithmetic.FdivrFloat64Handler(_decoder)); // FDIVR float64 (DC /7) + + // DD opcode handlers (load/store float64 operations) + _handlers.Add(new FloatingPoint.LoadStore.FldFloat64Handler(_decoder)); // FLD float64 (DD /0) + _handlers.Add(new FloatingPoint.LoadStore.FstFloat64Handler(_decoder)); // FST float64 (DD /2) + _handlers.Add(new FloatingPoint.LoadStore.FstpFloat64Handler(_decoder)); // FSTP float64 (DD /3) // Other floating point handlers - _handlers.Add(new FnstswHandler(_decoder)); // FNSTSW AX (DF E0) + _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 LoadStoreControlHandler(_decoder)); // Load and store control words (D9 /4-/7)