From c7af68f54dbc63de7fc898d9fd3270dfe4a8498c Mon Sep 17 00:00:00 2001 From: adamperlin Date: Mon, 8 Jun 2026 14:38:41 -0700 Subject: [PATCH 1/2] Add Wasm32 instruction set description along with PackedSimd, Vector128 definitions for Wasm --- src/coreclr/inc/corinfoinstructionset.h | 25 ++++++ src/coreclr/inc/jiteeversionguid.h | 10 +-- src/coreclr/inc/readytoruninstructionset.h | 2 + .../Runtime/ReadyToRunInstructionSet.cs | 2 + .../Runtime/ReadyToRunInstructionSetHelper.cs | 12 +++ .../JitInterface/CorInfoInstructionSet.cs | 82 +++++++++++++++++++ .../ThunkGenerator/InstructionSetDesc.txt | 14 +++- .../ThunkGenerator/InstructionSetGenerator.cs | 2 + 8 files changed, 143 insertions(+), 6 deletions(-) diff --git a/src/coreclr/inc/corinfoinstructionset.h b/src/coreclr/inc/corinfoinstructionset.h index a09fdf84086964..9fc011f6f8ee32 100644 --- a/src/coreclr/inc/corinfoinstructionset.h +++ b/src/coreclr/inc/corinfoinstructionset.h @@ -61,6 +61,11 @@ enum CORINFO_InstructionSet InstructionSet_Zbb=3, InstructionSet_Zbs=4, #endif // TARGET_RISCV64 +#ifdef TARGET_WASM + InstructionSet_WasmBase=1, + InstructionSet_PackedSimd=2, + InstructionSet_Vector128=3, +#endif // TARGET_WASM #ifdef TARGET_AMD64 InstructionSet_X86Base=1, InstructionSet_AVX=2, @@ -284,6 +289,8 @@ struct CORINFO_InstructionSetFlags #endif // TARGET_ARM64 #ifdef TARGET_RISCV64 #endif // TARGET_RISCV64 +#ifdef TARGET_WASM +#endif // TARGET_WASM #ifdef TARGET_AMD64 if (HasInstructionSet(InstructionSet_X86Base)) AddInstructionSet(InstructionSet_X86Base_X64); @@ -448,6 +455,12 @@ inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_Ins if (resultflags.HasInstructionSet(InstructionSet_Zbs) && !resultflags.HasInstructionSet(InstructionSet_RiscV64Base)) resultflags.RemoveInstructionSet(InstructionSet_Zbs); #endif // TARGET_RISCV64 +#ifdef TARGET_WASM + if (resultflags.HasInstructionSet(InstructionSet_Vector128) && !resultflags.HasInstructionSet(InstructionSet_PackedSimd)) + resultflags.RemoveInstructionSet(InstructionSet_Vector128); + if (resultflags.HasInstructionSet(InstructionSet_PackedSimd) && !resultflags.HasInstructionSet(InstructionSet_WasmBase)) + resultflags.RemoveInstructionSet(InstructionSet_PackedSimd); +#endif // TARGET_WASM #ifdef TARGET_AMD64 if (resultflags.HasInstructionSet(InstructionSet_X86Base) && !resultflags.HasInstructionSet(InstructionSet_X86Base_X64)) resultflags.RemoveInstructionSet(InstructionSet_X86Base); @@ -742,6 +755,14 @@ inline const char *InstructionSetToString(CORINFO_InstructionSet instructionSet) case InstructionSet_Zbs : return "Zbs"; #endif // TARGET_RISCV64 +#ifdef TARGET_WASM + case InstructionSet_WasmBase : + return "WasmBase"; + case InstructionSet_PackedSimd : + return "PackedSimd"; + case InstructionSet_Vector128 : + return "Vector128"; +#endif // TARGET_WASM #ifdef TARGET_AMD64 case InstructionSet_X86Base : return "X86Base"; @@ -943,6 +964,10 @@ inline CORINFO_InstructionSet InstructionSetFromR2RInstructionSet(ReadyToRunInst case READYTORUN_INSTRUCTION_Zbb: return InstructionSet_Zbb; case READYTORUN_INSTRUCTION_Zbs: return InstructionSet_Zbs; #endif // TARGET_RISCV64 +#ifdef TARGET_WASM + case READYTORUN_INSTRUCTION_WasmBase: return InstructionSet_WasmBase; + case READYTORUN_INSTRUCTION_PackedSimd: return InstructionSet_PackedSimd; +#endif // TARGET_WASM #ifdef TARGET_AMD64 case READYTORUN_INSTRUCTION_X86Base: return InstructionSet_X86Base; case READYTORUN_INSTRUCTION_Sse: return InstructionSet_X86Base; diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 3f1d8e566f18f4..13da93b5bc597b 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -37,11 +37,11 @@ #include -constexpr GUID JITEEVersionIdentifier = { /* 31a04b06-915e-42a0-bbd2-c9c397677ae5 */ - 0x31a04b06, - 0x915e, - 0x42a0, - {0xbb, 0xd2, 0xc9, 0xc3, 0x97, 0x67, 0x7a, 0xe5} +constexpr GUID JITEEVersionIdentifier = { /* 00584b4c-9681-41ae-87be-17bc0d7643a3 */ + 0x00584b4c, + 0x9681, + 0x41ae, + {0x87, 0xbe, 0x17, 0xbc, 0x0d, 0x76, 0x43, 0xa3} }; #endif // JIT_EE_VERSIONING_GUID_H diff --git a/src/coreclr/inc/readytoruninstructionset.h b/src/coreclr/inc/readytoruninstructionset.h index d6621204e21a75..6e491f85381089 100644 --- a/src/coreclr/inc/readytoruninstructionset.h +++ b/src/coreclr/inc/readytoruninstructionset.h @@ -98,6 +98,8 @@ enum ReadyToRunInstructionSet READYTORUN_INSTRUCTION_SveAes=88, READYTORUN_INSTRUCTION_SveSha3=89, READYTORUN_INSTRUCTION_SveSm4=90, + READYTORUN_INSTRUCTION_WasmBase=91, + READYTORUN_INSTRUCTION_PackedSimd=92, }; diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs index a56531e847e41c..14e8c9585a0495 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSet.cs @@ -101,5 +101,7 @@ public enum ReadyToRunInstructionSet SveAes = 88, SveSha3 = 89, SveSm4 = 90, + WasmBase = 91, + PackedSimd = 92, } } diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSetHelper.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSetHelper.cs index be24be220c3719..196200fc55434f 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSetHelper.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunInstructionSetHelper.cs @@ -78,6 +78,18 @@ public static class ReadyToRunInstructionSetHelper } } + case TargetArchitecture.Wasm32: + { + switch (instructionSet) + { + case InstructionSet.Wasm32_WasmBase: return ReadyToRunInstructionSet.WasmBase; + case InstructionSet.Wasm32_PackedSimd: return ReadyToRunInstructionSet.PackedSimd; + case InstructionSet.Wasm32_Vector128: return null; + + default: throw new Exception("Unknown instruction set"); + } + } + case TargetArchitecture.X64: { switch (instructionSet) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs b/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs index fb21652b239f52..7d83b59149c4dd 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs @@ -59,6 +59,9 @@ public enum InstructionSet RiscV64_Zba = InstructionSet_RiscV64.Zba, RiscV64_Zbb = InstructionSet_RiscV64.Zbb, RiscV64_Zbs = InstructionSet_RiscV64.Zbs, + Wasm32_WasmBase = InstructionSet_Wasm32.WasmBase, + Wasm32_PackedSimd = InstructionSet_Wasm32.PackedSimd, + Wasm32_Vector128 = InstructionSet_Wasm32.Vector128, X64_X86Base = InstructionSet_X64.X86Base, X64_AVX = InstructionSet_X64.AVX, X64_AVX2 = InstructionSet_X64.AVX2, @@ -206,6 +209,15 @@ public enum InstructionSet_RiscV64 Zbs = 4, } + public enum InstructionSet_Wasm32 + { + ILLEGAL = InstructionSet.ILLEGAL, + NONE = InstructionSet.NONE, + WasmBase = 1, + PackedSimd = 2, + Vector128 = 3, + } + public enum InstructionSet_X64 { ILLEGAL = InstructionSet.ILLEGAL, @@ -319,6 +331,8 @@ public unsafe struct InstructionSetFlags : IEnumerable public IEnumerable RiscV64Flags => this.Select((x) => (InstructionSet_RiscV64)x); + public IEnumerable Wasm32Flags => this.Select((x) => (InstructionSet_Wasm32)x); + public IEnumerable X64Flags => this.Select((x) => (InstructionSet_X64)x); public IEnumerable X86Flags => this.Select((x) => (InstructionSet_X86)x); @@ -438,6 +452,12 @@ public static InstructionSet ConvertToImpliedInstructionSetForVectorInstructionS case InstructionSet.ARM64_VectorT: return InstructionSet.ARM64_Sve; } break; + case TargetArchitecture.Wasm32: + switch (input) + { + case InstructionSet.Wasm32_Vector128: return InstructionSet.Wasm32_PackedSimd; + } + break; case TargetArchitecture.X64: switch (input) { @@ -581,6 +601,13 @@ public static InstructionSetFlags ExpandInstructionSetByImplicationHelper(Target resultflags.AddInstructionSet(InstructionSet.RiscV64_RiscV64Base); break; + case TargetArchitecture.Wasm32: + if (resultflags.HasInstructionSet(InstructionSet.Wasm32_Vector128)) + resultflags.AddInstructionSet(InstructionSet.Wasm32_PackedSimd); + if (resultflags.HasInstructionSet(InstructionSet.Wasm32_PackedSimd)) + resultflags.AddInstructionSet(InstructionSet.Wasm32_WasmBase); + break; + case TargetArchitecture.X64: if (resultflags.HasInstructionSet(InstructionSet.X64_X86Base)) resultflags.AddInstructionSet(InstructionSet.X64_X86Base_X64); @@ -879,6 +906,13 @@ private static InstructionSetFlags ExpandInstructionSetByReverseImplicationHelpe resultflags.AddInstructionSet(InstructionSet.RiscV64_Zbs); break; + case TargetArchitecture.Wasm32: + if (resultflags.HasInstructionSet(InstructionSet.Wasm32_PackedSimd)) + resultflags.AddInstructionSet(InstructionSet.Wasm32_Vector128); + if (resultflags.HasInstructionSet(InstructionSet.Wasm32_WasmBase)) + resultflags.AddInstructionSet(InstructionSet.Wasm32_PackedSimd); + break; + case TargetArchitecture.X64: if (resultflags.HasInstructionSet(InstructionSet.X64_X86Base_X64)) resultflags.AddInstructionSet(InstructionSet.X64_X86Base); @@ -1124,6 +1158,12 @@ public static IEnumerable ArchitectureToValidInstructionSets yield return new InstructionSetInfo("zbs", "", InstructionSet.RiscV64_Zbs, true); break; + case TargetArchitecture.Wasm32: + yield return new InstructionSetInfo("base", "WasmBase", InstructionSet.Wasm32_WasmBase, true); + yield return new InstructionSetInfo("simd128", "PackedSimd", InstructionSet.Wasm32_PackedSimd, true); + yield return new InstructionSetInfo("Vector128", "", InstructionSet.Wasm32_Vector128, false); + break; + case TargetArchitecture.X64: yield return new InstructionSetInfo("base", "X86Base", InstructionSet.X64_X86Base, true); yield return new InstructionSetInfo("base", "Sse", InstructionSet.X64_X86Base, true); @@ -1315,6 +1355,9 @@ public void Set64BitInstructionSetVariants(TargetArchitecture architecture) case TargetArchitecture.RiscV64: break; + case TargetArchitecture.Wasm32: + break; + case TargetArchitecture.X64: if (HasInstructionSet(InstructionSet.X64_X86Base)) AddInstructionSet(InstructionSet.X64_X86Base_X64); @@ -1381,6 +1424,9 @@ public void Set64BitInstructionSetVariantsUnconditionally(TargetArchitecture arc case TargetArchitecture.RiscV64: break; + case TargetArchitecture.Wasm32: + break; + case TargetArchitecture.X64: AddInstructionSet(InstructionSet.X64_X86Base_X64); AddInstructionSet(InstructionSet.X64_AVX_X64); @@ -1449,6 +1495,10 @@ public static InstructionSet LookupPlatformIntrinsicInstructionSet(TargetArchite platformIntrinsicNamespace = "System.Runtime.Intrinsics.Arm"; break; + case TargetArchitecture.Wasm32: + platformIntrinsicNamespace = "System.Runtime.Intrinsics.Wasm"; + break; + case TargetArchitecture.X64: platformIntrinsicNamespace = "System.Runtime.Intrinsics.X86"; break; @@ -1566,6 +1616,18 @@ public static InstructionSet LookupPlatformIntrinsicInstructionSet(TargetArchite case TargetArchitecture.RiscV64: switch (typeName) { + default: + return InstructionSet.ILLEGAL; + } + case TargetArchitecture.Wasm32: + switch (typeName) + { + case "WasmBase": + return InstructionSet.Wasm32_WasmBase; + + case "PackedSimd": + return InstructionSet.Wasm32_PackedSimd; + default: return InstructionSet.ILLEGAL; } @@ -2243,6 +2305,26 @@ public static IEnumerable LookupPlatformIntrinsicTypes(TypeSystemC } break; + case (InstructionSet.Wasm32_WasmBase, TargetArchitecture.Wasm32): + { + var type = context.SystemModule.GetType("System.Runtime.Intrinsics.Wasm"u8, "WasmBase"u8, false); + if (type != null) + { + yield return type; + } + } + break; + + case (InstructionSet.Wasm32_PackedSimd, TargetArchitecture.Wasm32): + { + var type = context.SystemModule.GetType("System.Runtime.Intrinsics.Wasm"u8, "PackedSimd"u8, false); + if (type != null) + { + yield return type; + } + } + break; + case (InstructionSet.X64_X86Base, TargetArchitecture.X64): case (InstructionSet.X64_X86Base_X64, TargetArchitecture.X64): { diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt index 1391dba1965a87..3c26eebd6d90b6 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt @@ -26,7 +26,7 @@ ; DO NOT CHANGE R2R NUMERIC VALUES OF THE EXISTING SETS. Changing R2R numeric values definitions would be R2R format breaking change. ; The ISA definitions should also be mapped to `hwintrinsicIsaRangeArray` in hwintrinsic.cpp. -; NEXT_AVAILABLE_R2R_BIT = 91 +; NEXT_AVAILABLE_R2R_BIT = 93 ; Definition of X86 instruction sets definearch ,X86 ,32Bit ,X64, X64, X86 @@ -302,3 +302,15 @@ instructionsetgroup ,armv8.6-a ,ARM64 ,armv8.5-a ; Technically, apple-m1 is v8.5+ instructionsetgroup ,apple-m1 ,ARM64 ,armv8.5-a + + +; Definition of Wasm instruction sets +definearch ,Wasm32 ,32Bit , , ,Wasm + +instructionset ,Wasm32 ,WasmBase , ,91 ,WasmBase ,base +instructionset ,Wasm32 ,PackedSimd , ,92 ,PackedSimd ,simd128 +instructionset ,Wasm32 , , , ,Vector128 , + +vectorinstructionset ,Wasm32 ,Vector128 +implication ,Wasm32 ,Vector128 ,PackedSimd +implication ,Wasm32 ,PackedSimd ,WasmBase \ No newline at end of file diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs index b8aa3e14548856..3acb2c3de66e43 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs @@ -121,6 +121,8 @@ private static string ArchToIfDefArch(string arch) return "AMD64"; if (arch == "RiscV64") return "RISCV64"; + if (arch == "Wasm32") + return "WASM"; return arch; } From 71d3c13cd5394d5017ba8eff53743034b5474089 Mon Sep 17 00:00:00 2001 From: adamperlin Date: Mon, 8 Jun 2026 16:42:36 -0700 Subject: [PATCH 2/2] Update GetHardwareIntrinsicId() to have a Wasm32 case --- src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs b/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs index f04bdd184f3a75..061d4e161cc3b0 100644 --- a/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs +++ b/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs @@ -95,6 +95,11 @@ public static string GetHardwareIntrinsicId(TargetArchitecture architecture, Typ { return ""; } + else if (architecture is TargetArchitecture.Wasm32) + { + // TODO-WASM: return the correct intrinsic id once xplat intrinsics are implemented. + return ""; + } else { throw new InternalCompilerErrorException($"Unknown architecture '{architecture}'");