Skip to content

Commit

Permalink
[LoongArch64] coreclr-vm directory (#62885)
Browse files Browse the repository at this point in the history
* Part6-2: -add the coreclr-vm directory for LoongArch64. (#59561)

Co-authored-by: Loongson's .NET-teams

* [LoongArch64] revert the syncblk.cpp.

* [LoongArch64] delete some unused codes.

* [LoongArch64] add vm/CMakeLists.txt from #62889.

* [LoongArch64] add related files from #62886 and #62893.

* [LoongArch64] moved vm/jitinterface.cpp from #62893.
moved inc/corinfo.h from #6288.

* [LoongArch64] run the file `src/coreclr/tools/Common/JitInterface/ThunkGenerator/gen.sh`
and merge the patch from #62893.

* [LoongArch64] revert vm/ceeload.h.
amend the `ToolBox/superpmi/superpmi-shared/agnostic.h`

* [LoongArch64] add empty interfaces within `CorInfoImpl.cs`.

* [LoongArch64] Fix the compiling error on Windows.

* [LoongArch64] Fix the compiling error for memory unaligned m_currentByteStackIndex.

* [LoongArch64] Delete the !TARGET_LOONGARCH64 for m_currentByteStackIndex.

* [LoongArch64] move ToolBox from #62886.

* [LoongArch64] amend the args when needs unsigned extending within CallTargetWorker.

* [LoongArch64] add bool type for args' unsigned extention.

* [LoongArch64] adding char type for args' unsigned extention.
Also rename `TARGET_LOONGARCH64` to `UNIX_LOONGARCH64_ABI` within ABI.

* [LoongArch64] amend renaming `TARGET_LOONGARCH64` to `UNIX_LOONGARCH64_ABI` within ABI.

* [LoongArch64] remove the JIT/EE interface to #62893.

* [LoongArch64] revert the rename `TARGET_LOONGARCH64` to `UNIX_LOONGARCH64_ABI`.
Also add unsigned extend for CHAR type.

* [LoongArch64] refactor the `ArgDestination and ArgLocDesc`.

* [LoongArch64] rename the `m_flag` and `getFieldTypeByHnd`.

* [LoongArch64] add `NATIVE_SYMBOL_READER_DLL` for compiling error.

* [LoongArch64] update the version of the `LICENSE description`.

* [LoongArch64] keep same with the comment in `jit/targetloongarch64.h`

* [LoongArch64] amend the code for reviewing.

* [LoongArch64] refactor LoongArch64-ABI within `vm`,
and also amend some code for review.

* [LoongArch64] delete unused codes.

* [LoongArch64] merge main for #65869.

* [LoongArch64] amend the format for reviewing.

* [LoongArch64] delete some unused code for reviewing.

* [LoongArch64] amend code for CR feedback @jkotas @janvorli

* [LoongArch64] add class type for LoongArch64-ABI.

* [LoongArch64] Amend the LoongArch64's ABI
after merged `MethodTable::GetLoongArch64PassStructInRegisterFlags()`
and `CEEInfo::getLoongArch64PassStructInRegisterFlags()`

* [LoongArch64] Fix the assert error
when running hello-world within debug-mode after refacting.

Co-authored-by: qiaopengcheng <[email protected]>
  • Loading branch information
shushanhf and qiaopengcheng authored Apr 21, 2022
1 parent 2389815 commit febeba3
Show file tree
Hide file tree
Showing 57 changed files with 6,737 additions and 520 deletions.
8 changes: 0 additions & 8 deletions src/coreclr/inc/clrnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1069,14 +1069,6 @@ RtlVirtualUnwind(
IN OUT PKNONVOLATILE_CONTEXT_POINTERS ContextPointers OPTIONAL
);

#ifndef IMAGE_REL_LOONGARCH64_PC
#define IMAGE_REL_LOONGARCH64_PC 0x0003
#endif

#ifndef IMAGE_REL_LOONGARCH64_JIR
#define IMAGE_REL_LOONGARCH64_JIR 0x0004
#endif

#endif // TARGET_LOONGARCH64

#endif // CLRNT_H_
8 changes: 4 additions & 4 deletions src/coreclr/inc/eetwain.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ virtual bool UnwindStackFrame(PREGDISPLAY pContext,
virtual bool IsGcSafe(EECodeInfo *pCodeInfo,
DWORD dwRelOffset) = 0;

#if defined(TARGET_ARM) || defined(TARGET_ARM64)
#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
virtual bool HasTailCalls(EECodeInfo *pCodeInfo) = 0;
#endif // TARGET_ARM || TARGET_ARM64
#endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64

#if defined(TARGET_AMD64) && defined(_DEBUG)
/*
Expand Down Expand Up @@ -455,10 +455,10 @@ virtual
bool IsGcSafe( EECodeInfo *pCodeInfo,
DWORD dwRelOffset);

#if defined(TARGET_ARM) || defined(TARGET_ARM64)
#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
virtual
bool HasTailCalls(EECodeInfo *pCodeInfo);
#endif // TARGET_ARM || TARGET_ARM64
#endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64

#if defined(TARGET_AMD64) && defined(_DEBUG)
/*
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/inc/jithelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@

JITHELPER(CORINFO_HELP_GVMLOOKUP_FOR_SLOT, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)

#ifndef TARGET_ARM64
#if !defined(TARGET_ARM64) && !defined(TARGET_LOONGARCH64)
JITHELPER(CORINFO_HELP_STACK_PROBE, JIT_StackProbe, CORINFO_HELP_SIG_REG_ONLY)
#else
JITHELPER(CORINFO_HELP_STACK_PROBE, NULL, CORINFO_HELP_SIG_UNDEF)
Expand Down
14 changes: 14 additions & 0 deletions src/coreclr/inc/stdmacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,20 @@
#define NOT_ARM64_ARG(x) , x
#endif

#ifdef TARGET_LOONGARCH64
#define LOONGARCH64_FIRST_ARG(x) x ,
#define LOONGARCH64_ARG(x) , x
#define LOONGARCH64_ONLY(x) x
#define NOT_LOONGARCH64(x)
#define NOT_LOONGARCH64_ARG(x)
#else
#define LOONGARCH64_FIRST_ARG(x)
#define LOONGARCH64_ARG(x)
#define LOONGARCH64_ONLY(x)
#define NOT_LOONGARCH64(x) x
#define NOT_LOONGARCH64_ARG(x) , x
#endif

#ifdef TARGET_64BIT
#define LOG2_PTRSIZE 3
#else
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,11 @@ void CompileResult::applyRelocs(RelocContext* rc, unsigned char* block1, ULONG b
}
}

if (targetArch == SPMI_TARGET_ARCHITECTURE_LOONGARCH64)
{
Assert(!"FIXME: Not Implements on loongarch64");
}

if (IsSpmiTarget64Bit())
{
if (relocType == IMAGE_REL_BASED_DIR64)
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ static SPMI_TARGET_ARCHITECTURE SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTUR
static SPMI_TARGET_ARCHITECTURE SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_ARM;
#elif defined(TARGET_ARM64)
static SPMI_TARGET_ARCHITECTURE SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_ARM64;
#elif defined(TARGET_LOONGARCH64)
static SPMI_TARGET_ARCHITECTURE SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_LOONGARCH64;
#else
#error Unsupported architecture
#endif
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/tools/superpmi/superpmi-shared/spmiutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,16 @@ enum SPMI_TARGET_ARCHITECTURE
SPMI_TARGET_ARCHITECTURE_X86,
SPMI_TARGET_ARCHITECTURE_AMD64,
SPMI_TARGET_ARCHITECTURE_ARM64,
SPMI_TARGET_ARCHITECTURE_ARM
SPMI_TARGET_ARCHITECTURE_ARM,
SPMI_TARGET_ARCHITECTURE_LOONGARCH64
};

SPMI_TARGET_ARCHITECTURE GetSpmiTargetArchitecture();
void SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE spmiTargetArchitecture);

inline bool IsSpmiTarget64Bit()
{
return (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_AMD64) || (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_ARM64);
return (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_AMD64) || (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_ARM64) || (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_LOONGARCH64);
}

inline size_t SpmiTargetPointerSize()
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/tools/superpmi/superpmi/superpmi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ void SetSuperPmiTargetArchitecture(const char* targetArchitecture)
{
SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE_ARM64);
}
else if (0 == _stricmp(targetArchitecture, "loongarch64"))
{
SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE_LOONGARCH64);
}
else
{
LogError("Illegal target architecture '%s'", targetArchitecture);
Expand Down
23 changes: 23 additions & 0 deletions src/coreclr/vm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,14 @@ else(CLR_CMAKE_TARGET_WIN32)
${ARCH_SOURCES_DIR}/pinvokestubs.S
${ARCH_SOURCES_DIR}/thunktemplates.S
)
elseif(CLR_CMAKE_TARGET_ARCH_LOONGARCH64)
set(VM_SOURCES_WKS_ARCH_ASM
${ARCH_SOURCES_DIR}/asmhelpers.S
${ARCH_SOURCES_DIR}/calldescrworkerloongarch64.S
${ARCH_SOURCES_DIR}/crthelpers.S
${ARCH_SOURCES_DIR}/pinvokestubs.S
${ARCH_SOURCES_DIR}/thunktemplates.S
)
endif()

endif(CLR_CMAKE_TARGET_WIN32)
Expand Down Expand Up @@ -864,6 +872,21 @@ elseif(CLR_CMAKE_TARGET_ARCH_ARM64)
${ARCH_SOURCES_DIR}/arm64singlestepper.cpp
)
endif(CLR_CMAKE_HOST_UNIX)
elseif(CLR_CMAKE_TARGET_ARCH_LOONGARCH64)
set(VM_SOURCES_DAC_AND_WKS_ARCH
${ARCH_SOURCES_DIR}/stubs.cpp
exceptionhandling.cpp
)

set(VM_HEADERS_DAC_AND_WKS_ARCH
${ARCH_SOURCES_DIR}/virtualcallstubcpu.hpp
exceptionhandling.h
)

set(VM_SOURCES_WKS_ARCH
${ARCH_SOURCES_DIR}/profiler.cpp
gcinfodecoder.cpp
)
endif()

if(CLR_CMAKE_HOST_UNIX)
Expand Down
65 changes: 63 additions & 2 deletions src/coreclr/vm/argdestination.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ class ArgDestination
LIMITED_METHOD_CONTRACT;
#if defined(UNIX_AMD64_ABI)
_ASSERTE((argLocDescForStructInRegs != NULL) || (offset != TransitionBlock::StructInRegsOffset));
#elif defined(TARGET_ARM64)
// This assert is not interesting on arm64. argLocDescForStructInRegs could be
#elif defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
// This assert is not interesting on arm64/loongarch64. argLocDescForStructInRegs could be
// initialized if the args are being enregistered.
#else
_ASSERTE(argLocDescForStructInRegs == NULL);
Expand Down Expand Up @@ -83,6 +83,67 @@ class ArgDestination
#endif // !DACCESS_COMPILE
#endif // defined(TARGET_ARM64)

#if defined(TARGET_LOONGARCH64)
bool IsStructPassedInRegs()
{
return m_argLocDescForStructInRegs != NULL;
}

#ifndef DACCESS_COMPILE
void CopyStructToRegisters(void *src, int fieldBytes)
{
_ASSERTE(IsStructPassedInRegs());
_ASSERTE(fieldBytes <= 16);

int argOfs = TransitionBlock::GetOffsetOfFloatArgumentRegisters() + m_argLocDescForStructInRegs->m_idxFloatReg * 8;

if (m_argLocDescForStructInRegs->m_structFields == STRUCT_FLOAT_FIELD_ONLY_TWO)
{ // struct with two floats.
_ASSERTE(m_argLocDescForStructInRegs->m_cFloatReg == 2);
_ASSERTE(m_argLocDescForStructInRegs->m_cGenReg == 0);
*(INT64*)((char*)m_base + argOfs) = *(INT32*)src;
*(INT64*)((char*)m_base + argOfs + 8) = *((INT32*)src + 1);
}
else if ((m_argLocDescForStructInRegs->m_structFields & STRUCT_FLOAT_FIELD_FIRST) != 0)
{ // the first field is float or double.
if ((m_argLocDescForStructInRegs->m_structFields & STRUCT_FIRST_FIELD_SIZE_IS8) == 0)
*(INT64*)((char*)m_base + argOfs) = *(INT32*)src; // the first field is float
else
*(UINT64*)((char*)m_base + argOfs) = *(UINT64*)src; // the first field is double.
_ASSERTE(m_argLocDescForStructInRegs->m_cFloatReg == 1);
_ASSERTE(m_argLocDescForStructInRegs->m_cGenReg == 1);
_ASSERTE((m_argLocDescForStructInRegs->m_structFields & STRUCT_FLOAT_FIELD_SECOND) == 0);//the second field is integer.
argOfs = TransitionBlock::GetOffsetOfArgumentRegisters() + m_argLocDescForStructInRegs->m_idxGenReg * 8;
if ((m_argLocDescForStructInRegs->m_structFields & STRUCT_HAS_8BYTES_FIELDS_MASK) != 0)
*(UINT64*)((char*)m_base + argOfs) = *((UINT64*)src + 1);
else
*(INT64*)((char*)m_base + argOfs) = *((INT32*)src + 1); // the second field is int32.
}
else if ((m_argLocDescForStructInRegs->m_structFields & STRUCT_FLOAT_FIELD_SECOND) != 0)
{ // the second field is float or double.
*(UINT64*)((char*)m_base + argOfs) = *(UINT64*)src; // NOTE: here ignoring the first size.
if ((m_argLocDescForStructInRegs->m_structFields & STRUCT_HAS_8BYTES_FIELDS_MASK) == 0)
*(UINT64*)((char*)m_base + argOfs) = *((INT32*)src + 1); // the second field is int32.
else
*(UINT64*)((char*)m_base + argOfs) = *((UINT64*)src + 1);
_ASSERTE(m_argLocDescForStructInRegs->m_cFloatReg == 1);
_ASSERTE(m_argLocDescForStructInRegs->m_cGenReg == 1);
_ASSERTE((m_argLocDescForStructInRegs->m_structFields & STRUCT_FLOAT_FIELD_FIRST) == 0);//the first field is integer.
argOfs = TransitionBlock::GetOffsetOfArgumentRegisters() + m_argLocDescForStructInRegs->m_idxGenReg * 8;
}
else
_ASSERTE(!"---------UNReachable-------LoongArch64!!!");
}
#endif // !DACCESS_COMPILE

PTR_VOID GetStructGenRegDestinationAddress()
{
_ASSERTE(IsStructPassedInRegs());
int argOfs = TransitionBlock::GetOffsetOfArgumentRegisters() + m_argLocDescForStructInRegs->m_idxGenReg * 8;
return dac_cast<PTR_VOID>(dac_cast<TADDR>(m_base) + argOfs);
}
#endif // defined(TARGET_LOONGARCH64)

#if defined(UNIX_AMD64_ABI)

// Returns true if the ArgDestination represents a struct passed in registers.
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/callcounting.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ class CallCountingStub
static const int CodeSize = 40;
#elif defined(TARGET_ARM)
static const int CodeSize = 32;
#elif defined(TARGET_LOONGARCH64)
static const int CodeSize = 40;
#endif

private:
Expand Down
29 changes: 28 additions & 1 deletion src/coreclr/vm/callhelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,17 +462,44 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT *
argDest.CopyStructToRegisters(pSrc, th.AsMethodTable()->GetNumInstanceFieldBytes(), 0);
}
else
#endif // UNIX_AMD64_ABI
#elif defined(TARGET_LOONGARCH64)
if (argDest.IsStructPassedInRegs())
{
argDest.CopyStructToRegisters(pSrc, stackSize);
}
else
#endif // TARGET_LOONGARCH64
{
PVOID pDest = argDest.GetDestinationAddress();

switch (stackSize)
{
#if defined(TARGET_LOONGARCH64)
case 1:
if (m_argIt.GetArgType() == ELEMENT_TYPE_U1 || m_argIt.GetArgType() == ELEMENT_TYPE_BOOLEAN)
*((INT64*)pDest) = (UINT8)pArguments[arg];
else
*((INT64*)pDest) = (INT8)pArguments[arg];
break;
case 2:
if (m_argIt.GetArgType() == ELEMENT_TYPE_U2 || m_argIt.GetArgType() == ELEMENT_TYPE_CHAR)
*((INT64*)pDest) = (UINT16)pArguments[arg];
else
*((INT64*)pDest) = (INT16)pArguments[arg];
break;
case 4:
if (m_argIt.GetArgType() == ELEMENT_TYPE_U4)
*((INT64*)pDest) = (UINT32)pArguments[arg];
else
*((INT64*)pDest) = (INT32)pArguments[arg];
break;
#else
case 1:
case 2:
case 4:
*((INT32*)pDest) = (INT32)pArguments[arg];
break;
#endif

case 8:
*((INT64*)pDest) = pArguments[arg];
Expand Down
Loading

0 comments on commit febeba3

Please sign in to comment.