-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Implement Sse2 memory fence instructions #16262
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -744,7 +744,7 @@ void CodeGen::genSSE2Intrinsic(GenTreeHWIntrinsic* node) | |
regNumber targetReg = node->gtRegNum; | ||
var_types targetType = node->TypeGet(); | ||
var_types baseType = node->gtSIMDBaseType; | ||
instruction ins = Compiler::insOfHWIntrinsic(intrinsicID, baseType); | ||
instruction ins = INS_invalid; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is fine, but from a stylistic perspective, since this is only used inside a subset of the switch cases, one might move the declaration down into those scopes. |
||
regNumber op1Reg = REG_NA; | ||
regNumber op2Reg = REG_NA; | ||
emitter* emit = getEmitter(); | ||
|
@@ -765,18 +765,37 @@ void CodeGen::genSSE2Intrinsic(GenTreeHWIntrinsic* node) | |
assert(op2 != nullptr); | ||
assert(baseType == TYP_DOUBLE); | ||
|
||
ins = Compiler::insOfHWIntrinsic(intrinsicID, baseType); | ||
op2Reg = op2->gtRegNum; | ||
ival = Compiler::ivalOfHWIntrinsic(intrinsicID); | ||
emit->emitIns_SIMD_R_R_R_I(ins, emitTypeSize(TYP_SIMD16), targetReg, op1Reg, op2Reg, ival); | ||
|
||
break; | ||
} | ||
|
||
case NI_SSE2_LoadFence: | ||
{ | ||
assert(baseType == TYP_VOID); | ||
assert(op1 == nullptr); | ||
assert(op2 == nullptr); | ||
emit->emitIns(INS_lfence); | ||
break; | ||
} | ||
case NI_SSE2_MemoryFence: | ||
{ | ||
assert(baseType == TYP_VOID); | ||
assert(op1 == nullptr); | ||
assert(op2 == nullptr); | ||
emit->emitIns(INS_mfence); | ||
break; | ||
} | ||
|
||
case NI_SSE2_MoveMask: | ||
{ | ||
assert(op2 == nullptr); | ||
assert(baseType == TYP_BYTE || baseType == TYP_UBYTE || baseType == TYP_DOUBLE); | ||
|
||
ins = Compiler::insOfHWIntrinsic(intrinsicID, baseType); | ||
emit->emitIns_R_R(ins, emitTypeSize(TYP_INT), targetReg, op1Reg); | ||
break; | ||
} | ||
|
@@ -788,6 +807,7 @@ void CodeGen::genSSE2Intrinsic(GenTreeHWIntrinsic* node) | |
assert(op1 == nullptr); | ||
assert(op2 == nullptr); | ||
|
||
ins = Compiler::insOfHWIntrinsic(intrinsicID, baseType); | ||
emit->emitIns_SIMD_R_R_R(ins, emitTypeSize(TYP_SIMD16), targetReg, targetReg, targetReg); | ||
break; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -736,6 +736,8 @@ GenTree* Compiler::impSSE2Intrinsic(NamedIntrinsic intrinsic, | |
var_types baseType = TYP_UNKNOWN; | ||
var_types retType = TYP_UNKNOWN; | ||
|
||
assert((simdSize == 16) || (simdSize == 0)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could use a comment; I think that whenever we do the "simdSize == 0" check it deserves a comment, e.g. "A simdSize of zero means that it is not a SIMD type" because it could be confusing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The SSE code added:
|
||
|
||
switch (intrinsic) | ||
{ | ||
case NI_SSE2_CompareLessThan: | ||
|
@@ -754,6 +756,17 @@ GenTree* Compiler::impSSE2Intrinsic(NamedIntrinsic intrinsic, | |
} | ||
break; | ||
|
||
case NI_SSE2_LoadFence: | ||
case NI_SSE2_MemoryFence: | ||
{ | ||
assert(sig->numArgs == 0); | ||
assert(JITtype2varType(sig->retType) == TYP_VOID); | ||
assert(simdSize == 0); | ||
|
||
retNode = gtNewSimdHWIntrinsicNode(TYP_VOID, intrinsic, TYP_VOID, simdSize); | ||
break; | ||
} | ||
|
||
case NI_SSE2_MoveMask: | ||
assert(sig->numArgs == 1); | ||
retType = JITtype2varType(sig->retType); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
// | ||
|
||
using System; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
using System.Runtime.Intrinsics.X86; | ||
using System.Runtime.Intrinsics; | ||
|
||
namespace IntelHardwareIntrinsicTest | ||
{ | ||
class Program | ||
{ | ||
const int Pass = 100; | ||
const int Fail = 0; | ||
|
||
static unsafe int Main(string[] args) | ||
{ | ||
int testResult = Pass; | ||
|
||
if (Sse2.IsSupported) | ||
{ | ||
try | ||
{ | ||
Sse2.LoadFence(); | ||
} | ||
catch | ||
{ | ||
testResult = Fail; | ||
} | ||
} | ||
|
||
return testResult; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> | ||
<PropertyGroup> | ||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
<SchemaVersion>2.0</SchemaVersion> | ||
<ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> | ||
<OutputType>Exe</OutputType> | ||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
</PropertyGroup> | ||
<!-- Default configurations to help VS understand the configurations --> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " /> | ||
<ItemGroup> | ||
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> | ||
<Visible>False</Visible> | ||
</CodeAnalysisDependentAssemblyPaths> | ||
</ItemGroup> | ||
<PropertyGroup> | ||
<DebugType>None</DebugType> | ||
<Optimize></Optimize> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Compile Include="LoadFence.cs" /> | ||
</ItemGroup> | ||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> | ||
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> | ||
<PropertyGroup> | ||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
<SchemaVersion>2.0</SchemaVersion> | ||
<ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> | ||
<OutputType>Exe</OutputType> | ||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
</PropertyGroup> | ||
<!-- Default configurations to help VS understand the configurations --> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " /> | ||
<ItemGroup> | ||
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> | ||
<Visible>False</Visible> | ||
</CodeAnalysisDependentAssemblyPaths> | ||
</ItemGroup> | ||
<PropertyGroup> | ||
<DebugType>None</DebugType> | ||
<Optimize>True</Optimize> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Compile Include="LoadFence.cs" /> | ||
</ItemGroup> | ||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> | ||
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
// | ||
|
||
using System; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
using System.Runtime.Intrinsics.X86; | ||
using System.Runtime.Intrinsics; | ||
|
||
namespace IntelHardwareIntrinsicTest | ||
{ | ||
class Program | ||
{ | ||
const int Pass = 100; | ||
const int Fail = 0; | ||
|
||
static unsafe int Main(string[] args) | ||
{ | ||
int testResult = Pass; | ||
|
||
if (Sse2.IsSupported) | ||
{ | ||
try | ||
{ | ||
Sse2.MemoryFence(); | ||
} | ||
catch | ||
{ | ||
testResult = Fail; | ||
} | ||
} | ||
|
||
return testResult; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> | ||
<PropertyGroup> | ||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
<SchemaVersion>2.0</SchemaVersion> | ||
<ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> | ||
<OutputType>Exe</OutputType> | ||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
</PropertyGroup> | ||
<!-- Default configurations to help VS understand the configurations --> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " /> | ||
<ItemGroup> | ||
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> | ||
<Visible>False</Visible> | ||
</CodeAnalysisDependentAssemblyPaths> | ||
</ItemGroup> | ||
<PropertyGroup> | ||
<DebugType>None</DebugType> | ||
<Optimize></Optimize> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Compile Include="MemoryFence.cs" /> | ||
</ItemGroup> | ||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> | ||
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> | ||
<PropertyGroup> | ||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
<SchemaVersion>2.0</SchemaVersion> | ||
<ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> | ||
<OutputType>Exe</OutputType> | ||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
</PropertyGroup> | ||
<!-- Default configurations to help VS understand the configurations --> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " /> | ||
<ItemGroup> | ||
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> | ||
<Visible>False</Visible> | ||
</CodeAnalysisDependentAssemblyPaths> | ||
</ItemGroup> | ||
<PropertyGroup> | ||
<DebugType>None</DebugType> | ||
<Optimize>True</Optimize> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Compile Include="MemoryFence.cs" /> | ||
</ItemGroup> | ||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> | ||
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup> | ||
</Project> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: We could probably just say
special case the fencing and prefetch instructions...