Description: <short summary of the patch>
 TODO: Put a short summary on the line above and replace this paragraph
 with a longer explanation of this change. Complete the meta-information
 with other relevant fields (see below for details). To make it easier, the
 information below has been extracted from the changelog. Adjust it or drop
 it.
 .
 mozjs60 (60.2.3-3.lnd.1) unstable; urgency=medium
 .
   * add loongarch64 support.
Author: Jianjun Han <hanjianjun@loongson.cn>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2021-01-13

--- mozjs60-60.2.3.orig/build/autoconf/config.sub
+++ mozjs60-60.2.3/build/autoconf/config.sub
@@ -273,6 +273,7 @@ case $basic_machine in
 	| mips | mipsbe | mipseb | mipsel | mipsle \
 	| mips16 \
 	| mips64 | mips64el \
+	| loongarch64 | loongarch \
 	| mips64octeon | mips64octeonel \
 	| mips64orion | mips64orionel \
 	| mips64r5900 | mips64r5900el \
@@ -399,6 +400,7 @@ case $basic_machine in
 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
 	| mips16-* \
 	| mips64-* | mips64el-* \
+	| loongarch64-* | loongarch-* \
 	| mips64octeon-* | mips64octeonel-* \
 	| mips64orion-* | mips64orionel-* \
 	| mips64r5900-* | mips64r5900el-* \
