| File: Compiler\HardwareIntrinsicILProvider.cs | Web Access |
| Project: src\runtime\src\coreclr\tools\aot\ILCompiler.Compiler\ILCompiler.Compiler.csproj (ILCompiler.Compiler) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using Internal.IL; using Internal.IL.Stubs; using Internal.JitInterface; using Internal.TypeSystem; namespace ILCompiler { public sealed class HardwareIntrinsicILProvider : ILProvider { private readonly InstructionSetSupport _isaSupport; private readonly TypeSystemContext _context; private readonly FieldDesc _isSupportedField; private readonly ILProvider _nestedProvider; private readonly Dictionary<string, InstructionSet> _instructionSetMap; public HardwareIntrinsicILProvider(InstructionSetSupport isaSupport, FieldDesc isSupportedField, ILProvider nestedProvider) { _isaSupport = isaSupport; _context = isSupportedField.Context; _isSupportedField = isSupportedField; _nestedProvider = nestedProvider; _instructionSetMap = new Dictionary<string, InstructionSet>(); foreach (var instructionSetInfo in InstructionSetFlags.ArchitectureToValidInstructionSets(_context.Target.Architecture)) { if (instructionSetInfo.ManagedName != "") _instructionSetMap.Add(instructionSetInfo.ManagedName, instructionSetInfo.InstructionSet); } } public override MethodIL GetMethodIL(MethodDesc method) { TypeDesc owningType = method.OwningType; string intrinsicId = InstructionSetSupport.GetHardwareIntrinsicId(_context.Target.Architecture, owningType); if (!string.IsNullOrEmpty(intrinsicId) && HardwareIntrinsicHelpers.IsIsSupportedMethod(method)) { InstructionSet instructionSet = _instructionSetMap[intrinsicId]; bool isSupported = _isaSupport.IsInstructionSetSupported(instructionSet); bool isOptimisticallySupported = _isaSupport.OptimisticFlags.HasInstructionSet(instructionSet); // If this is an instruction set that is optimistically supported, but is not one of the // intrinsics that are known to be always available, emit IL that checks the support level // at runtime. if (!isSupported && isOptimisticallySupported) { return HardwareIntrinsicHelpers.EmitIsSupportedIL(method, _isSupportedField, instructionSet); } else { ILOpcode flag = isSupported ? ILOpcode.ldc_i4_1 : ILOpcode.ldc_i4_0; return new ILStubMethodIL(method, new byte[] { (byte)flag, (byte)ILOpcode.ret }, Array.Empty<LocalVariableDefinition>(), null); } } return _nestedProvider.GetMethodIL(method); } } }