Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LoongArch64] coreclr-vm directory #62885

Merged
merged 49 commits into from
Apr 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
47d106f
Merge pull request #1 from dotnet/main
shushanhf Apr 27, 2021
411b59e
Merge branch 'dotnet:main' into master
shushanhf Oct 25, 2021
7eed4eb
Merge branch 'dotnet:main' into master
shushanhf Dec 6, 2021
0d7c9e4
Merge branch 'dotnet:main' into master
shushanhf Dec 10, 2021
2c534c5
Merge branch 'dotnet:main' into master
shushanhf Dec 14, 2021
6e14d76
Merge branch 'dotnet:main' into master
shushanhf Dec 15, 2021
359875d
Merge branch 'dotnet:main' into master
shushanhf Dec 15, 2021
192b095
Merge branch 'dotnet:main' into main
shushanhf Dec 16, 2021
8a9d654
Part6-2: -add the coreclr-vm directory for LoongArch64. (#59561)
shushanhf Dec 15, 2021
4606899
[LoongArch64] revert the syncblk.cpp.
Dec 17, 2021
e62a6cd
[LoongArch64] delete some unused codes.
Dec 18, 2021
cdb7606
[LoongArch64] add vm/CMakeLists.txt from #62889.
Dec 18, 2021
ad3b666
[LoongArch64] add related files from #62886 and #62893.
Dec 20, 2021
7d03307
[LoongArch64] moved vm/jitinterface.cpp from #62893.
Dec 20, 2021
f6ec562
[LoongArch64] run the file `src/coreclr/tools/Common/JitInterface/Thu…
shushanhf Dec 20, 2021
277de6f
[LoongArch64] revert vm/ceeload.h.
shushanhf Dec 20, 2021
d6dabd7
[LoongArch64] add empty interfaces within `CorInfoImpl.cs`.
Dec 21, 2021
63073dc
[LoongArch64] Fix the compiling error on Windows.
Dec 21, 2021
6aa5e1a
[LoongArch64] Fix the compiling error for memory unaligned m_currentB…
Dec 21, 2021
3e3c3b3
[LoongArch64] Delete the !TARGET_LOONGARCH64 for m_currentByteStackIn…
Dec 22, 2021
55eeb95
[LoongArch64] move ToolBox from #62886.
Dec 22, 2021
21040b8
[LoongArch64] amend the args when needs unsigned extending within Cal…
Dec 23, 2021
19e4357
[LoongArch64] add bool type for args' unsigned extention.
Dec 24, 2021
743c518
[LoongArch64] adding char type for args' unsigned extention.
Dec 24, 2021
cb91556
[LoongArch64] amend renaming `TARGET_LOONGARCH64` to `UNIX_LOONGARCH6…
Dec 24, 2021
1f790f4
[LoongArch64] remove the JIT/EE interface to #62893.
Dec 24, 2021
42fd640
[LoongArch64] revert the rename `TARGET_LOONGARCH64` to `UNIX_LOONGAR…
shushanhf Dec 25, 2021
7757e09
[LoongArch64] refactor the `ArgDestination and ArgLocDesc`.
Jan 7, 2022
ba9fba0
Merge branch 'main' into main_loongarch64_2
shushanhf Jan 12, 2022
86d4546
[LoongArch64] rename the `m_flag` and `getFieldTypeByHnd`.
shushanhf Jan 13, 2022
56b0a79
[LoongArch64] add `NATIVE_SYMBOL_READER_DLL` for compiling error.
shushanhf Jan 14, 2022
5798329
[LoongArch64] update the version of the `LICENSE description`.
Jan 19, 2022
c747f93
Merge branch 'main' into main_loongarch64_2
Feb 15, 2022
48b4734
[LoongArch64] keep same with the comment in `jit/targetloongarch64.h`
Feb 16, 2022
a96f159
Merge branch 'main' into main_loongarch64_2
Feb 18, 2022
aa96fba
[LoongArch64] amend the code for reviewing.
shushanhf Feb 21, 2022
cc96589
[LoongArch64] refactor LoongArch64-ABI within `vm`,
Feb 22, 2022
d3e6ca7
Merge branch 'main' into main_loongarch64_2
shushanhf Feb 23, 2022
4b32677
[LoongArch64] delete unused codes.
shushanhf Feb 23, 2022
9bb6899
Merge branch 'main' into main_loongarch64_2
Feb 25, 2022
c01407f
[LoongArch64] merge main for #65869.
Feb 25, 2022
14669dc
Merge branch 'main' into main_loongarch64_2
shushanhf Mar 1, 2022
7b8b887
[LoongArch64] amend the format for reviewing.
shushanhf Mar 1, 2022
ceee54a
[LoongArch64] delete some unused code for reviewing.
shushanhf Mar 1, 2022
00fdee0
[LoongArch64] amend code for CR feedback @jkotas @janvorli
shushanhf Mar 2, 2022
a623961
[LoongArch64] add class type for LoongArch64-ABI.
Mar 3, 2022
6566991
[LoongArch64] Amend the LoongArch64's ABI
shushanhf Mar 4, 2022
9f39e13
Merge branch 'main' into main_loongarch64_2
shushanhf Mar 22, 2022
d6c7080
[LoongArch64] Fix the assert error
shushanhf Apr 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -861,6 +861,11 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o
}
}

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to handle simple wrappers of primitive types (structs with just one field)?

They should be sign or zero extended based on the underlying type according to this comment:
loongson/LoongArch-Documentation#32 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is no need.
Becasue the field of struct will be pared again while using it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are saying that the comment loongson/LoongArch-Documentation#32 (comment) is not valid.

The calling convention details like this have to be very well understood and described. Could you please work on clarifying the ABI for simple wrappers of primitive types with your colleagues?

Copy link
Contributor Author

@shushanhf shushanhf Dec 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are saying that the comment loongson/LoongArch-Documentation#32 (comment) is not valid.

I am sorry for descriped unclear.
At the comment, using a register passing the struct {int a;} is signed extend.
Becasue it will use a instruction liking lw $register, $base, offset which will sign extent the upper bits within the register.

The calling convention details like this have to be very well understood and described. Could you please work on clarifying the ABI for simple wrappers of primitive types with your colleagues?

This PR is args passing by stack, the struct {...} which sizeof(struct) is less than or equal 4-byte, the upper bits are undefined.
But we signed extend the upper bits except the unsigned types, it will be ok and simply the cases.

*((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