From 9925c8bb81d34339ea0433192fdb1d58c12b8edb Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Fri, 22 Oct 2021 16:01:29 +1000 Subject: hw/riscv: virt: Don't use a macro for the PLIC configuration Using a macro for the PLIC configuration doesn't make the code any easier to read. Instead it makes it harder to figure out what is going on, so let's remove it. Signed-off-by: Alistair Francis Reviewed-by: Bin Meng Reviewed-by: Philippe Mathieu-Daudé Message-id: 20211022060133.3045020-1-alistair.francis@opensource.wdc.com --- include/hw/riscv/virt.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index d9105c1886..b8ef99f348 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -73,7 +73,6 @@ enum { VIRTIO_NDEV = 0x35 /* Arbitrary maximum number of interrupts */ }; -#define VIRT_PLIC_HART_CONFIG "MS" #define VIRT_PLIC_NUM_SOURCES 127 #define VIRT_PLIC_NUM_PRIORITIES 7 #define VIRT_PLIC_PRIORITY_BASE 0x04 -- cgit v1.2.3-55-g7522 From bf357e1d72cd8b7b590518dacdf4b65beb2c61e2 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Fri, 22 Oct 2021 16:01:30 +1000 Subject: hw/riscv: boot: Add a PLIC config string function Add a generic function that can create the PLIC strings. Signed-off-by: Alistair Francis Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Bin Meng Message-id: 20211022060133.3045020-2-alistair.francis@opensource.wdc.com --- hw/riscv/boot.c | 25 +++++++++++++++++++++++++ include/hw/riscv/boot.h | 2 ++ 2 files changed, 27 insertions(+) (limited to 'include') diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index d1ffc7b56c..519fa455a1 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -38,6 +38,31 @@ bool riscv_is_32bit(RISCVHartArrayState *harts) return harts->harts[0].env.misa_mxl_max == MXL_RV32; } +/* + * Return the per-socket PLIC hart topology configuration string + * (caller must free with g_free()) + */ +char *riscv_plic_hart_config_string(int hart_count) +{ + g_autofree const char **vals = g_new(const char *, hart_count + 1); + int i; + + for (i = 0; i < hart_count; i++) { + CPUState *cs = qemu_get_cpu(i); + CPURISCVState *env = &RISCV_CPU(cs)->env; + + if (riscv_has_ext(env, RVS)) { + vals[i] = "MS"; + } else { + vals[i] = "M"; + } + } + vals[i] = NULL; + + /* g_strjoinv() obliges us to cast away const here */ + return g_strjoinv(",", (char **)vals); +} + target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts, target_ulong firmware_end_addr) { if (riscv_is_32bit(harts)) { diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index 0e89400b09..baff11dd8a 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -31,6 +31,8 @@ bool riscv_is_32bit(RISCVHartArrayState *harts); +char *riscv_plic_hart_config_string(int hart_count); + target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts, target_ulong firmware_end_addr); target_ulong riscv_find_and_load_firmware(MachineState *machine, -- cgit v1.2.3-55-g7522 From 4e8fb53c0b58cbb18cd243a5b067e4f26db83f77 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Fri, 22 Oct 2021 16:01:31 +1000 Subject: hw/riscv: sifive_u: Use the PLIC config helper function Signed-off-by: Alistair Francis Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Bin Meng Tested-by: Bin Meng Message-id: 20211022060133.3045020-3-alistair.francis@opensource.wdc.com --- hw/riscv/sifive_u.c | 14 +------------- include/hw/riscv/sifive_u.h | 1 - 2 files changed, 1 insertion(+), 14 deletions(-) (limited to 'include') diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 0217006c27..589ae72a59 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -811,7 +811,6 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp) MemoryRegion *mask_rom = g_new(MemoryRegion, 1); MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1); char *plic_hart_config; - size_t plic_hart_config_len; int i, j; NICInfo *nd = &nd_table[0]; @@ -852,18 +851,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp) l2lim_mem); /* create PLIC hart topology configuration string */ - plic_hart_config_len = (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1) * - ms->smp.cpus; - plic_hart_config = g_malloc0(plic_hart_config_len); - for (i = 0; i < ms->smp.cpus; i++) { - if (i != 0) { - strncat(plic_hart_config, "," SIFIVE_U_PLIC_HART_CONFIG, - plic_hart_config_len); - } else { - strncat(plic_hart_config, "M", plic_hart_config_len); - } - plic_hart_config_len -= (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1); - } + plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus); /* MMIO */ s->plic = sifive_plic_create(memmap[SIFIVE_U_DEV_PLIC].base, diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h index f71c90c94c..8f63a183c4 100644 --- a/include/hw/riscv/sifive_u.h +++ b/include/hw/riscv/sifive_u.h @@ -156,7 +156,6 @@ enum { #define SIFIVE_U_MANAGEMENT_CPU_COUNT 1 #define SIFIVE_U_COMPUTE_CPU_COUNT 4 -#define SIFIVE_U_PLIC_HART_CONFIG "MS" #define SIFIVE_U_PLIC_NUM_SOURCES 54 #define SIFIVE_U_PLIC_NUM_PRIORITIES 7 #define SIFIVE_U_PLIC_PRIORITY_BASE 0x04 -- cgit v1.2.3-55-g7522 From 8486eb8cdcd336de8ae52d95da45af97f54db63e Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Fri, 22 Oct 2021 16:01:32 +1000 Subject: hw/riscv: microchip_pfsoc: Use the PLIC config helper function Signed-off-by: Alistair Francis Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Bin Meng Tested-by: Bin Meng Message-id: 20211022060133.3045020-4-alistair.francis@opensource.wdc.com --- hw/riscv/microchip_pfsoc.c | 14 +------------- include/hw/riscv/microchip_pfsoc.h | 1 - 2 files changed, 1 insertion(+), 14 deletions(-) (limited to 'include') diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c index 3fc8545562..57d779fb55 100644 --- a/hw/riscv/microchip_pfsoc.c +++ b/hw/riscv/microchip_pfsoc.c @@ -187,7 +187,6 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) MemoryRegion *envm_data = g_new(MemoryRegion, 1); MemoryRegion *qspi_xip_mem = g_new(MemoryRegion, 1); char *plic_hart_config; - size_t plic_hart_config_len; NICInfo *nd; int i; @@ -262,18 +261,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) l2lim_mem); /* create PLIC hart topology configuration string */ - plic_hart_config_len = (strlen(MICROCHIP_PFSOC_PLIC_HART_CONFIG) + 1) * - ms->smp.cpus; - plic_hart_config = g_malloc0(plic_hart_config_len); - for (i = 0; i < ms->smp.cpus; i++) { - if (i != 0) { - strncat(plic_hart_config, "," MICROCHIP_PFSOC_PLIC_HART_CONFIG, - plic_hart_config_len); - } else { - strncat(plic_hart_config, "M", plic_hart_config_len); - } - plic_hart_config_len -= (strlen(MICROCHIP_PFSOC_PLIC_HART_CONFIG) + 1); - } + plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus); /* PLIC */ s->plic = sifive_plic_create(memmap[MICROCHIP_PFSOC_PLIC].base, diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h index d30916f45d..a0673f5f59 100644 --- a/include/hw/riscv/microchip_pfsoc.h +++ b/include/hw/riscv/microchip_pfsoc.h @@ -138,7 +138,6 @@ enum { #define MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT 1 #define MICROCHIP_PFSOC_COMPUTE_CPU_COUNT 4 -#define MICROCHIP_PFSOC_PLIC_HART_CONFIG "MS" #define MICROCHIP_PFSOC_PLIC_NUM_SOURCES 185 #define MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES 7 #define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE 0x04 -- cgit v1.2.3-55-g7522 From 0e9030376e1a8eb6d15cb5e69dffa09a6ff16b92 Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Fri, 22 Oct 2021 00:08:45 +0800 Subject: softfloat: add APIs to handle alternative sNaN propagation for fmax/fmin For "fmax/fmin ft0, ft1, ft2" and if one of the inputs is sNaN, The original logic: Return NaN and set invalid flag if ft1 == sNaN || ft2 == sNan. The alternative path: Set invalid flag if ft1 == sNaN || ft2 == sNaN. Return NaN only if ft1 == NaN && ft2 == NaN. The IEEE 754 spec allows both implementation and some architecture such as riscv choose different defintions in two spec versions. (riscv-spec-v2.2 use original version, riscv-spec-20191213 changes to alternative) Signed-off-by: Chih-Min Chao Signed-off-by: Frank Chang Reviewed-by: Richard Henderson Message-Id: <20211021160847.2748577-2-frank.chang@sifive.com> Signed-off-by: Alistair Francis --- fpu/softfloat-parts.c.inc | 25 +++++++++++++++++++++++-- fpu/softfloat.c | 19 +++++++++++++------ include/fpu/softfloat.h | 10 ++++++++++ 3 files changed, 46 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index dddee92d6e..41d4b17e41 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -1219,14 +1219,35 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b, if (unlikely(ab_mask & float_cmask_anynan)) { /* - * For minnum/maxnum, if one operand is a QNaN, and the other + * For minNum/maxNum (IEEE 754-2008) + * or minimumNumber/maximumNumber (IEEE 754-2019), + * if one operand is a QNaN, and the other * operand is numerical, then return numerical argument. */ - if ((flags & minmax_isnum) + if ((flags & (minmax_isnum | minmax_isnumber)) && !(ab_mask & float_cmask_snan) && (ab_mask & ~float_cmask_qnan)) { return is_nan(a->cls) ? b : a; } + + /* + * In IEEE 754-2019, minNum, maxNum, minNumMag and maxNumMag + * are removed and replaced with minimum, minimumNumber, maximum + * and maximumNumber. + * minimumNumber/maximumNumber behavior for SNaN is changed to: + * If both operands are NaNs, a QNaN is returned. + * If either operand is a SNaN, + * an invalid operation exception is signaled, + * but unless both operands are NaNs, + * the SNaN is otherwise ignored and not converted to a QNaN. + */ + if ((flags & minmax_isnumber) + && (ab_mask & float_cmask_snan) + && (ab_mask & ~float_cmask_anynan)) { + float_raise(float_flag_invalid, s); + return is_nan(a->cls) ? b : a; + } + return parts_pick_nan(a, b, s); } diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 6e769f990c..9a28720d82 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -436,6 +436,11 @@ enum { minmax_isnum = 2, /* Set for the IEEE 754-2008 minNumMag() and minNumMag() operations. */ minmax_ismag = 4, + /* + * Set for the IEEE 754-2019 minimumNumber() and maximumNumber() + * operations. + */ + minmax_isnumber = 8, }; /* Simple helpers for checking if, or what kind of, NaN we have */ @@ -3927,12 +3932,14 @@ static float128 float128_minmax(float128 a, float128 b, { return type##_minmax(a, b, s, flags); } #define MINMAX_2(type) \ - MINMAX_1(type, max, 0) \ - MINMAX_1(type, maxnum, minmax_isnum) \ - MINMAX_1(type, maxnummag, minmax_isnum | minmax_ismag) \ - MINMAX_1(type, min, minmax_ismin) \ - MINMAX_1(type, minnum, minmax_ismin | minmax_isnum) \ - MINMAX_1(type, minnummag, minmax_ismin | minmax_isnum | minmax_ismag) + MINMAX_1(type, max, 0) \ + MINMAX_1(type, maxnum, minmax_isnum) \ + MINMAX_1(type, maxnummag, minmax_isnum | minmax_ismag) \ + MINMAX_1(type, maximum_number, minmax_isnumber) \ + MINMAX_1(type, min, minmax_ismin) \ + MINMAX_1(type, minnum, minmax_ismin | minmax_isnum) \ + MINMAX_1(type, minnummag, minmax_ismin | minmax_isnum | minmax_ismag) \ + MINMAX_1(type, minimum_number, minmax_ismin | minmax_isnumber) \ MINMAX_2(float16) MINMAX_2(bfloat16) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index ec7dca0960..a249991e61 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -243,6 +243,8 @@ float16 float16_minnum(float16, float16, float_status *status); float16 float16_maxnum(float16, float16, float_status *status); float16 float16_minnummag(float16, float16, float_status *status); float16 float16_maxnummag(float16, float16, float_status *status); +float16 float16_minimum_number(float16, float16, float_status *status); +float16 float16_maximum_number(float16, float16, float_status *status); float16 float16_sqrt(float16, float_status *status); FloatRelation float16_compare(float16, float16, float_status *status); FloatRelation float16_compare_quiet(float16, float16, float_status *status); @@ -422,6 +424,8 @@ bfloat16 bfloat16_minnum(bfloat16, bfloat16, float_status *status); bfloat16 bfloat16_maxnum(bfloat16, bfloat16, float_status *status); bfloat16 bfloat16_minnummag(bfloat16, bfloat16, float_status *status); bfloat16 bfloat16_maxnummag(bfloat16, bfloat16, float_status *status); +bfloat16 bfloat16_minimum_number(bfloat16, bfloat16, float_status *status); +bfloat16 bfloat16_maximum_number(bfloat16, bfloat16, float_status *status); bfloat16 bfloat16_sqrt(bfloat16, float_status *status); FloatRelation bfloat16_compare(bfloat16, bfloat16, float_status *status); FloatRelation bfloat16_compare_quiet(bfloat16, bfloat16, float_status *status); @@ -589,6 +593,8 @@ float32 float32_minnum(float32, float32, float_status *status); float32 float32_maxnum(float32, float32, float_status *status); float32 float32_minnummag(float32, float32, float_status *status); float32 float32_maxnummag(float32, float32, float_status *status); +float32 float32_minimum_number(float32, float32, float_status *status); +float32 float32_maximum_number(float32, float32, float_status *status); bool float32_is_quiet_nan(float32, float_status *status); bool float32_is_signaling_nan(float32, float_status *status); float32 float32_silence_nan(float32, float_status *status); @@ -778,6 +784,8 @@ float64 float64_minnum(float64, float64, float_status *status); float64 float64_maxnum(float64, float64, float_status *status); float64 float64_minnummag(float64, float64, float_status *status); float64 float64_maxnummag(float64, float64, float_status *status); +float64 float64_minimum_number(float64, float64, float_status *status); +float64 float64_maximum_number(float64, float64, float_status *status); bool float64_is_quiet_nan(float64 a, float_status *status); bool float64_is_signaling_nan(float64, float_status *status); float64 float64_silence_nan(float64, float_status *status); @@ -1210,6 +1218,8 @@ float128 float128_minnum(float128, float128, float_status *status); float128 float128_maxnum(float128, float128, float_status *status); float128 float128_minnummag(float128, float128, float_status *status); float128 float128_maxnummag(float128, float128, float_status *status); +float128 float128_minimum_number(float128, float128, float_status *status); +float128 float128_maximum_number(float128, float128, float_status *status); bool float128_is_quiet_nan(float128, float_status *status); bool float128_is_signaling_nan(float128, float_status *status); float128 float128_silence_nan(float128, float_status *status); -- cgit v1.2.3-55-g7522