public static void SplitLongOperand(BaseMethodCompiler methodCompiler, Operand operand, out Operand operandLow, out Operand operandHigh, Operand constantZero) { if (operand.Is64BitInteger) { methodCompiler.VirtualRegisters.SplitLongOperand(methodCompiler.TypeSystem, operand, 4, 0); operandLow = operand.Low; operandHigh = operand.High; return; } else { operandLow = operand; operandHigh = constantZero != null ? constantZero : Operand.CreateConstantSignedInt(methodCompiler.TypeSystem, 0); return; } throw new InvalidProgramException("@can not split" + operand.ToString()); }
/// <summary> /// Computes the opcode. /// </summary> /// <param name="destination">The destination operand.</param> /// <param name="source">The source operand.</param> /// <param name="third">The third operand.</param> /// <returns></returns> protected override OpCode ComputeOpCode(Operand destination, Operand source, Operand third) { if (destination.Register is SegmentRegister) { if (source.IsCPURegister) return SEG_RM; throw new ArgumentException(@"TODO: No opcode for move destination segment register"); } if (source.Register is SegmentRegister) { if (destination.IsCPURegister) return RM_SEG; throw new ArgumentException(@"TODO: No opcode for move source segment register"); } if (destination.IsCPURegister && source.IsConstant) return RM_C; if (destination.IsCPURegister && source.IsSymbol) return RM_C; if (destination.IsCPURegister && source.IsCPURegister) { Debug.Assert(!((source.IsByte || destination.IsByte) && (source.Register == GeneralPurposeRegister.ESI || source.Register == GeneralPurposeRegister.EDI)), source.ToString()); if (source.IsByte || destination.IsByte) return RM_U8; if (source.IsChar || destination.IsChar || source.IsShort || destination.IsShort) return R_RM_16; return R_RM; } if (destination.IsSymbol && source.IsCPURegister) { if (destination.IsByte || destination.IsBoolean) return RM_C_U8; if (destination.IsChar || destination.IsShort) return M_C_16; return RM_C; } throw new ArgumentException(@"No opcode for operand type. [" + destination + ", " + source + ")"); }
/// <summary> /// Computes the opcode. /// </summary> /// <param name="destination">The destination operand.</param> /// <param name="source">The source operand.</param> /// <param name="third">The third operand.</param> /// <returns></returns> protected override OpCode ComputeOpCode(Operand destination, Operand source, Operand third) { if (destination.IsRegister && destination.Register is SegmentRegister) return SR_R; if (source.IsRegister && source.Register is SegmentRegister) throw new ArgumentException(@"TODO: No opcode for move sourcee segment register"); if (destination.IsRegister && source.IsConstant) return RM_C; if (destination.IsMemoryAddress && source.IsConstant) { if (destination.IsByte || destination.IsBoolean) return RM_C_U8; if (destination.IsChar || destination.IsShort) return M_C_16; return RM_C; } if (destination.IsRegister && source.IsSymbol) return RM_C; if (destination.IsMemoryAddress && source.IsSymbol) return RM_C; if (destination.IsRegister && source.IsRegister) { Debug.Assert(!((source.IsByte || destination.IsByte) && (source.Register == GeneralPurposeRegister.ESI || source.Register == GeneralPurposeRegister.EDI)), source.ToString()); if (source.IsByte || destination.IsByte) return R_M_U8; if (source.IsChar || destination.IsChar || source.IsShort || destination.IsShort) return R_RM_16; return R_RM; } if (destination.IsRegister && source.IsMemoryAddress) { if (destination.IsByte) return R_M_U8; if (destination.IsChar || destination.IsShort) return R_RM_16; return R_RM; } if (destination.IsMemoryAddress && source.IsRegister) { if (destination.IsPointer && !source.IsPointer && destination.Type.ElementType != null) { if (destination.Type.ElementType.IsUI1 || destination.Type.ElementType.IsBoolean) return RM_R_U8; if (destination.Type.ElementType.IsChar || destination.Type.ElementType.IsUI2) return M_R_16; } if (destination.IsByte) return RM_R_U8; if (destination.IsChar || destination.IsShort) return M_R_16; return M_R; } if (destination.IsSymbol && source.IsRegister) { if (destination.IsByte || destination.IsBoolean) return RM_C_U8; if (destination.IsChar || destination.IsShort) return M_C_16; return RM_C; } throw new ArgumentException(@"No opcode for operand type. [" + destination + ", " + source + ")"); }