Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2017-11-09 03:20:39 +0300
committerGitHub <noreply@github.com>2017-11-09 03:20:39 +0300
commit162cead08753e6440d7e90ec4fb453a1a651785a (patch)
treedbb0478e51bd5b376386e6d0a38df7037fe51526
parent2bc2edc1e2b1b0e835366668b53ccfc48ece0949 (diff)
parent0566d28cd25fb5a8b708b94dd9ba7960a75e3b07 (diff)
Merge pull request #4894 from dotnet/master
Merge master to nmirror
-rw-r--r--Documentation/cross-building.md69
-rw-r--r--Documentation/how-to-build-ObjectWriter.md40
-rw-r--r--Documentation/how-to-build-and-run-ilcompiler-in-console-shell-prompt.md12
-rw-r--r--src/BuildIntegration/BuildFrameworkNativeObjects.proj8
-rw-r--r--src/BuildIntegration/Microsoft.NETCore.Native.Publish.targets61
-rw-r--r--src/BuildIntegration/Microsoft.NETCore.Native.targets28
-rw-r--r--src/Common/src/TypeSystem/Interop/IL/MarshalHelpers.cs9
-rw-r--r--src/ILCompiler.Build.Tasks/src/ComputeManagedAssemblies.cs168
-rw-r--r--src/ILCompiler.Build.Tasks/src/ILCompiler.Build.Tasks.csproj25
-rw-r--r--src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs251
-rw-r--r--src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs828
-rw-r--r--src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter_Statics.cs1
-rw-r--r--src/ILCompiler.WebAssembly/src/CodeGen/WebAssemblyObjectWriter.cs28
-rw-r--r--src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyCodegenNodeFactory.cs4
-rw-r--r--src/ILCompiler/ILCompiler.sln22
-rw-r--r--src/ILVerify/src/AccessVerificationHelpers.cs2
-rw-r--r--src/ILVerify/src/ILVerify.csproj4
-rw-r--r--src/Native/Bootstrap/main.cpp16
-rw-r--r--src/Native/CMakeLists.txt1
-rw-r--r--src/Native/ObjWriter/.nuget/Microsoft.DotNet.ObjectWriter.nuspec20
-rw-r--r--src/Native/ObjWriter/.nuget/runtime.json19
-rw-r--r--src/Native/ObjWriter/.nuget/toolchain.osx.10.10-x64.Microsoft.DotNet.ObjectWriter.nuspec20
-rw-r--r--src/Native/ObjWriter/.nuget/toolchain.ubuntu.14.04-x64.Microsoft.DotNet.ObjectWriter.nuspec20
-rw-r--r--src/Native/ObjWriter/.nuget/toolchain.win7-x64.Microsoft.DotNet.ObjectWriter.nuspec20
-rw-r--r--src/Native/ObjWriter/CMakeLists.txt41
-rw-r--r--src/Native/ObjWriter/cfi.h37
-rw-r--r--src/Native/ObjWriter/cordebuginfo.h327
-rw-r--r--src/Native/ObjWriter/cvconst.h3716
-rw-r--r--src/Native/ObjWriter/jitDebugInfo.h43
-rw-r--r--src/Native/ObjWriter/llvm.patch123
-rw-r--r--src/Native/ObjWriter/objwriter.cpp806
-rw-r--r--src/Native/ObjWriter/objwriter.exports26
-rw-r--r--src/Native/ObjWriter/objwriter.h312
-rw-r--r--src/Native/ObjWriter/typeBuilder.cpp321
-rw-r--r--src/Native/ObjWriter/typeBuilder.h145
-rw-r--r--src/Native/Runtime/unix/UnixContext.cpp126
-rw-r--r--src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems3
-rw-r--r--src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs (renamed from src/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs)266
-rw-r--r--src/System.Private.CoreLib/shared/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs38
-rw-r--r--src/System.Private.CoreLib/shared/System/Collections/HashHelpers.cs108
-rw-r--r--src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs14
-rw-r--r--src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs14
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs9
-rw-r--r--src/System.Private.CoreLib/src/System.Private.CoreLib.csproj5
-rw-r--r--src/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs30
-rw-r--r--src/System.Private.CoreLib/src/System/Decimal.cs7
-rw-r--r--src/System.Private.CoreLib/src/System/ThrowHelper.cs77
-rw-r--r--src/System.Private.Interop/src/Interop/Interop.WinRT.Basic.cs4
-rw-r--r--src/System.Private.Interop/src/System.Private.Interop.csproj2
-rw-r--r--tests/src/Simple/HelloWasm/Program.cs31
50 files changed, 7647 insertions, 660 deletions
diff --git a/Documentation/cross-building.md b/Documentation/cross-building.md
index afc0f07c9..247f933ac 100644
--- a/Documentation/cross-building.md
+++ b/Documentation/cross-building.md
@@ -1,7 +1,7 @@
Cross Compilation for ARM on Linux
==================================
-Through cross compilation, on Linux it is possible to build CoreCLR for arm or arm64.
+Through cross compilation, on Linux it is possible to build CoreRT for arm or arm64.
Requirements
------------
@@ -21,7 +21,7 @@ and conversely for arm64:
Generating the rootfs
---------------------
-The `cross\build-rootfs.sh` script can be used to download the files needed for cross compilation. It will generate an Ubuntu 14.04 rootfs as this is what CoreCLR targets.
+The `cross\build-rootfs.sh` script can be used to download the files needed for cross compilation. It will generate an Ubuntu 14.04 rootfs as this is what CoreRT targets.
Usage: build-rootfs.sh [BuildArch]
BuildArch can be: arm, arm64
@@ -38,7 +38,7 @@ and if you wanted to generate the rootfs elsewhere:
Cross compiling CoreCLR
-----------------------
-Once the rootfs has been generated, it will be possible to cross compile CoreCLR. If `ROOTFS_DIR` was set when generating the rootfs, then it must also be set when running `build.sh`.
+Once the rootfs has been generated, it will be possible to cross compile CoreRT. If `ROOTFS_DIR` was set when generating the rootfs, then it must also be set when running `build.sh`.
So, without `ROOTFS_DIR`:
@@ -49,3 +49,66 @@ And with:
$ ROOTFS_DIR=~/coreclr-cross/arm ./build.sh arm debug verbose clean cross
As usual the resulting binaries will be found in `bin/Product/BuildOS.BuildArch.BuildType/`
+
+Using CoreRT for cross compiling under arm on x86 host
+-----------------------
+It is possible to use CoreRT for compiling under arm/armel on x86 host (or on x64 machine using roots).
+
+1. Build CoreCLR for x86 (`checked` version)
+```
+sudo ./cross/build-rootfs.sh x86 xenial
+./build.sh clang3.9 x86 checked verbose cross skiptests
+```
+
+2. Build CoreFX (`Debug` version)
+3. Build CoreRT for armel, x64, x86
+```
+sudo ./cross/build-rootfs.sh armel tizen
+sudo ./cross/build-rootfs.sh x86 xenial
+./build.sh clang3.9 armel debug verbose cross
+./build.sh debug verbose skiptests
+./build.sh clang3.9 x86 debug verbose cross skiptests
+```
+
+4. Copy necessary binaries to working directory (in x86 rootfs)
+```
+cp ${CORECLR}/bin/Product/Linux.x86.Checked ${WORKING_DIR}
+cp ${CORERT}/bin/Linux.x86.Debug/tools/ilc.dll ${WORKING_DIR}
+cp ${CORERT}/bin/Linux.x86.Debug/tools/ILCompiler.* ${WORKING_DIR}
+cp ${CORERT}/bin/Linux.x86.Debug/tools/System.CommandLine.dll ${WORKING_DIR}
+cp ${CORERT}/bin/Linux.x86.Debug/tools/Microsoft.DiaSymReader.dll ${WORKING_DIR}
+cp ${CORERT}/bin/Linux.x86.Debug/tools/jitinterface.so ${WORKING_DIR}
+cp -r ${CORERT}/bin/Linux.x86.Debug/framework ${WORKING_DIR}
+
+# Copy CoreRT sdk binaries from target (armel) output folder
+cp -r ${CORERT}/bin/Linux.armel.Debug/sdk ${WORKING_DIR}
+```
+
+5. Rename RyuJIT compiler library
+```
+# Use cross-compiler library as default for ILC
+cp ${WORKING_DIR}/libarmelnonjit.so ${WORKING_DIR}/libclrjitilc.so
+
+# ... or ARM version instead if it's needed
+# cp ${WORKING_DIR}/libprotojit.so ${WORKING_DIR}/libclrjitilc.so
+```
+
+6. Build libobjwriter. You have to compile it on x86 chroot. Before compiling put coreclr/bin/Product/Linux.x86.Debug/ to some folder on x86 chroot as well. Versions which to used are mentioned on GitHub:
+https://github.com/dotnet/corert/issues/3776#issuecomment-337682166
+
+ And apply patch:
+https://gist.github.com/alpencolt/ec75fcc05d8c4ffbf143a052f7c115a8
+```
+mkdir build
+cd build
+cmake ../ -DWITH_CORECLR=../../coreclr/bin/Product/Linux.x86.Debug/ -DLLVM_TARGET_ARCH="ARM;X86" -DLLVM_TARGETS_TO_BUILD="ARM;X86" -DLLVM_DEFAULT_TARGET_TRIPLE=thumbv7-linux-gnueabi -DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_LLVM_DYLIB=1 -DLLVM_LINK_LLVM_DYLIB=1 -DLLVM_OPTIMIZED_TABLEGEN=1 -DHAVE_POSIX_SPAWN=0 -DLLVM_ENABLE_PIC=1 -DLLVM_BUILD_TESTS=0 -DLLVM_ENABLE_DOXYGEN=0 -DLLVM_INCLUDE_DOCS=0 -DLLVM_INCLUDE_TESTS=0 -DLLVM_BINUTILS_INCDIR=/usr/include
+make -j8 objwriter
+```
+
+7. And to execute use:
+```
+./corerun ilc.dll --verbose @Hello.ilc.rsp
+
+# For linking
+clang-3.9 -target arm-linux-gnueabi --sysroot=corert/cross/rootfs/armel -Bcorert/cross/rootfs/armel/usr/lib/gcc/armv7l-tizen-linux-gnueabi/6.2.1 -Lcorert/cross/rootfs/armel/usr/lib/gcc/armv7l-tizen-linux-gnueabi/6.2.1 Hello.o -o Hello corert/bin/Linux.armel.Debug/sdk/libbootstrapper.a corert/bin/Linux.armel.Debug/sdk/libRuntime.a corert/bin/Linux.armel.Debug/sdk/libSystem.Private.CoreLib.Native.a corert/bin/Linux.armel.Debug/framework/System.Native.a corert/bin/Linux.armel.Debug/framework/libSystem.Globalization.Native.a -g -Wl,-rpath,'$ORIGIN' -pthread -lstdc++ -ldl -lm -luuid -lrt -fPIC
+```
diff --git a/Documentation/how-to-build-ObjectWriter.md b/Documentation/how-to-build-ObjectWriter.md
new file mode 100644
index 000000000..a848a02ce
--- /dev/null
+++ b/Documentation/how-to-build-ObjectWriter.md
@@ -0,0 +1,40 @@
+# Build ObjectWriter library #
+
+ObjWriter is based on LLVM, so it requires recent CMake and GCC/Clang to build LLVM.
+See http://llvm.org/docs/GettingStarted.html#requirements for more details.
+
+1. Clone LLVM from official LLVM mirror github git repository:
+
+ ```
+ $ git clone -b release_50 https://github.com/llvm-mirror/llvm.git
+ ```
+
+2. Copy ObjWriter directory from CoreRT into LLVM tree
+
+ ```
+ $ cp -r CoreRT/src/Native/ObjWriter llvm/tools/
+ ```
+
+3. Apply the patch to LLVM:
+
+ ```
+ $ cd llvm
+ $ git apply tools/ObjWriter/llvm.patch
+ ```
+
+4. Configure and build LLVM with ObjWriter:
+
+ ```
+ $ mkdir build
+ $ cd build
+ $ cmake ../ -DCMAKE_BUILD_TYPE=Release -DLLVM_OPTIMIZED_TABLEGEN=1 -DHAVE_POSIX_SPAWN=0 -DLLVM_ENABLE_PIC=1 -DLLVM_BUILD_TESTS=0 -DLLVM_ENABLE_DOXYGEN=0 -DLLVM_INCLUDE_DOCS=0 -DLLVM_INCLUDE_TESTS=0
+ $ make -j10 objwriter
+ $ cd ..
+ ```
+
+* You can change the building type(CMAKE_BUILD_TYPE) to the debugging type(Debug), if necessary to debug ObjWriter.
+* Also, you can do this under chroot to building ObjWriter for other platforms.
+
+5. Get ObjWriter:
+
+ If all goes well, the build will complete in the previous step and you will get ObjWriter library as llvm/build/lib/libobjwriter.so
diff --git a/Documentation/how-to-build-and-run-ilcompiler-in-console-shell-prompt.md b/Documentation/how-to-build-and-run-ilcompiler-in-console-shell-prompt.md
index baf53f154..48b1f3b47 100644
--- a/Documentation/how-to-build-and-run-ilcompiler-in-console-shell-prompt.md
+++ b/Documentation/how-to-build-and-run-ilcompiler-in-console-shell-prompt.md
@@ -51,8 +51,6 @@ You should now be able to use the `dotnet` commands of the CLI tools.
* Please [open an issue](https://github.com/dotnet/corert/issues) if these instructions do not work anymore.
- * Projects with references to other projects or packages require workaround described in https://github.com/dotnet/corert/issues/2619#issuecomment-276095878
-
## Using RyuJIT ##
This approach uses the same code-generator (RyuJIT), as [CoreCLR](https://github.com/dotnet/coreclr), for compiling the application. Linking is done using the platform specific linker.
@@ -60,10 +58,10 @@ This approach uses the same code-generator (RyuJIT), as [CoreCLR](https://github
From the shell/command prompt, issue the following commands, from the folder containing your project, to generate the native executable
```
- dotnet build /t:LinkNative
+ dotnet publish -r win-x64|linux-x64|osx-x64
```
-Native executable will be dropped in `./bin/[configuration]/native/` folder and will have the same name as the folder in which your source file is present.
+Native executable will be dropped in `./bin/x64/[configuration]/netcoreapp2.0/publish/` folder and will have the same name as the folder in which your source file is present.
## Using CPP Code Generator ##
@@ -72,11 +70,15 @@ This approach uses [transpiler](https://en.wikipedia.org/wiki/Source-to-source_c
From the shell/command prompt, issue the following commands to generate the native executable:
```
- dotnet build /t:LinkNative /p:NativeCodeGen=cpp
+ dotnet publish /p:NativeCodeGen=cpp -r win-x64|linux-x64|osx-x64
```
For CoreRT debug build on Windows, add an extra `/p:AdditionalCppCompilerFlags=/MTd` argument.
+## Disabling Native Compilation
+
+Native compilation can be disabled during publishing by adding an extra `/p:NativeCompilationDuringPublish=false` argument.
+
## Workarounds for build errors on Windows ##
If you are seeing errors such as:
diff --git a/src/BuildIntegration/BuildFrameworkNativeObjects.proj b/src/BuildIntegration/BuildFrameworkNativeObjects.proj
index 3a1f2db03..806b087f4 100644
--- a/src/BuildIntegration/BuildFrameworkNativeObjects.proj
+++ b/src/BuildIntegration/BuildFrameworkNativeObjects.proj
@@ -1,7 +1,7 @@
<Project DefaultTargets="CreateLib" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
- <IlcCompileDependsOn>BuildOneFrameworkLibrary</IlcCompileDependsOn>
+ <IlcCompileDependsOn>ComputeIlcCompileInputs;BuildOneFrameworkLibrary</IlcCompileDependsOn>
<CreateLibDependsOn>BuildAllFrameworkLibrariesAsSingleLib</CreateLibDependsOn>
<IlcMultiModule>true</IlcMultiModule>
<NativeIntermediateOutputPath Condition="'$(FrameworkObjPath)' != ''">$(FrameworkObjPath)\</NativeIntermediateOutputPath>
@@ -11,12 +11,12 @@
<Import Project="Microsoft.NETCore.Native.targets" />
<Target Name="BuildAllFrameworkLibraries"
- Inputs="@(IlcReference)"
- Outputs="@(IlcReference->'$(NativeIntermediateOutputPath)\%(Filename)$(NativeObjectExt)')">
+ Inputs="@(DefaultFrameworkAssemblies)"
+ Outputs="@(DefaultFrameworkAssemblies->'$(NativeIntermediateOutputPath)\%(Filename)$(NativeObjectExt)')">
<ItemGroup>
<ProjectToBuild Include="$(MSBuildProjectFullPath)">
<AdditionalProperties>
- LibraryToCompile=%(IlcReference.Identity)
+ LibraryToCompile=%(DefaultFrameworkAssemblies.Identity)
</AdditionalProperties>
</ProjectToBuild>
</ItemGroup>
diff --git a/src/BuildIntegration/Microsoft.NETCore.Native.Publish.targets b/src/BuildIntegration/Microsoft.NETCore.Native.Publish.targets
new file mode 100644
index 000000000..755aa647f
--- /dev/null
+++ b/src/BuildIntegration/Microsoft.NETCore.Native.Publish.targets
@@ -0,0 +1,61 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <PropertyGroup>
+ <BuildTasksPath Condition="'$(BuildTasksPath)' == ''">$(MSBuildThisFileDirectory)..\tools\ILCompiler.Build.Tasks.dll</BuildTasksPath>
+
+ <!--
+ Prevent dotnet CLI from deploying the CoreCLR shim executable since we produce
+ a native executable.
+ -->
+ <DeployAppHost>false</DeployAppHost>
+ </PropertyGroup>
+
+ <Target Name="_ComputeIlcCompileInputs"
+ BeforeTargets="ComputeIlcCompileInputs">
+ <ItemGroup>
+ <IlcReference Include="@(_ManagedResolvedAssembliesToPublish)" />
+ </ItemGroup>
+ </Target>
+
+ <!--
+ This target hooks into the dotnet CLI publish pipeline. That pipeline has
+ a target called ComputeFilesToPublish which produces the ItemGroup
+ ResolvedFileToPublish based on the inputs of @(IntermediateAssembly)
+ and @(ResolvedAssembliesToPublish). We modify those two item groups
+ to control what gets published after CoreRT optimizes the application.
+ -->
+ <Target Name="ComputeLinkedFilesToPublish"
+ BeforeTargets="ComputeFilesToPublish"
+ DependsOnTargets="_ComputeAssembliesToCompileToNative;LinkNative">
+
+ <ItemGroup>
+ <ResolvedAssembliesToPublish Remove="@(_AssembliesToSkipPublish)" />
+ <ResolvedAssembliesToPublish Include="@(_LinkedResolvedAssemblies)" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <_NativeIntermediateAssembly Include="@(IntermediateAssembly->'$(NativeOutputPath)%(Filename)$(NativeBinaryExt)')" />
+ <IntermediateAssembly Remove="@(IntermediateAssembly)" />
+ <IntermediateAssembly Include="@(_NativeIntermediateAssembly)" />
+ </ItemGroup>
+ </Target>
+
+ <!--
+ Filter the input publish file list selecting managed assemblies for compilation.
+ Also produces _AssembliesToSkipPublish which chops out things from the publish
+ pipeline we don't want to see in the output (native images, CoreCLR artifacts)
+ until we get a proper AOT NetCore app package.
+ -->
+ <UsingTask TaskName="ComputeManagedAssemblies" AssemblyFile="$(BuildTasksPath)" />
+ <Target Name="_ComputeAssembliesToCompileToNative">
+
+ <ComputeManagedAssemblies Assemblies="@(ResolvedAssembliesToPublish)"
+ DotNetAppHostExecutableName="$(_DotNetAppHostExecutableName)" DotNetHostFxrLibraryName="$(_DotNetHostFxrLibraryName)" DotNetHostPolicyLibraryName="$(_DotNetHostPolicyLibraryName)"
+ SdkAssemblies="@(PrivateSdkAssemblies)" FrameworkAssemblies="@(FrameworkAssemblies)">
+ <Output TaskParameter="ManagedAssemblies" ItemName="_ManagedResolvedAssembliesToPublish" />
+ <Output TaskParameter="AssembliesToSkipPublish" ItemName="_AssembliesToSkipPublish" />
+ </ComputeManagedAssemblies>
+
+ </Target>
+
+</Project>
diff --git a/src/BuildIntegration/Microsoft.NETCore.Native.targets b/src/BuildIntegration/Microsoft.NETCore.Native.targets
index 6e522fe48..22dd34fb0 100644
--- a/src/BuildIntegration/Microsoft.NETCore.Native.targets
+++ b/src/BuildIntegration/Microsoft.NETCore.Native.targets
@@ -19,6 +19,7 @@ See the LICENSE file in the project root for more information.
<PropertyGroup>
<NativeIntermediateOutputPath Condition="'$(NativeIntermediateOutputPath)' == ''">$(IntermediateOutputPath)native\</NativeIntermediateOutputPath>
<NativeOutputPath Condition="'$(NativeOutputPath)' == ''">$(OutputPath)native\</NativeOutputPath>
+ <NativeCompilationDuringPublish Condition="'$(NativeCompilationDuringPublish)' == ''">true</NativeCompilationDuringPublish>
<!-- Workaround for lack of current host OS detection - https://github.com/Microsoft/msbuild/issues/539 -->
<TargetOS Condition="'$(TargetOS)' == '' and '$(OS)' == 'Unix' and Exists('/Applications')">OSX</TargetOS>
<TargetOS Condition="'$(TargetOS)' == ''">$(OS)</TargetOS>
@@ -60,20 +61,23 @@ See the LICENSE file in the project root for more information.
<SharedLibrary Condition="'$(OS)' != 'Windows_NT'">$(FrameworkLibPath)\libframework$(LibFileExt)</SharedLibrary>
</PropertyGroup>
- <ItemGroup Condition="$(BuildingFrameworkLibrary) != 'true'">
- <ManagedBinary Include="$(IntermediateOutputPath)$(TargetName)$(TargetExt)" />
- </ItemGroup>
+ <PropertyGroup Condition="'$(IlcCompileDependsOn)'=='' and '$(NativeCompilationDuringPublish)' != 'false'">
+ <IlcCompileDependsOn Condition="'$(BuildingFrameworkLibrary)' != 'true'">Compile;ComputeIlcCompileInputs</IlcCompileDependsOn>
+ <IlcCompileDependsOn Condition="'$(IlcMultiModule)' == 'true' and '$(BuildingFrameworkLibrary)' != 'true'">$(IlcCompileDependsOn);BuildFrameworkLib</IlcCompileDependsOn>
+ </PropertyGroup>
<ItemGroup>
- <IlcCompileInput Include="@(ManagedBinary)" />
- <IlcReference Include="$(IlcPath)\sdk\*.dll" />
- <IlcReference Include="$(IlcPath)\framework\*.dll" />
+ <DefaultFrameworkAssemblies Include="$(IlcPath)\sdk\*.dll" />
+ <DefaultFrameworkAssemblies Include="$(IlcPath)\framework\*.dll" />
</ItemGroup>
- <PropertyGroup Condition="'$(IlcCompileDependsOn)'==''">
- <IlcCompileDependsOn Condition="'$(BuildingFrameworkLibrary)' != 'true'">Compile</IlcCompileDependsOn>
- <IlcCompileDependsOn Condition="'$(IlcMultiModule)' == 'true' and '$(BuildingFrameworkLibrary)' != 'true'">$(IlcCompileDependsOn);BuildFrameworkLib</IlcCompileDependsOn>
- </PropertyGroup>
+ <Target Name="ComputeIlcCompileInputs">
+ <ItemGroup>
+ <ManagedBinary Condition="$(BuildingFrameworkLibrary) != 'true'" Include="$(IntermediateOutputPath)$(TargetName)$(TargetExt)" />
+ <IlcCompileInput Include="@(ManagedBinary)" />
+ <IlcReference Include="@(DefaultFrameworkAssemblies)" />
+ </ItemGroup>
+ </Target>
<!--
BuildFrameworkLib is invoked before IlcCompile in multi-module builds to
@@ -107,6 +111,7 @@ See the LICENSE file in the project root for more information.
<IlcArg Condition="$(Optimize) == 'true'" Include="-O" />
<IlcArg Condition="$(DebugSymbols) == 'true'" Include="-g" />
<IlcArg Condition="$(IlcGenerateMapFile) == 'true'" Include="--map:$(NativeIntermediateOutputPath)%(ManagedBinary.Filename).map.xml" />
+ <IlcArg Condition="$(RdXmlFile) != ''" Include="--rdxml:$(RdXmlFile)" />
</ItemGroup>
<MakeDir Directories="$(NativeIntermediateOutputPath)" />
@@ -178,4 +183,7 @@ See the LICENSE file in the project root for more information.
<Exec Command="$(CppLibCreator) @&quot;$(NativeIntermediateOutputPath)lib.rsp&quot;" Condition="'$(OS)' == 'Windows_NT'" />
<Exec Command="$(CppLibCreator) @(CustomLibArg, ' ')" Condition="'$(OS)' != 'Windows_NT'" />
</Target>
+
+ <Import Project="$(MSBuildThisFileDirectory)\Microsoft.NETCore.Native.Publish.targets" Condition="'$(NativeCompilationDuringPublish)' != 'false'" />
+
</Project>
diff --git a/src/Common/src/TypeSystem/Interop/IL/MarshalHelpers.cs b/src/Common/src/TypeSystem/Interop/IL/MarshalHelpers.cs
index 08458b899..00954908a 100644
--- a/src/Common/src/TypeSystem/Interop/IL/MarshalHelpers.cs
+++ b/src/Common/src/TypeSystem/Interop/IL/MarshalHelpers.cs
@@ -96,15 +96,6 @@ namespace Internal.TypeSystem.Interop
if (forceLazyResolution.HasValue)
return forceLazyResolution.Value;
- // In multi-module library mode, the WinRT p/invokes in System.Private.Interop cause linker failures
- // since we don't link against the OS libraries containing those APIs. Force them to be lazy.
- // See https://github.com/dotnet/corert/issues/2601
- string assemblySimpleName = ((IAssemblyDesc)((MetadataType)method.OwningType).Module).GetName().Name;
- if (assemblySimpleName == "System.Private.Interop")
- {
- return true;
- }
-
// Determine whether this call should be made through a lazy resolution or a static reference
// Eventually, this should be controlled by a custom attribute (or an extension to the metadata format).
if (importModule == "[MRT]" || importModule == "*")
diff --git a/src/ILCompiler.Build.Tasks/src/ComputeManagedAssemblies.cs b/src/ILCompiler.Build.Tasks/src/ComputeManagedAssemblies.cs
new file mode 100644
index 000000000..0e4998ece
--- /dev/null
+++ b/src/ILCompiler.Build.Tasks/src/ComputeManagedAssemblies.cs
@@ -0,0 +1,168 @@
+// 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 Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection.Metadata;
+using System.Reflection.PortableExecutable;
+
+
+
+namespace Build.Tasks
+{
+ public class ComputeManagedAssemblies : Task
+ {
+ [Required]
+ public ITaskItem[] Assemblies
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// The CoreRT-specific System.Private.* assemblies that must be used instead of the netcoreapp2.0 versions.
+ /// </summary>
+ [Required]
+ public ITaskItem[] SdkAssemblies
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// The set of AOT-specific framework assemblies we currently need to use which will replace the same-named ones
+ /// in the app's closure.
+ /// </summary>
+ [Required]
+ public ITaskItem[] FrameworkAssemblies
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// The native apphost (whose name ends up colliding with the CoreRT output binary)
+ /// </summary>
+ [Required]
+ public string DotNetAppHostExecutableName
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// The CoreCLR dotnet host fixer library that can be skipped during publish
+ /// </summary>
+ [Required]
+ public string DotNetHostFxrLibraryName
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// The CoreCLR dotnet host policy library that can be skipped during publish
+ /// </summary>
+ [Required]
+ public string DotNetHostPolicyLibraryName
+ {
+ get;
+ set;
+ }
+
+ [Output]
+ public ITaskItem[] ManagedAssemblies
+ {
+ get;
+ set;
+ }
+
+ [Output]
+ public ITaskItem[] AssembliesToSkipPublish
+ {
+ get;
+ set;
+ }
+
+ public override bool Execute()
+ {
+ var list = new List<ITaskItem>();
+ var assembliesToSkipPublish = new List<ITaskItem>();
+
+ var coreRTFrameworkAssembliesToUse = new HashSet<string>();
+
+ foreach (ITaskItem taskItem in SdkAssemblies)
+ {
+ coreRTFrameworkAssembliesToUse.Add(Path.GetFileName(taskItem.ItemSpec));
+ }
+
+ foreach (ITaskItem taskItem in FrameworkAssemblies)
+ {
+ coreRTFrameworkAssembliesToUse.Add(Path.GetFileName(taskItem.ItemSpec));
+ }
+
+ foreach (ITaskItem taskItem in Assemblies)
+ {
+ // In the case of disk-based assemblies, this holds the file path
+ string itemSpec = taskItem.ItemSpec;
+
+ // Skip the native apphost (whose name ends up colliding with the CoreRT output binary) and supporting libraries
+ if (itemSpec.EndsWith(DotNetAppHostExecutableName, StringComparison.OrdinalIgnoreCase) || itemSpec.Contains(DotNetHostFxrLibraryName) || itemSpec.Contains(DotNetHostPolicyLibraryName))
+ {
+ assembliesToSkipPublish.Add(taskItem);
+ continue;
+ }
+
+ // Prototype aid - remove the native CoreCLR runtime pieces from the publish folder
+ if (itemSpec.Contains("microsoft.netcore.app") && (itemSpec.Contains("\\native\\") || itemSpec.Contains("/native/")))
+ {
+ assembliesToSkipPublish.Add(taskItem);
+ continue;
+ }
+
+ // Remove any assemblies whose implementation we want to come from CoreRT's package.
+ // Currently that's System.Private.* SDK assemblies and a bunch of framework assemblies.
+ if (coreRTFrameworkAssembliesToUse.Contains(Path.GetFileName(itemSpec)))
+ {
+ assembliesToSkipPublish.Add(taskItem);
+ continue;
+ }
+
+ try
+ {
+ using (FileStream moduleStream = File.OpenRead(itemSpec))
+ using (var module = new PEReader(moduleStream))
+ {
+ if (module.HasMetadata)
+ {
+ MetadataReader moduleMetadataReader = module.GetMetadataReader();
+ if (moduleMetadataReader.IsAssembly)
+ {
+ string culture = moduleMetadataReader.GetString(moduleMetadataReader.GetAssemblyDefinition().Culture);
+
+ if (culture == "" || culture.Equals("neutral", StringComparison.OrdinalIgnoreCase))
+ {
+ // CoreRT doesn't consume resource assemblies yet so skip them
+ assembliesToSkipPublish.Add(taskItem);
+ list.Add(taskItem);
+ }
+ }
+ }
+ }
+ }
+ catch (BadImageFormatException)
+ {
+ }
+ }
+
+ ManagedAssemblies = list.ToArray();
+ AssembliesToSkipPublish = assembliesToSkipPublish.ToArray();
+
+ return true;
+ }
+ }
+}
diff --git a/src/ILCompiler.Build.Tasks/src/ILCompiler.Build.Tasks.csproj b/src/ILCompiler.Build.Tasks/src/ILCompiler.Build.Tasks.csproj
new file mode 100644
index 000000000..808a4de4c
--- /dev/null
+++ b/src/ILCompiler.Build.Tasks/src/ILCompiler.Build.Tasks.csproj
@@ -0,0 +1,25 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" Condition="'$(IsProjectNLibrary)' != 'true'" />
+ <PropertyGroup>
+ <OutputType>Library</OutputType>
+ <RootNamespace>ILCompiler</RootNamespace>
+ <AssemblyName>ILCompiler.Build.Tasks</AssemblyName>
+ <TargetFramework>netstandard1.3</TargetFramework>
+ <OutputPath>$(BaseOutputPath)$(OSPlatformConfig)/tools</OutputPath>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="ComputeManagedAssemblies.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <PackageReference Include="Microsoft.Build.Framework">
+ <Version>15.3.409</Version>
+ </PackageReference>
+ <PackageReference Include="Microsoft.Build.Utilities.Core">
+ <Version>15.3.409</Version>
+ </PackageReference>
+ <PackageReference Include="System.Reflection.Metadata">
+ <Version>1.4.2</Version>
+ </PackageReference>
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" Condition="'$(IsProjectNLibrary)' != 'true'" />
+</Project>
diff --git a/src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs b/src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs
index 98f862c54..2821420a9 100644
--- a/src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs
+++ b/src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs
@@ -9,6 +9,7 @@ using ILCompiler.Compiler.CppCodeGen;
using Internal.TypeSystem;
using LLVMSharp;
using ILCompiler.CodeGen;
+using System.Collections.Generic;
namespace Internal.IL
{
@@ -86,7 +87,7 @@ namespace Internal.IL
/// <param name="pos">Position where to insert <paramref name="v"/></param>
public void InsertAt(T v, int pos)
{
- Debug.Assert(pos < _top, "Invalid insertion point");
+ Debug.Assert(pos <= _top, "Invalid insertion point");
if (_top >= _stack.Length)
{
@@ -181,18 +182,51 @@ namespace Internal.IL
/// </summary>
public TypeDesc Type { get; }
- public LLVMValueRef LLVMValue { get; set; }
+ public LLVMValueRef ValueAsType(LLVMTypeRef type, LLVMBuilderRef builder)
+ {
+ return ValueAsTypeInternal(type, builder, false);
+ }
+
+ public LLVMValueRef ValueAsType(TypeDesc type, LLVMBuilderRef builder)
+ {
+ return ValueAsType(ILImporter.GetLLVMTypeForTypeDesc(type), builder);
+ }
+
+ public LLVMValueRef ValueForStackKind(StackValueKind kind, LLVMBuilderRef builder, bool signExtend)
+ {
+ if (kind == StackValueKind.Int32)
+ return ValueAsInt32(builder, signExtend);
+ else if (kind == StackValueKind.Int64)
+ return ValueAsInt64(builder, signExtend);
+ else if (kind == StackValueKind.Float)
+ return ValueAsType(LLVM.FloatType(), builder);
+ else if (kind == StackValueKind.NativeInt || kind == StackValueKind.ByRef || kind == StackValueKind.ObjRef)
+ return ValueAsInt32(builder, false);
+ else
+ throw new NotImplementedException();
+ }
+
+ public LLVMValueRef ValueAsInt32(LLVMBuilderRef builder, bool signExtend)
+ {
+ return ValueAsTypeInternal(LLVM.Int32Type(), builder, signExtend);
+ }
+
+ public LLVMValueRef ValueAsInt64(LLVMBuilderRef builder, bool signExtend)
+ {
+ return ValueAsTypeInternal(LLVM.Int32Type(), builder, signExtend);
+ }
+
+ protected abstract LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend);
/// <summary>
/// Initializes a new instance of StackEntry.
/// </summary>
/// <param name="kind">Kind of entry.</param>
/// <param name="type">Type if any of entry.</param>
- protected StackEntry(StackValueKind kind, LLVMValueRef llvmValue, TypeDesc type = null)
+ protected StackEntry(StackValueKind kind, TypeDesc type = null)
{
Kind = kind;
Type = type;
- LLVMValue = llvmValue;
}
/// <summary>
@@ -206,45 +240,6 @@ namespace Internal.IL
/// </summary>
/// <returns>A new instance of the same type as the current entry.</returns>
public abstract StackEntry Duplicate();
-
- /// <summary>
- /// Overridden and sealed to force descendants to override <see cref="BuildRepresentation"/>.
- /// </summary>
- /// <returns>String representation of current entry</returns>
- public override sealed string ToString()
- {
- StringBuilder s = new StringBuilder();
- BuildRepresentation(s);
- return s.ToString();
- }
-
- /// <summary>
- /// Build a representation of current entry in <paramref name="s"/>.
- /// </summary>
- /// <param name="s">StringBuilder where representation will be saved.</param>
- protected virtual void BuildRepresentation(StringBuilder s)
- {
- Debug.Assert(s != null, "StringBuilder is null.");
- if (Type != null)
- {
- s.Append(Type);
- if (Kind != StackValueKind.Unknown)
- {
- s.Append('(');
- s.Append(Kind);
- s.Append(')');
- }
- }
- else if (Kind != StackValueKind.Unknown)
- {
- if (Kind != StackValueKind.Unknown)
- {
- s.Append('(');
- s.Append(Kind);
- s.Append(')');
- }
- }
- }
}
/// <summary>
@@ -252,7 +247,7 @@ namespace Internal.IL
/// </summary>
internal abstract class ConstantEntry : StackEntry
{
- protected ConstantEntry(StackValueKind kind, LLVMValueRef llvmValue, TypeDesc type = null) : base(kind, llvmValue, type)
+ protected ConstantEntry(StackValueKind kind, TypeDesc type = null) : base(kind, type)
{
}
@@ -271,26 +266,36 @@ namespace Internal.IL
{
public T Value { get; }
- protected ConstantEntry(StackValueKind kind, T value, LLVMValueRef llvmValue, TypeDesc type = null) : base(kind, llvmValue, type)
+ protected ConstantEntry(StackValueKind kind, T value, TypeDesc type = null) : base(kind, type)
{
Value = value;
}
-
- protected override void BuildRepresentation(StringBuilder s)
- {
- base.BuildRepresentation(s);
- if (s.Length > 0)
- {
- s.Append(' ');
- }
- s.Append(Value);
- }
}
internal class Int32ConstantEntry : ConstantEntry<int>
{
- public Int32ConstantEntry(int value, TypeDesc type = null) : base(StackValueKind.Int32, value, LLVM.ConstInt(LLVM.Int32Type(), (ulong)value, LLVMMisc.False), type)
+ public Int32ConstantEntry(int value, TypeDesc type = null) : base(StackValueKind.Int32, value, type)
+ {
+ }
+
+ protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
{
+ if (type.TypeKind == LLVMTypeKind.LLVMPointerTypeKind && Value == 0)
+ {
+ return LLVM.ConstPointerNull(type);
+ }
+ else if (type.TypeKind == LLVMTypeKind.LLVMPointerTypeKind && Value != 0)
+ {
+ return LLVM.ConstIntToPtr(LLVM.ConstInt(LLVM.Int32Type(), (ulong)Value, LLVMMisc.False), type);
+ }
+ else if (type.TypeKind != LLVMTypeKind.LLVMIntegerTypeKind)
+ {
+ throw new NotImplementedException();
+ }
+ else
+ {
+ return LLVM.ConstInt(type, (ulong)Value, LLVMMisc.False);
+ }
}
public override StackEntry Duplicate()
@@ -324,7 +329,7 @@ namespace Internal.IL
internal class Int64ConstantEntry : ConstantEntry<long>
{
- public Int64ConstantEntry(long value, TypeDesc type = null) : base(StackValueKind.Int64, value, LLVM.ConstInt(LLVM.Int64Type(), (ulong)value, LLVMMisc.False), type)
+ public Int64ConstantEntry(long value, TypeDesc type = null) : base(StackValueKind.Int64, value, type)
{
}
@@ -333,6 +338,26 @@ namespace Internal.IL
return new Int64ConstantEntry(Value, Type);
}
+ protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
+ {
+ if (type.TypeKind == LLVMTypeKind.LLVMPointerTypeKind && Value == 0)
+ {
+ return LLVM.ConstPointerNull(type);
+ }
+ else if (type.TypeKind == LLVMTypeKind.LLVMPointerTypeKind && Value != 0)
+ {
+ return LLVM.ConstIntToPtr(LLVM.ConstInt(LLVM.Int64Type(), (ulong)Value, LLVMMisc.False), type);
+ }
+ else if (type.TypeKind != LLVMTypeKind.LLVMIntegerTypeKind)
+ {
+ throw new NotImplementedException();
+ }
+ else
+ {
+ return LLVM.ConstInt(type, (ulong)Value, LLVMMisc.False);
+ }
+ }
+
public override bool IsCastNecessary(TypeDesc destType)
{
switch (destType.UnderlyingType.Category)
@@ -363,10 +388,15 @@ namespace Internal.IL
internal class FloatConstantEntry : ConstantEntry<double>
{
- public FloatConstantEntry(double value, TypeDesc type = null) : base(StackValueKind.Float, value, LLVM.ConstReal(LLVM.FloatType(), value), type)
+ public FloatConstantEntry(double value, TypeDesc type = null) : base(StackValueKind.Float, value, type)
{
}
+ protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
+ {
+ return LLVM.ConstReal(type, Value);
+ }
+
public override StackEntry Duplicate()
{
return new FloatConstantEntry(Value, Type);
@@ -382,34 +412,77 @@ namespace Internal.IL
/// String representation of current expression
/// </summary>
public string Name { get; set; }
-
+ public LLVMValueRef RawLLVMValue { get; set; }
/// <summary>
/// Initializes new instance of ExpressionEntry
/// </summary>
/// <param name="kind">Kind of entry</param>
/// <param name="name">String representation of entry</param>
/// <param name="type">Type if any of entry</param>
- public ExpressionEntry(StackValueKind kind, string name, LLVMValueRef llvmValue, TypeDesc type = null) : base(kind, llvmValue, type)
+ public ExpressionEntry(StackValueKind kind, string name, LLVMValueRef llvmValue, TypeDesc type = null) : base(kind, type)
{
Name = name;
+ RawLLVMValue = llvmValue;
}
public override StackEntry Duplicate()
{
- return new ExpressionEntry(Kind, Name, LLVMValue, Type);
+ return new ExpressionEntry(Kind, Name, RawLLVMValue, Type);
}
- protected override void BuildRepresentation(StringBuilder s)
+ protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
{
- base.BuildRepresentation(s);
- if (s.Length > 0)
- {
- s.Append(' ');
- }
- s.Append(Name);
+ //TODO: deal with sign extension here
+ return ILImporter.CastIfNecessary(builder, RawLLVMValue, type);
+ }
+ }
+
+ internal class LoadExpressionEntry : ExpressionEntry
+ {
+ /// <summary>
+ /// Initializes new instance of ExpressionEntry
+ /// </summary>
+ /// <param name="kind">Kind of entry</param>
+ /// <param name="name">String representation of entry</param>
+ /// <param name="type">Type if any of entry</param>
+ public LoadExpressionEntry(StackValueKind kind, string name, LLVMValueRef llvmValue, TypeDesc type = null) : base(kind, name, llvmValue, type)
+ {
+ }
+
+ public override StackEntry Duplicate()
+ {
+ return new LoadExpressionEntry(Kind, Name, RawLLVMValue, Type);
+ }
+
+ protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
+ {
+ return ILImporter.LoadValue(builder, RawLLVMValue, Type, type, signExtend);
+ }
+ }
+
+ internal class AddressExpressionEntry : ExpressionEntry
+ {
+ /// <summary>
+ /// Initializes new instance of ExpressionEntry
+ /// </summary>
+ /// <param name="kind">Kind of entry</param>
+ /// <param name="name">String representation of entry</param>
+ /// <param name="type">Type if any of entry</param>
+ public AddressExpressionEntry(StackValueKind kind, string name, LLVMValueRef llvmValue, TypeDesc type = null) : base(kind, name, llvmValue, type)
+ {
+ }
+
+ public override StackEntry Duplicate()
+ {
+ return new LoadExpressionEntry(Kind, Name, RawLLVMValue, Type);
+ }
+
+ protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
+ {
+ return ILImporter.CastIfNecessary(builder, RawLLVMValue, type);
}
}
-
+
/// <summary>
/// Entry representing some token (either of TypeDesc, MethodDesc or FieldDesc) along with its string representation
/// </summary>
@@ -417,21 +490,19 @@ namespace Internal.IL
{
public T LdToken { get; }
- public LdTokenEntry(StackValueKind kind, string name, T token, LLVMValueRef value, TypeDesc type = null) : base(kind, name, value, type)
+ public LdTokenEntry(StackValueKind kind, string name, T token, TypeDesc type = null) : base(kind, name, default(LLVMValueRef), type)
{
LdToken = token;
}
public override StackEntry Duplicate()
{
- return new LdTokenEntry<T>(Kind, Name, LdToken, LLVMValue, Type);
+ return new LdTokenEntry<T>(Kind, Name, LdToken, Type);
}
- protected override void BuildRepresentation(StringBuilder s)
+ protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
{
- base.BuildRepresentation(s);
- s.Append(' ');
- s.Append(LdToken);
+ return ILImporter.CastIfNecessary(builder, RawLLVMValue, type);
}
}
@@ -442,7 +513,7 @@ namespace Internal.IL
/// </summary>
public static InvalidEntry Entry = new InvalidEntry();
- protected InvalidEntry() : base(StackValueKind.Unknown, default(LLVMValueRef), null)
+ protected InvalidEntry() : base(StackValueKind.Unknown, null)
{
}
@@ -451,9 +522,33 @@ namespace Internal.IL
return this;
}
- protected override void BuildRepresentation(StringBuilder s)
+ protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
+ {
+ throw new InvalidOperationException();
+ }
+ }
+
+ /// <summary>
+ /// Entry representing a writable sharable stack entry that can survive from one basic block to another
+ /// </summary>
+ internal class SpilledExpressionEntry : ExpressionEntry
+ {
+ public int LocalIndex;
+ private ILImporter _importer;
+ public SpilledExpressionEntry(StackValueKind kind, string name, TypeDesc type, int localIndex, ILImporter importer) : base(kind, name, new LLVMValueRef(IntPtr.Zero), type)
+ {
+ LocalIndex = localIndex;
+ _importer = importer;
+ }
+
+ protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
+ {
+ return _importer.LoadTemp(LocalIndex, type);
+ }
+
+ public override StackEntry Duplicate()
{
- s.Append("Invalid Entry");
+ return new SpilledExpressionEntry(Kind, Name, Type, LocalIndex, _importer);
}
}
}
diff --git a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs
index 8c7886288..745dd0d20 100644
--- a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs
+++ b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs
@@ -19,6 +19,13 @@ namespace Internal.IL
// backend before the actual compilation happens to gain insights into the code.
partial class ILImporter
{
+ public enum LocalVarKind
+ {
+ Argument,
+ Local,
+ Temp
+ }
+
ArrayBuilder<object> _dependencies = new ArrayBuilder<object>();
public IEnumerable<object> GetDependencies()
{
@@ -35,6 +42,7 @@ namespace Internal.IL
private LLVMBasicBlockRef _curBasicBlock;
private LLVMBuilderRef _builder;
private readonly LocalVariableDefinition[] _locals;
+ private List<SpilledExpressionEntry> _spilledExpressions = new List<SpilledExpressionEntry>();
private readonly byte[] _ilBytes;
@@ -154,6 +162,30 @@ namespace Internal.IL
return llvmFunction;
}
+ private LLVMValueRef GetOrCreateLLVMFunction(string mangledName, LLVMTypeRef functionType)
+ {
+ LLVMValueRef llvmFunction = LLVM.GetNamedFunction(Module, mangledName);
+
+ if (llvmFunction.Pointer == IntPtr.Zero)
+ {
+ return LLVM.AddFunction(Module, mangledName, functionType);
+ }
+ return llvmFunction;
+ }
+
+ private void ImportCallMemset(LLVMValueRef targetPointer, byte value, int length)
+ {
+ LLVMValueRef objectSizeValue = BuildConstInt32(length);
+ var memsetSignature = LLVM.FunctionType(LLVM.VoidType(), new LLVMTypeRef[] { LLVM.PointerType(LLVM.Int8Type(), 0), LLVM.Int8Type(), LLVM.Int32Type(), LLVM.Int32Type(), LLVM.Int1Type() }, false);
+ LLVM.BuildCall(_builder, GetOrCreateLLVMFunction("llvm.memset.p0i8.i32", memsetSignature), new LLVMValueRef[] { targetPointer, BuildConstInt8(value), objectSizeValue, BuildConstInt32(1), BuildConstInt1(0) }, String.Empty);
+ }
+
+ private void PushLoadExpression(StackValueKind kind, string name, LLVMValueRef rawLLVMValue, TypeDesc type)
+ {
+ Debug.Assert(kind != StackValueKind.Unknown, "Unknown stack kind");
+ _stack.Push(new LoadExpressionEntry(kind, name, rawLLVMValue, type));
+ }
+
/// <summary>
/// Push an expression named <paramref name="name"/> of kind <paramref name="kind"/>.
/// </summary>
@@ -194,45 +226,6 @@ namespace Internal.IL
_stack.Push(new ExpressionEntry(kind, name, llvmValue, type));
}
-
-
- /// <summary>
- /// Generate a cast in case the stack type of source is not identical or compatible with destination type.
- /// </summary>
- /// <param name="destType">Type of destination</param>
- /// <param name="srcEntry">Source entry from stack</param>
- private void AppendCastIfNecessary(TypeDesc destType, StackEntry srcEntry)
- {
- ConstantEntry constant = srcEntry as ConstantEntry;
- if ((constant != null) && (constant.IsCastNecessary(destType)) || !destType.IsValueType || destType != srcEntry.Type)
- {
- throw new NotImplementedException();
- /*
- Append("(");
- Append(GetSignatureTypeNameAndAddReference(destType));
- Append(")");*/
- }
- }
-
- private void AppendCastIfNecessary(StackValueKind dstType, TypeDesc srcType)
- {
- if (dstType == StackValueKind.ByRef)
- {
-
- throw new NotImplementedException();
- /*
- Append("(");
- Append(GetSignatureTypeNameAndAddReference(srcType));
- Append(")");*/
- }
- else
- if (srcType.IsPointer)
- {
- throw new NotImplementedException();
- //Append("(intptr_t)");
- }
- }
-
private void MarkInstructionBoundary()
{
@@ -281,6 +274,8 @@ namespace Internal.IL
var terminator = basicBlock.Block.GetBasicBlockTerminator();
if (terminator.Pointer == IntPtr.Zero)
{
+ if (_basicBlocks[_currentOffset].StartOffset == 0)
+ throw new InvalidProgramException();
LLVM.BuildBr(_builder, GetLLVMBasicBlockForBlock(_basicBlocks[_currentOffset]));
}
}
@@ -304,13 +299,72 @@ namespace Internal.IL
private void ImportLoadVar(int index, bool argument)
{
+ LLVMValueRef typedLoadLocation = LoadVarAddress(index, argument ? LocalVarKind.Argument : LocalVarKind.Local, out TypeDesc type);
+ PushLoadExpression(GetStackValueKind(type), "ld" + (argument ? "arg" : "loc") + index + "_", typedLoadLocation, type);
+ }
+
+ private LLVMValueRef LoadTemp(int index)
+ {
+ LLVMValueRef address = LoadVarAddress(index, LocalVarKind.Temp, out TypeDesc type);
+ return LLVM.BuildLoad(_builder, CastToPointerToTypeDesc(address, type), "ldtemp");
+ }
+
+ internal LLVMValueRef LoadTemp(int index, LLVMTypeRef asType)
+ {
+ LLVMValueRef address = LoadVarAddress(index, LocalVarKind.Temp, out TypeDesc type);
+ return LLVM.BuildLoad(_builder, CastIfNecessary(address, LLVM.PointerType(asType, 0)), "ldtemp");
+ }
+
+ private void StoreTemp(int index, LLVMValueRef value)
+ {
+ LLVMValueRef address = LoadVarAddress(index, LocalVarKind.Temp, out TypeDesc type);
+ LLVM.BuildStore(_builder, CastToTypeDesc(value, type), CastToPointerToTypeDesc(address, type));
+ }
+
+ internal static LLVMValueRef LoadValue(LLVMBuilderRef builder, LLVMValueRef address, TypeDesc sourceType, LLVMTypeRef targetType, bool signExtend)
+ {
+ if (targetType.TypeKind == LLVMTypeKind.LLVMIntegerTypeKind && sourceType.IsPrimitive && !sourceType.IsPointer)
+ {
+ var sourceLLVMType = ILImporter.GetLLVMTypeForTypeDesc(sourceType);
+ var typedAddress = CastIfNecessary(builder, address, LLVM.PointerType(sourceLLVMType, 0));
+ return CastIntValue(builder, LLVM.BuildLoad(builder, typedAddress, "ldvalue"), targetType, signExtend);
+ }
+ else
+ {
+ var typedAddress = CastIfNecessary(builder, address, LLVM.PointerType(targetType, 0));
+ return LLVM.BuildLoad(builder, typedAddress, "ldvalue");
+ }
+ }
+
+ private static LLVMValueRef CastIntValue(LLVMBuilderRef builder, LLVMValueRef value, LLVMTypeRef type, bool signExtend)
+ {
+ if (LLVM.TypeOf(value).Pointer == type.Pointer)
+ {
+ return value;
+ }
+ else if (LLVM.TypeOf(value).TypeKind == LLVMTypeKind.LLVMPointerTypeKind)
+ {
+ return LLVM.BuildPtrToInt(builder, value, type, "intcast");
+ }
+ else if (signExtend && type.GetIntTypeWidth() > LLVM.TypeOf(value).GetIntTypeWidth())
+ {
+ return LLVM.BuildSExtOrBitCast(builder, value, type, "SExtOrBitCast");
+ }
+ else
+ {
+ Debug.Assert(LLVM.TypeOf(value).TypeKind == LLVMTypeKind.LLVMIntegerTypeKind);
+ return LLVM.BuildIntCast(builder, value, type, "intcast");
+ }
+ }
+
+ private LLVMValueRef LoadVarAddress(int index, LocalVarKind kind, out TypeDesc type)
+ {
int varBase;
int varCountBase;
int varOffset;
LLVMTypeRef valueType;
- TypeDesc type;
- if (argument)
+ if (kind == LocalVarKind.Argument)
{
varCountBase = 0;
varBase = 0;
@@ -335,21 +389,25 @@ namespace Internal.IL
}
valueType = GetLLVMTypeForTypeDesc(type);
}
- else
+ else if (kind == LocalVarKind.Local)
{
varBase = GetTotalParameterOffset();
GetLocalSizeAndOffsetAtIndex(index, out int localSize, out varOffset);
valueType = GetLLVMTypeForTypeDesc(_locals[index].Type);
type = _locals[index].Type;
}
+ else
+ {
+ varBase = GetTotalRealLocalOffset();
+ GetSpillSizeAndOffsetAtIndex(index, out int localSize, out varOffset);
+ valueType = GetLLVMTypeForTypeDesc(_spilledExpressions[index].Type);
+ type = _spilledExpressions[index].Type;
+ }
- var loadLocation = LLVM.BuildGEP(_builder, LLVM.GetFirstParam(_llvmFunction),
+ return LLVM.BuildGEP(_builder, LLVM.GetFirstParam(_llvmFunction),
new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), (uint)(varBase + varOffset), LLVMMisc.False) },
String.Empty);
- var typedLoadLocation = LLVM.BuildPointerCast(_builder, loadLocation, LLVM.PointerType(valueType, 0), "typedLoadLocation");
- var loadResult = LLVM.BuildLoad(_builder, typedLoadLocation, "ld" + (argument ? "arg" : "loc") + index + "_");
- PushExpression(GetStackValueKind(type), String.Empty, loadResult, type);
}
private StackValueKind GetStackValueKind(TypeDesc type)
@@ -395,24 +453,16 @@ namespace Internal.IL
private void ImportStoreVar(int index, bool argument)
{
- if(argument)
- {
- throw new NotImplementedException("storing to argument");
- }
-
- GetLocalSizeAndOffsetAtIndex(index, out int localSize, out int localOffset);
-
- LLVMValueRef toStore = _stack.Pop().LLVMValue;
-
- LLVMTypeRef valueType = GetLLVMTypeForTypeDesc(_locals[index].Type);
-
- ImportStoreHelper(toStore, valueType, LLVM.GetFirstParam(_llvmFunction), (uint)(GetTotalParameterOffset() + localOffset));
+ TypeDesc varType;
+ StackEntry toStore = _stack.Pop();
+ LLVMValueRef varAddress = LoadVarAddress(index, argument ? LocalVarKind.Argument : LocalVarKind.Local, out varType);
+ CastingStore(varAddress, toStore, varType);
}
private void ImportStoreHelper(LLVMValueRef toStore, LLVMTypeRef valueType, LLVMValueRef basePtr, uint offset)
{
LLVMValueRef typedToStore = CastIfNecessary(toStore, valueType);
-
+
var storeLocation = LLVM.BuildGEP(_builder, basePtr,
new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), offset, LLVMMisc.False) },
String.Empty);
@@ -420,8 +470,34 @@ namespace Internal.IL
LLVM.BuildStore(_builder, typedToStore, typedStoreLocation);
}
+ private LLVMValueRef CastToRawPointer(LLVMValueRef source)
+ {
+ return CastIfNecessary(source, LLVM.PointerType(LLVM.Int8Type(), 0));
+ }
+
+ private LLVMValueRef CastToTypeDesc(LLVMValueRef source, TypeDesc type)
+ {
+ return CastIfNecessary(source, GetLLVMTypeForTypeDesc(type));
+ }
+
+ private LLVMValueRef CastToPointerToTypeDesc(LLVMValueRef source, TypeDesc type)
+ {
+ return CastIfNecessary(source, LLVM.PointerType(GetLLVMTypeForTypeDesc(type), 0));
+ }
+
+ private void CastingStore(LLVMValueRef address, StackEntry value, TypeDesc targetType)
+ {
+ var typedStoreLocation = CastToPointerToTypeDesc(address, targetType);
+ LLVM.BuildStore(_builder, value.ValueAsType(targetType, _builder), typedStoreLocation);
+ }
+
private LLVMValueRef CastIfNecessary(LLVMValueRef source, LLVMTypeRef valueType)
{
+ return CastIfNecessary(_builder, source, valueType);
+ }
+
+ internal static LLVMValueRef CastIfNecessary(LLVMBuilderRef builder, LLVMValueRef source, LLVMTypeRef valueType)
+ {
LLVMTypeRef sourceType = LLVM.TypeOf(source);
if (sourceType.Pointer == valueType.Pointer)
return source;
@@ -432,11 +508,19 @@ namespace Internal.IL
LLVMValueRef typedToStore = source;
if (toStoreKind == LLVMTypeKind.LLVMPointerTypeKind && valueTypeKind == LLVMTypeKind.LLVMPointerTypeKind)
{
- typedToStore = LLVM.BuildPointerCast(_builder, source, valueType, "CastIfNecessaryPtr");
+ typedToStore = LLVM.BuildPointerCast(builder, source, valueType, "CastIfNecessaryPtr");
}
else if (toStoreKind == LLVMTypeKind.LLVMPointerTypeKind && valueTypeKind == LLVMTypeKind.LLVMIntegerTypeKind)
{
- typedToStore = LLVM.BuildPtrToInt(_builder, source, valueType, "CastIfNecessaryInt");
+ typedToStore = LLVM.BuildPtrToInt(builder, source, valueType, "CastIfNecessaryInt");
+ }
+ else if (toStoreKind == LLVMTypeKind.LLVMIntegerTypeKind && valueTypeKind == LLVMTypeKind.LLVMArrayTypeKind)
+ {
+ typedToStore = LLVM.BuildLoad(builder, CastIfNecessary(builder, source, LLVM.PointerType(valueType, 0)), "CastIfNecessaryArrayLoad");
+ }
+ else if (toStoreKind == LLVMTypeKind.LLVMPointerTypeKind && valueTypeKind == LLVMTypeKind.LLVMArrayTypeKind)
+ {
+ typedToStore = LLVM.BuildLoad(builder, CastIfNecessary(builder, source, LLVM.PointerType(valueType, 0)), "CastIfNecessaryArrayLoad");
}
else if (toStoreKind == LLVMTypeKind.LLVMPointerTypeKind && valueTypeKind != LLVMTypeKind.LLVMIntegerTypeKind)
{
@@ -444,7 +528,7 @@ namespace Internal.IL
}
else if (toStoreKind == LLVMTypeKind.LLVMIntegerTypeKind && valueTypeKind == LLVMTypeKind.LLVMPointerTypeKind)
{
- typedToStore = LLVM.BuildIntToPtr(_builder, source, valueType, "CastIfNecessaryPtr");
+ typedToStore = LLVM.BuildIntToPtr(builder, source, valueType, "CastIfNecessaryPtr");
}
else if (toStoreKind != LLVMTypeKind.LLVMIntegerTypeKind && valueTypeKind == LLVMTypeKind.LLVMPointerTypeKind)
{
@@ -457,13 +541,21 @@ namespace Internal.IL
else if (toStoreKind == valueTypeKind && toStoreKind == LLVMTypeKind.LLVMIntegerTypeKind)
{
Debug.Assert(toStoreKind != LLVMTypeKind.LLVMPointerTypeKind && valueTypeKind != LLVMTypeKind.LLVMPointerTypeKind);
- typedToStore = LLVM.BuildIntCast(_builder, source, valueType, "CastIfNecessaryInt");
+ typedToStore = LLVM.BuildIntCast(builder, source, valueType, "CastIfNecessaryInt");
+ }
+ else if (toStoreKind == LLVMTypeKind.LLVMFloatTypeKind && valueTypeKind != LLVMTypeKind.LLVMFloatTypeKind)
+ {
+ typedToStore = LLVM.BuildIntCast(builder, source, valueType, "CastIfNecessaryFloat");
+ }
+ else if (toStoreKind != LLVMTypeKind.LLVMFloatTypeKind && valueTypeKind == LLVMTypeKind.LLVMFloatTypeKind)
+ {
+ typedToStore = LLVM.BuildFPCast(builder, source, valueType, "CastIfNecessaryFloat");
}
return typedToStore;
}
- private LLVMTypeRef GetLLVMTypeForTypeDesc(TypeDesc type)
+ internal static LLVMTypeRef GetLLVMTypeForTypeDesc(TypeDesc type)
{
switch (type.Category)
{
@@ -481,9 +573,9 @@ namespace Internal.IL
case TypeFlags.Int32:
case TypeFlags.UInt32:
+ return LLVM.Int32Type();
case TypeFlags.IntPtr:
case TypeFlags.UIntPtr:
- return LLVM.Int32Type();
case TypeFlags.Array:
case TypeFlags.SzArray:
case TypeFlags.ByRef:
@@ -492,7 +584,7 @@ namespace Internal.IL
return LLVM.PointerType(LLVM.Int8Type(), 0);
case TypeFlags.Pointer:
- return LLVM.PointerType(GetLLVMTypeForTypeDesc(type.GetParameterType()), 0);
+ return LLVM.PointerType(type.GetParameterType().IsVoid ? LLVM.Int8Type() : GetLLVMTypeForTypeDesc(type.GetParameterType()), 0);
case TypeFlags.Int64:
case TypeFlags.UInt64:
@@ -521,6 +613,16 @@ namespace Internal.IL
private int GetTotalLocalOffset()
{
+ int offset = GetTotalRealLocalOffset();
+ for (int i = 0; i < _spilledExpressions.Count; i++)
+ {
+ offset += _spilledExpressions[i].Type.GetElementSize().AsInt;
+ }
+ return offset;
+ }
+
+ private int GetTotalRealLocalOffset()
+ {
int offset = 0;
for (int i = 0; i < _locals.Length; i++)
{
@@ -592,22 +694,23 @@ namespace Internal.IL
}
}
- private void ImportAddressOfVar(int index, bool argument)
+ private void GetSpillSizeAndOffsetAtIndex(int index, out int size, out int offset)
{
- if (argument)
+ SpilledExpressionEntry spill = _spilledExpressions[index];
+ size = spill.Type.GetElementSize().AsInt;
+
+ offset = 0;
+ for (int i = 0; i < index; i++)
{
- throw new NotImplementedException("ldarga");
+ offset += _spilledExpressions[i].Type.GetElementSize().AsInt;
}
+ }
- int localOffset = GetTotalParameterOffset();
- GetLocalSizeAndOffsetAtIndex(index, out int size, out int offset);
- localOffset += offset;
-
- var localPtr = LLVM.BuildGEP(_builder, LLVM.GetFirstParam(_llvmFunction),
- new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), (uint)localOffset, LLVMMisc.False) }, "ldloca");
- //var typedLocalPtr = LLVM.BuildPointerCast(_builder, localPtr, GetLLVMTypeForTypeDesc(_locals[index].Type.MakePointerType()), "ldloca");
-
- _stack.Push(new ExpressionEntry(StackValueKind.ByRef, "ldloca", localPtr, _locals[index].Type.MakePointerType()));
+ private void ImportAddressOfVar(int index, bool argument)
+ {
+ TypeDesc type;
+ LLVMValueRef typedLoadLocation = LoadVarAddress(index, argument ? LocalVarKind.Argument : LocalVarKind.Local, out type);
+ _stack.Push(new AddressExpressionEntry(StackValueKind.ByRef, "ldloca", typedLoadLocation, type.MakePointerType()));
}
private void ImportDup()
@@ -640,8 +743,7 @@ namespace Internal.IL
{
StackEntry retVal = _stack.Pop();
LLVMTypeRef valueType = GetLLVMTypeForTypeDesc(_signature.ReturnType);
-
- ImportStoreHelper(retVal.LLVMValue, valueType, LLVM.GetNextParam(LLVM.GetFirstParam(_llvmFunction)), 0);
+ ImportStoreHelper(retVal.ValueAsType(valueType, _builder), valueType, LLVM.GetNextParam(LLVM.GetFirstParam(_llvmFunction)), 0);
}
LLVM.BuildRetVoid(_builder);
@@ -650,7 +752,6 @@ namespace Internal.IL
private void ImportCall(ILOpcode opcode, int token)
{
MethodDesc callee = (MethodDesc)_methodIL.GetObject(token);
-
if (callee.IsIntrinsic)
{
if (ImportIntrinsicCall(callee))
@@ -665,8 +766,29 @@ namespace Internal.IL
return;
}
+ if (opcode == ILOpcode.newobj)
+ {
+ if (callee.OwningType.IsString)
+ {
+ // String constructors actually look like regular method calls
+ IMethodNode node = _compilation.NodeFactory.StringAllocator(callee);
+ _dependencies.Add(node);
+ callee = node.Method;
+ opcode = ILOpcode.call;
+ }
+ else
+ {
+ StackEntry newObjResult = AllocateObject(callee.OwningType);
+ //one for the real result and one to be consumed by ctor
+ if (callee.Signature.Length > _stack.Length) //System.Reflection.MemberFilter.ctor
+ throw new InvalidProgramException();
+ _stack.InsertAt(newObjResult, _stack.Top - callee.Signature.Length);
+ _stack.InsertAt(newObjResult, _stack.Top - callee.Signature.Length);
+ }
+ }
+
// we don't really have virtual call support, but we'll treat it as direct for now
- if (opcode != ILOpcode.call && opcode != ILOpcode.callvirt)
+ if (opcode != ILOpcode.call && opcode != ILOpcode.callvirt && opcode != ILOpcode.newobj)
{
throw new NotImplementedException();
}
@@ -678,6 +800,50 @@ namespace Internal.IL
HandleCall(callee);
}
+ private ExpressionEntry AllocateObject(TypeDesc type)
+ {
+ MetadataType metadataType = (MetadataType)type;
+ int objectSize = metadataType.InstanceByteCount.AsInt;
+ if (metadataType.IsValueType)
+ {
+ objectSize += type.Context.Target.PointerSize;
+ }
+
+ LLVMValueRef allocatedMemory = LLVM.BuildMalloc(_builder, LLVM.ArrayType(LLVM.Int8Type(), (uint)objectSize), "newobj");
+ LLVMValueRef castMemory = LLVM.BuildPointerCast(_builder, allocatedMemory, LLVM.PointerType(LLVM.Int8Type(), 0), "castnewobj");
+ ImportCallMemset(castMemory, 0, objectSize);
+ LLVMValueRef eeTypePointer = GetEETypeForTypeDesc(type);
+ LLVMValueRef objectHeaderPtr = LLVM.BuildPointerCast(_builder, allocatedMemory, LLVM.PointerType(LLVM.TypeOf(eeTypePointer), 0), "objectHeaderPtr");
+ LLVM.BuildStore(_builder, eeTypePointer, objectHeaderPtr);
+ return new ExpressionEntry(StackValueKind.ObjRef, "newobj", castMemory, type);
+ }
+
+ private static LLVMValueRef BuildConstInt1(int number)
+ {
+ Debug.Assert(number == 0 || number == 1, "Non-boolean int1");
+ return LLVM.ConstInt(LLVM.Int1Type(), (ulong)number, LLVMMisc.False);
+ }
+
+ private static LLVMValueRef BuildConstInt8(byte number)
+ {
+ return LLVM.ConstInt(LLVM.Int8Type(), number, LLVMMisc.False);
+ }
+
+ private static LLVMValueRef BuildConstInt32(int number)
+ {
+ return LLVM.ConstInt(LLVM.Int32Type(), (ulong)number, LLVMMisc.False);
+ }
+
+ private LLVMValueRef GetEETypeForTypeDesc(TypeDesc target)
+ {
+ ISymbolNode node = _compilation.NodeFactory.ConstructedTypeSymbol(target);
+ LLVMValueRef eeTypePointer = LoadAddressOfSymbolNode(node);
+ _dependencies.Add(node);
+ var eeTypePtrType = _compilation.TypeSystemContext.SystemModule.GetKnownType("System", "EETypePtr");
+ var ptrPtrType = LLVM.PointerType(GetLLVMTypeForTypeDesc(eeTypePtrType), 0);
+ return LLVM.BuildPointerCast(_builder, eeTypePointer, ptrPtrType, "castEETypePtr");
+ }
+
/// <summary>
/// Implements intrinsic methods instread of calling them
/// </summary>
@@ -735,16 +901,16 @@ namespace Internal.IL
}
// The last argument is the top of the stack. We need to reverse them and store starting at the first argument
- LLVMValueRef[] argumentValues = new LLVMValueRef[callee.Signature.Length + instanceAdjustment];
+ StackEntry[] argumentValues = new StackEntry[callee.Signature.Length + instanceAdjustment];
for(int i = 0; i < argumentValues.Length; i++)
{
- argumentValues[argumentValues.Length - i - 1] = _stack.Pop().LLVMValue;
+ argumentValues[argumentValues.Length - i - 1] = _stack.Pop();
}
for (int index = 0; index < argumentValues.Length; index++)
{
- LLVMValueRef toStore = argumentValues[index];
+ StackEntry toStore = argumentValues[index];
TypeDesc argType;
if (index == 0 && !callee.Signature.IsStatic)
@@ -758,7 +924,7 @@ namespace Internal.IL
LLVMTypeRef valueType = GetLLVMTypeForTypeDesc(argType);
- ImportStoreHelper(toStore, valueType, castShadowStack, argOffset);
+ ImportStoreHelper(toStore.ValueAsType(valueType, _builder), valueType, castShadowStack, argOffset);
argOffset += (uint)argType.GetElementSize().AsInt;
}
@@ -772,8 +938,7 @@ namespace Internal.IL
{
LLVMTypeRef returnLLVMType = GetLLVMTypeForTypeDesc(callee.Signature.ReturnType);
LLVMValueRef returnLLVMPointer = LLVM.BuildPointerCast(_builder, returnAddress, LLVM.PointerType(returnLLVMType, 0), "castreturnpointer");
- LLVMValueRef loadResult = LLVM.BuildLoad(_builder, returnLLVMPointer, String.Empty);
- PushExpression(GetStackValueKind(callee.Signature.ReturnType), String.Empty, loadResult, callee.Signature.ReturnType);
+ PushLoadExpression(GetStackValueKind(callee.Signature.ReturnType), String.Empty, returnLLVMPointer, callee.Signature.ReturnType);
}
}
@@ -786,6 +951,11 @@ namespace Internal.IL
{
LLVMValueRef nativeFunc = LLVM.GetNamedFunction(Module, method.Name);
+ //emscripten dies if this is output because its expected to have i32, i32, i64. But the runtime has defined it as i8*, i8*, i64
+ if (method.Name == "memmove")
+ throw new NotImplementedException();
+
+
// Create an import if we haven't already
if (nativeFunc.Pointer == IntPtr.Zero)
{
@@ -806,24 +976,17 @@ namespace Internal.IL
LLVMValueRef[] arguments = new LLVMValueRef[method.Signature.Length];
for(int i = 0; i < arguments.Length; i++)
{
- LLVMValueRef argValue = _stack.Pop().LLVMValue;
-
// Arguments are reversed on the stack
// Coerce pointers to the native type
TypeDesc signatureType = method.Signature[arguments.Length - i - 1];
- LLVMValueRef typedValue = argValue;
- if (signatureType.IsPointer)
- {
- LLVMTypeRef signatureLlvmType = GetLLVMTypeForTypeDesc(signatureType);
- typedValue = LLVM.BuildPointerCast(_builder, argValue, signatureLlvmType, "castarg");
- }
- arguments[arguments.Length - i - 1] = typedValue;
+ arguments[arguments.Length - i - 1] = _stack.Pop().ValueAsType(GetLLVMTypeForTypeDesc(signatureType), _builder);
}
- var returnValue = LLVM.BuildCall(_builder, nativeFunc, arguments, "call");
+ //dont name the return value if the function returns void, its invalid
+ var returnValue = LLVM.BuildCall(_builder, nativeFunc, arguments, !method.Signature.ReturnType.IsVoid ? "call" : string.Empty);
if(!method.Signature.ReturnType.IsVoid)
- PushExpression(GetStackValueKind(method.Signature.ReturnType), String.Empty, returnValue, method.Signature.ReturnType);
+ PushExpression(GetStackValueKind(method.Signature.ReturnType), "retval", returnValue, method.Signature.ReturnType);
}
private void ImportCalli(int token)
@@ -862,6 +1025,10 @@ namespace Internal.IL
{
if (opcode == ILOpcode.br)
{
+ ImportFallthrough(target);
+ //TODO: why does this illegal branch happen in System.Reflection.MemberFilter.ctor
+ if (target.StartOffset == 0)
+ throw new InvalidProgramException();
LLVM.BuildBr(_builder, GetLLVMBasicBlockForBlock(target));
}
else
@@ -871,11 +1038,10 @@ namespace Internal.IL
if (opcode == ILOpcode.brfalse || opcode == ILOpcode.brtrue)
{
var op = _stack.Pop();
- LLVMValueRef value = op.LLVMValue;
- if (LLVM.GetTypeKind(LLVM.TypeOf(value)) == LLVMTypeKind.LLVMPointerTypeKind)
- {
- value = LLVM.BuildPtrToInt(_builder, value, LLVM.Int32Type(), String.Empty);
- }
+ LLVMValueRef value = op.ValueAsInt32(_builder, false);
+
+ if (LLVM.TypeOf(value).TypeKind != LLVMTypeKind.LLVMIntegerTypeKind)
+ throw new InvalidProgramException("branch on non integer");
if (opcode == ILOpcode.brfalse)
{
@@ -903,21 +1069,8 @@ namespace Internal.IL
kind = op2.Kind;
}
- LLVMValueRef left = op1.LLVMValue;
- LLVMValueRef right = op2.LLVMValue;
-
- if (kind == StackValueKind.NativeInt || kind == StackValueKind.ObjRef || kind == StackValueKind.ByRef)
- {
- if (LLVM.GetTypeKind(LLVM.TypeOf(left)) == LLVMTypeKind.LLVMPointerTypeKind)
- {
- left = LLVM.BuildPtrToInt(_builder, left, LLVM.Int32Type(), "lptrasint");
- }
- if (LLVM.GetTypeKind(LLVM.TypeOf(right)) == LLVMTypeKind.LLVMPointerTypeKind)
- {
- right = LLVM.BuildPtrToInt(_builder, right, LLVM.Int32Type(), "rptrasint");
- }
- }
-
+ LLVMValueRef left = op1.ValueForStackKind(kind, _builder, false);
+ LLVMValueRef right = op2.ValueForStackKind(kind, _builder, false);
switch (opcode)
{
@@ -959,19 +1112,17 @@ namespace Internal.IL
if (target.StartOffset == 0)
throw new NotImplementedException("cant branch to entry basic block");
- LLVM.BuildCondBr(_builder, condition, GetLLVMBasicBlockForBlock(target), GetLLVMBasicBlockForBlock(fallthrough));
-
+ ImportFallthrough(target);
ImportFallthrough(fallthrough);
+ LLVM.BuildCondBr(_builder, condition, GetLLVMBasicBlockForBlock(target), GetLLVMBasicBlockForBlock(fallthrough));
}
-
- ImportFallthrough(target);
}
private void ImportSwitchJump(int jmpBase, int[] jmpDelta, BasicBlock fallthrough)
{
var operand = _stack.Pop();
- var @switch = LLVM.BuildSwitch(_builder, operand.LLVMValue, GetLLVMBasicBlockForBlock(fallthrough), (uint)jmpDelta.Length);
+ var @switch = LLVM.BuildSwitch(_builder, operand.ValueAsInt32(_builder, false), GetLLVMBasicBlockForBlock(fallthrough), (uint)jmpDelta.Length);
for (var i = 0; i < jmpDelta.Length; i++)
{
var target = _basicBlocks[_currentOffset + jmpDelta[i]];
@@ -989,22 +1140,13 @@ namespace Internal.IL
private void ImportLoadIndirect(TypeDesc type)
{
- StackEntry pointer = _stack.Pop();
- LLVMTypeRef loadType = GetLLVMTypeForTypeDesc(type);
- LLVMTypeRef pointerType = LLVM.PointerType(loadType, 0);
-
- LLVMValueRef typedPointer;
- if (LLVM.GetTypeKind(LLVM.TypeOf(pointer.LLVMValue)) != LLVMTypeKind.LLVMPointerTypeKind)
- {
- typedPointer = LLVM.BuildIntToPtr(_builder, pointer.LLVMValue, pointerType, "ldindintptrcast");
- }
- else
- {
- typedPointer = LLVM.BuildPointerCast(_builder, pointer.LLVMValue, pointerType, "ldindptrcast");
- }
-
- LLVMValueRef load = LLVM.BuildLoad(_builder, typedPointer, "ldind");
- PushExpression(GetStackValueKind(type), "ldlind", load, type);
+ var pointer = _stack.Pop();
+ Debug.Assert(pointer is ExpressionEntry || pointer is ConstantEntry);
+ var expressionPointer = pointer as ExpressionEntry;
+ TypeDesc pointerElementType = pointer.Type.GetParameterType();
+ LLVMValueRef rawValue = expressionPointer?.RawLLVMValue ?? LLVM.ConstNull(GetLLVMTypeForTypeDesc(pointerElementType));
+ _stack.Push(new LoadExpressionEntry(type != null ? GetStackValueKind(type) : StackValueKind.ByRef, "ldind",
+ rawValue, pointer.Type.GetParameterType()));
}
private void ImportStoreIndirect(int token)
@@ -1016,29 +1158,18 @@ namespace Internal.IL
{
StackEntry value = _stack.Pop();
StackEntry destinationPointer = _stack.Pop();
- LLVMTypeRef requestedPointerType = LLVM.PointerType(GetLLVMTypeForTypeDesc(type), 0);
- LLVMValueRef typedValue = value.LLVMValue;
- LLVMValueRef typedPointer = destinationPointer.LLVMValue;
+ LLVMValueRef typedValue;
+ LLVMValueRef typedPointer;
- if (LLVM.GetTypeKind(LLVM.TypeOf(destinationPointer.LLVMValue)) != LLVMTypeKind.LLVMPointerTypeKind)
+ if (type != null)
{
- typedPointer = LLVM.BuildIntToPtr(_builder, destinationPointer.LLVMValue, requestedPointerType, "stindintptrcast");
+ typedValue = value.ValueAsType(type, _builder);
+ typedPointer = destinationPointer.ValueAsType(type.MakePointerType(), _builder);
}
else
{
- typedPointer = LLVM.BuildPointerCast(_builder, destinationPointer.LLVMValue, requestedPointerType, "stindptrcast");
- }
-
- if (value.Type != type)
- {
- if (LLVM.GetTypeKind(GetLLVMTypeForTypeDesc(value.Type)) != LLVMTypeKind.LLVMPointerTypeKind)
- {
- typedValue = LLVM.BuildIntCast(_builder, typedValue, GetLLVMTypeForTypeDesc(type), "stindvalcast");
- }
- else
- {
- typedValue = LLVM.BuildPointerCast(_builder, typedValue, GetLLVMTypeForTypeDesc(type), "stindvalptrcast");
- }
+ typedPointer = destinationPointer.ValueAsType(LLVM.PointerType(LLVM.Int32Type(), 0), _builder);
+ typedValue = value.ValueAsInt32(_builder, false);
}
LLVM.BuildStore(_builder, typedValue, typedPointer);
@@ -1065,106 +1196,140 @@ namespace Internal.IL
}
// The one exception from the above rule
- if ((kind == StackValueKind.ByRef) &&
- (opcode == ILOpcode.sub || opcode == ILOpcode.sub_ovf || opcode == ILOpcode.sub_ovf_un))
+ if (kind == StackValueKind.ByRef)
{
kind = StackValueKind.NativeInt;
- type = null;
+ type = type.MakePointerType();
}
LLVMValueRef result;
- LLVMValueRef left = op1.LLVMValue;
- LLVMValueRef right = op2.LLVMValue;
-
- if (kind == StackValueKind.NativeInt || kind == StackValueKind.ObjRef || kind == StackValueKind.ByRef)
+ LLVMValueRef left = op1.ValueForStackKind(kind, _builder, false);
+ LLVMValueRef right = op2.ValueForStackKind(kind, _builder, false);
+ if (kind == StackValueKind.Float)
{
- if (LLVM.GetTypeKind(LLVM.TypeOf(left)) == LLVMTypeKind.LLVMPointerTypeKind)
+ switch (opcode)
{
- left = LLVM.BuildPtrToInt(_builder, left, LLVM.Int32Type(), "lptrasint");
+ case ILOpcode.add:
+ result = LLVM.BuildFAdd(_builder, left, right, "fadd");
+ break;
+ case ILOpcode.sub:
+ result = LLVM.BuildFSub(_builder, left, right, "fsub");
+ break;
+ case ILOpcode.mul:
+ result = LLVM.BuildFMul(_builder, left, right, "fmul");
+ break;
+ case ILOpcode.div:
+ result = LLVM.BuildFDiv(_builder, left, right, "fdiv");
+ break;
+ case ILOpcode.rem:
+ result = LLVM.BuildFRem(_builder, left, right, "frem");
+ break;
+
+ // TODO: Overflow checks
+ case ILOpcode.add_ovf:
+ case ILOpcode.add_ovf_un:
+ result = LLVM.BuildFAdd(_builder, left, right, "fadd");
+ break;
+ case ILOpcode.sub_ovf:
+ case ILOpcode.sub_ovf_un:
+ result = LLVM.BuildFSub(_builder, left, right, "fsub");
+ break;
+ case ILOpcode.mul_ovf:
+ case ILOpcode.mul_ovf_un:
+ result = LLVM.BuildFMul(_builder, left, right, "fmul");
+ break;
+
+ default:
+ throw new InvalidOperationException(); // Should be unreachable
}
- if (LLVM.GetTypeKind(LLVM.TypeOf(right)) == LLVMTypeKind.LLVMPointerTypeKind)
+ }
+ else
+ {
+ switch (opcode)
{
- right = LLVM.BuildPtrToInt(_builder, right, LLVM.Int32Type(), "rptrasint");
+ case ILOpcode.add:
+ result = LLVM.BuildAdd(_builder, left, right, "add");
+ break;
+ case ILOpcode.sub:
+ result = LLVM.BuildSub(_builder, left, right, "sub");
+ break;
+ case ILOpcode.mul:
+ result = LLVM.BuildMul(_builder, left, right, "mul");
+ break;
+ case ILOpcode.div:
+ result = LLVM.BuildSDiv(_builder, left, right, "sdiv");
+ break;
+ case ILOpcode.div_un:
+ result = LLVM.BuildUDiv(_builder, left, right, "udiv");
+ break;
+ case ILOpcode.rem:
+ result = LLVM.BuildSRem(_builder, left, right, "srem");
+ break;
+ case ILOpcode.rem_un:
+ result = LLVM.BuildURem(_builder, left, right, "urem");
+ break;
+ case ILOpcode.and:
+ result = LLVM.BuildAnd(_builder, left, right, "and");
+ break;
+ case ILOpcode.or:
+ result = LLVM.BuildOr(_builder, left, right, "or");
+ break;
+ case ILOpcode.xor:
+ result = LLVM.BuildXor(_builder, left, right, "xor");
+ break;
+
+ // TODO: Overflow checks
+ case ILOpcode.add_ovf:
+ case ILOpcode.add_ovf_un:
+ result = LLVM.BuildAdd(_builder, left, right, "add");
+ break;
+ case ILOpcode.sub_ovf:
+ case ILOpcode.sub_ovf_un:
+ result = LLVM.BuildSub(_builder, left, right, "sub");
+ break;
+ case ILOpcode.mul_ovf:
+ case ILOpcode.mul_ovf_un:
+ result = LLVM.BuildMul(_builder, left, right, "mul");
+ break;
+
+ default:
+ throw new InvalidOperationException(); // Should be unreachable
}
}
- switch (opcode)
- {
- case ILOpcode.add:
- result = LLVM.BuildAdd(_builder, left, right, "add");
- break;
- case ILOpcode.sub:
- result = LLVM.BuildSub(_builder, left, right, "sub");
- break;
- case ILOpcode.mul:
- result = LLVM.BuildMul(_builder, left, right, "mul");
- break;
- case ILOpcode.div:
- result = LLVM.BuildSDiv(_builder, left, right, "sdiv");
- break;
- case ILOpcode.div_un:
- result = LLVM.BuildUDiv(_builder, left, right, "udiv");
- break;
- case ILOpcode.rem:
- result = LLVM.BuildSRem(_builder, left, right, "srem");
- break;
- case ILOpcode.rem_un:
- result = LLVM.BuildURem(_builder, left, right, "urem");
- break;
- case ILOpcode.and:
- result = LLVM.BuildAnd(_builder, left, right, "and");
- break;
- case ILOpcode.or:
- result = LLVM.BuildOr(_builder, left, right, "or");
- break;
- case ILOpcode.xor:
- result = LLVM.BuildXor(_builder, left, right, "xor");
- break;
- // TODO: Overflow checks
- case ILOpcode.add_ovf:
- case ILOpcode.add_ovf_un:
- result = LLVM.BuildAdd(_builder, left, right, "add");
- break;
- case ILOpcode.sub_ovf:
- case ILOpcode.sub_ovf_un:
- result = LLVM.BuildSub(_builder, left, right, "sub");
- break;
- case ILOpcode.mul_ovf:
- case ILOpcode.mul_ovf_un:
- result = LLVM.BuildMul(_builder, left, right, "mul");
- break;
-
- default:
- throw new InvalidOperationException(); // Should be unreachable
+ if (kind == StackValueKind.NativeInt || kind == StackValueKind.ByRef || kind == StackValueKind.ObjRef)
+ {
+ //we need to put the type back if we changed it because it started out a pointer
+ result = CastToTypeDesc(result, type);
}
-
- PushExpression(kind, "", result, type);
+ PushExpression(kind, "binop", result, type);
}
private void ImportShiftOperation(ILOpcode opcode)
{
LLVMValueRef result;
-
StackEntry numBitsToShift = _stack.Pop();
StackEntry valueToShift = _stack.Pop();
+ LLVMValueRef valueToShiftValue = valueToShift.ValueForStackKind(valueToShift.Kind, _builder, false);
+
switch (opcode)
{
case ILOpcode.shl:
- result = LLVM.BuildShl(_builder, valueToShift.LLVMValue, numBitsToShift.LLVMValue, "shl");
+ result = LLVM.BuildShl(_builder, valueToShiftValue, numBitsToShift.ValueAsInt32(_builder, false), "shl");
break;
case ILOpcode.shr:
- result = LLVM.BuildAShr(_builder, valueToShift.LLVMValue, numBitsToShift.LLVMValue, "shr");
+ result = LLVM.BuildAShr(_builder, valueToShiftValue, numBitsToShift.ValueAsInt32(_builder, false), "shr");
break;
case ILOpcode.shr_un:
- result = LLVM.BuildLShr(_builder, valueToShift.LLVMValue, numBitsToShift.LLVMValue, "shr");
+ result = LLVM.BuildLShr(_builder, valueToShiftValue, numBitsToShift.ValueAsInt32(_builder, false), "shr");
break;
default:
throw new InvalidOperationException(); // Should be unreachable
}
- PushExpression(valueToShift.Kind, "", result, valueToShift.Type);
+ PushExpression(valueToShift.Kind, "shiftop", result, valueToShift.Type);
}
private void ImportCompareOperation(ILOpcode opcode)
@@ -1185,34 +1350,8 @@ namespace Internal.IL
}
LLVMValueRef result;
- //TODO: deal with sign extension here instead of just casting
- var typeSaneOp1 = op1.LLVMValue;
- var typeSaneOp2 = op2.LLVMValue;
- if (op1.Type != op2.Type || op1.Type == null)
- {
- if (op1.Type != null && op2.Type != null)
- {
- if (op1.Type.IsPrimitive && op2.Type.IsPrimitive)
- {
- if (op1.Type.GetElementSize().AsInt > op2.Type.GetElementSize().AsInt)
- typeSaneOp2 = CastIfNecessary(op2.LLVMValue, GetLLVMTypeForTypeDesc(op1.Type));
- else
- typeSaneOp1 = CastIfNecessary(op1.LLVMValue, GetLLVMTypeForTypeDesc(op2.Type));
- }
- else
- {
- typeSaneOp2 = CastIfNecessary(op2.LLVMValue, GetLLVMTypeForTypeDesc(op1.Type));
- }
- }
- else if (op1.Type == null && op1.Kind == StackValueKind.ObjRef)
- {
- typeSaneOp1 = CastIfNecessary(op1.LLVMValue, LLVM.TypeOf(typeSaneOp2));
- }
- else if (op2.Type == null && op2.Kind == StackValueKind.ObjRef)
- {
- typeSaneOp2 = CastIfNecessary(op2.LLVMValue, LLVM.TypeOf(typeSaneOp1));
- }
- }
+ LLVMValueRef typeSaneOp1 = op1.ValueForStackKind(kind, _builder, true);
+ LLVMValueRef typeSaneOp2 = op2.ValueForStackKind(kind, _builder, true);
switch (opcode)
{
@@ -1235,23 +1374,30 @@ namespace Internal.IL
throw new NotSupportedException(); // unreachable
}
- PushExpression(kind, "", result, GetWellKnownType(WellKnownType.SByte));
+ PushExpression(StackValueKind.Int32, "cmpop", result, GetWellKnownType(WellKnownType.SByte));
}
private void ImportConvert(WellKnownType wellKnownType, bool checkOverflow, bool unsigned)
{
StackEntry value = _stack.Pop();
- StackEntry convertedValue = value.Duplicate();
+ LLVMValueRef convertedValue;
//conv.u for a pointer should change to a int8*
- if(wellKnownType == WellKnownType.UIntPtr)
+ if (wellKnownType == WellKnownType.UIntPtr)
{
if (value.Kind == StackValueKind.Int32)
{
- convertedValue.LLVMValue = LLVM.BuildIntToPtr(_builder, value.LLVMValue, LLVM.PointerType(LLVM.Int8Type(), 0), "conv.u");
+ convertedValue = LLVM.BuildIntToPtr(_builder, value.ValueAsInt32(_builder, false), LLVM.PointerType(LLVM.Int8Type(), 0), "conv.u");
+ }
+ else
+ {
+ convertedValue = value.ValueAsType(GetWellKnownType(wellKnownType), _builder);
}
}
-
- _stack.Push(convertedValue);
+ else
+ {
+ convertedValue = value.ValueAsType(GetWellKnownType(wellKnownType), _builder);
+ }
+ PushExpression(value.Kind, "conv", convertedValue, value.Type);
}
private void ImportUnaryOperation(ILOpcode opCode)
@@ -1264,21 +1410,21 @@ namespace Internal.IL
case ILOpcode.neg:
if (argument.Kind == StackValueKind.Float)
{
- result = LLVM.BuildFNeg(_builder, argument.LLVMValue, "neg");
+ result = LLVM.BuildFNeg(_builder, argument.ValueForStackKind(argument.Kind, _builder, false), "neg");
}
else
{
- result = LLVM.BuildNeg(_builder, argument.LLVMValue, "neg");
+ result = LLVM.BuildNeg(_builder, argument.ValueForStackKind(argument.Kind, _builder, true), "neg");
}
break;
case ILOpcode.not:
- result = LLVM.BuildNot(_builder, argument.LLVMValue, "not");
+ result = LLVM.BuildNot(_builder, argument.ValueForStackKind(argument.Kind, _builder, true), "not");
break;
default:
throw new NotSupportedException(); // unreachable
}
- PushExpression(argument.Kind, "", result, argument.Type);
+ PushExpression(argument.Kind, "unaryop", result, argument.Type);
}
private void ImportCpOpj(int token)
@@ -1287,6 +1433,37 @@ namespace Internal.IL
private void ImportUnbox(int token, ILOpcode opCode)
{
+ TypeDesc type = ResolveTypeToken(token);
+ if (type.IsNullable)
+ throw new NotImplementedException();
+
+ if (opCode == ILOpcode.unbox)
+ {
+ var unboxResult = _stack.Pop().ValueAsType(LLVM.PointerType(LLVM.Int8Type(), 0), _builder);
+ LLVMValueRef unboxData = LLVM.BuildGEP(_builder, unboxResult, new LLVMValueRef[] { BuildConstInt32(type.Context.Target.PointerSize) }, "unboxData");
+ //push the pointer to the data, but it shouldnt be implicitly dereferenced
+ PushExpression(GetStackValueKind(type), "unboxed", unboxData, type);
+ }
+ else //unbox_any
+ {
+ Debug.Assert(opCode == ILOpcode.unbox_any);
+
+ //TODO: when the runtime is ready switch this to calling the real RhUnboxAny
+ //LLVMValueRef eeType = GetEETypeForTypeDesc(type);
+ //var eeTypeDesc = _compilation.TypeSystemContext.SystemModule.GetKnownType("System", "EETypePtr");
+ //LLVMValueRef untypedObjectValue = LLVM.BuildAlloca(_builder, GetLLVMTypeForTypeDesc(type), "objptr");
+ //PushExpression(StackValueKind.ByRef, "objPtr", untypedObjectValue, type.MakePointerType());
+ //PushExpression(StackValueKind.ByRef, "eeType", eeType, eeTypeDesc);
+ //CallRuntimeExport(_compilation.TypeSystemContext, "RhUnboxAny");
+ //PushLoadExpression(GetStackValueKind(type), "unboxed", untypedObjectValue, type);
+ //this can be removed once we can call RhUnboxAny
+ if (!type.IsValueType)
+ throw new NotImplementedException();
+
+ var unboxResult = _stack.Pop().ValueAsType(LLVM.PointerType(LLVM.Int8Type(), 0), _builder);
+ LLVMValueRef unboxData = LLVM.BuildGEP(_builder, unboxResult, new LLVMValueRef[] { BuildConstInt32(type.Context.Target.PointerSize) }, "unboxData");
+ PushLoadExpression(GetStackValueKind(type), "unboxed", unboxData, type);
+ }
}
private void ImportRefAnyVal(int token)
@@ -1310,21 +1487,16 @@ namespace Internal.IL
if (ldtokenValue is TypeDesc)
{
ldtokenKind = WellKnownType.RuntimeTypeHandle;
- //AddTypeReference((TypeDesc)ldtokenValue, false);
-
- // todo: this doesn't work because we don't have the eetypeptr pushed. How do we get the eetypeptr?
+ PushExpression(StackValueKind.ByRef, "ldtoken", GetEETypeForTypeDesc(ldtokenValue as TypeDesc), _compilation.TypeSystemContext.SystemModule.GetKnownType("System", "EETypePtr"));
MethodDesc helper = _compilation.TypeSystemContext.GetHelperEntryPoint("LdTokenHelpers", "GetRuntimeTypeHandle");
- //AddMethodReference(helper);
+ AddMethodReference(helper);
HandleCall(helper);
name = ldtokenValue.ToString();
-
- //value = new LdTokenEntry<TypeDesc>(StackValueKind.ValueType, name, (TypeDesc)ldtokenValue, GetWellKnownType(ldtokenKind));
}
else if (ldtokenValue is FieldDesc)
{
ldtokenKind = WellKnownType.RuntimeFieldHandle;
- // todo: this is probably the wrong llvm value for the field
- value = new LdTokenEntry<FieldDesc>(StackValueKind.ValueType, null, (FieldDesc)ldtokenValue, LLVM.ConstInt(LLVM.Int32Type(), (uint)token, LLVMMisc.False), GetWellKnownType(ldtokenKind));
+ value = new LdTokenEntry<FieldDesc>(StackValueKind.ValueType, null, (FieldDesc)ldtokenValue, GetWellKnownType(ldtokenKind));
_stack.Push(value);
}
else if (ldtokenValue is MethodDesc)
@@ -1404,21 +1576,35 @@ namespace Internal.IL
private LLVMValueRef GetInstanceFieldAddress(StackEntry objectEntry, FieldDesc field)
{
var objectType = objectEntry.Type ?? field.OwningType;
- LLVMValueRef typedObjectValue;
+ LLVMValueRef untypedObjectValue;
+ LLVMTypeRef llvmObjectType = GetLLVMTypeForTypeDesc(objectType);
if (objectType.IsValueType && !objectType.IsPointer && objectEntry.Kind != StackValueKind.NativeInt && objectEntry.Kind != StackValueKind.ByRef)
{
- typedObjectValue = LLVM.BuildAlloca(_builder, GetLLVMTypeForTypeDesc(objectType), "objptr");
- LLVM.BuildStore(_builder, objectEntry.LLVMValue, typedObjectValue);
+ if (objectEntry is LoadExpressionEntry)
+ {
+ untypedObjectValue = CastToRawPointer(((LoadExpressionEntry)objectEntry).RawLLVMValue);
+ }
+ else
+ {
+ untypedObjectValue = LLVM.BuildAlloca(_builder, llvmObjectType, "objptr");
+ LLVM.BuildStore(_builder, objectEntry.ValueAsType(llvmObjectType, _builder), untypedObjectValue);
+ untypedObjectValue = LLVM.BuildPointerCast(_builder, untypedObjectValue, LLVM.PointerType(LLVMTypeRef.Int8Type(), 0), "objptrcast");
+ }
+ }
+ else
+ {
+ untypedObjectValue = objectEntry.ValueAsType(LLVM.PointerType(LLVMTypeRef.Int8Type(), 0), _builder);
+ }
+ if (field.Offset.AsInt == 0)
+ {
+ return untypedObjectValue;
}
else
{
- typedObjectValue = objectEntry.LLVMValue;
+ var loadLocation = LLVM.BuildGEP(_builder, untypedObjectValue,
+ new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), (ulong)field.Offset.AsInt, LLVMMisc.False) }, String.Empty);
+ return loadLocation;
}
-
- var untypedObjectPointer = CastIfNecessary(typedObjectValue, LLVM.PointerType(LLVMTypeRef.Int8Type(), 0));
- var loadLocation = LLVM.BuildGEP(_builder, untypedObjectPointer,
- new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), (ulong)field.Offset.AsInt, LLVMMisc.False) }, String.Empty);
- return LLVM.BuildPointerCast(_builder, loadLocation, LLVM.PointerType(GetLLVMTypeForTypeDesc(field.FieldType), 0), "fieldaddresscast");
}
private LLVMValueRef GetFieldAddress(FieldDesc field, bool isStatic)
@@ -1429,8 +1615,7 @@ namespace Internal.IL
if (!isStatic)
_stack.Pop();
- LLVMValueRef untypedFieldAddress = WebAssemblyObjectWriter.EmitGlobal(Module, field, _compilation.NameMangler);
- return LLVM.BuildPointerCast(_builder, untypedFieldAddress, LLVM.PointerType(GetLLVMTypeForTypeDesc(field.FieldType), 0), "tempfieldaddresscast");
+ return WebAssemblyObjectWriter.EmitGlobal(Module, field, _compilation.NameMangler);
}
else
{
@@ -1442,26 +1627,22 @@ namespace Internal.IL
{
FieldDesc field = (FieldDesc)_methodIL.GetObject(token);
LLVMValueRef fieldAddress = GetFieldAddress(field, isStatic);
- LLVMValueRef loadValue = LLVM.BuildLoad(_builder, fieldAddress, "ldfld_" + field.Name);
- PushExpression(GetStackValueKind(field.FieldType), "ldfld", loadValue, field.FieldType);
+ PushLoadExpression(GetStackValueKind(field.FieldType), "ldfld_" + field.Name, fieldAddress, field.FieldType);
}
private void ImportAddressOfField(int token, bool isStatic)
{
FieldDesc field = (FieldDesc)_methodIL.GetObject(token);
LLVMValueRef fieldAddress = GetFieldAddress(field, isStatic);
- PushExpression(StackValueKind.ByRef, "ldflda", fieldAddress, field.FieldType.MakePointerType());
+ _stack.Push(new AddressExpressionEntry(StackValueKind.ByRef, "ldflda", fieldAddress, field.FieldType.MakePointerType()));
}
private void ImportStoreField(int token, bool isStatic)
{
FieldDesc field = (FieldDesc)_methodIL.GetObject(token);
StackEntry valueEntry = _stack.Pop();
- LLVMValueRef value = valueEntry.LLVMValue;
-
- value = CastIfNecessary(value, GetLLVMTypeForTypeDesc(field.FieldType));
LLVMValueRef fieldAddress = GetFieldAddress(field, isStatic);
- LLVM.BuildStore(_builder, value, fieldAddress);
+ CastingStore(fieldAddress, valueEntry, field.FieldType);
}
// Loads symbol address. Address is represented as a i32*
@@ -1485,10 +1666,36 @@ namespace Internal.IL
private void ImportInitObj(int token)
{
+ TypeDesc type = ResolveTypeToken(token);
+ var valueEntry = _stack.Pop();
+ var llvmType = GetLLVMTypeForTypeDesc(type);
+ if (llvmType.TypeKind == LLVMTypeKind.LLVMArrayTypeKind)
+ ImportCallMemset(valueEntry.ValueAsType(LLVM.PointerType(LLVM.Int8Type(), 0), _builder), 0, type.GetElementSize().AsInt);
+ else if (llvmType.TypeKind == LLVMTypeKind.LLVMIntegerTypeKind)
+ LLVM.BuildStore(_builder, LLVM.ConstInt(llvmType, 0, LLVMMisc.False), valueEntry.ValueAsType(LLVM.PointerType(llvmType, 0), _builder));
+ else if (llvmType.TypeKind == LLVMTypeKind.LLVMPointerTypeKind)
+ LLVM.BuildStore(_builder, LLVM.ConstNull(llvmType), valueEntry.ValueAsType(LLVM.PointerType(llvmType, 0), _builder));
+ else if (llvmType.TypeKind == LLVMTypeKind.LLVMFloatTypeKind)
+ LLVM.BuildStore(_builder, LLVM.ConstReal(llvmType, 0.0), valueEntry.ValueAsType(LLVM.PointerType(llvmType, 0), _builder));
+ else
+ throw new NotImplementedException();
}
private void ImportBox(int token)
{
+ TypeDesc type = ResolveTypeToken(token);
+ if (type.IsValueType)
+ {
+ if (type.IsNullable)
+ throw new NotImplementedException();
+
+ var value = _stack.Pop();
+ ExpressionEntry boxTarget = AllocateObject(type);
+ LLVMValueRef boxData = LLVM.BuildGEP(_builder, boxTarget.RawLLVMValue, new LLVMValueRef[] { BuildConstInt32(type.Context.Target.PointerSize) }, "boxData");
+ LLVMValueRef typedBoxData = LLVM.BuildPointerCast(_builder, boxData, LLVM.PointerType(GetLLVMTypeForTypeDesc(type), 0), "typedBoxData");
+ LLVM.BuildStore(_builder, value.ValueAsType(type, _builder), typedBoxData);
+ _stack.Push(boxTarget);
+ }
}
private void ImportLeave(BasicBlock target)
@@ -1573,38 +1780,55 @@ namespace Internal.IL
if (_stack.Length > 0)
{
entryStack = new EvaluationStack<StackEntry>(_stack.Length);
-
-#pragma warning disable 162 // Due to not implement3ed exception incrementer in for needs pragma warning disable
for (int i = 0; i < _stack.Length; i++)
{
- // todo: do we need anything special for spilled stacks like cpp codegen does?
- entryStack.Push(_stack[i]);
- //entryStack.Push(NewSpillSlot(_stack[i]));
+ entryStack.Push(NewSpillSlot(_stack[i]));
}
-#pragma warning restore 162
}
next.EntryStack = entryStack;
}
if (entryStack != null)
{
- // todo: do we have to do anything here?
-#pragma warning disable 162// Due to not implement3ed exception incrementer in for needs pragma warning disable
for (int i = 0; i < entryStack.Length; i++)
{
- /*AppendLine();
- Append(entryStack[i]);
- Append(" = ");
- Append(_stack[i]);
- AppendSemicolon();*/
+ var currentEntry = _stack[i];
+ var entry = entryStack[i] as SpilledExpressionEntry;
+ if (entry == null)
+ throw new InvalidProgramException();
+
+ if (currentEntry is SpilledExpressionEntry)
+ continue; //this is already a sharable value
+
+ StoreTemp(entry.LocalIndex, currentEntry.ValueAsType(entry.Type, _builder));
}
-#pragma warning restore 162
}
MarkBasicBlock(next);
}
+ private void CallRuntimeExport(TypeSystemContext context, string methodName)
+ {
+ MetadataType helperType = context.SystemModule.GetKnownType("System.Runtime", "RuntimeExports");
+ MethodDesc helperMethod = helperType.GetKnownMethod(methodName, null);
+ HandleCall(helperMethod);
+ }
+
+ private StackEntry NewSpillSlot(StackEntry entry)
+ {
+ if (entry is SpilledExpressionEntry)
+ return entry;
+ else
+ {
+ var entryType = entry.Type ?? GetWellKnownType(WellKnownType.Object); //type is required here, currently the only time entry.Type is null is if someone has pushed a null literal
+ var entryIndex = _spilledExpressions.Count;
+ var newEntry = new SpilledExpressionEntry(entry.Kind, entry is ExpressionEntry ? ((ExpressionEntry)entry).Name : "spilled" + entryIndex, entryType, entryIndex, this);
+ _spilledExpressions.Add(newEntry);
+ return newEntry;
+ }
+ }
+
private TypeDesc ResolveTypeToken(int token)
{
return (TypeDesc)_methodIL.GetObject(token);
diff --git a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter_Statics.cs b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter_Statics.cs
index 8a814508e..3a5f48117 100644
--- a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter_Statics.cs
+++ b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter_Statics.cs
@@ -101,7 +101,6 @@ namespace Internal.IL
static LLVMValueRef TrapFunction = default(LLVMValueRef);
static LLVMValueRef DoNothingFunction = default(LLVMValueRef);
-
private static IEnumerable<string> GetParameterNamesForMethod(MethodDesc method)
{
// TODO: The uses of this method need revision. The right way to get to this info is from
diff --git a/src/ILCompiler.WebAssembly/src/CodeGen/WebAssemblyObjectWriter.cs b/src/ILCompiler.WebAssembly/src/CodeGen/WebAssemblyObjectWriter.cs
index 335157917..140e2b1bc 100644
--- a/src/ILCompiler.WebAssembly/src/CodeGen/WebAssemblyObjectWriter.cs
+++ b/src/ILCompiler.WebAssembly/src/CodeGen/WebAssemblyObjectWriter.cs
@@ -188,6 +188,17 @@ namespace ILCompiler.DependencyAnalysis
//throw new NotImplementedException(); // This function isn't complete
}
+ public static LLVMValueRef GetConstZeroArray(int length)
+ {
+ var int8Type = LLVM.Int8Type();
+ var result = new LLVMValueRef[length];
+ for (int i = 0; i < length; i++)
+ {
+ result[i] = LLVM.ConstInt(int8Type, 0, LLVMMisc.False);
+ }
+ return LLVM.ConstArray(int8Type, result);
+ }
+
public static LLVMValueRef EmitGlobal(LLVMModuleRef module, FieldDesc field, NameMangler nameMangler)
{
if (field.IsThreadStatic)
@@ -203,7 +214,7 @@ namespace ILCompiler.DependencyAnalysis
var valueType = LLVM.ArrayType(LLVM.Int8Type(), (uint)field.FieldType.GetElementSize().AsInt);
var llvmValue = LLVM.AddGlobal(module, valueType, nameMangler.GetMangledFieldName(field).ToString());
LLVM.SetLinkage(llvmValue, LLVMLinkage.LLVMInternalLinkage);
- LLVM.SetInitializer(llvmValue, LLVM.ConstPointerNull(valueType));
+ LLVM.SetInitializer(llvmValue, GetConstZeroArray(field.FieldType.GetElementSize().AsInt));
s_staticFieldMapping.Add(field, llvmValue);
return llvmValue;
}
@@ -262,7 +273,7 @@ namespace ILCompiler.DependencyAnalysis
{
LLVMValueRef valRef = IsFunction ? LLVM.GetNamedFunction(module, SymbolName) : LLVM.GetNamedGlobal(module, SymbolName);
- if (Offset != 0)
+ if (Offset != 0 && valRef.Pointer != IntPtr.Zero)
{
var pointerType = LLVM.PointerType(LLVM.Int8Type(), 0);
var bitCast = LLVM.ConstBitCast(valRef, pointerType);
@@ -313,8 +324,16 @@ namespace ILCompiler.DependencyAnalysis
if (ObjectSymbolRefs.TryGetValue(curOffset, out symbolRef))
{
LLVMValueRef pointedAtValue = symbolRef.ToLLVMValueRef(module);
- var ptrValue = LLVM.ConstBitCast(pointedAtValue, intPtrType);
- entries.Add(ptrValue);
+ //TODO: why did this come back null
+ if (pointedAtValue.Pointer != IntPtr.Zero)
+ {
+ var ptrValue = LLVM.ConstBitCast(pointedAtValue, intPtrType);
+ entries.Add(ptrValue);
+ }
+ else
+ {
+ entries.Add(LLVM.ConstPointerNull(intPtrType));
+ }
}
else
{
@@ -358,7 +377,6 @@ namespace ILCompiler.DependencyAnalysis
_dataToFill.Add(new ObjectNodeDataEmission(arrayglobal, _currentObjectData.ToArray(), _currentObjectSymbolRefs));
-
foreach (var symbolIdInfo in _symbolDefs)
{
EmitSymbolDef(arrayglobal, symbolIdInfo.Key, symbolIdInfo.Value);
diff --git a/src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyCodegenNodeFactory.cs b/src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyCodegenNodeFactory.cs
index 039969de2..978e29f8e 100644
--- a/src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyCodegenNodeFactory.cs
+++ b/src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyCodegenNodeFactory.cs
@@ -32,8 +32,8 @@ namespace ILCompiler.DependencyAnalysis
protected override IMethodNode CreateUnboxingStubNode(MethodDesc method)
{
- // TODO: this is wrong: this returns an assembly stub node
- return new UnboxingStubNode(method, Target);
+ // TODO: this is wrong: this returns an unstubbed node
+ return new WebAssemblyMethodCodeNode(method);
}
protected override ISymbolNode CreateReadyToRunHelperNode(ReadyToRunHelperKey helperCall)
diff --git a/src/ILCompiler/ILCompiler.sln b/src/ILCompiler/ILCompiler.sln
index 8008033a8..c210088aa 100644
--- a/src/ILCompiler/ILCompiler.sln
+++ b/src/ILCompiler/ILCompiler.sln
@@ -28,6 +28,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILCompiler.WebAssembly", ".
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "desktop", "desktop\desktop.csproj", "{CE9781B1-0028-4039-A48C-8193F0D28467}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILCompiler.Build.Tasks", "..\ILCompiler.Build.Tasks\src\ILCompiler.Build.Tasks.csproj", "{44DE7F7B-AD73-40EA-87CC-554F2F57C38A}"
+EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
..\System.Private.CoreLib\shared\System.Private.CoreLib.Shared.projitems*{be95c560-b508-4588-8907-f9fc5bc1a0cf}*SharedItemsImports = 4
@@ -253,6 +255,26 @@ Global
{CE9781B1-0028-4039-A48C-8193F0D28467}.Release|x64.Build.0 = Release|x64
{CE9781B1-0028-4039-A48C-8193F0D28467}.Release|x86.ActiveCfg = Release|Any CPU
{CE9781B1-0028-4039-A48C-8193F0D28467}.Release|x86.Build.0 = Release|Any CPU
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Debug|arm.ActiveCfg = Debug|arm
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Debug|arm.Build.0 = Debug|arm
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Debug|arm64.ActiveCfg = Debug|arm64
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Debug|arm64.Build.0 = Debug|arm64
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Debug|x64.ActiveCfg = Debug|x64
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Debug|x64.Build.0 = Debug|x64
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Debug|x86.ActiveCfg = Debug|x86
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Debug|x86.Build.0 = Debug|x86
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Release|arm.ActiveCfg = Release|arm
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Release|arm.Build.0 = Release|arm
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Release|arm64.ActiveCfg = Release|arm64
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Release|arm64.Build.0 = Release|arm64
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Release|x64.ActiveCfg = Release|x64
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Release|x64.Build.0 = Release|x64
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Release|x86.ActiveCfg = Release|x86
+ {44DE7F7B-AD73-40EA-87CC-554F2F57C38A}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/ILVerify/src/AccessVerificationHelpers.cs b/src/ILVerify/src/AccessVerificationHelpers.cs
index 37064f850..9274cad54 100644
--- a/src/ILVerify/src/AccessVerificationHelpers.cs
+++ b/src/ILVerify/src/AccessVerificationHelpers.cs
@@ -262,7 +262,7 @@ namespace ILVerify
foreach (var attribute in assembly.GetDecodedCustomAttributes("System.Runtime.CompilerServices", "InternalsVisibleToAttribute"))
{
- var friendValues = ((string)attribute.FixedArguments[0].Value).Split(", ");
+ var friendValues = ((string)attribute.FixedArguments[0].Value).Split(new string[] { ", " }, StringSplitOptions.None);
if (friendValues.Length >= 1 && friendValues.Length <= 2)
{
if (friendValues[0] != friendName.Name)
diff --git a/src/ILVerify/src/ILVerify.csproj b/src/ILVerify/src/ILVerify.csproj
index 73c0208a6..d07d962fa 100644
--- a/src/ILVerify/src/ILVerify.csproj
+++ b/src/ILVerify/src/ILVerify.csproj
@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
- <TargetFramework>netcoreapp2.0</TargetFramework>
+ <TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
<CLSCompliant>false</CLSCompliant>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
@@ -294,7 +294,7 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="System.IO.MemoryMappedFiles" Version="4.0.0" />
+ <PackageReference Include="System.IO.MemoryMappedFiles" Version="4.3.0" />
<PackageReference Include="System.Reflection.Metadata" Version="1.4.1" />
<PackageReference Include="System.CommandLine" Version="0.1.0-e160909-1" />
</ItemGroup>
diff --git a/src/Native/Bootstrap/main.cpp b/src/Native/Bootstrap/main.cpp
index bbeff8c9c..e3c1a2fc9 100644
--- a/src/Native/Bootstrap/main.cpp
+++ b/src/Native/Bootstrap/main.cpp
@@ -85,11 +85,12 @@ static char& __unbox_z = __stop___unbox;
#endif // !CPPCODEGEN
+// Do not warn that extern C methods throw exceptions. This is temporary
+// as long as we have unimplemented/throwing APIs in this file.
+#pragma warning(disable:4297)
#ifdef CPPCODEGEN
-#pragma warning(disable:4297)
-
extern "C" Object * RhNewObject(MethodTable * pMT);
extern "C" Object * RhNewArray(MethodTable * pMT, int32_t elements);
extern "C" void * RhTypeCast_IsInstanceOf(void * pObject, MethodTable * pMT);
@@ -238,15 +239,18 @@ extern "C" void RhpUniversalTransition_DebugStepTailCall()
{
throw "RhpUniversalTransition_DebugStepTailCall";
}
-extern "C" void CCWAddRef()
-{
- throw "CCWAddRef";
-}
void* RtRHeaderWrapper();
#endif // CPPCODEGEN
+// This works around System.Private.Interop's references to Interop.Native.
+// This won't be needed once we stop dragging in S.P.Interop for basic p/invoke support.
+extern "C" void CCWAddRef()
+{
+ throw "CCWAddRef";
+}
+
extern "C" void __fail_fast()
{
// TODO: FailFast
diff --git a/src/Native/CMakeLists.txt b/src/Native/CMakeLists.txt
index 5aeb930a5..e77b1b6f4 100644
--- a/src/Native/CMakeLists.txt
+++ b/src/Native/CMakeLists.txt
@@ -224,6 +224,7 @@ if(WIN32)
add_compile_options($<$<CONFIG:Debug>:-DDEBUG>)
add_compile_options($<$<CONFIG:Debug>:/MTd>)
add_compile_options($<$<CONFIG:Release>:/MT>)
+ add_compile_options(/source-charset:utf-8) # Force MSVC to compile source as UTF-8.
add_compile_options(/Zi) # enable debugging information
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DEBUG")
diff --git a/src/Native/ObjWriter/.nuget/Microsoft.DotNet.ObjectWriter.nuspec b/src/Native/ObjWriter/.nuget/Microsoft.DotNet.ObjectWriter.nuspec
new file mode 100644
index 000000000..f3421bb32
--- /dev/null
+++ b/src/Native/ObjWriter/.nuget/Microsoft.DotNet.ObjectWriter.nuspec
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<package >
+ <metadata>
+ <id>Microsoft.DotNet.ObjectWriter</id>
+ <version>1.0.19-prerelease-00001</version>
+ <title>Microsoft .NET Object File Generator</title>
+ <authors>Microsoft</authors>
+ <owners>Microsoft</owners>
+ <licenseUrl>http://go.microsoft.com/fwlink/?LinkId=329770</licenseUrl>
+ <projectUrl>https://github.com/dotnet/corert</projectUrl>
+ <iconUrl>http://go.microsoft.com/fwlink/?LinkID=288859</iconUrl>
+ <requireLicenseAcceptance>true</requireLicenseAcceptance>
+ <description>Provides object writer to the managed to native code-generator.</description>
+ <releaseNotes>Initial release</releaseNotes>
+ <copyright>Copyright &#169; Microsoft Corporation</copyright>
+ </metadata>
+ <files>
+ <file src="runtime.json" />
+ </files>
+</package>
diff --git a/src/Native/ObjWriter/.nuget/runtime.json b/src/Native/ObjWriter/.nuget/runtime.json
new file mode 100644
index 000000000..c9c5b8e6b
--- /dev/null
+++ b/src/Native/ObjWriter/.nuget/runtime.json
@@ -0,0 +1,19 @@
+{
+ "runtimes": {
+ "win7-x64": {
+ "Microsoft.DotNet.ObjectWriter": {
+ "toolchain.win7-x64.Microsoft.DotNet.ObjectWriter": "1.0.19-prerelease-00001"
+ }
+ },
+ "ubuntu.14.04-x64": {
+ "Microsoft.DotNet.ObjectWriter": {
+ "toolchain.ubuntu.14.04-x64.Microsoft.DotNet.ObjectWriter": "1.0.19-prerelease-00001"
+ }
+ },
+ "osx.10.10-x64": {
+ "Microsoft.DotNet.ObjectWriter": {
+ "toolchain.osx.10.10-x64.Microsoft.DotNet.ObjectWriter": "1.0.19-prerelease-00001"
+ }
+ }
+ }
+}
diff --git a/src/Native/ObjWriter/.nuget/toolchain.osx.10.10-x64.Microsoft.DotNet.ObjectWriter.nuspec b/src/Native/ObjWriter/.nuget/toolchain.osx.10.10-x64.Microsoft.DotNet.ObjectWriter.nuspec
new file mode 100644
index 000000000..7a571beaf
--- /dev/null
+++ b/src/Native/ObjWriter/.nuget/toolchain.osx.10.10-x64.Microsoft.DotNet.ObjectWriter.nuspec
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<package >
+ <metadata>
+ <id>toolchain.osx.10.10-x64.Microsoft.DotNet.ObjectWriter</id>
+ <version>1.0.19-prerelease-00001</version>
+ <title>Microsoft .NET Object File Generator</title>
+ <authors>Microsoft</authors>
+ <owners>Microsoft</owners>
+ <licenseUrl>http://go.microsoft.com/fwlink/?LinkId=329770</licenseUrl>
+ <projectUrl>https://github.com/dotnet/corert</projectUrl>
+ <iconUrl>http://go.microsoft.com/fwlink/?LinkID=288859</iconUrl>
+ <requireLicenseAcceptance>true</requireLicenseAcceptance>
+ <description>Provides object writer to the managed to native code-generator.</description>
+ <releaseNotes>Initial release</releaseNotes>
+ <copyright>Copyright &#169; Microsoft Corporation</copyright>
+ </metadata>
+ <files>
+ <file src="../libobjwriter.dylib" target="runtimes/osx.10.10-x64/native/libobjwriter.dylib" />
+ </files>
+</package>
diff --git a/src/Native/ObjWriter/.nuget/toolchain.ubuntu.14.04-x64.Microsoft.DotNet.ObjectWriter.nuspec b/src/Native/ObjWriter/.nuget/toolchain.ubuntu.14.04-x64.Microsoft.DotNet.ObjectWriter.nuspec
new file mode 100644
index 000000000..fd9c514c6
--- /dev/null
+++ b/src/Native/ObjWriter/.nuget/toolchain.ubuntu.14.04-x64.Microsoft.DotNet.ObjectWriter.nuspec
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<package >
+ <metadata>
+ <id>toolchain.ubuntu.14.04-x64.Microsoft.DotNet.ObjectWriter</id>
+ <version>1.0.19-prerelease-00001</version>
+ <title>Microsoft .NET Object File Generator</title>
+ <authors>Microsoft</authors>
+ <owners>Microsoft</owners>
+ <licenseUrl>http://go.microsoft.com/fwlink/?LinkId=329770</licenseUrl>
+ <projectUrl>https://github.com/dotnet/corert</projectUrl>
+ <iconUrl>http://go.microsoft.com/fwlink/?LinkID=288859</iconUrl>
+ <requireLicenseAcceptance>true</requireLicenseAcceptance>
+ <description>Provides object writer to the managed to native code-generator.</description>
+ <releaseNotes>Initial release</releaseNotes>
+ <copyright>Copyright &#169; Microsoft Corporation</copyright>
+ </metadata>
+ <files>
+ <file src="../libobjwriter.so" target="runtimes/ubuntu.14.04-x64/native/libobjwriter.so" />
+ </files>
+</package>
diff --git a/src/Native/ObjWriter/.nuget/toolchain.win7-x64.Microsoft.DotNet.ObjectWriter.nuspec b/src/Native/ObjWriter/.nuget/toolchain.win7-x64.Microsoft.DotNet.ObjectWriter.nuspec
new file mode 100644
index 000000000..a54cdc230
--- /dev/null
+++ b/src/Native/ObjWriter/.nuget/toolchain.win7-x64.Microsoft.DotNet.ObjectWriter.nuspec
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<package >
+ <metadata>
+ <id>toolchain.win7-x64.Microsoft.DotNet.ObjectWriter</id>
+ <version>1.0.19-prerelease-00001</version>
+ <title>Microsoft .NET Object File Generator</title>
+ <authors>Microsoft</authors>
+ <owners>Microsoft</owners>
+ <licenseUrl>http://go.microsoft.com/fwlink/?LinkId=329770</licenseUrl>
+ <projectUrl>https://github.com/dotnet/corert</projectUrl>
+ <iconUrl>http://go.microsoft.com/fwlink/?LinkID=288859</iconUrl>
+ <requireLicenseAcceptance>true</requireLicenseAcceptance>
+ <description>Provides object writer to the managed to native code-generator.</description>
+ <releaseNotes>Initial release</releaseNotes>
+ <copyright>Copyright &#169; Microsoft Corporation</copyright>
+ </metadata>
+ <files>
+ <file src="..\objwriter.dll" target="runtimes\win7-x64\native\objwriter.dll" />
+ </files>
+</package>
diff --git a/src/Native/ObjWriter/CMakeLists.txt b/src/Native/ObjWriter/CMakeLists.txt
new file mode 100644
index 000000000..ead1db75b
--- /dev/null
+++ b/src/Native/ObjWriter/CMakeLists.txt
@@ -0,0 +1,41 @@
+project(objwriter)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti")
+include_directories(${LLVM_INCLUDE_DIRS})
+include_directories(.)
+add_definitions(${LLVM_DEFINITIONS})
+
+if (WIN32)
+ # Create .def file containing a list of exports preceeded by
+ # 'EXPORTS'. The file "objwriter.exports" already contains the list, so we
+ # massage it into the correct format here to create "objwriter.exports.def".
+ set(OBJWRITER_EXPORTS_DEF ${CMAKE_CURRENT_BINARY_DIR}/objwriter.exports.def)
+ set(OBJWRITER_EXPORTS_DEF_TEMP ${OBJWRITER_EXPORTS_DEF}.txt)
+ file(READ "objwriter.exports" exports_list)
+ file(WRITE ${OBJWRITER_EXPORTS_DEF_TEMP} "LIBRARY OBJWRITER\n")
+ file(APPEND ${OBJWRITER_EXPORTS_DEF_TEMP} "EXPORTS\n")
+ file(APPEND ${OBJWRITER_EXPORTS_DEF_TEMP} ${exports_list})
+ # Copy the file only if it has changed.
+ execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${OBJWRITER_EXPORTS_DEF_TEMP} ${OBJWRITER_EXPORTS_DEF})
+endif()
+
+# Now build our tools
+add_library(objwriter
+ SHARED
+ objwriter.cpp
+ typeBuilder.cpp
+ objwriter.h # Visual Studio generator doesn't include necessary header files into the project automatically
+ typeBuilder.h
+ ${OBJWRITER_EXPORTS_DEF}
+)
+
+# Find the libraries that correspond to the LLVM components
+# that we wish to use
+llvm_map_components_to_libnames(llvm_libs
+ ${LLVM_TARGETS_TO_BUILD}
+)
+
+# Link against LLVM libraries
+target_link_libraries(objwriter
+${llvm_libs})
diff --git a/src/Native/ObjWriter/cfi.h b/src/Native/ObjWriter/cfi.h
new file mode 100644
index 000000000..fc359acd3
--- /dev/null
+++ b/src/Native/ObjWriter/cfi.h
@@ -0,0 +1,37 @@
+// 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.
+
+//
+// Keep in sync with https://github.com/dotnet/coreclr/blob/master/src/inc/cfi.h
+//
+
+#ifndef CFI_H_
+#define CFI_H_
+
+#define DWARF_REG_ILLEGAL -1
+enum CFI_OPCODE
+{
+ CFI_ADJUST_CFA_OFFSET, // Offset is adjusted relative to the current one.
+ CFI_DEF_CFA_REGISTER, // New register is used to compute CFA
+ CFI_REL_OFFSET // Register is saved at offset from the current CFA
+};
+
+struct CFI_CODE
+{
+ unsigned char CodeOffset;// Offset from the start of code the frame covers.
+ unsigned char CfiOpCode;
+ short DwarfReg; // Dwarf register number. 0~32 for x64.
+ int Offset;
+ CFI_CODE(unsigned char codeOffset, unsigned char cfiOpcode,
+ short dwarfReg, int offset)
+ : CodeOffset(codeOffset)
+ , CfiOpCode(cfiOpcode)
+ , DwarfReg(dwarfReg)
+ , Offset(offset)
+ {}
+};
+typedef CFI_CODE* PCFI_CODE;
+
+#endif // CFI_H
+
diff --git a/src/Native/ObjWriter/cordebuginfo.h b/src/Native/ObjWriter/cordebuginfo.h
new file mode 100644
index 000000000..1ed430a11
--- /dev/null
+++ b/src/Native/ObjWriter/cordebuginfo.h
@@ -0,0 +1,327 @@
+// 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.
+
+//
+// Keep in sync with https://github.com/dotnet/coreclr/blob/master/src/inc/cordebuginfo.h
+//
+
+/**********************************************************************************/
+// DebugInfo types shared by JIT-EE interface and EE-Debugger interface
+
+class ICorDebugInfo
+{
+public:
+ /*----------------------------- Boundary-info ---------------------------*/
+
+ enum MappingTypes
+ {
+ NO_MAPPING = -1,
+ PROLOG = -2,
+ EPILOG = -3,
+ MAX_MAPPING_VALUE = -3 // Sentinal value. This should be set to the largest magnitude value in the enum
+ // so that the compression routines know the enum's range.
+ };
+
+ enum BoundaryTypes
+ {
+ NO_BOUNDARIES = 0x00, // No implicit boundaries
+ STACK_EMPTY_BOUNDARIES = 0x01, // Boundary whenever the IL evaluation stack is empty
+ NOP_BOUNDARIES = 0x02, // Before every CEE_NOP instruction
+ CALL_SITE_BOUNDARIES = 0x04, // Before every CEE_CALL, CEE_CALLVIRT, etc instruction
+
+ // Set of boundaries that debugger should always reasonably ask the JIT for.
+ DEFAULT_BOUNDARIES = STACK_EMPTY_BOUNDARIES | NOP_BOUNDARIES | CALL_SITE_BOUNDARIES
+ };
+
+ // Note that SourceTypes can be OR'd together - it's possible that
+ // a sequence point will also be a stack_empty point, and/or a call site.
+ // The debugger will check to see if a boundary offset's source field &
+ // SEQUENCE_POINT is true to determine if the boundary is a sequence point.
+
+ enum SourceTypes
+ {
+ SOURCE_TYPE_INVALID = 0x00, // To indicate that nothing else applies
+ SEQUENCE_POINT = 0x01, // The debugger asked for it.
+ STACK_EMPTY = 0x02, // The stack is empty here
+ CALL_SITE = 0x04, // This is a call site.
+ NATIVE_END_OFFSET_UNKNOWN = 0x08, // Indicates a epilog endpoint
+ CALL_INSTRUCTION = 0x10 // The actual instruction of a call.
+
+ };
+
+ struct OffsetMapping
+ {
+ DWORD nativeOffset;
+ DWORD ilOffset;
+ SourceTypes source; // The debugger needs this so that
+ // we don't put Edit and Continue breakpoints where
+ // the stack isn't empty. We can put regular breakpoints
+ // there, though, so we need a way to discriminate
+ // between offsets.
+ };
+
+ /*------------------------------ Var-info -------------------------------*/
+
+ // Note: The debugger needs to target register numbers on platforms other than which the debugger itself
+ // is running. To this end it maintains its own values for REGNUM_SP and REGNUM_AMBIENT_SP across multiple
+ // platforms. So any change here that may effect these values should be reflected in the definitions
+ // contained in debug/inc/DbgIPCEvents.h.
+ enum RegNum
+ {
+#ifdef _TARGET_X86_
+ REGNUM_EAX,
+ REGNUM_ECX,
+ REGNUM_EDX,
+ REGNUM_EBX,
+ REGNUM_ESP,
+ REGNUM_EBP,
+ REGNUM_ESI,
+ REGNUM_EDI,
+#elif _TARGET_ARM_
+ REGNUM_R0,
+ REGNUM_R1,
+ REGNUM_R2,
+ REGNUM_R3,
+ REGNUM_R4,
+ REGNUM_R5,
+ REGNUM_R6,
+ REGNUM_R7,
+ REGNUM_R8,
+ REGNUM_R9,
+ REGNUM_R10,
+ REGNUM_R11,
+ REGNUM_R12,
+ REGNUM_SP,
+ REGNUM_LR,
+ REGNUM_PC,
+#elif _TARGET_ARM64_
+ REGNUM_X0,
+ REGNUM_X1,
+ REGNUM_X2,
+ REGNUM_X3,
+ REGNUM_X4,
+ REGNUM_X5,
+ REGNUM_X6,
+ REGNUM_X7,
+ REGNUM_X8,
+ REGNUM_X9,
+ REGNUM_X10,
+ REGNUM_X11,
+ REGNUM_X12,
+ REGNUM_X13,
+ REGNUM_X14,
+ REGNUM_X15,
+ REGNUM_X16,
+ REGNUM_X17,
+ REGNUM_X18,
+ REGNUM_X19,
+ REGNUM_X20,
+ REGNUM_X21,
+ REGNUM_X22,
+ REGNUM_X23,
+ REGNUM_X24,
+ REGNUM_X25,
+ REGNUM_X26,
+ REGNUM_X27,
+ REGNUM_X28,
+ REGNUM_FP,
+ REGNUM_LR,
+ REGNUM_SP,
+ REGNUM_PC,
+#elif _TARGET_AMD64_
+ REGNUM_RAX,
+ REGNUM_RCX,
+ REGNUM_RDX,
+ REGNUM_RBX,
+ REGNUM_RSP,
+ REGNUM_RBP,
+ REGNUM_RSI,
+ REGNUM_RDI,
+ REGNUM_R8,
+ REGNUM_R9,
+ REGNUM_R10,
+ REGNUM_R11,
+ REGNUM_R12,
+ REGNUM_R13,
+ REGNUM_R14,
+ REGNUM_R15,
+#else
+ PORTABILITY_WARNING("Register numbers not defined on this platform")
+#endif
+ REGNUM_COUNT,
+ REGNUM_AMBIENT_SP, // ambient SP support. Ambient SP is the original SP in the non-BP based frame.
+ // Ambient SP should not change even if there are push/pop operations in the method.
+
+#ifdef _TARGET_X86_
+ REGNUM_FP = REGNUM_EBP,
+ REGNUM_SP = REGNUM_ESP,
+#elif _TARGET_AMD64_
+ REGNUM_SP = REGNUM_RSP,
+#elif _TARGET_ARM_
+#ifdef REDHAWK
+ REGNUM_FP = REGNUM_R7,
+#else
+ REGNUM_FP = REGNUM_R11,
+#endif //REDHAWK
+#elif _TARGET_ARM64_
+ //Nothing to do here. FP is already alloted.
+#else
+ // RegNum values should be properly defined for this platform
+ REGNUM_FP = 0,
+ REGNUM_SP = 1,
+#endif
+
+ };
+
+ // VarLoc describes the location of a native variable. Note that currently, VLT_REG_BYREF and VLT_STK_BYREF
+ // are only used for value types on X64.
+
+ enum VarLocType
+ {
+ VLT_REG, // variable is in a register
+ VLT_REG_BYREF, // address of the variable is in a register
+ VLT_REG_FP, // variable is in an fp register
+ VLT_STK, // variable is on the stack (memory addressed relative to the frame-pointer)
+ VLT_STK_BYREF, // address of the variable is on the stack (memory addressed relative to the frame-pointer)
+ VLT_REG_REG, // variable lives in two registers
+ VLT_REG_STK, // variable lives partly in a register and partly on the stack
+ VLT_STK_REG, // reverse of VLT_REG_STK
+ VLT_STK2, // variable lives in two slots on the stack
+ VLT_FPSTK, // variable lives on the floating-point stack
+ VLT_FIXED_VA, // variable is a fixed argument in a varargs function (relative to VARARGS_HANDLE)
+
+ VLT_COUNT,
+ VLT_INVALID,
+ };
+
+ struct VarLoc
+ {
+ VarLocType vlType;
+
+ union
+ {
+ // VLT_REG/VLT_REG_FP -- Any pointer-sized enregistered value (TYP_INT, TYP_REF, etc)
+ // eg. EAX
+ // VLT_REG_BYREF -- the specified register contains the address of the variable
+ // eg. [EAX]
+
+ struct
+ {
+ RegNum vlrReg;
+ } vlReg;
+
+ // VLT_STK -- Any 32 bit value which is on the stack
+ // eg. [ESP+0x20], or [EBP-0x28]
+ // VLT_STK_BYREF -- the specified stack location contains the address of the variable
+ // eg. mov EAX, [ESP+0x20]; [EAX]
+
+ struct
+ {
+ RegNum vlsBaseReg;
+ signed vlsOffset;
+ } vlStk;
+
+ // VLT_REG_REG -- TYP_LONG with both DWords enregistred
+ // eg. RBM_EAXEDX
+
+ struct
+ {
+ RegNum vlrrReg1;
+ RegNum vlrrReg2;
+ } vlRegReg;
+
+ // VLT_REG_STK -- Partly enregistered TYP_LONG
+ // eg { LowerDWord=EAX UpperDWord=[ESP+0x8] }
+
+ struct
+ {
+ RegNum vlrsReg;
+ struct
+ {
+ RegNum vlrssBaseReg;
+ signed vlrssOffset;
+ } vlrsStk;
+ } vlRegStk;
+
+ // VLT_STK_REG -- Partly enregistered TYP_LONG
+ // eg { LowerDWord=[ESP+0x8] UpperDWord=EAX }
+
+ struct
+ {
+ struct
+ {
+ RegNum vlsrsBaseReg;
+ signed vlsrsOffset;
+ } vlsrStk;
+ RegNum vlsrReg;
+ } vlStkReg;
+
+ // VLT_STK2 -- Any 64 bit value which is on the stack,
+ // in 2 successsive DWords.
+ // eg 2 DWords at [ESP+0x10]
+
+ struct
+ {
+ RegNum vls2BaseReg;
+ signed vls2Offset;
+ } vlStk2;
+
+ // VLT_FPSTK -- enregisterd TYP_DOUBLE (on the FP stack)
+ // eg. ST(3). Actually it is ST("FPstkHeigth - vpFpStk")
+
+ struct
+ {
+ unsigned vlfReg;
+ } vlFPstk;
+
+ // VLT_FIXED_VA -- fixed argument of a varargs function.
+ // The argument location depends on the size of the variable
+ // arguments (...). Inspecting the VARARGS_HANDLE indicates the
+ // location of the first arg. This argument can then be accessed
+ // relative to the position of the first arg
+
+ struct
+ {
+ unsigned vlfvOffset;
+ } vlFixedVarArg;
+
+ // VLT_MEMORY
+
+ struct
+ {
+ void *rpValue; // pointer to the in-process
+ // location of the value.
+ } vlMemory;
+ };
+ };
+
+ // This is used to report implicit/hidden arguments
+
+ enum
+ {
+ VARARGS_HND_ILNUM = -1, // Value for the CORINFO_VARARGS_HANDLE varNumber
+ RETBUF_ILNUM = -2, // Pointer to the return-buffer
+ TYPECTXT_ILNUM = -3, // ParamTypeArg for CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG
+
+ UNKNOWN_ILNUM = -4, // Unknown variable
+
+ MAX_ILNUM = -4 // Sentinal value. This should be set to the largest magnitude value in th enum
+ // so that the compression routines know the enum's range.
+ };
+
+ struct ILVarInfo
+ {
+ DWORD startOffset;
+ DWORD endOffset;
+ DWORD varNumber;
+ };
+
+ struct NativeVarInfo
+ {
+ DWORD startOffset;
+ DWORD endOffset;
+ DWORD varNumber;
+ VarLoc loc;
+ };
+};
diff --git a/src/Native/ObjWriter/cvconst.h b/src/Native/ObjWriter/cvconst.h
new file mode 100644
index 000000000..5c4f2569e
--- /dev/null
+++ b/src/Native/ObjWriter/cvconst.h
@@ -0,0 +1,3716 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+// cvconst.h - codeview constant definitions
+//-----------------------------------------------------------------
+//
+// Copyright Microsoft Corporation. All Rights Reserved.
+//
+//---------------------------------------------------------------
+#ifndef _CVCONST_H_
+#define _CVCONST_H_
+
+// Enumeration for function call type
+
+typedef enum CV_call_e {
+ CV_CALL_NEAR_C = 0x00, // near right to left push, caller pops stack
+ CV_CALL_FAR_C = 0x01, // far right to left push, caller pops stack
+ CV_CALL_NEAR_PASCAL = 0x02, // near left to right push, callee pops stack
+ CV_CALL_FAR_PASCAL = 0x03, // far left to right push, callee pops stack
+ CV_CALL_NEAR_FAST =
+ 0x04, // near left to right push with regs, callee pops stack
+ CV_CALL_FAR_FAST =
+ 0x05, // far left to right push with regs, callee pops stack
+ CV_CALL_SKIPPED = 0x06, // skipped (unused) call index
+ CV_CALL_NEAR_STD = 0x07, // near standard call
+ CV_CALL_FAR_STD = 0x08, // far standard call
+ CV_CALL_NEAR_SYS = 0x09, // near sys call
+ CV_CALL_FAR_SYS = 0x0a, // far sys call
+ CV_CALL_THISCALL = 0x0b, // this call (this passed in register)
+ CV_CALL_MIPSCALL = 0x0c, // Mips call
+ CV_CALL_GENERIC = 0x0d, // Generic call sequence
+ CV_CALL_ALPHACALL = 0x0e, // Alpha call
+ CV_CALL_PPCCALL = 0x0f, // PPC call
+ CV_CALL_SHCALL = 0x10, // Hitachi SuperH call
+ CV_CALL_ARMCALL = 0x11, // ARM call
+ CV_CALL_AM33CALL = 0x12, // AM33 call
+ CV_CALL_TRICALL = 0x13, // TriCore Call
+ CV_CALL_SH5CALL = 0x14, // Hitachi SuperH-5 call
+ CV_CALL_M32RCALL = 0x15, // M32R Call
+ CV_CALL_CLRCALL = 0x16, // clr call
+ CV_CALL_INLINE =
+ 0x17, // Marker for routines always inlined and thus lacking a convention
+ CV_CALL_NEAR_VECTOR =
+ 0x18, // near left to right push with regs, callee pops stack
+ CV_CALL_RESERVED = 0x19 // first unused call enumeration
+
+ // Do NOT add any more machine specific conventions. This is to be used for
+ // calling conventions in the source only (e.g. __cdecl, __stdcall).
+} CV_call_e;
+
+// Values for the access protection of class attributes
+
+typedef enum CV_access_e {
+ CV_private = 1,
+ CV_protected = 2,
+ CV_public = 3
+} CV_access_e;
+
+typedef enum THUNK_ORDINAL {
+ THUNK_ORDINAL_NOTYPE, // standard thunk
+ THUNK_ORDINAL_ADJUSTOR, // "this" adjustor thunk
+ THUNK_ORDINAL_VCALL, // virtual call thunk
+ THUNK_ORDINAL_PCODE, // pcode thunk
+ THUNK_ORDINAL_LOAD, // thunk which loads the address to jump to
+ // via unknown means...
+
+ // trampoline thunk ordinals - only for use in Trampoline thunk symbols
+ THUNK_ORDINAL_TRAMP_INCREMENTAL,
+ THUNK_ORDINAL_TRAMP_BRANCHISLAND,
+
+} THUNK_ORDINAL;
+
+enum CV_SourceChksum_t {
+ CHKSUM_TYPE_NONE = 0, // indicates no checksum is available
+ CHKSUM_TYPE_MD5,
+ CHKSUM_TYPE_SHA1,
+ CHKSUM_TYPE_SHA_256,
+};
+
+//
+// DIA enums
+//
+
+enum SymTagEnum {
+ SymTagNull,
+ SymTagExe,
+ SymTagCompiland,
+ SymTagCompilandDetails,
+ SymTagCompilandEnv,
+ SymTagFunction,
+ SymTagBlock,
+ SymTagData,
+ SymTagAnnotation,
+ SymTagLabel,
+ SymTagPublicSymbol,
+ SymTagUDT,
+ SymTagEnum,
+ SymTagFunctionType,
+ SymTagPointerType,
+ SymTagArrayType,
+ SymTagBaseType,
+ SymTagTypedef,
+ SymTagBaseClass,
+ SymTagFriend,
+ SymTagFunctionArgType,
+ SymTagFuncDebugStart,
+ SymTagFuncDebugEnd,
+ SymTagUsingNamespace,
+ SymTagVTableShape,
+ SymTagVTable,
+ SymTagCustom,
+ SymTagThunk,
+ SymTagCustomType,
+ SymTagManagedType,
+ SymTagDimension,
+ SymTagCallSite,
+ SymTagInlineSite,
+ SymTagBaseInterface,
+ SymTagVectorType,
+ SymTagMatrixType,
+ SymTagHLSLType,
+ SymTagCaller,
+ SymTagCallee,
+ SymTagExport,
+ SymTagHeapAllocationSite,
+ SymTagCoffGroup,
+ SymTagMax
+};
+
+enum LocationType {
+ LocIsNull,
+ LocIsStatic,
+ LocIsTLS,
+ LocIsRegRel,
+ LocIsThisRel,
+ LocIsEnregistered,
+ LocIsBitField,
+ LocIsSlot,
+ LocIsIlRel,
+ LocInMetaData,
+ LocIsConstant,
+ LocTypeMax
+};
+
+enum DataKind {
+ DataIsUnknown,
+ DataIsLocal,
+ DataIsStaticLocal,
+ DataIsParam,
+ DataIsObjectPtr,
+ DataIsFileStatic,
+ DataIsGlobal,
+ DataIsMember,
+ DataIsStaticMember,
+ DataIsConstant
+};
+
+enum UdtKind { UdtStruct, UdtClass, UdtUnion, UdtInterface };
+
+enum BasicType {
+ btNoType = 0,
+ btVoid = 1,
+ btChar = 2,
+ btWChar = 3,
+ btInt = 6,
+ btUInt = 7,
+ btFloat = 8,
+ btBCD = 9,
+ btBool = 10,
+ btLong = 13,
+ btULong = 14,
+ btCurrency = 25,
+ btDate = 26,
+ btVariant = 27,
+ btComplex = 28,
+ btBit = 29,
+ btBSTR = 30,
+ btHresult = 31,
+ btChar16 = 32, // char16_t
+ btChar32 = 33, // char32_t
+};
+
+// enumeration for type modifier values
+
+typedef enum CV_modifier_e {
+ // 0x0000 - 0x01ff - Reserved.
+
+ CV_MOD_INVALID = 0x0000,
+
+ // Standard modifiers.
+
+ CV_MOD_CONST = 0x0001,
+ CV_MOD_VOLATILE = 0x0002,
+ CV_MOD_UNALIGNED = 0x0003,
+
+ // 0x0200 - 0x03ff - HLSL modifiers.
+
+ CV_MOD_HLSL_UNIFORM = 0x0200,
+ CV_MOD_HLSL_LINE = 0x0201,
+ CV_MOD_HLSL_TRIANGLE = 0x0202,
+ CV_MOD_HLSL_LINEADJ = 0x0203,
+ CV_MOD_HLSL_TRIANGLEADJ = 0x0204,
+ CV_MOD_HLSL_LINEAR = 0x0205,
+ CV_MOD_HLSL_CENTROID = 0x0206,
+ CV_MOD_HLSL_CONSTINTERP = 0x0207,
+ CV_MOD_HLSL_NOPERSPECTIVE = 0x0208,
+ CV_MOD_HLSL_SAMPLE = 0x0209,
+ CV_MOD_HLSL_CENTER = 0x020a,
+ CV_MOD_HLSL_SNORM = 0x020b,
+ CV_MOD_HLSL_UNORM = 0x020c,
+ CV_MOD_HLSL_PRECISE = 0x020d,
+ CV_MOD_HLSL_UAV_GLOBALLY_COHERENT = 0x020e,
+
+ // 0x0400 - 0xffff - Unused.
+
+} CV_modifier_e;
+
+// built-in type kinds
+
+typedef enum CV_builtin_e {
+
+ // 0x0000 - 0x01ff - Reserved.
+ CV_BI_INVALID = 0x0000,
+
+ // 0x0200 - 0x03ff - HLSL types.
+
+ CV_BI_HLSL_INTERFACE_POINTER = 0x0200,
+ CV_BI_HLSL_TEXTURE1D = 0x0201,
+ CV_BI_HLSL_TEXTURE1D_ARRAY = 0x0202,
+ CV_BI_HLSL_TEXTURE2D = 0x0203,
+ CV_BI_HLSL_TEXTURE2D_ARRAY = 0x0204,
+ CV_BI_HLSL_TEXTURE3D = 0x0205,
+ CV_BI_HLSL_TEXTURECUBE = 0x0206,
+ CV_BI_HLSL_TEXTURECUBE_ARRAY = 0x0207,
+ CV_BI_HLSL_TEXTURE2DMS = 0x0208,
+ CV_BI_HLSL_TEXTURE2DMS_ARRAY = 0x0209,
+ CV_BI_HLSL_SAMPLER = 0x020a,
+ CV_BI_HLSL_SAMPLERCOMPARISON = 0x020b,
+ CV_BI_HLSL_BUFFER = 0x020c,
+ CV_BI_HLSL_POINTSTREAM = 0x020d,
+ CV_BI_HLSL_LINESTREAM = 0x020e,
+ CV_BI_HLSL_TRIANGLESTREAM = 0x020f,
+ CV_BI_HLSL_INPUTPATCH = 0x0210,
+ CV_BI_HLSL_OUTPUTPATCH = 0x0211,
+ CV_BI_HLSL_RWTEXTURE1D = 0x0212,
+ CV_BI_HLSL_RWTEXTURE1D_ARRAY = 0x0213,
+ CV_BI_HLSL_RWTEXTURE2D = 0x0214,
+ CV_BI_HLSL_RWTEXTURE2D_ARRAY = 0x0215,
+ CV_BI_HLSL_RWTEXTURE3D = 0x0216,
+ CV_BI_HLSL_RWBUFFER = 0x0217,
+ CV_BI_HLSL_BYTEADDRESS_BUFFER = 0x0218,
+ CV_BI_HLSL_RWBYTEADDRESS_BUFFER = 0x0219,
+ CV_BI_HLSL_STRUCTURED_BUFFER = 0x021a,
+ CV_BI_HLSL_RWSTRUCTURED_BUFFER = 0x021b,
+ CV_BI_HLSL_APPEND_STRUCTURED_BUFFER = 0x021c,
+ CV_BI_HLSL_CONSUME_STRUCTURED_BUFFER = 0x021d,
+ CV_BI_HLSL_MIN8FLOAT = 0x021e,
+ CV_BI_HLSL_MIN10FLOAT = 0x021f,
+ CV_BI_HLSL_MIN16FLOAT = 0x0220,
+ CV_BI_HLSL_MIN12INT = 0x0221,
+ CV_BI_HLSL_MIN16INT = 0x0222,
+ CV_BI_HLSL_MIN16UINT = 0x0223,
+
+ // 0x0400 - 0xffff - Unused.
+
+} CV_builtin_e;
+
+// enum describing the compile flag source language
+
+typedef enum CV_CFL_LANG {
+ CV_CFL_C = 0x00,
+ CV_CFL_CXX = 0x01,
+ CV_CFL_FORTRAN = 0x02,
+ CV_CFL_MASM = 0x03,
+ CV_CFL_PASCAL = 0x04,
+ CV_CFL_BASIC = 0x05,
+ CV_CFL_COBOL = 0x06,
+ CV_CFL_LINK = 0x07,
+ CV_CFL_CVTRES = 0x08,
+ CV_CFL_CVTPGD = 0x09,
+ CV_CFL_CSHARP = 0x0A, // C#
+ CV_CFL_VB = 0x0B, // Visual Basic
+ CV_CFL_ILASM = 0x0C, // IL (as in CLR) ASM
+ CV_CFL_JAVA = 0x0D,
+ CV_CFL_JSCRIPT = 0x0E,
+ CV_CFL_MSIL = 0x0F, // Unknown MSIL (LTCG of .NETMODULE)
+ CV_CFL_HLSL = 0x10, // High Level Shader Language
+} CV_CFL_LANG;
+
+// enum describing target processor
+
+typedef enum CV_CPU_TYPE_e {
+ CV_CFL_8080 = 0x00,
+ CV_CFL_8086 = 0x01,
+ CV_CFL_80286 = 0x02,
+ CV_CFL_80386 = 0x03,
+ CV_CFL_80486 = 0x04,
+ CV_CFL_PENTIUM = 0x05,
+ CV_CFL_PENTIUMII = 0x06,
+ CV_CFL_PENTIUMPRO = CV_CFL_PENTIUMII,
+ CV_CFL_PENTIUMIII = 0x07,
+ CV_CFL_MIPS = 0x10,
+ CV_CFL_MIPSR4000 = CV_CFL_MIPS, // don't break current code
+ CV_CFL_MIPS16 = 0x11,
+ CV_CFL_MIPS32 = 0x12,
+ CV_CFL_MIPS64 = 0x13,
+ CV_CFL_MIPSI = 0x14,
+ CV_CFL_MIPSII = 0x15,
+ CV_CFL_MIPSIII = 0x16,
+ CV_CFL_MIPSIV = 0x17,
+ CV_CFL_MIPSV = 0x18,
+ CV_CFL_M68000 = 0x20,
+ CV_CFL_M68010 = 0x21,
+ CV_CFL_M68020 = 0x22,
+ CV_CFL_M68030 = 0x23,
+ CV_CFL_M68040 = 0x24,
+ CV_CFL_ALPHA = 0x30,
+ CV_CFL_ALPHA_21064 = 0x30,
+ CV_CFL_ALPHA_21164 = 0x31,
+ CV_CFL_ALPHA_21164A = 0x32,
+ CV_CFL_ALPHA_21264 = 0x33,
+ CV_CFL_ALPHA_21364 = 0x34,
+ CV_CFL_PPC601 = 0x40,
+ CV_CFL_PPC603 = 0x41,
+ CV_CFL_PPC604 = 0x42,
+ CV_CFL_PPC620 = 0x43,
+ CV_CFL_PPCFP = 0x44,
+ CV_CFL_PPCBE = 0x45,
+ CV_CFL_SH3 = 0x50,
+ CV_CFL_SH3E = 0x51,
+ CV_CFL_SH3DSP = 0x52,
+ CV_CFL_SH4 = 0x53,
+ CV_CFL_SHMEDIA = 0x54,
+ CV_CFL_ARM3 = 0x60,
+ CV_CFL_ARM4 = 0x61,
+ CV_CFL_ARM4T = 0x62,
+ CV_CFL_ARM5 = 0x63,
+ CV_CFL_ARM5T = 0x64,
+ CV_CFL_ARM6 = 0x65,
+ CV_CFL_ARM_XMAC = 0x66,
+ CV_CFL_ARM_WMMX = 0x67,
+ CV_CFL_ARM7 = 0x68,
+ CV_CFL_OMNI = 0x70,
+ CV_CFL_IA64 = 0x80,
+ CV_CFL_IA64_1 = 0x80,
+ CV_CFL_IA64_2 = 0x81,
+ CV_CFL_CEE = 0x90,
+ CV_CFL_AM33 = 0xA0,
+ CV_CFL_M32R = 0xB0,
+ CV_CFL_TRICORE = 0xC0,
+ CV_CFL_X64 = 0xD0,
+ CV_CFL_AMD64 = CV_CFL_X64,
+ CV_CFL_EBC = 0xE0,
+ CV_CFL_THUMB = 0xF0,
+ CV_CFL_ARMNT = 0xF4,
+ CV_CFL_ARM64 = 0xF6,
+ CV_CFL_D3D11_SHADER = 0x100,
+} CV_CPU_TYPE_e;
+
+typedef enum CV_HREG_e {
+ // Register subset shared by all processor types,
+ // must not overlap with any of the ranges below, hence the high values
+
+ CV_ALLREG_ERR = 30000,
+ CV_ALLREG_TEB = 30001,
+ CV_ALLREG_TIMER = 30002,
+ CV_ALLREG_EFAD1 = 30003,
+ CV_ALLREG_EFAD2 = 30004,
+ CV_ALLREG_EFAD3 = 30005,
+ CV_ALLREG_VFRAME = 30006,
+ CV_ALLREG_HANDLE = 30007,
+ CV_ALLREG_PARAMS = 30008,
+ CV_ALLREG_LOCALS = 30009,
+ CV_ALLREG_TID = 30010,
+ CV_ALLREG_ENV = 30011,
+ CV_ALLREG_CMDLN = 30012,
+
+ // Register set for the Intel 80x86 and ix86 processor series
+ // (plus PCODE registers)
+
+ CV_REG_NONE = 0,
+ CV_REG_AL = 1,
+ CV_REG_CL = 2,
+ CV_REG_DL = 3,
+ CV_REG_BL = 4,
+ CV_REG_AH = 5,
+ CV_REG_CH = 6,
+ CV_REG_DH = 7,
+ CV_REG_BH = 8,
+ CV_REG_AX = 9,
+ CV_REG_CX = 10,
+ CV_REG_DX = 11,
+ CV_REG_BX = 12,
+ CV_REG_SP = 13,
+ CV_REG_BP = 14,
+ CV_REG_SI = 15,
+ CV_REG_DI = 16,
+ CV_REG_EAX = 17,
+ CV_REG_ECX = 18,
+ CV_REG_EDX = 19,
+ CV_REG_EBX = 20,
+ CV_REG_ESP = 21,
+ CV_REG_EBP = 22,
+ CV_REG_ESI = 23,
+ CV_REG_EDI = 24,
+ CV_REG_ES = 25,
+ CV_REG_CS = 26,
+ CV_REG_SS = 27,
+ CV_REG_DS = 28,
+ CV_REG_FS = 29,
+ CV_REG_GS = 30,
+ CV_REG_IP = 31,
+ CV_REG_FLAGS = 32,
+ CV_REG_EIP = 33,
+ CV_REG_EFLAGS = 34,
+ CV_REG_TEMP = 40, // PCODE Temp
+ CV_REG_TEMPH = 41, // PCODE TempH
+ CV_REG_QUOTE = 42, // PCODE Quote
+ CV_REG_PCDR3 = 43, // PCODE reserved
+ CV_REG_PCDR4 = 44, // PCODE reserved
+ CV_REG_PCDR5 = 45, // PCODE reserved
+ CV_REG_PCDR6 = 46, // PCODE reserved
+ CV_REG_PCDR7 = 47, // PCODE reserved
+ CV_REG_CR0 = 80, // CR0 -- control registers
+ CV_REG_CR1 = 81,
+ CV_REG_CR2 = 82,
+ CV_REG_CR3 = 83,
+ CV_REG_CR4 = 84, // Pentium
+ CV_REG_DR0 = 90, // Debug register
+ CV_REG_DR1 = 91,
+ CV_REG_DR2 = 92,
+ CV_REG_DR3 = 93,
+ CV_REG_DR4 = 94,
+ CV_REG_DR5 = 95,
+ CV_REG_DR6 = 96,
+ CV_REG_DR7 = 97,
+ CV_REG_GDTR = 110,
+ CV_REG_GDTL = 111,
+ CV_REG_IDTR = 112,
+ CV_REG_IDTL = 113,
+ CV_REG_LDTR = 114,
+ CV_REG_TR = 115,
+
+ CV_REG_PSEUDO1 = 116,
+ CV_REG_PSEUDO2 = 117,
+ CV_REG_PSEUDO3 = 118,
+ CV_REG_PSEUDO4 = 119,
+ CV_REG_PSEUDO5 = 120,
+ CV_REG_PSEUDO6 = 121,
+ CV_REG_PSEUDO7 = 122,
+ CV_REG_PSEUDO8 = 123,
+ CV_REG_PSEUDO9 = 124,
+
+ CV_REG_ST0 = 128,
+ CV_REG_ST1 = 129,
+ CV_REG_ST2 = 130,
+ CV_REG_ST3 = 131,
+ CV_REG_ST4 = 132,
+ CV_REG_ST5 = 133,
+ CV_REG_ST6 = 134,
+ CV_REG_ST7 = 135,
+ CV_REG_CTRL = 136,
+ CV_REG_STAT = 137,
+ CV_REG_TAG = 138,
+ CV_REG_FPIP = 139,
+ CV_REG_FPCS = 140,
+ CV_REG_FPDO = 141,
+ CV_REG_FPDS = 142,
+ CV_REG_ISEM = 143,
+ CV_REG_FPEIP = 144,
+ CV_REG_FPEDO = 145,
+
+ CV_REG_MM0 = 146,
+ CV_REG_MM1 = 147,
+ CV_REG_MM2 = 148,
+ CV_REG_MM3 = 149,
+ CV_REG_MM4 = 150,
+ CV_REG_MM5 = 151,
+ CV_REG_MM6 = 152,
+ CV_REG_MM7 = 153,
+
+ CV_REG_XMM0 = 154, // KATMAI registers
+ CV_REG_XMM1 = 155,
+ CV_REG_XMM2 = 156,
+ CV_REG_XMM3 = 157,
+ CV_REG_XMM4 = 158,
+ CV_REG_XMM5 = 159,
+ CV_REG_XMM6 = 160,
+ CV_REG_XMM7 = 161,
+
+ CV_REG_XMM00 = 162, // KATMAI sub-registers
+ CV_REG_XMM01 = 163,
+ CV_REG_XMM02 = 164,
+ CV_REG_XMM03 = 165,
+ CV_REG_XMM10 = 166,
+ CV_REG_XMM11 = 167,
+ CV_REG_XMM12 = 168,
+ CV_REG_XMM13 = 169,
+ CV_REG_XMM20 = 170,
+ CV_REG_XMM21 = 171,
+ CV_REG_XMM22 = 172,
+ CV_REG_XMM23 = 173,
+ CV_REG_XMM30 = 174,
+ CV_REG_XMM31 = 175,
+ CV_REG_XMM32 = 176,
+ CV_REG_XMM33 = 177,
+ CV_REG_XMM40 = 178,
+ CV_REG_XMM41 = 179,
+ CV_REG_XMM42 = 180,
+ CV_REG_XMM43 = 181,
+ CV_REG_XMM50 = 182,
+ CV_REG_XMM51 = 183,
+ CV_REG_XMM52 = 184,
+ CV_REG_XMM53 = 185,
+ CV_REG_XMM60 = 186,
+ CV_REG_XMM61 = 187,
+ CV_REG_XMM62 = 188,
+ CV_REG_XMM63 = 189,
+ CV_REG_XMM70 = 190,
+ CV_REG_XMM71 = 191,
+ CV_REG_XMM72 = 192,
+ CV_REG_XMM73 = 193,
+
+ CV_REG_XMM0L = 194,
+ CV_REG_XMM1L = 195,
+ CV_REG_XMM2L = 196,
+ CV_REG_XMM3L = 197,
+ CV_REG_XMM4L = 198,
+ CV_REG_XMM5L = 199,
+ CV_REG_XMM6L = 200,
+ CV_REG_XMM7L = 201,
+
+ CV_REG_XMM0H = 202,
+ CV_REG_XMM1H = 203,
+ CV_REG_XMM2H = 204,
+ CV_REG_XMM3H = 205,
+ CV_REG_XMM4H = 206,
+ CV_REG_XMM5H = 207,
+ CV_REG_XMM6H = 208,
+ CV_REG_XMM7H = 209,
+
+ CV_REG_MXCSR = 211, // XMM status register
+
+ CV_REG_EDXEAX = 212, // EDX:EAX pair
+
+ CV_REG_EMM0L = 220, // XMM sub-registers (WNI integer)
+ CV_REG_EMM1L = 221,
+ CV_REG_EMM2L = 222,
+ CV_REG_EMM3L = 223,
+ CV_REG_EMM4L = 224,
+ CV_REG_EMM5L = 225,
+ CV_REG_EMM6L = 226,
+ CV_REG_EMM7L = 227,
+
+ CV_REG_EMM0H = 228,
+ CV_REG_EMM1H = 229,
+ CV_REG_EMM2H = 230,
+ CV_REG_EMM3H = 231,
+ CV_REG_EMM4H = 232,
+ CV_REG_EMM5H = 233,
+ CV_REG_EMM6H = 234,
+ CV_REG_EMM7H = 235,
+
+ // do not change the order of these regs, first one must be even too
+ CV_REG_MM00 = 236,
+ CV_REG_MM01 = 237,
+ CV_REG_MM10 = 238,
+ CV_REG_MM11 = 239,
+ CV_REG_MM20 = 240,
+ CV_REG_MM21 = 241,
+ CV_REG_MM30 = 242,
+ CV_REG_MM31 = 243,
+ CV_REG_MM40 = 244,
+ CV_REG_MM41 = 245,
+ CV_REG_MM50 = 246,
+ CV_REG_MM51 = 247,
+ CV_REG_MM60 = 248,
+ CV_REG_MM61 = 249,
+ CV_REG_MM70 = 250,
+ CV_REG_MM71 = 251,
+
+ CV_REG_YMM0 = 252, // AVX registers
+ CV_REG_YMM1 = 253,
+ CV_REG_YMM2 = 254,
+ CV_REG_YMM3 = 255,
+ CV_REG_YMM4 = 256,
+ CV_REG_YMM5 = 257,
+ CV_REG_YMM6 = 258,
+ CV_REG_YMM7 = 259,
+
+ CV_REG_YMM0H = 260,
+ CV_REG_YMM1H = 261,
+ CV_REG_YMM2H = 262,
+ CV_REG_YMM3H = 263,
+ CV_REG_YMM4H = 264,
+ CV_REG_YMM5H = 265,
+ CV_REG_YMM6H = 266,
+ CV_REG_YMM7H = 267,
+
+ CV_REG_YMM0I0 = 268, // AVX integer registers
+ CV_REG_YMM0I1 = 269,
+ CV_REG_YMM0I2 = 270,
+ CV_REG_YMM0I3 = 271,
+ CV_REG_YMM1I0 = 272,
+ CV_REG_YMM1I1 = 273,
+ CV_REG_YMM1I2 = 274,
+ CV_REG_YMM1I3 = 275,
+ CV_REG_YMM2I0 = 276,
+ CV_REG_YMM2I1 = 277,
+ CV_REG_YMM2I2 = 278,
+ CV_REG_YMM2I3 = 279,
+ CV_REG_YMM3I0 = 280,
+ CV_REG_YMM3I1 = 281,
+ CV_REG_YMM3I2 = 282,
+ CV_REG_YMM3I3 = 283,
+ CV_REG_YMM4I0 = 284,
+ CV_REG_YMM4I1 = 285,
+ CV_REG_YMM4I2 = 286,
+ CV_REG_YMM4I3 = 287,
+ CV_REG_YMM5I0 = 288,
+ CV_REG_YMM5I1 = 289,
+ CV_REG_YMM5I2 = 290,
+ CV_REG_YMM5I3 = 291,
+ CV_REG_YMM6I0 = 292,
+ CV_REG_YMM6I1 = 293,
+ CV_REG_YMM6I2 = 294,
+ CV_REG_YMM6I3 = 295,
+ CV_REG_YMM7I0 = 296,
+ CV_REG_YMM7I1 = 297,
+ CV_REG_YMM7I2 = 298,
+ CV_REG_YMM7I3 = 299,
+
+ CV_REG_YMM0F0 = 300, // AVX floating-point single precise registers
+ CV_REG_YMM0F1 = 301,
+ CV_REG_YMM0F2 = 302,
+ CV_REG_YMM0F3 = 303,
+ CV_REG_YMM0F4 = 304,
+ CV_REG_YMM0F5 = 305,
+ CV_REG_YMM0F6 = 306,
+ CV_REG_YMM0F7 = 307,
+ CV_REG_YMM1F0 = 308,
+ CV_REG_YMM1F1 = 309,
+ CV_REG_YMM1F2 = 310,
+ CV_REG_YMM1F3 = 311,
+ CV_REG_YMM1F4 = 312,
+ CV_REG_YMM1F5 = 313,
+ CV_REG_YMM1F6 = 314,
+ CV_REG_YMM1F7 = 315,
+ CV_REG_YMM2F0 = 316,
+ CV_REG_YMM2F1 = 317,
+ CV_REG_YMM2F2 = 318,
+ CV_REG_YMM2F3 = 319,
+ CV_REG_YMM2F4 = 320,
+ CV_REG_YMM2F5 = 321,
+ CV_REG_YMM2F6 = 322,
+ CV_REG_YMM2F7 = 323,
+ CV_REG_YMM3F0 = 324,
+ CV_REG_YMM3F1 = 325,
+ CV_REG_YMM3F2 = 326,
+ CV_REG_YMM3F3 = 327,
+ CV_REG_YMM3F4 = 328,
+ CV_REG_YMM3F5 = 329,
+ CV_REG_YMM3F6 = 330,
+ CV_REG_YMM3F7 = 331,
+ CV_REG_YMM4F0 = 332,
+ CV_REG_YMM4F1 = 333,
+ CV_REG_YMM4F2 = 334,
+ CV_REG_YMM4F3 = 335,
+ CV_REG_YMM4F4 = 336,
+ CV_REG_YMM4F5 = 337,
+ CV_REG_YMM4F6 = 338,
+ CV_REG_YMM4F7 = 339,
+ CV_REG_YMM5F0 = 340,
+ CV_REG_YMM5F1 = 341,
+ CV_REG_YMM5F2 = 342,
+ CV_REG_YMM5F3 = 343,
+ CV_REG_YMM5F4 = 344,
+ CV_REG_YMM5F5 = 345,
+ CV_REG_YMM5F6 = 346,
+ CV_REG_YMM5F7 = 347,
+ CV_REG_YMM6F0 = 348,
+ CV_REG_YMM6F1 = 349,
+ CV_REG_YMM6F2 = 350,
+ CV_REG_YMM6F3 = 351,
+ CV_REG_YMM6F4 = 352,
+ CV_REG_YMM6F5 = 353,
+ CV_REG_YMM6F6 = 354,
+ CV_REG_YMM6F7 = 355,
+ CV_REG_YMM7F0 = 356,
+ CV_REG_YMM7F1 = 357,
+ CV_REG_YMM7F2 = 358,
+ CV_REG_YMM7F3 = 359,
+ CV_REG_YMM7F4 = 360,
+ CV_REG_YMM7F5 = 361,
+ CV_REG_YMM7F6 = 362,
+ CV_REG_YMM7F7 = 363,
+
+ CV_REG_YMM0D0 = 364, // AVX floating-point double precise registers
+ CV_REG_YMM0D1 = 365,
+ CV_REG_YMM0D2 = 366,
+ CV_REG_YMM0D3 = 367,
+ CV_REG_YMM1D0 = 368,
+ CV_REG_YMM1D1 = 369,
+ CV_REG_YMM1D2 = 370,
+ CV_REG_YMM1D3 = 371,
+ CV_REG_YMM2D0 = 372,
+ CV_REG_YMM2D1 = 373,
+ CV_REG_YMM2D2 = 374,
+ CV_REG_YMM2D3 = 375,
+ CV_REG_YMM3D0 = 376,
+ CV_REG_YMM3D1 = 377,
+ CV_REG_YMM3D2 = 378,
+ CV_REG_YMM3D3 = 379,
+ CV_REG_YMM4D0 = 380,
+ CV_REG_YMM4D1 = 381,
+ CV_REG_YMM4D2 = 382,
+ CV_REG_YMM4D3 = 383,
+ CV_REG_YMM5D0 = 384,
+ CV_REG_YMM5D1 = 385,
+ CV_REG_YMM5D2 = 386,
+ CV_REG_YMM5D3 = 387,
+ CV_REG_YMM6D0 = 388,
+ CV_REG_YMM6D1 = 389,
+ CV_REG_YMM6D2 = 390,
+ CV_REG_YMM6D3 = 391,
+ CV_REG_YMM7D0 = 392,
+ CV_REG_YMM7D1 = 393,
+ CV_REG_YMM7D2 = 394,
+ CV_REG_YMM7D3 = 395,
+
+ CV_REG_BND0 = 396,
+ CV_REG_BND1 = 397,
+ CV_REG_BND2 = 398,
+ CV_REG_BND3 = 399,
+
+ // registers for the 68K processors
+
+ CV_R68_D0 = 0,
+ CV_R68_D1 = 1,
+ CV_R68_D2 = 2,
+ CV_R68_D3 = 3,
+ CV_R68_D4 = 4,
+ CV_R68_D5 = 5,
+ CV_R68_D6 = 6,
+ CV_R68_D7 = 7,
+ CV_R68_A0 = 8,
+ CV_R68_A1 = 9,
+ CV_R68_A2 = 10,
+ CV_R68_A3 = 11,
+ CV_R68_A4 = 12,
+ CV_R68_A5 = 13,
+ CV_R68_A6 = 14,
+ CV_R68_A7 = 15,
+ CV_R68_CCR = 16,
+ CV_R68_SR = 17,
+ CV_R68_USP = 18,
+ CV_R68_MSP = 19,
+ CV_R68_SFC = 20,
+ CV_R68_DFC = 21,
+ CV_R68_CACR = 22,
+ CV_R68_VBR = 23,
+ CV_R68_CAAR = 24,
+ CV_R68_ISP = 25,
+ CV_R68_PC = 26,
+ // reserved 27
+ CV_R68_FPCR = 28,
+ CV_R68_FPSR = 29,
+ CV_R68_FPIAR = 30,
+ // reserved 31
+ CV_R68_FP0 = 32,
+ CV_R68_FP1 = 33,
+ CV_R68_FP2 = 34,
+ CV_R68_FP3 = 35,
+ CV_R68_FP4 = 36,
+ CV_R68_FP5 = 37,
+ CV_R68_FP6 = 38,
+ CV_R68_FP7 = 39,
+ // reserved 40
+ CV_R68_MMUSR030 = 41,
+ CV_R68_MMUSR = 42,
+ CV_R68_URP = 43,
+ CV_R68_DTT0 = 44,
+ CV_R68_DTT1 = 45,
+ CV_R68_ITT0 = 46,
+ CV_R68_ITT1 = 47,
+ // reserved 50
+ CV_R68_PSR = 51,
+ CV_R68_PCSR = 52,
+ CV_R68_VAL = 53,
+ CV_R68_CRP = 54,
+ CV_R68_SRP = 55,
+ CV_R68_DRP = 56,
+ CV_R68_TC = 57,
+ CV_R68_AC = 58,
+ CV_R68_SCC = 59,
+ CV_R68_CAL = 60,
+ CV_R68_TT0 = 61,
+ CV_R68_TT1 = 62,
+ // reserved 63
+ CV_R68_BAD0 = 64,
+ CV_R68_BAD1 = 65,
+ CV_R68_BAD2 = 66,
+ CV_R68_BAD3 = 67,
+ CV_R68_BAD4 = 68,
+ CV_R68_BAD5 = 69,
+ CV_R68_BAD6 = 70,
+ CV_R68_BAD7 = 71,
+ CV_R68_BAC0 = 72,
+ CV_R68_BAC1 = 73,
+ CV_R68_BAC2 = 74,
+ CV_R68_BAC3 = 75,
+ CV_R68_BAC4 = 76,
+ CV_R68_BAC5 = 77,
+ CV_R68_BAC6 = 78,
+ CV_R68_BAC7 = 79,
+
+ // Register set for the MIPS 4000
+
+ CV_M4_NOREG = CV_REG_NONE,
+
+ CV_M4_IntZERO = 10, /* CPU REGISTER */
+ CV_M4_IntAT = 11,
+ CV_M4_IntV0 = 12,
+ CV_M4_IntV1 = 13,
+ CV_M4_IntA0 = 14,
+ CV_M4_IntA1 = 15,
+ CV_M4_IntA2 = 16,
+ CV_M4_IntA3 = 17,
+ CV_M4_IntT0 = 18,
+ CV_M4_IntT1 = 19,
+ CV_M4_IntT2 = 20,
+ CV_M4_IntT3 = 21,
+ CV_M4_IntT4 = 22,
+ CV_M4_IntT5 = 23,
+ CV_M4_IntT6 = 24,
+ CV_M4_IntT7 = 25,
+ CV_M4_IntS0 = 26,
+ CV_M4_IntS1 = 27,
+ CV_M4_IntS2 = 28,
+ CV_M4_IntS3 = 29,
+ CV_M4_IntS4 = 30,
+ CV_M4_IntS5 = 31,
+ CV_M4_IntS6 = 32,
+ CV_M4_IntS7 = 33,
+ CV_M4_IntT8 = 34,
+ CV_M4_IntT9 = 35,
+ CV_M4_IntKT0 = 36,
+ CV_M4_IntKT1 = 37,
+ CV_M4_IntGP = 38,
+ CV_M4_IntSP = 39,
+ CV_M4_IntS8 = 40,
+ CV_M4_IntRA = 41,
+ CV_M4_IntLO = 42,
+ CV_M4_IntHI = 43,
+
+ CV_M4_Fir = 50,
+ CV_M4_Psr = 51,
+
+ CV_M4_FltF0 = 60, /* Floating point registers */
+ CV_M4_FltF1 = 61,
+ CV_M4_FltF2 = 62,
+ CV_M4_FltF3 = 63,
+ CV_M4_FltF4 = 64,
+ CV_M4_FltF5 = 65,
+ CV_M4_FltF6 = 66,
+ CV_M4_FltF7 = 67,
+ CV_M4_FltF8 = 68,
+ CV_M4_FltF9 = 69,
+ CV_M4_FltF10 = 70,
+ CV_M4_FltF11 = 71,
+ CV_M4_FltF12 = 72,
+ CV_M4_FltF13 = 73,
+ CV_M4_FltF14 = 74,
+ CV_M4_FltF15 = 75,
+ CV_M4_FltF16 = 76,
+ CV_M4_FltF17 = 77,
+ CV_M4_FltF18 = 78,
+ CV_M4_FltF19 = 79,
+ CV_M4_FltF20 = 80,
+ CV_M4_FltF21 = 81,
+ CV_M4_FltF22 = 82,
+ CV_M4_FltF23 = 83,
+ CV_M4_FltF24 = 84,
+ CV_M4_FltF25 = 85,
+ CV_M4_FltF26 = 86,
+ CV_M4_FltF27 = 87,
+ CV_M4_FltF28 = 88,
+ CV_M4_FltF29 = 89,
+ CV_M4_FltF30 = 90,
+ CV_M4_FltF31 = 91,
+ CV_M4_FltFsr = 92,
+
+ // Register set for the ALPHA AXP
+
+ CV_ALPHA_NOREG = CV_REG_NONE,
+
+ CV_ALPHA_FltF0 = 10, // Floating point registers
+ CV_ALPHA_FltF1 = 11,
+ CV_ALPHA_FltF2 = 12,
+ CV_ALPHA_FltF3 = 13,
+ CV_ALPHA_FltF4 = 14,
+ CV_ALPHA_FltF5 = 15,
+ CV_ALPHA_FltF6 = 16,
+ CV_ALPHA_FltF7 = 17,
+ CV_ALPHA_FltF8 = 18,
+ CV_ALPHA_FltF9 = 19,
+ CV_ALPHA_FltF10 = 20,
+ CV_ALPHA_FltF11 = 21,
+ CV_ALPHA_FltF12 = 22,
+ CV_ALPHA_FltF13 = 23,
+ CV_ALPHA_FltF14 = 24,
+ CV_ALPHA_FltF15 = 25,
+ CV_ALPHA_FltF16 = 26,
+ CV_ALPHA_FltF17 = 27,
+ CV_ALPHA_FltF18 = 28,
+ CV_ALPHA_FltF19 = 29,
+ CV_ALPHA_FltF20 = 30,
+ CV_ALPHA_FltF21 = 31,
+ CV_ALPHA_FltF22 = 32,
+ CV_ALPHA_FltF23 = 33,
+ CV_ALPHA_FltF24 = 34,
+ CV_ALPHA_FltF25 = 35,
+ CV_ALPHA_FltF26 = 36,
+ CV_ALPHA_FltF27 = 37,
+ CV_ALPHA_FltF28 = 38,
+ CV_ALPHA_FltF29 = 39,
+ CV_ALPHA_FltF30 = 40,
+ CV_ALPHA_FltF31 = 41,
+
+ CV_ALPHA_IntV0 = 42, // Integer registers
+ CV_ALPHA_IntT0 = 43,
+ CV_ALPHA_IntT1 = 44,
+ CV_ALPHA_IntT2 = 45,
+ CV_ALPHA_IntT3 = 46,
+ CV_ALPHA_IntT4 = 47,
+ CV_ALPHA_IntT5 = 48,
+ CV_ALPHA_IntT6 = 49,
+ CV_ALPHA_IntT7 = 50,
+ CV_ALPHA_IntS0 = 51,
+ CV_ALPHA_IntS1 = 52,
+ CV_ALPHA_IntS2 = 53,
+ CV_ALPHA_IntS3 = 54,
+ CV_ALPHA_IntS4 = 55,
+ CV_ALPHA_IntS5 = 56,
+ CV_ALPHA_IntFP = 57,
+ CV_ALPHA_IntA0 = 58,
+ CV_ALPHA_IntA1 = 59,
+ CV_ALPHA_IntA2 = 60,
+ CV_ALPHA_IntA3 = 61,
+ CV_ALPHA_IntA4 = 62,
+ CV_ALPHA_IntA5 = 63,
+ CV_ALPHA_IntT8 = 64,
+ CV_ALPHA_IntT9 = 65,
+ CV_ALPHA_IntT10 = 66,
+ CV_ALPHA_IntT11 = 67,
+ CV_ALPHA_IntRA = 68,
+ CV_ALPHA_IntT12 = 69,
+ CV_ALPHA_IntAT = 70,
+ CV_ALPHA_IntGP = 71,
+ CV_ALPHA_IntSP = 72,
+ CV_ALPHA_IntZERO = 73,
+
+ CV_ALPHA_Fpcr = 74, // Control registers
+ CV_ALPHA_Fir = 75,
+ CV_ALPHA_Psr = 76,
+ CV_ALPHA_FltFsr = 77,
+ CV_ALPHA_SoftFpcr = 78,
+
+ // Register Set for Motorola/IBM PowerPC
+
+ /*
+ ** PowerPC General Registers ( User Level )
+ */
+ CV_PPC_GPR0 = 1,
+ CV_PPC_GPR1 = 2,
+ CV_PPC_GPR2 = 3,
+ CV_PPC_GPR3 = 4,
+ CV_PPC_GPR4 = 5,
+ CV_PPC_GPR5 = 6,
+ CV_PPC_GPR6 = 7,
+ CV_PPC_GPR7 = 8,
+ CV_PPC_GPR8 = 9,
+ CV_PPC_GPR9 = 10,
+ CV_PPC_GPR10 = 11,
+ CV_PPC_GPR11 = 12,
+ CV_PPC_GPR12 = 13,
+ CV_PPC_GPR13 = 14,
+ CV_PPC_GPR14 = 15,
+ CV_PPC_GPR15 = 16,
+ CV_PPC_GPR16 = 17,
+ CV_PPC_GPR17 = 18,
+ CV_PPC_GPR18 = 19,
+ CV_PPC_GPR19 = 20,
+ CV_PPC_GPR20 = 21,
+ CV_PPC_GPR21 = 22,
+ CV_PPC_GPR22 = 23,
+ CV_PPC_GPR23 = 24,
+ CV_PPC_GPR24 = 25,
+ CV_PPC_GPR25 = 26,
+ CV_PPC_GPR26 = 27,
+ CV_PPC_GPR27 = 28,
+ CV_PPC_GPR28 = 29,
+ CV_PPC_GPR29 = 30,
+ CV_PPC_GPR30 = 31,
+ CV_PPC_GPR31 = 32,
+
+ /*
+ ** PowerPC Condition Register ( User Level )
+ */
+ CV_PPC_CR = 33,
+ CV_PPC_CR0 = 34,
+ CV_PPC_CR1 = 35,
+ CV_PPC_CR2 = 36,
+ CV_PPC_CR3 = 37,
+ CV_PPC_CR4 = 38,
+ CV_PPC_CR5 = 39,
+ CV_PPC_CR6 = 40,
+ CV_PPC_CR7 = 41,
+
+ /*
+ ** PowerPC Floating Point Registers ( User Level )
+ */
+ CV_PPC_FPR0 = 42,
+ CV_PPC_FPR1 = 43,
+ CV_PPC_FPR2 = 44,
+ CV_PPC_FPR3 = 45,
+ CV_PPC_FPR4 = 46,
+ CV_PPC_FPR5 = 47,
+ CV_PPC_FPR6 = 48,
+ CV_PPC_FPR7 = 49,
+ CV_PPC_FPR8 = 50,
+ CV_PPC_FPR9 = 51,
+ CV_PPC_FPR10 = 52,
+ CV_PPC_FPR11 = 53,
+ CV_PPC_FPR12 = 54,
+ CV_PPC_FPR13 = 55,
+ CV_PPC_FPR14 = 56,
+ CV_PPC_FPR15 = 57,
+ CV_PPC_FPR16 = 58,
+ CV_PPC_FPR17 = 59,
+ CV_PPC_FPR18 = 60,
+ CV_PPC_FPR19 = 61,
+ CV_PPC_FPR20 = 62,
+ CV_PPC_FPR21 = 63,
+ CV_PPC_FPR22 = 64,
+ CV_PPC_FPR23 = 65,
+ CV_PPC_FPR24 = 66,
+ CV_PPC_FPR25 = 67,
+ CV_PPC_FPR26 = 68,
+ CV_PPC_FPR27 = 69,
+ CV_PPC_FPR28 = 70,
+ CV_PPC_FPR29 = 71,
+ CV_PPC_FPR30 = 72,
+ CV_PPC_FPR31 = 73,
+
+ /*
+ ** PowerPC Floating Point Status and Control Register ( User Level )
+ */
+ CV_PPC_FPSCR = 74,
+
+ /*
+ ** PowerPC Machine State Register ( Supervisor Level )
+ */
+ CV_PPC_MSR = 75,
+
+ /*
+ ** PowerPC Segment Registers ( Supervisor Level )
+ */
+ CV_PPC_SR0 = 76,
+ CV_PPC_SR1 = 77,
+ CV_PPC_SR2 = 78,
+ CV_PPC_SR3 = 79,
+ CV_PPC_SR4 = 80,
+ CV_PPC_SR5 = 81,
+ CV_PPC_SR6 = 82,
+ CV_PPC_SR7 = 83,
+ CV_PPC_SR8 = 84,
+ CV_PPC_SR9 = 85,
+ CV_PPC_SR10 = 86,
+ CV_PPC_SR11 = 87,
+ CV_PPC_SR12 = 88,
+ CV_PPC_SR13 = 89,
+ CV_PPC_SR14 = 90,
+ CV_PPC_SR15 = 91,
+
+ /*
+ ** For all of the special purpose registers add 100 to the SPR# that the
+ ** Motorola/IBM documentation gives with the exception of any imaginary
+ ** registers.
+ */
+
+ /*
+ ** PowerPC Special Purpose Registers ( User Level )
+ */
+ CV_PPC_PC = 99, // PC (imaginary register)
+
+ CV_PPC_MQ = 100, // MPC601
+ CV_PPC_XER = 101,
+ CV_PPC_RTCU = 104, // MPC601
+ CV_PPC_RTCL = 105, // MPC601
+ CV_PPC_LR = 108,
+ CV_PPC_CTR = 109,
+
+ CV_PPC_COMPARE = 110, // part of XER (internal to the debugger only)
+ CV_PPC_COUNT = 111, // part of XER (internal to the debugger only)
+
+ /*
+ ** PowerPC Special Purpose Registers ( Supervisor Level )
+ */
+ CV_PPC_DSISR = 118,
+ CV_PPC_DAR = 119,
+ CV_PPC_DEC = 122,
+ CV_PPC_SDR1 = 125,
+ CV_PPC_SRR0 = 126,
+ CV_PPC_SRR1 = 127,
+ CV_PPC_SPRG0 = 372,
+ CV_PPC_SPRG1 = 373,
+ CV_PPC_SPRG2 = 374,
+ CV_PPC_SPRG3 = 375,
+ CV_PPC_ASR = 280, // 64-bit implementations only
+ CV_PPC_EAR = 382,
+ CV_PPC_PVR = 287,
+ CV_PPC_BAT0U = 628,
+ CV_PPC_BAT0L = 629,
+ CV_PPC_BAT1U = 630,
+ CV_PPC_BAT1L = 631,
+ CV_PPC_BAT2U = 632,
+ CV_PPC_BAT2L = 633,
+ CV_PPC_BAT3U = 634,
+ CV_PPC_BAT3L = 635,
+ CV_PPC_DBAT0U = 636,
+ CV_PPC_DBAT0L = 637,
+ CV_PPC_DBAT1U = 638,
+ CV_PPC_DBAT1L = 639,
+ CV_PPC_DBAT2U = 640,
+ CV_PPC_DBAT2L = 641,
+ CV_PPC_DBAT3U = 642,
+ CV_PPC_DBAT3L = 643,
+
+ /*
+ ** PowerPC Special Purpose Registers Implementation Dependent ( Supervisor
+ *Level )
+ */
+
+ /*
+ ** Doesn't appear that IBM/Motorola has finished defining these.
+ */
+
+ CV_PPC_PMR0 = 1044, // MPC620,
+ CV_PPC_PMR1 = 1045, // MPC620,
+ CV_PPC_PMR2 = 1046, // MPC620,
+ CV_PPC_PMR3 = 1047, // MPC620,
+ CV_PPC_PMR4 = 1048, // MPC620,
+ CV_PPC_PMR5 = 1049, // MPC620,
+ CV_PPC_PMR6 = 1050, // MPC620,
+ CV_PPC_PMR7 = 1051, // MPC620,
+ CV_PPC_PMR8 = 1052, // MPC620,
+ CV_PPC_PMR9 = 1053, // MPC620,
+ CV_PPC_PMR10 = 1054, // MPC620,
+ CV_PPC_PMR11 = 1055, // MPC620,
+ CV_PPC_PMR12 = 1056, // MPC620,
+ CV_PPC_PMR13 = 1057, // MPC620,
+ CV_PPC_PMR14 = 1058, // MPC620,
+ CV_PPC_PMR15 = 1059, // MPC620,
+
+ CV_PPC_DMISS = 1076, // MPC603
+ CV_PPC_DCMP = 1077, // MPC603
+ CV_PPC_HASH1 = 1078, // MPC603
+ CV_PPC_HASH2 = 1079, // MPC603
+ CV_PPC_IMISS = 1080, // MPC603
+ CV_PPC_ICMP = 1081, // MPC603
+ CV_PPC_RPA = 1082, // MPC603
+
+ CV_PPC_HID0 = 1108, // MPC601, MPC603, MPC620
+ CV_PPC_HID1 = 1109, // MPC601
+ CV_PPC_HID2 = 1110, // MPC601, MPC603, MPC620 ( IABR )
+ CV_PPC_HID3 = 1111, // Not Defined
+ CV_PPC_HID4 = 1112, // Not Defined
+ CV_PPC_HID5 = 1113, // MPC601, MPC604, MPC620 ( DABR )
+ CV_PPC_HID6 = 1114, // Not Defined
+ CV_PPC_HID7 = 1115, // Not Defined
+ CV_PPC_HID8 = 1116, // MPC620 ( BUSCSR )
+ CV_PPC_HID9 = 1117, // MPC620 ( L2CSR )
+ CV_PPC_HID10 = 1118, // Not Defined
+ CV_PPC_HID11 = 1119, // Not Defined
+ CV_PPC_HID12 = 1120, // Not Defined
+ CV_PPC_HID13 = 1121, // MPC604 ( HCR )
+ CV_PPC_HID14 = 1122, // Not Defined
+ CV_PPC_HID15 = 1123, // MPC601, MPC604, MPC620 ( PIR )
+
+ //
+ // JAVA VM registers
+ //
+
+ CV_JAVA_PC = 1,
+
+ //
+ // Register set for the Hitachi SH3
+ //
+
+ CV_SH3_NOREG = CV_REG_NONE,
+
+ CV_SH3_IntR0 = 10, // CPU REGISTER
+ CV_SH3_IntR1 = 11,
+ CV_SH3_IntR2 = 12,
+ CV_SH3_IntR3 = 13,
+ CV_SH3_IntR4 = 14,
+ CV_SH3_IntR5 = 15,
+ CV_SH3_IntR6 = 16,
+ CV_SH3_IntR7 = 17,
+ CV_SH3_IntR8 = 18,
+ CV_SH3_IntR9 = 19,
+ CV_SH3_IntR10 = 20,
+ CV_SH3_IntR11 = 21,
+ CV_SH3_IntR12 = 22,
+ CV_SH3_IntR13 = 23,
+ CV_SH3_IntFp = 24,
+ CV_SH3_IntSp = 25,
+ CV_SH3_Gbr = 38,
+ CV_SH3_Pr = 39,
+ CV_SH3_Mach = 40,
+ CV_SH3_Macl = 41,
+
+ CV_SH3_Pc = 50,
+ CV_SH3_Sr = 51,
+
+ CV_SH3_BarA = 60,
+ CV_SH3_BasrA = 61,
+ CV_SH3_BamrA = 62,
+ CV_SH3_BbrA = 63,
+ CV_SH3_BarB = 64,
+ CV_SH3_BasrB = 65,
+ CV_SH3_BamrB = 66,
+ CV_SH3_BbrB = 67,
+ CV_SH3_BdrB = 68,
+ CV_SH3_BdmrB = 69,
+ CV_SH3_Brcr = 70,
+
+ //
+ // Additional registers for Hitachi SH processors
+ //
+
+ CV_SH_Fpscr = 75, // floating point status/control register
+ CV_SH_Fpul = 76, // floating point communication register
+
+ CV_SH_FpR0 = 80, // Floating point registers
+ CV_SH_FpR1 = 81,
+ CV_SH_FpR2 = 82,
+ CV_SH_FpR3 = 83,
+ CV_SH_FpR4 = 84,
+ CV_SH_FpR5 = 85,
+ CV_SH_FpR6 = 86,
+ CV_SH_FpR7 = 87,
+ CV_SH_FpR8 = 88,
+ CV_SH_FpR9 = 89,
+ CV_SH_FpR10 = 90,
+ CV_SH_FpR11 = 91,
+ CV_SH_FpR12 = 92,
+ CV_SH_FpR13 = 93,
+ CV_SH_FpR14 = 94,
+ CV_SH_FpR15 = 95,
+
+ CV_SH_XFpR0 = 96,
+ CV_SH_XFpR1 = 97,
+ CV_SH_XFpR2 = 98,
+ CV_SH_XFpR3 = 99,
+ CV_SH_XFpR4 = 100,
+ CV_SH_XFpR5 = 101,
+ CV_SH_XFpR6 = 102,
+ CV_SH_XFpR7 = 103,
+ CV_SH_XFpR8 = 104,
+ CV_SH_XFpR9 = 105,
+ CV_SH_XFpR10 = 106,
+ CV_SH_XFpR11 = 107,
+ CV_SH_XFpR12 = 108,
+ CV_SH_XFpR13 = 109,
+ CV_SH_XFpR14 = 110,
+ CV_SH_XFpR15 = 111,
+
+ //
+ // Register set for the ARM processor.
+ //
+
+ CV_ARM_NOREG = CV_REG_NONE,
+
+ CV_ARM_R0 = 10,
+ CV_ARM_R1 = 11,
+ CV_ARM_R2 = 12,
+ CV_ARM_R3 = 13,
+ CV_ARM_R4 = 14,
+ CV_ARM_R5 = 15,
+ CV_ARM_R6 = 16,
+ CV_ARM_R7 = 17,
+ CV_ARM_R8 = 18,
+ CV_ARM_R9 = 19,
+ CV_ARM_R10 = 20,
+ CV_ARM_R11 = 21, // Frame pointer, if allocated
+ CV_ARM_R12 = 22,
+ CV_ARM_SP = 23, // Stack pointer
+ CV_ARM_LR = 24, // Link Register
+ CV_ARM_PC = 25, // Program counter
+ CV_ARM_CPSR = 26, // Current program status register
+
+ CV_ARM_ACC0 = 27, // DSP co-processor 0 40 bit accumulator
+
+ //
+ // Registers for ARM VFP10 support
+ //
+
+ CV_ARM_FPSCR = 40,
+ CV_ARM_FPEXC = 41,
+
+ CV_ARM_FS0 = 50,
+ CV_ARM_FS1 = 51,
+ CV_ARM_FS2 = 52,
+ CV_ARM_FS3 = 53,
+ CV_ARM_FS4 = 54,
+ CV_ARM_FS5 = 55,
+ CV_ARM_FS6 = 56,
+ CV_ARM_FS7 = 57,
+ CV_ARM_FS8 = 58,
+ CV_ARM_FS9 = 59,
+ CV_ARM_FS10 = 60,
+ CV_ARM_FS11 = 61,
+ CV_ARM_FS12 = 62,
+ CV_ARM_FS13 = 63,
+ CV_ARM_FS14 = 64,
+ CV_ARM_FS15 = 65,
+ CV_ARM_FS16 = 66,
+ CV_ARM_FS17 = 67,
+ CV_ARM_FS18 = 68,
+ CV_ARM_FS19 = 69,
+ CV_ARM_FS20 = 70,
+ CV_ARM_FS21 = 71,
+ CV_ARM_FS22 = 72,
+ CV_ARM_FS23 = 73,
+ CV_ARM_FS24 = 74,
+ CV_ARM_FS25 = 75,
+ CV_ARM_FS26 = 76,
+ CV_ARM_FS27 = 77,
+ CV_ARM_FS28 = 78,
+ CV_ARM_FS29 = 79,
+ CV_ARM_FS30 = 80,
+ CV_ARM_FS31 = 81,
+
+ //
+ // ARM VFP Floating Point Extra control registers
+ //
+
+ CV_ARM_FPEXTRA0 = 90,
+ CV_ARM_FPEXTRA1 = 91,
+ CV_ARM_FPEXTRA2 = 92,
+ CV_ARM_FPEXTRA3 = 93,
+ CV_ARM_FPEXTRA4 = 94,
+ CV_ARM_FPEXTRA5 = 95,
+ CV_ARM_FPEXTRA6 = 96,
+ CV_ARM_FPEXTRA7 = 97,
+
+ // XSCALE Concan co-processor registers
+ CV_ARM_WR0 = 128,
+ CV_ARM_WR1 = 129,
+ CV_ARM_WR2 = 130,
+ CV_ARM_WR3 = 131,
+ CV_ARM_WR4 = 132,
+ CV_ARM_WR5 = 133,
+ CV_ARM_WR6 = 134,
+ CV_ARM_WR7 = 135,
+ CV_ARM_WR8 = 136,
+ CV_ARM_WR9 = 137,
+ CV_ARM_WR10 = 138,
+ CV_ARM_WR11 = 139,
+ CV_ARM_WR12 = 140,
+ CV_ARM_WR13 = 141,
+ CV_ARM_WR14 = 142,
+ CV_ARM_WR15 = 143,
+
+ // XSCALE Concan co-processor control registers
+ CV_ARM_WCID = 144,
+ CV_ARM_WCON = 145,
+ CV_ARM_WCSSF = 146,
+ CV_ARM_WCASF = 147,
+ CV_ARM_WC4 = 148,
+ CV_ARM_WC5 = 149,
+ CV_ARM_WC6 = 150,
+ CV_ARM_WC7 = 151,
+ CV_ARM_WCGR0 = 152,
+ CV_ARM_WCGR1 = 153,
+ CV_ARM_WCGR2 = 154,
+ CV_ARM_WCGR3 = 155,
+ CV_ARM_WC12 = 156,
+ CV_ARM_WC13 = 157,
+ CV_ARM_WC14 = 158,
+ CV_ARM_WC15 = 159,
+
+ //
+ // ARM VFPv3/Neon extended floating Point
+ //
+
+ CV_ARM_FS32 = 200,
+ CV_ARM_FS33 = 201,
+ CV_ARM_FS34 = 202,
+ CV_ARM_FS35 = 203,
+ CV_ARM_FS36 = 204,
+ CV_ARM_FS37 = 205,
+ CV_ARM_FS38 = 206,
+ CV_ARM_FS39 = 207,
+ CV_ARM_FS40 = 208,
+ CV_ARM_FS41 = 209,
+ CV_ARM_FS42 = 210,
+ CV_ARM_FS43 = 211,
+ CV_ARM_FS44 = 212,
+ CV_ARM_FS45 = 213,
+ CV_ARM_FS46 = 214,
+ CV_ARM_FS47 = 215,
+ CV_ARM_FS48 = 216,
+ CV_ARM_FS49 = 217,
+ CV_ARM_FS50 = 218,
+ CV_ARM_FS51 = 219,
+ CV_ARM_FS52 = 220,
+ CV_ARM_FS53 = 221,
+ CV_ARM_FS54 = 222,
+ CV_ARM_FS55 = 223,
+ CV_ARM_FS56 = 224,
+ CV_ARM_FS57 = 225,
+ CV_ARM_FS58 = 226,
+ CV_ARM_FS59 = 227,
+ CV_ARM_FS60 = 228,
+ CV_ARM_FS61 = 229,
+ CV_ARM_FS62 = 230,
+ CV_ARM_FS63 = 231,
+
+ // ARM double-precision floating point
+
+ CV_ARM_ND0 = 300,
+ CV_ARM_ND1 = 301,
+ CV_ARM_ND2 = 302,
+ CV_ARM_ND3 = 303,
+ CV_ARM_ND4 = 304,
+ CV_ARM_ND5 = 305,
+ CV_ARM_ND6 = 306,
+ CV_ARM_ND7 = 307,
+ CV_ARM_ND8 = 308,
+ CV_ARM_ND9 = 309,
+ CV_ARM_ND10 = 310,
+ CV_ARM_ND11 = 311,
+ CV_ARM_ND12 = 312,
+ CV_ARM_ND13 = 313,
+ CV_ARM_ND14 = 314,
+ CV_ARM_ND15 = 315,
+ CV_ARM_ND16 = 316,
+ CV_ARM_ND17 = 317,
+ CV_ARM_ND18 = 318,
+ CV_ARM_ND19 = 319,
+ CV_ARM_ND20 = 320,
+ CV_ARM_ND21 = 321,
+ CV_ARM_ND22 = 322,
+ CV_ARM_ND23 = 323,
+ CV_ARM_ND24 = 324,
+ CV_ARM_ND25 = 325,
+ CV_ARM_ND26 = 326,
+ CV_ARM_ND27 = 327,
+ CV_ARM_ND28 = 328,
+ CV_ARM_ND29 = 329,
+ CV_ARM_ND30 = 330,
+ CV_ARM_ND31 = 331,
+
+ // ARM extended precision floating point
+
+ CV_ARM_NQ0 = 400,
+ CV_ARM_NQ1 = 401,
+ CV_ARM_NQ2 = 402,
+ CV_ARM_NQ3 = 403,
+ CV_ARM_NQ4 = 404,
+ CV_ARM_NQ5 = 405,
+ CV_ARM_NQ6 = 406,
+ CV_ARM_NQ7 = 407,
+ CV_ARM_NQ8 = 408,
+ CV_ARM_NQ9 = 409,
+ CV_ARM_NQ10 = 410,
+ CV_ARM_NQ11 = 411,
+ CV_ARM_NQ12 = 412,
+ CV_ARM_NQ13 = 413,
+ CV_ARM_NQ14 = 414,
+ CV_ARM_NQ15 = 415,
+
+ //
+ // Register set for ARM64
+ //
+
+ CV_ARM64_NOREG = CV_REG_NONE,
+
+ // General purpose 32-bit integer registers
+
+ CV_ARM64_W0 = 10,
+ CV_ARM64_W1 = 11,
+ CV_ARM64_W2 = 12,
+ CV_ARM64_W3 = 13,
+ CV_ARM64_W4 = 14,
+ CV_ARM64_W5 = 15,
+ CV_ARM64_W6 = 16,
+ CV_ARM64_W7 = 17,
+ CV_ARM64_W8 = 18,
+ CV_ARM64_W9 = 19,
+ CV_ARM64_W10 = 20,
+ CV_ARM64_W11 = 21,
+ CV_ARM64_W12 = 22,
+ CV_ARM64_W13 = 23,
+ CV_ARM64_W14 = 24,
+ CV_ARM64_W15 = 25,
+ CV_ARM64_W16 = 26,
+ CV_ARM64_W17 = 27,
+ CV_ARM64_W18 = 28,
+ CV_ARM64_W19 = 29,
+ CV_ARM64_W20 = 30,
+ CV_ARM64_W21 = 31,
+ CV_ARM64_W22 = 32,
+ CV_ARM64_W23 = 33,
+ CV_ARM64_W24 = 34,
+ CV_ARM64_W25 = 35,
+ CV_ARM64_W26 = 36,
+ CV_ARM64_W27 = 37,
+ CV_ARM64_W28 = 38,
+ CV_ARM64_W29 = 39,
+ CV_ARM64_W30 = 40,
+ CV_ARM64_WZR = 41,
+
+ // General purpose 64-bit integer registers
+
+ CV_ARM64_X0 = 50,
+ CV_ARM64_X1 = 51,
+ CV_ARM64_X2 = 52,
+ CV_ARM64_X3 = 53,
+ CV_ARM64_X4 = 54,
+ CV_ARM64_X5 = 55,
+ CV_ARM64_X6 = 56,
+ CV_ARM64_X7 = 57,
+ CV_ARM64_X8 = 58,
+ CV_ARM64_X9 = 59,
+ CV_ARM64_X10 = 60,
+ CV_ARM64_X11 = 61,
+ CV_ARM64_X12 = 62,
+ CV_ARM64_X13 = 63,
+ CV_ARM64_X14 = 64,
+ CV_ARM64_X15 = 65,
+ CV_ARM64_IP0 = 66,
+ CV_ARM64_IP1 = 67,
+ CV_ARM64_X18 = 68,
+ CV_ARM64_X19 = 69,
+ CV_ARM64_X20 = 70,
+ CV_ARM64_X21 = 71,
+ CV_ARM64_X22 = 72,
+ CV_ARM64_X23 = 73,
+ CV_ARM64_X24 = 74,
+ CV_ARM64_X25 = 75,
+ CV_ARM64_X26 = 76,
+ CV_ARM64_X27 = 77,
+ CV_ARM64_X28 = 78,
+ CV_ARM64_FP = 79,
+ CV_ARM64_LR = 80,
+ CV_ARM64_SP = 81,
+ CV_ARM64_ZR = 82,
+
+ // statue register
+
+ CV_ARM64_NZCV = 90,
+
+ // 32-bit floating point registers
+
+ CV_ARM64_S0 = 100,
+ CV_ARM64_S1 = 101,
+ CV_ARM64_S2 = 102,
+ CV_ARM64_S3 = 103,
+ CV_ARM64_S4 = 104,
+ CV_ARM64_S5 = 105,
+ CV_ARM64_S6 = 106,
+ CV_ARM64_S7 = 107,
+ CV_ARM64_S8 = 108,
+ CV_ARM64_S9 = 109,
+ CV_ARM64_S10 = 110,
+ CV_ARM64_S11 = 111,
+ CV_ARM64_S12 = 112,
+ CV_ARM64_S13 = 113,
+ CV_ARM64_S14 = 114,
+ CV_ARM64_S15 = 115,
+ CV_ARM64_S16 = 116,
+ CV_ARM64_S17 = 117,
+ CV_ARM64_S18 = 118,
+ CV_ARM64_S19 = 119,
+ CV_ARM64_S20 = 120,
+ CV_ARM64_S21 = 121,
+ CV_ARM64_S22 = 122,
+ CV_ARM64_S23 = 123,
+ CV_ARM64_S24 = 124,
+ CV_ARM64_S25 = 125,
+ CV_ARM64_S26 = 126,
+ CV_ARM64_S27 = 127,
+ CV_ARM64_S28 = 128,
+ CV_ARM64_S29 = 129,
+ CV_ARM64_S30 = 130,
+ CV_ARM64_S31 = 131,
+
+ // 64-bit floating point registers
+
+ CV_ARM64_D0 = 140,
+ CV_ARM64_D1 = 141,
+ CV_ARM64_D2 = 142,
+ CV_ARM64_D3 = 143,
+ CV_ARM64_D4 = 144,
+ CV_ARM64_D5 = 145,
+ CV_ARM64_D6 = 146,
+ CV_ARM64_D7 = 147,
+ CV_ARM64_D8 = 148,
+ CV_ARM64_D9 = 149,
+ CV_ARM64_D10 = 150,
+ CV_ARM64_D11 = 151,
+ CV_ARM64_D12 = 152,
+ CV_ARM64_D13 = 153,
+ CV_ARM64_D14 = 154,
+ CV_ARM64_D15 = 155,
+ CV_ARM64_D16 = 156,
+ CV_ARM64_D17 = 157,
+ CV_ARM64_D18 = 158,
+ CV_ARM64_D19 = 159,
+ CV_ARM64_D20 = 160,
+ CV_ARM64_D21 = 161,
+ CV_ARM64_D22 = 162,
+ CV_ARM64_D23 = 163,
+ CV_ARM64_D24 = 164,
+ CV_ARM64_D25 = 165,
+ CV_ARM64_D26 = 166,
+ CV_ARM64_D27 = 167,
+ CV_ARM64_D28 = 168,
+ CV_ARM64_D29 = 169,
+ CV_ARM64_D30 = 170,
+ CV_ARM64_D31 = 171,
+
+ // 128-bit SIMD registers
+
+ CV_ARM64_Q0 = 180,
+ CV_ARM64_Q1 = 181,
+ CV_ARM64_Q2 = 182,
+ CV_ARM64_Q3 = 183,
+ CV_ARM64_Q4 = 184,
+ CV_ARM64_Q5 = 185,
+ CV_ARM64_Q6 = 186,
+ CV_ARM64_Q7 = 187,
+ CV_ARM64_Q8 = 188,
+ CV_ARM64_Q9 = 189,
+ CV_ARM64_Q10 = 190,
+ CV_ARM64_Q11 = 191,
+ CV_ARM64_Q12 = 192,
+ CV_ARM64_Q13 = 193,
+ CV_ARM64_Q14 = 194,
+ CV_ARM64_Q15 = 195,
+ CV_ARM64_Q16 = 196,
+ CV_ARM64_Q17 = 197,
+ CV_ARM64_Q18 = 198,
+ CV_ARM64_Q19 = 199,
+ CV_ARM64_Q20 = 200,
+ CV_ARM64_Q21 = 201,
+ CV_ARM64_Q22 = 202,
+ CV_ARM64_Q23 = 203,
+ CV_ARM64_Q24 = 204,
+ CV_ARM64_Q25 = 205,
+ CV_ARM64_Q26 = 206,
+ CV_ARM64_Q27 = 207,
+ CV_ARM64_Q28 = 208,
+ CV_ARM64_Q29 = 209,
+ CV_ARM64_Q30 = 210,
+ CV_ARM64_Q31 = 211,
+
+ // Floating point status register
+
+ CV_ARM64_FPSR = 220,
+
+ //
+ // Register set for Intel IA64
+ //
+
+ CV_IA64_NOREG = CV_REG_NONE,
+
+ // Branch Registers
+
+ CV_IA64_Br0 = 512,
+ CV_IA64_Br1 = 513,
+ CV_IA64_Br2 = 514,
+ CV_IA64_Br3 = 515,
+ CV_IA64_Br4 = 516,
+ CV_IA64_Br5 = 517,
+ CV_IA64_Br6 = 518,
+ CV_IA64_Br7 = 519,
+
+ // Predicate Registers
+
+ CV_IA64_P0 = 704,
+ CV_IA64_P1 = 705,
+ CV_IA64_P2 = 706,
+ CV_IA64_P3 = 707,
+ CV_IA64_P4 = 708,
+ CV_IA64_P5 = 709,
+ CV_IA64_P6 = 710,
+ CV_IA64_P7 = 711,
+ CV_IA64_P8 = 712,
+ CV_IA64_P9 = 713,
+ CV_IA64_P10 = 714,
+ CV_IA64_P11 = 715,
+ CV_IA64_P12 = 716,
+ CV_IA64_P13 = 717,
+ CV_IA64_P14 = 718,
+ CV_IA64_P15 = 719,
+ CV_IA64_P16 = 720,
+ CV_IA64_P17 = 721,
+ CV_IA64_P18 = 722,
+ CV_IA64_P19 = 723,
+ CV_IA64_P20 = 724,
+ CV_IA64_P21 = 725,
+ CV_IA64_P22 = 726,
+ CV_IA64_P23 = 727,
+ CV_IA64_P24 = 728,
+ CV_IA64_P25 = 729,
+ CV_IA64_P26 = 730,
+ CV_IA64_P27 = 731,
+ CV_IA64_P28 = 732,
+ CV_IA64_P29 = 733,
+ CV_IA64_P30 = 734,
+ CV_IA64_P31 = 735,
+ CV_IA64_P32 = 736,
+ CV_IA64_P33 = 737,
+ CV_IA64_P34 = 738,
+ CV_IA64_P35 = 739,
+ CV_IA64_P36 = 740,
+ CV_IA64_P37 = 741,
+ CV_IA64_P38 = 742,
+ CV_IA64_P39 = 743,
+ CV_IA64_P40 = 744,
+ CV_IA64_P41 = 745,
+ CV_IA64_P42 = 746,
+ CV_IA64_P43 = 747,
+ CV_IA64_P44 = 748,
+ CV_IA64_P45 = 749,
+ CV_IA64_P46 = 750,
+ CV_IA64_P47 = 751,
+ CV_IA64_P48 = 752,
+ CV_IA64_P49 = 753,
+ CV_IA64_P50 = 754,
+ CV_IA64_P51 = 755,
+ CV_IA64_P52 = 756,
+ CV_IA64_P53 = 757,
+ CV_IA64_P54 = 758,
+ CV_IA64_P55 = 759,
+ CV_IA64_P56 = 760,
+ CV_IA64_P57 = 761,
+ CV_IA64_P58 = 762,
+ CV_IA64_P59 = 763,
+ CV_IA64_P60 = 764,
+ CV_IA64_P61 = 765,
+ CV_IA64_P62 = 766,
+ CV_IA64_P63 = 767,
+
+ CV_IA64_Preds = 768,
+
+ // Banked General Registers
+
+ CV_IA64_IntH0 = 832,
+ CV_IA64_IntH1 = 833,
+ CV_IA64_IntH2 = 834,
+ CV_IA64_IntH3 = 835,
+ CV_IA64_IntH4 = 836,
+ CV_IA64_IntH5 = 837,
+ CV_IA64_IntH6 = 838,
+ CV_IA64_IntH7 = 839,
+ CV_IA64_IntH8 = 840,
+ CV_IA64_IntH9 = 841,
+ CV_IA64_IntH10 = 842,
+ CV_IA64_IntH11 = 843,
+ CV_IA64_IntH12 = 844,
+ CV_IA64_IntH13 = 845,
+ CV_IA64_IntH14 = 846,
+ CV_IA64_IntH15 = 847,
+
+ // Special Registers
+
+ CV_IA64_Ip = 1016,
+ CV_IA64_Umask = 1017,
+ CV_IA64_Cfm = 1018,
+ CV_IA64_Psr = 1019,
+
+ // Banked General Registers
+
+ CV_IA64_Nats = 1020,
+ CV_IA64_Nats2 = 1021,
+ CV_IA64_Nats3 = 1022,
+
+ // General-Purpose Registers
+
+ // Integer registers
+ CV_IA64_IntR0 = 1024,
+ CV_IA64_IntR1 = 1025,
+ CV_IA64_IntR2 = 1026,
+ CV_IA64_IntR3 = 1027,
+ CV_IA64_IntR4 = 1028,
+ CV_IA64_IntR5 = 1029,
+ CV_IA64_IntR6 = 1030,
+ CV_IA64_IntR7 = 1031,
+ CV_IA64_IntR8 = 1032,
+ CV_IA64_IntR9 = 1033,
+ CV_IA64_IntR10 = 1034,
+ CV_IA64_IntR11 = 1035,
+ CV_IA64_IntR12 = 1036,
+ CV_IA64_IntR13 = 1037,
+ CV_IA64_IntR14 = 1038,
+ CV_IA64_IntR15 = 1039,
+ CV_IA64_IntR16 = 1040,
+ CV_IA64_IntR17 = 1041,
+ CV_IA64_IntR18 = 1042,
+ CV_IA64_IntR19 = 1043,
+ CV_IA64_IntR20 = 1044,
+ CV_IA64_IntR21 = 1045,
+ CV_IA64_IntR22 = 1046,
+ CV_IA64_IntR23 = 1047,
+ CV_IA64_IntR24 = 1048,
+ CV_IA64_IntR25 = 1049,
+ CV_IA64_IntR26 = 1050,
+ CV_IA64_IntR27 = 1051,
+ CV_IA64_IntR28 = 1052,
+ CV_IA64_IntR29 = 1053,
+ CV_IA64_IntR30 = 1054,
+ CV_IA64_IntR31 = 1055,
+
+ // Register Stack
+ CV_IA64_IntR32 = 1056,
+ CV_IA64_IntR33 = 1057,
+ CV_IA64_IntR34 = 1058,
+ CV_IA64_IntR35 = 1059,
+ CV_IA64_IntR36 = 1060,
+ CV_IA64_IntR37 = 1061,
+ CV_IA64_IntR38 = 1062,
+ CV_IA64_IntR39 = 1063,
+ CV_IA64_IntR40 = 1064,
+ CV_IA64_IntR41 = 1065,
+ CV_IA64_IntR42 = 1066,
+ CV_IA64_IntR43 = 1067,
+ CV_IA64_IntR44 = 1068,
+ CV_IA64_IntR45 = 1069,
+ CV_IA64_IntR46 = 1070,
+ CV_IA64_IntR47 = 1071,
+ CV_IA64_IntR48 = 1072,
+ CV_IA64_IntR49 = 1073,
+ CV_IA64_IntR50 = 1074,
+ CV_IA64_IntR51 = 1075,
+ CV_IA64_IntR52 = 1076,
+ CV_IA64_IntR53 = 1077,
+ CV_IA64_IntR54 = 1078,
+ CV_IA64_IntR55 = 1079,
+ CV_IA64_IntR56 = 1080,
+ CV_IA64_IntR57 = 1081,
+ CV_IA64_IntR58 = 1082,
+ CV_IA64_IntR59 = 1083,
+ CV_IA64_IntR60 = 1084,
+ CV_IA64_IntR61 = 1085,
+ CV_IA64_IntR62 = 1086,
+ CV_IA64_IntR63 = 1087,
+ CV_IA64_IntR64 = 1088,
+ CV_IA64_IntR65 = 1089,
+ CV_IA64_IntR66 = 1090,
+ CV_IA64_IntR67 = 1091,
+ CV_IA64_IntR68 = 1092,
+ CV_IA64_IntR69 = 1093,
+ CV_IA64_IntR70 = 1094,
+ CV_IA64_IntR71 = 1095,
+ CV_IA64_IntR72 = 1096,
+ CV_IA64_IntR73 = 1097,
+ CV_IA64_IntR74 = 1098,
+ CV_IA64_IntR75 = 1099,
+ CV_IA64_IntR76 = 1100,
+ CV_IA64_IntR77 = 1101,
+ CV_IA64_IntR78 = 1102,
+ CV_IA64_IntR79 = 1103,
+ CV_IA64_IntR80 = 1104,
+ CV_IA64_IntR81 = 1105,
+ CV_IA64_IntR82 = 1106,
+ CV_IA64_IntR83 = 1107,
+ CV_IA64_IntR84 = 1108,
+ CV_IA64_IntR85 = 1109,
+ CV_IA64_IntR86 = 1110,
+ CV_IA64_IntR87 = 1111,
+ CV_IA64_IntR88 = 1112,
+ CV_IA64_IntR89 = 1113,
+ CV_IA64_IntR90 = 1114,
+ CV_IA64_IntR91 = 1115,
+ CV_IA64_IntR92 = 1116,
+ CV_IA64_IntR93 = 1117,
+ CV_IA64_IntR94 = 1118,
+ CV_IA64_IntR95 = 1119,
+ CV_IA64_IntR96 = 1120,
+ CV_IA64_IntR97 = 1121,
+ CV_IA64_IntR98 = 1122,
+ CV_IA64_IntR99 = 1123,
+ CV_IA64_IntR100 = 1124,
+ CV_IA64_IntR101 = 1125,
+ CV_IA64_IntR102 = 1126,
+ CV_IA64_IntR103 = 1127,
+ CV_IA64_IntR104 = 1128,
+ CV_IA64_IntR105 = 1129,
+ CV_IA64_IntR106 = 1130,
+ CV_IA64_IntR107 = 1131,
+ CV_IA64_IntR108 = 1132,
+ CV_IA64_IntR109 = 1133,
+ CV_IA64_IntR110 = 1134,
+ CV_IA64_IntR111 = 1135,
+ CV_IA64_IntR112 = 1136,
+ CV_IA64_IntR113 = 1137,
+ CV_IA64_IntR114 = 1138,
+ CV_IA64_IntR115 = 1139,
+ CV_IA64_IntR116 = 1140,
+ CV_IA64_IntR117 = 1141,
+ CV_IA64_IntR118 = 1142,
+ CV_IA64_IntR119 = 1143,
+ CV_IA64_IntR120 = 1144,
+ CV_IA64_IntR121 = 1145,
+ CV_IA64_IntR122 = 1146,
+ CV_IA64_IntR123 = 1147,
+ CV_IA64_IntR124 = 1148,
+ CV_IA64_IntR125 = 1149,
+ CV_IA64_IntR126 = 1150,
+ CV_IA64_IntR127 = 1151,
+
+ // Floating-Point Registers
+
+ // Low Floating Point Registers
+ CV_IA64_FltF0 = 2048,
+ CV_IA64_FltF1 = 2049,
+ CV_IA64_FltF2 = 2050,
+ CV_IA64_FltF3 = 2051,
+ CV_IA64_FltF4 = 2052,
+ CV_IA64_FltF5 = 2053,
+ CV_IA64_FltF6 = 2054,
+ CV_IA64_FltF7 = 2055,
+ CV_IA64_FltF8 = 2056,
+ CV_IA64_FltF9 = 2057,
+ CV_IA64_FltF10 = 2058,
+ CV_IA64_FltF11 = 2059,
+ CV_IA64_FltF12 = 2060,
+ CV_IA64_FltF13 = 2061,
+ CV_IA64_FltF14 = 2062,
+ CV_IA64_FltF15 = 2063,
+ CV_IA64_FltF16 = 2064,
+ CV_IA64_FltF17 = 2065,
+ CV_IA64_FltF18 = 2066,
+ CV_IA64_FltF19 = 2067,
+ CV_IA64_FltF20 = 2068,
+ CV_IA64_FltF21 = 2069,
+ CV_IA64_FltF22 = 2070,
+ CV_IA64_FltF23 = 2071,
+ CV_IA64_FltF24 = 2072,
+ CV_IA64_FltF25 = 2073,
+ CV_IA64_FltF26 = 2074,
+ CV_IA64_FltF27 = 2075,
+ CV_IA64_FltF28 = 2076,
+ CV_IA64_FltF29 = 2077,
+ CV_IA64_FltF30 = 2078,
+ CV_IA64_FltF31 = 2079,
+
+ // High Floating Point Registers
+ CV_IA64_FltF32 = 2080,
+ CV_IA64_FltF33 = 2081,
+ CV_IA64_FltF34 = 2082,
+ CV_IA64_FltF35 = 2083,
+ CV_IA64_FltF36 = 2084,
+ CV_IA64_FltF37 = 2085,
+ CV_IA64_FltF38 = 2086,
+ CV_IA64_FltF39 = 2087,
+ CV_IA64_FltF40 = 2088,
+ CV_IA64_FltF41 = 2089,
+ CV_IA64_FltF42 = 2090,
+ CV_IA64_FltF43 = 2091,
+ CV_IA64_FltF44 = 2092,
+ CV_IA64_FltF45 = 2093,
+ CV_IA64_FltF46 = 2094,
+ CV_IA64_FltF47 = 2095,
+ CV_IA64_FltF48 = 2096,
+ CV_IA64_FltF49 = 2097,
+ CV_IA64_FltF50 = 2098,
+ CV_IA64_FltF51 = 2099,
+ CV_IA64_FltF52 = 2100,
+ CV_IA64_FltF53 = 2101,
+ CV_IA64_FltF54 = 2102,
+ CV_IA64_FltF55 = 2103,
+ CV_IA64_FltF56 = 2104,
+ CV_IA64_FltF57 = 2105,
+ CV_IA64_FltF58 = 2106,
+ CV_IA64_FltF59 = 2107,
+ CV_IA64_FltF60 = 2108,
+ CV_IA64_FltF61 = 2109,
+ CV_IA64_FltF62 = 2110,
+ CV_IA64_FltF63 = 2111,
+ CV_IA64_FltF64 = 2112,
+ CV_IA64_FltF65 = 2113,
+ CV_IA64_FltF66 = 2114,
+ CV_IA64_FltF67 = 2115,
+ CV_IA64_FltF68 = 2116,
+ CV_IA64_FltF69 = 2117,
+ CV_IA64_FltF70 = 2118,
+ CV_IA64_FltF71 = 2119,
+ CV_IA64_FltF72 = 2120,
+ CV_IA64_FltF73 = 2121,
+ CV_IA64_FltF74 = 2122,
+ CV_IA64_FltF75 = 2123,
+ CV_IA64_FltF76 = 2124,
+ CV_IA64_FltF77 = 2125,
+ CV_IA64_FltF78 = 2126,
+ CV_IA64_FltF79 = 2127,
+ CV_IA64_FltF80 = 2128,
+ CV_IA64_FltF81 = 2129,
+ CV_IA64_FltF82 = 2130,
+ CV_IA64_FltF83 = 2131,
+ CV_IA64_FltF84 = 2132,
+ CV_IA64_FltF85 = 2133,
+ CV_IA64_FltF86 = 2134,
+ CV_IA64_FltF87 = 2135,
+ CV_IA64_FltF88 = 2136,
+ CV_IA64_FltF89 = 2137,
+ CV_IA64_FltF90 = 2138,
+ CV_IA64_FltF91 = 2139,
+ CV_IA64_FltF92 = 2140,
+ CV_IA64_FltF93 = 2141,
+ CV_IA64_FltF94 = 2142,
+ CV_IA64_FltF95 = 2143,
+ CV_IA64_FltF96 = 2144,
+ CV_IA64_FltF97 = 2145,
+ CV_IA64_FltF98 = 2146,
+ CV_IA64_FltF99 = 2147,
+ CV_IA64_FltF100 = 2148,
+ CV_IA64_FltF101 = 2149,
+ CV_IA64_FltF102 = 2150,
+ CV_IA64_FltF103 = 2151,
+ CV_IA64_FltF104 = 2152,
+ CV_IA64_FltF105 = 2153,
+ CV_IA64_FltF106 = 2154,
+ CV_IA64_FltF107 = 2155,
+ CV_IA64_FltF108 = 2156,
+ CV_IA64_FltF109 = 2157,
+ CV_IA64_FltF110 = 2158,
+ CV_IA64_FltF111 = 2159,
+ CV_IA64_FltF112 = 2160,
+ CV_IA64_FltF113 = 2161,
+ CV_IA64_FltF114 = 2162,
+ CV_IA64_FltF115 = 2163,
+ CV_IA64_FltF116 = 2164,
+ CV_IA64_FltF117 = 2165,
+ CV_IA64_FltF118 = 2166,
+ CV_IA64_FltF119 = 2167,
+ CV_IA64_FltF120 = 2168,
+ CV_IA64_FltF121 = 2169,
+ CV_IA64_FltF122 = 2170,
+ CV_IA64_FltF123 = 2171,
+ CV_IA64_FltF124 = 2172,
+ CV_IA64_FltF125 = 2173,
+ CV_IA64_FltF126 = 2174,
+ CV_IA64_FltF127 = 2175,
+
+ // Application Registers
+
+ CV_IA64_ApKR0 = 3072,
+ CV_IA64_ApKR1 = 3073,
+ CV_IA64_ApKR2 = 3074,
+ CV_IA64_ApKR3 = 3075,
+ CV_IA64_ApKR4 = 3076,
+ CV_IA64_ApKR5 = 3077,
+ CV_IA64_ApKR6 = 3078,
+ CV_IA64_ApKR7 = 3079,
+ CV_IA64_AR8 = 3080,
+ CV_IA64_AR9 = 3081,
+ CV_IA64_AR10 = 3082,
+ CV_IA64_AR11 = 3083,
+ CV_IA64_AR12 = 3084,
+ CV_IA64_AR13 = 3085,
+ CV_IA64_AR14 = 3086,
+ CV_IA64_AR15 = 3087,
+ CV_IA64_RsRSC = 3088,
+ CV_IA64_RsBSP = 3089,
+ CV_IA64_RsBSPSTORE = 3090,
+ CV_IA64_RsRNAT = 3091,
+ CV_IA64_AR20 = 3092,
+ CV_IA64_StFCR = 3093,
+ CV_IA64_AR22 = 3094,
+ CV_IA64_AR23 = 3095,
+ CV_IA64_EFLAG = 3096,
+ CV_IA64_CSD = 3097,
+ CV_IA64_SSD = 3098,
+ CV_IA64_CFLG = 3099,
+ CV_IA64_StFSR = 3100,
+ CV_IA64_StFIR = 3101,
+ CV_IA64_StFDR = 3102,
+ CV_IA64_AR31 = 3103,
+ CV_IA64_ApCCV = 3104,
+ CV_IA64_AR33 = 3105,
+ CV_IA64_AR34 = 3106,
+ CV_IA64_AR35 = 3107,
+ CV_IA64_ApUNAT = 3108,
+ CV_IA64_AR37 = 3109,
+ CV_IA64_AR38 = 3110,
+ CV_IA64_AR39 = 3111,
+ CV_IA64_StFPSR = 3112,
+ CV_IA64_AR41 = 3113,
+ CV_IA64_AR42 = 3114,
+ CV_IA64_AR43 = 3115,
+ CV_IA64_ApITC = 3116,
+ CV_IA64_AR45 = 3117,
+ CV_IA64_AR46 = 3118,
+ CV_IA64_AR47 = 3119,
+ CV_IA64_AR48 = 3120,
+ CV_IA64_AR49 = 3121,
+ CV_IA64_AR50 = 3122,
+ CV_IA64_AR51 = 3123,
+ CV_IA64_AR52 = 3124,
+ CV_IA64_AR53 = 3125,
+ CV_IA64_AR54 = 3126,
+ CV_IA64_AR55 = 3127,
+ CV_IA64_AR56 = 3128,
+ CV_IA64_AR57 = 3129,
+ CV_IA64_AR58 = 3130,
+ CV_IA64_AR59 = 3131,
+ CV_IA64_AR60 = 3132,
+ CV_IA64_AR61 = 3133,
+ CV_IA64_AR62 = 3134,
+ CV_IA64_AR63 = 3135,
+ CV_IA64_RsPFS = 3136,
+ CV_IA64_ApLC = 3137,
+ CV_IA64_ApEC = 3138,
+ CV_IA64_AR67 = 3139,
+ CV_IA64_AR68 = 3140,
+ CV_IA64_AR69 = 3141,
+ CV_IA64_AR70 = 3142,
+ CV_IA64_AR71 = 3143,
+ CV_IA64_AR72 = 3144,
+ CV_IA64_AR73 = 3145,
+ CV_IA64_AR74 = 3146,
+ CV_IA64_AR75 = 3147,
+ CV_IA64_AR76 = 3148,
+ CV_IA64_AR77 = 3149,
+ CV_IA64_AR78 = 3150,
+ CV_IA64_AR79 = 3151,
+ CV_IA64_AR80 = 3152,
+ CV_IA64_AR81 = 3153,
+ CV_IA64_AR82 = 3154,
+ CV_IA64_AR83 = 3155,
+ CV_IA64_AR84 = 3156,
+ CV_IA64_AR85 = 3157,
+ CV_IA64_AR86 = 3158,
+ CV_IA64_AR87 = 3159,
+ CV_IA64_AR88 = 3160,
+ CV_IA64_AR89 = 3161,
+ CV_IA64_AR90 = 3162,
+ CV_IA64_AR91 = 3163,
+ CV_IA64_AR92 = 3164,
+ CV_IA64_AR93 = 3165,
+ CV_IA64_AR94 = 3166,
+ CV_IA64_AR95 = 3167,
+ CV_IA64_AR96 = 3168,
+ CV_IA64_AR97 = 3169,
+ CV_IA64_AR98 = 3170,
+ CV_IA64_AR99 = 3171,
+ CV_IA64_AR100 = 3172,
+ CV_IA64_AR101 = 3173,
+ CV_IA64_AR102 = 3174,
+ CV_IA64_AR103 = 3175,
+ CV_IA64_AR104 = 3176,
+ CV_IA64_AR105 = 3177,
+ CV_IA64_AR106 = 3178,
+ CV_IA64_AR107 = 3179,
+ CV_IA64_AR108 = 3180,
+ CV_IA64_AR109 = 3181,
+ CV_IA64_AR110 = 3182,
+ CV_IA64_AR111 = 3183,
+ CV_IA64_AR112 = 3184,
+ CV_IA64_AR113 = 3185,
+ CV_IA64_AR114 = 3186,
+ CV_IA64_AR115 = 3187,
+ CV_IA64_AR116 = 3188,
+ CV_IA64_AR117 = 3189,
+ CV_IA64_AR118 = 3190,
+ CV_IA64_AR119 = 3191,
+ CV_IA64_AR120 = 3192,
+ CV_IA64_AR121 = 3193,
+ CV_IA64_AR122 = 3194,
+ CV_IA64_AR123 = 3195,
+ CV_IA64_AR124 = 3196,
+ CV_IA64_AR125 = 3197,
+ CV_IA64_AR126 = 3198,
+ CV_IA64_AR127 = 3199,
+
+ // CPUID Registers
+
+ CV_IA64_CPUID0 = 3328,
+ CV_IA64_CPUID1 = 3329,
+ CV_IA64_CPUID2 = 3330,
+ CV_IA64_CPUID3 = 3331,
+ CV_IA64_CPUID4 = 3332,
+
+ // Control Registers
+
+ CV_IA64_ApDCR = 4096,
+ CV_IA64_ApITM = 4097,
+ CV_IA64_ApIVA = 4098,
+ CV_IA64_CR3 = 4099,
+ CV_IA64_CR4 = 4100,
+ CV_IA64_CR5 = 4101,
+ CV_IA64_CR6 = 4102,
+ CV_IA64_CR7 = 4103,
+ CV_IA64_ApPTA = 4104,
+ CV_IA64_ApGPTA = 4105,
+ CV_IA64_CR10 = 4106,
+ CV_IA64_CR11 = 4107,
+ CV_IA64_CR12 = 4108,
+ CV_IA64_CR13 = 4109,
+ CV_IA64_CR14 = 4110,
+ CV_IA64_CR15 = 4111,
+ CV_IA64_StIPSR = 4112,
+ CV_IA64_StISR = 4113,
+ CV_IA64_CR18 = 4114,
+ CV_IA64_StIIP = 4115,
+ CV_IA64_StIFA = 4116,
+ CV_IA64_StITIR = 4117,
+ CV_IA64_StIIPA = 4118,
+ CV_IA64_StIFS = 4119,
+ CV_IA64_StIIM = 4120,
+ CV_IA64_StIHA = 4121,
+ CV_IA64_CR26 = 4122,
+ CV_IA64_CR27 = 4123,
+ CV_IA64_CR28 = 4124,
+ CV_IA64_CR29 = 4125,
+ CV_IA64_CR30 = 4126,
+ CV_IA64_CR31 = 4127,
+ CV_IA64_CR32 = 4128,
+ CV_IA64_CR33 = 4129,
+ CV_IA64_CR34 = 4130,
+ CV_IA64_CR35 = 4131,
+ CV_IA64_CR36 = 4132,
+ CV_IA64_CR37 = 4133,
+ CV_IA64_CR38 = 4134,
+ CV_IA64_CR39 = 4135,
+ CV_IA64_CR40 = 4136,
+ CV_IA64_CR41 = 4137,
+ CV_IA64_CR42 = 4138,
+ CV_IA64_CR43 = 4139,
+ CV_IA64_CR44 = 4140,
+ CV_IA64_CR45 = 4141,
+ CV_IA64_CR46 = 4142,
+ CV_IA64_CR47 = 4143,
+ CV_IA64_CR48 = 4144,
+ CV_IA64_CR49 = 4145,
+ CV_IA64_CR50 = 4146,
+ CV_IA64_CR51 = 4147,
+ CV_IA64_CR52 = 4148,
+ CV_IA64_CR53 = 4149,
+ CV_IA64_CR54 = 4150,
+ CV_IA64_CR55 = 4151,
+ CV_IA64_CR56 = 4152,
+ CV_IA64_CR57 = 4153,
+ CV_IA64_CR58 = 4154,
+ CV_IA64_CR59 = 4155,
+ CV_IA64_CR60 = 4156,
+ CV_IA64_CR61 = 4157,
+ CV_IA64_CR62 = 4158,
+ CV_IA64_CR63 = 4159,
+ CV_IA64_SaLID = 4160,
+ CV_IA64_SaIVR = 4161,
+ CV_IA64_SaTPR = 4162,
+ CV_IA64_SaEOI = 4163,
+ CV_IA64_SaIRR0 = 4164,
+ CV_IA64_SaIRR1 = 4165,
+ CV_IA64_SaIRR2 = 4166,
+ CV_IA64_SaIRR3 = 4167,
+ CV_IA64_SaITV = 4168,
+ CV_IA64_SaPMV = 4169,
+ CV_IA64_SaCMCV = 4170,
+ CV_IA64_CR75 = 4171,
+ CV_IA64_CR76 = 4172,
+ CV_IA64_CR77 = 4173,
+ CV_IA64_CR78 = 4174,
+ CV_IA64_CR79 = 4175,
+ CV_IA64_SaLRR0 = 4176,
+ CV_IA64_SaLRR1 = 4177,
+ CV_IA64_CR82 = 4178,
+ CV_IA64_CR83 = 4179,
+ CV_IA64_CR84 = 4180,
+ CV_IA64_CR85 = 4181,
+ CV_IA64_CR86 = 4182,
+ CV_IA64_CR87 = 4183,
+ CV_IA64_CR88 = 4184,
+ CV_IA64_CR89 = 4185,
+ CV_IA64_CR90 = 4186,
+ CV_IA64_CR91 = 4187,
+ CV_IA64_CR92 = 4188,
+ CV_IA64_CR93 = 4189,
+ CV_IA64_CR94 = 4190,
+ CV_IA64_CR95 = 4191,
+ CV_IA64_CR96 = 4192,
+ CV_IA64_CR97 = 4193,
+ CV_IA64_CR98 = 4194,
+ CV_IA64_CR99 = 4195,
+ CV_IA64_CR100 = 4196,
+ CV_IA64_CR101 = 4197,
+ CV_IA64_CR102 = 4198,
+ CV_IA64_CR103 = 4199,
+ CV_IA64_CR104 = 4200,
+ CV_IA64_CR105 = 4201,
+ CV_IA64_CR106 = 4202,
+ CV_IA64_CR107 = 4203,
+ CV_IA64_CR108 = 4204,
+ CV_IA64_CR109 = 4205,
+ CV_IA64_CR110 = 4206,
+ CV_IA64_CR111 = 4207,
+ CV_IA64_CR112 = 4208,
+ CV_IA64_CR113 = 4209,
+ CV_IA64_CR114 = 4210,
+ CV_IA64_CR115 = 4211,
+ CV_IA64_CR116 = 4212,
+ CV_IA64_CR117 = 4213,
+ CV_IA64_CR118 = 4214,
+ CV_IA64_CR119 = 4215,
+ CV_IA64_CR120 = 4216,
+ CV_IA64_CR121 = 4217,
+ CV_IA64_CR122 = 4218,
+ CV_IA64_CR123 = 4219,
+ CV_IA64_CR124 = 4220,
+ CV_IA64_CR125 = 4221,
+ CV_IA64_CR126 = 4222,
+ CV_IA64_CR127 = 4223,
+
+ // Protection Key Registers
+
+ CV_IA64_Pkr0 = 5120,
+ CV_IA64_Pkr1 = 5121,
+ CV_IA64_Pkr2 = 5122,
+ CV_IA64_Pkr3 = 5123,
+ CV_IA64_Pkr4 = 5124,
+ CV_IA64_Pkr5 = 5125,
+ CV_IA64_Pkr6 = 5126,
+ CV_IA64_Pkr7 = 5127,
+ CV_IA64_Pkr8 = 5128,
+ CV_IA64_Pkr9 = 5129,
+ CV_IA64_Pkr10 = 5130,
+ CV_IA64_Pkr11 = 5131,
+ CV_IA64_Pkr12 = 5132,
+ CV_IA64_Pkr13 = 5133,
+ CV_IA64_Pkr14 = 5134,
+ CV_IA64_Pkr15 = 5135,
+
+ // Region Registers
+
+ CV_IA64_Rr0 = 6144,
+ CV_IA64_Rr1 = 6145,
+ CV_IA64_Rr2 = 6146,
+ CV_IA64_Rr3 = 6147,
+ CV_IA64_Rr4 = 6148,
+ CV_IA64_Rr5 = 6149,
+ CV_IA64_Rr6 = 6150,
+ CV_IA64_Rr7 = 6151,
+
+ // Performance Monitor Data Registers
+
+ CV_IA64_PFD0 = 7168,
+ CV_IA64_PFD1 = 7169,
+ CV_IA64_PFD2 = 7170,
+ CV_IA64_PFD3 = 7171,
+ CV_IA64_PFD4 = 7172,
+ CV_IA64_PFD5 = 7173,
+ CV_IA64_PFD6 = 7174,
+ CV_IA64_PFD7 = 7175,
+ CV_IA64_PFD8 = 7176,
+ CV_IA64_PFD9 = 7177,
+ CV_IA64_PFD10 = 7178,
+ CV_IA64_PFD11 = 7179,
+ CV_IA64_PFD12 = 7180,
+ CV_IA64_PFD13 = 7181,
+ CV_IA64_PFD14 = 7182,
+ CV_IA64_PFD15 = 7183,
+ CV_IA64_PFD16 = 7184,
+ CV_IA64_PFD17 = 7185,
+
+ // Performance Monitor Config Registers
+
+ CV_IA64_PFC0 = 7424,
+ CV_IA64_PFC1 = 7425,
+ CV_IA64_PFC2 = 7426,
+ CV_IA64_PFC3 = 7427,
+ CV_IA64_PFC4 = 7428,
+ CV_IA64_PFC5 = 7429,
+ CV_IA64_PFC6 = 7430,
+ CV_IA64_PFC7 = 7431,
+ CV_IA64_PFC8 = 7432,
+ CV_IA64_PFC9 = 7433,
+ CV_IA64_PFC10 = 7434,
+ CV_IA64_PFC11 = 7435,
+ CV_IA64_PFC12 = 7436,
+ CV_IA64_PFC13 = 7437,
+ CV_IA64_PFC14 = 7438,
+ CV_IA64_PFC15 = 7439,
+
+ // Instruction Translation Registers
+
+ CV_IA64_TrI0 = 8192,
+ CV_IA64_TrI1 = 8193,
+ CV_IA64_TrI2 = 8194,
+ CV_IA64_TrI3 = 8195,
+ CV_IA64_TrI4 = 8196,
+ CV_IA64_TrI5 = 8197,
+ CV_IA64_TrI6 = 8198,
+ CV_IA64_TrI7 = 8199,
+
+ // Data Translation Registers
+
+ CV_IA64_TrD0 = 8320,
+ CV_IA64_TrD1 = 8321,
+ CV_IA64_TrD2 = 8322,
+ CV_IA64_TrD3 = 8323,
+ CV_IA64_TrD4 = 8324,
+ CV_IA64_TrD5 = 8325,
+ CV_IA64_TrD6 = 8326,
+ CV_IA64_TrD7 = 8327,
+
+ // Instruction Breakpoint Registers
+
+ CV_IA64_DbI0 = 8448,
+ CV_IA64_DbI1 = 8449,
+ CV_IA64_DbI2 = 8450,
+ CV_IA64_DbI3 = 8451,
+ CV_IA64_DbI4 = 8452,
+ CV_IA64_DbI5 = 8453,
+ CV_IA64_DbI6 = 8454,
+ CV_IA64_DbI7 = 8455,
+
+ // Data Breakpoint Registers
+
+ CV_IA64_DbD0 = 8576,
+ CV_IA64_DbD1 = 8577,
+ CV_IA64_DbD2 = 8578,
+ CV_IA64_DbD3 = 8579,
+ CV_IA64_DbD4 = 8580,
+ CV_IA64_DbD5 = 8581,
+ CV_IA64_DbD6 = 8582,
+ CV_IA64_DbD7 = 8583,
+
+ //
+ // Register set for the TriCore processor.
+ //
+
+ CV_TRI_NOREG = CV_REG_NONE,
+
+ // General Purpose Data Registers
+
+ CV_TRI_D0 = 10,
+ CV_TRI_D1 = 11,
+ CV_TRI_D2 = 12,
+ CV_TRI_D3 = 13,
+ CV_TRI_D4 = 14,
+ CV_TRI_D5 = 15,
+ CV_TRI_D6 = 16,
+ CV_TRI_D7 = 17,
+ CV_TRI_D8 = 18,
+ CV_TRI_D9 = 19,
+ CV_TRI_D10 = 20,
+ CV_TRI_D11 = 21,
+ CV_TRI_D12 = 22,
+ CV_TRI_D13 = 23,
+ CV_TRI_D14 = 24,
+ CV_TRI_D15 = 25,
+
+ // General Purpose Address Registers
+
+ CV_TRI_A0 = 26,
+ CV_TRI_A1 = 27,
+ CV_TRI_A2 = 28,
+ CV_TRI_A3 = 29,
+ CV_TRI_A4 = 30,
+ CV_TRI_A5 = 31,
+ CV_TRI_A6 = 32,
+ CV_TRI_A7 = 33,
+ CV_TRI_A8 = 34,
+ CV_TRI_A9 = 35,
+ CV_TRI_A10 = 36,
+ CV_TRI_A11 = 37,
+ CV_TRI_A12 = 38,
+ CV_TRI_A13 = 39,
+ CV_TRI_A14 = 40,
+ CV_TRI_A15 = 41,
+
+ // Extended (64-bit) data registers
+
+ CV_TRI_E0 = 42,
+ CV_TRI_E2 = 43,
+ CV_TRI_E4 = 44,
+ CV_TRI_E6 = 45,
+ CV_TRI_E8 = 46,
+ CV_TRI_E10 = 47,
+ CV_TRI_E12 = 48,
+ CV_TRI_E14 = 49,
+
+ // Extended (64-bit) address registers
+
+ CV_TRI_EA0 = 50,
+ CV_TRI_EA2 = 51,
+ CV_TRI_EA4 = 52,
+ CV_TRI_EA6 = 53,
+ CV_TRI_EA8 = 54,
+ CV_TRI_EA10 = 55,
+ CV_TRI_EA12 = 56,
+ CV_TRI_EA14 = 57,
+
+ CV_TRI_PSW = 58,
+ CV_TRI_PCXI = 59,
+ CV_TRI_PC = 60,
+ CV_TRI_FCX = 61,
+ CV_TRI_LCX = 62,
+ CV_TRI_ISP = 63,
+ CV_TRI_ICR = 64,
+ CV_TRI_BIV = 65,
+ CV_TRI_BTV = 66,
+ CV_TRI_SYSCON = 67,
+ CV_TRI_DPRx_0 = 68,
+ CV_TRI_DPRx_1 = 69,
+ CV_TRI_DPRx_2 = 70,
+ CV_TRI_DPRx_3 = 71,
+ CV_TRI_CPRx_0 = 68,
+ CV_TRI_CPRx_1 = 69,
+ CV_TRI_CPRx_2 = 70,
+ CV_TRI_CPRx_3 = 71,
+ CV_TRI_DPMx_0 = 68,
+ CV_TRI_DPMx_1 = 69,
+ CV_TRI_DPMx_2 = 70,
+ CV_TRI_DPMx_3 = 71,
+ CV_TRI_CPMx_0 = 68,
+ CV_TRI_CPMx_1 = 69,
+ CV_TRI_CPMx_2 = 70,
+ CV_TRI_CPMx_3 = 71,
+ CV_TRI_DBGSSR = 72,
+ CV_TRI_EXEVT = 73,
+ CV_TRI_SWEVT = 74,
+ CV_TRI_CREVT = 75,
+ CV_TRI_TRnEVT = 76,
+ CV_TRI_MMUCON = 77,
+ CV_TRI_ASI = 78,
+ CV_TRI_TVA = 79,
+ CV_TRI_TPA = 80,
+ CV_TRI_TPX = 81,
+ CV_TRI_TFA = 82,
+
+ //
+ // Register set for the AM33 and related processors.
+ //
+
+ CV_AM33_NOREG = CV_REG_NONE,
+
+ // "Extended" (general purpose integer) registers
+ CV_AM33_E0 = 10,
+ CV_AM33_E1 = 11,
+ CV_AM33_E2 = 12,
+ CV_AM33_E3 = 13,
+ CV_AM33_E4 = 14,
+ CV_AM33_E5 = 15,
+ CV_AM33_E6 = 16,
+ CV_AM33_E7 = 17,
+
+ // Address registers
+ CV_AM33_A0 = 20,
+ CV_AM33_A1 = 21,
+ CV_AM33_A2 = 22,
+ CV_AM33_A3 = 23,
+
+ // Integer data registers
+ CV_AM33_D0 = 30,
+ CV_AM33_D1 = 31,
+ CV_AM33_D2 = 32,
+ CV_AM33_D3 = 33,
+
+ // (Single-precision) floating-point registers
+ CV_AM33_FS0 = 40,
+ CV_AM33_FS1 = 41,
+ CV_AM33_FS2 = 42,
+ CV_AM33_FS3 = 43,
+ CV_AM33_FS4 = 44,
+ CV_AM33_FS5 = 45,
+ CV_AM33_FS6 = 46,
+ CV_AM33_FS7 = 47,
+ CV_AM33_FS8 = 48,
+ CV_AM33_FS9 = 49,
+ CV_AM33_FS10 = 50,
+ CV_AM33_FS11 = 51,
+ CV_AM33_FS12 = 52,
+ CV_AM33_FS13 = 53,
+ CV_AM33_FS14 = 54,
+ CV_AM33_FS15 = 55,
+ CV_AM33_FS16 = 56,
+ CV_AM33_FS17 = 57,
+ CV_AM33_FS18 = 58,
+ CV_AM33_FS19 = 59,
+ CV_AM33_FS20 = 60,
+ CV_AM33_FS21 = 61,
+ CV_AM33_FS22 = 62,
+ CV_AM33_FS23 = 63,
+ CV_AM33_FS24 = 64,
+ CV_AM33_FS25 = 65,
+ CV_AM33_FS26 = 66,
+ CV_AM33_FS27 = 67,
+ CV_AM33_FS28 = 68,
+ CV_AM33_FS29 = 69,
+ CV_AM33_FS30 = 70,
+ CV_AM33_FS31 = 71,
+
+ // Special purpose registers
+
+ // Stack pointer
+ CV_AM33_SP = 80,
+
+ // Program counter
+ CV_AM33_PC = 81,
+
+ // Multiply-divide/accumulate registers
+ CV_AM33_MDR = 82,
+ CV_AM33_MDRQ = 83,
+ CV_AM33_MCRH = 84,
+ CV_AM33_MCRL = 85,
+ CV_AM33_MCVF = 86,
+
+ // CPU status words
+ CV_AM33_EPSW = 87,
+ CV_AM33_FPCR = 88,
+
+ // Loop buffer registers
+ CV_AM33_LIR = 89,
+ CV_AM33_LAR = 90,
+
+ //
+ // Register set for the Mitsubishi M32R
+ //
+
+ CV_M32R_NOREG = CV_REG_NONE,
+
+ CV_M32R_R0 = 10,
+ CV_M32R_R1 = 11,
+ CV_M32R_R2 = 12,
+ CV_M32R_R3 = 13,
+ CV_M32R_R4 = 14,
+ CV_M32R_R5 = 15,
+ CV_M32R_R6 = 16,
+ CV_M32R_R7 = 17,
+ CV_M32R_R8 = 18,
+ CV_M32R_R9 = 19,
+ CV_M32R_R10 = 20,
+ CV_M32R_R11 = 21,
+ CV_M32R_R12 = 22, // Gloabal Pointer, if used
+ CV_M32R_R13 = 23, // Frame Pointer, if allocated
+ CV_M32R_R14 = 24, // Link Register
+ CV_M32R_R15 = 25, // Stack Pointer
+ CV_M32R_PSW = 26, // Preocessor Status Register
+ CV_M32R_CBR = 27, // Condition Bit Register
+ CV_M32R_SPI = 28, // Interrupt Stack Pointer
+ CV_M32R_SPU = 29, // User Stack Pointer
+ CV_M32R_SPO = 30, // OS Stack Pointer
+ CV_M32R_BPC = 31, // Backup Program Counter
+ CV_M32R_ACHI = 32, // Accumulator High
+ CV_M32R_ACLO = 33, // Accumulator Low
+ CV_M32R_PC = 34, // Program Counter
+
+ //
+ // Register set for the SuperH SHMedia processor including compact
+ // mode
+ //
+
+ // Integer - 64 bit general registers
+ CV_SHMEDIA_NOREG = CV_REG_NONE,
+ CV_SHMEDIA_R0 = 10,
+ CV_SHMEDIA_R1 = 11,
+ CV_SHMEDIA_R2 = 12,
+ CV_SHMEDIA_R3 = 13,
+ CV_SHMEDIA_R4 = 14,
+ CV_SHMEDIA_R5 = 15,
+ CV_SHMEDIA_R6 = 16,
+ CV_SHMEDIA_R7 = 17,
+ CV_SHMEDIA_R8 = 18,
+ CV_SHMEDIA_R9 = 19,
+ CV_SHMEDIA_R10 = 20,
+ CV_SHMEDIA_R11 = 21,
+ CV_SHMEDIA_R12 = 22,
+ CV_SHMEDIA_R13 = 23,
+ CV_SHMEDIA_R14 = 24,
+ CV_SHMEDIA_R15 = 25,
+ CV_SHMEDIA_R16 = 26,
+ CV_SHMEDIA_R17 = 27,
+ CV_SHMEDIA_R18 = 28,
+ CV_SHMEDIA_R19 = 29,
+ CV_SHMEDIA_R20 = 30,
+ CV_SHMEDIA_R21 = 31,
+ CV_SHMEDIA_R22 = 32,
+ CV_SHMEDIA_R23 = 33,
+ CV_SHMEDIA_R24 = 34,
+ CV_SHMEDIA_R25 = 35,
+ CV_SHMEDIA_R26 = 36,
+ CV_SHMEDIA_R27 = 37,
+ CV_SHMEDIA_R28 = 38,
+ CV_SHMEDIA_R29 = 39,
+ CV_SHMEDIA_R30 = 40,
+ CV_SHMEDIA_R31 = 41,
+ CV_SHMEDIA_R32 = 42,
+ CV_SHMEDIA_R33 = 43,
+ CV_SHMEDIA_R34 = 44,
+ CV_SHMEDIA_R35 = 45,
+ CV_SHMEDIA_R36 = 46,
+ CV_SHMEDIA_R37 = 47,
+ CV_SHMEDIA_R38 = 48,
+ CV_SHMEDIA_R39 = 49,
+ CV_SHMEDIA_R40 = 50,
+ CV_SHMEDIA_R41 = 51,
+ CV_SHMEDIA_R42 = 52,
+ CV_SHMEDIA_R43 = 53,
+ CV_SHMEDIA_R44 = 54,
+ CV_SHMEDIA_R45 = 55,
+ CV_SHMEDIA_R46 = 56,
+ CV_SHMEDIA_R47 = 57,
+ CV_SHMEDIA_R48 = 58,
+ CV_SHMEDIA_R49 = 59,
+ CV_SHMEDIA_R50 = 60,
+ CV_SHMEDIA_R51 = 61,
+ CV_SHMEDIA_R52 = 62,
+ CV_SHMEDIA_R53 = 63,
+ CV_SHMEDIA_R54 = 64,
+ CV_SHMEDIA_R55 = 65,
+ CV_SHMEDIA_R56 = 66,
+ CV_SHMEDIA_R57 = 67,
+ CV_SHMEDIA_R58 = 68,
+ CV_SHMEDIA_R59 = 69,
+ CV_SHMEDIA_R60 = 70,
+ CV_SHMEDIA_R61 = 71,
+ CV_SHMEDIA_R62 = 72,
+ CV_SHMEDIA_R63 = 73,
+
+ // Target Registers - 32 bit
+ CV_SHMEDIA_TR0 = 74,
+ CV_SHMEDIA_TR1 = 75,
+ CV_SHMEDIA_TR2 = 76,
+ CV_SHMEDIA_TR3 = 77,
+ CV_SHMEDIA_TR4 = 78,
+ CV_SHMEDIA_TR5 = 79,
+ CV_SHMEDIA_TR6 = 80,
+ CV_SHMEDIA_TR7 = 81,
+ CV_SHMEDIA_TR8 = 82, // future-proof
+ CV_SHMEDIA_TR9 = 83, // future-proof
+ CV_SHMEDIA_TR10 = 84, // future-proof
+ CV_SHMEDIA_TR11 = 85, // future-proof
+ CV_SHMEDIA_TR12 = 86, // future-proof
+ CV_SHMEDIA_TR13 = 87, // future-proof
+ CV_SHMEDIA_TR14 = 88, // future-proof
+ CV_SHMEDIA_TR15 = 89, // future-proof
+
+ // Single - 32 bit fp registers
+ CV_SHMEDIA_FR0 = 128,
+ CV_SHMEDIA_FR1 = 129,
+ CV_SHMEDIA_FR2 = 130,
+ CV_SHMEDIA_FR3 = 131,
+ CV_SHMEDIA_FR4 = 132,
+ CV_SHMEDIA_FR5 = 133,
+ CV_SHMEDIA_FR6 = 134,
+ CV_SHMEDIA_FR7 = 135,
+ CV_SHMEDIA_FR8 = 136,
+ CV_SHMEDIA_FR9 = 137,
+ CV_SHMEDIA_FR10 = 138,
+ CV_SHMEDIA_FR11 = 139,
+ CV_SHMEDIA_FR12 = 140,
+ CV_SHMEDIA_FR13 = 141,
+ CV_SHMEDIA_FR14 = 142,
+ CV_SHMEDIA_FR15 = 143,
+ CV_SHMEDIA_FR16 = 144,
+ CV_SHMEDIA_FR17 = 145,
+ CV_SHMEDIA_FR18 = 146,
+ CV_SHMEDIA_FR19 = 147,
+ CV_SHMEDIA_FR20 = 148,
+ CV_SHMEDIA_FR21 = 149,
+ CV_SHMEDIA_FR22 = 150,
+ CV_SHMEDIA_FR23 = 151,
+ CV_SHMEDIA_FR24 = 152,
+ CV_SHMEDIA_FR25 = 153,
+ CV_SHMEDIA_FR26 = 154,
+ CV_SHMEDIA_FR27 = 155,
+ CV_SHMEDIA_FR28 = 156,
+ CV_SHMEDIA_FR29 = 157,
+ CV_SHMEDIA_FR30 = 158,
+ CV_SHMEDIA_FR31 = 159,
+ CV_SHMEDIA_FR32 = 160,
+ CV_SHMEDIA_FR33 = 161,
+ CV_SHMEDIA_FR34 = 162,
+ CV_SHMEDIA_FR35 = 163,
+ CV_SHMEDIA_FR36 = 164,
+ CV_SHMEDIA_FR37 = 165,
+ CV_SHMEDIA_FR38 = 166,
+ CV_SHMEDIA_FR39 = 167,
+ CV_SHMEDIA_FR40 = 168,
+ CV_SHMEDIA_FR41 = 169,
+ CV_SHMEDIA_FR42 = 170,
+ CV_SHMEDIA_FR43 = 171,
+ CV_SHMEDIA_FR44 = 172,
+ CV_SHMEDIA_FR45 = 173,
+ CV_SHMEDIA_FR46 = 174,
+ CV_SHMEDIA_FR47 = 175,
+ CV_SHMEDIA_FR48 = 176,
+ CV_SHMEDIA_FR49 = 177,
+ CV_SHMEDIA_FR50 = 178,
+ CV_SHMEDIA_FR51 = 179,
+ CV_SHMEDIA_FR52 = 180,
+ CV_SHMEDIA_FR53 = 181,
+ CV_SHMEDIA_FR54 = 182,
+ CV_SHMEDIA_FR55 = 183,
+ CV_SHMEDIA_FR56 = 184,
+ CV_SHMEDIA_FR57 = 185,
+ CV_SHMEDIA_FR58 = 186,
+ CV_SHMEDIA_FR59 = 187,
+ CV_SHMEDIA_FR60 = 188,
+ CV_SHMEDIA_FR61 = 189,
+ CV_SHMEDIA_FR62 = 190,
+ CV_SHMEDIA_FR63 = 191,
+
+ // Double - 64 bit synonyms for 32bit fp register pairs
+ // subtract 128 to find first base single register
+ CV_SHMEDIA_DR0 = 256,
+ CV_SHMEDIA_DR2 = 258,
+ CV_SHMEDIA_DR4 = 260,
+ CV_SHMEDIA_DR6 = 262,
+ CV_SHMEDIA_DR8 = 264,
+ CV_SHMEDIA_DR10 = 266,
+ CV_SHMEDIA_DR12 = 268,
+ CV_SHMEDIA_DR14 = 270,
+ CV_SHMEDIA_DR16 = 272,
+ CV_SHMEDIA_DR18 = 274,
+ CV_SHMEDIA_DR20 = 276,
+ CV_SHMEDIA_DR22 = 278,
+ CV_SHMEDIA_DR24 = 280,
+ CV_SHMEDIA_DR26 = 282,
+ CV_SHMEDIA_DR28 = 284,
+ CV_SHMEDIA_DR30 = 286,
+ CV_SHMEDIA_DR32 = 288,
+ CV_SHMEDIA_DR34 = 290,
+ CV_SHMEDIA_DR36 = 292,
+ CV_SHMEDIA_DR38 = 294,
+ CV_SHMEDIA_DR40 = 296,
+ CV_SHMEDIA_DR42 = 298,
+ CV_SHMEDIA_DR44 = 300,
+ CV_SHMEDIA_DR46 = 302,
+ CV_SHMEDIA_DR48 = 304,
+ CV_SHMEDIA_DR50 = 306,
+ CV_SHMEDIA_DR52 = 308,
+ CV_SHMEDIA_DR54 = 310,
+ CV_SHMEDIA_DR56 = 312,
+ CV_SHMEDIA_DR58 = 314,
+ CV_SHMEDIA_DR60 = 316,
+ CV_SHMEDIA_DR62 = 318,
+
+ // Vector - 128 bit synonyms for 32bit fp register quads
+ // subtract 384 to find first base single register
+ CV_SHMEDIA_FV0 = 512,
+ CV_SHMEDIA_FV4 = 516,
+ CV_SHMEDIA_FV8 = 520,
+ CV_SHMEDIA_FV12 = 524,
+ CV_SHMEDIA_FV16 = 528,
+ CV_SHMEDIA_FV20 = 532,
+ CV_SHMEDIA_FV24 = 536,
+ CV_SHMEDIA_FV28 = 540,
+ CV_SHMEDIA_FV32 = 544,
+ CV_SHMEDIA_FV36 = 548,
+ CV_SHMEDIA_FV40 = 552,
+ CV_SHMEDIA_FV44 = 556,
+ CV_SHMEDIA_FV48 = 560,
+ CV_SHMEDIA_FV52 = 564,
+ CV_SHMEDIA_FV56 = 568,
+ CV_SHMEDIA_FV60 = 572,
+
+ // Matrix - 512 bit synonyms for 16 adjacent 32bit fp registers
+ // subtract 896 to find first base single register
+ CV_SHMEDIA_MTRX0 = 1024,
+ CV_SHMEDIA_MTRX16 = 1040,
+ CV_SHMEDIA_MTRX32 = 1056,
+ CV_SHMEDIA_MTRX48 = 1072,
+
+ // Control - Implementation defined 64bit control registers
+ CV_SHMEDIA_CR0 = 2000,
+ CV_SHMEDIA_CR1 = 2001,
+ CV_SHMEDIA_CR2 = 2002,
+ CV_SHMEDIA_CR3 = 2003,
+ CV_SHMEDIA_CR4 = 2004,
+ CV_SHMEDIA_CR5 = 2005,
+ CV_SHMEDIA_CR6 = 2006,
+ CV_SHMEDIA_CR7 = 2007,
+ CV_SHMEDIA_CR8 = 2008,
+ CV_SHMEDIA_CR9 = 2009,
+ CV_SHMEDIA_CR10 = 2010,
+ CV_SHMEDIA_CR11 = 2011,
+ CV_SHMEDIA_CR12 = 2012,
+ CV_SHMEDIA_CR13 = 2013,
+ CV_SHMEDIA_CR14 = 2014,
+ CV_SHMEDIA_CR15 = 2015,
+ CV_SHMEDIA_CR16 = 2016,
+ CV_SHMEDIA_CR17 = 2017,
+ CV_SHMEDIA_CR18 = 2018,
+ CV_SHMEDIA_CR19 = 2019,
+ CV_SHMEDIA_CR20 = 2020,
+ CV_SHMEDIA_CR21 = 2021,
+ CV_SHMEDIA_CR22 = 2022,
+ CV_SHMEDIA_CR23 = 2023,
+ CV_SHMEDIA_CR24 = 2024,
+ CV_SHMEDIA_CR25 = 2025,
+ CV_SHMEDIA_CR26 = 2026,
+ CV_SHMEDIA_CR27 = 2027,
+ CV_SHMEDIA_CR28 = 2028,
+ CV_SHMEDIA_CR29 = 2029,
+ CV_SHMEDIA_CR30 = 2030,
+ CV_SHMEDIA_CR31 = 2031,
+ CV_SHMEDIA_CR32 = 2032,
+ CV_SHMEDIA_CR33 = 2033,
+ CV_SHMEDIA_CR34 = 2034,
+ CV_SHMEDIA_CR35 = 2035,
+ CV_SHMEDIA_CR36 = 2036,
+ CV_SHMEDIA_CR37 = 2037,
+ CV_SHMEDIA_CR38 = 2038,
+ CV_SHMEDIA_CR39 = 2039,
+ CV_SHMEDIA_CR40 = 2040,
+ CV_SHMEDIA_CR41 = 2041,
+ CV_SHMEDIA_CR42 = 2042,
+ CV_SHMEDIA_CR43 = 2043,
+ CV_SHMEDIA_CR44 = 2044,
+ CV_SHMEDIA_CR45 = 2045,
+ CV_SHMEDIA_CR46 = 2046,
+ CV_SHMEDIA_CR47 = 2047,
+ CV_SHMEDIA_CR48 = 2048,
+ CV_SHMEDIA_CR49 = 2049,
+ CV_SHMEDIA_CR50 = 2050,
+ CV_SHMEDIA_CR51 = 2051,
+ CV_SHMEDIA_CR52 = 2052,
+ CV_SHMEDIA_CR53 = 2053,
+ CV_SHMEDIA_CR54 = 2054,
+ CV_SHMEDIA_CR55 = 2055,
+ CV_SHMEDIA_CR56 = 2056,
+ CV_SHMEDIA_CR57 = 2057,
+ CV_SHMEDIA_CR58 = 2058,
+ CV_SHMEDIA_CR59 = 2059,
+ CV_SHMEDIA_CR60 = 2060,
+ CV_SHMEDIA_CR61 = 2061,
+ CV_SHMEDIA_CR62 = 2062,
+ CV_SHMEDIA_CR63 = 2063,
+
+ CV_SHMEDIA_FPSCR = 2064,
+
+ // Compact mode synonyms
+ CV_SHMEDIA_GBR = CV_SHMEDIA_R16,
+ CV_SHMEDIA_MACL = 90, // synonym for lower 32bits of media R17
+ CV_SHMEDIA_MACH = 91, // synonym for upper 32bits of media R17
+ CV_SHMEDIA_PR = CV_SHMEDIA_R18,
+ CV_SHMEDIA_T = 92, // synonym for lowest bit of media R19
+ CV_SHMEDIA_FPUL = CV_SHMEDIA_FR32,
+ CV_SHMEDIA_PC = 93,
+ CV_SHMEDIA_SR = CV_SHMEDIA_CR0,
+
+ //
+ // AMD64 registers
+ //
+
+ CV_AMD64_AL = 1,
+ CV_AMD64_CL = 2,
+ CV_AMD64_DL = 3,
+ CV_AMD64_BL = 4,
+ CV_AMD64_AH = 5,
+ CV_AMD64_CH = 6,
+ CV_AMD64_DH = 7,
+ CV_AMD64_BH = 8,
+ CV_AMD64_AX = 9,
+ CV_AMD64_CX = 10,
+ CV_AMD64_DX = 11,
+ CV_AMD64_BX = 12,
+ CV_AMD64_SP = 13,
+ CV_AMD64_BP = 14,
+ CV_AMD64_SI = 15,
+ CV_AMD64_DI = 16,
+ CV_AMD64_EAX = 17,
+ CV_AMD64_ECX = 18,
+ CV_AMD64_EDX = 19,
+ CV_AMD64_EBX = 20,
+ CV_AMD64_ESP = 21,
+ CV_AMD64_EBP = 22,
+ CV_AMD64_ESI = 23,
+ CV_AMD64_EDI = 24,
+ CV_AMD64_ES = 25,
+ CV_AMD64_CS = 26,
+ CV_AMD64_SS = 27,
+ CV_AMD64_DS = 28,
+ CV_AMD64_FS = 29,
+ CV_AMD64_GS = 30,
+ CV_AMD64_FLAGS = 32,
+ CV_AMD64_RIP = 33,
+ CV_AMD64_EFLAGS = 34,
+
+ // Control registers
+ CV_AMD64_CR0 = 80,
+ CV_AMD64_CR1 = 81,
+ CV_AMD64_CR2 = 82,
+ CV_AMD64_CR3 = 83,
+ CV_AMD64_CR4 = 84,
+ CV_AMD64_CR8 = 88,
+
+ // Debug registers
+ CV_AMD64_DR0 = 90,
+ CV_AMD64_DR1 = 91,
+ CV_AMD64_DR2 = 92,
+ CV_AMD64_DR3 = 93,
+ CV_AMD64_DR4 = 94,
+ CV_AMD64_DR5 = 95,
+ CV_AMD64_DR6 = 96,
+ CV_AMD64_DR7 = 97,
+ CV_AMD64_DR8 = 98,
+ CV_AMD64_DR9 = 99,
+ CV_AMD64_DR10 = 100,
+ CV_AMD64_DR11 = 101,
+ CV_AMD64_DR12 = 102,
+ CV_AMD64_DR13 = 103,
+ CV_AMD64_DR14 = 104,
+ CV_AMD64_DR15 = 105,
+
+ CV_AMD64_GDTR = 110,
+ CV_AMD64_GDTL = 111,
+ CV_AMD64_IDTR = 112,
+ CV_AMD64_IDTL = 113,
+ CV_AMD64_LDTR = 114,
+ CV_AMD64_TR = 115,
+
+ CV_AMD64_ST0 = 128,
+ CV_AMD64_ST1 = 129,
+ CV_AMD64_ST2 = 130,
+ CV_AMD64_ST3 = 131,
+ CV_AMD64_ST4 = 132,
+ CV_AMD64_ST5 = 133,
+ CV_AMD64_ST6 = 134,
+ CV_AMD64_ST7 = 135,
+ CV_AMD64_CTRL = 136,
+ CV_AMD64_STAT = 137,
+ CV_AMD64_TAG = 138,
+ CV_AMD64_FPIP = 139,
+ CV_AMD64_FPCS = 140,
+ CV_AMD64_FPDO = 141,
+ CV_AMD64_FPDS = 142,
+ CV_AMD64_ISEM = 143,
+ CV_AMD64_FPEIP = 144,
+ CV_AMD64_FPEDO = 145,
+
+ CV_AMD64_MM0 = 146,
+ CV_AMD64_MM1 = 147,
+ CV_AMD64_MM2 = 148,
+ CV_AMD64_MM3 = 149,
+ CV_AMD64_MM4 = 150,
+ CV_AMD64_MM5 = 151,
+ CV_AMD64_MM6 = 152,
+ CV_AMD64_MM7 = 153,
+
+ CV_AMD64_XMM0 = 154, // KATMAI registers
+ CV_AMD64_XMM1 = 155,
+ CV_AMD64_XMM2 = 156,
+ CV_AMD64_XMM3 = 157,
+ CV_AMD64_XMM4 = 158,
+ CV_AMD64_XMM5 = 159,
+ CV_AMD64_XMM6 = 160,
+ CV_AMD64_XMM7 = 161,
+
+ CV_AMD64_XMM0_0 = 162, // KATMAI sub-registers
+ CV_AMD64_XMM0_1 = 163,
+ CV_AMD64_XMM0_2 = 164,
+ CV_AMD64_XMM0_3 = 165,
+ CV_AMD64_XMM1_0 = 166,
+ CV_AMD64_XMM1_1 = 167,
+ CV_AMD64_XMM1_2 = 168,
+ CV_AMD64_XMM1_3 = 169,
+ CV_AMD64_XMM2_0 = 170,
+ CV_AMD64_XMM2_1 = 171,
+ CV_AMD64_XMM2_2 = 172,
+ CV_AMD64_XMM2_3 = 173,
+ CV_AMD64_XMM3_0 = 174,
+ CV_AMD64_XMM3_1 = 175,
+ CV_AMD64_XMM3_2 = 176,
+ CV_AMD64_XMM3_3 = 177,
+ CV_AMD64_XMM4_0 = 178,
+ CV_AMD64_XMM4_1 = 179,
+ CV_AMD64_XMM4_2 = 180,
+ CV_AMD64_XMM4_3 = 181,
+ CV_AMD64_XMM5_0 = 182,
+ CV_AMD64_XMM5_1 = 183,
+ CV_AMD64_XMM5_2 = 184,
+ CV_AMD64_XMM5_3 = 185,
+ CV_AMD64_XMM6_0 = 186,
+ CV_AMD64_XMM6_1 = 187,
+ CV_AMD64_XMM6_2 = 188,
+ CV_AMD64_XMM6_3 = 189,
+ CV_AMD64_XMM7_0 = 190,
+ CV_AMD64_XMM7_1 = 191,
+ CV_AMD64_XMM7_2 = 192,
+ CV_AMD64_XMM7_3 = 193,
+
+ CV_AMD64_XMM0L = 194,
+ CV_AMD64_XMM1L = 195,
+ CV_AMD64_XMM2L = 196,
+ CV_AMD64_XMM3L = 197,
+ CV_AMD64_XMM4L = 198,
+ CV_AMD64_XMM5L = 199,
+ CV_AMD64_XMM6L = 200,
+ CV_AMD64_XMM7L = 201,
+
+ CV_AMD64_XMM0H = 202,
+ CV_AMD64_XMM1H = 203,
+ CV_AMD64_XMM2H = 204,
+ CV_AMD64_XMM3H = 205,
+ CV_AMD64_XMM4H = 206,
+ CV_AMD64_XMM5H = 207,
+ CV_AMD64_XMM6H = 208,
+ CV_AMD64_XMM7H = 209,
+
+ CV_AMD64_MXCSR = 211, // XMM status register
+
+ CV_AMD64_EMM0L = 220, // XMM sub-registers (WNI integer)
+ CV_AMD64_EMM1L = 221,
+ CV_AMD64_EMM2L = 222,
+ CV_AMD64_EMM3L = 223,
+ CV_AMD64_EMM4L = 224,
+ CV_AMD64_EMM5L = 225,
+ CV_AMD64_EMM6L = 226,
+ CV_AMD64_EMM7L = 227,
+
+ CV_AMD64_EMM0H = 228,
+ CV_AMD64_EMM1H = 229,
+ CV_AMD64_EMM2H = 230,
+ CV_AMD64_EMM3H = 231,
+ CV_AMD64_EMM4H = 232,
+ CV_AMD64_EMM5H = 233,
+ CV_AMD64_EMM6H = 234,
+ CV_AMD64_EMM7H = 235,
+
+ // do not change the order of these regs, first one must be even too
+ CV_AMD64_MM00 = 236,
+ CV_AMD64_MM01 = 237,
+ CV_AMD64_MM10 = 238,
+ CV_AMD64_MM11 = 239,
+ CV_AMD64_MM20 = 240,
+ CV_AMD64_MM21 = 241,
+ CV_AMD64_MM30 = 242,
+ CV_AMD64_MM31 = 243,
+ CV_AMD64_MM40 = 244,
+ CV_AMD64_MM41 = 245,
+ CV_AMD64_MM50 = 246,
+ CV_AMD64_MM51 = 247,
+ CV_AMD64_MM60 = 248,
+ CV_AMD64_MM61 = 249,
+ CV_AMD64_MM70 = 250,
+ CV_AMD64_MM71 = 251,
+
+ // Extended KATMAI registers
+ CV_AMD64_XMM8 = 252, // KATMAI registers
+ CV_AMD64_XMM9 = 253,
+ CV_AMD64_XMM10 = 254,
+ CV_AMD64_XMM11 = 255,
+ CV_AMD64_XMM12 = 256,
+ CV_AMD64_XMM13 = 257,
+ CV_AMD64_XMM14 = 258,
+ CV_AMD64_XMM15 = 259,
+
+ CV_AMD64_XMM8_0 = 260, // KATMAI sub-registers
+ CV_AMD64_XMM8_1 = 261,
+ CV_AMD64_XMM8_2 = 262,
+ CV_AMD64_XMM8_3 = 263,
+ CV_AMD64_XMM9_0 = 264,
+ CV_AMD64_XMM9_1 = 265,
+ CV_AMD64_XMM9_2 = 266,
+ CV_AMD64_XMM9_3 = 267,
+ CV_AMD64_XMM10_0 = 268,
+ CV_AMD64_XMM10_1 = 269,
+ CV_AMD64_XMM10_2 = 270,
+ CV_AMD64_XMM10_3 = 271,
+ CV_AMD64_XMM11_0 = 272,
+ CV_AMD64_XMM11_1 = 273,
+ CV_AMD64_XMM11_2 = 274,
+ CV_AMD64_XMM11_3 = 275,
+ CV_AMD64_XMM12_0 = 276,
+ CV_AMD64_XMM12_1 = 277,
+ CV_AMD64_XMM12_2 = 278,
+ CV_AMD64_XMM12_3 = 279,
+ CV_AMD64_XMM13_0 = 280,
+ CV_AMD64_XMM13_1 = 281,
+ CV_AMD64_XMM13_2 = 282,
+ CV_AMD64_XMM13_3 = 283,
+ CV_AMD64_XMM14_0 = 284,
+ CV_AMD64_XMM14_1 = 285,
+ CV_AMD64_XMM14_2 = 286,
+ CV_AMD64_XMM14_3 = 287,
+ CV_AMD64_XMM15_0 = 288,
+ CV_AMD64_XMM15_1 = 289,
+ CV_AMD64_XMM15_2 = 290,
+ CV_AMD64_XMM15_3 = 291,
+
+ CV_AMD64_XMM8L = 292,
+ CV_AMD64_XMM9L = 293,
+ CV_AMD64_XMM10L = 294,
+ CV_AMD64_XMM11L = 295,
+ CV_AMD64_XMM12L = 296,
+ CV_AMD64_XMM13L = 297,
+ CV_AMD64_XMM14L = 298,
+ CV_AMD64_XMM15L = 299,
+
+ CV_AMD64_XMM8H = 300,
+ CV_AMD64_XMM9H = 301,
+ CV_AMD64_XMM10H = 302,
+ CV_AMD64_XMM11H = 303,
+ CV_AMD64_XMM12H = 304,
+ CV_AMD64_XMM13H = 305,
+ CV_AMD64_XMM14H = 306,
+ CV_AMD64_XMM15H = 307,
+
+ CV_AMD64_EMM8L = 308, // XMM sub-registers (WNI integer)
+ CV_AMD64_EMM9L = 309,
+ CV_AMD64_EMM10L = 310,
+ CV_AMD64_EMM11L = 311,
+ CV_AMD64_EMM12L = 312,
+ CV_AMD64_EMM13L = 313,
+ CV_AMD64_EMM14L = 314,
+ CV_AMD64_EMM15L = 315,
+
+ CV_AMD64_EMM8H = 316,
+ CV_AMD64_EMM9H = 317,
+ CV_AMD64_EMM10H = 318,
+ CV_AMD64_EMM11H = 319,
+ CV_AMD64_EMM12H = 320,
+ CV_AMD64_EMM13H = 321,
+ CV_AMD64_EMM14H = 322,
+ CV_AMD64_EMM15H = 323,
+
+ // Low byte forms of some standard registers
+ CV_AMD64_SIL = 324,
+ CV_AMD64_DIL = 325,
+ CV_AMD64_BPL = 326,
+ CV_AMD64_SPL = 327,
+
+ // 64-bit regular registers
+ CV_AMD64_RAX = 328,
+ CV_AMD64_RBX = 329,
+ CV_AMD64_RCX = 330,
+ CV_AMD64_RDX = 331,
+ CV_AMD64_RSI = 332,
+ CV_AMD64_RDI = 333,
+ CV_AMD64_RBP = 334,
+ CV_AMD64_RSP = 335,
+
+ // 64-bit integer registers with 8-, 16-, and 32-bit forms (B, W, and D)
+ CV_AMD64_R8 = 336,
+ CV_AMD64_R9 = 337,
+ CV_AMD64_R10 = 338,
+ CV_AMD64_R11 = 339,
+ CV_AMD64_R12 = 340,
+ CV_AMD64_R13 = 341,
+ CV_AMD64_R14 = 342,
+ CV_AMD64_R15 = 343,
+
+ CV_AMD64_R8B = 344,
+ CV_AMD64_R9B = 345,
+ CV_AMD64_R10B = 346,
+ CV_AMD64_R11B = 347,
+ CV_AMD64_R12B = 348,
+ CV_AMD64_R13B = 349,
+ CV_AMD64_R14B = 350,
+ CV_AMD64_R15B = 351,
+
+ CV_AMD64_R8W = 352,
+ CV_AMD64_R9W = 353,
+ CV_AMD64_R10W = 354,
+ CV_AMD64_R11W = 355,
+ CV_AMD64_R12W = 356,
+ CV_AMD64_R13W = 357,
+ CV_AMD64_R14W = 358,
+ CV_AMD64_R15W = 359,
+
+ CV_AMD64_R8D = 360,
+ CV_AMD64_R9D = 361,
+ CV_AMD64_R10D = 362,
+ CV_AMD64_R11D = 363,
+ CV_AMD64_R12D = 364,
+ CV_AMD64_R13D = 365,
+ CV_AMD64_R14D = 366,
+ CV_AMD64_R15D = 367,
+
+ // AVX registers 256 bits
+ CV_AMD64_YMM0 = 368,
+ CV_AMD64_YMM1 = 369,
+ CV_AMD64_YMM2 = 370,
+ CV_AMD64_YMM3 = 371,
+ CV_AMD64_YMM4 = 372,
+ CV_AMD64_YMM5 = 373,
+ CV_AMD64_YMM6 = 374,
+ CV_AMD64_YMM7 = 375,
+ CV_AMD64_YMM8 = 376,
+ CV_AMD64_YMM9 = 377,
+ CV_AMD64_YMM10 = 378,
+ CV_AMD64_YMM11 = 379,
+ CV_AMD64_YMM12 = 380,
+ CV_AMD64_YMM13 = 381,
+ CV_AMD64_YMM14 = 382,
+ CV_AMD64_YMM15 = 383,
+
+ // AVX registers upper 128 bits
+ CV_AMD64_YMM0H = 384,
+ CV_AMD64_YMM1H = 385,
+ CV_AMD64_YMM2H = 386,
+ CV_AMD64_YMM3H = 387,
+ CV_AMD64_YMM4H = 388,
+ CV_AMD64_YMM5H = 389,
+ CV_AMD64_YMM6H = 390,
+ CV_AMD64_YMM7H = 391,
+ CV_AMD64_YMM8H = 392,
+ CV_AMD64_YMM9H = 393,
+ CV_AMD64_YMM10H = 394,
+ CV_AMD64_YMM11H = 395,
+ CV_AMD64_YMM12H = 396,
+ CV_AMD64_YMM13H = 397,
+ CV_AMD64_YMM14H = 398,
+ CV_AMD64_YMM15H = 399,
+
+ // Lower/upper 8 bytes of XMM registers. Unlike CV_AMD64_XMM<regnum><H/L>,
+ // these
+ // values reprsesent the bit patterns of the registers as 64-bit integers, not
+ // the representation of these registers as a double.
+ CV_AMD64_XMM0IL = 400,
+ CV_AMD64_XMM1IL = 401,
+ CV_AMD64_XMM2IL = 402,
+ CV_AMD64_XMM3IL = 403,
+ CV_AMD64_XMM4IL = 404,
+ CV_AMD64_XMM5IL = 405,
+ CV_AMD64_XMM6IL = 406,
+ CV_AMD64_XMM7IL = 407,
+ CV_AMD64_XMM8IL = 408,
+ CV_AMD64_XMM9IL = 409,
+ CV_AMD64_XMM10IL = 410,
+ CV_AMD64_XMM11IL = 411,
+ CV_AMD64_XMM12IL = 412,
+ CV_AMD64_XMM13IL = 413,
+ CV_AMD64_XMM14IL = 414,
+ CV_AMD64_XMM15IL = 415,
+
+ CV_AMD64_XMM0IH = 416,
+ CV_AMD64_XMM1IH = 417,
+ CV_AMD64_XMM2IH = 418,
+ CV_AMD64_XMM3IH = 419,
+ CV_AMD64_XMM4IH = 420,
+ CV_AMD64_XMM5IH = 421,
+ CV_AMD64_XMM6IH = 422,
+ CV_AMD64_XMM7IH = 423,
+ CV_AMD64_XMM8IH = 424,
+ CV_AMD64_XMM9IH = 425,
+ CV_AMD64_XMM10IH = 426,
+ CV_AMD64_XMM11IH = 427,
+ CV_AMD64_XMM12IH = 428,
+ CV_AMD64_XMM13IH = 429,
+ CV_AMD64_XMM14IH = 430,
+ CV_AMD64_XMM15IH = 431,
+
+ CV_AMD64_YMM0I0 = 432, // AVX integer registers
+ CV_AMD64_YMM0I1 = 433,
+ CV_AMD64_YMM0I2 = 434,
+ CV_AMD64_YMM0I3 = 435,
+ CV_AMD64_YMM1I0 = 436,
+ CV_AMD64_YMM1I1 = 437,
+ CV_AMD64_YMM1I2 = 438,
+ CV_AMD64_YMM1I3 = 439,
+ CV_AMD64_YMM2I0 = 440,
+ CV_AMD64_YMM2I1 = 441,
+ CV_AMD64_YMM2I2 = 442,
+ CV_AMD64_YMM2I3 = 443,
+ CV_AMD64_YMM3I0 = 444,
+ CV_AMD64_YMM3I1 = 445,
+ CV_AMD64_YMM3I2 = 446,
+ CV_AMD64_YMM3I3 = 447,
+ CV_AMD64_YMM4I0 = 448,
+ CV_AMD64_YMM4I1 = 449,
+ CV_AMD64_YMM4I2 = 450,
+ CV_AMD64_YMM4I3 = 451,
+ CV_AMD64_YMM5I0 = 452,
+ CV_AMD64_YMM5I1 = 453,
+ CV_AMD64_YMM5I2 = 454,
+ CV_AMD64_YMM5I3 = 455,
+ CV_AMD64_YMM6I0 = 456,
+ CV_AMD64_YMM6I1 = 457,
+ CV_AMD64_YMM6I2 = 458,
+ CV_AMD64_YMM6I3 = 459,
+ CV_AMD64_YMM7I0 = 460,
+ CV_AMD64_YMM7I1 = 461,
+ CV_AMD64_YMM7I2 = 462,
+ CV_AMD64_YMM7I3 = 463,
+ CV_AMD64_YMM8I0 = 464,
+ CV_AMD64_YMM8I1 = 465,
+ CV_AMD64_YMM8I2 = 466,
+ CV_AMD64_YMM8I3 = 467,
+ CV_AMD64_YMM9I0 = 468,
+ CV_AMD64_YMM9I1 = 469,
+ CV_AMD64_YMM9I2 = 470,
+ CV_AMD64_YMM9I3 = 471,
+ CV_AMD64_YMM10I0 = 472,
+ CV_AMD64_YMM10I1 = 473,
+ CV_AMD64_YMM10I2 = 474,
+ CV_AMD64_YMM10I3 = 475,
+ CV_AMD64_YMM11I0 = 476,
+ CV_AMD64_YMM11I1 = 477,
+ CV_AMD64_YMM11I2 = 478,
+ CV_AMD64_YMM11I3 = 479,
+ CV_AMD64_YMM12I0 = 480,
+ CV_AMD64_YMM12I1 = 481,
+ CV_AMD64_YMM12I2 = 482,
+ CV_AMD64_YMM12I3 = 483,
+ CV_AMD64_YMM13I0 = 484,
+ CV_AMD64_YMM13I1 = 485,
+ CV_AMD64_YMM13I2 = 486,
+ CV_AMD64_YMM13I3 = 487,
+ CV_AMD64_YMM14I0 = 488,
+ CV_AMD64_YMM14I1 = 489,
+ CV_AMD64_YMM14I2 = 490,
+ CV_AMD64_YMM14I3 = 491,
+ CV_AMD64_YMM15I0 = 492,
+ CV_AMD64_YMM15I1 = 493,
+ CV_AMD64_YMM15I2 = 494,
+ CV_AMD64_YMM15I3 = 495,
+
+ CV_AMD64_YMM0F0 = 496, // AVX floating-point single precise registers
+ CV_AMD64_YMM0F1 = 497,
+ CV_AMD64_YMM0F2 = 498,
+ CV_AMD64_YMM0F3 = 499,
+ CV_AMD64_YMM0F4 = 500,
+ CV_AMD64_YMM0F5 = 501,
+ CV_AMD64_YMM0F6 = 502,
+ CV_AMD64_YMM0F7 = 503,
+ CV_AMD64_YMM1F0 = 504,
+ CV_AMD64_YMM1F1 = 505,
+ CV_AMD64_YMM1F2 = 506,
+ CV_AMD64_YMM1F3 = 507,
+ CV_AMD64_YMM1F4 = 508,
+ CV_AMD64_YMM1F5 = 509,
+ CV_AMD64_YMM1F6 = 510,
+ CV_AMD64_YMM1F7 = 511,
+ CV_AMD64_YMM2F0 = 512,
+ CV_AMD64_YMM2F1 = 513,
+ CV_AMD64_YMM2F2 = 514,
+ CV_AMD64_YMM2F3 = 515,
+ CV_AMD64_YMM2F4 = 516,
+ CV_AMD64_YMM2F5 = 517,
+ CV_AMD64_YMM2F6 = 518,
+ CV_AMD64_YMM2F7 = 519,
+ CV_AMD64_YMM3F0 = 520,
+ CV_AMD64_YMM3F1 = 521,
+ CV_AMD64_YMM3F2 = 522,
+ CV_AMD64_YMM3F3 = 523,
+ CV_AMD64_YMM3F4 = 524,
+ CV_AMD64_YMM3F5 = 525,
+ CV_AMD64_YMM3F6 = 526,
+ CV_AMD64_YMM3F7 = 527,
+ CV_AMD64_YMM4F0 = 528,
+ CV_AMD64_YMM4F1 = 529,
+ CV_AMD64_YMM4F2 = 530,
+ CV_AMD64_YMM4F3 = 531,
+ CV_AMD64_YMM4F4 = 532,
+ CV_AMD64_YMM4F5 = 533,
+ CV_AMD64_YMM4F6 = 534,
+ CV_AMD64_YMM4F7 = 535,
+ CV_AMD64_YMM5F0 = 536,
+ CV_AMD64_YMM5F1 = 537,
+ CV_AMD64_YMM5F2 = 538,
+ CV_AMD64_YMM5F3 = 539,
+ CV_AMD64_YMM5F4 = 540,
+ CV_AMD64_YMM5F5 = 541,
+ CV_AMD64_YMM5F6 = 542,
+ CV_AMD64_YMM5F7 = 543,
+ CV_AMD64_YMM6F0 = 544,
+ CV_AMD64_YMM6F1 = 545,
+ CV_AMD64_YMM6F2 = 546,
+ CV_AMD64_YMM6F3 = 547,
+ CV_AMD64_YMM6F4 = 548,
+ CV_AMD64_YMM6F5 = 549,
+ CV_AMD64_YMM6F6 = 550,
+ CV_AMD64_YMM6F7 = 551,
+ CV_AMD64_YMM7F0 = 552,
+ CV_AMD64_YMM7F1 = 553,
+ CV_AMD64_YMM7F2 = 554,
+ CV_AMD64_YMM7F3 = 555,
+ CV_AMD64_YMM7F4 = 556,
+ CV_AMD64_YMM7F5 = 557,
+ CV_AMD64_YMM7F6 = 558,
+ CV_AMD64_YMM7F7 = 559,
+ CV_AMD64_YMM8F0 = 560,
+ CV_AMD64_YMM8F1 = 561,
+ CV_AMD64_YMM8F2 = 562,
+ CV_AMD64_YMM8F3 = 563,
+ CV_AMD64_YMM8F4 = 564,
+ CV_AMD64_YMM8F5 = 565,
+ CV_AMD64_YMM8F6 = 566,
+ CV_AMD64_YMM8F7 = 567,
+ CV_AMD64_YMM9F0 = 568,
+ CV_AMD64_YMM9F1 = 569,
+ CV_AMD64_YMM9F2 = 570,
+ CV_AMD64_YMM9F3 = 571,
+ CV_AMD64_YMM9F4 = 572,
+ CV_AMD64_YMM9F5 = 573,
+ CV_AMD64_YMM9F6 = 574,
+ CV_AMD64_YMM9F7 = 575,
+ CV_AMD64_YMM10F0 = 576,
+ CV_AMD64_YMM10F1 = 577,
+ CV_AMD64_YMM10F2 = 578,
+ CV_AMD64_YMM10F3 = 579,
+ CV_AMD64_YMM10F4 = 580,
+ CV_AMD64_YMM10F5 = 581,
+ CV_AMD64_YMM10F6 = 582,
+ CV_AMD64_YMM10F7 = 583,
+ CV_AMD64_YMM11F0 = 584,
+ CV_AMD64_YMM11F1 = 585,
+ CV_AMD64_YMM11F2 = 586,
+ CV_AMD64_YMM11F3 = 587,
+ CV_AMD64_YMM11F4 = 588,
+ CV_AMD64_YMM11F5 = 589,
+ CV_AMD64_YMM11F6 = 590,
+ CV_AMD64_YMM11F7 = 591,
+ CV_AMD64_YMM12F0 = 592,
+ CV_AMD64_YMM12F1 = 593,
+ CV_AMD64_YMM12F2 = 594,
+ CV_AMD64_YMM12F3 = 595,
+ CV_AMD64_YMM12F4 = 596,
+ CV_AMD64_YMM12F5 = 597,
+ CV_AMD64_YMM12F6 = 598,
+ CV_AMD64_YMM12F7 = 599,
+ CV_AMD64_YMM13F0 = 600,
+ CV_AMD64_YMM13F1 = 601,
+ CV_AMD64_YMM13F2 = 602,
+ CV_AMD64_YMM13F3 = 603,
+ CV_AMD64_YMM13F4 = 604,
+ CV_AMD64_YMM13F5 = 605,
+ CV_AMD64_YMM13F6 = 606,
+ CV_AMD64_YMM13F7 = 607,
+ CV_AMD64_YMM14F0 = 608,
+ CV_AMD64_YMM14F1 = 609,
+ CV_AMD64_YMM14F2 = 610,
+ CV_AMD64_YMM14F3 = 611,
+ CV_AMD64_YMM14F4 = 612,
+ CV_AMD64_YMM14F5 = 613,
+ CV_AMD64_YMM14F6 = 614,
+ CV_AMD64_YMM14F7 = 615,
+ CV_AMD64_YMM15F0 = 616,
+ CV_AMD64_YMM15F1 = 617,
+ CV_AMD64_YMM15F2 = 618,
+ CV_AMD64_YMM15F3 = 619,
+ CV_AMD64_YMM15F4 = 620,
+ CV_AMD64_YMM15F5 = 621,
+ CV_AMD64_YMM15F6 = 622,
+ CV_AMD64_YMM15F7 = 623,
+
+ CV_AMD64_YMM0D0 = 624, // AVX floating-point double precise registers
+ CV_AMD64_YMM0D1 = 625,
+ CV_AMD64_YMM0D2 = 626,
+ CV_AMD64_YMM0D3 = 627,
+ CV_AMD64_YMM1D0 = 628,
+ CV_AMD64_YMM1D1 = 629,
+ CV_AMD64_YMM1D2 = 630,
+ CV_AMD64_YMM1D3 = 631,
+ CV_AMD64_YMM2D0 = 632,
+ CV_AMD64_YMM2D1 = 633,
+ CV_AMD64_YMM2D2 = 634,
+ CV_AMD64_YMM2D3 = 635,
+ CV_AMD64_YMM3D0 = 636,
+ CV_AMD64_YMM3D1 = 637,
+ CV_AMD64_YMM3D2 = 638,
+ CV_AMD64_YMM3D3 = 639,
+ CV_AMD64_YMM4D0 = 640,
+ CV_AMD64_YMM4D1 = 641,
+ CV_AMD64_YMM4D2 = 642,
+ CV_AMD64_YMM4D3 = 643,
+ CV_AMD64_YMM5D0 = 644,
+ CV_AMD64_YMM5D1 = 645,
+ CV_AMD64_YMM5D2 = 646,
+ CV_AMD64_YMM5D3 = 647,
+ CV_AMD64_YMM6D0 = 648,
+ CV_AMD64_YMM6D1 = 649,
+ CV_AMD64_YMM6D2 = 650,
+ CV_AMD64_YMM6D3 = 651,
+ CV_AMD64_YMM7D0 = 652,
+ CV_AMD64_YMM7D1 = 653,
+ CV_AMD64_YMM7D2 = 654,
+ CV_AMD64_YMM7D3 = 655,
+ CV_AMD64_YMM8D0 = 656,
+ CV_AMD64_YMM8D1 = 657,
+ CV_AMD64_YMM8D2 = 658,
+ CV_AMD64_YMM8D3 = 659,
+ CV_AMD64_YMM9D0 = 660,
+ CV_AMD64_YMM9D1 = 661,
+ CV_AMD64_YMM9D2 = 662,
+ CV_AMD64_YMM9D3 = 663,
+ CV_AMD64_YMM10D0 = 664,
+ CV_AMD64_YMM10D1 = 665,
+ CV_AMD64_YMM10D2 = 666,
+ CV_AMD64_YMM10D3 = 667,
+ CV_AMD64_YMM11D0 = 668,
+ CV_AMD64_YMM11D1 = 669,
+ CV_AMD64_YMM11D2 = 670,
+ CV_AMD64_YMM11D3 = 671,
+ CV_AMD64_YMM12D0 = 672,
+ CV_AMD64_YMM12D1 = 673,
+ CV_AMD64_YMM12D2 = 674,
+ CV_AMD64_YMM12D3 = 675,
+ CV_AMD64_YMM13D0 = 676,
+ CV_AMD64_YMM13D1 = 677,
+ CV_AMD64_YMM13D2 = 678,
+ CV_AMD64_YMM13D3 = 679,
+ CV_AMD64_YMM14D0 = 680,
+ CV_AMD64_YMM14D1 = 681,
+ CV_AMD64_YMM14D2 = 682,
+ CV_AMD64_YMM14D3 = 683,
+ CV_AMD64_YMM15D0 = 684,
+ CV_AMD64_YMM15D1 = 685,
+ CV_AMD64_YMM15D2 = 686,
+ CV_AMD64_YMM15D3 = 687
+
+ // Note: Next set of platform registers need to go into a new enum...
+ // this one is above 44K now.
+
+} CV_HREG_e;
+
+typedef enum CV_HLSLREG_e {
+ CV_HLSLREG_TEMP = 0,
+ CV_HLSLREG_INPUT = 1,
+ CV_HLSLREG_OUTPUT = 2,
+ CV_HLSLREG_INDEXABLE_TEMP = 3,
+ CV_HLSLREG_IMMEDIATE32 = 4,
+ CV_HLSLREG_IMMEDIATE64 = 5,
+ CV_HLSLREG_SAMPLER = 6,
+ CV_HLSLREG_RESOURCE = 7,
+ CV_HLSLREG_CONSTANT_BUFFER = 8,
+ CV_HLSLREG_IMMEDIATE_CONSTANT_BUFFER = 9,
+ CV_HLSLREG_LABEL = 10,
+ CV_HLSLREG_INPUT_PRIMITIVEID = 11,
+ CV_HLSLREG_OUTPUT_DEPTH = 12,
+ CV_HLSLREG_NULL = 13,
+ CV_HLSLREG_RASTERIZER = 14,
+ CV_HLSLREG_OUTPUT_COVERAGE_MASK = 15,
+ CV_HLSLREG_STREAM = 16,
+ CV_HLSLREG_FUNCTION_BODY = 17,
+ CV_HLSLREG_FUNCTION_TABLE = 18,
+ CV_HLSLREG_INTERFACE = 19,
+ CV_HLSLREG_FUNCTION_INPUT = 20,
+ CV_HLSLREG_FUNCTION_OUTPUT = 21,
+ CV_HLSLREG_OUTPUT_CONTROL_POINT_ID = 22,
+ CV_HLSLREG_INPUT_FORK_INSTANCE_ID = 23,
+ CV_HLSLREG_INPUT_JOIN_INSTANCE_ID = 24,
+ CV_HLSLREG_INPUT_CONTROL_POINT = 25,
+ CV_HLSLREG_OUTPUT_CONTROL_POINT = 26,
+ CV_HLSLREG_INPUT_PATCH_CONSTANT = 27,
+ CV_HLSLREG_INPUT_DOMAIN_POINT = 28,
+ CV_HLSLREG_THIS_POINTER = 29,
+ CV_HLSLREG_UNORDERED_ACCESS_VIEW = 30,
+ CV_HLSLREG_THREAD_GROUP_SHARED_MEMORY = 31,
+ CV_HLSLREG_INPUT_THREAD_ID = 32,
+ CV_HLSLREG_INPUT_THREAD_GROUP_ID = 33,
+ CV_HLSLREG_INPUT_THREAD_ID_IN_GROUP = 34,
+ CV_HLSLREG_INPUT_COVERAGE_MASK = 35,
+ CV_HLSLREG_INPUT_THREAD_ID_IN_GROUP_FLATTENED = 36,
+ CV_HLSLREG_INPUT_GS_INSTANCE_ID = 37,
+ CV_HLSLREG_OUTPUT_DEPTH_GREATER_EQUAL = 38,
+ CV_HLSLREG_OUTPUT_DEPTH_LESS_EQUAL = 39,
+ CV_HLSLREG_CYCLE_COUNTER = 40,
+} CV_HLSLREG_e;
+
+enum StackFrameTypeEnum {
+ FrameTypeFPO, // Frame pointer omitted, FPO info available
+ FrameTypeTrap, // Kernel Trap frame
+ FrameTypeTSS, // Kernel Trap frame
+ FrameTypeStandard, // Standard EBP stackframe
+ FrameTypeFrameData, // Frame pointer omitted, FrameData info available
+
+ FrameTypeUnknown = -1, // Frame which does not have any debug info
+};
+
+enum MemoryTypeEnum {
+ MemTypeCode, // Read only code memory
+ MemTypeData, // Read only data/stack memory
+ MemTypeStack, // Read only stack memory
+ MemTypeCodeOnHeap, // Read only memory for code generated on heap by runtime
+
+ MemTypeAny = -1,
+};
+
+typedef enum CV_HLSLMemorySpace_e {
+ // HLSL specific memory spaces
+
+ CV_HLSL_MEMSPACE_DATA = 0x00,
+ CV_HLSL_MEMSPACE_SAMPLER = 0x01,
+ CV_HLSL_MEMSPACE_RESOURCE = 0x02,
+ CV_HLSL_MEMSPACE_RWRESOURCE = 0x03,
+
+ CV_HLSL_MEMSPACE_MAX = 0x0F,
+} CV_HLSLMemorySpace_e;
+
+#endif
diff --git a/src/Native/ObjWriter/jitDebugInfo.h b/src/Native/ObjWriter/jitDebugInfo.h
new file mode 100644
index 000000000..103dff8ad
--- /dev/null
+++ b/src/Native/ObjWriter/jitDebugInfo.h
@@ -0,0 +1,43 @@
+#ifndef JIT_DEBUG_INFO_H
+#define JIT_DEBUG_INFO_H
+
+typedef unsigned int DWORD;
+#define _TARGET_AMD64_ 1
+
+#include "cordebuginfo.h"
+#include "cvconst.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+
+struct DebugLocInfo {
+ int NativeOffset;
+ int FileId;
+ int LineNumber;
+ int ColNumber;
+};
+
+struct DebugVarInfo {
+ std::string Name;
+ int TypeIndex;
+ bool IsParam;
+ std::vector<ICorDebugInfo::NativeVarInfo> Ranges;
+
+ DebugVarInfo() {}
+ DebugVarInfo(char *ArgName, int ArgTypeIndex, bool ArgIsParam)
+ : Name(ArgName), TypeIndex(ArgTypeIndex), IsParam(ArgIsParam) {}
+};
+
+typedef unsigned short CVRegMapping;
+
+#define CVREGDAT(p2, cv) cv
+
+const CVRegMapping cvRegMapAmd64[] = {
+ CVREGDAT(REGNUM_RAX, CV_AMD64_RAX), CVREGDAT(REGNUM_RCX, CV_AMD64_RCX),
+ CVREGDAT(REGNUM_RDX, CV_AMD64_RDX), CVREGDAT(REGNUM_RBX, CV_AMD64_RBX),
+ CVREGDAT(REGNUM_RSP, CV_AMD64_RSP), CVREGDAT(REGNUM_RBP, CV_AMD64_RBP),
+ CVREGDAT(REGNUM_RSI, CV_AMD64_RSI), CVREGDAT(REGNUM_RDI, CV_AMD64_RDI),
+ CVREGDAT(REGNUM_R8, CV_AMD64_R8), CVREGDAT(REGNUM_R9, CV_AMD64_R9),
+ CVREGDAT(REGNUM_R10, CV_AMD64_R10), CVREGDAT(REGNUM_R11, CV_AMD64_R11),
+ CVREGDAT(REGNUM_R12, CV_AMD64_R12), CVREGDAT(REGNUM_R13, CV_AMD64_R13),
+ CVREGDAT(REGNUM_R14, CV_AMD64_R14), CVREGDAT(REGNUM_R15, CV_AMD64_R15)};
+
+#endif // JIT_DEBUG_INFO_H
diff --git a/src/Native/ObjWriter/llvm.patch b/src/Native/ObjWriter/llvm.patch
new file mode 100644
index 000000000..2dde952d5
--- /dev/null
+++ b/src/Native/ObjWriter/llvm.patch
@@ -0,0 +1,123 @@
+diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
+index 7c1189e46ab..d1d77c97311 100644
+--- a/include/llvm/MC/MCObjectStreamer.h
++++ b/include/llvm/MC/MCObjectStreamer.h
+@@ -101,6 +101,11 @@ public:
+ void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
+ bool = false) override;
+
++ /// \brief EmitValueImpl with additional param, that allows to emit PCRelative
++ /// MCFixup.
++ void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc,
++ bool isPCRelative);
++
+ /// \brief Emit an instruction to a special fragment, because this instruction
+ /// can change its size during relaxation.
+ virtual void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &);
+diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
+index 174397e2739..ef7161fb56c 100644
+--- a/lib/MC/MCObjectStreamer.cpp
++++ b/lib/MC/MCObjectStreamer.cpp
+@@ -122,7 +122,7 @@ void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) {
+ }
+
+ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
+- SMLoc Loc) {
++ SMLoc Loc, bool isPCRelative) {
+ MCStreamer::EmitValueImpl(Value, Size, Loc);
+ MCDataFragment *DF = getOrCreateDataFragment();
+ flushPendingLabels(DF, DF->getContents().size());
+@@ -143,10 +143,16 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
+ }
+ DF->getFixups().push_back(
+ MCFixup::create(DF->getContents().size(), Value,
+- MCFixup::getKindForSize(Size, false), Loc));
++ MCFixup::getKindForSize(Size, isPCRelative), Loc));
+ DF->getContents().resize(DF->getContents().size() + Size, 0);
+ }
+
++
++void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
++ SMLoc Loc) {
++ EmitValueImpl(Value, Size, Loc, false);
++}
++
+ void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
+ // We need to create a local symbol to avoid relocations.
+ Frame.Begin = getContext().createTempSymbol();
+diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+index a77df7a2598..e1aa7526f9b 100644
+--- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
++++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+@@ -48,6 +48,14 @@ public:
+ };
+ } // end anonymous namespace
+
++Optional<MCFixupKind> ARMAsmBackend::getFixupKind(StringRef Name) const {
++ return StringSwitch<Optional<MCFixupKind>>(Name)
++ .Case("R_ARM_THM_MOVW_ABS_NC", (MCFixupKind)ARM::fixup_t2_movw_lo16)
++ .Case("R_ARM_THM_MOVT_ABS", (MCFixupKind)ARM::fixup_t2_movt_hi16)
++ .Case("R_ARM_THM_JUMP24", (MCFixupKind)ARM::fixup_arm_thumb_blx)
++ .Default(MCAsmBackend::getFixupKind(Name));
++}
++
+ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
+ const static MCFixupKindInfo InfosLE[ARM::NumTargetFixupKinds] = {
+ // This table *must* be in the order that the fixup_* kinds are defined in
+@@ -386,6 +394,8 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
+ case FK_Data_2:
+ case FK_Data_4:
+ return Value;
++ case FK_PCRel_4:
++ return Value;
+ case FK_SecRel_2:
+ return Value;
+ case FK_SecRel_4:
+@@ -825,6 +835,9 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
+ case ARM::fixup_t2_so_imm:
+ return 4;
+
++ case FK_PCRel_4:
++ return 4;
++
+ case FK_SecRel_2:
+ return 2;
+ case FK_SecRel_4:
+diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
+index 02374966daf..01676a01683 100644
+--- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
++++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
+@@ -36,6 +36,7 @@ public:
+
+ bool hasNOP() const { return STI->getFeatureBits()[ARM::HasV6T2Ops]; }
+
++ Optional<MCFixupKind> getFixupKind(StringRef Name) const override;
+ const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
+
+ bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
+diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
+index 59f31be69d5..9b95598f99f 100644
+--- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
++++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
+@@ -103,6 +103,9 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
+ break;
+ }
+ break;
++ case FK_PCRel_4:
++ Type = ELF::R_ARM_REL32;
++ break;
+ case ARM::fixup_arm_blx:
+ case ARM::fixup_arm_uncondbl:
+ switch (Modifier) {
+diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
+index b654b8c5cb8..58d25159af8 100644
+--- a/tools/CMakeLists.txt
++++ b/tools/CMakeLists.txt
+@@ -46,6 +46,7 @@ add_llvm_external_project(clang)
+ add_llvm_external_project(llgo)
+ add_llvm_external_project(lld)
+ add_llvm_external_project(lldb)
++add_llvm_external_project(ObjWriter)
+
+ # Automatically add remaining sub-directories containing a 'CMakeLists.txt'
+ # file as external projects.
diff --git a/src/Native/ObjWriter/objwriter.cpp b/src/Native/ObjWriter/objwriter.cpp
new file mode 100644
index 000000000..5f22998a2
--- /dev/null
+++ b/src/Native/ObjWriter/objwriter.cpp
@@ -0,0 +1,806 @@
+//===---- objwriter.cpp --------------------------------*- C++ -*-===//
+//
+// object writer
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license.
+// See LICENSE file in the project root for full license information.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Implementation of object writer API for JIT/AOT
+///
+//===----------------------------------------------------------------------===//
+
+#include "objwriter.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCParser/AsmLexer.h"
+#include "llvm/MC/MCParser/MCTargetAsmParser.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSectionCOFF.h"
+#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compression.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/Win64EH.h"
+#include "llvm/Target/TargetMachine.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+bool error(const Twine &Error) {
+ errs() << Twine("error: ") + Error + "\n";
+ return false;
+}
+
+void ObjectWriter::InitTripleName() {
+ TripleName = sys::getDefaultTargetTriple();
+}
+
+Triple ObjectWriter::GetTriple() {
+ Triple TheTriple(TripleName);
+
+ if (TheTriple.getOS() == Triple::OSType::Darwin) {
+ TheTriple = Triple(
+ TheTriple.getArchName(), TheTriple.getVendorName(), "darwin",
+ TheTriple
+ .getEnvironmentName()); // it is workaround for llvm bug
+ // https://bugs.llvm.org//show_bug.cgi?id=24927.
+ }
+ return TheTriple;
+}
+
+bool ObjectWriter::Init(llvm::StringRef ObjectFilePath) {
+ llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+
+ // Initialize targets
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
+
+ TargetMOptions = InitMCTargetOptionsFromFlags();
+
+ InitTripleName();
+ Triple TheTriple = GetTriple();
+
+ // Get the target specific parser.
+ std::string TargetError;
+ const Target *TheTarget =
+ TargetRegistry::lookupTarget(TripleName, TargetError);
+ if (!TheTarget) {
+ return error("Unable to create target for " + ObjectFilePath + ": " +
+ TargetError);
+ }
+
+ std::error_code EC;
+ OS.reset(new raw_fd_ostream(ObjectFilePath, EC, sys::fs::F_None));
+ if (EC)
+ return error("Unable to create file for " + ObjectFilePath + ": " +
+ EC.message());
+
+ RegisterInfo.reset(TheTarget->createMCRegInfo(TripleName));
+ if (!RegisterInfo)
+ return error("Unable to create target register info!");
+
+ AsmInfo.reset(TheTarget->createMCAsmInfo(*RegisterInfo, TripleName));
+ if (!AsmInfo)
+ return error("Unable to create target asm info!");
+
+ ObjFileInfo.reset(new MCObjectFileInfo);
+ OutContext.reset(
+ new MCContext(AsmInfo.get(), RegisterInfo.get(), ObjFileInfo.get()));
+ ObjFileInfo->InitMCObjectFileInfo(TheTriple, false, CodeModel::Default,
+ *OutContext);
+
+ InstrInfo.reset(TheTarget->createMCInstrInfo());
+ if (!InstrInfo)
+ return error("no instr info info for target " + TripleName);
+
+ std::string FeaturesStr;
+ std::string MCPU;
+ SubtargetInfo.reset(
+ TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
+ if (!SubtargetInfo)
+ return error("no subtarget info for target " + TripleName);
+
+ CodeEmitter =
+ TheTarget->createMCCodeEmitter(*InstrInfo, *RegisterInfo, *OutContext);
+ if (!CodeEmitter)
+ return error("no code emitter for target " + TripleName);
+
+ AsmBackend = TheTarget->createMCAsmBackend(*RegisterInfo, TripleName, MCPU,
+ TargetMOptions);
+ if (!AsmBackend)
+ return error("no asm backend for target " + TripleName);
+
+ Streamer = (MCObjectStreamer *)TheTarget->createMCObjectStreamer(
+ TheTriple, *OutContext, *AsmBackend, *OS, CodeEmitter, *SubtargetInfo,
+ RelaxAll,
+ /*IncrementalLinkerCompatible*/ true,
+ /*DWARFMustBeAtTheEnd*/ false);
+ if (!Streamer)
+ return error("no object streamer for target " + TripleName);
+ Assembler = &Streamer->getAssembler();
+
+ TMachine.reset(TheTarget->createTargetMachine(TripleName, MCPU, FeaturesStr,
+ TargetOptions(), None));
+ if (!TMachine)
+ return error("no target machine for target " + TripleName);
+
+ AssemblerPrinter.reset(TheTarget->createAsmPrinter(
+ *TMachine, std::unique_ptr<MCStreamer>(Streamer)));
+ if (!AssemblerPrinter)
+ return error("no asm printer for target " + TripleName);
+
+ FrameOpened = false;
+ FuncId = 1;
+
+ SetCodeSectionAttribute("text", CustomSectionAttributes_Executable, nullptr);
+
+ if (ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF) {
+ TypeBuilder.SetStreamer(Streamer);
+ unsigned TargetPointerSize = AssemblerPrinter->getPointerSize();
+ TypeBuilder.SetTargetPointerSize(TargetPointerSize);
+ }
+
+ return true;
+}
+
+void ObjectWriter::Finish() { Streamer->Finish(); }
+
+void ObjectWriter::SwitchSection(const char *SectionName,
+ CustomSectionAttributes attributes,
+ const char *ComdatName) {
+ MCSection *Section = GetSection(SectionName, attributes, ComdatName);
+ Streamer->SwitchSection(Section);
+ if (Sections.count(Section) == 0) {
+ Sections.insert(Section);
+ if (ObjFileInfo->getObjectFileType() == ObjFileInfo->IsMachO) {
+ assert(!Section->getBeginSymbol());
+ // Output a DWARF linker-local symbol.
+ // This symbol is used as a base for other symbols in a section.
+ MCSymbol *SectionStartSym = OutContext->createTempSymbol();
+ Streamer->EmitLabel(SectionStartSym);
+ Section->setBeginSymbol(SectionStartSym);
+ }
+ }
+}
+
+MCSection *ObjectWriter::GetSection(const char *SectionName,
+ CustomSectionAttributes attributes,
+ const char *ComdatName) {
+ MCSection *Section = nullptr;
+
+ if (strcmp(SectionName, "text") == 0) {
+ Section = ObjFileInfo->getTextSection();
+ } else if (strcmp(SectionName, "data") == 0) {
+ Section = ObjFileInfo->getDataSection();
+ } else if (strcmp(SectionName, "rdata") == 0) {
+ Section = ObjFileInfo->getReadOnlySection();
+ } else if (strcmp(SectionName, "xdata") == 0) {
+ Section = ObjFileInfo->getXDataSection();
+ } else {
+ Section = GetSpecificSection(SectionName, attributes, ComdatName);
+ }
+ assert(Section);
+ return Section;
+}
+
+MCSection *ObjectWriter::GetSpecificSection(const char *SectionName,
+ CustomSectionAttributes attributes,
+ const char *ComdatName) {
+ Triple TheTriple(TripleName);
+ MCSection *Section = nullptr;
+ SectionKind Kind = (attributes & CustomSectionAttributes_Executable)
+ ? SectionKind::getText()
+ : (attributes & CustomSectionAttributes_Writeable)
+ ? SectionKind::getData()
+ : SectionKind::getReadOnly();
+ switch (TheTriple.getObjectFormat()) {
+ case Triple::MachO: {
+ unsigned typeAndAttributes = 0;
+ if (attributes & CustomSectionAttributes_MachO_Init_Func_Pointers) {
+ typeAndAttributes |= MachO::SectionType::S_MOD_INIT_FUNC_POINTERS;
+ }
+ Section = OutContext->getMachOSection(
+ (attributes & CustomSectionAttributes_Executable) ? "__TEXT" : "__DATA",
+ SectionName, typeAndAttributes, Kind);
+ break;
+ }
+ case Triple::COFF: {
+ unsigned Characteristics = COFF::IMAGE_SCN_MEM_READ;
+
+ if (attributes & CustomSectionAttributes_Executable) {
+ Characteristics |= COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE;
+ } else if (attributes & CustomSectionAttributes_Writeable) {
+ Characteristics |=
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_WRITE;
+ } else {
+ Characteristics |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
+ }
+
+ if (ComdatName != nullptr) {
+ Section = OutContext->getCOFFSection(
+ SectionName, Characteristics | COFF::IMAGE_SCN_LNK_COMDAT, Kind,
+ ComdatName, COFF::COMDATType::IMAGE_COMDAT_SELECT_ANY);
+ } else {
+ Section = OutContext->getCOFFSection(SectionName, Characteristics, Kind);
+ }
+ break;
+ }
+ case Triple::ELF: {
+ unsigned Flags = ELF::SHF_ALLOC;
+ if (ComdatName != nullptr) {
+ MCSymbolELF *GroupSym =
+ cast<MCSymbolELF>(OutContext->getOrCreateSymbol(ComdatName));
+ OutContext->createELFGroupSection(GroupSym);
+ Flags |= ELF::SHF_GROUP;
+ }
+ if (attributes & CustomSectionAttributes_Executable) {
+ Flags |= ELF::SHF_EXECINSTR;
+ } else if (attributes & CustomSectionAttributes_Writeable) {
+ Flags |= ELF::SHF_WRITE;
+ }
+ Section =
+ OutContext->getELFSection(SectionName, ELF::SHT_PROGBITS, Flags, 0,
+ ComdatName != nullptr ? ComdatName : "");
+ break;
+ }
+ default:
+ error("Unknown output format for target " + TripleName);
+ break;
+ }
+ return Section;
+}
+
+void ObjectWriter::SetCodeSectionAttribute(const char *SectionName,
+ CustomSectionAttributes attributes,
+ const char *ComdatName) {
+ MCSection *Section = GetSection(SectionName, attributes, ComdatName);
+
+ assert(!Section->hasInstructions());
+ Section->setHasInstructions(true);
+ if (ObjFileInfo->getObjectFileType() != ObjFileInfo->IsCOFF) {
+ OutContext->addGenDwarfSection(Section);
+ }
+}
+
+void ObjectWriter::EmitAlignment(int ByteAlignment) {
+ Streamer->EmitValueToAlignment(ByteAlignment, 0x90 /* Nop */);
+}
+
+void ObjectWriter::EmitBlob(int BlobSize, const char *Blob) {
+ Streamer->EmitBytes(StringRef(Blob, BlobSize));
+}
+
+void ObjectWriter::EmitIntValue(uint64_t Value, unsigned Size) {
+ Streamer->EmitIntValue(Value, Size);
+}
+
+void ObjectWriter::EmitSymbolDef(const char *SymbolName) {
+ MCSymbol *Sym = OutContext->getOrCreateSymbol(Twine(SymbolName));
+ Streamer->EmitSymbolAttribute(Sym, MCSA_Global);
+ Streamer->EmitLabel(Sym);
+}
+
+const MCSymbolRefExpr *
+ObjectWriter::GetSymbolRefExpr(const char *SymbolName,
+ MCSymbolRefExpr::VariantKind Kind) {
+ // Create symbol reference
+ MCSymbol *T = OutContext->getOrCreateSymbol(SymbolName);
+ Assembler->registerSymbol(*T);
+ return MCSymbolRefExpr::create(T, Kind, *OutContext);
+}
+
+int ObjectWriter::EmitSymbolRef(const char *SymbolName,
+ RelocType RelocationType, int Delta) {
+ bool IsPCRelative = false;
+ int Size = 0;
+ MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
+
+ // Convert RelocationType to MCSymbolRefExpr
+ switch (RelocationType) {
+ case RelocType::IMAGE_REL_BASED_ABSOLUTE:
+ assert(ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF);
+ Kind = MCSymbolRefExpr::VK_COFF_IMGREL32;
+ Size = 4;
+ break;
+ case RelocType::IMAGE_REL_BASED_HIGHLOW:
+ Size = 4;
+ break;
+ case RelocType::IMAGE_REL_BASED_DIR64:
+ Size = 8;
+ break;
+ case RelocType::IMAGE_REL_BASED_REL32:
+ Size = 4;
+ IsPCRelative = true;
+ break;
+ default:
+ assert(false && "NYI RelocationType!");
+ }
+
+ const MCExpr *TargetExpr = GetSymbolRefExpr(SymbolName, Kind);
+
+ if (IsPCRelative) {
+ // If the fixup is pc-relative, we need to bias the value to be relative to
+ // the start of the field, not the end of the field
+ TargetExpr = MCBinaryExpr::createSub(
+ TargetExpr, MCConstantExpr::create(Size, *OutContext), *OutContext);
+ }
+
+ if (Delta != 0) {
+ TargetExpr = MCBinaryExpr::createAdd(
+ TargetExpr, MCConstantExpr::create(Delta, *OutContext), *OutContext);
+ }
+ Streamer->EmitValueImpl(TargetExpr, Size, SMLoc(), IsPCRelative);
+ return Size;
+}
+
+void ObjectWriter::EmitWinFrameInfo(const char *FunctionName, int StartOffset,
+ int EndOffset, const char *BlobSymbolName) {
+ assert(ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF);
+
+ // .pdata emission
+ MCSection *Section = ObjFileInfo->getPDataSection();
+
+ // If the function was emitted to a Comdat section, create an associative
+ // section to place the frame info in. This is due to the Windows linker
+ // requirement that a function and its unwind info come from the same
+ // object file.
+ MCSymbol *Fn = OutContext->getOrCreateSymbol(Twine(FunctionName));
+ const MCSectionCOFF *FunctionSection = cast<MCSectionCOFF>(&Fn->getSection());
+ if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
+ Section = OutContext->getAssociativeCOFFSection(
+ cast<MCSectionCOFF>(Section), FunctionSection->getCOMDATSymbol());
+ }
+
+ Streamer->SwitchSection(Section);
+ Streamer->EmitValueToAlignment(4);
+
+ const MCExpr *BaseRefRel =
+ GetSymbolRefExpr(FunctionName, MCSymbolRefExpr::VK_COFF_IMGREL32);
+
+ // start Offset
+ const MCExpr *StartOfs = MCConstantExpr::create(StartOffset, *OutContext);
+ Streamer->EmitValue(
+ MCBinaryExpr::createAdd(BaseRefRel, StartOfs, *OutContext), 4);
+
+ // end Offset
+ const MCExpr *EndOfs = MCConstantExpr::create(EndOffset, *OutContext);
+ Streamer->EmitValue(MCBinaryExpr::createAdd(BaseRefRel, EndOfs, *OutContext),
+ 4);
+
+ // frame symbol reference
+ Streamer->EmitValue(
+ GetSymbolRefExpr(BlobSymbolName, MCSymbolRefExpr::VK_COFF_IMGREL32), 4);
+}
+
+void ObjectWriter::EmitCFIStart(int Offset) {
+ assert(!FrameOpened && "frame should be closed before CFIStart");
+ Streamer->EmitCFIStartProc(false);
+ FrameOpened = true;
+}
+
+void ObjectWriter::EmitCFIEnd(int Offset) {
+ assert(FrameOpened && "frame should be opened before CFIEnd");
+ Streamer->EmitCFIEndProc();
+ FrameOpened = false;
+}
+
+void ObjectWriter::EmitCFILsda(const char *LsdaBlobSymbolName) {
+ assert(FrameOpened && "frame should be opened before CFILsda");
+
+ // Create symbol reference
+ MCSymbol *T = OutContext->getOrCreateSymbol(LsdaBlobSymbolName);
+ Assembler->registerSymbol(*T);
+ Streamer->EmitCFILsda(T, llvm::dwarf::Constants::DW_EH_PE_pcrel |
+ llvm::dwarf::Constants::DW_EH_PE_sdata4);
+}
+
+void ObjectWriter::EmitCFICode(int Offset, const char *Blob) {
+ assert(FrameOpened && "frame should be opened before CFICode");
+
+ const CFI_CODE *CfiCode = (const CFI_CODE *)Blob;
+ switch (CfiCode->CfiOpCode) {
+ case CFI_ADJUST_CFA_OFFSET:
+ assert(CfiCode->DwarfReg == DWARF_REG_ILLEGAL &&
+ "Unexpected Register Value for OpAdjustCfaOffset");
+ Streamer->EmitCFIAdjustCfaOffset(CfiCode->Offset);
+ break;
+ case CFI_REL_OFFSET:
+ Streamer->EmitCFIRelOffset(CfiCode->DwarfReg, CfiCode->Offset);
+ break;
+ case CFI_DEF_CFA_REGISTER:
+ assert(CfiCode->Offset == 0 &&
+ "Unexpected Offset Value for OpDefCfaRegister");
+ Streamer->EmitCFIDefCfaRegister(CfiCode->DwarfReg);
+ break;
+ default:
+ assert(false && "Unrecognized CFI");
+ break;
+ }
+}
+
+void ObjectWriter::EmitLabelDiff(const MCSymbol *From, const MCSymbol *To,
+ unsigned int Size) {
+ MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
+ const MCExpr *FromRef = MCSymbolRefExpr::create(From, Variant, *OutContext),
+ *ToRef = MCSymbolRefExpr::create(To, Variant, *OutContext);
+ const MCExpr *AddrDelta =
+ MCBinaryExpr::create(MCBinaryExpr::Sub, ToRef, FromRef, *OutContext);
+ Streamer->EmitValue(AddrDelta, Size);
+}
+
+void ObjectWriter::EmitSymRecord(int Size, SymbolRecordKind SymbolKind) {
+ RecordPrefix Rec;
+ Rec.RecordLen = ulittle16_t(Size + sizeof(ulittle16_t));
+ Rec.RecordKind = ulittle16_t((uint16_t)SymbolKind);
+ Streamer->EmitBytes(StringRef((char *)&Rec, sizeof(Rec)));
+}
+
+void ObjectWriter::EmitCOFFSecRel32Value(MCExpr const *Value) {
+ MCDataFragment *DF = Streamer->getOrCreateDataFragment();
+ MCFixup Fixup = MCFixup::create(DF->getContents().size(), Value, FK_SecRel_4);
+ DF->getFixups().push_back(Fixup);
+ DF->getContents().resize(DF->getContents().size() + 4, 0);
+}
+
+void ObjectWriter::EmitVarDefRange(const MCSymbol *Fn,
+ const LocalVariableAddrRange &Range) {
+ const MCSymbolRefExpr *BaseSym = MCSymbolRefExpr::create(Fn, *OutContext);
+ const MCExpr *Offset = MCConstantExpr::create(Range.OffsetStart, *OutContext);
+ const MCExpr *Expr = MCBinaryExpr::createAdd(BaseSym, Offset, *OutContext);
+ EmitCOFFSecRel32Value(Expr);
+ Streamer->EmitCOFFSectionIndex(Fn);
+ Streamer->EmitIntValue(Range.Range, 2);
+}
+
+void ObjectWriter::EmitCVDebugVarInfo(const MCSymbol *Fn,
+ const DebugVarInfo LocInfos[],
+ int NumVarInfos) {
+ for (int I = 0; I < NumVarInfos; I++) {
+ // Emit an S_LOCAL record
+ DebugVarInfo Var = LocInfos[I];
+ TypeIndex Type = TypeIndex(Var.TypeIndex);
+ LocalSymFlags Flags = LocalSymFlags::None;
+ unsigned SizeofSym = sizeof(Type) + sizeof(Flags);
+ unsigned NameLength = Var.Name.length() + 1;
+ EmitSymRecord(SizeofSym + NameLength, SymbolRecordKind::LocalSym);
+ if (Var.IsParam) {
+ Flags |= LocalSymFlags::IsParameter;
+ }
+ Streamer->EmitBytes(StringRef((char *)&Type, sizeof(Type)));
+ Streamer->EmitIntValue(static_cast<uint16_t>(Flags), sizeof(Flags));
+ Streamer->EmitBytes(StringRef(Var.Name.c_str(), NameLength));
+
+ for (const auto &Range : Var.Ranges) {
+ // Emit a range record
+ switch (Range.loc.vlType) {
+ case ICorDebugInfo::VLT_REG:
+ case ICorDebugInfo::VLT_REG_FP: {
+
+ // Currently only support integer registers.
+ // TODO: support xmm registers
+ if (Range.loc.vlReg.vlrReg >=
+ sizeof(cvRegMapAmd64) / sizeof(cvRegMapAmd64[0])) {
+ break;
+ }
+ SymbolRecordKind SymbolKind = SymbolRecordKind::DefRangeRegisterSym;
+ unsigned SizeofDefRangeRegisterSym = sizeof(DefRangeRegisterSym::Hdr) +
+ sizeof(DefRangeRegisterSym::Range);
+ EmitSymRecord(SizeofDefRangeRegisterSym, SymbolKind);
+
+ DefRangeRegisterSym DefRangeRegisterSymbol(SymbolKind);
+ DefRangeRegisterSymbol.Range.OffsetStart = Range.startOffset;
+ DefRangeRegisterSymbol.Range.Range =
+ Range.endOffset - Range.startOffset;
+ DefRangeRegisterSymbol.Range.ISectStart = 0;
+ DefRangeRegisterSymbol.Hdr.Register =
+ cvRegMapAmd64[Range.loc.vlReg.vlrReg];
+ unsigned Length = sizeof(DefRangeRegisterSymbol.Hdr);
+ Streamer->EmitBytes(
+ StringRef((char *)&DefRangeRegisterSymbol.Hdr, Length));
+ EmitVarDefRange(Fn, DefRangeRegisterSymbol.Range);
+ break;
+ }
+
+ case ICorDebugInfo::VLT_STK: {
+
+ // TODO: support REGNUM_AMBIENT_SP
+ if (Range.loc.vlStk.vlsBaseReg >=
+ sizeof(cvRegMapAmd64) / sizeof(cvRegMapAmd64[0])) {
+ break;
+ }
+
+ assert(Range.loc.vlStk.vlsBaseReg <
+ sizeof(cvRegMapAmd64) / sizeof(cvRegMapAmd64[0]) &&
+ "Register number should be in the range of [REGNUM_RAX, "
+ "REGNUM_R15].");
+
+ SymbolRecordKind SymbolKind = SymbolRecordKind::DefRangeRegisterRelSym;
+ unsigned SizeofDefRangeRegisterRelSym =
+ sizeof(DefRangeRegisterRelSym::Hdr) +
+ sizeof(DefRangeRegisterRelSym::Range);
+ EmitSymRecord(SizeofDefRangeRegisterRelSym, SymbolKind);
+
+ DefRangeRegisterRelSym DefRangeRegisterRelSymbol(SymbolKind);
+ DefRangeRegisterRelSymbol.Range.OffsetStart = Range.startOffset;
+ DefRangeRegisterRelSymbol.Range.Range =
+ Range.endOffset - Range.startOffset;
+ DefRangeRegisterRelSymbol.Range.ISectStart = 0;
+ DefRangeRegisterRelSymbol.Hdr.Register =
+ cvRegMapAmd64[Range.loc.vlStk.vlsBaseReg];
+ DefRangeRegisterRelSymbol.Hdr.BasePointerOffset =
+ Range.loc.vlStk.vlsOffset;
+
+ unsigned Length = sizeof(DefRangeRegisterRelSymbol.Hdr);
+ Streamer->EmitBytes(
+ StringRef((char *)&DefRangeRegisterRelSymbol.Hdr, Length));
+ EmitVarDefRange(Fn, DefRangeRegisterRelSymbol.Range);
+ break;
+ }
+
+ case ICorDebugInfo::VLT_REG_BYREF:
+ case ICorDebugInfo::VLT_STK_BYREF:
+ case ICorDebugInfo::VLT_REG_REG:
+ case ICorDebugInfo::VLT_REG_STK:
+ case ICorDebugInfo::VLT_STK_REG:
+ case ICorDebugInfo::VLT_STK2:
+ case ICorDebugInfo::VLT_FPSTK:
+ case ICorDebugInfo::VLT_FIXED_VA:
+ // TODO: for optimized debugging
+ break;
+
+ default:
+ assert(false && "Unknown varloc type!");
+ break;
+ }
+ }
+ }
+}
+
+void ObjectWriter::EmitCVDebugFunctionInfo(const char *FunctionName,
+ int FunctionSize) {
+ assert(ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF);
+
+ // Mark the end of function.
+ MCSymbol *FnEnd = OutContext->createTempSymbol();
+ Streamer->EmitLabel(FnEnd);
+
+ MCSection *Section = ObjFileInfo->getCOFFDebugSymbolsSection();
+ Streamer->SwitchSection(Section);
+ // Emit debug section magic before the first entry.
+ if (FuncId == 1) {
+ Streamer->EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4);
+ }
+ MCSymbol *Fn = OutContext->getOrCreateSymbol(Twine(FunctionName));
+
+ // Emit a symbol subsection, required by VS2012+ to find function boundaries.
+ MCSymbol *SymbolsBegin = OutContext->createTempSymbol(),
+ *SymbolsEnd = OutContext->createTempSymbol();
+ Streamer->EmitIntValue(unsigned(DebugSubsectionKind::Symbols), 4);
+ EmitLabelDiff(SymbolsBegin, SymbolsEnd);
+ Streamer->EmitLabel(SymbolsBegin);
+ {
+ ProcSym ProcSymbol(SymbolRecordKind::GlobalProcIdSym);
+ ProcSymbol.CodeSize = FunctionSize;
+ ProcSymbol.DbgEnd = FunctionSize;
+
+ unsigned FunctionNameLength = strlen(FunctionName) + 1;
+ unsigned HeaderSize =
+ sizeof(ProcSymbol.Parent) + sizeof(ProcSymbol.End) +
+ sizeof(ProcSymbol.Next) + sizeof(ProcSymbol.CodeSize) +
+ sizeof(ProcSymbol.DbgStart) + sizeof(ProcSymbol.DbgEnd) +
+ sizeof(ProcSymbol.FunctionType);
+ unsigned SymbolSize = HeaderSize + 4 + 2 + 1 + FunctionNameLength;
+ EmitSymRecord(SymbolSize, SymbolRecordKind::GlobalProcIdSym);
+
+ Streamer->EmitBytes(StringRef((char *)&ProcSymbol.Parent, HeaderSize));
+ // Emit relocation
+ Streamer->EmitCOFFSecRel32(Fn, 0);
+ Streamer->EmitCOFFSectionIndex(Fn);
+
+ // Emit flags
+ Streamer->EmitIntValue(0, 1);
+
+ // Emit the function display name as a null-terminated string.
+
+ Streamer->EmitBytes(StringRef(FunctionName, FunctionNameLength));
+
+ // Emit local var info
+ int NumVarInfos = DebugVarInfos.size();
+ if (NumVarInfos > 0) {
+ EmitCVDebugVarInfo(Fn, &DebugVarInfos[0], NumVarInfos);
+ DebugVarInfos.clear();
+ }
+
+ // We're done with this function.
+ EmitSymRecord(0, SymbolRecordKind::ProcEnd);
+ }
+
+ Streamer->EmitLabel(SymbolsEnd);
+
+ // Every subsection must be aligned to a 4-byte boundary.
+ Streamer->EmitValueToAlignment(4);
+
+ // We have an assembler directive that takes care of the whole line table.
+ // We also increase function id for the next function.
+ Streamer->EmitCVLinetableDirective(FuncId++, Fn, FnEnd);
+}
+
+void ObjectWriter::EmitDebugFileInfo(int FileId, const char *FileName) {
+ assert(FileId > 0 && "FileId should be greater than 0.");
+ if (ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF) {
+ Streamer->EmitCVFileDirective(FileId, FileName);
+ } else {
+ Streamer->EmitDwarfFileDirective(FileId, "", FileName);
+ }
+}
+
+void ObjectWriter::EmitDebugFunctionInfo(const char *FunctionName,
+ int FunctionSize) {
+ if (ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF) {
+ Streamer->EmitCVFuncIdDirective(FuncId);
+ EmitCVDebugFunctionInfo(FunctionName, FunctionSize);
+ } else {
+ if (ObjFileInfo->getObjectFileType() == ObjFileInfo->IsELF) {
+ MCSymbol *Sym = OutContext->getOrCreateSymbol(Twine(FunctionName));
+ Streamer->EmitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);
+ Streamer->emitELFSize(Sym,
+ MCConstantExpr::create(FunctionSize, *OutContext));
+ }
+ // TODO: Should test it for Macho.
+ }
+}
+
+void ObjectWriter::EmitDebugVar(char *Name, int TypeIndex, bool IsParm,
+ int RangeCount,
+ const ICorDebugInfo::NativeVarInfo *Ranges) {
+ assert(RangeCount != 0);
+ DebugVarInfo NewVar(Name, TypeIndex, IsParm);
+
+ for (int I = 0; I < RangeCount; I++) {
+ assert(Ranges[0].varNumber == Ranges[I].varNumber);
+ NewVar.Ranges.push_back(Ranges[I]);
+ }
+
+ DebugVarInfos.push_back(NewVar);
+}
+
+void ObjectWriter::EmitDebugLoc(int NativeOffset, int FileId, int LineNumber,
+ int ColNumber) {
+ assert(FileId > 0 && "FileId should be greater than 0.");
+ if (ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF) {
+ Streamer->EmitCVFuncIdDirective(FuncId);
+ Streamer->EmitCVLocDirective(FuncId, FileId, LineNumber, ColNumber, false,
+ true, "", SMLoc());
+ } else {
+ Streamer->EmitDwarfLocDirective(FileId, LineNumber, ColNumber, 1, 0, 0, "");
+ }
+}
+
+void ObjectWriter::EmitCVUserDefinedTypesSymbols() {
+ const auto &UDTs = TypeBuilder.GetUDTs();
+ if (UDTs.empty()) {
+ return;
+ }
+ MCSection *Section = ObjFileInfo->getCOFFDebugSymbolsSection();
+ Streamer->SwitchSection(Section);
+
+ MCSymbol *SymbolsBegin = OutContext->createTempSymbol(),
+ *SymbolsEnd = OutContext->createTempSymbol();
+ Streamer->EmitIntValue(unsigned(DebugSubsectionKind::Symbols), 4);
+ EmitLabelDiff(SymbolsBegin, SymbolsEnd);
+ Streamer->EmitLabel(SymbolsBegin);
+
+ for (const std::pair<std::string, codeview::TypeIndex> &UDT : UDTs) {
+ unsigned NameLength = UDT.first.length() + 1;
+ unsigned RecordLength = 2 + 4 + NameLength;
+ Streamer->EmitIntValue(RecordLength, 2);
+ Streamer->EmitIntValue(unsigned(SymbolKind::S_UDT), 2);
+ Streamer->EmitIntValue(UDT.second.getIndex(), 4);
+ Streamer->EmitBytes(StringRef(UDT.first.c_str(), NameLength));
+ }
+ Streamer->EmitLabel(SymbolsEnd);
+ Streamer->EmitValueToAlignment(4);
+}
+
+void ObjectWriter::EmitDebugModuleInfo() {
+ if (ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF) {
+ TypeBuilder.EmitTypeInformation(ObjFileInfo->getCOFFDebugTypesSection());
+ EmitCVUserDefinedTypesSymbols();
+ }
+
+ // Ensure ending all sections.
+ for (auto Section : Sections) {
+ Streamer->endSection(Section);
+ }
+
+ if (ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF) {
+ MCSection *Section = ObjFileInfo->getCOFFDebugSymbolsSection();
+ Streamer->SwitchSection(Section);
+ Streamer->EmitCVFileChecksumsDirective();
+ Streamer->EmitCVStringTableDirective();
+ } else {
+ OutContext->setGenDwarfForAssembly(true);
+ }
+}
+
+unsigned
+ObjectWriter::GetEnumTypeIndex(const EnumTypeDescriptor &TypeDescriptor,
+ const EnumRecordTypeDescriptor *TypeRecords) {
+ assert(ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF &&
+ "only COFF is supported now");
+ return TypeBuilder.GetEnumTypeIndex(TypeDescriptor, TypeRecords);
+}
+
+unsigned
+ObjectWriter::GetClassTypeIndex(const ClassTypeDescriptor &ClassDescriptor) {
+ assert(ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF &&
+ "only COFF is supported now");
+ return TypeBuilder.GetClassTypeIndex(ClassDescriptor);
+}
+
+unsigned ObjectWriter::GetCompleteClassTypeIndex(
+ const ClassTypeDescriptor &ClassDescriptor,
+ const ClassFieldsTypeDescriptior &ClassFieldsDescriptor,
+ const DataFieldDescriptor *FieldsDescriptors) {
+ assert(ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF &&
+ "only COFF is supported now");
+ return TypeBuilder.GetCompleteClassTypeIndex(
+ ClassDescriptor, ClassFieldsDescriptor, FieldsDescriptors);
+}
+
+unsigned
+ObjectWriter::GetArrayTypeIndex(const ClassTypeDescriptor &ClassDescriptor,
+ const ArrayTypeDescriptor &ArrayDescriptor) {
+ assert(ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF &&
+ "only COFF is supported now");
+ return TypeBuilder.GetArrayTypeIndex(ClassDescriptor, ArrayDescriptor);
+}
+
+unsigned
+ObjectWriter::GetPointerTypeIndex(const PointerTypeDescriptor& PointerDescriptor) {
+ assert(ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF &&
+ "only COFF is supported now");
+ return TypeBuilder.GetPointerTypeIndex(PointerDescriptor);
+}
+
+unsigned
+ObjectWriter::GetMemberFunctionTypeIndex(const MemberFunctionTypeDescriptor& MemberDescriptor,
+ uint32_t const *const ArgumentTypes) {
+ assert(ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF &&
+ "only COFF is supported now");
+ return TypeBuilder.GetMemberFunctionTypeIndex(MemberDescriptor, ArgumentTypes);
+}
+
+unsigned
+ObjectWriter::GetMemberFunctionId(const MemberFunctionIdTypeDescriptor& MemberIdDescriptor) {
+ assert(ObjFileInfo->getObjectFileType() == ObjFileInfo->IsCOFF &&
+ "only COFF is supported now");
+ return TypeBuilder.GetMemberFunctionId(MemberIdDescriptor);
+}
+
diff --git a/src/Native/ObjWriter/objwriter.exports b/src/Native/ObjWriter/objwriter.exports
new file mode 100644
index 000000000..c42c465df
--- /dev/null
+++ b/src/Native/ObjWriter/objwriter.exports
@@ -0,0 +1,26 @@
+InitObjWriter
+FinishObjWriter
+SwitchSection
+SetCodeSectionAttribute
+EmitAlignment
+EmitBlob
+EmitIntValue
+EmitSymbolDef
+EmitSymbolRef
+EmitWinFrameInfo
+EmitCFIStart
+EmitCFIEnd
+EmitCFICode
+EmitCFILsda
+EmitDebugFileInfo
+EmitDebugLoc
+EmitDebugFunctionInfo
+EmitDebugModuleInfo
+EmitDebugVar
+GetEnumTypeIndex
+GetClassTypeIndex
+GetCompleteClassTypeIndex
+GetArrayTypeIndex
+GetPointerTypeIndex
+GetMemberFunctionTypeIndex
+GetMemberFunctionIdTypeIndex \ No newline at end of file
diff --git a/src/Native/ObjWriter/objwriter.h b/src/Native/ObjWriter/objwriter.h
new file mode 100644
index 000000000..bf9757b37
--- /dev/null
+++ b/src/Native/ObjWriter/objwriter.h
@@ -0,0 +1,312 @@
+//===---- objwriter.h --------------------------------*- C++ -*-===//
+//
+// object writer
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license.
+// See LICENSE file in the project root for full license information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
+
+#include "cfi.h"
+#include "jitDebugInfo.h"
+#include <string>
+#include <set>
+#include "typeBuilder.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+enum CustomSectionAttributes : int32_t {
+ CustomSectionAttributes_ReadOnly = 0x0000,
+ CustomSectionAttributes_Writeable = 0x0001,
+ CustomSectionAttributes_Executable = 0x0002,
+ CustomSectionAttributes_MachO_Init_Func_Pointers = 0x0100,
+};
+
+enum class RelocType {
+ IMAGE_REL_BASED_ABSOLUTE = 0x00,
+ IMAGE_REL_BASED_HIGHLOW = 0x03,
+ IMAGE_REL_BASED_DIR64 = 0x0A,
+ IMAGE_REL_BASED_REL32 = 0x10,
+};
+
+class ObjectWriter {
+public:
+ bool Init(StringRef FunctionName);
+ void Finish();
+
+ void SwitchSection(const char *SectionName,
+ CustomSectionAttributes attributes,
+ const char *ComdatName);
+ void SetCodeSectionAttribute(const char *SectionName,
+ CustomSectionAttributes attributes,
+ const char *ComdatName);
+
+ void EmitAlignment(int ByteAlignment);
+ void EmitBlob(int BlobSize, const char *Blob);
+ void EmitIntValue(uint64_t Value, unsigned Size);
+ void EmitSymbolDef(const char *SymbolName);
+ void EmitWinFrameInfo(const char *FunctionName, int StartOffset,
+ int EndOffset, const char *BlobSymbolName);
+ int EmitSymbolRef(const char *SymbolName, RelocType RelocType, int Delta);
+
+ void EmitDebugFileInfo(int FileId, const char *FileName);
+ void EmitDebugFunctionInfo(const char *FunctionName, int FunctionSize);
+ void EmitDebugVar(char *Name, int TypeIndex, bool IsParm, int RangeCount,
+ const ICorDebugInfo::NativeVarInfo *Ranges);
+ void EmitDebugLoc(int NativeOffset, int FileId, int LineNumber,
+ int ColNumber);
+ void EmitDebugModuleInfo();
+
+ void EmitCFIStart(int Offset);
+ void EmitCFIEnd(int Offset);
+ void EmitCFILsda(const char *LsdaBlobSymbolName);
+ void EmitCFICode(int Offset, const char *Blob);
+
+ unsigned GetEnumTypeIndex(const EnumTypeDescriptor &TypeDescriptor,
+ const EnumRecordTypeDescriptor *TypeRecords);
+ unsigned GetClassTypeIndex(const ClassTypeDescriptor &ClassDescriptor);
+ unsigned GetCompleteClassTypeIndex(
+ const ClassTypeDescriptor &ClassDescriptor,
+ const ClassFieldsTypeDescriptior &ClassFieldsDescriptor,
+ const DataFieldDescriptor *FieldsDescriptors);
+
+ unsigned GetArrayTypeIndex(const ClassTypeDescriptor &ClassDescriptor,
+ const ArrayTypeDescriptor &ArrayDescriptor);
+
+ unsigned GetPointerTypeIndex(const PointerTypeDescriptor& PointerDescriptor);
+
+ unsigned GetMemberFunctionTypeIndex(const MemberFunctionTypeDescriptor& MemberDescriptor,
+ uint32_t const *const ArgumentTypes);
+
+ unsigned GetMemberFunctionId(const MemberFunctionIdTypeDescriptor& MemberIdDescriptor);
+
+private:
+ void EmitLabelDiff(const MCSymbol *From, const MCSymbol *To,
+ unsigned int Size = 4);
+ void EmitSymRecord(int Size, SymbolRecordKind SymbolKind);
+ void EmitCOFFSecRel32Value(MCExpr const *Value);
+
+ void EmitVarDefRange(const MCSymbol *Fn, const LocalVariableAddrRange &Range);
+ void EmitCVDebugVarInfo(const MCSymbol *Fn, const DebugVarInfo LocInfos[],
+ int NumVarInfos);
+ void EmitCVDebugFunctionInfo(const char *FunctionName, int FunctionSize);
+
+ const MCSymbolRefExpr *GetSymbolRefExpr(
+ const char *SymbolName,
+ MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None);
+
+ MCSection *GetSection(const char *SectionName,
+ CustomSectionAttributes attributes,
+ const char *ComdatName);
+
+ MCSection *GetSpecificSection(const char *SectionName,
+ CustomSectionAttributes attributes,
+ const char *ComdatName);
+
+ void EmitCVUserDefinedTypesSymbols();
+
+ void InitTripleName();
+ Triple GetTriple();
+
+private:
+ std::unique_ptr<MCRegisterInfo> RegisterInfo;
+ std::unique_ptr<MCAsmInfo> AsmInfo;
+ std::unique_ptr<MCObjectFileInfo> ObjFileInfo;
+ std::unique_ptr<MCContext> OutContext;
+ MCAsmBackend *AsmBackend; // Owned by MCStreamer
+ std::unique_ptr<MCInstrInfo> InstrInfo;
+ std::unique_ptr<MCSubtargetInfo> SubtargetInfo;
+ MCCodeEmitter *CodeEmitter; // Owned by MCStreamer
+ std::unique_ptr<TargetMachine> TMachine;
+ std::unique_ptr<AsmPrinter> AssemblerPrinter;
+ MCAssembler *Assembler; // Owned by MCStreamer
+
+ std::unique_ptr<raw_fd_ostream> OS;
+ MCTargetOptions TargetMOptions;
+ bool FrameOpened;
+ std::vector<DebugVarInfo> DebugVarInfos;
+
+ std::set<MCSection *> Sections;
+ int FuncId;
+
+ UserDefinedTypesBuilder TypeBuilder;
+
+ std::string TripleName;
+
+ MCObjectStreamer *Streamer; // Owned by AsmPrinter
+};
+
+// When object writer is created/initialized successfully, it is returned.
+// Or null object is returned. Client should check this.
+extern "C" ObjectWriter *InitObjWriter(const char *ObjectFilePath) {
+ ObjectWriter *OW = new ObjectWriter();
+ if (OW->Init(ObjectFilePath)) {
+ return OW;
+ }
+ delete OW;
+ return nullptr;
+}
+
+extern "C" void FinishObjWriter(ObjectWriter *OW) {
+ assert(OW && "ObjWriter is null");
+ OW->Finish();
+ delete OW;
+}
+
+extern "C" void SwitchSection(ObjectWriter *OW, const char *SectionName,
+ CustomSectionAttributes attributes,
+ const char *ComdatName) {
+ assert(OW && "ObjWriter is null");
+ OW->SwitchSection(SectionName, attributes, ComdatName);
+}
+
+extern "C" void SetCodeSectionAttribute(ObjectWriter *OW,
+ const char *SectionName,
+ CustomSectionAttributes attributes,
+ const char *ComdatName) {
+ assert(OW && "ObjWriter is null");
+ OW->SetCodeSectionAttribute(SectionName, attributes, ComdatName);
+}
+
+extern "C" void EmitAlignment(ObjectWriter *OW, int ByteAlignment) {
+ assert(OW && "ObjWriter is null");
+ OW->EmitAlignment(ByteAlignment);
+}
+
+extern "C" void EmitBlob(ObjectWriter *OW, int BlobSize, const char *Blob) {
+ assert(OW && "ObjWriter null");
+ OW->EmitBlob(BlobSize, Blob);
+}
+
+extern "C" void EmitIntValue(ObjectWriter *OW, uint64_t Value, unsigned Size) {
+ assert(OW && "ObjWriter is null");
+ OW->EmitIntValue(Value, Size);
+}
+
+extern "C" void EmitSymbolDef(ObjectWriter *OW, const char *SymbolName) {
+ assert(OW && "ObjWriter is null");
+ OW->EmitSymbolDef(SymbolName);
+}
+
+extern "C" int EmitSymbolRef(ObjectWriter *OW, const char *SymbolName,
+ RelocType RelocType, int Delta) {
+ assert(OW && "ObjWriter is null");
+ return OW->EmitSymbolRef(SymbolName, RelocType, Delta);
+}
+
+extern "C" void EmitWinFrameInfo(ObjectWriter *OW, const char *FunctionName,
+ int StartOffset, int EndOffset,
+ const char *BlobSymbolName) {
+ assert(OW && "ObjWriter is null");
+ OW->EmitWinFrameInfo(FunctionName, StartOffset, EndOffset, BlobSymbolName);
+}
+
+extern "C" void EmitCFIStart(ObjectWriter *OW, int Offset) {
+ assert(OW && "ObjWriter is null");
+ OW->EmitCFIStart(Offset);
+}
+
+extern "C" void EmitCFIEnd(ObjectWriter *OW, int Offset) {
+ assert(OW && "ObjWriter is null");
+ OW->EmitCFIEnd(Offset);
+}
+
+extern "C" void EmitCFILsda(ObjectWriter *OW, const char *LsdaBlobSymbolName) {
+ assert(OW && "ObjWriter is null");
+ OW->EmitCFILsda(LsdaBlobSymbolName);
+}
+
+extern "C" void EmitCFICode(ObjectWriter *OW, int Offset, const char *Blob) {
+ assert(OW && "ObjWriter is null");
+ OW->EmitCFICode(Offset, Blob);
+}
+
+extern "C" void EmitDebugFileInfo(ObjectWriter *OW, int FileId,
+ const char *FileName) {
+ assert(OW && "ObjWriter is null");
+ OW->EmitDebugFileInfo(FileId, FileName);
+}
+
+extern "C" void EmitDebugFunctionInfo(ObjectWriter *OW,
+ const char *FunctionName,
+ int FunctionSize) {
+ assert(OW && "ObjWriter is null");
+ OW->EmitDebugFunctionInfo(FunctionName, FunctionSize);
+}
+
+extern "C" void EmitDebugVar(ObjectWriter *OW, char *Name, int TypeIndex,
+ bool IsParam, int RangeCount,
+ ICorDebugInfo::NativeVarInfo *Ranges) {
+ assert(OW && "ObjWriter is null");
+ OW->EmitDebugVar(Name, TypeIndex, IsParam, RangeCount, Ranges);
+}
+
+extern "C" void EmitDebugLoc(ObjectWriter *OW, int NativeOffset, int FileId,
+ int LineNumber, int ColNumber) {
+ assert(OW && "ObjWriter is null");
+ OW->EmitDebugLoc(NativeOffset, FileId, LineNumber, ColNumber);
+}
+
+// This should be invoked at the end of module emission to finalize
+// debug module info.
+extern "C" void EmitDebugModuleInfo(ObjectWriter *OW) {
+ assert(OW && "ObjWriter is null");
+ OW->EmitDebugModuleInfo();
+}
+
+extern "C" unsigned GetEnumTypeIndex(ObjectWriter *OW,
+ EnumTypeDescriptor TypeDescriptor,
+ EnumRecordTypeDescriptor *TypeRecords) {
+ assert(OW && "ObjWriter is null");
+ return OW->GetEnumTypeIndex(TypeDescriptor, TypeRecords);
+}
+
+extern "C" unsigned GetClassTypeIndex(ObjectWriter *OW,
+ ClassTypeDescriptor ClassDescriptor) {
+ assert(OW && "ObjWriter is null");
+ return OW->GetClassTypeIndex(ClassDescriptor);
+}
+
+extern "C" unsigned
+GetCompleteClassTypeIndex(ObjectWriter *OW, ClassTypeDescriptor ClassDescriptor,
+ ClassFieldsTypeDescriptior ClassFieldsDescriptor,
+ DataFieldDescriptor *FieldsDescriptors) {
+ assert(OW && "ObjWriter is null");
+ return OW->GetCompleteClassTypeIndex(ClassDescriptor, ClassFieldsDescriptor,
+ FieldsDescriptors);
+}
+
+extern "C" unsigned GetArrayTypeIndex(ObjectWriter *OW,
+ ClassTypeDescriptor ClassDescriptor,
+ ArrayTypeDescriptor ArrayDescriptor) {
+ assert(OW && "ObjWriter is null");
+ return OW->GetArrayTypeIndex(ClassDescriptor, ArrayDescriptor);
+}
+
+extern "C" unsigned GetPointerTypeIndex(ObjectWriter *OW,
+ PointerTypeDescriptor PointerDescriptor) {
+ assert(OW && "ObjWriter is null");
+ return OW->GetPointerTypeIndex(PointerDescriptor);
+}
+
+extern "C" unsigned GetMemberFunctionTypeIndex(ObjectWriter *OW,
+ MemberFunctionTypeDescriptor MemberDescriptor,
+ uint32_t *ArgumentTypes) {
+ assert(OW && "ObjWriter is null");
+ return OW->GetMemberFunctionTypeIndex(MemberDescriptor, ArgumentTypes);
+}
+
+extern "C" unsigned GetMemberFunctionIdTypeIndex(ObjectWriter *OW,
+ MemberFunctionIdTypeDescriptor MemberIdDescriptor) {
+ assert(OW && "ObjWriter is null");
+ return OW->GetMemberFunctionId(MemberIdDescriptor);
+}
diff --git a/src/Native/ObjWriter/typeBuilder.cpp b/src/Native/ObjWriter/typeBuilder.cpp
new file mode 100644
index 000000000..2b6edacc5
--- /dev/null
+++ b/src/Native/ObjWriter/typeBuilder.cpp
@@ -0,0 +1,321 @@
+//===---- typeBuilder.cpp --------------------------------*- C++ -*-===//
+//
+// type builder implementation using codeview::TypeTableBuilder
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license.
+// See LICENSE file in the project root for full license information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "typeBuilder.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include <sstream>
+#include <vector>
+
+UserDefinedTypesBuilder::UserDefinedTypesBuilder()
+ : Allocator(), TypeTable(Allocator), Streamer(nullptr),
+ TargetPointerSize(0)
+{
+ VFTableShapeRecord vfTableShape(TypeRecordKind::VFTableShape);
+ ClassVTableTypeIndex = TypeTable.writeKnownType(vfTableShape);
+}
+
+void UserDefinedTypesBuilder::SetStreamer(MCObjectStreamer *Streamer) {
+ assert(this->Streamer == nullptr);
+ assert(Streamer != nullptr);
+ this->Streamer = Streamer;
+}
+
+void UserDefinedTypesBuilder::SetTargetPointerSize(unsigned TargetPointerSize) {
+ assert(this->TargetPointerSize == 0);
+ assert(TargetPointerSize != 0);
+ this->TargetPointerSize = TargetPointerSize;
+}
+
+void UserDefinedTypesBuilder::EmitCodeViewMagicVersion() {
+ Streamer->EmitValueToAlignment(4);
+ Streamer->AddComment("Debug section magic");
+ Streamer->EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4);
+}
+
+ClassOptions UserDefinedTypesBuilder::GetCommonClassOptions() {
+ return ClassOptions();
+}
+
+void UserDefinedTypesBuilder::EmitTypeInformation(
+ MCSection *COFFDebugTypesSection) {
+
+ if (TypeTable.empty())
+ return;
+
+ Streamer->SwitchSection(COFFDebugTypesSection);
+ EmitCodeViewMagicVersion();
+
+ TypeTable.ForEachRecord([&](TypeIndex FieldTypeIndex,
+ ArrayRef<uint8_t> Record) {
+ StringRef S(reinterpret_cast<const char *>(Record.data()), Record.size());
+ Streamer->EmitBinaryData(S);
+ });
+}
+
+unsigned UserDefinedTypesBuilder::GetEnumFieldListType(
+ uint64 Count, const EnumRecordTypeDescriptor *TypeRecords) {
+ FieldListRecordBuilder FLRB(TypeTable);
+ FLRB.begin();
+#ifndef NDEBUG
+ uint64 MaxInt = (unsigned int)-1;
+ assert(Count <= MaxInt && "There are too many fields inside enum");
+#endif
+ for (int i = 0; i < (int)Count; ++i) {
+ EnumRecordTypeDescriptor record = TypeRecords[i];
+ EnumeratorRecord ER(MemberAccess::Public, APSInt::getUnsigned(record.Value),
+ record.Name);
+ FLRB.writeMemberType(ER);
+ }
+ TypeIndex Type = FLRB.end(true);
+ return Type.getIndex();
+}
+
+unsigned UserDefinedTypesBuilder::GetEnumTypeIndex(
+ const EnumTypeDescriptor &TypeDescriptor,
+ const EnumRecordTypeDescriptor *TypeRecords) {
+
+ ClassOptions CO = GetCommonClassOptions();
+ unsigned FieldListIndex =
+ GetEnumFieldListType(TypeDescriptor.ElementCount, TypeRecords);
+ TypeIndex FieldListIndexType = TypeIndex(FieldListIndex);
+ TypeIndex ElementTypeIndex = TypeIndex(TypeDescriptor.ElementType);
+
+ EnumRecord EnumRecord(TypeDescriptor.ElementCount, CO, FieldListIndexType,
+ TypeDescriptor.Name, StringRef(),
+ ElementTypeIndex);
+
+ TypeIndex Type = TypeTable.writeKnownType(EnumRecord);
+ UserDefinedTypes.push_back(std::make_pair(TypeDescriptor.Name, Type));
+ return Type.getIndex();
+}
+
+unsigned UserDefinedTypesBuilder::GetClassTypeIndex(
+ const ClassTypeDescriptor &ClassDescriptor) {
+ TypeRecordKind Kind =
+ ClassDescriptor.IsStruct ? TypeRecordKind::Struct : TypeRecordKind::Class;
+ ClassOptions CO = ClassOptions::ForwardReference | GetCommonClassOptions();
+
+ TypeIndex FieldListIndex = TypeIndex();
+ uint16_t memberCount = 0;
+
+ if (!ClassDescriptor.IsStruct) {
+ FieldListRecordBuilder FLBR(TypeTable);
+ FLBR.begin();
+ memberCount++;
+ AddClassVTShape(FLBR);
+ FieldListIndex = FLBR.end(true);
+ }
+
+ ClassRecord CR(Kind, memberCount, CO, FieldListIndex, TypeIndex(), TypeIndex(), 0,
+ ClassDescriptor.Name, StringRef());
+ TypeIndex FwdDeclTI = TypeTable.writeKnownType(CR);
+ return FwdDeclTI.getIndex();
+}
+
+unsigned UserDefinedTypesBuilder::GetCompleteClassTypeIndex(
+ const ClassTypeDescriptor &ClassDescriptor,
+ const ClassFieldsTypeDescriptior &ClassFieldsDescriptor,
+ const DataFieldDescriptor *FieldsDescriptors) {
+
+ FieldListRecordBuilder FLBR(TypeTable);
+ FLBR.begin();
+
+ uint16_t memberCount = 0;
+ if (!ClassDescriptor.IsStruct) {
+ memberCount++;
+ AddClassVTShape(FLBR);
+ }
+
+ if (ClassDescriptor.BaseClassId != 0) {
+ memberCount++;
+ AddBaseClass(FLBR, ClassDescriptor.BaseClassId);
+ }
+
+ for (int i = 0; i < ClassFieldsDescriptor.FieldsCount; ++i) {
+ DataFieldDescriptor desc = FieldsDescriptors[i];
+ MemberAccess Access = MemberAccess::Public;
+ TypeIndex MemberBaseType(desc.FieldTypeIndex);
+ if (desc.Offset == 0xFFFFFFFF)
+ {
+ StaticDataMemberRecord SDMR(Access, MemberBaseType, desc.Name);
+ FLBR.writeMemberType(SDMR);
+ }
+ else
+ {
+ int MemberOffsetInBytes = desc.Offset;
+ DataMemberRecord DMR(Access, MemberBaseType, MemberOffsetInBytes,
+ desc.Name);
+ FLBR.writeMemberType(DMR);
+ }
+ memberCount++;
+ }
+ TypeIndex FieldListIndex = FLBR.end(true);
+ TypeRecordKind Kind =
+ ClassDescriptor.IsStruct ? TypeRecordKind::Struct : TypeRecordKind::Class;
+ ClassOptions CO = GetCommonClassOptions();
+ ClassRecord CR(Kind, memberCount, CO, FieldListIndex,
+ TypeIndex(), TypeIndex(), ClassFieldsDescriptor.Size,
+ ClassDescriptor.Name, StringRef());
+ TypeIndex ClassIndex = TypeTable.writeKnownType(CR);
+
+ UserDefinedTypes.push_back(std::make_pair(ClassDescriptor.Name, ClassIndex));
+
+ return ClassIndex.getIndex();
+}
+
+unsigned UserDefinedTypesBuilder::GetArrayTypeIndex(
+ const ClassTypeDescriptor &ClassDescriptor,
+ const ArrayTypeDescriptor &ArrayDescriptor) {
+ FieldListRecordBuilder FLBR(TypeTable);
+ FLBR.begin();
+
+ unsigned Offset = 0;
+ unsigned FieldsCount = 0;
+
+ assert(ClassDescriptor.BaseClassId != 0);
+
+ AddClassVTShape(FLBR);
+ FieldsCount++;
+ AddBaseClass(FLBR, ClassDescriptor.BaseClassId);
+ FieldsCount++;
+ Offset += TargetPointerSize;
+
+ MemberAccess Access = MemberAccess::Public;
+ TypeIndex IndexType = TypeIndex(SimpleTypeKind::Int32);
+ DataMemberRecord CountDMR(Access, IndexType, Offset, "count");
+ FLBR.writeMemberType(CountDMR);
+ FieldsCount++;
+ Offset += TargetPointerSize;
+
+ if (ArrayDescriptor.IsMultiDimensional == 1) {
+ for (unsigned i = 0; i < ArrayDescriptor.Rank; ++i) {
+ DataMemberRecord LengthDMR(Access, TypeIndex(SimpleTypeKind::Int32),
+ Offset, ArrayDimentions.GetLengthName(i));
+ FLBR.writeMemberType(LengthDMR);
+ FieldsCount++;
+ Offset += 4;
+ }
+
+ for (unsigned i = 0; i < ArrayDescriptor.Rank; ++i) {
+ DataMemberRecord BoundsDMR(Access, TypeIndex(SimpleTypeKind::Int32),
+ Offset, ArrayDimentions.GetBoundsName(i));
+ FLBR.writeMemberType(BoundsDMR);
+ FieldsCount++;
+ Offset += 4;
+ }
+ }
+
+ TypeIndex ElementTypeIndex = TypeIndex(ArrayDescriptor.ElementType);
+ ArrayRecord AR(ElementTypeIndex, IndexType, ArrayDescriptor.Size, "");
+ TypeIndex ArrayIndex = TypeTable.writeKnownType(AR);
+ DataMemberRecord ArrayDMR(Access, ArrayIndex, Offset, "values");
+ FLBR.writeMemberType(ArrayDMR);
+ FieldsCount++;
+
+ TypeIndex FieldListIndex = FLBR.end(true);
+
+ assert(ClassDescriptor.IsStruct == false);
+ TypeRecordKind Kind = TypeRecordKind::Class;
+ ClassOptions CO = GetCommonClassOptions();
+ ClassRecord CR(Kind, FieldsCount, CO, FieldListIndex, TypeIndex(),
+ TypeIndex(), ArrayDescriptor.Size, ClassDescriptor.Name,
+ StringRef());
+ TypeIndex ClassIndex = TypeTable.writeKnownType(CR);
+
+ UserDefinedTypes.push_back(std::make_pair(ClassDescriptor.Name, ClassIndex));
+
+ return ClassIndex.getIndex();
+}
+
+unsigned UserDefinedTypesBuilder::GetPointerTypeIndex(const PointerTypeDescriptor& PointerDescriptor)
+{
+ uint32_t elementType = PointerDescriptor.ElementType;
+ PointerKind pointerKind = PointerDescriptor.Is64Bit ? PointerKind::Near64 : PointerKind::Near32;
+ PointerMode pointerMode = PointerDescriptor.IsReference ? PointerMode::LValueReference : PointerMode::Pointer;
+ PointerOptions pointerOptions = PointerDescriptor.IsConst ? PointerOptions::Const : PointerOptions::None;
+
+ PointerRecord PointerToClass(TypeIndex(elementType), pointerKind, pointerMode, pointerOptions, 0);
+ TypeIndex PointerIndex = TypeTable.writeKnownType(PointerToClass);
+ return PointerIndex.getIndex();
+}
+
+unsigned UserDefinedTypesBuilder::GetMemberFunctionTypeIndex(const MemberFunctionTypeDescriptor& MemberDescriptor,
+ uint32_t const *const ArgumentTypes)
+{
+ std::vector<TypeIndex> argumentTypes;
+ argumentTypes.reserve(MemberDescriptor.NumberOfArguments);
+ for (uint16_t iArgument = 0; iArgument < MemberDescriptor.NumberOfArguments; iArgument++)
+ {
+ argumentTypes.emplace_back(ArgumentTypes[iArgument]);
+ }
+
+ ArgListRecord ArgList(TypeRecordKind::ArgList, argumentTypes);
+ TypeIndex ArgumentList = TypeTable.writeKnownType(ArgList);
+
+ MemberFunctionRecord MemberFunction(TypeIndex(MemberDescriptor.ReturnType),
+ TypeIndex(MemberDescriptor.ContainingClass),
+ TypeIndex(MemberDescriptor.TypeIndexOfThisPointer),
+ CallingConvention(MemberDescriptor.CallingConvention),
+ FunctionOptions::None, MemberDescriptor.NumberOfArguments,
+ ArgumentList,
+ MemberDescriptor.ThisAdjust);
+
+ TypeIndex MemberFunctionIndex = TypeTable.writeKnownType(MemberFunction);
+ return MemberFunctionIndex.getIndex();
+}
+
+unsigned UserDefinedTypesBuilder::GetMemberFunctionId(const MemberFunctionIdTypeDescriptor& MemberIdDescriptor)
+{
+ MemberFuncIdRecord MemberFuncId(TypeIndex(MemberIdDescriptor.MemberFunction), TypeIndex(MemberIdDescriptor.ParentClass), MemberIdDescriptor.Name);
+ TypeIndex MemberFuncIdIndex = TypeTable.writeKnownType(MemberFuncId);
+ return MemberFuncIdIndex.getIndex();
+}
+
+void UserDefinedTypesBuilder::AddBaseClass(FieldListRecordBuilder &FLBR,
+ unsigned BaseClassId) {
+ MemberAttributes def;
+ TypeIndex BaseTypeIndex(BaseClassId);
+ BaseClassRecord BCR(def, BaseTypeIndex, 0);
+ FLBR.writeMemberType(BCR);
+}
+
+void UserDefinedTypesBuilder::AddClassVTShape(FieldListRecordBuilder &FLBR) {
+ VFPtrRecord VfPtr(ClassVTableTypeIndex);
+ FLBR.writeMemberType(VfPtr);
+}
+
+const char *ArrayDimensionsDescriptor::GetLengthName(unsigned index) {
+ if (Lengths.size() <= index) {
+ Resize(index + 1);
+ }
+ return Lengths[index].c_str();
+}
+
+const char *ArrayDimensionsDescriptor::GetBoundsName(unsigned index) {
+ if (Bounds.size() <= index) {
+ Resize(index);
+ }
+ return Bounds[index].c_str();
+}
+
+void ArrayDimensionsDescriptor::Resize(unsigned NewSize) {
+ unsigned OldSize = Lengths.size();
+ assert(OldSize == Bounds.size());
+ Lengths.resize(NewSize);
+ Bounds.resize(NewSize);
+ for (unsigned i = OldSize; i < NewSize; ++i) {
+ std::stringstream ss;
+ ss << "length" << i;
+ ss >> Lengths[i];
+ ss.clear();
+ ss << "bounds" << i;
+ ss >> Bounds[i];
+ }
+}
diff --git a/src/Native/ObjWriter/typeBuilder.h b/src/Native/ObjWriter/typeBuilder.h
new file mode 100644
index 000000000..a5037b769
--- /dev/null
+++ b/src/Native/ObjWriter/typeBuilder.h
@@ -0,0 +1,145 @@
+//===---- typeBuilder.h --------------------------------*- C++ -*-===//
+//
+// type builder is used to convert .Net types into CodeView descriptors.
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license.
+// See LICENSE file in the project root for full license information.
+//
+//===----------------------------------------------------------------------===//
+
+#pragma once
+
+#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
+#include "llvm/MC/MCObjectStreamer.h"
+
+#include <string>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+typedef unsigned long long uint64;
+
+#pragma pack(push, 8)
+
+extern "C" struct EnumRecordTypeDescriptor {
+ uint64 Value;
+ char *Name;
+};
+
+extern "C" struct EnumTypeDescriptor {
+ uint32_t ElementType;
+ uint64 ElementCount;
+ char *Name;
+};
+
+extern "C" struct ClassTypeDescriptor {
+ int32_t IsStruct;
+ char *Name;
+ uint32_t BaseClassId;
+};
+
+extern "C" struct DataFieldDescriptor {
+ uint32_t FieldTypeIndex;
+ uint64 Offset;
+ char *Name;
+};
+
+extern "C" struct ClassFieldsTypeDescriptior {
+ uint64 Size;
+ int32_t FieldsCount;
+};
+
+extern "C" struct ArrayTypeDescriptor {
+ uint32_t Rank;
+ uint32_t ElementType;
+ uint32_t Size;
+ int32_t IsMultiDimensional;
+};
+
+extern "C" struct PointerTypeDescriptor {
+ uint32_t ElementType;
+ int32_t IsReference;
+ int32_t IsConst;
+ int32_t Is64Bit;
+};
+
+extern "C" struct MemberFunctionTypeDescriptor {
+ uint32_t ReturnType;
+ uint32_t ContainingClass;
+ uint32_t TypeIndexOfThisPointer;
+ int32_t ThisAdjust;
+ uint32_t CallingConvention;
+ uint16_t NumberOfArguments;
+};
+
+extern "C" struct MemberFunctionIdTypeDescriptor {
+ uint32_t MemberFunction;
+ uint32_t ParentClass;
+ char *Name;
+};
+
+class ArrayDimensionsDescriptor {
+public:
+ const char *GetLengthName(unsigned index);
+ const char *GetBoundsName(unsigned index);
+
+private:
+ void Resize(unsigned NewSize);
+
+ std::vector<std::string> Lengths;
+ std::vector<std::string> Bounds;
+};
+
+#pragma pack(pop)
+class UserDefinedTypesBuilder {
+public:
+ UserDefinedTypesBuilder();
+ void SetStreamer(MCObjectStreamer *Streamer);
+ void SetTargetPointerSize(unsigned TargetPointerSize);
+ void EmitTypeInformation(MCSection *COFFDebugTypesSection);
+
+ unsigned GetEnumTypeIndex(const EnumTypeDescriptor &TypeDescriptor,
+ const EnumRecordTypeDescriptor *TypeRecords);
+ unsigned GetClassTypeIndex(const ClassTypeDescriptor &ClassDescriptor);
+ unsigned GetCompleteClassTypeIndex(
+ const ClassTypeDescriptor &ClassDescriptor,
+ const ClassFieldsTypeDescriptior &ClassFieldsDescriptor,
+ const DataFieldDescriptor *FieldsDescriptors);
+
+ unsigned GetArrayTypeIndex(const ClassTypeDescriptor &ClassDescriptor,
+ const ArrayTypeDescriptor &ArrayDescriptor);
+
+ unsigned GetPointerTypeIndex(const PointerTypeDescriptor& PointerDescriptor);
+
+ unsigned GetMemberFunctionTypeIndex(const MemberFunctionTypeDescriptor& MemberDescriptor,
+ uint32_t const *const ArgumentTypes);
+
+ unsigned GetMemberFunctionId(const MemberFunctionIdTypeDescriptor& MemberIdDescriptor);
+
+ const std::vector<std::pair<std::string, codeview::TypeIndex>> &GetUDTs() {
+ return UserDefinedTypes;
+ }
+
+private:
+ void EmitCodeViewMagicVersion();
+ ClassOptions GetCommonClassOptions();
+
+ unsigned GetEnumFieldListType(uint64 Count,
+ const EnumRecordTypeDescriptor *TypeRecords);
+
+ void AddBaseClass(FieldListRecordBuilder &FLBR, unsigned BaseClassId);
+ void AddClassVTShape(FieldListRecordBuilder &FLBR);
+
+ BumpPtrAllocator Allocator;
+ TypeTableBuilder TypeTable;
+
+ MCObjectStreamer *Streamer;
+ unsigned TargetPointerSize;
+
+ ArrayDimensionsDescriptor ArrayDimentions;
+ TypeIndex ClassVTableTypeIndex;
+
+ std::vector<std::pair<std::string, codeview::TypeIndex>> UserDefinedTypes;
+};
diff --git a/src/Native/Runtime/unix/UnixContext.cpp b/src/Native/Runtime/unix/UnixContext.cpp
index 3be92658f..0fdbc23ca 100644
--- a/src/Native/Runtime/unix/UnixContext.cpp
+++ b/src/Native/Runtime/unix/UnixContext.cpp
@@ -197,45 +197,11 @@
#endif // __APPLE__
-// Update unw_context_t from REGDISPLAY
-static void RegDisplayToUnwindContext(REGDISPLAY* regDisplay, unw_context_t *unwContext)
-{
-#if defined(_ARM_)
- // Assuming that unw_set_reg() on cursor will point the cursor to the
- // supposed stack frame is dangerous for libunwind-arm in Linux.
- // It is because libunwind's unw_cursor_t has other data structure
- // initialized by unw_init_local(), which are not updated by
- // unw_set_reg().
-
-#define ASSIGN_REG(regIndex, regName) \
- unwContext->data[regIndex] = (regDisplay->regName);
-
-#define ASSIGN_REG_PTR(regIndex, regName) \
- if (regDisplay->p##regName != NULL) \
- unwContext->data[regIndex] = *(regDisplay->p##regName);
-
- ASSIGN_REG_PTR(4, R4);
- ASSIGN_REG_PTR(5, R5);
- ASSIGN_REG_PTR(6, R6);
- ASSIGN_REG_PTR(7, R7);
- ASSIGN_REG_PTR(8, R8);
- ASSIGN_REG_PTR(9, R9);
- ASSIGN_REG_PTR(10, R10);
- ASSIGN_REG_PTR(11, R11);
- ASSIGN_REG(13, SP);
- ASSIGN_REG_PTR(14, LR);
- ASSIGN_REG(15, IP);
-
-#undef ASSIGN_REG
-#undef ASSIGN_REG_PTR
-
-#endif // _ARM_
-}
-
-// Update unw_cursor_t from REGDISPLAY
+// Update unw_cursor_t from REGDISPLAY.
+// NOTE: We don't set the IP here since the current use cases for this function
+// don't require it.
static void RegDisplayToUnwindCursor(REGDISPLAY* regDisplay, unw_cursor_t *cursor)
{
-#if defined(_AMD64_)
#define ASSIGN_REG(regName1, regName2) \
unw_set_reg(cursor, regName1, regDisplay->regName2);
@@ -243,7 +209,7 @@ static void RegDisplayToUnwindCursor(REGDISPLAY* regDisplay, unw_cursor_t *curso
if (regDisplay->p##regName2 != NULL) \
unw_set_reg(cursor, regName1, *(regDisplay->p##regName2));
- ASSIGN_REG(UNW_REG_IP, IP)
+#if defined(_AMD64_)
ASSIGN_REG(UNW_REG_SP, SP)
ASSIGN_REG_PTR(UNW_X86_64_RBP, Rbp)
ASSIGN_REG_PTR(UNW_X86_64_RBX, Rbx)
@@ -251,10 +217,61 @@ static void RegDisplayToUnwindCursor(REGDISPLAY* regDisplay, unw_cursor_t *curso
ASSIGN_REG_PTR(UNW_X86_64_R13, R13)
ASSIGN_REG_PTR(UNW_X86_64_R14, R14)
ASSIGN_REG_PTR(UNW_X86_64_R15, R15)
+#elif _ARM_
+ ASSIGN_REG(UNW_ARM_SP, SP)
+ ASSIGN_REG_PTR(UNW_ARM_R4, R4)
+ ASSIGN_REG_PTR(UNW_ARM_R5, R5)
+ ASSIGN_REG_PTR(UNW_ARM_R6, R6)
+ ASSIGN_REG_PTR(UNW_ARM_R7, R7)
+ ASSIGN_REG_PTR(UNW_ARM_R8, R8)
+ ASSIGN_REG_PTR(UNW_ARM_R9, R9)
+ ASSIGN_REG_PTR(UNW_ARM_R10, R10)
+ ASSIGN_REG_PTR(UNW_ARM_R11, R11)
+ ASSIGN_REG_PTR(UNW_ARM_R14, LR)
+#endif
#undef ASSIGN_REG
#undef ASSIGN_REG_PTR
-#endif // _AMD64_
+}
+
+// Returns the unw_proc_info_t for a given IP.
+bool GetUnwindProcInfo(PCODE ip, unw_proc_info_t *procInfo)
+{
+ int st;
+
+ unw_context_t unwContext;
+ unw_cursor_t cursor;
+
+ st = unw_getcontext(&unwContext);
+ if (st < 0)
+ {
+ return false;
+ }
+
+#ifdef _AMD64_
+ // We manually index into the unw_context_t's internals for now because there's
+ // no better way to modify it. This will go away in the future when we locate the
+ // LSDA and other information without initializing an unwind cursor.
+ unwContext.data[16] = ip;
+#elif _ARM_
+ ((uint32_t*)(unwContext.data))[15] = ip;
+#else
+ #error "GetUnwindProcInfo is not supported on this arch yet."
+#endif
+
+ st = unw_init_local(&cursor, &unwContext);
+ if (st < 0)
+ {
+ return false;
+ }
+
+ st = unw_get_proc_info(&cursor, procInfo);
+ if (st < 0)
+ {
+ return false;
+ }
+
+ return true;
}
// Initialize unw_cursor_t and unw_context_t from REGDISPLAY
@@ -268,7 +285,18 @@ bool InitializeUnwindContextAndCursor(REGDISPLAY* regDisplay, unw_cursor_t* curs
return false;
}
- RegDisplayToUnwindContext(regDisplay, unwContext);
+ // Set the IP here instead of after unwinder initialization. unw_init_local
+ // will do some initialization of internal structures based on the IP value.
+ // We manually index into the unw_context_t's internals for now because there's
+ // no better way to modify it. This whole function will go away in the future
+ // when we are able to read unwind info without initializing an unwind cursor.
+#ifdef _AMD64_
+ unwContext->data[16] = regDisplay->IP;
+#elif _ARM_
+ ((uint32_t*)(unwContext->data))[15] = regDisplay->IP;
+#else
+ #error "InitializeUnwindContextAndCursor is not supported on this arch yet."
+#endif
st = unw_init_local(cursor, unwContext);
if (st < 0)
@@ -276,7 +304,7 @@ bool InitializeUnwindContextAndCursor(REGDISPLAY* regDisplay, unw_cursor_t* curs
return false;
}
- // Set the unwind context to the specified windows context
+ // Set the unwind context to the specified Windows context.
RegDisplayToUnwindCursor(regDisplay, cursor);
return true;
@@ -516,21 +544,9 @@ uint64_t GetPC(void* context)
// Find LSDA and start address for a function at address controlPC
bool FindProcInfo(UIntNative controlPC, UIntNative* startAddress, UIntNative* lsda)
{
- unw_context_t unwContext;
- unw_cursor_t cursor;
- REGDISPLAY regDisplay;
- memset(&regDisplay, 0, sizeof(REGDISPLAY));
-
- regDisplay.SetIP((PCODE)controlPC);
-
- if (!InitializeUnwindContextAndCursor(&regDisplay, &cursor, &unwContext))
- {
- return false;
- }
-
unw_proc_info_t procInfo;
- int st = unw_get_proc_info(&cursor, &procInfo);
- if (st < 0)
+
+ if (!GetUnwindProcInfo((PCODE)controlPC, &procInfo))
{
return false;
}
diff --git a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
index 90a656f52..5b7629f24 100644
--- a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
+++ b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
@@ -53,6 +53,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\CharEnumerator.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\CLSCompliantAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\DictionaryEntry.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\Dictionary.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\ICollection.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\ICollectionDebugView.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IComparer.cs" />
@@ -67,7 +68,9 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IReadOnlyList.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\KeyNotFoundException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\KeyValuePair.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\NonRandomizedStringEqualityComparer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\List.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\HashHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\ICollection.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\IComparer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\IDictionary.cs" />
diff --git a/src/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs
index bf5e4df08..5b576973a 100644
--- a/src/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs
+++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs
@@ -1,8 +1,7 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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 Internal.Runtime.CompilerServices;
using System;
using System.Collections;
using System.Diagnostics;
@@ -50,7 +49,6 @@ namespace System.Collections.Generic
private Entry[] entries;
private int count;
private int version;
-
private int freeList;
private int freeCount;
private IEqualityComparer<TKey> comparer;
@@ -60,7 +58,7 @@ namespace System.Collections.Generic
// constants for serialization
private const string VersionName = "Version"; // Do not rename (binary serialization)
- private const string HashSizeName = "HashSize"; // Do not rename (binary serialization). Must save buckets.Length
+ private const string HashSizeName = "HashSize"; // Do not rename (binary serialization). Must save buckets.Length
private const string KeyValuePairsName = "KeyValuePairs"; // Do not rename (binary serialization)
private const string ComparerName = "Comparer"; // Do not rename (binary serialization)
@@ -72,7 +70,7 @@ namespace System.Collections.Generic
public Dictionary(int capacity, IEqualityComparer<TKey> comparer)
{
- if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity), capacity, SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (capacity < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity);
if (capacity > 0) Initialize(capacity);
this.comparer = comparer ?? EqualityComparer<TKey>.Default;
@@ -89,7 +87,7 @@ namespace System.Collections.Generic
{
if (dictionary == null)
{
- throw new ArgumentNullException(nameof(dictionary));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
}
// It is likely that the passed-in dictionary is Dictionary<TKey,TValue>. When this is the case,
@@ -124,7 +122,7 @@ namespace System.Collections.Generic
{
if (collection == null)
{
- throw new ArgumentNullException(nameof(collection));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
foreach (KeyValuePair<TKey, TValue> pair in collection)
@@ -138,7 +136,7 @@ namespace System.Collections.Generic
// We can't do anything with the keys and values until the entire graph has been deserialized
// and we have a resonable estimate that GetHashCode is not going to fail. For the time being,
// we'll just cache this. The graph is not valid until OnDeserialization has been called.
- DictionaryHashHelpers.SerializationInfoTable.Add(this, info);
+ HashHelpers.SerializationInfoTable.Add(this, info);
}
public IEqualityComparer<TKey> Comparer
@@ -214,7 +212,8 @@ namespace System.Collections.Generic
{
int i = FindEntry(key);
if (i >= 0) return entries[i].value;
- throw new KeyNotFoundException();
+ ThrowHelper.ThrowKeyNotFoundException();
+ return default(TValue);
}
set
{
@@ -297,17 +296,17 @@ namespace System.Collections.Generic
{
if (array == null)
{
- throw new ArgumentNullException(nameof(array));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
if (index < 0 || index > array.Length)
{
- throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < Count)
{
- throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
int count = this.count;
@@ -335,7 +334,7 @@ namespace System.Collections.Generic
{
if (info == null)
{
- throw new ArgumentNullException(nameof(info));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.info);
}
info.AddValue(VersionName, version);
@@ -354,7 +353,7 @@ namespace System.Collections.Generic
{
if (key == null)
{
- throw new ArgumentNullException(nameof(key));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
if (buckets != null)
@@ -381,7 +380,7 @@ namespace System.Collections.Generic
{
if (key == null)
{
- throw new ArgumentNullException(nameof(key));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
if (buckets == null) Initialize(0);
@@ -402,7 +401,7 @@ namespace System.Collections.Generic
if (behavior == InsertionBehavior.ThrowOnExisting)
{
- throw new ArgumentException(SR.Format(SR.Argument_AddingDuplicate, key));
+ ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(key);
}
return false;
@@ -411,7 +410,6 @@ namespace System.Collections.Generic
}
int index;
-
if (freeCount > 0)
{
index = freeList;
@@ -436,6 +434,9 @@ namespace System.Collections.Generic
buckets[targetBucket] = index;
version++;
+ // If we hit the collision threshold we'll need to switch to the comparer which is using randomized string hashing
+ // i.e. EqualityComparer<string>.Default.
+
if (collisionCount > HashHelpers.HashCollisionThreshold && comparer is NonRandomizedStringEqualityComparer)
{
comparer = (IEqualityComparer<TKey>)EqualityComparer<string>.Default;
@@ -448,7 +449,8 @@ namespace System.Collections.Generic
public virtual void OnDeserialization(object sender)
{
SerializationInfo siInfo;
- DictionaryHashHelpers.SerializationInfoTable.TryGetValue(this, out siInfo);
+ HashHelpers.SerializationInfoTable.TryGetValue(this, out siInfo);
+
if (siInfo == null)
{
// We can return immediately if this function is called twice.
@@ -467,19 +469,19 @@ namespace System.Collections.Generic
entries = new Entry[hashsize];
freeList = -1;
- KeyValuePair<TKey, TValue>[] array =
- (KeyValuePair<TKey, TValue>[])siInfo.GetValue(KeyValuePairsName, typeof(KeyValuePair<TKey, TValue>[]));
+ KeyValuePair<TKey, TValue>[] array = (KeyValuePair<TKey, TValue>[])
+ siInfo.GetValue(KeyValuePairsName, typeof(KeyValuePair<TKey, TValue>[]));
if (array == null)
{
- throw new SerializationException(SR.Serialization_MissingKeys);
+ ThrowHelper.ThrowSerializationException(ExceptionResource.Serialization_MissingKeys);
}
for (int i = 0; i < array.Length; i++)
{
if (array[i].Key == null)
{
- throw new SerializationException(SR.Serialization_NullKey);
+ ThrowHelper.ThrowSerializationException(ExceptionResource.Serialization_NullKey);
}
Add(array[i].Key, array[i].Value);
}
@@ -490,7 +492,7 @@ namespace System.Collections.Generic
}
version = realVersion;
- DictionaryHashHelpers.SerializationInfoTable.Remove(this);
+ HashHelpers.SerializationInfoTable.Remove(this);
}
private void Resize()
@@ -503,7 +505,6 @@ namespace System.Collections.Generic
Debug.Assert(newSize >= entries.Length);
int[] newBuckets = new int[newSize];
for (int i = 0; i < newBuckets.Length; i++) newBuckets[i] = -1;
-
Entry[] newEntries = new Entry[newSize];
Array.Copy(entries, 0, newEntries, 0, count);
@@ -539,7 +540,7 @@ namespace System.Collections.Generic
{
if (key == null)
{
- throw new ArgumentNullException(nameof(key));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
if (buckets != null)
@@ -547,27 +548,40 @@ namespace System.Collections.Generic
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int bucket = hashCode % buckets.Length;
int last = -1;
- for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next)
+ int i = buckets[bucket];
+ while (i >= 0)
{
- if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
+ ref Entry entry = ref entries[i];
+
+ if (entry.hashCode == hashCode && comparer.Equals(entry.key, key))
{
if (last < 0)
{
- buckets[bucket] = entries[i].next;
+ buckets[bucket] = entry.next;
}
else
{
- entries[last].next = entries[i].next;
+ entries[last].next = entry.next;
+ }
+ entry.hashCode = -1;
+ entry.next = freeList;
+
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<TKey>())
+ {
+ entry.key = default(TKey);
+ }
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<TValue>())
+ {
+ entry.value = default(TValue);
}
- entries[i].hashCode = -1;
- entries[i].next = freeList;
- entries[i].key = default(TKey);
- entries[i].value = default(TValue);
freeList = i;
freeCount++;
version++;
return true;
}
+
+ last = i;
+ i = entry.next;
}
}
return false;
@@ -580,7 +594,7 @@ namespace System.Collections.Generic
{
if (key == null)
{
- throw new ArgumentNullException(nameof(key));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
if (buckets != null)
@@ -588,30 +602,43 @@ namespace System.Collections.Generic
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int bucket = hashCode % buckets.Length;
int last = -1;
- for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next)
+ int i = buckets[bucket];
+ while (i >= 0)
{
- if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
+ ref Entry entry = ref entries[i];
+
+ if (entry.hashCode == hashCode && comparer.Equals(entry.key, key))
{
if (last < 0)
{
- buckets[bucket] = entries[i].next;
+ buckets[bucket] = entry.next;
}
else
{
- entries[last].next = entries[i].next;
+ entries[last].next = entry.next;
}
- value = entries[i].value;
+ value = entry.value;
- entries[i].hashCode = -1;
- entries[i].next = freeList;
- entries[i].key = default(TKey);
- entries[i].value = default(TValue);
+ entry.hashCode = -1;
+ entry.next = freeList;
+
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<TKey>())
+ {
+ entry.key = default(TKey);
+ }
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<TValue>())
+ {
+ entry.value = default(TValue);
+ }
freeList = i;
freeCount++;
version++;
return true;
}
+
+ last = i;
+ i = entry.next;
}
}
value = default(TValue);
@@ -646,27 +673,27 @@ namespace System.Collections.Generic
{
if (array == null)
{
- throw new ArgumentNullException(nameof(array));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
if (array.Rank != 1)
{
- throw new ArgumentException(SR.Arg_RankMultiDimNotSupported, nameof(array));
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
if (array.GetLowerBound(0) != 0)
{
- throw new ArgumentException(SR.Arg_NonZeroLowerBound, nameof(array));
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
if (index < 0 || index > array.Length)
{
- throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < Count)
{
- throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
KeyValuePair<TKey, TValue>[] pairs = array as KeyValuePair<TKey, TValue>[];
@@ -678,7 +705,6 @@ namespace System.Collections.Generic
{
DictionaryEntry[] dictEntryArray = array as DictionaryEntry[];
Entry[] entries = this.entries;
-
for (int i = 0; i < count; i++)
{
if (entries[i].hashCode >= 0)
@@ -692,7 +718,7 @@ namespace System.Collections.Generic
object[] objects = array as object[];
if (objects == null)
{
- throw new ArgumentException(SR.Argument_InvalidArrayType, nameof(array));
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
try
@@ -709,7 +735,7 @@ namespace System.Collections.Generic
}
catch (ArrayTypeMismatchException)
{
- throw new ArgumentException(SR.Argument_InvalidArrayType, nameof(array));
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
@@ -730,7 +756,7 @@ namespace System.Collections.Generic
{
if (_syncRoot == null)
{
- System.Threading.Interlocked.CompareExchange<object>(ref _syncRoot, new object(), null);
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
return _syncRoot;
}
@@ -774,10 +800,9 @@ namespace System.Collections.Generic
{
if (key == null)
{
- throw new ArgumentNullException(nameof(key));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
- if (value == null && !(default(TValue) == null))
- throw new ArgumentNullException(nameof(value));
+ ThrowHelper.IfNullAndNullsAreIllegalThenThrow<TValue>(value, ExceptionArgument.value);
try
{
@@ -788,12 +813,12 @@ namespace System.Collections.Generic
}
catch (InvalidCastException)
{
- throw new ArgumentException(SR.Format(SR.Arg_WrongType, value, typeof(TValue)), nameof(value));
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(TValue));
}
}
catch (InvalidCastException)
{
- throw new ArgumentException(SR.Format(SR.Arg_WrongType, key, typeof(TKey)), nameof(key));
+ ThrowHelper.ThrowWrongKeyTypeArgumentException(key, typeof(TKey));
}
}
}
@@ -802,7 +827,7 @@ namespace System.Collections.Generic
{
if (key == null)
{
- throw new ArgumentNullException(nameof(key));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
return (key is TKey);
}
@@ -811,11 +836,9 @@ namespace System.Collections.Generic
{
if (key == null)
{
- throw new ArgumentNullException(nameof(key));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
-
- if (value == null && !(default(TValue) == null))
- throw new ArgumentNullException(nameof(value));
+ ThrowHelper.IfNullAndNullsAreIllegalThenThrow<TValue>(value, ExceptionArgument.value);
try
{
@@ -827,12 +850,12 @@ namespace System.Collections.Generic
}
catch (InvalidCastException)
{
- throw new ArgumentException(SR.Format(SR.Arg_WrongType, value, typeof(TValue)), nameof(value));
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(TValue));
}
}
catch (InvalidCastException)
{
- throw new ArgumentException(SR.Format(SR.Arg_WrongType, key, typeof(TKey)), nameof(key));
+ ThrowHelper.ThrowWrongKeyTypeArgumentException(key, typeof(TKey));
}
}
@@ -884,20 +907,20 @@ namespace System.Collections.Generic
{
if (version != dictionary.version)
{
- throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
// Use unsigned comparison since we set index to dictionary.count+1 when the enumeration ends.
// dictionary.count+1 could be negative if dictionary.count is Int32.MaxValue
while ((uint)index < (uint)dictionary.count)
{
- if (dictionary.entries[index].hashCode >= 0)
+ ref Entry entry = ref dictionary.entries[index++];
+
+ if (entry.hashCode >= 0)
{
- current = new KeyValuePair<TKey, TValue>(dictionary.entries[index].key, dictionary.entries[index].value);
- index++;
+ current = new KeyValuePair<TKey, TValue>(entry.key, entry.value);
return true;
}
- index++;
}
index = dictionary.count + 1;
@@ -920,7 +943,7 @@ namespace System.Collections.Generic
{
if (index == 0 || (index == dictionary.count + 1))
{
- throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
if (getEnumeratorRetType == DictEntry)
@@ -938,7 +961,7 @@ namespace System.Collections.Generic
{
if (version != dictionary.version)
{
- throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
index = 0;
@@ -951,7 +974,7 @@ namespace System.Collections.Generic
{
if (index == 0 || (index == dictionary.count + 1))
{
- throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return new DictionaryEntry(current.Key, current.Value);
@@ -964,7 +987,7 @@ namespace System.Collections.Generic
{
if (index == 0 || (index == dictionary.count + 1))
{
- throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return current.Key;
@@ -977,7 +1000,7 @@ namespace System.Collections.Generic
{
if (index == 0 || (index == dictionary.count + 1))
{
- throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return current.Value;
@@ -995,7 +1018,7 @@ namespace System.Collections.Generic
{
if (dictionary == null)
{
- throw new ArgumentNullException(nameof(dictionary));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
}
this.dictionary = dictionary;
}
@@ -1009,22 +1032,21 @@ namespace System.Collections.Generic
{
if (array == null)
{
- throw new ArgumentNullException(nameof(array));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
if (index < 0 || index > array.Length)
{
- throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < dictionary.Count)
{
- throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
int count = dictionary.count;
Entry[] entries = dictionary.entries;
-
for (int i = 0; i < count; i++)
{
if (entries[i].hashCode >= 0) array[index++] = entries[i].key;
@@ -1043,12 +1065,12 @@ namespace System.Collections.Generic
void ICollection<TKey>.Add(TKey item)
{
- throw new NotSupportedException(SR.NotSupported_KeyCollectionSet);
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
}
void ICollection<TKey>.Clear()
{
- throw new NotSupportedException(SR.NotSupported_KeyCollectionSet);
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
}
bool ICollection<TKey>.Contains(TKey item)
@@ -1058,7 +1080,8 @@ namespace System.Collections.Generic
bool ICollection<TKey>.Remove(TKey item)
{
- throw new NotSupportedException(SR.NotSupported_KeyCollectionSet);
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
+ return false;
}
IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator()
@@ -1075,27 +1098,27 @@ namespace System.Collections.Generic
{
if (array == null)
{
- throw new ArgumentNullException(nameof(array));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
if (array.Rank != 1)
{
- throw new ArgumentException(SR.Arg_RankMultiDimNotSupported, nameof(array));
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
if (array.GetLowerBound(0) != 0)
{
- throw new ArgumentException(SR.Arg_NonZeroLowerBound, nameof(array));
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
if (index < 0 || index > array.Length)
{
- throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < dictionary.Count)
{
- throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
TKey[] keys = array as TKey[];
@@ -1108,12 +1131,11 @@ namespace System.Collections.Generic
object[] objects = array as object[];
if (objects == null)
{
- throw new ArgumentException(SR.Argument_InvalidArrayType, nameof(array));
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
int count = dictionary.count;
Entry[] entries = dictionary.entries;
-
try
{
for (int i = 0; i < count; i++)
@@ -1123,7 +1145,7 @@ namespace System.Collections.Generic
}
catch (ArrayTypeMismatchException)
{
- throw new ArgumentException(SR.Argument_InvalidArrayType, nameof(array));
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
@@ -1161,18 +1183,18 @@ namespace System.Collections.Generic
{
if (version != dictionary.version)
{
- throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
while ((uint)index < (uint)dictionary.count)
{
- if (dictionary.entries[index].hashCode >= 0)
+ ref Entry entry = ref dictionary.entries[index++];
+
+ if (entry.hashCode >= 0)
{
- currentKey = dictionary.entries[index].key;
- index++;
+ currentKey = entry.key;
return true;
}
- index++;
}
index = dictionary.count + 1;
@@ -1194,7 +1216,7 @@ namespace System.Collections.Generic
{
if (index == 0 || (index == dictionary.count + 1))
{
- throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return currentKey;
@@ -1205,7 +1227,7 @@ namespace System.Collections.Generic
{
if (version != dictionary.version)
{
- throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
index = 0;
@@ -1224,7 +1246,7 @@ namespace System.Collections.Generic
{
if (dictionary == null)
{
- throw new ArgumentNullException(nameof(dictionary));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
}
this.dictionary = dictionary;
}
@@ -1238,22 +1260,21 @@ namespace System.Collections.Generic
{
if (array == null)
{
- throw new ArgumentNullException(nameof(array));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
if (index < 0 || index > array.Length)
{
- throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < dictionary.Count)
{
- throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
int count = dictionary.count;
Entry[] entries = dictionary.entries;
-
for (int i = 0; i < count; i++)
{
if (entries[i].hashCode >= 0) array[index++] = entries[i].value;
@@ -1272,17 +1293,18 @@ namespace System.Collections.Generic
void ICollection<TValue>.Add(TValue item)
{
- throw new NotSupportedException(SR.NotSupported_ValueCollectionSet);
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
}
bool ICollection<TValue>.Remove(TValue item)
{
- throw new NotSupportedException(SR.NotSupported_ValueCollectionSet);
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
+ return false;
}
void ICollection<TValue>.Clear()
{
- throw new NotSupportedException(SR.NotSupported_ValueCollectionSet);
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
}
bool ICollection<TValue>.Contains(TValue item)
@@ -1304,26 +1326,26 @@ namespace System.Collections.Generic
{
if (array == null)
{
- throw new ArgumentNullException(nameof(array));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
if (array.Rank != 1)
{
- throw new ArgumentException(SR.Arg_RankMultiDimNotSupported, nameof(array));
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
if (array.GetLowerBound(0) != 0)
{
- throw new ArgumentException(SR.Arg_NonZeroLowerBound, nameof(array));
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
if (index < 0 || index > array.Length)
{
- throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < dictionary.Count)
- throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
TValue[] values = array as TValue[];
if (values != null)
@@ -1335,12 +1357,11 @@ namespace System.Collections.Generic
object[] objects = array as object[];
if (objects == null)
{
- throw new ArgumentException(SR.Argument_InvalidArrayType, nameof(array));
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
int count = dictionary.count;
Entry[] entries = dictionary.entries;
-
try
{
for (int i = 0; i < count; i++)
@@ -1350,7 +1371,7 @@ namespace System.Collections.Generic
}
catch (ArrayTypeMismatchException)
{
- throw new ArgumentException(SR.Argument_InvalidArrayType, nameof(array));
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
@@ -1388,18 +1409,18 @@ namespace System.Collections.Generic
{
if (version != dictionary.version)
{
- throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
while ((uint)index < (uint)dictionary.count)
{
- if (dictionary.entries[index].hashCode >= 0)
+ ref Entry entry = ref dictionary.entries[index++];
+
+ if (entry.hashCode >= 0)
{
- currentValue = dictionary.entries[index].value;
- index++;
+ currentValue = entry.value;
return true;
}
- index++;
}
index = dictionary.count + 1;
currentValue = default(TValue);
@@ -1420,7 +1441,7 @@ namespace System.Collections.Generic
{
if (index == 0 || (index == dictionary.count + 1))
{
- throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return currentValue;
@@ -1431,7 +1452,7 @@ namespace System.Collections.Generic
{
if (version != dictionary.version)
{
- throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
index = 0;
currentValue = default(TValue);
@@ -1439,9 +1460,4 @@ namespace System.Collections.Generic
}
}
}
-
- internal class DictionaryHashHelpers
- {
- internal static ConditionalWeakTable<object, SerializationInfo> SerializationInfoTable { get; } = new ConditionalWeakTable<object, SerializationInfo>();
- }
}
diff --git a/src/System.Private.CoreLib/shared/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs
new file mode 100644
index 000000000..ef44fefc8
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs
@@ -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.Runtime.Serialization;
+
+namespace System.Collections.Generic
+{
+ // NonRandomizedStringEqualityComparer is the comparer used by default with the Dictionary<string,...>
+ // We use NonRandomizedStringEqualityComparer as default comparer as it doesnt use the randomized string hashing which
+ // keeps the performance not affected till we hit collision threshold and then we switch to the comparer which is using
+ // randomized string hashing.
+ [Serializable] // Required for compatibility with .NET Core 2.0 as we exposed the NonRandomizedStringEqualityComparer inside the serialization blob
+#if CORECLR
+ internal
+#else
+ public
+#endif
+ sealed class NonRandomizedStringEqualityComparer : EqualityComparer<string>, ISerializable
+ {
+ internal static new IEqualityComparer<string> Default { get; } = new NonRandomizedStringEqualityComparer();
+
+ private NonRandomizedStringEqualityComparer() { }
+
+ // This is used by the serialization engine.
+ private NonRandomizedStringEqualityComparer(SerializationInfo information, StreamingContext context) { }
+
+ public sealed override bool Equals(string x, string y) => string.Equals(x, y);
+
+ public sealed override int GetHashCode(string obj) => obj?.GetLegacyNonRandomizedHashCode() ?? 0;
+
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ // We are doing this to stay compatible with .NET Framework.
+ info.SetType(typeof(GenericEqualityComparer<string>));
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/System/Collections/HashHelpers.cs b/src/System.Private.CoreLib/shared/System/Collections/HashHelpers.cs
new file mode 100644
index 000000000..49cff85b5
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/System/Collections/HashHelpers.cs
@@ -0,0 +1,108 @@
+// 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.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+using System.Threading;
+
+namespace System.Collections
+{
+ internal static class HashHelpers
+ {
+ public const int HashCollisionThreshold = 100;
+
+ public const int HashPrime = 101;
+
+ // Table of prime numbers to use as hash table sizes.
+ // A typical resize algorithm would pick the smallest prime number in this array
+ // that is larger than twice the previous capacity.
+ // Suppose our Hashtable currently has capacity x and enough elements are added
+ // such that a resize needs to occur. Resizing first computes 2x then finds the
+ // first prime in the table greater than 2x, i.e. if primes are ordered
+ // p_1, p_2, ..., p_i, ..., it finds p_n such that p_n-1 < 2x < p_n.
+ // Doubling is important for preserving the asymptotic complexity of the
+ // hashtable operations such as add. Having a prime guarantees that double
+ // hashing does not lead to infinite loops. IE, your hash function will be
+ // h1(key) + i*h2(key), 0 <= i < size. h2 and the size must be relatively prime.
+ public static readonly int[] primes = {
+ 3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919,
+ 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591,
+ 17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437,
+ 187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263,
+ 1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369};
+
+ public static bool IsPrime(int candidate)
+ {
+ if ((candidate & 1) != 0)
+ {
+ int limit = (int)Math.Sqrt(candidate);
+ for (int divisor = 3; divisor <= limit; divisor += 2)
+ {
+ if ((candidate % divisor) == 0)
+ return false;
+ }
+ return true;
+ }
+ return (candidate == 2);
+ }
+
+ public static int GetPrime(int min)
+ {
+ if (min < 0)
+ throw new ArgumentException(SR.Arg_HTCapacityOverflow);
+
+ for (int i = 0; i < primes.Length; i++)
+ {
+ int prime = primes[i];
+ if (prime >= min) return prime;
+ }
+
+ //outside of our predefined table.
+ //compute the hard way.
+ for (int i = (min | 1); i < Int32.MaxValue; i += 2)
+ {
+ if (IsPrime(i) && ((i - 1) % HashPrime != 0))
+ return i;
+ }
+ return min;
+ }
+
+ // Returns size of hashtable to grow to.
+ public static int ExpandPrime(int oldSize)
+ {
+ int newSize = 2 * oldSize;
+
+ // Allow the hashtables to grow to maximum possible size (~2G elements) before encoutering capacity overflow.
+ // Note that this check works even when _items.Length overflowed thanks to the (uint) cast
+ if ((uint)newSize > MaxPrimeArrayLength && MaxPrimeArrayLength > oldSize)
+ {
+ Debug.Assert(MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength");
+ return MaxPrimeArrayLength;
+ }
+
+ return GetPrime(newSize);
+ }
+
+
+ // This is the maximum prime smaller than Array.MaxArrayLength
+ public const int MaxPrimeArrayLength = 0x7FEFFFFD;
+
+
+ // Used by Hashtable and Dictionary's SeralizationInfo .ctor's to store the SeralizationInfo
+ // object until OnDeserialization is called.
+ private static ConditionalWeakTable<object, SerializationInfo> s_serializationInfoTable;
+
+ internal static ConditionalWeakTable<object, SerializationInfo> SerializationInfoTable
+ {
+ get
+ {
+ if (s_serializationInfoTable == null)
+ Interlocked.CompareExchange(ref s_serializationInfoTable, new ConditionalWeakTable<object, SerializationInfo>(), null);
+
+ return s_serializationInfoTable;
+ }
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs
index 071911813..fa3e7c06c 100644
--- a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs
+++ b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs
@@ -35,7 +35,7 @@ namespace System.Runtime.CompilerServices
/// <summary>Provides an awaiter for a <see cref="ConfiguredValueTaskAwaitable{TResult}"/>.</summary>
[StructLayout(LayoutKind.Auto)]
- public struct ConfiguredValueTaskAwaiter : ICriticalNotifyCompletion
+ public struct ConfiguredValueTaskAwaiter : ICriticalNotifyCompletion, IConfiguredValueTaskAwaiter
{
/// <summary>The value being awaited.</summary>
private ValueTask<TResult> _value; // Methods are called on this; avoid making it readonly so as to avoid unnecessary copies
@@ -71,6 +71,18 @@ namespace System.Runtime.CompilerServices
/// <summary>Gets the task underlying <see cref="_value"/>.</summary>
internal Task<TResult> AsTask() => _value.AsTask();
+
+ /// <summary>Gets the task underlying the incomplete <see cref="_value"/>.</summary>
+ /// <remarks>This method is used when awaiting and IsCompleted returned false; thus we expect the value task to be wrapping a non-null task.</remarks>
+ (Task, bool) IConfiguredValueTaskAwaiter.GetTask() => (_value.AsTaskExpectNonNull(), _continueOnCapturedContext);
}
}
+
+ /// <summary>
+ /// Internal interface used to enable extract the Task from arbitrary configured ValueTask awaiters.
+ /// </summary>
+ internal interface IConfiguredValueTaskAwaiter
+ {
+ (Task task, bool continueOnCapturedContext) GetTask();
+ }
}
diff --git a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs
index 203039a4a..0b0ed8595 100644
--- a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs
+++ b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs
@@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace System.Runtime.CompilerServices
{
/// <summary>Provides an awaiter for a <see cref="ValueTask{TResult}"/>.</summary>
- public struct ValueTaskAwaiter<TResult> : ICriticalNotifyCompletion
+ public struct ValueTaskAwaiter<TResult> : ICriticalNotifyCompletion, IValueTaskAwaiter
{
/// <summary>The value being awaited.</summary>
private ValueTask<TResult> _value; // Methods are called on this; avoid making it readonly so as to avoid unnecessary copies
@@ -38,5 +38,17 @@ namespace System.Runtime.CompilerServices
/// <summary>Gets the task underlying <see cref="_value"/>.</summary>
internal Task<TResult> AsTask() => _value.AsTask();
+
+ /// <summary>Gets the task underlying the incomplete <see cref="_value"/>.</summary>
+ /// <remarks>This method is used when awaiting and IsCompleted returned false; thus we expect the value task to be wrapping a non-null task.</remarks>
+ Task IValueTaskAwaiter.GetTask() => _value.AsTaskExpectNonNull();
+ }
+
+ /// <summary>
+ /// Internal interface used to enable extract the Task from arbitrary ValueTask awaiters.
+ /// </summary>>
+ internal interface IValueTaskAwaiter
+ {
+ Task GetTask();
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs
index 384e4a8ab..4ccf0f8a4 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs
@@ -116,6 +116,15 @@ namespace System.Threading.Tasks
// and the hash code we generate in GetHashCode.
_task ?? AsyncTaskMethodBuilder<TResult>.GetTaskForResult(_result);
+ internal Task<TResult> AsTaskExpectNonNull() =>
+ // Return the task if we were constructed from one, otherwise manufacture one.
+ // Unlike AsTask(), this method is called only when we expect _task to be non-null,
+ // and thus we don't want GetTaskForResult inlined.
+ _task ?? GetTaskForResultNoInlining();
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private Task<TResult> GetTaskForResultNoInlining() => AsyncTaskMethodBuilder<TResult>.GetTaskForResult(_result);
+
/// <summary>Gets whether the <see cref="ValueTask{TResult}"/> represents a completed operation.</summary>
public bool IsCompleted => _task == null || _task.IsCompleted;
diff --git a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
index 941ff5475..3c4f91f71 100644
--- a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
+++ b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
@@ -195,8 +195,6 @@
<Compile Include="System\Collections\Generic\CompatibilityEqualityComparers.cs" />
<Compile Include="System\Collections\Generic\EqualityComparer.cs" />
<Compile Include="System\Collections\Generic\EqualOnlyComparer.cs" />
- <Compile Include="System\Collections\Generic\Dictionary.cs" />
- <Compile Include="System\Collections\Generic\NonRandomizedStringEqualityComparer.cs" />
<Compile Include="System\Collections\LowLevelComparer.cs" />
<Compile Include="System\CurrentSystemTimeZone.Cache.cs" />
<Compile Include="System\Decimal.DecCalc.cs" />
@@ -709,9 +707,6 @@
<Compile Include="..\..\Common\src\System\Collections\Generic\LowLevelDictionary.cs">
<Link>System\Collections\Generic\LowLevelDictionary.cs</Link>
</Compile>
- <Compile Include="..\..\Common\src\System\Collections\HashHelpers.cs">
- <Link>System\Collections\HashHelpers.cs</Link>
- </Compile>
<Compile Include="..\..\Common\src\System\Collections\Concurrent\ConcurrentUnifier.cs">
<Link>System\Collections\Concurrent\ConcurrentUnifier.cs</Link>
</Compile>
diff --git a/src/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs b/src/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs
deleted file mode 100644
index a1f3e38bd..000000000
--- a/src/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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.
-
-namespace System.Collections.Generic
-{
- // NonRandomizedStringEqualityComparer is the comparer used by default with the Dictionary<string,...>
- // As the randomized string hashing is now turned on with no opt-out, we need to keep the performance not affected
- // as much as possible in the main stream scenarios like Dictionary<string,>
- // We use NonRandomizedStringEqualityComparer as default comparer as it doesnt use the randomized string hashing which
- // keep the performance not affected till we hit collision threshold and then we switch to the comparer which is using
- // randomized string hashing.
- [Serializable]
- [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
- public sealed class NonRandomizedStringEqualityComparer : EqualityComparer<string>
- {
- private static volatile IEqualityComparer<string> s_nonRandomizedComparer;
-
- internal static new IEqualityComparer<string> Default => s_nonRandomizedComparer ?? (s_nonRandomizedComparer = new NonRandomizedStringEqualityComparer());
-
- public sealed override bool Equals(string x, string y) => string.Equals(x, y);
-
- public sealed override int GetHashCode(string obj)
- {
- if (obj == null)
- return 0;
- return obj.GetLegacyNonRandomizedHashCode();
- }
- }
-}
diff --git a/src/System.Private.CoreLib/src/System/Decimal.cs b/src/System.Private.CoreLib/src/System/Decimal.cs
index 9ee8069f3..ad5709161 100644
--- a/src/System.Private.CoreLib/src/System/Decimal.cs
+++ b/src/System.Private.CoreLib/src/System/Decimal.cs
@@ -556,6 +556,11 @@ namespace System
return Number.TryParseDecimal(s.AsReadOnlySpan(), NumberStyles.Number, null, out result);
}
+ public static bool TryParse(ReadOnlySpan<char> s, out decimal result)
+ {
+ return Number.TryParseDecimal(s, NumberStyles.Number, null, out result);
+ }
+
public static Boolean TryParse(String s, NumberStyles style, IFormatProvider provider, out Decimal result)
{
ValidateParseStyleFloatingPoint(style);
@@ -567,7 +572,7 @@ namespace System
return Number.TryParseDecimal(s.AsReadOnlySpan(), style, provider, out result);
}
- public static Boolean TryParse(ReadOnlySpan<char> s, out Decimal result, NumberStyles style = NumberStyles.Integer, IFormatProvider provider = null)
+ public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider provider, out decimal result)
{
ValidateParseStyleFloatingPoint(style);
return Number.TryParseDecimal(s, style, provider, out result);
diff --git a/src/System.Private.CoreLib/src/System/ThrowHelper.cs b/src/System.Private.CoreLib/src/System/ThrowHelper.cs
index 4ca4103dc..01a31fae6 100644
--- a/src/System.Private.CoreLib/src/System/ThrowHelper.cs
+++ b/src/System.Private.CoreLib/src/System/ThrowHelper.cs
@@ -35,8 +35,10 @@
// multiple times for different instantiation.
//
+using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
namespace System
{
@@ -102,6 +104,38 @@ namespace System
ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
+ private static ArgumentException GetWrongKeyTypeArgumentException(object key, Type targetType)
+ {
+ return new ArgumentException(SR.Format(SR.Arg_WrongType, key, targetType), nameof(key));
+ }
+ internal static void ThrowWrongKeyTypeArgumentException(object key, Type targetType)
+ {
+ throw GetWrongKeyTypeArgumentException(key, targetType);
+ }
+
+ private static ArgumentException GetWrongValueTypeArgumentException(object value, Type targetType)
+ {
+ return new ArgumentException(SR.Format(SR.Arg_WrongType, value, targetType), nameof(value));
+ }
+ internal static void ThrowWrongValueTypeArgumentException(object value, Type targetType)
+ {
+ throw GetWrongValueTypeArgumentException(value, targetType);
+ }
+
+ private static ArgumentException GetAddingDuplicateWithKeyArgumentException(object key)
+ {
+ return new ArgumentException(SR.Format(SR.Argument_AddingDuplicate, key));
+ }
+ internal static void ThrowAddingDuplicateWithKeyArgumentException(object key)
+ {
+ throw GetAddingDuplicateWithKeyArgumentException(key);
+ }
+
+ internal static void ThrowKeyNotFoundException()
+ {
+ throw new KeyNotFoundException();
+ }
+
internal static void ThrowArgumentException(ExceptionResource resource)
{
throw new ArgumentException(GetResourceString(resource));
@@ -121,15 +155,6 @@ namespace System
throw new ArgumentException(GetResourceString(ExceptionResource.Argument_InvalidArrayType));
}
- private static ArgumentException GetWrongValueTypeArgumentException(object value, Type targetType)
- {
- return new ArgumentException(SR.Format(SR.Arg_WrongType, value, targetType), nameof(value));
- }
- internal static void ThrowWrongValueTypeArgumentException(object value, Type targetType)
- {
- throw GetWrongValueTypeArgumentException(value, targetType);
- }
-
internal static void ThrowArgumentNullException(ExceptionArgument argument)
{
throw new ArgumentNullException(GetArgumentName(argument));
@@ -155,6 +180,10 @@ namespace System
throw new InvalidOperationException(GetResourceString(ExceptionResource.InvalidOperation_EnumOpCantHappen));
}
+ internal static void ThrowSerializationException(ExceptionResource resource)
+ {
+ throw new SerializationException(GetResourceString(resource));
+ }
internal static void ThrowNotSupportedException(ExceptionResource resource)
{
@@ -176,14 +205,20 @@ namespace System
{
switch (argument)
{
+ case ExceptionArgument.obj:
+ return "obj";
+ case ExceptionArgument.dictionary:
+ return "dictionary";
case ExceptionArgument.array:
return "array";
+ case ExceptionArgument.info:
+ return "info";
+ case ExceptionArgument.key:
+ return "key";
case ExceptionArgument.text:
return "text";
case ExceptionArgument.values:
return "values";
- case ExceptionArgument.obj:
- return "obj";
case ExceptionArgument.value:
return "value";
case ExceptionArgument.startIndex:
@@ -218,6 +253,8 @@ namespace System
return "comparison";
case ExceptionArgument.pointer:
return "pointer";
+ case ExceptionArgument.start:
+ return "start";
default:
Debug.Assert(false,
"The enum value is not defined, please check the ExceptionArgument Enum.");
@@ -261,6 +298,14 @@ namespace System
return SR.InvalidOperation_EnumFailedVersion;
case ExceptionResource.InvalidOperation_EnumOpCantHappen:
return SR.InvalidOperation_EnumOpCantHappen;
+ case ExceptionResource.Serialization_MissingKeys:
+ return SR.Serialization_MissingKeys;
+ case ExceptionResource.Serialization_NullKey:
+ return SR.Serialization_NullKey;
+ case ExceptionResource.NotSupported_KeyCollectionSet:
+ return SR.NotSupported_KeyCollectionSet;
+ case ExceptionResource.NotSupported_ValueCollectionSet:
+ return SR.NotSupported_ValueCollectionSet;
default:
Debug.Assert(false,
"The enum value is not defined, please check the ExceptionResource Enum.");
@@ -274,10 +319,13 @@ namespace System
//
internal enum ExceptionArgument
{
+ obj,
+ dictionary,
array,
+ info,
+ key,
text,
values,
- obj,
value,
startIndex,
task,
@@ -295,6 +343,7 @@ namespace System
action,
comparison,
pointer,
+ start
}
//
@@ -318,5 +367,9 @@ namespace System
ArgumentOutOfRange_BiggerThanCollection,
InvalidOperation_EnumFailedVersion,
InvalidOperation_EnumOpCantHappen,
+ Serialization_MissingKeys,
+ Serialization_NullKey,
+ NotSupported_KeyCollectionSet,
+ NotSupported_ValueCollectionSet,
}
}
diff --git a/src/System.Private.Interop/src/Interop/Interop.WinRT.Basic.cs b/src/System.Private.Interop/src/Interop/Interop.WinRT.Basic.cs
index b265e8c16..8989c2f72 100644
--- a/src/System.Private.Interop/src/Interop/Interop.WinRT.Basic.cs
+++ b/src/System.Private.Interop/src/Interop/Interop.WinRT.Basic.cs
@@ -67,6 +67,7 @@ namespace System.Runtime.InteropServices
public static partial class ExternalInterop
{
+#if ENABLE_MIN_WINRT
[DllImport(Libraries.CORE_WINRT)]
[McgGeneratedNativeCallCodeAttribute]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
@@ -80,6 +81,7 @@ namespace System.Runtime.InteropServices
uint length,
HSTRING_HEADER* phstringHeader,
void* hstring);
+#endif
[DllImport(Libraries.CORE_COM)]
[McgGeneratedNativeCallCodeAttribute]
@@ -157,6 +159,7 @@ namespace System.Runtime.InteropServices
}
}
+#if ENABLE_MIN_WINRT
internal static unsafe void RoGetActivationFactory(string className, ref Guid iid, out IntPtr ppv)
{
fixed (char* unsafe_className = className)
@@ -186,6 +189,7 @@ namespace System.Runtime.InteropServices
}
}
}
+#endif
public static unsafe int CoGetContextToken(out IntPtr ppToken)
{
diff --git a/src/System.Private.Interop/src/System.Private.Interop.csproj b/src/System.Private.Interop/src/System.Private.Interop.csproj
index 34b57e303..a16d0f8ec 100644
--- a/src/System.Private.Interop/src/System.Private.Interop.csproj
+++ b/src/System.Private.Interop/src/System.Private.Interop.csproj
@@ -189,11 +189,11 @@
<Compile Include="Windows\Foundation\Size.cs" />
<Compile Include="Windows\Foundation\TokenizerHelper.cs" />
<Compile Include="Windows\Foundation\IReference.cs" />
+ <Compile Include="Interop\Interop.WinRT.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
<Compile Include="Interop\Interop.Sync.Windows.cs" />
- <Compile Include="Interop\Interop.WinRT.cs" />
<Compile Include="Interop\Interop.WinRT.Basic.cs" />
<Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.MemAllocFree.cs">
diff --git a/tests/src/Simple/HelloWasm/Program.cs b/tests/src/Simple/HelloWasm/Program.cs
index 453a8555e..6d4a5a6e7 100644
--- a/tests/src/Simple/HelloWasm/Program.cs
+++ b/tests/src/Simple/HelloWasm/Program.cs
@@ -11,10 +11,12 @@ internal static class Program
private static unsafe void Main(string[] args)
{
Add(1, 2);
-
+ var tempObj = new TestClass(1337);
int tempInt = 0;
(*(&tempInt)) = 9;
+ tempObj.TestMethod("Hello");
+
if(tempInt == 9)
{
PrintLine("Hello from C#!");
@@ -22,6 +24,8 @@ internal static class Program
TwoByteStr str = new TwoByteStr() { first = 1, second = 2 };
TwoByteStr str2 = new TwoByteStr() { first = 3, second = 4 };
+ *(&str) = str2;
+ str2 = *(&str);
if (str2.second == 4)
{
@@ -34,6 +38,12 @@ internal static class Program
PrintLine("static int field test: Ok.");
}
+ var boxedInt = (object)tempInt;
+ if(((int)boxedInt) == 9)
+ {
+ PrintLine("box test: Ok.");
+ }
+
var not = Not(0xFFFFFFFF) == 0x00000000;
if (not)
{
@@ -57,6 +67,7 @@ internal static class Program
{
PrintLine("shiftRight test: Ok.");
}
+
var unsignedShift = UnsignedShift(0xFFFFFFFFu, 4) == 0x0FFFFFFFu;
if (unsignedShift)
{
@@ -159,3 +170,21 @@ public struct TwoByteStr
public byte second;
}
+public class TestClass
+{
+ public string TestString {get; set;}
+
+ public TestClass(int number)
+ {
+ if(number != 1337)
+ throw new Exception();
+ }
+
+ public void TestMethod(string str)
+ {
+ TestString = str;
+ if(TestString != str)
+ throw new Exception();
+ }
+}
+