1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4// CGENSYS.H -
5//
6// Generic header for choosing system-dependent helpers
7//
8
9
10
11#ifndef __cgensys_h__
12#define __cgensys_h__
13
14class MethodDesc;
15class Stub;
16class Thread;
17class CrawlFrame;
18struct EE_ILEXCEPTION_CLAUSE;
19struct TransitionBlock;
20struct VASigCookie;
21struct CORCOMPILE_EXTERNAL_METHOD_THUNK;
22class ComPlusCallMethodDesc;
23
24#include <cgencpu.h>
25
26
27#ifdef EnC_SUPPORTED
28void ResumeAtJit(PT_CONTEXT pContext, LPVOID oldFP);
29#endif
30
31#if defined(_TARGET_X86_)
32void ResumeAtJitEH (CrawlFrame* pCf, BYTE* startPC, EE_ILEXCEPTION_CLAUSE *EHClausePtr, DWORD nestingLevel, Thread *pThread, BOOL unwindStack);
33int CallJitEHFilter (CrawlFrame* pCf, BYTE* startPC, EE_ILEXCEPTION_CLAUSE *EHClausePtr, DWORD nestingLevel, OBJECTREF thrownObj);
34void CallJitEHFinally(CrawlFrame* pCf, BYTE* startPC, EE_ILEXCEPTION_CLAUSE *EHClausePtr, DWORD nestingLevel);
35#endif // _TARGET_X86_
36
37//These are in util.cpp
38extern size_t GetLogicalProcessorCacheSizeFromOS();
39extern size_t GetIntelDeterministicCacheEnum();
40extern size_t GetIntelDescriptorValuesCache();
41extern DWORD GetLogicalCpuCountFromOS();
42extern DWORD GetLogicalCpuCountFallback();
43
44
45// Try to determine the largest last-level cache size of the machine - return 0 if unknown or no L2/L3 cache
46size_t GetCacheSizePerLogicalCpu(BOOL bTrueSize = TRUE);
47
48
49#ifdef FEATURE_COMINTEROP
50extern "C" UINT32 STDCALL CLRToCOMWorker(TransitionBlock * pTransitionBlock, ComPlusCallMethodDesc * pMD);
51extern "C" void GenericComPlusCallStub(void);
52
53extern "C" void GenericComCallStub(void);
54#endif // FEATURE_COMINTEROP
55
56// Non-CPU-specific helper functions called by the CPU-dependent code
57extern "C" PCODE STDCALL PreStubWorker(TransitionBlock * pTransitionBlock, MethodDesc * pMD);
58
59extern "C" void STDCALL VarargPInvokeStubWorker(TransitionBlock * pTransitionBlock, VASigCookie * pVASigCookie, MethodDesc * pMD);
60extern "C" void STDCALL VarargPInvokeStub(void);
61extern "C" void STDCALL VarargPInvokeStub_RetBuffArg(void);
62
63extern "C" void STDCALL GenericPInvokeCalliStubWorker(TransitionBlock * pTransitionBlock, VASigCookie * pVASigCookie, PCODE pUnmanagedTarget);
64extern "C" void STDCALL GenericPInvokeCalliHelper(void);
65
66extern "C" PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBlock, TADDR pIndirection, DWORD sectionIndex, Module * pModule);
67extern "C" void STDCALL ExternalMethodFixupStub(void);
68extern "C" void STDCALL ExternalMethodFixupPatchLabel(void);
69
70extern "C" void STDCALL VirtualMethodFixupStub(void);
71extern "C" void STDCALL VirtualMethodFixupPatchLabel(void);
72
73extern "C" void STDCALL TransparentProxyStub(void);
74extern "C" void STDCALL TransparentProxyStub_CrossContext();
75extern "C" void STDCALL TransparentProxyStubPatchLabel(void);
76
77#ifdef FEATURE_READYTORUN
78extern "C" void STDCALL DelayLoad_MethodCall();
79
80extern "C" void STDCALL DelayLoad_Helper();
81extern "C" void STDCALL DelayLoad_Helper_Obj();
82extern "C" void STDCALL DelayLoad_Helper_ObjObj();
83#endif
84
85// Returns information about the CPU processor.
86// Note that this information may be the least-common-denominator in the
87// case of a multi-proc machine.
88
89#ifdef _TARGET_X86_
90void GetSpecificCpuInfo(CORINFO_CPU * cpuInfo);
91#else
92inline void GetSpecificCpuInfo(CORINFO_CPU * cpuInfo)
93{
94 LIMITED_METHOD_CONTRACT;
95 cpuInfo->dwCPUType = 0;
96 cpuInfo->dwFeatures = 0;
97 cpuInfo->dwExtendedFeatures = 0;
98}
99
100#endif // !_TARGET_X86_
101
102#if (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && !defined(CROSSGEN_COMPILE)
103extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]);
104extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]);
105extern "C" DWORD __stdcall xmmYmmStateSupport();
106#endif
107
108inline bool TargetHasAVXSupport()
109{
110#if (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && !defined(CROSSGEN_COMPILE)
111 unsigned char buffer[16];
112 // All x86/AMD64 targets support cpuid.
113 (void) getcpuid(1, buffer);
114 // getcpuid executes cpuid with eax set to its first argument, and ecx cleared.
115 // It returns the resulting eax, ebx, ecx and edx (in that order) in buffer[].
116 // The AVX feature is ECX bit 28.
117 return ((buffer[11] & 0x10) != 0);
118#endif // (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && !defined(CROSSGEN_COMPILE)
119 return false;
120}
121
122#ifdef FEATURE_PREJIT
123// Can code compiled for "minReqdCpuType" be used on "actualCpuType"
124inline BOOL IsCompatibleCpuInfo(const CORINFO_CPU * actualCpuInfo,
125 const CORINFO_CPU * minReqdCpuInfo)
126{
127 LIMITED_METHOD_CONTRACT;
128 return ((minReqdCpuInfo->dwFeatures & actualCpuInfo->dwFeatures) ==
129 minReqdCpuInfo->dwFeatures);
130}
131#endif // FEATURE_PREJIT
132
133
134#ifndef DACCESS_COMPILE
135// Given an address in a slot, figure out if the prestub will be called
136BOOL DoesSlotCallPrestub(PCODE pCode);
137#endif
138
139#ifdef DACCESS_COMPILE
140
141// Used by dac/strike to make sense of non-jit/non-jit-helper call targets
142// generated by the runtime.
143BOOL GetAnyThunkTarget (T_CONTEXT *pctx, TADDR *pTarget, TADDR *pTargetMethodDesc);
144
145#endif // DACCESS_COMPILE
146
147
148
149//
150// ResetProcessorStateHolder saves/restores processor state around calls to
151// mscorlib during exception handling.
152//
153class ResetProcessorStateHolder
154{
155#if defined(_TARGET_AMD64_)
156 ULONG m_mxcsr;
157#endif
158
159public:
160
161 ResetProcessorStateHolder ()
162 {
163#if defined(_TARGET_AMD64_)
164 m_mxcsr = _mm_getcsr();
165 _mm_setcsr(0x1f80);
166#endif // _TARGET_AMD64_
167 }
168
169 ~ResetProcessorStateHolder ()
170 {
171#if defined(_TARGET_AMD64_)
172 _mm_setcsr(m_mxcsr);
173#endif // _TARGET_AMD64_
174 }
175};
176
177
178#endif // !__cgensys_h__
179