Skip to content

Commit

Permalink
Core: ISIL: Implement some more x86 stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
SamboyCoding committed Aug 12, 2024
1 parent e57a269 commit 671f78c
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cpp2IL.Core/ISIL/InstructionSetIndependentOpCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class InstructionSetIndependentOpCode
public static readonly InstructionSetIndependentOpCode JumpIfLessOrEqual = new(IsilMnemonic.JumpIfLessOrEqual, 1, InstructionSetIndependentOperand.OperandType.Instruction);

public static readonly InstructionSetIndependentOpCode Interrupt = new(IsilMnemonic.Interrupt, 0);
public static readonly InstructionSetIndependentOpCode Nop = new(IsilMnemonic.Nop, 0);

public static readonly InstructionSetIndependentOpCode NotImplemented = new(IsilMnemonic.NotImplemented, 1, InstructionSetIndependentOperand.OperandType.Immediate);

Expand Down
1 change: 1 addition & 0 deletions Cpp2IL.Core/ISIL/IsilBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ private void CreateJump(ulong instructionAddress, ulong target, InstructionSetIn
public void Invalid(ulong instructionAddress, string text) => AddInstruction(new(InstructionSetIndependentOpCode.Invalid, instructionAddress, IsilFlowControl.Continue, InstructionSetIndependentOperand.MakeImmediate(text)));

public void Interrupt(ulong instructionAddress) => AddInstruction(new(InstructionSetIndependentOpCode.Interrupt, instructionAddress, IsilFlowControl.Interrupt));
public void Nop(ulong instructionAddress) => AddInstruction(new(InstructionSetIndependentOpCode.Nop, instructionAddress, IsilFlowControl.Continue));

private InstructionSetIndependentOperand[] PrepareCallOperands(ulong dest, InstructionSetIndependentOperand[] args)
{
Expand Down
1 change: 1 addition & 0 deletions Cpp2IL.Core/ISIL/IsilMnemonic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public enum IsilMnemonic
JumpIfLessOrEqual,
SignExtend,
Interrupt,
Nop,
NotImplemented,
Invalid,
}
60 changes: 59 additions & 1 deletion Cpp2IL.Core/InstructionSets/X86InstructionSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,22 @@ private void ConvertInstructionStatement(Instruction instruction, IsilBuilder bu
switch (instruction.Mnemonic)
{
case Mnemonic.Mov:
case Mnemonic.Movzx: //For all intents and purposes we don't care about zero-extending
case Mnemonic.Movaps: //Movaps is basically just a mov but with the potential future detail that the size is dependent on reg size
case Mnemonic.Movups: //Movaps but unaligned
case Mnemonic.Movss: //Same as movaps but for floats
case Mnemonic.Movd: //Mov but specifically dword
case Mnemonic.Movq: //Mov but specifically qword
case Mnemonic.Movsd: //Mov but specifically double
case Mnemonic.Movdqa: //Movaps but multiple integers at once in theory
case Mnemonic.Cvtdq2ps: //Technically a convert double to single, but for analysis purposes we can just treat it as a move
builder.Move(instruction.IP, ConvertOperand(instruction, 0), ConvertOperand(instruction, 1));
break;
case Mnemonic.Lea:
builder.LoadAddress(instruction.IP, ConvertOperand(instruction, 0), ConvertOperand(instruction, 1));
break;
case Mnemonic.Xor:
case Mnemonic.Xorps: //xorps is just floating point xor
if (instruction.Op0Kind == OpKind.Register && instruction.Op1Kind == OpKind.Register && instruction.Op0Register == instruction.Op1Register)
builder.Move(instruction.IP, ConvertOperand(instruction, 0), InstructionSetIndependentOperand.MakeImmediate(0));
else
Expand All @@ -84,9 +94,11 @@ private void ConvertInstructionStatement(Instruction instruction, IsilBuilder bu
builder.ShiftRight(instruction.IP, ConvertOperand(instruction, 0), ConvertOperand(instruction, 1));
break;
case Mnemonic.And:
case Mnemonic.Andps: //Floating point and
builder.And(instruction.IP, ConvertOperand(instruction, 0), ConvertOperand(instruction, 0), ConvertOperand(instruction, 1));
break;
case Mnemonic.Or:
case Mnemonic.Orps: //Floating point or
builder.Or(instruction.IP, ConvertOperand(instruction, 0), ConvertOperand(instruction, 0), ConvertOperand(instruction, 1));
break;
case Mnemonic.Not:
Expand Down Expand Up @@ -120,6 +132,16 @@ private void ConvertInstructionStatement(Instruction instruction, IsilBuilder bu
else if (instruction.OpCount == 3) builder.Multiply(instruction.IP, ConvertOperand(instruction, 0), ConvertOperand(instruction, 1), ConvertOperand(instruction, 2));
else builder.Multiply(instruction.IP, ConvertOperand(instruction, 0), ConvertOperand(instruction, 0), ConvertOperand(instruction, 1));
break;
case Mnemonic.Mulss:
case Mnemonic.Vmulss:
if (instruction.OpCount == 3)
builder.Multiply(instruction.IP, ConvertOperand(instruction, 0), ConvertOperand(instruction, 1), ConvertOperand(instruction, 2));
else if (instruction.OpCount == 2)
builder.Multiply(instruction.IP, ConvertOperand(instruction, 0), ConvertOperand(instruction, 0), ConvertOperand(instruction, 1));
else
goto default;

break;
case Mnemonic.Ret:
if (context.IsVoid)
builder.Return(instruction.IP);
Expand Down Expand Up @@ -156,6 +178,34 @@ private void ConvertInstructionStatement(Instruction instruction, IsilBuilder bu
builder.Add(instruction.IP, left, left, right);

break;
case Mnemonic.Addss:
case Mnemonic.Subss:
//Addss and subss are just floating point add/sub, but we don't need to handle the stack stuff
//But we do need to handle 2 vs 3 operand forms
InstructionSetIndependentOperand dest;
InstructionSetIndependentOperand src1;
InstructionSetIndependentOperand src2;

if (instruction.OpCount == 3)
{
//dest, src1, src2
dest = ConvertOperand(instruction, 0);
src1 = ConvertOperand(instruction, 1);
src2 = ConvertOperand(instruction, 2);
} else if (instruction.OpCount == 2)
{
//DestAndSrc1, Src2
dest = ConvertOperand(instruction, 0);
src1 = dest;
src2 = ConvertOperand(instruction, 1);
} else
goto default;

if (instruction.Mnemonic == Mnemonic.Subss)
builder.Subtract(instruction.IP, dest, src1, src2);
else
builder.Add(instruction.IP, dest, src1, src2);
break;
case Mnemonic.Dec:
case Mnemonic.Inc:
// no CF
Expand Down Expand Up @@ -222,8 +272,11 @@ private void ConvertInstructionStatement(Instruction instruction, IsilBuilder bu
builder.Compare(instruction.IP, ConvertOperand(instruction, 0), InstructionSetIndependentOperand.MakeImmediate(0));
break;
}
goto default;

//Fall through to cmp, as test is just a cmp that doesn't set flags
goto case Mnemonic.Cmp;
case Mnemonic.Cmp:
case Mnemonic.Comiss: //comiss is just a floating point compare
builder.Compare(instruction.IP, ConvertOperand(instruction, 0), ConvertOperand(instruction, 1));
break;
case Mnemonic.Jmp:
Expand Down Expand Up @@ -312,6 +365,11 @@ private void ConvertInstructionStatement(Instruction instruction, IsilBuilder bu
case Mnemonic.Int3:
builder.Interrupt(instruction.IP); // We'll add it but eliminate later
break;
case Mnemonic.Nop:
//While this is literally a nop and there's in theory no point emitting anything for it, it could be used as a jump target.
//So we'll emit an ISIL nop for it.
builder.Nop(instruction.IP);
break;
default:
builder.NotImplemented(instruction.IP, FormatInstruction(instruction));
break;
Expand Down

0 comments on commit 671f78c

Please sign in to comment.