diff --git a/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs b/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs
index 2f35f083f24d2..cab9ca34d5bc7 100644
--- a/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs
+++ b/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs
@@ -191,6 +191,27 @@ public InstructionSetSupportBuilder(TargetArchitecture architecture)
/// returns "false" if instruction set isn't valid on this architecture
public bool AddSupportedInstructionSet(string instructionSet)
{
+ // First, check if it's a "known cpu family" group of instruction sets e.g. "haswell"
+ var sets = InstructionSetFlags.CpuNameToInstructionSets(instructionSet, _architecture);
+ if (sets != null)
+ {
+ foreach (string set in sets)
+ {
+ if (!s_instructionSetSupport[_architecture].ContainsKey(set))
+ {
+ // Groups can contain other groups
+ if (AddSupportedInstructionSet(set))
+ {
+ continue;
+ }
+ return false;
+ }
+ _supportedInstructionSets.Add(set);
+ _unsupportedInstructionSets.Remove(set);
+ }
+ return true;
+ }
+
if (!s_instructionSetSupport[_architecture].ContainsKey(instructionSet))
return false;
diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs b/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs
index 8e82477d4f202..b3c266dc01c7b 100644
--- a/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs
+++ b/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs
@@ -752,6 +752,32 @@ private static InstructionSetFlags ExpandInstructionSetByReverseImplicationHelpe
return resultflags;
}
+ private static Dictionary<(string, TargetArchitecture), string> AllInstructionSetGroups { get; } = new()
+ {
+ { ("x86-x64", TargetArchitecture.X64), "sse2" },
+ { ("x86-x64", TargetArchitecture.X86), "sse2" },
+ { ("x86-x64-v2", TargetArchitecture.X64), "sse4.2 popcnt" },
+ { ("x86-x64-v2", TargetArchitecture.X86), "sse4.2 popcnt" },
+ { ("x86-x64-v3", TargetArchitecture.X64), "x86-x64-v2 avx2 bmi bmi2 lzcnt movbe fma" },
+ { ("x86-x64-v3", TargetArchitecture.X86), "x86-x64-v2 avx2 bmi bmi2 lzcnt movbe fma" },
+ { ("skylake", TargetArchitecture.X64), "x86-x64-v3" },
+ { ("skylake", TargetArchitecture.X86), "x86-x64-v3" },
+ { ("armv8-a", TargetArchitecture.ARM64), "neon" },
+ { ("armv8.1-a", TargetArchitecture.ARM64), "armv8-a lse crc rdma" },
+ { ("armv8.2-a", TargetArchitecture.ARM64), "armv8.1-a" },
+ { ("armv8.3-a", TargetArchitecture.ARM64), "armv8.2-a rcpc" },
+ { ("armv8.4-a", TargetArchitecture.ARM64), "armv8.3-a dotprod" },
+ { ("armv8.5-a", TargetArchitecture.ARM64), "armv8.4-a" },
+ { ("armv8.6-a", TargetArchitecture.ARM64), "armv8.5-a" },
+ { ("apple-m1", TargetArchitecture.ARM64), "armv8.5-a" },
+ };
+
+ public static IEnumerable AllCpuNames =>
+ AllInstructionSetGroups.Keys.Select(key => key.Item1).Distinct();
+
+ public static IEnumerable CpuNameToInstructionSets(string cpu, TargetArchitecture arch) =>
+ AllInstructionSetGroups.TryGetValue((cpu, arch), out string value) ? value.Split(' ') : null;
+
public struct InstructionSetInfo
{
public readonly string Name;
diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt
index bab454dd4dbe3..327d4b7140b8b 100644
--- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt
+++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt
@@ -134,3 +134,22 @@ implication ,ARM64 ,Sha1 ,ArmBase
implication ,ARM64 ,Sha256 ,ArmBase
implication ,ARM64 ,Vector64 ,AdvSimd
implication ,ARM64 ,Vector128 ,AdvSimd
+
+
+; ,name and aliases ,archs ,lower baselines included by implication
+;
+instructionsetgroup ,x86-x64 ,X64 X86 ,sse2
+instructionsetgroup ,x86-x64-v2 ,X64 X86 ,sse4.2 popcnt
+instructionsetgroup ,x86-x64-v3 ,X64 X86 ,x86-x64-v2 avx2 bmi bmi2 lzcnt movbe fma
+instructionsetgroup ,skylake ,X64 X86 ,x86-x64-v3
+
+instructionsetgroup ,armv8-a ,ARM64 ,neon
+instructionsetgroup ,armv8.1-a ,ARM64 ,armv8-a lse crc rdma
+instructionsetgroup ,armv8.2-a ,ARM64 ,armv8.1-a
+instructionsetgroup ,armv8.3-a ,ARM64 ,armv8.2-a rcpc
+instructionsetgroup ,armv8.4-a ,ARM64 ,armv8.3-a dotprod
+instructionsetgroup ,armv8.5-a ,ARM64 ,armv8.4-a
+instructionsetgroup ,armv8.6-a ,ARM64 ,armv8.5-a
+
+; Technically, apple-m1 is v8.5+
+instructionsetgroup ,apple-m1 ,ARM64 ,armv8.5-a
diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs
index 5152a6ebde110..d8c6042fd0d96 100644
--- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs
+++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs
@@ -58,6 +58,8 @@ public string PublicName
}
}
+ record InstructionSetGroup(string Names, string Archs, string Sets);
+
class InstructionSetImplication
{
public string Architecture { get; }
@@ -81,6 +83,7 @@ public InstructionSetImplication(string architecture, InstructionSetImplication
List _instructionSets = new List();
List _implications = new List();
+ List _instructionSetsGroups = new List();
Dictionary> _64bitVariants = new Dictionary>();
SortedDictionary _r2rNamesByName = new SortedDictionary();
SortedDictionary _r2rNamesByNumber = new SortedDictionary();
@@ -184,6 +187,11 @@ public bool ParseInput(TextReader tr)
ValidateArchitectureEncountered(command[1]);
_implications.Add(new InstructionSetImplication(command[1],command[2], command[3]));
break;
+ case "instructionsetgroup":
+ if (command.Length != 4)
+ throw new Exception("Incorrect number of args for instructionsetgroup");
+ _instructionSetsGroups.Add(new InstructionSetGroup(command[1], command[2], command[3]));
+ break;
case "copyinstructionsets":
if (command.Length != 3)
throw new Exception("Incorrect number of args for instructionset");
@@ -605,6 +613,28 @@ private static InstructionSetFlags ExpandInstructionSetByReverseImplicationHelpe
return resultflags;
}
+ private static Dictionary<(string, TargetArchitecture), string> AllInstructionSetGroups { get; } = new()
+ {
+");
+ foreach (InstructionSetGroup group in _instructionSetsGroups)
+ {
+ foreach (string name in group.Names.Split(' '))
+ {
+ foreach (string arch in group.Archs.Split(' '))
+ {
+ string key = $"\"{name}\",".PadRight(13, ' ') + $" TargetArchitecture.{arch}),".PadRight(27, ' ');
+ tr.WriteLine($" {{ ({key} \"{group.Sets}\" }},");
+ }
+ }
+ }
+ tr.Write(@" };
+
+ public static IEnumerable AllCpuNames =>
+ AllInstructionSetGroups.Keys.Select(key => key.Item1).Distinct();
+
+ public static IEnumerable CpuNameToInstructionSets(string cpu, TargetArchitecture arch) =>
+ AllInstructionSetGroups.TryGetValue((cpu, arch), out string value) ? value.Split(' ') : null;
+
public struct InstructionSetInfo
{
public readonly string Name;
diff --git a/src/coreclr/tools/aot/ILCompiler/Program.cs b/src/coreclr/tools/aot/ILCompiler/Program.cs
index eb3643851fd50..115ca29863cd2 100644
--- a/src/coreclr/tools/aot/ILCompiler/Program.cs
+++ b/src/coreclr/tools/aot/ILCompiler/Program.cs
@@ -305,6 +305,10 @@ private ArgumentSyntax ParseCommandLine(string[] args)
extraHelp.Add(archString.ToString());
}
+ extraHelp.Add("");
+ extraHelp.Add("The following CPU names are predefined groups of instruction sets and can be used in --instruction-set too:");
+ extraHelp.Add(string.Join(", ", Internal.JitInterface.InstructionSetFlags.AllCpuNames));
+
argSyntax.ExtraHelpParagraphs = extraHelp;
}
@@ -438,7 +442,15 @@ private int Run(string[] args)
}
else if (_targetArchitecture == TargetArchitecture.ARM64)
{
- instructionSetSupportBuilder.AddSupportedInstructionSet("neon"); // Lower baselines included by implication
+ if (_targetOS == TargetOS.OSX)
+ {
+ // For osx-arm64 we know that apple-m1 is a baseline
+ instructionSetSupportBuilder.AddSupportedInstructionSet("apple-m1");
+ }
+ else
+ {
+ instructionSetSupportBuilder.AddSupportedInstructionSet("neon"); // Lower baselines included by implication
+ }
}
if (_instructionSet != null)
diff --git a/src/coreclr/tools/aot/crossgen2/CommandLineOptions.cs b/src/coreclr/tools/aot/crossgen2/CommandLineOptions.cs
index ceefe4d1705d6..86a5340faa89f 100644
--- a/src/coreclr/tools/aot/crossgen2/CommandLineOptions.cs
+++ b/src/coreclr/tools/aot/crossgen2/CommandLineOptions.cs
@@ -241,6 +241,10 @@ public CommandLineOptions(string[] args)
extraHelp.Add(archString.ToString());
}
+ extraHelp.Add("");
+ extraHelp.Add(SR.CpuFamilies);
+ extraHelp.Add(string.Join(", ", Internal.JitInterface.InstructionSetFlags.AllCpuNames));
+
argSyntax.ExtraHelpParagraphs = extraHelp;
HelpText = argSyntax.GetHelpText();
diff --git a/src/coreclr/tools/aot/crossgen2/Program.cs b/src/coreclr/tools/aot/crossgen2/Program.cs
index de6370cc5066e..81bdb61ae09ef 100644
--- a/src/coreclr/tools/aot/crossgen2/Program.cs
+++ b/src/coreclr/tools/aot/crossgen2/Program.cs
@@ -20,6 +20,7 @@
using ILCompiler.Reflection.ReadyToRun;
using ILCompiler.DependencyAnalysis;
using ILCompiler.IBC;
+using System.Diagnostics;
namespace ILCompiler
{
@@ -245,10 +246,17 @@ private InstructionSetSupport ConfigureInstructionSetSupport()
}
else if (_targetArchitecture == TargetArchitecture.ARM64)
{
- instructionSetSupportBuilder.AddSupportedInstructionSet("neon"); // Lower baselines included by implication
+ if (_targetOS == TargetOS.OSX)
+ {
+ // For osx-arm64 we know that apple-m1 is a baseline
+ instructionSetSupportBuilder.AddSupportedInstructionSet("apple-m1");
+ }
+ else
+ {
+ instructionSetSupportBuilder.AddSupportedInstructionSet("neon"); // Lower baselines included by implication
+ }
}
-
if (_commandLineOptions.InstructionSet != null)
{
List instructionSetParams = new List();
diff --git a/src/coreclr/tools/aot/crossgen2/Properties/Resources.resx b/src/coreclr/tools/aot/crossgen2/Properties/Resources.resx
index 929181a75bebb..37720091236db 100644
--- a/src/coreclr/tools/aot/crossgen2/Properties/Resources.resx
+++ b/src/coreclr/tools/aot/crossgen2/Properties/Resources.resx
@@ -387,4 +387,7 @@
"{0}" was specified to the --non-local-generics-module switch, but was not in the set of modules associated with the compile
+
+ The following CPU names are predefined groups of instruction sets and can be used in --instruction-set too:
+
\ No newline at end of file