Merge tag 'pull-loongarch-20230920' of https://gitlab.com/gaosong/qemu into staging

Add LASX instructions support.

# -----BEGIN PGP SIGNATURE-----
#
# iLMEAAEIAB0WIQS4/x2g0v3LLaCcbCxAov/yOSY+3wUCZQqV7wAKCRBAov/yOSY+
# 35GTA/9rXGbr9pIUnlGstUnWzIJb0vs6f4kt9DaKRPF1zyxaF/59sgl3gqCNAjBA
# eAKfm5W4B8ABJ+PYR3ZVAg9AcAP9AOEi+qV6DgRwvYPPK3WbGqIpJL7i+7gNMMUs
# gppv+IfJEkri8YLXXa7GWffuGOebqdqyD6Pl1B2eiKS4KYSRGw==
# =fNr2
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 20 Sep 2023 02:49:19 EDT
# gpg:                using RSA key B8FF1DA0D2FDCB2DA09C6C2C40A2FFF239263EDF
# gpg: Good signature from "Song Gao <m17746591750@163.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: B8FF 1DA0 D2FD CB2D A09C  6C2C 40A2 FFF2 3926 3EDF

* tag 'pull-loongarch-20230920' of https://gitlab.com/gaosong/qemu: (57 commits)
  target/loongarch: CPUCFG support LASX
  target/loongarch: Move simply DO_XX marcos togther
  target/loongarch: Implement xvld xvst
  target/loongarch: Implement xvshuf xvperm{i} xvshuf4i
  target/loongarch: Implement xvpack xvpick xvilv{l/h}
  target/loongarch: Implement xvreplve xvinsve0 xvpickve
  target/loongarch: Implement xvinsgr2vr xvpickve2gr
  target/loongarch: Implement xvbitsel xvset
  target/loongarch: Implement xvfcmp
  target/loongarch: Implement xvseq xvsle xvslt
  target/loongarch: Implement LASX fpu fcvt instructions
  target/loongarch: Implement LASX fpu arith instructions
  target/loongarch: Implement xvfrstp
  target/loongarch: Implement xvbitclr xvbitset xvbitrev
  target/loongarch: Implement xvpcnt
  target/loongarch: Implement xvclo xvclz
  target/loongarch: Implement xvssrlrn xvssrarn
  target/loongarch: Implement xvssrln xvssran
  target/loongarch: Implement xvsrlrn xvsrarn
  target/loongarch: Implement xvsrln xvsran
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi
2023-09-20 13:56:18 -04:00
16 changed files with 7350 additions and 4051 deletions
+1
View File
@@ -12,6 +12,7 @@
#include "linux-user/trace.h"
#include "target/loongarch/internals.h"
#include "target/loongarch/vec.h"
/* FP context was used */
#define SC_USED_FP (1 << 0)
+4
View File
@@ -19,6 +19,7 @@
#include "cpu-csr.h"
#include "sysemu/reset.h"
#include "tcg/tcg.h"
#include "vec.h"
const char * const regnames[32] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -54,6 +55,7 @@ static const char * const excp_names[] = {
[EXCCODE_DBP] = "Debug breakpoint",
[EXCCODE_BCE] = "Bound Check Exception",
[EXCCODE_SXD] = "128 bit vector instructions Disable exception",
[EXCCODE_ASXD] = "256 bit vector instructions Disable exception",
};
const char *loongarch_exception_name(int32_t exception)
@@ -189,6 +191,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
case EXCCODE_FPD:
case EXCCODE_FPE:
case EXCCODE_SXD:
case EXCCODE_ASXD:
env->CSR_BADV = env->pc;
QEMU_FALLTHROUGH;
case EXCCODE_BCE:
@@ -390,6 +393,7 @@ static void loongarch_la464_initfn(Object *obj)
data = FIELD_DP32(data, CPUCFG2, FP_DP, 1);
data = FIELD_DP32(data, CPUCFG2, FP_VER, 1);
data = FIELD_DP32(data, CPUCFG2, LSX, 1),
data = FIELD_DP32(data, CPUCFG2, LASX, 1),
data = FIELD_DP32(data, CPUCFG2, LLFTP, 1);
data = FIELD_DP32(data, CPUCFG2, LLFTP_VER, 1);
data = FIELD_DP32(data, CPUCFG2, LSPW, 1);
+15 -11
View File
@@ -251,18 +251,20 @@ FIELD(TLB_MISC, ASID, 1, 10)
FIELD(TLB_MISC, VPPN, 13, 35)
FIELD(TLB_MISC, PS, 48, 6)
#define LSX_LEN (128)
#define LSX_LEN (128)
#define LASX_LEN (256)
typedef union VReg {
int8_t B[LSX_LEN / 8];
int16_t H[LSX_LEN / 16];
int32_t W[LSX_LEN / 32];
int64_t D[LSX_LEN / 64];
uint8_t UB[LSX_LEN / 8];
uint16_t UH[LSX_LEN / 16];
uint32_t UW[LSX_LEN / 32];
uint64_t UD[LSX_LEN / 64];
Int128 Q[LSX_LEN / 128];
}VReg;
int8_t B[LASX_LEN / 8];
int16_t H[LASX_LEN / 16];
int32_t W[LASX_LEN / 32];
int64_t D[LASX_LEN / 64];
uint8_t UB[LASX_LEN / 8];
uint16_t UH[LASX_LEN / 16];
uint32_t UW[LASX_LEN / 32];
uint64_t UD[LASX_LEN / 64];
Int128 Q[LASX_LEN / 128];
} VReg;
typedef union fpr_t fpr_t;
union fpr_t {
@@ -460,6 +462,7 @@ static inline void set_pc(CPULoongArchState *env, uint64_t value)
#define HW_FLAGS_CRMD_PG R_CSR_CRMD_PG_MASK /* 0x10 */
#define HW_FLAGS_EUEN_FPE 0x04
#define HW_FLAGS_EUEN_SXE 0x08
#define HW_FLAGS_EUEN_ASXE 0x10
#define HW_FLAGS_VA32 0x20
static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,
@@ -470,6 +473,7 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,
*flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK);
*flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE;
*flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE;
*flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE) * HW_FLAGS_EUEN_ASXE;
*flags |= is_va32(env) * HW_FLAGS_VA32;
}
File diff suppressed because it is too large Load Diff
+1
View File
@@ -11,6 +11,7 @@
#include "internals.h"
#include "exec/gdbstub.h"
#include "gdbstub/helpers.h"
#include "vec.h"
uint64_t read_fcc(CPULoongArchState *env)
{
+326 -305
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-22
View File
@@ -21,28 +21,6 @@
/* Global bit for huge page */
#define LOONGARCH_HGLOBAL_SHIFT 12
#if HOST_BIG_ENDIAN
#define B(x) B[15 - (x)]
#define H(x) H[7 - (x)]
#define W(x) W[3 - (x)]
#define D(x) D[1 - (x)]
#define UB(x) UB[15 - (x)]
#define UH(x) UH[7 - (x)]
#define UW(x) UW[3 - (x)]
#define UD(x) UD[1 -(x)]
#define Q(x) Q[x]
#else
#define B(x) B[x]
#define H(x) H[x]
#define W(x) W[x]
#define D(x) D[x]
#define UB(x) UB[x]
#define UH(x) UH[x]
#define UW(x) UW[x]
#define UD(x) UD[x]
#define Q(x) Q[x]
#endif
void loongarch_translate_init(void);
void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
File diff suppressed because it is too large Load Diff
+35 -1
View File
@@ -8,7 +8,7 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "migration/cpu.h"
#include "internals.h"
#include "vec.h"
static const VMStateDescription vmstate_fpu_reg = {
.name = "fpu_reg",
@@ -76,6 +76,39 @@ static const VMStateDescription vmstate_lsx = {
},
};
static const VMStateDescription vmstate_lasxh_reg = {
.name = "lasxh_reg",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT64(UD(2), VReg),
VMSTATE_UINT64(UD(3), VReg),
VMSTATE_END_OF_LIST()
}
};
#define VMSTATE_LASXH_REGS(_field, _state, _start) \
VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, 32, 0, \
vmstate_lasxh_reg, fpr_t)
static bool lasx_needed(void *opaque)
{
LoongArchCPU *cpu = opaque;
return FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LASX);
}
static const VMStateDescription vmstate_lasx = {
.name = "cpu/lasx",
.version_id = 1,
.minimum_version_id = 1,
.needed = lasx_needed,
.fields = (VMStateField[]) {
VMSTATE_LASXH_REGS(env.fpr, LoongArchCPU, 0),
VMSTATE_END_OF_LIST()
},
};
/* TLB state */
const VMStateDescription vmstate_tlb = {
.name = "cpu/tlb",
@@ -163,6 +196,7 @@ const VMStateDescription vmstate_loongarch_cpu = {
.subsections = (const VMStateDescription*[]) {
&vmstate_fpu,
&vmstate_lsx,
&vmstate_lasx,
NULL
}
};
+1 -1
View File
@@ -11,7 +11,7 @@ loongarch_tcg_ss.add(files(
'op_helper.c',
'translate.c',
'gdbstub.c',
'lsx_helper.c',
'vec_helper.c',
))
loongarch_tcg_ss.add(zlib)
+18 -1
View File
@@ -18,6 +18,7 @@
#include "fpu/softfloat.h"
#include "translate.h"
#include "internals.h"
#include "vec.h"
/* Global register indices */
TCGv cpu_gpr[32], cpu_pc;
@@ -36,6 +37,18 @@ static inline int vec_full_offset(int regno)
return offsetof(CPULoongArchState, fpr[regno]);
}
static inline int vec_reg_offset(int regno, int index, MemOp mop)
{
const uint8_t size = 1 << mop;
int offs = index * size;
if (HOST_BIG_ENDIAN && size < 8 ) {
offs ^= (8 - size);
}
return offs + vec_full_offset(regno);
}
static inline void get_vreg64(TCGv_i64 dest, int regno, int index)
{
tcg_gen_ld_i64(dest, cpu_env,
@@ -123,6 +136,10 @@ static void loongarch_tr_init_disas_context(DisasContextBase *dcbase,
ctx->vl = LSX_LEN;
}
if (FIELD_EX64(env->cpucfg[2], CPUCFG2, LASX)) {
ctx->vl = LASX_LEN;
}
ctx->la64 = is_la64(env);
ctx->va32 = (ctx->base.tb->flags & HW_FLAGS_VA32) != 0;
@@ -261,7 +278,7 @@ static uint64_t make_address_pc(DisasContext *ctx, uint64_t addr)
#include "insn_trans/trans_fmemory.c.inc"
#include "insn_trans/trans_branch.c.inc"
#include "insn_trans/trans_privileged.c.inc"
#include "insn_trans/trans_lsx.c.inc"
#include "insn_trans/trans_vec.c.inc"
static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
{
+1
View File
@@ -23,6 +23,7 @@
#define avail_LSPW(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, LSPW))
#define avail_LAM(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, LAM))
#define avail_LSX(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, LSX))
#define avail_LASX(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, LASX))
#define avail_IOCSR(C) (FIELD_EX32((C)->cpucfg1, CPUCFG1, IOCSR))
/*
+75
View File
@@ -0,0 +1,75 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* QEMU LoongArch vector utilitites
*
* Copyright (c) 2023 Loongson Technology Corporation Limited
*/
#ifndef LOONGARCH_VEC_H
#define LOONGARCH_VEC_H
#if HOST_BIG_ENDIAN
#define B(x) B[(x) ^ 15]
#define H(x) H[(x) ^ 7]
#define W(x) W[(x) ^ 3]
#define D(x) D[(x) ^ 1]
#define UB(x) UB[(x) ^ 15]
#define UH(x) UH[(x) ^ 7]
#define UW(x) UW[(x) ^ 3]
#define UD(x) UD[(x) ^ 1]
#define Q(x) Q[x]
#else
#define B(x) B[x]
#define H(x) H[x]
#define W(x) W[x]
#define D(x) D[x]
#define UB(x) UB[x]
#define UH(x) UH[x]
#define UW(x) UW[x]
#define UD(x) UD[x]
#define Q(x) Q[x]
#endif /* HOST_BIG_ENDIAN */
#define DO_ADD(a, b) (a + b)
#define DO_SUB(a, b) (a - b)
#define DO_VAVG(a, b) ((a >> 1) + (b >> 1) + (a & b & 1))
#define DO_VAVGR(a, b) ((a >> 1) + (b >> 1) + ((a | b) & 1))
#define DO_VABSD(a, b) ((a > b) ? (a -b) : (b-a))
#define DO_VABS(a) ((a < 0) ? (-a) : (a))
#define DO_MIN(a, b) (a < b ? a : b)
#define DO_MAX(a, b) (a > b ? a : b)
#define DO_MUL(a, b) (a * b)
#define DO_MADD(a, b, c) (a + b * c)
#define DO_MSUB(a, b, c) (a - b * c)
#define DO_DIVU(N, M) (unlikely(M == 0) ? 0 : N / M)
#define DO_REMU(N, M) (unlikely(M == 0) ? 0 : N % M)
#define DO_DIV(N, M) (unlikely(M == 0) ? 0 :\
unlikely((N == -N) && (M == (__typeof(N))(-1))) ? N : N / M)
#define DO_REM(N, M) (unlikely(M == 0) ? 0 :\
unlikely((N == -N) && (M == (__typeof(N))(-1))) ? 0 : N % M)
#define DO_SIGNCOV(a, b) (a == 0 ? 0 : a < 0 ? -b : b)
#define R_SHIFT(a, b) (a >> b)
#define DO_CLO_B(N) (clz32(~N & 0xff) - 24)
#define DO_CLO_H(N) (clz32(~N & 0xffff) - 16)
#define DO_CLO_W(N) (clz32(~N))
#define DO_CLO_D(N) (clz64(~N))
#define DO_CLZ_B(N) (clz32(N) - 24)
#define DO_CLZ_H(N) (clz32(N) - 16)
#define DO_CLZ_W(N) (clz32(N))
#define DO_CLZ_D(N) (clz64(N))
#define DO_BITCLR(a, bit) (a & ~(1ull << bit))
#define DO_BITSET(a, bit) (a | 1ull << bit)
#define DO_BITREV(a, bit) (a ^ (1ull << bit))
#define VSEQ(a, b) (a == b ? -1 : 0)
#define VSLE(a, b) (a <= b ? -1 : 0)
#define VSLT(a, b) (a < b ? -1 : 0)
#define SHF_POS(i, imm) (((i) & 0xfc) + (((imm) >> (2 * ((i) & 0x03))) & 0x03))
#endif /* LOONGARCH_VEC_H */
File diff suppressed because it is too large Load Diff