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/inc/cordebug.idl b/src/coreclr/inc/cordebug.idl index 97e53150b055e0..a5f67044fb6a7b 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/crosscomp.h b/src/coreclr/inc/crosscomp.h index 8d515a174385cf..63a48d0e4ceeae 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/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/llvm/ELF.h b/src/coreclr/inc/llvm/ELF.h index 5cb3f82da21412..9e89b48b514a3c 100644 --- a/src/coreclr/inc/llvm/ELF.h +++ b/src/coreclr/inc/llvm/ELF.h @@ -343,6 +343,7 @@ enum { EM_NORC = 218, // Nanoradio Optimized RISC EM_CSR_KALIMBA = 219, // CSR Kalimba architecture family EM_AMDGPU = 224, // AMD GPU architecture + 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 +548,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 +675,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 +776,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 +1042,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..7a51ec54e2f38c 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,41 @@ typedef struct _Arm64VolatileContextPointer }; } Arm64VolatileContextPointer; #endif //TARGET_ARM64 + +#if defined(TARGET_LOONGARCH64) +typedef struct _Loongarch64VolatileContextPointer +{ + PDWORD64 R0; + 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 +327,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 +373,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 +469,26 @@ 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.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 +568,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/volatile.h b/src/coreclr/inc/volatile.h index e127fe25f99b1f..f7761e56eca6e8 100644 --- a/src/coreclr/inc/volatile.h +++ b/src/coreclr/inc/volatile.h @@ -68,8 +68,8 @@ #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_S390X) -#error The Volatile type is currently only defined for GCC when targeting x86, AMD64, ARM, ARM64, or S390X CPUs +#if defined(__GNUC__) && !defined(HOST_X86) && !defined(HOST_AMD64) && !defined(HOST_ARM) && !defined(HOST_ARM64) && !defined(HOST_LOONGARCH64) && !defined(HOST_S390X) +#error The Volatile type is currently only defined for GCC when targeting x86, AMD64, ARM, ARM64, LOONGARCH64, or S390X CPUs #endif #if defined(__GNUC__) @@ -79,6 +79,8 @@ #elif 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/pal/inc/rt/ntimage.h b/src/coreclr/pal/inc/rt/ntimage.h index cd56b305aed482..e6970cca7cd386 100644 --- a/src/coreclr/pal/inc/rt/ntimage.h +++ b/src/coreclr/pal/inc/rt/ntimage.h @@ -240,6 +240,7 @@ typedef struct _IMAGE_FILE_HEADER { #define IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian #define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian #define IMAGE_FILE_MACHINE_CEE 0xC0EE +#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // LOONGARCH64. // // Directory format.