/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); throw new NotImplementedException(); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); // Opcode specific handling int index; switch (opcode) { case OpCode.Ldloc: case OpCode.Ldloc_s: index = (int)decoder.Instruction.Operand; break; case OpCode.Ldloc_0: index = 0; break; case OpCode.Ldloc_1: index = 1; break; case OpCode.Ldloc_2: index = 2; break; case OpCode.Ldloc_3: index = 3; break; default: throw new InvalidMetadataException(); } // Push the loaded value onto the evaluation stack var local = decoder.Compiler.LocalVariables[index]; var result = AllocateVirtualRegisterOrStackSlot(decoder.Compiler, local.Type); ctx.Operand1 = local; ctx.Result = result; }
/// <summary> /// Decodes the specified CIL instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> /// <remarks> /// This method is used by instructions to retrieve immediate operands /// From the instruction stream. /// </remarks> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); int index; // Opcode specific handling switch (opcode) { case OpCode.Ldarg: case OpCode.Ldarg_s: index = (int)decoder.Instruction.Operand; break; case OpCode.Ldarg_0: index = 0; break; case OpCode.Ldarg_1: index = 1; break; case OpCode.Ldarg_2: index = 2; break; case OpCode.Ldarg_3: index = 3; break; default: throw new System.NotImplementedException(); } // Push the loaded value onto the evaluation stack var parameterOperand = decoder.Compiler.GetParameterOperand(index); var result = LoadInstruction.CreateResultOperand(decoder, parameterOperand.Type); ctx.Operand1 = parameterOperand; ctx.Result = result; }
/// <summary> /// Gets the instruction modifier. /// </summary> /// <param name="node">The context.</param> /// <returns></returns> protected override string GetModifier(InstructionNode node) { switch (((node.Instruction) as CIL.BaseCILInstruction).OpCode) { case OpCode.Beq_s: return @"=="; case OpCode.Beq: return @"=="; case OpCode.Bge_s: return @">="; case OpCode.Bge: return @">="; case OpCode.Bge_un_s: return @">= unordered"; case OpCode.Bge_un: return @">= unordered"; case OpCode.Bgt_s: return @">"; case OpCode.Bgt: return @">"; case OpCode.Bgt_un_s: return @"> unordered"; case OpCode.Bgt_un: return @"> unordered"; case OpCode.Ble_s: return @"<="; case OpCode.Ble: return @"<="; case OpCode.Ble_un_s: return @"<= unordered"; case OpCode.Ble_un: return @"<= unordered"; case OpCode.Blt_s: return @"<"; case OpCode.Blt: return @"<"; case OpCode.Blt_un_s: return @"< unordered"; case OpCode.Blt_un: return @"< unordered"; case OpCode.Bne_un_s: return @"!= unordered"; case OpCode.Bne_un: return @"!= unordered"; default: throw new InvalidOperationException(@"Opcode not set."); } }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); // Push the address on the stack ctx.Result = decoder.Compiler.CreateVirtualRegister(decoder.TypeSystem.BuiltIn.U); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); // FIXME: Validate operands & verify instruction ctx.Result = decoder.Compiler.CreateVirtualRegister(decoder.TypeSystem.BuiltIn.I4); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); // Set the result ctx.Result = decoder.Compiler.CreateVirtualRegister(decoder.TypeSystem.BuiltIn.I4); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); var type = (MosaType)decoder.Instruction.Operand; ctx.Result = decoder.Compiler.CreateVirtualRegister(type.ToManagedPointer()); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); var type = (MosaType)decoder.Instruction.Operand; throw new NotImplementCompilerException(); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); var block = decoder.GetBlock((int)decoder.Instruction.Operand); ctx.AddBranchTarget(block); }
/// <summary> /// Emits the constant operands. /// </summary> /// <param name="node">The node.</param> protected void EmitFloatingPointConstants(InstructionNode node) { if (node.OperandCount > 0) node.Operand1 = EmitFloatingPointConstant(node.Operand1); if (node.OperandCount > 1) node.Operand2 = EmitFloatingPointConstant(node.Operand2); if (node.OperandCount > 2) node.Operand3 = EmitFloatingPointConstant(node.Operand3); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); byte nocheck = (byte)decoder.Instruction.Operand; //FUTURE: //ctx.Other = nocheck; }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); var type = (MosaType)decoder.Instruction.Operand; ctx.Result = decoder.Compiler.CreateVirtualRegister(decoder.TypeSystem.BuiltIn.Object); ctx.MosaType = type; }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); var type = (MosaMethod)decoder.Instruction.Operand; //TODO throw new NotImplementedException(); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); var type = (MosaType)decoder.Instruction.Operand; ctx.Result = decoder.Compiler.AllocateVirtualRegisterOrStackSlot(type); ctx.ResultCount = 1; }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); // Retrieve the type reference var type = (MosaType)decoder.Instruction.Operand; ctx.MosaType = type; }
private static bool CheckAssignmentForCompliance(InstructionNode allocation, InstructionNode assignment) { // Only direct assignment without any casts is compliant. We can't perform casts or anything alike here, // as that is hard to complete at this point of time. var allocationType = (allocation.InvokeMethod != null) ? allocation.InvokeMethod.DeclaringType : allocation.Result.Type.ElementType; var storageType = (allocation.Instruction is CIL.NewarrInstruction) ? assignment.Operand1.Type.ElementType : assignment.MosaField.DeclaringType; return ReferenceEquals(allocationType, storageType); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); MosaType type = (elementType == null) ? type = (MosaType)decoder.Instruction.Operand : type = decoder.TypeSystem.GetTypeFromTypeCode(elementType.Value); ctx.Result = LoadInstruction.CreateResultOperand(decoder, type); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { base.Decode(ctx, decoder); var field = (MosaField)decoder.Instruction.Operand; decoder.Compiler.Scheduler.TrackFieldReferenced(field); ctx.MosaField = field; ctx.Result = AllocateVirtualRegisterOrStackSlot(decoder.Compiler, field.FieldType.ToManagedPointer()); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); var field = (MosaField)decoder.Instruction.Operand; decoder.Compiler.Scheduler.TrackFieldReferenced(field); ctx.MosaField = field; }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); MosaType type = (elementType == null) ? type = (MosaType)decoder.Instruction.Operand : type = decoder.TypeSystem.GetTypeFromTypeCode(elementType.Value); ctx.Result = AllocateVirtualRegisterOrStackSlot(decoder.Compiler, type); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); // Retrieve a type reference from the immediate argument // FIXME: Limit the token types var token = (MosaType)decoder.Instruction.Operand; throw new NotImplementedException(); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); // Opcode specific handling Operand local = decoder.Compiler.GetLocalOperand((int)decoder.Instruction.Operand); ctx.Operand1 = local; ctx.Result = decoder.Compiler.CreateVirtualRegister(local.Type.ToManagedPointer()); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { base.Decode(ctx, decoder); var field = (MosaField)decoder.Instruction.Operand; decoder.Compiler.Scheduler.TrackFieldReferenced(field); ctx.MosaField = field; ctx.Result = LoadInstruction.CreateResultOperand(decoder, field.FieldType.ToManagedPointer()); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); var field = (MosaField)decoder.Instruction.Operand; decoder.Compiler.Scheduler.TrackFieldReferenced(field); ctx.MosaField = field; ctx.Result = LoadInstruction.CreateResultOperand(decoder, field.FieldType); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode the base first base.Decode(ctx, decoder); // The argument is the result ctx.Result = decoder.Compiler.Parameters[(int)decoder.Instruction.Operand]; // FIXME: Do some type compatibility checks // See verification for this instruction and // verification types. }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); var method = (MosaMethod)decoder.Instruction.Operand; decoder.Compiler.Scheduler.TrackMethodInvoked(method); ctx.Result = decoder.Compiler.CreateVirtualRegister(decoder.TypeSystem.ToFnPtr(method.Signature)); ctx.InvokeMethod = method; }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); // Opcode specific handling int index = (int)decoder.Instruction.Operand; var parameterOperand = decoder.Compiler.Parameters[index]; ctx.Operand1 = parameterOperand; ctx.Result = decoder.Compiler.CreateVirtualRegister(parameterOperand.Type.ToManagedPointer()); }
public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); var type = (MosaType)decoder.Instruction.Operand; //Operand result = decoder.Compiler.CreateVirtualRegister(type); //ctx.Result = result; ctx.Result = LoadInstruction.CreateResultOperand(decoder, type); ctx.MosaType = type; }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); var field = (MosaField)decoder.Instruction.Operand; decoder.Compiler.Scheduler.TrackFieldReferenced(field); ctx.MosaField = field; ctx.Result = decoder.Compiler.CreateVirtualRegister(field.FieldType.ToManagedPointer()); }
/// <summary> /// Emits the instruction. /// </summary> /// <param name="node">The node.</param> /// <param name="codeEmitter">The code emitter.</param> protected virtual void EmitInstruction(InstructionNode node, BaseCodeEmitter codeEmitter) { (node.Instruction as BasePlatformInstruction).Emit(node, codeEmitter); }
private void Phi(InstructionNode node) { //if (Trace.Active) Trace.Log(node.ToString()); var result = GetVariableState(node.Result); if (result.IsOverDefined) { return; } var sourceBlocks = node.PhiBlocks; var currentBlock = node.Block; //if (Trace.Active) Trace.Log("Loop: " + currentBlock.PreviousBlocks.Count.ToString()); for (var index = 0; index < currentBlock.PreviousBlocks.Count; index++) { var predecessor = sourceBlocks[index]; phiStatements.AddIfNew(predecessor, node); bool executable = blockStates[predecessor.Sequence]; //if (Trace.Active) Trace.Log("# " + index.ToString() + ": " + predecessor.ToString() + " " + (executable ? "Yes" : "No")); if (!executable) { continue; } if (result.IsOverDefined) { continue; } var op = node.GetOperand(index); var operand = GetVariableState(op); //if (Trace.Active) Trace.Log("# " + index.ToString() + ": " + operand.ToString()); CheckAndUpdateNullAssignment(result, operand); if (operand.IsOverDefined) { UpdateToOverDefined(result); continue; } else if (operand.IsSingleConstant) { UpdateToConstant(result, operand.ConstantUnsignedLongInteger); continue; } else if (operand.HasMultipleConstants) { foreach (var c in operand.Constants) { UpdateToConstant(result, c); if (result.IsOverDefined) { break; } } } } }
/// <summary> /// Simple copy propagation. /// </summary> /// <param name="node">The node.</param> protected void SimpleForwardCopyPropagation(InstructionNode node) { var result = node.Result; var source = node.Operand1; if (!result.IsVirtualRegister) { return; } if (!source.IsVirtualRegister) { return; } if (result.Definitions.Count != 1) { return; } if (source.Definitions.Count != 1) { return; } if (!source.IsResolvedConstant) { return; } if (node.StatusRegister == StatusRegister.Set) { return; } if (node.ConditionCode != ConditionCode.Always) { return; } Debug.Assert(result != source); changed = true; //ReplaceOperand(result, source); foreach (var useNode in result.Uses.ToArray()) { for (int i = 0; i < useNode.OperandCount; i++) { var operand = useNode.GetOperand(i); if (result == operand) { trace?.Log("*** SimpleForwardCopyPropagation"); trace?.Log($"BEFORE:\t{useNode}"); useNode.SetOperand(i, source); trace?.Log($"AFTER: \t{useNode}"); } } } Debug.Assert(result.Uses.Count == 0); trace?.Log($"REMOVED:\t{node}"); node.Empty(); IRInstructionRemovedCount.Increment(); }
protected override void Emit(InstructionNode node, ARMv6CodeEmitter emitter) { EmitMultiplyInstruction(node, emitter); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="node">The node.</param> /// <param name="emitter">The emitter.</param> public override void Emit(InstructionNode node, BaseCodeEmitter emitter) { LeaAddress(node, emitter); }
private bool ProcessInstruction(InstructionNode node) { //if (MainTrace.Active) MainTrace.Log(context.ToString()); var instruction = node.Instruction; if (instruction == IRInstruction.MoveInt32 || instruction == IRInstruction.MoveInt64) { Move(node); } else if (instruction == IRInstruction.NewObject || instruction == IRInstruction.NewArray || instruction == IRInstruction.NewString) { NewObject(node); } else if (instruction == IRInstruction.CallDynamic || instruction == IRInstruction.CallInterface || instruction == IRInstruction.CallDirect || instruction == IRInstruction.CallStatic || instruction == IRInstruction.CallVirtual || instruction == IRInstruction.IntrinsicMethodCall) { Call(node); } else if (instruction == IRInstruction.LoadInt32 || instruction == IRInstruction.LoadInt64 || instruction == IRInstruction.LoadSignExtend8x32 || instruction == IRInstruction.LoadSignExtend16x32 || instruction == IRInstruction.LoadSignExtend8x64 || instruction == IRInstruction.LoadSignExtend16x64 || instruction == IRInstruction.LoadSignExtend32x64 || instruction == IRInstruction.LoadZeroExtend8x32 || instruction == IRInstruction.LoadZeroExtend16x32 || instruction == IRInstruction.LoadZeroExtend8x64 || instruction == IRInstruction.LoadZeroExtend16x64 || instruction == IRInstruction.LoadZeroExtend32x64 || instruction == IRInstruction.LoadFloatR4 || instruction == IRInstruction.LoadFloatR8 || instruction == IRInstruction.LoadParamSignExtend8x32 || instruction == IRInstruction.LoadParamSignExtend16x32 || instruction == IRInstruction.LoadParamInt32 || instruction == IRInstruction.LoadParamInt64 || instruction == IRInstruction.LoadParamSignExtend8x64 || instruction == IRInstruction.LoadParamSignExtend16x64 || instruction == IRInstruction.LoadParamSignExtend32x64 || instruction == IRInstruction.LoadParamZeroExtend8x32 || instruction == IRInstruction.LoadParamZeroExtend16x32 || instruction == IRInstruction.LoadParamZeroExtend8x64 || instruction == IRInstruction.LoadParamZeroExtend16x64 || instruction == IRInstruction.LoadParamZeroExtend32x64 || instruction == IRInstruction.LoadParamFloatR4 || instruction == IRInstruction.LoadParamFloatR8) { Load(node); } else if (instruction == IRInstruction.Add32 || instruction == IRInstruction.Add64 || instruction == IRInstruction.Sub32 || instruction == IRInstruction.Sub64 || instruction == IRInstruction.MulSigned32 || instruction == IRInstruction.MulUnsigned32 || instruction == IRInstruction.MulSigned64 || instruction == IRInstruction.MulUnsigned64 || instruction == IRInstruction.DivSigned32 || instruction == IRInstruction.DivUnsigned32 || instruction == IRInstruction.RemSigned32 || instruction == IRInstruction.RemUnsigned32 || instruction == IRInstruction.DivSigned64 || instruction == IRInstruction.DivUnsigned64 || instruction == IRInstruction.RemSigned64 || instruction == IRInstruction.RemUnsigned64 || instruction == IRInstruction.ShiftLeft32 || instruction == IRInstruction.ShiftRight32 || instruction == IRInstruction.ShiftLeft64 || instruction == IRInstruction.ShiftRight64 || instruction == IRInstruction.ArithShiftRight32 || instruction == IRInstruction.ArithShiftRight64) { IntegerOperation(node); } else if (instruction == IRInstruction.CompareInt32x32 || instruction == IRInstruction.CompareInt64x32 || instruction == IRInstruction.CompareInt64x64) { CompareIntegerOperation(node); } else if (instruction == IRInstruction.Phi) { Phi(node); } else if (instruction == IRInstruction.Jmp) { Jmp(node); } else if (instruction == IRInstruction.CompareIntBranch32 || instruction == IRInstruction.CompareIntBranch64) { return(CompareIntegerBranch(node)); } else if (instruction == IRInstruction.AddressOf) { AddressOf(node); } else if (instruction == IRInstruction.SignExtend8x32 || instruction == IRInstruction.SignExtend16x32 || instruction == IRInstruction.SignExtend8x64 || instruction == IRInstruction.SignExtend16x64 || instruction == IRInstruction.SignExtend32x64 || instruction == IRInstruction.ZeroExtend8x32 || instruction == IRInstruction.ZeroExtend16x32 || instruction == IRInstruction.ZeroExtend8x64 || instruction == IRInstruction.ZeroExtend16x64 || instruction == IRInstruction.ZeroExtend32x64) { Move(node); } else if (instruction == IRInstruction.Switch) { Switch(node); } else if (instruction == IRInstruction.FinallyStart) { FinallyStart(node); } else if (instruction == IRInstruction.SetReturn32 || instruction == IRInstruction.SetReturn64 || instruction == IRInstruction.SetReturnR4 || instruction == IRInstruction.SetReturnR8 || instruction == IRInstruction.SetReturnCompound) { // nothing } else { // for all other instructions Default(node); } return(true); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="node">The node.</param> /// <param name="emitter">The emitter.</param> protected override void Emit(InstructionNode node, MachineCodeEmitter emitter) { // TODO }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="emitter">The emitter.</param> internal override void EmitLegacy(InstructionNode node, X86CodeEmitter emitter) { emitter.WriteByte(0xC3); }
public IEnumerable <StoreDynamicDataStateProvider> MatchLoadToStore(InstructionNode loadNode) { return(_StateProviders.Where(x => x.IsLoadNodeMatching(loadNode))); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="node">The node.</param> /// <param name="emitter">The emitter.</param> protected override void Emit(InstructionNode node, MachineCodeEmitter emitter) { emitter.WriteByte(0xCD); emitter.WriteByte((byte)node.Operand1.ConstantUnsignedInteger); }
public IndexedArgument(int argIndex, InstructionNode argument, CoupledIndexedArgList containingList) { ArgIndex = argIndex; Argument = argument; ContainingList = containingList; }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="node">The node.</param> /// <param name="emitter">The emitter.</param> protected override void Emit(InstructionNode node, ARMv6CodeEmitter emitter) { // TODO }
private bool CompareIntegerBranch(InstructionNode node) { var operand1 = GetVariableState(node.Operand1); var operand2 = GetVariableState(node.Operand2); var compareNull = NullComparisionCheck(node.ConditionCode, operand1, operand2); if (compareNull.HasValue) { if (compareNull.Value) { Branch(node); } return(!compareNull.Value); } if (operand1.IsOverDefined || operand2.IsOverDefined) { Branch(node); return(true); } else if (operand1.IsSingleConstant && operand2.IsSingleConstant) { bool?compare = Compare(operand1.ConstantUnsignedLongInteger, operand2.ConstantUnsignedLongInteger, node.ConditionCode); if (!compare.HasValue) { // assume it always branches Branch(node); return(true); } if (compare.Value) { Branch(node); } return(!compare.Value); } else if (operand1.HasOnlyConstants && operand2.HasOnlyConstants) { bool?final = null; foreach (var c1 in operand1.Constants) { foreach (var c2 in operand2.Constants) { bool?compare = Compare(c1, c2, node.ConditionCode); if (!compare.HasValue) { Branch(node); return(true); } if (!final.HasValue) { final = compare; continue; } else if (final.Value == compare.Value) { continue; } else { Branch(node); return(true); } } } if (final.Value) { Branch(node); } return(!final.Value); } Branch(node); return(true); }
private void AddInstruction(InstructionNode node) { instructionWorkList.Push(node); }
protected override void Emit(InstructionNode node, ARMv6CodeEmitter emitter) { EmitDataProcessingInstruction(node, emitter, Bits.b1010); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public virtual void Decode(InstructionNode ctx, IInstructionDecoder decoder) { ctx.SetInstruction(this, DefaultOperandCount, DefaultResultCount); }
public override void Verify(InstructionNode instructionWrapper) { instructionWrapper.DataFlowBackRelated.CheckNumberings(); }
public override void Emit(InstructionNode node, BaseCodeEmitter emitter) { System.Diagnostics.Debug.Assert(node.ResultCount == 1); System.Diagnostics.Debug.Assert(node.OperandCount == 2); if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 5) && node.Operand2.IsConstantZero) { emitter.OpcodeEncoder.AppendByte(0x8D); emitter.OpcodeEncoder.Append2Bits(0b01); emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); emitter.OpcodeEncoder.Append3Bits(0b101); emitter.OpcodeEncoder.AppendByte(0x00); return; } if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 4) && node.Operand2.IsConstantZero) { emitter.OpcodeEncoder.AppendByte(0x8D); emitter.OpcodeEncoder.Append2Bits(0b00); emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); emitter.OpcodeEncoder.Append3Bits(0b100); emitter.OpcodeEncoder.Append2Bits(0b00); emitter.OpcodeEncoder.Append3Bits(0b100); emitter.OpcodeEncoder.Append3Bits(0b100); return; } if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 4) && (node.Operand2.IsConstant && node.Operand2.ConstantSignedInteger >= -128 && node.Operand2.ConstantSignedInteger <= 127)) { emitter.OpcodeEncoder.AppendByte(0x8D); emitter.OpcodeEncoder.Append2Bits(0b01); emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); emitter.OpcodeEncoder.Append3Bits(0b100); emitter.OpcodeEncoder.Append2Bits(0b00); emitter.OpcodeEncoder.Append3Bits(0b100); emitter.OpcodeEncoder.Append3Bits(0b100); emitter.OpcodeEncoder.Append8BitImmediate(node.Operand2); return; } if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 4) && node.Operand2.IsConstant) { emitter.OpcodeEncoder.AppendByte(0x8D); emitter.OpcodeEncoder.Append2Bits(0b10); emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); emitter.OpcodeEncoder.Append3Bits(0b100); emitter.OpcodeEncoder.Append8BitImmediate(node.Operand2); return; } if (node.Operand1.IsCPURegister && node.Operand2.IsCPURegister) { emitter.OpcodeEncoder.AppendByte(0x8D); emitter.OpcodeEncoder.Append2Bits(0b00); emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); emitter.OpcodeEncoder.Append3Bits(0b100); emitter.OpcodeEncoder.Append2Bits(0b00); emitter.OpcodeEncoder.Append3Bits(node.Operand2.Register.RegisterCode); emitter.OpcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode); return; } if (node.Operand1.IsCPURegister && node.Operand2.IsConstantZero) { emitter.OpcodeEncoder.AppendByte(0x8D); emitter.OpcodeEncoder.Append2Bits(0b00); emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); emitter.OpcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode); return; } if (node.Operand1.IsCPURegister && (node.Operand2.IsConstant && node.Operand2.ConstantSignedInteger >= -128 && node.Operand2.ConstantSignedInteger <= 127)) { emitter.OpcodeEncoder.AppendByte(0x8D); emitter.OpcodeEncoder.Append2Bits(0b01); emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); emitter.OpcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode); emitter.OpcodeEncoder.Append8BitImmediate(node.Operand2); return; } if (node.Operand1.IsCPURegister && node.Operand2.IsConstant) { emitter.OpcodeEncoder.AppendByte(0x8D); emitter.OpcodeEncoder.Append2Bits(0b10); emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); emitter.OpcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode); emitter.OpcodeEncoder.Append32BitImmediate(node.Operand2); return; } if (node.Operand1.IsConstant && node.Operand2.IsConstantZero) { emitter.OpcodeEncoder.AppendByte(0x8D); emitter.OpcodeEncoder.Append2Bits(0b00); emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); emitter.OpcodeEncoder.Append3Bits(0b101); emitter.OpcodeEncoder.Append32BitImmediate(node.Operand1); return; } throw new Compiler.Common.Exceptions.CompilerException("Invalid Opcode"); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="node">The node.</param> /// <param name="emitter">The emitter.</param> protected override void Emit(InstructionNode node, MachineCodeEmitter emitter) { emitter.Emit(opcode, node.Operand3, null); }
private Operand Map(Operand operand, Dictionary <Operand, Operand> map, InstructionNode callSiteNode) { if (operand == null) { return(null); } if (map.TryGetValue(operand, out Operand mappedOperand)) { return(mappedOperand); } if (operand.IsSymbol) { if (operand.StringData != null) { mappedOperand = Operand.CreateStringSymbol(operand.Name, operand.StringData, operand.Type.TypeSystem); } else if (operand.Method != null) { mappedOperand = Operand.CreateSymbolFromMethod(operand.Method, operand.Type.TypeSystem); } else if (operand.Name != null) { mappedOperand = Operand.CreateSymbol(operand.Type, operand.Name); } } else if (operand.IsParameter) { mappedOperand = callSiteNode.GetOperand(operand.Index + 1); } else if (operand.IsStackLocal) { mappedOperand = MethodCompiler.AddStackLocal(operand.Type, operand.IsPinned); } else if (operand.IsVirtualRegister) { mappedOperand = AllocateVirtualRegister(operand.Type); } else if (operand.IsStaticField) { mappedOperand = Operand.CreateStaticField(operand.Field, TypeSystem); } else if (operand.IsCPURegister) { mappedOperand = operand; } else if (operand.IsConstant) { mappedOperand = operand; } Debug.Assert(mappedOperand != null); if (operand.HasLongParent) { MethodCompiler.SplitLongOperand(mappedOperand); if (operand.IsLow) { mappedOperand = mappedOperand.Low; } else if (operand.IsHigh) { mappedOperand = mappedOperand.High; } } map.Add(operand, mappedOperand); return(mappedOperand); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="node">The node.</param> /// <param name="emitter">The emitter.</param> public override void Emit(InstructionNode node, BaseCodeEmitter emitter) { MovssRegToMemory(node, emitter); }
protected void Inline(InstructionNode callSiteNode, BasicBlocks blocks) { var mapBlocks = new Dictionary <BasicBlock, BasicBlock>(blocks.Count); var map = new Dictionary <Operand, Operand>(); var nextBlock = Split(callSiteNode); // create basic blocks foreach (var block in blocks) { var newBlock = CreateNewBlock(); mapBlocks.Add(block, newBlock); } // copy instructions foreach (var block in blocks) { var newBlock = mapBlocks[block]; for (var node = block.AfterFirst; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) { continue; } if (node.Instruction == IRInstruction.Prologue) { continue; } if (node.Instruction == IRInstruction.Epilogue) { newBlock.BeforeLast.Insert(new InstructionNode(IRInstruction.Jmp, nextBlock)); continue; } if (node.Instruction == IRInstruction.SetReturn32 || node.Instruction == IRInstruction.SetReturn64 || node.Instruction == IRInstruction.SetReturnR4 || node.Instruction == IRInstruction.SetReturnR8 || node.Instruction == IRInstruction.SetReturnCompound) { if (callSiteNode.Result != null) { var newOperand = Map(node.Operand1, map, callSiteNode); BaseInstruction moveInstruction = null; if (node.Instruction == IRInstruction.SetReturn32) { moveInstruction = IRInstruction.MoveInt32; } else if (node.Instruction == IRInstruction.SetReturn64) { moveInstruction = IRInstruction.MoveInt64; } else if (node.Instruction == IRInstruction.SetReturnR4) { moveInstruction = IRInstruction.MoveFloatR4; } else if (node.Instruction == IRInstruction.SetReturnR8) { moveInstruction = IRInstruction.MoveFloatR8; } else if (node.Instruction == IRInstruction.SetReturnCompound) { moveInstruction = IRInstruction.MoveCompound; } Debug.Assert(moveInstruction != null); var moveNode = new InstructionNode(moveInstruction, callSiteNode.Result, newOperand); newBlock.BeforeLast.Insert(moveNode); } continue; } var newNode = new InstructionNode(node.Instruction, node.OperandCount, node.ResultCount) { ConditionCode = node.ConditionCode, Label = callSiteNode.Label }; if (node.BranchTargets != null) { // copy targets foreach (var target in node.BranchTargets) { newNode.AddBranchTarget(mapBlocks[target]); } } // copy results for (int i = 0; i < node.ResultCount; i++) { var op = node.GetResult(i); var newOp = Map(op, map, callSiteNode); newNode.SetResult(i, newOp); } // copy operands for (int i = 0; i < node.OperandCount; i++) { var op = node.GetOperand(i); var newOp = Map(op, map, callSiteNode); newNode.SetOperand(i, newOp); } // copy other if (node.MosaType != null) { newNode.MosaType = node.MosaType; } if (node.MosaField != null) { newNode.MosaField = node.MosaField; } UpdateParameterInstructions(newNode); newBlock.BeforeLast.Insert(newNode); } } var prologue = mapBlocks[blocks.PrologueBlock]; var callSiteOperands = callSiteNode.GetOperands(); if (callSiteOperands.Count > 1) { var context = new Context(prologue); for (int i = 1; i < callSiteOperands.Count; i++) { var operand = callSiteOperands[i]; if (!operand.IsVirtualRegister || operand.Low == null) { continue; } context.AppendInstruction(IRInstruction.GetLow64, operand.Low, operand); context.AppendInstruction(IRInstruction.GetHigh64, operand.High, operand); } } callSiteNode.SetInstruction(IRInstruction.Jmp, prologue); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="node">The node.</param> /// <param name="emitter">The emitter.</param> public override void Emit(InstructionNode node, BaseCodeEmitter emitter) { MovsdMemoryToReg(node, emitter); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="node">The node.</param> /// <param name="emitter">The emitter.</param> protected override void Emit(InstructionNode node, MachineCodeEmitter emitter) { EmitDataProcessingInstruction(node, emitter, Bits.b1001); }
private void Switch(InstructionNode node) { // no optimization attempted Branch(node); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="node">The node.</param> /// <param name="emitter">The emitter.</param> protected override void Emit(InstructionNode node, MachineCodeEmitter emitter) { var opCode = ComputeOpCode(node.Size, node.Result, node.Operand1); emitter.Emit(opCode, node.Result, node.Operand1); }
protected BasicBlocks CopyInstructions() { var newBasicBlocks = new BasicBlocks(); var mapBlocks = new Dictionary <BasicBlock, BasicBlock>(BasicBlocks.Count); var map = new Dictionary <Operand, Operand>(); foreach (var block in BasicBlocks) { var newBlock = newBasicBlocks.CreateBlock(block.Label); mapBlocks.Add(block, newBlock); } var newPrologueBlock = newBasicBlocks.GetByLabel(BasicBlock.PrologueLabel); foreach (var operand in MethodCompiler.Parameters) { if (operand.Definitions.Count > 0) { var newOp = Map(operand, map); var newOperand = Operand.CreateVirtualRegister(operand.Type, -operand.Index); newPrologueBlock.BeforeLast.Insert(new InstructionNode(IRInstruction.Move, newOperand, newOp)); // redirect map from parameter to virtual register going forward map.Remove(operand); map.Add(operand, newOperand); } } foreach (var block in BasicBlocks) { var newBlock = newBasicBlocks.GetByLabel(block.Label); for (var node = block.First.Next; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) { continue; } var newNode = new InstructionNode(node.Instruction, node.OperandCount, node.ResultCount); newNode.Size = node.Size; newNode.ConditionCode = node.ConditionCode; if (node.BranchTargets != null) { // copy targets foreach (var target in node.BranchTargets) { newNode.AddBranchTarget(mapBlocks[target]); } } // copy results for (int i = 0; i < node.ResultCount; i++) { var op = node.GetResult(i); var newOp = Map(op, map); newNode.SetResult(i, newOp); } // copy operands for (int i = 0; i < node.OperandCount; i++) { var op = node.GetOperand(i); var newOp = Map(op, map); newNode.SetOperand(i, newOp); } // copy other if (node.MosaType != null) { newNode.MosaType = node.MosaType; } if (node.MosaField != null) { newNode.MosaField = node.MosaField; } if (node.InvokeMethod != null) { newNode.InvokeMethod = node.InvokeMethod; } newBlock.BeforeLast.Insert(newNode); } } var trace = CreateTraceLog("InlineMap"); if (trace.Active) { foreach (var entry in map) { trace.Log(entry.Value.ToString() + " from: " + entry.Key.ToString()); } } return(newBasicBlocks); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="node">The node.</param> /// <param name="emitter">The emitter.</param> internal override void EmitLegacy(InstructionNode node, X86CodeEmitter emitter) { emitter.Emit(opcode, node.Operand2); }
public override void Emit(InstructionNode node, OpcodeEncoder opcodeEncoder) { System.Diagnostics.Debug.Assert(node.ResultCount == 1); System.Diagnostics.Debug.Assert(node.OperandCount == 2); if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 5) && node.Operand2.IsConstantZero) { opcodeEncoder.SuppressByte(0x40); opcodeEncoder.Append4Bits(0b0100); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append8Bits(0x8B); opcodeEncoder.Append2Bits(0b01); opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); opcodeEncoder.Append3Bits(0b101); opcodeEncoder.Append8Bits(0x00); return; } if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 5) && node.Operand2.IsCPURegister) { opcodeEncoder.SuppressByte(0x40); opcodeEncoder.Append4Bits(0b0100); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append1Bit((node.Operand2.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append8Bits(0x8B); opcodeEncoder.Append2Bits(0b01); opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); opcodeEncoder.Append3Bits(0b100); opcodeEncoder.Append2Bits(0b00); opcodeEncoder.Append3Bits(node.Operand2.Register.RegisterCode); opcodeEncoder.Append3Bits(0b101); opcodeEncoder.Append8Bits(0x00); return; } if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 4) && node.Operand2.IsConstantZero) { opcodeEncoder.SuppressByte(0x40); opcodeEncoder.Append4Bits(0b0100); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append8Bits(0x8B); opcodeEncoder.Append2Bits(0b00); opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); opcodeEncoder.Append3Bits(0b100); opcodeEncoder.Append2Bits(0b00); opcodeEncoder.Append3Bits(0b100); opcodeEncoder.Append3Bits(0b100); return; } if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 4) && (node.Operand2.IsConstant && node.Operand2.ConstantSigned32 >= -128 && node.Operand2.ConstantSigned32 <= 127)) { opcodeEncoder.SuppressByte(0x40); opcodeEncoder.Append4Bits(0b0100); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append8Bits(0x8B); opcodeEncoder.Append2Bits(0b01); opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); opcodeEncoder.Append3Bits(0b100); opcodeEncoder.Append2Bits(0b00); opcodeEncoder.Append3Bits(0b100); opcodeEncoder.Append3Bits(0b100); opcodeEncoder.Append8BitImmediate(node.Operand2); return; } if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 4) && node.Operand2.IsConstant) { opcodeEncoder.SuppressByte(0x40); opcodeEncoder.Append4Bits(0b0100); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append8Bits(0x8B); opcodeEncoder.Append2Bits(0b10); opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); opcodeEncoder.Append3Bits(0b100); opcodeEncoder.Append8BitImmediate(node.Operand2); return; } if (node.Operand1.IsCPURegister && node.Operand2.IsCPURegister) { opcodeEncoder.SuppressByte(0x40); opcodeEncoder.Append4Bits(0b0100); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append1Bit((node.Operand1.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append8Bits(0x8B); opcodeEncoder.Append2Bits(0b00); opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); opcodeEncoder.Append3Bits(0b100); opcodeEncoder.Append2Bits(0b00); opcodeEncoder.Append3Bits(node.Operand2.Register.RegisterCode); opcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode); return; } if (node.Operand1.IsCPURegister && node.Operand2.IsConstantZero) { opcodeEncoder.SuppressByte(0x40); opcodeEncoder.Append4Bits(0b0100); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Operand1.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append8Bits(0x8B); opcodeEncoder.Append2Bits(0b00); opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); opcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode); return; } if (node.Operand1.IsCPURegister && (node.Operand2.IsConstant && node.Operand2.ConstantSigned32 >= -128 && node.Operand2.ConstantSigned32 <= 127)) { opcodeEncoder.SuppressByte(0x40); opcodeEncoder.Append4Bits(0b0100); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Operand1.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append8Bits(0x8B); opcodeEncoder.Append2Bits(0b01); opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); opcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append8BitImmediate(node.Operand2); return; } if (node.Operand1.IsCPURegister && node.Operand2.IsConstant) { opcodeEncoder.SuppressByte(0x40); opcodeEncoder.Append4Bits(0b0100); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Operand1.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append8Bits(0x8B); opcodeEncoder.Append2Bits(0b10); opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); opcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append32BitImmediate(node.Operand2); return; } if (node.Operand1.IsConstant && node.Operand2.IsConstantZero) { opcodeEncoder.SuppressByte(0x40); opcodeEncoder.Append4Bits(0b0100); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append8Bits(0x8B); opcodeEncoder.Append2Bits(0b00); opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); opcodeEncoder.Append3Bits(0b101); opcodeEncoder.Append32BitImmediate(node.Operand1); return; } if (node.Operand1.IsConstant && node.Operand2.IsConstant) { opcodeEncoder.SuppressByte(0x40); opcodeEncoder.Append4Bits(0b0100); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append8Bits(0x8B); opcodeEncoder.Append2Bits(0b00); opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); opcodeEncoder.Append3Bits(0b101); opcodeEncoder.Append32BitImmediateWithOffset(node.Operand1, node.Operand2); return; } throw new Compiler.Common.Exceptions.CompilerException("Invalid Opcode"); }