summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlrzlin <lrzlin@163.com>2022-11-06 14:18:35 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-12-08 22:46:06 -0500
commitea25088d4edd9f96e48f0a7f9407fd8eb9c2ae9c (patch)
tree4ec1da1736d0d223403907283139d52228fa56ac
parentd122e02247a371b14c3e906556900c0d600f424d (diff)
downloadhaskell-ea25088d4edd9f96e48f0a7f9407fd8eb9c2ae9c.tar.gz
Add initial support for LoongArch Architecture.
-rw-r--r--compiler/CodeGen.Platform.h72
-rw-r--r--compiler/GHC/CmmToAsm.hs1
-rw-r--r--compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs3
-rw-r--r--compiler/GHC/CmmToAsm/Reg/Linear.hs1
-rw-r--r--compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs1
-rw-r--r--compiler/GHC/CmmToAsm/Reg/Target.hs5
-rw-r--r--compiler/GHC/Driver/Pipeline/Execute.hs1
-rw-r--r--compiler/GHC/Platform.hs1
-rw-r--r--compiler/GHC/Platform/LoongArch64.hs9
-rw-r--r--compiler/GHC/Platform/Regs.hs6
-rw-r--r--compiler/ghc.cabal.in1
-rw-r--r--configure.ac2
-rw-r--r--hadrian/src/Oracles/Flag.hs3
-rw-r--r--libraries/base/System/Info.hs2
-rw-r--r--libraries/ghc-boot/GHC/Platform/ArchOS.hs2
-rw-r--r--llvm-targets2
-rw-r--r--m4/fptools_set_haskell_platform_vars.m45
-rw-r--r--m4/ghc_convert_cpu.m46
-rw-r--r--m4/ghc_tables_next_to_code.m42
-rw-r--r--m4/ghc_unregisterised.m42
-rw-r--r--rts/StgCRunAsm.S120
-rw-r--r--rts/include/stg/MachRegs.h51
-rw-r--r--rts/include/stg/MachRegsForHost.h4
-rw-r--r--rts/include/stg/SMP.h6
-rw-r--r--rts/linker/Elf.c6
-rw-r--r--rts/rts.cabal.in2
-rw-r--r--testsuite/tests/count-deps/CountDepsAst.stdout1
-rw-r--r--testsuite/tests/count-deps/CountDepsParser.stdout1
-rwxr-xr-xutils/llvm-targets/gen-data-layout.sh3
29 files changed, 314 insertions, 7 deletions
diff --git a/compiler/CodeGen.Platform.h b/compiler/CodeGen.Platform.h
index 42274b2f8d..01ea529fa0 100644
--- a/compiler/CodeGen.Platform.h
+++ b/compiler/CodeGen.Platform.h
@@ -377,6 +377,74 @@ import GHC.Platform.Reg
# define ft10 62
# define ft11 63
+#elif defined(MACHREGS_loongarch64)
+
+# define zero 0
+# define ra 1
+# define tp 2
+# define sp 3
+# define a0 4
+# define a1 5
+# define a2 6
+# define a3 7
+# define a4 8
+# define a5 9
+# define a6 10
+# define a7 11
+# define t0 12
+# define t1 13
+# define t2 14
+# define t3 15
+# define t4 16
+# define t5 17
+# define t6 18
+# define t7 19
+# define t8 20
+# define u0 21
+# define fp 22
+# define s0 23
+# define s1 24
+# define s2 25
+# define s3 26
+# define s4 27
+# define s5 28
+# define s6 29
+# define s7 30
+# define s8 31
+
+# define fa0 32
+# define fa1 33
+# define fa2 34
+# define fa3 35
+# define fa4 36
+# define fa5 37
+# define fa6 38
+# define fa7 39
+# define ft0 40
+# define ft1 41
+# define ft2 42
+# define ft3 43
+# define ft4 44
+# define ft5 45
+# define ft6 46
+# define ft7 47
+# define ft8 48
+# define ft9 49
+# define ft10 50
+# define ft11 51
+# define ft12 52
+# define ft13 53
+# define ft14 54
+# define ft15 55
+# define fs0 56
+# define fs1 57
+# define fs2 58
+# define fs3 59
+# define fs4 60
+# define fs5 61
+# define fs6 62
+# define fs7 63
+
#endif
callerSaves :: GlobalReg -> Bool
@@ -665,7 +733,9 @@ globalRegMaybe :: GlobalReg -> Maybe RealReg
|| defined(MACHREGS_powerpc) \
|| defined(MACHREGS_arm) || defined(MACHREGS_aarch64) \
|| defined(MACHREGS_s390x) || defined(MACHREGS_riscv64) \
- || defined(MACHREGS_wasm32)
+ || defined(MACHREGS_wasm32) \
+ || defined(MACHREGS_loongarch64)
+
# if defined(REG_Base)
globalRegMaybe BaseReg = Just (RealRegSingle REG_Base)
# endif
diff --git a/compiler/GHC/CmmToAsm.hs b/compiler/GHC/CmmToAsm.hs
index adb71e11a8..f4eb61c449 100644
--- a/compiler/GHC/CmmToAsm.hs
+++ b/compiler/GHC/CmmToAsm.hs
@@ -166,6 +166,7 @@ nativeCodeGen logger config modLoc h us cmms
ArchMipseb -> panic "nativeCodeGen: No NCG for mipseb"
ArchMipsel -> panic "nativeCodeGen: No NCG for mipsel"
ArchRISCV64 -> panic "nativeCodeGen: No NCG for RISCV64"
+ ArchLoongArch64->panic "nativeCodeGen: No NCG for LoongArch64"
ArchUnknown -> panic "nativeCodeGen: No NCG for unknown arch"
ArchJavaScript-> panic "nativeCodeGen: No NCG for JavaScript"
ArchWasm32 -> Wasm32.ncgWasm platform us modLoc h cmms
diff --git a/compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs b/compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs
index 7e0c570387..26ce377ab1 100644
--- a/compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs
+++ b/compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs
@@ -118,6 +118,7 @@ trivColorable platform virtualRegSqueeze realRegSqueeze RcInteger conflicts excl
ArchMipsel -> panic "trivColorable ArchMipsel"
ArchS390X -> panic "trivColorable ArchS390X"
ArchRISCV64 -> panic "trivColorable ArchRISCV64"
+ ArchLoongArch64->panic "trivColorable ArchLoongArch64"
ArchJavaScript-> panic "trivColorable ArchJavaScript"
ArchWasm32 -> panic "trivColorable ArchWasm32"
ArchUnknown -> panic "trivColorable ArchUnknown")
@@ -152,6 +153,7 @@ trivColorable platform virtualRegSqueeze realRegSqueeze RcFloat conflicts exclus
ArchMipsel -> panic "trivColorable ArchMipsel"
ArchS390X -> panic "trivColorable ArchS390X"
ArchRISCV64 -> panic "trivColorable ArchRISCV64"
+ ArchLoongArch64->panic "trivColorable ArchLoongArch64"
ArchJavaScript-> panic "trivColorable ArchJavaScript"
ArchWasm32 -> panic "trivColorable ArchWasm32"
ArchUnknown -> panic "trivColorable ArchUnknown")
@@ -185,6 +187,7 @@ trivColorable platform virtualRegSqueeze realRegSqueeze RcDouble conflicts exclu
ArchMipsel -> panic "trivColorable ArchMipsel"
ArchS390X -> panic "trivColorable ArchS390X"
ArchRISCV64 -> panic "trivColorable ArchRISCV64"
+ ArchLoongArch64->panic "trivColorable ArchLoongArch64"
ArchJavaScript-> panic "trivColorable ArchJavaScript"
ArchWasm32 -> panic "trivColorable ArchWasm32"
ArchUnknown -> panic "trivColorable ArchUnknown")
diff --git a/compiler/GHC/CmmToAsm/Reg/Linear.hs b/compiler/GHC/CmmToAsm/Reg/Linear.hs
index 8469242214..3064bf0d91 100644
--- a/compiler/GHC/CmmToAsm/Reg/Linear.hs
+++ b/compiler/GHC/CmmToAsm/Reg/Linear.hs
@@ -224,6 +224,7 @@ linearRegAlloc config entry_ids block_live sccs
ArchMipseb -> panic "linearRegAlloc ArchMipseb"
ArchMipsel -> panic "linearRegAlloc ArchMipsel"
ArchRISCV64 -> panic "linearRegAlloc ArchRISCV64"
+ ArchLoongArch64-> panic "linearRegAlloc ArchLoongArch64"
ArchJavaScript -> panic "linearRegAlloc ArchJavaScript"
ArchWasm32 -> panic "linearRegAlloc ArchWasm32"
ArchUnknown -> panic "linearRegAlloc ArchUnknown"
diff --git a/compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs b/compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs
index 65c2805e9b..519ea55fca 100644
--- a/compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs
+++ b/compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs
@@ -77,6 +77,7 @@ maxSpillSlots config = case platformArch (ncgPlatform config) of
ArchMipseb -> panic "maxSpillSlots ArchMipseb"
ArchMipsel -> panic "maxSpillSlots ArchMipsel"
ArchRISCV64 -> panic "maxSpillSlots ArchRISCV64"
+ ArchLoongArch64->panic "maxSpillSlots ArchLoongArch64"
ArchJavaScript-> panic "maxSpillSlots ArchJavaScript"
ArchWasm32 -> panic "maxSpillSlots ArchWasm32"
ArchUnknown -> panic "maxSpillSlots ArchUnknown"
diff --git a/compiler/GHC/CmmToAsm/Reg/Target.hs b/compiler/GHC/CmmToAsm/Reg/Target.hs
index 97440d1ac6..a94010987a 100644
--- a/compiler/GHC/CmmToAsm/Reg/Target.hs
+++ b/compiler/GHC/CmmToAsm/Reg/Target.hs
@@ -50,6 +50,7 @@ targetVirtualRegSqueeze platform
ArchMipseb -> panic "targetVirtualRegSqueeze ArchMipseb"
ArchMipsel -> panic "targetVirtualRegSqueeze ArchMipsel"
ArchRISCV64 -> panic "targetVirtualRegSqueeze ArchRISCV64"
+ ArchLoongArch64->panic "targetVirtualRegSqueeze ArchLoongArch64"
ArchJavaScript-> panic "targetVirtualRegSqueeze ArchJavaScript"
ArchWasm32 -> panic "targetVirtualRegSqueeze ArchWasm32"
ArchUnknown -> panic "targetVirtualRegSqueeze ArchUnknown"
@@ -69,6 +70,7 @@ targetRealRegSqueeze platform
ArchMipseb -> panic "targetRealRegSqueeze ArchMipseb"
ArchMipsel -> panic "targetRealRegSqueeze ArchMipsel"
ArchRISCV64 -> panic "targetRealRegSqueeze ArchRISCV64"
+ ArchLoongArch64->panic "targetRealRegSqueeze ArchLoongArch64"
ArchJavaScript-> panic "targetRealRegSqueeze ArchJavaScript"
ArchWasm32 -> panic "targetRealRegSqueeze ArchWasm32"
ArchUnknown -> panic "targetRealRegSqueeze ArchUnknown"
@@ -87,6 +89,7 @@ targetClassOfRealReg platform
ArchMipseb -> panic "targetClassOfRealReg ArchMipseb"
ArchMipsel -> panic "targetClassOfRealReg ArchMipsel"
ArchRISCV64 -> panic "targetClassOfRealReg ArchRISCV64"
+ ArchLoongArch64->panic "targetClassOfRealReg ArchLoongArch64"
ArchJavaScript-> panic "targetClassOfRealReg ArchJavaScript"
ArchWasm32 -> panic "targetClassOfRealReg ArchWasm32"
ArchUnknown -> panic "targetClassOfRealReg ArchUnknown"
@@ -105,6 +108,7 @@ targetMkVirtualReg platform
ArchMipseb -> panic "targetMkVirtualReg ArchMipseb"
ArchMipsel -> panic "targetMkVirtualReg ArchMipsel"
ArchRISCV64 -> panic "targetMkVirtualReg ArchRISCV64"
+ ArchLoongArch64->panic "targetMkVirtualReg ArchLoongArch64"
ArchJavaScript-> panic "targetMkVirtualReg ArchJavaScript"
ArchWasm32 -> panic "targetMkVirtualReg ArchWasm32"
ArchUnknown -> panic "targetMkVirtualReg ArchUnknown"
@@ -123,6 +127,7 @@ targetRegDotColor platform
ArchMipseb -> panic "targetRegDotColor ArchMipseb"
ArchMipsel -> panic "targetRegDotColor ArchMipsel"
ArchRISCV64 -> panic "targetRegDotColor ArchRISCV64"
+ ArchLoongArch64->panic "targetRegDotColor ArchLoongArch64"
ArchJavaScript-> panic "targetRegDotColor ArchJavaScript"
ArchWasm32 -> panic "targetRegDotColor ArchWasm32"
ArchUnknown -> panic "targetRegDotColor ArchUnknown"
diff --git a/compiler/GHC/Driver/Pipeline/Execute.hs b/compiler/GHC/Driver/Pipeline/Execute.hs
index bd9ee7805a..7c8dcaaa88 100644
--- a/compiler/GHC/Driver/Pipeline/Execute.hs
+++ b/compiler/GHC/Driver/Pipeline/Execute.hs
@@ -1015,6 +1015,7 @@ llvmOptions llvm_config dflags =
abi :: String
abi = case platformArch (targetPlatform dflags) of
ArchRISCV64 -> "lp64d"
+ ArchLoongArch64 -> "lp64d"
_ -> ""
-- | What phase to run after one of the backend code generators has run
diff --git a/compiler/GHC/Platform.hs b/compiler/GHC/Platform.hs
index b345d1535a..a630e0c1d3 100644
--- a/compiler/GHC/Platform.hs
+++ b/compiler/GHC/Platform.hs
@@ -263,6 +263,7 @@ platformCConvNeedsExtension platform = case platformArch platform of
ArchPPC_64 _ -> True
ArchS390X -> True
ArchRISCV64 -> True
+ ArchLoongArch64 -> True
ArchAArch64
-- Apple's AArch64 ABI requires that the caller sign-extend
-- small integer arguments. See
diff --git a/compiler/GHC/Platform/LoongArch64.hs b/compiler/GHC/Platform/LoongArch64.hs
new file mode 100644
index 0000000000..deabbbb4c0
--- /dev/null
+++ b/compiler/GHC/Platform/LoongArch64.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE CPP #-}
+
+module GHC.Platform.LoongArch64 where
+
+import GHC.Prelude
+
+#define MACHREGS_NO_REGS 0
+#define MACHREGS_loongarch64 1
+#include "CodeGen.Platform.h" \ No newline at end of file
diff --git a/compiler/GHC/Platform/Regs.hs b/compiler/GHC/Platform/Regs.hs
index 7f1ad5adc6..429f977a99 100644
--- a/compiler/GHC/Platform/Regs.hs
+++ b/compiler/GHC/Platform/Regs.hs
@@ -16,6 +16,7 @@ import qualified GHC.Platform.X86 as X86
import qualified GHC.Platform.X86_64 as X86_64
import qualified GHC.Platform.RISCV64 as RISCV64
import qualified GHC.Platform.Wasm32 as Wasm32
+import qualified GHC.Platform.LoongArch64 as LoongArch64
import qualified GHC.Platform.NoRegs as NoRegs
-- | Returns 'True' if this global register is stored in a caller-saves
@@ -33,6 +34,7 @@ callerSaves platform
ArchAArch64 -> AArch64.callerSaves
ArchRISCV64 -> RISCV64.callerSaves
ArchWasm32 -> Wasm32.callerSaves
+ ArchLoongArch64 -> LoongArch64.callerSaves
arch
| arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->
PPC.callerSaves
@@ -56,6 +58,7 @@ activeStgRegs platform
ArchAArch64 -> AArch64.activeStgRegs
ArchRISCV64 -> RISCV64.activeStgRegs
ArchWasm32 -> Wasm32.activeStgRegs
+ ArchLoongArch64 -> LoongArch64.activeStgRegs
arch
| arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->
PPC.activeStgRegs
@@ -74,6 +77,7 @@ haveRegBase platform
ArchAArch64 -> AArch64.haveRegBase
ArchRISCV64 -> RISCV64.haveRegBase
ArchWasm32 -> Wasm32.haveRegBase
+ ArchLoongArch64 -> LoongArch64.haveRegBase
arch
| arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->
PPC.haveRegBase
@@ -92,6 +96,7 @@ globalRegMaybe platform
ArchAArch64 -> AArch64.globalRegMaybe
ArchRISCV64 -> RISCV64.globalRegMaybe
ArchWasm32 -> Wasm32.globalRegMaybe
+ ArchLoongArch64 -> LoongArch64.globalRegMaybe
arch
| arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->
PPC.globalRegMaybe
@@ -110,6 +115,7 @@ freeReg platform
ArchAArch64 -> AArch64.freeReg
ArchRISCV64 -> RISCV64.freeReg
ArchWasm32 -> Wasm32.freeReg
+ ArchLoongArch64 -> LoongArch64.freeReg
arch
| arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->
PPC.freeReg
diff --git a/compiler/ghc.cabal.in b/compiler/ghc.cabal.in
index 34ccc26270..3ad8271127 100644
--- a/compiler/ghc.cabal.in
+++ b/compiler/ghc.cabal.in
@@ -569,6 +569,7 @@ Library
GHC.Platform.Reg.Class
GHC.Platform.Regs
GHC.Platform.RISCV64
+ GHC.Platform.LoongArch64
GHC.Platform.S390X
GHC.Platform.Wasm32
GHC.Platform.Ways
diff --git a/configure.ac b/configure.ac
index 2e683cdef3..09c48d592c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -333,7 +333,7 @@ AC_SUBST(TablesNextToCode)
dnl ** Does target have runtime linker support?
dnl --------------------------------------------------------------
case "$target" in
- powerpc64-*|powerpc64le-*|powerpc-ibm-aix*|s390x-ibm-linux|riscv64-*|wasm*|js-*)
+ powerpc64-*|powerpc64le-*|powerpc-ibm-aix*|s390x-ibm-linux|riscv64-*|wasm*|js-*|loongarch64-*)
TargetHasRTSLinker=NO
;;
*)
diff --git a/hadrian/src/Oracles/Flag.hs b/hadrian/src/Oracles/Flag.hs
index 41fc723b44..836834cbfc 100644
--- a/hadrian/src/Oracles/Flag.hs
+++ b/hadrian/src/Oracles/Flag.hs
@@ -118,7 +118,8 @@ targetSupportsSMP = do
, "arm"
, "aarch64"
, "s390x"
- , "riscv64"]
+ , "riscv64"
+ , "loongarch64"]
if -- The THREADED_RTS requires `BaseReg` to be in a register and the
-- Unregisterised mode doesn't allow that.
| unreg -> return False
diff --git a/libraries/base/System/Info.hs b/libraries/base/System/Info.hs
index 39ef75bd0f..0d5d0ce429 100644
--- a/libraries/base/System/Info.hs
+++ b/libraries/base/System/Info.hs
@@ -89,6 +89,8 @@ os = HOST_OS
-- * "powerpc64le"
-- * "riscv32"
-- * "riscv64"
+-- * "loongarch32"
+-- * "loongarch64"
-- * "rs6000"
-- * "s390"
-- * "s390x"
diff --git a/libraries/ghc-boot/GHC/Platform/ArchOS.hs b/libraries/ghc-boot/GHC/Platform/ArchOS.hs
index fa8042671a..3a2774db7d 100644
--- a/libraries/ghc-boot/GHC/Platform/ArchOS.hs
+++ b/libraries/ghc-boot/GHC/Platform/ArchOS.hs
@@ -44,6 +44,7 @@ data Arch
| ArchMipseb
| ArchMipsel
| ArchRISCV64
+ | ArchLoongArch64
| ArchJavaScript
| ArchWasm32
deriving (Read, Show, Eq, Ord)
@@ -134,6 +135,7 @@ stringEncodeArch = \case
ArchMipseb -> "mipseb"
ArchMipsel -> "mipsel"
ArchRISCV64 -> "riscv64"
+ ArchLoongArch64 -> "loongarch64"
ArchJavaScript -> "js"
ArchWasm32 -> "wasm32"
diff --git a/llvm-targets b/llvm-targets
index eb254cffde..213a2ea4d6 100644
--- a/llvm-targets
+++ b/llvm-targets
@@ -43,6 +43,8 @@
,("s390x-ibm-linux", ("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64", "z10", ""))
,("riscv64-unknown-linux-gnu", ("e-m:e-p:64:64-i64:64-i128:128-n64-S128", "", "+m +a +f +d +c +relax"))
,("riscv64-unknown-linux", ("e-m:e-p:64:64-i64:64-i128:128-n64-S128", "", "+m +a +f +d +c +relax"))
+,("loongarch64-unknown-linux-gnu", ("e-m:e-p:64:64-i64:64-i128:128-n64-S128", "", "+f +d"))
+,("loongarch64-unknown-linux", ("e-m:e-p:64:64-i64:64-i128:128-n64-S128", "", "+f +d"))
,("i386-apple-darwin", ("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:128-n8:16:32-S128", "penryn", ""))
,("x86_64-apple-darwin", ("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "penryn", ""))
,("arm64-apple-darwin", ("e-m:o-i64:64-i128:128-n32:64-S128", "generic", "+v8.3a +fp-armv8 +neon +crc +crypto +fullfp16 +ras +lse +rdm +rcpc +zcm +zcz +sha2 +aes"))
diff --git a/m4/fptools_set_haskell_platform_vars.m4 b/m4/fptools_set_haskell_platform_vars.m4
index d0c091e57d..1a32b3046b 100644
--- a/m4/fptools_set_haskell_platform_vars.m4
+++ b/m4/fptools_set_haskell_platform_vars.m4
@@ -45,7 +45,10 @@ AC_DEFUN([FPTOOLS_SET_HASKELL_PLATFORM_VARS_SHELL_FUNCTIONS],
wasm32)
test -z "[$]2" || eval "[$]2=ArchWasm32"
;;
- hppa|hppa1_1|ia64|m68k|nios2|riscv32|rs6000|s390|sh4|vax)
+ loongarch64)
+ test -z "[$]2" || eval "[$]2=ArchLoongArch64"
+ ;;
+ hppa|hppa1_1|ia64|m68k|nios2|riscv32|loongarch32|rs6000|s390|sh4|vax)
test -z "[$]2" || eval "[$]2=ArchUnknown"
;;
js)
diff --git a/m4/ghc_convert_cpu.m4 b/m4/ghc_convert_cpu.m4
index 8c1f1925e7..b3f1789bbc 100644
--- a/m4/ghc_convert_cpu.m4
+++ b/m4/ghc_convert_cpu.m4
@@ -56,6 +56,12 @@ case "$1" in
riscv|riscv32*)
$2="riscv32"
;;
+ loongarch64*)
+ $2="loongarch64"
+ ;;
+ loongarch32*)
+ $2="loongarch32"
+ ;;
rs6000)
$2="rs6000"
;;
diff --git a/m4/ghc_tables_next_to_code.m4 b/m4/ghc_tables_next_to_code.m4
index 3e0ced2137..8acf250c44 100644
--- a/m4/ghc_tables_next_to_code.m4
+++ b/m4/ghc_tables_next_to_code.m4
@@ -17,7 +17,7 @@ AC_DEFUN([GHC_TABLES_NEXT_TO_CODE],
case "$Unregisterised" in
NO)
case "$TargetArch" in
- ia64|powerpc64|powerpc64le|s390x|wasm32)
+ ia64|powerpc64|powerpc64le|s390x|wasm32|loongarch64)
TablesNextToCodeDefault=NO
AC_MSG_RESULT([no])
;;
diff --git a/m4/ghc_unregisterised.m4 b/m4/ghc_unregisterised.m4
index aafb92e165..38b445067d 100644
--- a/m4/ghc_unregisterised.m4
+++ b/m4/ghc_unregisterised.m4
@@ -5,7 +5,7 @@ AC_DEFUN([GHC_UNREGISTERISED],
[
AC_MSG_CHECKING(whether target supports a registerised ABI)
case "$TargetArch" in
- i386|x86_64|powerpc|powerpc64|powerpc64le|s390x|arm|aarch64|riscv64|wasm32|js)
+ i386|x86_64|powerpc|powerpc64|powerpc64le|s390x|arm|aarch64|riscv64|wasm32|js|loongarch64)
UnregisterisedDefault=NO
AC_MSG_RESULT([yes])
;;
diff --git a/rts/StgCRunAsm.S b/rts/StgCRunAsm.S
index 9216e6c759..d4172c5af4 100644
--- a/rts/StgCRunAsm.S
+++ b/rts/StgCRunAsm.S
@@ -370,6 +370,126 @@ StgReturn:
ret
.cfi_endproc
.size StgReturn, .-StgReturn
+
+#elif defined(loongarch64_HOST_ARCH)
+# define STACK_FRAME_SIZE (RESERVED_C_STACK_BYTES+160)
+ .text
+ .align 1
+ .globl StgRun
+ .type StgRun, @function
+StgRun:
+ .cfi_startproc
+ addi.d $sp,$sp,-160
+ .cfi_def_cfa_offset 160
+ /* save callee-saved registers plus ra */
+ st.d $ra,$sp,152
+ st.d $fp,$sp,144
+ st.d $s0,$sp,136
+ st.d $s1,$sp,128
+ st.d $s2,$sp,120
+ st.d $s3,$sp,112
+ st.d $s4,$sp,104
+ st.d $s5,$sp,96
+ st.d $s6,$sp,88
+ st.d $s7,$sp,80
+ st.d $s8,$sp,72
+ fst.d $fs0,$sp,56
+ fst.d $fs1,$sp,48
+ fst.d $fs2,$sp,40
+ fst.d $fs3,$sp,32
+ fst.d $fs4,$sp,24
+ fst.d $fs5,$sp,16
+ fst.d $fs6,$sp,8
+ fst.d $fs7,$sp,0
+ /* allocate stack frame */
+ li.d $t0,RESERVED_C_STACK_BYTES
+ sub.d $sp,$sp,$t0
+ .cfi_def_cfa_offset STACK_FRAME_SIZE
+ .cfi_offset 1, -8
+ .cfi_offset 22, -16
+ .cfi_offset 23, -24
+ .cfi_offset 24, -32
+ .cfi_offset 25, -40
+ .cfi_offset 26, -48
+ .cfi_offset 27, -56
+ .cfi_offset 28, -64
+ .cfi_offset 29, -72
+ .cfi_offset 30, -80
+ .cfi_offset 31, -88
+ .cfi_offset 56, -104
+ .cfi_offset 57, -112
+ .cfi_offset 58, -120
+ .cfi_offset 59, -128
+ .cfi_offset 60, -136
+ .cfi_offset 61, -144
+ .cfi_offset 62, -152
+ .cfi_offset 63, -160
+ /* set STGs BaseReg from LoongArch a1 */
+ move $s0,$a1
+ /* jump to STG function */
+ jr $a0
+ .cfi_endproc
+ .size StgRun, .-StgRun
+
+ .text
+ .align 2
+ .globl StgReturn
+ .type StgReturn, @function
+StgReturn:
+ .cfi_startproc
+ /* set return value from STGs R1 (LoongArch64 s3) */
+ move $a0,$s3
+ /* deallocate stack frame */
+ li.d $t0,RESERVED_C_STACK_BYTES
+ add.d $sp,$sp,$t0
+ .cfi_def_cfa_offset 160
+ /* restore callee-saved registers and ra */
+ ld.d $ra,$sp,152
+ .cfi_restore 1
+ ld.d $fp,$sp,144
+ .cfi_restore 22
+ ld.d $s0,$sp,136
+ .cfi_restore 23
+ ld.d $s1,$sp,128
+ .cfi_restore 24
+ ld.d $s2,$sp,120
+ .cfi_restore 25
+ ld.d $s3,$sp,112
+ .cfi_restore 26
+ ld.d $s4,$sp,104
+ .cfi_restore 27
+ ld.d $s5,$sp,96
+ .cfi_restore 28
+ ld.d $s6,$sp,88
+ .cfi_restore 29
+ ld.d $s7,$sp,80
+ .cfi_restore 30
+ ld.d $s8,$sp,72
+ .cfi_restore 31
+ fld.d $fs0,$sp,56
+ .cfi_restore 56
+ fld.d $fs1,$sp,48
+ .cfi_restore 57
+ fld.d $fs2,$sp,40
+ .cfi_restore 58
+ fld.d $fs3,$sp,32
+ .cfi_restore 59
+ fld.d $fs4,$sp,24
+ .cfi_restore 60
+ fld.d $fs5,$sp,16
+ .cfi_restore 61
+ fld.d $fs6,$sp,8
+ .cfi_restore 62
+ fld.d $fs7,$sp,0
+ .cfi_restore 63
+ addi.d $sp,$sp,160
+ .cfi_def_cfa_offset 0
+ /* jump back to caller of StgRun() */
+ ret
+ .cfi_endproc
+ .size StgReturn, .-StgReturn
+
+ .section .note.GNU-stack,"",@progbits
#endif
#endif /* !USE_MINIINTERPRETER */
diff --git a/rts/include/stg/MachRegs.h b/rts/include/stg/MachRegs.h
index 2563f938ca..f0253865ea 100644
--- a/rts/include/stg/MachRegs.h
+++ b/rts/include/stg/MachRegs.h
@@ -626,6 +626,57 @@ the stack. See Note [Overlapping global registers] for implications.
#define REG_HpLim 27
#define REG_CCCS 28
+/* -----------------------------------------------------------------------------
+ The loongarch64 register mapping
+
+ Register | Role(s) | Call effect
+ ------------+-----------------------------------------+-------------
+ zero | Hard-wired zero | -
+ ra | Return address | caller-saved
+ tp | Thread pointer | -
+ sp | Stack pointer | callee-saved
+ a0,a1 | Arguments / return values | caller-saved
+ a2..a7 | Arguments | caller-saved
+ t0..t8 | - | caller-saved
+ u0 | Reserve | -
+ fp | Frame pointer | callee-saved
+ s0..s8 | - | callee-saved
+ fa0,fa1 | Arguments / return values | caller-saved
+ fa2..fa7 | Arguments | caller-saved
+ ft0..ft15 | - | caller-saved
+ fs0..fs7 | - | callee-saved
+
+ Each general purpose register as well as each floating-point
+ register is 64 bits wide, also, the u0 register is called r21 in some cases.
+
+ -------------------------------------------------------------------------- */
+#elif defined(MACHREGS_loongarch64)
+
+#define REG(x) __asm__("$" #x)
+
+#define REG_Base s0
+#define REG_Sp s1
+#define REG_Hp s2
+#define REG_R1 s3
+#define REG_R2 s4
+#define REG_R3 s5
+#define REG_R4 s6
+#define REG_R5 s7
+#define REG_SpLim s8
+
+#define REG_F1 fs0
+#define REG_F2 fs1
+#define REG_F3 fs2
+#define REG_F4 fs3
+
+#define REG_D1 fs4
+#define REG_D2 fs5
+#define REG_D3 fs6
+#define REG_D4 fs7
+
+#define MAX_REAL_FLOAT_REG 4
+#define MAX_REAL_DOUBLE_REG 4
+
#else
#error Cannot find platform to give register info for
diff --git a/rts/include/stg/MachRegsForHost.h b/rts/include/stg/MachRegsForHost.h
index 78f823d95c..6452df4158 100644
--- a/rts/include/stg/MachRegsForHost.h
+++ b/rts/include/stg/MachRegsForHost.h
@@ -79,6 +79,10 @@
#define MACHREGS_NO_REGS 1
#endif
+#if defined(loongarch64_HOST_ARCH)
+#define MACHREGS_loongarch64 1
+#endif
+
#endif
#include "MachRegs.h"
diff --git a/rts/include/stg/SMP.h b/rts/include/stg/SMP.h
index b8f72a1248..aaa54e8435 100644
--- a/rts/include/stg/SMP.h
+++ b/rts/include/stg/SMP.h
@@ -393,6 +393,8 @@ write_barrier(void) {
__asm__ __volatile__ ("dmb st" : : : "memory");
#elif defined(riscv64_HOST_ARCH)
__asm__ __volatile__ ("fence w,w" : : : "memory");
+#elif defined(loongarch64_HOST_ARCH)
+ __asm__ __volatile__ ("dbar 0" : : : "memory");
#else
#error memory barriers unimplemented on this architecture
#endif
@@ -417,6 +419,8 @@ store_load_barrier(void) {
__asm__ __volatile__ ("dmb sy" : : : "memory");
#elif defined(riscv64_HOST_ARCH)
__asm__ __volatile__ ("fence w,r" : : : "memory");
+#elif defined(loongarch64_HOST_ARCH)
+ __asm__ __volatile__ ("dbar 0" : : : "memory");
#else
#error memory barriers unimplemented on this architecture
#endif
@@ -441,6 +445,8 @@ load_load_barrier(void) {
__asm__ __volatile__ ("dmb ld" : : : "memory");
#elif defined(riscv64_HOST_ARCH)
__asm__ __volatile__ ("fence r,r" : : : "memory");
+#elif defined(loongarch64_HOST_ARCH)
+ __asm__ __volatile__ ("dbar 0" : : : "memory");
#else
#error memory barriers unimplemented on this architecture
#endif
diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c
index bbcd8b4208..3595a4c3d4 100644
--- a/rts/linker/Elf.c
+++ b/rts/linker/Elf.c
@@ -417,6 +417,12 @@ ocVerifyImage_ELF ( ObjectCode* oc )
oc->fileName);
return 0;
#endif
+#if defined(EM_LOONGARCH)
+ case EM_LOONGARCH: IF_DEBUG(linker,debugBelch( "loongarch64" ));
+ errorBelch("%s: RTS linker not implemented on loongarch64",
+ oc->fileName);
+ return 0;
+#endif
default: IF_DEBUG(linker,debugBelch( "unknown" ));
errorBelch("%s: unknown architecture (e_machine == %d)"
, oc->fileName, ehdr->e_machine);
diff --git a/rts/rts.cabal.in b/rts/rts.cabal.in
index 9cdaae0bbe..e4a78a64cf 100644
--- a/rts/rts.cabal.in
+++ b/rts/rts.cabal.in
@@ -516,7 +516,7 @@ library
c-sources: adjustor/NativeIA64.c
-- Use assembler STG entrypoint on architectures where it is used
- if arch(ppc) || arch(ppc64) || arch(s390x) || arch(riscv64)
+ if arch(ppc) || arch(ppc64) || arch(s390x) || arch(riscv64) || arch(loongarch64)
asm-sources: StgCRunAsm.S
c-sources: Adjustor.c
diff --git a/testsuite/tests/count-deps/CountDepsAst.stdout b/testsuite/tests/count-deps/CountDepsAst.stdout
index 8db15009b1..c3b067c31e 100644
--- a/testsuite/tests/count-deps/CountDepsAst.stdout
+++ b/testsuite/tests/count-deps/CountDepsAst.stdout
@@ -155,6 +155,7 @@ GHC.Platform
GHC.Platform.AArch64
GHC.Platform.ARM
GHC.Platform.Constants
+GHC.Platform.LoongArch64
GHC.Platform.NoRegs
GHC.Platform.PPC
GHC.Platform.Profile
diff --git a/testsuite/tests/count-deps/CountDepsParser.stdout b/testsuite/tests/count-deps/CountDepsParser.stdout
index 8e41f78ac5..8ff84fd40d 100644
--- a/testsuite/tests/count-deps/CountDepsParser.stdout
+++ b/testsuite/tests/count-deps/CountDepsParser.stdout
@@ -162,6 +162,7 @@ GHC.Platform
GHC.Platform.AArch64
GHC.Platform.ARM
GHC.Platform.Constants
+GHC.Platform.LoongArch64
GHC.Platform.NoRegs
GHC.Platform.PPC
GHC.Platform.Profile
diff --git a/utils/llvm-targets/gen-data-layout.sh b/utils/llvm-targets/gen-data-layout.sh
index 2a506b189d..e5ead7ddeb 100755
--- a/utils/llvm-targets/gen-data-layout.sh
+++ b/utils/llvm-targets/gen-data-layout.sh
@@ -82,6 +82,9 @@ TARGETS=(
# Linux riscv64
"riscv64-unknown-linux-gnu"
"riscv64-unknown-linux"
+ # Linux loongarch64
+ "loongarch64-unknown-linux-gnu"
+ "loongarch64-unknown-linux"
#########################
# Darwin