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

pull-loongarch-20230824

# -----BEGIN PGP SIGNATURE-----
#
# iLMEAAEIAB0WIQS4/x2g0v3LLaCcbCxAov/yOSY+3wUCZOcdAwAKCRBAov/yOSY+
# 3w3CA/sH8+Ay+Qnaqa2vEyuhOlFQuxHKeR7mYfsitAdzh8yMK2K8C2iBUzDzL1H3
# kZmZbCcYX7ko9RLhsuXmvfBJ7iwzY55ozSHLIjJ/VS4JVE5B0cUSZ5jjIPDqpzDs
# 7TUt9qpTkwg0e+klzVREWLSWP5xopvkRvFHZM3KZZhGMphOTUQ==
# =/HHZ
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 24 Aug 2023 05:04:03 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-20230824' of https://gitlab.com/gaosong/qemu: (31 commits)
  hw/loongarch: Fix ACPI processor id off-by-one error
  target/loongarch: Split fcc register to fcc0-7 in gdbstub
  hw/intc/loongarch_pch: fix edge triggered irq handling
  target/loongarch: cpu: Implement get_arch_id callback
  target/loongarch: Add avail_IOCSR to check iocsr instructions
  target/loongarch: Add avail_LSX to check LSX instructions
  target/loongarch: Add avail_LAM to check atomic instructions
  target/loongarch: Add avail_LSPW to check LSPW instructions
  target/loongarch: Add avail_FP/FP_SP/FP_DP to check fpu instructions
  hw/loongarch: Remove restriction of la464 cores in the virt machine
  target/loongarch: Add LoongArch32 cpu la132
  target/loongarch: Add avail_64 to check la64-only instructions
  target/loongarch: Add a check parameter to the TRANS macro
  target/loongarch: Sign extend results in VA32 mode
  target/loongarch: Truncate high 32 bits of address in VA32 mode
  target/loongarch: Extract set_pc() helper
  target/loongarch: Extract make_address_pc() helper
  target/loongarch: Extract make_address_i() helper
  target/loongarch: Extract make_address_x() helper
  target/loongarch: Add LA64 & VA32 to DisasContext
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi
2023-08-24 09:17:05 -04:00
28 changed files with 1548 additions and 1050 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
TARGET_ARCH=loongarch64
TARGET_BASE_ARCH=loongarch
TARGET_SUPPORTS_MTTCG=y
TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml
TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml
TARGET_NEED_FDT=y
+45
View File
@@ -0,0 +1,45 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2022 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. -->
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.loongarch.base">
<reg name="r0" bitsize="32" type="uint32" group="general"/>
<reg name="r1" bitsize="32" type="code_ptr" group="general"/>
<reg name="r2" bitsize="32" type="data_ptr" group="general"/>
<reg name="r3" bitsize="32" type="data_ptr" group="general"/>
<reg name="r4" bitsize="32" type="uint32" group="general"/>
<reg name="r5" bitsize="32" type="uint32" group="general"/>
<reg name="r6" bitsize="32" type="uint32" group="general"/>
<reg name="r7" bitsize="32" type="uint32" group="general"/>
<reg name="r8" bitsize="32" type="uint32" group="general"/>
<reg name="r9" bitsize="32" type="uint32" group="general"/>
<reg name="r10" bitsize="32" type="uint32" group="general"/>
<reg name="r11" bitsize="32" type="uint32" group="general"/>
<reg name="r12" bitsize="32" type="uint32" group="general"/>
<reg name="r13" bitsize="32" type="uint32" group="general"/>
<reg name="r14" bitsize="32" type="uint32" group="general"/>
<reg name="r15" bitsize="32" type="uint32" group="general"/>
<reg name="r16" bitsize="32" type="uint32" group="general"/>
<reg name="r17" bitsize="32" type="uint32" group="general"/>
<reg name="r18" bitsize="32" type="uint32" group="general"/>
<reg name="r19" bitsize="32" type="uint32" group="general"/>
<reg name="r20" bitsize="32" type="uint32" group="general"/>
<reg name="r21" bitsize="32" type="uint32" group="general"/>
<reg name="r22" bitsize="32" type="data_ptr" group="general"/>
<reg name="r23" bitsize="32" type="uint32" group="general"/>
<reg name="r24" bitsize="32" type="uint32" group="general"/>
<reg name="r25" bitsize="32" type="uint32" group="general"/>
<reg name="r26" bitsize="32" type="uint32" group="general"/>
<reg name="r27" bitsize="32" type="uint32" group="general"/>
<reg name="r28" bitsize="32" type="uint32" group="general"/>
<reg name="r29" bitsize="32" type="uint32" group="general"/>
<reg name="r30" bitsize="32" type="uint32" group="general"/>
<reg name="r31" bitsize="32" type="uint32" group="general"/>
<reg name="orig_a0" bitsize="32" type="uint32" group="general"/>
<reg name="pc" bitsize="32" type="code_ptr" group="general"/>
<reg name="badv" bitsize="32" type="code_ptr" group="general"/>
</feature>
+8 -1
View File
@@ -45,6 +45,13 @@
<reg name="f29" bitsize="64" type="fputype" group="float"/>
<reg name="f30" bitsize="64" type="fputype" group="float"/>
<reg name="f31" bitsize="64" type="fputype" group="float"/>
<reg name="fcc" bitsize="64" type="uint64" group="float"/>
<reg name="fcc0" bitsize="8" type="uint8" group="float"/>
<reg name="fcc1" bitsize="8" type="uint8" group="float"/>
<reg name="fcc2" bitsize="8" type="uint8" group="float"/>
<reg name="fcc3" bitsize="8" type="uint8" group="float"/>
<reg name="fcc4" bitsize="8" type="uint8" group="float"/>
<reg name="fcc5" bitsize="8" type="uint8" group="float"/>
<reg name="fcc6" bitsize="8" type="uint8" group="float"/>
<reg name="fcc7" bitsize="8" type="uint8" group="float"/>
<reg name="fcsr" bitsize="32" type="uint32" group="float"/>
</feature>
+6 -1
View File
@@ -30,7 +30,11 @@ static void pch_pic_update_irq(LoongArchPCHPIC *s, uint64_t mask, int level)
qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
}
} else {
val = mask & s->intisr;
/*
* intirr means requested pending irq
* do not clear pending irq for edge-triggered on lowering edge
*/
val = mask & s->intisr & ~s->intirr;
if (val) {
irq = ctz64(val);
s->intisr &= ~MAKE_64BIT_MASK(irq, 1);
@@ -51,6 +55,7 @@ static void pch_pic_irq_handler(void *opaque, int irq, int level)
/* Edge triggered */
if (level) {
if ((s->last_intirr & mask) == 0) {
/* marked pending on a rising edge */
s->intirr |= mask;
}
s->last_intirr |= mask;
+1 -1
View File
@@ -127,7 +127,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams)
build_append_int_noprefix(table_data, 17, 1); /* Type */
build_append_int_noprefix(table_data, 15, 1); /* Length */
build_append_int_noprefix(table_data, 1, 1); /* Version */
build_append_int_noprefix(table_data, i + 1, 4); /* ACPI Processor ID */
build_append_int_noprefix(table_data, i, 4); /* ACPI Processor ID */
build_append_int_noprefix(table_data, arch_id, 4); /* Core ID */
build_append_int_noprefix(table_data, 1, 4); /* Flags */
}
+2 -5
View File
@@ -798,11 +798,6 @@ static void loongarch_init(MachineState *machine)
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
}
if (!strstr(cpu_model, "la464")) {
error_report("LoongArch/TCG needs cpu type la464");
exit(1);
}
if (ram_size < 1 * GiB) {
error_report("ram_size must be greater than 1G.");
exit(1);
@@ -815,6 +810,8 @@ static void loongarch_init(MachineState *machine)
cpu = cpu_create(machine->cpu_type);
cpu->cpu_index = i;
machine->possible_cpus->cpus[i].cpu = OBJECT(cpu);
lacpu = LOONGARCH_CPU(cpu);
lacpu->phy_id = machine->possible_cpus->cpus[i].arch_id;
}
fdt_add_cpu_nodes(lams);
+12 -10
View File
@@ -57,7 +57,8 @@ FIELD(CSR_TLBIDX, PS, 24, 6)
FIELD(CSR_TLBIDX, NE, 31, 1)
#define LOONGARCH_CSR_TLBEHI 0x11 /* TLB EntryHi */
FIELD(CSR_TLBEHI, VPPN, 13, 35)
FIELD(CSR_TLBEHI_32, VPPN, 13, 19)
FIELD(CSR_TLBEHI_64, VPPN, 13, 35)
#define LOONGARCH_CSR_TLBELO0 0x12 /* TLB EntryLo0 */
#define LOONGARCH_CSR_TLBELO1 0x13 /* TLB EntryLo1 */
@@ -66,10 +67,11 @@ FIELD(TLBENTRY, D, 1, 1)
FIELD(TLBENTRY, PLV, 2, 2)
FIELD(TLBENTRY, MAT, 4, 2)
FIELD(TLBENTRY, G, 6, 1)
FIELD(TLBENTRY, PPN, 12, 36)
FIELD(TLBENTRY, NR, 61, 1)
FIELD(TLBENTRY, NX, 62, 1)
FIELD(TLBENTRY, RPLV, 63, 1)
FIELD(TLBENTRY_32, PPN, 8, 24)
FIELD(TLBENTRY_64, PPN, 12, 36)
FIELD(TLBENTRY_64, NR, 61, 1)
FIELD(TLBENTRY_64, NX, 62, 1)
FIELD(TLBENTRY_64, RPLV, 63, 1)
#define LOONGARCH_CSR_ASID 0x18 /* Address space identifier */
FIELD(CSR_ASID, ASID, 0, 10)
@@ -163,7 +165,8 @@ FIELD(CSR_TLBRERA, PC, 2, 62)
#define LOONGARCH_CSR_TLBRELO1 0x8d /* TLB refill entrylo1 */
#define LOONGARCH_CSR_TLBREHI 0x8e /* TLB refill entryhi */
FIELD(CSR_TLBREHI, PS, 0, 6)
FIELD(CSR_TLBREHI, VPPN, 13, 35)
FIELD(CSR_TLBREHI_32, VPPN, 13, 19)
FIELD(CSR_TLBREHI_64, VPPN, 13, 35)
#define LOONGARCH_CSR_TLBRPRMD 0x8f /* TLB refill mode info */
FIELD(CSR_TLBRPRMD, PPLV, 0, 2)
FIELD(CSR_TLBRPRMD, PIE, 2, 1)
@@ -187,10 +190,9 @@ FIELD(CSR_DMW, PLV1, 1, 1)
FIELD(CSR_DMW, PLV2, 2, 1)
FIELD(CSR_DMW, PLV3, 3, 1)
FIELD(CSR_DMW, MAT, 4, 2)
FIELD(CSR_DMW, VSEG, 60, 4)
#define dmw_va2pa(va) \
(va & MAKE_64BIT_MASK(0, TARGET_VIRT_ADDR_SPACE_BITS))
FIELD(CSR_DMW_32, PSEG, 25, 3)
FIELD(CSR_DMW_32, VSEG, 29, 3)
FIELD(CSR_DMW_64, VSEG, 60, 4)
/* Debug CSRs */
#define LOONGARCH_CSR_DBG 0x500 /* debug config */
+92 -18
View File
@@ -81,7 +81,7 @@ static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
env->pc = value;
set_pc(env, value);
}
static vaddr loongarch_cpu_get_pc(CPUState *cs)
@@ -168,7 +168,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
set_DERA:
env->CSR_DERA = env->pc;
env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DST, 1);
env->pc = env->CSR_EENTRY + 0x480;
set_pc(env, env->CSR_EENTRY + 0x480);
break;
case EXCCODE_INT:
if (FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) {
@@ -249,7 +249,8 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
/* Find the highest-priority interrupt. */
vector = 31 - clz32(pending);
env->pc = env->CSR_EENTRY + (EXCCODE_EXTERNAL_INT + vector) * vec_size;
set_pc(env, env->CSR_EENTRY + \
(EXCCODE_EXTERNAL_INT + vector) * vec_size);
qemu_log_mask(CPU_LOG_INT,
"%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
" cause %d\n" " A " TARGET_FMT_lx " D "
@@ -260,10 +261,9 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
env->CSR_ECFG, env->CSR_ESTAT);
} else {
if (tlbfill) {
env->pc = env->CSR_TLBRENTRY;
set_pc(env, env->CSR_TLBRENTRY);
} else {
env->pc = env->CSR_EENTRY;
env->pc += EXCODE_MCODE(cause) * vec_size;
set_pc(env, env->CSR_EENTRY + EXCODE_MCODE(cause) * vec_size);
}
qemu_log_mask(CPU_LOG_INT,
"%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
@@ -324,7 +324,7 @@ static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
CPULoongArchState *env = &cpu->env;
tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
env->pc = tb->pc;
set_pc(env, tb->pc);
}
static void loongarch_restore_state_to_opc(CPUState *cs,
@@ -334,7 +334,7 @@ static void loongarch_restore_state_to_opc(CPUState *cs,
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
env->pc = data[0];
set_pc(env, data[0]);
}
#endif /* CONFIG_TCG */
@@ -391,6 +391,7 @@ static void loongarch_la464_initfn(Object *obj)
data = FIELD_DP32(data, CPUCFG2, LSX, 1),
data = FIELD_DP32(data, CPUCFG2, LLFTP, 1);
data = FIELD_DP32(data, CPUCFG2, LLFTP_VER, 1);
data = FIELD_DP32(data, CPUCFG2, LSPW, 1);
data = FIELD_DP32(data, CPUCFG2, LAM, 1);
env->cpucfg[2] = data;
@@ -439,6 +440,35 @@ static void loongarch_la464_initfn(Object *obj)
env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);
}
static void loongarch_la132_initfn(Object *obj)
{
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
CPULoongArchState *env = &cpu->env;
int i;
for (i = 0; i < 21; i++) {
env->cpucfg[i] = 0x0;
}
cpu->dtb_compatible = "loongarch,Loongson-1C103";
env->cpucfg[0] = 0x148042; /* PRID */
uint32_t data = 0;
data = FIELD_DP32(data, CPUCFG1, ARCH, 1); /* LA32 */
data = FIELD_DP32(data, CPUCFG1, PGMMU, 1);
data = FIELD_DP32(data, CPUCFG1, IOCSR, 1);
data = FIELD_DP32(data, CPUCFG1, PALEN, 0x1f); /* 32 bits */
data = FIELD_DP32(data, CPUCFG1, VALEN, 0x1f); /* 32 bits */
data = FIELD_DP32(data, CPUCFG1, UAL, 1);
data = FIELD_DP32(data, CPUCFG1, RI, 0);
data = FIELD_DP32(data, CPUCFG1, EP, 0);
data = FIELD_DP32(data, CPUCFG1, RPLV, 0);
data = FIELD_DP32(data, CPUCFG1, HP, 1);
data = FIELD_DP32(data, CPUCFG1, IOCSR_BRD, 1);
env->cpucfg[1] = data;
}
static void loongarch_cpu_list_entry(gpointer data, gpointer user_data)
{
const char *typename = object_class_get_name(OBJECT_CLASS(data));
@@ -544,6 +574,8 @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp)
static void loongarch_qemu_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
qemu_log_mask(LOG_UNIMP, "[%s]: Unimplemented reg 0x%" HWADDR_PRIx "\n",
__func__, addr);
}
static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size)
@@ -690,12 +722,14 @@ static struct TCGCPUOps loongarch_tcg_ops = {
static const struct SysemuCPUOps loongarch_sysemu_ops = {
.get_phys_page_debug = loongarch_cpu_get_phys_page_debug,
};
#endif
static gchar *loongarch_gdb_arch_name(CPUState *cs)
static int64_t loongarch_cpu_get_arch_id(CPUState *cs)
{
return g_strdup("loongarch64");
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
return cpu->phy_id;
}
#endif
static void loongarch_cpu_class_init(ObjectClass *c, void *data)
{
@@ -715,26 +749,51 @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data)
cc->set_pc = loongarch_cpu_set_pc;
cc->get_pc = loongarch_cpu_get_pc;
#ifndef CONFIG_USER_ONLY
cc->get_arch_id = loongarch_cpu_get_arch_id;
dc->vmsd = &vmstate_loongarch_cpu;
cc->sysemu_ops = &loongarch_sysemu_ops;
#endif
cc->disas_set_info = loongarch_cpu_disas_set_info;
cc->gdb_read_register = loongarch_cpu_gdb_read_register;
cc->gdb_write_register = loongarch_cpu_gdb_write_register;
cc->disas_set_info = loongarch_cpu_disas_set_info;
cc->gdb_num_core_regs = 35;
cc->gdb_core_xml_file = "loongarch-base64.xml";
cc->gdb_stop_before_watchpoint = true;
cc->gdb_arch_name = loongarch_gdb_arch_name;
#ifdef CONFIG_TCG
cc->tcg_ops = &loongarch_tcg_ops;
#endif
}
#define DEFINE_LOONGARCH_CPU_TYPE(model, initfn) \
static gchar *loongarch32_gdb_arch_name(CPUState *cs)
{
return g_strdup("loongarch32");
}
static void loongarch32_cpu_class_init(ObjectClass *c, void *data)
{
CPUClass *cc = CPU_CLASS(c);
cc->gdb_num_core_regs = 35;
cc->gdb_core_xml_file = "loongarch-base32.xml";
cc->gdb_arch_name = loongarch32_gdb_arch_name;
}
static gchar *loongarch64_gdb_arch_name(CPUState *cs)
{
return g_strdup("loongarch64");
}
static void loongarch64_cpu_class_init(ObjectClass *c, void *data)
{
CPUClass *cc = CPU_CLASS(c);
cc->gdb_num_core_regs = 35;
cc->gdb_core_xml_file = "loongarch-base64.xml";
cc->gdb_arch_name = loongarch64_gdb_arch_name;
}
#define DEFINE_LOONGARCH_CPU_TYPE(size, model, initfn) \
{ \
.parent = TYPE_LOONGARCH_CPU, \
.parent = TYPE_LOONGARCH##size##_CPU, \
.instance_init = initfn, \
.name = LOONGARCH_CPU_TYPE_NAME(model), \
}
@@ -750,7 +809,22 @@ static const TypeInfo loongarch_cpu_type_infos[] = {
.class_size = sizeof(LoongArchCPUClass),
.class_init = loongarch_cpu_class_init,
},
DEFINE_LOONGARCH_CPU_TYPE("la464", loongarch_la464_initfn),
{
.name = TYPE_LOONGARCH32_CPU,
.parent = TYPE_LOONGARCH_CPU,
.abstract = true,
.class_init = loongarch32_cpu_class_init,
},
{
.name = TYPE_LOONGARCH64_CPU,
.parent = TYPE_LOONGARCH_CPU,
.abstract = true,
.class_init = loongarch64_cpu_class_init,
},
DEFINE_LOONGARCH_CPU_TYPE(64, "la464", loongarch_la464_initfn),
DEFINE_LOONGARCH_CPU_TYPE(32, "la132", loongarch_la132_initfn),
};
DEFINE_TYPES(loongarch_cpu_type_infos)
+35
View File
@@ -132,6 +132,11 @@ FIELD(CPUCFG1, HP, 24, 1)
FIELD(CPUCFG1, IOCSR_BRD, 25, 1)
FIELD(CPUCFG1, MSG_INT, 26, 1)
/* cpucfg[1].arch */
#define CPUCFG1_ARCH_LA32R 0
#define CPUCFG1_ARCH_LA32 1
#define CPUCFG1_ARCH_LA64 2
/* cpucfg[2] bits */
FIELD(CPUCFG2, FP, 0, 1)
FIELD(CPUCFG2, FP_SP, 1, 1)
@@ -371,12 +376,15 @@ struct ArchCPU {
CPUNegativeOffsetState neg;
CPULoongArchState env;
QEMUTimer timer;
uint32_t phy_id;
/* 'compatible' string for this CPU for Linux device trees */
const char *dtb_compatible;
};
#define TYPE_LOONGARCH_CPU "loongarch-cpu"
#define TYPE_LOONGARCH32_CPU "loongarch32-cpu"
#define TYPE_LOONGARCH64_CPU "loongarch64-cpu"
OBJECT_DECLARE_CPU_TYPE(LoongArchCPU, LoongArchCPUClass,
LOONGARCH_CPU)
@@ -420,6 +428,31 @@ static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
#endif
}
static inline bool is_la64(CPULoongArchState *env)
{
return FIELD_EX32(env->cpucfg[1], CPUCFG1, ARCH) == CPUCFG1_ARCH_LA64;
}
static inline bool is_va32(CPULoongArchState *env)
{
/* VA32 if !LA64 or VA32L[1-3] */
bool va32 = !is_la64(env);
uint64_t plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
if (plv >= 1 && (FIELD_EX64(env->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) {
va32 = true;
}
return va32;
}
static inline void set_pc(CPULoongArchState *env, uint64_t value)
{
if (is_va32(env)) {
env->pc = (uint32_t)value;
} else {
env->pc = value;
}
}
/*
* LoongArch CPUs hardware flags.
*/
@@ -427,6 +460,7 @@ static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
#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_VA32 0x20
static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,
uint64_t *cs_base, uint32_t *flags)
@@ -436,6 +470,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 |= is_va32(env) * HW_FLAGS_VA32;
}
void loongarch_cpu_list(void);
+33 -17
View File
@@ -34,16 +34,25 @@ int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
uint64_t val;
if (0 <= n && n < 32) {
return gdb_get_regl(mem_buf, env->gpr[n]);
val = env->gpr[n];
} else if (n == 32) {
/* orig_a0 */
return gdb_get_regl(mem_buf, 0);
val = 0;
} else if (n == 33) {
return gdb_get_regl(mem_buf, env->pc);
val = env->pc;
} else if (n == 34) {
return gdb_get_regl(mem_buf, env->CSR_BADV);
val = env->CSR_BADV;
}
if (0 <= n && n <= 34) {
if (is_la64(env)) {
return gdb_get_reg64(mem_buf, val);
} else {
return gdb_get_reg32(mem_buf, val);
}
}
return 0;
}
@@ -52,15 +61,24 @@ int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
target_ulong tmp = ldtul_p(mem_buf);
target_ulong tmp;
int read_length;
int length = 0;
if (is_la64(env)) {
tmp = ldq_p(mem_buf);
read_length = 8;
} else {
tmp = ldl_p(mem_buf);
read_length = 4;
}
if (0 <= n && n < 32) {
env->gpr[n] = tmp;
length = sizeof(target_ulong);
length = read_length;
} else if (n == 33) {
env->pc = tmp;
length = sizeof(target_ulong);
set_pc(env, tmp);
length = read_length;
}
return length;
}
@@ -70,10 +88,9 @@ static int loongarch_gdb_get_fpu(CPULoongArchState *env,
{
if (0 <= n && n < 32) {
return gdb_get_reg64(mem_buf, env->fpr[n].vreg.D(0));
} else if (n == 32) {
uint64_t val = read_fcc(env);
return gdb_get_reg64(mem_buf, val);
} else if (n == 33) {
} else if (32 <= n && n < 40) {
return gdb_get_reg8(mem_buf, env->cf[n - 32]);
} else if (n == 40) {
return gdb_get_reg32(mem_buf, env->fcsr0);
}
return 0;
@@ -87,11 +104,10 @@ static int loongarch_gdb_set_fpu(CPULoongArchState *env,
if (0 <= n && n < 32) {
env->fpr[n].vreg.D(0) = ldq_p(mem_buf);
length = 8;
} else if (n == 32) {
uint64_t val = ldq_p(mem_buf);
write_fcc(env, val);
length = 8;
} else if (n == 33) {
} else if (32 <= n && n < 40) {
env->cf[n - 32] = ldub_p(mem_buf);
length = 1;
} else if (n == 40) {
env->fcsr0 = ldl_p(mem_buf);
length = 4;
}
+55 -43
View File
@@ -72,7 +72,7 @@ static bool gen_pc(DisasContext *ctx, arg_r_i *a,
target_ulong (*func)(target_ulong, int))
{
TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
target_ulong addr = func(ctx->base.pc_next, a->imm);
target_ulong addr = make_address_pc(ctx, func(ctx->base.pc_next, a->imm));
tcg_gen_movi_tl(dest, addr);
gen_set_gpr(a->rd, dest, EXT_NONE);
@@ -199,6 +199,10 @@ static bool trans_lu32i_d(DisasContext *ctx, arg_lu32i_d *a)
TCGv src1 = gpr_src(ctx, a->rd, EXT_NONE);
TCGv src2 = tcg_constant_tl(a->imm);
if (!avail_64(ctx)) {
return false;
}
tcg_gen_deposit_tl(dest, src1, src2, 32, 32);
gen_set_gpr(a->rd, dest, EXT_NONE);
@@ -211,6 +215,10 @@ static bool trans_lu52i_d(DisasContext *ctx, arg_lu52i_d *a)
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
TCGv src2 = tcg_constant_tl(a->imm);
if (!avail_64(ctx)) {
return false;
}
tcg_gen_deposit_tl(dest, src1, src2, 52, 12);
gen_set_gpr(a->rd, dest, EXT_NONE);
@@ -242,51 +250,55 @@ static bool trans_addu16i_d(DisasContext *ctx, arg_addu16i_d *a)
TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
if (!avail_64(ctx)) {
return false;
}
tcg_gen_addi_tl(dest, src1, a->imm << 16);
gen_set_gpr(a->rd, dest, EXT_NONE);
return true;
}
TRANS(add_w, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_add_tl)
TRANS(add_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_add_tl)
TRANS(sub_w, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_sub_tl)
TRANS(sub_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_sub_tl)
TRANS(and, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_and_tl)
TRANS(or, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_or_tl)
TRANS(xor, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_xor_tl)
TRANS(nor, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_nor_tl)
TRANS(andn, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_andc_tl)
TRANS(orn, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_orc_tl)
TRANS(slt, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_slt)
TRANS(sltu, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sltu)
TRANS(mul_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, tcg_gen_mul_tl)
TRANS(mul_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_mul_tl)
TRANS(mulh_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_NONE, gen_mulh_w)
TRANS(mulh_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_NONE, gen_mulh_w)
TRANS(mulh_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_d)
TRANS(mulh_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_du)
TRANS(mulw_d_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_NONE, tcg_gen_mul_tl)
TRANS(mulw_d_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_NONE, tcg_gen_mul_tl)
TRANS(div_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, gen_div_w)
TRANS(mod_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, gen_rem_w)
TRANS(div_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_SIGN, gen_div_du)
TRANS(mod_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_SIGN, gen_rem_du)
TRANS(div_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_div_d)
TRANS(mod_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rem_d)
TRANS(div_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_div_du)
TRANS(mod_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rem_du)
TRANS(slti, gen_rri_v, EXT_NONE, EXT_NONE, gen_slt)
TRANS(sltui, gen_rri_v, EXT_NONE, EXT_NONE, gen_sltu)
TRANS(addi_w, gen_rri_c, EXT_NONE, EXT_SIGN, tcg_gen_addi_tl)
TRANS(addi_d, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_addi_tl)
TRANS(alsl_w, gen_rrr_sa, EXT_NONE, EXT_SIGN, gen_alsl)
TRANS(alsl_wu, gen_rrr_sa, EXT_NONE, EXT_ZERO, gen_alsl)
TRANS(alsl_d, gen_rrr_sa, EXT_NONE, EXT_NONE, gen_alsl)
TRANS(pcaddi, gen_pc, gen_pcaddi)
TRANS(pcalau12i, gen_pc, gen_pcalau12i)
TRANS(pcaddu12i, gen_pc, gen_pcaddu12i)
TRANS(pcaddu18i, gen_pc, gen_pcaddu18i)
TRANS(andi, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_andi_tl)
TRANS(ori, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_ori_tl)
TRANS(xori, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_xori_tl)
TRANS(add_w, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_add_tl)
TRANS(add_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_add_tl)
TRANS(sub_w, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_sub_tl)
TRANS(sub_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_sub_tl)
TRANS(and, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_and_tl)
TRANS(or, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_or_tl)
TRANS(xor, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_xor_tl)
TRANS(nor, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_nor_tl)
TRANS(andn, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_andc_tl)
TRANS(orn, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_orc_tl)
TRANS(slt, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_slt)
TRANS(sltu, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sltu)
TRANS(mul_w, ALL, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, tcg_gen_mul_tl)
TRANS(mul_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_mul_tl)
TRANS(mulh_w, ALL, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_NONE, gen_mulh_w)
TRANS(mulh_wu, ALL, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_NONE, gen_mulh_w)
TRANS(mulh_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_d)
TRANS(mulh_du, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_du)
TRANS(mulw_d_w, 64, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_NONE, tcg_gen_mul_tl)
TRANS(mulw_d_wu, 64, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_NONE, tcg_gen_mul_tl)
TRANS(div_w, ALL, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, gen_div_w)
TRANS(mod_w, ALL, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, gen_rem_w)
TRANS(div_wu, ALL, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_SIGN, gen_div_du)
TRANS(mod_wu, ALL, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_SIGN, gen_rem_du)
TRANS(div_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_div_d)
TRANS(mod_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rem_d)
TRANS(div_du, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_div_du)
TRANS(mod_du, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rem_du)
TRANS(slti, ALL, gen_rri_v, EXT_NONE, EXT_NONE, gen_slt)
TRANS(sltui, ALL, gen_rri_v, EXT_NONE, EXT_NONE, gen_sltu)
TRANS(addi_w, ALL, gen_rri_c, EXT_NONE, EXT_SIGN, tcg_gen_addi_tl)
TRANS(addi_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_addi_tl)
TRANS(alsl_w, ALL, gen_rrr_sa, EXT_NONE, EXT_SIGN, gen_alsl)
TRANS(alsl_wu, 64, gen_rrr_sa, EXT_NONE, EXT_ZERO, gen_alsl)
TRANS(alsl_d, 64, gen_rrr_sa, EXT_NONE, EXT_NONE, gen_alsl)
TRANS(pcaddi, ALL, gen_pc, gen_pcaddi)
TRANS(pcalau12i, ALL, gen_pc, gen_pcalau12i)
TRANS(pcaddu12i, ALL, gen_pc, gen_pcaddu12i)
TRANS(pcaddu18i, 64, gen_pc, gen_pcaddu18i)
TRANS(andi, ALL, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_andi_tl)
TRANS(ori, ALL, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_ori_tl)
TRANS(xori, ALL, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_xori_tl)
+43 -42
View File
@@ -7,9 +7,8 @@ static bool gen_ll(DisasContext *ctx, arg_rr_i *a, MemOp mop)
{
TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
TCGv t0 = tcg_temp_new();
TCGv t0 = make_address_i(ctx, src1, a->imm);
tcg_gen_addi_tl(t0, src1, a->imm);
tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, mop);
tcg_gen_st_tl(t0, cpu_env, offsetof(CPULoongArchState, lladdr));
tcg_gen_st_tl(dest, cpu_env, offsetof(CPULoongArchState, llval));
@@ -62,49 +61,51 @@ static bool gen_am(DisasContext *ctx, arg_rrr *a,
return false;
}
addr = make_address_i(ctx, addr, 0);
func(dest, addr, val, ctx->mem_idx, mop);
gen_set_gpr(a->rd, dest, EXT_NONE);
return true;
}
TRANS(ll_w, gen_ll, MO_TESL)
TRANS(sc_w, gen_sc, MO_TESL)
TRANS(ll_d, gen_ll, MO_TEUQ)
TRANS(sc_d, gen_sc, MO_TEUQ)
TRANS(amswap_w, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
TRANS(amswap_d, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
TRANS(amadd_w, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
TRANS(amadd_d, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
TRANS(amand_w, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
TRANS(amand_d, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
TRANS(amor_w, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
TRANS(amor_d, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
TRANS(amxor_w, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
TRANS(amxor_d, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
TRANS(ammax_w, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
TRANS(ammax_d, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
TRANS(ammin_w, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
TRANS(ammin_d, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
TRANS(ammax_wu, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
TRANS(ammax_du, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
TRANS(ammin_wu, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
TRANS(ammin_du, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
TRANS(amswap_db_w, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
TRANS(amswap_db_d, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
TRANS(amadd_db_w, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
TRANS(amadd_db_d, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
TRANS(amand_db_w, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
TRANS(amand_db_d, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
TRANS(amor_db_w, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
TRANS(amor_db_d, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
TRANS(amxor_db_w, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
TRANS(amxor_db_d, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
TRANS(ammax_db_w, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
TRANS(ammax_db_d, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
TRANS(ammin_db_w, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
TRANS(ammin_db_d, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
TRANS(ammax_db_wu, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
TRANS(ammax_db_du, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
TRANS(ammin_db_wu, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
TRANS(ammin_db_du, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
TRANS(ll_w, ALL, gen_ll, MO_TESL)
TRANS(sc_w, ALL, gen_sc, MO_TESL)
TRANS(ll_d, 64, gen_ll, MO_TEUQ)
TRANS(sc_d, 64, gen_sc, MO_TEUQ)
TRANS(amswap_w, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
TRANS(amswap_d, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
TRANS(amadd_w, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
TRANS(amadd_d, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
TRANS(amand_w, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
TRANS(amand_d, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
TRANS(amor_w, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
TRANS(amor_d, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
TRANS(amxor_w, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
TRANS(amxor_d, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
TRANS(ammax_w, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
TRANS(ammax_d, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
TRANS(ammin_w, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
TRANS(ammin_d, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
TRANS(ammax_wu, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
TRANS(ammax_du, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
TRANS(ammin_wu, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
TRANS(ammin_du, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
TRANS(amswap_db_w, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
TRANS(amswap_db_d, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
TRANS(amadd_db_w, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
TRANS(amadd_db_d, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
TRANS(amand_db_w, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
TRANS(amand_db_d, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
TRANS(amor_db_w, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
TRANS(amor_db_d, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
TRANS(amxor_db_w, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
TRANS(amxor_db_d, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
TRANS(ammax_db_w, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
TRANS(ammax_db_d, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
TRANS(ammin_db_w, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
TRANS(ammin_db_d, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
TRANS(ammax_db_wu, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
TRANS(ammax_db_du, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
TRANS(ammin_db_wu, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
TRANS(ammin_db_du, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
+28 -28
View File
@@ -178,31 +178,31 @@ static void gen_masknez(TCGv dest, TCGv src1, TCGv src2)
tcg_gen_movcond_tl(TCG_COND_NE, dest, src2, zero, zero, src1);
}
TRANS(ext_w_h, gen_rr, EXT_NONE, EXT_NONE, tcg_gen_ext16s_tl)
TRANS(ext_w_b, gen_rr, EXT_NONE, EXT_NONE, tcg_gen_ext8s_tl)
TRANS(clo_w, gen_rr, EXT_NONE, EXT_NONE, gen_clo_w)
TRANS(clz_w, gen_rr, EXT_ZERO, EXT_NONE, gen_clz_w)
TRANS(cto_w, gen_rr, EXT_NONE, EXT_NONE, gen_cto_w)
TRANS(ctz_w, gen_rr, EXT_NONE, EXT_NONE, gen_ctz_w)
TRANS(clo_d, gen_rr, EXT_NONE, EXT_NONE, gen_clo_d)
TRANS(clz_d, gen_rr, EXT_NONE, EXT_NONE, gen_clz_d)
TRANS(cto_d, gen_rr, EXT_NONE, EXT_NONE, gen_cto_d)
TRANS(ctz_d, gen_rr, EXT_NONE, EXT_NONE, gen_ctz_d)
TRANS(revb_2h, gen_rr, EXT_NONE, EXT_SIGN, gen_revb_2h)
TRANS(revb_4h, gen_rr, EXT_NONE, EXT_NONE, gen_revb_4h)
TRANS(revb_2w, gen_rr, EXT_NONE, EXT_NONE, gen_revb_2w)
TRANS(revb_d, gen_rr, EXT_NONE, EXT_NONE, tcg_gen_bswap64_i64)
TRANS(revh_2w, gen_rr, EXT_NONE, EXT_NONE, gen_revh_2w)
TRANS(revh_d, gen_rr, EXT_NONE, EXT_NONE, gen_revh_d)
TRANS(bitrev_4b, gen_rr, EXT_ZERO, EXT_SIGN, gen_helper_bitswap)
TRANS(bitrev_8b, gen_rr, EXT_NONE, EXT_NONE, gen_helper_bitswap)
TRANS(bitrev_w, gen_rr, EXT_NONE, EXT_SIGN, gen_helper_bitrev_w)
TRANS(bitrev_d, gen_rr, EXT_NONE, EXT_NONE, gen_helper_bitrev_d)
TRANS(maskeqz, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_maskeqz)
TRANS(masknez, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_masknez)
TRANS(bytepick_w, gen_rrr_sa, EXT_NONE, EXT_NONE, gen_bytepick_w)
TRANS(bytepick_d, gen_rrr_sa, EXT_NONE, EXT_NONE, gen_bytepick_d)
TRANS(bstrins_w, gen_bstrins, EXT_SIGN)
TRANS(bstrins_d, gen_bstrins, EXT_NONE)
TRANS(bstrpick_w, gen_bstrpick, EXT_SIGN)
TRANS(bstrpick_d, gen_bstrpick, EXT_NONE)
TRANS(ext_w_h, ALL, gen_rr, EXT_NONE, EXT_NONE, tcg_gen_ext16s_tl)
TRANS(ext_w_b, ALL, gen_rr, EXT_NONE, EXT_NONE, tcg_gen_ext8s_tl)
TRANS(clo_w, ALL, gen_rr, EXT_NONE, EXT_NONE, gen_clo_w)
TRANS(clz_w, ALL, gen_rr, EXT_ZERO, EXT_NONE, gen_clz_w)
TRANS(cto_w, ALL, gen_rr, EXT_NONE, EXT_NONE, gen_cto_w)
TRANS(ctz_w, ALL, gen_rr, EXT_NONE, EXT_NONE, gen_ctz_w)
TRANS(clo_d, 64, gen_rr, EXT_NONE, EXT_NONE, gen_clo_d)
TRANS(clz_d, 64, gen_rr, EXT_NONE, EXT_NONE, gen_clz_d)
TRANS(cto_d, 64, gen_rr, EXT_NONE, EXT_NONE, gen_cto_d)
TRANS(ctz_d, 64, gen_rr, EXT_NONE, EXT_NONE, gen_ctz_d)
TRANS(revb_2h, ALL, gen_rr, EXT_NONE, EXT_SIGN, gen_revb_2h)
TRANS(revb_4h, 64, gen_rr, EXT_NONE, EXT_NONE, gen_revb_4h)
TRANS(revb_2w, 64, gen_rr, EXT_NONE, EXT_NONE, gen_revb_2w)
TRANS(revb_d, 64, gen_rr, EXT_NONE, EXT_NONE, tcg_gen_bswap64_i64)
TRANS(revh_2w, 64, gen_rr, EXT_NONE, EXT_NONE, gen_revh_2w)
TRANS(revh_d, 64, gen_rr, EXT_NONE, EXT_NONE, gen_revh_d)
TRANS(bitrev_4b, ALL, gen_rr, EXT_ZERO, EXT_SIGN, gen_helper_bitswap)
TRANS(bitrev_8b, 64, gen_rr, EXT_NONE, EXT_NONE, gen_helper_bitswap)
TRANS(bitrev_w, ALL, gen_rr, EXT_NONE, EXT_SIGN, gen_helper_bitrev_w)
TRANS(bitrev_d, 64, gen_rr, EXT_NONE, EXT_NONE, gen_helper_bitrev_d)
TRANS(maskeqz, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_maskeqz)
TRANS(masknez, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_masknez)
TRANS(bytepick_w, ALL, gen_rrr_sa, EXT_NONE, EXT_NONE, gen_bytepick_w)
TRANS(bytepick_d, 64, gen_rrr_sa, EXT_NONE, EXT_NONE, gen_bytepick_d)
TRANS(bstrins_w, ALL, gen_bstrins, EXT_SIGN)
TRANS(bstrins_d, 64, gen_bstrins, EXT_NONE)
TRANS(bstrpick_w, ALL, gen_bstrpick, EXT_SIGN)
TRANS(bstrpick_d, 64, gen_bstrpick, EXT_NONE)
+14 -13
View File
@@ -12,7 +12,7 @@ static bool trans_b(DisasContext *ctx, arg_b *a)
static bool trans_bl(DisasContext *ctx, arg_bl *a)
{
tcg_gen_movi_tl(cpu_gpr[1], ctx->base.pc_next + 4);
tcg_gen_movi_tl(cpu_gpr[1], make_address_pc(ctx, ctx->base.pc_next + 4));
gen_goto_tb(ctx, 0, ctx->base.pc_next + a->offs);
ctx->base.is_jmp = DISAS_NORETURN;
return true;
@@ -23,8 +23,9 @@ static bool trans_jirl(DisasContext *ctx, arg_jirl *a)
TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
tcg_gen_addi_tl(cpu_pc, src1, a->imm);
tcg_gen_movi_tl(dest, ctx->base.pc_next + 4);
TCGv addr = make_address_i(ctx, src1, a->imm);
tcg_gen_mov_tl(cpu_pc, addr);
tcg_gen_movi_tl(dest, make_address_pc(ctx, ctx->base.pc_next + 4));
gen_set_gpr(a->rd, dest, EXT_NONE);
tcg_gen_lookup_and_goto_ptr();
ctx->base.is_jmp = DISAS_NORETURN;
@@ -71,13 +72,13 @@ static bool gen_cz_bc(DisasContext *ctx, arg_c_offs *a, TCGCond cond)
return true;
}
TRANS(beq, gen_rr_bc, TCG_COND_EQ)
TRANS(bne, gen_rr_bc, TCG_COND_NE)
TRANS(blt, gen_rr_bc, TCG_COND_LT)
TRANS(bge, gen_rr_bc, TCG_COND_GE)
TRANS(bltu, gen_rr_bc, TCG_COND_LTU)
TRANS(bgeu, gen_rr_bc, TCG_COND_GEU)
TRANS(beqz, gen_rz_bc, TCG_COND_EQ)
TRANS(bnez, gen_rz_bc, TCG_COND_NE)
TRANS(bceqz, gen_cz_bc, TCG_COND_EQ)
TRANS(bcnez, gen_cz_bc, TCG_COND_NE)
TRANS(beq, ALL, gen_rr_bc, TCG_COND_EQ)
TRANS(bne, ALL, gen_rr_bc, TCG_COND_NE)
TRANS(blt, ALL, gen_rr_bc, TCG_COND_LT)
TRANS(bge, ALL, gen_rr_bc, TCG_COND_GE)
TRANS(bltu, ALL, gen_rr_bc, TCG_COND_LTU)
TRANS(bgeu, ALL, gen_rr_bc, TCG_COND_GEU)
TRANS(beqz, ALL, gen_rz_bc, TCG_COND_EQ)
TRANS(bnez, ALL, gen_rz_bc, TCG_COND_NE)
TRANS(bceqz, 64, gen_cz_bc, TCG_COND_EQ)
TRANS(bcnez, 64, gen_cz_bc, TCG_COND_NE)
+16 -8
View File
@@ -20,6 +20,10 @@ static bool trans_asrtle_d(DisasContext *ctx, arg_asrtle_d * a)
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
if (!avail_64(ctx)) {
return false;
}
gen_helper_asrtle_d(cpu_env, src1, src2);
return true;
}
@@ -29,6 +33,10 @@ static bool trans_asrtgt_d(DisasContext *ctx, arg_asrtgt_d * a)
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
if (!avail_64(ctx)) {
return false;
}
gen_helper_asrtgt_d(cpu_env, src1, src2);
return true;
}
@@ -89,11 +97,11 @@ static bool gen_crc(DisasContext *ctx, arg_rrr *a,
return true;
}
TRANS(crc_w_b_w, gen_crc, gen_helper_crc32, tcg_constant_tl(1))
TRANS(crc_w_h_w, gen_crc, gen_helper_crc32, tcg_constant_tl(2))
TRANS(crc_w_w_w, gen_crc, gen_helper_crc32, tcg_constant_tl(4))
TRANS(crc_w_d_w, gen_crc, gen_helper_crc32, tcg_constant_tl(8))
TRANS(crcc_w_b_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(1))
TRANS(crcc_w_h_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(2))
TRANS(crcc_w_w_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(4))
TRANS(crcc_w_d_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(8))
TRANS(crc_w_b_w, 64, gen_crc, gen_helper_crc32, tcg_constant_tl(1))
TRANS(crc_w_h_w, 64, gen_crc, gen_helper_crc32, tcg_constant_tl(2))
TRANS(crc_w_w_w, 64, gen_crc, gen_helper_crc32, tcg_constant_tl(4))
TRANS(crc_w_d_w, 64, gen_crc, gen_helper_crc32, tcg_constant_tl(8))
TRANS(crcc_w_b_w, 64, gen_crc, gen_helper_crc32c, tcg_constant_tl(1))
TRANS(crcc_w_h_w, 64, gen_crc, gen_helper_crc32c, tcg_constant_tl(2))
TRANS(crcc_w_w_w, 64, gen_crc, gen_helper_crc32c, tcg_constant_tl(4))
TRANS(crcc_w_d_w, 64, gen_crc, gen_helper_crc32c, tcg_constant_tl(8))
+60 -36
View File
@@ -67,6 +67,10 @@ static bool trans_fcopysign_s(DisasContext *ctx, arg_fcopysign_s *a)
TCGv src1 = get_fpr(ctx, a->fk);
TCGv src2 = get_fpr(ctx, a->fj);
if (!avail_FP_SP(ctx)) {
return false;
}
CHECK_FPE;
tcg_gen_deposit_i64(dest, src1, src2, 0, 31);
@@ -81,6 +85,10 @@ static bool trans_fcopysign_d(DisasContext *ctx, arg_fcopysign_d *a)
TCGv src1 = get_fpr(ctx, a->fk);
TCGv src2 = get_fpr(ctx, a->fj);
if (!avail_FP_DP(ctx)) {
return false;
}
CHECK_FPE;
tcg_gen_deposit_i64(dest, src1, src2, 0, 63);
@@ -94,6 +102,10 @@ static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a)
TCGv dest = get_fpr(ctx, a->fd);
TCGv src = get_fpr(ctx, a->fj);
if (!avail_FP_SP(ctx)) {
return false;
}
CHECK_FPE;
tcg_gen_andi_i64(dest, src, MAKE_64BIT_MASK(0, 31));
@@ -108,6 +120,10 @@ static bool trans_fabs_d(DisasContext *ctx, arg_fabs_d *a)
TCGv dest = get_fpr(ctx, a->fd);
TCGv src = get_fpr(ctx, a->fj);
if (!avail_FP_DP(ctx)) {
return false;
}
CHECK_FPE;
tcg_gen_andi_i64(dest, src, MAKE_64BIT_MASK(0, 63));
@@ -121,6 +137,10 @@ static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a)
TCGv dest = get_fpr(ctx, a->fd);
TCGv src = get_fpr(ctx, a->fj);
if (!avail_FP_SP(ctx)) {
return false;
}
CHECK_FPE;
tcg_gen_xori_i64(dest, src, 0x80000000);
@@ -135,6 +155,10 @@ static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a)
TCGv dest = get_fpr(ctx, a->fd);
TCGv src = get_fpr(ctx, a->fj);
if (!avail_FP_DP(ctx)) {
return false;
}
CHECK_FPE;
tcg_gen_xori_i64(dest, src, 0x8000000000000000LL);
@@ -143,41 +167,41 @@ static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a)
return true;
}
TRANS(fadd_s, gen_fff, gen_helper_fadd_s)
TRANS(fadd_d, gen_fff, gen_helper_fadd_d)
TRANS(fsub_s, gen_fff, gen_helper_fsub_s)
TRANS(fsub_d, gen_fff, gen_helper_fsub_d)
TRANS(fmul_s, gen_fff, gen_helper_fmul_s)
TRANS(fmul_d, gen_fff, gen_helper_fmul_d)
TRANS(fdiv_s, gen_fff, gen_helper_fdiv_s)
TRANS(fdiv_d, gen_fff, gen_helper_fdiv_d)
TRANS(fmax_s, gen_fff, gen_helper_fmax_s)
TRANS(fmax_d, gen_fff, gen_helper_fmax_d)
TRANS(fmin_s, gen_fff, gen_helper_fmin_s)
TRANS(fmin_d, gen_fff, gen_helper_fmin_d)
TRANS(fmaxa_s, gen_fff, gen_helper_fmaxa_s)
TRANS(fmaxa_d, gen_fff, gen_helper_fmaxa_d)
TRANS(fmina_s, gen_fff, gen_helper_fmina_s)
TRANS(fmina_d, gen_fff, gen_helper_fmina_d)
TRANS(fscaleb_s, gen_fff, gen_helper_fscaleb_s)
TRANS(fscaleb_d, gen_fff, gen_helper_fscaleb_d)
TRANS(fsqrt_s, gen_ff, gen_helper_fsqrt_s)
TRANS(fsqrt_d, gen_ff, gen_helper_fsqrt_d)
TRANS(frecip_s, gen_ff, gen_helper_frecip_s)
TRANS(frecip_d, gen_ff, gen_helper_frecip_d)
TRANS(frsqrt_s, gen_ff, gen_helper_frsqrt_s)
TRANS(frsqrt_d, gen_ff, gen_helper_frsqrt_d)
TRANS(flogb_s, gen_ff, gen_helper_flogb_s)
TRANS(flogb_d, gen_ff, gen_helper_flogb_d)
TRANS(fclass_s, gen_ff, gen_helper_fclass_s)
TRANS(fclass_d, gen_ff, gen_helper_fclass_d)
TRANS(fmadd_s, gen_muladd, gen_helper_fmuladd_s, 0)
TRANS(fmadd_d, gen_muladd, gen_helper_fmuladd_d, 0)
TRANS(fmsub_s, gen_muladd, gen_helper_fmuladd_s, float_muladd_negate_c)
TRANS(fmsub_d, gen_muladd, gen_helper_fmuladd_d, float_muladd_negate_c)
TRANS(fnmadd_s, gen_muladd, gen_helper_fmuladd_s, float_muladd_negate_result)
TRANS(fnmadd_d, gen_muladd, gen_helper_fmuladd_d, float_muladd_negate_result)
TRANS(fnmsub_s, gen_muladd, gen_helper_fmuladd_s,
TRANS(fadd_s, FP_SP, gen_fff, gen_helper_fadd_s)
TRANS(fadd_d, FP_DP, gen_fff, gen_helper_fadd_d)
TRANS(fsub_s, FP_SP, gen_fff, gen_helper_fsub_s)
TRANS(fsub_d, FP_DP, gen_fff, gen_helper_fsub_d)
TRANS(fmul_s, FP_SP, gen_fff, gen_helper_fmul_s)
TRANS(fmul_d, FP_DP, gen_fff, gen_helper_fmul_d)
TRANS(fdiv_s, FP_SP, gen_fff, gen_helper_fdiv_s)
TRANS(fdiv_d, FP_DP, gen_fff, gen_helper_fdiv_d)
TRANS(fmax_s, FP_SP, gen_fff, gen_helper_fmax_s)
TRANS(fmax_d, FP_DP, gen_fff, gen_helper_fmax_d)
TRANS(fmin_s, FP_SP, gen_fff, gen_helper_fmin_s)
TRANS(fmin_d, FP_DP, gen_fff, gen_helper_fmin_d)
TRANS(fmaxa_s, FP_SP, gen_fff, gen_helper_fmaxa_s)
TRANS(fmaxa_d, FP_DP, gen_fff, gen_helper_fmaxa_d)
TRANS(fmina_s, FP_SP, gen_fff, gen_helper_fmina_s)
TRANS(fmina_d, FP_DP, gen_fff, gen_helper_fmina_d)
TRANS(fscaleb_s, FP_SP, gen_fff, gen_helper_fscaleb_s)
TRANS(fscaleb_d, FP_DP, gen_fff, gen_helper_fscaleb_d)
TRANS(fsqrt_s, FP_SP, gen_ff, gen_helper_fsqrt_s)
TRANS(fsqrt_d, FP_DP, gen_ff, gen_helper_fsqrt_d)
TRANS(frecip_s, FP_SP, gen_ff, gen_helper_frecip_s)
TRANS(frecip_d, FP_DP, gen_ff, gen_helper_frecip_d)
TRANS(frsqrt_s, FP_SP, gen_ff, gen_helper_frsqrt_s)
TRANS(frsqrt_d, FP_DP, gen_ff, gen_helper_frsqrt_d)
TRANS(flogb_s, FP_SP, gen_ff, gen_helper_flogb_s)
TRANS(flogb_d, FP_DP, gen_ff, gen_helper_flogb_d)
TRANS(fclass_s, FP_SP, gen_ff, gen_helper_fclass_s)
TRANS(fclass_d, FP_DP, gen_ff, gen_helper_fclass_d)
TRANS(fmadd_s, FP_SP, gen_muladd, gen_helper_fmuladd_s, 0)
TRANS(fmadd_d, FP_DP, gen_muladd, gen_helper_fmuladd_d, 0)
TRANS(fmsub_s, FP_SP, gen_muladd, gen_helper_fmuladd_s, float_muladd_negate_c)
TRANS(fmsub_d, FP_DP, gen_muladd, gen_helper_fmuladd_d, float_muladd_negate_c)
TRANS(fnmadd_s, FP_SP, gen_muladd, gen_helper_fmuladd_s, float_muladd_negate_result)
TRANS(fnmadd_d, FP_DP, gen_muladd, gen_helper_fmuladd_d, float_muladd_negate_result)
TRANS(fnmsub_s, FP_SP, gen_muladd, gen_helper_fmuladd_s,
float_muladd_negate_c | float_muladd_negate_result)
TRANS(fnmsub_d, gen_muladd, gen_helper_fmuladd_d,
TRANS(fnmsub_d, FP_DP, gen_muladd, gen_helper_fmuladd_d,
float_muladd_negate_c | float_muladd_negate_result)
@@ -29,6 +29,10 @@ static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a)
uint32_t flags;
void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
if (!avail_FP_SP(ctx)) {
return false;
}
CHECK_FPE;
var = tcg_temp_new();
@@ -49,6 +53,10 @@ static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a)
uint32_t flags;
void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
if (!avail_FP_DP(ctx)) {
return false;
}
CHECK_FPE;
var = tcg_temp_new();
+28 -28
View File
@@ -3,31 +3,31 @@
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
TRANS(fcvt_s_d, gen_ff, gen_helper_fcvt_s_d)
TRANS(fcvt_d_s, gen_ff, gen_helper_fcvt_d_s)
TRANS(ftintrm_w_s, gen_ff, gen_helper_ftintrm_w_s)
TRANS(ftintrm_w_d, gen_ff, gen_helper_ftintrm_w_d)
TRANS(ftintrm_l_s, gen_ff, gen_helper_ftintrm_l_s)
TRANS(ftintrm_l_d, gen_ff, gen_helper_ftintrm_l_d)
TRANS(ftintrp_w_s, gen_ff, gen_helper_ftintrp_w_s)
TRANS(ftintrp_w_d, gen_ff, gen_helper_ftintrp_w_d)
TRANS(ftintrp_l_s, gen_ff, gen_helper_ftintrp_l_s)
TRANS(ftintrp_l_d, gen_ff, gen_helper_ftintrp_l_d)
TRANS(ftintrz_w_s, gen_ff, gen_helper_ftintrz_w_s)
TRANS(ftintrz_w_d, gen_ff, gen_helper_ftintrz_w_d)
TRANS(ftintrz_l_s, gen_ff, gen_helper_ftintrz_l_s)
TRANS(ftintrz_l_d, gen_ff, gen_helper_ftintrz_l_d)
TRANS(ftintrne_w_s, gen_ff, gen_helper_ftintrne_w_s)
TRANS(ftintrne_w_d, gen_ff, gen_helper_ftintrne_w_d)
TRANS(ftintrne_l_s, gen_ff, gen_helper_ftintrne_l_s)
TRANS(ftintrne_l_d, gen_ff, gen_helper_ftintrne_l_d)
TRANS(ftint_w_s, gen_ff, gen_helper_ftint_w_s)
TRANS(ftint_w_d, gen_ff, gen_helper_ftint_w_d)
TRANS(ftint_l_s, gen_ff, gen_helper_ftint_l_s)
TRANS(ftint_l_d, gen_ff, gen_helper_ftint_l_d)
TRANS(ffint_s_w, gen_ff, gen_helper_ffint_s_w)
TRANS(ffint_s_l, gen_ff, gen_helper_ffint_s_l)
TRANS(ffint_d_w, gen_ff, gen_helper_ffint_d_w)
TRANS(ffint_d_l, gen_ff, gen_helper_ffint_d_l)
TRANS(frint_s, gen_ff, gen_helper_frint_s)
TRANS(frint_d, gen_ff, gen_helper_frint_d)
TRANS(fcvt_s_d, FP_DP, gen_ff, gen_helper_fcvt_s_d)
TRANS(fcvt_d_s, FP_DP, gen_ff, gen_helper_fcvt_d_s)
TRANS(ftintrm_w_s, FP_SP, gen_ff, gen_helper_ftintrm_w_s)
TRANS(ftintrm_w_d, FP_DP, gen_ff, gen_helper_ftintrm_w_d)
TRANS(ftintrm_l_s, FP_SP, gen_ff, gen_helper_ftintrm_l_s)
TRANS(ftintrm_l_d, FP_DP, gen_ff, gen_helper_ftintrm_l_d)
TRANS(ftintrp_w_s, FP_SP, gen_ff, gen_helper_ftintrp_w_s)
TRANS(ftintrp_w_d, FP_DP, gen_ff, gen_helper_ftintrp_w_d)
TRANS(ftintrp_l_s, FP_SP, gen_ff, gen_helper_ftintrp_l_s)
TRANS(ftintrp_l_d, FP_DP, gen_ff, gen_helper_ftintrp_l_d)
TRANS(ftintrz_w_s, FP_SP, gen_ff, gen_helper_ftintrz_w_s)
TRANS(ftintrz_w_d, FP_DP, gen_ff, gen_helper_ftintrz_w_d)
TRANS(ftintrz_l_s, FP_SP, gen_ff, gen_helper_ftintrz_l_s)
TRANS(ftintrz_l_d, FP_DP, gen_ff, gen_helper_ftintrz_l_d)
TRANS(ftintrne_w_s, FP_SP, gen_ff, gen_helper_ftintrne_w_s)
TRANS(ftintrne_w_d, FP_DP, gen_ff, gen_helper_ftintrne_w_d)
TRANS(ftintrne_l_s, FP_SP, gen_ff, gen_helper_ftintrne_l_s)
TRANS(ftintrne_l_d, FP_DP, gen_ff, gen_helper_ftintrne_l_d)
TRANS(ftint_w_s, FP_SP, gen_ff, gen_helper_ftint_w_s)
TRANS(ftint_w_d, FP_DP, gen_ff, gen_helper_ftint_w_d)
TRANS(ftint_l_s, FP_SP, gen_ff, gen_helper_ftint_l_s)
TRANS(ftint_l_d, FP_DP, gen_ff, gen_helper_ftint_l_d)
TRANS(ffint_s_w, FP_SP, gen_ff, gen_helper_ffint_s_w)
TRANS(ffint_s_l, FP_SP, gen_ff, gen_helper_ffint_s_l)
TRANS(ffint_d_w, FP_DP, gen_ff, gen_helper_ffint_d_w)
TRANS(ffint_d_l, FP_DP, gen_ff, gen_helper_ffint_d_l)
TRANS(frint_s, FP_SP, gen_ff, gen_helper_frint_s)
TRANS(frint_d, FP_DP, gen_ff, gen_helper_frint_d)
+24 -38
View File
@@ -17,11 +17,7 @@ static bool gen_fload_i(DisasContext *ctx, arg_fr_i *a, MemOp mop)
CHECK_FPE;
if (a->imm) {
TCGv temp = tcg_temp_new();
tcg_gen_addi_tl(temp, addr, a->imm);
addr = temp;
}
addr = make_address_i(ctx, addr, a->imm);
tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
maybe_nanbox_load(dest, mop);
@@ -37,11 +33,7 @@ static bool gen_fstore_i(DisasContext *ctx, arg_fr_i *a, MemOp mop)
CHECK_FPE;
if (a->imm) {
TCGv temp = tcg_temp_new();
tcg_gen_addi_tl(temp, addr, a->imm);
addr = temp;
}
addr = make_address_i(ctx, addr, a->imm);
tcg_gen_qemu_st_tl(src, addr, ctx->mem_idx, mop);
@@ -57,8 +49,7 @@ static bool gen_floadx(DisasContext *ctx, arg_frr *a, MemOp mop)
CHECK_FPE;
addr = tcg_temp_new();
tcg_gen_add_tl(addr, src1, src2);
addr = make_address_x(ctx, src1, src2);
tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
maybe_nanbox_load(dest, mop);
set_fpr(a->fd, dest);
@@ -75,8 +66,7 @@ static bool gen_fstorex(DisasContext *ctx, arg_frr *a, MemOp mop)
CHECK_FPE;
addr = tcg_temp_new();
tcg_gen_add_tl(addr, src1, src2);
addr = make_address_x(ctx, src1, src2);
tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop);
return true;
@@ -91,9 +81,8 @@ static bool gen_fload_gt(DisasContext *ctx, arg_frr *a, MemOp mop)
CHECK_FPE;
addr = tcg_temp_new();
gen_helper_asrtgt_d(cpu_env, src1, src2);
tcg_gen_add_tl(addr, src1, src2);
addr = make_address_x(ctx, src1, src2);
tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
maybe_nanbox_load(dest, mop);
set_fpr(a->fd, dest);
@@ -110,9 +99,8 @@ static bool gen_fstore_gt(DisasContext *ctx, arg_frr *a, MemOp mop)
CHECK_FPE;
addr = tcg_temp_new();
gen_helper_asrtgt_d(cpu_env, src1, src2);
tcg_gen_add_tl(addr, src1, src2);
addr = make_address_x(ctx, src1, src2);
tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop);
return true;
@@ -127,9 +115,8 @@ static bool gen_fload_le(DisasContext *ctx, arg_frr *a, MemOp mop)
CHECK_FPE;
addr = tcg_temp_new();
gen_helper_asrtle_d(cpu_env, src1, src2);
tcg_gen_add_tl(addr, src1, src2);
addr = make_address_x(ctx, src1, src2);
tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
maybe_nanbox_load(dest, mop);
set_fpr(a->fd, dest);
@@ -146,27 +133,26 @@ static bool gen_fstore_le(DisasContext *ctx, arg_frr *a, MemOp mop)
CHECK_FPE;
addr = tcg_temp_new();
gen_helper_asrtle_d(cpu_env, src1, src2);
tcg_gen_add_tl(addr, src1, src2);
addr = make_address_x(ctx, src1, src2);
tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop);
return true;
}
TRANS(fld_s, gen_fload_i, MO_TEUL)
TRANS(fst_s, gen_fstore_i, MO_TEUL)
TRANS(fld_d, gen_fload_i, MO_TEUQ)
TRANS(fst_d, gen_fstore_i, MO_TEUQ)
TRANS(fldx_s, gen_floadx, MO_TEUL)
TRANS(fldx_d, gen_floadx, MO_TEUQ)
TRANS(fstx_s, gen_fstorex, MO_TEUL)
TRANS(fstx_d, gen_fstorex, MO_TEUQ)
TRANS(fldgt_s, gen_fload_gt, MO_TEUL)
TRANS(fldgt_d, gen_fload_gt, MO_TEUQ)
TRANS(fldle_s, gen_fload_le, MO_TEUL)
TRANS(fldle_d, gen_fload_le, MO_TEUQ)
TRANS(fstgt_s, gen_fstore_gt, MO_TEUL)
TRANS(fstgt_d, gen_fstore_gt, MO_TEUQ)
TRANS(fstle_s, gen_fstore_le, MO_TEUL)
TRANS(fstle_d, gen_fstore_le, MO_TEUQ)
TRANS(fld_s, FP_SP, gen_fload_i, MO_TEUL)
TRANS(fst_s, FP_SP, gen_fstore_i, MO_TEUL)
TRANS(fld_d, FP_DP, gen_fload_i, MO_TEUQ)
TRANS(fst_d, FP_DP, gen_fstore_i, MO_TEUQ)
TRANS(fldx_s, FP_SP, gen_floadx, MO_TEUL)
TRANS(fldx_d, FP_DP, gen_floadx, MO_TEUQ)
TRANS(fstx_s, FP_SP, gen_fstorex, MO_TEUL)
TRANS(fstx_d, FP_DP, gen_fstorex, MO_TEUQ)
TRANS(fldgt_s, FP_SP, gen_fload_gt, MO_TEUL)
TRANS(fldgt_d, FP_DP, gen_fload_gt, MO_TEUQ)
TRANS(fldle_s, FP_SP, gen_fload_le, MO_TEUL)
TRANS(fldle_d, FP_DP, gen_fload_le, MO_TEUQ)
TRANS(fstgt_s, FP_SP, gen_fstore_gt, MO_TEUL)
TRANS(fstgt_d, FP_DP, gen_fstore_gt, MO_TEUQ)
TRANS(fstle_s, FP_SP, gen_fstore_le, MO_TEUL)
TRANS(fstle_d, FP_DP, gen_fstore_le, MO_TEUQ)
+44 -8
View File
@@ -15,6 +15,10 @@ static bool trans_fsel(DisasContext *ctx, arg_fsel *a)
TCGv src2 = get_fpr(ctx, a->fk);
TCGv cond;
if (!avail_FP(ctx)) {
return false;
}
CHECK_FPE;
cond = tcg_temp_new();
@@ -48,6 +52,10 @@ static bool gen_r2f(DisasContext *ctx, arg_fr *a,
TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
TCGv dest = get_fpr(ctx, a->fd);
if (!avail_FP(ctx)) {
return false;
}
CHECK_FPE;
func(dest, src);
@@ -62,6 +70,10 @@ static bool gen_f2r(DisasContext *ctx, arg_rf *a,
TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
TCGv src = get_fpr(ctx, a->fj);
if (!avail_FP(ctx)) {
return false;
}
CHECK_FPE;
func(dest, src);
@@ -75,6 +87,10 @@ static bool trans_movgr2fcsr(DisasContext *ctx, arg_movgr2fcsr *a)
uint32_t mask = fcsr_mask[a->fcsrd];
TCGv Rj = gpr_src(ctx, a->rj, EXT_NONE);
if (!avail_FP(ctx)) {
return false;
}
CHECK_FPE;
if (mask == UINT32_MAX) {
@@ -105,6 +121,10 @@ static bool trans_movfcsr2gr(DisasContext *ctx, arg_movfcsr2gr *a)
{
TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
if (!avail_FP(ctx)) {
return false;
}
CHECK_FPE;
tcg_gen_ld32u_i64(dest, cpu_env, offsetof(CPULoongArchState, fcsr0));
@@ -134,6 +154,10 @@ static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a)
TCGv t0;
TCGv src = get_fpr(ctx, a->fj);
if (!avail_FP(ctx)) {
return false;
}
CHECK_FPE;
t0 = tcg_temp_new();
@@ -147,6 +171,10 @@ static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a)
{
TCGv dest = get_fpr(ctx, a->fd);
if (!avail_FP(ctx)) {
return false;
}
CHECK_FPE;
tcg_gen_ld8u_tl(dest, cpu_env,
@@ -160,6 +188,10 @@ static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a)
{
TCGv t0;
if (!avail_FP(ctx)) {
return false;
}
CHECK_FPE;
t0 = tcg_temp_new();
@@ -171,6 +203,10 @@ static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a)
static bool trans_movcf2gr(DisasContext *ctx, arg_movcf2gr *a)
{
if (!avail_FP(ctx)) {
return false;
}
CHECK_FPE;
tcg_gen_ld8u_tl(gpr_dst(ctx, a->rd, EXT_NONE), cpu_env,
@@ -178,11 +214,11 @@ static bool trans_movcf2gr(DisasContext *ctx, arg_movcf2gr *a)
return true;
}
TRANS(fmov_s, gen_f2f, tcg_gen_mov_tl, true)
TRANS(fmov_d, gen_f2f, tcg_gen_mov_tl, false)
TRANS(movgr2fr_w, gen_r2f, gen_movgr2fr_w)
TRANS(movgr2fr_d, gen_r2f, tcg_gen_mov_tl)
TRANS(movgr2frh_w, gen_r2f, gen_movgr2frh_w)
TRANS(movfr2gr_s, gen_f2r, tcg_gen_ext32s_tl)
TRANS(movfr2gr_d, gen_f2r, tcg_gen_mov_tl)
TRANS(movfrh2gr_s, gen_f2r, gen_movfrh2gr_s)
TRANS(fmov_s, FP_SP, gen_f2f, tcg_gen_mov_tl, true)
TRANS(fmov_d, FP_DP, gen_f2f, tcg_gen_mov_tl, false)
TRANS(movgr2fr_w, FP_SP, gen_r2f, gen_movgr2fr_w)
TRANS(movgr2fr_d, 64, gen_r2f, tcg_gen_mov_tl)
TRANS(movgr2frh_w, FP_DP, gen_r2f, gen_movgr2frh_w)
TRANS(movfr2gr_s, FP_SP, gen_f2r, tcg_gen_ext32s_tl)
TRANS(movfr2gr_d, 64, gen_f2r, tcg_gen_mov_tl)
TRANS(movfrh2gr_s, FP_DP, gen_f2r, gen_movfrh2gr_s)

Some files were not shown because too many files have changed in this diff Show More