public ReplaceInstructionOnly ( |
||
instruction | The instruction. | |
return | void |
/// <summary> /// Visitation function for AddFloat. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.AddFloat(Context context) { if (context.Result.IsR4) { context.ReplaceInstructionOnly(X86.Addss); context.Size = InstructionSize.Size32; } else { context.ReplaceInstructionOnly(X86.Addsd); context.Size = InstructionSize.Size64; } }
/// <summary> /// Addresses the of instruction. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.AddressOf(Context context) { Operand result = context.Result; Operand register = AllocateVirtualRegister(result.Type); context.Result = register; context.ReplaceInstructionOnly(X86.Lea); context.AppendInstruction(X86.Mov, result, register); }
/// <summary> /// Addresses the of instruction. /// </summary> /// <param name="context">The context.</param> void IR.IIRVisitor.AddressOfInstruction(Context context) { var opRes = context.Result; RegisterOperand register = new RegisterOperand(opRes.Type, GeneralPurposeRegister.EAX); context.Result = register; context.ReplaceInstructionOnly(Instruction.LeaInstruction); //context.Ignore = true; context.AppendInstruction(Instruction.MovInstruction, opRes, register); }
/// <summary> /// Addresses the of instruction. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.AddressOf(Context context) { var opRes = context.Result; Operand register = Operand.CreateCPURegister(opRes.Type, GeneralPurposeRegister.EAX); //VirtualRegisterOperand register = AllocateVirtualRegister(opRes.Type); context.Result = register; context.ReplaceInstructionOnly(X86.Lea); context.AppendInstruction(X86.Mov, opRes, register); }
/// <summary> /// Addresses the of instruction. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.AddressOf(Context context) { var opRes = context.Result; RegisterOperand register = new RegisterOperand(opRes.Type, GeneralPurposeRegister.EAX); //VirtualRegisterOperand register = methodCompiler.VirtualRegisterLayout.AllocateVirtualRegister(opRes.Type); context.Result = register; context.ReplaceInstructionOnly(X86.Lea); context.AppendInstruction(X86.Mov, opRes, register); }
private void PerformStaticAllocationOf(Context allocation, Context assignment) { RuntimeType allocatedType = allocation.InvokeTarget.DeclaringType; // Allocate a linker symbol to refer to for this allocation. Use the destination field name as the linker symbol name. string symbolName = assignment.RuntimeField.ToString() + @"<<$cctor"; using (var stream = methodCompiler.Linker.Allocate(symbolName, SectionKind.BSS, typeLayout.GetTypeSize(allocatedType), 4)) { // FIXME: Do we have to initialize this? string methodTableSymbol = GetMethodTableForType(allocatedType); if (methodTableSymbol != null) methodCompiler.Linker.Link(LinkType.AbsoluteAddress | LinkType.NativeI4, symbolName, 0, 0, methodTableSymbol, IntPtr.Zero); } // Issue a load request before the newobj and before the assignment. Operand symbol1 = this.InsertLoadBeforeInstruction(allocation, symbolName, assignment.RuntimeField.SignatureType); allocation.Operand1 = symbol1; Operand symbol2 = this.InsertLoadBeforeInstruction(assignment, symbolName, assignment.RuntimeField.SignatureType); assignment.Operand1 = symbol2; // Change the newobj to a call and increase the operand count to include the this ptr. allocation.OperandCount++; allocation.ResultCount = 0; allocation.ReplaceInstructionOnly(Instruction.Get(OpCode.Call)); }
/// <summary> /// Visitation function for SignExtendedMoveInstruction instructions. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.SignExtendedMove(Context context) { context.ReplaceInstructionOnly(X86.Movsx); }
/// <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; //context.Operand1 = EmitConstant(context.Operand1); if (context.Result.StackType == StackTypeCode.F) { // TODO: } else if (context.Result.IsMemoryAddress && context.Operand1.IsMemoryAddress) { Operand load = Operand.CreateCPURegister(BuiltInSigType.IntPtr, GeneralPurposeRegister.R9); context.SetInstruction(AVR32.Ld, load, operand); context.AppendInstruction(AVR32.St, result, load); //if (!Is32Bit(operand) && IsSigned(operand)) // context.SetInstruction(Instruction.Movsx, load, operand); //else if (!Is32Bit(operand) && IsUnsigned(operand)) // context.SetInstruction(Instruction.Movzx, load, operand); //else // context.SetInstruction(Instruction.Mov, load, operand); //context.AppendInstruction(Instruction.Mov, result, store); } else if (context.Result.IsRegister && context.Operand1.IsMemoryAddress) { context.ReplaceInstructionOnly(AVR32.Ld); } else if (context.Result.IsMemoryAddress && context.Operand1.IsRegister) { context.SetInstruction(AVR32.St, result, operand); } else if (context.Result.IsRegister && context.Operand1.IsRegister) { context.ReplaceInstructionOnly(AVR32.Mov); } else if (context.Result.IsMemoryAddress && context.Operand1.IsConstant) { Operand load = Operand.CreateCPURegister(BuiltInSigType.IntPtr, GeneralPurposeRegister.R9); context.SetInstruction(AVR32.Mov, load, operand); context.AppendInstruction(AVR32.St, result, load); } else if (context.Result.IsMemoryAddress && context.Operand1.IsSymbol) { //context.SetInstruction(Instruction.St, result, operand); } }
/// <summary> /// Visitation function for <see cref="IX86Visitor.Movsx"/> instructions. /// </summary> /// <param name="context">The context.</param> void IX86Visitor.Movsx(Context context) { if (Is32Bit(context.Operand1)) { context.ReplaceInstructionOnly(X86.Mov); } else { Operand result = context.Result; if (!(result is RegisterOperand)) { RegisterOperand ecx = new RegisterOperand(context.Result.Type, GeneralPurposeRegister.ECX); context.Result = ecx; context.AppendInstruction(X86.Mov, result, ecx); } } }
/// <summary> /// Visitation function for SubSigned. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.SubSigned(Context context) { context.ReplaceInstructionOnly(ARMv6.Sub); }
/// <summary> /// Visitation function for <see cref="IX86Visitor.Movzx"/> instructions. /// </summary> /// <param name="context">The context.</param> public void Movzx(Context context) { if (context.Operand1.IsInt || context.Operand1.IsPointer || !context.Operand1.IsValueType) { context.ReplaceInstructionOnly(X86.Mov); } }
/// <summary> /// Visitation function for MoveInstruction. /// </summary> /// <param name="context">The context.</param> void IR.IIRVisitor.Move(Context context) { Operand result = context.Result; Operand operand = context.Operand1; //context.Operand1 = EmitConstant(context.Operand1); if (context.Result.StackType == StackTypeCode.F) { // TODO: } else { if (context.Result is MemoryOperand && context.Operand1 is MemoryOperand) { RegisterOperand load = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.R9); context.SetInstruction(AVR32.Ld, load, operand); context.AppendInstruction(AVR32.St, result, load); //if (!Is32Bit(operand) && IsSigned(operand)) // context.SetInstruction(Instruction.Movsx, load, operand); //else if (!Is32Bit(operand) && IsUnsigned(operand)) // context.SetInstruction(Instruction.Movzx, load, operand); //else // context.SetInstruction(Instruction.Mov, load, operand); //context.AppendInstruction(Instruction.Mov, result, store); } else if (context.Result is RegisterOperand && context.Operand1 is MemoryOperand) { context.ReplaceInstructionOnly(AVR32.Ld); } else if (context.Result is MemoryOperand && context.Operand1 is RegisterOperand) { context.SetInstruction(AVR32.St, result, operand); } else if (context.Result is RegisterOperand && context.Operand1 is RegisterOperand) { context.ReplaceInstructionOnly(AVR32.Mov); } else if (context.Result is MemoryOperand && context.Operand1 is ConstantOperand) { RegisterOperand load = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.R9); context.SetInstruction(AVR32.Mov, load, operand); context.AppendInstruction(AVR32.St, result, load); } else if (context.Result is MemoryOperand && context.Operand1 is SymbolOperand) { //context.SetInstruction(Instruction.St, result, operand); } else if (context.Result is MemoryOperand && context.Operand1 is LabelOperand) { //context.SetInstruction(Instruction.St, result, operand); } } }
/// <summary> /// Visitation function for IntegerToFloatingPointConversion. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.IntegerToFloatConversion(Context context) { if (context.Result.Type.Type == CilElementType.R4) context.ReplaceInstructionOnly(X86.Cvtsi2ss); else if (context.Result.Type.Type == CilElementType.R8) context.ReplaceInstructionOnly(X86.Cvtsi2sd); else throw new NotSupportedException(); }
/// <summary> /// Visitation function for FloatingPointToIntegerConversionInstruction. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.FloatToIntegerConversion(Context context) { Operand source = context.Operand1; Operand destination = context.Result; switch (destination.Type.Type) { case CilElementType.I1: goto case CilElementType.I4; case CilElementType.I2: goto case CilElementType.I4; case CilElementType.I4: if (source.Type.Type == CilElementType.R8) context.ReplaceInstructionOnly(X86.Cvttsd2si); else context.ReplaceInstructionOnly(X86.Cvttss2si); break; case CilElementType.I8: return; // FIXME: throw new NotSupportedException(); case CilElementType.U1: goto case CilElementType.U4; case CilElementType.U2: goto case CilElementType.U4; case CilElementType.U4: return; // FIXME: throw new NotSupportedException(); case CilElementType.U8: return; // FIXME: throw new NotSupportedException(); case CilElementType.I: goto case CilElementType.I4; case CilElementType.U: goto case CilElementType.U4; } }
/// <summary> /// Visitation function for DivUInstruction. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.DivUnsigned(Context context) { context.ReplaceInstructionOnly(X86.Div); Operand edx = Operand.CreateCPURegister(BuiltInSigType.IntPtr, GeneralPurposeRegister.EDX); Context before = context.InsertBefore(); before.SetInstruction(X86.Xor, edx, edx); if (context.Operand1.IsConstant) { Operand ecx = Operand.CreateCPURegister(context.Operand1.Type, GeneralPurposeRegister.ECX); before.AppendInstruction(X86.Mov, ecx, context.Operand1); context.Operand1 = ecx; } }
/// <summary> /// Special handling for shift operations, which require the shift amount in the ECX or as a constant register. /// </summary> /// <param name="context">The transformation context.</param> /// <param name="instruction">The instruction to transform.</param> private void HandleShiftOperation(Context context, BaseInstruction instruction) { EmitOperandConstants(context); context.ReplaceInstructionOnly(instruction); }
/// <summary> /// Handles the non commutative operation. /// </summary> /// <param name="context">The context.</param> /// <param name="instruction">The instruction.</param> private void HandleNonCommutativeOperation(Context context, BaseInstruction instruction) { EmitResultConstants(context); EmitOperandConstants(context); context.ReplaceInstructionOnly(instruction); }
/// <summary> /// Visitation function for ZeroExtendedMoveInstruction. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.ZeroExtendedMove(Context context) { context.ReplaceInstructionOnly(X86.Movzx); }
/// <summary> /// Visitation function for SignExtendedMoveInstruction"/> instructions. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.SignExtendedMove(Context context) { context.ReplaceInstructionOnly(AVR32.Lds); }
/// <summary> /// Visitation function for CallInstruction"/> instructions. /// </summary> /// <param name="context">The context.</param> void IR.IIRVisitor.Call(Context context) { if (context.OperandCount == 0 && context.BranchTargets != null) { // inter-method call; usually for exception processing context.ReplaceInstructionOnly(AVR32.Rcall); } else { callingConvention.MakeCall(context); } }
/// <summary> /// Visitation function for JmpInstruction. /// </summary> /// <param name="context">The context.</param> void IR.IIRVisitor.Jmp(Context context) { context.ReplaceInstructionOnly(AVR32.Rjmp); }
/// <summary> /// Visitation function for JmpInstruction. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.Jmp(Context context) { context.ReplaceInstructionOnly(X86.Jmp); }
/// <summary> /// Visitation function for SignExtendedMoveInstruction"/> instructions. /// </summary> /// <param name="context">The context.</param> void IR.IIRVisitor.SignExtendedMove(Context context) { var offset = context.Operand2; var type = context.Other as SigType; if (offset != null) { var r8 = new RegisterOperand(BuiltInSigType.Int32, GeneralPurposeRegister.R8); var destination = context.Result; var source = context.Operand1 as MemoryOperand; var elementType = type == null ? GetElementType(source.Type) : GetElementType(type); var constantOffset = offset as ConstantOperand; var offsetPtr = IntPtr.Zero; context.SetInstruction(AVR32.Ld, r8, source); if (constantOffset != null) { offsetPtr = new IntPtr(Convert.ToInt64(constantOffset.Value)); } else { context.AppendInstruction(AVR32.Mov, r8, offset); context.AppendInstruction(AVR32.Add, r8, r8); } context.AppendInstruction(AVR32.Lds, destination, new MemoryOperand(elementType, GeneralPurposeRegister.R8, offsetPtr)); } else { context.ReplaceInstructionOnly(AVR32.Lds); } }
/// <summary> /// Visitation function for LogicalAndInstruction. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.LogicalAnd(Context context) { context.ReplaceInstructionOnly(X86.And); }
/// <summary> /// Visitation function for LogicalOrInstruction. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.LogicalOr(Context context) { context.ReplaceInstructionOnly(ARMv6.Orr); }
/// <summary> /// Visitation function for LogicalXorInstruction. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.LogicalXor(Context context) { context.ReplaceInstructionOnly(X86.Xor); }
/// <summary> /// Visitation function for AddUnsigned. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.AddUnsigned(Context context) { context.ReplaceInstructionOnly(ARMv6.Add); }
/// <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; context.Operand1 = EmitConstant(context.Operand1); if (context.Result.StackType == StackTypeCode.F) { Debug.Assert(context.Operand1.StackType == StackTypeCode.F, @"Move can't convert to floating point type."); if (context.Result.Type.Type == context.Operand1.Type.Type) { if (context.Result.Type.Type == CilElementType.R4) MoveFloatingPoint(context, X86.Movss); else if (context.Result.Type.Type == CilElementType.R8) MoveFloatingPoint(context, X86.Movsd); } else if (context.Result.Type.Type == CilElementType.R8) { context.SetInstruction(X86.Cvtss2sd, context.Result, context.Operand1); } else if (context.Result.Type.Type == CilElementType.R4) { context.SetInstruction(X86.Cvtsd2ss, context.Result, context.Operand1); } } else { if (context.Result.IsMemoryAddress && context.Operand1.IsMemoryAddress) { Operand load = Operand.CreateCPURegister(BuiltInSigType.IntPtr, GeneralPurposeRegister.EDX); Operand store = Operand.CreateCPURegister(operand.Type, GeneralPurposeRegister.EDX); if (!Is32Bit(operand) && IsSigned(operand)) context.SetInstruction(X86.Movsx, load, operand); else if (!Is32Bit(operand) && IsUnsigned(operand)) context.SetInstruction(X86.Movzx, load, operand); else context.SetInstruction(X86.Mov, load, operand); context.AppendInstruction(X86.Mov, result, store); } else context.ReplaceInstructionOnly(X86.Mov); } }
/// <summary> /// Visitation function for <see cref="IX86Visitor.Movzx"/> instructions. /// </summary> /// <param name="context">The context.</param> void IX86Visitor.Movzx(Context context) { if (Is32Bit(context.Operand1)) { context.ReplaceInstructionOnly(X86.Mov); } else { Operand result = context.Result; if (!(result.IsRegister)) { Operand ecx = Operand.CreateCPURegister(context.Result.Type, GeneralPurposeRegister.ECX); context.SetInstruction(X86.Movzx, ecx, context.Operand1); context.AppendInstruction(X86.Mov, result, ecx); } } }
/// <summary> /// Removes the any floating point constant and replace instruction. /// </summary> /// <param name="context">The context.</param> /// <param name="instruction">The instruction.</param> private void ReplaceInstructionAndAnyFloatingPointConstant(Context context, BaseInstruction instruction) { EmitFloatingPointConstants(context); context.ReplaceInstructionOnly(instruction); }