Skip to content

Commit 51afa06

Browse files
shushanhfqiaopengcheng
andauthored
[LoongArch64] coreclr-jit directory (#62843)
* Part6-1: add the coreclr-jit directory for LoongArch64. (#59561) Co-authored-by: Loongson's .NET-teams * [LoongArch64] add jit/CMakeLists.txt from #62889. * [LoongArch64] update LoongArch64 after merge from main. * [LoongArch64] Fix the error for "IsLoongArch64". * [LoongArch64] Fix the cross-compiling error. * [LoongArch64] Fixed the compiling errors after merge. * [LoongArch64] revert `src/coreclr/jit/ICorJitInfo_API_names.h`. * [LoongArch64] workround the compiling error on windows. * [LoongArch64] amend the code-format. * [LoongArch64] update by `git apply format.patch`. * [LoongArch64] Delete the interface getArgType2. And refactor the returned values of `getFieldSizeClassificationByHnd`. Keep aligned with #62893 `02ff4bfa41d7887b151d381e2697ba82ab6a0bca`. * [LoongArch64] update code by `git apply format.patch` And update `getLoongArch64PassStructInRegisterFlags`. * [LoongArch64] Fixed the error when passing float-arg by integer-reg. * [Loongarch64] amend patch formate by 'git apply format.patch' * [LoongArch64] update the version of the `LICENSE description`. * [LoongArch64] amend the CodeGen::genFnPrologCalleeRegArgs for the SC_IG_BUFFER_SIZE. * [LoongArch64]: update the crossgen2 within the JIT. * [LoongArch64] git-apply the `format.patch`. * [LoongArch64] Fix the compiling error after merge-main. * [LoongArch64] amend the code for reviewing by @BruceForstall. * [LoongArch64] apply the `format.patch`. * [LoongArch64] round 2 amend for reviewing by @BruceForstall. * [LoongArch64] round 3 amend for reviewing by @BruceForstall. * [LoongArch64] amend the format. * [LoongArch64] round 4 amending for reviewing. * [LoongArch64] add compiling the `clrjit_unix_loongarch64_*`. * [LoongArch64] delete unused code and amend the format. Also amend inst_Mov. * [LoongArch64] apply the format and fix compiling warning. * [LoongArch64] round 1 amend for reviewing by @kunalspathak. * [LoongArch64] merge fast-tail-call from main. * [LoongArch64] temp commit for windows compiling error. * [LoongArch64] amend format for reviewing. * [LoongArch64] amend the coding for LA-ABI's flags. * [LoongArch64] amend some missed CRs. * [LoongArch64] amend some code for CR. * [LoongArch64] amend some code for CR round2. * [LoongArch64] amend the output format of `emitDisInsName`. * [LoongArch64] remove the optimization for type-cast which depends on LoongArch64. * [LoongArch64] ament the code for CR. * [LoongArch64] amend some code for CR. * [LoongArch64] amend some code for CR round2. * [LoongArch64] amend some code for CR round3. * [LoongArch64] amend some code for CR round4. * [LoongArch64] amend some code for CR round5. * [LoongArch64] amend some code after refacting. * [LoongArch64] amend the compare and fix the error when running hello-world within debug-mode. Co-authored-by: qiaopengcheng <[email protected]>
1 parent f89fbb9 commit 51afa06

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+23600
-272
lines changed

src/coreclr/gcinfo/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64)
7575
create_gcinfo_lib(TARGET gcinfo_win_x64 OS win ARCH x64)
7676
endif (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64)
7777

78+
if (CLR_CMAKE_TARGET_ARCH_LOONGARCH64)
79+
create_gcinfo_lib(TARGET gcinfo_unix_loongarch64 OS unix ARCH loongarch64)
80+
endif (CLR_CMAKE_TARGET_ARCH_LOONGARCH64)
81+
7882
create_gcinfo_lib(TARGET gcinfo_universal_arm OS universal ARCH arm)
7983
create_gcinfo_lib(TARGET gcinfo_win_x86 OS win ARCH x86)
8084

src/coreclr/inc/clrconfigvalues.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,12 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_GDBJitEmitDebugFrame, W("GDBJitEmitDebugFrame"
745745
//
746746
// Hardware Intrinsic ISAs
747747
//
748+
#if defined(TARGET_LOONGARCH64)
749+
//TODO: should implement LoongArch64's features.
750+
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableHWIntrinsic, W("EnableHWIntrinsic"), 0, "Allows Base+ hardware intrinsics to be disabled")
751+
#else
748752
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableHWIntrinsic, W("EnableHWIntrinsic"), 1, "Allows Base+ hardware intrinsics to be disabled")
753+
#endif // defined(TARGET_LOONGARCH64)
749754

