diff --git a/.vsconfig b/.vsconfig
index 402799aa5537e..f949b82c3744d 100644
--- a/.vsconfig
+++ b/.vsconfig
@@ -41,7 +41,6 @@
"Microsoft.VisualStudio.Component.VC.CMake.Project",
"Microsoft.VisualStudio.Component.VC.CoreIde",
"Microsoft.VisualStudio.Component.VC.Redist.14.Latest",
- "Microsoft.VisualStudio.Component.VC.Tools.ARM",
"Microsoft.VisualStudio.Component.VC.Tools.ARM64",
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"Microsoft.VisualStudio.Component.Windows10SDK.19041",
diff --git a/docs/infra/test-configurations.md b/docs/infra/test-configurations.md
index 3b96e74e66c82..eabcc14bd8c1e 100644
--- a/docs/infra/test-configurations.md
+++ b/docs/infra/test-configurations.md
@@ -29,7 +29,6 @@ All builds are
- Windows 10 x64 Client VS2019
- x64 Release
- x86 Release
- - arm32 Release
- arm64 Release
- Ubuntu 18.04 x64
- Linux x64 Release
diff --git a/docs/workflow/README.md b/docs/workflow/README.md
index dbef0e3e7a533..74bbc892f3efa 100644
--- a/docs/workflow/README.md
+++ b/docs/workflow/README.md
@@ -17,8 +17,8 @@ The repo can be built for the following platforms, using the provided setup and
| :---- | :------: | :------: | :------: | :------: |
| x64 | ✔ | ✔ | ✔ | ✔ |
| x86 | ✔ | | | |
-| ARM | ✔ | ✔ | | |
-| ARM64 | ✔ | ✔ | ✔ | |
+| Arm32 | | ✔ | | |
+| Arm64 | ✔ | ✔ | ✔ | |
| | [Requirements](requirements/windows-requirements.md) | [Requirements](requirements/linux-requirements.md) | [Requirements](requirements/macos-requirements.md) | [Requirements](requirements/freebsd-requirements.md)
Additionally, keep in mind that cloning the full history of this repo takes roughly 400-500 MB of network transfer, inflating to a repository that can consume somewhere between 1 to 1.5 GB. A build of the repo can take somewhere between 10 and 20 GB of space for a single OS and Platform configuration depending on the portions of the product built. This might increase over time, so consider this to be a minimum bar for working with this codebase.
diff --git a/docs/workflow/building/coreclr/cross-building.md b/docs/workflow/building/coreclr/cross-building.md
index 4fbbdebdd404e..7bbe28abb6410 100644
--- a/docs/workflow/building/coreclr/cross-building.md
+++ b/docs/workflow/building/coreclr/cross-building.md
@@ -1,7 +1,7 @@
# Cross-Building for Different Architectures and Operating Systems
* [Windows Cross-Building](#windows-cross-building)
- * [Cross-Compiling for ARM32 and ARM64 on Windows](#cross-compiling-for-arm32-and-arm64-on-windows)
+ * [Cross-Compiling for ARM64 on Windows](#cross-compiling-for-arm64-on-windows)
* [Cross-Compiling for x86 on Windows](#cross-compiling-for-x86-on-windows)
* [macOS Cross-Building](#macos-cross-building)
* [Linux Cross-Building](#linux-cross-building)
@@ -21,9 +21,9 @@ This guide will go more in-depth on how to do cross-building across multiple ope
This section will go over cross-compiling on Windows. Currently, Windows allows you to cross-compile from x64 to basically any other architecture.
-### Cross-Compiling for ARM32 and ARM64 on Windows
+### Cross-Compiling for ARM64 on Windows
-To do cross-compilation for ARM32/ARM64 on Windows, first make sure you have the appropriate tools and Windows SDK installed. This is described in detail in the [Windows requirements doc](/docs/workflow/requirements/windows-requirements.md#visual-studio).
+To do cross-compilation for ARM64 on Windows, first make sure you have the appropriate tools and Windows SDK installed. This is described in detail in the [Windows requirements doc](/docs/workflow/requirements/windows-requirements.md#visual-studio).
Once you have all the required dependencies, it is a straightforward process. Windows knows how to cross-build behind curtains, so all you have to do is specify which architecture you want to build for:
diff --git a/docs/workflow/requirements/windows-requirements.md b/docs/workflow/requirements/windows-requirements.md
index 4ee557ce63c35..06675bdb8c39e 100644
--- a/docs/workflow/requirements/windows-requirements.md
+++ b/docs/workflow/requirements/windows-requirements.md
@@ -35,8 +35,7 @@ Install [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/). The
* It's recommended to use **Workloads** installation approach. The following are the minimum requirements:
* **.NET Desktop Development** with all default components,
* **Desktop Development with C++** with all default components.
-* To build for Arm32 or Arm64, make sure that you have the right architecture-specific compilers installed. In the **Individual components** window, in the **Compilers, build tools, and runtimes** section:
- * For Arm32, check the box for _MSVC v143* VS 2022 C++ ARM build tools (Latest)_.
+* To build for Arm64, make sure that you have the right architecture-specific compilers installed. In the **Individual components** window, in the **Compilers, build tools, and runtimes** section:
* For Arm64, check the box for _MSVC v143* VS 2022 C++ ARM64 build tools (Latest)_.
* To build the tests, you will need some additional components:
* **C++/CLI support for v142 build tools (Latest)**.
diff --git a/eng/Subsets.props b/eng/Subsets.props
index f1af6a47bfddc..093120feb2411 100644
--- a/eng/Subsets.props
+++ b/eng/Subsets.props
@@ -267,19 +267,6 @@
Category="clr" />
-
-
-
-
diff --git a/eng/pipelines/mono/templates/workloads-build.yml b/eng/pipelines/mono/templates/workloads-build.yml
index 55060a01171c6..fb53430c03791 100644
--- a/eng/pipelines/mono/templates/workloads-build.yml
+++ b/eng/pipelines/mono/templates/workloads-build.yml
@@ -72,7 +72,6 @@ jobs:
IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.WebAssembly.Sdk*.nupkg
IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.WebAssembly.Wasi*.nupkg
IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.WebAssembly.Templates*.nupkg
- IntermediateArtifacts/windows_arm/Shipping/Microsoft.NETCore.App.Runtime.win-arm*.nupkg
IntermediateArtifacts/windows_arm64/Shipping/Microsoft.NETCore.App.Runtime.win-arm64*.nupkg
IntermediateArtifacts/windows_x64/Shipping/Microsoft.NETCore.App.Runtime.win-x64*.nupkg
IntermediateArtifacts/windows_x86/Shipping/Microsoft.NETCore.App.Runtime.win-x86*.nupkg
diff --git a/src/coreclr/CMakeSettings.json b/src/coreclr/CMakeSettings.json
index c60469ea8ad48..10c8ff47cb5bf 100644
--- a/src/coreclr/CMakeSettings.json
+++ b/src/coreclr/CMakeSettings.json
@@ -50,29 +50,6 @@
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x86" ]
},
- {
- "name": "windows.arm.Debug",
- "generator": "Ninja",
- "configurationType": "Debug",
- "buildRoot": "${env.artifactsObj}\\${name}",
- "installRoot": "${env.artifactsBin}\\${name}",
- "cmakeCommandArgs": "-DCLR_CMAKE_HOST_ARCH=arm",
- "buildCommandArgs": "",
- "ctestCommandArgs": "",
- "inheritEnvironments": [ "msvc_arm" ]
- },
- {
- "name": "windows.arm.Release",
- "generator": "Ninja",
- "configurationType": "Release",
- "buildRoot": "${env.artifactsObj}\\${name}",
- "installRoot": "${env.artifactsBin}\\${name}",
- "cmakeCommandArgs": "-DCLR_CMAKE_HOST_ARCH=arm",
- "buildCommandArgs": "",
- "ctestCommandArgs": "",
- "inheritEnvironments": [ "msvc_arm" ],
- "variables": []
- },
{
"name": "windows.arm64.Debug",
"generator": "Ninja",
@@ -98,4 +75,4 @@
"variables": []
}
]
-}
\ No newline at end of file
+}
diff --git a/src/coreclr/build-runtime.cmd b/src/coreclr/build-runtime.cmd
index a8fca255b8611..40ced7a1f977c 100644
--- a/src/coreclr/build-runtime.cmd
+++ b/src/coreclr/build-runtime.cmd
@@ -42,7 +42,6 @@ set __BuildAll=
set __TargetArchX64=0
set __TargetArchX86=0
-set __TargetArchArm=0
set __TargetArchArm64=0
set __BuildTypeDebug=0
@@ -87,7 +86,6 @@ if /i "%1" == "--help" goto Usage
if /i "%1" == "-all" (set __BuildAll=1&shift&goto Arg_Loop)
if /i "%1" == "-x64" (set __TargetArchX64=1&shift&goto Arg_Loop)
if /i "%1" == "-x86" (set __TargetArchX86=1&shift&goto Arg_Loop)
-if /i "%1" == "-arm" (set __TargetArchArm=1&shift&goto Arg_Loop)
if /i "%1" == "-arm64" (set __TargetArchArm64=1&shift&goto Arg_Loop)
if /i "%1" == "-debug" (set __BuildTypeDebug=1&shift&goto Arg_Loop)
@@ -101,7 +99,6 @@ REM don't add more, use the - syntax instead
if /i "%1" == "all" (set __BuildAll=1&shift&goto Arg_Loop)
if /i "%1" == "x64" (set __TargetArchX64=1&shift&goto Arg_Loop)
if /i "%1" == "x86" (set __TargetArchX86=1&shift&goto Arg_Loop)
-if /i "%1" == "arm" (set __TargetArchArm=1&shift&goto Arg_Loop)
if /i "%1" == "arm64" (set __TargetArchArm64=1&shift&goto Arg_Loop)
if /i "%1" == "debug" (set __BuildTypeDebug=1&shift&goto Arg_Loop)
@@ -165,7 +162,7 @@ if defined VCINSTALLDIR (
if defined __BuildAll goto BuildAll
-set /A __TotalSpecifiedTargetArch=__TargetArchX64 + __TargetArchX86 + __TargetArchArm + __TargetArchArm64
+set /A __TotalSpecifiedTargetArch=__TargetArchX64 + __TargetArchX86 + __TargetArchArm64
if %__TotalSpecifiedTargetArch% GTR 1 (
echo Error: more than one build architecture specified, but "all" not specified.
goto Usage
@@ -176,7 +173,6 @@ if "%__ProcessorArch%"=="" set __ProcessorArch=%PROCESSOR_ARCHITECTURE%
if %__TargetArchX64%==1 set __TargetArch=x64
if %__TargetArchX86%==1 set __TargetArch=x86
-if %__TargetArchArm%==1 set __TargetArch=arm
if %__TargetArchArm64%==1 set __TargetArch=arm64
if "%__HostArch%" == "" set __HostArch=%__TargetArch%
@@ -191,10 +187,6 @@ if %__BuildTypeChecked%==1 set __BuildType=Checked
if %__BuildTypeRelease%==1 set __BuildType=Release
if %__EnforcePgo%==1 (
- if %__TargetArchArm%==1 (
- echo NOTICE: enforcepgo does nothing on arm architecture
- set __EnforcePgo=0
- )
if %__TargetArchArm64%==1 (
echo NOTICE: enforcepgo does nothing on arm64 architecture
set __EnforcePgo=0
@@ -451,7 +443,7 @@ REM ============================================================================
set __TargetArchList=
-set /A __TotalSpecifiedTargetArch=__TargetArchX64 + __TargetArchX86 + __TargetArchArm + __TargetArchArm64
+set /A __TotalSpecifiedTargetArch=__TargetArchX64 + __TargetArchX86 + __TargetArchArm64
if %__TotalSpecifiedTargetArch% EQU 0 (
REM Nothing specified means we want to build all architectures.
set __TargetArchList=x64 x86 arm arm64
@@ -461,7 +453,6 @@ REM Otherwise, add all the specified architectures to the list.
if %__TargetArchX64%==1 set __TargetArchList=%__TargetArchList% x64
if %__TargetArchX86%==1 set __TargetArchList=%__TargetArchList% x86
-if %__TargetArchArm%==1 set __TargetArchList=%__TargetArchList% arm
if %__TargetArchArm64%==1 set __TargetArchList=%__TargetArchList% arm64
set __BuildTypeList=
@@ -545,7 +536,7 @@ echo All arguments are optional. The options are:
echo.
echo.-? -h -help --help: view this message.
echo -all: Builds all configurations and platforms.
-echo Build architecture: one of -x64, -x86, -arm, -arm64 ^(default: -x64^).
+echo Build architecture: one of -x64, -x86, -arm64 ^(default: -x64^).
echo Build type: one of -Debug, -Checked, -Release ^(default: -Debug^).
echo -component ^ : specify this option one or more times to limit components built to those specified.
echo Allowed ^: hosts jit alljits runtime paltests iltools nativeaot spmi
diff --git a/src/coreclr/debug/di/arm/floatconversion.asm b/src/coreclr/debug/di/arm/floatconversion.asm
deleted file mode 100644
index a8b62b8892121..0000000000000
--- a/src/coreclr/debug/di/arm/floatconversion.asm
+++ /dev/null
@@ -1,17 +0,0 @@
-; Licensed to the .NET Foundation under one or more agreements.
-; The .NET Foundation licenses this file to you under the MIT license.
-
-#include "ksarm.h"
-
-;; Arguments
-;; input: (in R0) the address of the ULONGLONG to be converted to a double
-;; output: the double corresponding to the ULONGLONG input value
-
- LEAF_ENTRY FPFillR8
- vldr D0, [R0]
- bx lr
- LEAF_END
-
-
-;; Must be at very end of file
- END
diff --git a/src/coreclr/debug/ee/arm/dbghelpers.asm b/src/coreclr/debug/ee/arm/dbghelpers.asm
deleted file mode 100644
index 0d1040859af44..0000000000000
--- a/src/coreclr/debug/ee/arm/dbghelpers.asm
+++ /dev/null
@@ -1,89 +0,0 @@
-; Licensed to the .NET Foundation under one or more agreements.
-; The .NET Foundation licenses this file to you under the MIT license.
-
-#include "ksarm.h"
-#include "asmconstants.h"
-
- IMPORT FuncEvalHijackWorker
- IMPORT FuncEvalHijackPersonalityRoutine
- IMPORT ExceptionHijackWorker
- IMPORT ExceptionHijackPersonalityRoutine
- EXPORT ExceptionHijackEnd
-
- MACRO
- CHECK_STACK_ALIGNMENT
-
-#ifdef _DEBUG
- push {r0}
- add r0, sp, #4
- tst r0, #7
- pop {r0}
- beq %0
- EMIT_BREAKPOINT
-0
-#endif
- MEND
-
- TEXTAREA
-
-;
-; hijacking stub used to perform a func-eval, see Debugger::FuncEvalSetup() for use.
-;
-; on entry:
-; r0 : pointer to DebuggerEval object
-;
-
- NESTED_ENTRY FuncEvalHijack,,FuncEvalHijackPersonalityRoutine
-
- ; NOTE: FuncEvalHijackPersonalityRoutine is dependent on the stack layout so if
- ; you change the prolog you will also need to update the personality routine.
-
- ; push arg to the stack so our personality routine can find it
- ; push lr to get good stacktrace in debugger
- PROLOG_PUSH {r0,lr}
-
- CHECK_STACK_ALIGNMENT
-
- ; FuncEvalHijackWorker returns the address we should jump to.
- bl FuncEvalHijackWorker
-
- ; effective NOP to terminate unwind
- mov r2, r2
-
- EPILOG_STACK_FREE 8
- EPILOG_BRANCH_REG r0
-
- NESTED_END FuncEvalHijack
-
-;
-; This is the general purpose hijacking stub. DacDbiInterfaceImpl::Hijack() will
-; set the registers with the appropriate parameters from out-of-process.
-;
-; on entry:
-; r0 : pointer to CONTEXT
-; r1 : pointer to EXCEPTION_RECORD
-; r2 : EHijackReason
-; r3 : void* pdata
-;
-
- NESTED_ENTRY ExceptionHijack,,ExceptionHijackPersonalityRoutine
-
- CHECK_STACK_ALIGNMENT
-
- ; make the call
- bl ExceptionHijackWorker
-
- ; effective NOP to terminate unwind
- mov r3, r3
-
- ; *** should never get here ***
- EMIT_BREAKPOINT
-
-; exported label so the debugger knows where the end of this function is
-ExceptionHijackEnd
- NESTED_END
-
-
- ; must be at end of file
- END
-
diff --git a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt
index 2eb522293a107..84e4b42284a52 100644
--- a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt
+++ b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt
@@ -187,8 +187,6 @@ if(CLR_CMAKE_TARGET_WIN32)
set(CLRDEBUGINFO_RESOURCE_NAME CLRDEBUGINFOWINDOWSX86)
elseif(CLR_CMAKE_TARGET_ARCH_ARM64)
set(CLRDEBUGINFO_RESOURCE_NAME CLRDEBUGINFOWINDOWSARM64)
- elseif(CLR_CMAKE_TARGET_ARCH_ARM)
- set(CLRDEBUGINFO_RESOURCE_NAME CLRDEBUGINFOWINDOWSARM)
endif(CLR_CMAKE_TARGET_ARCH_AMD64)
add_custom_target(
diff --git a/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp b/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp
index aceb755fa5dd5..96cc1e3934ef4 100644
--- a/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp
+++ b/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp
@@ -123,7 +123,7 @@ static PTR_VOID GetUnwindDataBlob(TADDR moduleBase, PTR_RUNTIME_FUNCTION pRuntim
return pUnwindInfo;
-#elif defined(TARGET_ARM) || defined(TARGET_ARM64)
+#elif defined(TARGET_ARM64)
// if this function uses packed unwind data then at least one of the two least significant bits
// will be non-zero. if this is the case then there will be no xdata record to enumerate.
@@ -133,15 +133,9 @@ static PTR_VOID GetUnwindDataBlob(TADDR moduleBase, PTR_RUNTIME_FUNCTION pRuntim
PTR_UInt32 xdata = dac_cast(pRuntimeFunction->UnwindData + moduleBase);
int size = 4;
-#if defined(TARGET_ARM)
- // See https://docs.microsoft.com/en-us/cpp/build/arm-exception-handling
- int unwindWords = xdata[0] >> 28;
- int epilogScopes = (xdata[0] >> 23) & 0x1f;
-#else
// See https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
int unwindWords = xdata[0] >> 27;
int epilogScopes = (xdata[0] >> 22) & 0x1f;
-#endif
if (unwindWords == 0 && epilogScopes == 0)
{
@@ -191,10 +185,6 @@ static int LookupUnwindInfoForMethod(uint32_t relativePc,
int low,
int high)
{
-#ifdef TARGET_ARM
- relativePc |= THUMB_CODE;
-#endif
-
// Binary search the RUNTIME_FUNCTION table
// Use linear search once we get down to a small number of elements
// to avoid Binary search overhead.
@@ -504,7 +494,7 @@ uintptr_t CoffNativeCodeManager::GetConservativeUpperBoundForOutgoingArgs(Method
upperBound = dac_cast(pRegisterSet->GetFP() - ((PTR_UNWIND_INFO) pUnwindDataBlob)->FrameOffset);
}
-#elif defined(TARGET_ARM) || defined(TARGET_ARM64)
+#elif defined(TARGET_ARM64)
// Unwind the current method context to get the caller's stack pointer
// and use it as the upper bound for the callee
SIZE_T EstablisherFrame;
@@ -733,9 +723,9 @@ bool CoffNativeCodeManager::GetReturnAddressHijackInfo(MethodInfo * pMethodIn
// Decode the GC info for the current method to determine its return type
GcInfoDecoderFlags flags = DECODE_RETURN_KIND;
-#if defined(TARGET_ARM) || defined(TARGET_ARM64)
+#if defined(TARGET_ARM64)
flags = (GcInfoDecoderFlags)(flags | DECODE_HAS_TAILCALLS);
-#endif // TARGET_ARM || TARGET_ARM64
+#endif // TARGET_ARM64
GcInfoDecoder decoder(GCInfoToken(p), flags);
*pRetValueKind = GetGcRefKind(decoder.GetReturnKind());
diff --git a/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.h b/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.h
index 50bbc0e85373c..445a998fdb00b 100644
--- a/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.h
+++ b/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.h
@@ -9,11 +9,6 @@ struct T_RUNTIME_FUNCTION {
uint32_t EndAddress;
uint32_t UnwindInfoAddress;
};
-#elif defined(TARGET_ARM)
-struct T_RUNTIME_FUNCTION {
- uint32_t BeginAddress;
- uint32_t UnwindData;
-};
#elif defined(TARGET_ARM64)
struct T_RUNTIME_FUNCTION {
uint32_t BeginAddress;
diff --git a/src/coreclr/vm/CMakeLists.txt b/src/coreclr/vm/CMakeLists.txt
index 9c3fbaff8a997..fada96c3a4a29 100644
--- a/src/coreclr/vm/CMakeLists.txt
+++ b/src/coreclr/vm/CMakeLists.txt
@@ -673,19 +673,6 @@ elseif(CLR_CMAKE_TARGET_ARCH_I386)
${ARCH_SOURCES_DIR}/thunktemplates.asm
)
- set(VM_HEADERS_WKS_ARCH_ASM
- ${ARCH_SOURCES_DIR}/asmconstants.h
- )
-elseif(CLR_CMAKE_TARGET_ARCH_ARM)
- set(VM_SOURCES_WKS_ARCH_ASM
- ${ARCH_SOURCES_DIR}/asmhelpers.asm
- ${ARCH_SOURCES_DIR}/CrtHelpers.asm
- ${ARCH_SOURCES_DIR}/ehhelpers.asm
- ${ARCH_SOURCES_DIR}/patchedcode.asm
- ${ARCH_SOURCES_DIR}/PInvokeStubs.asm
- ${ARCH_SOURCES_DIR}/thunktemplates.asm
- )
-
set(VM_HEADERS_WKS_ARCH_ASM
${ARCH_SOURCES_DIR}/asmconstants.h
)
diff --git a/src/coreclr/vm/arm/CrtHelpers.asm b/src/coreclr/vm/arm/CrtHelpers.asm
deleted file mode 100644
index fd762e74e0c39..0000000000000
--- a/src/coreclr/vm/arm/CrtHelpers.asm
+++ /dev/null
@@ -1,156 +0,0 @@
-; Licensed to the .NET Foundation under one or more agreements.
-; The .NET Foundation licenses this file to you under the MIT license.
-
-; ***********************************************************************
-; File: CrtHelpers.asm
-;
-; ***********************************************************************
-
-#include "ksarm.h"
-
-#include "asmconstants.h"
-
-#include "asmmacros.h"
-
- TEXTAREA
-
-; JIT_MemSet/JIT_MemCpy
-;
-; It is IMPORANT that the exception handling code is able to find these guys
-; on the stack, but to keep them from being tailcalled by VC++ we need to turn
-; off optimization and it ends up being a wasteful implementation.
-;
-; Hence these assembly helpers.
-;
-;EXTERN_C void __stdcall JIT_MemSet(void* _dest, int c, size_t count)
- LEAF_ENTRY JIT_MemSet
-
-;
-; The memset function sets the first count bytes of
-; dest to the character c (r1).
-;
-; Doesn't return a value
-;
-
- subs r2, r2, #4
- blt ByteSet
-
- ands r1, r1, #&FF
- orr r1, r1, r1, lsl #8
-CheckAlign ; 2-3 cycles
- ands r3, r0, #3 ; Check alignment and fix if possible
- bne Align
-
-BlockSet ; 6-7 cycles
- orr r1, r1, r1, lsl #16
- subs r2, r2, #12
- mov r3, r1
- blt BlkSet8
-
-BlkSet16 ; 7 cycles/16 bytes
- stm r0!, {r1, r3}
- subs r2, r2, #16
- stm r0!, {r1, r3}
- bge BlkSet16
-
-BlkSet8 ; 4 cycles/8 bytes
- adds r2, r2, #8
- blt BlkSet4
- stm r0!, {r1, r3}
- sub r2, r2, #8
-
-BlkSet4
- adds r2, r2, #4 ; 4 cycles/4 bytes
- blt ByteSet
- str r1, [r0], #4
- b MaybeExit
-
-ByteSet
- adds r2, r2, #4
-MaybeExit
- beq ExitMemSet
-
- strb r1, [r0] ; 5 cycles/1-3bytes
- cmp r2, #2
- blt ExitMemSet
- strb r1, [r0, #1]
- strbgt r1, [r0, #2]
-
-ExitMemSet
-
- bx lr
-
-Align ; 8 cycles/1-3 bytes
- tst r0, #1 ; Check byte alignment
- beq AlignHalf
- subs r2, r2, #1
- strb r1, [r0], #1
-AlignHalf
- tst r0, #2 ; Check Half-word alignment
- beq BlockSet
- subs r2, r2, #2
- strh r1, [r0], #2
- b BlockSet
-
- LEAF_END_MARKED JIT_MemSet
-
-
-;EXTERN_C void __stdcall JIT_MemCpy(void* _dest, const void *_src, size_t count)
- LEAF_ENTRY JIT_MemCpy
-;
-; It only requires 4 byte alignment
-; and doesn't return a value
-
- cmp r2, #0 ; quick check for 0 length
- beq ExitMemCpy ; if zero, exit
-
- tst r0, #3 ; skip directly to aligned if already aligned
- beq DestAligned ; if 0, we're already aligned; go large
-
-ByteLoop1
- subs r2, r2, #1 ; decrement byte counter
- ldrb r3, [r1], #1 ; copy one byte
- strb r3, [r0], #1
- beq ExitMemCpy ; if the byte counter hits 0, exit early
- tst r0, #3 ; are we aligned now?
- bne ByteLoop1 ; nope, keep going
-
-DestAligned
- subs r2, r2, #8 ; byte counter -= 8
- blt AlignedFinished ; if that puts us negative, skip the big copy
-
- tst r1, #3 ; is the 4-byte source aligned?
- addne r2, r2, #8 ; if not, fix the byte counter (+= 8)
- bne ByteLoop2 ; and do all the rest with bytes
-
-QwordLoop
- subs r2, r2, #8 ; decrement byte counter by 8
- ldm r1!, {r3,r12} ; copy one qword
- stm r0!, {r3,r12} ;
- bge QwordLoop ; loop until the byte counter goes negative
-
-AlignedFinished
- adds r2, r2, #4 ; add 4 to recover a potential >= 4-byte tail
- blt AlignedFinished2
- ldr r3, [r1], #4
- str r3, [r0], #4
- b MaybeExitMemCpy
-AlignedFinished2
- adds r2, r2, #4 ; add 4 more to the byte counter to recover
-
-MaybeExitMemCpy
- beq ExitMemCpy ; the remaining count
-
-ByteLoop2
- subs r2, r2, #1 ; decrement the counter
- ldrb r3, [r1], #1 ; copy one byte
- strb r3, [r0], #1
- bne ByteLoop2 ; loop until the counter hits 0
-
-ExitMemCpy
- bx lr
-
- LEAF_END_MARKED JIT_MemCpy
-
- END
-
diff --git a/src/coreclr/vm/arm/PInvokeStubs.asm b/src/coreclr/vm/arm/PInvokeStubs.asm
deleted file mode 100644
index 60209b08a5445..0000000000000
--- a/src/coreclr/vm/arm/PInvokeStubs.asm
+++ /dev/null
@@ -1,227 +0,0 @@
-; Licensed to the .NET Foundation under one or more agreements.
-; The .NET Foundation licenses this file to you under the MIT license.
-
-#include "ksarm.h"
-
-#include "asmconstants.h"
-
-#include "asmmacros.h"
-
-
- IMPORT VarargPInvokeStubWorker
- IMPORT GenericPInvokeCalliStubWorker
- IMPORT JIT_PInvokeEndRarePath
-
- IMPORT s_gsCookie
- IMPORT g_TrapReturningThreads
-
- SETALIAS InlinedCallFrame_vftable, ??_7InlinedCallFrame@@6B@
- IMPORT $InlinedCallFrame_vftable
-
-; ------------------------------------------------------------------
-; Macro to generate PInvoke Stubs.
-; $__PInvokeStubFuncName : function which calls the actual stub obtained from VASigCookie
-; $__PInvokeGenStubFuncName : function which generates the IL stubs for PInvoke
-;
-; Params :-
-; $FuncPrefix : prefix of the function name for the stub
-; Eg. VarargPinvoke, GenericPInvokeCalli
-; $VASigCookieReg : register which contains the VASigCookie
-; $SaveFPArgs : "Yes" or "No" . For varidic functions FP Args are not present in FP regs
-; So need not save FP Args registers for vararg Pinvoke
- MACRO
-
- PINVOKE_STUB $FuncPrefix,$VASigCookieReg,$SaveFPArgs
-
- GBLS __PInvokeStubFuncName
- GBLS __PInvokeGenStubFuncName
- GBLS __PInvokeStubWorkerName
-
- IF "$FuncPrefix" == "GenericPInvokeCalli"
-__PInvokeStubFuncName SETS "$FuncPrefix":CC:"Helper"
- ELSE
-__PInvokeStubFuncName SETS "$FuncPrefix":CC:"Stub"
- ENDIF
-__PInvokeGenStubFuncName SETS "$FuncPrefix":CC:"GenILStub"
-__PInvokeStubWorkerName SETS "$FuncPrefix":CC:"StubWorker"
-
- IF "$VASigCookieReg" == "r1"
-__PInvokeStubFuncName SETS "$__PInvokeStubFuncName":CC:"_RetBuffArg"
-__PInvokeGenStubFuncName SETS "$__PInvokeGenStubFuncName":CC:"_RetBuffArg"
- ENDIF
-
- NESTED_ENTRY $__PInvokeStubFuncName
-
- ; save reg value before using the reg
- PROLOG_PUSH {$VASigCookieReg}
-
- ; get the stub
- ldr $VASigCookieReg, [$VASigCookieReg,#VASigCookie__pNDirectILStub]
-
- ; if null goto stub generation
- cbz $VASigCookieReg, %0
-
- EPILOG_STACK_FREE 4
-
- EPILOG_BRANCH_REG $VASigCookieReg
-
-0
-
- EPILOG_POP {$VASigCookieReg}
- EPILOG_BRANCH $__PInvokeGenStubFuncName
-
- NESTED_END
-
-
- NESTED_ENTRY $__PInvokeGenStubFuncName
-
- PROLOG_WITH_TRANSITION_BLOCK 0, $SaveFPArgs
-
- ; r2 = UnmanagedTarget\ MethodDesc
- mov r2, r12
-
- ; r1 = VaSigCookie
- IF "$VASigCookieReg" != "r1"
- mov r1, $VASigCookieReg
- ENDIF
-
- ; r0 = pTransitionBlock
- add r0, sp, #__PWTB_TransitionBlock
-
- ; save hidden arg
- mov r4, r12
-
- bl $__PInvokeStubWorkerName
-
- ; restore hidden arg (method desc or unmanaged target)
- mov r12, r4
-
- EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
-
- EPILOG_BRANCH $__PInvokeStubFuncName
-
- NESTED_END
-
- MEND
-
-
-
- TEXTAREA
-; ------------------------------------------------------------------
-; JIT_PInvokeBegin helper
-;
-; in:
-; r0 = InlinedCallFrame*: pointer to the InlinedCallFrame data, including the GS cookie slot (GS cookie right
-; before actual InlinedCallFrame data)
-;
- LEAF_ENTRY JIT_PInvokeBegin
-
- ldr r1, =s_gsCookie
- ldr r1, [r1]
- str r1, [r0]
- add r0, r0, SIZEOF__GSCookie
-
- ;; r0 = pFrame
-
- ;; set first slot to the value of InlinedCallFrame::`vftable' (checked by runtime code)
- ldr r1, =$InlinedCallFrame_vftable
- str r1, [r0]
-
- mov r1, 0
- str r1, [r0, #InlinedCallFrame__m_Datum]
-
- str sp, [r0, #InlinedCallFrame__m_pCallSiteSP]
- str r11, [r0, #InlinedCallFrame__m_pCalleeSavedFP]
- str lr, [r0, #InlinedCallFrame__m_pCallerReturnAddress]
- str r9, [r0, #InlinedCallFrame__m_pSPAfterProlog]
-
- ;; r1 = GetThread(), TRASHES r2
- INLINE_GETTHREAD r1, r2
-
- ;; pFrame->m_Next = pThread->m_pFrame;
- ldr r2, [r1, #Thread_m_pFrame]
- str r2, [r0, #Frame__m_Next]
-
- ;; pThread->m_pFrame = pFrame;
- str r0, [r1, #Thread_m_pFrame]
-
- ;; pThread->m_fPreemptiveGCDisabled = 0
- mov r2, 0
- str r2, [r1, #Thread_m_fPreemptiveGCDisabled]
-
- bx lr
-
- LEAF_END
-
-; ------------------------------------------------------------------
-; JIT_PInvokeEnd helper
-;
-; in:
-; r0 = InlinedCallFrame*
-;
- LEAF_ENTRY JIT_PInvokeEnd
-
- add r0, r0, SIZEOF__GSCookie
-
- ;; r1 = GetThread(), TRASHES r2
- INLINE_GETTHREAD r1, r2
-
- ;; r0 = pFrame
- ;; r1 = pThread
-
- ;; pThread->m_fPreemptiveGCDisabled = 1
- mov r2, 1
- str r2, [r1, #Thread_m_fPreemptiveGCDisabled]
-
- ;; Check return trap
- ldr r2, =g_TrapReturningThreads
- ldr r2, [r2]
- cbnz r2, RarePath
-
- ;; pThread->m_pFrame = pFrame->m_Next
- ldr r2, [r0, #Frame__m_Next]
- str r2, [r1, #Thread_m_pFrame]
-
- bx lr
-
-RarePath
- b JIT_PInvokeEndRarePath
-
- LEAF_END
-
- INLINE_GETTHREAD_CONSTANT_POOL
-
-; ------------------------------------------------------------------
-; VarargPInvokeStub & VarargPInvokeGenILStub
-; There is a separate stub when the method has a hidden return buffer arg.
-;
-; in:
-; r0 = VASigCookie*
-; r12 = MethodDesc *
-;
- PINVOKE_STUB VarargPInvoke, r0, {false}
-
-
-; ------------------------------------------------------------------
-; GenericPInvokeCalliHelper & GenericPInvokeCalliGenILStub
-; Helper for generic pinvoke calli instruction
-;
-; in:
-; r4 = VASigCookie*
-; r12 = Unmanaged target
-;
- PINVOKE_STUB GenericPInvokeCalli, r4, {true}
-
-; ------------------------------------------------------------------
-; VarargPInvokeStub_RetBuffArg & VarargPInvokeGenILStub_RetBuffArg
-; Vararg PInvoke Stub when the method has a hidden return buffer arg
-;
-; in:
-; r1 = VASigCookie*
-; r12 = MethodDesc*
-;
- PINVOKE_STUB VarargPInvoke, r1, {false}
-
-
-; Must be at very end of file
- END
diff --git a/src/coreclr/vm/arm/asmhelpers.asm b/src/coreclr/vm/arm/asmhelpers.asm
deleted file mode 100644
index c47d56d9d8c12..0000000000000
--- a/src/coreclr/vm/arm/asmhelpers.asm
+++ /dev/null
@@ -1,1739 +0,0 @@
-; Licensed to the .NET Foundation under one or more agreements.
-; The .NET Foundation licenses this file to you under the MIT license.
-
-#include "ksarm.h"
-
-#include "asmconstants.h"
-
-#include "asmmacros.h"
-
- IMPORT JIT_InternalThrow
- IMPORT JIT_WriteBarrier
- IMPORT TheUMEntryPrestubWorker
- IMPORT PreStubWorker
- IMPORT PreStubGetMethodDescForCompactEntryPoint
- IMPORT NDirectImportWorker
- IMPORT VSD_ResolveWorker
-
-#ifdef WRITE_BARRIER_CHECK
- SETALIAS g_GCShadow, ?g_GCShadow@@3PAEA
- SETALIAS g_GCShadowEnd, ?g_GCShadowEnd@@3PAEA
-
- IMPORT g_lowest_address
- IMPORT $g_GCShadow
- IMPORT $g_GCShadowEnd
-#endif // WRITE_BARRIER_CHECK
-
-
-#ifdef FEATURE_COMINTEROP
- IMPORT CLRToCOMWorker
- IMPORT ComPreStubWorker
- IMPORT COMToCLRWorker
-#endif
- IMPORT CallDescrWorkerUnwindFrameChainHandler
- IMPORT UMEntryPrestubUnwindFrameChainHandler
-#ifdef FEATURE_COMINTEROP
- IMPORT ReverseComUnwindFrameChainHandler
-#endif
-
-#ifdef FEATURE_HIJACK
- IMPORT OnHijackWorker
-#endif ;FEATURE_HIJACK
-
- IMPORT GetCurrentSavedRedirectContext
-
- ;; Import to support cross-moodule external method invocation in ngen images
- IMPORT ExternalMethodFixupWorker
-
-#ifdef FEATURE_READYTORUN
- IMPORT DynamicHelperWorker
-#endif
-
- IMPORT JIT_RareDisableHelperWorker
-
- ;; Imports for singleDomain statics helpers
- IMPORT JIT_GetSharedNonGCStaticBase_Helper
- IMPORT JIT_GetSharedGCStaticBase_Helper
-
- TEXTAREA
-
-;; LPVOID __stdcall GetCurrentIP(void);
- LEAF_ENTRY GetCurrentIP
- mov r0, lr
- bx lr
- LEAF_END
-
-;; LPVOID __stdcall GetCurrentSP(void);
- LEAF_ENTRY GetCurrentSP
- mov r0, sp
- bx lr
- LEAF_END
-
-;;-----------------------------------------------------------------------------
-;; This helper routine enregisters the appropriate arguments and makes the
-;; actual call.
-;;-----------------------------------------------------------------------------
-;;void CallDescrWorkerInternal(CallDescrData * pCallDescrData);
- NESTED_ENTRY CallDescrWorkerInternal,,CallDescrWorkerUnwindFrameChainHandler
- PROLOG_PUSH {r4,r5,r7,lr}
- PROLOG_STACK_SAVE r7
-
- mov r5,r0 ; save pCallDescrData in r5
-
- ldr r1, [r5,#CallDescrData__numStackSlots]
- cbz r1, Ldonestack
-
- ;; Add frame padding to ensure frame size is a multiple of 8 (a requirement of the OS ABI).
- ;; We push four registers (above) and numStackSlots arguments (below). If this comes to an odd number
- ;; of slots we must pad with another. This simplifies to "if the low bit of numStackSlots is set,
- ;; extend the stack another four bytes".
- lsls r2, r1, #2
- and r3, r2, #4
- sub sp, sp, r3
-
- ;; This loop copies numStackSlots words
- ;; from [pSrcEnd-4,pSrcEnd-8,...] to [sp-4,sp-8,...]
- ldr r0, [r5,#CallDescrData__pSrc]
- add r0,r0,r2
-Lstackloop
- ldr r2, [r0,#-4]!
- str r2, [sp,#-4]!
- subs r1, r1, #1
- bne Lstackloop
-Ldonestack
-
- ;; If FP arguments are supplied in registers (r3 != NULL) then initialize all of them from the pointer
- ;; given in r3. Do not use "it" since it faults in floating point even when the instruction is not executed.
- ldr r3, [r5,#CallDescrData__pFloatArgumentRegisters]
- cbz r3, LNoFloatingPoint
- vldm r3, {s0-s15}
-LNoFloatingPoint
-
- ;; Copy [pArgumentRegisters, ..., pArgumentRegisters + 12]
- ;; into r0, ..., r3
-
- ldr r4, [r5,#CallDescrData__pArgumentRegisters]
- ldm r4, {r0-r3}
-
- CHECK_STACK_ALIGNMENT
-
- ;; call pTarget
- ;; Note that remoting expect target in r4.
- ldr r4, [r5,#CallDescrData__pTarget]
- blx r4
-
- ldr r3, [r5,#CallDescrData__fpReturnSize]
-
- ;; Save FP return value if appropriate
- cbz r3, LFloatingPointReturnDone
-
- ;; Float return case
- ;; Do not use "it" since it faults in floating point even when the instruction is not executed.
- cmp r3, #4
- bne LNoFloatReturn
- vmov r0, s0
- b LFloatingPointReturnDone
-LNoFloatReturn
-
- ;; Double return case
- ;; Do not use "it" since it faults in floating point even when the instruction is not executed.
- cmp r3, #8
- bne LNoDoubleReturn
- vmov r0, r1, s0, s1
- b LFloatingPointReturnDone
-LNoDoubleReturn
-
- add r2, r5, #CallDescrData__returnValue
-
- cmp r3, #16
- bne LNoFloatHFAReturn
- vstm r2, {s0-s3}
- b LReturnDone
-LNoFloatHFAReturn
-
- cmp r3, #32
- bne LNoDoubleHFAReturn
- vstm r2, {d0-d3}
- b LReturnDone
-LNoDoubleHFAReturn
-
- EMIT_BREAKPOINT ; Unreachable
-
-LFloatingPointReturnDone
-
- ;; Save return value into retbuf
- str r0, [r5, #(CallDescrData__returnValue + 0)]
- str r1, [r5, #(CallDescrData__returnValue + 4)]
-
-LReturnDone
-
-#ifdef _DEBUG
- ;; trash the floating point registers to ensure that the HFA return values
- ;; won't survive by accident
- vldm sp, {d0-d3}
-#endif
-
- EPILOG_STACK_RESTORE r7
- EPILOG_POP {r4,r5,r7,pc}
-
- NESTED_END
-
-; ------------------------------------------------------------------
-
-; void LazyMachStateCaptureState(struct LazyMachState *pState);
- LEAF_ENTRY LazyMachStateCaptureState
-
- ;; marks that this is not yet valid
- mov r1, #0
- str r1, [r0, #MachState__isValid]
-
- str lr, [r0, #LazyMachState_captureIp]
- str sp, [r0, #LazyMachState_captureSp]
-
- add r1, r0, #LazyMachState_captureR4_R11
- stm r1, {r4-r11}
-
- mov pc, lr
-
- LEAF_END
-
-; void SinglecastDelegateInvokeStub(Delegate *pThis)
- LEAF_ENTRY SinglecastDelegateInvokeStub
- cmp r0, #0
- beq LNullThis
-
- ldr r12, [r0, #DelegateObject___methodPtr]
- ldr r0, [r0, #DelegateObject___target]
-
- bx r12
-
-LNullThis
- mov r0, #CORINFO_NullReferenceException_ASM
- b JIT_InternalThrow
-
- LEAF_END
-
-;
-; r12 = UMEntryThunk*
-;
- NESTED_ENTRY TheUMEntryPrestub,,UMEntryPrestubUnwindFrameChainHandler
-
- PROLOG_PUSH {r0-r4,lr}
- PROLOG_VPUSH {d0-d7}
-
- CHECK_STACK_ALIGNMENT
-
- mov r0, r12
- bl TheUMEntryPrestubWorker
-
- ; Record real target address in r12.
- mov r12, r0
-
- ; Epilog
- EPILOG_VPOP {d0-d7}
- EPILOG_POP {r0-r4,lr}
- EPILOG_BRANCH_REG r12
-
- NESTED_END
-
-; ------------------------------------------------------------------
-
- NESTED_ENTRY ThePreStub
-
- PROLOG_WITH_TRANSITION_BLOCK
-
- add r0, sp, #__PWTB_TransitionBlock ; pTransitionBlock
- mov r1, r12 ; pMethodDesc
-
- bl PreStubWorker
-
- mov r12, r0
-
- EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
- EPILOG_BRANCH_REG r12
-
- NESTED_END
-
-; ------------------------------------------------------------------
-
- NESTED_ENTRY ThePreStubCompactARM
-
- ; r12 - address of compact entry point + PC_REG_RELATIVE_OFFSET
-
- PROLOG_WITH_TRANSITION_BLOCK
-
- mov r0, r12
-
- bl PreStubGetMethodDescForCompactEntryPoint
-
- mov r12, r0 ; pMethodDesc
-
- EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
-
- b ThePreStub
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; This method does nothing. It's just a fixed function for the debugger to put a breakpoint on.
- LEAF_ENTRY ThePreStubPatch
- nop
-ThePreStubPatchLabel
- EXPORT ThePreStubPatchLabel
- bx lr
- LEAF_END
-
-; ------------------------------------------------------------------
-; The call in ndirect import precode points to this function.
- NESTED_ENTRY NDirectImportThunk
-
- PROLOG_PUSH {r0-r4,lr} ; Spill general argument registers, return address and
- ; arbitrary register to keep stack aligned
- PROLOG_VPUSH {d0-d7} ; Spill floating point argument registers
-
- CHECK_STACK_ALIGNMENT
-
- mov r0, r12
- bl NDirectImportWorker
- mov r12, r0
-
- EPILOG_VPOP {d0-d7}
- EPILOG_POP {r0-r4,lr}
-
- ; If we got back from NDirectImportWorker, the MD has been successfully
- ; linked. Proceed to execute the original DLL call.
- EPILOG_BRANCH_REG r12
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; void ResolveWorkerAsmStub(r0, r1, r2, r3, r4:IndirectionCellAndFlags, r12:DispatchToken)
-;
-; The stub dispatch thunk which transfers control to VSD_ResolveWorker.
- NESTED_ENTRY ResolveWorkerAsmStub
-
- PROLOG_WITH_TRANSITION_BLOCK
-
- add r0, sp, #__PWTB_TransitionBlock ; pTransitionBlock
- mov r2, r12 ; token
-
- ; indirection cell in r4 - should be consistent with REG_ARM_STUB_SPECIAL
- bic r1, r4, #3 ; indirection cell
- and r3, r4, #3 ; flags
-
- bl VSD_ResolveWorker
-
- mov r12, r0
-
- EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
- EPILOG_BRANCH_REG r12
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; void ResolveWorkerChainLookupAsmStub(r0, r1, r2, r3, r4:IndirectionCellAndFlags, r12:DispatchToken)
- NESTED_ENTRY ResolveWorkerChainLookupAsmStub
-
- ; ARMSTUB TODO: implement chained lookup
- b ResolveWorkerAsmStub
-
- NESTED_END
-
-#if defined(FEATURE_COMINTEROP)
-
-; ------------------------------------------------------------------
-; setStubReturnValue
-; r0 - size of floating point return value (MetaSig::GetFPReturnSize())
-; r1 - pointer to the return buffer in the stub frame
- LEAF_ENTRY setStubReturnValue
-
- cbz r0, NoFloatingPointRetVal
-
- ;; Float return case
- ;; Do not use "it" since it faults in floating point even when the instruction is not executed.
- cmp r0, #4
- bne LNoFloatRetVal
- vldr s0, [r1]
- bx lr
-LNoFloatRetVal
-
- ;; Double return case
- ;; Do not use "it" since it faults in floating point even when the instruction is not executed.
- cmp r0, #8
- bne LNoDoubleRetVal
- vldr d0, [r1]
- bx lr
-LNoDoubleRetVal
-
- cmp r0, #16
- bne LNoFloatHFARetVal
- vldm r1, {s0-s3}
- bx lr
-LNoFloatHFARetVal
-
- cmp r0, #32
- bne LNoDoubleHFARetVal
- vldm r1, {d0-d3}
- bx lr
-LNoDoubleHFARetVal
-
- EMIT_BREAKPOINT ; Unreachable
-
-NoFloatingPointRetVal
-
- ;; Restore the return value from retbuf
- ldr r0, [r1]
- ldr r1, [r1, #4]
- bx lr
-
- LEAF_END
-
-#endif // FEATURE_COMINTEROP
-
-
-#if defined(FEATURE_COMINTEROP)
-; ------------------------------------------------------------------
-; Function used by remoting/COM interop to get floating point return value (since it's not in the same
-; register(s) as non-floating point values).
-;
-; On entry;
-; r0 : size of the FP result (4 or 8 bytes)
-; r1 : pointer to 64-bit buffer to receive result
-;
-; On exit:
-; buffer pointed to by r1 on entry contains the float or double argument as appropriate
-;
- LEAF_ENTRY getFPReturn
-
- cmp r0, #4
- bne LgetFP8
- vmov r2, s0
- str r2, [r1]
- bx lr
-LgetFP8
- vmov r2, r3, d0
- strd r2, r3, [r1]
- bx lr
-
- LEAF_END
-
-; ------------------------------------------------------------------
-; Function used by remoting/COM interop to set floating point return value (since it's not in the same
-; register(s) as non-floating point values).
-;
-; On entry:
-; r0 : size of the FP result (4 or 8 bytes)
-; r2/r3 : 32-bit or 64-bit FP result
-;
-; On exit:
-; s0 : float result if r0 == 4
-; d0 : double result if r0 == 8
-;
- LEAF_ENTRY setFPReturn
-
- cmp r0, #4
- bne LsetFP8
- vmov s0, r2
- bx lr
-LsetFP8
- vmov d0, r2, r3
- bx lr
-
- LEAF_END
-
-#endif defined(FEATURE_COMINTEROP)
-
-
-#ifdef FEATURE_COMINTEROP
-; ------------------------------------------------------------------
-; GenericComPlusCallStub that erects a ComPlusMethodFrame and calls into the runtime
-; (CLRToCOMWorker) to dispatch rare cases of the interface call.
-;
-; On entry:
-; r0 : 'this' object
-; r12 : Interface MethodDesc*
-; plus user arguments in registers and on the stack
-;
-; On exit:
-; r0/r1/s0/d0 set to return value of the call as appropriate
-;
- NESTED_ENTRY GenericComPlusCallStub
-
- PROLOG_WITH_TRANSITION_BLOCK ASM_ENREGISTERED_RETURNTYPE_MAXSIZE
-
- add r0, sp, #__PWTB_TransitionBlock ; pTransitionBlock
- mov r1, r12 ; pMethodDesc
-
- ; Call CLRToCOMWorker(pFrame). This call will set up the rest of the frame (including the vfptr,
- ; the GS cookie and linking to the thread), make the client call and return with correct registers set
- ; (r0/r1/s0-s3/d0-d3 as appropriate).
-
- bl CLRToCOMWorker
-
- ; r0 = fpRetSize
-
- ; return value is stored before float argument registers
- add r1, sp, #(__PWTB_FloatArgumentRegisters - ASM_ENREGISTERED_RETURNTYPE_MAXSIZE)
- bl setStubReturnValue
-
- EPILOG_WITH_TRANSITION_BLOCK_RETURN
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; COM to CLR stub called the first time a particular method is invoked.
-;
-; On entry:
-; r12 : (MethodDesc* - ComCallMethodDesc_Offset_FromR12) provided by prepad thunk
-; plus user arguments in registers and on the stack
-;
-; On exit:
-; tail calls to real method
-;
- NESTED_ENTRY ComCallPreStub
-
- GBLA ComCallPreStub_FrameSize
- GBLA ComCallPreStub_FramePad
- GBLA ComCallPreStub_StackAlloc
- GBLA ComCallPreStub_Frame
- GBLA ComCallPreStub_ErrorReturn
-
-; Set the defaults
-ComCallPreStub_FramePad SETA 8 ; error return
-ComCallPreStub_FrameSize SETA (ComCallPreStub_FramePad + SIZEOF__GSCookie + SIZEOF__ComMethodFrame)
-
- IF ComCallPreStub_FrameSize:MOD:8 != 0
-ComCallPreStub_FramePad SETA ComCallPreStub_FramePad + 4
-ComCallPreStub_FrameSize SETA ComCallPreStub_FrameSize + 4
- ENDIF
-
-ComCallPreStub_StackAlloc SETA ComCallPreStub_FrameSize - SIZEOF__ArgumentRegisters - 2 * 4
-ComCallPreStub_Frame SETA SIZEOF__FloatArgumentRegisters + ComCallPreStub_FramePad + SIZEOF__GSCookie
-ComCallPreStub_ErrorReturn SETA SIZEOF__FloatArgumentRegisters
-
- PROLOG_PUSH {r0-r3} ; Spill general argument registers
- PROLOG_PUSH {r11,lr} ; Save return address
- PROLOG_STACK_ALLOC ComCallPreStub_StackAlloc ; Alloc non-spill portion of stack frame
- PROLOG_VPUSH {d0-d7} ; Spill floating point argument registers
-
- CHECK_STACK_ALIGNMENT
-
- ; Finish initializing the frame. The C++ helper will fill in the GS cookie and vfptr and link us to
- ; the Thread frame chain (see ComPrestubMethodFrame::Push). That leaves us with m_pFuncDesc.
- ; The prepad thunk passes us a value which is the MethodDesc* - ComCallMethodDesc_Offset_FromR12 (due to encoding limitations in the
- ; thunk). So we must correct this by adding 4 before storing the pointer.
- add r12, #(ComCallMethodDesc_Offset_FromR12)
- str r12, [sp, #(ComCallPreStub_Frame + UnmanagedToManagedFrame__m_pvDatum)]
-
- ; Call the C++ worker: ComPreStubWorker(&Frame)
- add r0, sp, #(ComCallPreStub_Frame)
- add r1, sp, #(ComCallPreStub_ErrorReturn)
- bl ComPreStubWorker
-
- ; Handle failure case.
- cbz r0, ErrorExit
-
- ; Stash real target address where it won't be overwritten by restoring the calling state.
- mov r12, r0
-
- EPILOG_VPOP {d0-d7} ; Restore floating point argument registers
- EPILOG_STACK_FREE ComCallPreStub_StackAlloc
- EPILOG_POP {r11,lr}
- EPILOG_POP {r0-r3} ; Restore argument registers
- ; Tail call the real target. Actually ComPreStubWorker returns the address of the prepad thunk on ARM,
- ; that way we don't run out of volatile registers trying to remember both the new target address and
- ; the hidden MethodDesc* argument. ComPreStubWorker patched the prepad though so the second time
- ; through we won't end up here again.
- EPILOG_BRANCH_REG r12
-
-ErrorExit
- ; Failed to find a stub to call. Retrieve the return value ComPreStubWorker set for us.
- ldr r0, [sp, #(ComCallPreStub_ErrorReturn)]
- ldr r1, [sp, #(ComCallPreStub_ErrorReturn+4)]
- EPILOG_STACK_FREE ComCallPreStub_StackAlloc + SIZEOF__FloatArgumentRegisters
- EPILOG_POP {r11,lr}
- EPILOG_STACK_FREE SIZEOF__ArgumentRegisters
- EPILOG_RETURN
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; COM to CLR stub which sets up a ComMethodFrame and calls COMToCLRWorker.
-;
-; On entry:
-; r12 : (MethodDesc* - ComCallMethodDesc_Offset_FromR12) provided by prepad thunk
-; plus user arguments in registers and on the stack
-;
-; On exit:
-; Result in r0/r1/s0/d0 as per the real method being called
-;
- NESTED_ENTRY GenericComCallStub,,ReverseComUnwindFrameChainHandler
-
-; Calculate space needed on stack for alignment padding, a GS cookie and a ComMethodFrame (minus the last
-; field, m_ReturnAddress, which we'll push explicitly).
-
- GBLA GenericComCallStub_FrameSize
- GBLA GenericComCallStub_FramePad
- GBLA GenericComCallStub_StackAlloc
- GBLA GenericComCallStub_Frame
-
-; Set the defaults
-GenericComCallStub_FramePad SETA 0
-GenericComCallStub_FrameSize SETA (GenericComCallStub_FramePad + SIZEOF__GSCookie + SIZEOF__ComMethodFrame)
-
- IF GenericComCallStub_FrameSize:MOD:8 != 0
-GenericComCallStub_FramePad SETA 4
-GenericComCallStub_FrameSize SETA GenericComCallStub_FrameSize + GenericComCallStub_FramePad
- ENDIF
-
-GenericComCallStub_StackAlloc SETA GenericComCallStub_FrameSize - SIZEOF__ArgumentRegisters - 2 * 4
-GenericComCallStub_Frame SETA SIZEOF__FloatArgumentRegisters + GenericComCallStub_FramePad + SIZEOF__GSCookie
-
- PROLOG_PUSH {r0-r3} ; Spill general argument registers
- PROLOG_PUSH {r11,lr} ; Save return address
- PROLOG_STACK_ALLOC GenericComCallStub_StackAlloc ; Alloc non-spill portion of stack frame
- PROLOG_VPUSH {d0-d7} ; Spill floating point argument registers
-
- CHECK_STACK_ALIGNMENT
-
- ; Store MethodDesc* in frame. Due to a limitation of the prepad, r12 actually contains a value
- ; "ComCallMethodDesc_Offset_FromR12" less than the pointer we want, so fix that up.
- add r12, r12, #(ComCallMethodDesc_Offset_FromR12)
- str r12, [sp, #(GenericComCallStub_Frame + UnmanagedToManagedFrame__m_pvDatum)]
-
- ; Call COMToCLRWorker(pThread, pFrame). Note that pThread is computed inside the method so we don't
- ; need to set it up here.
- ;
- ; Setup R1 to point to the start of the explicit frame. We account for alignment padding and
- ; space for GSCookie.
- add r1, sp, #(GenericComCallStub_Frame)
- bl COMToCLRWorker
-
- EPILOG_STACK_FREE GenericComCallStub_StackAlloc + SIZEOF__FloatArgumentRegisters
- EPILOG_POP {r11,lr}
- EPILOG_STACK_FREE SIZEOF__ArgumentRegisters
- EPILOG_RETURN
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; COM to CLR stub called from COMToCLRWorker that actually dispatches to the real managed method.
-;
-; On entry:
-; r0 : dwStackSlots, count of argument stack slots to copy
-; r1 : pFrame, ComMethodFrame pushed by GenericComCallStub above
-; r2 : pTarget, address of code to call
-; r3 : pSecretArg, hidden argument passed to target above in r12
-; [sp, #0] : pDangerousThis, managed 'this' reference
-;
-; On exit:
-; Result in r0/r1/s0/d0 as per the real method being called
-;
- NESTED_ENTRY COMToCLRDispatchHelper,,CallDescrWorkerUnwindFrameChainHandler
-
- PROLOG_PUSH {r4-r5,r7,lr}
- PROLOG_STACK_SAVE r7
-
- ; Copy stack-based arguments. Make sure the eventual SP ends up 8-byte aligned. Note that the
- ; following calculations assume that the prolog has left the stack already aligned.
- CHECK_STACK_ALIGNMENT
-
- cbz r0, COMToCLRDispatchHelper_ArgumentsSetup
-
- lsl r4, r0, #2 ; r4 = (dwStackSlots * 4)
- and r5, r4, #4 ; Align the stack
- sub sp, sp, r5
-
- add r5, r1, #SIZEOF__ComMethodFrame
- add r5, r5, r4
-
-COMToCLRDispatchHelper_StackLoop
- ldr r4, [r5,#-4]!
- str r4, [sp,#-4]!
- subs r0, r0, #1
- bne COMToCLRDispatchHelper_StackLoop
-
- CHECK_STACK_ALIGNMENT
-
-COMToCLRDispatchHelper_ArgumentsSetup
- ; Load floating point argument registers.
- sub r4, r1, #(GenericComCallStub_Frame)
- vldm r4, {d0-d7}
-
- ; Prepare the call target and hidden argument prior to overwriting r0-r3.
- mov r12, r3 ; r12 = hidden argument
- mov lr, r2 ; lr = target code
-
- ; Load general argument registers except r0.
- add r4, r1, #(SIZEOF__ComMethodFrame - SIZEOF__ArgumentRegisters + 4)
- ldm r4, {r1-r3}
-
- ; Load r0 from the managed this, not the original incoming IUnknown*.
- ldr r0, [r7, #(4 * 4)]
-
- ; Make the call.
- blx lr
-
- EPILOG_STACK_RESTORE r7
- EPILOG_POP {r4-r5,r7,pc}
-
- NESTED_END
-
-#endif // FEATURE_COMINTEROP
-
-#ifdef PROFILING_SUPPORTED
-
-PROFILE_ENTER equ 1
-PROFILE_LEAVE equ 2
-PROFILE_TAILCALL equ 4
-
- ; ------------------------------------------------------------------
- ; void JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle)
- LEAF_ENTRY JIT_ProfilerEnterLeaveTailcallStub
- bx lr
- LEAF_END
-
- ; Define the layout of the PROFILE_PLATFORM_SPECIFIC_DATA we push on the stack for all profiler
- ; helpers.
- map 0
- field 4 ; r0
- field 4 ; r1
- field 4 ; r11
- field 4 ; Pc (caller's PC, i.e. LR)
- field SIZEOF__FloatArgumentRegisters ; spilled floating point argument registers
-functionId field 4
-probeSp field 4
-profiledSp field 4
-hiddenArg field 4
-flags field 4
-
-SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA field 0
-
-; ------------------------------------------------------------------
-; Macro used to generate profiler helpers. In all cases we push a partially initialized
-; PROFILE_PLATFORM_SPECIFIC_DATA structure on the stack and call into a C++ helper to continue processing.
-;
-; On entry:
-; r0 : clientInfo
-; r1/r2 : return values (in case of leave)
-; frame pointer(r11) must be set (in case of enter)
-; all arguments are on stack at frame pointer (r11) + 8bytes (save lr & prev r11).
-;
-; On exit:
-; All register values are preserved including volatile registers
-;
- MACRO
- DefineProfilerHelper $HelperName, $Flags
-
- GBLS __ProfilerHelperFunc
-__ProfilerHelperFunc SETS "$HelperName":CC:"Naked"
-
- NESTED_ENTRY $__ProfilerHelperFunc
-
- IMPORT $HelperName ; The C++ helper which does most of the work
-
- PROLOG_PUSH {r0,r3,r9,r12} ; save volatile general purpose registers. remaining r1 & r2 are saved below...saving r9 as it is required for virtualunwinding
- PROLOG_STACK_ALLOC (6*4) ; Reserve space for tail end of structure (5*4 bytes) and extra 4 bytes is for aligning the stack at 8-byte boundary
- PROLOG_VPUSH {d0-d7} ; Spill floting point argument registers
- PROLOG_PUSH {r1,r11,lr} ; Save possible return value in r1, frame pointer and return address
- PROLOG_PUSH {r2} ; Save possible return value in r0. Before calling Leave Hook Jit moves contents of r0 to r2
- ; so pushing r2 instead of r0. This push statement cannot be combined with the above push
- ; as r2 gets pushed before r1.
-
- CHECK_STACK_ALIGNMENT
-
- ; Zero r1 for use clearing fields in the PROFILE_PLATFORM_SPECIFIC_DATA.
- eor r1, r1
-
- ; Clear functionId.
- str r1, [sp, #functionId]
-
- ; Save caller's SP (at the point this helper was called).
- add r2, sp, #(SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA + 20)
- str r2, [sp, #probeSp]
-
- ; Save caller's SP (at the point where only argument registers have been spilled).
- ldr r2, [r11]
- add r2, r2, #8 ; location of arguments is at frame pointer(r11) + 8 (lr & prev frame ptr is saved before changing
- str r2, [sp, #profiledSp]
-
- ; Clear hiddenArg.
- str r1, [sp, #hiddenArg]
-
- ; Set flags to indicate type of helper called.
- mov r1, #($Flags)
- str r1, [sp, #flags]
-
- ; Call C++ portion of helper (<$HelperName>(clientInfo, &profilePlatformSpecificData)).
- mov r1, sp
- bl $HelperName
-
- EPILOG_POP {r2}
- EPILOG_POP {r1,r11,lr}
- EPILOG_VPOP {d0-d7}
- EPILOG_STACK_FREE (6*4)
- EPILOG_POP {r0,r3,r9,r12}
-
- EPILOG_RETURN
-
- NESTED_END
-
- MEND
-
- DefineProfilerHelper ProfileEnter, PROFILE_ENTER
- DefineProfilerHelper ProfileLeave, PROFILE_LEAVE
- DefineProfilerHelper ProfileTailcall, PROFILE_TAILCALL
-
-#endif // PROFILING_SUPPORTED
-
- ;
- ; If a preserved register were pushed onto the stack between
- ; the managed caller and the H_M_F, _R4_R11 will point to its
- ; location on the stack and it would have been updated on the
- ; stack by the GC already and it will be popped back into the
- ; appropriate register when the appropriate epilog is run.
- ;
- ; Otherwise, the register is preserved across all the code
- ; in this HCALL or FCALL, so we need to update those registers
- ; here because the GC will have updated our copies in the
- ; frame.
- ;
- ; So, if _R4_R11 points into the MachState, we need to update
- ; the register here. That's what this macro does.
- ;
-
- MACRO
- RestoreRegMS $regIndex, $reg
-
- ; Incoming:
- ;
- ; R0 = address of MachState
- ;
- ; $regIndex: Index of the register (R4-R11). For R4, index is 4.
- ; For R5, index is 5, and so on.
- ;
- ; $reg: Register name (e.g. R4, R5, etc)
- ;
- ; Get the address of the specified captured register from machine state
- add r2, r0, #(MachState__captureR4_R11 + (($regIndex-4)*4))
-
- ; Get the address of the specified preserved register from machine state
- ldr r3, [r0, #(MachState___R4_R11 + (($regIndex-4)*4))]
-
- cmp r2, r3
- bne %FT0
- ldr $reg, [r2]
-0
-
- MEND
-
-; EXTERN_C int __fastcall HelperMethodFrameRestoreState(
-; INDEBUG_COMMA(HelperMethodFrame *pFrame)
-; MachState *pState
-; )
- LEAF_ENTRY HelperMethodFrameRestoreState
-
-#ifdef _DEBUG
- mov r0, r1
-#endif
-
- ; If machine state is invalid, then simply exit
- ldr r1, [r0, #MachState__isValid]
- cmp r1, #0
- beq Done
-
- RestoreRegMS 4, R4
- RestoreRegMS 5, R5
- RestoreRegMS 6, R6
- RestoreRegMS 7, R7
- RestoreRegMS 8, R8
- RestoreRegMS 9, R9
- RestoreRegMS 10, R10
- RestoreRegMS 11, R11
-Done
- ; Its imperative that the return value of HelperMethodFrameRestoreState is zero
- ; as it is used in the state machine to loop until it becomes zero.
- ; Refer to HELPER_METHOD_FRAME_END macro for details.
- mov r0,#0
- bx lr
-
- LEAF_END
-
-#ifdef FEATURE_HIJACK
-
-; ------------------------------------------------------------------
-; Hijack function for functions which return a value type
- NESTED_ENTRY OnHijackTripThread
- PROLOG_PUSH {r0,r4-r11,lr}
-
- PROLOG_VPUSH {d0-d3} ; saving as d0-d3 can have the floating point return value
- PROLOG_PUSH {r1} ; saving as r1 can have partial return value when return is > 32 bits
- PROLOG_STACK_ALLOC 4 ; 8 byte align
-
- CHECK_STACK_ALIGNMENT
-
- add r0, sp, #40
- bl OnHijackWorker
-
- EPILOG_STACK_FREE 4
- EPILOG_POP {r1}
- EPILOG_VPOP {d0-d3}
-
- EPILOG_POP {r0,r4-r11,pc}
- NESTED_END
-
-#endif ; FEATURE_HIJACK
-
-; ------------------------------------------------------------------
-; Macro to generate Redirection Stubs
-;
-; $reason : reason for redirection
-; Eg. GCThreadControl
-; NOTE: If you edit this macro, make sure you update GetCONTEXTFromRedirectedStubStackFrame.
-; This function is used by both the personality routine and the debugger to retrieve the original CONTEXT.
- MACRO
- GenerateRedirectedHandledJITCaseStub $reason
-
- GBLS __RedirectionStubFuncName
- GBLS __RedirectionStubEndFuncName
- GBLS __RedirectionFuncName
-__RedirectionStubFuncName SETS "RedirectedHandledJITCaseFor":CC:"$reason":CC:"_Stub"
-__RedirectionStubEndFuncName SETS "RedirectedHandledJITCaseFor":CC:"$reason":CC:"_StubEnd"
-__RedirectionFuncName SETS "|?RedirectedHandledJITCaseFor":CC:"$reason":CC:"@Thread@@CAXXZ|"
-
- IMPORT $__RedirectionFuncName
-
- NESTED_ENTRY $__RedirectionStubFuncName
-
- PROLOG_PUSH {r7,lr} ; return address
- PROLOG_STACK_ALLOC 4 ; stack slot to save the CONTEXT *
- PROLOG_STACK_SAVE r7
-
- ;REDIRECTSTUB_SP_OFFSET_CONTEXT is defined in asmconstants.h
- ;If CONTEXT is not saved at 0 offset from SP it must be changed as well.
- ASSERT REDIRECTSTUB_SP_OFFSET_CONTEXT == 0
-
- ; Runtime check for 8-byte alignment. This check is necessary as this function can be
- ; entered before complete execution of the prolog of another function.
- and r0, r7, #4
- sub sp, sp, r0
-
- ; stack must be 8 byte aligned
- CHECK_STACK_ALIGNMENT
-
- ;
- ; Save a copy of the redirect CONTEXT*.
- ; This is needed for the debugger to unwind the stack.
- ;
- bl GetCurrentSavedRedirectContext
- str r0, [r7]
-
- ;
- ; Fetch the interrupted pc and save it as our return address.
- ;
- ldr r1, [r0, #CONTEXT_Pc]
- str r1, [r7, #8]
-
- ;
- ; Call target, which will do whatever we needed to do in the context
- ; of the target thread, and will RtlRestoreContext when it is done.
- ;
- bl $__RedirectionFuncName
-
- EMIT_BREAKPOINT ; Unreachable
-
-; Put a label here to tell the debugger where the end of this function is.
-$__RedirectionStubEndFuncName
- EXPORT $__RedirectionStubEndFuncName
-
- NESTED_END
-
- MEND
-
-; ------------------------------------------------------------------
-; Redirection Stub for GC in fully interruptible method
- GenerateRedirectedHandledJITCaseStub GCThreadControl
-; ------------------------------------------------------------------
- GenerateRedirectedHandledJITCaseStub DbgThreadControl
-; ------------------------------------------------------------------
- GenerateRedirectedHandledJITCaseStub UserSuspend
-
-#ifdef _DEBUG
-; ------------------------------------------------------------------
-; Redirection Stub for GC Stress
- GenerateRedirectedHandledJITCaseStub GCStress
-#endif
-
-; ------------------------------------------------------------------
-; Functions to probe for stack space
-; Input reg r4 = amount of stack to probe for
-; value of reg r4 is preserved on exit from function
-; r12 is trashed
-; The below two functions were copied from vctools\crt\crtw32\startup\arm\chkstk.asm
-
- NESTED_ENTRY checkStack
- subs r12,sp,r4
- mrc p15,#0,r4,c13,c0,#2 ; get TEB *
- ldr r4,[r4,#8] ; get Stack limit
- bcc checkStack_neg ; if r12 is less then 0 set it to 0
-checkStack_label1
- cmp r12, r4
- bcc stackProbe ; must probe to extend guardpage if r12 is beyond stackLimit
- sub r4, sp, r12 ; restore value of r4
- EPILOG_RETURN
-checkStack_neg
- mov r12, #0
- b checkStack_label1
- NESTED_END
-
- NESTED_ENTRY stackProbe
- PROLOG_PUSH {r5,r6}
- mov r6, r12
- bfc r6, #0, #0xc ; align down (4K)
-stackProbe_loop
- sub r4,r4,#0x1000 ; dec stack Limit by 4K as page size is 4K
- ldr r5,[r4] ; try to read ... this should move the guard page
- cmp r4,r6
- bne stackProbe_loop
- EPILOG_POP {r5,r6}
- EPILOG_NOP sub r4,sp,r12
- EPILOG_RETURN
- NESTED_END
-
-;------------------------------------------------
-; JIT_RareDisableHelper
-;
-; The JIT expects this helper to preserve registers used for return values
-;
- NESTED_ENTRY JIT_RareDisableHelper
-
- PROLOG_PUSH {r0-r1, r11, lr} ; save integer return value
- PROLOG_VPUSH {d0-d3} ; floating point return value
-
- CHECK_STACK_ALIGNMENT
-
- bl JIT_RareDisableHelperWorker
-
- EPILOG_VPOP {d0-d3}
- EPILOG_POP {r0-r1, r11, pc}
-
- NESTED_END
-
-
-;
-; JIT Static access helpers for single appdomain case
-;
-
-; ------------------------------------------------------------------
-; void* JIT_GetSharedNonGCStaticBase(SIZE_T moduleDomainID, DWORD dwClassDomainID)
-
- LEAF_ENTRY JIT_GetSharedNonGCStaticBase_SingleAppDomain
-
- ; If class is not initialized, bail to C++ helper
- add r2, r0, #DomainLocalModule__m_pDataBlob
- ldrb r2, [r2, r1]
- tst r2, #1
- beq CallCppHelper1
-
- bx lr
-
-CallCppHelper1
- ; Tail call JIT_GetSharedNonGCStaticBase_Helper
- b JIT_GetSharedNonGCStaticBase_Helper
- LEAF_END
-
-
-; ------------------------------------------------------------------
-; void* JIT_GetSharedNonGCStaticBaseNoCtor(SIZE_T moduleDomainID, DWORD dwClassDomainID)
-
- LEAF_ENTRY JIT_GetSharedNonGCStaticBaseNoCtor_SingleAppDomain
-
- bx lr
- LEAF_END
-
-
-; ------------------------------------------------------------------
-; void* JIT_GetSharedGCStaticBase(SIZE_T moduleDomainID, DWORD dwClassDomainID)
-
- LEAF_ENTRY JIT_GetSharedGCStaticBase_SingleAppDomain
-
- ; If class is not initialized, bail to C++ helper
- add r2, r0, #DomainLocalModule__m_pDataBlob
- ldrb r2, [r2, r1]
- tst r2, #1
- beq CallCppHelper3
-
- ldr r0, [r0, #DomainLocalModule__m_pGCStatics]
- bx lr
-
-CallCppHelper3
- ; Tail call Jit_GetSharedGCStaticBase_Helper
- b JIT_GetSharedGCStaticBase_Helper
- LEAF_END
-
-
-; ------------------------------------------------------------------
-; void* JIT_GetSharedGCStaticBaseNoCtor(SIZE_T moduleDomainID, DWORD dwClassDomainID)
-
- LEAF_ENTRY JIT_GetSharedGCStaticBaseNoCtor_SingleAppDomain
-
- ldr r0, [r0, #DomainLocalModule__m_pGCStatics]
- bx lr
- LEAF_END
-
-
-; ------------------------------------------------------------------
-; GC write barrier support.
-;
-; There's some complexity here for a couple of reasons:
-;
-; Firstly, there are a few variations of barrier types (input registers, checked vs unchecked, UP vs MP etc.).
-; So first we define a number of helper macros that perform fundamental pieces of a barrier and then we define
-; the final barrier functions by assembling these macros in various combinations.
-;
-; Secondly, for performance reasons we believe it's advantageous to be able to modify the barrier functions
-; over the lifetime of the CLR. Specifically ARM has real problems reading the values of external globals (we
-; need two memory indirections to do this) so we'd like to be able to directly set the current values of
-; various GC globals (e.g. g_lowest_address and g_card_table) into the barrier code itself and then reset them
-; every time they change (the GC already calls the VM to inform it of these changes). To handle this without
-; creating too much fragility such as hardcoding instruction offsets in the VM update code, we wrap write
-; barrier creation and GC globals access in a set of macros that create a table of descriptors describing each
-; offset that must be patched.
-;
-
-; Many of the following macros need a scratch register. Define a name for it here so it's easy to modify this
-; in the future.
- GBLS __wbscratch
-__wbscratch SETS "r3"
-
-;
-; First define the meta-macros used to support dynamically patching write barriers.
-;
-
- ; WRITEBARRIERAREA
- ;
- ; As we assemble each write barrier function we build a descriptor for the offsets within that function
- ; that need to be patched at runtime. We write these descriptors into a read-only portion of memory. Use a
- ; specially-named linker section for this to ensure all the descriptors are contiguous and form a table.
- ; During the final link of the CLR this section should be merged into the regular read-only data section.
- ;
- ; This macro handles switching assembler output to the above section (similar to the TEXTAREA or
- ; RODATAAREA macros defined by kxarm.h).
- ;
- MACRO
- WRITEBARRIERAREA
- AREA |.clrwb|,DATA,READONLY
- MEND
-
- ; BEGIN_WRITE_BARRIERS
- ;
- ; This macro must be invoked before any write barriers are defined. It sets up and exports a symbol,
- ; g_rgWriteBarrierDescriptors, used by the VM to locate the start of the table describing the offsets in
- ; each write barrier that need to be modified dynamically.
- ;
- MACRO
- BEGIN_WRITE_BARRIERS
-
- ; Define a global boolean to track whether we're currently in a BEGIN_WRITE_BARRIERS section. This is
- ; used purely to catch incorrect attempts to define a write barrier outside the section.
- GBLL __defining_write_barriers
-__defining_write_barriers SETL {true}
-
- ; Switch to the descriptor table section.
- WRITEBARRIERAREA
-
- ; Define and export a symbol pointing to the start of the descriptor table.
-g_rgWriteBarrierDescriptors
- EXPORT g_rgWriteBarrierDescriptors
-
- ; Switch back to the code section.
- TEXTAREA
- MEND
-
- ; END_WRITE_BARRIERS
- ;
- ; This macro must be invoked after all write barriers have been defined. It finalizes the creation of the
- ; barrier descriptor table by writing a sentinel value at the end.
- ;
- MACRO
- END_WRITE_BARRIERS
-
- ASSERT __defining_write_barriers
-__defining_write_barriers SETL {false}
-
- ; Switch to the descriptor table section.
- WRITEBARRIERAREA
-
- ; Write the sentinel value to the end of the descriptor table (a function entrypoint address of zero).
- DCD 0
-
- ; Switch back to the code section.
- TEXTAREA
- MEND
-
- ; WRITE_BARRIER_ENTRY
- ;
- ; Declare the start of a write barrier function. Use similarly to NESTED_ENTRY. This is the only legal way
- ; to declare a write barrier function.
- ;
- MACRO
- WRITE_BARRIER_ENTRY $name
-
- ; Ensure we're called inside a BEGIN_WRITE_BARRIERS section.
- ASSERT __defining_write_barriers
-
- ; Do the standard function declaration logic. Must use a NESTED_ENTRY since we require unwind info to
- ; be registered (for the case where the barrier AVs and the runtime needs to recover).
- LEAF_ENTRY $name
-
- ; Record the function name as it's used as the basis for unique label name creation in some of the
- ; macros below.
- GBLS __write_barrier_name
-__write_barrier_name SETS "$name"
-
- ; Declare globals to collect the values of the offsets of instructions that load GC global values.
- GBLA __g_lowest_address_offset
- GBLA __g_highest_address_offset
- GBLA __g_ephemeral_low_offset
- GBLA __g_ephemeral_high_offset
- GBLA __g_card_table_offset
-
- ; Initialize the above offsets to 0xffff. The default of zero is unsatisfactory because we could
- ; legally have an offset of zero and we need some way to distinguish unset values (both for debugging
- ; and because some write barriers don't use all the globals).
-__g_lowest_address_offset SETA 0xffff
-__g_highest_address_offset SETA 0xffff
-__g_ephemeral_low_offset SETA 0xffff
-__g_ephemeral_high_offset SETA 0xffff
-__g_card_table_offset SETA 0xffff
-
- MEND
-
- ; WRITE_BARRIER_END
- ;
- ; The partner to WRITE_BARRIER_ENTRY, used like NESTED_END.
- ;
- MACRO
- WRITE_BARRIER_END
-
- LTORG ; force the literal pool to be emitted here so that copy code picks it up
- ; Use the standard macro to end the function definition.
- LEAF_END_MARKED $__write_barrier_name
-
-; Define a local string to hold the name of a label identifying the end of the write barrier function.
- LCLS __EndLabelName
-__EndLabelName SETS "$__write_barrier_name":CC:"_End"
-
- ; Switch to the descriptor table section.
- WRITEBARRIERAREA
-
- ; Emit the descripter for this write barrier. The order of these datums must be kept in sync with the
- ; definition of the WriteBarrierDescriptor structure in vm\arm\stubs.cpp.
- DCD $__write_barrier_name
- DCD $__EndLabelName
- DCD __g_lowest_address_offset
- DCD __g_highest_address_offset
- DCD __g_ephemeral_low_offset
- DCD __g_ephemeral_high_offset
- DCD __g_card_table_offset
-
- ; Switch back to the code section.
- TEXTAREA
-
- MEND
-
- ; LOAD_GC_GLOBAL
- ;
- ; Used any time we want to load the value of one of the supported GC globals into a register. This records
- ; the offset of the instructions used to do this (a movw/movt pair) so we can modify the actual value
- ; loaded at runtime.
- ;
- ; Note that a given write barrier can only load a given global once (which will be compile-time asserted
- ; below).
- ;
- MACRO
- LOAD_GC_GLOBAL $regName, $globalName
-
- ; Map the GC global name to the name of the variable tracking the offset for this function.
- LCLS __offset_name
-__offset_name SETS "__$globalName._offset"
-
- ; Ensure that we only attempt to load this global at most once in the current barrier function (we
- ; have this limitation purely because we only record one offset for each GC global).
- ASSERT $__offset_name == 0xffff
-
- ; Define a unique name for a label we're about to define used in the calculation of the current
- ; function offset.
- LCLS __offset_label_name
-__offset_label_name SETS "$__write_barrier_name$__offset_name"
-
- ; Define the label.
-$__offset_label_name
-
- ; Write the current function offset into the tracking variable.
-$__offset_name SETA ($__offset_label_name - $__FuncStartLabel)
-
- ; Emit the instructions which will be patched to provide the value of the GC global (we start with a
- ; value of zero, so the write barriers have to be patched at least once before first use).
- movw $regName, #0
- movt $regName, #0
- MEND
-
-;
-; Now define the macros used in the bodies of write barrier implementations.
-;
-
- ; UPDATE_GC_SHADOW
- ;
- ; Update the GC shadow heap to aid debugging (no-op unless WRITE_BARRIER_CHECK is defined). Assumes the
- ; location being written lies on the GC heap (either we've already performed the dynamic check or this is
- ; statically asserted by the JIT by calling the unchecked version of the write barrier).
- ;
- ; Input:
- ; $ptrReg : register containing the location (in the real heap) to be updated
- ; $valReg : register containing the value (an objref) to be written to the location above
- ;
- ; Output:
- ; $__wbscratch : trashed
- ;
- MACRO
- UPDATE_GC_SHADOW $ptrReg, $valReg
-#ifdef WRITE_BARRIER_CHECK
-
- ; Need one additional temporary register to hold the shadow pointer. Assume r7 is OK for now (and
- ; assert it). If this becomes a problem in the future the register choice can be parameterized.
- LCLS pShadow
-pShadow SETS "r7"
- ASSERT "$ptrReg" != "$pShadow"
- ASSERT "$valReg" != "$pShadow"
-
- push {$pShadow}
-
- ; Compute address of shadow heap location:
- ; pShadow = g_GCShadow + ($ptrReg - g_lowest_address)
- ldr $__wbscratch, =g_lowest_address
- ldr $__wbscratch, [$__wbscratch]
- sub $pShadow, $ptrReg, $__wbscratch
- ldr $__wbscratch, =$g_GCShadow
- ldr $__wbscratch, [$__wbscratch]
- add $pShadow, $__wbscratch
-
- ; if (pShadow >= g_GCShadow) goto end
- ldr $__wbscratch, =$g_GCShadowEnd
- ldr $__wbscratch, [$__wbscratch]
- cmp $pShadow, $__wbscratch
- bhs %FT0
-
- ; *pShadow = $valReg
- str $valReg, [$pShadow]
-
- ; Ensure that the write to the shadow heap occurs before the read from the GC heap so that race
- ; conditions are caught by INVALIDGCVALUE.
- dmb
-
- ; if (*$ptrReg == $valReg) goto end
- ldr $__wbscratch, [$ptrReg]
- cmp $__wbscratch, $valReg
- beq %FT0
-
- ; *pShadow = INVALIDGCVALUE (0xcccccccd)
- movw $__wbscratch, #0xcccd
- movt $__wbscratch, #0xcccc
- str $__wbscratch, [$pShadow]
-
-0
- pop {$pShadow}
-#endif // WRITE_BARRIER_CHECK
- MEND
-
- ; UPDATE_CARD_TABLE
- ;
- ; Update the card table as necessary (if the object reference being assigned in the barrier refers to an
- ; object in the ephemeral generation). Otherwise this macro is a no-op. Assumes the location being written
- ; lies on the GC heap (either we've already performed the dynamic check or this is statically asserted by
- ; the JIT by calling the unchecked version of the write barrier).
- ;
- ; Additionally this macro can produce a uni-proc or multi-proc variant of the code. This governs whether
- ; we bother to check if the card table has been updated before making our own update (on an MP system it
- ; can be helpful to perform this check to avoid cache line thrashing, on an SP system the code path length
- ; is more important).
- ;
- ; Input:
- ; $ptrReg : register containing the location to be updated
- ; $valReg : register containing the value (an objref) to be written to the location above
- ; $mp : boolean indicating whether the code will run on an MP system
- ; $postGrow : boolean: {true} for post-grow version, {false} otherwise
- ; $tmpReg : additional register that can be trashed (can alias $ptrReg or $valReg if needed)
- ;
- ; Output:
- ; $tmpReg : trashed (defaults to $ptrReg)
- ; $__wbscratch : trashed
- ;
- MACRO
- UPDATE_CARD_TABLE $ptrReg, $valReg, $mp, $postGrow, $tmpReg
- ASSERT "$ptrReg" != "$__wbscratch"
- ASSERT "$valReg" != "$__wbscratch"
- ASSERT "$tmpReg" != "$__wbscratch"
-
- ; In most cases the callers of this macro are fine with scratching $ptrReg, the exception being the
- ; ref write barrier, which wants to scratch $valReg instead. Ideally we could set $ptrReg as the
- ; default for the $tmpReg parameter, but limitations in armasm won't allow that. Similarly it doesn't
- ; seem to like us trying to redefine $tmpReg in the body of the macro. Instead we define a new local
- ; string variable and set that either with the value of $tmpReg or $ptrReg if $tmpReg wasn't
- ; specified.
- LCLS tempReg
- IF "$tmpReg" == ""
-tempReg SETS "$ptrReg"
- ELSE
-tempReg SETS "$tmpReg"
- ENDIF
-
- ; Check whether the value object lies in the ephemeral generations. If not we don't have to update the
- ; card table.
- LOAD_GC_GLOBAL $__wbscratch, g_ephemeral_low
- cmp $valReg, $__wbscratch
- blo %FT0
- ; Only in post grow higher generation can be beyond ephemeral segment
- IF $postGrow
- LOAD_GC_GLOBAL $__wbscratch, g_ephemeral_high
- cmp $valReg, $__wbscratch
- bhs %FT0
- ENDIF
-
- ; Update the card table.
- LOAD_GC_GLOBAL $__wbscratch, g_card_table
- add $__wbscratch, $__wbscratch, $ptrReg, lsr #10
-
- ; On MP systems make sure the card hasn't already been set first to avoid thrashing cache lines
- ; between CPUs.
- ; @ARMTODO: Check that the conditional store doesn't unconditionally gain exclusive access to the
- ; cache line anyway. Compare perf with a branch over and verify that omitting the compare on uniproc
- ; machines really is a perf win.
- IF $mp
- ldrb $tempReg, [$__wbscratch]
- cmp $tempReg, #0xff
- movne $tempReg, #0xff
- strbne $tempReg, [$__wbscratch]
- ELSE
- mov $tempReg, #0xff
- strb $tempReg, [$__wbscratch]
- ENDIF
-0
- MEND
-
- ; CHECK_GC_HEAP_RANGE
- ;
- ; Verifies that the given value points into the GC heap range. If so the macro will fall through to the
- ; following code. Otherwise (if the value points outside the GC heap) a branch to the supplied label will
- ; be made.
- ;
- ; Input:
- ; $ptrReg : register containing the location to be updated
- ; $label : label branched to on a range check failure
- ;
- ; Output:
- ; $__wbscratch : trashed
- ;
- MACRO
- CHECK_GC_HEAP_RANGE $ptrReg, $label
- ASSERT "$ptrReg" != "$__wbscratch"
-
- LOAD_GC_GLOBAL $__wbscratch, g_lowest_address
- cmp $ptrReg, $__wbscratch
- blo $label
- LOAD_GC_GLOBAL $__wbscratch, g_highest_address
- cmp $ptrReg, $__wbscratch
- bhs $label
- MEND
-
-;
-; Finally define the write barrier functions themselves. Currently we don't provide variations that use
-; different input registers. If the JIT wants this at a later stage in order to improve code quality it would
-; be a relatively simple change to implement via an additional macro parameter to WRITE_BARRIER_ENTRY.
-;
-; The calling convention for the first batch of write barriers is:
-;
-; On entry:
-; r0 : the destination address (LHS of the assignment)
-; r1 : the object reference (RHS of the assignment)
-;
-; On exit:
-; r0 : trashed
-; $__wbscratch : trashed
-;
-
- ; If you update any of the writebarrier be sure to update the sizes of patchable
- ; writebarriers in
- ; see ValidateWriteBarriers()
-
- ; The write barriers are macro taking arguments like
- ; $name: Name of the write barrier
- ; $mp: {true} for multi-proc, {false} otherwise
- ; $post: {true} for post-grow version, {false} otherwise
-
- MACRO
- JIT_WRITEBARRIER $name, $mp, $post
- WRITE_BARRIER_ENTRY $name
- IF $mp
- dmb ; Perform a memory barrier
- ENDIF
- str r1, [r0] ; Write the reference
- UPDATE_GC_SHADOW r0, r1 ; Update the shadow GC heap for debugging
- UPDATE_CARD_TABLE r0, r1, $mp, $post ; Update the card table if necessary
- bx lr
- WRITE_BARRIER_END
- MEND
-
- MACRO
- JIT_CHECKEDWRITEBARRIER_SP $name, $post
- WRITE_BARRIER_ENTRY $name
- str r1, [r0] ; Write the reference
- CHECK_GC_HEAP_RANGE r0, %F1 ; Check whether the destination is in the GC heap
- UPDATE_GC_SHADOW r0, r1 ; Update the shadow GC heap for debugging
- UPDATE_CARD_TABLE r0, r1, {false}, $post; Update the card table if necessary
-1
- bx lr
- WRITE_BARRIER_END
- MEND
-
- MACRO
- JIT_CHECKEDWRITEBARRIER_MP $name, $post
- WRITE_BARRIER_ENTRY $name
- CHECK_GC_HEAP_RANGE r0, %F1 ; Check whether the destination is in the GC heap
- dmb ; Perform a memory barrier
- str r1, [r0] ; Write the reference
- UPDATE_GC_SHADOW r0, r1 ; Update the shadow GC heap for debugging
- UPDATE_CARD_TABLE r0, r1, {true}, $post ; Update the card table if necessary
- bx lr
-1
- str r1, [r0] ; Write the reference
- bx lr
- WRITE_BARRIER_END
- MEND
-
-; The ByRef write barriers have a slightly different interface:
-;
-; On entry:
-; r0 : the destination address (object reference written here)
-; r1 : the source address (points to object reference to write)
-;
-; On exit:
-; r0 : incremented by 4
-; r1 : incremented by 4
-; r2 : trashed
-; $__wbscratch : trashed
-;
- MACRO
- JIT_BYREFWRITEBARRIER $name, $mp, $post
- WRITE_BARRIER_ENTRY $name
- IF $mp
- dmb ; Perform a memory barrier
- ENDIF
- ldr r2, [r1] ; Load target object ref from source pointer
- str r2, [r0] ; Write the reference to the destination pointer
- CHECK_GC_HEAP_RANGE r0, %F1 ; Check whether the destination is in the GC heap
- UPDATE_GC_SHADOW r0, r2 ; Update the shadow GC heap for debugging
- UPDATE_CARD_TABLE r0, r2, $mp, $post, r2 ; Update the card table if necessary (trash r2 rather than r0)
-1
- add r0, #4 ; Increment the destination pointer by 4
- add r1, #4 ; Increment the source pointer by 4
- bx lr
- WRITE_BARRIER_END
- MEND
-
- BEGIN_WRITE_BARRIERS
-
- ; There 4 versions of each write barriers. A 2x2 combination of multi-proc/single-proc and pre/post grow version
- JIT_WRITEBARRIER JIT_WriteBarrier_SP_Pre, {false}, {false}
- JIT_WRITEBARRIER JIT_WriteBarrier_SP_Post, {false}, {true}
- JIT_WRITEBARRIER JIT_WriteBarrier_MP_Pre, {true}, {false}
- JIT_WRITEBARRIER JIT_WriteBarrier_MP_Post, {true}, {true}
-
- JIT_CHECKEDWRITEBARRIER_SP JIT_CheckedWriteBarrier_SP_Pre, {false}
- JIT_CHECKEDWRITEBARRIER_SP JIT_CheckedWriteBarrier_SP_Post, {true}
- JIT_CHECKEDWRITEBARRIER_MP JIT_CheckedWriteBarrier_MP_Pre, {false}
- JIT_CHECKEDWRITEBARRIER_MP JIT_CheckedWriteBarrier_MP_Post, {true}
-
- JIT_BYREFWRITEBARRIER JIT_ByRefWriteBarrier_SP_Pre, {false}, {false}
- JIT_BYREFWRITEBARRIER JIT_ByRefWriteBarrier_SP_Post, {false}, {true}
- JIT_BYREFWRITEBARRIER JIT_ByRefWriteBarrier_MP_Pre, {true}, {false}
- JIT_BYREFWRITEBARRIER JIT_ByRefWriteBarrier_MP_Post, {true}, {true}
-
- END_WRITE_BARRIERS
-
- IMPORT JIT_WriteBarrier_Loc
-
-; ------------------------------------------------------------------
-; __declspec(naked) void F_CALL_CONV JIT_WriteBarrier_Callable(Object **dst, Object* val)
- LEAF_ENTRY JIT_WriteBarrier_Callable
-
- ; Branch to the write barrier
- ldr r2, =JIT_WriteBarrier_Loc ; or R3? See targetarm.h
- ldr pc, [r2]
-
- LEAF_END
-
-#ifdef FEATURE_READYTORUN
-
- NESTED_ENTRY DelayLoad_MethodCall_FakeProlog
-
- ; Match what the lazy thunk has pushed. The actual method arguments will be spilled later.
- PROLOG_PUSH {r1-r3}
-
- ; This is where execution really starts.
-DelayLoad_MethodCall
- EXPORT DelayLoad_MethodCall
-
- PROLOG_PUSH {r0}
-
- PROLOG_WITH_TRANSITION_BLOCK 0x0, {true}, DoNotPushArgRegs
-
- ; Load the helper arguments
- ldr r5, [sp,#(__PWTB_TransitionBlock+10*4)] ; pModule
- ldr r6, [sp,#(__PWTB_TransitionBlock+11*4)] ; sectionIndex
- ldr r7, [sp,#(__PWTB_TransitionBlock+12*4)] ; indirection
-
- ; Spill the actual method arguments
- str r1, [sp,#(__PWTB_TransitionBlock+10*4)]
- str r2, [sp,#(__PWTB_TransitionBlock+11*4)]
- str r3, [sp,#(__PWTB_TransitionBlock+12*4)]
-
- add r0, sp, #__PWTB_TransitionBlock ; pTransitionBlock
-
- mov r1, r7 ; pIndirection
- mov r2, r6 ; sectionIndex
- mov r3, r5 ; pModule
-
- bl ExternalMethodFixupWorker
-
- ; mov the address we patched to in R12 so that we can tail call to it
- mov r12, r0
-
- EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
-
- PATCH_LABEL ExternalMethodFixupPatchLabel
- EPILOG_BRANCH_REG r12
-
- NESTED_END
-
-
- MACRO
- DynamicHelper $frameFlags, $suffix
-
- GBLS __FakePrologName
-__FakePrologName SETS "DelayLoad_Helper":CC:"$suffix":CC:"_FakeProlog"
-
- NESTED_ENTRY $__FakePrologName
-
- ; Match what the lazy thunk has pushed. The actual method arguments will be spilled later.
- PROLOG_PUSH {r1-r3}
-
- GBLS __RealName
-__RealName SETS "DelayLoad_Helper":CC:"$suffix"
-
- ; This is where execution really starts.
-$__RealName
- EXPORT $__RealName
-
- PROLOG_PUSH {r0}
-
- PROLOG_WITH_TRANSITION_BLOCK 0x4, {false}, DoNotPushArgRegs
-
- ; Load the helper arguments
- ldr r5, [sp,#(__PWTB_TransitionBlock+10*4)] ; pModule
- ldr r6, [sp,#(__PWTB_TransitionBlock+11*4)] ; sectionIndex
- ldr r7, [sp,#(__PWTB_TransitionBlock+12*4)] ; indirection
-
- ; Spill the actual method arguments
- str r1, [sp,#(__PWTB_TransitionBlock+10*4)]
- str r2, [sp,#(__PWTB_TransitionBlock+11*4)]
- str r3, [sp,#(__PWTB_TransitionBlock+12*4)]
-
- add r0, sp, #__PWTB_TransitionBlock ; pTransitionBlock
-
- mov r1, r7 ; pIndirection
- mov r2, r6 ; sectionIndex
- mov r3, r5 ; pModule
-
- mov r4, $frameFlags
- str r4, [sp,#0]
-
- bl DynamicHelperWorker
-
- cbnz r0, %FT0
- ldr r0, [sp,#(__PWTB_TransitionBlock+9*4)] ; The result is stored in the argument area of the transition block
-
- EPILOG_WITH_TRANSITION_BLOCK_RETURN
-
-0
- mov r12, r0
- EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
- EPILOG_BRANCH_REG r12
-
- NESTED_END
-
- MEND
-
- DynamicHelper DynamicHelperFrameFlags_Default
- DynamicHelper DynamicHelperFrameFlags_ObjectArg, _Obj
- DynamicHelper DynamicHelperFrameFlags_ObjectArg | DynamicHelperFrameFlags_ObjectArg2, _ObjObj
-
-#endif // FEATURE_READYTORUN
-
-;;-----------------------------------------------------------------------------
-;; The following helper will access ("probe") a word on each page of the stack
-;; starting with the page right beneath sp down to the one pointed to by r4.
-;; The procedure is needed to make sure that the "guard" page is pushed down below the allocated stack frame.
-;; The call to the helper will be emitted by JIT in the function/funclet prolog when stack frame is larger than an OS page.
-;;-----------------------------------------------------------------------------
-; On entry:
-; r4 - points to the lowest address on the stack frame being allocated (i.e. [InitialSp - FrameSize])
-; sp - points to some byte on the last probed page
-; On exit:
-; r4 - is preserved
-; r5 - is not preserved
-;
-; NOTE: this helper will probe at least one page below the one pointed to by sp.
-#define PROBE_PAGE_SIZE 4096
-#define PROBE_PAGE_SIZE_LOG2 12
-
- LEAF_ENTRY JIT_StackProbe
- PROLOG_PUSH {r7}
- PROLOG_STACK_SAVE r7
-
- mov r5, sp ; r5 points to some byte on the last probed page
- bfc r5, #0, #PROBE_PAGE_SIZE_LOG2 ; r5 points to the **lowest address** on the last probed page
- mov sp, r5
-
-ProbeLoop
- ; Immediate operand for the following instruction can not be greater than 4095.
- sub sp, #(PROBE_PAGE_SIZE - 4) ; sp points to the **fourth** byte on the **next page** to probe
- ldr r5, [sp, #-4]! ; sp points to the lowest address on the **last probed** page
- cmp sp, r4
- bhi ProbeLoop ; if (sp > r4), then we need to probe at least one more page.
-
- EPILOG_STACK_RESTORE r7
- EPILOG_POP {r7}
- EPILOG_BRANCH_REG lr
- LEAF_END_MARKED JIT_StackProbe
-
-#ifdef FEATURE_TIERED_COMPILATION
-
- IMPORT OnCallCountThresholdReached
-
- NESTED_ENTRY OnCallCountThresholdReachedStub
- PROLOG_WITH_TRANSITION_BLOCK
-
- add r0, sp, #__PWTB_TransitionBlock ; TransitionBlock *
- mov r1, r12 ; stub-identifying token
- bl OnCallCountThresholdReached
- mov r12, r0
-
- EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
- EPILOG_BRANCH_REG r12
- NESTED_END
-
-#endif ; FEATURE_TIERED_COMPILATION
-
-; Must be at very end of file
- END
diff --git a/src/coreclr/vm/arm/cgencpu.h b/src/coreclr/vm/arm/cgencpu.h
index 1017052e8ab9e..aeb620718fe5c 100644
--- a/src/coreclr/vm/arm/cgencpu.h
+++ b/src/coreclr/vm/arm/cgencpu.h
@@ -32,10 +32,6 @@ struct ArgLocDesc;
extern PCODE GetPreStubEntryPoint();
-#ifndef TARGET_UNIX
-#define USE_REDIRECT_FOR_GCSTRESS
-#endif // TARGET_UNIX
-
// CPU-dependent functions
Stub * GenerateInitPInvokeFrameHelper();
@@ -48,10 +44,6 @@ EXTERN_C void checkStack(void);
//**********************************************************************
#define COMMETHOD_PREPAD 12 // # extra bytes to allocate in addition to sizeof(ComCallMethodDesc)
-#ifdef FEATURE_COMINTEROP
-#define COMMETHOD_CALL_PRESTUB_SIZE 12
-#define COMMETHOD_CALL_PRESTUB_ADDRESS_OFFSET 8 // the offset of the call target address inside the prestub
-#endif // FEATURE_COMINTEROP
#define STACK_ALIGN_SIZE 4
@@ -229,10 +221,6 @@ inline void ClearITState(T_CONTEXT *context) {
context->Cpsr = context->Cpsr & 0xf9ff03ff;
}
-#ifdef FEATURE_COMINTEROP
-void emitCOMStubCall (ComCallMethodDesc *pCOMMethodRX, ComCallMethodDesc *pCOMMethodRW, PCODE target);
-#endif // FEATURE_COMINTEROP
-
//------------------------------------------------------------------------
inline void emitUnconditionalBranchThumb(LPBYTE pBuffer, int16_t offset)
{
diff --git a/src/coreclr/vm/arm/ehhelpers.asm b/src/coreclr/vm/arm/ehhelpers.asm
deleted file mode 100644
index e0d17f15eb4d6..0000000000000
--- a/src/coreclr/vm/arm/ehhelpers.asm
+++ /dev/null
@@ -1,153 +0,0 @@
-; Licensed to the .NET Foundation under one or more agreements.
-; The .NET Foundation licenses this file to you under the MIT license.
-
-#include "ksarm.h"
-
-#include "asmconstants.h"
-
-#include "asmmacros.h"
-
- IMPORT HijackHandler
- IMPORT ThrowControlForThread
-
-;
-; WARNING!! These functions immediately ruin thread unwindability. This is
-; WARNING!! OK as long as there is a mechanism for saving the thread context
-; WARNING!! prior to running these functions as well as a mechanism for
-; WARNING!! restoring the context prior to any stackwalk. This means that
-; WARNING!! we need to ensure that no GC can occur while the stack is
-; WARNING!! unwalkable. This further means that we cannot allow any exception
-; WARNING!! to occur when the stack is unwalkable
-;
-
- TEXTAREA
-
- ; GSCookie, scratch area
- GBLA OFFSET_OF_FRAME
-
- ; GSCookie + alignment padding
-OFFSET_OF_FRAME SETA 4 + SIZEOF__GSCookie
-
- MACRO
- GenerateRedirectedStubWithFrame $STUB, $TARGET
-
- ;
- ; This is the primary function to which execution will be redirected to.
- ;
- NESTED_ENTRY $STUB
-
- ;
- ; IN: lr: original IP before redirect
- ;
-
- PROLOG_PUSH {r4,r7,lr}
- PROLOG_STACK_ALLOC OFFSET_OF_FRAME + SIZEOF__FaultingExceptionFrame
-
- ; At this point, the stack maybe misaligned if the thread abort was asynchronously
- ; triggered in the prolog or epilog of the managed method. For such a case, we must
- ; align the stack before calling into the VM.
- ;
- ; Runtime check for 8-byte alignment.
- PROLOG_STACK_SAVE r7
- and r0, r7, #4
- sub sp, sp, r0
-
- ; Save pointer to FEF for GetFrameFromRedirectedStubStackFrame
- add r4, sp, #OFFSET_OF_FRAME
-
- ; Prepare to initialize to NULL
- mov r1,#0
- str r1, [r4] ; Initialize vtbl (it is not strictly necessary)
- str r1, [r4, #FaultingExceptionFrame__m_fFilterExecuted] ; Initialize BOOL for personality routine
-
- mov r0, r4 ; move the ptr to FEF in R0
-
- ; stack must be 8 byte aligned
- CHECK_STACK_ALIGNMENT
-
- bl $TARGET
-
- ; Target should not return.
- EMIT_BREAKPOINT
-
- NESTED_END $STUB
-
- MEND
-
-; ------------------------------------------------------------------
-;
-; Helpers for ThreadAbort exceptions
-;
-
- NESTED_ENTRY RedirectForThreadAbort2,,HijackHandler
- PROLOG_PUSH {r0, lr}
-
- ; stack must be 8 byte aligned
- CHECK_STACK_ALIGNMENT
-
- ; On entry:
- ;
- ; R0 = Address of FaultingExceptionFrame.
- ;
- ; Invoke the helper to setup the FaultingExceptionFrame and raise the exception
- bl ThrowControlForThread
-
- ; ThrowControlForThread doesn't return.
- EMIT_BREAKPOINT
-
- NESTED_END RedirectForThreadAbort2
-
- GenerateRedirectedStubWithFrame RedirectForThreadAbort, RedirectForThreadAbort2
-
-; ------------------------------------------------------------------
-
- ; This helper enables us to call into a funclet after applying the non-volatiles
- NESTED_ENTRY CallEHFunclet
-
- PROLOG_PUSH {r4-r11, lr}
- PROLOG_STACK_ALLOC 4
-
- ; On entry:
- ;
- ; R0 = throwable
- ; R1 = PC to invoke
- ; R2 = address of R4 register in CONTEXT record; used to restore the non-volatile registers of CrawlFrame
- ; R3 = address of the location where the SP of funclet's caller (i.e. this helper) should be saved.
- ;
- ; Save the SP of this function
- str sp, [r3]
- ; apply the non-volatiles corresponding to the CrawlFrame
- ldm r2, {r4-r11}
- ; Invoke the funclet
- blx r1
-
- EPILOG_STACK_FREE 4
- EPILOG_POP {r4-r11, pc}
-
- NESTED_END CallEHFunclet
-
- ; This helper enables us to call into a filter funclet by passing it the CallerSP to lookup the
- ; frame pointer for accessing the locals in the parent method.
- NESTED_ENTRY CallEHFilterFunclet
-
- PROLOG_PUSH {lr}
- PROLOG_STACK_ALLOC 4
-
- ; On entry:
- ;
- ; R0 = throwable
- ; R1 = SP of the caller of the method/funclet containing the filter
- ; R2 = PC to invoke
- ; R3 = address of the location where the SP of funclet's caller (i.e. this helper) should be saved.
- ;
- ; Save the SP of this function
- str sp, [r3]
- ; Invoke the filter funclet
- blx r2
-
- EPILOG_STACK_FREE 4
- EPILOG_POP {pc}
-
- NESTED_END CallEHFilterFunclet
- END
-
diff --git a/src/coreclr/vm/arm/patchedcode.asm b/src/coreclr/vm/arm/patchedcode.asm
deleted file mode 100644
index 3228829f3f604..0000000000000
--- a/src/coreclr/vm/arm/patchedcode.asm
+++ /dev/null
@@ -1,61 +0,0 @@
-; Licensed to the .NET Foundation under one or more agreements.
-; The .NET Foundation licenses this file to you under the MIT license.
-
-#include "ksarm.h"
-
-#include "asmconstants.h"
-
-#include "asmmacros.h"
-
-
- TEXTAREA
-
-
-; ------------------------------------------------------------------
-; Start of the writeable code region
- LEAF_ENTRY JIT_PatchedCodeStart
- bx lr
- LEAF_END
-
-; ------------------------------------------------------------------
-; GC write barrier support.
-;
-; GC Write barriers are defined in asmhelpers.asm. The following functions are used to define
-; patchable location where the write-barriers are copied over at runtime
-
- LEAF_ENTRY JIT_PatchedWriteBarrierStart
- ; Cannot be empty function to prevent LNK1223
- bx lr
- LEAF_END
-
- ; These write barriers are overwritten on the fly
- ; See ValidateWriteBarriers on how the sizes of these should be calculated
- ALIGN 4
- LEAF_ENTRY JIT_WriteBarrier
- SPACE (0x84)
- LEAF_END_MARKED JIT_WriteBarrier
-
- ALIGN 4
- LEAF_ENTRY JIT_CheckedWriteBarrier
- SPACE (0x9C)
- LEAF_END_MARKED JIT_CheckedWriteBarrier
-
- ALIGN 4
- LEAF_ENTRY JIT_ByRefWriteBarrier
- SPACE (0xA0)
- LEAF_END_MARKED JIT_ByRefWriteBarrier
-
- LEAF_ENTRY JIT_PatchedWriteBarrierLast
- ; Cannot be empty function to prevent LNK1223
- bx lr
- LEAF_END
-
-; ------------------------------------------------------------------
-; End of the writeable code region
- LEAF_ENTRY JIT_PatchedCodeLast
- bx lr
- LEAF_END
-
-
-; Must be at very end of file
- END
diff --git a/src/coreclr/vm/arm/stubs.cpp b/src/coreclr/vm/arm/stubs.cpp
index 750972f51e984..634eea810a31d 100644
--- a/src/coreclr/vm/arm/stubs.cpp
+++ b/src/coreclr/vm/arm/stubs.cpp
@@ -280,13 +280,8 @@ void StubLinkerCPU::Init(void)
// value of the global into a register.
struct WriteBarrierDescriptor
{
-#ifdef TARGET_UNIX
DWORD m_funcStartOffset; // Offset to the start of the barrier function relative to this struct address
DWORD m_funcEndOffset; // Offset to the end of the barrier function relative to this struct address
-#else // TARGET_UNIX
- BYTE * m_pFuncStart; // Pointer to the start of the barrier function
- BYTE * m_pFuncEnd; // Pointer to the end of the barrier function
-#endif // TARGET_UNIX
DWORD m_dw_g_lowest_address_offset; // Offset of the instruction reading g_lowest_address
DWORD m_dw_g_highest_address_offset; // Offset of the instruction reading g_highest_address
DWORD m_dw_g_ephemeral_low_offset; // Offset of the instruction reading g_ephemeral_low
@@ -440,21 +435,12 @@ void UpdateGCWriteBarriers(bool postGrow = false)
// Iterate through the write barrier patch table created in the .clrwb section
// (see write barrier asm code)
WriteBarrierDescriptor * pDesc = &g_rgWriteBarrierDescriptors;
-#ifdef TARGET_UNIX
while (pDesc->m_funcStartOffset)
-#else // TARGET_UNIX
- while (pDesc->m_pFuncStart)
-#endif // TARGET_UNIX
{
// If the write barrier is being currently used (as in copied over to the patchable site)
// then read the patch location from the table and use the offset to patch the target asm code
-#ifdef TARGET_UNIX
PBYTE to = FindWBMapping((BYTE *)pDesc + pDesc->m_funcStartOffset);
size_t barrierSize = pDesc->m_funcEndOffset - pDesc->m_funcStartOffset;
-#else // TARGET_UNIX
- PBYTE to = FindWBMapping(pDesc->m_pFuncStart);
- size_t barrierSize = pDesc->m_pFuncEnd - pDesc->m_pFuncStart;
-#endif // TARGET_UNIX
if(to)
{
to = (PBYTE)PCODEToPINSTR((PCODE)GetWriteBarrierCodeLocation(to));
@@ -564,9 +550,6 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
do
{
-#ifndef TARGET_UNIX
- pvControlPc = Thread::VirtualUnwindCallFrame(&ctx, &nonVolRegPtrs);
-#else // !TARGET_UNIX
#ifdef DACCESS_COMPILE
HRESULT hr = DacVirtualUnwind(threadId, &ctx, &nonVolRegPtrs);
if (FAILED(hr))
@@ -582,7 +565,6 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
}
#endif // DACCESS_COMPILE
pvControlPc = GetIP(&ctx);
-#endif // !TARGET_UNIX
if (funCallDepth > 0)
{
--funCallDepth;
@@ -1141,21 +1123,17 @@ Stub *GenerateInitPInvokeFrameHelper()
ThumbReg regScratch = ThumbReg(6);
ThumbReg regR9 = ThumbReg(9);
-#ifdef TARGET_UNIX
// Erect frame to perform call to GetThread
psl->ThumbEmitProlog(1, sizeof(ArgumentRegisters), FALSE); // Save r4 for aligned stack
// Save argument registers around the GetThread call. Don't bother with using ldm/stm since this inefficient path anyway.
for (int reg = 0; reg < 4; reg++)
psl->ThumbEmitStoreRegIndirect(ThumbReg(reg), thumbRegSp, offsetof(ArgumentRegisters, r) + sizeof(*ArgumentRegisters::r) * reg);
-#endif
psl->ThumbEmitGetThread(regThread);
-#ifdef TARGET_UNIX
for (int reg = 0; reg < 4; reg++)
psl->ThumbEmitLoadRegIndirect(ThumbReg(reg), thumbRegSp, offsetof(ArgumentRegisters, r) + sizeof(*ArgumentRegisters::r) * reg);
-#endif
// mov [regFrame + FrameInfo.offsetOfGSCookie], GetProcessGSCookie()
psl->ThumbEmitMovConstant(regScratch, GetProcessGSCookie());
@@ -1180,27 +1158,16 @@ Stub *GenerateInitPInvokeFrameHelper()
psl->ThumbEmitMovConstant(regScratch, 0);
psl->ThumbEmitStoreRegIndirect(regScratch, regFrame, FrameInfo.offsetOfReturnAddress - negSpace);
-#ifdef TARGET_UNIX
DWORD cbSavedRegs = sizeof(ArgumentRegisters) + 2 * 4; // r0-r3, r4, lr
psl->ThumbEmitAdd(regScratch, thumbRegSp, cbSavedRegs);
psl->ThumbEmitStoreRegIndirect(regScratch, regFrame, FrameInfo.offsetOfCallSiteSP - negSpace);
-#else
- // str SP, [regFrame + FrameInfo.offsetOfCallSiteSP]
- psl->ThumbEmitStoreRegIndirect(thumbRegSp, regFrame, FrameInfo.offsetOfCallSiteSP - negSpace);
-#endif
// mov [regThread + offsetof(Thread, m_pFrame)], regFrame
psl->ThumbEmitStoreRegIndirect(regFrame, regThread, offsetof(Thread, m_pFrame));
// leave current Thread in R4
-#ifdef TARGET_UNIX
psl->ThumbEmitEpilog();
-#else
- // Return. The return address has been restored into LR at this point.
- // bx lr
- psl->ThumbEmitJumpRegister(thumbRegLr);
-#endif
// A single process-wide stub that will never unload
RETURN psl->Link(SystemDomain::GetGlobalLoaderAllocator()->GetStubHeap());
@@ -1208,8 +1175,6 @@ Stub *GenerateInitPInvokeFrameHelper()
void StubLinkerCPU::ThumbEmitGetThread(ThumbReg dest)
{
-#ifdef TARGET_UNIX
-
ThumbEmitMovConstant(ThumbReg(0), (TADDR)GetThreadHelper);
ThumbEmitCallRegister(ThumbReg(0));
@@ -1218,20 +1183,6 @@ void StubLinkerCPU::ThumbEmitGetThread(ThumbReg dest)
{
ThumbEmitMovRegReg(dest, ThumbReg(0));
}
-
-#else // TARGET_UNIX
-
- // mrc p15, 0, dest, c13, c0, 2
- Emit16(0xee1d);
- Emit16((WORD)(0x0f50 | (dest << 12)));
-
- ThumbEmitLoadRegIndirect(dest, dest, offsetof(TEB, ThreadLocalStoragePointer));
-
- ThumbEmitLoadRegIndirect(dest, dest, sizeof(void *) * _tls_index);
-
- ThumbEmitLoadRegIndirect(dest, dest, (int)Thread::GetOffsetOfThreadStatic(&gCurrentThreadInfo));
-
-#endif // TARGET_UNIX
}
@@ -1819,34 +1770,6 @@ VOID ResetCurrentContext()
#endif // !DACCESS_COMPILE
-#ifdef FEATURE_COMINTEROP
-void emitCOMStubCall (ComCallMethodDesc *pCOMMethodRX, ComCallMethodDesc *pCOMMethodRW, PCODE target)
-{
- WRAPPER_NO_CONTRACT;
-
- // mov r12, pc
- // ldr pc, [pc, #0]
- // dcd 0
- // dcd target
- WORD rgCode[] = {
- 0x46fc,
- 0xf8df, 0xf004
- };
-
- BYTE *pBufferRX = (BYTE*)pCOMMethodRX - COMMETHOD_CALL_PRESTUB_SIZE;
- BYTE *pBufferRW = (BYTE*)pCOMMethodRW - COMMETHOD_CALL_PRESTUB_SIZE;
-
- memcpy(pBufferRW, rgCode, sizeof(rgCode));
- *((PCODE*)(pBufferRW + sizeof(rgCode) + 2)) = target;
-
- // Ensure that the updated instructions get actually written
- ClrFlushInstructionCache(pBufferRX, COMMETHOD_CALL_PRESTUB_SIZE);
-
- _ASSERTE(IS_ALIGNED(pBufferRX + COMMETHOD_CALL_PRESTUB_ADDRESS_OFFSET, sizeof(void*)) &&
- *((PCODE*)(pBufferRX + COMMETHOD_CALL_PRESTUB_ADDRESS_OFFSET)) == target);
-}
-#endif // FEATURE_COMINTEROP
-
void MovRegImm(BYTE* p, int reg, TADDR imm)
{
LIMITED_METHOD_CONTRACT;
diff --git a/src/coreclr/vm/arm/thunktemplates.asm b/src/coreclr/vm/arm/thunktemplates.asm
deleted file mode 100644
index 6562be72146c2..0000000000000
--- a/src/coreclr/vm/arm/thunktemplates.asm
+++ /dev/null
@@ -1,43 +0,0 @@
-; Licensed to the .NET Foundation under one or more agreements.
-; The .NET Foundation licenses this file to you under the MIT license.
-
-#include "ksarm.h"
-#include "asmconstants.h"
-#include "asmmacros.h"
-
-
- TEXTAREA
-
- ALIGN 4
-
- #define DATA_SLOT(stub, field) stub##Code + PAGE_SIZE + stub##Data__##field
-
- LEAF_ENTRY StubPrecodeCode
- ldr r12, DATA_SLOT(StubPrecode, MethodDesc)
- ldr pc, DATA_SLOT(StubPrecode, Target)
- LEAF_END_MARKED StubPrecodeCode
-
- ALIGN 4
-
- LEAF_ENTRY FixupPrecodeCode
- ldr pc, DATA_SLOT(FixupPrecode, Target)
- ldr r12, DATA_SLOT(FixupPrecode, MethodDesc)
- ldr pc, DATA_SLOT(FixupPrecode, PrecodeFixupThunk)
- LEAF_END_MARKED FixupPrecodeCode
-
- ALIGN 4
-
- LEAF_ENTRY CallCountingStubCode
- push {r0}
- ldr r12, DATA_SLOT(CallCountingStub, RemainingCallCountCell)
- ldrh r0, [r12]
- subs r0, r0, #1
- strh r0, [r12]
- pop {r0}
- beq CountReachedZero
- ldr pc, DATA_SLOT(CallCountingStub, TargetForMethod)
-CountReachedZero
- ldr pc, DATA_SLOT(CallCountingStub, TargetForThresholdReached)
- LEAF_END_MARKED CallCountingStubCode
-
- END
diff --git a/src/native/corehost/apphost/standalone/CMakeLists.txt b/src/native/corehost/apphost/standalone/CMakeLists.txt
index a002464614770..b682fd9ebaed8 100644
--- a/src/native/corehost/apphost/standalone/CMakeLists.txt
+++ b/src/native/corehost/apphost/standalone/CMakeLists.txt
@@ -48,7 +48,7 @@ if(CLR_CMAKE_TARGET_WIN32)
)
endif()
-# Specify non-default Windows libs to be used for Arm/Arm64 builds
-if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64))
+# Specify non-default Windows libs to be used for Arm64 builds
+if (CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_ARM64)
target_link_libraries(apphost PRIVATE shell32.lib)
endif()
diff --git a/src/native/corehost/build.cmd b/src/native/corehost/build.cmd
index 470746f4dde9f..e43bcae3cf3cc 100644
--- a/src/native/corehost/build.cmd
+++ b/src/native/corehost/build.cmd
@@ -30,7 +30,6 @@ if /i [%1] == [Checked] (set CMAKE_BUILD_TYPE=Checked&&shift&goto Arg_Loop)
if /i [%1] == [AnyCPU] (set __BuildArch=x64&&shift&goto Arg_Loop)
if /i [%1] == [x86] (set __BuildArch=x86&&shift&goto Arg_Loop)
-if /i [%1] == [arm] (set __BuildArch=arm&&shift&goto Arg_Loop)
if /i [%1] == [x64] (set __BuildArch=x64&&shift&goto Arg_Loop)
if /i [%1] == [amd64] (set __BuildArch=x64&&shift&goto Arg_Loop)
if /i [%1] == [arm64] (set __BuildArch=arm64&&shift&goto Arg_Loop)
@@ -94,7 +93,6 @@ if not exist "%__IntermediatesDir%" md "%__IntermediatesDir%"
if /i "%__BuildArch%" == "x64" (set cm_BaseRid=win7)
if /i "%__BuildArch%" == "x86" (set cm_BaseRid=win7)
-if /i "%__BuildArch%" == "arm" (set cm_BaseRid=win8)
if /i "%__BuildArch%" == "arm64" (set cm_BaseRid=win10)
:: Form the base RID to be used if we are doing a portable build
if /i "%__PortableBuild%" == "1" (set cm_BaseRid=win)
diff --git a/src/native/corehost/ijwhost/CMakeLists.txt b/src/native/corehost/ijwhost/CMakeLists.txt
index 6a4fdbb4d4ce1..1661f162974d5 100644
--- a/src/native/corehost/ijwhost/CMakeLists.txt
+++ b/src/native/corehost/ijwhost/CMakeLists.txt
@@ -32,7 +32,7 @@ add_definitions(-DFEATURE_LIBHOST=1)
convert_to_absolute_path(SOURCES ${SOURCES})
convert_to_absolute_path(ASM_HELPERS_SOURCES ${ASM_HELPERS_SOURCES})
-if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64))
+if (CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_ARM64)
preprocess_files(ASM_HELPERS_SOURCES ${ASM_HELPERS_SOURCES})
if (CMAKE_GENERATOR MATCHES "Visual Studio")
compile_asm(TARGET ijwhost ASM_FILES ${ASM_HELPERS_SOURCES} OUTPUT_OBJECTS ASM_HELPERS_SOURCES)
@@ -47,8 +47,8 @@ list(APPEND SOURCES ${ASM_HELPERS_SOURCES})
include(../lib.cmake)
-# Specify non-default Windows libs to be used for Arm/Arm64 builds
-if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64))
+# Specify non-default Windows libs to be used for Arm64 builds
+if (CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_ARM64)
target_link_libraries(ijwhost PRIVATE Ole32.lib)
endif()
diff --git a/src/native/corehost/ijwhost/arm/asmhelpers.asm b/src/native/corehost/ijwhost/arm/asmhelpers.asm
deleted file mode 100644
index 8c3d306579a94..0000000000000
--- a/src/native/corehost/ijwhost/arm/asmhelpers.asm
+++ /dev/null
@@ -1,41 +0,0 @@
-; Licensed to the .NET Foundation under one or more agreements.
-; The .NET Foundation licenses this file to you under the MIT license.
-;
-
-#include "ksarm.h"
-
- TEXTAREA
-
- EXTERN start_runtime_and_get_target_address
-
- ;; Common code called from a bootstrap_thunk to call start_runtime_and_get_target_address and obtain the
- ;; real target address to which to tail call.
- ;;
- ;; On entry:
- ;; r12 : parameter provided by the thunk that points back into the thunk itself
- ;; other argument registers and possibly stack locations set up ready to make the real call
- ;;
- ;; On exit:
- ;; tail calls to the real target method
- ;;
- CFG_ALIGN
- NESTED_ENTRY start_runtime_thunk_stub
-
- PROLOG_PUSH {r0-r3} ; Save general argument registers
- PROLOG_PUSH {r4,lr} ; Save return address (r4 is saved simply to preserve stack alignment)
- PROLOG_VPUSH {d0-d7} ; Save floating point argument registers
-
- mov r0, r12 ; Only argument to start_runtime_and_get_target_address is the hidden thunk parameter
- bl start_runtime_and_get_target_address
-
- mov r12, r0 ; Preserve result (real target address)
-
- EPILOG_VPOP {d0-d7} ; Restore floating point argument registers
- EPILOG_POP {r4,lr} ; Restore return address
- EPILOG_POP {r0-r3} ; Restore general argument registers
-
- EPILOG_BRANCH_REG r12 ; Tail call to real target
-
- NESTED_END
-
- END
diff --git a/src/native/corehost/ijwhost/arm/bootstrap_thunk.cpp b/src/native/corehost/ijwhost/arm/bootstrap_thunk.cpp
deleted file mode 100644
index a8b47becfb8b5..0000000000000
--- a/src/native/corehost/ijwhost/arm/bootstrap_thunk.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-#include "bootstrap_thunk.h"
-#include "corhdr.h"
-#include "pal.h"
-
-//=================================================================================
-// Get thunk from the address that the thunk code provided
-bootstrap_thunk *bootstrap_thunk::get_thunk_from_cookie(std::uintptr_t cookie)
-{
-
- // Cookie is generated via the first thunk instruction:
- // mov r12, pc
- // The pc is returned from the hardware as the pc at the start of the instruction (i.e. the thunk address)
- // + 4. So we can recover the thunk address simply by subtracting 4 from the cookie.
- return (bootstrap_thunk *)(cookie - 4);
-}
-
-//=================================================================================
-// Get thunk from the thunk code entry point address
-bootstrap_thunk *bootstrap_thunk::get_thunk_from_entrypoint(std::uintptr_t entryAddr)
-{
- // The entry point is at the start of the thunk but the code address will have the low-order bit set to
- // indicate Thumb code and we need to mask that out.
- return (bootstrap_thunk *)(entryAddr & ~1);
-}
-
-//=================================================================================
-// Returns the slot address of the vtable entry for this thunk
-std::uintptr_t *bootstrap_thunk::get_slot_address()
-{
- return m_slot;
-}
-
-//=================================================================================
-// Returns the pal::dll_t for this thunk's module
-pal::dll_t bootstrap_thunk::get_dll_handle()
-{
- return m_dll;
-}
-
-//=================================================================================
-// Returns the token of this thunk
-std::uint32_t bootstrap_thunk::get_token()
-{
- return m_token;
-}
-
-//=================================================================================
-std::uintptr_t bootstrap_thunk::get_entrypoint()
-{
- // Set the low-order bit of the address returned to indicate to the hardware that it's Thumb code.
- return (std::uintptr_t)this | 1;
-}
-
-//=================================================================================
-// Initializes the thunk to point to the bootstrap helper that will load the
-// runtime and perform the real thunk initialization.
-//
-void bootstrap_thunk::initialize(std::uintptr_t pThunkInitFcn,
- pal::dll_t dll,
- std::uint32_t token,
- std::uintptr_t *pSlot)
-{
-
- // Initialize code section of the thunk:
- WORD rgCode[] = {
- 0x46fc, // mov r12, pc
- 0xf8df, 0xf004, // ldr pc, [pc, #4]
- 0x0000 // padding for 4-byte alignment of target address that follows
- };
- BYTE *pCode = (BYTE*)this;
- memcpy(pCode, rgCode, sizeof(rgCode));
- pCode += sizeof(rgCode);
- *(std::uintptr_t*)pCode = pThunkInitFcn;
-
- m_dll = dll;
- m_slot = pSlot;
- m_token = token;
-}
diff --git a/src/native/corehost/ijwhost/arm/bootstrap_thunk.h b/src/native/corehost/ijwhost/arm/bootstrap_thunk.h
deleted file mode 100644
index 2ce6cd5ac436d..0000000000000
--- a/src/native/corehost/ijwhost/arm/bootstrap_thunk.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-#ifndef IJW_BOOTSTRAP_THUNK_H
-#define IJW_BOOTSTRAP_THUNK_H
-
-#if !defined(TARGET_ARM)
-#error "This file should only be included on arm builds."
-#endif
-
-#include "pal.h"
-#include "corhdr.h"
-
-extern "C" void start_runtime_thunk_stub();
-
-#include
-//=================================================================================
-class bootstrap_thunk
-{
-private:
- WORD m_rgCode[4];
- std::uintptr_t m_pBootstrapCode;
-
- pal::dll_t m_dll; // pal::dll_t of this module
- std::uintptr_t* m_slot; // VTable slot for this thunk
- std::uint32_t m_token; // Token for this thunk
-
-public:
- // Get thunk from the address that the thunk code provided
- static bootstrap_thunk *get_thunk_from_cookie(std::uintptr_t cookie);
-
- // Get thunk from the thunk code entry point address
- static bootstrap_thunk *get_thunk_from_entrypoint(std::uintptr_t entryAddr);
-
- // Initializes the thunk to point to pThunkInitFcn that will load the
- // runtime and perform the real thunk initialization.
- void initialize(std::uintptr_t pThunkInitFcn,
- pal::dll_t dll,
- std::uint32_t token,
- std::uintptr_t *pSlot);
-
- // Returns the slot address of the vtable entry for this thunk
- std::uintptr_t *get_slot_address();
-
- // Returns the pal::dll_t for this thunk's module
- pal::dll_t get_dll_handle();
-
- // Returns the token of this thunk
- std::uint32_t get_token();
-
- std::uintptr_t get_entrypoint();
-};
-#include
-
-#endif
diff --git a/src/tests/build.cmd b/src/tests/build.cmd
index 22bc3ea843ee3..7e70fa991dc1a 100644
--- a/src/tests/build.cmd
+++ b/src/tests/build.cmd
@@ -70,7 +70,6 @@ if /i "%1" == "--" (set processedArgs=!processedArgs! %1&s
@REM The following arguments do not support '/', '-', or '--' prefixes
if /i "%1" == "x64" (set __BuildArch=x64&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "x86" (set __BuildArch=x86&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
-if /i "%1" == "arm" (set __BuildArch=arm&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "arm64" (set __BuildArch=arm64&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "debug" (set __BuildType=Debug&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
@@ -371,7 +370,7 @@ echo All arguments are optional and case-insensitive, and the '-' prefix is opti
echo.
echo.-? -h --help: View this message.
echo.
-echo Build architecture: one of "x64", "x86", "arm", "arm64" ^(default: x64^).
+echo Build architecture: one of "x64", "x86", "arm64" ^(default: x64^).
echo Build type: one of "Debug", "Checked", "Release" ^(default: Debug^).
echo.
echo -Rebuild: Clean up all test artifacts prior to building tests.
diff --git a/src/tests/issues.targets b/src/tests/issues.targets
index bf27e2cb576e8..02dc07ab9a940 100644
--- a/src/tests/issues.targets
+++ b/src/tests/issues.targets
@@ -294,235 +294,6 @@
-
-
-
- https://github.com/dotnet/runtime/issues/49184
-
-
- https://github.com/dotnet/runtime/issues/11360
-
-
- https://github.com/dotnet/runtime/issues/11360
-
-
- https://github.com/dotnet/runtime/issues/11360
-
-
- https://github.com/dotnet/runtime/issues/11360
-
-
- https://github.com/dotnet/runtime/issues/11360
-
-
- https://github.com/dotnet/runtime/issues/11360
-
-
- https://github.com/dotnet/runtime/issues/11360
-
-
- https://github.com/dotnet/runtime/issues/11360
-
-
- https://github.com/dotnet/runtime/issues/11360
-
-
- https://github.com/dotnet/runtime/issues/11360
-
-
- https://github.com/dotnet/runtime/issues/11360
-
-
- Native member function calling conventions not supported on Windows ARM32.
-
-
- Native member function calling conventions not supported on Windows ARM32.
-
-
- Native member function calling conventions not supported on Windows ARM32.
-
-
- Native member function calling conventions not supported on Windows ARM32.
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/67870
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- https://github.com/dotnet/runtime/issues/12979
-
-
- Allocates large contiguous array that is not consistently available on 32-bit platforms
-
-
- https://github.com/dotnet/runtime/issues/60152
-
-
- https://github.com/dotnet/runtime/issues/66745
-
-
- https://github.com/dotnet/runtime/issues/66745
-
-
- https://github.com/dotnet/runtime/issues/84750
-
-
- https://github.com/dotnet/runtime/issues/84750
-
-
- https://github.com/dotnet/runtime/issues/81241
-
-
-
diff --git a/src/tests/run.cmd b/src/tests/run.cmd
index 0c79426b6c437..bcd49e479e3f0 100644
--- a/src/tests/run.cmd
+++ b/src/tests/run.cmd
@@ -45,7 +45,6 @@ if /i "%1" == "-help" goto Usage
if /i "%1" == "x64" (set __BuildArch=x64&shift&goto Arg_Loop)
if /i "%1" == "x86" (set __BuildArch=x86&shift&goto Arg_Loop)
-if /i "%1" == "arm" (set __BuildArch=arm&shift&goto Arg_Loop)
if /i "%1" == "arm64" (set __BuildArch=arm64&shift&goto Arg_Loop)
if /i "%1" == "debug" (set __BuildType=Debug&shift&goto Arg_Loop)
@@ -200,7 +199,7 @@ echo.
echo where:
echo.
echo./? -? /h -h /help -help - View this message.
-echo ^ - Specifies build architecture: x64, x86, arm, or arm64 ^(default: x64^).
+echo ^ - Specifies build architecture: x64, x86, or arm64 ^(default: x64^).
echo ^ - Specifies build type: Debug, Release, or Checked ^(default: Debug^).
echo TestEnv ^ - Run a custom script before every test to set custom test environment settings.
echo sequential - Run tests sequentially ^(no parallelism^).