public static int GetRuntimeRequiredIsaFlags(InstructionSetSupport instructionSetSupport) { int result = 0; switch (instructionSetSupport.Architecture) { case TargetArchitecture.X86: case TargetArchitecture.X64: foreach (InstructionSet instructionSet in instructionSetSupport.SupportedFlags) { result |= XArchIntrinsicConstants.FromInstructionSet(instructionSet); } break; case TargetArchitecture.ARM64: foreach (InstructionSet instructionSet in instructionSetSupport.SupportedFlags) { result |= Arm64IntrinsicConstants.FromInstructionSet(instructionSet); } break; default: Debug.Fail("Unsupported Architecture"); break; } return(result); }
/// <summary> /// Generates IL for the IsSupported property that reads this information from a field initialized by the runtime /// at startup. Only works for intrinsics that the code generator can generate detection code for. /// </summary> public static MethodIL EmitIsSupportedIL(MethodDesc method, FieldDesc isSupportedField, InstructionSet instructionSet) { Debug.Assert(IsIsSupportedMethod(method)); Debug.Assert(isSupportedField.IsStatic && isSupportedField.FieldType.IsWellKnownType(WellKnownType.Int32)); int flag = 0; switch (method.Context.Target.Architecture) { case TargetArchitecture.X86: case TargetArchitecture.X64: flag = XArchIntrinsicConstants.FromInstructionSet(instructionSet); break; case TargetArchitecture.ARM64: flag = Arm64IntrinsicConstants.FromInstructionSet(instructionSet); break; default: Debug.Fail("Unsupported Architecture"); break; } var emit = new ILEmitter(); ILCodeStream codeStream = emit.NewCodeStream(); codeStream.Emit(ILOpcode.ldsfld, emit.NewToken(isSupportedField)); codeStream.EmitLdc(flag); codeStream.Emit(ILOpcode.and); codeStream.EmitLdc(0); codeStream.Emit(ILOpcode.cgt_un); codeStream.Emit(ILOpcode.ret); return(emit.Link(method)); }