750755
#if defined(TARGET_AMD64) || defined(TARGET_X86)
751756
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableAES, W("EnableAES"), 1, "Allows AES+ hardware intrinsics to be disabled")

src/coreclr/inc/crosscomp.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ enum
399399

400400
#define CONTEXT_UNWOUND_TO_CALL 0x20000000
401401

402-
typedef struct DECLSPEC_ALIGN(16) _T_CONTEXT {
402+
typedef struct DECLSPEC_ALIGN(8) _T_CONTEXT {
403403

404404
//
405405
// Control flags.
@@ -414,8 +414,8 @@ typedef struct DECLSPEC_ALIGN(16) _T_CONTEXT {
414414
DWORD64 Ra;
415415
DWORD64 Tp;
416416
DWORD64 Sp;
417-
DWORD64 A0;//DWORD64 V0;
418-
DWORD64 A1;//DWORD64 V1;
417+
DWORD64 A0;
418+
DWORD64 A1;
419419
DWORD64 A2;
420420
DWORD64 A3;
421421
DWORD64 A4;
@@ -447,7 +447,7 @@ typedef struct DECLSPEC_ALIGN(16) _T_CONTEXT {
447447
//
448448
// Floating Point Registers
449449
//
450-
//TODO: support the SIMD.
450+
//TODO-LoongArch64: support the SIMD.
451451
DWORD64 F[32];
452452
DWORD Fcsr;
453453
} T_CONTEXT, *PT_CONTEXT;
@@ -469,7 +469,6 @@ typedef struct _T_RUNTIME_FUNCTION {
469469
};
470470
} T_RUNTIME_FUNCTION, *PT_RUNTIME_FUNCTION;
471471

472-
473472
//
474473
// Define exception dispatch context structure.
475474
//
@@ -489,8 +488,6 @@ typedef struct _T_DISPATCHER_CONTEXT {
489488
PBYTE NonVolatileRegisters;
490489
} T_DISPATCHER_CONTEXT, *PT_DISPATCHER_CONTEXT;
491490

492-
493-
494491
//
495492
// Nonvolatile context pointer record.
496493
//

src/coreclr/inc/palclr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,4 +606,8 @@
606606

607607
#include "palclr_win.h"
608608

609+
#ifndef IMAGE_FILE_MACHINE_LOONGARCH64
610+
#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // LOONGARCH64.
611+
#endif
612+
609613
#endif // defined(HOST_WINDOWS)

src/coreclr/inc/targetosarch.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,38 @@ class TargetArchitecture
4141
static const bool IsArm64 = false;
4242
static const bool IsArm32 = true;
4343
static const bool IsArmArch = true;
44+
static const bool IsLoongArch64 = false;
4445
#elif defined(TARGET_ARM64)
4546
static const bool IsX86 = false;
4647
static const bool IsX64 = false;
4748
static const bool IsArm64 = true;
4849
static const bool IsArm32 = false;
4950
static const bool IsArmArch = true;
51+
static const bool IsLoongArch64 = false;
5052
#elif defined(TARGET_AMD64)
5153
static const bool IsX86 = false;
5254
static const bool IsX64 = true;
5355
static const bool IsArm64 = false;
5456
static const bool IsArm32 = false;
5557
static const bool IsArmArch = false;
58+
static const bool IsLoongArch64 = false;
5659
#elif defined(TARGET_X86)
5760
static const bool IsX86 = true;
5861
static const bool IsX64 = false;
5962
static const bool IsArm64 = false;
6063
static const bool IsArm32 = false;
6164
static const bool IsArmArch = false;
65+
static const bool IsLoongArch64 = false;
66+
#elif defined(TARGET_LOONGARCH64)
67+
static const bool IsX86 = false;
68+
static const bool IsX64 = false;
69+
static const bool IsArm64 = false;
70+
static const bool IsArm32 = false;
71+
static const bool IsArmArch = false;
72+
static const bool IsLoongArch64 = true;
6273
#else
6374
#error Unknown architecture
6475
#endif
6576
};
6677

67-
#endif // targetosarch_h
78+
#endif // targetosarch_h

src/coreclr/jit/CMakeLists.txt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ function(create_standalone_jit)
4848
elseif(TARGETDETAILS_ARCH STREQUAL "s390x")
4949
set(JIT_ARCH_SOURCES ${JIT_S390X_SOURCES})
5050
set(JIT_ARCH_HEADERS ${JIT_S390X_HEADERS})
51+
elseif(TARGETDETAILS_ARCH STREQUAL "loongarch64")
52+
set(JIT_ARCH_SOURCES ${JIT_LOONGARCH64_SOURCES})
53+
set(JIT_ARCH_HEADERS ${JIT_LOONGARCH64_HEADERS})
5154
else()
5255
clr_unknown_arch()
5356
endif()
@@ -237,6 +240,15 @@ set( JIT_S390X_SOURCES
237240
# Not supported as JIT target
238241
)
239242

243+
set( JIT_LOONGARCH64_SOURCES
244+
codegenloongarch64.cpp
245+
emitloongarch64.cpp
246+
lowerloongarch64.cpp
247+
lsraloongarch64.cpp
248+
targetloongarch64.cpp
249+
unwindloongarch64.cpp
250+
)
251+
240252
# We include the headers here for better experience in IDEs.
241253
set( JIT_HEADERS
242254
../inc/corinfo.h
@@ -383,6 +395,13 @@ set ( JIT_S390X_HEADERS
383395
# Not supported as JIT target
384396
)
385397

398+
set( JIT_LOONGARCH64_HEADERS
399+
emitloongarch64.h
400+
emitfmtsloongarch64.h
401+
instrsloongarch64.h
402+
registerloongarch64.h
403+
)
404+
386405
convert_to_absolute_path(JIT_SOURCES ${JIT_SOURCES})
387406
convert_to_absolute_path(JIT_HEADERS ${JIT_HEADERS})
388407
convert_to_absolute_path(JIT_RESOURCES ${JIT_RESOURCES})
@@ -401,6 +420,8 @@ convert_to_absolute_path(JIT_ARMV6_SOURCES ${JIT_ARMV6_SOURCES})
401420
convert_to_absolute_path(JIT_ARMV6_HEADERS ${JIT_ARMV6_HEADERS})
402421
convert_to_absolute_path(JIT_S390X_SOURCES ${JIT_S390X_SOURCES})
403422
convert_to_absolute_path(JIT_S390X_HEADERS ${JIT_S390X_HEADERS})
423+
convert_to_absolute_path(JIT_LOONGARCH64_SOURCES ${JIT_LOONGARCH64_SOURCES})
424+
convert_to_absolute_path(JIT_LOONGARCH64_HEADERS ${JIT_LOONGARCH64_HEADERS})
404425

405426
if(CLR_CMAKE_TARGET_ARCH_AMD64)
406427
set(JIT_ARCH_SOURCES ${JIT_AMD64_SOURCES})
@@ -420,6 +441,9 @@ elseif(CLR_CMAKE_TARGET_ARCH_ARM64)
420441
elseif(CLR_CMAKE_TARGET_ARCH_S390X)
421442
set(JIT_ARCH_SOURCES ${JIT_S390X_SOURCES})
422443
set(JIT_ARCH_HEADERS ${JIT_S390X_HEADERS})
444+
elseif(CLR_CMAKE_TARGET_ARCH_LOONGARCH64)
445+
set(JIT_ARCH_SOURCES ${JIT_LOONGARCH64_SOURCES})
446+
set(JIT_ARCH_HEADERS ${JIT_LOONGARCH64_HEADERS})
423447
else()
424448
clr_unknown_arch()
425449
endif()
@@ -562,6 +586,10 @@ if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64)
562586
create_standalone_jit(TARGET clrjit_win_x64_${ARCH_HOST_NAME} OS win ARCH x64 DESTINATIONS .)
563587
endif (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64)
564588

589+
if (CLR_CMAKE_TARGET_ARCH_LOONGARCH64)
590+
create_standalone_jit(TARGET clrjit_unix_loongarch64_${ARCH_HOST_NAME} OS unix ARCH loongarch64 DESTINATIONS .)
591+
endif (CLR_CMAKE_TARGET_ARCH_LOONGARCH64)
592+
565593
create_standalone_jit(TARGET clrjit_universal_arm_${ARCH_HOST_NAME} OS universal ARCH arm DESTINATIONS .)
566594
target_compile_definitions(clrjit_universal_arm_${ARCH_HOST_NAME} PRIVATE ARM_SOFTFP CONFIGURABLE_ARM_ABI)
567595
create_standalone_jit(TARGET clrjit_win_x86_${ARCH_HOST_NAME} OS win ARCH x86 DESTINATIONS .)

src/coreclr/jit/codegen.h

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,16 @@ class CodeGen final : public CodeGenInterface
235235

236236
void genJumpToThrowHlpBlk(emitJumpKind jumpKind, SpecialCodeKind codeKind, BasicBlock* failBlk = nullptr);
237237

238+
#ifdef TARGET_LOONGARCH64
239+
void genSetRegToIcon(regNumber reg, ssize_t val, var_types type);
240+
void genJumpToThrowHlpBlk_la(SpecialCodeKind codeKind,
241+
instruction ins,
242+
regNumber reg1,
243+
BasicBlock* failBlk = nullptr,
244+
regNumber reg2 = REG_R0);
245+
#else
238246
void genCheckOverflow(GenTree* tree);
247+
#endif
239248

240249
//-------------------------------------------------------------------------
241250
//
@@ -251,7 +260,11 @@ class CodeGen final : public CodeGenInterface
251260
//
252261

253262
void genEstablishFramePointer(int delta, bool reportUnwindData);
263+
#if defined(TARGET_LOONGARCH64)
264+
void genFnPrologCalleeRegArgs();
265+
#else
254266
void genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbered, RegState* regState);
267+
#endif
255268
void genEnregisterIncomingStackArgs();
256269
#if defined(TARGET_ARM64)
257270
void genEnregisterOSRArgsAndLocals(regNumber initReg, bool* pInitRegZeroed);
@@ -263,7 +276,7 @@ class CodeGen final : public CodeGenInterface
263276
void genClearStackVec3ArgUpperBits();
264277
#endif // UNIX_AMD64_ABI && FEATURE_SIMD
265278

