Merge tag 'pull-la-20220719' of https://gitlab.com/rth7680/qemu into staging

LoongArch64 patch queue:

Add dockerfile for loongarch cross compile
Add reference files for float tests.
Add simple tests for div, mod, clo, fclass, fcmp, pcadd
Add bios and kernel boot support.
Add smbios, acpi, and fdt support.
Fix pch-pic update-irq.
Fix some errors identified by coverity.

# gpg: Signature made Tue 19 Jul 2022 18:26:04 BST
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* tag 'pull-la-20220719' of https://gitlab.com/rth7680/qemu: (21 commits)
  hw/loongarch: Add fdt support
  hw/loongarch: Add acpi ged support
  hw/loongarch: Add smbios support
  hw/loongarch: Add linux kernel booting support
  hw/loongarch: Add uefi bios loading support
  hw/loongarch: Add fw_cfg table support
  tests/tcg/loongarch64: Add pcadd related instructions test
  tests/tcg/loongarch64: Add fp comparison instructions test
  tests/tcg/loongarch64: Add fclass test
  tests/tcg/loongarch64: Add div and mod related instructions test
  tests/tcg/loongarch64: Add clo related instructions test
  tests/tcg/loongarch64: Add float reference files
  target/loongarch: Fix float_convd/float_convs test failing
  fpu/softfloat: Add LoongArch specializations for pickNaN*
  target/loongarch/cpu: Fix cpucfg default value
  target/loongarch/op_helper: Fix coverity cond_at_most error
  target/loongarch/tlb_helper: Fix coverity integer overflow error
  target/loongarch/cpu: Fix coverity errors about excp_names
  hw/intc/loongarch_pch_pic: Fix bugs for update_irq function
  target/loongarch: Fix loongarch_cpu_class_by_name
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2022-07-19 22:54:43 +01:00
28 changed files with 4147 additions and 101 deletions
+1
View File
@@ -2,3 +2,4 @@ TARGET_ARCH=loongarch64
TARGET_BASE_ARCH=loongarch
TARGET_SUPPORTS_MTTCG=y
TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu64.xml
TARGET_NEED_FDT=y
Vendored
+5
View File
@@ -1933,6 +1933,7 @@ probe_target_compiler() {
hexagon) container_hosts=x86_64 ;;
hppa) container_hosts=x86_64 ;;
i386) container_hosts=x86_64 ;;
loongarch64) container_hosts=x86_64 ;;
m68k) container_hosts=x86_64 ;;
microblaze) container_hosts=x86_64 ;;
mips64el) container_hosts=x86_64 ;;
@@ -1987,6 +1988,10 @@ probe_target_compiler() {
container_image=fedora-i386-cross
container_cross_prefix=
;;
loongarch64)
container_image=debian-loongarch-cross
container_cross_prefix=loongarch64-unknown-linux-gnu-
;;
m68k)
container_image=debian-m68k-cross
container_cross_prefix=m68k-linux-gnu-
+25 -1
View File
@@ -390,7 +390,8 @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
static int pickNaN(FloatClass a_cls, FloatClass b_cls,
bool aIsLargerSignificand, float_status *status)
{
#if defined(TARGET_ARM) || defined(TARGET_MIPS) || defined(TARGET_HPPA)
#if defined(TARGET_ARM) || defined(TARGET_MIPS) || defined(TARGET_HPPA) \
|| defined(TARGET_LOONGARCH64)
/* ARM mandated NaN propagation rules (see FPProcessNaNs()), take
* the first of:
* 1. A if it is signaling
@@ -574,6 +575,29 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
return 1;
}
}
#elif defined(TARGET_LOONGARCH64)
/*
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
* case sets InvalidOp and returns the input value 'c'
*/
if (infzero) {
float_raise(float_flag_invalid | float_flag_invalid_imz, status);
return 2;
}
/* Prefer sNaN over qNaN, in the c, a, b order. */
if (is_snan(c_cls)) {
return 2;
} else if (is_snan(a_cls)) {
return 0;
} else if (is_snan(b_cls)) {
return 1;
} else if (is_qnan(c_cls)) {
return 2;
} else if (is_qnan(a_cls)) {
return 0;
} else {
return 1;
}
#elif defined(TARGET_PPC)
/* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
* to return an input NaN if we have one (ie c) rather than generating
+5 -5
View File
@@ -15,21 +15,21 @@
static void pch_pic_update_irq(LoongArchPCHPIC *s, uint64_t mask, int level)
{
unsigned long val;
uint64_t val;
int irq;
if (level) {
val = mask & s->intirr & ~s->int_mask;
if (val) {
irq = find_first_bit(&val, 64);
s->intisr |= 0x1ULL << irq;
irq = ctz64(val);
s->intisr |= MAKE_64BIT_MASK(irq, 1);
qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
}
} else {
val = mask & s->intisr;
if (val) {
irq = find_first_bit(&val, 64);
s->intisr &= ~(0x1ULL << irq);
irq = ctz64(val);
s->intisr &= ~MAKE_64BIT_MASK(irq, 1);
qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 0);
}
}
+3
View File
@@ -14,3 +14,6 @@ config LOONGARCH_VIRT
select LOONGARCH_PCH_MSI
select LOONGARCH_EXTIOI
select LS7A_RTC
select SMBIOS
select ACPI_PCI
select ACPI_HW_REDUCED
File diff suppressed because it is too large Load Diff
+33
View File
@@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* QEMU fw_cfg helpers (LoongArch specific)
*
* Copyright (C) 2021 Loongson Technology Corporation Limited
*/
#include "qemu/osdep.h"
#include "hw/loongarch/fw_cfg.h"
#include "hw/loongarch/virt.h"
#include "hw/nvram/fw_cfg.h"
#include "sysemu/sysemu.h"
static void fw_cfg_boot_set(void *opaque, const char *boot_device,
Error **errp)
{
fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
}
FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, MachineState *ms)
{
FWCfgState *fw_cfg;
int max_cpus = ms->smp.max_cpus;
int smp_cpus = ms->smp.cpus;
fw_cfg = fw_cfg_init_mem_wide(VIRT_FWCFG_BASE + 8, VIRT_FWCFG_BASE, 8, 0, NULL);
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
return fw_cfg;
}
+15
View File
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* QEMU fw_cfg helpers (LoongArch specific)
*
* Copyright (C) 2021 Loongson Technology Corporation Limited
*/
#ifndef HW_LOONGARCH_FW_CFG_H
#define HW_LOONGARCH_FW_CFG_H
#include "hw/boards.h"
#include "hw/nvram/fw_cfg.h"
FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, MachineState *ms);
#endif
+414 -19
View File
File diff suppressed because it is too large Load Diff
+5 -1
View File
@@ -1,4 +1,8 @@
loongarch_ss = ss.source_set()
loongarch_ss.add(when: 'CONFIG_LOONGARCH_VIRT', if_true: files('loongson3.c'))
loongarch_ss.add(files(
'fw_cfg.c',
))
loongarch_ss.add(when: 'CONFIG_LOONGARCH_VIRT', if_true: [files('loongson3.c'), fdt])
loongarch_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-build.c'))
hw_arch += {'loongarch': loongarch_ss}
+25
View File
@@ -17,6 +17,19 @@
#define LOONGARCH_ISA_IO_BASE 0x18000000UL
#define LOONGARCH_ISA_IO_SIZE 0x0004000
#define VIRT_FWCFG_BASE 0x1e020000UL
#define VIRT_BIOS_BASE 0x1c000000UL
#define VIRT_BIOS_SIZE (4 * MiB)
#define VIRT_LOWMEM_BASE 0
#define VIRT_LOWMEM_SIZE 0x10000000
#define VIRT_HIGHMEM_BASE 0x90000000
#define VIRT_GED_EVT_ADDR 0x100e0000
#define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN)
#define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN)
#define LA_FDT_BASE 0x1c400000
#define LA_FDT_SIZE 0x100000
struct LoongArchMachineState {
/*< private >*/
@@ -26,8 +39,20 @@ struct LoongArchMachineState {
MemoryRegion lowmem;
MemoryRegion highmem;
MemoryRegion isa_io;
MemoryRegion bios;
bool bios_loaded;
/* State for other subsystems/APIs: */
FWCfgState *fw_cfg;
Notifier machine_done;
OnOffAuto acpi;
char *oem_id;
char *oem_table_id;
DeviceState *acpi_ged;
int fdt_size;
};
#define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt")
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, LOONGARCH_MACHINE)
bool loongarch_is_acpi_enabled(LoongArchMachineState *lams);
void loongarch_acpi_setup(LoongArchMachineState *lams);
#endif
+4
View File
@@ -23,6 +23,9 @@
#define LS7A_PCI_IO_BASE 0x18004000UL
#define LS7A_PCI_IO_SIZE 0xC000
#define LS7A_PCI_MEM_BASE 0x40000000UL
#define LS7A_PCI_MEM_SIZE 0x40000000UL
#define LS7A_PCH_REG_BASE 0x10000000UL
#define LS7A_IOAPIC_REG_BASE (LS7A_PCH_REG_BASE)
#define LS7A_PCH_MSI_ADDR_LOW 0x2FF00000UL
@@ -41,4 +44,5 @@
#define LS7A_MISC_REG_BASE (LS7A_PCH_REG_BASE + 0x00080000)
#define LS7A_RTC_REG_BASE (LS7A_MISC_REG_BASE + 0x00050100)
#define LS7A_RTC_LEN 0x100
#define LS7A_SCI_IRQ (PCH_PIC_IRQ_OFFSET + 4)
#endif
+20 -9
View File
@@ -140,7 +140,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
if (cs->exception_index != EXCCODE_INT) {
if (cs->exception_index < 0 ||
cs->exception_index > ARRAY_SIZE(excp_names)) {
cs->exception_index >= ARRAY_SIZE(excp_names)) {
name = "unknown";
} else {
name = excp_names[cs->exception_index];
@@ -190,8 +190,8 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
cause = cs->exception_index;
break;
default:
qemu_log("Error: exception(%d) '%s' has not been supported\n",
cs->exception_index, excp_names[cs->exception_index]);
qemu_log("Error: exception(%d) has not been supported\n",
cs->exception_index);
abort();
}
@@ -341,6 +341,7 @@ static void loongarch_la464_initfn(Object *obj)
env->cpucfg[i] = 0x0;
}
cpu->dtb_compatible = "loongarch,Loongson-3A5000";
env->cpucfg[0] = 0x14c010; /* PRID */
uint32_t data = 0;
@@ -406,7 +407,7 @@ static void loongarch_la464_initfn(Object *obj)
data = 0;
data = FIELD_DP32(data, CPUCFG20, L3IU_WAYS, 15);
data = FIELD_DP32(data, CPUCFG20, L3IU_SETS, 14);
data = FIELD_DP32(data, CPUCFG20, L3IU_SETS, 6);
data = FIELD_DP32(data, CPUCFG20, L3IU_SIZE, 6);
env->cpucfg[20] = data;
env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);
@@ -571,12 +572,22 @@ static void loongarch_cpu_init(Object *obj)
static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model)
{
ObjectClass *oc;
char *typename;
typename = g_strdup_printf(LOONGARCH_CPU_TYPE_NAME("%s"), cpu_model);
oc = object_class_by_name(typename);
g_free(typename);
return oc;
oc = object_class_by_name(cpu_model);
if (!oc) {
g_autofree char *typename
= g_strdup_printf(LOONGARCH_CPU_TYPE_NAME("%s"), cpu_model);
oc = object_class_by_name(typename);
if (!oc) {
return NULL;
}
}
if (object_class_dynamic_cast(oc, TYPE_LOONGARCH_CPU)
&& !object_class_is_abstract(oc)) {
return oc;
}
return NULL;
}
void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags)
+3
View File
@@ -326,6 +326,9 @@ struct ArchCPU {
CPUNegativeOffsetState neg;
CPULoongArchState env;
QEMUTimer timer;
/* 'compatible' string for this CPU for Linux device trees */
const char *dtb_compatible;
};
#define TYPE_LOONGARCH_CPU "loongarch-cpu"
+80 -63
View File
@@ -13,9 +13,6 @@
#include "fpu/softfloat.h"
#include "internals.h"
#define FLOAT_TO_INT32_OVERFLOW 0x7fffffff
#define FLOAT_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
static inline uint64_t nanbox_s(float32 fp)
{
return fp | MAKE_64BIT_MASK(32, 32);
@@ -544,9 +541,10 @@ uint64_t helper_ftintrm_l_d(CPULoongArchState *env, uint64_t fj)
fd = float64_to_int64(fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT64_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float64_is_any_nan(fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -561,9 +559,10 @@ uint64_t helper_ftintrm_l_s(CPULoongArchState *env, uint64_t fj)
fd = float32_to_int64((uint32_t)fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT64_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float32_is_any_nan((uint32_t)fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -578,9 +577,10 @@ uint64_t helper_ftintrm_w_d(CPULoongArchState *env, uint64_t fj)
fd = (uint64_t)float64_to_int32(fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT32_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float64_is_any_nan(fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -595,9 +595,10 @@ uint64_t helper_ftintrm_w_s(CPULoongArchState *env, uint64_t fj)
fd = (uint64_t)float32_to_int32((uint32_t)fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT32_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float32_is_any_nan((uint32_t)fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -612,9 +613,10 @@ uint64_t helper_ftintrp_l_d(CPULoongArchState *env, uint64_t fj)
fd = float64_to_int64(fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT64_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float64_is_any_nan(fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -629,9 +631,10 @@ uint64_t helper_ftintrp_l_s(CPULoongArchState *env, uint64_t fj)
fd = float32_to_int64((uint32_t)fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT64_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float32_is_any_nan((uint32_t)fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -646,9 +649,10 @@ uint64_t helper_ftintrp_w_d(CPULoongArchState *env, uint64_t fj)
fd = (uint64_t)float64_to_int32(fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT32_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float64_is_any_nan(fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -663,9 +667,10 @@ uint64_t helper_ftintrp_w_s(CPULoongArchState *env, uint64_t fj)
fd = (uint64_t)float32_to_int32((uint32_t)fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT32_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float32_is_any_nan((uint32_t)fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -679,9 +684,10 @@ uint64_t helper_ftintrz_l_d(CPULoongArchState *env, uint64_t fj)
fd = float64_to_int64_round_to_zero(fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT64_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float64_is_any_nan(fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -695,9 +701,10 @@ uint64_t helper_ftintrz_l_s(CPULoongArchState *env, uint64_t fj)
fd = float32_to_int64_round_to_zero((uint32_t)fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT64_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float32_is_any_nan((uint32_t)fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -711,9 +718,10 @@ uint64_t helper_ftintrz_w_d(CPULoongArchState *env, uint64_t fj)
fd = (uint64_t)float64_to_int32_round_to_zero(fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT32_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float64_is_any_nan(fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -727,9 +735,10 @@ uint64_t helper_ftintrz_w_s(CPULoongArchState *env, uint64_t fj)
fd = float32_to_int32_round_to_zero((uint32_t)fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT32_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float32_is_any_nan((uint32_t)fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return (uint64_t)fd;
@@ -744,9 +753,10 @@ uint64_t helper_ftintrne_l_d(CPULoongArchState *env, uint64_t fj)
fd = float64_to_int64(fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT64_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float64_is_any_nan(fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -761,9 +771,10 @@ uint64_t helper_ftintrne_l_s(CPULoongArchState *env, uint64_t fj)
fd = float32_to_int64((uint32_t)fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT64_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float32_is_any_nan((uint32_t)fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -778,9 +789,10 @@ uint64_t helper_ftintrne_w_d(CPULoongArchState *env, uint64_t fj)
fd = (uint64_t)float64_to_int32(fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT32_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float64_is_any_nan(fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -795,9 +807,10 @@ uint64_t helper_ftintrne_w_s(CPULoongArchState *env, uint64_t fj)
fd = float32_to_int32((uint32_t)fj, &env->fp_status);
set_float_rounding_mode(old_mode, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT32_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float32_is_any_nan((uint32_t)fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return (uint64_t)fd;
@@ -808,9 +821,10 @@ uint64_t helper_ftint_l_d(CPULoongArchState *env, uint64_t fj)
uint64_t fd;
fd = float64_to_int64(fj, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT64_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float64_is_any_nan(fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -821,9 +835,10 @@ uint64_t helper_ftint_l_s(CPULoongArchState *env, uint64_t fj)
uint64_t fd;
fd = float32_to_int64((uint32_t)fj, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) &
(float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT64_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float32_is_any_nan((uint32_t)fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -834,9 +849,10 @@ uint64_t helper_ftint_w_s(CPULoongArchState *env, uint64_t fj)
uint64_t fd;
fd = (uint64_t)float32_to_int32((uint32_t)fj, &env->fp_status);
if (get_float_exception_flags(&env->fp_status)
& (float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT32_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float32_is_any_nan((uint32_t)fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
@@ -847,9 +863,10 @@ uint64_t helper_ftint_w_d(CPULoongArchState *env, uint64_t fj)
uint64_t fd;
fd = (uint64_t)float64_to_int32(fj, &env->fp_status);
if (get_float_exception_flags(&env->fp_status)
& (float_flag_invalid | float_flag_overflow)) {
fd = FLOAT_TO_INT32_OVERFLOW;
if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
if (float64_is_any_nan(fj)) {
fd = 0;
}
}
update_fcsr0(env, GETPC());
return fd;
+1 -1
View File
@@ -81,7 +81,7 @@ target_ulong helper_crc32c(target_ulong val, target_ulong m, uint64_t sz)
target_ulong helper_cpucfg(CPULoongArchState *env, target_ulong rj)
{
return rj > 21 ? 0 : env->cpucfg[rj];
return rj >= ARRAY_SIZE(env->cpucfg) ? 0 : env->cpucfg[rj];
}
uint64_t helper_rdtime_d(CPULoongArchState *env)
+2 -2
View File
@@ -298,7 +298,7 @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
} else {
tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
}
pagesize = 1 << tlb_ps;
pagesize = MAKE_64BIT_MASK(tlb_ps, 1);
mask = MAKE_64BIT_MASK(0, tlb_ps + 1);
if (tlb_v0) {
@@ -736,7 +736,7 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
(tmp0 & (~(1 << R_TLBENTRY_G_SHIFT)));
ps = ptbase + ptwidth - 1;
if (odd) {
tmp0 += (1 << ps);
tmp0 += MAKE_64BIT_MASK(ps, 1);
}
} else {
/* 0:64bit, 1:128bit, 2:192bit, 3:256bit */
+2
View File
@@ -140,6 +140,7 @@ docker-image-debian-nios2-cross: $(DOCKER_FILES_DIR)/debian-toolchain.docker \
# Specialist build images, sometimes very limited tools
docker-image-debian-tricore-cross: docker-image-debian10
docker-image-debian-all-test-cross: docker-image-debian10
docker-image-debian-loongarch-cross: docker-image-debian11
docker-image-debian-microblaze-cross: docker-image-debian10
docker-image-debian-nios2-cross: docker-image-debian10
docker-image-debian-powerpc-test-cross: docker-image-debian11
@@ -149,6 +150,7 @@ docker-image-debian-riscv64-test-cross: docker-image-debian11
DOCKER_PARTIAL_IMAGES += debian-alpha-cross
DOCKER_PARTIAL_IMAGES += debian-powerpc-test-cross
DOCKER_PARTIAL_IMAGES += debian-hppa-cross
DOCKER_PARTIAL_IMAGES += debian-loongarch-cross
DOCKER_PARTIAL_IMAGES += debian-m68k-cross debian-mips64-cross
DOCKER_PARTIAL_IMAGES += debian-microblaze-cross
DOCKER_PARTIAL_IMAGES += debian-nios2-cross
@@ -0,0 +1,25 @@
#
# Docker cross-compiler target
#
# This docker target builds on the debian11 base image,
# using a prebuilt toolchains for LoongArch64 from:
# https://github.com/loongson/build-tools/releases
#
FROM qemu/debian11
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \
DEBIAN_FRONTEND=noninteractive eatmydata \
apt-get install -y --no-install-recommends \
build-essential \
ca-certificates \
curl \
gettext \
git \
python3-minimal
RUN curl -#SL https://github.com/loongson/build-tools/releases/download/2022.05.29/loongarch64-clfs-5.0-cross-tools-gcc-glibc.tar.xz \
| tar -xJC /opt
ENV PATH $PATH:/opt/cross-tools/bin
ENV LD_LIBRARY_PATH /opt/cross-tools/lib:/opt/cross-tools/loongarch64-unknown-linux-gnu/lib:$LD_LIBRARY_PATH
+19
View File
@@ -0,0 +1,19 @@
# -*- Mode: makefile -*-
#
# LoongArch64 specific tweaks
# Loongarch64 doesn't support gdb, so skip the EXTRA_RUNS
EXTRA_RUNS =
LOONGARCH64_SRC=$(SRC_PATH)/tests/tcg/loongarch64
VPATH += $(LOONGARCH64_SRC)
LDFLAGS+=-lm
LOONGARCH64_TESTS = test_bit
LOONGARCH64_TESTS += test_div
LOONGARCH64_TESTS += test_fclass
LOONGARCH64_TESTS += test_fpcom
LOONGARCH64_TESTS += test_pcadd
TESTS += $(LOONGARCH64_TESTS)

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