/// <summary> /// Computes the opcode. /// </summary> /// <param name="size">The size.</param> /// <param name="destination">The destination operand.</param> /// <param name="source">The source operand.</param> /// <returns></returns> /// <exception cref="NotImplementCompilerException"></exception> private OpCode ComputeOpCode(InstructionSize size, Operand destination, Operand source) { Debug.Assert(destination.IsConstant || destination.IsCPURegister); Debug.Assert(size != InstructionSize.None); Debug.Assert(size != InstructionSize.Native); //size = BaseMethodCompilerStage.GetInstructionSize(size, destination); if (destination.IsCPURegister) { if (size == InstructionSize.Size8) return R_8; if (size == InstructionSize.Size16) return R_16; return R_32; } if (destination.IsConstant) { if (size == InstructionSize.Size8) return C_8; if (size == InstructionSize.Size16) return C_16; return C_32; } throw new NotImplementCompilerException(); }
/// <summary> /// Computes the opcode. /// </summary> /// <param name="size">The size.</param> /// <param name="destination">The destination operand.</param> /// <param name="source">The source operand.</param> /// <returns></returns> /// <exception cref="System.ArgumentException">@No opcode for operand type. [ + destination + , + source + )</exception> private OpCode ComputeOpCode(InstructionSize size, Operand destination, Operand source) { Debug.Assert(destination.IsMemoryAddress); Debug.Assert(source.IsRegister || source.IsConstant || source.IsSymbol); size = BaseMethodCompilerStage.GetInstructionSize(size, destination); if (source.IsSymbol) return RM_C; if (source.IsConstant) { if (size == InstructionSize.Size8) return RM_C_U8; if (size == InstructionSize.Size16) return M_C_16; return RM_C; } if (source.IsRegister) { if (size == InstructionSize.Size8) return RM_R_U8; if (size == InstructionSize.Size16) return M_R_16; return M_R; } throw new ArgumentException(@"No opcode for operand type. [" + destination + ", " + source + ")"); }
public static OpcodeEncoder AppendInteger(this OpcodeEncoder encoder, Operand operand, InstructionSize size) { if (size == InstructionSize.Size32) return encoder.AppendIntegerValue(operand.ConstantUnsignedInteger); if (size == InstructionSize.Size8) return encoder.AppendByteValue((byte)operand.ConstantUnsignedInteger); if (size == InstructionSize.Size16) return encoder.AppendShortValue((ushort)operand.ConstantUnsignedInteger); throw new InvalidCompilerException("Instruction size invalid"); }
public OpcodeEncoder AppendIntegerOfSize(Operand operand, InstructionSize size) { if (size == InstructionSize.Size32) { return(AppendIntegerValue(operand.ConstantUnsignedInteger)); } if (size == InstructionSize.Size8) { return(AppendByteValue((byte)operand.ConstantUnsignedInteger)); } if (size == InstructionSize.Size16) { return(AppendShortValue((ushort)operand.ConstantUnsignedInteger)); } throw new CompilerException("Instruction size invalid"); }
/// <summary> /// Computes the opcode. /// </summary> /// <param name="size">The size.</param> /// <param name="destination">The destination operand.</param> /// <param name="source">The source operand.</param> /// <returns></returns> /// <exception cref="System.ArgumentException">@No opcode for operand type. [ + destination + , + source + )</exception> private OpCode ComputeOpCode(InstructionSize size, Operand destination, Operand source) { Debug.Assert(destination.IsRegister); Debug.Assert(source.IsMemoryAddress); size = BaseMethodCompilerStage.GetInstructionSize(size, destination); Debug.Assert(size != InstructionSize.Size64); if (size == InstructionSize.Size8) return R_M_U8; if (size == InstructionSize.Size16) return R_RM_16; return R_RM; }
/// <summary> /// Inserts the load instruction. /// </summary> /// <param name="context">The context.</param> /// <param name="destination">The destination.</param> /// <param name="source">The source.</param> /// <param name="offset">The offset.</param> public override void InsertLoadInstruction(Context context, Operand destination, Operand source, Operand offset) { BaseInstruction instruction = X86.MovLoad; InstructionSize size = InstructionSize.Size32; if (destination.IsR4) { instruction = X86.MovssLoad; } else if (destination.IsR8) { instruction = X86.MovsdLoad; size = InstructionSize.Size64; } context.AppendInstruction(instruction, size, destination, source, offset); }
public override void InsertStoreInstruction(Context context, Operand destination, Operand offset, Operand value) { BaseInstruction instruction = X86.MovStore; InstructionSize size = InstructionSize.Size32; if (value.IsR4) { instruction = X86.MovssStore; } else if (value.IsR8) { instruction = X86.MovsdStore; size = InstructionSize.Size64; } context.AppendInstruction(instruction, size, null, destination, offset, value); }
/// <summary> /// Create platform move. /// </summary> /// <param name="context">The context.</param> /// <param name="destination">The destination.</param> /// <param name="source">The source.</param> public override void InsertMoveInstruction(Context context, Operand destination, Operand source) { BaseInstruction instruction = X86.Mov; InstructionSize size = InstructionSize.Size32; if (destination.IsR4) { instruction = X86.Movss; size = InstructionSize.Size32; } else if (destination.IsR8) { instruction = X86.Movsd; size = InstructionSize.Size64; } context.AppendInstruction(instruction, size, destination, source); }
/// <summary> /// Computes the opcode. /// </summary> /// <param name="size">The size.</param> /// <param name="destination">The destination operand.</param> /// <param name="source">The source operand.</param> /// <returns></returns> /// <exception cref="System.ArgumentException">@No opcode for operand type. [ + destination + , + source + )</exception> private OpCode ComputeOpCode(InstructionSize size, Operand destination, Operand source) { Debug.Assert(destination.IsMemoryAddress); Debug.Assert(source.IsRegister || source.IsConstant || source.IsSymbol); size = BaseMethodCompilerStage.GetInstructionSize(size, destination); if (source.IsSymbol) { return(RM_C); } if (source.IsConstant) { if (size == InstructionSize.Size8) { return(RM_C_U8); } if (size == InstructionSize.Size16) { return(M_C_16); } return(RM_C); } if (source.IsRegister) { if (size == InstructionSize.Size8) { return(RM_R_U8); } if (size == InstructionSize.Size16) { return(M_R_16); } return(M_R); } throw new ArgumentException(@"No opcode for operand type. [" + destination + ", " + source + ")"); }
public static string GetSizeString(InstructionSize size) { switch (size) { case InstructionSize.Size32: return("32"); case InstructionSize.Size8: return("8"); case InstructionSize.Size16: return("16"); case InstructionSize.Size64: return("64"); case InstructionSize.Size128: return("128"); case InstructionSize.Native: return("Native"); default: return(string.Empty); } }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> /// <exception cref="InvalidCompilerException"></exception> void IIntrinsicInternalMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { const InstructionSize size = InstructionSize.Size16; if (context.OperandCount == 1) { context.SetInstruction(IRInstruction.LoadZeroExtended, size, context.Result, context.Operand1, methodCompiler.ConstantZero); } else if (context.OperandCount == 2) { context.SetInstruction(IRInstruction.LoadZeroExtended, size, context.Result, context.Operand1, context.Operand2); } else { throw new InvalidCompilerException(); } LoadStore.OrderLoadOperands(context.Node, methodCompiler); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> /// <exception cref="InvalidCompilerException"></exception> void IIntrinsicInternalMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { const InstructionSize size = InstructionSize.Size32; if (context.OperandCount == 2) { context.SetInstruction(IRInstruction.StoreInteger, size, null, context.Operand1, methodCompiler.ConstantZero, context.Operand2); } else if (context.OperandCount == 3) { context.SetInstruction(IRInstruction.StoreInteger, size, null, context.Operand1, context.Operand2, context.Operand3); } else { throw new InvalidCompilerException(); } LoadStore.OrderStoreOperands(context.Node, methodCompiler); }
/// <summary> /// Computes the opcode. /// </summary> /// <param name="size">The size.</param> /// <param name="destination">The destination operand.</param> /// <param name="source">The source operand.</param> /// <returns></returns> /// <exception cref="System.ArgumentException">@No opcode for operand type. [ + destination + , + source + )</exception> private OpCode ComputeOpCode(InstructionSize size, Operand destination, Operand source) { Debug.Assert(destination.IsRegister); Debug.Assert(source.IsMemoryAddress); size = BaseMethodCompilerStage.GetInstructionSize(size, destination); Debug.Assert(size != InstructionSize.Size64); if (size == InstructionSize.Size8) { return(R_M_U8); } if (size == InstructionSize.Size16) { return(R_RM_16); } return(R_RM); }
/// <summary> /// Computes the opcode. /// </summary> /// <param name="size">The size.</param> /// <param name="destination">The destination operand.</param> /// <param name="source">The source operand.</param> /// <returns></returns> /// <exception cref="NotImplementCompilerException"></exception> private OpCode ComputeOpCode(InstructionSize size, Operand destination, Operand source) { Debug.Assert(destination.IsConstant || destination.IsCPURegister); Debug.Assert(size != InstructionSize.None); Debug.Assert(size != InstructionSize.Native); //size = BaseMethodCompilerStage.GetInstructionSize(size, destination); if (destination.IsCPURegister) { if (size == InstructionSize.Size8) { return(R_8); } if (size == InstructionSize.Size16) { return(R_16); } return(R_32); } if (destination.IsConstant) { if (size == InstructionSize.Size8) { return(C_8); } if (size == InstructionSize.Size16) { return(C_16); } return(C_32); } throw new NotImplementCompilerException(); }
/// <summary> /// Visitation function for MoveInstruction. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.Move(Context context) { Operand result = context.Result; Operand operand = context.Operand1; X86Instruction instruction = X86.Mov; InstructionSize size = InstructionSize.None; if (result.IsR) { //Debug.Assert(operand.IsFloatingPoint, @"Move can't convert to floating point type."); if (result.Type == operand.Type) { if (result.IsR4) { instruction = X86.Movss; size = InstructionSize.Size32; } else if (result.IsR8) { instruction = X86.Movsd; size = InstructionSize.Size64; } } else if (result.IsR8) { instruction = X86.Cvtss2sd; } else if (result.IsR4) { instruction = X86.Cvtsd2ss; } } context.ReplaceInstructionOnly(instruction); context.Size = size; }
public OpcodeEncoder AppendConditionalIntegerOfSize(bool include, Operand operand, InstructionSize size) { if (!include) { return(this); } return(AppendIntegerOfSize(operand, size)); }
/// <summary> /// Expands the signed move instruction for 64-bits. /// </summary> /// <param name="context">The context.</param> private void ExpandSignedMove(Context context) { Operand op0 = context.Result; Operand op1 = context.Operand1; Debug.Assert(op0 != null, @"I8 not in a memory operand!"); Operand op0L, op0H; SplitLongOperand(op0, out op0L, out op0H); if (op1.IsBoolean) { context.SetInstruction(X86.Movzx, InstructionSize.Size8, op0L, op1); context.AppendInstruction(X86.Mov, op0H, ConstantZero); } else if (op1.IsI1 || op1.IsI2) { Operand v1 = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); Operand v2 = AllocateVirtualRegister(TypeSystem.BuiltIn.U4); Operand v3 = AllocateVirtualRegister(TypeSystem.BuiltIn.U4); InstructionSize size = op1.IsI1 ? InstructionSize.Size8 : InstructionSize.Size16; context.SetInstruction(X86.Movsx, size, v1, op1); context.AppendInstruction2(X86.Cdq, v3, v2, v1); context.AppendInstruction(X86.Mov, op0L, v2); context.AppendInstruction(X86.Mov, op0H, v3); } else if (op1.IsI4 || op1.IsU4 || op1.IsPointer || op1.IsI || op1.IsU) { Operand v1 = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); Operand v2 = AllocateVirtualRegister(TypeSystem.BuiltIn.U4); Operand v3 = AllocateVirtualRegister(TypeSystem.BuiltIn.U4); context.SetInstruction(X86.Mov, v1, op1); context.AppendInstruction2(X86.Cdq, v3, v2, v1); context.AppendInstruction(X86.Mov, op0L, v2); context.AppendInstruction(X86.Mov, op0H, v3); } else if (op1.IsI8) { context.SetInstruction(X86.Mov, op0, op1); } else if (op1.IsU1 || op1.IsU2) { Operand v1 = AllocateVirtualRegister(TypeSystem.BuiltIn.U4); Operand v2 = AllocateVirtualRegister(TypeSystem.BuiltIn.U4); Operand v3 = AllocateVirtualRegister(TypeSystem.BuiltIn.U4); InstructionSize size = op1.IsI1 ? InstructionSize.Size8 : InstructionSize.Size16; context.SetInstruction(X86.Movzx, size, v1, op1); context.AppendInstruction2(X86.Cdq, v3, v2, v1); context.AppendInstruction(X86.Mov, op0L, v2); context.AppendInstruction(X86.Mov, op0H, ConstantZero); } else { throw new InvalidCompilerException(); } }
/// <summary> /// Appends the instruction after the current index. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="size">The size.</param> /// <param name="result">The result.</param> /// <param name="operand1">The operand1.</param> public void AppendInstruction(BaseInstruction instruction, InstructionSize size, Operand result, Operand operand1) { AppendInstruction(instruction, result, operand1); Size = size; }
/// <summary> /// Sets the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="size">The size.</param> /// <param name="result">The result.</param> /// <param name="operand1">The operand1.</param> /// <param name="operand2">The operand2.</param> /// <param name="operand3">The operand3.</param> public void SetInstruction(BaseInstruction instruction, InstructionSize size, Operand result, Operand operand1, Operand operand2, Operand operand3) { SetInstruction(instruction, result, operand1, operand2, operand3); Size = size; }
/// <summary> /// Sets the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="size">The size.</param> /// <param name="result">The result.</param> /// <param name="operand1">The operand1.</param> public void SetInstruction(BaseInstruction instruction, InstructionSize size, Operand result, Operand operand1) { Node.SetInstruction(instruction, size, result, operand1); }
/// <summary> /// Appends the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="size">The size.</param> /// <param name="result">The result.</param> /// <param name="operand1">The operand1.</param> /// <param name="operand2">The operand2.</param> public void AppendInstruction(BaseInstruction instruction, InstructionSize size, Operand result, Operand operand1, Operand operand2) { AppendInstruction(); SetInstruction(instruction, size, result, operand1, operand2); }
/// <summary> /// Appends the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="size">The size.</param> /// <param name="result">The result.</param> /// <param name="operand1">The operand1.</param> /// <param name="operand2">The operand2.</param> /// <param name="operand3">The operand3.</param> /// <param name="operand4">The operand4.</param> public void AppendInstruction(BaseInstruction instruction, InstructionSize size, Operand result, Operand operand1, Operand operand2, Operand operand3, Operand operand4) { AppendInstruction(); Node.SetInstruction(instruction, size, result, operand1, operand2, operand3, operand4); }
/// <summary> /// Floating point compare instruction. /// </summary> /// <param name="context">The context.</param> /// <param name="instruction">The instruction.</param> /// <param name="size">The size.</param> private void FloatCompare(Context context, X86Instruction instruction, InstructionSize size) { Operand result = context.Result; Operand left = context.Operand1; Operand right = context.Operand2; ConditionCode condition = context.ConditionCode; // normalize condition switch (condition) { case ConditionCode.Equal: break; case ConditionCode.NotEqual: break; case ConditionCode.UnsignedGreaterOrEqual: condition = ConditionCode.GreaterOrEqual; break; case ConditionCode.UnsignedGreaterThan: condition = ConditionCode.GreaterThan; break; case ConditionCode.UnsignedLessOrEqual: condition = ConditionCode.LessOrEqual; break; case ConditionCode.UnsignedLessThan: condition = ConditionCode.LessThan; break; } Debug.Assert(!(left.IsR4 && right.IsR8)); Debug.Assert(!(left.IsR8 && right.IsR4)); switch (condition) { case ConditionCode.Equal: { // a==b // mov eax, 1 // ucomisd xmm0, xmm1 // jp L3 // jne L3 // ret //L3: // mov eax, 0 var newBlocks = CreateNewBlockContexts(2); var nextBlock = Split(context); context.SetInstruction(X86.Mov, result, CreateConstant(1)); context.AppendInstruction(instruction, size, null, left, right); context.AppendInstruction(X86.Branch, ConditionCode.Parity, newBlocks[1].Block); context.AppendInstruction(X86.Jmp, newBlocks[0].Block); newBlocks[0].AppendInstruction(X86.Branch, ConditionCode.NotEqual, newBlocks[1].Block); newBlocks[0].AppendInstruction(X86.Jmp, nextBlock.Block); newBlocks[1].AppendInstruction(X86.Mov, result, ConstantZero); newBlocks[1].AppendInstruction(X86.Jmp, nextBlock.Block); break; } case ConditionCode.NotEqual: { // a!=b // mov eax, 1 // ucomisd xmm0, xmm1 // jp L5 // setne al // movzx eax, al //L5: var newBlocks = CreateNewBlockContexts(1); var nextBlock = Split(context); context.SetInstruction(X86.Mov, result, CreateConstant(1)); context.AppendInstruction(instruction, size, null, left, right); context.AppendInstruction(X86.Branch, ConditionCode.Parity, nextBlock.Block); context.AppendInstruction(X86.Jmp, newBlocks[0].Block); newBlocks[0].AppendInstruction(X86.Setcc, ConditionCode.NotEqual, result); //newBlocks[0].AppendInstruction(X86.Movzx, InstructionSize.Size8, result, result); newBlocks[0].AppendInstruction(X86.Jmp, nextBlock.Block); break; } case ConditionCode.LessThan: { // a<b // mov eax, 0 // ucomisd xmm1, xmm0 // seta al context.SetInstruction(X86.Mov, result, ConstantZero); context.AppendInstruction(instruction, size, null, right, left); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterThan, result); break; } case ConditionCode.GreaterThan: { // a>b // mov eax, 0 // ucomisd xmm0, xmm1 // seta al context.SetInstruction(X86.Mov, result, ConstantZero); context.AppendInstruction(instruction, size, null, left, right); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterThan, result); break; } case ConditionCode.LessOrEqual: { // a<=b // mov eax, 0 // ucomisd xmm1, xmm0 // setae al context.SetInstruction(X86.Mov, result, ConstantZero); context.AppendInstruction(instruction, size, null, right, left); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterOrEqual, result); break; } case ConditionCode.GreaterOrEqual: { // a>=b // mov eax, 0 // ucomisd xmm0, xmm1 // setae al context.SetInstruction(X86.Mov, result, ConstantZero); context.AppendInstruction(instruction, size, null, left, right); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterOrEqual, result); break; } } }
/// <summary> /// Gets the size of the instruction. /// </summary> /// <param name="size">The size.</param> /// <param name="type">The type.</param> /// <returns></returns> public static InstructionSize GetInstructionSize(InstructionSize size, MosaType type) { if (size != InstructionSize.None) return size; return GetInstructionSize(type); }
/// <summary> /// Sets the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="size">The size.</param> /// <param name="result">The result.</param> /// <param name="operand1">The operand1.</param> /// <param name="operand2">The operand2.</param> /// <param name="operand3">The operand3.</param> public void SetInstruction(BaseInstruction instruction, InstructionSize size, Operand result, Operand operand1, Operand operand2, Operand operand3) { Node.SetInstruction(instruction, size, result, operand1, operand2, operand3); }
/// <summary> /// Gets the size of the instruction. /// </summary> /// <param name="size">The size.</param> /// <param name="operand">The operand.</param> /// <returns></returns> public static InstructionSize GetInstructionSize(InstructionSize size, Operand operand) { if (size != InstructionSize.None) return size; return GetInstructionSize(operand); }
/// <summary> /// Floating point compare instruction. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.FloatCompare(Context context) { Operand result = context.Result; Operand left = context.Operand1; Operand right = context.Operand2; ConditionCode condition = context.ConditionCode; // normalize condition switch (condition) { case ConditionCode.Equal: break; case ConditionCode.NotEqual: break; case ConditionCode.UnsignedGreaterOrEqual: condition = ConditionCode.GreaterOrEqual; break; case ConditionCode.UnsignedGreaterThan: condition = ConditionCode.GreaterThan; break; case ConditionCode.UnsignedLessOrEqual: condition = ConditionCode.LessOrEqual; break; case ConditionCode.UnsignedLessThan: condition = ConditionCode.LessThan; break; } // TODO - Move the following to its own pre-IR decomposition stage for this instruction // Swap, if necessary, the operands to place register operand first than memory operand // otherwise the memory operand will have to be loaded into a register if ((condition == ConditionCode.Equal || condition == ConditionCode.NotEqual) && left.IsMemoryAddress && !right.IsMemoryAddress) { // swap order of operands to move var t = left; left = right; right = t; } Context before = context.InsertBefore(); // Compare using the smallest precision if (left.IsR4 && right.IsR8) { Operand rop = AllocateVirtualRegister(TypeSystem.BuiltIn.R4); before.SetInstruction(X86.Cvtsd2ss, rop, right); right = rop; } if (left.IsR8 && right.IsR4) { Operand rop = AllocateVirtualRegister(TypeSystem.BuiltIn.R4); before.SetInstruction(X86.Cvtsd2ss, rop, left); left = rop; } X86Instruction instruction = null; InstructionSize size = InstructionSize.None; if (left.IsR4) { instruction = X86.Ucomiss; size = InstructionSize.Size32; } else { instruction = X86.Ucomisd; size = InstructionSize.Size64; } switch (condition) { case ConditionCode.Equal: { // a==b // mov eax, 1 // ucomisd xmm0, xmm1 // jp L3 // jne L3 // ret //L3: // mov eax, 0 var newBlocks = CreateNewBlockContexts(2); Context nextBlock = Split(context); context.SetInstruction(X86.Mov, result, Operand.CreateConstant(TypeSystem, 1)); context.AppendInstruction(instruction, size, null, left, right); context.AppendInstruction(X86.Branch, ConditionCode.Parity, newBlocks[1].Block); context.AppendInstruction(X86.Jmp, newBlocks[0].Block); newBlocks[0].AppendInstruction(X86.Branch, ConditionCode.NotEqual, newBlocks[1].Block); newBlocks[0].AppendInstruction(X86.Jmp, nextBlock.Block); newBlocks[1].AppendInstruction(X86.Mov, result, ConstantZero); newBlocks[1].AppendInstruction(X86.Jmp, nextBlock.Block); break; } case ConditionCode.NotEqual: { // a!=b // mov eax, 1 // ucomisd xmm0, xmm1 // jp L5 // setne al // movzx eax, al //L5: var newBlocks = CreateNewBlockContexts(1); Context nextBlock = Split(context); context.SetInstruction(X86.Mov, result, Operand.CreateConstant(TypeSystem, 1)); context.AppendInstruction(instruction, size, null, left, right); context.AppendInstruction(X86.Branch, ConditionCode.Parity, nextBlock.Block); context.AppendInstruction(X86.Jmp, newBlocks[0].Block); newBlocks[0].AppendInstruction(X86.Setcc, ConditionCode.NotEqual, result); newBlocks[0].AppendInstruction(X86.Movzx, result, result); newBlocks[0].AppendInstruction(X86.Jmp, nextBlock.Block); break; } case ConditionCode.LessThan: { // a<b // mov eax, 0 // ucomisd xmm1, xmm0 // seta al context.SetInstruction(X86.Mov, result, ConstantZero); context.AppendInstruction(instruction, size, null, right, left); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterThan, result); break; } case ConditionCode.GreaterThan: { // a>b // mov eax, 0 // ucomisd xmm0, xmm1 // seta al context.SetInstruction(X86.Mov, result, ConstantZero); context.AppendInstruction(instruction, size, null, left, right); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterThan, result); break; } case ConditionCode.LessOrEqual: { // a<=b // mov eax, 0 // ucomisd xmm1, xmm0 // setae al context.SetInstruction(X86.Mov, result, ConstantZero); context.AppendInstruction(instruction, size, null, right, left); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterOrEqual, result); break; } case ConditionCode.GreaterOrEqual: { // a>=b // mov eax, 0 // ucomisd xmm0, xmm1 // setae al context.SetInstruction(X86.Mov, result, ConstantZero); context.AppendInstruction(instruction, size, null, left, right); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterOrEqual, result); break; } } }
/// <summary> /// Appends the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="size">The size.</param> /// <param name="result">The result.</param> /// <param name="operand1">The operand1.</param> public void AppendInstruction(BaseInstruction instruction, InstructionSize size, Operand result, Operand operand1) { AppendInstruction(); Node.SetInstruction(instruction, size, result, operand1); }
public void EmitNew(OpCode opCode, ConstructorInfo constructor, int?argumentCount = null, int?resultCount = null) { ilSize += InstructionSize.Get(opCode); AdjustStack(opCode, argumentCount ?? constructor.GetParameters().Length, resultCount); }
public static string GetSizeString(InstructionSize size) { switch (size) { case InstructionSize.Size32: return "32"; case InstructionSize.Size8: return "8"; case InstructionSize.Size16: return "16"; case InstructionSize.Size64: return "64"; case InstructionSize.Size128: return "128"; case InstructionSize.Native: return "Native"; default: return string.Empty; } }
/// <summary> /// Replaces the instruction only. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="size">The size.</param> public void ReplaceInstruction(BaseInstruction instruction, InstructionSize size) { Instruction = instruction; Size = size; }