266-
#if defined(TARGET_ARM64)
279+
#if defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
267280
bool genInstrWithConstant(instruction ins,
268281
emitAttr attr,
269282
regNumber reg1,
@@ -323,6 +336,7 @@ class CodeGen final : public CodeGenInterface
323336
void genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, int lowestCalleeSavedOffset, int spDelta);
324337

325338
void genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroed);
339+
326340
#else
327341
void genPushCalleeSavedRegisters();
328342
#endif
@@ -408,7 +422,25 @@ class CodeGen final : public CodeGenInterface
408422

409423
FuncletFrameInfoDsc genFuncletInfo;
410424

411-
#endif // TARGET_AMD64
425+
#elif defined(TARGET_LOONGARCH64)
426+
427+
// A set of information that is used by funclet prolog and epilog generation.
428+
// It is collected once, before funclet prologs and epilogs are generated,
429+
// and used by all funclet prologs and epilogs, which must all be the same.
430+
struct FuncletFrameInfoDsc
431+
{
432+
regMaskTP fiSaveRegs; // Set of callee-saved registers saved in the funclet prolog (includes RA)
433+
int fiFunction_CallerSP_to_FP_delta; // Delta between caller SP and the frame pointer in the parent function
434+
// (negative)
435+
int fiSP_to_FPRA_save_delta; // FP/RA register save offset from SP (positive)
436+
int fiSP_to_PSP_slot_delta; // PSP slot offset from SP (positive)
437+
int fiCallerSP_to_PSP_slot_delta; // PSP slot offset from Caller SP (negative)
438+
int fiFrameType; // Funclet frame types are numbered. See genFuncletProlog() for details.
439+
int fiSpDelta1; // Stack pointer delta 1 (negative)
440+
};
441+
442+
FuncletFrameInfoDsc genFuncletInfo;
443+
#endif // TARGET_LOONGARCH64
412444

