* [Qemu-devel] [PATCH 81/99] target/arm: Implement FP data-processing (3 source) for fp16
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Richard Henderson <richard.henderson@linaro.org>
We missed all of the scalar fp16 fma operations.
Cc: qemu-stable@nongnu.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180512003217.9105-8-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 95f9864fde6078e2d2c036a07cc4fe44f199be96)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
target/arm/translate-a64.c | 48 ++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 5260849f03..9880a5d047 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -5234,6 +5234,44 @@ static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
tcg_temp_free_i64(tcg_res);
}
+/* Floating-point data-processing (3 source) - half precision */
+static void handle_fp_3src_half(DisasContext *s, bool o0, bool o1,
+ int rd, int rn, int rm, int ra)
+{
+ TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
+ TCGv_ptr fpst = get_fpstatus_ptr(true);
+
+ tcg_op1 = read_fp_hreg(s, rn);
+ tcg_op2 = read_fp_hreg(s, rm);
+ tcg_op3 = read_fp_hreg(s, ra);
+
+ /* These are fused multiply-add, and must be done as one
+ * floating point operation with no rounding between the
+ * multiplication and addition steps.
+ * NB that doing the negations here as separate steps is
+ * correct : an input NaN should come out with its sign bit
+ * flipped if it is a negated-input.
+ */
+ if (o1 == true) {
+ tcg_gen_xori_i32(tcg_op3, tcg_op3, 0x8000);
+ }
+
+ if (o0 != o1) {
+ tcg_gen_xori_i32(tcg_op1, tcg_op1, 0x8000);
+ }
+
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);
+
+ write_fp_sreg(s, rd, tcg_res);
+
+ tcg_temp_free_ptr(fpst);
+ tcg_temp_free_i32(tcg_op1);
+ tcg_temp_free_i32(tcg_op2);
+ tcg_temp_free_i32(tcg_op3);
+ tcg_temp_free_i32(tcg_res);
+}
+
/* Floating point data-processing (3 source)
* 31 30 29 28 24 23 22 21 20 16 15 14 10 9 5 4 0
* +---+---+---+-----------+------+----+------+----+------+------+------+
@@ -5263,6 +5301,16 @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
}
handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra);
break;
+ case 3:
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ unallocated_encoding(s);
+ return;
+ }
+ if (!fp_access_check(s)) {
+ return;
+ }
+ handle_fp_3src_half(s, o0, o1, rd, rn, rm, ra);
+ break;
default:
unallocated_encoding(s);
}
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 07/99] target/arm: Implement v8M VLLDM and VLSTM
From: Michael Roth @ 2018-07-23 20:16 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Peter Maydell <peter.maydell@linaro.org>
For v8M the instructions VLLDM and VLSTM support lazy saving
and restoring of the secure floating-point registers. Even
if the floating point extension is not implemented, these
instructions must act as NOPs in Secure state, so they can
be used as part of the secure-to-nonsecure call sequence.
Fixes: https://bugs.launchpad.net/qemu/+bug/1768295
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180503105730.5958-1-peter.maydell@linaro.org
(cherry picked from commit b1e5336a9899016c53d59eba53ebf6abcc21995c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
target/arm/translate.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/target/arm/translate.c b/target/arm/translate.c
index db1ce6510a..64b9bf33af 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -10783,8 +10783,23 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
/* Coprocessor. */
if (arm_dc_feature(s, ARM_FEATURE_M)) {
/* We don't currently implement M profile FP support,
- * so this entire space should give a NOCP fault.
+ * so this entire space should give a NOCP fault, with
+ * the exception of the v8M VLLDM and VLSTM insns, which
+ * must be NOPs in Secure state and UNDEF in Nonsecure state.
*/
+ if (arm_dc_feature(s, ARM_FEATURE_V8) &&
+ (insn & 0xffa00f00) == 0xec200a00) {
+ /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
+ * - VLLDM, VLSTM
+ * We choose to UNDEF if the RAZ bits are non-zero.
+ */
+ if (!s->v8m_secure || (insn & 0x0040f0ff)) {
+ goto illegal_op;
+ }
+ /* Just NOP since FP support is not implemented */
+ break;
+ }
+ /* All other insns: NOCP */
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
default_exception_el(s));
break;
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 79/99] target/arm: Introduce and use read_fp_hreg
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Richard Henderson <richard.henderson@linaro.org>
Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180512003217.9105-6-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 3d99d931266eaeaf7e83703a53f32232cd6faad7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
target/arm/translate-a64.c | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index c5be901b5f..bcb3b5c5e7 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -614,6 +614,14 @@ static TCGv_i32 read_fp_sreg(DisasContext *s, int reg)
return v;
}
+static TCGv_i32 read_fp_hreg(DisasContext *s, int reg)
+{
+ TCGv_i32 v = tcg_temp_new_i32();
+
+ tcg_gen_ld16u_i32(v, cpu_env, fp_reg_offset(s, reg, MO_16));
+ return v;
+}
+
/* Clear the bits above an N-bit vector, for N = (is_q ? 128 : 64).
* If SVE is not enabled, then there are only 128 bits in the vector.
*/
@@ -4638,11 +4646,9 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
{
TCGv_ptr fpst = NULL;
- TCGv_i32 tcg_op = tcg_temp_new_i32();
+ TCGv_i32 tcg_op = read_fp_hreg(s, rn);
TCGv_i32 tcg_res = tcg_temp_new_i32();
- read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
-
switch (opcode) {
case 0x0: /* FMOV */
tcg_gen_mov_i32(tcg_res, tcg_op);
@@ -7538,13 +7544,10 @@ static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_op2);
tcg_temp_free_i64(tcg_res);
} else {
- TCGv_i32 tcg_op1 = tcg_temp_new_i32();
- TCGv_i32 tcg_op2 = tcg_temp_new_i32();
+ TCGv_i32 tcg_op1 = read_fp_hreg(s, rn);
+ TCGv_i32 tcg_op2 = read_fp_hreg(s, rm);
TCGv_i64 tcg_res = tcg_temp_new_i64();
- read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
- read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
-
gen_helper_neon_mull_s16(tcg_res, tcg_op1, tcg_op2);
gen_helper_neon_addl_saturate_s32(tcg_res, cpu_env, tcg_res, tcg_res);
@@ -8085,13 +8088,10 @@ static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s,
fpst = get_fpstatus_ptr(true);
- tcg_op1 = tcg_temp_new_i32();
- tcg_op2 = tcg_temp_new_i32();
+ tcg_op1 = read_fp_hreg(s, rn);
+ tcg_op2 = read_fp_hreg(s, rm);
tcg_res = tcg_temp_new_i32();
- read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
- read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
-
switch (fpopcode) {
case 0x03: /* FMULX */
gen_helper_advsimd_mulxh(tcg_res, tcg_op1, tcg_op2, fpst);
@@ -12010,11 +12010,9 @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
}
if (is_scalar) {
- TCGv_i32 tcg_op = tcg_temp_new_i32();
+ TCGv_i32 tcg_op = read_fp_hreg(s, rn);
TCGv_i32 tcg_res = tcg_temp_new_i32();
- read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
-
switch (fpop) {
case 0x1a: /* FCVTNS */
case 0x1b: /* FCVTMS */
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 80/99] target/arm: Implement FP data-processing (2 source) for fp16
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Richard Henderson <richard.henderson@linaro.org>
We missed all of the scalar fp16 binary operations.
Cc: qemu-stable@nongnu.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180512003217.9105-7-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit b8f5171cf01420a9f0ee895c5591e9b9914f391a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
target/arm/translate-a64.c | 65 ++++++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index bcb3b5c5e7..5260849f03 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -5056,6 +5056,61 @@ static void handle_fp_2src_double(DisasContext *s, int opcode,
tcg_temp_free_i64(tcg_res);
}
+/* Floating-point data-processing (2 source) - half precision */
+static void handle_fp_2src_half(DisasContext *s, int opcode,
+ int rd, int rn, int rm)
+{
+ TCGv_i32 tcg_op1;
+ TCGv_i32 tcg_op2;
+ TCGv_i32 tcg_res;
+ TCGv_ptr fpst;
+
+ tcg_res = tcg_temp_new_i32();
+ fpst = get_fpstatus_ptr(true);
+ tcg_op1 = read_fp_hreg(s, rn);
+ tcg_op2 = read_fp_hreg(s, rm);
+
+ switch (opcode) {
+ case 0x0: /* FMUL */
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x1: /* FDIV */
+ gen_helper_advsimd_divh(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x2: /* FADD */
+ gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x3: /* FSUB */
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x4: /* FMAX */
+ gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x5: /* FMIN */
+ gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x6: /* FMAXNM */
+ gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x7: /* FMINNM */
+ gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x8: /* FNMUL */
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
+ tcg_gen_xori_i32(tcg_res, tcg_res, 0x8000);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ write_fp_sreg(s, rd, tcg_res);
+
+ tcg_temp_free_ptr(fpst);
+ tcg_temp_free_i32(tcg_op1);
+ tcg_temp_free_i32(tcg_op2);
+ tcg_temp_free_i32(tcg_res);
+}
+
/* Floating point data-processing (2 source)
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
* +---+---+---+-----------+------+---+------+--------+-----+------+------+
@@ -5088,6 +5143,16 @@ static void disas_fp_2src(DisasContext *s, uint32_t insn)
}
handle_fp_2src_double(s, opcode, rd, rn, rm);
break;
+ case 3:
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ unallocated_encoding(s);
+ return;
+ }
+ if (!fp_access_check(s)) {
+ return;
+ }
+ handle_fp_2src_half(s, opcode, rd, rn, rm);
+ break;
default:
unallocated_encoding(s);
}
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 78/99] target/arm: Implement FCVT (scalar, fixed-point) for fp16
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Richard Henderson <richard.henderson@linaro.org>
Cc: qemu-stable@nongnu.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180512003217.9105-5-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 2752728016bef06e7c9cfb961019272859beeca4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
target/arm/translate-a64.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 33be611bdb..c5be901b5f 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -5454,8 +5454,21 @@ static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
bool sf = extract32(insn, 31, 1);
bool itof;
- if (sbit || (type > 1)
- || (!sf && scale < 32)) {
+ if (sbit || (!sf && scale < 32)) {
+ unallocated_encoding(s);
+ return;
+ }
+
+ switch (type) {
+ case 0: /* float32 */
+ case 1: /* float64 */
+ break;
+ case 3: /* float16 */
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ break;
+ }
+ /* fallthru */
+ default:
unallocated_encoding(s);
return;
}
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 77/99] target/arm: Implement FCVT (scalar, integer) for fp16
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Richard Henderson <richard.henderson@linaro.org>
Cc: qemu-stable@nongnu.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180512003217.9105-4-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 564a0632504fad840491aa9a59453f4e64a316c4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
target/arm/helper.c | 38 ++++++++++++++-
target/arm/helper.h | 6 +++
target/arm/translate-a64.c | 96 +++++++++++++++++++++++++++++++-------
3 files changed, 122 insertions(+), 18 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index c07c1d7f48..1043d6ed32 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11416,8 +11416,12 @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
#undef VFP_CONV_FIX_A64
/* Conversion to/from f16 can overflow to infinity before/after scaling.
- * Therefore we convert to f64 (which does not round), scale,
- * and then convert f64 to f16 (which may round).
+ * Therefore we convert to f64, scale, and then convert f64 to f16; or
+ * vice versa for conversion to integer.
+ *
+ * For 16- and 32-bit integers, the conversion to f64 never rounds.
+ * For 64-bit integers, any integer that would cause rounding will also
+ * overflow to f16 infinity, so there is no double rounding problem.
*/
static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
@@ -11435,6 +11439,16 @@ float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
}
+float16 HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
+{
+ return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst);
+}
+
+float16 HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
+{
+ return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst);
+}
+
static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
{
if (unlikely(float16_is_any_nan(f))) {
@@ -11464,6 +11478,26 @@ uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst)
return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
}
+uint32_t HELPER(vfp_toslh)(float16 x, uint32_t shift, void *fpst)
+{
+ return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst);
+}
+
+uint32_t HELPER(vfp_toulh)(float16 x, uint32_t shift, void *fpst)
+{
+ return float64_to_uint32(do_prescale_fp16(x, shift, fpst), fpst);
+}
+
+uint64_t HELPER(vfp_tosqh)(float16 x, uint32_t shift, void *fpst)
+{
+ return float64_to_int64(do_prescale_fp16(x, shift, fpst), fpst);
+}
+
+uint64_t HELPER(vfp_touqh)(float16 x, uint32_t shift, void *fpst)
+{
+ return float64_to_uint64(do_prescale_fp16(x, shift, fpst), fpst);
+}
+
/* Set the current fp rounding mode and return the old one.
* The argument is a softfloat float_round_ value.
*/
diff --git a/target/arm/helper.h b/target/arm/helper.h
index 1969b37f2d..ce89968b2d 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -151,6 +151,10 @@ DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_touhh, i32, f16, i32, ptr)
DEF_HELPER_3(vfp_toshh, i32, f16, i32, ptr)
+DEF_HELPER_3(vfp_toulh, i32, f16, i32, ptr)
+DEF_HELPER_3(vfp_toslh, i32, f16, i32, ptr)
+DEF_HELPER_3(vfp_touqh, i64, f16, i32, ptr)
+DEF_HELPER_3(vfp_tosqh, i64, f16, i32, ptr)
DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr)
DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr)
DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr)
@@ -177,6 +181,8 @@ DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr)
DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr)
DEF_HELPER_3(vfp_sltoh, f16, i32, i32, ptr)
DEF_HELPER_3(vfp_ultoh, f16, i32, i32, ptr)
+DEF_HELPER_3(vfp_sqtoh, f16, i64, i32, ptr)
+DEF_HELPER_3(vfp_uqtoh, f16, i64, i32, ptr)
DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr)
DEF_HELPER_FLAGS_2(set_neon_rmode, TCG_CALL_NO_RWG, i32, i32, env)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index b05f9bfe91..33be611bdb 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -5268,11 +5268,11 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
bool itof, int rmode, int scale, int sf, int type)
{
bool is_signed = !(opcode & 1);
- bool is_double = type;
TCGv_ptr tcg_fpstatus;
- TCGv_i32 tcg_shift;
+ TCGv_i32 tcg_shift, tcg_single;
+ TCGv_i64 tcg_double;
- tcg_fpstatus = get_fpstatus_ptr(false);
+ tcg_fpstatus = get_fpstatus_ptr(type == 3);
tcg_shift = tcg_const_i32(64 - scale);
@@ -5290,8 +5290,9 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
tcg_int = tcg_extend;
}
- if (is_double) {
- TCGv_i64 tcg_double = tcg_temp_new_i64();
+ switch (type) {
+ case 1: /* float64 */
+ tcg_double = tcg_temp_new_i64();
if (is_signed) {
gen_helper_vfp_sqtod(tcg_double, tcg_int,
tcg_shift, tcg_fpstatus);
@@ -5301,8 +5302,10 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
}
write_fp_dreg(s, rd, tcg_double);
tcg_temp_free_i64(tcg_double);
- } else {
- TCGv_i32 tcg_single = tcg_temp_new_i32();
+ break;
+
+ case 0: /* float32 */
+ tcg_single = tcg_temp_new_i32();
if (is_signed) {
gen_helper_vfp_sqtos(tcg_single, tcg_int,
tcg_shift, tcg_fpstatus);
@@ -5312,6 +5315,23 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
}
write_fp_sreg(s, rd, tcg_single);
tcg_temp_free_i32(tcg_single);
+ break;
+
+ case 3: /* float16 */
+ tcg_single = tcg_temp_new_i32();
+ if (is_signed) {
+ gen_helper_vfp_sqtoh(tcg_single, tcg_int,
+ tcg_shift, tcg_fpstatus);
+ } else {
+ gen_helper_vfp_uqtoh(tcg_single, tcg_int,
+ tcg_shift, tcg_fpstatus);
+ }
+ write_fp_sreg(s, rd, tcg_single);
+ tcg_temp_free_i32(tcg_single);
+ break;
+
+ default:
+ g_assert_not_reached();
}
} else {
TCGv_i64 tcg_int = cpu_reg(s, rd);
@@ -5328,8 +5348,9 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
- if (is_double) {
- TCGv_i64 tcg_double = read_fp_dreg(s, rn);
+ switch (type) {
+ case 1: /* float64 */
+ tcg_double = read_fp_dreg(s, rn);
if (is_signed) {
if (!sf) {
gen_helper_vfp_tosld(tcg_int, tcg_double,
@@ -5347,9 +5368,14 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
tcg_shift, tcg_fpstatus);
}
}
+ if (!sf) {
+ tcg_gen_ext32u_i64(tcg_int, tcg_int);
+ }
tcg_temp_free_i64(tcg_double);
- } else {
- TCGv_i32 tcg_single = read_fp_sreg(s, rn);
+ break;
+
+ case 0: /* float32 */
+ tcg_single = read_fp_sreg(s, rn);
if (sf) {
if (is_signed) {
gen_helper_vfp_tosqs(tcg_int, tcg_single,
@@ -5371,14 +5397,39 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
tcg_temp_free_i32(tcg_dest);
}
tcg_temp_free_i32(tcg_single);
+ break;
+
+ case 3: /* float16 */
+ tcg_single = read_fp_sreg(s, rn);
+ if (sf) {
+ if (is_signed) {
+ gen_helper_vfp_tosqh(tcg_int, tcg_single,
+ tcg_shift, tcg_fpstatus);
+ } else {
+ gen_helper_vfp_touqh(tcg_int, tcg_single,
+ tcg_shift, tcg_fpstatus);
+ }
+ } else {
+ TCGv_i32 tcg_dest = tcg_temp_new_i32();
+ if (is_signed) {
+ gen_helper_vfp_toslh(tcg_dest, tcg_single,
+ tcg_shift, tcg_fpstatus);
+ } else {
+ gen_helper_vfp_toulh(tcg_dest, tcg_single,
+ tcg_shift, tcg_fpstatus);
+ }
+ tcg_gen_extu_i32_i64(tcg_int, tcg_dest);
+ tcg_temp_free_i32(tcg_dest);
+ }
+ tcg_temp_free_i32(tcg_single);
+ break;
+
+ default:
+ g_assert_not_reached();
}
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
tcg_temp_free_i32(tcg_rmode);
-
- if (!sf) {
- tcg_gen_ext32u_i64(tcg_int, tcg_int);
- }
}
tcg_temp_free_ptr(tcg_fpstatus);
@@ -5548,7 +5599,20 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
/* actual FP conversions */
bool itof = extract32(opcode, 1, 1);
- if (type > 1 || (rmode != 0 && opcode > 1)) {
+ if (rmode != 0 && opcode > 1) {
+ unallocated_encoding(s);
+ return;
+ }
+ switch (type) {
+ case 0: /* float32 */
+ case 1: /* float64 */
+ break;
+ case 3: /* float16 */
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ break;
+ }
+ /* fallthru */
+ default:
unallocated_encoding(s);
return;
}
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 75/99] fpu/softfloat: Fix conversion from uint64 to float128
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Petr Tesarik, Richard Henderson
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Petr Tesarik <ptesarik@suse.com>
The significand is passed to normalizeRoundAndPackFloat128() as high
first, low second. The current code passes the integer first, so the
result is incorrectly shifted left by 64 bits.
This bug affects the emulation of s390x instruction CXLGBR (convert
from logical 64-bit binary-integer operand to extended BFP result).
Cc: qemu-stable@nongnu.org
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
Message-Id: <20180511071052.1443-1-ptesarik@suse.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 6603d50648901e8b9e6d66ec1142accf0b1df1e6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
fpu/softfloat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 9bcaaebe4f..a926b91864 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -3147,7 +3147,7 @@ float128 uint64_to_float128(uint64_t a, float_status *status)
if (a == 0) {
return float128_zero;
}
- return normalizeRoundAndPackFloat128(0, 0x406E, a, 0, status);
+ return normalizeRoundAndPackFloat128(0, 0x406E, 0, a, status);
}
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 76/99] target/arm: Implement FMOV (general) for fp16
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Richard Henderson <richard.henderson@linaro.org>
Adding the fp16 moves to/from general registers.
Cc: qemu-stable@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180512003217.9105-2-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 68130236e30a1ec64363f4915349feee181bfbc1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
target/arm/translate-a64.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 639cd95772..b05f9bfe91 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -5457,6 +5457,15 @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_hi_offset(s, rd));
clear_vec_high(s, true, rd);
break;
+ case 3:
+ /* 16 bit */
+ tmp = tcg_temp_new_i64();
+ tcg_gen_ext16u_i64(tmp, tcg_rn);
+ write_fp_dreg(s, rd, tmp);
+ tcg_temp_free_i64(tmp);
+ break;
+ default:
+ g_assert_not_reached();
}
} else {
TCGv_i64 tcg_rd = cpu_reg(s, rd);
@@ -5474,6 +5483,12 @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
/* 64 bits from top half */
tcg_gen_ld_i64(tcg_rd, cpu_env, fp_reg_hi_offset(s, rn));
break;
+ case 3:
+ /* 16 bit */
+ tcg_gen_ld16u_i64(tcg_rd, cpu_env, fp_reg_offset(s, rn, MO_16));
+ break;
+ default:
+ g_assert_not_reached();
}
}
}
@@ -5513,6 +5528,12 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
case 0xa: /* 64 bit */
case 0xd: /* 64 bit to top half of quad */
break;
+ case 0x6: /* 16-bit float, 32-bit int */
+ case 0xe: /* 16-bit float, 64-bit int */
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ break;
+ }
+ /* fallthru */
default:
/* all other sf/type/rmode combinations are invalid */
unallocated_encoding(s);
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 74/99] target/arm: Clear SVE high bits for FMOV
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Richard Henderson <richard.henderson@linaro.org>
Use write_fp_dreg and clear_vec_high to zero the bits
that need zeroing for these cases.
Cc: qemu-stable@nongnu.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180502221552.3873-5-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 9a9f1f59521f46e8ff4527d9a2b52f83577e2aa3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
target/arm/translate-a64.c | 17 +++++------------
1 file changed, 5 insertions(+), 12 deletions(-)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 3c4c9b9fdc..639cd95772 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -5438,31 +5438,24 @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
if (itof) {
TCGv_i64 tcg_rn = cpu_reg(s, rn);
+ TCGv_i64 tmp;
switch (type) {
case 0:
- {
/* 32 bit */
- TCGv_i64 tmp = tcg_temp_new_i64();
+ tmp = tcg_temp_new_i64();
tcg_gen_ext32u_i64(tmp, tcg_rn);
- tcg_gen_st_i64(tmp, cpu_env, fp_reg_offset(s, rd, MO_64));
- tcg_gen_movi_i64(tmp, 0);
- tcg_gen_st_i64(tmp, cpu_env, fp_reg_hi_offset(s, rd));
+ write_fp_dreg(s, rd, tmp);
tcg_temp_free_i64(tmp);
break;
- }
case 1:
- {
/* 64 bit */
- TCGv_i64 tmp = tcg_const_i64(0);
- tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_offset(s, rd, MO_64));
- tcg_gen_st_i64(tmp, cpu_env, fp_reg_hi_offset(s, rd));
- tcg_temp_free_i64(tmp);
+ write_fp_dreg(s, rd, tcg_rn);
break;
- }
case 2:
/* 64 bit to top half. */
tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_hi_offset(s, rd));
+ clear_vec_high(s, true, rd);
break;
}
} else {
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 73/99] target/arm: Fix float16 to/from int16
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Richard Henderson <richard.henderson@linaro.org>
The instruction "ucvtf v0.4h, v04h, #2", with input 0x8000u,
overflows the intermediate float16 to infinity before we have a
chance to scale the output. Use float64 as the intermediate type
so that no input argument (uint32_t in this case) can overflow
or round before scaling. Given the declared argument, the signed
int32_t function has the same problem.
When converting from float16 to integer, using u/int32_t instead
of u/int16_t means that the bounding is incorrect.
Cc: qemu-stable@nongnu.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180502221552.3873-4-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 88808a022c06f98d81cd3f2d105a5734c5614839)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
target/arm/helper.c | 53 ++++++++++++++++++++++++++++++++++++--
target/arm/helper.h | 4 +--
target/arm/translate-a64.c | 4 +--
3 files changed, 55 insertions(+), 6 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b14fdab140..c07c1d7f48 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11409,11 +11409,60 @@ VFP_CONV_FIX_A64(sq, s, 32, 64, int64)
VFP_CONV_FIX(uh, s, 32, 32, uint16)
VFP_CONV_FIX(ul, s, 32, 32, uint32)
VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
-VFP_CONV_FIX_A64(sl, h, 16, 32, int32)
-VFP_CONV_FIX_A64(ul, h, 16, 32, uint32)
+
#undef VFP_CONV_FIX
#undef VFP_CONV_FIX_FLOAT
#undef VFP_CONV_FLOAT_FIX_ROUND
+#undef VFP_CONV_FIX_A64
+
+/* Conversion to/from f16 can overflow to infinity before/after scaling.
+ * Therefore we convert to f64 (which does not round), scale,
+ * and then convert f64 to f16 (which may round).
+ */
+
+static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
+{
+ return float64_to_float16(float64_scalbn(f, -shift, fpst), true, fpst);
+}
+
+float16 HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
+{
+ return do_postscale_fp16(int32_to_float64(x, fpst), shift, fpst);
+}
+
+float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
+{
+ return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
+}
+
+static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
+{
+ if (unlikely(float16_is_any_nan(f))) {
+ float_raise(float_flag_invalid, fpst);
+ return 0;
+ } else {
+ int old_exc_flags = get_float_exception_flags(fpst);
+ float64 ret;
+
+ ret = float16_to_float64(f, true, fpst);
+ ret = float64_scalbn(ret, shift, fpst);
+ old_exc_flags |= get_float_exception_flags(fpst)
+ & float_flag_input_denormal;
+ set_float_exception_flags(old_exc_flags, fpst);
+
+ return ret;
+ }
+}
+
+uint32_t HELPER(vfp_toshh)(float16 x, uint32_t shift, void *fpst)
+{
+ return float64_to_int16(do_prescale_fp16(x, shift, fpst), fpst);
+}
+
+uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst)
+{
+ return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
+}
/* Set the current fp rounding mode and return the old one.
* The argument is a softfloat float_round_ value.
diff --git a/target/arm/helper.h b/target/arm/helper.h
index 34e8cc8904..1969b37f2d 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -149,8 +149,8 @@ DEF_HELPER_3(vfp_toshd_round_to_zero, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_tosld_round_to_zero, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr)
-DEF_HELPER_3(vfp_toulh, i32, f16, i32, ptr)
-DEF_HELPER_3(vfp_toslh, i32, f16, i32, ptr)
+DEF_HELPER_3(vfp_touhh, i32, f16, i32, ptr)
+DEF_HELPER_3(vfp_toshh, i32, f16, i32, ptr)
DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr)
DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr)
DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 61735dc185..3c4c9b9fdc 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -7263,9 +7263,9 @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
switch (size) {
case MO_16:
if (is_u) {
- fn = gen_helper_vfp_toulh;
+ fn = gen_helper_vfp_touhh;
} else {
- fn = gen_helper_vfp_toslh;
+ fn = gen_helper_vfp_toshh;
}
break;
case MO_32:
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 72/99] target/arm: Implement vector shifted FCVT for fp16
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Richard Henderson <richard.henderson@linaro.org>
While we have some of the scalar paths for FCVT for fp16,
we failed to decode the fp16 version of these instructions.
Cc: qemu-stable@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180502221552.3873-3-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit d0ba8e74acd299b092786ffc30b306638d395a9e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
target/arm/translate-a64.c | 63 +++++++++++++++++++++++++++-----------
1 file changed, 45 insertions(+), 18 deletions(-)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index f0fa6045e4..61735dc185 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -7202,19 +7202,28 @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
bool is_q, bool is_u,
int immh, int immb, int rn, int rd)
{
- bool is_double = extract32(immh, 3, 1);
int immhb = immh << 3 | immb;
- int fracbits = (is_double ? 128 : 64) - immhb;
- int pass;
+ int pass, size, fracbits;
TCGv_ptr tcg_fpstatus;
TCGv_i32 tcg_rmode, tcg_shift;
- if (!extract32(immh, 2, 2)) {
- unallocated_encoding(s);
- return;
- }
-
- if (!is_scalar && !is_q && is_double) {
+ if (immh & 0x8) {
+ size = MO_64;
+ if (!is_scalar && !is_q) {
+ unallocated_encoding(s);
+ return;
+ }
+ } else if (immh & 0x4) {
+ size = MO_32;
+ } else if (immh & 0x2) {
+ size = MO_16;
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ unallocated_encoding(s);
+ return;
+ }
+ } else {
+ /* Should have split out AdvSIMD modified immediate earlier. */
+ assert(immh == 1);
unallocated_encoding(s);
return;
}
@@ -7226,11 +7235,12 @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
assert(!(is_scalar && is_q));
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(FPROUNDING_ZERO));
- tcg_fpstatus = get_fpstatus_ptr(false);
+ tcg_fpstatus = get_fpstatus_ptr(size == MO_16);
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
+ fracbits = (16 << size) - immhb;
tcg_shift = tcg_const_i32(fracbits);
- if (is_double) {
+ if (size == MO_64) {
int maxpass = is_scalar ? 1 : 2;
for (pass = 0; pass < maxpass; pass++) {
@@ -7247,20 +7257,37 @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
}
clear_vec_high(s, is_q, rd);
} else {
- int maxpass = is_scalar ? 1 : is_q ? 4 : 2;
- for (pass = 0; pass < maxpass; pass++) {
- TCGv_i32 tcg_op = tcg_temp_new_i32();
+ void (*fn)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
+ int maxpass = is_scalar ? 1 : ((8 << is_q) >> size);
- read_vec_element_i32(s, tcg_op, rn, pass, MO_32);
+ switch (size) {
+ case MO_16:
+ if (is_u) {
+ fn = gen_helper_vfp_toulh;
+ } else {
+ fn = gen_helper_vfp_toslh;
+ }
+ break;
+ case MO_32:
if (is_u) {
- gen_helper_vfp_touls(tcg_op, tcg_op, tcg_shift, tcg_fpstatus);
+ fn = gen_helper_vfp_touls;
} else {
- gen_helper_vfp_tosls(tcg_op, tcg_op, tcg_shift, tcg_fpstatus);
+ fn = gen_helper_vfp_tosls;
}
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ for (pass = 0; pass < maxpass; pass++) {
+ TCGv_i32 tcg_op = tcg_temp_new_i32();
+
+ read_vec_element_i32(s, tcg_op, rn, pass, size);
+ fn(tcg_op, tcg_op, tcg_shift, tcg_fpstatus);
if (is_scalar) {
write_fp_sreg(s, rd, tcg_op);
} else {
- write_vec_element_i32(s, tcg_op, rd, pass, MO_32);
+ write_vec_element_i32(s, tcg_op, rd, pass, size);
}
tcg_temp_free_i32(tcg_op);
}
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 71/99] target/arm: Implement vector shifted SCVF/UCVF for fp16
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Richard Henderson <richard.henderson@linaro.org>
While we have some of the scalar paths for *CVF for fp16,
we failed to decode the fp16 version of these instructions.
Cc: qemu-stable@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180502221552.3873-2-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit a6117fae4576edfe7a5a5b802a742c33112c0993)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
target/arm/translate-a64.c | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index c91329249d..f0fa6045e4 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -7159,13 +7159,26 @@ static void handle_simd_shift_intfp_conv(DisasContext *s, bool is_scalar,
int immh, int immb, int opcode,
int rn, int rd)
{
- bool is_double = extract32(immh, 3, 1);
- int size = is_double ? MO_64 : MO_32;
- int elements;
+ int size, elements, fracbits;
int immhb = immh << 3 | immb;
- int fracbits = (is_double ? 128 : 64) - immhb;
- if (!extract32(immh, 2, 2)) {
+ if (immh & 8) {
+ size = MO_64;
+ if (!is_scalar && !is_q) {
+ unallocated_encoding(s);
+ return;
+ }
+ } else if (immh & 4) {
+ size = MO_32;
+ } else if (immh & 2) {
+ size = MO_16;
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ unallocated_encoding(s);
+ return;
+ }
+ } else {
+ /* immh == 0 would be a failure of the decode logic */
+ g_assert(immh == 1);
unallocated_encoding(s);
return;
}
@@ -7173,20 +7186,14 @@ static void handle_simd_shift_intfp_conv(DisasContext *s, bool is_scalar,
if (is_scalar) {
elements = 1;
} else {
- elements = is_double ? 2 : is_q ? 4 : 2;
- if (is_double && !is_q) {
- unallocated_encoding(s);
- return;
- }
+ elements = (8 << is_q) >> size;
}
+ fracbits = (16 << size) - immhb;
if (!fp_access_check(s)) {
return;
}
- /* immh == 0 would be a failure of the decode logic */
- g_assert(immh);
-
handle_simd_intfp_conv(s, rd, rn, elements, !is_u, fracbits, size);
}
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 06/99] tcg/arm: Fix memory barrier encoding
From: Michael Roth @ 2018-07-23 20:16 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Henry Wertz, Richard Henderson
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Henry Wertz <hwertz10@gmail.com>
I found with qemu 2.11.x or newer that I would get an illegal instruction
error running some Intel binaries on my ARM chromebook. On investigation,
I found it was quitting on memory barriers.
qemu instruction:
mb $0x31
was translating as:
0x604050cc: 5bf07ff5 blpl #0x600250a8
After patch it gives:
0x604050cc: f57ff05b dmb ish
In short, I found INSN_DMB_ISH (memory barrier for ARMv7) appeared to be
correct based on online docs, but due to some endian-related shenanigans it
had to be byte-swapped to suit qemu; it appears INSN_DMB_MCR (memory
barrier for ARMv6) also should be byte swapped (and this patch does so).
I have not checked for correctness of aarch64's barrier instruction.
Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Henry Wertz <hwertz10@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 3f814b803797c007abfe5c4041de754e01723031)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
tcg/arm/tcg-target.inc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c
index dc83f3e5be..56a32a470f 100644
--- a/tcg/arm/tcg-target.inc.c
+++ b/tcg/arm/tcg-target.inc.c
@@ -159,8 +159,8 @@ typedef enum {
INSN_STRD_IMM = 0x004000f0,
INSN_STRD_REG = 0x000000f0,
- INSN_DMB_ISH = 0x5bf07ff5,
- INSN_DMB_MCR = 0xba0f07ee,
+ INSN_DMB_ISH = 0xf57ff05b,
+ INSN_DMB_MCR = 0xee070fba,
/* Architected nop introduced in v6k. */
/* ??? This is an MSR (imm) 0,0,0 insn. Anyone know if this
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 70/99] fpu/softfloat: Don't set Invalid for float-to-int(MAXINT)
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Peter Maydell <peter.maydell@linaro.org>
In float-to-integer conversion, if the floating point input
converts exactly to the largest or smallest integer that
fits in to the result type, this is not an overflow.
In this situation we were producing the correct result value,
but were incorrectly setting the Invalid flag.
For example for Arm A64, "FCVTAS w0, d0" on an input of
0x41dfffffffc00000 should produce 0x7fffffff and set no flags.
Fix the boundary case to take the right half of the if()
statements.
This fixes a regression from 2.11 introduced by the softfloat
refactoring.
Cc: qemu-stable@nongnu.org
Fixes: ab52f973a50
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180510140141.12120-1-peter.maydell@linaro.org
(cherry picked from commit 333583757c5e910b040bef793974773635ce1918)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
fpu/softfloat.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 8401b37bd4..9bcaaebe4f 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1368,14 +1368,14 @@ static int64_t round_to_int_and_pack(FloatParts in, int rmode,
r = UINT64_MAX;
}
if (p.sign) {
- if (r < -(uint64_t) min) {
+ if (r <= -(uint64_t) min) {
return -r;
} else {
s->float_exception_flags = orig_flags | float_flag_invalid;
return min;
}
} else {
- if (r < max) {
+ if (r <= max) {
return r;
} else {
s->float_exception_flags = orig_flags | float_flag_invalid;
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 69/99] target/arm: Fix fp_status_f16 tininess before rounding
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Peter Maydell <peter.maydell@linaro.org>
In commit d81ce0ef2c4f105 we added an extra float_status field
fp_status_fp16 for Arm, but forgot to initialize it correctly
by setting it to float_tininess_before_rounding. This currently
will only cause problems for the new V8_FP16 feature, since the
float-to-float conversion code doesn't use it yet. The effect
would be that we failed to set the Underflow IEEE exception flag
in all the cases where we should.
Add the missing initialization.
Fixes: d81ce0ef2c4f105
Cc: qemu-stable@nongnu.org
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20180512004311.9299-16-richard.henderson@linaro.org
(cherry picked from commit bcc531f0364796104df4443d17f99b5fb494eca2)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
target/arm/cpu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 022d8c5787..7ebe3fcadf 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -311,6 +311,8 @@ static void arm_cpu_reset(CPUState *s)
&env->vfp.fp_status);
set_float_detect_tininess(float_tininess_before_rounding,
&env->vfp.standard_fp_status);
+ set_float_detect_tininess(float_tininess_before_rounding,
+ &env->vfp.fp_status_f16);
#ifndef CONFIG_USER_ONLY
if (kvm_enabled()) {
kvm_arm_reset_vcpu(cpu);
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 68/99] blockjob: expose error string via query
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, John Snow, Kevin Wolf
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: John Snow <jsnow@redhat.com>
When we've reached the concluded state, we need to expose the error
state if applicable. Add the new field.
This should be sufficient for determining if a job completed
successfully or not after concluding; if we want to discriminate
based on how it failed more mechanically, we can always add an
explicit return code enumeration later.
I didn't bother to make it only show up if we are in the concluded
state; I don't think it's necessary.
Cc: qemu-stable@nongnu.org
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit ab9ba614556ac5b0f8d96b99e0dba19f1e28d6c2)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
blockjob.c | 2 ++
qapi/block-core.json | 6 +++++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/blockjob.c b/blockjob.c
index 27f957e571..4de48166b2 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -831,6 +831,8 @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
info->status = job->status;
info->auto_finalize = job->auto_finalize;
info->auto_dismiss = job->auto_dismiss;
+ info->has_error = job->ret != 0;
+ info->error = job->ret ? g_strdup(strerror(-job->ret)) : NULL;
return info;
}
diff --git a/qapi/block-core.json b/qapi/block-core.json
index c50517bff3..7da3bea6bc 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1172,6 +1172,9 @@
# @auto-dismiss: Job will dismiss itself when CONCLUDED, moving to the NULL
# state and disappearing from the query list. (since 2.12)
#
+# @error: Error information if the job did not complete successfully.
+# Not set if the job completed successfully. (since 2.12.1)
+#
# Since: 1.1
##
{ 'struct': 'BlockJobInfo',
@@ -1179,7 +1182,8 @@
'offset': 'int', 'busy': 'bool', 'paused': 'bool', 'speed': 'int',
'io-status': 'BlockDeviceIoStatus', 'ready': 'bool',
'status': 'BlockJobStatus',
- 'auto-finalize': 'bool', 'auto-dismiss': 'bool' } }
+ 'auto-finalize': 'bool', 'auto-dismiss': 'bool',
+ '*error': 'str' } }
##
# @query-block-jobs:
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 67/99] RISC-V: Minimal QEMU 2.12 fix for sifive_u machine
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Michael Clark, Sagar Karandikar, Bastian Koppelmann,
Palmer Dabbelt, Alistair Francis
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Michael Clark <mjc@sifive.com>
The 'sifive_u' board has a bug where the ROM is
created as RAM at the wrong address and marked
readonly. The bug renders the board unusable.
This is a minimal fix and allows booting Linux.
5aec3247c190f10654250203a1742490ae7343a2
"RISC-V: Mark ROM read-only after copying in code"
contains a comprehensive fix using the ROM APIs
memory_region_init_rom and rom_add_blob_fixed_as
which could be backported.
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Michael Clark <mjc@sifive.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
hw/riscv/sifive_u.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 1c2deefa6c..19b034449c 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -250,9 +250,9 @@ static void riscv_sifive_u_init(MachineState *machine)
/* boot rom */
memory_region_init_ram(boot_rom, NULL, "riscv.sifive.u.mrom",
- memmap[SIFIVE_U_MROM].base, &error_fatal);
- memory_region_set_readonly(boot_rom, true);
- memory_region_add_subregion(sys_memory, 0x0, boot_rom);
+ memmap[SIFIVE_U_MROM].size, &error_fatal);
+ memory_region_add_subregion(sys_memory, memmap[SIFIVE_U_MROM].base,
+ boot_rom);
if (machine->kernel_filename) {
load_kernel(machine->kernel_filename);
@@ -282,6 +282,7 @@ static void riscv_sifive_u_init(MachineState *machine)
qemu_fdt_dumpdtb(s->fdt, s->fdt_size);
cpu_physical_memory_write(memmap[SIFIVE_U_MROM].base +
sizeof(reset_vec), s->fdt, s->fdt_size);
+ memory_region_set_readonly(boot_rom, true);
/* MMIO */
s->plic = sifive_plic_create(memmap[SIFIVE_U_PLIC].base,
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 66/99] tcg: Limit the number of ops in a TB
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Richard Henderson <richard.henderson@linaro.org>
In 6001f7729e12 we partially attempt to address the branch
displacement overflow caused by 15fa08f845.
However, gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vqtbX.c
is a testcase that contains a TB so large as to overflow anyway.
The limit here of 8000 ops produces a maximum output TB size of
24112 bytes on a ppc64le host with that test case. This is still
much less than the maximum forward branch distance of 32764 bytes.
Cc: qemu-stable@nongnu.org
Fixes: 15fa08f845 ("tcg: Dynamically allocate TCGOps")
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit abebf92597186be2bc48d487235da28b1127860f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
tcg/tcg.c | 3 +++
tcg/tcg.h | 8 +++++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index bb24526c93..66997cc653 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -866,6 +866,7 @@ void tcg_func_start(TCGContext *s)
/* No temps have been previously allocated for size or locality. */
memset(s->free_temps, 0, sizeof(s->free_temps));
+ s->nb_ops = 0;
s->nb_labels = 0;
s->current_frame_offset = s->frame_start;
@@ -1983,6 +1984,7 @@ void tcg_op_remove(TCGContext *s, TCGOp *op)
{
QTAILQ_REMOVE(&s->ops, op, link);
QTAILQ_INSERT_TAIL(&s->free_ops, op, link);
+ s->nb_ops--;
#ifdef CONFIG_PROFILER
atomic_set(&s->prof.del_op_count, s->prof.del_op_count + 1);
@@ -2002,6 +2004,7 @@ static TCGOp *tcg_op_alloc(TCGOpcode opc)
}
memset(op, 0, offsetof(TCGOp, link));
op->opc = opc;
+ s->nb_ops++;
return op;
}
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 30896ca304..17cf764565 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -655,6 +655,7 @@ struct TCGContext {
int nb_globals;
int nb_temps;
int nb_indirects;
+ int nb_ops;
/* goto_tb support */
tcg_insn_unit *code_buf;
@@ -844,7 +845,12 @@ static inline TCGOp *tcg_last_op(void)
/* Test for whether to terminate the TB for using too many opcodes. */
static inline bool tcg_op_buf_full(void)
{
- return false;
+ /* This is not a hard limit, it merely stops translation when
+ * we have produced "enough" opcodes. We want to limit TB size
+ * such that a RISC host can reasonably use a 16-bit signed
+ * branch within the TB.
+ */
+ return tcg_ctx->nb_ops >= 8000;
}
/* pool based memory allocation */
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 65/99] softfloat: Handle default NaN mode after pickNaNMulAdd, not before
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Peter Maydell
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Peter Maydell <peter.maydell@linaro.org>
It is implementation defined whether a multiply-add of
(0,inf,qnan) or (inf,0,qnan) raises InvalidaOperation or
not, so we let the target-specific pickNaNMulAdd function
handle this. This means that we must do the "return the
default NaN in default NaN mode" check after the call,
not before. Correct the ordering, and restore the comment
from the old propagateFloat64MulAddNaN() that warned about
this corner case.
This fixes a regression from 2.11 for Arm guests where we would
incorrectly fail to set the Invalid flag for these cases.
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180504100547.14621-1-peter.maydell@linaro.org
(cherry picked from commit 1839189bbf89889076aadf0c793c1b57977b28d7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
fpu/softfloat.c | 48 ++++++++++++++++++++++++++++--------------------
1 file changed, 28 insertions(+), 20 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 70e0c40a1c..8401b37bd4 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -602,34 +602,42 @@ static FloatParts pick_nan(FloatParts a, FloatParts b, float_status *s)
static FloatParts pick_nan_muladd(FloatParts a, FloatParts b, FloatParts c,
bool inf_zero, float_status *s)
{
+ int which;
+
if (is_snan(a.cls) || is_snan(b.cls) || is_snan(c.cls)) {
s->float_exception_flags |= float_flag_invalid;
}
+ which = pickNaNMulAdd(is_qnan(a.cls), is_snan(a.cls),
+ is_qnan(b.cls), is_snan(b.cls),
+ is_qnan(c.cls), is_snan(c.cls),
+ inf_zero, s);
+
if (s->default_nan_mode) {
+ /* Note that this check is after pickNaNMulAdd so that function
+ * has an opportunity to set the Invalid flag.
+ */
a.cls = float_class_dnan;
- } else {
- switch (pickNaNMulAdd(is_qnan(a.cls), is_snan(a.cls),
- is_qnan(b.cls), is_snan(b.cls),
- is_qnan(c.cls), is_snan(c.cls),
- inf_zero, s)) {
- case 0:
- break;
- case 1:
- a = b;
- break;
- case 2:
- a = c;
- break;
- case 3:
- a.cls = float_class_dnan;
- return a;
- default:
- g_assert_not_reached();
- }
+ return a;
+ }
- a.cls = float_class_msnan;
+ switch (which) {
+ case 0:
+ break;
+ case 1:
+ a = b;
+ break;
+ case 2:
+ a = c;
+ break;
+ case 3:
+ a.cls = float_class_dnan;
+ return a;
+ default:
+ g_assert_not_reached();
}
+ a.cls = float_class_msnan;
+
return a;
}
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 64/99] tcg/i386: Fix dup_vec in non-AVX2 codepath
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Peter Maydell, Richard Henderson
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Peter Maydell <peter.maydell@linaro.org>
The VPUNPCKLD* instructions are all "non-destructive source",
indicated by "NDS" in the encoding string in the x86 ISA manual.
This means that they take two source operands, one of which is
encoded in the VEX.vvvv field. We were incorrectly treating them
as if they were destructive-source and passing 0 as the 'v'
argument of tcg_out_vex_modrm(). This meant we were always
using %xmm0 as one of the source operands, causing incorrect
results if the register allocator happened to want to use
something else. For instance the input AArch64 insn:
DUP v26.16b, w21
which becomes TCG IR ops:
dup_vec v128,e8,tmp2,x21
st_vec v128,e8,tmp2,env,$0xa40
was assembled to:
0x607c568c: c4 c1 7a 7e 86 e8 00 00 vmovq 0xe8(%r14), %xmm0
0x607c5694: 00
0x607c5695: c5 f9 60 c8 vpunpcklbw %xmm0, %xmm0, %xmm1
0x607c5699: c5 f9 61 c9 vpunpcklwd %xmm1, %xmm0, %xmm1
0x607c569d: c5 f9 70 c9 00 vpshufd $0, %xmm1, %xmm1
0x607c56a2: c4 c1 7a 7f 8e 40 0a 00 vmovdqu %xmm1, 0xa40(%r14)
0x607c56aa: 00
when the vpunpcklwd insn should be "%xmm1, %xmm1, %xmm1".
This resulted in our incorrectly setting the output vector to
q26=0000320000003200:0000320000003200
when given an input of x21 == 0000000002803200
rather than the expected all-zeroes.
Pass the correct source register number to tcg_out_vex_modrm()
for these insns.
Fixes: 770c2fc7bb70804a
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20180504153431.5169-1-peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 7eb30ef0ba2eb59e7430d4848ae8d4bf4e50f768)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
tcg/i386/tcg-target.inc.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index d7e59e79c5..5357909fff 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -854,11 +854,11 @@ static void tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
switch (vece) {
case MO_8:
/* ??? With zero in a register, use PSHUFB. */
- tcg_out_vex_modrm(s, OPC_PUNPCKLBW, r, 0, a);
+ tcg_out_vex_modrm(s, OPC_PUNPCKLBW, r, a, a);
a = r;
/* FALLTHRU */
case MO_16:
- tcg_out_vex_modrm(s, OPC_PUNPCKLWD, r, 0, a);
+ tcg_out_vex_modrm(s, OPC_PUNPCKLWD, r, a, a);
a = r;
/* FALLTHRU */
case MO_32:
@@ -867,7 +867,7 @@ static void tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
tcg_out8(s, 0);
break;
case MO_64:
- tcg_out_vex_modrm(s, OPC_PUNPCKLQDQ, r, 0, a);
+ tcg_out_vex_modrm(s, OPC_PUNPCKLQDQ, r, a, a);
break;
default:
g_assert_not_reached();
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 63/99] nbd/client: Relax handling of large NBD_CMD_BLOCK_STATUS reply
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Eric Blake
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Eric Blake <eblake@redhat.com>
The NBD spec is proposing a relaxation of NBD_CMD_BLOCK_STATUS
where a server may have the final extent per context give a
length beyond the original request, if it can easily prove that
subsequent bytes have the same status, on the grounds that a
client can take advantage of this information for fewer block
status requests. Since qemu 2.12 as a client always sends
NBD_CMD_FLAG_REQ_ONE, and rejects a server that sends extra
length, the upstream NBD spec will probably limit this behavior
to clients that don't request REQ_ONE semantics; but it doesn't
hurt to relax qemu to always be permissive of this server
behavior, even if it continues to use REQ_ONE.
CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20180503222626.1303410-1-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
(cherry picked from commit acfd8f7a5f92e703d2d046cbe3d510008a697194)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/nbd-client.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/block/nbd-client.c b/block/nbd-client.c
index e7caf49fbb..8d69eaaa32 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -259,14 +259,18 @@ static int nbd_parse_blockstatus_payload(NBDClientSession *client,
if (extent->length == 0 ||
(client->info.min_block && !QEMU_IS_ALIGNED(extent->length,
- client->info.min_block)) ||
- extent->length > orig_length)
- {
+ client->info.min_block))) {
error_setg(errp, "Protocol error: server sent status chunk with "
"invalid length");
return -EINVAL;
}
+ /* The server is allowed to send us extra information on the final
+ * extent; just clamp it to the length we requested. */
+ if (extent->length > orig_length) {
+ extent->length = orig_length;
+ }
+
return 0;
}
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 62/99] riscv: requires libfdt
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, KONRAD Frederic, Michael Clark
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: KONRAD Frederic <frederic.konrad@adacore.com>
When compiling on a machine without libfdt installed the configure script
should try to get libfdt from the git or should die because otherwise
CONFIG_LIBFDT is not set and the build process end in an error in the link
phase.. eg:
hw/riscv/virt.o: In function `riscv_virt_board_init':
qemu/src/hw/riscv/virt.c:317: undefined reference to `qemu_fdt_setprop_cell'
qemu/src/hw/riscv/virt.c:319: undefined reference to `qemu_fdt_setprop_cell'
qemu/src/hw/riscv/virt.c:345: undefined reference to `qemu_fdt_dumpdtb'
collect2: error: ld returned 1 exit status
make[1]: *** [qemu-system-riscv64] Error 1
make: *** [subdir-riscv64-softmmu] Error 2
Cc: qemu-stable@nongnu.org
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Michael Clark <mjc@sifive.com>
Signed-off-by: KONRAD Frederic <frederic.konrad@adacore.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Message-Id: <1525360636-18229-4-git-send-email-frederic.konrad@adacore.com>
(cherry picked from commit a666409f0df5dce113a5bd2c4c144a0792f2a4a3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
configure | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure b/configure
index 44bf1fef04..457684a7e6 100755
--- a/configure
+++ b/configure
@@ -3734,7 +3734,7 @@ fi
fdt_required=no
for target in $target_list; do
case $target in
- aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu)
+ aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu|riscv*-softmmu)
fdt_required=yes
;;
esac
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 61/99] riscv: htif: increase the priority of the htif subregion
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, KONRAD Frederic, Michael Clark
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: KONRAD Frederic <frederic.konrad@adacore.com>
The htif device is supposed to be mapped over an other subregion. So increase
its priority to one to avoid any conflict.
Here is the output of info mtree:
Before:
(qemu) info mtree
address-space: memory
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-000000000000000f (prio 0, i/o): riscv.htif.uart
0000000000000000-0000000000011fff (prio 0, ram): riscv.spike.bootrom
0000000002000000-000000000200ffff (prio 0, i/o): riscv.sifive.clint
0000000080000000-0000000087ffffff (prio 0, ram): riscv.spike.ram
address-space: I/O
0000000000000000-000000000000ffff (prio 0, i/o): io
address-space: cpu-memory-0
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-000000000000000f (prio 0, i/o): riscv.htif.uart
0000000000000000-0000000000011fff (prio 0, ram): riscv.spike.bootrom
0000000002000000-000000000200ffff (prio 0, i/o): riscv.sifive.clint
0000000080000000-0000000087ffffff (prio 0, ram): riscv.spike.ram
After:
(qemu) info mtree
address-space: memory
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-000000000000000f (prio 1, i/o): riscv.htif.uart
0000000000000000-0000000000011fff (prio 0, ram): riscv.spike.bootrom
0000000002000000-000000000200ffff (prio 0, i/o): riscv.sifive.clint
0000000080000000-0000000087ffffff (prio 0, ram): riscv.spike.ram
address-space: I/O
0000000000000000-000000000000ffff (prio 0, i/o): io
address-space: cpu-memory-0
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-000000000000000f (prio 1, i/o): riscv.htif.uart
0000000000000000-0000000000011fff (prio 0, ram): riscv.spike.bootrom
0000000002000000-000000000200ffff (prio 0, i/o): riscv.sifive.clint
0000000080000000-0000000087ffffff (prio 0, ram): riscv.spike.ram
Reviewed-by: Michael Clark <mjc@sifive.com>
Signed-off-by: KONRAD Frederic <frederic.konrad@adacore.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Message-Id: <1525360636-18229-3-git-send-email-frederic.konrad@adacore.com>
(cherry picked from commit 6fad7d1893f6ea926063067af957009bc320406f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
hw/riscv/riscv_htif.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/hw/riscv/riscv_htif.c b/hw/riscv/riscv_htif.c
index be252ec8cc..f73512941f 100644
--- a/hw/riscv/riscv_htif.c
+++ b/hw/riscv/riscv_htif.c
@@ -253,8 +253,9 @@ HTIFState *htif_mm_init(MemoryRegion *address_space, MemoryRegion *main_mem,
htif_be_change, s, NULL, true);
if (address_symbol_set == 3) {
memory_region_init_io(&s->mmio, NULL, &htif_mm_ops, s,
- TYPE_HTIF_UART, size);
- memory_region_add_subregion(address_space, base, &s->mmio);
+ TYPE_HTIF_UART, size);
+ memory_region_add_subregion_overlap(address_space, base,
+ &s->mmio, 1);
}
return s;
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 05/99] s390-ccw: force diag 308 subcode to unsigned long
From: Michael Roth @ 2018-07-23 20:16 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Cornelia Huck, Thomas Huth
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: Cornelia Huck <cohuck@redhat.com>
We currently pass an integer as the subcode parameter. However,
the upper bits of the register containing the subcode need to
be 0, which is not guaranteed unless we explicitly specify the
subcode to be an unsigned long value.
Fixes: d046c51dad3 ("pc-bios/s390-ccw: Get device address via diag 308/6")
Cc: qemu-stable@nongnu.org
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 63d8b5ace31c1e1f3996fe4cd551d6d377594d5a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
pc-bios/s390-ccw/iplb.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h
index 5357a36d51..ded20c834e 100644
--- a/pc-bios/s390-ccw/iplb.h
+++ b/pc-bios/s390-ccw/iplb.h
@@ -101,10 +101,11 @@ static inline bool manage_iplb(IplParameterBlock *iplb, bool store)
{
register unsigned long addr asm("0") = (unsigned long) iplb;
register unsigned long rc asm("1") = 0;
+ unsigned long subcode = store ? 6 : 5;
asm volatile ("diag %0,%2,0x308\n"
: "+d" (addr), "+d" (rc)
- : "d" (store ? 6 : 5)
+ : "d" (subcode)
: "memory", "cc");
return rc == 0x01;
}
--
2.17.1
^ permalink raw reply related
* [Qemu-devel] [PATCH 60/99] riscv: spike: allow base == 0
From: Michael Roth @ 2018-07-23 20:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, KONRAD Frederic, Michael Clark
In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com>
From: KONRAD Frederic <frederic.konrad@adacore.com>
The sanity check on base doesn't allow htif to be mapped @0. Check if the
symbol exists instead so we can map it where we want.
Reviewed-by: Michael Clark <mjc@sifive.com>
Signed-off-by: KONRAD Frederic <frederic.konrad@adacore.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Message-Id: <1525360636-18229-2-git-send-email-frederic.konrad@adacore.com>
(cherry picked from commit 17b9751e85b9989cc841ed387794d7f1e8aa5e46)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
hw/riscv/riscv_htif.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/hw/riscv/riscv_htif.c b/hw/riscv/riscv_htif.c
index 3e17f30251..be252ec8cc 100644
--- a/hw/riscv/riscv_htif.c
+++ b/hw/riscv/riscv_htif.c
@@ -41,17 +41,20 @@
} while (0)
static uint64_t fromhost_addr, tohost_addr;
+static int address_symbol_set;
void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
- uint64_t st_size)
+ uint64_t st_size)
{
if (strcmp("fromhost", st_name) == 0) {
+ address_symbol_set |= 1;
fromhost_addr = st_value;
if (st_size != 8) {
error_report("HTIF fromhost must be 8 bytes");
exit(1);
}
} else if (strcmp("tohost", st_name) == 0) {
+ address_symbol_set |= 2;
tohost_addr = st_value;
if (st_size != 8) {
error_report("HTIF tohost must be 8 bytes");
@@ -248,7 +251,7 @@ HTIFState *htif_mm_init(MemoryRegion *address_space, MemoryRegion *main_mem,
qemu_chr_fe_init(&s->chr, chr, &error_abort);
qemu_chr_fe_set_handlers(&s->chr, htif_can_recv, htif_recv, htif_event,
htif_be_change, s, NULL, true);
- if (base) {
+ if (address_symbol_set == 3) {
memory_region_init_io(&s->mmio, NULL, &htif_mm_ops, s,
TYPE_HTIF_UART, size);
memory_region_add_subregion(address_space, base, &s->mmio);
--
2.17.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.