From 46ebed3b128041d4c574cb9de0041f472ae34485 Mon Sep 17 00:00:00 2001 From: Qiao Pengcheng Date: Wed, 15 Dec 2021 21:56:52 +0800 Subject: [PATCH 01/19] [LoongArch64] add coreclr-inc,gc, ToolBox directory. (#59561) Co-authored-by: Loongson's .NET-teams --- .../superpmi-shared/compileresult.cpp | 5 + .../superpmi/superpmi-shared/spmiutil.cpp | 2 + .../superpmi/superpmi-shared/spmiutil.h | 5 +- .../ToolBox/superpmi/superpmi/jitinstance.cpp | 4 + .../ToolBox/superpmi/superpmi/superpmi.cpp | 4 + src/coreclr/binder/assemblybindercommon.cpp | 4 + src/coreclr/binder/inc/bindertypes.hpp | 1 + src/coreclr/debug/createdump/datatarget.cpp | 4 +- src/coreclr/debug/createdump/dumpwriterelf.h | 2 + src/coreclr/debug/createdump/memoryregion.h | 2 +- src/coreclr/debug/createdump/threadinfo.h | 24 + .../debug/createdump/threadinfounix.cpp | 5 + src/coreclr/debug/daccess/daccess.cpp | 2 + .../debug/daccess/loongarch64/primitives.cpp | 11 + src/coreclr/debug/daccess/request.cpp | 12 + src/coreclr/debug/dbgutil/elfreader.cpp | 2 + .../debug/di/loongarch64/cordbregisterset.cpp | 152 ++++++ .../debug/di/loongarch64/floatconversion.S | 12 + .../debug/di/loongarch64/primitives.cpp | 9 + src/coreclr/debug/di/module.cpp | 2 + src/coreclr/debug/di/platformspecific.cpp | 3 + src/coreclr/debug/di/rsthread.cpp | 8 +- src/coreclr/debug/di/shimremotedatatarget.cpp | 4 + src/coreclr/debug/ee/debugger.cpp | 5 + src/coreclr/debug/ee/loongarch64/dbghelpers.S | 49 ++ .../ee/loongarch64/loongarch64walker.cpp | 483 ++++++++++++++++++ .../debug/ee/loongarch64/primitives.cpp | 17 + src/coreclr/debug/inc/dbgipcevents.h | 75 +++ src/coreclr/debug/inc/dbgtargetcontext.h | 97 ++++ .../debug/inc/loongarch64/primitives.h | 267 ++++++++++ .../debug/shared/loongarch64/primitives.cpp | 90 ++++ src/coreclr/debug/shim/debugshim.cpp | 10 + src/coreclr/enablesanitizers.sh | 5 + src/coreclr/gc/env/gcenv.base.h | 5 + src/coreclr/gc/env/gcenv.interlocked.inl | 3 + src/coreclr/gc/env/volatile.h | 6 +- src/coreclr/gc/gc.cpp | 8 + src/coreclr/gc/unix/gcenv.unix.cpp | 4 +- src/coreclr/gcdump/gcdumpnonx86.cpp | 4 +- src/coreclr/gcinfo/gcinfodumper.cpp | 65 ++- src/coreclr/gcinfo/gcinfoencoder.cpp | 20 +- src/coreclr/inc/clrnt.h | 69 +++ src/coreclr/inc/cor.h | 8 + src/coreclr/inc/corcompile.h | 16 + src/coreclr/inc/cordebug.idl | 71 ++- src/coreclr/inc/cordebuginfo.h | 36 ++ src/coreclr/inc/corinfo.h | 4 + src/coreclr/inc/corinfoinstructionset.h | 5 + src/coreclr/inc/crosscomp.h | 140 +++++ src/coreclr/inc/cvconst.h | 5 +- src/coreclr/inc/eetwain.h | 8 +- src/coreclr/inc/eexcp.h | 4 +- src/coreclr/inc/gcinfodecoder.h | 16 +- src/coreclr/inc/gcinfoencoder.h | 4 +- src/coreclr/inc/gcinfotypes.h | 58 ++- src/coreclr/inc/jithelpers.h | 2 +- src/coreclr/inc/llvm/ELF.h | 47 ++ src/coreclr/inc/pedecoder.h | 2 + src/coreclr/inc/regdisp.h | 76 ++- src/coreclr/inc/sigparser.h | 4 + src/coreclr/inc/stdmacros.h | 15 +- src/coreclr/inc/switches.h | 2 +- src/coreclr/inc/targetosarch.h | 13 +- src/coreclr/inc/volatile.h | 6 +- 64 files changed, 2062 insertions(+), 41 deletions(-) create mode 100644 src/coreclr/debug/daccess/loongarch64/primitives.cpp create mode 100644 src/coreclr/debug/di/loongarch64/cordbregisterset.cpp create mode 100644 src/coreclr/debug/di/loongarch64/floatconversion.S create mode 100644 src/coreclr/debug/di/loongarch64/primitives.cpp create mode 100644 src/coreclr/debug/ee/loongarch64/dbghelpers.S create mode 100644 src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp create mode 100644 src/coreclr/debug/ee/loongarch64/primitives.cpp create mode 100644 src/coreclr/debug/inc/loongarch64/primitives.h create mode 100644 src/coreclr/debug/shared/loongarch64/primitives.cpp diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index 729064aa1b0bc8..03128d7d2e0c4f 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -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) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp index 4d21d7d2d56434..97f4ca40631da5 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp @@ -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 diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h index bc6bfa4f34fc24..16543880d944b7 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h @@ -53,7 +53,8 @@ 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(); @@ -61,7 +62,7 @@ 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() diff --git a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp index 07d90549de43ed..8ee9f726e878bf 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp @@ -346,6 +346,10 @@ JitInstance::Result JitInstance::CompileMethod(MethodContext* MethodToCompile, i matchesTargetArch = (targetArch == SPMI_TARGET_ARCHITECTURE_ARM64); break; + case IMAGE_FILE_MACHINE_LOONGARCH64: + matchesTargetArch = (targetArch == SPMI_TARGET_ARCHITECTURE_LOONGARCH64); + break; + default: LogError("Unknown target architecture"); break; diff --git a/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp b/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp index f71ee9c1fe32be..523e07da9c9b4b 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp @@ -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); diff --git a/src/coreclr/binder/assemblybindercommon.cpp b/src/coreclr/binder/assemblybindercommon.cpp index 830c673ea06a63..2bec176b44063e 100644 --- a/src/coreclr/binder/assemblybindercommon.cpp +++ b/src/coreclr/binder/assemblybindercommon.cpp @@ -215,6 +215,8 @@ namespace BINDER_SPACE *PeKind = peARM64; else if (dwImageType == IMAGE_FILE_MACHINE_AMD64) *PeKind = peAMD64; + else if (dwImageType == IMAGE_FILE_MACHINE_LOONGARCH64) + *PeKind = peLOONGARCH64; else { // We don't support other architectures @@ -1447,6 +1449,8 @@ BOOL AssemblyBinderCommon::IsValidArchitecture(PEKIND kArchitecture) peARM; #elif defined(TARGET_ARM64) peARM64; +#elif defined(TARGET_LOONGARCH64) + peLOONGARCH64; #else PORTABILITY_ASSERT("processArchitecture"); #endif diff --git a/src/coreclr/binder/inc/bindertypes.hpp b/src/coreclr/binder/inc/bindertypes.hpp index 101ef3c8d9593f..15a07b3d7b5aac 100644 --- a/src/coreclr/binder/inc/bindertypes.hpp +++ b/src/coreclr/binder/inc/bindertypes.hpp @@ -68,6 +68,7 @@ typedef enum __PEKIND peAMD64 = 0x00000004, peARM = 0x00000005, peARM64 = 0x00000006, + peLOONGARCH64 = 0x00000007, peInvalid = 0xffffffff, } PEKIND; diff --git a/src/coreclr/debug/createdump/datatarget.cpp b/src/coreclr/debug/createdump/datatarget.cpp index 7d2ab1973ff602..d119498c2b2b53 100644 --- a/src/coreclr/debug/createdump/datatarget.cpp +++ b/src/coreclr/debug/createdump/datatarget.cpp @@ -65,6 +65,8 @@ DumpDataTarget::GetMachineType( *machine = IMAGE_FILE_MACHINE_ARM64; #elif HOST_X86 *machine = IMAGE_FILE_MACHINE_I386; +#elif HOST_LOONGARCH64 + *machine = IMAGE_FILE_MACHINE_LOONGARCH64; #else #error Unsupported architecture #endif @@ -75,7 +77,7 @@ HRESULT STDMETHODCALLTYPE DumpDataTarget::GetPointerSize( /* [out] */ ULONG32 *size) { -#if defined(HOST_AMD64) || defined(HOST_ARM64) +#if defined(HOST_AMD64) || defined(HOST_ARM64) || defined(HOST_LOONGARCH64) *size = 8; #elif defined(HOST_ARM) || defined(HOST_X86) *size = 4; diff --git a/src/coreclr/debug/createdump/dumpwriterelf.h b/src/coreclr/debug/createdump/dumpwriterelf.h index 6da55da2f13750..cb8731871de211 100644 --- a/src/coreclr/debug/createdump/dumpwriterelf.h +++ b/src/coreclr/debug/createdump/dumpwriterelf.h @@ -21,6 +21,8 @@ #define ELF_ARCH EM_AARCH64 #elif defined(__arm__) #define ELF_ARCH EM_ARM +#elif defined(__loongarch64) +#define ELF_ARCH EM_LOONGARCH #endif #define PH_HDR_CANARY 0xFFFF diff --git a/src/coreclr/debug/createdump/memoryregion.h b/src/coreclr/debug/createdump/memoryregion.h index b5bb44f67a2cdf..c7f1765ccd02bd 100644 --- a/src/coreclr/debug/createdump/memoryregion.h +++ b/src/coreclr/debug/createdump/memoryregion.h @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if !defined(PAGE_SIZE) && (defined(__arm__) || defined(__aarch64__)) +#if !defined(PAGE_SIZE) && (defined(__arm__) || defined(__aarch64__) || defined(__loongarch64)) #define PAGE_SIZE sysconf(_SC_PAGESIZE) #endif diff --git a/src/coreclr/debug/createdump/threadinfo.h b/src/coreclr/debug/createdump/threadinfo.h index 4142b55e333dd7..0f9215c8fbbdb2 100644 --- a/src/coreclr/debug/createdump/threadinfo.h +++ b/src/coreclr/debug/createdump/threadinfo.h @@ -12,6 +12,13 @@ class CrashInfo; #define MCREG_Cpsr(mc) ((mc).pstate) #endif +#if defined(__loongarch64) +// See src/pal/src/include/pal/context.h +#define MCREG_Fp(mc) ((mc).gpr[22]) +#define MCREG_Sp(mc) ((mc).gpr[3]) +#define MCREG_Pc(mc) ((mc).pc) +#endif + #define FPREG_ErrorOffset(fpregs) *(DWORD*)&((fpregs).rip) #define FPREG_ErrorSelector(fpregs) *(((WORD*)&((fpregs).rip)) + 2) #define FPREG_DataOffset(fpregs) *(DWORD*)&((fpregs).rdp) @@ -19,6 +26,19 @@ class CrashInfo; #if defined(__arm__) #define user_regs_struct user_regs #define user_fpregs_struct user_fpregs +#elif defined(__loongarch64) +//usr/include/loongarch64-linux-gnu/sys/user.h +//struct user_regs_struct +//{ +// unsigned long long gpr[32]; +// unsigned long long pc; +//} __attribute__((__packed__)); + +struct user_fpregs_struct +{ + unsigned long long fpregs[32]; + unsigned long fpscr; +} __attribute__((__packed__)); #endif #if defined(__aarch64__) @@ -130,6 +150,10 @@ class ThreadInfo inline const uint64_t GetInstructionPointer() const { return MCREG_Pc(m_gpRegisters); } inline const uint64_t GetStackPointer() const { return MCREG_Sp(m_gpRegisters); } inline const uint64_t GetFramePointer() const { return MCREG_Fp(m_gpRegisters); } +#elif defined(__loongarch64) + inline const uint64_t GetInstructionPointer() const { return MCREG_Pc(m_gpRegisters); } + inline const uint64_t GetStackPointer() const { return MCREG_Sp(m_gpRegisters); } + inline const uint64_t GetFramePointer() const { return MCREG_Fp(m_gpRegisters); } #elif defined(__arm__) inline const uint64_t GetInstructionPointer() const { return m_gpRegisters.ARM_pc; } inline const uint64_t GetStackPointer() const { return m_gpRegisters.ARM_sp; } diff --git a/src/coreclr/debug/createdump/threadinfounix.cpp b/src/coreclr/debug/createdump/threadinfounix.cpp index 856dfbb2993793..0a6f87eddb0e18 100644 --- a/src/coreclr/debug/createdump/threadinfounix.cpp +++ b/src/coreclr/debug/createdump/threadinfounix.cpp @@ -57,6 +57,8 @@ ThreadInfo::Initialize() TRACE("Thread %04x PC %08lx SP %08lx\n", m_tid, (unsigned long)m_gpRegisters.ARM_pc, (unsigned long)m_gpRegisters.ARM_sp); #elif defined(__x86_64__) TRACE("Thread %04x RIP %016llx RSP %016llx\n", m_tid, (unsigned long long)m_gpRegisters.rip, (unsigned long long)m_gpRegisters.rsp); +#elif defined(__loongarch64) + TRACE("Thread %04x PC %016llx SP %016llx\n", m_tid, (unsigned long long)m_gpRegisters.pc, (unsigned long long)m_gpRegisters.gpr[3]); #else #error "Unsupported architecture" #endif @@ -221,6 +223,9 @@ ThreadInfo::GetThreadContext(uint32_t flags, CONTEXT* context) const memcpy(context->D, m_vfpRegisters.fpregs, sizeof(context->D)); #endif } +#elif defined(__loongarch64) + assert(!"Unimplemented yet on Loongarch64!"); +#pragma message("Unimplemented yet on Loongarch64.") #else #error Platform not supported #endif diff --git a/src/coreclr/debug/daccess/daccess.cpp b/src/coreclr/debug/daccess/daccess.cpp index f9ec95c1f41838..df61a309813f92 100644 --- a/src/coreclr/debug/daccess/daccess.cpp +++ b/src/coreclr/debug/daccess/daccess.cpp @@ -5517,6 +5517,8 @@ ClrDataAccess::Initialize(void) CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_ARM; #elif defined(TARGET_ARM64) CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_ARM64; + #elif defined(TARGET_LOONGARCH64) + CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_LOONGARCH64; #else #error Unknown Processor. #endif diff --git a/src/coreclr/debug/daccess/loongarch64/primitives.cpp b/src/coreclr/debug/daccess/loongarch64/primitives.cpp new file mode 100644 index 00000000000000..cc67cb10432df7 --- /dev/null +++ b/src/coreclr/debug/daccess/loongarch64/primitives.cpp @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Copyright (c) Loongson Technology. All rights reserved. + +// + +#include "stdafx.h" + +#include "../../shared/loongarch64/primitives.cpp" diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp index fe66a8b30b4212..a5d72df0d95983 100644 --- a/src/coreclr/debug/daccess/request.cpp +++ b/src/coreclr/debug/daccess/request.cpp @@ -624,6 +624,18 @@ ClrDataAccess::GetRegisterName(int regNum, unsigned int count, __out_z __inout_e { W("eax"), W("ecx"), W("edx"), W("ebx"), W("esp"), W("ebp"), W("esi"), W("edi"), }; +#elif defined(TARGET_LOONGARCH64) + static const WCHAR *regs[] = + { + W("R0"), W("AT"), W("V0"), W("V1"), + W("A0"), W("A1"), W("A2"), W("A3"), + W("A4"), W("A5"), W("A6"), W("A7"), + W("T0"), W("T1"), W("T2"), W("T3"), + W("T8"), W("T9"), W("S0"), W("S1"), + W("S2"), W("S3"), W("S4"), W("S5"), + W("S6"), W("S7"), W("K0"), W("K1"), + W("GP"), W("SP"), W("FP"), W("RA") + }; #endif // Caller frame registers are encoded as "-(reg+1)". diff --git a/src/coreclr/debug/dbgutil/elfreader.cpp b/src/coreclr/debug/dbgutil/elfreader.cpp index bc6300a7717410..af16b71674f506 100644 --- a/src/coreclr/debug/dbgutil/elfreader.cpp +++ b/src/coreclr/debug/dbgutil/elfreader.cpp @@ -555,6 +555,8 @@ Elf64_Ehdr::Elf64_Ehdr() e_machine = EM_X86_64; #elif defined(TARGET_ARM64) e_machine = EM_AARCH64; +#elif defined(TARGET_LOONGARCH64) + e_machine = EM_LOONGARCH; #endif e_flags = 0; e_version = 1; diff --git a/src/coreclr/debug/di/loongarch64/cordbregisterset.cpp b/src/coreclr/debug/di/loongarch64/cordbregisterset.cpp new file mode 100644 index 00000000000000..fe67ebdb68904d --- /dev/null +++ b/src/coreclr/debug/di/loongarch64/cordbregisterset.cpp @@ -0,0 +1,152 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Copyright (c) Loongson Technology. All rights reserved. + +//***************************************************************************** +// File: CordbRegisterSet.cpp +// + +// +//***************************************************************************** +#include "primitives.h" + + +HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG64* pAvailable) +{ + assert(!"unimplemented on LOONGARCH yet"); + FAIL_IF_NEUTERED(this); + VALIDATE_POINTER_TO_OBJECT(pAvailable, ULONG64 *); + + *pAvailable = SETBITULONG64(REGISTER_LOONGARCH64_PC) + | SETBITULONG64(REGISTER_LOONGARCH64_SP) +#if 0 + | SETBITULONG64(REGISTER_LOONGARCH64_X0) + | SETBITULONG64(REGISTER_LOONGARCH64_X1) + | SETBITULONG64(REGISTER_LOONGARCH64_X2) + | SETBITULONG64(REGISTER_LOONGARCH64_X3) + | SETBITULONG64(REGISTER_LOONGARCH64_X4) + | SETBITULONG64(REGISTER_LOONGARCH64_X5) + | SETBITULONG64(REGISTER_LOONGARCH64_X6) + | SETBITULONG64(REGISTER_LOONGARCH64_X7) + | SETBITULONG64(REGISTER_LOONGARCH64_X8) + | SETBITULONG64(REGISTER_LOONGARCH64_X9) + | SETBITULONG64(REGISTER_LOONGARCH64_X10) + | SETBITULONG64(REGISTER_LOONGARCH64_X11) + | SETBITULONG64(REGISTER_LOONGARCH64_X12) + | SETBITULONG64(REGISTER_LOONGARCH64_X13) + | SETBITULONG64(REGISTER_LOONGARCH64_X14) + | SETBITULONG64(REGISTER_LOONGARCH64_X15) + | SETBITULONG64(REGISTER_LOONGARCH64_X16) + | SETBITULONG64(REGISTER_LOONGARCH64_X17) + | SETBITULONG64(REGISTER_LOONGARCH64_X18) + | SETBITULONG64(REGISTER_LOONGARCH64_X19) + | SETBITULONG64(REGISTER_LOONGARCH64_X20) + | SETBITULONG64(REGISTER_LOONGARCH64_X21) + | SETBITULONG64(REGISTER_LOONGARCH64_X22) + | SETBITULONG64(REGISTER_LOONGARCH64_X23) + | SETBITULONG64(REGISTER_LOONGARCH64_X24) + | SETBITULONG64(REGISTER_LOONGARCH64_X25) + | SETBITULONG64(REGISTER_LOONGARCH64_X26) + | SETBITULONG64(REGISTER_LOONGARCH64_X27) + | SETBITULONG64(REGISTER_LOONGARCH64_X28) +#endif + | SETBITULONG64(REGISTER_LOONGARCH64_FP) + | SETBITULONG64(REGISTER_LOONGARCH64_RA); + + return S_OK; +} + +HRESULT CordbRegisterSet::GetRegisters(ULONG64 mask, ULONG32 regCount, + CORDB_REGISTER regBuffer[]) +{ + assert(!"unimplemented on LOONGARCH yet"); + PUBLIC_REENTRANT_API_ENTRY(this); + FAIL_IF_NEUTERED(this); + ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess()); + + UINT iRegister = 0; + + VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER, regCount, true, true); + + // @LOONGARCH64TODO: floating point support +#if 0 + for (int i = REGISTER_LOONGARCH64_PC; + i <= REGISTER_LOONGARCH64_LR && iRegister < regCount; + i++) + { + if (mask & SETBITULONG64(i)) + { + if ((i >= REGISTER_LOONGARCH64_X0) && (i <= REGISTER_LOONGARCH64_X28)) + { + regBuffer[iRegister++] = m_rd->X[i - REGISTER_LOONGARCH64_X0]; + continue; + } + + switch (i) + { + case REGISTER_LOONGARCH64_PC: + regBuffer[iRegister++] = m_rd->PC; break; + case REGISTER_LOONGARCH64_SP: + regBuffer[iRegister++] = m_rd->SP; break; + case REGISTER_LOONGARCH64_FP: + regBuffer[iRegister++] = m_rd->FP; break; + default: + _ASSERTE(false); break; + } + } + } +#endif + _ASSERTE (iRegister <= regCount); + return S_OK; +} + + +HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG32 regCount, + BYTE pAvailable[]) +{ + FAIL_IF_NEUTERED(this); + VALIDATE_POINTER_TO_OBJECT_ARRAY(pAvailable, CORDB_REGISTER, regCount, true, true); + + // Defer to adapter for v1.0 interface + return GetRegistersAvailableAdapter(regCount, pAvailable); +} + + +HRESULT CordbRegisterSet::GetRegisters(ULONG32 maskCount, BYTE mask[], + ULONG32 regCount, CORDB_REGISTER regBuffer[]) +{ + FAIL_IF_NEUTERED(this); + VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER, regCount, true, true); + + // Defer to adapter for v1.0 interface + return GetRegistersAdapter(maskCount, mask, regCount, regBuffer); +} + + +// This is just a convenience function to convert a regdisplay into a Context. +// Since a context has more info than a regdisplay, the conversion isn't perfect +// and the context can't be fully accurate. +void CordbRegisterSet::InternalCopyRDToContext(DT_CONTEXT *pInputContext) +{ INTERNAL_SYNC_API_ENTRY(GetProcess()); + _ASSERTE(pInputContext); + assert(!"unimplemented on LOONGARCH yet"); + + if ((pInputContext->ContextFlags & DT_CONTEXT_INTEGER) == DT_CONTEXT_INTEGER) + { +#if 0 + for (int i = 0 ; i < 29 ; ++i) + { + pInputContext->X[i] = m_rd->X[i]; + } +#endif + } + + if ((pInputContext->ContextFlags & DT_CONTEXT_CONTROL) == DT_CONTEXT_CONTROL) + { + pInputContext->SP = m_rd->SP; + pInputContext->PC = m_rd->PC; + pInputContext->FP = m_rd->FP; + } +} diff --git a/src/coreclr/debug/di/loongarch64/floatconversion.S b/src/coreclr/debug/di/loongarch64/floatconversion.S new file mode 100644 index 00000000000000..83043e4ee66ca2 --- /dev/null +++ b/src/coreclr/debug/di/loongarch64/floatconversion.S @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include + +// Arguments +// input: (in A0) the value to be converted to a double +// output: the double corresponding to the _NEON128 input value +LEAF_ENTRY FPFillR8, .TEXT + ld.d $a0, $a0, 0 + jirl $r0, $ra, 0 +LEAF_END FPFillR8, .TEXT diff --git a/src/coreclr/debug/di/loongarch64/primitives.cpp b/src/coreclr/debug/di/loongarch64/primitives.cpp new file mode 100644 index 00000000000000..dac7063c7e8791 --- /dev/null +++ b/src/coreclr/debug/di/loongarch64/primitives.cpp @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Copyright (c) Loongson Technology. All rights reserved. + +// + +#include "../../shared/loongarch64/primitives.cpp" diff --git a/src/coreclr/debug/di/module.cpp b/src/coreclr/debug/di/module.cpp index 9951d4a6af305f..1076336e84be3a 100644 --- a/src/coreclr/debug/di/module.cpp +++ b/src/coreclr/debug/di/module.cpp @@ -4507,6 +4507,8 @@ int CordbNativeCode::GetCallInstructionLength(BYTE *ip, ULONG32 count) return 2; #elif defined(TARGET_ARM64) return MAX_INSTRUCTION_LENGTH; +#elif defined(TARGET_LOONGARCH64) + return MAX_INSTRUCTION_LENGTH; #elif defined(TARGET_X86) if (count < 2) return -1; diff --git a/src/coreclr/debug/di/platformspecific.cpp b/src/coreclr/debug/di/platformspecific.cpp index fb2d8eb92453e4..5247fd8436bc95 100644 --- a/src/coreclr/debug/di/platformspecific.cpp +++ b/src/coreclr/debug/di/platformspecific.cpp @@ -34,6 +34,9 @@ #elif TARGET_ARM64 #include "arm64/cordbregisterset.cpp" #include "arm64/primitives.cpp" +#elif TARGET_LOONGARCH64 +#include "loongarch64/cordbregisterset.cpp" +#include "loongarch64/primitives.cpp" #else #error Unsupported platform #endif diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index 577574b796019c..54e9e0f9d3ef74 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -8344,6 +8344,9 @@ HRESULT CordbJITILFrame::GetNativeVariable(CordbType *type, #elif defined(TARGET_ARM64) hr = m_nativeFrame->GetLocalFloatingPointValue(pNativeVarInfo->loc.vlReg.vlrReg + REGISTER_ARM64_V0, type, ppValue); +#elif defined(TARGET_LOONGARCH64) + hr = m_nativeFrame->GetLocalFloatingPointValue(pNativeVarInfo->loc.vlReg.vlrReg + REGISTER_LOONGARCH64_F0, + type, ppValue); #else #error Platform not implemented #endif // TARGET_ARM @ARMTODO @@ -8780,6 +8783,8 @@ HRESULT CordbJITILFrame::GetReturnValueForType(CordbType *pType, ICorDebugValue const CorDebugRegister floatRegister = REGISTER_ARM64_V0; #elif defined(TARGET_ARM) const CorDebugRegister floatRegister = REGISTER_ARM_D0; +#elif defined(TARGET_LOONGARCH64) + const CorDebugRegister floatRegister = REGISTER_LOONGARCH64_F0; #endif #if defined(TARGET_X86) @@ -8792,7 +8797,8 @@ HRESULT CordbJITILFrame::GetReturnValueForType(CordbType *pType, ICorDebugValue #elif defined(TARGET_ARM) const CorDebugRegister ptrRegister = REGISTER_ARM_R0; const CorDebugRegister ptrHighWordRegister = REGISTER_ARM_R1; - +#elif defined(TARGET_LOONGARCH64) + const CorDebugRegister ptrRegister = REGISTER_LOONGARCH64_A0; #endif CorElementType corReturnType = pType->GetElementType(); diff --git a/src/coreclr/debug/di/shimremotedatatarget.cpp b/src/coreclr/debug/di/shimremotedatatarget.cpp index 9a01508e211585..1a5fb8562a6be3 100644 --- a/src/coreclr/debug/di/shimremotedatatarget.cpp +++ b/src/coreclr/debug/di/shimremotedatatarget.cpp @@ -230,6 +230,8 @@ ShimRemoteDataTarget::GetPlatform( *pPlatform = CORDB_PLATFORM_POSIX_ARM; #elif defined(TARGET_ARM64) *pPlatform = CORDB_PLATFORM_POSIX_ARM64; + #elif defined(TARGET_LOONGARCH64) + *pPlatform = CORDB_PLATFORM_POSIX_LOONGARCH64; #else #error Unknown Processor. #endif @@ -242,6 +244,8 @@ ShimRemoteDataTarget::GetPlatform( *pPlatform = CORDB_PLATFORM_WINDOWS_ARM; #elif defined(TARGET_ARM64) *pPlatform = CORDB_PLATFORM_WINDOWS_ARM64; + #elif defined(TARGET_LOONGARCH64) + *pPlatform = CORDB_PLATFORM_WINDOWS_LOONGARCH64; #else #error Unknown Processor. #endif diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 8e5200d37d5097..427bda5c8386b3 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -6663,6 +6663,8 @@ void Debugger::InitDebuggerLaunchJitInfo(Thread * pThread, EXCEPTION_POINTERS * s_DebuggerLaunchJitInfo.dwProcessorArchitecture = PROCESSOR_ARCHITECTURE_ARM; #elif defined(TARGET_ARM64) s_DebuggerLaunchJitInfo.dwProcessorArchitecture = PROCESSOR_ARCHITECTURE_ARM64; +#elif defined(TARGET_LOONGARCH64) + s_DebuggerLaunchJitInfo.dwProcessorArchitecture = PROCESSOR_ARCHITECTURE_LOONGARCH64; #else #error Unknown processor. #endif @@ -13543,6 +13545,9 @@ LONG Debugger::FirstChanceSuspendHijackWorker(CONTEXT *pContext, SPEW(fprintf(stderr, "0x%x D::FCHF: code=0x%08x, addr=0x%08x, Pc=0x%p, Sp=0x%p, EFlags=0x%08x\n", tid, pExceptionRecord->ExceptionCode, pExceptionRecord->ExceptionAddress, pContext->Pc, pContext->Sp, pContext->EFlags)); +#elif defined(TARGET_LOONGARCH64) + SPEW(fprintf(stderr, "0x%x D::FCHF: code=0x%08x, addr=0x%08x, Pc=0x%p, Sp=0x%p\n", + tid, pExceptionRecord->ExceptionCode, pExceptionRecord->ExceptionAddress, pContext->Pc, pContext->Sp)); #endif // This memory is used as IPC during the hijack. We will place a pointer to this in diff --git a/src/coreclr/debug/ee/loongarch64/dbghelpers.S b/src/coreclr/debug/ee/loongarch64/dbghelpers.S new file mode 100644 index 00000000000000..aa4233e77364fb --- /dev/null +++ b/src/coreclr/debug/ee/loongarch64/dbghelpers.S @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Copyright (c) Loongson Technology. All rights reserved. + +#include "asmconstants.h" +#include "unixasmmacros.inc" + +// +// hijacking stub used to perform a func-eval, see Debugger::FuncEvalSetup() for use. +// +// on entry: +// x0 : pointer to DebuggerEval object +// + +// @dbgtodo- once we port Funceval, use the ExceptionHijack stub instead of this func-eval stub. +NESTED_ENTRY FuncEvalHijack, _TEXT, UnhandledExceptionHandlerUnix + // 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 + // $fp,$ra + PROLOG_SAVE_REG_PAIR_INDEXED 22, 1, -32 + st.d $a0, $sp, 16 + + // FuncEvalHijackWorker returns the address we should jump to. + bl C_FUNC(FuncEvalHijackWorker) + + EPILOG_STACK_FREE 32 + EPILOG_BRANCH_REG $v0 +NESTED_END FuncEvalHijack + +// This is the general purpose hijacking stub. The DacDbi Hijack primitive will +// set up the stack and then set the IP here, and so this just makes the call. +NESTED_ENTRY ExceptionHijack, _TEXT, UnhandledExceptionHandlerUnix + // make the call + bl C_FUNC(ExceptionHijackWorker) + + // effective NOP to terminate unwind ??? + nop + + // *** should never get here *** + EMIT_BREAKPOINT +// exported label so the debugger knows where the end of this function is +PATCH_LABEL ExceptionHijackEnd + +NESTED_END ExceptionHijack, _TEXT diff --git a/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp b/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp new file mode 100644 index 00000000000000..660f43760e0799 --- /dev/null +++ b/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp @@ -0,0 +1,483 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Copyright (c) Loongson Technology. All rights reserved. + +//***************************************************************************** +// File: Loongarch64walker.cpp +// + +// +// LOONGARCH64 instruction decoding/stepping logic +// +//***************************************************************************** + +#include "stdafx.h" +#include "walker.h" +#include "frames.h" +#include "openum.h" + +#ifdef TARGET_LOONGARCH64 + +PCODE Expand19bitoffset(PCODE opcode) +{ + _ASSERTE(!"=====Not implements for loongarch64. -1"); + opcode = opcode >> 5; + PCODE offset = (opcode & 0x7FFFF) << 2; //imm19:00 -> 21 bits + + //Sign Extension + if ((offset & 0x100000)) //Check for 21'st bit + { + offset = offset | 0xFFFFFFFFFFE00000; + } + return offset; +} + +void NativeWalker::Decode() +{ + _ASSERTE(!"=====Not implements for loongarch64. -2"); + + PT_CONTEXT context = NULL; + int RegNum = -1; + PCODE offset = MAX_INSTRUCTION_LENGTH; + + //Reset so that we do not provide bogus info + m_type = WALK_UNKNOWN; + m_skipIP = NULL; + m_nextIP = NULL; + + if (m_registers == NULL) + { + //walker does not use WALK_NEXT + //Without registers decoding will work only for handful of instructions + return; + } + + m_skipIP = m_ip + MAX_INSTRUCTION_LENGTH; + + context = m_registers->pCurrentContext; + // Fetch first word of the current instruction.If the current instruction is a break instruction, we'll + // need to check the patch table to get the correct instruction. + PRD_TYPE opcode = CORDbgGetInstruction(m_ip); + PRD_TYPE unpatchedOpcode; + if (DebuggerController::CheckGetPatchedOpcode(m_ip, &unpatchedOpcode)) + { + opcode = unpatchedOpcode; + } + + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decode instruction at %p, opcode: %x\n", m_ip,opcode)); + + + + if (NativeWalker::DecodeCallInst(opcode, RegNum, m_type)) //Unconditional Branch (register) instructions + { + if (m_type == WALK_RETURN) + { + m_skipIP = NULL; + } + m_nextIP = (BYTE*)GetReg(context, RegNum); + return; + } + + + if (NativeWalker::DecodePCRelativeBranchInst(context, opcode, offset, m_type)) + { + if (m_type == WALK_BRANCH) + { + m_skipIP = NULL; + } + } + + m_nextIP = m_ip + offset; + + + return; +} + + +//When control reaches here m_pSharedPatchBypassBuffer has the original instructions in m_pSharedPatchBypassBuffer->PatchBypass +BYTE* NativeWalker::SetupOrSimulateInstructionForPatchSkip(T_CONTEXT * context, SharedPatchBypassBuffer* m_pSharedPatchBypassBuffer, const BYTE *address, PRD_TYPE opcode) +{ + _ASSERTE(!"=====Not implements for loongarch64. -3"); + + BYTE* patchBypass = m_pSharedPatchBypassBuffer->PatchBypass; + PCODE offset = 0; + PCODE ip = 0; + WALK_TYPE walk = WALK_UNKNOWN; + int RegNum =-1; + + + /* + Modify the patchBypass if the opcode is IP-relative, otherwise return it + The following are the instructions that are IP-relative : + . ADR and ADRP. + . The Load register (literal) instruction class. + . Direct branches that use an immediate offset. + . The unconditional branch with link instructions, BL and BLR, that use the PC to create the return link + address. + */ + + _ASSERTE((UINT_PTR)address == context->Pc); + + if ((opcode & 0x1F000000) == 0x10000000) //ADR & ADRP + { + + TADDR immhigh = ((opcode >> 5) & 0x007FFFF) << 2; + TADDR immlow = (opcode & 0x60000000) >> 29; + offset = immhigh | immlow; //ADR + RegNum = (opcode & 0x1F); + + //Sign Extension + if ((offset & 0x100000)) //Check for 21'st bit + { + offset = offset | 0xFFFFFFFFFFE00000; + } + + if ((opcode & 0x80000000) != 0) //ADRP + { + offset = offset << 12; + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to ADRP X%d %p\n", opcode, RegNum, offset)); + } + else + { + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to ADR X%d %p\n", opcode, RegNum, offset)); + } + + + } + + else if ((opcode & 0x3B000000) == 0x18000000) //LDR Literal (General or SIMD) + { + + offset = Expand19bitoffset(opcode); + RegNum = (opcode & 0x1F); + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to LDR[SW] | PRFM X%d %p\n", opcode, RegNum, offset)); + } + else if (NativeWalker::DecodePCRelativeBranchInst(context,opcode, offset, walk)) + { + _ASSERTE(RegNum == -1); + } + else if (NativeWalker::DecodeCallInst(opcode, RegNum, walk)) + { + _ASSERTE(offset == 0); + } + //else Just execute the opcodes as is + //{ + //} + + if (offset != 0) // calculate the next ip from current ip + { + ip = (PCODE)address + offset; + } + else if(RegNum >= 0) + { + ip = GetReg(context, RegNum); + } + + //Do instruction emulation inplace here + + if (walk == WALK_BRANCH || walk == WALK_CALL || walk == WALK_RETURN) + { + CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patchBypass, 0xd503201f); //Add Nop in buffer + + m_pSharedPatchBypassBuffer->RipTargetFixup = ip; //Control Flow simulation alone is done DebuggerPatchSkip::TriggerExceptionHook + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x is a Control Flow instr \n", opcode)); + + if (walk == WALK_CALL) //initialize Lr + { + SetRA(context, (PCODE)address + MAX_INSTRUCTION_LENGTH); + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x is a Call instr, setting RA to %p \n", opcode,GetRA(context))); + } + } + else if(RegNum >= 0) + { + CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patchBypass, 0xd503201f); //Add Nop in buffer + + PCODE RegContents; + if ((opcode & 0x3B000000) == 0x18000000) //LDR Literal + { + RegContents = (PCODE)GetMem(ip); + if ((opcode & 0x4000000)) //LDR literal for SIMD + { + NEON128 SimdRegContents; + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to LDR V%d %p\n", opcode, RegNum, offset)); + short opc = (opcode >> 30); + switch (opc) + { + case 0: //4byte data into St + RegContents = 0xFFFFFFFF & RegContents; //zero the upper 32bit + SetReg(context, RegNum, RegContents); + case 1: //8byte data into Dt + SetReg(context, RegNum, RegContents); + break; + + case 2: //SIMD 16 byte data + SimdRegContents = GetSimdMem(ip); + SetSimdReg(context, RegNum, SimdRegContents); + break; + default: + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate Unknown opcode: %x [LDR(litera,SIMD &FP)] \n", opcode)); + _ASSERTE(!("Loongarch64Walker::Simulated Unknown opcode")); + + } + } + else + { + short opc = (opcode >> 30); + switch (opc) + { + case 0: //4byte data into Wt + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to LDR W%d %p\n", opcode, RegNum, offset)); + RegContents = 0xFFFFFFFF & RegContents; //zero the upper 32bits + SetReg(context, RegNum, RegContents); + break; + + case 1: //8byte data into Xt + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to LDR X%d %p\n", opcode, RegNum, offset)); + SetReg(context, RegNum, RegContents); + break; + + case 2: //LDRSW + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to LDRSW X%d %p\n", opcode, RegNum, offset)); + RegContents = 0xFFFFFFFF & RegContents; + + if (RegContents & 0x80000000) //Sign extend the Word + { + RegContents = 0xFFFFFFFF00000000 | RegContents; + } + SetReg(context, RegNum, RegContents); + break; + case 3: + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x as PRFM ,but do nothing \n", opcode)); + + break; + default: + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate Unknown opcode: %x [LDR(literal)] \n", opcode)); + _ASSERTE(!("Loongarch64Walker::Simulated Unknown opcode")); + + } + } + } + else + { + RegContents = ip; + SetReg(context, RegNum, RegContents); + } + + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to update Reg X[V]%d, as %p \n", opcode, RegNum, GetReg(context, RegNum))); + } + //else Just execute the opcodes as IS + //{ + //} + + return patchBypass; +} + +//Decodes PC Relative Branch Instructions +//This code is shared between the NativeWalker and DebuggerPatchSkip. +//So ENSURE THIS FUNCTION DOES NOT CHANGE ANY STATE OF THE DEBUGEE +//This Function Decodes : +// BL offset +// B offset +// B.Cond offset +// CB[N]Z X offset +// TB[N]Z X offset + +//Output of the Function are: +//offset - Offset from current PC to which control will go next +//WALK_TYPE + +BOOL NativeWalker::DecodePCRelativeBranchInst(PT_CONTEXT context, const PRD_TYPE& opcode, PCODE& offset, WALK_TYPE& walk) +{ + _ASSERTE(!"=====Not implements for loongarch64. -4"); +#ifdef _DEBUG + PCODE incomingoffset = offset; + WALK_TYPE incomingwalk = walk; +#endif + + if ((opcode & 0x7C000000) == 0x14000000) // Decode B & BL + { + offset = (opcode & 0x03FFFFFF) << 2; + // Sign extension + if ((offset & 0x4000000)) //Check for 26'st bit + { + offset = offset | 0xFFFFFFFFF8000000; + } + + if ((opcode & 0x80000000) != 0) //BL + { + walk = WALK_CALL; + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to BL %p \n", opcode, offset)); + } + else + { + walk = WALK_BRANCH; //B + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to B %p \n", opcode, offset)); + } + return TRUE; + } + + //Conditional Branches + _ASSERTE(context != NULL); + + + if ((opcode & 0xFF000010) == 0x54000000) // B.cond + { + WORD cond = opcode & 0xF; + bool result = false; + switch (cond >> 1) + { + case 0x0: result = (context->Cpsr & NZCV_Z) != 0; // EQ or NE + break; + case 0x1: result = (context->Cpsr & NZCV_C) != 0; // CS or CC + break; + case 0x2: result = (context->Cpsr & NZCV_N) != 0; // MI or PL + break; + case 0x3: result = (context->Cpsr & NZCV_V) != 0; // VS or VC + break; + case 0x4: result = ((context->Cpsr & NZCV_C) != 0) && ((context->Cpsr & NZCV_Z) == 0); // HI or LS + break; + case 0x5: result = ((context->Cpsr & NZCV_N) >> NZCV_N_BIT) == ((context->Cpsr & NZCV_V) >> NZCV_V_BIT); // GE or LT + break; + case 0x6: result = ((context->Cpsr & NZCV_N) >> NZCV_N_BIT) == ((context->Cpsr & NZCV_V) >> NZCV_V_BIT) && ((context->Cpsr & NZCV_Z) == 0); // GT or LE + break; + case 0x7: result = true; // AL + break; + } + + if ((cond & 0x1) && (cond & 0xF) != 0) { result = !result; } + + if (result) + { + walk = WALK_BRANCH; + offset = Expand19bitoffset(opcode); + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to B.cond %p \n", opcode, offset)); + } + else // NOP + { + walk = WALK_UNKNOWN; + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to B.cond but evaluated as NOP \n", opcode)); + offset = MAX_INSTRUCTION_LENGTH; + } + + return TRUE; + + } + + + int RegNum = opcode & 0x1F; + PCODE RegContent = GetReg(context, RegNum); + + if ((opcode & 0xFE000000) == 0x34000000) // CBNZ || CBZ + { + bool result = false; + + if (!(opcode & 0x80000000)) //if sf == '1' the 64 else 32 + { + RegContent = 0xFFFFFFFF & RegContent; //zero the upper 32bit + } + + if (opcode & 0x01000000) //CBNZ + { + result = RegContent != 0; + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to CBNZ X%d \n", opcode, RegNum)); + } + else //CBZ + { + result = RegContent == 0; + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to CBZ X%d \n", opcode, RegNum)); + } + + if (result) + { + walk = WALK_BRANCH; + offset = Expand19bitoffset(opcode); + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to CB[N]Z X%d %p \n", opcode, RegNum, offset)); + } + else // NOP + { + walk = WALK_UNKNOWN; + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to B.cond but evaluated as NOP \n", opcode)); + offset = MAX_INSTRUCTION_LENGTH; + } + + + return TRUE; + } + if ((opcode & 0x7E000000) == 0x36000000) // TBNZ || TBZ + { + bool result = false; + int bit_pos = ((opcode >> 19) & 0x1F); + + if (opcode & 0x80000000) + { + bit_pos = bit_pos + 32; + } + + PCODE bit_val = 1 << bit_pos; + if (opcode & 0x01000000) //TBNZ + { + result = (RegContent & bit_val) != 0; + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to TBNZ X%d \n", opcode, RegNum)); + } + else //TBZ + { + result = (RegContent & bit_val) == 0; + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to CB[N]Z X%d \n", opcode, RegNum)); + } + if (result) + { + walk = WALK_BRANCH; + offset = ((opcode >> 5) & 0x3FFF) << 2; //imm14:00 -> 16 bits + if (offset & 0x8000) //sign extension check for 16'th bit + { + offset = offset | 0xFFFFFFFFFFFF0000; + } + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to TB[N]Z X%d %p \n", opcode, RegNum, offset)); + } + else // NOP + { + walk = WALK_UNKNOWN; + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to B.cond but evaluated as NOP \n", opcode)); + offset = MAX_INSTRUCTION_LENGTH; + } + + return TRUE; + } + + _ASSERTE(offset == incomingoffset); + _ASSERTE(walk == incomingwalk); + return FALSE; +} + +BOOL NativeWalker::DecodeCallInst(const PRD_TYPE& opcode, int& RegNum, WALK_TYPE& walk) +{ + if ((opcode & 0xFF9FFC1F) == 0xD61F0000) // BR, BLR or RET -Unconditional Branch (register) instructions + { + + RegNum = (opcode & 0x3E0) >> 5; + + + short op = (opcode & 0x00600000) >> 21; //Checking for 23 and 22 bits + switch (op) + { + case 0: LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to BR X%d\n", opcode, RegNum)); + walk = WALK_BRANCH; + break; + case 1: LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to BLR X%d\n", opcode, RegNum)); + walk = WALK_CALL; + break; + case 2: LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to Ret X%d\n", opcode, RegNum)); + walk = WALK_RETURN; + break; + default: + LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate Unknown opcode: %x [Branch] \n", opcode)); + _ASSERTE(!("Loongarch64Walker::Decoded Unknown opcode")); + } + + return TRUE; + } + return FALSE; +} +#endif diff --git a/src/coreclr/debug/ee/loongarch64/primitives.cpp b/src/coreclr/debug/ee/loongarch64/primitives.cpp new file mode 100644 index 00000000000000..ac1fa859f0d85a --- /dev/null +++ b/src/coreclr/debug/ee/loongarch64/primitives.cpp @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Copyright (c) Loongson Technology. All rights reserved. + +// + +#include "stdafx.h" +#include "threads.h" +#include "../../shared/loongarch64/primitives.cpp" + +void CopyREGDISPLAY(REGDISPLAY* pDst, REGDISPLAY* pSrc) +{ + CONTEXT tmp; + CopyRegDisplay(pSrc, pDst, &tmp); +} diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h index db4a00fca1c865..38269b16df53ed 100644 --- a/src/coreclr/debug/inc/dbgipcevents.h +++ b/src/coreclr/debug/inc/dbgipcevents.h @@ -1163,6 +1163,74 @@ struct MSLAYOUT DebuggerREGDISPLAY SIZE_T LR; SIZE_T SP; SIZE_T PC; +#elif defined(TARGET_LOONGARCH64) + #define DebuggerIPCE_FloatCount 32 + SIZE_T R0; + void *pR0; + SIZE_T RA; + void *pRA; + SIZE_T TP; + void *pTP; + SIZE_T SP; + void *pSP; + SIZE_T A0; + void *pA0; + SIZE_T A1; + void *pA1; + SIZE_T A2; + void *pA2; + SIZE_T A3; + void *pA3; + SIZE_T A4; + void *pA4; + SIZE_T A5; + void *pA5; + SIZE_T A6; + void *pA6; + SIZE_T A7; + void *pA7; + SIZE_T T0; + void *pT0; + SIZE_T T1; + void *pT1; + SIZE_T T2; + void *pT2; + SIZE_T T3; + void *pT3; + SIZE_T T4; + void *pT4; + SIZE_T T5; + void *pT5; + SIZE_T T6; + void *pT6; + SIZE_T T7; + void *pT7; + SIZE_T T8; + void *pT8; + SIZE_T X0; + void *pX0; + SIZE_T FP; + void *pFP; + SIZE_T S0; + void *pS0; + SIZE_T S1; + void *pS1; + SIZE_T S2; + void *pS2; + SIZE_T S3; + void *pS3; + SIZE_T S4; + void *pS4; + SIZE_T S5; + void *pS5; + SIZE_T S6; + void *pS6; + SIZE_T S7; + void *pS7; + SIZE_T S8; + void *pS8; + SIZE_T PC; + void *pPC; #else #define DebuggerIPCE_FloatCount 1 @@ -1880,6 +1948,13 @@ C_ASSERT(DBG_TARGET_REGNUM_AMBIENT_SP == ICorDebugInfo::REGNUM_AMBIENT_SP); C_ASSERT(DBG_TARGET_REGNUM_SP == ICorDebugInfo::REGNUM_SP); C_ASSERT(DBG_TARGET_REGNUM_AMBIENT_SP == ICorDebugInfo::REGNUM_AMBIENT_SP); #endif // TARGET_ARM64 +#elif defined(TARGET_LOONGARCH64) +#define DBG_TARGET_REGNUM_SP 3 +#define DBG_TARGET_REGNUM_AMBIENT_SP 34 +#ifdef TARGET_LOONGARCH64 +C_ASSERT(DBG_TARGET_REGNUM_SP == ICorDebugInfo::REGNUM_SP); +C_ASSERT(DBG_TARGET_REGNUM_AMBIENT_SP == ICorDebugInfo::REGNUM_AMBIENT_SP); +#endif #else #error Target registers are not defined for this platform #endif diff --git a/src/coreclr/debug/inc/dbgtargetcontext.h b/src/coreclr/debug/inc/dbgtargetcontext.h index f96a18c008dd28..37eb7eb11bd712 100644 --- a/src/coreclr/debug/inc/dbgtargetcontext.h +++ b/src/coreclr/debug/inc/dbgtargetcontext.h @@ -48,6 +48,8 @@ #define DTCONTEXT_IS_ARM #elif defined (TARGET_ARM64) #define DTCONTEXT_IS_ARM64 +#elif defined (TARGET_LOONGARCH64) +#define DTCONTEXT_IS_LOONGARCH64 #endif #if defined(DTCONTEXT_IS_X86) @@ -447,6 +449,101 @@ typedef DECLSPEC_ALIGN(16) struct { } DT_CONTEXT; +#elif defined(DTCONTEXT_IS_LOONGARCH64) +#define DT_CONTEXT_LOONGARCH64 0x00800000L + +#define DT_CONTEXT_CONTROL (DT_CONTEXT_LOONGARCH64 | 0x1L) +#define DT_CONTEXT_INTEGER (DT_CONTEXT_LOONGARCH64 | 0x2L) +#define DT_CONTEXT_FLOATING_POINT (DT_CONTEXT_LOONGARCH64 | 0x4L) +#define DT_CONTEXT_DEBUG_REGISTERS (DT_CONTEXT_LOONGARCH64 | 0x8L) + +#define DT_CONTEXT_FULL (DT_CONTEXT_CONTROL | DT_CONTEXT_INTEGER | DT_CONTEXT_FLOATING_POINT) +#define DT_CONTEXT_ALL (DT_CONTEXT_CONTROL | DT_CONTEXT_INTEGER | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_DEBUG_REGISTERS) + +#define DT_LOONGARCH64_MAX_BREAKPOINTS 8 +#define DT_LOONGARCH64_MAX_WATCHPOINTS 2 + +typedef DECLSPEC_ALIGN(16) struct { + // + // Control flags. + // + + /* +0x000 */ DWORD ContextFlags; + + // + // Integer registers + // + DWORD64 R0; + DWORD64 RA; + DWORD64 TP; + DWORD64 SP; + DWORD64 A0; + DWORD64 A1; + DWORD64 A2; + DWORD64 A3; + DWORD64 A4; + DWORD64 A5; + DWORD64 A6; + DWORD64 A7; + DWORD64 T0; + DWORD64 T1; + DWORD64 T2; + DWORD64 T3; + DWORD64 T4; + DWORD64 T5; + DWORD64 T6; + DWORD64 T7; + DWORD64 T8; + DWORD64 X0; + DWORD64 FP; + DWORD64 S0; + DWORD64 S1; + DWORD64 S2; + DWORD64 S3; + DWORD64 S4; + DWORD64 S5; + DWORD64 S6; + DWORD64 S7; + DWORD64 S8; + DWORD64 PC; + + // + // Floating Point Registers + // + DWORD64 F0; + DWORD64 F1; + DWORD64 F2; + DWORD64 F3; + DWORD64 F4; + DWORD64 F5; + DWORD64 F6; + DWORD64 F7; + DWORD64 F8; + DWORD64 F9; + DWORD64 F10; + DWORD64 F11; + DWORD64 F12; + DWORD64 F13; + DWORD64 F14; + DWORD64 F15; + DWORD64 F16; + DWORD64 F17; + DWORD64 F18; + DWORD64 F19; + DWORD64 F20; + DWORD64 F21; + DWORD64 F22; + DWORD64 F23; + DWORD64 F24; + DWORD64 F25; + DWORD64 F26; + DWORD64 F27; + DWORD64 F28; + DWORD64 F29; + DWORD64 F30; + DWORD64 F31; +} DT_CONTEXT; + #else #error Unsupported platform #endif diff --git a/src/coreclr/debug/inc/loongarch64/primitives.h b/src/coreclr/debug/inc/loongarch64/primitives.h new file mode 100644 index 00000000000000..71a29defcabd98 --- /dev/null +++ b/src/coreclr/debug/inc/loongarch64/primitives.h @@ -0,0 +1,267 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Copyright (c) Loongson Technology. All rights reserved. + +//***************************************************************************** +// File: primitives.h +// + +// +// Platform-specific debugger primitives +// +//***************************************************************************** + +#ifndef PRIMITIVES_H_ +#define PRIMITIVES_H_ + +typedef const BYTE CORDB_ADDRESS_TYPE; +typedef DPTR(CORDB_ADDRESS_TYPE) PTR_CORDB_ADDRESS_TYPE; + +#define MAX_INSTRUCTION_LENGTH 4 + +// Given a return address retrieved during stackwalk, +// this is the offset by which it should be decremented to land at the call instruction. +#define STACKWALK_CONTROLPC_ADJUST_OFFSET 8 + +#define PRD_TYPE LONG +#define CORDbg_BREAK_INSTRUCTION_SIZE 4 +#define CORDbg_BREAK_INSTRUCTION (LONG)0xD43E0000 + +inline CORDB_ADDRESS GetPatchEndAddr(CORDB_ADDRESS patchAddr) +{ + LIMITED_METHOD_DAC_CONTRACT; + return patchAddr + CORDbg_BREAK_INSTRUCTION_SIZE; +} + +#define InitializePRDToBreakInst(_pPRD) *(_pPRD) = CORDbg_BREAK_INSTRUCTION +#define PRDIsBreakInst(_pPRD) (*(_pPRD) == CORDbg_BREAK_INSTRUCTION) + + +#define CORDbgGetInstructionEx(_buffer, _requestedAddr, _patchAddr, _dummy1, _dummy2) \ + CORDbgGetInstructionExImpl((CORDB_ADDRESS_TYPE *)((_buffer) + (_patchAddr) - (_requestedAddr))); + +#define CORDbgSetInstructionEx(_buffer, _requestedAddr, _patchAddr, _opcode, _dummy2) \ + CORDbgSetInstructionExImpl((CORDB_ADDRESS_TYPE *)((_buffer) + (_patchAddr) - (_requestedAddr)), (_opcode)); + +#define CORDbgInsertBreakpointEx(_buffer, _requestedAddr, _patchAddr, _dummy1, _dummy2) \ + CORDbgInsertBreakpointExImpl((CORDB_ADDRESS_TYPE *)((_buffer) + (_patchAddr) - (_requestedAddr))); + + +constexpr CorDebugRegister g_JITToCorDbgReg[] = +{ + REGISTER_LOONGARCH64_R0, + REGISTER_LOONGARCH64_RA, + REGISTER_LOONGARCH64_TP, + REGISTER_LOONGARCH64_SP, + REGISTER_LOONGARCH64_A0, + REGISTER_LOONGARCH64_A1, + REGISTER_LOONGARCH64_A2, + REGISTER_LOONGARCH64_A3, + REGISTER_LOONGARCH64_A4, + REGISTER_LOONGARCH64_A5, + REGISTER_LOONGARCH64_A6, + REGISTER_LOONGARCH64_A7, + REGISTER_LOONGARCH64_T0, + REGISTER_LOONGARCH64_T1, + REGISTER_LOONGARCH64_T2, + REGISTER_LOONGARCH64_T3, + REGISTER_LOONGARCH64_T4, + REGISTER_LOONGARCH64_T5, + REGISTER_LOONGARCH64_T6, + REGISTER_LOONGARCH64_T7, + REGISTER_LOONGARCH64_T8, + REGISTER_LOONGARCH64_X0, + REGISTER_LOONGARCH64_FP, + REGISTER_LOONGARCH64_S0, + REGISTER_LOONGARCH64_S1, + REGISTER_LOONGARCH64_S2, + REGISTER_LOONGARCH64_S3, + REGISTER_LOONGARCH64_S4, + REGISTER_LOONGARCH64_S5, + REGISTER_LOONGARCH64_S6, + REGISTER_LOONGARCH64_S7, + REGISTER_LOONGARCH64_S8, + REGISTER_LOONGARCH64_PC +}; + +inline void CORDbgSetIP(DT_CONTEXT *context, LPVOID eip) { + LIMITED_METHOD_CONTRACT; + + context->PC = (DWORD64)eip; +} + +inline LPVOID CORDbgGetSP(const DT_CONTEXT * context) { + LIMITED_METHOD_CONTRACT; + + return (LPVOID)(size_t)(context->SP); +} + +inline void CORDbgSetSP(DT_CONTEXT *context, LPVOID esp) { + LIMITED_METHOD_CONTRACT; + + context->SP = (DWORD64)esp; +} + +inline LPVOID CORDbgGetFP(const DT_CONTEXT * context) { + LIMITED_METHOD_CONTRACT; + + return (LPVOID)(size_t)(context->FP); +} + +inline void CORDbgSetFP(DT_CONTEXT *context, LPVOID fp) { + LIMITED_METHOD_CONTRACT; + + context->FP = (DWORD64)fp; +} + + +inline BOOL CompareControlRegisters(const DT_CONTEXT * pCtx1, const DT_CONTEXT * pCtx2) +{ + LIMITED_METHOD_DAC_CONTRACT; + + // @LOONGARCHTODO: Sort out frame registers + + if ((pCtx1->PC == pCtx2->PC) && + (pCtx1->SP == pCtx2->SP) && + (pCtx1->FP == pCtx2->FP)) + { + return TRUE; + } + + return FALSE; +} + +inline void CORDbgSetInstruction(CORDB_ADDRESS_TYPE* address, + PRD_TYPE instruction) +{ + // In a DAC build, this function assumes the input is an host address. + LIMITED_METHOD_DAC_CONTRACT; + + ULONGLONG ptraddr = dac_cast(address); + *(PRD_TYPE *)ptraddr = instruction; + FlushInstructionCache(GetCurrentProcess(), + address, + sizeof(PRD_TYPE)); +} + +inline PRD_TYPE CORDbgGetInstruction(UNALIGNED CORDB_ADDRESS_TYPE* address) +{ + LIMITED_METHOD_CONTRACT; + + ULONGLONG ptraddr = dac_cast(address); + return *(PRD_TYPE *)ptraddr; +} + +// +// Mapping from ICorDebugInfo register numbers to CorDebugRegister +// numbers. Note: this must match the order in corinfo.h. +// +inline CorDebugRegister ConvertRegNumToCorDebugRegister(ICorDebugInfo::RegNum reg) +{ + LIMITED_METHOD_CONTRACT; + _ASSERTE(reg >= 0); + _ASSERTE(static_cast(reg) < ARRAY_SIZE(g_JITToCorDbgReg)); + return g_JITToCorDbgReg[reg]; +} + +inline LPVOID CORDbgGetIP(DT_CONTEXT *context) +{ + LIMITED_METHOD_CONTRACT; + + return (LPVOID)(size_t)(context->PC); +} + +inline void CORDbgSetInstructionExImpl(CORDB_ADDRESS_TYPE* address, + PRD_TYPE instruction) +{ + LIMITED_METHOD_DAC_CONTRACT; + + *(PRD_TYPE *)address = instruction; + FlushInstructionCache(GetCurrentProcess(), + address, + sizeof(PRD_TYPE)); +} + +inline PRD_TYPE CORDbgGetInstructionExImpl(UNALIGNED CORDB_ADDRESS_TYPE* address) +{ + LIMITED_METHOD_CONTRACT; + + return *(PRD_TYPE *)address; +} + +inline void CORDbgInsertBreakpoint(UNALIGNED CORDB_ADDRESS_TYPE *address) +{ + LIMITED_METHOD_CONTRACT; + + CORDbgSetInstruction(address, CORDbg_BREAK_INSTRUCTION); +} + +inline void CORDbgInsertBreakpointExImpl(UNALIGNED CORDB_ADDRESS_TYPE *address) +{ + LIMITED_METHOD_CONTRACT; + + CORDbgSetInstruction(address, CORDbg_BREAK_INSTRUCTION); +} + +// After a breakpoint exception, the CPU points to _after_ the break instruction. +// Adjust the IP so that it points at the break instruction. This lets us patch that +// opcode and re-excute what was underneath the bp. +inline void CORDbgAdjustPCForBreakInstruction(DT_CONTEXT* pContext) +{ + LIMITED_METHOD_CONTRACT; + + // @LOONGARCHTODO: LOONGARCH appears to leave the PC at the start of the breakpoint (at least according to Windbg, + // which may be adjusting the view). + return; +} + +inline bool AddressIsBreakpoint(CORDB_ADDRESS_TYPE* address) +{ + LIMITED_METHOD_CONTRACT; + + return CORDbgGetInstruction(address) == CORDbg_BREAK_INSTRUCTION; +} + +inline void SetSSFlag(DT_CONTEXT *pContext) +{ +assert(!"unimplemented on LOONGARCH yet"); + _ASSERTE(pContext != NULL); +// pContext->Cpsr |= 0x00200000; +} + +inline void UnsetSSFlag(DT_CONTEXT *pContext) +{ +assert(!"unimplemented on LOONGARCH yet"); + _ASSERTE(pContext != NULL); +// pContext->Cpsr &= ~0x00200000; +} + +inline bool IsSSFlagEnabled(DT_CONTEXT * pContext) +{ +assert(!"unimplemented on LOONGARCH yet"); + _ASSERTE(pContext != NULL); +// return (pContext->Cpsr & 0x00200000) != 0; + return false; +} + + +inline bool PRDIsEqual(PRD_TYPE p1, PRD_TYPE p2) +{ + return p1 == p2; +} + +inline void InitializePRD(PRD_TYPE *p1) +{ + *p1 = 0; +} + +inline bool PRDIsEmpty(PRD_TYPE p1) +{ + LIMITED_METHOD_CONTRACT; + + return p1 == 0; +} + +#endif // PRIMITIVES_H_ diff --git a/src/coreclr/debug/shared/loongarch64/primitives.cpp b/src/coreclr/debug/shared/loongarch64/primitives.cpp new file mode 100644 index 00000000000000..f46c04aa558925 --- /dev/null +++ b/src/coreclr/debug/shared/loongarch64/primitives.cpp @@ -0,0 +1,90 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Copyright (c) Loongson Technology. All rights reserved. + +//***************************************************************************** +// File: primitives.cpp +// + +// +// Platform-specific debugger primitives +// +//***************************************************************************** + +#include "primitives.h" + + +// +// CopyThreadContext() does an intelligent copy from pSrc to pDst, +// respecting the ContextFlags of both contexts. +// +void CORDbgCopyThreadContext(DT_CONTEXT* pDst, const DT_CONTEXT* pSrc) +{ + _ASSERTE(!"=====Not implements for loongarch64. --1"); + + DWORD dstFlags = pDst->ContextFlags; + DWORD srcFlags = pSrc->ContextFlags; + LOG((LF_CORDB, LL_INFO1000000, + "CP::CTC: pDst=0x%08x dstFlags=0x%x, pSrc=0x%08x srcFlags=0x%x\n", + pDst, dstFlags, pSrc, srcFlags)); + +#if 0 + if ((dstFlags & srcFlags & DT_CONTEXT_CONTROL) == DT_CONTEXT_CONTROL) + { + CopyContextChunk(&(pDst->Fp), &(pSrc->Fp), &(pDst->V), + DT_CONTEXT_CONTROL); + CopyContextChunk(&(pDst->Cpsr), &(pSrc->Cpsr), &(pDst->X), + DT_CONTEXT_CONTROL); + } + + if ((dstFlags & srcFlags & DT_CONTEXT_INTEGER) == DT_CONTEXT_INTEGER) + CopyContextChunk(&(pDst->X[0]), &(pSrc->X[0]), &(pDst->Fp), + DT_CONTEXT_INTEGER); + + if ((dstFlags & srcFlags & DT_CONTEXT_FLOATING_POINT) == DT_CONTEXT_FLOATING_POINT) + CopyContextChunk(&(pDst->V[0]), &(pSrc->V[0]), &(pDst->Bcr[0]), + DT_CONTEXT_FLOATING_POINT); + + if ((dstFlags & srcFlags & DT_CONTEXT_DEBUG_REGISTERS) == + DT_CONTEXT_DEBUG_REGISTERS) + CopyContextChunk(&(pDst->Bcr[0]), &(pSrc->Bcr[0]), &(pDst->Wvr[LOONGARCH64_MAX_WATCHPOINTS]), + DT_CONTEXT_DEBUG_REGISTERS); +#endif +} + +#if defined(ALLOW_VMPTR_ACCESS) || !defined(RIGHT_SIDE_COMPILE) +void SetDebuggerREGDISPLAYFromREGDISPLAY(DebuggerREGDISPLAY* pDRD, REGDISPLAY* pRD) +{ + _ASSERTE(!"=====Not implements for loongarch64. --2"); + SUPPORTS_DAC_HOST_ONLY; + + DT_CONTEXT* pContext = reinterpret_cast(pRD->pCurrentContext); + + // We must pay attention to the context flags so that we only use valid portions + // of the context. + DWORD flags = pContext->ContextFlags; + if ((flags & DT_CONTEXT_CONTROL) == DT_CONTEXT_CONTROL) + { + pDRD->FP = (SIZE_T)CORDbgGetFP(pContext); + pDRD->PC = (SIZE_T)pContext->PC; + } + +#if 0 + if ((flags & DT_CONTEXT_INTEGER) == DT_CONTEXT_INTEGER) + { + for(int i = 0 ; i < 29 ; i++) + { + pDRD->X[i] = (SIZE_T)pContext->X[i]; + } + } +#endif + + pDRD->SP = pRD->SP; + + LOG( (LF_CORDB, LL_INFO1000, "DT::TASSC:Registers:" + "SP = %x", + pDRD->SP) ); +} +#endif // ALLOW_VMPTR_ACCESS || !RIGHT_SIDE_COMPILE diff --git a/src/coreclr/debug/shim/debugshim.cpp b/src/coreclr/debug/shim/debugshim.cpp index b86c8eb0cfcc3a..dd2ff1895b2d40 100644 --- a/src/coreclr/debug/shim/debugshim.cpp +++ b/src/coreclr/debug/shim/debugshim.cpp @@ -21,6 +21,10 @@ #define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian #endif +#ifndef IMAGE_FILE_MACHINE_LOONGARCH64 +#define IMAGE_FILE_MACHINE_LOONGARCH64 0xDD64 // LOONGARCH64 Little-Endian +#endif + //***************************************************************************** // CLRDebuggingImpl implementation (ICLRDebugging) //***************************************************************************** @@ -648,6 +652,8 @@ HRESULT CLRDebuggingImpl::FormatLongDacModuleName(__out_z __inout_ecount(cchBuff const WCHAR* pHostArch = W("arm"); #elif defined(HOST_ARM64) const WCHAR* pHostArch = W("arm64"); +#elif defined(HOST_LOONGARCH64) + const WCHAR* pHostArch = W("loongarch64"); #else _ASSERTE(!"Unknown host arch"); return E_NOTIMPL; @@ -681,6 +687,10 @@ HRESULT CLRDebuggingImpl::FormatLongDacModuleName(__out_z __inout_ecount(cchBuff { pTargetArch = W("arm64"); } + else if(targetImageFileMachine == IMAGE_FILE_MACHINE_LOONGARCH64) + { + pTargetArch = W("loongarch64"); + } else { _ASSERTE(!"Unknown target image file machine type"); diff --git a/src/coreclr/enablesanitizers.sh b/src/coreclr/enablesanitizers.sh index c79ef8c69ddf3f..7e8c4b9d7c4e0b 100755 --- a/src/coreclr/enablesanitizers.sh +++ b/src/coreclr/enablesanitizers.sh @@ -73,6 +73,11 @@ else __ClangMinorVersion=9 __ExportSymbolizerPath=0 ;; + clang8.0) + __ClangMajorVersion=8 + __ClangMinorVersion=0 + __ExportSymbolizerPath=0 + ;; *) echo "Unknown arg: $i" return 1 diff --git a/src/coreclr/gc/env/gcenv.base.h b/src/coreclr/gc/env/gcenv.base.h index 59f01879d2ff19..3486769a51060a 100644 --- a/src/coreclr/gc/env/gcenv.base.h +++ b/src/coreclr/gc/env/gcenv.base.h @@ -230,6 +230,11 @@ typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(void* lpThreadParameter); #define MemoryBarrier __sync_synchronize #endif // __arm__ || __aarch64__ +#ifdef __loongarch64 + #define YieldProcessor() __asm__ volatile( "dbar 0; \n") + #define MemoryBarrier __sync_synchronize +#endif // __loongarch64 + #endif // _MSC_VER #ifdef _MSC_VER diff --git a/src/coreclr/gc/env/gcenv.interlocked.inl b/src/coreclr/gc/env/gcenv.interlocked.inl index 549b5d35909fed..03d487a5320170 100644 --- a/src/coreclr/gc/env/gcenv.interlocked.inl +++ b/src/coreclr/gc/env/gcenv.interlocked.inl @@ -17,6 +17,9 @@ __forceinline void Interlocked::ArmInterlockedOperationBarrier() // See PAL_ArmInterlockedOperationBarrier() in the PAL __sync_synchronize(); #endif // HOST_ARM64 +#ifdef HOST_LOONGARCH64 + __sync_synchronize(); +#endif //HOST_LOONGARCH64 } #endif // !_MSC_VER diff --git a/src/coreclr/gc/env/volatile.h b/src/coreclr/gc/env/volatile.h index b47ff3847d4455..c55b304b960c16 100644 --- a/src/coreclr/gc/env/volatile.h +++ b/src/coreclr/gc/env/volatile.h @@ -66,14 +66,16 @@ #error The Volatile type is currently only defined for Visual C++ and GNU C++ #endif -#if defined(__GNUC__) && !defined(HOST_X86) && !defined(HOST_AMD64) && !defined(HOST_ARM) && !defined(HOST_ARM64) && !defined(HOST_WASM) -#error The Volatile type is currently only defined for GCC when targeting x86, AMD64, ARM, ARM64 or Wasm +#if defined(__GNUC__) && !defined(HOST_X86) && !defined(HOST_AMD64) && !defined(HOST_ARM) && !defined(HOST_ARM64) && !defined(HOST_LOONGARCH64) && !defined(HOST_WASM) +#error The Volatile type is currently only defined for GCC when targeting x86, AMD64, ARM, ARM64, LOONGARCH64 or Wasm #endif #if defined(__GNUC__) #if defined(HOST_ARM) || defined(HOST_ARM64) // This is functionally equivalent to the MemoryBarrier() macro used on ARM on Windows. #define VOLATILE_MEMORY_BARRIER() asm volatile ("dmb ish" : : : "memory") +#elif defined(HOST_LOONGARCH64) +#define VOLATILE_MEMORY_BARRIER() asm volatile ("dbar 0 " : : : "memory") #else // // For GCC, we prevent reordering by the compiler by inserting the following after a volatile diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index ace66eac266709..cced07b47c1b43 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -5916,6 +5916,14 @@ extern "C" uint64_t __rdtsc(); #else // _MSC_VER extern "C" ptrdiff_t get_cycle_count(void); #endif // _MSC_VER +#elif defined(TARGET_LOONGARCH64) + static ptrdiff_t get_cycle_count() + { + ////FIXME: TODO for LOONGARCH64: + //ptrdiff_t cycle; + __asm__ volatile ("break \n"); + return 0; + } #else static ptrdiff_t get_cycle_count() { diff --git a/src/coreclr/gc/unix/gcenv.unix.cpp b/src/coreclr/gc/unix/gcenv.unix.cpp index 895d2afdf395a9..688e30613fb28e 100644 --- a/src/coreclr/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/gc/unix/gcenv.unix.cpp @@ -98,6 +98,8 @@ extern "C" # define __NR_membarrier 389 # elif defined(__aarch64__) # define __NR_membarrier 283 +# elif defined(__loongarch64) +# define __NR_membarrier 283 # elif # error Unknown architecture # endif @@ -159,7 +161,7 @@ FOR_ALL_NUMA_FUNCTIONS #endif // HAVE_NUMA_H -#if defined(HOST_ARM) || defined(HOST_ARM64) +#if defined(HOST_ARM) || defined(HOST_ARM64) || defined(HOST_LOONGARCH64) #define SYSCONF_GET_NUMPROCS _SC_NPROCESSORS_CONF #else #define SYSCONF_GET_NUMPROCS _SC_NPROCESSORS_ONLN diff --git a/src/coreclr/gcdump/gcdumpnonx86.cpp b/src/coreclr/gcdump/gcdumpnonx86.cpp index 235c8bf24acb11..d9790a12d60e2e 100644 --- a/src/coreclr/gcdump/gcdumpnonx86.cpp +++ b/src/coreclr/gcdump/gcdumpnonx86.cpp @@ -69,7 +69,9 @@ PCSTR GetRegName (UINT32 regnum) static CHAR szRegName[16]; _snprintf_s(szRegName, ARRAY_SIZE(szRegName), sizeof(szRegName), "r%u", regnum); return szRegName; - +#elif defined(TARGET_LOONGARCH64) + assert(!"unimplemented on LOONGARCH yet"); + return "???"; #endif } diff --git a/src/coreclr/gcinfo/gcinfodumper.cpp b/src/coreclr/gcinfo/gcinfodumper.cpp index 3ea383832046b3..7e49018353d714 100644 --- a/src/coreclr/gcinfo/gcinfodumper.cpp +++ b/src/coreclr/gcinfo/gcinfodumper.cpp @@ -186,6 +186,44 @@ BOOL GcInfoDumper::ReportPointerRecord ( REG(Lr, Lr), { FIELD_OFFSET(T_CONTEXT, Sp) }, #undef REG +#elif defined(TARGET_LOONGARCH64) +#undef REG +#define REG(reg, field) { FIELD_OFFSET(Loongarch64VolatileContextPointer, field) } + REG(zero, R0), + REG(a0, A0), + REG(a1, A1), + REG(a2, A2), + REG(a3, A3), + REG(a4, A4), + REG(a5, A5), + REG(a6, A6), + REG(a7, A7), + REG(t0, T0), + REG(t1, T1), + REG(t2, T2), + REG(t3, T3), + REG(t4, T4), + REG(t5, T5), + REG(t6, T6), + REG(t7, T7), + REG(t8, T8), + REG(x0, X0), +#undef REG +#define REG(reg, field) { FIELD_OFFSET(T_KNONVOLATILE_CONTEXT_POINTERS, field) } + REG(s0, S0), + REG(s1, S1), + REG(s2, S2), + REG(s3, S3), + REG(s4, S4), + REG(s5, S5), + REG(s6, S6), + REG(s7, S7), + REG(s8, S8), + REG(tp, Tp), + REG(fp, Fp), + REG(ra, Ra), + { FIELD_OFFSET(T_CONTEXT, Sp) }, +#undef REG #else PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this platform.") #endif @@ -207,10 +245,16 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this #elif defined(TARGET_ARM) iSPRegister = (FIELD_OFFSET(T_CONTEXT, Sp) - FIELD_OFFSET(T_CONTEXT, R0)) / sizeof(ULONG); UINT iBFRegister = m_StackBaseRegister; +#elif defined(TARGET_LOONGARCH64) + assert(!"unimplemented on LOONGARCH yet"); + iSPRegister = 0; #endif #if defined(TARGET_ARM) || defined(TARGET_ARM64) BYTE* pContext = (BYTE*)&(pRD->volatileCurrContextPointers); +#elif defined(TARGET_LOONGARCH64) + assert(!"unimplemented on LOONGARCH yet"); + BYTE* pContext = (BYTE*)pRD->pCurrentContext; #else BYTE* pContext = (BYTE*)pRD->pCurrentContext; #endif @@ -277,6 +321,8 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this { break; } +#elif defined(TARGET_LOONGARCH64) + assert(!"unimplemented on LOONGARCH yet"); #endif { _ASSERTE(iReg < nCONTEXTRegisters); @@ -301,6 +347,9 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this { pReg = (SIZE_T*)((BYTE*)pRD->pCurrentContext + rgRegisters[iReg].cbContextOffset); } +#elif defined(TARGET_LOONGARCH64) + assert(!"unimplemented on LOONGARCH yet"); + pReg = (SIZE_T*)(pContext + rgRegisters[iReg].cbContextOffset); #else pReg = (SIZE_T*)(pContext + rgRegisters[iReg].cbContextOffset); #endif @@ -370,6 +419,10 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this { #if defined(TARGET_ARM) || defined(TARGET_ARM64) base = GC_SP_REL; +#elif defined(TARGET_LOONGARCH64) + assert(!"unimplemented on LOONGARCH yet"); + //TODO: should confirm ? + base = GC_SP_REL; #else if (0 == ctx) base = GC_SP_REL; @@ -399,6 +452,8 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this #if defined(TARGET_ARM) || defined(TARGET_ARM64) pContext = (BYTE*)pRD->pCurrentContextPointers; +#elif defined(TARGET_LOONGARCH64) + assert(!"unimplemented on LOONGARCH yet"); #else pContext = (BYTE*)pRD->pCallerContext; #endif @@ -602,6 +657,9 @@ GcInfoDumper::EnumerateStateChangesResults GcInfoDumper::EnumerateStateChanges ( { *(ppVolatileReg+iReg) = ®disp.pCurrentContext->X0 + iReg; } +#elif defined(TARGET_LOONGARCH64) +#pragma message("Unimplemented for LOONGARCH64 yet.") + assert(!"unimplemented on LOONGARCH yet"); #else PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on this platform.") #endif @@ -649,9 +707,9 @@ PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on th (GcInfoDecoderFlags)( DECODE_SECURITY_OBJECT | DECODE_CODE_LENGTH | DECODE_VARARG -#if defined(TARGET_ARM) || defined(TARGET_ARM64) +#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) | DECODE_HAS_TAILCALLS -#endif // TARGET_ARM || TARGET_ARM64 +#endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64 | DECODE_INTERRUPTIBILITY), offset); @@ -672,6 +730,9 @@ PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on th UINT32 safePointOffset = offset; #if defined(TARGET_AMD64) || defined(TARGET_ARM) || defined(TARGET_ARM64) safePointOffset++; +#elif defined(TARGET_LOONGARCH64) +#pragma message("Unimplemented for LOONGARCH64 yet.") + assert(!"unimplemented on LOONGARCH yet"); #endif if(safePointDecoder.IsSafePoint(safePointOffset)) { diff --git a/src/coreclr/gcinfo/gcinfoencoder.cpp b/src/coreclr/gcinfo/gcinfoencoder.cpp index 8be8b262f1a4a1..19e914676b2f81 100644 --- a/src/coreclr/gcinfo/gcinfoencoder.cpp +++ b/src/coreclr/gcinfo/gcinfoencoder.cpp @@ -487,7 +487,7 @@ GcInfoEncoder::GcInfoEncoder( m_ReversePInvokeFrameSlot = NO_REVERSE_PINVOKE_FRAME; #ifdef TARGET_AMD64 m_WantsReportOnlyLeaf = false; -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) m_HasTailCalls = false; #endif // TARGET_AMD64 m_IsVarArg = false; @@ -747,6 +747,9 @@ void GcInfoEncoder::SetStackBaseRegister( UINT32 regNum ) _ASSERTE( regNum != NO_STACK_BASE_REGISTER ); _ASSERTE(DENORMALIZE_STACK_BASE_REGISTER(NORMALIZE_STACK_BASE_REGISTER(regNum)) == regNum); _ASSERTE( m_StackBaseRegister == NO_STACK_BASE_REGISTER || m_StackBaseRegister == regNum ); +#if defined(TARGET_LOONGARCH64) + assert(regNum == 3 || 22 == regNum); +#endif m_StackBaseRegister = regNum; } @@ -762,7 +765,7 @@ void GcInfoEncoder::SetWantsReportOnlyLeaf() { m_WantsReportOnlyLeaf = true; } -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) void GcInfoEncoder::SetHasTailCalls() { m_HasTailCalls = true; @@ -1017,7 +1020,7 @@ void GcInfoEncoder::Build() (m_SizeOfEditAndContinuePreservedArea == NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA) && #ifdef TARGET_AMD64 !m_WantsReportOnlyLeaf && -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) !m_HasTailCalls && #endif // TARGET_AMD64 !IsStructReturnKind(m_ReturnKind); @@ -1028,6 +1031,9 @@ void GcInfoEncoder::Build() { // Slim encoding means nothing special, partially interruptible, maybe a default frame register GCINFO_WRITE(m_Info1, 0, 1, FlagsSize); // Slim encoding +#if defined(TARGET_LOONGARCH64) + assert(m_StackBaseRegister == 22 || 3 == m_StackBaseRegister); +#endif GCINFO_WRITE(m_Info1, (m_StackBaseRegister == NO_STACK_BASE_REGISTER) ? 0 : 1, 1, FlagsSize); GCINFO_WRITE(m_Info1, m_ReturnKind, SIZE_OF_RETURN_KIND_IN_SLIM_HEADER, RetKindSize); @@ -1040,10 +1046,13 @@ void GcInfoEncoder::Build() GCINFO_WRITE(m_Info1, (hasGSCookie ? 1 : 0), 1, FlagsSize); GCINFO_WRITE(m_Info1, ((m_PSPSymStackSlot != NO_PSP_SYM) ? 1 : 0), 1, FlagsSize); GCINFO_WRITE(m_Info1, m_contextParamType, 2, FlagsSize); +#if defined(TARGET_LOONGARCH64) + assert(m_StackBaseRegister == 22 || 3 == m_StackBaseRegister); +#endif GCINFO_WRITE(m_Info1, ((m_StackBaseRegister != NO_STACK_BASE_REGISTER) ? 1 : 0), 1, FlagsSize); #ifdef TARGET_AMD64 GCINFO_WRITE(m_Info1, (m_WantsReportOnlyLeaf ? 1 : 0), 1, FlagsSize); -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) GCINFO_WRITE(m_Info1, (m_HasTailCalls ? 1 : 0), 1, FlagsSize); #endif // TARGET_AMD64 GCINFO_WRITE(m_Info1, ((m_SizeOfEditAndContinuePreservedArea != NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA) ? 1 : 0), 1, FlagsSize); @@ -1140,6 +1149,9 @@ void GcInfoEncoder::Build() if(!slimHeader && (m_StackBaseRegister != NO_STACK_BASE_REGISTER)) { +#if defined(TARGET_LOONGARCH64) + assert(m_StackBaseRegister == 22 || 3 == m_StackBaseRegister); +#endif GCINFO_WRITE_VARL_U(m_Info1, NORMALIZE_STACK_BASE_REGISTER(m_StackBaseRegister), STACK_BASE_REGISTER_ENCBASE, StackBaseSize); } diff --git a/src/coreclr/inc/clrnt.h b/src/coreclr/inc/clrnt.h index a833da67bcc9b5..b56bd9ae45deca 100644 --- a/src/coreclr/inc/clrnt.h +++ b/src/coreclr/inc/clrnt.h @@ -1016,6 +1016,10 @@ RtlVirtualUnwind( #define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian #endif +#ifndef IMAGE_FILE_MACHINE_LOONGARCH64 +#define IMAGE_FILE_MACHINE_LOONGARCH64 0xDD64 // LOONGARCH64 Little-Endian +#endif + #ifndef IMAGE_REL_ARM64_BRANCH26 #define IMAGE_REL_ARM64_BRANCH26 0x0003 // 26 bit offset << 2 & sign ext. for B & BL #endif @@ -1028,6 +1032,71 @@ RtlVirtualUnwind( #define IMAGE_REL_ARM64_PAGEOFFSET_12A 0x0006 // ADD 12 bit page offset #endif +#endif // TARGET_ARM64 + +#ifdef TARGET_LOONGARCH64 +#include "daccess.h" + +#define UNW_FLAG_NHANDLER 0x0 /* any handler */ +#define UNW_FLAG_EHANDLER 0x1 /* filter handler */ +#define UNW_FLAG_UHANDLER 0x2 /* unwind handler */ + +// This function returns the RVA of the end of the function (exclusive, so one byte after the actual end) +// using the unwind info on LOONGARCH64. (see ExternalAPIs\Win9CoreSystem\inc\winnt.h) +FORCEINLINE +ULONG64 +RtlpGetFunctionEndAddress ( + __in PT_RUNTIME_FUNCTION FunctionEntry, + __in ULONG64 ImageBase + ) +{ + ULONG64 FunctionLength; + + FunctionLength = FunctionEntry->UnwindData; + if ((FunctionLength & 3) != 0) { + FunctionLength = (FunctionLength >> 2) & 0x7ff; + } else { + memcpy(&FunctionLength, (void*)(ImageBase + FunctionLength), sizeof(UINT32)); + FunctionLength &= 0x3ffff; + } + + return FunctionEntry->BeginAddress + 4 * FunctionLength; +} + +#define RUNTIME_FUNCTION__BeginAddress(FunctionEntry) ((FunctionEntry)->BeginAddress) +#define RUNTIME_FUNCTION__SetBeginAddress(FunctionEntry,address) ((FunctionEntry)->BeginAddress = (address)) + +#define RUNTIME_FUNCTION__EndAddress(FunctionEntry, ImageBase) (RtlpGetFunctionEndAddress(FunctionEntry, (ULONG64)(ImageBase))) + +#define RUNTIME_FUNCTION__SetUnwindInfoAddress(prf,address) do { (prf)->UnwindData = (address); } while (0) + +typedef struct _UNWIND_INFO { + // dummy +} UNWIND_INFO, *PUNWIND_INFO; + +EXTERN_C +NTSYSAPI +PEXCEPTION_ROUTINE +NTAPI +RtlVirtualUnwind( + IN ULONG HandlerType, + IN ULONG64 ImageBase, + IN ULONG64 ControlPc, + IN PRUNTIME_FUNCTION FunctionEntry, + IN OUT PCONTEXT ContextRecord, + OUT PVOID *HandlerData, + OUT PULONG64 EstablisherFrame, + IN OUT PKNONVOLATILE_CONTEXT_POINTERS ContextPointers OPTIONAL + ); + +#ifndef IMAGE_FILE_MACHINE_LOONGARCH64 +#define IMAGE_FILE_MACHINE_LOONGARCH64 0xDD64 // LOONGARCH64 Little-Endian #endif +#ifndef IMAGE_REL_LOONGARCH64_PC +#define IMAGE_REL_LOONGARCH64_PC 0x0004 +#endif + +#endif // TARGET_LOONGARCH64 + #endif // CLRNT_H_ diff --git a/src/coreclr/inc/cor.h b/src/coreclr/inc/cor.h index 8ccc151cc0378e..58a97736255e8f 100644 --- a/src/coreclr/inc/cor.h +++ b/src/coreclr/inc/cor.h @@ -2233,7 +2233,11 @@ inline ULONG CorSigCompressPointer( // return number of bytes of that compressed void * pvPointer, // [IN] given uncompressed data void * pData) // [OUT] buffer where iLen will be compressed and stored. { +#ifdef TARGET_LOONGARCH64 + memcpy(pData, &pvPointer, sizeof(void*)); +#else *((void * UNALIGNED *)pData) = pvPointer; +#endif return sizeof(void *); } @@ -2242,7 +2246,11 @@ inline ULONG CorSigUncompressPointer( // return number of bytes of that compre PCCOR_SIGNATURE pData, // [IN] compressed data void ** ppvPointer) // [OUT] the expanded *pData { +#ifdef TARGET_LOONGARCH64 + memcpy((void*)ppvPointer, (void*)pData, sizeof(void*)); +#else *ppvPointer = *(void * const UNALIGNED *)pData; +#endif return sizeof(void *); } diff --git a/src/coreclr/inc/corcompile.h b/src/coreclr/inc/corcompile.h index 3c7a7caa97a2c1..449758fb991563 100644 --- a/src/coreclr/inc/corcompile.h +++ b/src/coreclr/inc/corcompile.h @@ -185,6 +185,22 @@ inline BOOL CORCOMPILE_IS_FIXUP_TAGGED(SIZE_T fixup, PTR_CORCOMPILE_IMPORT_SECTI PCODE m_pTarget; }; +#elif defined(TARGET_LOONGARCH64) + struct CORCOMPILE_EXTERNAL_METHOD_THUNK + { + // Array of words to do the following: + // pcaddi $r21, 0 ; Save the current address relative to which we will get slot ID and address to patch. + // ld.d $r21, $r21, 16 ; Load the target address. + // jirl $r0,$r21,0 ; Jump to the target + DWORD m_rgCode[3]; + + DWORD m_padding; //aligning stack to 16 bytes + + // The target address - initially, this will point to ExternalMethodFixupStub. + // Post patchup by the stub, it will point to the actual method body. + PCODE m_pTarget; + }; + #endif // diff --git a/src/coreclr/inc/cordebug.idl b/src/coreclr/inc/cordebug.idl index 97e53150b055e0..95bc8815f58915 100644 --- a/src/coreclr/inc/cordebug.idl +++ b/src/coreclr/inc/cordebug.idl @@ -285,7 +285,8 @@ interface ICorDebugDataTarget : IUnknown CORDB_PLATFORM_POSIX_AMD64, // Posix supporting OS on Intel x64 CORDB_PLATFORM_POSIX_X86, // Posix supporting OS on Intel x86 CORDB_PLATFORM_POSIX_ARM, // Posix supporting OS on ARM32 - CORDB_PLATFORM_POSIX_ARM64 // Posix supporting OS on ARM64 + CORDB_PLATFORM_POSIX_ARM64, // Posix supporting OS on ARM64 + CORDB_PLATFORM_POSIX_LOONGARCH64 // Posix supporting OS on LOONGARCH64 } CorDebugPlatform; HRESULT GetPlatform([out] CorDebugPlatform * pTargetPlatform); @@ -3917,6 +3918,74 @@ interface ICorDebugRegisterSet : IUnknown REGISTER_ARM64_V30, REGISTER_ARM64_V31, + // LOONGARCH64 registers + REGISTER_LOONGARCH64_R0 = 0, + REGISTER_LOONGARCH64_RA, + REGISTER_LOONGARCH64_TP, + REGISTER_LOONGARCH64_SP, + REGISTER_LOONGARCH64_A0, + REGISTER_LOONGARCH64_A1, + REGISTER_LOONGARCH64_A2, + REGISTER_LOONGARCH64_A3, + REGISTER_LOONGARCH64_A4, + REGISTER_LOONGARCH64_A5, + REGISTER_LOONGARCH64_A6, + REGISTER_LOONGARCH64_A7, + REGISTER_LOONGARCH64_T0, + REGISTER_LOONGARCH64_T1, + REGISTER_LOONGARCH64_T2, + REGISTER_LOONGARCH64_T3, + REGISTER_LOONGARCH64_T4, + REGISTER_LOONGARCH64_T5, + REGISTER_LOONGARCH64_T6, + REGISTER_LOONGARCH64_T7, + REGISTER_LOONGARCH64_T8, + REGISTER_LOONGARCH64_X0, + REGISTER_LOONGARCH64_FP, + REGISTER_LOONGARCH64_S0, + REGISTER_LOONGARCH64_S1, + REGISTER_LOONGARCH64_S2, + REGISTER_LOONGARCH64_S3, + REGISTER_LOONGARCH64_S4, + REGISTER_LOONGARCH64_S5, + REGISTER_LOONGARCH64_S6, + REGISTER_LOONGARCH64_S7, + REGISTER_LOONGARCH64_S8, + REGISTER_LOONGARCH64_PC, + + REGISTER_LOONGARCH64_F0, + REGISTER_LOONGARCH64_F1, + REGISTER_LOONGARCH64_F2, + REGISTER_LOONGARCH64_F3, + REGISTER_LOONGARCH64_F4, + REGISTER_LOONGARCH64_F5, + REGISTER_LOONGARCH64_F6, + REGISTER_LOONGARCH64_F7, + REGISTER_LOONGARCH64_F8, + REGISTER_LOONGARCH64_F9, + REGISTER_LOONGARCH64_F10, + REGISTER_LOONGARCH64_F11, + REGISTER_LOONGARCH64_F12, + REGISTER_LOONGARCH64_F13, + REGISTER_LOONGARCH64_F14, + REGISTER_LOONGARCH64_F15, + REGISTER_LOONGARCH64_F16, + REGISTER_LOONGARCH64_F17, + REGISTER_LOONGARCH64_F18, + REGISTER_LOONGARCH64_F19, + REGISTER_LOONGARCH64_F20, + REGISTER_LOONGARCH64_F21, + REGISTER_LOONGARCH64_F22, + REGISTER_LOONGARCH64_F23, + REGISTER_LOONGARCH64_F24, + REGISTER_LOONGARCH64_F25, + REGISTER_LOONGARCH64_F26, + REGISTER_LOONGARCH64_F27, + REGISTER_LOONGARCH64_F28, + REGISTER_LOONGARCH64_F29, + REGISTER_LOONGARCH64_F30, + REGISTER_LOONGARCH64_F31, + // other architectures here } CorDebugRegister; diff --git a/src/coreclr/inc/cordebuginfo.h b/src/coreclr/inc/cordebuginfo.h index e2683d36ddcd79..cc411cfd3193a3 100644 --- a/src/coreclr/inc/cordebuginfo.h +++ b/src/coreclr/inc/cordebuginfo.h @@ -145,6 +145,40 @@ class ICorDebugInfo REGNUM_R13, REGNUM_R14, REGNUM_R15, +#elif TARGET_LOONGARCH64 + REGNUM_R0, + REGNUM_RA, + REGNUM_TP, + REGNUM_SP, + REGNUM_A0, + REGNUM_A1, + REGNUM_A2, + REGNUM_A3, + REGNUM_A4, + REGNUM_A5, + REGNUM_A6, + REGNUM_A7, + REGNUM_T0, + REGNUM_T1, + REGNUM_T2, + REGNUM_T3, + REGNUM_T4, + REGNUM_T5, + REGNUM_T6, + REGNUM_T7, + REGNUM_T8, + REGNUM_X0, + REGNUM_FP, + REGNUM_S0, + REGNUM_S1, + REGNUM_S2, + REGNUM_S3, + REGNUM_S4, + REGNUM_S5, + REGNUM_S6, + REGNUM_S7, + REGNUM_S8, + REGNUM_PC, #else PORTABILITY_WARNING("Register numbers not defined on this platform") #endif @@ -165,6 +199,8 @@ class ICorDebugInfo #endif //REDHAWK #elif TARGET_ARM64 //Nothing to do here. FP is already alloted. +#elif TARGET_LOONGARCH64 + //Nothing to do here. FP is already alloted. #else // RegNum values should be properly defined for this platform REGNUM_FP = 0, diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index f6f341e56f32a6..5dfa0c2d276aa4 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2712,6 +2712,9 @@ class ICorStaticInfo CORINFO_SIG_INFO* sig, /* IN */ CORINFO_ARG_LIST_HANDLE args, /* IN */ CORINFO_CLASS_HANDLE *vcTypeRet /* OUT */ +#if defined(TARGET_LOONGARCH64) + ,int *flags = NULL +#endif ) = 0; // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it @@ -2848,6 +2851,7 @@ class ICorStaticInfo /* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr ) = 0; + virtual uint32_t getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) = 0; }; /***************************************************************************** diff --git a/src/coreclr/inc/corinfoinstructionset.h b/src/coreclr/inc/corinfoinstructionset.h index 39003cb7398521..fb2964ea42fa82 100644 --- a/src/coreclr/inc/corinfoinstructionset.h +++ b/src/coreclr/inc/corinfoinstructionset.h @@ -114,6 +114,11 @@ enum CORINFO_InstructionSet InstructionSet_AVXVNNI_X64=36, #endif // TARGET_X86 +#ifdef TARGET_LOONGARCH64 + InstructionSet_Base=1, // Base instructions available on all LOONGARCH64 platforms + InstructionSet_Atomics=2, // ll/sc +#endif //TARGET_LOONGARCH64 + }; struct CORINFO_InstructionSetFlags diff --git a/src/coreclr/inc/crosscomp.h b/src/coreclr/inc/crosscomp.h index 84b6f81606f3fa..b3efdc4d5f9701 100644 --- a/src/coreclr/inc/crosscomp.h +++ b/src/coreclr/inc/crosscomp.h @@ -382,6 +382,144 @@ enum #endif // TARGET_ARM64 && !HOST_ARM64 +#elif defined(HOST_AMD64) && defined(TARGET_LOONGARCH64) // Host amd64 managing LOONGARCH64 related code + +#ifndef CROSS_COMPILE +#define CROSS_COMPILE +#endif + +// +// Specify the number of breakpoints and watchpoints that the OS +// will track. Architecturally, LOONGARCH64 supports up to 16. In practice, +// however, almost no one implements more than 4 of each. +// + +#define LOONGARCH64_MAX_BREAKPOINTS 8 +#define LOONGARCH64_MAX_WATCHPOINTS 2 + +#define CONTEXT_UNWOUND_TO_CALL 0x20000000 + +typedef struct DECLSPEC_ALIGN(16) _T_CONTEXT { + + // + // Control flags. + // + + /* +0x000 */ DWORD ContextFlags; + + // + // Integer registers + // + DWORD64 R0; + DWORD64 Ra; + DWORD64 Tp; + DWORD64 Sp; + DWORD64 A0;//DWORD64 V0; + DWORD64 A1;//DWORD64 V1; + DWORD64 A2; + DWORD64 A3; + DWORD64 A4; + DWORD64 A5; + DWORD64 A6; + DWORD64 A7; + DWORD64 T0; + DWORD64 T1; + DWORD64 T2; + DWORD64 T3; + DWORD64 T4; + DWORD64 T5; + DWORD64 T6; + DWORD64 T7; + DWORD64 T8; + DWORD64 X0; + DWORD64 Fp; + DWORD64 S0; + DWORD64 S1; + DWORD64 S2; + DWORD64 S3; + DWORD64 S4; + DWORD64 S5; + DWORD64 S6; + DWORD64 S7; + DWORD64 S8; + DWORD64 Pc; + + // + // Floating Point Registers + // + //TODO: support the SIMD. + DWORD64 F[32]; + DWORD Fcsr; +} T_CONTEXT, *PT_CONTEXT; + +// _IMAGE_LOONGARCH64_RUNTIME_FUNCTION_ENTRY (see ExternalAPIs\Win9CoreSystem\inc\winnt.h) +typedef struct _T_RUNTIME_FUNCTION { + DWORD BeginAddress; + union { + DWORD UnwindData; + struct { + DWORD Flag : 2; + DWORD FunctionLength : 11; + DWORD RegF : 3; + DWORD RegI : 4; + DWORD H : 1; + DWORD CR : 2; + DWORD FrameSize : 9; + } PackedUnwindData; + }; +} T_RUNTIME_FUNCTION, *PT_RUNTIME_FUNCTION; + + +// +// Define exception dispatch context structure. +// + +typedef struct _T_DISPATCHER_CONTEXT { + DWORD64 ControlPc; + DWORD64 ImageBase; + PT_RUNTIME_FUNCTION FunctionEntry; + DWORD64 EstablisherFrame; + DWORD64 TargetPc; + PCONTEXT ContextRecord; + PEXCEPTION_ROUTINE LanguageHandler; + PVOID HandlerData; + PVOID HistoryTable; + DWORD ScopeIndex; + BOOLEAN ControlPcIsUnwound; + PBYTE NonVolatileRegisters; +} T_DISPATCHER_CONTEXT, *PT_DISPATCHER_CONTEXT; + + + +// +// Nonvolatile context pointer record. +// + +typedef struct _T_KNONVOLATILE_CONTEXT_POINTERS { + + PDWORD64 S0; + PDWORD64 S1; + PDWORD64 S2; + PDWORD64 S3; + PDWORD64 S4; + PDWORD64 S5; + PDWORD64 S6; + PDWORD64 S7; + PDWORD64 S8; + PDWORD64 Fp; + PDWORD64 Tp; + PDWORD64 Ra; + + PDWORD64 F24; + PDWORD64 F25; + PDWORD64 F26; + PDWORD64 F27; + PDWORD64 F28; + PDWORD64 F29; + PDWORD64 F30; + PDWORD64 F31; +} T_KNONVOLATILE_CONTEXT_POINTERS, *PT_KNONVOLATILE_CONTEXT_POINTERS; + #else #define T_CONTEXT CONTEXT @@ -420,6 +558,8 @@ enum #define DAC_CS_NATIVE_DATA_SIZE 80 #elif defined(TARGET_LINUX) && defined(TARGET_ARM64) #define DAC_CS_NATIVE_DATA_SIZE 116 +#elif defined(TARGET_LINUX) && defined(TARGET_LOONGARCH64) +#define DAC_CS_NATIVE_DATA_SIZE 96 #elif defined(TARGET_LINUX) && defined(TARGET_X86) #define DAC_CS_NATIVE_DATA_SIZE 76 #elif defined(TARGET_LINUX) && defined(TARGET_AMD64) diff --git a/src/coreclr/inc/cvconst.h b/src/coreclr/inc/cvconst.h index 3fbbfdd011a2cb..ff668feaee564c 100644 --- a/src/coreclr/inc/cvconst.h +++ b/src/coreclr/inc/cvconst.h @@ -41,7 +41,8 @@ typedef enum CV_call_e { CV_CALL_CLRCALL = 0x16, // clr call CV_CALL_INLINE = 0x17, // Marker for routines always inlined and thus lacking a convention CV_CALL_NEAR_VECTOR = 0x18, // near left to right push with regs, callee pops stack - CV_CALL_RESERVED = 0x19 // first unused call enumeration + CV_CALL_LOONGARCHCALL = 0x19, // loongarch call + CV_CALL_RESERVED = 0x1a // first unused call enumeration // Do NOT add any more machine specific conventions. This is to be used for // calling conventions in the source only (e.g. __cdecl, __stdcall). @@ -374,6 +375,7 @@ typedef enum CV_CPU_TYPE_e { CV_CFL_ARMNT = 0xF4, CV_CFL_ARM64 = 0xF6, CV_CFL_D3D11_SHADER = 0x100, + CV_CFL_LOONGARCH64 = 0x200, } CV_CPU_TYPE_e; typedef enum CV_HREG_e { @@ -3646,6 +3648,7 @@ typedef enum CV_HREG_e { // Note: Next set of platform registers need to go into a new enum... // this one is above 44K now. + // TODO for LOONGARCH64: ?!?!? } CV_HREG_e; diff --git a/src/coreclr/inc/eetwain.h b/src/coreclr/inc/eetwain.h index f2c51b5f724b6b..8653d5eed14cac 100644 --- a/src/coreclr/inc/eetwain.h +++ b/src/coreclr/inc/eetwain.h @@ -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) /* @@ -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) /* diff --git a/src/coreclr/inc/eexcp.h b/src/coreclr/inc/eexcp.h index 3bb4fde975f9fb..d9cdf801287559 100644 --- a/src/coreclr/inc/eexcp.h +++ b/src/coreclr/inc/eexcp.h @@ -127,7 +127,7 @@ inline BOOL IsDuplicateClause(EE_ILEXCEPTION_CLAUSE* pEHClause) return pEHClause->Flags & COR_ILEXCEPTION_CLAUSE_DUPLICATED; } -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) +#if defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) // Finally is the only EH construct that can be part of the execution as being fall-through. // // "Cloned" finally is a contruct that represents a finally block that is used as @@ -149,7 +149,7 @@ inline BOOL IsClonedFinally(EE_ILEXCEPTION_CLAUSE* pEHClause) (pEHClause->TryStartPC == pEHClause->HandlerStartPC) && IsFinally(pEHClause) && IsDuplicateClause(pEHClause)); } -#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) +#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) #endif // __eexcp_h__ diff --git a/src/coreclr/inc/gcinfodecoder.h b/src/coreclr/inc/gcinfodecoder.h index 13b95756302a65..66814e64573227 100644 --- a/src/coreclr/inc/gcinfodecoder.h +++ b/src/coreclr/inc/gcinfodecoder.h @@ -85,6 +85,8 @@ inline TADDR GetSP(T_CONTEXT* context) return (TADDR)context->Sp; #elif defined(TARGET_ARM64) return (TADDR)context->Sp; +#elif defined(TARGET_LOONGARCH64) + return (TADDR)context->Sp; #else _ASSERTE(!"nyi for platform"); #endif @@ -98,6 +100,8 @@ inline PCODE GetIP(T_CONTEXT* context) return (PCODE)context->Pc; #elif defined(TARGET_ARM64) return (PCODE)context->Pc; +#elif defined(TARGET_LOONGARCH64) + return (PCODE)context->Pc; #else _ASSERTE(!"nyi for platform"); #endif @@ -212,9 +216,9 @@ enum GcInfoDecoderFlags DECODE_EDIT_AND_CONTINUE = 0x800, DECODE_REVERSE_PINVOKE_VAR = 0x1000, DECODE_RETURN_KIND = 0x2000, -#if defined(TARGET_ARM) || defined(TARGET_ARM64) +#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) DECODE_HAS_TAILCALLS = 0x4000, -#endif // TARGET_ARM || TARGET_ARM64 +#endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64 }; enum GcInfoHeaderFlags @@ -231,7 +235,7 @@ enum GcInfoHeaderFlags GC_INFO_HAS_STACK_BASE_REGISTER = 0x40, #ifdef TARGET_AMD64 GC_INFO_WANTS_REPORT_ONLY_LEAF = 0x80, -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) GC_INFO_HAS_TAILCALLS = 0x80, #endif // TARGET_AMD64 GC_INFO_HAS_EDIT_AND_CONTINUE_PRESERVED_SLOTS = 0x100, @@ -536,9 +540,9 @@ class GcInfoDecoder bool HasMethodTableGenericsInstContext(); bool GetIsVarArg(); bool WantsReportOnlyLeaf(); -#if defined(TARGET_ARM) || defined(TARGET_ARM64) +#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) bool HasTailCalls(); -#endif // TARGET_ARM || TARGET_ARM64 +#endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64 ReturnKind GetReturnKind(); UINT32 GetCodeLength(); UINT32 GetStackBaseRegister(); @@ -561,7 +565,7 @@ class GcInfoDecoder bool m_GenericSecretParamIsMT; #ifdef TARGET_AMD64 bool m_WantsReportOnlyLeaf; -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) bool m_HasTailCalls; #endif // TARGET_AMD64 INT32 m_SecurityObjectStackSlot; diff --git a/src/coreclr/inc/gcinfoencoder.h b/src/coreclr/inc/gcinfoencoder.h index 559a211d8eeb52..2848612303c1f1 100644 --- a/src/coreclr/inc/gcinfoencoder.h +++ b/src/coreclr/inc/gcinfoencoder.h @@ -440,7 +440,7 @@ class GcInfoEncoder // instead of once for each live function/funclet on the stack. // Called only by RyuJIT (not JIT64) void SetWantsReportOnlyLeaf(); -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) void SetHasTailCalls(); #endif // TARGET_AMD64 @@ -496,7 +496,7 @@ class GcInfoEncoder bool m_IsVarArg; #if defined(TARGET_AMD64) bool m_WantsReportOnlyLeaf; -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) bool m_HasTailCalls; #endif // TARGET_AMD64 INT32 m_SecurityObjectStackSlot; diff --git a/src/coreclr/inc/gcinfotypes.h b/src/coreclr/inc/gcinfotypes.h index 2ac8902283de61..901f147b99975a 100644 --- a/src/coreclr/inc/gcinfotypes.h +++ b/src/coreclr/inc/gcinfotypes.h @@ -156,7 +156,7 @@ struct GcStackSlot // 10 RT_ByRef // 11 RT_Unset -#elif defined(TARGET_AMD64) || defined(TARGET_ARM64) +#elif defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) // Slim Header: @@ -773,6 +773,62 @@ void FASTCALL decodeCallPattern(int pattern, #define LIVESTATE_RLE_RUN_ENCBASE 2 #define LIVESTATE_RLE_SKIP_ENCBASE 4 +#elif defined(TARGET_LOONGARCH64) +#ifndef TARGET_POINTER_SIZE +#define TARGET_POINTER_SIZE 8 // equal to sizeof(void*) and the managed pointer size in bytes for this target +#endif +#define NUM_NORM_CODE_OFFSETS_PER_CHUNK (64) +#define NUM_NORM_CODE_OFFSETS_PER_CHUNK_LOG2 (6) +#define NORMALIZE_STACK_SLOT(x) ((x)>>3) // GC Pointers are 8-bytes aligned +#define DENORMALIZE_STACK_SLOT(x) ((x)<<3) +#define NORMALIZE_CODE_LENGTH(x) ((x)>>2) // All Instructions are 4 bytes long +#define DENORMALIZE_CODE_LENGTH(x) ((x)<<2) +#define NORMALIZE_STACK_BASE_REGISTER(x) ((x)^22) // Encode Frame pointer fp=$22 as zero +#define DENORMALIZE_STACK_BASE_REGISTER(x) ((x)^22) +#define NORMALIZE_SIZE_OF_STACK_AREA(x) ((x)>>3) +#define DENORMALIZE_SIZE_OF_STACK_AREA(x) ((x)<<3) +#define CODE_OFFSETS_NEED_NORMALIZATION 0 +#define NORMALIZE_CODE_OFFSET(x) (x) // Instructions are 4 bytes long, but the safe-point +#define DENORMALIZE_CODE_OFFSET(x) (x) // offsets are encoded with a -1 adjustment. +#define NORMALIZE_REGISTER(x) (x) +#define DENORMALIZE_REGISTER(x) (x) +#define NORMALIZE_NUM_SAFE_POINTS(x) (x) +#define DENORMALIZE_NUM_SAFE_POINTS(x) (x) +#define NORMALIZE_NUM_INTERRUPTIBLE_RANGES(x) (x) +#define DENORMALIZE_NUM_INTERRUPTIBLE_RANGES(x) (x) + +#define PSP_SYM_STACK_SLOT_ENCBASE 6 +#define GENERICS_INST_CONTEXT_STACK_SLOT_ENCBASE 6 +#define SECURITY_OBJECT_STACK_SLOT_ENCBASE 6 +#define GS_COOKIE_STACK_SLOT_ENCBASE 6 +#define CODE_LENGTH_ENCBASE 8 +#define SIZE_OF_RETURN_KIND_IN_SLIM_HEADER 2 +#define SIZE_OF_RETURN_KIND_IN_FAT_HEADER 4 +////TODO for LOONGARCH64. +// FP/SP encoded as 0 or 2 ?? +#define STACK_BASE_REGISTER_ENCBASE 2 +#define SIZE_OF_STACK_AREA_ENCBASE 3 +#define SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE 4 +#define REVERSE_PINVOKE_FRAME_ENCBASE 6 +#define NUM_REGISTERS_ENCBASE 3 +#define NUM_STACK_SLOTS_ENCBASE 2 +#define NUM_UNTRACKED_SLOTS_ENCBASE 1 +#define NORM_PROLOG_SIZE_ENCBASE 5 +#define NORM_EPILOG_SIZE_ENCBASE 3 +#define NORM_CODE_OFFSET_DELTA_ENCBASE 3 +#define INTERRUPTIBLE_RANGE_DELTA1_ENCBASE 6 +#define INTERRUPTIBLE_RANGE_DELTA2_ENCBASE 6 +#define REGISTER_ENCBASE 3 +#define REGISTER_DELTA_ENCBASE 2 +#define STACK_SLOT_ENCBASE 6 +#define STACK_SLOT_DELTA_ENCBASE 4 +#define NUM_SAFE_POINTS_ENCBASE 3 +#define NUM_INTERRUPTIBLE_RANGES_ENCBASE 1 +#define NUM_EH_CLAUSES_ENCBASE 2 +#define POINTER_SIZE_ENCBASE 3 +#define LIVESTATE_RLE_RUN_ENCBASE 2 +#define LIVESTATE_RLE_SKIP_ENCBASE 4 + #else #ifndef TARGET_X86 diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index 4d1fc11f0e8cb2..e6408d4369a65d 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -341,7 +341,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) diff --git a/src/coreclr/inc/llvm/ELF.h b/src/coreclr/inc/llvm/ELF.h index 5cb3f82da21412..addc538725abbe 100644 --- a/src/coreclr/inc/llvm/ELF.h +++ b/src/coreclr/inc/llvm/ELF.h @@ -343,6 +343,10 @@ enum { EM_NORC = 218, // Nanoradio Optimized RISC EM_CSR_KALIMBA = 219, // CSR Kalimba architecture family EM_AMDGPU = 224, // AMD GPU architecture + EM_RISCV = 243, // RISC-V + EM_LANAI = 244, // Lanai 32-bit processor + EM_BPF = 247, // Linux kernel bpf virtual machine + EM_LOONGARCH = 258, // LoongArch processor // A request has been made to the maintainer of the official registry for // such numbers for an official value for WebAssembly. As soon as one is @@ -547,6 +551,14 @@ enum { ODK_PAGESIZE = 11 // Page size information }; +// LoongArch Specific e_flags +enum : unsigned { + EF_LARCH_ABI = 0x0003, + EF_LARCH_ABI_LP32 = 0x0001, + EF_LARCH_ABI_XLP32 = 0x0002, + EF_LARCH_ABI_LP64 = 0x0003, +}; + // Hexagon-specific e_flags enum { // Object processor version flags, bits[11:0] @@ -666,6 +678,11 @@ enum : unsigned { SHT_MIPS_OPTIONS = 0x7000000d, // General options SHT_MIPS_ABIFLAGS = 0x7000002a, // ABI information. + SHT_LOONGARCH_REGINFO = 0x70000006, // Register usage information + SHT_LOONGARCH_OPTIONS = 0x7000000d, // General options + SHT_LOONGARCH_DWARF = 0x7000001e, // DWARF debugging section. + SHT_LOONGARCH_ABIFLAGS = 0x7000002a, // ABI information. + SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type. SHT_LOUSER = 0x80000000, // Lowest type reserved for applications. SHT_HIUSER = 0xffffffff // Highest type reserved for applications. @@ -762,6 +779,30 @@ enum : unsigned { // Section data is string data by default. SHF_MIPS_STRING = 0x80000000, + // Linker must retain only one copy. + SHF_LOONGARCH_NODUPES = 0x01000000, + + // Linker must generate implicit hidden weak names. + SHF_LOONGARCH_NAMES = 0x02000000, + + // Section data local to process. + SHF_LOONGARCH_LOCAL = 0x04000000, + + // Do not strip this section. + SHF_LOONGARCH_NOSTRIP = 0x08000000, + + // Section must be part of global data area. + SHF_LOONGARCH_GPREL = 0x10000000, + + // This section should be merged. + SHF_LOONGARCH_MERGE = 0x20000000, + + // Address size to be inferred from section entry size. + SHF_LOONGARCH_ADDR = 0x40000000, + + // Section data is string data by default. + SHF_LOONGARCH_STRING = 0x80000000, + SHF_AMDGPU_HSA_GLOBAL = 0x00100000, SHF_AMDGPU_HSA_READONLY = 0x00200000, SHF_AMDGPU_HSA_CODE = 0x00400000, @@ -1004,6 +1045,12 @@ enum { PT_MIPS_OPTIONS = 0x70000002, // Options segment. PT_MIPS_ABIFLAGS = 0x70000003, // Abiflags segment. + // LOONGARCH program header types. + PT_LOONGARCH_REGINFO = 0x70000000, // Register usage information. + PT_LOONGARCH_RTPROC = 0x70000001, // Runtime procedure table. + PT_LOONGARCH_OPTIONS = 0x70000002, // Options segment. + PT_LOONGARCH_ABIFLAGS = 0x70000003, // Abiflags segment. + // AMDGPU program header types. PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM = 0x60000000, PT_AMDGPU_HSA_LOAD_GLOBAL_AGENT = 0x60000001, diff --git a/src/coreclr/inc/pedecoder.h b/src/coreclr/inc/pedecoder.h index 7479f685b46bc2..7cd145f452082d 100644 --- a/src/coreclr/inc/pedecoder.h +++ b/src/coreclr/inc/pedecoder.h @@ -81,6 +81,8 @@ inline CHECK CheckOverflow(RVA value1, COUNT_T value2) #define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_ARMNT #elif defined(TARGET_ARM64) #define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_ARM64 +#elif defined(TARGET_LOONGARCH64) +#define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_LOONGARCH64 #elif defined(TARGET_S390X) #define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_UNKNOWN #else diff --git a/src/coreclr/inc/regdisp.h b/src/coreclr/inc/regdisp.h index b031b0a80bafc9..670a5c630f0241 100644 --- a/src/coreclr/inc/regdisp.h +++ b/src/coreclr/inc/regdisp.h @@ -44,7 +44,7 @@ struct REGDISPLAY_BASE { #endif // DEBUG_REGDISPLAY TADDR SP; - TADDR ControlPC; + TADDR ControlPC; // LOONGARCH: use RA for PC }; inline PCODE GetControlPC(const REGDISPLAY_BASE *pRD) { @@ -184,11 +184,42 @@ typedef struct _Arm64VolatileContextPointer }; } Arm64VolatileContextPointer; #endif //TARGET_ARM64 + +#if defined(TARGET_LOONGARCH64) +typedef struct _Loongarch64VolatileContextPointer +{ + PDWORD64 R0; + //PDWORD64 Tp; + PDWORD64 A0; + PDWORD64 A1; + PDWORD64 A2; + PDWORD64 A3; + PDWORD64 A4; + PDWORD64 A5; + PDWORD64 A6; + PDWORD64 A7; + PDWORD64 T0; + PDWORD64 T1; + PDWORD64 T2; + PDWORD64 T3; + PDWORD64 T4; + PDWORD64 T5; + PDWORD64 T6; + PDWORD64 T7; + PDWORD64 T8; + PDWORD64 X0; +} Loongarch64VolatileContextPointer; +#endif + struct REGDISPLAY : public REGDISPLAY_BASE { #ifdef TARGET_ARM64 Arm64VolatileContextPointer volatileCurrContextPointers; #endif +#ifdef TARGET_LOONGARCH64 + Loongarch64VolatileContextPointer volatileCurrContextPointers; +#endif + REGDISPLAY() { // Initialize @@ -297,6 +328,8 @@ inline LPVOID GetRegdisplayReturnValue(REGDISPLAY *display) return (LPVOID)((TADDR)display->pCurrentContext->R0); #elif defined(TARGET_X86) return (LPVOID)display->pCurrentContext->Eax; +#elif defined(TARGET_LOONGARCH64) + return (LPVOID)display->pCurrentContext->A0; #else PORTABILITY_ASSERT("GetRegdisplayReturnValue NYI for this platform (Regdisp.h)"); return NULL; @@ -341,7 +374,20 @@ inline void FillContextPointers(PT_KNONVOLATILE_CONTEXT_POINTERS pCtxPtrs, PT_CO { *(&pCtxPtrs->X19 + i) = (&pCtx->X19 + i); } -#elif defined(TARGET_ARM) // TARGET_ARM64 +#elif defined(TARGET_LOONGARCH64) // TARGET_ARM64 + *(&pCtxPtrs->S0) = &pCtx->S0; + *(&pCtxPtrs->S1) = &pCtx->S1; + *(&pCtxPtrs->S2) = &pCtx->S2; + *(&pCtxPtrs->S3) = &pCtx->S3; + *(&pCtxPtrs->S4) = &pCtx->S4; + *(&pCtxPtrs->S5) = &pCtx->S5; + *(&pCtxPtrs->S6) = &pCtx->S6; + *(&pCtxPtrs->S7) = &pCtx->S7; + *(&pCtxPtrs->S8) = &pCtx->S8; + *(&pCtxPtrs->Tp) = &pCtx->Tp; + *(&pCtxPtrs->Fp) = &pCtx->Fp; + *(&pCtxPtrs->Ra) = &pCtx->Ra; +#elif defined(TARGET_ARM) // TARGET_LOONGARCH64 // Copy over the nonvolatile integer registers (R4-R11) for (int i = 0; i < 8; i++) { @@ -424,7 +470,28 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC // Fill volatile context pointers. They can be used by GC in the case of the leaf frame for (int i=0; i < 18; i++) pRD->volatileCurrContextPointers.X[i] = &pctx->X[i]; -#endif // TARGET_ARM64 +#elif defined(TARGET_LOONGARCH64) // TARGET_ARM64 + //pRD->volatileCurrContextPointers.R0 = &pctx->R0; + //pRD->volatileCurrContextPointers.Tp = &pctx->Tp; + pRD->volatileCurrContextPointers.A0 = &pctx->A0; + pRD->volatileCurrContextPointers.A1 = &pctx->A1; + pRD->volatileCurrContextPointers.A2 = &pctx->A2; + pRD->volatileCurrContextPointers.A3 = &pctx->A3; + pRD->volatileCurrContextPointers.A4 = &pctx->A4; + pRD->volatileCurrContextPointers.A5 = &pctx->A5; + pRD->volatileCurrContextPointers.A6 = &pctx->A6; + pRD->volatileCurrContextPointers.A7 = &pctx->A7; + pRD->volatileCurrContextPointers.T0 = &pctx->T0; + pRD->volatileCurrContextPointers.T1 = &pctx->T1; + pRD->volatileCurrContextPointers.T2 = &pctx->T2; + pRD->volatileCurrContextPointers.T3 = &pctx->T3; + pRD->volatileCurrContextPointers.T4 = &pctx->T4; + pRD->volatileCurrContextPointers.T5 = &pctx->T5; + pRD->volatileCurrContextPointers.T6 = &pctx->T6; + pRD->volatileCurrContextPointers.T7 = &pctx->T7; + pRD->volatileCurrContextPointers.T8 = &pctx->T8; + pRD->volatileCurrContextPointers.X0 = &pctx->X0; +#endif // TARGET_LOONGARCH64 #ifdef DEBUG_REGDISPLAY pRD->_pThread = NULL; @@ -504,6 +571,9 @@ inline size_t * getRegAddr (unsigned regNum, PTR_CONTEXT regs) #elif defined(TARGET_ARM64) _ASSERTE(regNum < 31); return (size_t *)®s->X0 + regNum; +#elif defined(TARGET_LOONGARCH64) + _ASSERTE(regNum < 32); + return (size_t *)®s->R0 + regNum; #else _ASSERTE(!"@TODO Port - getRegAddr (Regdisp.h)"); #endif diff --git a/src/coreclr/inc/sigparser.h b/src/coreclr/inc/sigparser.h index 1e861c4cd3edf8..c729f33f6bbfca 100644 --- a/src/coreclr/inc/sigparser.h +++ b/src/coreclr/inc/sigparser.h @@ -544,7 +544,11 @@ class SigParser } if (pPtr != NULL) { +#if defined(TARGET_LOONGARCH64) + memcpy(pPtr, m_ptr, sizeof(void*)); +#else *pPtr = *(void * UNALIGNED *)m_ptr; +#endif } SkipBytes(sizeof(void *)); diff --git a/src/coreclr/inc/stdmacros.h b/src/coreclr/inc/stdmacros.h index 2d0a0576172aa5..604bb3a3a2f4c1 100644 --- a/src/coreclr/inc/stdmacros.h +++ b/src/coreclr/inc/stdmacros.h @@ -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 @@ -135,7 +149,6 @@ #define ALIGN_ACCESS ((1< Date: Sat, 18 Dec 2021 08:42:56 +0800 Subject: [PATCH 02/19] [LoongArch64] move inc/switches.h to #62889. --- src/coreclr/inc/switches.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/inc/switches.h b/src/coreclr/inc/switches.h index 65cda94ed9900b..9e066527a8bde1 100644 --- a/src/coreclr/inc/switches.h +++ b/src/coreclr/inc/switches.h @@ -51,7 +51,7 @@ #if defined(TARGET_X86) || defined(TARGET_ARM) #define USE_LAZY_PREFERRED_RANGE 0 -#elif defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_S390X) || defined(TARGET_LOONGARCH64) +#elif defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_S390X) #if defined(HOST_UNIX) // In PAL we have a smechanism that reserves memory on start up that is From 50bc1810e330bb9a391658844825b9c8686020fd Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Sat, 18 Dec 2021 14:54:03 +0800 Subject: [PATCH 03/19] [LoongArch64] move some configure files from #62889. --- src/coreclr/debug/createdump/CMakeLists.txt | 13 +++++++++++++ src/coreclr/debug/di/CMakeLists.txt | 2 +- src/coreclr/debug/ee/wks/CMakeLists.txt | 2 +- src/coreclr/dlls/mscordac/CMakeLists.txt | 3 +++ src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt | 2 ++ src/coreclr/gcinfo/CMakeLists.txt | 5 +++-- src/coreclr/inc/targetosarch.h | 11 ----------- 7 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/coreclr/debug/createdump/CMakeLists.txt b/src/coreclr/debug/createdump/CMakeLists.txt index f0093b7cb66601..bf8d0004b4eb58 100644 --- a/src/coreclr/debug/createdump/CMakeLists.txt +++ b/src/coreclr/debug/createdump/CMakeLists.txt @@ -81,6 +81,7 @@ else() add_dependencies(createdump pal_redefines_file) endif(CLR_CMAKE_HOST_OSX) +if(NOT CLR_CMAKE_TARGET_ARCH_LOONGARCH64) target_link_libraries(createdump corguids dbgutil @@ -88,6 +89,18 @@ endif(CLR_CMAKE_HOST_OSX) mscordaccore dl ) +else(CLR_CMAKE_TARGET_ARCH_LOONGARCH64) + target_link_libraries(createdump + corguids + dbgutil + # share the PAL in the dac module + pthread + rt + lzma + mscordaccore + dl + ) +endif() add_dependencies(createdump mscordaccore) diff --git a/src/coreclr/debug/di/CMakeLists.txt b/src/coreclr/debug/di/CMakeLists.txt index b0272c4d2518d8..f45a27ac7a9d5e 100644 --- a/src/coreclr/debug/di/CMakeLists.txt +++ b/src/coreclr/debug/di/CMakeLists.txt @@ -67,7 +67,7 @@ if(CLR_CMAKE_HOST_WIN32) endif() elseif(CLR_CMAKE_HOST_UNIX) - if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_ARM) + if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64) set(CORDBDI_SOURCES_ASM_FILE ${ARCH_SOURCES_DIR}/floatconversion.S ) diff --git a/src/coreclr/debug/ee/wks/CMakeLists.txt b/src/coreclr/debug/ee/wks/CMakeLists.txt index 6411b64d436ff7..f50bc8f6fb6d59 100644 --- a/src/coreclr/debug/ee/wks/CMakeLists.txt +++ b/src/coreclr/debug/ee/wks/CMakeLists.txt @@ -7,7 +7,7 @@ if (CLR_CMAKE_TARGET_WIN32) set(ASM_FILE ${CORDBEE_DIR}/${ARCH_SOURCES_DIR}/dbghelpers.asm) - if(CLR_CMAKE_HOST_ARCH_ARM OR CLR_CMAKE_HOST_ARCH_ARM64) + if(CLR_CMAKE_HOST_ARCH_ARM OR CLR_CMAKE_HOST_ARCH_ARM64 OR CLR_CMAKE_HOST_ARCH_LOONGARCH64) preprocess_files(ASM_FILE ${ASM_FILE}) if (CMAKE_GENERATOR MATCHES "Visual Studio") diff --git a/src/coreclr/dlls/mscordac/CMakeLists.txt b/src/coreclr/dlls/mscordac/CMakeLists.txt index 8d04b34e48aad7..f2931c43db1cb8 100644 --- a/src/coreclr/dlls/mscordac/CMakeLists.txt +++ b/src/coreclr/dlls/mscordac/CMakeLists.txt @@ -49,6 +49,9 @@ else(CLR_CMAKE_HOST_WIN32) if (CLR_CMAKE_HOST_ARCH_ARM OR CLR_CMAKE_HOST_ARCH_ARM64) set(JUMP_INSTRUCTION b) + elseif (CLR_CMAKE_HOST_ARCH_LOONGARCH64) + # FIXME for LOONGARCH64 + set(JUMP_INSTRUCTION "break //TODO, b") else() set(JUMP_INSTRUCTION jmp) endif() diff --git a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt index 31c5b0151ff7f7..954ebad775be17 100644 --- a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt @@ -183,6 +183,8 @@ if(CLR_CMAKE_TARGET_WIN32) list(APPEND PREPROCESS_DEFINITIONS -DTARGET_AMD64) elseif (CLR_CMAKE_HOST_ARCH_ARM64) list(APPEND PREPROCESS_DEFINITIONS -DTARGET_ARM64) + elseif (CLR_CMAKE_HOST_ARCH_LOONGARCH64) + list(APPEND PREPROCESS_DEFINITIONS -DTARGET_LOONGARCH64) elseif (CLR_CMAKE_HOST_ARCH_ARM) list(APPEND PREPROCESS_DEFINITIONS -DTARGET_ARM) elseif (CLR_CMAKE_HOST_ARCH_I386) diff --git a/src/coreclr/gcinfo/CMakeLists.txt b/src/coreclr/gcinfo/CMakeLists.txt index 8c966bb3403b5e..b30acadf6e32f8 100644 --- a/src/coreclr/gcinfo/CMakeLists.txt +++ b/src/coreclr/gcinfo/CMakeLists.txt @@ -69,11 +69,12 @@ if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_ARM) create_gcinfo_lib(TARGET gcinfo_${TARGET_OS_NAME}_${ARCH_TARGET_NAME} OS ${TARGET_OS_NAME} ARCH ${ARCH_TARGET_NAME}) endif() -if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64) +if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64) create_gcinfo_lib(TARGET gcinfo_universal_arm64 OS universal ARCH arm64) create_gcinfo_lib(TARGET gcinfo_unix_x64 OS unix ARCH x64) create_gcinfo_lib(TARGET gcinfo_win_x64 OS win ARCH x64) -endif (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64) + create_gcinfo_lib(TARGET gcinfo_unix_loongarch64 OS unix ARCH loongarch64) +endif (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64) create_gcinfo_lib(TARGET gcinfo_universal_arm OS universal ARCH arm) create_gcinfo_lib(TARGET gcinfo_win_x86 OS win ARCH x86) diff --git a/src/coreclr/inc/targetosarch.h b/src/coreclr/inc/targetosarch.h index 9025a8608af0fc..3f6d96b4d8a273 100644 --- a/src/coreclr/inc/targetosarch.h +++ b/src/coreclr/inc/targetosarch.h @@ -41,35 +41,24 @@ class TargetArchitecture static const bool IsArm64 = false; static const bool IsArm32 = true; static const bool IsArmArch = true; - static const bool IsLoongArch64 = false; #elif defined(TARGET_ARM64) static const bool IsX86 = false; static const bool IsX64 = false; static const bool IsArm64 = true; static const bool IsArm32 = false; static const bool IsArmArch = true; - static const bool IsLoongArch64 = false; #elif defined(TARGET_AMD64) static const bool IsX86 = false; static const bool IsX64 = true; static const bool IsArm64 = false; static const bool IsArm32 = false; static const bool IsArmArch = false; - static const bool IsLoongArch64 = false; #elif defined(TARGET_X86) static const bool IsX86 = true; static const bool IsX64 = false; static const bool IsArm64 = false; static const bool IsArm32 = false; static const bool IsArmArch = false; - static const bool IsLoongArch64 = false; -#elif defined(TARGET_LOONGARCH64) - static const bool IsX86 = false; - static const bool IsX64 = false; - static const bool IsArm64 = false; - static const bool IsArm32 = false; - static const bool IsArmArch = false; - static const bool IsLoongArch64 = true; #else #error Unknown architecture #endif From 49104b34ce52921b64de71718c8fe823b2ebd923 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Sat, 18 Dec 2021 16:45:16 +0800 Subject: [PATCH 04/19] [LoongArch64] revert the modify when moved from #62889. --- src/coreclr/debug/createdump/CMakeLists.txt | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/coreclr/debug/createdump/CMakeLists.txt b/src/coreclr/debug/createdump/CMakeLists.txt index bf8d0004b4eb58..f0093b7cb66601 100644 --- a/src/coreclr/debug/createdump/CMakeLists.txt +++ b/src/coreclr/debug/createdump/CMakeLists.txt @@ -81,7 +81,6 @@ else() add_dependencies(createdump pal_redefines_file) endif(CLR_CMAKE_HOST_OSX) -if(NOT CLR_CMAKE_TARGET_ARCH_LOONGARCH64) target_link_libraries(createdump corguids dbgutil @@ -89,18 +88,6 @@ if(NOT CLR_CMAKE_TARGET_ARCH_LOONGARCH64) mscordaccore dl ) -else(CLR_CMAKE_TARGET_ARCH_LOONGARCH64) - target_link_libraries(createdump - corguids - dbgutil - # share the PAL in the dac module - pthread - rt - lzma - mscordaccore - dl - ) -endif() add_dependencies(createdump mscordaccore) From d3e0468609481e134c1bcbb1fdf2d5fb3fcf2198 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Mon, 20 Dec 2021 09:33:07 +0800 Subject: [PATCH 05/19] [LoongArch64] moved the inc/stdmacros.h to #62885. --- src/coreclr/inc/stdmacros.h | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/coreclr/inc/stdmacros.h b/src/coreclr/inc/stdmacros.h index 604bb3a3a2f4c1..2d0a0576172aa5 100644 --- a/src/coreclr/inc/stdmacros.h +++ b/src/coreclr/inc/stdmacros.h @@ -111,20 +111,6 @@ #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 @@ -149,6 +135,7 @@ #define ALIGN_ACCESS ((1< Date: Mon, 20 Dec 2021 10:30:07 +0800 Subject: [PATCH 06/19] [LoongArch64] moved inc/corinfo.h to #62885. --- src/coreclr/inc/corinfo.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 5dfa0c2d276aa4..f6f341e56f32a6 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2712,9 +2712,6 @@ class ICorStaticInfo CORINFO_SIG_INFO* sig, /* IN */ CORINFO_ARG_LIST_HANDLE args, /* IN */ CORINFO_CLASS_HANDLE *vcTypeRet /* OUT */ -#if defined(TARGET_LOONGARCH64) - ,int *flags = NULL -#endif ) = 0; // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it @@ -2851,7 +2848,6 @@ class ICorStaticInfo /* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr ) = 0; - virtual uint32_t getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) = 0; }; /***************************************************************************** From 9c211b94c34b2639a5c6e6a6521397f0d13d68fb Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Tue, 21 Dec 2021 08:48:05 +0800 Subject: [PATCH 07/19] [LoongArch64] modify the related files for compiling error. --- src/coreclr/debug/shim/debugshim.cpp | 2 +- src/coreclr/gcinfo/CMakeLists.txt | 1 - src/coreclr/inc/clrnt.h | 6 +----- src/coreclr/pal/inc/rt/ntimage.h | 6 ++++++ 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/coreclr/debug/shim/debugshim.cpp b/src/coreclr/debug/shim/debugshim.cpp index dd2ff1895b2d40..ff7b8387bc7c86 100644 --- a/src/coreclr/debug/shim/debugshim.cpp +++ b/src/coreclr/debug/shim/debugshim.cpp @@ -22,7 +22,7 @@ #endif #ifndef IMAGE_FILE_MACHINE_LOONGARCH64 -#define IMAGE_FILE_MACHINE_LOONGARCH64 0xDD64 // LOONGARCH64 Little-Endian +#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // LOONGARCH64 Little-Endian #endif //***************************************************************************** diff --git a/src/coreclr/gcinfo/CMakeLists.txt b/src/coreclr/gcinfo/CMakeLists.txt index b30acadf6e32f8..eab41ec4f145fe 100644 --- a/src/coreclr/gcinfo/CMakeLists.txt +++ b/src/coreclr/gcinfo/CMakeLists.txt @@ -73,7 +73,6 @@ if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARG create_gcinfo_lib(TARGET gcinfo_universal_arm64 OS universal ARCH arm64) create_gcinfo_lib(TARGET gcinfo_unix_x64 OS unix ARCH x64) create_gcinfo_lib(TARGET gcinfo_win_x64 OS win ARCH x64) - create_gcinfo_lib(TARGET gcinfo_unix_loongarch64 OS unix ARCH loongarch64) endif (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64) create_gcinfo_lib(TARGET gcinfo_universal_arm OS universal ARCH arm) diff --git a/src/coreclr/inc/clrnt.h b/src/coreclr/inc/clrnt.h index b56bd9ae45deca..1edeaca9735abe 100644 --- a/src/coreclr/inc/clrnt.h +++ b/src/coreclr/inc/clrnt.h @@ -1016,10 +1016,6 @@ RtlVirtualUnwind( #define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian #endif -#ifndef IMAGE_FILE_MACHINE_LOONGARCH64 -#define IMAGE_FILE_MACHINE_LOONGARCH64 0xDD64 // LOONGARCH64 Little-Endian -#endif - #ifndef IMAGE_REL_ARM64_BRANCH26 #define IMAGE_REL_ARM64_BRANCH26 0x0003 // 26 bit offset << 2 & sign ext. for B & BL #endif @@ -1090,7 +1086,7 @@ RtlVirtualUnwind( ); #ifndef IMAGE_FILE_MACHINE_LOONGARCH64 -#define IMAGE_FILE_MACHINE_LOONGARCH64 0xDD64 // LOONGARCH64 Little-Endian +#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // LOONGARCH64 Little-Endian #endif #ifndef IMAGE_REL_LOONGARCH64_PC diff --git a/src/coreclr/pal/inc/rt/ntimage.h b/src/coreclr/pal/inc/rt/ntimage.h index 1880375184f057..78c8fb7307580a 100644 --- a/src/coreclr/pal/inc/rt/ntimage.h +++ b/src/coreclr/pal/inc/rt/ntimage.h @@ -239,6 +239,7 @@ typedef struct _IMAGE_FILE_HEADER { #define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) #define IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian #define IMAGE_FILE_MACHINE_CEE 0xC0EE +#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // LOONGARCH64. // // Directory format. @@ -1025,6 +1026,11 @@ typedef IMAGE_RELOCATION UNALIGNED *PIMAGE_RELOCATION; #define IMAGE_REL_IA64_GPREL32 0x001C #define IMAGE_REL_IA64_ADDEND 0x001F +// +// LOONGARCH64 relocation types +// +#define IMAGE_REL_LOONGARCH64_PC 0x0004 + // // CEF relocation types. // From 7fc185f2914c380df9237276eb23b61ac55df622 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Tue, 21 Dec 2021 09:19:19 +0800 Subject: [PATCH 08/19] [LoongArch64] revert the `src/coreclr/gcinfo/CMakeLists.txt` to original. --- src/coreclr/gcinfo/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/gcinfo/CMakeLists.txt b/src/coreclr/gcinfo/CMakeLists.txt index eab41ec4f145fe..8c966bb3403b5e 100644 --- a/src/coreclr/gcinfo/CMakeLists.txt +++ b/src/coreclr/gcinfo/CMakeLists.txt @@ -69,11 +69,11 @@ if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_ARM) create_gcinfo_lib(TARGET gcinfo_${TARGET_OS_NAME}_${ARCH_TARGET_NAME} OS ${TARGET_OS_NAME} ARCH ${ARCH_TARGET_NAME}) endif() -if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64) +if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64) create_gcinfo_lib(TARGET gcinfo_universal_arm64 OS universal ARCH arm64) create_gcinfo_lib(TARGET gcinfo_unix_x64 OS unix ARCH x64) create_gcinfo_lib(TARGET gcinfo_win_x64 OS win ARCH x64) -endif (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64) +endif (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64) create_gcinfo_lib(TARGET gcinfo_universal_arm OS universal ARCH arm) create_gcinfo_lib(TARGET gcinfo_win_x86 OS win ARCH x86) From b859a4fe6177fce8339b3a4025e009c63cc1c670 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Tue, 21 Dec 2021 11:26:40 +0800 Subject: [PATCH 09/19] [LoongArch64] delete unused files on windows. --- src/coreclr/binder/assemblybindercommon.cpp | 4 ---- src/coreclr/binder/inc/bindertypes.hpp | 1 - 2 files changed, 5 deletions(-) diff --git a/src/coreclr/binder/assemblybindercommon.cpp b/src/coreclr/binder/assemblybindercommon.cpp index 2bec176b44063e..830c673ea06a63 100644 --- a/src/coreclr/binder/assemblybindercommon.cpp +++ b/src/coreclr/binder/assemblybindercommon.cpp @@ -215,8 +215,6 @@ namespace BINDER_SPACE *PeKind = peARM64; else if (dwImageType == IMAGE_FILE_MACHINE_AMD64) *PeKind = peAMD64; - else if (dwImageType == IMAGE_FILE_MACHINE_LOONGARCH64) - *PeKind = peLOONGARCH64; else { // We don't support other architectures @@ -1449,8 +1447,6 @@ BOOL AssemblyBinderCommon::IsValidArchitecture(PEKIND kArchitecture) peARM; #elif defined(TARGET_ARM64) peARM64; -#elif defined(TARGET_LOONGARCH64) - peLOONGARCH64; #else PORTABILITY_ASSERT("processArchitecture"); #endif diff --git a/src/coreclr/binder/inc/bindertypes.hpp b/src/coreclr/binder/inc/bindertypes.hpp index 15a07b3d7b5aac..101ef3c8d9593f 100644 --- a/src/coreclr/binder/inc/bindertypes.hpp +++ b/src/coreclr/binder/inc/bindertypes.hpp @@ -68,7 +68,6 @@ typedef enum __PEKIND peAMD64 = 0x00000004, peARM = 0x00000005, peARM64 = 0x00000006, - peLOONGARCH64 = 0x00000007, peInvalid = 0xffffffff, } PEKIND; From 3e89670884a44ca94be450f584bcd0bb8256deb1 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Tue, 21 Dec 2021 12:15:10 +0800 Subject: [PATCH 10/19] [LoongArch64] add define IMAGE_FILE_MACHINE_LOONGARCH64. --- src/coreclr/pal/inc/pal.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 237b75275cec96..b3527fc085a921 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -3829,6 +3829,7 @@ typedef LPOSVERSIONINFOEXA LPOSVERSIONINFOEX; #define IMAGE_FILE_MACHINE_I386 0x014c #define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian +#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // LOONGARCH64 Little-Endian typedef struct _SYSTEM_INFO { WORD wProcessorArchitecture_PAL_Undefined; From f0618ea595f2ff3c9f57dd3d9f297f1760627b8a Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Tue, 21 Dec 2021 17:29:49 +0800 Subject: [PATCH 11/19] [LoongArch64] workround the compiling error for IMAGE_FILE_MACHINE_LOONGARCH64 on windows. --- src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp index 8ee9f726e878bf..0bfca2438509c0 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp @@ -346,9 +346,11 @@ JitInstance::Result JitInstance::CompileMethod(MethodContext* MethodToCompile, i matchesTargetArch = (targetArch == SPMI_TARGET_ARCHITECTURE_ARM64); break; +#ifdef TARGET_UNIX case IMAGE_FILE_MACHINE_LOONGARCH64: matchesTargetArch = (targetArch == SPMI_TARGET_ARCHITECTURE_LOONGARCH64); break; +#endif default: LogError("Unknown target architecture"); From 054033f66bc1845b2900136f6d2c08459c6c0c34 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Tue, 21 Dec 2021 19:46:49 +0800 Subject: [PATCH 12/19] [LoongArch64] workround the compiling error for SPMI_TARGET_ARCHITECTURE_LOONGARCH64 on windows. --- src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index 03128d7d2e0c4f..4d0917428e1c26 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -861,10 +861,12 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o } } +#ifdef HOST_UNIX if (targetArch == SPMI_TARGET_ARCHITECTURE_LOONGARCH64) { assert(!"FIXME: Not Implements on loongarch64"); } +#endif if (IsSpmiTarget64Bit()) { From b7cb02bdc289b7967d44eb118838c65b248e4adb Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Wed, 22 Dec 2021 11:36:27 +0800 Subject: [PATCH 13/19] [LoongArch64] delete the memcpy for LoongArch64 and revert workround patches. --- .../ToolBox/superpmi/superpmi-shared/compileresult.cpp | 4 +--- src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp | 2 -- src/coreclr/inc/cor.h | 8 -------- src/coreclr/inc/sigparser.h | 4 ---- 4 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index 4d0917428e1c26..9051458948c157 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -861,12 +861,10 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o } } -#ifdef HOST_UNIX if (targetArch == SPMI_TARGET_ARCHITECTURE_LOONGARCH64) { - assert(!"FIXME: Not Implements on loongarch64"); + Assert(!"FIXME: Not Implements on loongarch64"); } -#endif if (IsSpmiTarget64Bit()) { diff --git a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp index 0bfca2438509c0..8ee9f726e878bf 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp @@ -346,11 +346,9 @@ JitInstance::Result JitInstance::CompileMethod(MethodContext* MethodToCompile, i matchesTargetArch = (targetArch == SPMI_TARGET_ARCHITECTURE_ARM64); break; -#ifdef TARGET_UNIX case IMAGE_FILE_MACHINE_LOONGARCH64: matchesTargetArch = (targetArch == SPMI_TARGET_ARCHITECTURE_LOONGARCH64); break; -#endif default: LogError("Unknown target architecture"); diff --git a/src/coreclr/inc/cor.h b/src/coreclr/inc/cor.h index 58a97736255e8f..8ccc151cc0378e 100644 --- a/src/coreclr/inc/cor.h +++ b/src/coreclr/inc/cor.h @@ -2233,11 +2233,7 @@ inline ULONG CorSigCompressPointer( // return number of bytes of that compressed void * pvPointer, // [IN] given uncompressed data void * pData) // [OUT] buffer where iLen will be compressed and stored. { -#ifdef TARGET_LOONGARCH64 - memcpy(pData, &pvPointer, sizeof(void*)); -#else *((void * UNALIGNED *)pData) = pvPointer; -#endif return sizeof(void *); } @@ -2246,11 +2242,7 @@ inline ULONG CorSigUncompressPointer( // return number of bytes of that compre PCCOR_SIGNATURE pData, // [IN] compressed data void ** ppvPointer) // [OUT] the expanded *pData { -#ifdef TARGET_LOONGARCH64 - memcpy((void*)ppvPointer, (void*)pData, sizeof(void*)); -#else *ppvPointer = *(void * const UNALIGNED *)pData; -#endif return sizeof(void *); } diff --git a/src/coreclr/inc/sigparser.h b/src/coreclr/inc/sigparser.h index c729f33f6bbfca..1e861c4cd3edf8 100644 --- a/src/coreclr/inc/sigparser.h +++ b/src/coreclr/inc/sigparser.h @@ -544,11 +544,7 @@ class SigParser } if (pPtr != NULL) { -#if defined(TARGET_LOONGARCH64) - memcpy(pPtr, m_ptr, sizeof(void*)); -#else *pPtr = *(void * UNALIGNED *)m_ptr; -#endif } SkipBytes(sizeof(void *)); From 72919c1e92a0f6f3495ebdd3b3f91e3cdeef73c3 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Wed, 22 Dec 2021 15:34:10 +0800 Subject: [PATCH 14/19] [LoongArch64] exclude the gc, ToolBox and config files from this PR. --- .../superpmi-shared/compileresult.cpp | 5 - .../superpmi/superpmi-shared/spmiutil.cpp | 2 - .../superpmi/superpmi-shared/spmiutil.h | 5 +- .../ToolBox/superpmi/superpmi/jitinstance.cpp | 4 - .../ToolBox/superpmi/superpmi/superpmi.cpp | 4 - src/coreclr/debug/createdump/datatarget.cpp | 4 +- .../ee/loongarch64/loongarch64walker.cpp | 435 +----------------- src/coreclr/dlls/mscordac/CMakeLists.txt | 3 - .../dlls/mscoree/coreclr/CMakeLists.txt | 2 - src/coreclr/enablesanitizers.sh | 5 - src/coreclr/gc/env/gcenv.base.h | 5 - src/coreclr/gc/env/gcenv.interlocked.inl | 3 - src/coreclr/gc/env/volatile.h | 6 +- src/coreclr/gc/gc.cpp | 8 - src/coreclr/gc/unix/gcenv.unix.cpp | 4 +- src/coreclr/gcdump/gcdumpnonx86.cpp | 4 +- src/coreclr/gcinfo/gcinfodumper.cpp | 65 +-- src/coreclr/gcinfo/gcinfoencoder.cpp | 20 +- src/coreclr/inc/clrnt.h | 65 --- src/coreclr/inc/cvconst.h | 5 +- src/coreclr/inc/eetwain.h | 8 +- src/coreclr/inc/gcinfodecoder.h | 16 +- src/coreclr/inc/gcinfoencoder.h | 4 +- src/coreclr/inc/gcinfotypes.h | 58 +-- src/coreclr/inc/jithelpers.h | 2 +- src/coreclr/inc/llvm/ELF.h | 5 +- src/coreclr/inc/targetosarch.h | 2 +- src/coreclr/pal/inc/pal.h | 1 - src/coreclr/pal/inc/rt/ntimage.h | 6 - 29 files changed, 36 insertions(+), 720 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index 9051458948c157..729064aa1b0bc8 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -861,11 +861,6 @@ 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) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp index 97f4ca40631da5..4d21d7d2d56434 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp @@ -251,8 +251,6 @@ 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 diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h index 16543880d944b7..bc6bfa4f34fc24 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h @@ -53,8 +53,7 @@ enum SPMI_TARGET_ARCHITECTURE SPMI_TARGET_ARCHITECTURE_X86, SPMI_TARGET_ARCHITECTURE_AMD64, SPMI_TARGET_ARCHITECTURE_ARM64, - SPMI_TARGET_ARCHITECTURE_ARM, - SPMI_TARGET_ARCHITECTURE_LOONGARCH64 + SPMI_TARGET_ARCHITECTURE_ARM }; SPMI_TARGET_ARCHITECTURE GetSpmiTargetArchitecture(); @@ -62,7 +61,7 @@ void SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE spmiTargetArchitecture); inline bool IsSpmiTarget64Bit() { - return (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_AMD64) || (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_ARM64) || (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_LOONGARCH64); + return (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_AMD64) || (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_ARM64); } inline size_t SpmiTargetPointerSize() diff --git a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp index 8ee9f726e878bf..07d90549de43ed 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp @@ -346,10 +346,6 @@ JitInstance::Result JitInstance::CompileMethod(MethodContext* MethodToCompile, i matchesTargetArch = (targetArch == SPMI_TARGET_ARCHITECTURE_ARM64); break; - case IMAGE_FILE_MACHINE_LOONGARCH64: - matchesTargetArch = (targetArch == SPMI_TARGET_ARCHITECTURE_LOONGARCH64); - break; - default: LogError("Unknown target architecture"); break; diff --git a/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp b/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp index 523e07da9c9b4b..f71ee9c1fe32be 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp @@ -53,10 +53,6 @@ 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); diff --git a/src/coreclr/debug/createdump/datatarget.cpp b/src/coreclr/debug/createdump/datatarget.cpp index d119498c2b2b53..7d2ab1973ff602 100644 --- a/src/coreclr/debug/createdump/datatarget.cpp +++ b/src/coreclr/debug/createdump/datatarget.cpp @@ -65,8 +65,6 @@ DumpDataTarget::GetMachineType( *machine = IMAGE_FILE_MACHINE_ARM64; #elif HOST_X86 *machine = IMAGE_FILE_MACHINE_I386; -#elif HOST_LOONGARCH64 - *machine = IMAGE_FILE_MACHINE_LOONGARCH64; #else #error Unsupported architecture #endif @@ -77,7 +75,7 @@ HRESULT STDMETHODCALLTYPE DumpDataTarget::GetPointerSize( /* [out] */ ULONG32 *size) { -#if defined(HOST_AMD64) || defined(HOST_ARM64) || defined(HOST_LOONGARCH64) +#if defined(HOST_AMD64) || defined(HOST_ARM64) *size = 8; #elif defined(HOST_ARM) || defined(HOST_X86) *size = 4; diff --git a/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp b/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp index 660f43760e0799..6c731e0cfc5cb1 100644 --- a/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp +++ b/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp @@ -20,78 +20,9 @@ #ifdef TARGET_LOONGARCH64 -PCODE Expand19bitoffset(PCODE opcode) -{ - _ASSERTE(!"=====Not implements for loongarch64. -1"); - opcode = opcode >> 5; - PCODE offset = (opcode & 0x7FFFF) << 2; //imm19:00 -> 21 bits - - //Sign Extension - if ((offset & 0x100000)) //Check for 21'st bit - { - offset = offset | 0xFFFFFFFFFFE00000; - } - return offset; -} - void NativeWalker::Decode() { - _ASSERTE(!"=====Not implements for loongarch64. -2"); - - PT_CONTEXT context = NULL; - int RegNum = -1; - PCODE offset = MAX_INSTRUCTION_LENGTH; - - //Reset so that we do not provide bogus info - m_type = WALK_UNKNOWN; - m_skipIP = NULL; - m_nextIP = NULL; - - if (m_registers == NULL) - { - //walker does not use WALK_NEXT - //Without registers decoding will work only for handful of instructions - return; - } - - m_skipIP = m_ip + MAX_INSTRUCTION_LENGTH; - - context = m_registers->pCurrentContext; - // Fetch first word of the current instruction.If the current instruction is a break instruction, we'll - // need to check the patch table to get the correct instruction. - PRD_TYPE opcode = CORDbgGetInstruction(m_ip); - PRD_TYPE unpatchedOpcode; - if (DebuggerController::CheckGetPatchedOpcode(m_ip, &unpatchedOpcode)) - { - opcode = unpatchedOpcode; - } - - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decode instruction at %p, opcode: %x\n", m_ip,opcode)); - - - - if (NativeWalker::DecodeCallInst(opcode, RegNum, m_type)) //Unconditional Branch (register) instructions - { - if (m_type == WALK_RETURN) - { - m_skipIP = NULL; - } - m_nextIP = (BYTE*)GetReg(context, RegNum); - return; - } - - - if (NativeWalker::DecodePCRelativeBranchInst(context, opcode, offset, m_type)) - { - if (m_type == WALK_BRANCH) - { - m_skipIP = NULL; - } - } - - m_nextIP = m_ip + offset; - - + _ASSERTE(!"TODO:=====Not implements for LOONGARCH64. -2"); return; } @@ -99,179 +30,8 @@ void NativeWalker::Decode() //When control reaches here m_pSharedPatchBypassBuffer has the original instructions in m_pSharedPatchBypassBuffer->PatchBypass BYTE* NativeWalker::SetupOrSimulateInstructionForPatchSkip(T_CONTEXT * context, SharedPatchBypassBuffer* m_pSharedPatchBypassBuffer, const BYTE *address, PRD_TYPE opcode) { - _ASSERTE(!"=====Not implements for loongarch64. -3"); - - BYTE* patchBypass = m_pSharedPatchBypassBuffer->PatchBypass; - PCODE offset = 0; - PCODE ip = 0; - WALK_TYPE walk = WALK_UNKNOWN; - int RegNum =-1; - - - /* - Modify the patchBypass if the opcode is IP-relative, otherwise return it - The following are the instructions that are IP-relative : - . ADR and ADRP. - . The Load register (literal) instruction class. - . Direct branches that use an immediate offset. - . The unconditional branch with link instructions, BL and BLR, that use the PC to create the return link - address. - */ - - _ASSERTE((UINT_PTR)address == context->Pc); - - if ((opcode & 0x1F000000) == 0x10000000) //ADR & ADRP - { - - TADDR immhigh = ((opcode >> 5) & 0x007FFFF) << 2; - TADDR immlow = (opcode & 0x60000000) >> 29; - offset = immhigh | immlow; //ADR - RegNum = (opcode & 0x1F); - - //Sign Extension - if ((offset & 0x100000)) //Check for 21'st bit - { - offset = offset | 0xFFFFFFFFFFE00000; - } - - if ((opcode & 0x80000000) != 0) //ADRP - { - offset = offset << 12; - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to ADRP X%d %p\n", opcode, RegNum, offset)); - } - else - { - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to ADR X%d %p\n", opcode, RegNum, offset)); - } - - - } - - else if ((opcode & 0x3B000000) == 0x18000000) //LDR Literal (General or SIMD) - { - - offset = Expand19bitoffset(opcode); - RegNum = (opcode & 0x1F); - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to LDR[SW] | PRFM X%d %p\n", opcode, RegNum, offset)); - } - else if (NativeWalker::DecodePCRelativeBranchInst(context,opcode, offset, walk)) - { - _ASSERTE(RegNum == -1); - } - else if (NativeWalker::DecodeCallInst(opcode, RegNum, walk)) - { - _ASSERTE(offset == 0); - } - //else Just execute the opcodes as is - //{ - //} - - if (offset != 0) // calculate the next ip from current ip - { - ip = (PCODE)address + offset; - } - else if(RegNum >= 0) - { - ip = GetReg(context, RegNum); - } - - //Do instruction emulation inplace here - - if (walk == WALK_BRANCH || walk == WALK_CALL || walk == WALK_RETURN) - { - CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patchBypass, 0xd503201f); //Add Nop in buffer - - m_pSharedPatchBypassBuffer->RipTargetFixup = ip; //Control Flow simulation alone is done DebuggerPatchSkip::TriggerExceptionHook - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x is a Control Flow instr \n", opcode)); - - if (walk == WALK_CALL) //initialize Lr - { - SetRA(context, (PCODE)address + MAX_INSTRUCTION_LENGTH); - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x is a Call instr, setting RA to %p \n", opcode,GetRA(context))); - } - } - else if(RegNum >= 0) - { - CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patchBypass, 0xd503201f); //Add Nop in buffer - - PCODE RegContents; - if ((opcode & 0x3B000000) == 0x18000000) //LDR Literal - { - RegContents = (PCODE)GetMem(ip); - if ((opcode & 0x4000000)) //LDR literal for SIMD - { - NEON128 SimdRegContents; - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to LDR V%d %p\n", opcode, RegNum, offset)); - short opc = (opcode >> 30); - switch (opc) - { - case 0: //4byte data into St - RegContents = 0xFFFFFFFF & RegContents; //zero the upper 32bit - SetReg(context, RegNum, RegContents); - case 1: //8byte data into Dt - SetReg(context, RegNum, RegContents); - break; - - case 2: //SIMD 16 byte data - SimdRegContents = GetSimdMem(ip); - SetSimdReg(context, RegNum, SimdRegContents); - break; - default: - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate Unknown opcode: %x [LDR(litera,SIMD &FP)] \n", opcode)); - _ASSERTE(!("Loongarch64Walker::Simulated Unknown opcode")); - - } - } - else - { - short opc = (opcode >> 30); - switch (opc) - { - case 0: //4byte data into Wt - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to LDR W%d %p\n", opcode, RegNum, offset)); - RegContents = 0xFFFFFFFF & RegContents; //zero the upper 32bits - SetReg(context, RegNum, RegContents); - break; - - case 1: //8byte data into Xt - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to LDR X%d %p\n", opcode, RegNum, offset)); - SetReg(context, RegNum, RegContents); - break; - - case 2: //LDRSW - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to LDRSW X%d %p\n", opcode, RegNum, offset)); - RegContents = 0xFFFFFFFF & RegContents; - - if (RegContents & 0x80000000) //Sign extend the Word - { - RegContents = 0xFFFFFFFF00000000 | RegContents; - } - SetReg(context, RegNum, RegContents); - break; - case 3: - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x as PRFM ,but do nothing \n", opcode)); - - break; - default: - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate Unknown opcode: %x [LDR(literal)] \n", opcode)); - _ASSERTE(!("Loongarch64Walker::Simulated Unknown opcode")); - - } - } - } - else - { - RegContents = ip; - SetReg(context, RegNum, RegContents); - } - - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate opcode: %x to update Reg X[V]%d, as %p \n", opcode, RegNum, GetReg(context, RegNum))); - } - //else Just execute the opcodes as IS - //{ - //} - - return patchBypass; + _ASSERTE(!"TODO:=====Not implements for LOONGARCH64. -3"); + return NULL; } //Decodes PC Relative Branch Instructions @@ -281,8 +41,6 @@ BYTE* NativeWalker::SetupOrSimulateInstructionForPatchSkip(T_CONTEXT * context, // BL offset // B offset // B.Cond offset -// CB[N]Z X offset -// TB[N]Z X offset //Output of the Function are: //offset - Offset from current PC to which control will go next @@ -290,194 +48,13 @@ BYTE* NativeWalker::SetupOrSimulateInstructionForPatchSkip(T_CONTEXT * context, BOOL NativeWalker::DecodePCRelativeBranchInst(PT_CONTEXT context, const PRD_TYPE& opcode, PCODE& offset, WALK_TYPE& walk) { - _ASSERTE(!"=====Not implements for loongarch64. -4"); -#ifdef _DEBUG - PCODE incomingoffset = offset; - WALK_TYPE incomingwalk = walk; -#endif - - if ((opcode & 0x7C000000) == 0x14000000) // Decode B & BL - { - offset = (opcode & 0x03FFFFFF) << 2; - // Sign extension - if ((offset & 0x4000000)) //Check for 26'st bit - { - offset = offset | 0xFFFFFFFFF8000000; - } - - if ((opcode & 0x80000000) != 0) //BL - { - walk = WALK_CALL; - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to BL %p \n", opcode, offset)); - } - else - { - walk = WALK_BRANCH; //B - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to B %p \n", opcode, offset)); - } - return TRUE; - } - - //Conditional Branches - _ASSERTE(context != NULL); - - - if ((opcode & 0xFF000010) == 0x54000000) // B.cond - { - WORD cond = opcode & 0xF; - bool result = false; - switch (cond >> 1) - { - case 0x0: result = (context->Cpsr & NZCV_Z) != 0; // EQ or NE - break; - case 0x1: result = (context->Cpsr & NZCV_C) != 0; // CS or CC - break; - case 0x2: result = (context->Cpsr & NZCV_N) != 0; // MI or PL - break; - case 0x3: result = (context->Cpsr & NZCV_V) != 0; // VS or VC - break; - case 0x4: result = ((context->Cpsr & NZCV_C) != 0) && ((context->Cpsr & NZCV_Z) == 0); // HI or LS - break; - case 0x5: result = ((context->Cpsr & NZCV_N) >> NZCV_N_BIT) == ((context->Cpsr & NZCV_V) >> NZCV_V_BIT); // GE or LT - break; - case 0x6: result = ((context->Cpsr & NZCV_N) >> NZCV_N_BIT) == ((context->Cpsr & NZCV_V) >> NZCV_V_BIT) && ((context->Cpsr & NZCV_Z) == 0); // GT or LE - break; - case 0x7: result = true; // AL - break; - } - - if ((cond & 0x1) && (cond & 0xF) != 0) { result = !result; } - - if (result) - { - walk = WALK_BRANCH; - offset = Expand19bitoffset(opcode); - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to B.cond %p \n", opcode, offset)); - } - else // NOP - { - walk = WALK_UNKNOWN; - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to B.cond but evaluated as NOP \n", opcode)); - offset = MAX_INSTRUCTION_LENGTH; - } - - return TRUE; - - } - - - int RegNum = opcode & 0x1F; - PCODE RegContent = GetReg(context, RegNum); - - if ((opcode & 0xFE000000) == 0x34000000) // CBNZ || CBZ - { - bool result = false; - - if (!(opcode & 0x80000000)) //if sf == '1' the 64 else 32 - { - RegContent = 0xFFFFFFFF & RegContent; //zero the upper 32bit - } - - if (opcode & 0x01000000) //CBNZ - { - result = RegContent != 0; - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to CBNZ X%d \n", opcode, RegNum)); - } - else //CBZ - { - result = RegContent == 0; - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to CBZ X%d \n", opcode, RegNum)); - } - - if (result) - { - walk = WALK_BRANCH; - offset = Expand19bitoffset(opcode); - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to CB[N]Z X%d %p \n", opcode, RegNum, offset)); - } - else // NOP - { - walk = WALK_UNKNOWN; - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to B.cond but evaluated as NOP \n", opcode)); - offset = MAX_INSTRUCTION_LENGTH; - } - - - return TRUE; - } - if ((opcode & 0x7E000000) == 0x36000000) // TBNZ || TBZ - { - bool result = false; - int bit_pos = ((opcode >> 19) & 0x1F); - - if (opcode & 0x80000000) - { - bit_pos = bit_pos + 32; - } - - PCODE bit_val = 1 << bit_pos; - if (opcode & 0x01000000) //TBNZ - { - result = (RegContent & bit_val) != 0; - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to TBNZ X%d \n", opcode, RegNum)); - } - else //TBZ - { - result = (RegContent & bit_val) == 0; - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to CB[N]Z X%d \n", opcode, RegNum)); - } - if (result) - { - walk = WALK_BRANCH; - offset = ((opcode >> 5) & 0x3FFF) << 2; //imm14:00 -> 16 bits - if (offset & 0x8000) //sign extension check for 16'th bit - { - offset = offset | 0xFFFFFFFFFFFF0000; - } - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to TB[N]Z X%d %p \n", opcode, RegNum, offset)); - } - else // NOP - { - walk = WALK_UNKNOWN; - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to B.cond but evaluated as NOP \n", opcode)); - offset = MAX_INSTRUCTION_LENGTH; - } - - return TRUE; - } - - _ASSERTE(offset == incomingoffset); - _ASSERTE(walk == incomingwalk); + _ASSERTE(!"TODO:=====Not implements for LOONGARCH64. -4"); return FALSE; } BOOL NativeWalker::DecodeCallInst(const PRD_TYPE& opcode, int& RegNum, WALK_TYPE& walk) { - if ((opcode & 0xFF9FFC1F) == 0xD61F0000) // BR, BLR or RET -Unconditional Branch (register) instructions - { - - RegNum = (opcode & 0x3E0) >> 5; - - - short op = (opcode & 0x00600000) >> 21; //Checking for 23 and 22 bits - switch (op) - { - case 0: LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to BR X%d\n", opcode, RegNum)); - walk = WALK_BRANCH; - break; - case 1: LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to BLR X%d\n", opcode, RegNum)); - walk = WALK_CALL; - break; - case 2: LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Decoded opcode: %x to Ret X%d\n", opcode, RegNum)); - walk = WALK_RETURN; - break; - default: - LOG((LF_CORDB, LL_INFO100000, "Loongarch64Walker::Simulate Unknown opcode: %x [Branch] \n", opcode)); - _ASSERTE(!("Loongarch64Walker::Decoded Unknown opcode")); - } - - return TRUE; - } - return FALSE; + _ASSERTE(!"TODO:=====Not implements for LOONGARCH64. -5"); + return FALSE; } #endif diff --git a/src/coreclr/dlls/mscordac/CMakeLists.txt b/src/coreclr/dlls/mscordac/CMakeLists.txt index f2931c43db1cb8..8d04b34e48aad7 100644 --- a/src/coreclr/dlls/mscordac/CMakeLists.txt +++ b/src/coreclr/dlls/mscordac/CMakeLists.txt @@ -49,9 +49,6 @@ else(CLR_CMAKE_HOST_WIN32) if (CLR_CMAKE_HOST_ARCH_ARM OR CLR_CMAKE_HOST_ARCH_ARM64) set(JUMP_INSTRUCTION b) - elseif (CLR_CMAKE_HOST_ARCH_LOONGARCH64) - # FIXME for LOONGARCH64 - set(JUMP_INSTRUCTION "break //TODO, b") else() set(JUMP_INSTRUCTION jmp) endif() diff --git a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt index 954ebad775be17..31c5b0151ff7f7 100644 --- a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt @@ -183,8 +183,6 @@ if(CLR_CMAKE_TARGET_WIN32) list(APPEND PREPROCESS_DEFINITIONS -DTARGET_AMD64) elseif (CLR_CMAKE_HOST_ARCH_ARM64) list(APPEND PREPROCESS_DEFINITIONS -DTARGET_ARM64) - elseif (CLR_CMAKE_HOST_ARCH_LOONGARCH64) - list(APPEND PREPROCESS_DEFINITIONS -DTARGET_LOONGARCH64) elseif (CLR_CMAKE_HOST_ARCH_ARM) list(APPEND PREPROCESS_DEFINITIONS -DTARGET_ARM) elseif (CLR_CMAKE_HOST_ARCH_I386) diff --git a/src/coreclr/enablesanitizers.sh b/src/coreclr/enablesanitizers.sh index 7e8c4b9d7c4e0b..c79ef8c69ddf3f 100755 --- a/src/coreclr/enablesanitizers.sh +++ b/src/coreclr/enablesanitizers.sh @@ -73,11 +73,6 @@ else __ClangMinorVersion=9 __ExportSymbolizerPath=0 ;; - clang8.0) - __ClangMajorVersion=8 - __ClangMinorVersion=0 - __ExportSymbolizerPath=0 - ;; *) echo "Unknown arg: $i" return 1 diff --git a/src/coreclr/gc/env/gcenv.base.h b/src/coreclr/gc/env/gcenv.base.h index 3486769a51060a..59f01879d2ff19 100644 --- a/src/coreclr/gc/env/gcenv.base.h +++ b/src/coreclr/gc/env/gcenv.base.h @@ -230,11 +230,6 @@ typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(void* lpThreadParameter); #define MemoryBarrier __sync_synchronize #endif // __arm__ || __aarch64__ -#ifdef __loongarch64 - #define YieldProcessor() __asm__ volatile( "dbar 0; \n") - #define MemoryBarrier __sync_synchronize -#endif // __loongarch64 - #endif // _MSC_VER #ifdef _MSC_VER diff --git a/src/coreclr/gc/env/gcenv.interlocked.inl b/src/coreclr/gc/env/gcenv.interlocked.inl index 03d487a5320170..549b5d35909fed 100644 --- a/src/coreclr/gc/env/gcenv.interlocked.inl +++ b/src/coreclr/gc/env/gcenv.interlocked.inl @@ -17,9 +17,6 @@ __forceinline void Interlocked::ArmInterlockedOperationBarrier() // See PAL_ArmInterlockedOperationBarrier() in the PAL __sync_synchronize(); #endif // HOST_ARM64 -#ifdef HOST_LOONGARCH64 - __sync_synchronize(); -#endif //HOST_LOONGARCH64 } #endif // !_MSC_VER diff --git a/src/coreclr/gc/env/volatile.h b/src/coreclr/gc/env/volatile.h index c55b304b960c16..b47ff3847d4455 100644 --- a/src/coreclr/gc/env/volatile.h +++ b/src/coreclr/gc/env/volatile.h @@ -66,16 +66,14 @@ #error The Volatile type is currently only defined for Visual C++ and GNU C++ #endif -#if defined(__GNUC__) && !defined(HOST_X86) && !defined(HOST_AMD64) && !defined(HOST_ARM) && !defined(HOST_ARM64) && !defined(HOST_LOONGARCH64) && !defined(HOST_WASM) -#error The Volatile type is currently only defined for GCC when targeting x86, AMD64, ARM, ARM64, LOONGARCH64 or Wasm +#if defined(__GNUC__) && !defined(HOST_X86) && !defined(HOST_AMD64) && !defined(HOST_ARM) && !defined(HOST_ARM64) && !defined(HOST_WASM) +#error The Volatile type is currently only defined for GCC when targeting x86, AMD64, ARM, ARM64 or Wasm #endif #if defined(__GNUC__) #if defined(HOST_ARM) || defined(HOST_ARM64) // This is functionally equivalent to the MemoryBarrier() macro used on ARM on Windows. #define VOLATILE_MEMORY_BARRIER() asm volatile ("dmb ish" : : : "memory") -#elif defined(HOST_LOONGARCH64) -#define VOLATILE_MEMORY_BARRIER() asm volatile ("dbar 0 " : : : "memory") #else // // For GCC, we prevent reordering by the compiler by inserting the following after a volatile diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index cced07b47c1b43..ace66eac266709 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -5916,14 +5916,6 @@ extern "C" uint64_t __rdtsc(); #else // _MSC_VER extern "C" ptrdiff_t get_cycle_count(void); #endif // _MSC_VER -#elif defined(TARGET_LOONGARCH64) - static ptrdiff_t get_cycle_count() - { - ////FIXME: TODO for LOONGARCH64: - //ptrdiff_t cycle; - __asm__ volatile ("break \n"); - return 0; - } #else static ptrdiff_t get_cycle_count() { diff --git a/src/coreclr/gc/unix/gcenv.unix.cpp b/src/coreclr/gc/unix/gcenv.unix.cpp index 688e30613fb28e..895d2afdf395a9 100644 --- a/src/coreclr/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/gc/unix/gcenv.unix.cpp @@ -98,8 +98,6 @@ extern "C" # define __NR_membarrier 389 # elif defined(__aarch64__) # define __NR_membarrier 283 -# elif defined(__loongarch64) -# define __NR_membarrier 283 # elif # error Unknown architecture # endif @@ -161,7 +159,7 @@ FOR_ALL_NUMA_FUNCTIONS #endif // HAVE_NUMA_H -#if defined(HOST_ARM) || defined(HOST_ARM64) || defined(HOST_LOONGARCH64) +#if defined(HOST_ARM) || defined(HOST_ARM64) #define SYSCONF_GET_NUMPROCS _SC_NPROCESSORS_CONF #else #define SYSCONF_GET_NUMPROCS _SC_NPROCESSORS_ONLN diff --git a/src/coreclr/gcdump/gcdumpnonx86.cpp b/src/coreclr/gcdump/gcdumpnonx86.cpp index d9790a12d60e2e..235c8bf24acb11 100644 --- a/src/coreclr/gcdump/gcdumpnonx86.cpp +++ b/src/coreclr/gcdump/gcdumpnonx86.cpp @@ -69,9 +69,7 @@ PCSTR GetRegName (UINT32 regnum) static CHAR szRegName[16]; _snprintf_s(szRegName, ARRAY_SIZE(szRegName), sizeof(szRegName), "r%u", regnum); return szRegName; -#elif defined(TARGET_LOONGARCH64) - assert(!"unimplemented on LOONGARCH yet"); - return "???"; + #endif } diff --git a/src/coreclr/gcinfo/gcinfodumper.cpp b/src/coreclr/gcinfo/gcinfodumper.cpp index 7e49018353d714..3ea383832046b3 100644 --- a/src/coreclr/gcinfo/gcinfodumper.cpp +++ b/src/coreclr/gcinfo/gcinfodumper.cpp @@ -186,44 +186,6 @@ BOOL GcInfoDumper::ReportPointerRecord ( REG(Lr, Lr), { FIELD_OFFSET(T_CONTEXT, Sp) }, #undef REG -#elif defined(TARGET_LOONGARCH64) -#undef REG -#define REG(reg, field) { FIELD_OFFSET(Loongarch64VolatileContextPointer, field) } - REG(zero, R0), - REG(a0, A0), - REG(a1, A1), - REG(a2, A2), - REG(a3, A3), - REG(a4, A4), - REG(a5, A5), - REG(a6, A6), - REG(a7, A7), - REG(t0, T0), - REG(t1, T1), - REG(t2, T2), - REG(t3, T3), - REG(t4, T4), - REG(t5, T5), - REG(t6, T6), - REG(t7, T7), - REG(t8, T8), - REG(x0, X0), -#undef REG -#define REG(reg, field) { FIELD_OFFSET(T_KNONVOLATILE_CONTEXT_POINTERS, field) } - REG(s0, S0), - REG(s1, S1), - REG(s2, S2), - REG(s3, S3), - REG(s4, S4), - REG(s5, S5), - REG(s6, S6), - REG(s7, S7), - REG(s8, S8), - REG(tp, Tp), - REG(fp, Fp), - REG(ra, Ra), - { FIELD_OFFSET(T_CONTEXT, Sp) }, -#undef REG #else PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this platform.") #endif @@ -245,16 +207,10 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this #elif defined(TARGET_ARM) iSPRegister = (FIELD_OFFSET(T_CONTEXT, Sp) - FIELD_OFFSET(T_CONTEXT, R0)) / sizeof(ULONG); UINT iBFRegister = m_StackBaseRegister; -#elif defined(TARGET_LOONGARCH64) - assert(!"unimplemented on LOONGARCH yet"); - iSPRegister = 0; #endif #if defined(TARGET_ARM) || defined(TARGET_ARM64) BYTE* pContext = (BYTE*)&(pRD->volatileCurrContextPointers); -#elif defined(TARGET_LOONGARCH64) - assert(!"unimplemented on LOONGARCH yet"); - BYTE* pContext = (BYTE*)pRD->pCurrentContext; #else BYTE* pContext = (BYTE*)pRD->pCurrentContext; #endif @@ -321,8 +277,6 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this { break; } -#elif defined(TARGET_LOONGARCH64) - assert(!"unimplemented on LOONGARCH yet"); #endif { _ASSERTE(iReg < nCONTEXTRegisters); @@ -347,9 +301,6 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this { pReg = (SIZE_T*)((BYTE*)pRD->pCurrentContext + rgRegisters[iReg].cbContextOffset); } -#elif defined(TARGET_LOONGARCH64) - assert(!"unimplemented on LOONGARCH yet"); - pReg = (SIZE_T*)(pContext + rgRegisters[iReg].cbContextOffset); #else pReg = (SIZE_T*)(pContext + rgRegisters[iReg].cbContextOffset); #endif @@ -419,10 +370,6 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this { #if defined(TARGET_ARM) || defined(TARGET_ARM64) base = GC_SP_REL; -#elif defined(TARGET_LOONGARCH64) - assert(!"unimplemented on LOONGARCH yet"); - //TODO: should confirm ? - base = GC_SP_REL; #else if (0 == ctx) base = GC_SP_REL; @@ -452,8 +399,6 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this #if defined(TARGET_ARM) || defined(TARGET_ARM64) pContext = (BYTE*)pRD->pCurrentContextPointers; -#elif defined(TARGET_LOONGARCH64) - assert(!"unimplemented on LOONGARCH yet"); #else pContext = (BYTE*)pRD->pCallerContext; #endif @@ -657,9 +602,6 @@ GcInfoDumper::EnumerateStateChangesResults GcInfoDumper::EnumerateStateChanges ( { *(ppVolatileReg+iReg) = ®disp.pCurrentContext->X0 + iReg; } -#elif defined(TARGET_LOONGARCH64) -#pragma message("Unimplemented for LOONGARCH64 yet.") - assert(!"unimplemented on LOONGARCH yet"); #else PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on this platform.") #endif @@ -707,9 +649,9 @@ PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on th (GcInfoDecoderFlags)( DECODE_SECURITY_OBJECT | DECODE_CODE_LENGTH | DECODE_VARARG -#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#if defined(TARGET_ARM) || defined(TARGET_ARM64) | DECODE_HAS_TAILCALLS -#endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64 +#endif // TARGET_ARM || TARGET_ARM64 | DECODE_INTERRUPTIBILITY), offset); @@ -730,9 +672,6 @@ PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on th UINT32 safePointOffset = offset; #if defined(TARGET_AMD64) || defined(TARGET_ARM) || defined(TARGET_ARM64) safePointOffset++; -#elif defined(TARGET_LOONGARCH64) -#pragma message("Unimplemented for LOONGARCH64 yet.") - assert(!"unimplemented on LOONGARCH yet"); #endif if(safePointDecoder.IsSafePoint(safePointOffset)) { diff --git a/src/coreclr/gcinfo/gcinfoencoder.cpp b/src/coreclr/gcinfo/gcinfoencoder.cpp index 19e914676b2f81..8be8b262f1a4a1 100644 --- a/src/coreclr/gcinfo/gcinfoencoder.cpp +++ b/src/coreclr/gcinfo/gcinfoencoder.cpp @@ -487,7 +487,7 @@ GcInfoEncoder::GcInfoEncoder( m_ReversePInvokeFrameSlot = NO_REVERSE_PINVOKE_FRAME; #ifdef TARGET_AMD64 m_WantsReportOnlyLeaf = false; -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) m_HasTailCalls = false; #endif // TARGET_AMD64 m_IsVarArg = false; @@ -747,9 +747,6 @@ void GcInfoEncoder::SetStackBaseRegister( UINT32 regNum ) _ASSERTE( regNum != NO_STACK_BASE_REGISTER ); _ASSERTE(DENORMALIZE_STACK_BASE_REGISTER(NORMALIZE_STACK_BASE_REGISTER(regNum)) == regNum); _ASSERTE( m_StackBaseRegister == NO_STACK_BASE_REGISTER || m_StackBaseRegister == regNum ); -#if defined(TARGET_LOONGARCH64) - assert(regNum == 3 || 22 == regNum); -#endif m_StackBaseRegister = regNum; } @@ -765,7 +762,7 @@ void GcInfoEncoder::SetWantsReportOnlyLeaf() { m_WantsReportOnlyLeaf = true; } -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) void GcInfoEncoder::SetHasTailCalls() { m_HasTailCalls = true; @@ -1020,7 +1017,7 @@ void GcInfoEncoder::Build() (m_SizeOfEditAndContinuePreservedArea == NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA) && #ifdef TARGET_AMD64 !m_WantsReportOnlyLeaf && -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) !m_HasTailCalls && #endif // TARGET_AMD64 !IsStructReturnKind(m_ReturnKind); @@ -1031,9 +1028,6 @@ void GcInfoEncoder::Build() { // Slim encoding means nothing special, partially interruptible, maybe a default frame register GCINFO_WRITE(m_Info1, 0, 1, FlagsSize); // Slim encoding -#if defined(TARGET_LOONGARCH64) - assert(m_StackBaseRegister == 22 || 3 == m_StackBaseRegister); -#endif GCINFO_WRITE(m_Info1, (m_StackBaseRegister == NO_STACK_BASE_REGISTER) ? 0 : 1, 1, FlagsSize); GCINFO_WRITE(m_Info1, m_ReturnKind, SIZE_OF_RETURN_KIND_IN_SLIM_HEADER, RetKindSize); @@ -1046,13 +1040,10 @@ void GcInfoEncoder::Build() GCINFO_WRITE(m_Info1, (hasGSCookie ? 1 : 0), 1, FlagsSize); GCINFO_WRITE(m_Info1, ((m_PSPSymStackSlot != NO_PSP_SYM) ? 1 : 0), 1, FlagsSize); GCINFO_WRITE(m_Info1, m_contextParamType, 2, FlagsSize); -#if defined(TARGET_LOONGARCH64) - assert(m_StackBaseRegister == 22 || 3 == m_StackBaseRegister); -#endif GCINFO_WRITE(m_Info1, ((m_StackBaseRegister != NO_STACK_BASE_REGISTER) ? 1 : 0), 1, FlagsSize); #ifdef TARGET_AMD64 GCINFO_WRITE(m_Info1, (m_WantsReportOnlyLeaf ? 1 : 0), 1, FlagsSize); -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) GCINFO_WRITE(m_Info1, (m_HasTailCalls ? 1 : 0), 1, FlagsSize); #endif // TARGET_AMD64 GCINFO_WRITE(m_Info1, ((m_SizeOfEditAndContinuePreservedArea != NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA) ? 1 : 0), 1, FlagsSize); @@ -1149,9 +1140,6 @@ void GcInfoEncoder::Build() if(!slimHeader && (m_StackBaseRegister != NO_STACK_BASE_REGISTER)) { -#if defined(TARGET_LOONGARCH64) - assert(m_StackBaseRegister == 22 || 3 == m_StackBaseRegister); -#endif GCINFO_WRITE_VARL_U(m_Info1, NORMALIZE_STACK_BASE_REGISTER(m_StackBaseRegister), STACK_BASE_REGISTER_ENCBASE, StackBaseSize); } diff --git a/src/coreclr/inc/clrnt.h b/src/coreclr/inc/clrnt.h index 1edeaca9735abe..a833da67bcc9b5 100644 --- a/src/coreclr/inc/clrnt.h +++ b/src/coreclr/inc/clrnt.h @@ -1028,71 +1028,6 @@ RtlVirtualUnwind( #define IMAGE_REL_ARM64_PAGEOFFSET_12A 0x0006 // ADD 12 bit page offset #endif -#endif // TARGET_ARM64 - -#ifdef TARGET_LOONGARCH64 -#include "daccess.h" - -#define UNW_FLAG_NHANDLER 0x0 /* any handler */ -#define UNW_FLAG_EHANDLER 0x1 /* filter handler */ -#define UNW_FLAG_UHANDLER 0x2 /* unwind handler */ - -// This function returns the RVA of the end of the function (exclusive, so one byte after the actual end) -// using the unwind info on LOONGARCH64. (see ExternalAPIs\Win9CoreSystem\inc\winnt.h) -FORCEINLINE -ULONG64 -RtlpGetFunctionEndAddress ( - __in PT_RUNTIME_FUNCTION FunctionEntry, - __in ULONG64 ImageBase - ) -{ - ULONG64 FunctionLength; - - FunctionLength = FunctionEntry->UnwindData; - if ((FunctionLength & 3) != 0) { - FunctionLength = (FunctionLength >> 2) & 0x7ff; - } else { - memcpy(&FunctionLength, (void*)(ImageBase + FunctionLength), sizeof(UINT32)); - FunctionLength &= 0x3ffff; - } - - return FunctionEntry->BeginAddress + 4 * FunctionLength; -} - -#define RUNTIME_FUNCTION__BeginAddress(FunctionEntry) ((FunctionEntry)->BeginAddress) -#define RUNTIME_FUNCTION__SetBeginAddress(FunctionEntry,address) ((FunctionEntry)->BeginAddress = (address)) - -#define RUNTIME_FUNCTION__EndAddress(FunctionEntry, ImageBase) (RtlpGetFunctionEndAddress(FunctionEntry, (ULONG64)(ImageBase))) - -#define RUNTIME_FUNCTION__SetUnwindInfoAddress(prf,address) do { (prf)->UnwindData = (address); } while (0) - -typedef struct _UNWIND_INFO { - // dummy -} UNWIND_INFO, *PUNWIND_INFO; - -EXTERN_C -NTSYSAPI -PEXCEPTION_ROUTINE -NTAPI -RtlVirtualUnwind( - IN ULONG HandlerType, - IN ULONG64 ImageBase, - IN ULONG64 ControlPc, - IN PRUNTIME_FUNCTION FunctionEntry, - IN OUT PCONTEXT ContextRecord, - OUT PVOID *HandlerData, - OUT PULONG64 EstablisherFrame, - IN OUT PKNONVOLATILE_CONTEXT_POINTERS ContextPointers OPTIONAL - ); - -#ifndef IMAGE_FILE_MACHINE_LOONGARCH64 -#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // LOONGARCH64 Little-Endian #endif -#ifndef IMAGE_REL_LOONGARCH64_PC -#define IMAGE_REL_LOONGARCH64_PC 0x0004 -#endif - -#endif // TARGET_LOONGARCH64 - #endif // CLRNT_H_ diff --git a/src/coreclr/inc/cvconst.h b/src/coreclr/inc/cvconst.h index ff668feaee564c..3fbbfdd011a2cb 100644 --- a/src/coreclr/inc/cvconst.h +++ b/src/coreclr/inc/cvconst.h @@ -41,8 +41,7 @@ typedef enum CV_call_e { CV_CALL_CLRCALL = 0x16, // clr call CV_CALL_INLINE = 0x17, // Marker for routines always inlined and thus lacking a convention CV_CALL_NEAR_VECTOR = 0x18, // near left to right push with regs, callee pops stack - CV_CALL_LOONGARCHCALL = 0x19, // loongarch call - CV_CALL_RESERVED = 0x1a // first unused call enumeration + CV_CALL_RESERVED = 0x19 // first unused call enumeration // Do NOT add any more machine specific conventions. This is to be used for // calling conventions in the source only (e.g. __cdecl, __stdcall). @@ -375,7 +374,6 @@ typedef enum CV_CPU_TYPE_e { CV_CFL_ARMNT = 0xF4, CV_CFL_ARM64 = 0xF6, CV_CFL_D3D11_SHADER = 0x100, - CV_CFL_LOONGARCH64 = 0x200, } CV_CPU_TYPE_e; typedef enum CV_HREG_e { @@ -3648,7 +3646,6 @@ typedef enum CV_HREG_e { // Note: Next set of platform registers need to go into a new enum... // this one is above 44K now. - // TODO for LOONGARCH64: ?!?!? } CV_HREG_e; diff --git a/src/coreclr/inc/eetwain.h b/src/coreclr/inc/eetwain.h index 8653d5eed14cac..f2c51b5f724b6b 100644 --- a/src/coreclr/inc/eetwain.h +++ b/src/coreclr/inc/eetwain.h @@ -211,9 +211,9 @@ virtual bool UnwindStackFrame(PREGDISPLAY pContext, virtual bool IsGcSafe(EECodeInfo *pCodeInfo, DWORD dwRelOffset) = 0; -#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#if defined(TARGET_ARM) || defined(TARGET_ARM64) virtual bool HasTailCalls(EECodeInfo *pCodeInfo) = 0; -#endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64 +#endif // TARGET_ARM || TARGET_ARM64 #if defined(TARGET_AMD64) && defined(_DEBUG) /* @@ -455,10 +455,10 @@ virtual bool IsGcSafe( EECodeInfo *pCodeInfo, DWORD dwRelOffset); -#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#if defined(TARGET_ARM) || defined(TARGET_ARM64) virtual bool HasTailCalls(EECodeInfo *pCodeInfo); -#endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64 +#endif // TARGET_ARM || TARGET_ARM64 #if defined(TARGET_AMD64) && defined(_DEBUG) /* diff --git a/src/coreclr/inc/gcinfodecoder.h b/src/coreclr/inc/gcinfodecoder.h index 66814e64573227..13b95756302a65 100644 --- a/src/coreclr/inc/gcinfodecoder.h +++ b/src/coreclr/inc/gcinfodecoder.h @@ -85,8 +85,6 @@ inline TADDR GetSP(T_CONTEXT* context) return (TADDR)context->Sp; #elif defined(TARGET_ARM64) return (TADDR)context->Sp; -#elif defined(TARGET_LOONGARCH64) - return (TADDR)context->Sp; #else _ASSERTE(!"nyi for platform"); #endif @@ -100,8 +98,6 @@ inline PCODE GetIP(T_CONTEXT* context) return (PCODE)context->Pc; #elif defined(TARGET_ARM64) return (PCODE)context->Pc; -#elif defined(TARGET_LOONGARCH64) - return (PCODE)context->Pc; #else _ASSERTE(!"nyi for platform"); #endif @@ -216,9 +212,9 @@ enum GcInfoDecoderFlags DECODE_EDIT_AND_CONTINUE = 0x800, DECODE_REVERSE_PINVOKE_VAR = 0x1000, DECODE_RETURN_KIND = 0x2000, -#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#if defined(TARGET_ARM) || defined(TARGET_ARM64) DECODE_HAS_TAILCALLS = 0x4000, -#endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64 +#endif // TARGET_ARM || TARGET_ARM64 }; enum GcInfoHeaderFlags @@ -235,7 +231,7 @@ enum GcInfoHeaderFlags GC_INFO_HAS_STACK_BASE_REGISTER = 0x40, #ifdef TARGET_AMD64 GC_INFO_WANTS_REPORT_ONLY_LEAF = 0x80, -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) GC_INFO_HAS_TAILCALLS = 0x80, #endif // TARGET_AMD64 GC_INFO_HAS_EDIT_AND_CONTINUE_PRESERVED_SLOTS = 0x100, @@ -540,9 +536,9 @@ class GcInfoDecoder bool HasMethodTableGenericsInstContext(); bool GetIsVarArg(); bool WantsReportOnlyLeaf(); -#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#if defined(TARGET_ARM) || defined(TARGET_ARM64) bool HasTailCalls(); -#endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64 +#endif // TARGET_ARM || TARGET_ARM64 ReturnKind GetReturnKind(); UINT32 GetCodeLength(); UINT32 GetStackBaseRegister(); @@ -565,7 +561,7 @@ class GcInfoDecoder bool m_GenericSecretParamIsMT; #ifdef TARGET_AMD64 bool m_WantsReportOnlyLeaf; -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) bool m_HasTailCalls; #endif // TARGET_AMD64 INT32 m_SecurityObjectStackSlot; diff --git a/src/coreclr/inc/gcinfoencoder.h b/src/coreclr/inc/gcinfoencoder.h index 2848612303c1f1..559a211d8eeb52 100644 --- a/src/coreclr/inc/gcinfoencoder.h +++ b/src/coreclr/inc/gcinfoencoder.h @@ -440,7 +440,7 @@ class GcInfoEncoder // instead of once for each live function/funclet on the stack. // Called only by RyuJIT (not JIT64) void SetWantsReportOnlyLeaf(); -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) void SetHasTailCalls(); #endif // TARGET_AMD64 @@ -496,7 +496,7 @@ class GcInfoEncoder bool m_IsVarArg; #if defined(TARGET_AMD64) bool m_WantsReportOnlyLeaf; -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) bool m_HasTailCalls; #endif // TARGET_AMD64 INT32 m_SecurityObjectStackSlot; diff --git a/src/coreclr/inc/gcinfotypes.h b/src/coreclr/inc/gcinfotypes.h index 901f147b99975a..2ac8902283de61 100644 --- a/src/coreclr/inc/gcinfotypes.h +++ b/src/coreclr/inc/gcinfotypes.h @@ -156,7 +156,7 @@ struct GcStackSlot // 10 RT_ByRef // 11 RT_Unset -#elif defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#elif defined(TARGET_AMD64) || defined(TARGET_ARM64) // Slim Header: @@ -773,62 +773,6 @@ void FASTCALL decodeCallPattern(int pattern, #define LIVESTATE_RLE_RUN_ENCBASE 2 #define LIVESTATE_RLE_SKIP_ENCBASE 4 -#elif defined(TARGET_LOONGARCH64) -#ifndef TARGET_POINTER_SIZE -#define TARGET_POINTER_SIZE 8 // equal to sizeof(void*) and the managed pointer size in bytes for this target -#endif -#define NUM_NORM_CODE_OFFSETS_PER_CHUNK (64) -#define NUM_NORM_CODE_OFFSETS_PER_CHUNK_LOG2 (6) -#define NORMALIZE_STACK_SLOT(x) ((x)>>3) // GC Pointers are 8-bytes aligned -#define DENORMALIZE_STACK_SLOT(x) ((x)<<3) -#define NORMALIZE_CODE_LENGTH(x) ((x)>>2) // All Instructions are 4 bytes long -#define DENORMALIZE_CODE_LENGTH(x) ((x)<<2) -#define NORMALIZE_STACK_BASE_REGISTER(x) ((x)^22) // Encode Frame pointer fp=$22 as zero -#define DENORMALIZE_STACK_BASE_REGISTER(x) ((x)^22) -#define NORMALIZE_SIZE_OF_STACK_AREA(x) ((x)>>3) -#define DENORMALIZE_SIZE_OF_STACK_AREA(x) ((x)<<3) -#define CODE_OFFSETS_NEED_NORMALIZATION 0 -#define NORMALIZE_CODE_OFFSET(x) (x) // Instructions are 4 bytes long, but the safe-point -#define DENORMALIZE_CODE_OFFSET(x) (x) // offsets are encoded with a -1 adjustment. -#define NORMALIZE_REGISTER(x) (x) -#define DENORMALIZE_REGISTER(x) (x) -#define NORMALIZE_NUM_SAFE_POINTS(x) (x) -#define DENORMALIZE_NUM_SAFE_POINTS(x) (x) -#define NORMALIZE_NUM_INTERRUPTIBLE_RANGES(x) (x) -#define DENORMALIZE_NUM_INTERRUPTIBLE_RANGES(x) (x) - -#define PSP_SYM_STACK_SLOT_ENCBASE 6 -#define GENERICS_INST_CONTEXT_STACK_SLOT_ENCBASE 6 -#define SECURITY_OBJECT_STACK_SLOT_ENCBASE 6 -#define GS_COOKIE_STACK_SLOT_ENCBASE 6 -#define CODE_LENGTH_ENCBASE 8 -#define SIZE_OF_RETURN_KIND_IN_SLIM_HEADER 2 -#define SIZE_OF_RETURN_KIND_IN_FAT_HEADER 4 -////TODO for LOONGARCH64. -// FP/SP encoded as 0 or 2 ?? -#define STACK_BASE_REGISTER_ENCBASE 2 -#define SIZE_OF_STACK_AREA_ENCBASE 3 -#define SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE 4 -#define REVERSE_PINVOKE_FRAME_ENCBASE 6 -#define NUM_REGISTERS_ENCBASE 3 -#define NUM_STACK_SLOTS_ENCBASE 2 -#define NUM_UNTRACKED_SLOTS_ENCBASE 1 -#define NORM_PROLOG_SIZE_ENCBASE 5 -#define NORM_EPILOG_SIZE_ENCBASE 3 -#define NORM_CODE_OFFSET_DELTA_ENCBASE 3 -#define INTERRUPTIBLE_RANGE_DELTA1_ENCBASE 6 -#define INTERRUPTIBLE_RANGE_DELTA2_ENCBASE 6 -#define REGISTER_ENCBASE 3 -#define REGISTER_DELTA_ENCBASE 2 -#define STACK_SLOT_ENCBASE 6 -#define STACK_SLOT_DELTA_ENCBASE 4 -#define NUM_SAFE_POINTS_ENCBASE 3 -#define NUM_INTERRUPTIBLE_RANGES_ENCBASE 1 -#define NUM_EH_CLAUSES_ENCBASE 2 -#define POINTER_SIZE_ENCBASE 3 -#define LIVESTATE_RLE_RUN_ENCBASE 2 -#define LIVESTATE_RLE_SKIP_ENCBASE 4 - #else #ifndef TARGET_X86 diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index e6408d4369a65d..4d1fc11f0e8cb2 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -341,7 +341,7 @@ JITHELPER(CORINFO_HELP_GVMLOOKUP_FOR_SLOT, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB) -#if !defined(TARGET_ARM64) && !defined(TARGET_LOONGARCH64) +#ifndef TARGET_ARM64 JITHELPER(CORINFO_HELP_STACK_PROBE, JIT_StackProbe, CORINFO_HELP_SIG_REG_ONLY) #else JITHELPER(CORINFO_HELP_STACK_PROBE, NULL, CORINFO_HELP_SIG_UNDEF) diff --git a/src/coreclr/inc/llvm/ELF.h b/src/coreclr/inc/llvm/ELF.h index addc538725abbe..9e89b48b514a3c 100644 --- a/src/coreclr/inc/llvm/ELF.h +++ b/src/coreclr/inc/llvm/ELF.h @@ -343,10 +343,7 @@ enum { EM_NORC = 218, // Nanoradio Optimized RISC EM_CSR_KALIMBA = 219, // CSR Kalimba architecture family EM_AMDGPU = 224, // AMD GPU architecture - EM_RISCV = 243, // RISC-V - EM_LANAI = 244, // Lanai 32-bit processor - EM_BPF = 247, // Linux kernel bpf virtual machine - EM_LOONGARCH = 258, // LoongArch processor + EM_LOONGARCH = 258, // LoongArch processor // A request has been made to the maintainer of the official registry for // such numbers for an official value for WebAssembly. As soon as one is diff --git a/src/coreclr/inc/targetosarch.h b/src/coreclr/inc/targetosarch.h index 3f6d96b4d8a273..b2d1c06a22d669 100644 --- a/src/coreclr/inc/targetosarch.h +++ b/src/coreclr/inc/targetosarch.h @@ -64,4 +64,4 @@ class TargetArchitecture #endif }; -#endif // targetosarch_h +#endif // targetosarch_h \ No newline at end of file diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index b3527fc085a921..237b75275cec96 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -3829,7 +3829,6 @@ typedef LPOSVERSIONINFOEXA LPOSVERSIONINFOEX; #define IMAGE_FILE_MACHINE_I386 0x014c #define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian -#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // LOONGARCH64 Little-Endian typedef struct _SYSTEM_INFO { WORD wProcessorArchitecture_PAL_Undefined; diff --git a/src/coreclr/pal/inc/rt/ntimage.h b/src/coreclr/pal/inc/rt/ntimage.h index 78c8fb7307580a..1880375184f057 100644 --- a/src/coreclr/pal/inc/rt/ntimage.h +++ b/src/coreclr/pal/inc/rt/ntimage.h @@ -239,7 +239,6 @@ typedef struct _IMAGE_FILE_HEADER { #define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) #define IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian #define IMAGE_FILE_MACHINE_CEE 0xC0EE -#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // LOONGARCH64. // // Directory format. @@ -1026,11 +1025,6 @@ typedef IMAGE_RELOCATION UNALIGNED *PIMAGE_RELOCATION; #define IMAGE_REL_IA64_GPREL32 0x001C #define IMAGE_REL_IA64_ADDEND 0x001F -// -// LOONGARCH64 relocation types -// -#define IMAGE_REL_LOONGARCH64_PC 0x0004 - // // CEF relocation types. // From c806a8f09767553db76112d463929b5bfe1b3f0c Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Fri, 14 Jan 2022 12:05:03 +0800 Subject: [PATCH 15/19] [LoongArch64] amend code for compiling error on LoongArch64-machine. --- src/coreclr/binder/assemblybindercommon.cpp | 2 +- src/coreclr/debug/createdump/datatarget.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/coreclr/binder/assemblybindercommon.cpp b/src/coreclr/binder/assemblybindercommon.cpp index 830c673ea06a63..31a46e41d82417 100644 --- a/src/coreclr/binder/assemblybindercommon.cpp +++ b/src/coreclr/binder/assemblybindercommon.cpp @@ -1448,7 +1448,7 @@ BOOL AssemblyBinderCommon::IsValidArchitecture(PEKIND kArchitecture) #elif defined(TARGET_ARM64) peARM64; #else - PORTABILITY_ASSERT("processArchitecture"); + peMSIL; #endif return (kArchitecture == processArchitecture); diff --git a/src/coreclr/debug/createdump/datatarget.cpp b/src/coreclr/debug/createdump/datatarget.cpp index 7d2ab1973ff602..d119498c2b2b53 100644 --- a/src/coreclr/debug/createdump/datatarget.cpp +++ b/src/coreclr/debug/createdump/datatarget.cpp @@ -65,6 +65,8 @@ DumpDataTarget::GetMachineType( *machine = IMAGE_FILE_MACHINE_ARM64; #elif HOST_X86 *machine = IMAGE_FILE_MACHINE_I386; +#elif HOST_LOONGARCH64 + *machine = IMAGE_FILE_MACHINE_LOONGARCH64; #else #error Unsupported architecture #endif @@ -75,7 +77,7 @@ HRESULT STDMETHODCALLTYPE DumpDataTarget::GetPointerSize( /* [out] */ ULONG32 *size) { -#if defined(HOST_AMD64) || defined(HOST_ARM64) +#if defined(HOST_AMD64) || defined(HOST_ARM64) || defined(HOST_LOONGARCH64) *size = 8; #elif defined(HOST_ARM) || defined(HOST_X86) *size = 4; From f829e9a90608dbc0e6e354aa3e3b805199b239e9 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Wed, 19 Jan 2022 09:51:17 +0800 Subject: [PATCH 16/19] [LoongArch64] update the version of the `LICENSE description`. --- src/coreclr/debug/daccess/loongarch64/primitives.cpp | 5 ----- src/coreclr/debug/di/loongarch64/cordbregisterset.cpp | 3 --- src/coreclr/debug/di/loongarch64/primitives.cpp | 5 ----- src/coreclr/debug/ee/loongarch64/dbghelpers.S | 3 --- src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp | 3 --- src/coreclr/debug/ee/loongarch64/primitives.cpp | 5 ----- src/coreclr/debug/inc/loongarch64/primitives.h | 3 --- src/coreclr/debug/shared/loongarch64/primitives.cpp | 3 --- 8 files changed, 30 deletions(-) diff --git a/src/coreclr/debug/daccess/loongarch64/primitives.cpp b/src/coreclr/debug/daccess/loongarch64/primitives.cpp index cc67cb10432df7..34d5201c080819 100644 --- a/src/coreclr/debug/daccess/loongarch64/primitives.cpp +++ b/src/coreclr/debug/daccess/loongarch64/primitives.cpp @@ -1,10 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// Copyright (c) Loongson Technology. All rights reserved. - -// #include "stdafx.h" diff --git a/src/coreclr/debug/di/loongarch64/cordbregisterset.cpp b/src/coreclr/debug/di/loongarch64/cordbregisterset.cpp index fe67ebdb68904d..5150dddda12625 100644 --- a/src/coreclr/debug/di/loongarch64/cordbregisterset.cpp +++ b/src/coreclr/debug/di/loongarch64/cordbregisterset.cpp @@ -1,8 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// Copyright (c) Loongson Technology. All rights reserved. //***************************************************************************** // File: CordbRegisterSet.cpp diff --git a/src/coreclr/debug/di/loongarch64/primitives.cpp b/src/coreclr/debug/di/loongarch64/primitives.cpp index dac7063c7e8791..1c60eb66b1dba4 100644 --- a/src/coreclr/debug/di/loongarch64/primitives.cpp +++ b/src/coreclr/debug/di/loongarch64/primitives.cpp @@ -1,9 +1,4 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// Copyright (c) Loongson Technology. All rights reserved. - -// #include "../../shared/loongarch64/primitives.cpp" diff --git a/src/coreclr/debug/ee/loongarch64/dbghelpers.S b/src/coreclr/debug/ee/loongarch64/dbghelpers.S index aa4233e77364fb..07103d6c6771b3 100644 --- a/src/coreclr/debug/ee/loongarch64/dbghelpers.S +++ b/src/coreclr/debug/ee/loongarch64/dbghelpers.S @@ -1,8 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// Copyright (c) Loongson Technology. All rights reserved. #include "asmconstants.h" #include "unixasmmacros.inc" diff --git a/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp b/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp index 6c731e0cfc5cb1..8d8bfa78063522 100644 --- a/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp +++ b/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp @@ -1,8 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// Copyright (c) Loongson Technology. All rights reserved. //***************************************************************************** // File: Loongarch64walker.cpp diff --git a/src/coreclr/debug/ee/loongarch64/primitives.cpp b/src/coreclr/debug/ee/loongarch64/primitives.cpp index ac1fa859f0d85a..bef18245f06dba 100644 --- a/src/coreclr/debug/ee/loongarch64/primitives.cpp +++ b/src/coreclr/debug/ee/loongarch64/primitives.cpp @@ -1,10 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// Copyright (c) Loongson Technology. All rights reserved. - -// #include "stdafx.h" #include "threads.h" diff --git a/src/coreclr/debug/inc/loongarch64/primitives.h b/src/coreclr/debug/inc/loongarch64/primitives.h index 71a29defcabd98..f5bba34508444f 100644 --- a/src/coreclr/debug/inc/loongarch64/primitives.h +++ b/src/coreclr/debug/inc/loongarch64/primitives.h @@ -1,8 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// Copyright (c) Loongson Technology. All rights reserved. //***************************************************************************** // File: primitives.h diff --git a/src/coreclr/debug/shared/loongarch64/primitives.cpp b/src/coreclr/debug/shared/loongarch64/primitives.cpp index f46c04aa558925..08635ec8693f86 100644 --- a/src/coreclr/debug/shared/loongarch64/primitives.cpp +++ b/src/coreclr/debug/shared/loongarch64/primitives.cpp @@ -1,8 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// Copyright (c) Loongson Technology. All rights reserved. //***************************************************************************** // File: primitives.cpp From 21367019509a83deeaadfc8027277016fc59f23a Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Thu, 24 Feb 2022 15:13:03 +0800 Subject: [PATCH 17/19] [LoongArch64] amend the code about debug. --- src/coreclr/debug/createdump/threadinfo.h | 7 +- .../debug/di/loongarch64/cordbregisterset.cpp | 244 ++++++++++++++---- src/coreclr/debug/inc/dbgipcevents.h | 34 --- .../debug/inc/loongarch64/primitives.h | 23 +- src/coreclr/inc/clrnt.h | 10 +- src/coreclr/inc/cordebug.idl | 7 +- src/coreclr/pal/inc/pal.h | 4 +- src/coreclr/pal/prebuilt/inc/cordebug.h | 85 +++--- 8 files changed, 255 insertions(+), 159 deletions(-) diff --git a/src/coreclr/debug/createdump/threadinfo.h b/src/coreclr/debug/createdump/threadinfo.h index 0f9215c8fbbdb2..41c6ac05405650 100644 --- a/src/coreclr/debug/createdump/threadinfo.h +++ b/src/coreclr/debug/createdump/threadinfo.h @@ -27,12 +27,7 @@ class CrashInfo; #define user_regs_struct user_regs #define user_fpregs_struct user_fpregs #elif defined(__loongarch64) -//usr/include/loongarch64-linux-gnu/sys/user.h -//struct user_regs_struct -//{ -// unsigned long long gpr[32]; -// unsigned long long pc; -//} __attribute__((__packed__)); +// struct user_regs_struct {} defined `/usr/include/loongarch64-linux-gnu/sys/user.h` struct user_fpregs_struct { diff --git a/src/coreclr/debug/di/loongarch64/cordbregisterset.cpp b/src/coreclr/debug/di/loongarch64/cordbregisterset.cpp index 5150dddda12625..679509e61b2b8e 100644 --- a/src/coreclr/debug/di/loongarch64/cordbregisterset.cpp +++ b/src/coreclr/debug/di/loongarch64/cordbregisterset.cpp @@ -12,45 +12,73 @@ HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG64* pAvailable) { - assert(!"unimplemented on LOONGARCH yet"); FAIL_IF_NEUTERED(this); VALIDATE_POINTER_TO_OBJECT(pAvailable, ULONG64 *); *pAvailable = SETBITULONG64(REGISTER_LOONGARCH64_PC) | SETBITULONG64(REGISTER_LOONGARCH64_SP) -#if 0 - | SETBITULONG64(REGISTER_LOONGARCH64_X0) - | SETBITULONG64(REGISTER_LOONGARCH64_X1) - | SETBITULONG64(REGISTER_LOONGARCH64_X2) - | SETBITULONG64(REGISTER_LOONGARCH64_X3) - | SETBITULONG64(REGISTER_LOONGARCH64_X4) - | SETBITULONG64(REGISTER_LOONGARCH64_X5) - | SETBITULONG64(REGISTER_LOONGARCH64_X6) - | SETBITULONG64(REGISTER_LOONGARCH64_X7) - | SETBITULONG64(REGISTER_LOONGARCH64_X8) - | SETBITULONG64(REGISTER_LOONGARCH64_X9) - | SETBITULONG64(REGISTER_LOONGARCH64_X10) - | SETBITULONG64(REGISTER_LOONGARCH64_X11) - | SETBITULONG64(REGISTER_LOONGARCH64_X12) - | SETBITULONG64(REGISTER_LOONGARCH64_X13) - | SETBITULONG64(REGISTER_LOONGARCH64_X14) - | SETBITULONG64(REGISTER_LOONGARCH64_X15) - | SETBITULONG64(REGISTER_LOONGARCH64_X16) - | SETBITULONG64(REGISTER_LOONGARCH64_X17) - | SETBITULONG64(REGISTER_LOONGARCH64_X18) - | SETBITULONG64(REGISTER_LOONGARCH64_X19) - | SETBITULONG64(REGISTER_LOONGARCH64_X20) - | SETBITULONG64(REGISTER_LOONGARCH64_X21) - | SETBITULONG64(REGISTER_LOONGARCH64_X22) - | SETBITULONG64(REGISTER_LOONGARCH64_X23) - | SETBITULONG64(REGISTER_LOONGARCH64_X24) - | SETBITULONG64(REGISTER_LOONGARCH64_X25) - | SETBITULONG64(REGISTER_LOONGARCH64_X26) - | SETBITULONG64(REGISTER_LOONGARCH64_X27) - | SETBITULONG64(REGISTER_LOONGARCH64_X28) -#endif | SETBITULONG64(REGISTER_LOONGARCH64_FP) - | SETBITULONG64(REGISTER_LOONGARCH64_RA); + | SETBITULONG64(REGISTER_LOONGARCH64_RA) + | SETBITULONG64(REGISTER_LOONGARCH64_TP) + | SETBITULONG64(REGISTER_LOONGARCH64_A0) + | SETBITULONG64(REGISTER_LOONGARCH64_A1) + | SETBITULONG64(REGISTER_LOONGARCH64_A2) + | SETBITULONG64(REGISTER_LOONGARCH64_A3) + | SETBITULONG64(REGISTER_LOONGARCH64_A4) + | SETBITULONG64(REGISTER_LOONGARCH64_A5) + | SETBITULONG64(REGISTER_LOONGARCH64_A6) + | SETBITULONG64(REGISTER_LOONGARCH64_A7) + | SETBITULONG64(REGISTER_LOONGARCH64_T0) + | SETBITULONG64(REGISTER_LOONGARCH64_T1) + | SETBITULONG64(REGISTER_LOONGARCH64_T2) + | SETBITULONG64(REGISTER_LOONGARCH64_T3) + | SETBITULONG64(REGISTER_LOONGARCH64_T4) + | SETBITULONG64(REGISTER_LOONGARCH64_T5) + | SETBITULONG64(REGISTER_LOONGARCH64_T6) + | SETBITULONG64(REGISTER_LOONGARCH64_T7) + | SETBITULONG64(REGISTER_LOONGARCH64_T8) + | SETBITULONG64(REGISTER_LOONGARCH64_X0) + | SETBITULONG64(REGISTER_LOONGARCH64_S0) + | SETBITULONG64(REGISTER_LOONGARCH64_S1) + | SETBITULONG64(REGISTER_LOONGARCH64_S2) + | SETBITULONG64(REGISTER_LOONGARCH64_S3) + | SETBITULONG64(REGISTER_LOONGARCH64_S4) + | SETBITULONG64(REGISTER_LOONGARCH64_S5) + | SETBITULONG64(REGISTER_LOONGARCH64_S6) + | SETBITULONG64(REGISTER_LOONGARCH64_S7) + | SETBITULONG64(REGISTER_LOONGARCH64_S8) + | SETBITULONG64(REGISTER_LOONGARCH64_F0) + | SETBITULONG64(REGISTER_LOONGARCH64_F1) + | SETBITULONG64(REGISTER_LOONGARCH64_F2) + | SETBITULONG64(REGISTER_LOONGARCH64_F3) + | SETBITULONG64(REGISTER_LOONGARCH64_F4) + | SETBITULONG64(REGISTER_LOONGARCH64_F5) + | SETBITULONG64(REGISTER_LOONGARCH64_F6) + | SETBITULONG64(REGISTER_LOONGARCH64_F7) + | SETBITULONG64(REGISTER_LOONGARCH64_F8) + | SETBITULONG64(REGISTER_LOONGARCH64_F9) + | SETBITULONG64(REGISTER_LOONGARCH64_F10) + | SETBITULONG64(REGISTER_LOONGARCH64_F11) + | SETBITULONG64(REGISTER_LOONGARCH64_F12) + | SETBITULONG64(REGISTER_LOONGARCH64_F13) + | SETBITULONG64(REGISTER_LOONGARCH64_F14) + | SETBITULONG64(REGISTER_LOONGARCH64_F15) + | SETBITULONG64(REGISTER_LOONGARCH64_F16) + | SETBITULONG64(REGISTER_LOONGARCH64_F17) + | SETBITULONG64(REGISTER_LOONGARCH64_F18) + | SETBITULONG64(REGISTER_LOONGARCH64_F19) + | SETBITULONG64(REGISTER_LOONGARCH64_F20) + | SETBITULONG64(REGISTER_LOONGARCH64_F21) + | SETBITULONG64(REGISTER_LOONGARCH64_F22) + | SETBITULONG64(REGISTER_LOONGARCH64_F23) + | SETBITULONG64(REGISTER_LOONGARCH64_F24) + | SETBITULONG64(REGISTER_LOONGARCH64_F25) + | SETBITULONG64(REGISTER_LOONGARCH64_F26) + | SETBITULONG64(REGISTER_LOONGARCH64_F27) + | SETBITULONG64(REGISTER_LOONGARCH64_F28) + | SETBITULONG64(REGISTER_LOONGARCH64_F29) + | SETBITULONG64(REGISTER_LOONGARCH64_F30) + | SETBITULONG64(REGISTER_LOONGARCH64_F31); return S_OK; } @@ -58,7 +86,6 @@ HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG64* pAvailable) HRESULT CordbRegisterSet::GetRegisters(ULONG64 mask, ULONG32 regCount, CORDB_REGISTER regBuffer[]) { - assert(!"unimplemented on LOONGARCH yet"); PUBLIC_REENTRANT_API_ENTRY(this); FAIL_IF_NEUTERED(this); ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess()); @@ -67,17 +94,46 @@ HRESULT CordbRegisterSet::GetRegisters(ULONG64 mask, ULONG32 regCount, VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER, regCount, true, true); - // @LOONGARCH64TODO: floating point support -#if 0 for (int i = REGISTER_LOONGARCH64_PC; - i <= REGISTER_LOONGARCH64_LR && iRegister < regCount; + i <= REGISTER_LOONGARCH64_F31 && iRegister < regCount; i++) { if (mask & SETBITULONG64(i)) { - if ((i >= REGISTER_LOONGARCH64_X0) && (i <= REGISTER_LOONGARCH64_X28)) + _ASSERTE (iRegister < regCount); + + if ((i >= REGISTER_LOONGARCH64_A0) && (i <= REGISTER_LOONGARCH64_X0)) + { + regBuffer[iRegister++] = *(ULONG64*)((char*)(&m_rd->A0) + ((i - REGISTER_LOONGARCH64_A0) << 3)); + continue; + } + + if ((i >= REGISTER_LOONGARCH64_S0) && (i <= REGISTER_LOONGARCH64_S8)) + { + regBuffer[iRegister++] = *(ULONG64*)((char*)(&m_rd->S0) + ((i - REGISTER_LOONGARCH64_S0) << 3)); + continue; + } + + if ((i >= REGISTER_LOONGARCH64_F0) && (i <= REGISTER_LOONGARCH64_F31)) { - regBuffer[iRegister++] = m_rd->X[i - REGISTER_LOONGARCH64_X0]; + if (!m_thread->m_fFloatStateValid) + { + HRESULT hr = S_OK; + EX_TRY + { + m_thread->LoadFloatState(); + } + EX_CATCH_HRESULT(hr); + + if ( !SUCCEEDED(hr) ) + { + return hr; + } + LOG( ( LF_CORDB, LL_INFO1000, "CRS::GR: Loaded float state\n" ) ); + } + + regBuffer[iRegister++] = *(CORDB_REGISTER*) + &(m_thread->m_floatValues[(i - REGISTER_LOONGARCH64_F0)]); continue; } @@ -89,12 +145,16 @@ HRESULT CordbRegisterSet::GetRegisters(ULONG64 mask, ULONG32 regCount, regBuffer[iRegister++] = m_rd->SP; break; case REGISTER_LOONGARCH64_FP: regBuffer[iRegister++] = m_rd->FP; break; + case REGISTER_LOONGARCH64_RA: + regBuffer[iRegister++] = m_rd->RA; break; + case REGISTER_LOONGARCH64_TP: + regBuffer[iRegister++] = m_rd->TP; break; default: _ASSERTE(false); break; } } } -#endif + _ASSERTE (iRegister <= regCount); return S_OK; } @@ -106,8 +166,19 @@ HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG32 regCount, FAIL_IF_NEUTERED(this); VALIDATE_POINTER_TO_OBJECT_ARRAY(pAvailable, CORDB_REGISTER, regCount, true, true); - // Defer to adapter for v1.0 interface - return GetRegistersAvailableAdapter(regCount, pAvailable); + for (int i = 0 ; i < (int)regCount ; ++i) + { + if (i * 8 <= REGISTER_LOONGARCH64_F31) + { + pAvailable[i] = (i * 8 == REGISTER_LOONGARCH64_F31) ? BYTE(0x1) : BYTE(0xff); + } + else + { + pAvailable[i] = 0; + } + } + + return S_OK; } @@ -117,8 +188,74 @@ HRESULT CordbRegisterSet::GetRegisters(ULONG32 maskCount, BYTE mask[], FAIL_IF_NEUTERED(this); VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER, regCount, true, true); - // Defer to adapter for v1.0 interface - return GetRegistersAdapter(maskCount, mask, regCount, regBuffer); + UINT iRegister = 0; + + for (int m = 0 ; m < (int)maskCount ; ++m) + { + for (int bit = 0 ; bit < 8 ; ++bit) + { + if (mask[m] & SETBITULONG64(bit)) + { + _ASSERTE (iRegister < regCount); + + int i = m * 8 + bit; + + if ((i >= REGISTER_LOONGARCH64_A0) && (i <= REGISTER_LOONGARCH64_X0)) + { + regBuffer[iRegister++] = *(ULONG64*)((char*)(&m_rd->A0) + ((i - REGISTER_LOONGARCH64_A0) << 3)); + continue; + } + + if ((i >= REGISTER_LOONGARCH64_S0) && (i <= REGISTER_LOONGARCH64_S8)) + { + regBuffer[iRegister++] = *(ULONG64*)((char*)(&m_rd->S0) + ((i - REGISTER_LOONGARCH64_S0) << 3)); + continue; + } + + + if ((i >= REGISTER_LOONGARCH64_F0) && (i <= REGISTER_LOONGARCH64_F31)) + { + if (!m_thread->m_fFloatStateValid) + { + HRESULT hr = S_OK; + EX_TRY + { + m_thread->LoadFloatState(); + } + EX_CATCH_HRESULT(hr); + + if ( !SUCCEEDED(hr) ) + { + return hr; + } + LOG( ( LF_CORDB, LL_INFO1000, "CRS::GR: Loaded float state\n" ) ); + } + + regBuffer[iRegister++] = *(CORDB_REGISTER*) + &(m_thread->m_floatValues[(i - REGISTER_LOONGARCH64_F0)]); + continue; + } + + switch (i) + { + case REGISTER_LOONGARCH64_PC: + regBuffer[iRegister++] = m_rd->PC; break; + case REGISTER_LOONGARCH64_SP: + regBuffer[iRegister++] = m_rd->SP; break; + case REGISTER_LOONGARCH64_FP: + regBuffer[iRegister++] = m_rd->FP; break; + case REGISTER_LOONGARCH64_RA: + regBuffer[iRegister++] = m_rd->RA; break; + case REGISTER_LOONGARCH64_TP: + regBuffer[iRegister++] = m_rd->TP; break; + default: + _ASSERTE(false); break; + } + } + } + } + + return S_OK; } @@ -128,16 +265,25 @@ HRESULT CordbRegisterSet::GetRegisters(ULONG32 maskCount, BYTE mask[], void CordbRegisterSet::InternalCopyRDToContext(DT_CONTEXT *pInputContext) { INTERNAL_SYNC_API_ENTRY(GetProcess()); _ASSERTE(pInputContext); - assert(!"unimplemented on LOONGARCH yet"); if ((pInputContext->ContextFlags & DT_CONTEXT_INTEGER) == DT_CONTEXT_INTEGER) { -#if 0 - for (int i = 0 ; i < 29 ; ++i) + ULONG64* pDest = &pInputContext->A0; + ULONG64* pSrc = &m_rd->A0; + for (int i = REGISTER_LOONGARCH64_A0; i < REGISTER_LOONGARCH64_X0; ++i) { - pInputContext->X[i] = m_rd->X[i]; + *pDest++ = *pSrc++; } -#endif + + pDest = &pInputContext->S0; + pSrc = &m_rd->S0; + for (int i = REGISTER_LOONGARCH64_S0; i <= REGISTER_LOONGARCH64_S8; ++i) + { + *pDest++ = *pSrc++; + } + + pInputContext->TP = m_rd->TP; + pInputContext->RA = m_rd->RA; } if ((pInputContext->ContextFlags & DT_CONTEXT_CONTROL) == DT_CONTEXT_CONTROL) diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h index a5560929a849af..6cea497955c4fd 100644 --- a/src/coreclr/debug/inc/dbgipcevents.h +++ b/src/coreclr/debug/inc/dbgipcevents.h @@ -1138,72 +1138,38 @@ struct MSLAYOUT DebuggerREGDISPLAY SIZE_T PC; #elif defined(TARGET_LOONGARCH64) #define DebuggerIPCE_FloatCount 32 - SIZE_T R0; - void *pR0; SIZE_T RA; - void *pRA; SIZE_T TP; - void *pTP; SIZE_T SP; - void *pSP; SIZE_T A0; - void *pA0; SIZE_T A1; - void *pA1; SIZE_T A2; - void *pA2; SIZE_T A3; - void *pA3; SIZE_T A4; - void *pA4; SIZE_T A5; - void *pA5; SIZE_T A6; - void *pA6; SIZE_T A7; - void *pA7; SIZE_T T0; - void *pT0; SIZE_T T1; - void *pT1; SIZE_T T2; - void *pT2; SIZE_T T3; - void *pT3; SIZE_T T4; - void *pT4; SIZE_T T5; - void *pT5; SIZE_T T6; - void *pT6; SIZE_T T7; - void *pT7; SIZE_T T8; - void *pT8; SIZE_T X0; - void *pX0; SIZE_T FP; - void *pFP; SIZE_T S0; - void *pS0; SIZE_T S1; - void *pS1; SIZE_T S2; - void *pS2; SIZE_T S3; - void *pS3; SIZE_T S4; - void *pS4; SIZE_T S5; - void *pS5; SIZE_T S6; - void *pS6; SIZE_T S7; - void *pS7; SIZE_T S8; - void *pS8; SIZE_T PC; - void *pPC; #else #define DebuggerIPCE_FloatCount 1 diff --git a/src/coreclr/debug/inc/loongarch64/primitives.h b/src/coreclr/debug/inc/loongarch64/primitives.h index f5bba34508444f..a28c108bf99ae1 100644 --- a/src/coreclr/debug/inc/loongarch64/primitives.h +++ b/src/coreclr/debug/inc/loongarch64/primitives.h @@ -24,7 +24,7 @@ typedef DPTR(CORDB_ADDRESS_TYPE) PTR_CORDB_ADDRESS_TYPE; #define PRD_TYPE LONG #define CORDbg_BREAK_INSTRUCTION_SIZE 4 -#define CORDbg_BREAK_INSTRUCTION (LONG)0xD43E0000 +#define CORDbg_BREAK_INSTRUCTION (LONG)0x002A0005 inline CORDB_ADDRESS GetPatchEndAddr(CORDB_ADDRESS patchAddr) { @@ -48,7 +48,6 @@ inline CORDB_ADDRESS GetPatchEndAddr(CORDB_ADDRESS patchAddr) constexpr CorDebugRegister g_JITToCorDbgReg[] = { - REGISTER_LOONGARCH64_R0, REGISTER_LOONGARCH64_RA, REGISTER_LOONGARCH64_TP, REGISTER_LOONGARCH64_SP, @@ -118,7 +117,7 @@ inline BOOL CompareControlRegisters(const DT_CONTEXT * pCtx1, const DT_CONTEXT * { LIMITED_METHOD_DAC_CONTRACT; - // @LOONGARCHTODO: Sort out frame registers + // TODO-LoongArch64: Sort out frame registers if ((pCtx1->PC == pCtx2->PC) && (pCtx1->SP == pCtx2->SP) && @@ -209,8 +208,7 @@ inline void CORDbgAdjustPCForBreakInstruction(DT_CONTEXT* pContext) { LIMITED_METHOD_CONTRACT; - // @LOONGARCHTODO: LOONGARCH appears to leave the PC at the start of the breakpoint (at least according to Windbg, - // which may be adjusting the view). + // LoongArch64 appears to leave the PC at the start of the breakpoint. return; } @@ -223,23 +221,20 @@ inline bool AddressIsBreakpoint(CORDB_ADDRESS_TYPE* address) inline void SetSSFlag(DT_CONTEXT *pContext) { -assert(!"unimplemented on LOONGARCH yet"); - _ASSERTE(pContext != NULL); -// pContext->Cpsr |= 0x00200000; + // TODO-LoongArch64: LoongArch64 doesn't support cpsr. + _ASSERTE(!"unimplemented on LOONGARCH64 yet"); } inline void UnsetSSFlag(DT_CONTEXT *pContext) { -assert(!"unimplemented on LOONGARCH yet"); - _ASSERTE(pContext != NULL); -// pContext->Cpsr &= ~0x00200000; + // TODO-LoongArch64: LoongArch64 doesn't support cpsr. + _ASSERTE(!"unimplemented on LOONGARCH64 yet"); } inline bool IsSSFlagEnabled(DT_CONTEXT * pContext) { -assert(!"unimplemented on LOONGARCH yet"); - _ASSERTE(pContext != NULL); -// return (pContext->Cpsr & 0x00200000) != 0; + // TODO-LoongArch64: LoongArch64 doesn't support cpsr. + _ASSERTE(!"unimplemented on LOONGARCH64 yet"); return false; } diff --git a/src/coreclr/inc/clrnt.h b/src/coreclr/inc/clrnt.h index 0e1480c3cebc59..9d5e8c9cb8fc28 100644 --- a/src/coreclr/inc/clrnt.h +++ b/src/coreclr/inc/clrnt.h @@ -1069,14 +1069,10 @@ RtlVirtualUnwind( IN OUT PKNONVOLATILE_CONTEXT_POINTERS ContextPointers OPTIONAL ); -#ifndef IMAGE_REL_LOONGARCH64_PC -#define IMAGE_REL_LOONGARCH64_PC 0x0003 -#endif +#endif // TARGET_LOONGARCH64 -#ifndef IMAGE_REL_LOONGARCH64_JIR -#define IMAGE_REL_LOONGARCH64_JIR 0x0004 +#ifndef IMAGE_FILE_MACHINE_LOONGARCH64 +#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // LOONGARCH64. #endif -#endif // TARGET_LOONGARCH64 - #endif // CLRNT_H_ diff --git a/src/coreclr/inc/cordebug.idl b/src/coreclr/inc/cordebug.idl index a5f67044fb6a7b..785a00d5bda5ab 100644 --- a/src/coreclr/inc/cordebug.idl +++ b/src/coreclr/inc/cordebug.idl @@ -3919,10 +3919,11 @@ interface ICorDebugRegisterSet : IUnknown REGISTER_ARM64_V31, // LoongArch64 registers - REGISTER_LOONGARCH64_R0 = 0, + REGISTER_LOONGARCH64_PC = 0, + REGISTER_LOONGARCH64_SP, + REGISTER_LOONGARCH64_FP, REGISTER_LOONGARCH64_RA, REGISTER_LOONGARCH64_TP, - REGISTER_LOONGARCH64_SP, REGISTER_LOONGARCH64_A0, REGISTER_LOONGARCH64_A1, REGISTER_LOONGARCH64_A2, @@ -3941,7 +3942,6 @@ interface ICorDebugRegisterSet : IUnknown REGISTER_LOONGARCH64_T7, REGISTER_LOONGARCH64_T8, REGISTER_LOONGARCH64_X0, - REGISTER_LOONGARCH64_FP, REGISTER_LOONGARCH64_S0, REGISTER_LOONGARCH64_S1, REGISTER_LOONGARCH64_S2, @@ -3951,7 +3951,6 @@ interface ICorDebugRegisterSet : IUnknown REGISTER_LOONGARCH64_S6, REGISTER_LOONGARCH64_S7, REGISTER_LOONGARCH64_S8, - REGISTER_LOONGARCH64_PC, REGISTER_LOONGARCH64_F0, REGISTER_LOONGARCH64_F1, diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 9d9a437a79bdb3..80bcd11b798f4e 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -2278,7 +2278,7 @@ typedef struct DECLSPEC_ALIGN(16) _CONTEXT { /* +0x000 */ DWORD ContextFlags; // - // Integer registers, abi=N64. + // Integer registers. // DWORD64 R0; DWORD64 Ra; @@ -2317,7 +2317,7 @@ typedef struct DECLSPEC_ALIGN(16) _CONTEXT { // // Floating Point Registers // - //TODO: support the SIMD. + // TODO-LoongArch64: support the SIMD. DWORD64 F[32]; DWORD Fcsr; } CONTEXT, *PCONTEXT, *LPCONTEXT; diff --git a/src/coreclr/pal/prebuilt/inc/cordebug.h b/src/coreclr/pal/prebuilt/inc/cordebug.h index 226ae1c0ca7691..a868b7f2bfabf8 100644 --- a/src/coreclr/pal/prebuilt/inc/cordebug.h +++ b/src/coreclr/pal/prebuilt/inc/cordebug.h @@ -9193,49 +9193,48 @@ enum CorDebugRegister REGISTER_ARM64_V29 = ( REGISTER_ARM64_V28 + 1 ) , REGISTER_ARM64_V30 = ( REGISTER_ARM64_V29 + 1 ) , REGISTER_ARM64_V31 = ( REGISTER_ARM64_V30 + 1 ) , - REGISTER_LOONGARCH64_R0 = 0, - REGISTER_LOONGARCH64_RA = ( REGISTER_LOONGARCH64_R0 + 1 ) , - REGISTER_LOONGARCH64_TP = ( REGISTER_LOONGARCH64_RA + 1 ) , - REGISTER_LOONGARCH64_SP = ( REGISTER_LOONGARCH64_TP + 1 ) , - REGISTER_LOONGARCH64_A0 = ( REGISTER_LOONGARCH64_SP + 1 ) , - REGISTER_LOONGARCH64_A1 = ( REGISTER_LOONGARCH64_A0 + 1 ) , - REGISTER_LOONGARCH64_A2 = ( REGISTER_LOONGARCH64_A1 + 1 ) , - REGISTER_LOONGARCH64_A3 = ( REGISTER_LOONGARCH64_A2 + 1 ) , - REGISTER_LOONGARCH64_A4 = ( REGISTER_LOONGARCH64_A3 + 1 ) , - REGISTER_LOONGARCH64_A5 = ( REGISTER_LOONGARCH64_A4 + 1 ) , - REGISTER_LOONGARCH64_A6 = ( REGISTER_LOONGARCH64_A5 + 1 ) , - REGISTER_LOONGARCH64_A7 = ( REGISTER_LOONGARCH64_A6 + 1 ) , - REGISTER_LOONGARCH64_T0 = ( REGISTER_LOONGARCH64_A7 + 1 ) , - REGISTER_LOONGARCH64_T1 = ( REGISTER_LOONGARCH64_T0 + 1 ) , - REGISTER_LOONGARCH64_T2 = ( REGISTER_LOONGARCH64_T1 + 1 ) , - REGISTER_LOONGARCH64_T3 = ( REGISTER_LOONGARCH64_T2 + 1 ) , - REGISTER_LOONGARCH64_T4 = ( REGISTER_LOONGARCH64_T3 + 1 ) , - REGISTER_LOONGARCH64_T5 = ( REGISTER_LOONGARCH64_T4 + 1 ) , - REGISTER_LOONGARCH64_T6 = ( REGISTER_LOONGARCH64_T5 + 1 ) , - REGISTER_LOONGARCH64_T7 = ( REGISTER_LOONGARCH64_T6 + 1 ) , - REGISTER_LOONGARCH64_T8 = ( REGISTER_LOONGARCH64_T7 + 1 ) , - REGISTER_LOONGARCH64_X0 = ( REGISTER_LOONGARCH64_T8 + 1 ) , - REGISTER_LOONGARCH64_FP = ( REGISTER_LOONGARCH64_X0 + 1 ) , - REGISTER_LOONGARCH64_S0 = ( REGISTER_LOONGARCH64_FP + 1 ) , - REGISTER_LOONGARCH64_S1 = ( REGISTER_LOONGARCH64_S0 + 1 ) , - REGISTER_LOONGARCH64_S2 = ( REGISTER_LOONGARCH64_S1 + 1 ) , - REGISTER_LOONGARCH64_S3 = ( REGISTER_LOONGARCH64_S2 + 1 ) , - REGISTER_LOONGARCH64_S4 = ( REGISTER_LOONGARCH64_S3 + 1 ) , - REGISTER_LOONGARCH64_S5 = ( REGISTER_LOONGARCH64_S4 + 1 ) , - REGISTER_LOONGARCH64_S6 = ( REGISTER_LOONGARCH64_S5 + 1 ) , - REGISTER_LOONGARCH64_S7 = ( REGISTER_LOONGARCH64_S6 + 1 ) , - REGISTER_LOONGARCH64_S8 = ( REGISTER_LOONGARCH64_S7 + 1 ) , - REGISTER_LOONGARCH64_PC = ( REGISTER_LOONGARCH64_S8 + 1 ) , - REGISTER_LOONGARCH64_F0 = ( REGISTER_LOONGARCH64_PC + 1 ) , - REGISTER_LOONGARCH64_F1 = ( REGISTER_LOONGARCH64_F0 + 1 ) , - REGISTER_LOONGARCH64_F2 = ( REGISTER_LOONGARCH64_F1 + 1 ) , - REGISTER_LOONGARCH64_F3 = ( REGISTER_LOONGARCH64_F2 + 1 ) , - REGISTER_LOONGARCH64_F4 = ( REGISTER_LOONGARCH64_F3 + 1 ) , - REGISTER_LOONGARCH64_F5 = ( REGISTER_LOONGARCH64_F4 + 1 ) , - REGISTER_LOONGARCH64_F6 = ( REGISTER_LOONGARCH64_F5 + 1 ) , - REGISTER_LOONGARCH64_F7 = ( REGISTER_LOONGARCH64_F6 + 1 ) , - REGISTER_LOONGARCH64_F8 = ( REGISTER_LOONGARCH64_F7 + 1 ) , - REGISTER_LOONGARCH64_F9 = ( REGISTER_LOONGARCH64_F8 + 1 ) , + REGISTER_LOONGARCH64_PC = 0, + REGISTER_LOONGARCH64_SP = ( REGISTER_LOONGARCH64_PC + 1 ) , + REGISTER_LOONGARCH64_FP = ( REGISTER_LOONGARCH64_SP + 1 ) , + REGISTER_LOONGARCH64_RA = ( REGISTER_LOONGARCH64_FP + 1 ) , + REGISTER_LOONGARCH64_TP = ( REGISTER_LOONGARCH64_RA + 1 ) , + REGISTER_LOONGARCH64_A0 = ( REGISTER_LOONGARCH64_TP + 1 ) , + REGISTER_LOONGARCH64_A1 = ( REGISTER_LOONGARCH64_A0 + 1 ) , + REGISTER_LOONGARCH64_A2 = ( REGISTER_LOONGARCH64_A1 + 1 ) , + REGISTER_LOONGARCH64_A3 = ( REGISTER_LOONGARCH64_A2 + 1 ) , + REGISTER_LOONGARCH64_A4 = ( REGISTER_LOONGARCH64_A3 + 1 ) , + REGISTER_LOONGARCH64_A5 = ( REGISTER_LOONGARCH64_A4 + 1 ) , + REGISTER_LOONGARCH64_A6 = ( REGISTER_LOONGARCH64_A5 + 1 ) , + REGISTER_LOONGARCH64_A7 = ( REGISTER_LOONGARCH64_A6 + 1 ) , + REGISTER_LOONGARCH64_T0 = ( REGISTER_LOONGARCH64_A7 + 1 ) , + REGISTER_LOONGARCH64_T1 = ( REGISTER_LOONGARCH64_T0 + 1 ) , + REGISTER_LOONGARCH64_T2 = ( REGISTER_LOONGARCH64_T1 + 1 ) , + REGISTER_LOONGARCH64_T3 = ( REGISTER_LOONGARCH64_T2 + 1 ) , + REGISTER_LOONGARCH64_T4 = ( REGISTER_LOONGARCH64_T3 + 1 ) , + REGISTER_LOONGARCH64_T5 = ( REGISTER_LOONGARCH64_T4 + 1 ) , + REGISTER_LOONGARCH64_T6 = ( REGISTER_LOONGARCH64_T5 + 1 ) , + REGISTER_LOONGARCH64_T7 = ( REGISTER_LOONGARCH64_T6 + 1 ) , + REGISTER_LOONGARCH64_T8 = ( REGISTER_LOONGARCH64_T7 + 1 ) , + REGISTER_LOONGARCH64_X0 = ( REGISTER_LOONGARCH64_T8 + 1 ) , + REGISTER_LOONGARCH64_S0 = ( REGISTER_LOONGARCH64_X0 + 1 ) , + REGISTER_LOONGARCH64_S1 = ( REGISTER_LOONGARCH64_S0 + 1 ) , + REGISTER_LOONGARCH64_S2 = ( REGISTER_LOONGARCH64_S1 + 1 ) , + REGISTER_LOONGARCH64_S3 = ( REGISTER_LOONGARCH64_S2 + 1 ) , + REGISTER_LOONGARCH64_S4 = ( REGISTER_LOONGARCH64_S3 + 1 ) , + REGISTER_LOONGARCH64_S5 = ( REGISTER_LOONGARCH64_S4 + 1 ) , + REGISTER_LOONGARCH64_S6 = ( REGISTER_LOONGARCH64_S5 + 1 ) , + REGISTER_LOONGARCH64_S7 = ( REGISTER_LOONGARCH64_S6 + 1 ) , + REGISTER_LOONGARCH64_S8 = ( REGISTER_LOONGARCH64_S7 + 1 ) , + REGISTER_LOONGARCH64_F0 = ( REGISTER_LOONGARCH64_S8 + 1 ) , + REGISTER_LOONGARCH64_F1 = ( REGISTER_LOONGARCH64_F0 + 1 ) , + REGISTER_LOONGARCH64_F2 = ( REGISTER_LOONGARCH64_F1 + 1 ) , + REGISTER_LOONGARCH64_F3 = ( REGISTER_LOONGARCH64_F2 + 1 ) , + REGISTER_LOONGARCH64_F4 = ( REGISTER_LOONGARCH64_F3 + 1 ) , + REGISTER_LOONGARCH64_F5 = ( REGISTER_LOONGARCH64_F4 + 1 ) , + REGISTER_LOONGARCH64_F6 = ( REGISTER_LOONGARCH64_F5 + 1 ) , + REGISTER_LOONGARCH64_F7 = ( REGISTER_LOONGARCH64_F6 + 1 ) , + REGISTER_LOONGARCH64_F8 = ( REGISTER_LOONGARCH64_F7 + 1 ) , + REGISTER_LOONGARCH64_F9 = ( REGISTER_LOONGARCH64_F8 + 1 ) , REGISTER_LOONGARCH64_F10 = ( REGISTER_LOONGARCH64_F9 + 1 ) , REGISTER_LOONGARCH64_F11 = ( REGISTER_LOONGARCH64_F10 + 1 ) , REGISTER_LOONGARCH64_F12 = ( REGISTER_LOONGARCH64_F11 + 1 ) , From e058faada7fcedd604b8ee39d3362739eb9b99b3 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Thu, 24 Feb 2022 20:40:10 +0800 Subject: [PATCH 18/19] [LoongArch64] temp submit for fixing the windows compiling error. --- src/coreclr/inc/clrnt.h | 4 ---- src/coreclr/inc/palclr.h | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/inc/clrnt.h b/src/coreclr/inc/clrnt.h index 9d5e8c9cb8fc28..0c87336d1336a1 100644 --- a/src/coreclr/inc/clrnt.h +++ b/src/coreclr/inc/clrnt.h @@ -1071,8 +1071,4 @@ RtlVirtualUnwind( #endif // TARGET_LOONGARCH64 -#ifndef IMAGE_FILE_MACHINE_LOONGARCH64 -#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // LOONGARCH64. -#endif - #endif // CLRNT_H_ diff --git a/src/coreclr/inc/palclr.h b/src/coreclr/inc/palclr.h index 2ab9c62c3e8446..40fe2d1d3a2d1d 100644 --- a/src/coreclr/inc/palclr.h +++ b/src/coreclr/inc/palclr.h @@ -606,4 +606,8 @@ #include "palclr_win.h" +#ifndef IMAGE_FILE_MACHINE_LOONGARCH64 +#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // LOONGARCH64. +#endif + #endif // defined(HOST_WINDOWS) From c8fb52a0f22406a45a064963d6b509441f115c64 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Sun, 24 Apr 2022 22:03:51 +0800 Subject: [PATCH 19/19] [LoongArch64] amend some LA's implements for CR. --- src/coreclr/debug/createdump/threadinfo.h | 3 +- .../debug/createdump/threadinfounix.cpp | 21 ++- src/coreclr/debug/ee/CMakeLists.txt | 2 + .../ee/loongarch64/loongarch64walker.cpp | 154 +++++++++++++++--- src/coreclr/debug/ee/walker.h | 17 ++ src/coreclr/debug/inc/dbgtargetcontext.h | 33 +--- .../debug/inc/loongarch64/primitives.h | 4 +- .../debug/shared/loongarch64/primitives.cpp | 53 +++--- src/coreclr/inc/crosscomp.h | 4 +- src/coreclr/pal/inc/pal.h | 2 +- .../pal/src/arch/loongarch64/context2.S | 9 +- src/coreclr/vm/loongarch64/cgencpu.h | 7 + 12 files changed, 220 insertions(+), 89 deletions(-) diff --git a/src/coreclr/debug/createdump/threadinfo.h b/src/coreclr/debug/createdump/threadinfo.h index 41c6ac05405650..ed82c1ec51a652 100644 --- a/src/coreclr/debug/createdump/threadinfo.h +++ b/src/coreclr/debug/createdump/threadinfo.h @@ -13,7 +13,8 @@ class CrashInfo; #endif #if defined(__loongarch64) -// See src/pal/src/include/pal/context.h +// See src/coreclr/pal/src/include/pal/context.h +#define MCREG_Ra(mc) ((mc).gpr[1]) #define MCREG_Fp(mc) ((mc).gpr[22]) #define MCREG_Sp(mc) ((mc).gpr[3]) #define MCREG_Pc(mc) ((mc).pc) diff --git a/src/coreclr/debug/createdump/threadinfounix.cpp b/src/coreclr/debug/createdump/threadinfounix.cpp index 5c5aeab9fbfe73..8474fcb5964bb8 100644 --- a/src/coreclr/debug/createdump/threadinfounix.cpp +++ b/src/coreclr/debug/createdump/threadinfounix.cpp @@ -224,8 +224,25 @@ ThreadInfo::GetThreadContext(uint32_t flags, CONTEXT* context) const #endif } #elif defined(__loongarch64) - assert(!"Unimplemented yet on Loongarch64!"); -#pragma message("Unimplemented yet on Loongarch64.") + if ((flags & CONTEXT_CONTROL) == CONTEXT_CONTROL) + { + context->Ra = MCREG_Ra(m_gpRegisters); + context->Sp = MCREG_Sp(m_gpRegisters); + context->Fp = MCREG_Fp(m_gpRegisters); + context->Pc = MCREG_Pc(m_gpRegisters); + } + if ((flags & CONTEXT_INTEGER) == CONTEXT_INTEGER) + { + context->Tp = m_gpRegisters.gpr[2]; + memcpy(&context->A0, &m_gpRegisters.gpr[4], sizeof(context->A0)*(21 - 4 + 1)); + memcpy(&context->S0, &m_gpRegisters.gpr[23], sizeof(context->S0)*9); + } + if ((flags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) + { + assert(sizeof(context->F) == sizeof(m_fpRegisters.fpregs)); + memcpy(context->F, m_fpRegisters.fpregs, sizeof(context->F)); + context->Fcsr = m_fpRegisters.fpscr; + } #else #error Platform not supported #endif diff --git a/src/coreclr/debug/ee/CMakeLists.txt b/src/coreclr/debug/ee/CMakeLists.txt index 8a9eda3da3165f..4e59f05eb96c94 100644 --- a/src/coreclr/debug/ee/CMakeLists.txt +++ b/src/coreclr/debug/ee/CMakeLists.txt @@ -65,6 +65,8 @@ elseif(CLR_CMAKE_TARGET_ARCH_ARM) list(APPEND CORDBEE_SOURCES_WKS ${ARCH_SOURCES_DIR}/armwalker.cpp) elseif(CLR_CMAKE_TARGET_ARCH_ARM64) list(APPEND CORDBEE_SOURCES_WKS ${ARCH_SOURCES_DIR}/arm64walker.cpp) +elseif(CLR_CMAKE_TARGET_ARCH_LOONGARCH64) + list(APPEND CORDBEE_SOURCES_WKS ${ARCH_SOURCES_DIR}/loongarch64walker.cpp) endif() convert_to_absolute_path(CORDBEE_SOURCES_DAC ${CORDBEE_SOURCES_DAC}) diff --git a/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp b/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp index 8d8bfa78063522..fe1bef86cd84fa 100644 --- a/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp +++ b/src/coreclr/debug/ee/loongarch64/loongarch64walker.cpp @@ -19,39 +19,149 @@ void NativeWalker::Decode() { - _ASSERTE(!"TODO:=====Not implements for LOONGARCH64. -2"); + PT_CONTEXT context = NULL; + int RegNum = -1; + PCODE offset = MAX_INSTRUCTION_LENGTH; + + //Reset so that we do not provide bogus info + m_type = WALK_UNKNOWN; + m_skipIP = NULL; + m_nextIP = NULL; + + if (m_registers == NULL) + { + //walker does not use WALK_NEXT + //Without registers decoding will work only for handful of instructions + return; + } + + m_skipIP = m_ip + MAX_INSTRUCTION_LENGTH; + + context = m_registers->pCurrentContext; + // Fetch first word of the current instruction.If the current instruction is a break instruction, we'll + // need to check the patch table to get the correct instruction. + PRD_TYPE opcode = CORDbgGetInstruction(m_ip); + PRD_TYPE unpatchedOpcode; + if (DebuggerController::CheckGetPatchedOpcode(m_ip, &unpatchedOpcode)) + { + opcode = unpatchedOpcode; + } + + LOG((LF_CORDB, LL_INFO100000, "LoongArch64Walker::Decode instruction at %p, opcode: %x\n", m_ip, opcode)); + + if (NativeWalker::DecodeJumpInst(opcode, RegNum, offset, m_type)) //Unconditional jump (register) instructions + { + if (m_type == WALK_RETURN) + { + m_skipIP = NULL; + } + m_nextIP = (BYTE*)GetReg(context, RegNum) + offset; + return; + } + + if (NativeWalker::DecodePCRelativeBranchInst(context, opcode, offset, m_type)) + { + if (m_type == WALK_BRANCH) + { + m_skipIP = NULL; + } + } + + m_nextIP = m_ip + offset; + return; } - -//When control reaches here m_pSharedPatchBypassBuffer has the original instructions in m_pSharedPatchBypassBuffer->PatchBypass -BYTE* NativeWalker::SetupOrSimulateInstructionForPatchSkip(T_CONTEXT * context, SharedPatchBypassBuffer* m_pSharedPatchBypassBuffer, const BYTE *address, PRD_TYPE opcode) +// Decodes PC Relative Branch Instructions +// +// This Function Decodes : +// BL offset +// B offset +// +// Output of the Function are: +// offset - Offset from current PC to which control will go next +// WALK_TYPE +BOOL NativeWalker::DecodePCRelativeBranchInst(PT_CONTEXT context, const PRD_TYPE opcode, PCODE& offset, WALK_TYPE& walk) { - _ASSERTE(!"TODO:=====Not implements for LOONGARCH64. -3"); - return NULL; -} + if (((opcode >> 24) & 0xFC) == 0x50) // Decode B + { + offset = (opcode >> 10) & 0xFFFF; // Get the low-16bits offset field. + offset |= (opcode & 0x3FF) << 16; // Get the hight-10bits offset field. -//Decodes PC Relative Branch Instructions -//This code is shared between the NativeWalker and DebuggerPatchSkip. -//So ENSURE THIS FUNCTION DOES NOT CHANGE ANY STATE OF THE DEBUGEE -//This Function Decodes : -// BL offset -// B offset -// B.Cond offset + // Check whether sign extension + if ((opcode & 0x200) != 0) + { + offset = ((int)(offset << 6)) >> 4; // Also 4-bytes aligned + } + else + { + offset <<= 2; // 4-bytes aligned + } -//Output of the Function are: -//offset - Offset from current PC to which control will go next -//WALK_TYPE + walk = WALK_BRANCH; //B + LOG((LF_CORDB, LL_INFO100000, "LoongArch64Walker::Decoded opcode: %x to B %x \n", opcode, offset)); + + return TRUE; + } + else if (((opcode >> 24) & 0xFC) == 0x54) // Decode BL + { + offset = (opcode >> 10) & 0xFFFF; // Get the low-16bits offset field. + offset |= (opcode & 0x3FF) << 16; // Get the hight-10bits offset field. + + // Check whether sign extension + if ((opcode & 0x200) != 0) + { + offset = ((int)(offset << 6)) >> 4; // Also 4-bytes aligned + } + else + { + offset <<= 2; // 4-bytes aligned + } + + walk = WALK_CALL; + LOG((LF_CORDB, LL_INFO100000, "LoongArch64Walker::Decoded opcode: %x to BL %x \n", opcode, offset)); + + return TRUE; + } -BOOL NativeWalker::DecodePCRelativeBranchInst(PT_CONTEXT context, const PRD_TYPE& opcode, PCODE& offset, WALK_TYPE& walk) -{ - _ASSERTE(!"TODO:=====Not implements for LOONGARCH64. -4"); return FALSE; } -BOOL NativeWalker::DecodeCallInst(const PRD_TYPE& opcode, int& RegNum, WALK_TYPE& walk) +BOOL NativeWalker::DecodeJumpInst(const PRD_TYPE opcode, int& RegNum, PCODE& offset, WALK_TYPE& walk) { - _ASSERTE(!"TODO:=====Not implements for LOONGARCH64. -5"); + if ((opcode & 0xFC000000) == 0x4C000000) // jirl - Unconditional Jump (register) instructions + { + RegNum = (opcode >> 5) & 0x1F; // rj is the target registor. + + short op = opcode & 0x1F; // Checking for linker registor by rd field. + switch (op) + { + case 0: + if (RegNum == 1) + { + LOG((LF_CORDB, LL_INFO100000, "LoongArch64Walker::Decoded opcode: %x to Ret X%d\n", opcode, RegNum)); + walk = WALK_RETURN; + } + else + { + LOG((LF_CORDB, LL_INFO100000, "LoongArch64Walker::Decoded opcode: %x to jr Reg%d\n", opcode, RegNum)); + walk = WALK_BRANCH; + } + break; + case 1: LOG((LF_CORDB, LL_INFO100000, "LoongArch64Walker::Decoded opcode: %x to jirl Reg%d\n", opcode, RegNum)); + walk = WALK_CALL; + break; + default: + LOG((LF_CORDB, LL_INFO100000, "LoongArch64Walker::Simulate Unknown opcode: %x [Branch] \n", opcode)); + _ASSERTE(!("LoongArch64Walker::Decoded Unknown opcode")); + } + + offset = (short)(opcode >> 10); // get the offset fields and signExtend. + offset <<= 2; // 4-bytes aligned. + + return TRUE; + } + return FALSE; } #endif diff --git a/src/coreclr/debug/ee/walker.h b/src/coreclr/debug/ee/walker.h index d16d4c740c89d1..4e16dc537153db 100644 --- a/src/coreclr/debug/ee/walker.h +++ b/src/coreclr/debug/ee/walker.h @@ -215,6 +215,23 @@ class NativeWalker : public Walker static BYTE* SetupOrSimulateInstructionForPatchSkip(T_CONTEXT * context, SharedPatchBypassBuffer * m_pSharedPatchBypassBuffer, const BYTE *address, PRD_TYPE opcode); }; +#elif defined (TARGET_LOONGARCH64) +#include "controller.h" +class NativeWalker : public Walker +{ +public: + void Init(const BYTE *ip, REGDISPLAY *pregisters) + { + Walker::Init(ip, pregisters); + } + void Decode(); + static void DecodeInstructionForPatchSkip(const BYTE *address, InstructionAttribute * pInstrAttrib) + { + pInstrAttrib->Reset(); + } + static BOOL DecodePCRelativeBranchInst(PT_CONTEXT context,const PRD_TYPE opcode, PCODE& offset, WALK_TYPE& walk); + static BOOL DecodeJumpInst(const PRD_TYPE opcode, int& RegNum, PCODE& offset, WALK_TYPE& walk); +}; #else PORTABILITY_WARNING("NativeWalker not implemented on this platform"); class NativeWalker : public Walker diff --git a/src/coreclr/debug/inc/dbgtargetcontext.h b/src/coreclr/debug/inc/dbgtargetcontext.h index 37eb7eb11bd712..5104c5d25d4e5a 100644 --- a/src/coreclr/debug/inc/dbgtargetcontext.h +++ b/src/coreclr/debug/inc/dbgtargetcontext.h @@ -510,38 +510,7 @@ typedef DECLSPEC_ALIGN(16) struct { // // Floating Point Registers // - DWORD64 F0; - DWORD64 F1; - DWORD64 F2; - DWORD64 F3; - DWORD64 F4; - DWORD64 F5; - DWORD64 F6; - DWORD64 F7; - DWORD64 F8; - DWORD64 F9; - DWORD64 F10; - DWORD64 F11; - DWORD64 F12; - DWORD64 F13; - DWORD64 F14; - DWORD64 F15; - DWORD64 F16; - DWORD64 F17; - DWORD64 F18; - DWORD64 F19; - DWORD64 F20; - DWORD64 F21; - DWORD64 F22; - DWORD64 F23; - DWORD64 F24; - DWORD64 F25; - DWORD64 F26; - DWORD64 F27; - DWORD64 F28; - DWORD64 F29; - DWORD64 F30; - DWORD64 F31; + ULONGLONG F[32]; } DT_CONTEXT; #else diff --git a/src/coreclr/debug/inc/loongarch64/primitives.h b/src/coreclr/debug/inc/loongarch64/primitives.h index a28c108bf99ae1..995f83a1488dd3 100644 --- a/src/coreclr/debug/inc/loongarch64/primitives.h +++ b/src/coreclr/debug/inc/loongarch64/primitives.h @@ -82,10 +82,10 @@ constexpr CorDebugRegister g_JITToCorDbgReg[] = REGISTER_LOONGARCH64_PC }; -inline void CORDbgSetIP(DT_CONTEXT *context, LPVOID eip) { +inline void CORDbgSetIP(DT_CONTEXT *context, LPVOID ip) { LIMITED_METHOD_CONTRACT; - context->PC = (DWORD64)eip; + context->PC = (DWORD64)ip; } inline LPVOID CORDbgGetSP(const DT_CONTEXT * context) { diff --git a/src/coreclr/debug/shared/loongarch64/primitives.cpp b/src/coreclr/debug/shared/loongarch64/primitives.cpp index 08635ec8693f86..f435989b8baef1 100644 --- a/src/coreclr/debug/shared/loongarch64/primitives.cpp +++ b/src/coreclr/debug/shared/loongarch64/primitives.cpp @@ -19,42 +19,53 @@ // void CORDbgCopyThreadContext(DT_CONTEXT* pDst, const DT_CONTEXT* pSrc) { - _ASSERTE(!"=====Not implements for loongarch64. --1"); - DWORD dstFlags = pDst->ContextFlags; DWORD srcFlags = pSrc->ContextFlags; LOG((LF_CORDB, LL_INFO1000000, "CP::CTC: pDst=0x%08x dstFlags=0x%x, pSrc=0x%08x srcFlags=0x%x\n", pDst, dstFlags, pSrc, srcFlags)); -#if 0 if ((dstFlags & srcFlags & DT_CONTEXT_CONTROL) == DT_CONTEXT_CONTROL) { - CopyContextChunk(&(pDst->Fp), &(pSrc->Fp), &(pDst->V), - DT_CONTEXT_CONTROL); - CopyContextChunk(&(pDst->Cpsr), &(pSrc->Cpsr), &(pDst->X), - DT_CONTEXT_CONTROL); + LOG((LF_CORDB, LL_INFO1000000, + "CP::CTC: RA: pDst=0x%lx, pSrc=0x%lx, Flags=0x%x\n", + pDst->RA, pSrc->RA, DT_CONTEXT_CONTROL)); + pDst->RA = pSrc->RA; + + LOG((LF_CORDB, LL_INFO1000000, + "CP::CTC: SP: pDst=0x%lx, pSrc=0x%lx, Flags=0x%x\n", + pDst->SP, pSrc->SP, DT_CONTEXT_CONTROL)); + pDst->SP = pSrc->SP; + + LOG((LF_CORDB, LL_INFO1000000, + "CP::CTC: FP: pDst=0x%lx, pSrc=0x%lx, Flags=0x%x\n", + pDst->FP, pSrc->FP, DT_CONTEXT_CONTROL)); + pDst->FP = pSrc->FP; + + LOG((LF_CORDB, LL_INFO1000000, + "CP::CTC: PC: pDst=0x%lx, pSrc=0x%lx, Flags=0x%x\n", + pDst->PC, pSrc->PC, DT_CONTEXT_CONTROL)); + pDst->PC = pSrc->PC; } if ((dstFlags & srcFlags & DT_CONTEXT_INTEGER) == DT_CONTEXT_INTEGER) - CopyContextChunk(&(pDst->X[0]), &(pSrc->X[0]), &(pDst->Fp), + { + CopyContextChunk(&pDst->A0, &pSrc->A0, &pDst->FP, DT_CONTEXT_INTEGER); + CopyContextChunk(&pDst->S0, &pSrc->S0, &pDst->PC, + DT_CONTEXT_INTEGER); + } if ((dstFlags & srcFlags & DT_CONTEXT_FLOATING_POINT) == DT_CONTEXT_FLOATING_POINT) - CopyContextChunk(&(pDst->V[0]), &(pSrc->V[0]), &(pDst->Bcr[0]), + { + CopyContextChunk(&pDst->F[0], &pSrc->F[0], &pDst->F[32], DT_CONTEXT_FLOATING_POINT); - - if ((dstFlags & srcFlags & DT_CONTEXT_DEBUG_REGISTERS) == - DT_CONTEXT_DEBUG_REGISTERS) - CopyContextChunk(&(pDst->Bcr[0]), &(pSrc->Bcr[0]), &(pDst->Wvr[LOONGARCH64_MAX_WATCHPOINTS]), - DT_CONTEXT_DEBUG_REGISTERS); -#endif + } } #if defined(ALLOW_VMPTR_ACCESS) || !defined(RIGHT_SIDE_COMPILE) void SetDebuggerREGDISPLAYFromREGDISPLAY(DebuggerREGDISPLAY* pDRD, REGDISPLAY* pRD) { - _ASSERTE(!"=====Not implements for loongarch64. --2"); SUPPORTS_DAC_HOST_ONLY; DT_CONTEXT* pContext = reinterpret_cast(pRD->pCurrentContext); @@ -66,17 +77,15 @@ void SetDebuggerREGDISPLAYFromREGDISPLAY(DebuggerREGDISPLAY* pDRD, REGDISPLAY* p { pDRD->FP = (SIZE_T)CORDbgGetFP(pContext); pDRD->PC = (SIZE_T)pContext->PC; + pDRD->RA = (SIZE_T)pContext->RA; } -#if 0 if ((flags & DT_CONTEXT_INTEGER) == DT_CONTEXT_INTEGER) { - for(int i = 0 ; i < 29 ; i++) - { - pDRD->X[i] = (SIZE_T)pContext->X[i]; - } + pDRD->TP = pContext->TP; + memcpy(&pDRD->A0, &pContext->A0, sizeof(pDRD->A0)*(21 - 4 + 1)); + memcpy(&pDRD->S0, &pContext->S0, sizeof(pDRD->S0)* 9); } -#endif pDRD->SP = pRD->SP; diff --git a/src/coreclr/inc/crosscomp.h b/src/coreclr/inc/crosscomp.h index 1a7fdb37b9c252..d7d8378cd1f845 100644 --- a/src/coreclr/inc/crosscomp.h +++ b/src/coreclr/inc/crosscomp.h @@ -399,7 +399,7 @@ enum #define CONTEXT_UNWOUND_TO_CALL 0x20000000 -typedef struct DECLSPEC_ALIGN(8) _T_CONTEXT { +typedef struct DECLSPEC_ALIGN(16) _T_CONTEXT { // // Control flags. @@ -448,7 +448,7 @@ typedef struct DECLSPEC_ALIGN(8) _T_CONTEXT { // Floating Point Registers // //TODO-LoongArch64: support the SIMD. - DWORD64 F[32]; + ULONGLONG F[32]; DWORD Fcsr; } T_CONTEXT, *PT_CONTEXT; diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 3a484ce840cdf4..e677165299a471 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -2318,7 +2318,7 @@ typedef struct DECLSPEC_ALIGN(16) _CONTEXT { // Floating Point Registers // // TODO-LoongArch64: support the SIMD. - DWORD64 F[32]; + ULONGLONG F[32]; DWORD Fcsr; } CONTEXT, *PCONTEXT, *LPCONTEXT; diff --git a/src/coreclr/pal/src/arch/loongarch64/context2.S b/src/coreclr/pal/src/arch/loongarch64/context2.S index ff0b6e040b42d9..97e02574fb4365 100644 --- a/src/coreclr/pal/src/arch/loongarch64/context2.S +++ b/src/coreclr/pal/src/arch/loongarch64/context2.S @@ -97,7 +97,7 @@ LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT): ld.d $t6, $a0, CONTEXT_T6 ld.d $t7, $a0, CONTEXT_T7 ld.d $t8, $a0, CONTEXT_T8 - //ld.d $r21,$a0, CONTEXT_X0 + ld.d $s0, $a0, CONTEXT_S0 ld.d $s1, $a0, CONTEXT_S1 ld.d $s2, $a0, CONTEXT_S2 @@ -106,10 +106,8 @@ LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT): ld.d $s5, $a0, CONTEXT_S5 ld.d $s6, $a0, CONTEXT_S6 ld.d $s7, $a0, CONTEXT_S7 -#ifndef CONTEXT_S8 -#error "----------------nodefine8" -#endif ld.d $s8, $a0, CONTEXT_S8 + ld.d $a0, $a0, CONTEXT_A0 LOCAL_LABEL(No_Restore_CONTEXT_INTEGER): @@ -127,7 +125,8 @@ LOCAL_LABEL(No_Restore_CONTEXT_INTEGER): LOCAL_LABEL(No_Restore_CONTEXT_CONTROL): - jirl $r0, $ra, 0 + ld.d $t4, $t4, CONTEXT_T4 + jirl $r0, $ra, 0 LEAF_END RtlRestoreContext, _TEXT // Incoming: diff --git a/src/coreclr/vm/loongarch64/cgencpu.h b/src/coreclr/vm/loongarch64/cgencpu.h index 277724276d21a1..ea682213c3aa46 100644 --- a/src/coreclr/vm/loongarch64/cgencpu.h +++ b/src/coreclr/vm/loongarch64/cgencpu.h @@ -167,6 +167,13 @@ inline void SetRA(T_CONTEXT * context, TADDR ip) { context->Ra = ip; } +inline TADDR GetReg(T_CONTEXT * context, int Regnum) +{ + LIMITED_METHOD_DAC_CONTRACT; + _ASSERTE((Regnum > 0) && (Regnum < 32)); + return (TADDR)(&context->R0 + Regnum); +} + extern "C" LPVOID __stdcall GetCurrentSP(); inline void SetSP(T_CONTEXT *context, TADDR sp) {