413445
#if defined(TARGET_XARCH)
414446

@@ -598,6 +630,10 @@ class CodeGen final : public CodeGenInterface
598630
void genArm64EmitterUnitTests();
599631
#endif
600632

633+
#if defined(DEBUG) && defined(TARGET_LOONGARCH64)
634+
void genLoongArch64EmitterUnitTests();
635+
#endif
636+
601637
#if defined(DEBUG) && defined(LATE_DISASM) && defined(TARGET_AMD64)
602638
void genAmd64EmitterUnitTests();
603639
#endif
@@ -1234,8 +1270,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12341270
void genCodeForStoreLclFld(GenTreeLclFld* tree);
12351271
void genCodeForStoreLclVar(GenTreeLclVar* tree);
12361272
void genCodeForReturnTrap(GenTreeOp* tree);
1237-
void genCodeForJcc(GenTreeCC* tree);
1238-
void genCodeForSetcc(GenTreeCC* setcc);
12391273
void genCodeForStoreInd(GenTreeStoreInd* tree);
12401274
void genCodeForSwap(GenTreeOp* tree);
12411275
void genCodeForCpObj(GenTreeObj* cpObjNode);
@@ -1324,7 +1358,11 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13241358
void genTableBasedSwitch(GenTree* tree);
13251359
void genCodeForArrIndex(GenTreeArrIndex* treeNode);
13261360
void genCodeForArrOffset(GenTreeArrOffs* treeNode);
1361+
#if defined(TARGET_LOONGARCH64)
1362+
instruction genGetInsForOper(GenTree* treeNode);
1363+
#else
13271364
instruction genGetInsForOper(genTreeOps oper, var_types type);
1365+
#endif
13281366
bool genEmitOptimizedGCWriteBarrier(GCInfo::WriteBarrierForm writeBarrierForm, GenTree* addr, GenTree* data);
13291367
GenTree* getCallTarget(const GenTreeCall* call, CORINFO_METHOD_HANDLE* methHnd);
13301368
regNumber getCallIndirectionCellReg(const GenTreeCall* call);
@@ -1333,7 +1371,11 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13331371
void genJmpMethod(GenTree* jmp);
13341372
BasicBlock* genCallFinally(BasicBlock* block);
13351373
void genCodeForJumpTrue(GenTreeOp* jtrue);
1336-
#ifdef TARGET_ARM64
1374+
#if defined(TARGET_LOONGARCH64)
1375+
// TODO: refactor for LA.
1376+
void genCodeForJumpCompare(GenTreeOp* tree);
1377+
#endif
1378+
#if defined(TARGET_ARM64)
13371379
void genCodeForJumpCompare(GenTreeOp* tree);
13381380
void genCodeForMadd(GenTreeOp* tree);
13391381
void genCodeForBfiz(GenTreeOp* tree);
@@ -1349,6 +1391,10 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13491391
void genMultiRegStoreToSIMDLocal(GenTreeLclVar* lclNode);
13501392
void genMultiRegStoreToLocal(GenTreeLclVar* lclNode);
13511393