--- mozjs60-60.2.3.orig/build/moz.configure/init.configure
+++ mozjs60-60.2.3/build/moz.configure/init.configure
@@ -670,6 +670,9 @@ def split_triplet(triplet, allow_unknown
     elif cpu in ('mips64', 'mips64el'):
         canonical_cpu = 'mips64'
         endianness = 'little' if 'el' in cpu else 'big'
+    elif cpu in ('loongarch64', 'loongarch64'):
+        canonical_cpu = 'loongarch64'
+        endianness = 'little'
     elif cpu.startswith('aarch64'):
         canonical_cpu = 'aarch64'
         endianness = 'little'
--- mozjs60-60.2.3.orig/intl/icu/source/config.sub
+++ mozjs60-60.2.3/intl/icu/source/config.sub
@@ -273,6 +273,7 @@ case $basic_machine in
 	| mips | mipsbe | mipseb | mipsel | mipsle \
 	| mips16 \
 	| mips64 | mips64el \
+	| loongarch64 | loongarch \
 	| mips64octeon | mips64octeonel \
 	| mips64orion | mips64orionel \
 	| mips64r5900 | mips64r5900el \
@@ -392,6 +393,7 @@ case $basic_machine in
 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
 	| mips16-* \
 	| mips64-* | mips64el-* \
+	| loongarch64-* | loongarch-* \
 	| mips64octeon-* | mips64octeonel-* \
 	| mips64orion-* | mips64orionel-* \
 	| mips64r5900-* | mips64r5900el-* \
--- mozjs60-60.2.3.orig/js/moz.configure
+++ mozjs60-60.2.3/js/moz.configure
@@ -107,7 +107,7 @@ def disable_export_js(value):
 # =======================================================
 @depends(target)
 def ion_default(target):
-    if target.cpu in ('x86', 'x86_64', 'arm', 'aarch64', 'mips32', 'mips64'):
+    if target.cpu in ('x86', 'x86_64', 'arm', 'aarch64', 'mips32', 'mips64', 'loongarch64'):
         return True
 
 js_option('--enable-ion',
@@ -118,7 +118,7 @@ set_config('ENABLE_ION', depends_if('--e
 
 # JIT code simulator for cross compiles
 # =======================================================
-js_option('--enable-simulator', choices=('arm', 'arm64', 'mips32', 'mips64'),
+js_option('--enable-simulator', choices=('arm', 'arm64', 'mips32', 'mips64', 'loongarch64'),
           nargs=1,
           help='Enable a JIT code simulator for the specified architecture')
 
@@ -133,7 +133,7 @@ def simulator(ion_enabled, simulator_ena
         if target.cpu != 'x86':
             die('The %s simulator only works on x86.' % sim_cpu)
 
-    if sim_cpu in ('arm64', 'mips64'):
+    if sim_cpu in ('arm64', 'mips64', 'loongarch64'):
         if target.cpu != 'x86_64':
             die('The %s simulator only works on x86-64.' % sim_cpu)
 
@@ -177,6 +177,7 @@ set_define('JS_CODEGEN_ARM', jit_codegen
 set_define('JS_CODEGEN_ARM64', jit_codegen.arm64)
 set_define('JS_CODEGEN_MIPS32', jit_codegen.mips32)
 set_define('JS_CODEGEN_MIPS64', jit_codegen.mips64)
+set_define('JS_CODEGEN_LOONGARCH64', jit_codegen.loongarch64)
 set_define('JS_CODEGEN_X86', jit_codegen.x86)
 set_define('JS_CODEGEN_X64', jit_codegen.x64)
 
--- mozjs60-60.2.3.orig/js/src/ctypes/libffi/config.sub
+++ mozjs60-60.2.3/js/src/ctypes/libffi/config.sub
@@ -272,6 +272,7 @@ case $basic_machine in
 	| mips | mipsbe | mipseb | mipsel | mipsle \
 	| mips16 \
 	| mips64 | mips64el \
+	| loongarch64 | loongarch \
 	| mips64octeon | mips64octeonel \
 	| mips64orion | mips64orionel \
 	| mips64r5900 | mips64r5900el \
@@ -390,6 +391,7 @@ case $basic_machine in
 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
 	| mips16-* \
 	| mips64-* | mips64el-* \
+	| loongarch64-* | loongarch-* \
 	| mips64octeon-* | mips64octeonel-* \
 	| mips64orion-* | mips64orionel-* \
 	| mips64r5900-* | mips64r5900el-* \
--- mozjs60-60.2.3.orig/js/src/jit/AtomicOperations.h
+++ mozjs60-60.2.3/js/src/jit/AtomicOperations.h
@@ -367,7 +367,7 @@ AtomicOperations::isLockfreeJS(int32_t s
 # else
 #  error "No AtomicOperations support for this platform+compiler combination"
 # endif
-#elif defined(__mips__)
+#elif defined(__mips__) || defined(__loongarch__)
 # if defined(__clang__) || defined(__GNUC__)
 #  include "jit/mips-shared/AtomicOperations-mips-shared.h"
 # else
--- mozjs60-60.2.3.orig/js/src/jit/MacroAssembler.h
+++ mozjs60-60.2.3/js/src/jit/MacroAssembler.h
@@ -89,7 +89,7 @@ using mozilla::FloatingPoint;
 //   ////}}} check_macroassembler_style
 
 
-# define ALL_ARCH mips32, mips64, arm, arm64, x86, x64
+# define ALL_ARCH mips32, mips64, loongarch64, arm, arm64, x86, x64
 # define ALL_SHARED_ARCH arm, arm64, x86_shared, mips_shared
 
 // * How this macro works:
@@ -135,6 +135,7 @@ using mozilla::FloatingPoint;
 # define DEFINED_ON_arm64
 # define DEFINED_ON_mips32
 # define DEFINED_ON_mips64
+# define DEFINED_ON_loongarch64
 # define DEFINED_ON_mips_shared
 # define DEFINED_ON_none
 
@@ -165,6 +166,11 @@ using mozilla::FloatingPoint;
 # define DEFINED_ON_mips64 define
 # undef DEFINED_ON_mips_shared
 # define DEFINED_ON_mips_shared define
+#elif defined(JS_CODEGEN_LOONGARCH64)
+# undef DEFINED_ON_loongarch64
+# define DEFINED_ON_loongarch64 define
+# undef DEFINED_ON_loongarch_shared
+# define DEFINED_ON_loongarch_shared define
 #elif defined(JS_CODEGEN_NONE)
 # undef DEFINED_ON_none
 # define DEFINED_ON_none crash
@@ -446,19 +452,19 @@ class MacroAssembler : public MacroAssem
     // Stack manipulation functions.
 
     void PushRegsInMask(LiveRegisterSet set)
-                            DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+                            DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
     void PushRegsInMask(LiveGeneralRegisterSet set);
 
     // Like PushRegsInMask, but instead of pushing the registers, store them to
     // |dest|. |dest| should point to the end of the reserved space, so the
     // first register will be stored at |dest.offset - sizeof(register)|.
     void storeRegsInMask(LiveRegisterSet set, Address dest, Register scratch)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     void PopRegsInMask(LiveRegisterSet set);
     void PopRegsInMask(LiveGeneralRegisterSet set);
     void PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore)
-                                 DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+                                 DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     void Push(const Operand op) DEFINED_ON(x86_shared);
     void Push(Register reg) PER_SHARED_ARCH;
@@ -862,10 +868,10 @@ class MacroAssembler : public MacroAssem
 
     inline void mul64(const Operand& src, const Register64& dest) DEFINED_ON(x64);
     inline void mul64(const Operand& src, const Register64& dest, const Register temp)
-        DEFINED_ON(x64, mips64);
+        DEFINED_ON(x64, mips64,loongarch64);
     inline void mul64(Imm64 imm, const Register64& dest) PER_ARCH;
     inline void mul64(Imm64 imm, const Register64& dest, const Register temp)
-        DEFINED_ON(x86, x64, arm, mips32, mips64);
+        DEFINED_ON(x86, x64, arm, mips32, mips64, loongarch64);
     inline void mul64(const Register64& src, const Register64& dest, const Register temp)
         PER_ARCH;
 
@@ -995,7 +1001,7 @@ class MacroAssembler : public MacroAssem
 
     template <typename T1, typename T2>
     inline void cmp32Set(Condition cond, T1 lhs, T2 rhs, Register dest)
-        DEFINED_ON(x86_shared, arm, arm64, mips32, mips64);
+        DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loongarch64);
 
     template <typename T1, typename T2>
     inline void cmpPtrSet(Condition cond, T1 lhs, T2 rhs, Register dest)
@@ -1253,7 +1259,7 @@ class MacroAssembler : public MacroAssem
     inline void branchTestUndefined(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
     inline void branchTestInt32(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
     inline void branchTestDouble(Condition cond, Register tag, Label* label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
     inline void branchTestNumber(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
     inline void branchTestBoolean(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
     inline void branchTestString(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
@@ -1270,57 +1276,57 @@ class MacroAssembler : public MacroAssem
     inline void branchTestUndefined(Condition cond, const Address& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestUndefined(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestUndefined(Condition cond, const ValueOperand& value, Label* label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     inline void branchTestInt32(Condition cond, const Address& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestInt32(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestInt32(Condition cond, const ValueOperand& value, Label* label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     inline void branchTestDouble(Condition cond, const Address& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestDouble(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestDouble(Condition cond, const ValueOperand& value, Label* label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     inline void branchTestNumber(Condition cond, const ValueOperand& value, Label* label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     inline void branchTestBoolean(Condition cond, const Address& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestBoolean(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestBoolean(Condition cond, const ValueOperand& value, Label* label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     inline void branchTestString(Condition cond, const Address& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestString(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestString(Condition cond, const ValueOperand& value, Label* label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     inline void branchTestSymbol(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestSymbol(Condition cond, const ValueOperand& value, Label* label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     inline void branchTestNull(Condition cond, const Address& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestNull(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestNull(Condition cond, const ValueOperand& value, Label* label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     // Clobbers the ScratchReg on x64.
     inline void branchTestObject(Condition cond, const Address& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestObject(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestObject(Condition cond, const ValueOperand& value, Label* label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     inline void branchTestGCThing(Condition cond, const Address& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestGCThing(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
 
     inline void branchTestPrimitive(Condition cond, const ValueOperand& value, Label* label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     inline void branchTestMagic(Condition cond, const Address& address, Label* label) PER_SHARED_ARCH;
     inline void branchTestMagic(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
     template <class L>
     inline void branchTestMagic(Condition cond, const ValueOperand& value, L label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     inline void branchTestMagic(Condition cond, const Address& valaddr, JSWhyMagic why, Label* label) PER_ARCH;
 
@@ -1333,11 +1339,11 @@ class MacroAssembler : public MacroAssem
     // Checks if given Value is evaluated to true or false in a condition.
     // The type of the value should match the type of the method.
     inline void branchTestInt32Truthy(bool truthy, const ValueOperand& value, Label* label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
     inline void branchTestDoubleTruthy(bool truthy, FloatRegister reg, Label* label) PER_SHARED_ARCH;
     inline void branchTestBooleanTruthy(bool truthy, const ValueOperand& value, Label* label) PER_ARCH;
     inline void branchTestStringTruthy(bool truthy, const ValueOperand& value, Label* label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86_shared);
 
     // Create an unconditional branch to the address given as argument.
     inline void branchToComputedAddress(const BaseIndex& address) PER_ARCH;
@@ -1453,9 +1459,9 @@ class MacroAssembler : public MacroAssem
     // ========================================================================
     // Memory access primitives.
     inline void storeUncanonicalizedDouble(FloatRegister src, const Address& dest)
-        DEFINED_ON(x86_shared, arm, arm64, mips32, mips64);
+        DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loongarch64);
     inline void storeUncanonicalizedDouble(FloatRegister src, const BaseIndex& dest)
-        DEFINED_ON(x86_shared, arm, arm64, mips32, mips64);
+        DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loongarch64);
     inline void storeUncanonicalizedDouble(FloatRegister src, const Operand& dest)
         DEFINED_ON(x86_shared);
 
@@ -1466,9 +1472,9 @@ class MacroAssembler : public MacroAssem
     using MacroAssemblerSpecific::boxDouble;
 
     inline void storeUncanonicalizedFloat32(FloatRegister src, const Address& dest)
-        DEFINED_ON(x86_shared, arm, arm64, mips32, mips64);
+        DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loongarch64);
     inline void storeUncanonicalizedFloat32(FloatRegister src, const BaseIndex& dest)
-        DEFINED_ON(x86_shared, arm, arm64, mips32, mips64);
+        DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loongarch64);
     inline void storeUncanonicalizedFloat32(FloatRegister src, const Operand& dest)
         DEFINED_ON(x86_shared);
 
@@ -1507,10 +1513,10 @@ class MacroAssembler : public MacroAssem
 
     // temp required on x86 and x64; must be undefined on mips64.
     void convertUInt64ToFloat32(Register64 src, FloatRegister dest, Register temp)
-        DEFINED_ON(arm64, mips64, x64, x86);
+        DEFINED_ON(arm64, mips64, loongarch64, x64, x86);
 
     void convertInt64ToFloat32(Register64 src, FloatRegister dest)
-        DEFINED_ON(arm64, mips64, x64, x86);
+        DEFINED_ON(arm64, mips64, loongarch64, x64, x86);
 
     bool convertUInt64ToDoubleNeedsTemp() PER_ARCH;
 
@@ -1518,7 +1524,7 @@ class MacroAssembler : public MacroAssem
     void convertUInt64ToDouble(Register64 src, FloatRegister dest, Register temp) PER_ARCH;
 
     void convertInt64ToDouble(Register64 src, FloatRegister dest)
-        DEFINED_ON(arm64, mips64, x64, x86);
+        DEFINED_ON(arm64, mips64, loongarch64, x64, x86);
 
   public:
     // ========================================================================
@@ -1534,11 +1540,11 @@ class MacroAssembler : public MacroAssem
     // saturated in-place to 'boundsCheckLimit'.
     template <class L>
     inline void wasmBoundsCheck(Condition cond, Register index, Register boundsCheckLimit, L label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86);
 
     template <class L>
     inline void wasmBoundsCheck(Condition cond, Register index, Address boundsCheckLimit, L label)
-        DEFINED_ON(arm, arm64, mips32, mips64, x86);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x86);
 
     // On x86, each instruction adds its own wasm::MemoryAccess's to the
     // wasm::MemoryAccessVector (there can be multiple when i64 is involved).
@@ -1559,18 +1565,18 @@ class MacroAssembler : public MacroAssem
         DEFINED_ON(arm, arm64, mips_shared);
     void wasmLoadI64(const wasm::MemoryAccessDesc& access, Register memoryBase, Register ptr,
                      Register ptrScratch, Register64 output)
-        DEFINED_ON(arm, arm64, mips32, mips64);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64);
     void wasmStore(const wasm::MemoryAccessDesc& access, AnyRegister value, Register memoryBase,
                    Register ptr, Register ptrScratch)
-        DEFINED_ON(arm, arm64, mips_shared);
+        DEFINED_ON(arm, arm64, loongarch64, mips_shared);
     void wasmStoreI64(const wasm::MemoryAccessDesc& access, Register64 value, Register memoryBase,
                       Register ptr, Register ptrScratch)
-        DEFINED_ON(arm, arm64, mips32, mips64);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64);
 
     // `ptr` will always be updated.
     void wasmUnalignedLoad(const wasm::MemoryAccessDesc& access, Register memoryBase, Register ptr,
                            Register ptrScratch, Register output, Register tmp)
-        DEFINED_ON(arm, mips32, mips64);
+        DEFINED_ON(arm, mips32, mips64, loongarch64);
 
     // ARM: `ptr` will always be updated and `tmp1` is always needed.  `tmp2` is
     // needed for Float32; `tmp2` and `tmp3` are needed for Float64.  Temps must
@@ -1579,29 +1585,29 @@ class MacroAssembler : public MacroAssem
     void wasmUnalignedLoadFP(const wasm::MemoryAccessDesc& access, Register memoryBase, Register ptr,
                              Register ptrScratch, FloatRegister output, Register tmp1, Register tmp2,
                              Register tmp3)
-        DEFINED_ON(arm, mips32, mips64);
+        DEFINED_ON(arm, mips32, mips64, loongarch64);
 
     // `ptr` will always be updated.
     void wasmUnalignedLoadI64(const wasm::MemoryAccessDesc& access, Register memoryBase, Register ptr,
                               Register ptrScratch, Register64 output, Register tmp)
-        DEFINED_ON(arm, mips32, mips64);
+        DEFINED_ON(arm, mips32, mips64, loongarch64);
 
     // ARM: `ptr` and `value` will always be updated.  'tmp' must be Invalid.
     // MIPS: `ptr` will always be updated.
     void wasmUnalignedStore(const wasm::MemoryAccessDesc& access, Register value, Register memoryBase,
                             Register ptr, Register ptrScratch, Register tmp)
-        DEFINED_ON(arm, mips32, mips64);
+        DEFINED_ON(arm, mips32, mips64, loongarch64);
 
     // `ptr` will always be updated.
     void wasmUnalignedStoreFP(const wasm::MemoryAccessDesc& access, FloatRegister floatValue,
                               Register memoryBase, Register ptr, Register ptrScratch, Register tmp)
-        DEFINED_ON(arm, mips32, mips64);
+        DEFINED_ON(arm, mips32, mips64, loongarch64);
 
     // `ptr` will always be updated.
     void wasmUnalignedStoreI64(const wasm::MemoryAccessDesc& access, Register64 value,
                                Register memoryBase, Register ptr, Register ptrScratch,
                                Register tmp)
-        DEFINED_ON(arm, mips32, mips64);
+        DEFINED_ON(arm, mips32, mips64, loongarch64);
 
     // wasm specific methods, used in both the wasm baseline compiler and ion.
 
@@ -1627,20 +1633,20 @@ class MacroAssembler : public MacroAssem
     // after the last emitted instruction.
     void wasmTruncateDoubleToInt64(FloatRegister input, Register64 output, bool isSaturating,
                                    Label* oolEntry, Label* oolRejoin, FloatRegister tempDouble)
-        DEFINED_ON(arm64, x86, x64, mips64);
+        DEFINED_ON(arm64, x86, x64, mips64, loongarch64);
     void wasmTruncateDoubleToUInt64(FloatRegister input, Register64 output, bool isSaturating,
                                     Label* oolEntry, Label* oolRejoin, FloatRegister tempDouble)
-        DEFINED_ON(arm64, x86, x64, mips64);
+        DEFINED_ON(arm64, x86, x64, mips64, loongarch64);
     void oolWasmTruncateCheckF64ToI64(FloatRegister input, Register64 output, TruncFlags flags,
                                       wasm::BytecodeOffset off, Label* rejoin)
         DEFINED_ON(arm, arm64, x86_shared, mips_shared);
 
     void wasmTruncateFloat32ToInt64(FloatRegister input, Register64 output, bool isSaturating,
                                     Label* oolEntry, Label* oolRejoin, FloatRegister tempDouble)
-        DEFINED_ON(arm64, x86, x64, mips64);
+        DEFINED_ON(arm64, x86, x64, mips64, loongarch64);
     void wasmTruncateFloat32ToUInt64(FloatRegister input, Register64 output, bool isSaturating,
                                      Label* oolEntry, Label* oolRejoin, FloatRegister tempDouble)
-        DEFINED_ON(arm64, x86, x64, mips64);
+        DEFINED_ON(arm64, x86, x64, mips64, loongarch64);
     void oolWasmTruncateCheckF32ToI64(FloatRegister input, Register64 output, TruncFlags flags,
                                       wasm::BytecodeOffset off, Label* rejoin)
         DEFINED_ON(arm, arm64, x86_shared, mips_shared);
@@ -1856,11 +1862,11 @@ class MacroAssembler : public MacroAssem
 
     void atomicFetchOp64(const Synchronization& sync, AtomicOp op, Register64 value,
                          const Address& mem, Register64 temp, Register64 output)
-        DEFINED_ON(arm, arm64, mips32, mips64, x64);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x64);
 
     void atomicFetchOp64(const Synchronization& sync, AtomicOp op, Register64 value,
                          const BaseIndex& mem, Register64 temp, Register64 output)
-        DEFINED_ON(arm, arm64, mips32, mips64, x64);
+        DEFINED_ON(arm, arm64, mips32, mips64, loongarch64, x64);
 
     void atomicFetchOp64(const Synchronization& sync, AtomicOp op, const Address& value,
                          const Address& mem, Register64 temp, Register64 output)
@@ -2368,7 +2374,7 @@ class MacroAssembler : public MacroAssem
     template <typename T> inline void addToStackPtr(T t);
     template <typename T> inline void addStackPtrTo(T t);
 
-    void subFromStackPtr(Imm32 imm32) DEFINED_ON(mips32, mips64, arm, x86, x64);
+    void subFromStackPtr(Imm32 imm32) DEFINED_ON(mips32, mips64, loongarch64, arm, x86, x64);
     void subFromStackPtr(Register reg);
 
     template <typename T>
--- mozjs60-60.2.3.orig/mfbt/double-conversion/double-conversion/utils.h
+++ mozjs60-60.2.3/mfbt/double-conversion/double-conversion/utils.h
@@ -70,7 +70,7 @@ inline void abort_noreturn() { MOZ_CRASH
 #if defined(_M_X64) || defined(__x86_64__) || \
     defined(__ARMEL__) || defined(__avr32__) || \
     defined(__hppa__) || defined(__ia64__) || \
-    defined(__mips__) || \
+    defined(__mips__) || defined(__loongarch__) || defined(__loongarch64) || \
     defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
     defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
     defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
--- mozjs60-60.2.3.orig/mfbt/tests/TestPoisonArea.cpp
+++ mozjs60-60.2.3/mfbt/tests/TestPoisonArea.cpp
@@ -145,6 +145,9 @@
 #elif defined __mips
 #define RETURN_INSTR 0x03e00008 /* jr ra */
 
+#elif defined __loongarch64
+#define RETURN_INSTR 0x03e00008 /* jr ra */
+
 #ifdef __MIPSEL
 /* On mipsel, jr ra needs to be followed by a nop.
    0x03e00008 as a 64 bits integer just does that */
--- mozjs60-60.2.3.orig/nsprpub/build/autoconf/config.sub
+++ mozjs60-60.2.3/nsprpub/build/autoconf/config.sub
@@ -269,6 +269,7 @@ case $basic_machine in
 	| mips | mipsbe | mipseb | mipsel | mipsle \
 	| mips16 \
 	| mips64 | mips64el \
+	| loongarch64 | loongarch \
 	| mips64octeon | mips64octeonel \
 	| mips64orion | mips64orionel \
 	| mips64r5900 | mips64r5900el \
@@ -388,6 +389,7 @@ case $basic_machine in
 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
 	| mips16-* \
 	| mips64-* | mips64el-* \
+	| loongarch64-* | loongarch-* \
 	| mips64octeon-* | mips64octeonel-* \
 	| mips64orion-* | mips64orionel-* \
 	| mips64r5900-* | mips64r5900el-* \
--- mozjs60-60.2.3.orig/nsprpub/pr/include/md/_freebsd.cfg
+++ mozjs60-60.2.3/nsprpub/pr/include/md/_freebsd.cfg
@@ -490,6 +490,53 @@
 #define PR_BYTES_PER_WORD_LOG2   3
 #define PR_BYTES_PER_DWORD_LOG2  3
 
+#elif defined(__loongarch__)
+
+#undef  IS_BIG_ENDIAN
+#define IS_LITTLE_ENDIAN 1
+
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
 #elif defined(__mips__)
 
 #if defined(__MIPSEB__) || defined(_MIPSEB)
--- mozjs60-60.2.3.orig/nsprpub/pr/include/md/_linux.cfg
+++ mozjs60-60.2.3/nsprpub/pr/include/md/_linux.cfg
@@ -496,6 +496,56 @@
 #define PR_BYTES_PER_WORD_LOG2   2
 #define PR_BYTES_PER_DWORD_LOG2  3
 
+#elif defined(__loongarch__)
+
+/* For _ABI64 */
+#include <sgidefs.h>
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
 #elif defined(__mips__)
 
 /* For _ABI64 */
--- mozjs60-60.2.3.orig/nsprpub/pr/include/md/_linux.h
+++ mozjs60-60.2.3/nsprpub/pr/include/md/_linux.h
@@ -37,6 +37,8 @@
 #define _PR_SI_ARCHITECTURE "sparc"
 #elif defined(__i386__)
 #define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__loongarch__)
+#define _PR_SI_ARCHITECTURE "loongarch"
 #elif defined(__mips__)
 #define _PR_SI_ARCHITECTURE "mips"
 #elif defined(__arm__)
@@ -67,7 +69,7 @@
 #define _MD_DEFAULT_STACK_SIZE	65536L
 #define _MD_MMAP_FLAGS          MAP_PRIVATE
 
-#if defined(__aarch64__) || defined(__mips__)
+#if defined(__aarch64__) || defined(__mips__) || defined(__loongarch__)
 #define _MD_MINIMUM_STACK_SIZE  0x20000
 #endif
 
@@ -162,6 +164,16 @@ extern PRInt32 _PR_ppc_AtomicSet(PRInt32
 #endif
 #endif
 
+#if defined(__loongarch__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+/* Use GCC built-in functions */
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_INCREMENT(ptr) __sync_add_and_fetch(ptr, 1)
+#define _MD_ATOMIC_DECREMENT(ptr) __sync_sub_and_fetch(ptr, 1)
+#define _MD_ATOMIC_ADD(ptr, i) __sync_add_and_fetch(ptr, i)
+#define _MD_ATOMIC_SET(ptr, nv) __sync_lock_test_and_set(ptr, nv)
+#endif
+
 #if defined(__mips__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
 /* Use GCC built-in functions */
 #define _PR_HAVE_ATOMIC_OPS
@@ -438,6 +450,18 @@ extern void _MD_CleanupBeforeExit(void);
 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
 #define PR_NUM_GCREGS   6
 
+#elif defined(__loongarch__)
+/* Linux/MIPS */
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
+#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__fp = (val))
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[0].__fp)
+#define _MD_SP_TYPE __ptr_t
+#else
+#error "Linux/Loongarch pre-glibc2 not supported yet"
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+
 #elif defined(__mips__)
 /* Linux/MIPS */
 #if defined(__GLIBC__) && __GLIBC__ >= 2
@@ -517,6 +541,19 @@ extern void _MD_CleanupBeforeExit(void);
     _thread->md.sp = _MD_GET_SP_PTR(_thread); \
     _thread->md.fp = _MD_GET_FP_PTR(_thread); \
     _MD_SET_FP(_thread, 0); \
+}
+
+#elif defined(__loongarch__)
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    (void) sigsetjmp(CONTEXT(_thread), 1);  \
+    _thread->md.context[0].__jmpbuf[0].__pc = (__ptr_t) _main;  \
+    _MD_GET_SP(_thread) = (_MD_SP_TYPE) ((_sp) - 64); \
+    _thread->md.sp = _MD_GET_SP_PTR(_thread); \
+    _thread->md.fp = _MD_GET_FP_PTR(_thread); \
+    _MD_SET_FP(_thread, 0); \
 }
 
 #elif defined(__mips__)
--- mozjs60-60.2.3.orig/nsprpub/pr/include/pratom.h
+++ mozjs60-60.2.3/nsprpub/pr/include/pratom.h
@@ -108,6 +108,8 @@ NSPR_API(PRInt32)	PR_AtomicAdd(PRInt32 *
            (defined(__arm__) && \
            defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || \
            defined(__aarch64__) || defined(__alpha) || \
+           (defined(__loongarch__) && \
+           defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || \
            (defined(__mips__) && \
            defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)))))
 
--- mozjs60-60.2.3.orig/python/mozbuild/mozbuild/configure/constants.py
+++ mozjs60-60.2.3/python/mozbuild/mozbuild/configure/constants.py
@@ -48,6 +48,7 @@ CPU_bitness = {
     'ia64': 64,
     'mips32': 32,
     'mips64': 64,
+    'loongarch64': 64,
     'ppc': 32,
     'ppc64': 64,
     's390': 32,
@@ -87,6 +88,7 @@ CPU_preprocessor_checks = OrderedDict((
     ('sparc64', '__sparc__ && __arch64__'),
     ('sparc', '__sparc__'),
     ('mips64', '__mips64'),
+    ('loongarch64', '__loongarch64'),
     ('mips32', '__mips__'),
     ('sh4', '__sh__'),
 ))
