diff --git a/docs/design/coreclr/botr/readytorun-format.md b/docs/design/coreclr/botr/readytorun-format.md index b48e55339d9ec6..0a2ebf34cc72b3 100644 --- a/docs/design/coreclr/botr/readytorun-format.md +++ b/docs/design/coreclr/botr/readytorun-format.md @@ -1059,6 +1059,7 @@ The string format is: | `l` | returns `i64` | | `f` | returns `f32` | | `d` | returns `f64` | +| `V` | returns `v128` (a `Vector128`, or a 16-byte `Vector`) | | `S` | struct return via hidden buffer, `N` is the struct size in bytes | **This pointer** (if the method has a `this` parameter): @@ -1085,6 +1086,7 @@ it knows a hidden retbuf pointer argument is present in the Wasm parameter list. | `l` | `i64` parameter | | `f` | `f32` parameter | | `d` | `f64` parameter | +| `V` | `v128` parameter (a `Vector128`, or a 16-byte `Vector`, passed by value) | | `S` | struct parameter passed by reference, `` is the struct size in bytes | | `e` | empty struct parameter — elided from Wasm args but present in the string | diff --git a/src/coreclr/vm/wasm/helpers.cpp b/src/coreclr/vm/wasm/helpers.cpp index 5295261aa3b27d..2f6ff7fddb2f73 100644 --- a/src/coreclr/vm/wasm/helpers.cpp +++ b/src/coreclr/vm/wasm/helpers.cpp @@ -989,6 +989,7 @@ namespace ToI64, ToF32, ToF64, + ToV128, ToStruct, // S — multi-field struct passed by pointer, structSize holds the size ToEmpty, // e — empty struct, takes no wasm argument }; @@ -1032,6 +1033,23 @@ namespace } MethodTable* pMT = th.AsMethodTable(); + + bool isSupportedVectorBaseType = + pMT->IsIntrinsicType() && + (pMT->GetNumGenericArgs() == 1) && + CorIsNumericalType(pMT->GetInstantiation()[0].GetSignatureCorElementType()); + if (isSupportedVectorBaseType) + { + PTR_MethodTable pVector128MT = CoreLibBinder::GetClassIfExist(CLASS__VECTOR128T); + PTR_MethodTable pVectorTMT = CoreLibBinder::GetClassIfExist(CLASS__VECTORT); + + if ((pVector128MT != nullptr && pMT->HasSameTypeDefAs(pVector128MT)) || + ((size == 16) && (pVectorTMT != nullptr) && pMT->HasSameTypeDefAs(pVectorTMT))) + { + return { ConvertType::ToV128, 0 }; + } + } + uint32_t numInstanceFields = pMT->GetNumInstanceFields(); // WASM-TODO: Empty structs should return ToEmpty once .NET @@ -1107,6 +1125,7 @@ namespace case ConvertType::ToI64: c = 'l'; break; case ConvertType::ToF32: c = 'f'; break; case ConvertType::ToF64: c = 'd'; break; + case ConvertType::ToV128: c = 'V'; break; case ConvertType::ToEmpty: c = 'e'; break; case ConvertType::ToStruct: {