/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var zero = Operand.CreateConstant(0, methodCompiler.TypeSystem); var size = BaseMethodCompilerStage.GetInstructionSize(context.Size, context.InvokeMethod.Signature.Parameters[1].ParameterType); context.SetInstruction(X86.MovStore, size, null, context.Operand1, zero, context.Operand2); }
private static void MovRegToMemory(InstructionNode node, MachineCodeEmitter emitter) { Debug.Assert(node.Operand3.IsRegister); Debug.Assert(node.ResultCount == 0); Debug.Assert(!node.Operand3.IsConstant); var size = BaseMethodCompilerStage.GetInstructionSize(node.Size, node.Operand1.Type); var linkreference = node.Operand1.IsLabel || node.Operand1.IsField || node.Operand1.IsSymbol; // reg to memory 1000 100w: mod reg r/m var opcode = new OpcodeEncoder() .AppendConditionalPrefix(0x66, size == InstructionSize.Size16) // 8:prefix: 16bit .AppendNibble(Bits.b1000) // 4:opcode .Append3Bits(Bits.b100) // 3:opcode .AppendWidthBit(size != InstructionSize.Size8) // 1:width .ModRegRMSIBDisplacement(node.Operand3, node.Operand1, node.Operand2) // Mod-Reg-RM-?SIB-?Displacement .AppendConditionalIntegerValue(0, linkreference); // 32:memory if (linkreference) { emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8); } else { emitter.Emit(opcode); } }
/// <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 + ")"); }
/// <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); }