1394+
#if defined(TARGET_LOONGARCH64)
1395+
void genMultiRegCallStoreToLocal(GenTree* treeNode);
1396+
#endif
1397+
13521398
// Codegen for multi-register struct returns.
13531399
bool isStructReturn(GenTree* treeNode);
13541400
#ifdef FEATURE_SIMD
@@ -1364,9 +1410,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13641410
void genFloatReturn(GenTree* treeNode);
13651411
#endif // TARGET_X86
13661412

1367-
#if defined(TARGET_ARM64)
1413+
#if defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
13681414
void genSimpleReturn(GenTree* treeNode);
1369-
#endif // TARGET_ARM64
1415+
#endif // TARGET_ARM64 || TARGET_LOONGARCH64
13701416

13711417
void genReturn(GenTree* treeNode);
13721418

@@ -1656,6 +1702,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
16561702
instruction genMapShiftInsToShiftByConstantIns(instruction ins, int shiftByValue);
16571703
#endif // TARGET_XARCH
16581704

1705+
#ifndef TARGET_LOONGARCH64
16591706
// Maps a GenCondition code to a sequence of conditional jumps or other conditional instructions
16601707
// such as X86's SETcc. A sequence of instructions rather than just a single one is required for
16611708
// certain floating point conditions.
@@ -1699,6 +1746,10 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
16991746

17001747
void inst_JCC(GenCondition condition, BasicBlock* target);
17011748
void inst_SETCC(GenCondition condition, var_types type, regNumber dstReg);
1749+
1750+
void genCodeForJcc(GenTreeCC* tree);
1751+
void genCodeForSetcc(GenTreeCC* setcc);
1752+
#endif // !TARGET_LOONGARCH64
17021753
};
17031754

17041755
// A simple phase that just invokes a method on the codegen instance

0 commit comments

Comments
 (0)