set(CMAKE_EXE_LINKER_FLAGS_CHECKED "")
set(CMAKE_SHARED_LINKER_FLAGS_CHECKED "")
-# Disable the following line for UNIX altjit on Windows
set(CMAKE_CXX_STANDARD_LIBRARIES "") # do not link against standard win32 libs i.e. kernel32, uuid, user32, etc.
if (WIN32)
# Linker flags
#
- # Disable the following line for UNIX altjit on Windows
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /MANIFEST:NO") #Do not create Side-by-Side Assembly Manifest
if (CLR_CMAKE_PLATFORM_ARCH_ARM)
clr_unknown_arch()
endif ()
-# Enable for UNIX altjit on Windows - set(CLR_CMAKE_PLATFORM_UNIX_AMD64 1)
-# Enable for UNIX altjit on Windows - add_definitions(-DCLR_CMAKE_PLATFORM_UNIX=1)
-
#--------------------------------------
# Compile Options
#--------------------------------------
add_definitions(-DFEATURE_MANAGED_ETW_CHANNELS)
if(FEATURE_MERGE_JIT_AND_ENGINE)
- # Disable the following for UNIX altjit on Windows
add_definitions(-DFEATURE_MERGE_JIT_AND_ENGINE)
endif(FEATURE_MERGE_JIT_AND_ENGINE)
add_definitions(-DFEATURE_MULTICOREJIT)
endif ()
add_definitions(-DFEATURE_SVR_GC)
add_definitions(-DFEATURE_SYMDIFF)
+if (CLR_CMAKE_PLATFORM_ARCH_AMD64)
+ # Enable the AMD64 Unix struct passing JIT-EE interface for all AMD64 platforms, to enable altjit.
+ add_definitions(-DFEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
+endif (CLR_CMAKE_PLATFORM_ARCH_AMD64)
if(CLR_CMAKE_PLATFORM_UNIX_AMD64)
add_definitions(-DFEATURE_MULTIREG_RETURN)
add_definitions(-DFEATURE_UNIX_AMD64_STRUCT_PASSING)
- add_definitions(-DFEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
endif (CLR_CMAKE_PLATFORM_UNIX_AMD64)
add_definitions(-DFEATURE_USE_ASM_GC_WRITE_BARRIERS)
if(CLR_CMAKE_PLATFORM_ARCH_AMD64 AND NOT WIN32)
#if defined(FEATURE_HFA)
MTFLAG_ENTRY(IsHFA),
#endif // FEATURE_HFA
-#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
MTFLAG_ENTRY(IsRegStructPassed),
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
MTFLAG_ENTRY(IsByRefLike),
MTFLAG_ENTRY(UNUSED_ComponentSize_5),
MTFLAG_ENTRY(UNUSED_ComponentSize_6),
include_directories("./jitstd")
include_directories("../inc")
-# Enable the following for UNIX altjit on Windows
-# add_definitions(-DALT_JIT)
-
if (CLR_CMAKE_TARGET_ARCH_AMD64 OR (CLR_CMAKE_TARGET_ARCH_I386 AND NOT CLR_CMAKE_PLATFORM_UNIX))
add_definitions(-DFEATURE_SIMD)
add_definitions(-DFEATURE_AVX_SUPPORT)
# On x86, build RyuJIT/ARM32 cross-compiling altjit.
# On amd64, build RyuJIT/ARM64 cross-compiling altjit.
add_subdirectory(protononjit)
+
+ # Build Linux/x86-running-on-Windows altjit or
+ # Linux/AMD64-running-on-Windows altjit..
+ add_subdirectory(linuxnonjit)
endif ()
if (CLR_CMAKE_PLATFORM_ARCH_I386 AND WIN32)
addrInfo.addr,
0, // argSize
EA_UNKNOWN // retSize
- FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(EA_UNKNOWN), // secondRetSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(EA_UNKNOWN), // secondRetSize
gcInfo.gcVarPtrSetCur,
gcInfo.gcRegGCrefSetCur,
gcInfo.gcRegByrefSetCur,
void genPutStructArgStk(GenTreePutArgStk* treeNode);
-int genMove8IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
-int genMove4IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
-int genMove2IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
-int genMove1IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
+unsigned genMove8IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
+unsigned genMove4IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
+unsigned genMove2IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
+unsigned genMove1IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
void genStructPutArgRepMovs(GenTreePutArgStk* putArgStkNode);
void genStructPutArgUnroll(GenTreePutArgStk* putArgStkNode);
void genStoreRegToStackArg(var_types type, regNumber reg, int offset);
// On x86, longTmpReg must be an xmm reg; on x64 it must be an integer register.
// This is checked by genStoreRegToStackArg.
//
-int CodeGen::genMove8IfNeeded(unsigned size, regNumber longTmpReg, GenTree* srcAddr, unsigned offset)
+unsigned CodeGen::genMove8IfNeeded(unsigned size, regNumber longTmpReg, GenTree* srcAddr, unsigned offset)
{
#ifdef _TARGET_X86_
instruction longMovIns = INS_movq;
// intTmpReg must be an integer register.
// This is checked by genStoreRegToStackArg.
//
-int CodeGen::genMove4IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
+unsigned CodeGen::genMove4IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
{
if ((size & 4) != 0)
{
// intTmpReg must be an integer register.
// This is checked by genStoreRegToStackArg.
//
-int CodeGen::genMove2IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
+unsigned CodeGen::genMove2IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
{
if ((size & 2) != 0)
{
// intTmpReg must be an integer register.
// This is checked by genStoreRegToStackArg.
//
-int CodeGen::genMove1IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
+unsigned CodeGen::genMove1IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
{
if ((size & 1) != 0)
GenTreePtr dstAddr = putArgNode;
GenTreePtr src = putArgNode->gtOp.gtOp1;
- size_t size = putArgNode->getArgSize();
+ unsigned size = putArgNode->getArgSize();
assert(size <= CPBLK_UNROLL_LIMIT);
emitter* emit = getEmitter();
{
int delta;
-#ifdef PLATFORM_UNIX
+#ifdef UNIX_AMD64_ABI
// We require frame chaining on Unix to support native tool unwinding (such as
// unwinding by the native debugger). We have a CLR-only extension to the
// If Unix ever supports EnC, the RSP == RBP assumption will have to be reevaluated.
delta = genTotalFrameSize();
-#else // !PLATFORM_UNIX
+#else // !UNIX_AMD64_ABI
// As per Amd64 ABI, RBP offset from initial RSP can be between 0 and 240 if
// RBP needs to be reported in unwind codes. This case would arise for methods
delta = genTotalFrameSize();
}
-#endif // !PLATFORM_UNIX
+#endif // !UNIX_AMD64_ABI
return delta;
}
INDEBUG_LDISASM_COMMA(nullptr) addr,
argSize,
retSize
- FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(EA_UNKNOWN),
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(EA_UNKNOWN),
gcInfo.gcVarPtrSetCur,
gcInfo.gcRegGCrefSetCur,
gcInfo.gcRegByrefSetCur,
// with an ARM-targeting "altjit").
info.compMatchedVM = IMAGE_FILE_MACHINE_TARGET == info.compCompHnd->getExpectedTargetArchitecture();
-#if defined(ALT_JIT) && defined(UNIX_AMD64_ABI)
- // ToDo: This code is to allow us to run UNIX codegen on Windows for now. Remove when appropriate.
- // Make sure that the generated UNIX altjit code is skipped on Windows. The static jit codegen is used to run.
+#if (defined(_TARGET_UNIX_) && !defined(_HOST_UNIX_)) || (!defined(_TARGET_UNIX_) && defined(_HOST_UNIX_))
+ // The host and target platforms don't match. This info isn't handled by the existing
+ // getExpectedTargetArchitecture() JIT-EE interface method.
info.compMatchedVM = false;
-#endif // UNIX_AMD64_ABI
+#endif
#if COR_JIT_EE_VERSION > 460
compMaxUncheckedOffsetForNullObject = eeGetEEInfo()->maxUncheckedOffsetForNullObject;
{
if (compJitHaltMethod())
{
-#if !defined(_TARGET_ARM64_) && !defined(PLATFORM_UNIX)
+#if !defined(_TARGET_ARM64_) && !defined(_HOST_UNIX_)
// TODO-ARM64-NYI: re-enable this when we have an OS that supports a pop-up dialog
// Don't do an assert, but just put up the dialog box so we get just-in-time debugger
add_definitions(-DLEGACY_BACKEND)
endif(CLR_CMAKE_TARGET_ARCH_ARM)
-# Disable the following for UNIX altjit on Windows
if(CLR_CMAKE_PLATFORM_UNIX)
add_compile_options(-fPIC)
${SHARED_LIB_SOURCES}
${JIT_ARCH_SOURCES}
)
-# Disable up to here (see above) the following for UNIX altjit on Windows
-# Enable the following for UNIX altjit on Windows
-# add_library_clr(ClrJit
-# SHARED
-# ${SHARED_LIB_SOURCES}
-# )
-
-# Enable the following for UNIX altjit on Windows
-#target_link_libraries(ClrJit
-# utilcode
-# gcinfo
-# runtime_library
-# )
-
-# Disable the following for UNIX altjit on Windows
endif(CLR_CMAKE_PLATFORM_UNIX)
#include "emit.h"
#include "corexcep.h"
-#if !defined(PLATFORM_UNIX)
+#if !defined(_HOST_UNIX_)
#include <io.h> // For _dup, _setmode
#include <fcntl.h> // For _O_TEXT
#include <errno.h> // For EINVAL
assert(!JitConfig.isInitialized());
JitConfig.initialize(jitHost);
-#if defined(PLATFORM_UNIX)
+#if defined(_HOST_UNIX_)
jitstdout = procstdout();
-#else
+#else // !_HOST_UNIX_
if (jitstdout == nullptr)
{
int stdoutFd = _fileno(procstdout());
{
jitstdout = procstdout();
}
-#endif // PLATFORM_UNIX
+#endif // !_HOST_UNIX_
#ifdef FEATURE_TRACELOGGING
JitTelemetry::NotifyDllProcessAttach();
if (EBPbased)
{
-#if defined(_TARGET_AMD64_) && !defined(PLATFORM_UNIX)
+#if defined(_TARGET_AMD64_) && !defined(UNIX_AMD64_ABI)
// If localloc is not used, then ebp chaining is done and hence
// offset of locals will be at negative offsets, Otherwise offsets
// will be positive. In future, when RBP gets positioned in the
#define _TARGET_ARMARCH_
#endif
+// If the UNIX_AMD64_ABI is defined make sure that _TARGET_AMD64_ is also defined.
+#if defined(UNIX_AMD64_ABI)
+#if !defined(_TARGET_AMD64_)
+#error When UNIX_AMD64_ABI is defined you must define _TARGET_AMD64_ defined as well.
+#endif
+#endif
+
+// If the UNIX_X86_ABI is defined make sure that _TARGET_X86_ is also defined.
+#if defined(UNIX_X86_ABI)
+#if !defined(_TARGET_X86_)
+#error When UNIX_X86_ABI is defined you must define _TARGET_X86_ defined as well.
+#endif
+#endif
+
+#if defined(PLATFORM_UNIX)
+#define _HOST_UNIX_
+#endif
+
+// Are we generating code to target Unix? This is true if we will run on Unix (_HOST_UNIX_ is defined).
+// It's also true if we are building an altjit targetting Unix, which we determine by checking if either
+// UNIX_AMD64_ABI or UNIX_X86_ABI is defined.
+#if defined(_HOST_UNIX_) || ((defined(UNIX_AMD64_ABI) || defined(UNIX_X86_ABI)) && defined(ALT_JIT))
+#define _TARGET_UNIX_
+#endif
+
// --------------------------------------------------------------------------------
// IMAGE_FILE_MACHINE_TARGET
// --------------------------------------------------------------------------------
// Include the AMD64 unwind codes when appropriate.
#if defined(_TARGET_AMD64_)
+// We need to temporarily set PLATFORM_UNIX, if necessary, to get the Unix-specific unwind codes.
+#if defined(_TARGET_UNIX_) && !defined(_HOST_UNIX_)
+#define PLATFORM_UNIX
+#endif
#include "win64unwind.h"
+#if defined(_TARGET_UNIX_) && !defined(_HOST_UNIX_)
+#undef PLATFORM_UNIX
+#endif
#endif
// Macros for defining strongly-typed enums. Use as follows:
typedef unsigned int type;
};
-#ifndef PLATFORM_UNIX
+#ifndef _HOST_UNIX_
template<>
struct make_unsigned<long>
{
typedef unsigned long type;
};
-#endif // PLATFORM_UNIX
+
+#endif // !_HOST_UNIX_
template<>
struct make_unsigned<__int64>
--- /dev/null
+project(linuxnonjit)
+
+add_definitions(-DALT_JIT)
+add_definitions(-DFEATURE_NO_HOST)
+add_definitions(-DSELF_NO_HOST)
+add_definitions(-DFEATURE_READYTORUN_COMPILER)
+remove_definitions(-DFEATURE_MERGE_JIT_AND_ENGINE)
+
+if (CLR_CMAKE_PLATFORM_ARCH_I386)
+ remove_definitions(-DFEATURE_SIMD)
+ remove_definitions(-DFEATURE_AVX_SUPPORT)
+ add_definitions(-DUNIX_X86_ABI)
+ set(JIT_ARCH_ALTJIT_SOURCES ${JIT_I386_SOURCES})
+elseif(CLR_CMAKE_PLATFORM_ARCH_AMD64)
+ add_definitions(-DUNIX_AMD64_ABI)
+ add_definitions(-DFEATURE_UNIX_AMD64_STRUCT_PASSING)
+ set(JIT_ARCH_ALTJIT_SOURCES ${JIT_AMD64_SOURCES})
+else()
+ clr_unknown_arch()
+endif()
+
+if(WIN32)
+ add_definitions(-DFX_VER_INTERNALNAME_STR=linuxnonjit.dll)
+endif(WIN32)
+
+add_library_clr(linuxnonjit
+ SHARED
+ ${SHARED_LIB_SOURCES}
+ ${JIT_ARCH_ALTJIT_SOURCES}
+)
+
+add_dependencies(linuxnonjit jit_exports)
+
+set_property(TARGET linuxnonjit APPEND_STRING PROPERTY LINK_FLAGS ${JIT_EXPORTS_LINKER_OPTION})
+set_property(TARGET linuxnonjit APPEND_STRING PROPERTY LINK_DEPENDS ${JIT_EXPORTS_FILE})
+
+set(RYUJIT_LINK_LIBRARIES
+ utilcodestaticnohost
+ gcinfo
+)
+
+if(CLR_CMAKE_PLATFORM_UNIX)
+ list(APPEND RYUJIT_LINK_LIBRARIES
+ mscorrc_debug
+ coreclrpal
+ palrt
+ )
+else()
+ list(APPEND RYUJIT_LINK_LIBRARIES
+ ${STATIC_MT_CRT_LIB}
+ ${STATIC_MT_VCRT_LIB}
+ kernel32.lib
+ advapi32.lib
+ ole32.lib
+ oleaut32.lib
+ uuid.lib
+ user32.lib
+ version.lib
+ shlwapi.lib
+ bcrypt.lib
+ crypt32.lib
+ RuntimeObject.lib
+ )
+endif(CLR_CMAKE_PLATFORM_UNIX)
+
+target_link_libraries(linuxnonjit
+ ${RYUJIT_LINK_LIBRARIES}
+)
+
+# add the install targets
+install_clr(linuxnonjit)
#ifndef _TARGET_H_
#define _TARGET_H_
-// If the UNIX_AMD64_ABI is defined make sure that _TARGET_AMD64_ is also defined.
-#if defined(UNIX_AMD64_ABI)
-#if !defined(_TARGET_AMD64_)
-#error When UNIX_AMD64_ABI is defined you must define _TARGET_AMD64_ defined as well.
-#endif
-#endif
-
-// If the UNIX_X86_ABI is defined make sure that _TARGET_X86_ is also defined.
-#if defined(UNIX_X86_ABI)
-#if !defined(_TARGET_X86_)
-#error When UNIX_X86_ABI is defined you must define _TARGET_X86_ defined as well.
-#endif
-#endif
-
-#if (defined(FEATURE_CORECLR) && defined(PLATFORM_UNIX))
+#if defined(FEATURE_CORECLR) && defined(_TARGET_UNIX_)
#define FEATURE_VARARG 0
-#else // !(defined(FEATURE_CORECLR) && defined(PLATFORM_UNIX))
+#else // !(defined(FEATURE_CORECLR) && defined(_TARGET_UNIX_))
#define FEATURE_VARARG 1
-#endif // !(defined(FEATURE_CORECLR) && defined(PLATFORM_UNIX))
+#endif // !(defined(FEATURE_CORECLR) && defined(_TARGET_UNIX_))
/*****************************************************************************/
// The following are human readable names for the target architectures
func->unwindHeader.FrameRegister = (BYTE)reg;
-#ifdef PLATFORM_UNIX
+#ifdef UNIX_AMD64_ABI
if (offset > 240)
{
// On Unix only, we have a CLR-only extension to the AMD64 unwind codes: UWOP_SET_FPREG_LARGE.
func->unwindHeader.FrameOffset = 15;
}
else
-#endif // PLATFORM_UNIX
+#endif // UNIX_AMD64_ABI
{
assert(func->unwindCodeSlot > sizeof(UNWIND_CODE));
UNWIND_CODE* code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo); // This should be zero
break;
-#ifdef PLATFORM_UNIX
+#ifdef UNIX_AMD64_ABI
case UWOP_SET_FPREG_LARGE:
printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SET_FPREG_LARGE (%u) OpInfo: Unused (%u)\n",
}
break;
-#endif // PLATFORM_UNIX
+#endif // UNIX_AMD64_ABI
case UWOP_SAVE_NONVOL:
printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SAVE_NONVOL (%u) OpInfo: %s (%u)\n",
#ifdef UNIX_AMD64_ABI
if (generateCFIUnwindCodes())
{
- unwindCodeBytes = func->cfiCodes->size() * sizeof(CFI_CODE);
+ unwindCodeBytes = (DWORD)(func->cfiCodes->size() * sizeof(CFI_CODE));
}
else
#endif // UNIX_AMD64_ABI
#ifdef UNIX_AMD64_ABI
if (generateCFIUnwindCodes())
{
- int size = func->cfiCodes->size();
+ DWORD size = (DWORD)func->cfiCodes->size();
if (size > 0)
{
unwindCodeBytes = size * sizeof(CFI_CODE);
// same code for all platforms, hence it is here instead of in the targetXXX.cpp
// files.
-#ifdef PLATFORM_UNIX
+#ifdef _TARGET_UNIX_
// Should we distinguish Mac? Can we?
// Should we distinguish flavors of Unix? Can we?
const char* Target::g_tgtPlatformName = "Unix";
-#else // !PLATFORM_UNIX
+#else // !_TARGET_UNIX_
const char* Target::g_tgtPlatformName = "Windows";
-#endif // !PLATFORM_UNIX
+#endif // !_TARGET_UNIX_
/*****************************************************************************/
__fallthrough;
case TYP_BYREF:
-#ifndef PLATFORM_UNIX
+
+#ifdef _MSC_VER
+
assert(&typeid(T) == &typeid(size_t)); // We represent ref/byref constants as size_t's.
-#endif // PLATFORM_UNIX
+
+#endif // _MSC_VER
+
__fallthrough;
case TYP_INT:
#ifdef _DEBUG
{
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
// Validate that the return value is not too big for the buffer passed
if (m_pMD->GetMethodTable()->IsRegPassedStruct())
{
_ASSERTE(cbReturnValue >= thReturnValueType.GetSize());
}
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
// The metasig should be reset
_ASSERTE(m_methodSig.GetArgNum() == 0);
e_ZERO_SIZED = 0x04,
// The size of the struct is explicitly specified in the meta-data.
e_HAS_EXPLICIT_SIZE = 0x08,
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
-#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF defined at the same time.
+#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING defined at the same time.
#endif // FEATURE_HFA
e_NATIVE_PASS_IN_REGISTERS = 0x10, // Flag wheter a native struct is passed in registers.
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
// HFA type of the unmanaged layout
e_R4_HFA = 0x10,
return m_cbPackingSize;
}
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
bool IsNativeStructPassedInRegisters()
{
LIMITED_METHOD_CONTRACT;
return (m_bFlags & e_NATIVE_PASS_IN_REGISTERS) != 0;
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
bool IsNativeHFA()
m_bFlags |= (hfaType == ELEMENT_TYPE_R4) ? e_R4_HFA : e_R8_HFA;
}
#endif
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
void SetNativeStructPassedInRegisters()
{
LIMITED_METHOD_CONTRACT;
m_bFlags |= e_NATIVE_PASS_IN_REGISTERS;
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
};
}
_ASSERTE(methodTablePtr != nullptr);
+ // If we have full support for FEATURE_UNIX_AMD64_STRUCT_PASSING, and not just the interface,
+ // then we've cached whether this is a reg passed struct in the MethodTable, computed during
+ // MethodTable construction. Otherwise, we are just building in the interface, and we haven't
+ // computed or cached anything, so we need to compute it now.
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
bool canPassInRegisters = useNativeLayout ? methodTablePtr->GetLayoutInfo()->IsNativeStructPassedInRegisters()
- : methodTablePtr->IsRegPassedStruct();
+ : methodTablePtr->IsRegPassedStruct();
+#else // !defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+ SystemVStructRegisterPassingHelper helper((unsigned int)th.GetSize());
+ bool canPassInRegisters = methodTablePtr->ClassifyEightBytes(&helper, 0, 0, useNativeLayout);
+#endif // !defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+
if (canPassInRegisters)
{
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
SystemVStructRegisterPassingHelper helper((unsigned int)th.GetSize());
bool result = methodTablePtr->ClassifyEightBytes(&helper, 0, 0, useNativeLayout);
// The answer must be true at this point.
_ASSERTE(result);
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+
structPassInRegDescPtr->passedInRegisters = true;
structPassInRegDescPtr->eightByteCount = helper.eightByteCount;
}
// Assigns the classification types to the array with eightbyte types.
-void MethodTable::AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel)
+void MethodTable::AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel) const
{
static const size_t CLR_SYSTEMV_MAX_BYTES_TO_PASS_IN_REGISTERS = CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS * SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES;
static_assert_no_msg(CLR_SYSTEMV_MAX_BYTES_TO_PASS_IN_REGISTERS == SYSTEMV_MAX_NUM_FIELDS_IN_REGISTER_PASSED_STRUCT);
private:
#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
- void AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel);
+ void AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel) const;
// Builds the internal data structures and classifies struct eightbytes for Amd System V calling convention.
bool ClassifyEightBytesWithManagedLayout(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel, unsigned int startOffsetOfStruct, bool isNativeStruct);
bool ClassifyEightBytesWithNativeLayout(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel, unsigned int startOffsetOfStruct, bool isNativeStruct);
}
#endif // FEATURE_HFA
-#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
inline bool IsRegPassedStruct()
{
LIMITED_METHOD_CONTRACT;
LIMITED_METHOD_CONTRACT;
SetFlag(enum_flag_IsRegStructPassed);
}
-#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
+#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
#ifdef FEATURE_HFA
enum_flag_HasPreciseInitCctors = 0x00000400, // Do we need to run class constructors at allocation time? (Not perf important, could be moved to EEClass
#if defined(FEATURE_HFA)
-#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
-#error Can't define both FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+#error Can't define both FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING
#endif
enum_flag_IsHFA = 0x00000800, // This type is an HFA (Homogenous Floating-point Aggregate)
#endif // FEATURE_HFA
-#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
#if defined(FEATURE_HFA)
-#error Can't define both FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#error Can't define both FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING
#endif
enum_flag_IsRegStructPassed = 0x00000800, // This type is a System V register passed struct.
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
enum_flag_IsByRefLike = 0x00001000,
#ifdef FEATURE_HFA
CheckForHFA(pByValueClassCache);
#endif
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
-#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF defined at the same time.
+#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING defined at the same time.
#endif // FEATURE_HFA
SystemVAmd64CheckForPassStructInRegister();
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
}
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
-#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF defined at the same time.
+#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING defined at the same time.
#endif // FEATURE_HFA
if (HasLayout())
{
SystemVAmd64CheckForPassNativeStructInRegister();
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
if (HasLayout())
{
return (1 << (DWORD)(DWORD_PTR&)(pFD->m_pMTOfEnclosingClass));
}
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
// checks whether the struct is enregisterable.
void MethodTableBuilder::SystemVAmd64CheckForPassStructInRegister()
{
eeClass->SetEightByteClassification(helper->eightByteCount, helper->eightByteClassifications, helper->eightByteSizes);
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
//---------------------------------------------------------------------------------------
VOID CheckForNativeHFA();
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
// checks whether the struct is enregisterable.
void SystemVAmd64CheckForPassStructInRegister();
void SystemVAmd64CheckForPassNativeStructInRegister();
// Store the eightbyte classification into the EEClass
void StoreEightByteClassification(SystemVStructRegisterPassingHelper* helper);
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
// this accesses the field size which is temporarily stored in m_pMTOfEnclosingClass
// during class loading. Don't use any other time