惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
GbyAI
GbyAI
aimingoo的专栏
aimingoo的专栏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
腾讯CDC
博客园 - Franky
Engineering at Meta
Engineering at Meta
C
Check Point Blog
T
The Blog of Author Tim Ferriss
有赞技术团队
有赞技术团队
Microsoft Azure Blog
Microsoft Azure Blog
MyScale Blog
MyScale Blog
I
InfoQ
Blog — PlanetScale
Blog — PlanetScale
P
Proofpoint News Feed
The GitHub Blog
The GitHub Blog
N
Netflix TechBlog - Medium
Last Week in AI
Last Week in AI
S
SegmentFault 最新的问题
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
WordPress大学
WordPress大学

博客园 - 秋·风

修复lazarus datetimepicker控件在linux下拉不能选择日期的bug 用fpc trunk编译lazarus控件找不到TTimeZone 在银河麒麟v10操作系统应用程序执行遇到“权限不够”的提示 修复pl_cindy的Panel系列控件在gtk3出错的bug 龙芯 3A4000工具链的编译(mingw64) lazarus 4.8及之前的版本QT5中文输入多字词组时只输入前2个中文 修正lazarus在GTK3下的Synedit只能输入2个中文字符的Bug lazarus trunk linux从2026.07.02开始,LCLWidgetType默认使用gtk3,怎样改回gtk2 【aarch64-win64】DonAlfredo终于修复fpc将TSmallPoint赋值为一个负数,并将TSmallPoint赋值给TPoint时得到一个655xx的数值的bug lazarus编译时提示链接出错的处理方法 mORMot2两个BUG 【aarch64-win64】发现fpc aarch64-win64 将TSmallPoint赋值为一个负数,并赋值给TPoint时得到一个655xx的数值的bug 修复aarch64 win64下lazarus不弹出SourceTabPopUpMenu fpc aarch64-win64版编译应用时遇到一个奇怪的bug 在windows 11 on arm64系统编译lazarus出错的处理方法 修复TDBMemo只读不能使用Ctrl+C复制文字的Bug freepascal打补丁后已支持windows 11 on arm64(lazarus aarch64 windows版也可以运行了) 查看libc.so.6的版本号 Lazarus移动版启动程序 fpc 3.2.2交叉编译i386-linux链接出错 lazarus鸿蒙开发13:使用鸿蒙原生API画图--lazarus侧关键代码 lazarus鸿蒙开发12:使用鸿蒙原生API画图--鸿蒙侧关键代码 lazarus鸿蒙开发11:使用鸿蒙原生接口画图 lazarus鸿蒙开发10:lazarus一键编译、打包助手 lazarus鸿蒙开发9:使用命令行编译DevEco Studio应用 lazarus鸿蒙开发8:在DevEco Studio的日志窗口显示日志信息 lazarus鸿蒙开发6:鸿蒙project配置 lazarus鸿蒙开发5:编译ohos_hap_project lazarus鸿蒙开发4:编译OHOS_QT_Lazarus lazarus鸿蒙开发3:编译libLazarusOHOS_Wrapper.so
lazarus鸿蒙开发7:在 Windows 上为 OpenHarmony (LoongArch6...
秋·风 · 2026-06-06 · via 博客园 - 秋·风

注:本文是龙芯公司张工分享的。

1. 概述

本文档旨在指导开发者如何在 Windows 操作系统上,为面向 LoongArch64 架构的 OpenHarmony 4.1 (API 11) 系统编译 Qt 5.15.12 版本的软件开发工具包 (SDK)。

  • Qt 版本v5.15.12-lts-lgpl
  • 目标平台: OpenHarmony 4.1 (API 11),兼容 5.0
  • 目标架构loongarch64
  • 编译环境: Windows
  • OpenHarmony Qt 补丁版本Alpha_v6 (或更新版本)

重要提示: OpenHarmony 社区提供的 Alpha_v6 补丁版本仅支持 OpenHarmony API 11(OHOS 4.1), 兼容OpenHarmony API 12(OHOS 5.0),不再兼容早期的 API 9 和 API 10。同时,由于 Qt 5.12.12 版本存在较多问题,已停止维护,请务必使用 Qt 5.15.12。

2. 前置条件:环境准备

在开始编译之前,请确保您的 Windows 系统已安装并配置好以下工具。您可以使用 winget 包管理器快速安装。

打开 PowerShell 或 CMD 窗口,执行以下命令:

# 安装 LLVM-MinGW 工具链 (UCRT 版本),**注意要在环境变量里将其安装的 PATH 移到最前,保证调用的工具链是 LLVM-MinGW**
winget install MartinStorsjo.LLVM-MinGW.UCRT

# 安装 Strawberry Perl
winget install StrawberryPerl.StrawberryPerl

# 安装 Python 3.11
winget install Python.Python.3.11

# 安装 Git
winget install Git.Git

除此之外,您还需要:

  • OpenHarmony SDK: 需要适用于 Windows 的 Native SDK,并解压到指定目录(例如 C:\windows-ohos-sdk)。

  1. 克隆 Qt5 仓库 打开 Git Bash 或 CMD,选择一个工作目录(如 C:\src),然后克隆 Qt5 的官方源码仓库。
    git clone https://github.com/qt/qt5
    cd qt5
  2. 切换到指定版本 切换到 v5.15.12-lts-lgpl 长期支持版。
    git checkout -b v5.15.12-lts-lgpl v5.15.12-lts-lgpl
  3. 初始化子模块 这一步会下载 Qt 依赖的所有子模块,需要一些时间。
    git submodule update --init

步骤二:获取并应用 OpenHarmony 补丁

OpenHarmony SIG 团队提供了适配 Qt 的补丁,需要手动应用到源码中。

  1. 获取补丁文件 补丁文件可以从 OpenHarmony Qt SIG 的 Gitee 仓库获取: https://gitee.com/openharmony-sig/qt/tags

请下载 Alpha_v6 或更高版本的 v5.15.12 对应的补丁包,并解压到本地目录(例如 C:\src\ohos-qt-patches)。

  1. 应用补丁 依次进入需要打补丁的子模块目录,使用 git apply 命令应用补丁。请将 <您的补丁路径> 替换为您实际的补丁文件存放路径。
    # 假设 Qt 源码位于 C:\src\qt5,补丁位于 C:\src\ohos-qt-patches
    # 注意:请根据您的实际路径进行调整
    
    # 1. 为 qtbase 打补丁
    cd C:\src\qt5\qtbase
    git apply C:\src\ohos-qt-patches\patch\v5.15.12\qtbase.patch
    
    # 2. 为 qt3d 打补丁
    cd C:\src\qt5\qt3d
    git apply C:\src\ohos-qt-patches\patch\v5.15.12\qt3d.patch
    
    # 3. 为 qtconnectivity 打补丁
    cd C:\src\qt5\qtconnectivity
    git apply C:\src\ohos-qt-patches\patch\v5.15.12\qtconnectivity.patch
    
    # 4. 为 qtdeclarative 打补丁
    cd C:\src\qt5\qtdeclarative
    git apply C:\src\ohos-qt-patches\patch\v5.15.12\qtdeclarative.patch
    
    # 5. 为 qtmultimedia 打补丁
    cd C:\src\qt5\qtmultimedia
    git apply C:\src\ohos-qt-patches\patch\v5.15.12\qtmultimedia.patch
    
    # 6. 为 qtquickcontrols 打补丁
    cd C:\src\qt5\qtquickcontrols
    git apply C:\src\ohos-qt-patches\patch\v5.15.12\qtquickcontrols.patch
    
    # 7. 为 qtsensors 打补丁
    cd C:\src\qt5\qtsensors
    git apply C:\src\ohos-qt-patches\patch\v5.15.12\qtsensors.patch
    
    # 8. 为 qtwebview 打补丁
    cd C:\src\qt5\qtwebview
    git apply C:\src\ohos-qt-patches\patch\v5.15.12\qtwebview.patch

应用完所有补丁后,返回 qt5 根目录。

  1. 添加 LoongArch 架构支持
diff --git a/mkspecs/common/oh-base-head.conf b/mkspecs/common/oh-base-head.conf
index d7be2121374..bb4a955e31e 100644
--- a/mkspecs/common/oh-base-head.conf
+++ b/mkspecs/common/oh-base-head.conf
@@ -6,6 +6,7 @@ isEmpty(NDK_TOOLCHAIN_PREFIX) {
     equals(OHOS_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-ohos
     else: equals(OHOS_ARCH, armeabi-v7a): NDK_TOOLCHAIN_PREFIX = arm-linux-ohos
     else: equals(OHOS_ARCH, x86_64): NDK_TOOLCHAIN_PREFIX = x86_64-linux-ohos
+    else: equals(OHOS_ARCH, loongarch64): NDK_TOOLCHAIN_PREFIX = loongarch64-linux-ohos
     else: NDK_TOOLCHAIN_PREFIX = arm-linux-ohos
 }
 
diff --git a/mkspecs/common/oh-base-tail.conf b/mkspecs/common/oh-base-tail.conf
index 4039af1e790..1f43ed9b507 100644
--- a/mkspecs/common/oh-base-tail.conf
+++ b/mkspecs/common/oh-base-tail.conf
@@ -4,6 +4,8 @@ else: equals(OHOS_ARCH, arm64-v8a): \
     QMAKE_CFLAGS += -march=armv8a -msoft-float -mfpu=vfp -fno-builtin-memmove
 else: equals(OHOS_ARCH, x86_64): \
     QMAKE_CFLAGS += -march=x86_64
+else: equals(OHOS_ARCH, loongarch64): \
+    QMAKE_CFLAGS += -march=loongarch64
 else: \
     QMAKE_CFLAGS += -march=armv7a -msoft-float -mfpu=vfp -fno-builtin-memmove
 
diff --git a/mkspecs/oh-clang/qmake.conf b/mkspecs/oh-clang/qmake.conf
index 5bfd38b4f5c..57a1f859b7a 100644
--- a/mkspecs/oh-clang/qmake.conf
+++ b/mkspecs/oh-clang/qmake.conf
@@ -20,6 +20,8 @@ else:equals(OHOS_ARCH,arm64-v8a): \
         QMAKE_CFLAGS += -target aarch64-linux-ohos
 else:equals(OHOS_ARCH,x86-64): \
         QMAKE_CFLAGS += -target x86_64-linux-ohos
+else:equals(OHOS_ARCH,loongarch64): \
+        QMAKE_CFLAGS += -target loongarch64-linux-ohos
 
 #QMAKE_CFLAGS+=--gcc-toolchain=$$NDK_LLVM_PATH
 QMAKE_LINK += -Wl,--exclude-libs,$$shell_path($$SDK_ROOT/native/llvm/lib/$$NDK_TOOLCHAIN_PREFIX/libunwind.a)
diff --git a/src/3rdparty/double-conversion/include/double-conversion/utils.h b/src/3rdparty/double-conversion/include/double-conversion/utils.h
index 70e697ca005..46293d3d58b 100644
--- a/src/3rdparty/double-conversion/include/double-conversion/utils.h
+++ b/src/3rdparty/double-conversion/include/double-conversion/utils.h
@@ -101,6 +101,7 @@ int main(int argc, char** argv) {
     defined(_MIPS_ARCH_MIPS32R2) || defined(__ARMEB__) ||\
     defined(__AARCH64EL__) || defined(__aarch64__) || defined(__AARCH64EB__) || \
     defined(__riscv) || \
+    defined(__loongarch64) || \
     defined(__or1k__) || defined(__arc__) || \
     defined(__EMSCRIPTEN__)
 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
diff --git a/src/corelib/global/archdetect.cpp b/src/corelib/global/archdetect.cpp
index 1d00b7f5a52..cbea45ee480 100644
--- a/src/corelib/global/archdetect.cpp
+++ b/src/corelib/global/archdetect.cpp
@@ -83,6 +83,8 @@
 #  define ARCH_PROCESSOR "sparcv9"
 #elif defined(Q_PROCESSOR_SPARC)
 #  define ARCH_PROCESSOR "sparc"
+#elif defined(Q_PROCESSOR_LOONGARCH_64)
+#  define ARCH_PROCESSOR "loongarch64"
 #else
 #  define ARCH_PROCESSOR "unknown"
 #endif
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h
index 8d657208503..a9f41381513 100644
--- a/src/corelib/global/qprocessordetection.h
+++ b/src/corelib/global/qprocessordetection.h
@@ -223,6 +223,20 @@
 #  define Q_PROCESSOR_WORDSIZE   8
 // Q_BYTE_ORDER not defined, use endianness auto-detection
 
+/*
+    LoongArch family
+
+    LoongArch is bi-endian, use endianness auto-detection implemented below.
+*/
+#elif defined(__loongarch__)
+#  define Q_PROCESSOR_LOONGARCH
+#  if __loongarch_grlen == 64
+#    define Q_PROCESSOR_LOONGARCH_64
+#  else
+#    define Q_PROCESSOR_LOONGARCH_32
+#  endif
+#  define Q_BYTE_ORDER Q_LITTLE_ENDIAN
+
 /*
     MIPS family, known revisions: I, II, III, IV, 32, 64
 
diff --git a/src/plugins/platforms/openharmony/qopenharmonymain.cpp b/src/plugins/platforms/openharmony/qopenharmonymain.cpp
index 18becb238fc..9d3b44ee5c4 100644
--- a/src/plugins/platforms/openharmony/qopenharmonymain.cpp
+++ b/src/plugins/platforms/openharmony/qopenharmonymain.cpp
@@ -112,6 +112,8 @@ static napi_value startQtApplication(napi_env env, napi_callback_info info)
     QByteArray libDir = bundle + "/libs/arm64";
 #elif defined(Q_PROCESSOR_ARM_32)
     QByteArray libDir = bundle + "/libs/arm";
+#elif defined(Q_PROCESSOR_LOONGARCH_64)
+    QByteArray libDir = bundle + "/libs/loongarch64";
 #endif
 
     QByteArrayList qmls = {bundle + "/entry/resources/rawfile"};

保存上述 diff 为 loongarch_support.patch

cd C:\src\qt5\qtbase
git apply loongarch_support.patch
  1. 添加 LSX 和 LASX 向量支持
diff --git a/configure.json b/configure.json
index 4763ff645f0..e6f85f9199a 100644
--- a/configure.json
+++ b/configure.json
@@ -96,6 +96,9 @@
             "ltcg": "boolean",
             "make": { "type": "addString", "values": [ "examples", "libs", "tests", "tools" ] },
             "make-tool": "string",
+
+            "lsx": "boolean",
+            "lasx": "boolean",
             "mips_dsp": "boolean",
             "mips_dspr2": "boolean",
             "mp": { "type": "boolean", "name": "msvc_mp" },
@@ -607,6 +610,14 @@
             "type": "x86SimdAlways",
             "test": "x86_simd"
         },
+        "lsx": {
+            "label": "LSX instructions",
+            "type": "LoongArchSimd"
+        },
+        "lasx": {
+            "label": "LASX instructions",
+            "type": "LoongArchSimd"
+        },
         "posix_fallocate": {
             "label": "POSIX fallocate()",
             "type": "compile",
@@ -1082,6 +1093,22 @@
             "condition": "tests.signaling_nan",
             "output": [ "publicFeature" ]
         },
+        "lsx": {
+            "label": "LSX",
+            "condition": "(arch.loongarch64 || arch.loongarch) && tests.lsx",
+            "output": [
+                "privateConfig",
+                { "type": "define", "name": "QT_COMPILER_SUPPORTS_LSX", "value": 1 }
+            ]
+        },
+        "lasx": {
+            "label": "LASX",
+            "condition": "(arch.loongarch64 || arch.loongarch) && tests.lasx",
+            "output": [
+                "privateConfig",
+                { "type": "define", "name": "QT_COMPILER_SUPPORTS_LASX", "value": 1 }
+            ]
+        },
         "sse2": {
             "label": "SSE2",
             "condition": "(arch.i386 || arch.x86_64) && tests.sse2",
@@ -1646,7 +1673,18 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5
                             "type": "feature",
                             "args": "mips_dspr2",
                             "condition": "arch.mips"
+                        },
+                        {
+                            "type": "feature",
+                            "args": "lsx",
+                            "condition": "arch.loongarch || arch.loongarch64"
+                        },
+                        {
+                            "type": "feature",
+                            "args": "lasx",
+                            "condition": "arch.loongarch || arch.loongarch64"
                         }
+
                     ]
                 },
                 {
diff --git a/configure.pri b/configure.pri
index 365a16403eb..fe86fe458cf 100644
--- a/configure.pri
+++ b/configure.pri
@@ -445,6 +445,13 @@ defineTest(qtConfTest_x86Simd) {
     qtConfTest_compile($${1})
 }
 
+defineTest(qtConfTest_LoongArchSimd) {
+    simd = $$section(1, ".", -1)    # last component
+    $${1}.args = CONFIG+=add_cflags DEFINES+=NO_ATTRIBUTE SIMD=$$simd
+    $${1}.test = loongarch_simd
+    qtConfTest_compile($${1})
+}
+
 defineTest(qtConfTest_x86SimdAlways) {
     configs =
     fpfx = $${currentConfig}.features
diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf
index fa65c1dd371..84b8d4852dd 100644
--- a/mkspecs/common/gcc-base.conf
+++ b/mkspecs/common/gcc-base.conf
@@ -119,6 +119,8 @@ QMAKE_CFLAGS_VAES      += -mvaes
 QMAKE_CFLAGS_NEON      += -mfpu=neon
 QMAKE_CFLAGS_MIPS_DSP  += -mdsp
 QMAKE_CFLAGS_MIPS_DSPR2 += -mdspr2
+QMAKE_CFLAGS_LSX  += -mlsx
+QMAKE_CFLAGS_LASX += -mlasx
 
 # -march=haswell is supported as of GCC 4.9 and Clang 3.6
 QMAKE_CFLAGS_ARCH_HASWELL           = -march=core-avx2
diff --git a/mkspecs/features/simd.prf b/mkspecs/features/simd.prf
index 8e041297d2f..a825fdd4a6f 100644
--- a/mkspecs/features/simd.prf
+++ b/mkspecs/features/simd.prf
@@ -146,6 +146,8 @@ addSimdCompiler(rdseed)
 addSimdCompiler(neon)
 addSimdCompiler(mips_dsp)
 addSimdCompiler(mips_dspr2)
+addSimdCompiler(lsx)
+addSimdCompiler(lasx)
 
 # Haswell sub-architecture
 defineTest(addSimdArch) {
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index 798ac93ad24..c016fa5bec8 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -109,6 +109,19 @@ static const char features_string[] =
     " dspr2\0"
     "\0";
 
+static const int features_indices[] = {
+       0,    5
+};
+#elif defined(Q_PROCESSOR_LOONGARCH)
+/* Data:
+ lsx
+ lasx
+*/
+static const char features_string[] =
+    " lsx\0"
+    " lasx\0"
+    "\0";
+
 static const int features_indices[] = {
        0,    5
 };
@@ -183,6 +196,28 @@ static inline quint64 detectProcessorFeatures()
     return features;
 }
 
+#elif defined(Q_PROCESSOR_LOONGARCH)
+/* have to supply these defines for glibc 2.37- and musl */
+#ifndef HWCAP_LOONGARCH_LSX
+#define HWCAP_LOONGARCH_LSX	(1 << 4)
+#endif
+#ifndef HWCAP_LOONGARCH_LASX
+#define HWCAP_LOONGARCH_LASX	(1 << 5)
+#endif
+
+    #include <sys/auxv.h>
+static inline quint64 detectProcessorFeatures()
+{
+    quint64 features = 0;
+    quint64 hwcap = getauxval(AT_HWCAP);
+
+    if (hwcap & HWCAP_LOONGARCH_LSX)
+        features |= CpuFeatureLSX;
+    if (hwcap & HWCAP_LOONGARCH_LASX)
+        features |= CpuFeatureLASX;
+    return features;
+}
+
 #elif defined(Q_PROCESSOR_X86)
 
 #ifdef Q_PROCESSOR_X86_32
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index 26e98c45423..7ad2b200076 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -164,6 +164,16 @@
 #  if !defined(__MIPS_DSPR2__) && defined(__mips_dspr2) && defined(Q_PROCESSOR_MIPS_32)
 #    define __MIPS_DSPR2__
 #  endif
+#elif defined(Q_PROCESSOR_LOONGARCH)
+#  define QT_COMPILER_SUPPORTS_HERE(x)    QT_COMPILER_SUPPORTS(x)
+#  if defined(Q_CC_GNU)
+     /* GCC requires attributes for a function */
+#    define QT_FUNCTION_TARGET_STRING_lsx      "lsx"
+#    define QT_FUNCTION_TARGET_STRING_lasx     "lasx"
+#    define QT_FUNCTION_TARGET(x)  __attribute__((__target__(QT_FUNCTION_TARGET_STRING_ ## x)))
+#  else
+#    define QT_FUNCTION_TARGET(x)
+#  endif
 #elif defined(Q_PROCESSOR_X86) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)
 #  define QT_COMPILER_SUPPORTS_HERE(x)    ((__ ## x ## __) || QT_COMPILER_SUPPORTS(x))
 #  if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
@@ -177,6 +187,16 @@
 #  define QT_FUNCTION_TARGET(x)
 #endif
 
+/* -- loongarch64 intrinsic support -- */
+#ifdef __loongarch_asx
+// #include the intrinsics
+#  include<lsxintrin.h>
+#  include<lasxintrin.h>
+#elif defined __loongarch_sx
+// #include the intrinsics
+#  include<lsxintrin.h>
+#endif
+
 #ifdef Q_PROCESSOR_X86
 /* -- x86 intrinsic support -- */
 
@@ -317,6 +337,9 @@ enum CPUFeatures {
 #elif defined(Q_PROCESSOR_MIPS)
     CpuFeatureDSP           = 2,
     CpuFeatureDSPR2         = 4,
+#elif defined(Q_PROCESSOR_LOONGARCH)
+    CpuFeatureLSX           = 2,
+    CpuFeatureLASX          = 4,
 #endif
 
     // used only to indicate that the CPU detection was initialised
@@ -335,6 +358,12 @@ static const quint64 qCompilerCpuFeatures = 0
 #endif
 #if defined __mips_dspr2
         | CpuFeatureDSPR2
+#endif
+#if defined __loongarch_sx
+        | CpuFeatureLSX
+#endif
+#if defined __loongarch_asx
+        | CpuFeatureLASX
 #endif
         ;
 #endif
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index 01e48c17ddd..ed9a1a19c2b 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -92,6 +92,8 @@ qtConfig(png) {
 # SIMD
 !android {
     SSSE3_SOURCES += image/qimage_ssse3.cpp
+    LSX_SOURCES += image/qimage_lsx.cpp
+    LASX_SOURCES += image/qimage_lasx.cpp
     NEON_SOURCES += image/qimage_neon.cpp
     MIPS_DSPR2_SOURCES += image/qimage_mips_dspr2.cpp
     MIPS_DSPR2_ASM += image/qimage_mips_dspr2_asm.S
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 9257ab8cfeb..a0ae270cd10 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -162,6 +162,9 @@ extern void QT_FASTCALL storeRGB32FromARGB32PM_sse4(uchar *dest, const uint *src
 #elif defined(__ARM_NEON__) && (Q_BYTE_ORDER == Q_LITTLE_ENDIAN)
 extern void QT_FASTCALL storeRGB32FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count,
                                                     const QVector<QRgb> *, QDitherInfo *);
+#elif defined QT_COMPILER_SUPPORTS_LSX
+extern void QT_FASTCALL storeRGB32FromARGB32PM_lsx(uchar *dest, const uint *src, int index, int count,
+                                                   const QVector<QRgb> *, QDitherInfo *);
 #endif
 
 void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
@@ -187,6 +190,11 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
                 store = storeRGB32FromARGB32PM_sse4;
             else
                 store = storeRGB32FromARGB32PM;
+#elif defined QT_COMPILER_SUPPORTS_LSX
+            if (qCpuHasFeature(LSX))
+                store = storeRGB32FromARGB32PM_lsx;
+            else
+                store = storeRGB32FromARGB32PM;
 #elif defined(__ARM_NEON__) && (Q_BYTE_ORDER == Q_LITTLE_ENDIAN)
             store = storeRGB32FromARGB32PM_neon;
 #else
@@ -351,6 +359,11 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im
                 store = storeRGB32FromARGB32PM_sse4;
             else
                 store = storeRGB32FromARGB32PM;
+#elif defined QT_COMPILER_SUPPORTS_LSX
+            if (qCpuHasFeature(LSX))
+                store = storeRGB32FromARGB32PM_lsx;
+            else
+                store = storeRGB32FromARGB32PM;
 #elif defined(__ARM_NEON__) && (Q_BYTE_ORDER == Q_LITTLE_ENDIAN)
             store = storeRGB32FromARGB32PM_neon;
 #else
@@ -2416,6 +2429,28 @@ static void qInitImageConversions()
     }
 #endif
 
+#if defined(QT_COMPILER_SUPPORTS_LASX)
+    if (qCpuHasFeature(LASX)) {
+        extern void convert_RGB888_to_RGB32_lasx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+        qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_lasx;
+        qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_lasx;
+        qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_lasx;
+        qimage_converter_map[QImage::Format_BGR888][QImage::Format_RGBX8888] = convert_RGB888_to_RGB32_lasx;
+        qimage_converter_map[QImage::Format_BGR888][QImage::Format_RGBA8888] = convert_RGB888_to_RGB32_lasx;
+        qimage_converter_map[QImage::Format_BGR888][QImage::Format_RGBA8888_Premultiplied] = convert_RGB888_to_RGB32_lasx;
+    }
+#elif defined(QT_COMPILER_SUPPORTS_LSX)
+    if (qCpuHasFeature(LSX)) {
+        extern void convert_RGB888_to_RGB32_lsx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+        qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_lsx;
+        qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_lsx;
+        qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_lsx;
+        qimage_converter_map[QImage::Format_BGR888][QImage::Format_RGBX8888] = convert_RGB888_to_RGB32_lsx;
+        qimage_converter_map[QImage::Format_BGR888][QImage::Format_RGBA8888] = convert_RGB888_to_RGB32_lsx;
+        qimage_converter_map[QImage::Format_BGR888][QImage::Format_RGBA8888_Premultiplied] = convert_RGB888_to_RGB32_lsx;
+    }
+#endif
+
 #if defined(__ARM_NEON__)
     extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
     qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index b272377fb2e..683262cd152 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -365,7 +365,7 @@ inline QImage::Format qt_opaqueVersionForPainting(QImage::Format format)
 inline QImage::Format qt_alphaVersionForPainting(QImage::Format format)
 {
     QImage::Format toFormat = qt_alphaVersion(format);
-#if defined(__ARM_NEON__) || defined(__SSE2__)
+#if defined(__ARM_NEON__) || defined(__SSE2__) || defined(QT_COMPILE_SUPPORTS_LSX)
     // If we are switching depth anyway and we have optimized ARGB32PM routines, upgrade to that.
     if (qt_depthForFormat(format) != qt_depthForFormat(toFormat) && qt_depthForFormat(toFormat) <= 32)
         toFormat = QImage::Format_ARGB32_Premultiplied;
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index bb0fc0ffbae..2be984edb12 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -21,7 +21,9 @@ HEADERS += \
         painting/qdatabuffer_p.h \
         painting/qdrawhelper_p.h \
         painting/qdrawhelper_x86_p.h \
+        painting/qdrawhelper_loongarch64_p.h \
         painting/qdrawingprimitive_sse2_p.h \
+        painting/qdrawingprimitive_lsx_p.h \
         painting/qemulationpaintengine_p.h \
         painting/qfixed_p.h \
         painting/qgrayraster_p.h \
@@ -135,6 +137,10 @@ gcc:equals(QT_GCC_MAJOR_VERSION, 5) {
     NO_PCH_SOURCES += painting/qdrawhelper.cpp
 }
 
+lsx{
+    QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_LSX
+}
+
 !android {
     SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
     SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
@@ -142,6 +148,10 @@ gcc:equals(QT_GCC_MAJOR_VERSION, 5) {
                       painting/qimagescale_sse4.cpp
     ARCH_HASWELL_SOURCES += painting/qdrawhelper_avx2.cpp
 
+    LSX_SOURCES += painting/qdrawhelper_lsx.cpp \
+                   painting/qimagescale_lsx.cpp
+    LASX_SOURCES += painting/qdrawhelper_lasx.cpp
+
     NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
     NEON_HEADERS += painting/qdrawhelper_neon_p.h
 }
diff --git a/src/gui/painting/qcompositionfunctions.cpp b/src/gui/painting/qcompositionfunctions.cpp
index aa3f1489342..a94b5c4c261 100644
--- a/src/gui/painting/qcompositionfunctions.cpp
+++ b/src/gui/painting/qcompositionfunctions.cpp
@@ -247,6 +247,73 @@ struct Rgba64OperationsSSE2 : public Rgba64OperationsBase
 };
 #endif
 
+#if defined(__loongarch_sx)
+struct Rgba64OperationsLSX : public Rgba64OperationsBase
+{
+    typedef __m128i OptimalType;
+    typedef __m128i OptimalScalar;
+    static OptimalType load(const Type *ptr)
+    {
+        return __lsx_vilvl_d(__lsx_vldi(0), __lsx_vldrepl_d(ptr, 0));
+    }
+    static OptimalType convert(const Type &value)
+    {
+        return __lsx_vinsgr2vr_d(__lsx_vldi(0), value, 0);
+    }
+    static void store(Type *ptr, OptimalType value)
+    {
+        __lsx_vstelm_d(value, ptr, 0, 0);
+    }
+    static OptimalType add(OptimalType a, OptimalType b)
+    {
+        return __lsx_vadd_h(a, b);
+    }
+//    same as above:
+//    static OptimalScalar add(OptimalScalar a, OptimalScalar b)
+    static OptimalType plus(OptimalType a, OptimalType b)
+    {
+        return __lsx_vsadd_hu(a, b);
+    }
+    static OptimalScalar alpha(OptimalType c)
+    {
+        const __m128i shuffleMask = (__m128i)(v8i16){3, 3, 3, 3, 4, 5, 6, 7};
+        return __lsx_vshuf_h(shuffleMask, __lsx_vldi(0), c);
+    }
+    static OptimalScalar invAlpha(Scalar c)
+    {
+        return scalar(65535 - c);
+    }
+    static OptimalScalar invAlpha(OptimalType c)
+    {
+        return __lsx_vxor_v(__lsx_vreplgr2vr_h(-1), alpha(c));
+    }
+    static OptimalScalar scalar(Scalar n)
+    {
+        const __m128i shuffleMask = (__m128i)(v8i16){0, 0, 0, 0, 4, 5, 6, 7};
+        return __lsx_vshuf_h(shuffleMask, __lsx_vldi(0), __lsx_vinsgr2vr_w(__lsx_vldi(0), n, 0));
+    }
+    static OptimalType multiplyAlpha8bit(OptimalType val, uint8_t a)
+    {
+        return multiplyAlpha255(val, a);
+    }
+//    same as above:
+//    static OptimalScalar multiplyAlpha8bit(OptimalScalar a, uint8_t a)
+    static OptimalType interpolate8bit(OptimalType x, uint8_t a1, OptimalType y, uint8_t a2)
+    {
+        return interpolate255(x, a1, y, a2);
+    }
+    static OptimalType multiplyAlpha(OptimalType val, OptimalScalar a)
+    {
+        return multiplyAlpha65535(val, a);
+    }
+    static OptimalType interpolate(OptimalType x, OptimalScalar a1, OptimalType y, const OptimalScalar &a2)
+    {
+        return interpolate65535(x, a1, y, a2);
+    }
+};
+#endif
+
+
 #if defined(__ARM_NEON__)
 struct Rgba64OperationsNEON : public Rgba64OperationsBase
 {
@@ -314,6 +381,8 @@ struct Rgba64OperationsNEON : public Rgba64OperationsBase
 
 #if defined(__SSE2__)
 typedef Rgba64OperationsSSE2 Rgba64Operations;
+#elif defined(__loongarch_sx)
+typedef Rgba64OperationsLSX Rgba64Operations;
 #elif defined(__ARM_NEON__)
 typedef Rgba64OperationsNEON Rgba64Operations;
 #else
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index a61793508ac..2d993cab1b7 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -37,7 +37,6 @@
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
-
 #include <qglobal.h>
 
 #include <qstylehints.h>
@@ -48,6 +47,8 @@
 #include <private/qpaintengine_raster_p.h>
 #include <private/qpainter_p.h>
 #include <private/qdrawhelper_x86_p.h>
+#include <private/qdrawhelper_loongarch64_p.h>
+#include <private/qdrawingprimitive_lsx_p.h>
 #include <private/qdrawingprimitive_sse2_p.h>
 #include <private/qdrawhelper_neon_p.h>
 #if defined(QT_COMPILER_SUPPORTS_MIPS_DSP) || defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2)
@@ -354,6 +355,8 @@ static void QT_FASTCALL convertToRGB32(uint *buffer, int count, const QVector<QR
 
 #if defined(__SSE2__) && !defined(__SSSE3__) && QT_COMPILER_SUPPORTS_SSSE3
 extern const uint * QT_FASTCALL fetchPixelsBPP24_ssse3(uint *dest, const uchar*src, int index, int count);
+#elif defined QT_COMPILER_SUPPORTS_LSX
+extern const uint * QT_FASTCALL fetchPixelsBPP24_lsx(uint *dest, const uchar*src, int index, int count);
 #endif
 
 template<QImage::Format Format>
@@ -369,6 +372,12 @@ static const uint *QT_FASTCALL fetchRGBToRGB32(uint *buffer, const uchar *src, i
         convertToRGB32<Format>(buffer, count, nullptr);
         return buffer;
     }
+#elif defined QT_COMPILER_SUPPORTS_LSX
+    if (BPP == QPixelLayout::BPP24 && qCpuHasFeature(LSX)) {
+        fetchPixelsBPP24_lsx(buffer, src, index, count);
+        convertToRGB32<Format>(buffer, count, nullptr);
+        return buffer;
+    }
 #endif
     for (int i = 0; i < count; ++i)
         buffer[i] = convertPixelToRGB32<Format>(fetchPixel<BPP>(src, index + i));
@@ -460,6 +469,12 @@ static const uint *QT_FASTCALL fetchARGBPMToARGB32PM(uint *buffer, const uchar *
         convertARGBPMToARGB32PM<Format>(buffer, count, nullptr);
         return buffer;
     }
+#elif defined QT_COMPILER_SUPPORTS_LSX
+    if (BPP == QPixelLayout::BPP24 && qCpuHasFeature(LSX)) {
+        fetchPixelsBPP24_lsx(buffer, src, index, count);
+        convertARGBPMToARGB32PM<Format>(buffer, count, nullptr);
+        return buffer;
+    }
 #endif
     for (int i = 0; i < count; ++i)
         buffer[i] = convertPixelToARGB32PM<Format>(fetchPixel<BPP>(src, index + i));
@@ -1021,6 +1036,110 @@ static inline void qConvertRGBA64PMToA2RGB30PM_sse2(uint *dest, const QRgba64 *b
     SIMD_EPILOGUE(i, count, 15)
         *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
 }
+
+#elif defined __loongarch_sx
+template<bool RGBA, bool maskAlpha>
+static inline void qConvertARGB32PMToRGBA64PM_lsx(QRgba64 *buffer, const uint *src, int count)
+{
+    if (count <= 0)
+        return;
+
+    const __m128i amask = __lsx_vreplgr2vr_w(0xff000000);
+    const __m128i shuffleMask = (__m128i)(v8i16){2, 1, 0, 3, 6, 5, 4, 7};
+    int i = 0;
+    for (; ((uintptr_t)buffer & 0xf) && i < count; ++i) {
+        uint s = *src++;
+        if (maskAlpha)
+            s = s | 0xff000000;
+        if (RGBA)
+            s = RGBA2ARGB(s);
+        *buffer++ = QRgba64::fromArgb32(s);
+    }
+    for (; i < count-3; i += 4) {
+        __m128i vs = __lsx_vld((const __m128i*)src, 0);
+        if (maskAlpha)
+            vs = __lsx_vor_v(vs, amask);
+        src += 4;
+        __m128i v1 = __lsx_vilvl_b(vs, vs);
+        __m128i v2 = __lsx_vilvh_b(vs, vs);
+        if (!RGBA) {
+            v1 = __lsx_vshuf_h(shuffleMask, v1, v1);
+            v2 = __lsx_vshuf_h(shuffleMask, v2, v2);
+        }
+        __lsx_vst(v1, buffer, 0);
+        buffer += 2;
+        __lsx_vst(v2, buffer, 0);
+        buffer += 2;
+    }
+
+    SIMD_EPILOGUE(i, count, 3) {
+        uint s = *src++;
+        if (maskAlpha)
+            s = s | 0xff000000;
+        if (RGBA)
+            s = RGBA2ARGB(s);
+        *buffer++ = QRgba64::fromArgb32(s);
+    }
+}
+
+template<QtPixelOrder PixelOrder>
+static inline void qConvertRGBA64PMToA2RGB30PM_lsx(uint *dest, const QRgba64 *buffer, int count)
+{
+    const __m128i gmask = __lsx_vreplgr2vr_w(0x000ffc00);
+    const __m128i cmask = __lsx_vreplgr2vr_w(0x000003ff);
+    int i = 0;
+    __m128i vr, vg, vb, va;
+    for (; i < count && uintptr_t(buffer) & 0xF; ++i) {
+        *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
+    }
+
+    for (; i < count-15; i += 16) {
+        __m128i vOr = __lsx_vreplgr2vr_w(0);
+        __m128i vAnd = __lsx_vreplgr2vr_w(0xffffffff);
+        for (int j = 0; j < 16; j += 2) {
+            __m128i vs = __lsx_vld((const __m128i*)(buffer + j), 0);
+            vOr = __lsx_vor_v(vOr, vs);
+            vAnd = __lsx_vand_v(vAnd, vs);
+        }
+        const quint16 orAlpha = ((uint)__lsx_vpickve2gr_h(vOr, 3)) | ((uint)__lsx_vpickve2gr_h(vOr, 7));
+        const quint16 andAlpha = ((uint)__lsx_vpickve2gr_h(vAnd, 3)) & ((uint)__lsx_vpickve2gr_h(vAnd, 7));
+
+        if (andAlpha == 0xffff) {
+            for (int j = 0; j < 16; j += 2) {
+                __m128i vs = __lsx_vld((const __m128i*)buffer, 0);
+                buffer += 2;
+                vr = __lsx_vsrli_d(vs, 6);
+                vg = __lsx_vsrli_d(vs, 16 + 6 - 10);
+                vb = __lsx_vsrli_d(vs, 32 + 6);
+                vr = __lsx_vand_v(vr, cmask);
+                vg = __lsx_vand_v(vg, gmask);
+                vb = __lsx_vand_v(vb, cmask);
+                va = __lsx_vsrli_d(vs, 48 + 14);
+                if (PixelOrder == PixelOrderRGB)
+                    vr = __lsx_vslli_w(vr, 20);
+                else
+                    vb = __lsx_vslli_w(vb, 20);
+                va = __lsx_vslli_w(va, 30);
+                __m128i vd = __lsx_vor_v(__lsx_vor_v(vr, vg), __lsx_vor_v(vb, va));
+                vd = __lsx_vshuf4i_w(vd, 0b11011000);
+                __lsx_vstelm_d(vd, dest, 0, 0);
+                dest += 2;
+            }
+        } else if (orAlpha == 0) {
+            for (int j = 0; j < 16; ++j) {
+                *dest++ = 0;
+                buffer++;
+            }
+        } else {
+            for (int j = 0; j < 16; ++j)
+                *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
+        }
+    }
+
+    SIMD_EPILOGUE(i, count, 15)
+        *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
+}
+
 #elif defined(__ARM_NEON__)
 template<bool RGBA, bool maskAlpha>
 static inline void qConvertARGB32PMToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count)
@@ -1070,11 +1189,72 @@ static inline void qConvertARGB32PMToRGBA64PM_neon(QRgba64 *buffer, const uint *
 }
 #endif
 
+#if defined __loongarch_asx
+template<bool RGBA, bool maskAlpha>
+static inline void qConvertARGB32PMToRGBA64PM_lasx(QRgba64 *buffer, const uint *src, int count)
+{
+    if (count <= 0)
+        return;
+    const __m256i amask = __lasx_xvreplgr2vr_w(0xff000000);
+    const __m256i shuffleMask = (__m256i)(v16i16){2, 1, 0, 3, 6, 5, 4, 7, 2, 1, 0, 3, 6, 5, 4, 7};
+    int i = 0;
+    for (; ((uintptr_t)buffer & 0xf) && i < count; ++i) {
+        uint s = *src++;
+        if (maskAlpha)
+            s = s | 0xff000000;
+        if (RGBA)
+            s = RGBA2ARGB(s);
+        *buffer++ = QRgba64::fromArgb32(s);
+    }
+    for (; i < count-7; i += 8) {
+        __m256i vs = __lasx_xvld((const __m256i*)src, 0);
+        if (maskAlpha)
+            vs = __lasx_xvor_v(vs, amask);
+        src += 8;
+        __m256i v1 = __lasx_xvilvl_b(vs, vs);
+        __m256i v2 = __lasx_xvilvh_b(vs, vs);
+        if (!RGBA) {
+            v1 = __lasx_xvshuf_h(shuffleMask, v1, v1);
+            v2 = __lasx_xvshuf_h(shuffleMask, v2, v2);
+        }
+        __lasx_xvstelm_d(v1, buffer, 0, 0);
+        buffer ++;
+        __lasx_xvstelm_d(v1, buffer, 0, 1);
+        buffer ++;
+        __lasx_xvstelm_d(v2, buffer, 0, 0);
+        buffer ++;
+        __lasx_xvstelm_d(v2, buffer, 0, 1);
+        buffer ++;
+        __lasx_xvstelm_d(v1, buffer, 0, 2);
+        buffer ++;
+        __lasx_xvstelm_d(v1, buffer, 0, 3);
+        buffer ++;
+        __lasx_xvstelm_d(v2, buffer, 0, 2);
+        buffer ++;
+        __lasx_xvstelm_d(v2, buffer, 0, 3);
+        buffer ++;
+    }
+
+    SIMD_EPILOGUE(i, count, 7) {
+        uint s = *src++;
+        if (maskAlpha)
+            s = s | 0xff000000;
+        if (RGBA)
+            s = RGBA2ARGB(s);
+        *buffer++ = QRgba64::fromArgb32(s);
+    }
+}
+#endif //__loongarch_asx
+
 static const QRgba64 *QT_FASTCALL convertRGB32ToRGB64(QRgba64 *buffer, const uint *src, int count,
                                                       const QVector<QRgb> *, QDitherInfo *)
 {
 #ifdef __SSE2__
     qConvertARGB32PMToRGBA64PM_sse2<false, true>(buffer, src, count);
+#elif defined(__loongarch_asx)
+    qConvertARGB32PMToRGBA64PM_lasx<false, true>(buffer, src, count);
+#elif defined(__loongarch_sx)
+    qConvertARGB32PMToRGBA64PM_lsx<false, true>(buffer, src, count);
 #elif defined(__ARM_NEON__)
     qConvertARGB32PMToRGBA64PM_neon<false, true>(buffer, src, count);
 #else
@@ -1109,6 +1289,10 @@ static const QRgba64 *QT_FASTCALL convertARGB32PMToRGBA64PM(QRgba64 *buffer, con
 {
 #ifdef __SSE2__
     qConvertARGB32PMToRGBA64PM_sse2<false, false>(buffer, src, count);
+#elif defined(__loongarch_asx)
+    qConvertARGB32PMToRGBA64PM_lasx<false, false>(buffer, src, count);
+#elif defined(__loongarch_sx)
+    qConvertARGB32PMToRGBA64PM_lsx<false, false>(buffer, src, count);
 #elif defined(__ARM_NEON__)
     qConvertARGB32PMToRGBA64PM_neon<false, false>(buffer, src, count);
 #else
@@ -1164,6 +1348,10 @@ static const QRgba64 *QT_FASTCALL convertRGBA8888PMToRGBA64PM(QRgba64 *buffer, c
 {
 #ifdef __SSE2__
     qConvertARGB32PMToRGBA64PM_sse2<true, false>(buffer, src, count);
+#elif defined(__loongarch_asx)
+    qConvertARGB32PMToRGBA64PM_lasx<true, false>(buffer, src, count);
+#elif defined(__loongarch_sx)
+    qConvertARGB32PMToRGBA64PM_lsx<true, false>(buffer, src, count);
 #elif defined(__ARM_NEON__)
     qConvertARGB32PMToRGBA64PM_neon<true, false>(buffer, src, count);
 #else
@@ -1276,6 +1464,104 @@ static inline void qConvertA2RGB30PMToRGBA64PM_sse2(QRgba64 *buffer, const uint
     SIMD_EPILOGUE(i, count, 3)
         *buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++);
 }
+#elif defined(__loongarch_asx)
+template<QtPixelOrder PixelOrder>
+static inline void qConvertA2RGB30PMToRGBA64PM_lasx(QRgba64 *buffer, const uint *src, int count)
+{
+    if (count <= 0)
+        return;
+
+    const __m256i rmask = __lasx_xvreplgr2vr_w(0x3ff00000);
+    const __m256i gmask = __lasx_xvreplgr2vr_w(0x000ffc00);
+    const __m256i bmask = __lasx_xvreplgr2vr_w(0x000003ff);
+    const __m256i afactor = __lasx_xvreplgr2vr_h(0x5555);
+    int i = 0;
+
+    for (; ((uintptr_t)buffer & 0xf) && i < count; ++i)
+        *buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++);
+
+    for (; i < count-7; i += 8) {
+        __m256i vs = __lasx_xvld((const __m256i*)src, 0);
+        src += 8;
+        __m256i va = __lasx_xvsrli_w(vs, 30);
+        __m256i vr = __lasx_xvand_v(vs, rmask);
+        __m256i vb = __lasx_xvand_v(vs, bmask);
+        __m256i vg = __lasx_xvand_v(vs, gmask);
+        va = __lasx_xvmul_h(va, afactor);
+        vr = __lasx_xvor_v(__lasx_xvsrli_w(vr, 14), __lasx_xvsrli_w(vr, 24));
+        vg = __lasx_xvor_v(__lasx_xvsrli_w(vg, 4), __lasx_xvsrli_w(vg, 14));
+        vb = __lasx_xvor_v(__lasx_xvslli_w(vb, 6), __lasx_xvsrli_w(vb, 4));
+        __m256i vrb;
+        if (PixelOrder == PixelOrderRGB)
+             vrb = __lasx_xvor_v(vr, __lasx_xvbsll_v(vb, 2));
+        else
+             vrb = __lasx_xvor_v(vb, __lasx_xvbsll_v(vr, 2));
+        __m256i vga = __lasx_xvor_v(vg, __lasx_xvbsll_v(va, 2));
+        __m256i v1 = __lasx_xvilvl_h(vga, vrb);
+        __m256i v2 = __lasx_xvilvh_h(vga, vrb);
+        __lasx_xvstelm_d(v1, buffer, 0, 0);
+        buffer ++;
+        __lasx_xvstelm_d(v1, buffer, 0, 1);
+        buffer ++;
+        __lasx_xvstelm_d(v2, buffer, 0, 0);
+        buffer ++;
+        __lasx_xvstelm_d(v2, buffer, 0, 1);
+        buffer ++;
+        __lasx_xvstelm_d(v1, buffer, 0, 2);
+        buffer ++;
+        __lasx_xvstelm_d(v1, buffer, 0, 3);
+        buffer ++;
+        __lasx_xvstelm_d(v2, buffer, 0, 2);
+        buffer ++;
+        __lasx_xvstelm_d(v2, buffer, 0, 3);
+        buffer ++;
+    }
+
+    SIMD_EPILOGUE(i, count, 7)
+        *buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++);
+}
+#elif defined(__loongarch_sx)
+template<QtPixelOrder PixelOrder>
+static inline void qConvertA2RGB30PMToRGBA64PM_lsx(QRgba64 *buffer, const uint *src, int count)
+{
+    if (count <= 0)
+        return;
+
+    const __m128i rmask = __lsx_vreplgr2vr_w(0x3ff00000);
+    const __m128i gmask = __lsx_vreplgr2vr_w(0x000ffc00);
+    const __m128i bmask = __lsx_vreplgr2vr_w(0x000003ff);
+    const __m128i afactor = __lsx_vreplgr2vr_h(0x5555);
+    int i = 0;
+
+    for (; ((uintptr_t)buffer & 0xf) && i < count; ++i)
+        *buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++);
+
+    for (; i < count-3; i += 4) {
+        __m128i vs = __lsx_vld((const __m128i*)src, 0);
+        src += 4;
+        __m128i va = __lsx_vsrli_w(vs, 30);
+        __m128i vr = __lsx_vand_v(vs, rmask);
+        __m128i vb = __lsx_vand_v(vs, bmask);
+        __m128i vg = __lsx_vand_v(vs, gmask);
+        va = __lsx_vmul_h(va, afactor);
+        vr = __lsx_vor_v(__lsx_vsrli_w(vr, 14), __lsx_vsrli_w(vr, 24));
+        vg = __lsx_vor_v(__lsx_vsrli_w(vg, 4), __lsx_vsrli_w(vg, 14));
+        vb = __lsx_vor_v(__lsx_vslli_w(vb, 6), __lsx_vsrli_w(vb, 4));
+        __m128i vrb;
+        if (PixelOrder == PixelOrderRGB)
+             vrb = __lsx_vor_v(vr, __lsx_vbsll_v(vb, 2));
+        else
+             vrb = __lsx_vor_v(vb, __lsx_vbsll_v(vr, 2));
+        __m128i vga = __lsx_vor_v(vg, __lsx_vbsll_v(va, 2));
+        __lsx_vst(__lsx_vilvl_h(vga, vrb), buffer, 0);
+        buffer += 2;
+        __lsx_vst(__lsx_vilvh_h(vga, vrb), buffer, 0);
+        buffer += 2;
+    }
+
+    SIMD_EPILOGUE(i, count, 3)
+        *buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++);
+}
 #endif
 
 template<QtPixelOrder PixelOrder>
@@ -1284,6 +1570,10 @@ static const QRgba64 *QT_FASTCALL convertA2RGB30PMToRGBA64PM(QRgba64 *buffer, co
 {
 #ifdef __SSE2__
     qConvertA2RGB30PMToRGBA64PM_sse2<PixelOrder>(buffer, src, count);
+#elif defined (__loongarch_asx)
+    qConvertA2RGB30PMToRGBA64PM_lasx<PixelOrder>(buffer, src, count);
+#elif defined (__loongarch_sx)
+    qConvertA2RGB30PMToRGBA64PM_lsx<PixelOrder>(buffer, src, count);
 #else
     for (int i = 0; i < count; ++i)
         buffer[i] = qConvertA2rgb30ToRgb64<PixelOrder>(src[i]);
@@ -1356,6 +1646,37 @@ void qt_convertRGBA64ToARGB32(uint *dst, const QRgba64 *src, int count)
         _mm_storel_epi64((__m128i*)(dst), v1);
         dst += 2;
     }
+#elif defined(__loongarch_sx)
+    if (((uintptr_t)dst & 0x7) && count > 0) {
+        uint s = (*src++).toArgb32();
+        if (RGBA)
+            s = ARGB2RGBA(s);
+        *dst++ = s;
+        i++;
+    }
+    const __m128i vhalf = __lsx_vreplgr2vr_w(0x80);
+    const __m128i vzero = {0, 0};
+    const __m128i shuffleMask = (__m128i)(v8i16){2,1,0,3,6,5,4,7};
+    for (; i < count-1; i += 2) {
+        __m128i vs = __lsx_vld((const __m128i*)src, 0);
+        src += 2;
+        if (!RGBA) {
+            vs = __lsx_vshuf_h(shuffleMask, vzero, vs);
+        }
+        __m128i v1 = __lsx_vilvl_h(vzero, vs);
+        __m128i v2 = __lsx_vilvh_h(vzero, vs);
+        v1 = __lsx_vadd_w(v1, vhalf);
+        v2 = __lsx_vadd_w(v2, vhalf);
+        v1 = __lsx_vsub_w(v1, __lsx_vsrli_w(v1, 8));
+        v2 = __lsx_vsub_w(v2, __lsx_vsrli_w(v2, 8));
+        v1 = __lsx_vsrli_w(v1, 8);
+        v2 = __lsx_vsrli_w(v2, 8);
+        v1 = __lsx_vpickev_h(__lsx_vsat_w(v2, 15), __lsx_vsat_w(v1, 15));
+        v1 = __lsx_vmaxi_h(v1, 0);
+        v1 = __lsx_vpickev_b(vzero, __lsx_vsat_hu(v1, 7));
+        __lsx_vstelm_d(v1, dst, 0, 0);
+        dst += 2;
+    }
 #endif
     for (; i < count; i++) {
         uint s = (*src++).toArgb32();
@@ -1592,6 +1913,8 @@ static void QT_FASTCALL storeRGB30FromRGBA64PM(uchar *dest, const QRgba64 *src,
     uint *d = (uint*)dest + index;
 #ifdef __SSE2__
     qConvertRGBA64PMToA2RGB30PM_sse2<PixelOrder>(d, src, count);
+#elif defined (__loongarch_sx)
+    qConvertRGBA64PMToA2RGB30PM_lsx<PixelOrder>(d, src, count);
 #else
     for (int i = 0; i < count; ++i)
         d[i] = qConvertRgb64ToRgb30<PixelOrder>(src[i]);
@@ -2350,6 +2673,43 @@ static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, u
 }
 #endif
 
+#if defined(__loongarch_sx)
+#define interpolate_4_pixels_16_lsx(tl, tr, bl, br, distx, disty, colorMask, v_256, b)  \
+{ \
+    const __m128i dxdy = __lsx_vmul_h(distx, disty); \
+    const __m128i distx_ = __lsx_vslli_h(distx, 4); \
+    const __m128i disty_ = __lsx_vslli_h(disty, 4); \
+    const __m128i idxidy =  __lsx_vadd_h(dxdy, __lsx_vsub_h(v_256, __lsx_vadd_h(distx_, disty_)));\
+    const __m128i dxidy = __lsx_vsub_h(distx_, dxdy);\
+    const __m128i idxdy = __lsx_vsub_h(disty_,dxdy);\
+ \
+    __m128i tlAG = __lsx_vsrli_h(tl, 8); \
+    __m128i tlRB = __lsx_vand_v(tl, colorMask); \
+    __m128i trAG = __lsx_vsrli_h(tr, 8); \
+    __m128i trRB = __lsx_vand_v(tr, colorMask); \
+    __m128i blAG = __lsx_vsrli_h(bl, 8); \
+    __m128i blRB = __lsx_vand_v(bl, colorMask); \
+    __m128i brAG = __lsx_vsrli_h(br, 8); \
+    __m128i brRB = __lsx_vand_v(br, colorMask); \
+ \
+    tlAG = __lsx_vmul_h(tlAG, idxidy); \
+    tlRB = __lsx_vmul_h(tlRB, idxidy); \
+    trAG = __lsx_vmul_h(trAG, dxidy); \
+    trRB = __lsx_vmul_h(trRB, dxidy); \
+    blAG = __lsx_vmul_h(blAG, idxdy); \
+    blRB = __lsx_vmul_h(blRB, idxdy); \
+    brAG = __lsx_vmul_h(brAG, dxdy); \
+    brRB = __lsx_vmul_h(brRB, dxdy); \
+ \
+    /* Add the values, and shift to only keep 8 significant bits per colors */ \
+    __m128i rAG =__lsx_vadd_h(__lsx_vadd_h(tlAG, trAG), __lsx_vadd_h(blAG, brAG)); \
+    __m128i rRB =__lsx_vadd_h(__lsx_vadd_h(tlRB, trRB), __lsx_vadd_h(blRB, brRB)); \
+    rAG = __lsx_vandn_v(colorMask, rAG); \
+    rRB = __lsx_vsrli_h(rRB, 8); \
+    __lsx_vst(__lsx_vor_v(rAG, rRB), b, 0); \
+}
+#endif
+
 #if defined(__ARM_NEON__)
 #define interpolate_4_pixels_16_neon(tl, tr, bl, br, distx, disty, disty_, colorMask, invColorMask, v_256, b)  \
 { \
@@ -2699,6 +3059,35 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper(uint *
             v_fx = _mm_add_epi32(v_fx, v_fdx);
         }
         fx = _mm_cvtsi128_si32(v_fx);
+#elif defined (__loongarch_sx)
+        const __m128i shuffleMask = (__m128i)(v8i16){0,0,2,2,4,4,6,6};
+        const __m128i colorMask = __lsx_vreplgr2vr_w(0x00ff00ff);
+        const __m128i v_256 = __lsx_vreplgr2vr_h(256);
+        const __m128i v_disty = __lsx_vreplgr2vr_h(disty4);
+        const __m128i v_fdx = __lsx_vreplgr2vr_w(fdx*4);
+        const __m128i v_fx_r = __lsx_vreplgr2vr_w(0x8);
+        __m128i v_fx = (__m128i)(v4i32){fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx};
+
+        while (b < boundedEnd - 3) {
+            __m128i offset = __lsx_vsrli_w(v_fx, 16);
+            const int offset0 = __lsx_vpickve2gr_w(offset, 0);
+            const int offset1 = __lsx_vpickve2gr_w(offset, 1);
+            const int offset2 = __lsx_vpickve2gr_w(offset, 2);
+            const int offset3 = __lsx_vpickve2gr_w(offset, 3);
+            const __m128i tl = (__m128i)(v4u32){s1[offset0], s1[offset1], s1[offset2], s1[offset3]};
+            const __m128i tr = (__m128i)(v4u32){s1[offset0 + 1], s1[offset1 + 1], s1[offset2 + 1], s1[offset3 + 1]};
+            const __m128i bl = (__m128i)(v4u32){s2[offset0], s2[offset1], s2[offset2], s2[offset3]};
+            const __m128i br = (__m128i)(v4u32){s2[offset0 + 1], s2[offset1 + 1], s2[offset2 + 1], s2[offset3 + 1]};
+
+            __m128i v_distx = __lsx_vsrli_h(v_fx, 8);
+            v_distx = __lsx_vsrli_h(__lsx_vadd_w(v_distx, v_fx_r), 4);
+            v_distx = __lsx_vshuf_h(shuffleMask, v_distx, v_distx);
+
+            interpolate_4_pixels_16_lsx(tl, tr, bl, br, v_distx, v_disty, colorMask, v_256, b);
+            b += 4;
+            v_fx = __lsx_vadd_w(v_fx, v_fdx);
+        }
+        fx = __lsx_vpickve2gr_w(v_fx, 0);
 #elif defined(__ARM_NEON__)
         const int16x8_t colorMask = vdupq_n_s16(0x00ff);
         const int16x8_t invColorMask = vmvnq_s16(colorMask);
@@ -2909,6 +3298,53 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper(uint
         }
         fx = _mm_cvtsi128_si32(v_fx);
         fy = _mm_cvtsi128_si32(v_fy);
+#elif defined(__loongarch_sx)
+        const __m128i colorMask = __lsx_vreplgr2vr_w(0x00ff00ff);
+        const __m128i v_256 = __lsx_vreplgr2vr_h(256);
+        const __m128i v_fdx = __lsx_vreplgr2vr_w(fdx*4);
+        const __m128i v_fdy = __lsx_vreplgr2vr_w(fdy*4);
+        const __m128i v_fxy_r = __lsx_vreplgr2vr_w(0x8);
+        __m128i v_fx = (__m128i)(v4i32){fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx};
+        __m128i v_fy = (__m128i)(v4i32){fy, fy + fdy, fy + fdy + fdy, fy + fdy + fdy + fdy};
+
+        const uchar *textureData = image.imageData;
+        const qsizetype bytesPerLine = image.bytesPerLine;
+        const __m128i zero = {0,0};
+        const __m128i shuffleMask = (__m128i)(v8i16){0,0,0,0,4,5,6,7};
+        const __m128i shuffleMask1 = (__m128i)(v8i16){0,0,2,2,4,4,6,6};
+        const __m128i vbpl = __lsx_vshuf_h(shuffleMask, zero, __lsx_vinsgr2vr_w(zero, bytesPerLine/4, 0));
+
+        while (b < boundedEnd - 3) {
+            const __m128i vy = __lsx_vpickev_h(zero, __lsx_vsat_w(__lsx_vsrli_w(v_fy, 16), 15));
+            // 4x16bit * 4x16bit -> 4x32bit
+            __m128i offset = __lsx_vilvl_h(__lsx_vmuh_h(vy, vbpl), __lsx_vmul_h(vy, vbpl));
+            offset = __lsx_vadd_w(offset, __lsx_vsrli_w(v_fx, 16));
+            const int offset0 = __lsx_vpickve2gr_w(offset, 0);
+            const int offset1 = __lsx_vpickve2gr_w(offset, 1);
+            const int offset2 = __lsx_vpickve2gr_w(offset, 2);
+            const int offset3 = __lsx_vpickve2gr_w(offset, 3);
+            const uint *topData = (const uint *)(textureData);
+            const __m128i tl = (__m128i)(v4u32){topData[offset0], topData[offset1], topData[offset2], topData[offset3]};
+            const __m128i tr = (__m128i)(v4u32){topData[offset0 + 1], topData[offset1 + 1], topData[offset2 + 1], topData[offset3 + 1]};
+            const uint *bottomData = (const uint *)(textureData + bytesPerLine);
+            const __m128i bl = (__m128i)(v4u32){bottomData[offset0], bottomData[offset1], bottomData[offset2], bottomData[offset3]};
+            const __m128i br = (__m128i)(v4u32){bottomData[offset0 + 1], bottomData[offset1 + 1], bottomData[offset2 + 1], bottomData[offset3 + 1]};
+
+            __m128i v_distx = __lsx_vsrli_h(v_fx, 8);
+            __m128i v_disty = __lsx_vsrli_h(v_fy, 8);
+            v_distx = __lsx_vsrli_h(__lsx_vadd_w(v_distx, v_fxy_r), 4);
+            v_disty = __lsx_vsrli_h(__lsx_vadd_w(v_disty, v_fxy_r), 4);
+            v_distx = __lsx_vshuf_h(shuffleMask1, zero, v_distx);
+            v_disty = __lsx_vshuf_h(shuffleMask1, zero, v_disty);
+
+            interpolate_4_pixels_16_lsx(tl, tr, bl, br, v_distx, v_disty, colorMask, v_256, b);
+            b += 4;
+            v_fx = __lsx_vadd_w(v_fx, v_fdx);
+            v_fy = __lsx_vadd_w(v_fy, v_fdy);
+        }
+        fx = __lsx_vpickve2gr_w(v_fx, 0);
+        fy = __lsx_vpickve2gr_w(v_fy, 0);
+
 #elif defined(__ARM_NEON__)
         const int16x8_t colorMask = vdupq_n_s16(0x00ff);
         const int16x8_t invColorMask = vmvnq_s16(colorMask);
@@ -4538,6 +4974,9 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData)
 #ifdef __SSE2__
             } else if (spans->len > 16) {
                 op.funcSolid(target, spans->len, color, spans->coverage);
+#elif defined(__loongarch_sx)
+            } else if (spans->len > 16) {
+                op.funcSolid(target, spans->len, color, spans->coverage);
 #endif
             } else {
                 uint c = BYTE_MUL(color, spans->coverage);
@@ -5432,7 +5871,7 @@ void qBlendTexture(int count, const QSpan *spans, void *userData)
         proc = processTextureSpansRGB16[blendType];
         break;
 #if QT_CONFIG(raster_64bit)
-#if defined(__SSE2__) || defined(__ARM_NEON__) || (Q_PROCESSOR_WORDSIZE == 8)
+#if defined(__SSE2__) || defined(__ARM_NEON__) || defined(QT_COMPILER_SUPPORTS_LSX) || (Q_PROCESSOR_WORDSIZE == 8)
     case QImage::Format_ARGB32:
     case QImage::Format_RGBA8888:
 #endif
@@ -5542,7 +5981,7 @@ void qBlendGradient(int count, const QSpan *spans, void *userData)
             return blend_vertical_gradient_argb(count, spans, userData);
         return blend_src_generic(count, spans, userData);
 #if QT_CONFIG(raster_64bit)
-#if defined(__SSE2__) || defined(__ARM_NEON__) || (Q_PROCESSOR_WORDSIZE == 8)
+#if defined(__SSE2__) || defined(__ARM_NEON__) || defined(QT_COMPILER_SUPPORTS_LSX) || (Q_PROCESSOR_WORDSIZE == 8)
     case QImage::Format_ARGB32:
     case QImage::Format_RGBA8888:
 #endif
@@ -6649,7 +7088,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
     },
 };
 
-#if !defined(__SSE2__)
+#if !defined(__SSE2__) && !defined(QT_COMPILER_SUPPORTS_LSX)
 void qt_memfill64(quint64 *dest, quint64 color, qsizetype count)
 {
     qt_memfill_template<quint64>(dest, color, count);
@@ -6665,6 +7104,10 @@ void qt_memfill24(quint24 *dest, quint24 color, qsizetype count)
     extern void qt_memfill24_ssse3(quint24 *, quint24, qsizetype);
     if (qCpuHasFeature(SSSE3))
         return qt_memfill24_ssse3(dest, color, count);
+#  elif defined QT_COMPILER_SUPPORTS_LSX
+    extern void qt_memfill24_lsx(quint24 *, quint24, qsizetype);
+    if (qCpuHasFeature(LSX))
+        return qt_memfill24_lsx(dest, color, count);
 #  endif
 
     const quint32 v = color;
@@ -6716,7 +7159,7 @@ void qt_memfill16(quint16 *dest, quint16 value, qsizetype count)
     qt_memfill32(reinterpret_cast<quint32*>(dest), value32, count / 2);
 }
 
-#if !defined(__SSE2__) && !defined(__ARM_NEON__) && !defined(__MIPS_DSP__)
+#if !defined(__SSE2__) && !defined(__ARM_NEON__) && !defined(__MIPS_DSP__) && !defined(QT_COMPILER_SUPPORTS_LSX)
 void qt_memfill32(quint32 *dest, quint32 color, qsizetype count)
 {
     qt_memfill_template<quint32>(dest, color, count);
@@ -6727,10 +7170,19 @@ decltype(qt_memfill32_sse2) *qt_memfill32 = nullptr;
 decltype(qt_memfill64_sse2) *qt_memfill64 = nullptr;
 #endif
 
+#ifdef QT_COMPILER_SUPPORTS_LSX
+decltype(qt_memfill32_lsx) *qt_memfill32 = nullptr;
+decltype(qt_memfill64_lsx) *qt_memfill64 = nullptr;
+#endif
+
 #ifdef QT_COMPILER_SUPPORTS_SSE4_1
 template<QtPixelOrder> void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count, const QVector<QRgb> *, QDitherInfo *);
 #endif
 
+#if defined QT_COMPILER_SUPPORTS_LSX
+template<QtPixelOrder> void QT_FASTCALL storeA2RGB30PMFromARGB32PM_lsx(uchar *dest, const uint *src, int index, int count, const QVector<QRgb> *, QDitherInfo *);
+#endif
+
 extern void qInitBlendFunctions();
 
 static void qInitDrawhelperFunctions()
@@ -6941,6 +7393,195 @@ static void qInitDrawhelperFunctions()
 
 #endif // SSE2
 
+#if defined(QT_COMPILER_SUPPORTS_LSX)
+    if (qCpuHasFeature(LSX)) {
+        qt_memfill32 = qt_memfill32_lsx;
+        qt_memfill64 = qt_memfill64_lsx;
+
+        qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_lsx;
+        qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_lsx;
+        qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_lsx;
+        qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_lsx;
+        qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit8888_lsx;
+        qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit8888_lsx;
+        qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit8888_lsx;
+
+        extern void qt_scale_image_argb32_on_argb32_lsx(uchar *destPixels, int dbpl,
+                                                        const uchar *srcPixels, int sbpl, int srch,
+                                                        const QRectF &targetRect,
+                                                        const QRectF &sourceRect,
+                                                        const QRect &clip,
+                                                        int const_alpha);
+
+        qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
+        qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
+        qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
+        qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
+
+        extern void qt_blend_rgb32_on_rgb32_lsx(uchar *destPixels, int dbpl,
+                                                const uchar *srcPixels, int sbpl,
+                                                int w, int h,
+                                                int const_alpha);
+
+        extern void qt_blend_argb32_on_argb32_lsx(uchar *destPixels, int dbpl,
+                                                  const uchar *srcPixels, int sbpl,
+                                                  int w, int h,
+                                                  int const_alpha);
+
+        qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lsx;
+        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lsx;
+        qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
+        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
+
+        qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lsx;
+        qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lsx;
+        qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
+        qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
+
+        extern const uint * QT_FASTCALL qt_fetch_radial_gradient_lsx(uint *buffer, const Operator *op, const QSpanData *data,
+                                                                     int y, int x, int length);
+
+        qt_fetch_radial_gradient = qt_fetch_radial_gradient_lsx;
+
+        extern void QT_FASTCALL comp_func_SourceOver_lsx(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
+        extern void QT_FASTCALL comp_func_solid_SourceOver_lsx(uint *destPixels, int length, uint color, uint const_alpha);
+        extern void QT_FASTCALL comp_func_Source_lsx(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
+        extern void QT_FASTCALL comp_func_solid_Source_lsx(uint *destPixels, int length, uint color, uint const_alpha);
+        extern void QT_FASTCALL comp_func_Plus_lsx(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
+        qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_lsx;
+        qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_lsx;
+        qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_lsx;
+        qt_functionForModeSolid_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_lsx;
+        qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_lsx;
+
+        extern const uint * QT_FASTCALL qt_fetchUntransformed_888_lsx(uint *buffer, const Operator *, const QSpanData *data,
+                                                                      int y, int x, int length);
+        sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_lsx;
+        extern void QT_FASTCALL rbSwap_888_lsx(uchar *dst, const uchar *src, int count);
+        qPixelLayouts[QImage::Format_RGB888].rbSwap = rbSwap_888_lsx;
+        qPixelLayouts[QImage::Format_BGR888].rbSwap = rbSwap_888_lsx;
+
+        extern void QT_FASTCALL convertARGB32ToARGB32PM_lsx(uint *buffer, int count, const QVector<QRgb> *);
+        extern void QT_FASTCALL convertRGBA8888ToARGB32PM_lsx(uint *buffer, int count, const QVector<QRgb> *);
+        extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_lsx(uint *buffer, const uchar *src, int index, int count,
+                                                                 const QVector<QRgb> *, QDitherInfo *);
+        extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_lsx(uint *buffer, const uchar *src, int index, int count,
+                                                                   const QVector<QRgb> *, QDitherInfo *);
+        extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_lsx(QRgba64 *buffer, const uint *src, int count,
+                                                                       const QVector<QRgb> *, QDitherInfo *);
+        extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_lsx(QRgba64 *buffer, const uint *src, int count,
+                                                                         const QVector<QRgb> *, QDitherInfo *);
+        extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_lsx(QRgba64 *buffer, const uchar *src, int index, int count,
+                                                                    const QVector<QRgb> *, QDitherInfo *);
+        extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_lsx(QRgba64 *buffer, const uchar *src, int index, int count,
+                                                                      const QVector<QRgb> *, QDitherInfo *);
+        extern void QT_FASTCALL storeARGB32FromARGB32PM_lsx(uchar *dest, const uint *src, int index, int count,
+                                                            const QVector<QRgb> *, QDitherInfo *);
+        extern void QT_FASTCALL storeRGBA8888FromARGB32PM_lsx(uchar *dest, const uint *src, int index, int count,
+                                                              const QVector<QRgb> *, QDitherInfo *);
+        extern void QT_FASTCALL storeRGBXFromARGB32PM_lsx(uchar *dest, const uint *src, int index, int count,
+                                                          const QVector<QRgb> *, QDitherInfo *);
+        extern void QT_FASTCALL storeARGB32FromRGBA64PM_lsx(uchar *dest, const QRgba64 *src, int index, int count,
+                                                            const QVector<QRgb> *, QDitherInfo *);
+        extern void QT_FASTCALL storeRGBA8888FromRGBA64PM_lsx(uchar *dest, const QRgba64 *src, int index, int count,
+                                                              const QVector<QRgb> *, QDitherInfo *);
+        extern void QT_FASTCALL destStore64ARGB32_lsx(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length);
+        extern void QT_FASTCALL destStore64RGBA8888_lsx(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length);
+        qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_lsx;
+        qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_lsx;
+        qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_lsx;
+        qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_lsx;
+        qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_lsx;
+        qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_lsx;
+        qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lsx;
+        qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lsx;
+        qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lsx;
+        qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lsx;
+        qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_lsx;
+        qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_lsx;
+        qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_lsx;
+        qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_lsx<PixelOrderBGR>;
+        qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_lsx<PixelOrderRGB>;
+        qStoreFromRGBA64PM[QImage::Format_ARGB32] = storeARGB32FromRGBA64PM_lsx;
+        qStoreFromRGBA64PM[QImage::Format_RGBA8888] = storeRGBA8888FromRGBA64PM_lsx;
+#if QT_CONFIG(raster_64bit)
+        destStoreProc64[QImage::Format_ARGB32] = destStore64ARGB32_lsx;
+        destStoreProc64[QImage::Format_RGBA8888] = destStore64RGBA8888_lsx;
+#endif
+    }
+
+#if defined(QT_COMPILER_SUPPORTS_LASX)
+    if (qCpuHasFeature(LASX)) {
+        qt_memfill32 = qt_memfill32_lasx;
+        qt_memfill64 = qt_memfill64_lasx;
+
+        extern void qt_blend_rgb32_on_rgb32_lasx(uchar *destPixels, int dbpl,
+                                                 const uchar *srcPixels, int sbpl,
+                                                 int w, int h, int const_alpha);
+        extern void qt_blend_argb32_on_argb32_lasx(uchar *destPixels, int dbpl,
+                                                   const uchar *srcPixels, int sbpl,
+                                                   int w, int h, int const_alpha);
+        qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lasx;
+        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lasx;
+        qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
+        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
+        qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lasx;
+        qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lasx;
+        qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
+        qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
+
+        extern void QT_FASTCALL comp_func_Source_lasx(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
+        extern void QT_FASTCALL comp_func_SourceOver_lasx(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
+        extern void QT_FASTCALL comp_func_solid_SourceOver_lasx(uint *destPixels, int length, uint color, uint const_alpha);
+        qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_lasx;
+        qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_lasx;
+        qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_lasx;
+#if QT_CONFIG(raster_64bit)
+        extern void QT_FASTCALL comp_func_Source_rgb64_lasx(QRgba64 *destPixels, const QRgba64 *srcPixels, int length, uint const_alpha);
+        extern void QT_FASTCALL comp_func_SourceOver_rgb64_lasx(QRgba64 *destPixels, const QRgba64 *srcPixels, int length, uint const_alpha);
+        extern void QT_FASTCALL comp_func_solid_SourceOver_rgb64_lasx(QRgba64 *destPixels, int length, QRgba64 color, uint const_alpha);
+        qt_functionForMode64_C[QPainter::CompositionMode_Source] = comp_func_Source_rgb64_lasx;
+        qt_functionForMode64_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_rgb64_lasx;
+        qt_functionForModeSolid64_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgb64_lasx;
+#endif
+
+        extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_lasx(uint *b, uint *end, const QTextureData &image,
+                                                                                          int &fx, int &fy, int fdx, int /*fdy*/);
+        extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper_lasx(uint *b, uint *end, const QTextureData &image,
+                                                                                       int &fx, int &fy, int fdx, int /*fdy*/);
+        extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_lasx(uint *b, uint *end, const QTextureData &image,
+                                                                                         int &fx, int &fy, int fdx, int fdy);
+
+        bilinearFastTransformHelperARGB32PM[0][SimpleScaleTransform] = fetchTransformedBilinearARGB32PM_simple_scale_helper_lasx;
+        bilinearFastTransformHelperARGB32PM[0][DownscaleTransform] = fetchTransformedBilinearARGB32PM_downscale_helper_lasx;
+        bilinearFastTransformHelperARGB32PM[0][FastRotateTransform] = fetchTransformedBilinearARGB32PM_fast_rotate_helper_lasx;
+
+        extern void QT_FASTCALL convertARGB32ToARGB32PM_lasx(uint *buffer, int count, const QVector<QRgb> *);
+        extern void QT_FASTCALL convertRGBA8888ToARGB32PM_lasx(uint *buffer, int count, const QVector<QRgb> *);
+        extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_lasx(uint *buffer, const uchar *src, int index, int count,
+                                                                  const QVector<QRgb> *, QDitherInfo *);
+        extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_lasx(uint *buffer, const uchar *src, int index, int count,
+                                                                    const QVector<QRgb> *, QDitherInfo *);
+        qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_lasx;
+        qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_lasx;
+        qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_lasx;
+        qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_lasx;
+
+#if QT_CONFIG(raster_64bit)
+        extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_lasx(QRgba64 *, const uint *, int, const QVector<QRgb> *, QDitherInfo *);
+        extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_lasx(QRgba64 *, const uint *, int count, const QVector<QRgb> *, QDitherInfo *);
+        extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_lasx(QRgba64 *, const uchar *, int, int, const QVector<QRgb> *, QDitherInfo *);
+        extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_lasx(QRgba64 *, const uchar *, int, int, const QVector<QRgb> *, QDitherInfo *);
+        qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_lasx;
+        qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lasx;
+        qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_lasx;
+        qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lasx;
+#endif
+    }
+#endif  //QT_COMPILER_SUPPORTS_LASX
+
+#endif //QT_COMPILER_SUPPORTS_LSX
+
 #if defined(__ARM_NEON__)
     qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
     qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index b90d0b32027..c5dbf71cd56 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -186,6 +186,9 @@ void qBlendTexture(int count, const QSpan *spans, void *userData);
 #ifdef __SSE2__
 extern void (*qt_memfill64)(quint64 *dest, quint64 value, qsizetype count);
 extern void (*qt_memfill32)(quint32 *dest, quint32 value, qsizetype count);
+#elif defined(QT_COMPILER_SUPPORTS_LSX)
+extern void (*qt_memfill64)(quint64 *dest, quint64 value, qsizetype count);
+extern void (*qt_memfill32)(quint32 *dest, quint32 value, qsizetype count);
 #else
 extern void qt_memfill64(quint64 *dest, quint64 value, qsizetype count);
 extern void qt_memfill32(quint32 *dest, quint32 value, qsizetype count);
diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp
index 86057cdd335..f06967d3a51 100644
--- a/src/gui/painting/qimagescale.cpp
+++ b/src/gui/painting/qimagescale.cpp
@@ -289,6 +289,18 @@ void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi, unsigned int *dest,
                                        int dw, int dh, int dow, int sow);
 #endif
 
+#if defined(QT_COMPILER_SUPPORTS_LSX)
+template<bool RGB>
+void qt_qimageScaleAARGBA_up_x_down_y_lsx(QImageScaleInfo *isi, unsigned int *dest,
+                                          int dw, int dh, int dow, int sow);
+template<bool RGB>
+void qt_qimageScaleAARGBA_down_x_up_y_lsx(QImageScaleInfo *isi, unsigned int *dest,
+                                          int dw, int dh, int dow, int sow);
+template<bool RGB>
+void qt_qimageScaleAARGBA_down_xy_lsx(QImageScaleInfo *isi, unsigned int *dest,
+                                      int dw, int dh, int dow, int sow);
+#endif
+
 #if defined(__ARM_NEON__)
 template<bool RGB>
 void qt_qimageScaleAARGBA_up_x_down_y_neon(QImageScaleInfo *isi, unsigned int *dest,
@@ -381,6 +393,10 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
         if (qCpuHasFeature(SSE4_1))
             qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(isi, dest, dw, dh, dow, sow);
         else
+#elif defined(QT_COMPILER_SUPPORTS_LSX)
+        if (qCpuHasFeature(LSX))
+            qt_qimageScaleAARGBA_up_x_down_y_lsx<false>(isi, dest, dw, dh, dow, sow);
+        else
 #elif defined(__ARM_NEON__)
         if (qCpuHasFeature(NEON))
             qt_qimageScaleAARGBA_up_x_down_y_neon<false>(isi, dest, dw, dh, dow, sow);
@@ -394,6 +410,10 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
         if (qCpuHasFeature(SSE4_1))
             qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(isi, dest, dw, dh, dow, sow);
         else
+#elif defined(QT_COMPILER_SUPPORTS_LSX)
+        if (qCpuHasFeature(LSX))
+            qt_qimageScaleAARGBA_down_x_up_y_lsx<false>(isi, dest, dw, dh, dow, sow);
+        else
 #elif defined(__ARM_NEON__)
         if (qCpuHasFeature(NEON))
             qt_qimageScaleAARGBA_down_x_up_y_neon<false>(isi, dest, dw, dh, dow, sow);
@@ -405,7 +425,11 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
     else {
 #ifdef QT_COMPILER_SUPPORTS_SSE4_1
         if (qCpuHasFeature(SSE4_1))
-            qt_qimageScaleAARGBA_down_xy_sse4<false>(isi, dest, dw, dh, dow, sow);
+            qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(isi, dest, dw, dh, dow, sow);
+        else
+#elif defined(QT_COMPILER_SUPPORTS_LSX)
+        if (qCpuHasFeature(LSX))
+            qt_qimageScaleAARGBA_down_xy_lsx<false>(isi, dest, dw, dh, dow, sow);
         else
 #elif defined(__ARM_NEON__)
         if (qCpuHasFeature(NEON))
@@ -810,6 +834,10 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
         if (qCpuHasFeature(SSE4_1))
             qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(isi, dest, dw, dh, dow, sow);
         else
+#elif defined(QT_COMPILER_SUPPORTS_LSX)
+        if (qCpuHasFeature(LSX))
+            qt_qimageScaleAARGBA_up_x_down_y_lsx<true>(isi, dest, dw, dh, dow, sow);
+        else
 #elif defined(__ARM_NEON__)
         if (qCpuHasFeature(NEON))
             qt_qimageScaleAARGBA_up_x_down_y_neon<true>(isi, dest, dw, dh, dow, sow);
@@ -823,6 +851,10 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
         if (qCpuHasFeature(SSE4_1))
             qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(isi, dest, dw, dh, dow, sow);
         else
+#elif defined(QT_COMPILER_SUPPORTS_LSX)
+        if (qCpuHasFeature(LSX))
+            qt_qimageScaleAARGBA_down_x_up_y_lsx<true>(isi, dest, dw, dh, dow, sow);
+        else
 #elif defined(__ARM_NEON__)
         if (qCpuHasFeature(NEON))
             qt_qimageScaleAARGBA_down_x_up_y_neon<true>(isi, dest, dw, dh, dow, sow);
@@ -836,6 +868,10 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
         if (qCpuHasFeature(SSE4_1))
             qt_qimageScaleAARGBA_down_xy_sse4<true>(isi, dest, dw, dh, dow, sow);
         else
+#elif defined(QT_COMPILER_SUPPORTS_LSX)
+        if (qCpuHasFeature(LSX))
+            qt_qimageScaleAARGBA_down_xy_lsx<true>(isi, dest, dw, dh, dow, sow);
+        else
 #elif defined(__ARM_NEON__)
         if (qCpuHasFeature(NEON))
             qt_qimageScaleAARGBA_down_xy_neon<true>(isi, dest, dw, dh, dow, sow);
diff --git a/src/gui/painting/qrgba64_p.h b/src/gui/painting/qrgba64_p.h
index 0a19604c5d3..46220fade9e 100644
--- a/src/gui/painting/qrgba64_p.h
+++ b/src/gui/painting/qrgba64_p.h
@@ -90,6 +90,26 @@ Q_ALWAYS_INLINE __m128i multiplyAlpha65535(__m128i rgba64, uint alpha65535)
 }
 #endif
 
+#if defined(__loongarch_sx)
+Q_ALWAYS_INLINE __m128i multiplyAlpha65535(__m128i rgba64, __m128i va)
+{
+    __m128i vs = rgba64;
+    vs = __lsx_vilvl_h(__lsx_vmuh_hu(vs, va), __lsx_vmul_h(vs, va));
+    vs = __lsx_vadd_w(vs, __lsx_vsrli_w(vs, 16));
+    vs = __lsx_vadd_w(vs, __lsx_vreplgr2vr_w(0x8000));
+    vs = __lsx_vsrai_w(vs, 16);
+    vs = __lsx_vpickev_h(__lsx_vldi(0), __lsx_vsat_w(vs, 15));
+    return vs;
+}
+Q_ALWAYS_INLINE __m128i multiplyAlpha65535(__m128i rgba64, uint alpha65535)
+{
+    const __m128i shuffleMask = (__m128i)(v8i16){0, 0, 0, 0, 4, 5, 6, 7};
+    const __m128i va = __lsx_vshuf_h(shuffleMask, __lsx_vldi(0),
+                                     __lsx_vinsgr2vr_w(__lsx_vldi(0), alpha65535, 0));
+    return multiplyAlpha65535(rgba64, va);
+}
+#endif
+
 #if defined(__ARM_NEON__)
 Q_ALWAYS_INLINE uint16x4_t multiplyAlpha65535(uint16x4_t rgba64, uint16x4_t alpha65535)
 {
@@ -108,7 +128,7 @@ Q_ALWAYS_INLINE uint16x4_t multiplyAlpha65535(uint16x4_t rgba64, uint alpha65535
 template<typename T>
 inline T multiplyAlpha255(T rgba64, uint alpha255)
 {
-#if defined(__SSE2__) || defined(__ARM_NEON__)
+#if defined(__SSE2__) || defined(__ARM_NEON__) || defined(__loongarch_sx)
     return multiplyAlpha65535(rgba64, alpha255 * 257);
 #else
     return QRgba64::fromRgba64(qt_div_255(rgba64.red()   * alpha255),
@@ -130,6 +150,13 @@ Q_ALWAYS_INLINE __m128i interpolate255(__m128i x, uint alpha1, __m128i y, uint a
 }
 #endif
 
+#if defined __loongarch_sx
+Q_ALWAYS_INLINE __m128i interpolate255(__m128i x, uint alpha1, __m128i y, uint alpha2)
+{
+    return __lsx_vadd_w(multiplyAlpha255(x, alpha1), multiplyAlpha255(y, alpha2));
+}
+#endif
+
 #if defined __ARM_NEON__
 Q_ALWAYS_INLINE uint16x4_t interpolate255(uint16x4_t x, uint alpha1, uint16x4_t y, uint alpha2)
 {
@@ -154,6 +181,17 @@ Q_ALWAYS_INLINE __m128i interpolate65535(__m128i x, __m128i alpha1, __m128i y, c
 }
 #endif
 
+#if defined __loongarch_sx
+Q_ALWAYS_INLINE __m128i interpolate65535(__m128i x, uint alpha1, __m128i y, uint alpha2)
+{
+    return __lsx_vadd_w(multiplyAlpha65535(x, alpha1), multiplyAlpha65535(y, alpha2));
+}
+Q_ALWAYS_INLINE __m128i interpolate65535(__m128i x, __m128i alpha1, __m128i y, const __m128i &alpha2)
+{
+    return __lsx_vadd_w(multiplyAlpha65535(x, alpha1), multiplyAlpha65535(y, alpha2));
+}
+#endif
+
 #if defined __ARM_NEON__
 Q_ALWAYS_INLINE uint16x4_t interpolate65535(uint16x4_t x, uint alpha1, uint16x4_t y, uint alpha2)
 {
@@ -185,6 +223,18 @@ Q_ALWAYS_INLINE uint toArgb32(__m128i v)
     v = _mm_packus_epi16(v, v);
     return _mm_cvtsi128_si32(v);
 }
+#elif defined __loongarch_sx
+Q_ALWAYS_INLINE uint toArgb32(__m128i v)
+{
+    v = __lsx_vilvl_h(__lsx_vldi(0), v);
+    v = __lsx_vadd_w(v, __lsx_vreplgr2vr_w(128));
+    v = __lsx_vsub_w(v, __lsx_vsrli_w(v, 8));
+    v = __lsx_vsrli_w(v, 8);
+    v = __lsx_vpickev_h(__lsx_vsat_w(v, 15), __lsx_vsat_w(v, 15));
+    __m128i tmp = __lsx_vmaxi_h(v, 0);
+    v = __lsx_vpickev_b(__lsx_vsat_hu(tmp, 7), __lsx_vsat_hu(tmp, 7));
+    return __lsx_vpickve2gr_w(v, 0);
+}
 #elif defined __ARM_NEON__
 Q_ALWAYS_INLINE uint toArgb32(uint16x4_t v)
 {
@@ -201,6 +251,11 @@ Q_ALWAYS_INLINE uint toArgb32(QRgba64 rgba64)
     __m128i v = _mm_loadl_epi64((const __m128i *)&rgba64);
     v = _mm_shufflelo_epi16(v, _MM_SHUFFLE(3, 0, 1, 2));
     return toArgb32(v);
+#elif defined __loongarch_sx
+    __m128i v = __lsx_vilvl_d(__lsx_vldi(0), __lsx_vldrepl_d((const __m128i*)&rgba64, 0));
+    const __m128i shuffleMask = (__m128i)(v8i16){2, 1, 0, 3, 4, 5, 6, 7};
+    v = __lsx_vshuf_h(shuffleMask, __lsx_vldi(0), v);
+    return toArgb32(v);
 #elif defined __ARM_NEON__
     uint16x4_t v = vreinterpret_u16_u64(vld1_u64(reinterpret_cast<const uint64_t *>(&rgba64)));
 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
@@ -220,6 +275,9 @@ Q_ALWAYS_INLINE uint toRgba8888(QRgba64 rgba64)
 #if defined __SSE2__
     __m128i v = _mm_loadl_epi64((const __m128i *)&rgba64);
     return toArgb32(v);
+#elif defined __loongarch_sx
+    __m128i v = __lsx_vilvl_d(__lsx_vldi(0), __lsx_vldrepl_d((const __m128i*)&rgba64, 0));
+    return toArgb32(v);
 #elif defined __ARM_NEON__
     uint16x4_t v = vreinterpret_u16_u64(vld1_u64(reinterpret_cast<const uint64_t *>(&rgba64)));
     return toArgb32(v);
@@ -248,6 +306,24 @@ inline QRgba64 rgbBlend(QRgba64 d, QRgba64 s, uint rgbAlpha)
     vd = _mm_packs_epi32(vd, _mm_setzero_si128());
 
     _mm_storel_epi64((__m128i *)&blend, vd);
+#elif defined(__loongarch_sx)
+    const __m128i zero = __lsx_vldi(0);
+    __m128i vd = __lsx_vilvl_d(zero, __lsx_vldrepl_d((const __m128i *)&d, 0));
+    __m128i vs = __lsx_vilvl_d(zero, __lsx_vldrepl_d((const __m128i *)&s, 0));
+    __m128i va = __lsx_vinsgr2vr_w(zero, rgbAlpha, 0);
+    va = __lsx_vilvl_b(va, va);
+    const __m128i shuffleMask = (__m128i)(v8i16){2, 1, 0, 3, 4, 5, 6, 7};
+    va = __lsx_vshuf_h(shuffleMask, zero, va);
+    __m128i vb = __lsx_vxor_v(__lsx_vreplgr2vr_h(-1), va);
+
+    vs = __lsx_vilvl_h(__lsx_vmuh_hu(vs, va), __lsx_vmul_h(vs, va));
+    vd = __lsx_vilvl_h(__lsx_vmuh_hu(vd, vb), __lsx_vmul_h(vd, vb));
+    vd = __lsx_vadd_w(vd, vs);
+    vd = __lsx_vadd_w(vd, __lsx_vsrli_w(vd, 16));
+    vd = __lsx_vadd_w(vd, __lsx_vreplgr2vr_w(0x8000));
+    vd = __lsx_vsrai_w(vd, 16);
+    vd = __lsx_vpickev_h(zero, __lsx_vsat_w(vd, 15));
+    __lsx_vstelm_d(vd, (__m128i *)&blend, 0, 0);
 #elif defined(__ARM_NEON__)
     uint16x4_t vd = vreinterpret_u16_u64(vmov_n_u64(d));
     uint16x4_t vs = vreinterpret_u16_u64(vmov_n_u64(s));

保存上述 diff 为 simd_loongarch_support.patch

cd C:\src\qt5\qtbase
git apply simd_loongarch_support.patch

步骤三:配置环境变量

CMD 命令行窗口 中设置以下环境变量,这些变量将指导 configure 脚本找到正确的工具链和 SDK。

REM 确保您位于 Qt 源码的 qtbase 目录下
cd C:\src\qt5

REM 1. 设置 OpenHarmony SDK 路径 (请根据您的实际路径修改)
SET OHOS_SDK_PATH=C:\windows-ohos-sdk\12

REM 2. 设置 OpenHarmony SDK 的 sysroot 路径
SET OHOS_SDK_SYSROOT=%OHOS_SDK_PATH%\native\sysroot

REM 3. 设置 LLVM 工具链路径
SET LLVM_INSTALL_DIR=%OHOS_SDK_PATH%\native\llvm

REM 4. 设置要跳过的 Qt 模块,以加快编译速度和减小体积
SET QT_SKIPS=-skip qtactiveqt -skip qtandroidextras -skip qtcanvas3d -skip qtdatavis3d -skip qtdoc -skip qtgamepad -skip qtgraphicaleffects -skip qtlocation -skip qtmacextras -skip qtnetworkauth -skip qtpurchasing -skip qtremoteobjects -skip qtrepotools -skip qtscript -skip qtscxml -skip qtserialbus -skip qtserialport -skip qtspeech -skip qtsystems -skip qttools -skip qttranslations -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebglplugin -skip qtwebsockets -skip qtwinextras -skip qtx11extras -no-dbus

步骤四:配置、编译与安装

继续在同一个 CMD 窗口中执行以下命令。

  1. 运行 Configure 此命令使用 oh-clang 交叉编译平台,并指定目标架构为 loongarch64
    mkdir build
    cd build
    ..\configure.bat -xplatform oh-clang -device-option OHOS_ARCH=loongarch64 -release -opensource -confirm-license %QT_SKIPS% -nomake tests -nomake examples -prefix ./qtoh

    configure 参数解析:

    • -xplatform oh-clang: 指定使用 oh-clang 平台规格文件,这是 OpenHarmony 平台特有的编译配置。
    • -device-option OHOS_ARCH=loongarch64: 明确告诉配置脚本,目标设备的架构是 loongarch64。
    • -release: 编译发布版本,优化性能。
    • -opensource: 声明使用开源许可证(LGPL)。
    • -confirm-license: 自动确认许可证,避免交互式提示。
    • %QT_SKIPS%: 使用前面定义的环境变量,跳过不需要的模块。
    • -nomake tests -nomake examples: 不编译测试和示例项目,进一步节省编译时间和磁盘空间。
    • -prefix ./qtoh: 指定了安装目录。编译完成后,SDK 将被安装到编译目录下的 qtoh 文件夹中。
  2. 执行编译 使用 mingw32-make 进行编译。为了利用多核 CPU 加快速度,可以使用 -j 参数。
    REM 使用 %NUMBER_OF_PROCESSORS% 自动获取 CPU 核心数
    mingw32-make -j%NUMBER_OF_PROCESSORS%
    
    REM 或者手动指定核心数,例如 8 核
    REM mingw32-make -j8

编译过程将花费较长时间,请耐心等待。

  1. 安装到目标目录 编译完成后,执行安装命令,将生成的文件复制到 -prefix 指定的目录。
    mingw32-make install

4. 编译完成

当 install 命令成功执行后,您将在 C:\src\qt5\build\qtoh 目录下找到为 OpenHarmony (LoongArch64) 编译好的 Qt SDK。该 SDK 包含了头文件、库文件和相关工具,可以用于后续的应用程序开发。