Re: [PATCH] tcg/i386: Bound shift count expanding sari_vec
Patchew URL: https://patchew.org/QEMU/20200311052145.14004-1-richard.hender...@linaro.org/ Hi, This series failed the asan build test. Please find the testing commands and their output below. If you have Docker installed, you can probably reproduce it locally. === TEST SCRIPT BEGIN === #!/bin/bash export ARCH=x86_64 make docker-image-fedora V=1 NETWORK=1 time make docker-test-debug@fedora TARGET_LIST=x86_64-softmmu J=14 NETWORK=1 === TEST SCRIPT END === PASS 1 fdc-test /x86_64/fdc/cmos PASS 2 fdc-test /x86_64/fdc/no_media_on_start PASS 3 fdc-test /x86_64/fdc/read_without_media ==6144==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 4 fdc-test /x86_64/fdc/media_change PASS 5 fdc-test /x86_64/fdc/sense_interrupt PASS 6 fdc-test /x86_64/fdc/relative_seek --- PASS 32 test-opts-visitor /visitor/opts/range/beyond PASS 33 test-opts-visitor /visitor/opts/dict/unvisited MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-coroutine -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-coroutine" ==6189==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! ==6189==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x7ffc99a81000; bottom 0x7f7f89faa000; size: 0x007d0fad7000 (537133936640) False positive error reports may follow For details see https://github.com/google/sanitizers/issues/189 PASS 1 test-coroutine /basic/no-dangling-access --- PASS 12 test-aio /aio/event/flush PASS 13 test-aio /aio/event/wait/no-flush-cb PASS 14 test-aio /aio/timer/schedule ==6204==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 15 test-aio /aio/coroutine/queue-chaining PASS 16 test-aio /aio-gsource/flush PASS 17 test-aio /aio-gsource/bh/schedule --- PASS 12 fdc-test /x86_64/fdc/read_no_dma_19 PASS 13 fdc-test /x86_64/fdc/fuzz-registers MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64 QTEST_QEMU_IMG=qemu-img tests/qtest/ide-test -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="ide-test" ==6212==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 ide-test /x86_64/ide/identify PASS 28 test-aio /aio-gsource/timer/schedule MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-aio-multithread -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-aio-multithread" ==6218==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! ==6221==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-aio-multithread /aio/multi/lifecycle PASS 2 ide-test /x86_64/ide/flush ==6238==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 3 ide-test /x86_64/ide/bmdma/simple_rw PASS 2 test-aio-multithread /aio/multi/schedule ==6244==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 4 ide-test /x86_64/ide/bmdma/trim PASS 3 test-aio-multithread /aio/multi/mutex/contended ==6255==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 4 test-aio-multithread /aio/multi/mutex/handoff PASS 5 test-aio-multithread /aio/multi/mutex/mcs PASS 6 test-aio-multithread /aio/multi/mutex/pthread MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-throttle -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-throttle" ==6277==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-throttle /throttle/leak_bucket PASS 2 test-throttle /throttle/compute_wait PASS 3 test-throttle /throttle/init --- PASS 14 test-throttle /throttle/config/max PASS 15 test-throttle /throttle/config/iops_size MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-thread-pool -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-thread-pool" ==6281==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-thread-pool /thread-pool/submit PASS 2 test-thread-pool /thread-pool/submit-aio PASS 3 test-thread-pool /thread-pool/submit-co PASS 4 test-thread-pool /thread-pool/submit-many ==6348==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 5 test-thread-pool /thread-pool/cancel PASS 6 test-thread-pool /thread-pool/cancel-async MALLOC_PERTURB_=${MALLOC_PERTURB_:-$((
Re: [PATCH 0/7] post-rst-conversion cleanups
On 3/6/20 9:17 AM, Peter Maydell wrote: > Peter Maydell (7): > Makefile: Remove redundant Texinfo related code > Update comments in .hx files that mention Texinfo > hxtool: Remove Texinfo generation support > docs/sphinx/hxtool.py: Remove STEXI/ETEXI support > Makefile: Make all Sphinx documentation depend on the extensions > docs/index.rst, docs/index.html.in: Reorder manuals > docs/qemu-option-trace.rst.inc: Remove redundant comment Reviewed-by: Richard Henderson r~
[PATCH v4 34/60] target/riscv: vector widening floating-point fused multiply-add instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 17 + target/riscv/insn32.decode | 8 +++ target/riscv/insn_trans/trans_rvv.inc.c | 10 +++ target/riscv/vector_helper.c| 84 + 4 files changed, 119 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 3b6dd96918..57e0fee929 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -888,3 +888,20 @@ DEF_HELPER_6(vfmsub_vf_d, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfnmsub_vf_h, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfnmsub_vf_w, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfnmsub_vf_d, void, ptr, ptr, i64, ptr, env, i32) + +DEF_HELPER_6(vfwmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwnmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwnmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwnmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwnmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwnmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwnmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwnmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwnmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 9834091a86..b7cb116cf4 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -474,6 +474,14 @@ vfmsub_vv 101010 . . . 001 . 1010111 @r_vm vfmsub_vf 101010 . . . 101 . 1010111 @r_vm vfnmsub_vv 101011 . . . 001 . 1010111 @r_vm vfnmsub_vf 101011 . . . 101 . 1010111 @r_vm +vfwmacc_vv 00 . . . 001 . 1010111 @r_vm +vfwmacc_vf 00 . . . 101 . 1010111 @r_vm +vfwnmacc_vv 01 . . . 001 . 1010111 @r_vm +vfwnmacc_vf 01 . . . 101 . 1010111 @r_vm +vfwmsac_vv 10 . . . 001 . 1010111 @r_vm +vfwmsac_vf 10 . . . 101 . 1010111 @r_vm +vfwnmsac_vv 11 . . . 001 . 1010111 @r_vm +vfwnmsac_vf 11 . . . 101 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 172de867ea..06d6e2625b 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1824,3 +1824,13 @@ GEN_OPFVF_TRANS(vfmadd_vf, opfvf_check) GEN_OPFVF_TRANS(vfnmadd_vf, opfvf_check) GEN_OPFVF_TRANS(vfmsub_vf, opfvf_check) GEN_OPFVF_TRANS(vfnmsub_vf, opfvf_check) + +/* Vector Widening Floating-Point Fused Multiply-Add Instructions */ +GEN_OPFVV_WIDEN_TRANS(vfwmacc_vv, opfvv_widen_check) +GEN_OPFVV_WIDEN_TRANS(vfwnmacc_vv, opfvv_widen_check) +GEN_OPFVV_WIDEN_TRANS(vfwmsac_vv, opfvv_widen_check) +GEN_OPFVV_WIDEN_TRANS(vfwnmsac_vv, opfvv_widen_check) +GEN_OPFVF_WIDEN_TRANS(vfwmacc_vf) +GEN_OPFVF_WIDEN_TRANS(vfwnmacc_vf) +GEN_OPFVF_WIDEN_TRANS(vfwmsac_vf) +GEN_OPFVF_WIDEN_TRANS(vfwnmsac_vf) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 2e0341adb0..9bff516a15 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -3404,3 +3404,87 @@ RVVCALL(OPFVF3, vfnmsub_vf_d, OP_UUU_D, H8, H8, fnmsub64) GEN_VEXT_VF(vfnmsub_vf_h, 2, 2, clearh) GEN_VEXT_VF(vfnmsub_vf_w, 4, 4, clearl) GEN_VEXT_VF(vfnmsub_vf_d, 8, 8, clearq) + +/* Vector Widening Floating-Point Fused Multiply-Add Instructions */ +static uint32_t fwmacc16(uint16_t a, uint16_t b, uint32_t d, float_status *s) +{ +return float32_muladd(float16_to_float32(a, true, s), +float16_to_float32(b, true, s), d, 0, s); +} +static uint64_t fwmacc32(uint32_t a, uint32_t b, uint64_t d, float_status *s) +{ +return float64_muladd(float32_to_float64(a, s), +float32_to_float64(b, s), d, 0, s); +} +RVVCALL(OPFVV3, vfwmacc_vv_h, WOP_UUU_H, H4, H2, H2, fwmacc16) +RVVCALL(OPFVV3, vfwmacc_vv_w, WOP_UUU_W, H8, H4, H4, fwmacc32) +GEN_VEXT_VV_ENV(vfwmacc_vv_h, 2, 4, clearl) +GEN_VEXT_VV_ENV(vfwmacc_vv_w, 4, 8, clearq) +RVVCALL(OPFVF3, vfwmacc_vf_h, WOP_UUU_H, H4, H2, fwmacc16) +RVVCALL(OPFVF3, vfwmacc_vf_w, WOP_UUU_W, H8, H4, fwmacc32) +GEN_VEXT_VF(vfwmacc_vf_h, 2, 4, clearl) +GEN_VEXT_VF(vfwmacc_vf_w, 4, 8, clearq) + +static uint32_t fwnmacc16(uint16_t a, uint16_t b,
[PATCH v4 30/60] target/riscv: vector widening floating-point add/subtract instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 17 +++ target/riscv/insn32.decode | 8 ++ target/riscv/insn_trans/trans_rvv.inc.c | 131 target/riscv/vector_helper.c| 77 ++ 4 files changed, 233 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 6b46677eeb..f242fa4e4b 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -801,3 +801,20 @@ DEF_HELPER_6(vfsub_vf_d, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfrsub_vf_h, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfrsub_vf_w, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfrsub_vf_d, void, ptr, ptr, i64, ptr, env, i32) + +DEF_HELPER_6(vfwadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwadd_wv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwadd_wv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwsub_wv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwsub_wv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwadd_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwadd_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwsub_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwsub_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwadd_wf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwadd_wf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwsub_wf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwsub_wf_w, void, ptr, ptr, i64, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 32918c4d11..5ec95541c6 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -443,6 +443,14 @@ vfadd_vf00 . . . 101 . 1010111 @r_vm vfsub_vv10 . . . 001 . 1010111 @r_vm vfsub_vf10 . . . 101 . 1010111 @r_vm vfrsub_vf 100111 . . . 101 . 1010111 @r_vm +vfwadd_vv 11 . . . 001 . 1010111 @r_vm +vfwadd_vf 11 . . . 101 . 1010111 @r_vm +vfwadd_wv 110100 . . . 001 . 1010111 @r_vm +vfwadd_wf 110100 . . . 101 . 1010111 @r_vm +vfwsub_vv 110010 . . . 001 . 1010111 @r_vm +vfwsub_vf 110010 . . . 101 . 1010111 @r_vm +vfwsub_wv 110110 . . . 001 . 1010111 @r_vm +vfwsub_wf 110110 . . . 101 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index af4dcb96c6..ab04f469af 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1664,3 +1664,134 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ GEN_OPFVF_TRANS(vfadd_vf, opfvf_check) GEN_OPFVF_TRANS(vfsub_vf, opfvf_check) GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check) + +/* Vector Widening Floating-Point Add/Subtract Instructions */ +static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a) +{ +return (vext_check_isa_ill(s, RVV) && +vext_check_overlap_mask(s, a->rd, a->vm, true) && +vext_check_reg(s, a->rd, true) && +vext_check_reg(s, a->rs2, false) && +vext_check_reg(s, a->rs1, false) && +vext_check_overlap_group(a->rd, 2 << s->lmul, a->rs2, +1 << s->lmul) && +vext_check_overlap_group(a->rd, 2 << s->lmul, a->rs1, +1 << s->lmul) && +(s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0)); +} + +/* OPFVV with WIDEN */ +#define GEN_OPFVV_WIDEN_TRANS(NAME, CHECK) \ +static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ +{\ +if (CHECK(s, a)) { \ +uint32_t data = 0; \ +static gen_helper_gvec_4_ptr * const fns[2] = { \ +gen_helper_##NAME##_h, gen_helper_##NAME##_w,\ +}; \ +data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ +data = FIELD_DP32(data, VDATA, VM, a->vm); \ +data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ +tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ +vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2),\ +cpu_env, 0, s->vlen / 8, data, fns[s->sew - 1]); \ +return true; \ +}
[PATCH v4 31/60] target/riscv: vector single-width floating-point multiply/divide instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 16 + target/riscv/insn32.decode | 5 +++ target/riscv/insn_trans/trans_rvv.inc.c | 7 target/riscv/vector_helper.c| 48 + 4 files changed, 76 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index f242fa4e4b..a2d7ed19a8 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -818,3 +818,19 @@ DEF_HELPER_6(vfwadd_wf_h, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfwadd_wf_w, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfwsub_wf_h, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfwsub_wf_w, void, ptr, ptr, i64, ptr, env, i32) + +DEF_HELPER_6(vfmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmul_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfdiv_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfdiv_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfdiv_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmul_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfmul_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfmul_vf_d, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfdiv_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfdiv_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfdiv_vf_d, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfrdiv_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfrdiv_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfrdiv_vf_d, void, ptr, ptr, i64, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 5ec95541c6..050b2fd467 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -451,6 +451,11 @@ vfwsub_vv 110010 . . . 001 . 1010111 @r_vm vfwsub_vf 110010 . . . 101 . 1010111 @r_vm vfwsub_wv 110110 . . . 001 . 1010111 @r_vm vfwsub_wf 110110 . . . 101 . 1010111 @r_vm +vfmul_vv100100 . . . 001 . 1010111 @r_vm +vfmul_vf100100 . . . 101 . 1010111 @r_vm +vfdiv_vv10 . . . 001 . 1010111 @r_vm +vfdiv_vf10 . . . 101 . 1010111 @r_vm +vfrdiv_vf 11 . . . 101 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index ab04f469af..8dcbff6c64 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1795,3 +1795,10 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ } GEN_OPFWF_WIDEN_TRANS(vfwadd_wf) GEN_OPFWF_WIDEN_TRANS(vfwsub_wf) + +/* Vector Single-Width Floating-Point Multiply/Divide Instructions */ +GEN_OPFVV_TRANS(vfmul_vv, opfvv_check) +GEN_OPFVV_TRANS(vfdiv_vv, opfvv_check) +GEN_OPFVF_TRANS(vfmul_vf, opfvf_check) +GEN_OPFVF_TRANS(vfdiv_vf, opfvf_check) +GEN_OPFVF_TRANS(vfrdiv_vf, opfvf_check) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 0840c5d662..bd7ee4de18 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -3106,3 +3106,51 @@ RVVCALL(OPFVF2, vfwsub_wf_h, WOP_WUUU_H, H4, H2, vfwsubw16) RVVCALL(OPFVF2, vfwsub_wf_w, WOP_WUUU_W, H8, H4, vfwsubw32) GEN_VEXT_VF(vfwsub_wf_h, 2, 4, clearl) GEN_VEXT_VF(vfwsub_wf_w, 4, 8, clearq) + +/* Vector Single-Width Floating-Point Multiply/Divide Instructions */ +RVVCALL(OPFVV2, vfmul_vv_h, OP_UUU_H, H2, H2, H2, float16_mul) +RVVCALL(OPFVV2, vfmul_vv_w, OP_UUU_W, H4, H4, H4, float32_mul) +RVVCALL(OPFVV2, vfmul_vv_d, OP_UUU_D, H8, H8, H8, float64_mul) +GEN_VEXT_VV_ENV(vfmul_vv_h, 2, 2, clearh) +GEN_VEXT_VV_ENV(vfmul_vv_w, 4, 4, clearl) +GEN_VEXT_VV_ENV(vfmul_vv_d, 8, 8, clearq) +RVVCALL(OPFVF2, vfmul_vf_h, OP_UUU_H, H2, H2, float16_mul) +RVVCALL(OPFVF2, vfmul_vf_w, OP_UUU_W, H4, H4, float32_mul) +RVVCALL(OPFVF2, vfmul_vf_d, OP_UUU_D, H8, H8, float64_mul) +GEN_VEXT_VF(vfmul_vf_h, 2, 2, clearh) +GEN_VEXT_VF(vfmul_vf_w, 4, 4, clearl) +GEN_VEXT_VF(vfmul_vf_d, 8, 8, clearq) + +RVVCALL(OPFVV2, vfdiv_vv_h, OP_UUU_H, H2, H2, H2, float16_div) +RVVCALL(OPFVV2, vfdiv_vv_w, OP_UUU_W, H4, H4, H4, float32_div) +RVVCALL(OPFVV2, vfdiv_vv_d, OP_UUU_D, H8, H8, H8, float64_div) +GEN_VEXT_VV_ENV(vfdiv_vv_h, 2, 2, clearh) +GEN_VEXT_VV_ENV(vfdiv_vv_w, 4, 4, clearl) +GEN_VEXT_VV_ENV(vfdiv_vv_d, 8, 8, clearq) +RVVCALL(OPFVF2, vfdiv_vf_h, OP_UUU_H, H2, H2, float16_div) +RVVCALL(OPFVF2, vfdiv_vf_w, OP_UUU_W, H4, H4, float32_div) +RVVCALL(OPFVF2, vfdiv_vf_d, OP_UUU_D, H8, H8, float64_div) +GEN_VEXT_VF(vfdiv_vf_h, 2, 2, clearh) +GEN_VEXT_VF(vfdiv_vf_w, 4, 4, clearl) +GEN_VEXT_VF(vfdiv_vf_d, 8, 8, clearq) + +static uint16_t float16_rdiv(uint16_t a, uint16_t b, float_status *s) +{ +
[PATCH v4 28/60] target/riscv: vector narrowing fixed-point clip instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 13 +++ target/riscv/insn32.decode | 6 ++ target/riscv/insn_trans/trans_rvv.inc.c | 8 ++ target/riscv/vector_helper.c| 128 4 files changed, 155 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index efc84fbd79..4cad8679ec 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -772,3 +772,16 @@ DEF_HELPER_6(vssra_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vssra_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vssra_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vssra_vx_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vnclip_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnclip_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnclip_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnclipu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnclipu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnclipu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnclipu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnclipu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnclipu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnclip_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnclip_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnclip_vx_w, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index d6d111e04a..c7d589566f 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -432,6 +432,12 @@ vssrl_vi101010 . . . 011 . 1010111 @r_vm vssra_vv101011 . . . 000 . 1010111 @r_vm vssra_vx101011 . . . 100 . 1010111 @r_vm vssra_vi101011 . . . 011 . 1010111 @r_vm +vnclipu_vv 101110 . . . 000 . 1010111 @r_vm +vnclipu_vx 101110 . . . 100 . 1010111 @r_vm +vnclipu_vi 101110 . . . 011 . 1010111 @r_vm +vnclip_vv 10 . . . 000 . 1010111 @r_vm +vnclip_vx 10 . . . 100 . 1010111 @r_vm +vnclip_vi 10 . . . 011 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 21f896ea26..11b4887275 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1549,3 +1549,11 @@ GEN_OPIVX_TRANS(vssrl_vx, opivx_check) GEN_OPIVX_TRANS(vssra_vx, opivx_check) GEN_OPIVI_TRANS(vssrl_vi, 1, vssrl_vx, opivx_check) GEN_OPIVI_TRANS(vssra_vi, 0, vssra_vx, opivx_check) + +/* Vector Narrowing Fixed-Point Clip Instructions */ +GEN_OPIVV_NARROW_TRANS(vnclipu_vv) +GEN_OPIVV_NARROW_TRANS(vnclip_vv) +GEN_OPIVX_NARROW_TRANS(vnclipu_vx) +GEN_OPIVX_NARROW_TRANS(vnclip_vx) +GEN_OPIVI_NARROW_TRANS(vnclipu_vi, 1, vnclipu_vx) +GEN_OPIVI_NARROW_TRANS(vnclip_vi, 1, vnclip_vx) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index ec0f822fcf..7f61d4c0c4 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -869,6 +869,12 @@ GEN_VEXT_AMO(vamomaxuw_v_w, uint32_t, uint32_t, idx_w, clearl) #define WOP_SSU_B int16_t, int8_t, uint8_t, int16_t, uint16_t #define WOP_SSU_H int32_t, int16_t, uint16_t, int32_t, uint32_t #define WOP_SSU_W int64_t, int32_t, uint32_t, int64_t, uint64_t +#define NOP_SSS_B int8_t, int8_t, int16_t, int8_t, int16_t +#define NOP_SSS_H int16_t, int16_t, int32_t, int16_t, int32_t +#define NOP_SSS_W int32_t, int32_t, int64_t, int32_t, int64_t +#define NOP_UUU_B uint8_t, uint8_t, uint16_t, uint8_t, uint16_t +#define NOP_UUU_H uint16_t, uint16_t, uint32_t, uint16_t, uint32_t +#define NOP_UUU_W uint32_t, uint32_t, uint64_t, uint32_t, uint64_t /* operation of two vector elements */ #define OPIVV2(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP)\ @@ -2812,3 +2818,125 @@ GEN_VEXT_VX_ENV(vssra_vx_b, 1, 1, clearb) GEN_VEXT_VX_ENV(vssra_vx_h, 2, 2, clearh) GEN_VEXT_VX_ENV(vssra_vx_w, 4, 4, clearl) GEN_VEXT_VX_ENV(vssra_vx_d, 8, 8, clearq) + +/* Vector Narrowing Fixed-Point Clip Instructions */ +static int8_t vnclip8(CPURISCVState *env, int16_t a, int8_t b) +{ +uint8_t round, shift = b & 0xf; +int16_t res; + +round = get_round(env, a, shift); +res = (a >> shift) + round; +if (res > INT8_MAX) { +env->vxsat = 0x1; +return INT8_MAX; +} else if (res < INT8_MIN) { +env->vxsat = 0x1; +return INT8_MIN; +} else { +return res; +} +} +static int16_t vnclip16(CPURISCVState *env, int32_t a, int16_t b) +{ +uint8_t round, shift = b & 0x1f; +int32_t res; + +round = get_round(env, a, shift); +res = (a >> shift) + round; +if (res > INT16_MAX) { +
[PATCH v4 23/60] target/riscv: vector single-width saturating add and subtract
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 33 +++ target/riscv/insn32.decode | 10 + target/riscv/insn_trans/trans_rvv.inc.c | 16 ++ target/riscv/vector_helper.c| 278 4 files changed, 337 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 121e9e57e7..95da00d365 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -674,3 +674,36 @@ DEF_HELPER_6(vmerge_vxm_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmerge_vxm_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmerge_vxm_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmerge_vxm_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vsaddu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsaddu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsaddu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsaddu_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssubu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssubu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssubu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssubu_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssub_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssub_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssub_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssub_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsaddu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsaddu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsaddu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsaddu_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsadd_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsadd_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsadd_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsadd_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssubu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssubu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssubu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssubu_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssub_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssub_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssub_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssub_vx_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index bcb8273bcc..44baadf582 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -402,6 +402,16 @@ vwmaccus_vx 11 . . . 110 . 1010111 @r_vm vmerge_vvm 010111 . . . 000 . 1010111 @r_vm vmerge_vxm 010111 . . . 100 . 1010111 @r_vm vmerge_vim 010111 . . . 011 . 1010111 @r_vm +vsaddu_vv 10 . . . 000 . 1010111 @r_vm +vsaddu_vx 10 . . . 100 . 1010111 @r_vm +vsaddu_vi 10 . . . 011 . 1010111 @r_vm +vsadd_vv11 . . . 000 . 1010111 @r_vm +vsadd_vx11 . . . 100 . 1010111 @r_vm +vsadd_vi11 . . . 011 . 1010111 @r_vm +vssubu_vv 100010 . . . 000 . 1010111 @r_vm +vssubu_vx 100010 . . . 100 . 1010111 @r_vm +vssub_vv100011 . . . 000 . 1010111 @r_vm +vssub_vx100011 . . . 100 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index aff5ca8663..ad55766b98 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1505,3 +1505,19 @@ static bool opivx_vmerge_check(DisasContext *s, arg_rmrr *a) GEN_OPIVX_TRANS(vmerge_vxm, opivx_vmerge_check) GEN_OPIVI_TRANS(vmerge_vim, 0, vmerge_vxm, opivx_vmerge_check) + +/* + *** Vector Fixed-Point Arithmetic Instructions + */ + +/* Vector Single-Width Saturating Add and Subtract */ +GEN_OPIVV_GVEC_TRANS(vsaddu_vv, usadd) +GEN_OPIVV_GVEC_TRANS(vsadd_vv, ssadd) +GEN_OPIVV_GVEC_TRANS(vssubu_vv, ussub) +GEN_OPIVV_GVEC_TRANS(vssub_vv, sssub) +GEN_OPIVX_TRANS(vsaddu_vx, opivx_check) +GEN_OPIVX_TRANS(vsadd_vx, opivx_check) +GEN_OPIVX_TRANS(vssubu_vx, opivx_check) +GEN_OPIVX_TRANS(vssub_vx, opivx_check) +GEN_OPIVI_TRANS(vsaddu_vi, 1, vsaddu_vx, opivx_check) +GEN_OPIVI_TRANS(vsadd_vi, 0, vsadd_vx, opivx_check) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 273b705847..c7b8c1bff4 100644 ---
[PATCH v4 25/60] target/riscv: vector single-width fractional multiply with rounding and saturation
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 9 +++ target/riscv/insn32.decode | 2 + target/riscv/insn_trans/trans_rvv.inc.c | 4 + target/riscv/vector_helper.c| 103 4 files changed, 118 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index d3837d2ca4..333eccca57 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -724,3 +724,12 @@ DEF_HELPER_6(vasub_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vasub_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vasub_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vasub_vx_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vsmul_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsmul_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsmul_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsmul_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsmul_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsmul_vx_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 0227a16b16..99f70924d6 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -417,6 +417,8 @@ vaadd_vx100100 . . . 100 . 1010111 @r_vm vaadd_vi100100 . . . 011 . 1010111 @r_vm vasub_vv100110 . . . 000 . 1010111 @r_vm vasub_vx100110 . . . 100 . 1010111 @r_vm +vsmul_vv100111 . . . 000 . 1010111 @r_vm +vsmul_vx100111 . . . 100 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 9988fad2fe..60e1e63b7b 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1528,3 +1528,7 @@ GEN_OPIVV_TRANS(vasub_vv, opivv_check) GEN_OPIVX_TRANS(vaadd_vx, opivx_check) GEN_OPIVX_TRANS(vasub_vx, opivx_check) GEN_OPIVI_TRANS(vaadd_vi, 0, vaadd_vx, opivx_check) + +/* Vector Single-Width Fractional Multiply with Rounding and Saturation */ +GEN_OPIVV_TRANS(vsmul_vv, opivv_check) +GEN_OPIVX_TRANS(vsmul_vx, opivx_check) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index b0a7a3b6e4..74ad07743c 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -2420,3 +2420,106 @@ GEN_VEXT_VX_ENV(vasub_vx_b, 1, 1, clearb) GEN_VEXT_VX_ENV(vasub_vx_h, 2, 2, clearh) GEN_VEXT_VX_ENV(vasub_vx_w, 4, 4, clearl) GEN_VEXT_VX_ENV(vasub_vx_d, 8, 8, clearq) + +/* Vector Single-Width Fractional Multiply with Rounding and Saturation */ +static inline int8_t vsmul8(CPURISCVState *env, int8_t a, int8_t b) +{ +uint8_t round; +int16_t res; + +res = (int16_t)a * (int16_t)b; +round = get_round(env, res, 7); +res = (res >> 7) + round; + +if (res > INT8_MAX) { +env->vxsat = 0x1; +return INT8_MAX; +} else if (res < INT8_MIN) { +env->vxsat = 0x1; +return INT8_MIN; +} else { +return res; +} +} +static int16_t vsmul16(CPURISCVState *env, int16_t a, int16_t b) +{ +uint8_t round; +int32_t res; + +res = (int32_t)a * (int32_t)b; +round = get_round(env, res, 15); +res = (res >> 15) + round; + +if (res > INT16_MAX) { +env->vxsat = 0x1; +return INT16_MAX; +} else if (res < INT16_MIN) { +env->vxsat = 0x1; +return INT16_MIN; +} else { +return res; +} +} +static int32_t vsmul32(CPURISCVState *env, int32_t a, int32_t b) +{ +uint8_t round; +int64_t res; + +res = (int64_t)a * (int64_t)b; +round = get_round(env, res, 31); +res = (res >> 31) + round; + +if (res > INT32_MAX) { +env->vxsat = 0x1; +return INT32_MAX; +} else if (res < INT32_MIN) { +env->vxsat = 0x1; +return INT32_MIN; +} else { +return res; +} +} +static int64_t vsmul64(CPURISCVState *env, int64_t a, int64_t b) +{ +uint8_t round; +uint64_t hi_64, lo_64, Hi62; +uint8_t hi62, hi63, lo63; + +muls64(_64, _64, a, b); +hi62 = extract64(hi_64, 62, 1); +lo63 = extract64(lo_64, 63, 1); +hi63 = extract64(hi_64, 63, 1); +Hi62 = extract64(hi_64, 0, 62); +if (hi62 != hi63) { +env->vxsat = 0x1; +return INT64_MAX; +} +round = get_round(env, lo_64, 63); +if (round && (Hi62 == 0x3fff) && lo63) { +env->vxsat = 0x1; +return hi62 ? INT64_MIN : INT64_MAX; +} else { +if (lo63 && round) { +return (hi_64 + 1) << 1; +} else { +return (hi_64 << 1) | lo63 | round; +} +} +} +RVVCALL(OPIVV2_ENV,
[PATCH v4 24/60] target/riscv: vector single-width averaging add and subtract
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 17 target/riscv/insn32.decode | 5 + target/riscv/insn_trans/trans_rvv.inc.c | 7 ++ target/riscv/vector_helper.c| 129 4 files changed, 158 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 95da00d365..d3837d2ca4 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -707,3 +707,20 @@ DEF_HELPER_6(vssub_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vssub_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vssub_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vssub_vx_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vaadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vaadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vaadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vaadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vasub_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vasub_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vasub_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vasub_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vaadd_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vaadd_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vaadd_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vaadd_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vasub_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vasub_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vasub_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vasub_vx_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 44baadf582..0227a16b16 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -412,6 +412,11 @@ vssubu_vv 100010 . . . 000 . 1010111 @r_vm vssubu_vx 100010 . . . 100 . 1010111 @r_vm vssub_vv100011 . . . 000 . 1010111 @r_vm vssub_vx100011 . . . 100 . 1010111 @r_vm +vaadd_vv100100 . . . 000 . 1010111 @r_vm +vaadd_vx100100 . . . 100 . 1010111 @r_vm +vaadd_vi100100 . . . 011 . 1010111 @r_vm +vasub_vv100110 . . . 000 . 1010111 @r_vm +vasub_vx100110 . . . 100 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index ad55766b98..9988fad2fe 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1521,3 +1521,10 @@ GEN_OPIVX_TRANS(vssubu_vx, opivx_check) GEN_OPIVX_TRANS(vssub_vx, opivx_check) GEN_OPIVI_TRANS(vsaddu_vi, 1, vsaddu_vx, opivx_check) GEN_OPIVI_TRANS(vsadd_vi, 0, vsadd_vx, opivx_check) + +/* Vector Single-Width Averaging Add and Subtract */ +GEN_OPIVV_TRANS(vaadd_vv, opivv_check) +GEN_OPIVV_TRANS(vasub_vv, opivv_check) +GEN_OPIVX_TRANS(vaadd_vx, opivx_check) +GEN_OPIVX_TRANS(vasub_vx, opivx_check) +GEN_OPIVI_TRANS(vaadd_vi, 0, vaadd_vx, opivx_check) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index c7b8c1bff4..b0a7a3b6e4 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -2291,3 +2291,132 @@ GEN_VEXT_VX_ENV(vssub_vx_b, 1, 1, clearb) GEN_VEXT_VX_ENV(vssub_vx_h, 2, 2, clearh) GEN_VEXT_VX_ENV(vssub_vx_w, 4, 4, clearl) GEN_VEXT_VX_ENV(vssub_vx_d, 8, 8, clearq) + +/* Vector Single-Width Averaging Add and Subtract */ +static inline uint8_t get_round(CPURISCVState *env, uint64_t v, uint8_t shift) +{ +uint8_t d = extract64(v, shift, 1); +uint8_t d1; +uint64_t D1, D2; +int mod = env->vxrm; + +if (shift == 0 || shift > 64) { +return 0; +} + +d1 = extract64(v, shift - 1, 1); +D1 = extract64(v, 0, shift); +if (mod == 0) { /* round-to-nearest-up (add +0.5 LSB) */ +return d1; +} else if (mod == 1) { /* round-to-nearest-even */ +if (shift > 1) { +D2 = extract64(v, 0, shift - 1); +return d1 & ((D2 != 0) | d); +} else { +return d1 & d; +} +} else if (mod == 3) { /* round-to-odd (OR bits into LSB, aka "jam") */ +return !d & (D1 != 0); +} +return 0; /* round-down (truncate) */ +} + +static inline int8_t aadd8(CPURISCVState *env, int8_t a, int8_t b) +{ +int16_t res = (int16_t)a + (int16_t)b; +uint8_t round = get_round(env, res, 1); +res = (res >> 1) + round; +return res; +} +static inline int16_t aadd16(CPURISCVState *env, int16_t a, int16_t b) +{ +int32_t res = (int32_t)a + (int32_t)b; +uint8_t round = get_round(env, res, 1); +res = (res >> 1) + round; +return res; +} +static inline int32_t aadd32(CPURISCVState *env, int32_t a,
[PATCH] tcg/i386: Bound shift count expanding sari_vec
A given RISU testcase for SVE can produce tcg-op-vec.c:511: do_shifti: Assertion `i >= 0 && i < (8 << vece)' failed. because expand_vec_sari gave a shift count of 32 to a MO_32 vector shift. In 44f1441dbe1, we changed from direct expansion of vector opcodes to re-use of the tcg expanders. So while the comment correctly notes that the hw will handle such a shift count, we now have to take our own sanity checks into account. Which is easy in this particular case. Fixes: 44f1441dbe1 Signed-off-by: Richard Henderson --- tcg/i386/tcg-target.inc.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c index cdedcb2b25..223dba9c8c 100644 --- a/tcg/i386/tcg-target.inc.c +++ b/tcg/i386/tcg-target.inc.c @@ -3391,12 +3391,15 @@ static void expand_vec_sari(TCGType type, unsigned vece, case MO_64: if (imm <= 32) { -/* We can emulate a small sign extend by performing an arithmetic +/* + * We can emulate a small sign extend by performing an arithmetic * 32-bit shift and overwriting the high half of a 64-bit logical - * shift (note that the ISA says shift of 32 is valid). + * shift. Note that the ISA says shift of 32 is valid, but TCG + * does not, so we have to bound the smaller shift -- we get the + * same result in the high half either way. */ t1 = tcg_temp_new_vec(type); -tcg_gen_sari_vec(MO_32, t1, v1, imm); +tcg_gen_sari_vec(MO_32, t1, v1, MIN(imm, 31)); tcg_gen_shri_vec(MO_64, v0, v1, imm); vec_gen_4(INDEX_op_x86_blend_vec, type, MO_32, tcgv_vec_arg(v0), tcgv_vec_arg(v0), -- 2.17.1
[PATCH v4 29/60] target/riscv: vector single-width floating-point add/subtract instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 16 target/riscv/insn32.decode | 5 ++ target/riscv/insn_trans/trans_rvv.inc.c | 107 target/riscv/vector_helper.c| 89 4 files changed, 217 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 4cad8679ec..6b46677eeb 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -785,3 +785,19 @@ DEF_HELPER_6(vnclipu_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vnclip_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vnclip_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vnclip_vx_w, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vfadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfadd_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfadd_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfadd_vf_d, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfsub_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfsub_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfsub_vf_d, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfrsub_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfrsub_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfrsub_vf_d, void, ptr, ptr, i64, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index c7d589566f..32918c4d11 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -438,6 +438,11 @@ vnclipu_vi 101110 . . . 011 . 1010111 @r_vm vnclip_vv 10 . . . 000 . 1010111 @r_vm vnclip_vx 10 . . . 100 . 1010111 @r_vm vnclip_vi 10 . . . 011 . 1010111 @r_vm +vfadd_vv00 . . . 001 . 1010111 @r_vm +vfadd_vf00 . . . 101 . 1010111 @r_vm +vfsub_vv10 . . . 001 . 1010111 @r_vm +vfsub_vf10 . . . 101 . 1010111 @r_vm +vfrsub_vf 100111 . . . 101 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 11b4887275..af4dcb96c6 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1557,3 +1557,110 @@ GEN_OPIVX_NARROW_TRANS(vnclipu_vx) GEN_OPIVX_NARROW_TRANS(vnclip_vx) GEN_OPIVI_NARROW_TRANS(vnclipu_vi, 1, vnclipu_vx) GEN_OPIVI_NARROW_TRANS(vnclip_vi, 1, vnclip_vx) + +/* + *** Vector Float Point Arithmetic Instructions + */ +/* Vector Single-Width Floating-Point Add/Subtract Instructions */ + +/* + * If the current SEW does not correspond to a supported IEEE floating-point + * type, an illegal instruction exception is raised. + */ +static bool opfvv_check(DisasContext *s, arg_rmrr *a) +{ +return (vext_check_isa_ill(s, RVV) && +vext_check_overlap_mask(s, a->rd, a->vm, false) && +vext_check_reg(s, a->rd, false) && +vext_check_reg(s, a->rs2, false) && +vext_check_reg(s, a->rs1, false) && +(s->sew != 0)); +} + +/* OPFVV without GVEC IR */ +#define GEN_OPFVV_TRANS(NAME, CHECK) \ +static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ +{ \ +if (CHECK(s, a)) { \ +uint32_t data = 0; \ +static gen_helper_gvec_4_ptr * const fns[3] = {\ +gen_helper_##NAME##_h, \ +gen_helper_##NAME##_w, \ +gen_helper_##NAME##_d, \ +}; \ +data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ +data = FIELD_DP32(data, VDATA, VM, a->vm); \ +data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ +tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ +vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2), \ +cpu_env, 0, s->vlen / 8, data, fns[s->sew - 1]); \ +return true; \ +} \ +return false; \ +} +GEN_OPFVV_TRANS(vfadd_vv, opfvv_check)
[PATCH v4 21/60] target/riscv: vector widening integer multiply-add instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 22 target/riscv/insn32.decode | 7 target/riscv/insn_trans/trans_rvv.inc.c | 9 + target/riscv/vector_helper.c| 45 + 4 files changed, 83 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 098288df76..1f0d3d60e3 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -643,3 +643,25 @@ DEF_HELPER_6(vnmsub_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vnmsub_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vnmsub_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vnmsub_vx_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vwmaccu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmaccu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmaccu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmacc_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmaccsu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmaccsu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmaccsu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmaccu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmaccu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmaccu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmacc_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmacc_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmacc_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmaccsu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmaccsu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmaccsu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmaccus_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmaccus_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmaccus_vx_w, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 58de888afa..2a5b945139 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -392,6 +392,13 @@ vmadd_vv101001 . . . 010 . 1010111 @r_vm vmadd_vx101001 . . . 110 . 1010111 @r_vm vnmsub_vv 101011 . . . 010 . 1010111 @r_vm vnmsub_vx 101011 . . . 110 . 1010111 @r_vm +vwmaccu_vv 00 . . . 010 . 1010111 @r_vm +vwmaccu_vx 00 . . . 110 . 1010111 @r_vm +vwmacc_vv 01 . . . 010 . 1010111 @r_vm +vwmacc_vx 01 . . . 110 . 1010111 @r_vm +vwmaccsu_vv 10 . . . 010 . 1010111 @r_vm +vwmaccsu_vx 10 . . . 110 . 1010111 @r_vm +vwmaccus_vx 11 . . . 110 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 05f7ae0bc4..958737d097 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1472,3 +1472,12 @@ GEN_OPIVX_TRANS(vmacc_vx, opivx_check) GEN_OPIVX_TRANS(vnmsac_vx, opivx_check) GEN_OPIVX_TRANS(vmadd_vx, opivx_check) GEN_OPIVX_TRANS(vnmsub_vx, opivx_check) + +/* Vector Widening Integer Multiply-Add Instructions */ +GEN_OPIVV_WIDEN_TRANS(vwmaccu_vv, opivv_widen_check) +GEN_OPIVV_WIDEN_TRANS(vwmacc_vv, opivv_widen_check) +GEN_OPIVV_WIDEN_TRANS(vwmaccsu_vv, opivv_widen_check) +GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx) +GEN_OPIVX_WIDEN_TRANS(vwmacc_vx) +GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx) +GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index e5082c8adc..5109654f9f 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -1910,3 +1910,48 @@ GEN_VEXT_VX(vnmsub_vx_b, 1, 1, clearb) GEN_VEXT_VX(vnmsub_vx_h, 2, 2, clearh) GEN_VEXT_VX(vnmsub_vx_w, 4, 4, clearl) GEN_VEXT_VX(vnmsub_vx_d, 8, 8, clearq) + +/* Vector Widening Integer Multiply-Add Instructions */ +RVVCALL(OPIVV3, vwmaccu_vv_b, WOP_UUU_B, H2, H1, H1, DO_MACC) +RVVCALL(OPIVV3, vwmaccu_vv_h, WOP_UUU_H, H4, H2, H2, DO_MACC) +RVVCALL(OPIVV3, vwmaccu_vv_w, WOP_UUU_W, H8, H4, H4, DO_MACC) +RVVCALL(OPIVV3, vwmacc_vv_b, WOP_SSS_B, H2, H1, H1, DO_MACC) +RVVCALL(OPIVV3, vwmacc_vv_h, WOP_SSS_H, H4, H2, H2, DO_MACC) +RVVCALL(OPIVV3, vwmacc_vv_w, WOP_SSS_W, H8, H4, H4, DO_MACC) +RVVCALL(OPIVV3, vwmaccsu_vv_b, WOP_SSU_B, H2, H1, H1, DO_MACC) +RVVCALL(OPIVV3, vwmaccsu_vv_h, WOP_SSU_H, H4, H2, H2, DO_MACC) +RVVCALL(OPIVV3, vwmaccsu_vv_w, WOP_SSU_W, H8, H4, H4, DO_MACC) +GEN_VEXT_VV(vwmaccu_vv_b, 1, 2, clearh) +GEN_VEXT_VV(vwmaccu_vv_h, 2, 4, clearl) +GEN_VEXT_VV(vwmaccu_vv_w, 4, 8, clearq) +GEN_VEXT_VV(vwmacc_vv_b, 1, 2, clearh)
[PATCH v4 26/60] target/riscv: vector widening saturating scaled multiply-add
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 22 +++ target/riscv/insn32.decode | 7 + target/riscv/insn_trans/trans_rvv.inc.c | 9 ++ target/riscv/vector_helper.c| 180 4 files changed, 218 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 333eccca57..74c1c695e0 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -733,3 +733,25 @@ DEF_HELPER_6(vsmul_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vsmul_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vsmul_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vsmul_vx_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vwsmaccu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsmaccu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsmaccu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsmacc_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsmaccsu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsmaccsu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsmaccsu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsmaccu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsmaccu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsmaccu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsmacc_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsmacc_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsmacc_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsmaccsu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsmaccsu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsmaccsu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsmaccus_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsmaccus_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsmaccus_vx_w, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 99f70924d6..8798919d3e 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -419,6 +419,13 @@ vasub_vv100110 . . . 000 . 1010111 @r_vm vasub_vx100110 . . . 100 . 1010111 @r_vm vsmul_vv100111 . . . 000 . 1010111 @r_vm vsmul_vx100111 . . . 100 . 1010111 @r_vm +vwsmaccu_vv 00 . . . 000 . 1010111 @r_vm +vwsmaccu_vx 00 . . . 100 . 1010111 @r_vm +vwsmacc_vv 01 . . . 000 . 1010111 @r_vm +vwsmacc_vx 01 . . . 100 . 1010111 @r_vm +vwsmaccsu_vv10 . . . 000 . 1010111 @r_vm +vwsmaccsu_vx10 . . . 100 . 1010111 @r_vm +vwsmaccus_vx11 . . . 100 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 60e1e63b7b..68bebd3c37 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1532,3 +1532,12 @@ GEN_OPIVI_TRANS(vaadd_vi, 0, vaadd_vx, opivx_check) /* Vector Single-Width Fractional Multiply with Rounding and Saturation */ GEN_OPIVV_TRANS(vsmul_vv, opivv_check) GEN_OPIVX_TRANS(vsmul_vx, opivx_check) + +/* Vector Widening Saturating Scaled Multiply-Add */ +GEN_OPIVV_WIDEN_TRANS(vwsmaccu_vv, opivv_widen_check) +GEN_OPIVV_WIDEN_TRANS(vwsmacc_vv, opivv_widen_check) +GEN_OPIVV_WIDEN_TRANS(vwsmaccsu_vv, opivv_widen_check) +GEN_OPIVX_WIDEN_TRANS(vwsmaccu_vx) +GEN_OPIVX_WIDEN_TRANS(vwsmacc_vx) +GEN_OPIVX_WIDEN_TRANS(vwsmaccsu_vx) +GEN_OPIVX_WIDEN_TRANS(vwsmaccus_vx) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 74ad07743c..90c19577fa 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -2523,3 +2523,183 @@ GEN_VEXT_VX_ENV(vsmul_vx_b, 1, 1, clearb) GEN_VEXT_VX_ENV(vsmul_vx_h, 2, 2, clearh) GEN_VEXT_VX_ENV(vsmul_vx_w, 4, 4, clearl) GEN_VEXT_VX_ENV(vsmul_vx_d, 8, 8, clearq) + +/* Vector Widening Saturating Scaled Multiply-Add */ +static uint16_t vwsmaccu8(CPURISCVState *env, uint8_t a, uint8_t b, +uint16_t c) +{ +uint8_t round; +uint16_t res = (uint16_t)a * (uint16_t)b; + +round = get_round(env, res, 4); +res = (res >> 4) + round; +return saddu16(env, c, res); +} +static uint32_t vwsmaccu16(CPURISCVState *env, uint16_t a, uint16_t b, +uint32_t c) +{ +uint8_t round; +uint32_t res = (uint32_t)a * (uint32_t)b; + +round = get_round(env, res, 8); +res = (res >> 8) + round; +return saddu32(env, c, res); +} +static uint64_t vwsmaccu32(CPURISCVState *env, uint32_t a, uint32_t b, +uint64_t c) +{ +uint8_t round; +uint64_t res = (uint64_t)a *
[PATCH v4 20/60] target/riscv: vector single-width integer multiply-add instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 33 ++ target/riscv/insn32.decode | 8 +++ target/riscv/insn_trans/trans_rvv.inc.c | 10 +++ target/riscv/vector_helper.c| 88 + 4 files changed, 139 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 1704b8c512..098288df76 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -610,3 +610,36 @@ DEF_HELPER_6(vwmulu_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vwmulsu_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vwmulsu_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vwmulsu_vx_w, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vmacc_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmacc_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnmsac_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnmsac_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnmsub_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnmsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnmsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnmsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmacc_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmacc_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmacc_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmacc_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnmsac_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnmsac_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnmsac_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnmsac_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmadd_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmadd_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmadd_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmadd_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnmsub_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnmsub_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnmsub_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnmsub_vx_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index ceddfe4b6c..58de888afa 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -384,6 +384,14 @@ vwmulsu_vv 111010 . . . 010 . 1010111 @r_vm vwmulsu_vx 111010 . . . 110 . 1010111 @r_vm vwmul_vv111011 . . . 010 . 1010111 @r_vm vwmul_vx111011 . . . 110 . 1010111 @r_vm +vmacc_vv101101 . . . 010 . 1010111 @r_vm +vmacc_vx101101 . . . 110 . 1010111 @r_vm +vnmsac_vv 10 . . . 010 . 1010111 @r_vm +vnmsac_vx 10 . . . 110 . 1010111 @r_vm +vmadd_vv101001 . . . 010 . 1010111 @r_vm +vmadd_vx101001 . . . 110 . 1010111 @r_vm +vnmsub_vv 101011 . . . 010 . 1010111 @r_vm +vnmsub_vx 101011 . . . 110 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 990433f866..05f7ae0bc4 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1462,3 +1462,13 @@ GEN_OPIVV_WIDEN_TRANS(vwmulsu_vv, opivv_widen_check) GEN_OPIVX_WIDEN_TRANS(vwmul_vx) GEN_OPIVX_WIDEN_TRANS(vwmulu_vx) GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx) + +/* Vector Single-Width Integer Multiply-Add Instructions */ +GEN_OPIVV_TRANS(vmacc_vv, opivv_check) +GEN_OPIVV_TRANS(vnmsac_vv, opivv_check) +GEN_OPIVV_TRANS(vmadd_vv, opivv_check) +GEN_OPIVV_TRANS(vnmsub_vv, opivv_check) +GEN_OPIVX_TRANS(vmacc_vx, opivx_check) +GEN_OPIVX_TRANS(vnmsac_vx, opivx_check) +GEN_OPIVX_TRANS(vmadd_vx, opivx_check) +GEN_OPIVX_TRANS(vnmsub_vx, opivx_check) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index beb84f9674..e5082c8adc 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -1822,3 +1822,91 @@ GEN_VEXT_VX(vwmulu_vx_w, 4, 8, clearq) GEN_VEXT_VX(vwmulsu_vx_b, 1, 2, clearh) GEN_VEXT_VX(vwmulsu_vx_h, 2, 4, clearl) GEN_VEXT_VX(vwmulsu_vx_w, 4, 8, clearq) + +/* Vector Single-Width Integer Multiply-Add Instructions */ +#define
[PATCH v4 18/60] target/riscv: vector integer divide instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 33 +++ target/riscv/insn32.decode | 8 +++ target/riscv/insn_trans/trans_rvv.inc.c | 10 target/riscv/vector_helper.c| 74 + 4 files changed, 125 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index f42a12eef3..357f149198 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -558,3 +558,36 @@ DEF_HELPER_6(vmulhsu_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmulhsu_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmulhsu_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmulhsu_vx_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vdivu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vdivu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vdivu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vdivu_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vdiv_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vdiv_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vdiv_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vdiv_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vremu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vremu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vremu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vremu_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vrem_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vrem_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vrem_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vrem_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vdivu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vdivu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vdivu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vdivu_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vdiv_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vdiv_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vdiv_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vdiv_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vremu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vremu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vremu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vremu_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vrem_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vrem_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vrem_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vrem_vx_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index a8ac4e9e9d..2afe24dd34 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -370,6 +370,14 @@ vmulhu_vv 100100 . . . 010 . 1010111 @r_vm vmulhu_vx 100100 . . . 110 . 1010111 @r_vm vmulhsu_vv 100110 . . . 010 . 1010111 @r_vm vmulhsu_vx 100110 . . . 110 . 1010111 @r_vm +vdivu_vv10 . . . 010 . 1010111 @r_vm +vdivu_vx10 . . . 110 . 1010111 @r_vm +vdiv_vv 11 . . . 010 . 1010111 @r_vm +vdiv_vx 11 . . . 110 . 1010111 @r_vm +vremu_vv100010 . . . 010 . 1010111 @r_vm +vremu_vx100010 . . . 110 . 1010111 @r_vm +vrem_vv 100011 . . . 010 . 1010111 @r_vm +vrem_vx 100011 . . . 110 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index a1ecc9f52d..9f0645a92b 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1444,3 +1444,13 @@ GEN_OPIVX_GVEC_TRANS(vmul_vx, muls) GEN_OPIVX_TRANS(vmulh_vx, opivx_check) GEN_OPIVX_TRANS(vmulhu_vx, opivx_check) GEN_OPIVX_TRANS(vmulhsu_vx, opivx_check) + +/* Vector Integer Divide Instructions */ +GEN_OPIVV_TRANS(vdivu_vv, opivv_check) +GEN_OPIVV_TRANS(vdiv_vv, opivv_check) +GEN_OPIVV_TRANS(vremu_vv, opivv_check) +GEN_OPIVV_TRANS(vrem_vv, opivv_check) +GEN_OPIVX_TRANS(vdivu_vx, opivx_check) +GEN_OPIVX_TRANS(vdiv_vx, opivx_check) +GEN_OPIVX_TRANS(vremu_vx, opivx_check) +GEN_OPIVX_TRANS(vrem_vx, opivx_check) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 93daafd5bd..6330f5882f 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -1697,3 +1697,77 @@ GEN_VEXT_VX(vmulhsu_vx_b, 1, 1, clearb) GEN_VEXT_VX(vmulhsu_vx_h, 2, 2, clearh) GEN_VEXT_VX(vmulhsu_vx_w, 4, 4, clearl) GEN_VEXT_VX(vmulhsu_vx_d, 8, 8, clearq) + +/* Vector Integer Divide Instructions */ +#define DO_DIVU(N, M) (unlikely(M == 0) ? (__typeof(N))(-1) : N / M) +#define
[PATCH v4 27/60] target/riscv: vector single-width scaling shift instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 17 target/riscv/insn32.decode | 6 ++ target/riscv/insn_trans/trans_rvv.inc.c | 8 ++ target/riscv/vector_helper.c| 109 4 files changed, 140 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 74c1c695e0..efc84fbd79 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -755,3 +755,20 @@ DEF_HELPER_6(vwsmaccsu_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vwsmaccus_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vwsmaccus_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vwsmaccus_vx_w, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vssrl_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssrl_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssrl_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssrl_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssra_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssra_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssra_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssra_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vssrl_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssrl_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssrl_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssrl_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssra_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssra_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssra_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vssra_vx_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 8798919d3e..d6d111e04a 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -426,6 +426,12 @@ vwsmacc_vx 01 . . . 100 . 1010111 @r_vm vwsmaccsu_vv10 . . . 000 . 1010111 @r_vm vwsmaccsu_vx10 . . . 100 . 1010111 @r_vm vwsmaccus_vx11 . . . 100 . 1010111 @r_vm +vssrl_vv101010 . . . 000 . 1010111 @r_vm +vssrl_vx101010 . . . 100 . 1010111 @r_vm +vssrl_vi101010 . . . 011 . 1010111 @r_vm +vssra_vv101011 . . . 000 . 1010111 @r_vm +vssra_vx101011 . . . 100 . 1010111 @r_vm +vssra_vi101011 . . . 011 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 68bebd3c37..21f896ea26 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1541,3 +1541,11 @@ GEN_OPIVX_WIDEN_TRANS(vwsmaccu_vx) GEN_OPIVX_WIDEN_TRANS(vwsmacc_vx) GEN_OPIVX_WIDEN_TRANS(vwsmaccsu_vx) GEN_OPIVX_WIDEN_TRANS(vwsmaccus_vx) + +/* Vector Single-Width Scaling Shift Instructions */ +GEN_OPIVV_TRANS(vssrl_vv, opivv_check) +GEN_OPIVV_TRANS(vssra_vv, opivv_check) +GEN_OPIVX_TRANS(vssrl_vx, opivx_check) +GEN_OPIVX_TRANS(vssra_vx, opivx_check) +GEN_OPIVI_TRANS(vssrl_vi, 1, vssrl_vx, opivx_check) +GEN_OPIVI_TRANS(vssra_vi, 0, vssra_vx, opivx_check) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 90c19577fa..ec0f822fcf 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -2703,3 +2703,112 @@ RVVCALL(OPIVX3_ENV, vwsmaccus_vx_w, WOP_SUS_W, H8, H4, vwsmaccus32) GEN_VEXT_VX_ENV(vwsmaccus_vx_b, 1, 2, clearh) GEN_VEXT_VX_ENV(vwsmaccus_vx_h, 2, 4, clearl) GEN_VEXT_VX_ENV(vwsmaccus_vx_w, 4, 8, clearq) + +/* Vector Single-Width Scaling Shift Instructions */ +static uint8_t vssrl8(CPURISCVState *env, uint8_t a, uint8_t b) +{ +uint8_t round, shift = b & 0x7; +uint8_t res; + +round = get_round(env, a, shift); +res = (a >> shift) + round; +return res; +} +static uint16_t vssrl16(CPURISCVState *env, uint16_t a, uint16_t b) +{ +uint8_t round, shift = b & 0xf; +uint16_t res; + +round = get_round(env, a, shift); +res = (a >> shift) + round; +return res; +} +static uint32_t vssrl32(CPURISCVState *env, uint32_t a, uint32_t b) +{ +uint8_t round, shift = b & 0x1f; +uint32_t res; + +round = get_round(env, a, shift); +res = (a >> shift) + round; +return res; +} +static uint64_t vssrl64(CPURISCVState *env, uint64_t a, uint64_t b) +{ +uint8_t round, shift = b & 0x3f; +uint64_t res; + +round = get_round(env, a, shift); +res = (a >> shift) + round; +return res; +} +RVVCALL(OPIVV2_ENV, vssrl_vv_b, OP_UUU_B, H1, H1, H1, vssrl8) +RVVCALL(OPIVV2_ENV, vssrl_vv_h, OP_UUU_H, H2, H2, H2, vssrl16) +RVVCALL(OPIVV2_ENV, vssrl_vv_w, OP_UUU_W, H4, H4, H4, vssrl32) +RVVCALL(OPIVV2_ENV, vssrl_vv_d, OP_UUU_D, H8, H8, H8, vssrl64)
[PATCH v4 35/60] target/riscv: vector floating-point square-root instruction
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 4 +++ target/riscv/insn32.decode | 3 ++ target/riscv/insn_trans/trans_rvv.inc.c | 37 +++ target/riscv/vector_helper.c| 40 + 4 files changed, 84 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 57e0fee929..c2f9871490 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -905,3 +905,7 @@ DEF_HELPER_6(vfwmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfwmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfwnmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfwnmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32) + +DEF_HELPER_5(vfsqrt_v_h, void, ptr, ptr, ptr, env, i32) +DEF_HELPER_5(vfsqrt_v_w, void, ptr, ptr, ptr, env, i32) +DEF_HELPER_5(vfsqrt_v_d, void, ptr, ptr, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index b7cb116cf4..fc9aebc6d6 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -45,6 +45,7 @@ shamt rs1 rd aq rl rs2 rs1 rd vm rd rs1 rs2 + vm rd rs2 vm wd rd rs1 rs2 vm rd rs1 nf vm rd rs1 rs2 nf @@ -68,6 +69,7 @@ @r2_rm ... . . ... . ... %rs1 %rm %rd @r2 ... . . ... . ... %rs1 %rd @r2_nfvm ... ... vm:1 . . ... . ... %nf %rs1 %rd +@r2_vm .. vm:1 . . ... . ... %rs2 %rd @r_nfvm ... ... vm:1 . . ... . ... %nf %rs2 %rs1 %rd @r_vm.. vm:1 . . ... . ... %rs2 %rs1 %rd @r_wdvm . wd:1 vm:1 . . ... . ... %rs2 %rs1 %rd @@ -482,6 +484,7 @@ vfwmsac_vv 10 . . . 001 . 1010111 @r_vm vfwmsac_vf 10 . . . 101 . 1010111 @r_vm vfwnmsac_vv 11 . . . 001 . 1010111 @r_vm vfwnmsac_vf 11 . . . 101 . 1010111 @r_vm +vfsqrt_v100011 . . 0 001 . 1010111 @r2_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 06d6e2625b..3e4f7de240 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1834,3 +1834,40 @@ GEN_OPFVF_WIDEN_TRANS(vfwmacc_vf) GEN_OPFVF_WIDEN_TRANS(vfwnmacc_vf) GEN_OPFVF_WIDEN_TRANS(vfwmsac_vf) GEN_OPFVF_WIDEN_TRANS(vfwnmsac_vf) + +/* Vector Floating-Point Square-Root Instruction */ + +/* + * If the current SEW does not correspond to a supported IEEE floating-point + * type, an illegal instruction exception is raised + */ +static bool opfv_check(DisasContext *s, arg_rmr *a) +{ + return (vext_check_isa_ill(s, RVV) && +vext_check_overlap_mask(s, a->rd, a->vm, false) && +vext_check_reg(s, a->rd, false) && +vext_check_reg(s, a->rs2, false) && +(s->sew != 0)); +} + +#define GEN_OPFV_TRANS(NAME, CHECK)\ +static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ +{ \ +if (CHECK(s, a)) { \ +uint32_t data = 0; \ +static gen_helper_gvec_3_ptr * const fns[3] = {\ +gen_helper_##NAME##_h, \ +gen_helper_##NAME##_w, \ +gen_helper_##NAME##_d, \ +}; \ +data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ +data = FIELD_DP32(data, VDATA, VM, a->vm); \ +data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ +tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ +vreg_ofs(s, a->rs2), cpu_env, 0, \ +s->vlen / 8, data, fns[s->sew - 1]); \ +return true; \ +} \ +return false; \ +} +GEN_OPFV_TRANS(vfsqrt_v, opfv_check) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 9bff516a15..088bb51af0 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -3488,3 +3488,43 @@ RVVCALL(OPFVF3, vfwnmsac_vf_h, WOP_UUU_H, H4, H2, fwnmsac16) RVVCALL(OPFVF3, vfwnmsac_vf_w, WOP_UUU_W, H8, H4, fwnmsac32) GEN_VEXT_VF(vfwnmsac_vf_h, 2, 4, clearl) GEN_VEXT_VF(vfwnmsac_vf_w, 4, 8, clearq) + +/* Vector Floating-Point Square-Root Instruction */ +/* (TD, T2, TX2) */ +#define OP_UU_H uint16_t, uint16_t, uint16_t +#define OP_UU_W uint32_t, uint32_t,
[PATCH v4 16/60] target/riscv: vector integer min/max instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 33 target/riscv/insn32.decode | 8 +++ target/riscv/insn_trans/trans_rvv.inc.c | 10 target/riscv/vector_helper.c| 71 + 4 files changed, 122 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 4e6c47c2d2..c7d4ff185a 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -492,3 +492,36 @@ DEF_HELPER_6(vmsgt_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmsgt_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmsgt_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmsgt_vx_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vminu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vminu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vminu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vminu_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmin_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmin_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmin_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmin_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmaxu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmaxu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmaxu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmaxu_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmax_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmax_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmax_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmax_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vminu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vminu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vminu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vminu_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmin_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmin_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmin_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmin_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmaxu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmaxu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmaxu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmaxu_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmax_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmax_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmax_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmax_vx_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 525b2fa442..a7619f4e3d 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -354,6 +354,14 @@ vmsgtu_vx 00 . . . 100 . 1010111 @r_vm vmsgtu_vi 00 . . . 011 . 1010111 @r_vm vmsgt_vx01 . . . 100 . 1010111 @r_vm vmsgt_vi01 . . . 011 . 1010111 @r_vm +vminu_vv000100 . . . 000 . 1010111 @r_vm +vminu_vx000100 . . . 100 . 1010111 @r_vm +vmin_vv 000101 . . . 000 . 1010111 @r_vm +vmin_vx 000101 . . . 100 . 1010111 @r_vm +vmaxu_vv000110 . . . 000 . 1010111 @r_vm +vmaxu_vx000110 . . . 100 . 1010111 @r_vm +vmax_vv 000111 . . . 000 . 1010111 @r_vm +vmax_vx 000111 . . . 100 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 078d275af6..4437a77878 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1424,3 +1424,13 @@ GEN_OPIVI_TRANS(vmsleu_vi, 1, vmsleu_vx, opivx_cmp_check) GEN_OPIVI_TRANS(vmsle_vi, 0, vmsle_vx, opivx_cmp_check) GEN_OPIVI_TRANS(vmsgtu_vi, 1, vmsgtu_vx, opivx_cmp_check) GEN_OPIVI_TRANS(vmsgt_vi, 0, vmsgt_vx, opivx_cmp_check) + +/* Vector Integer Min/Max Instructions */ +GEN_OPIVV_GVEC_TRANS(vminu_vv, umin) +GEN_OPIVV_GVEC_TRANS(vmin_vv, smin) +GEN_OPIVV_GVEC_TRANS(vmaxu_vv, umax) +GEN_OPIVV_GVEC_TRANS(vmax_vv, smax) +GEN_OPIVX_TRANS(vminu_vx, opivx_check) +GEN_OPIVX_TRANS(vmin_vx, opivx_check) +GEN_OPIVX_TRANS(vmaxu_vx, opivx_check) +GEN_OPIVX_TRANS(vmax_vx, opivx_check) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index e7a4e99f46..03e001262f 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -849,6 +849,10 @@ GEN_VEXT_AMO(vamomaxuw_v_w, uint32_t, uint32_t, idx_w, clearl) #define OP_SSS_H int16_t, int16_t, int16_t, int16_t, int16_t #define OP_SSS_W int32_t, int32_t, int32_t, int32_t, int32_t #define OP_SSS_D int64_t, int64_t, int64_t,
[PATCH v4 11/60] target/riscv: vector integer add-with-carry / subtract-with-borrow instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 33 ++ target/riscv/insn32.decode | 10 ++ target/riscv/insn_trans/trans_rvv.inc.c | 108 ++ target/riscv/vector_helper.c| 140 4 files changed, 291 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 1256defb6c..72c733bf49 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -339,3 +339,36 @@ DEF_HELPER_6(vwadd_wx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vwsub_wx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vwsub_wx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vwsub_wx_w, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vadc_vvm_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vadc_vvm_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vadc_vvm_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vadc_vvm_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsbc_vvm_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsbc_vvm_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsbc_vvm_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsbc_vvm_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmadc_vvm_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmadc_vvm_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmadc_vvm_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmadc_vvm_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsbc_vvm_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsbc_vvm_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsbc_vvm_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsbc_vvm_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vadc_vxm_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vadc_vxm_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vadc_vxm_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vadc_vxm_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsbc_vxm_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsbc_vxm_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsbc_vxm_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsbc_vxm_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmadc_vxm_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmadc_vxm_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmadc_vxm_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmadc_vxm_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsbc_vxm_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsbc_vxm_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsbc_vxm_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsbc_vxm_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 4bdbfd16fa..e8ddf95d3d 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -300,6 +300,16 @@ vwsubu_wv 110110 . . . 010 . 1010111 @r_vm vwsubu_wx 110110 . . . 110 . 1010111 @r_vm vwsub_wv110111 . . . 010 . 1010111 @r_vm vwsub_wx110111 . . . 110 . 1010111 @r_vm +vadc_vvm01 1 . . 000 . 1010111 @r +vadc_vxm01 1 . . 100 . 1010111 @r +vadc_vim01 1 . . 011 . 1010111 @r +vmadc_vvm 010001 1 . . 000 . 1010111 @r +vmadc_vxm 010001 1 . . 100 . 1010111 @r +vmadc_vim 010001 1 . . 011 . 1010111 @r +vsbc_vvm010010 1 . . 000 . 1010111 @r +vsbc_vxm010010 1 . . 100 . 1010111 @r +vmsbc_vvm 010011 1 . . 000 . 1010111 @r +vmsbc_vxm 010011 1 . . 100 . 1010111 @r vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 7f6fe82fb3..a1f2e84eb8 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1104,3 +1104,111 @@ GEN_OPIWX_WIDEN_TRANS(vwaddu_wx) GEN_OPIWX_WIDEN_TRANS(vwadd_wx) GEN_OPIWX_WIDEN_TRANS(vwsubu_wx) GEN_OPIWX_WIDEN_TRANS(vwsub_wx) + +/* OPIVV with UNMASKED */ +#define GEN_OPIVV_R_TRANS(NAME, CHECK) \ +static bool trans_##NAME(DisasContext *s, arg_r *a)\ +{ \ +if (CHECK(s, a)) { \ +uint32_t data = 0; \ +static gen_helper_gvec_4_ptr * const fns[4] = {\ +gen_helper_##NAME##_b, gen_helper_##NAME##_h, \ +gen_helper_##NAME##_w, gen_helper_##NAME##_d, \ +}; \ + \ +data =
[PATCH v4 22/60] target/riscv: vector integer merge and move instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 9 target/riscv/insn32.decode | 3 ++ target/riscv/insn_trans/trans_rvv.inc.c | 24 ++ target/riscv/vector_helper.c| 58 + 4 files changed, 94 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 1f0d3d60e3..121e9e57e7 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -665,3 +665,12 @@ DEF_HELPER_6(vwmaccsu_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vwmaccus_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vwmaccus_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vwmaccus_vx_w, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vmerge_vvm_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmerge_vvm_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmerge_vvm_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmerge_vvm_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmerge_vxm_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmerge_vxm_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmerge_vxm_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmerge_vxm_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 2a5b945139..bcb8273bcc 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -399,6 +399,9 @@ vwmacc_vx 01 . . . 110 . 1010111 @r_vm vwmaccsu_vv 10 . . . 010 . 1010111 @r_vm vwmaccsu_vx 10 . . . 110 . 1010111 @r_vm vwmaccus_vx 11 . . . 110 . 1010111 @r_vm +vmerge_vvm 010111 . . . 000 . 1010111 @r_vm +vmerge_vxm 010111 . . . 100 . 1010111 @r_vm +vmerge_vim 010111 . . . 011 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 958737d097..aff5ca8663 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1481,3 +1481,27 @@ GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx) GEN_OPIVX_WIDEN_TRANS(vwmacc_vx) GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx) GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx) + +/* Vector Integer Merge and Move Instructions */ +static bool opivv_vmerge_check(DisasContext *s, arg_rmrr *a) +{ +return (vext_check_isa_ill(s, RVV) && +vext_check_overlap_mask(s, a->rd, a->vm, false) && +vext_check_reg(s, a->rd, false) && +vext_check_reg(s, a->rs2, false) && +vext_check_reg(s, a->rs1, false) && +((a->vm == 0) || (a->rs2 == 0))); +} +GEN_OPIVV_TRANS(vmerge_vvm, opivv_vmerge_check) + +static bool opivx_vmerge_check(DisasContext *s, arg_rmrr *a) +{ +return (vext_check_isa_ill(s, RVV) && +vext_check_overlap_mask(s, a->rd, a->vm, false) && +vext_check_reg(s, a->rd, false) && +vext_check_reg(s, a->rs2, false) && +((a->vm == 0) || (a->rs2 == 0))); +} +GEN_OPIVX_TRANS(vmerge_vxm, opivx_vmerge_check) + +GEN_OPIVI_TRANS(vmerge_vim, 0, vmerge_vxm, opivx_vmerge_check) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 5109654f9f..273b705847 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -1955,3 +1955,61 @@ GEN_VEXT_VX(vwmaccsu_vx_w, 4, 8, clearq) GEN_VEXT_VX(vwmaccus_vx_b, 1, 2, clearh) GEN_VEXT_VX(vwmaccus_vx_h, 2, 4, clearl) GEN_VEXT_VX(vwmaccus_vx_w, 4, 8, clearq) + +/* Vector Integer Merge and Move Instructions */ +#define GEN_VEXT_VMERGE_VV(NAME, ETYPE, H, CLEAR_FN) \ +void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ +CPURISCVState *env, uint32_t desc) \ +{\ +uint32_t mlen = vext_mlen(desc); \ +uint32_t vm = vext_vm(desc); \ +uint32_t vl = env->vl; \ +uint32_t esz = sizeof(ETYPE);\ +uint32_t vlmax = vext_maxsz(desc) / esz; \ +uint32_t i; \ + \ +for (i = 0; i < vl; i++) { \ +if (!vm && !vext_elem_mask(v0, mlen, i)) { \ +ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ +*((ETYPE *)vd + H1(i)) = s2; \ +} else { \ +ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ +*((ETYPE *)vd + H(i)) = s1; \ +
[PATCH v4 33/60] target/riscv: vector single-width floating-point fused multiply-add instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 49 + target/riscv/insn32.decode | 16 ++ target/riscv/insn_trans/trans_rvv.inc.c | 18 ++ target/riscv/vector_helper.c| 228 4 files changed, 311 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 3ec2dcadd4..3b6dd96918 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -839,3 +839,52 @@ DEF_HELPER_6(vfwmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vfwmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vfwmul_vf_h, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfwmul_vf_w, void, ptr, ptr, i64, ptr, env, i32) + +DEF_HELPER_6(vfmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmacc_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfnmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfnmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfnmacc_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmsac_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfnmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfnmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfnmsac_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfnmadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfnmadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfnmadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfnmsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfnmsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfnmsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfmacc_vf_d, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfnmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfnmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfnmacc_vf_d, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfmsac_vf_d, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfnmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfnmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfnmsac_vf_d, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfmadd_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfmadd_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfmadd_vf_d, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfnmadd_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfnmadd_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfnmadd_vf_d, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfmsub_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfmsub_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfmsub_vf_d, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfnmsub_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfnmsub_vf_w, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfnmsub_vf_d, void, ptr, ptr, i64, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index e0ee8f5a7c..9834091a86 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -458,6 +458,22 @@ vfdiv_vf10 . . . 101 . 1010111 @r_vm vfrdiv_vf 11 . . . 101 . 1010111 @r_vm vfwmul_vv 111000 . . . 001 . 1010111 @r_vm vfwmul_vf 111000 . . . 101 . 1010111 @r_vm +vfmacc_vv 101100 . . . 001 . 1010111 @r_vm +vfnmacc_vv 101101 . . . 001 . 1010111 @r_vm +vfnmacc_vf 101101 . . . 101 . 1010111 @r_vm +vfmacc_vf 101100 . . . 101 . 1010111 @r_vm +vfmsac_vv 101110 . . . 001 . 1010111 @r_vm +vfmsac_vf 101110 . . . 101 . 1010111 @r_vm +vfnmsac_vv 10 . . . 001 . 1010111 @r_vm +vfnmsac_vf 10 . . . 101 . 1010111 @r_vm +vfmadd_vv 101000 . . . 001 . 1010111 @r_vm +vfmadd_vf 101000 . . . 101 . 1010111 @r_vm +vfnmadd_vv 101001 . . . 001 . 1010111 @r_vm +vfnmadd_vf 101001 . . . 101 . 1010111 @r_vm +vfmsub_vv 101010 . . . 001 .
[PATCH v4 14/60] target/riscv: vector narrowing integer right shift instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 13 target/riscv/insn32.decode | 6 ++ target/riscv/insn_trans/trans_rvv.inc.c | 91 + target/riscv/vector_helper.c| 14 4 files changed, 124 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 47284c7476..0f36a8ce43 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -422,3 +422,16 @@ DEF_HELPER_6(vsra_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vsra_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vsra_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vsra_vx_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vnsrl_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnsrl_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnsrl_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnsra_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnsra_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnsra_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vnsrl_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnsrl_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnsrl_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnsra_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnsra_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vnsra_vx_w, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index dbbfa34b97..e21b3d6b5e 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -328,6 +328,12 @@ vsrl_vi 101000 . . . 011 . 1010111 @r_vm vsra_vv 101001 . . . 000 . 1010111 @r_vm vsra_vx 101001 . . . 100 . 1010111 @r_vm vsra_vi 101001 . . . 011 . 1010111 @r_vm +vnsrl_vv101100 . . . 000 . 1010111 @r_vm +vnsrl_vx101100 . . . 100 . 1010111 @r_vm +vnsrl_vi101100 . . . 011 . 1010111 @r_vm +vnsra_vv101101 . . . 000 . 1010111 @r_vm +vnsra_vx101101 . . . 100 . 1010111 @r_vm +vnsra_vi101101 . . . 011 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index a60518e1df..7033eeaa4d 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1267,3 +1267,94 @@ GEN_OPIVX_GVEC_SHIFT_TRANS(vsra_vx, sars) GEN_OPIVI_GVEC_TRANS(vsll_vi, 1, vsll_vx, shli) GEN_OPIVI_GVEC_TRANS(vsrl_vi, 1, vsrl_vx, shri) GEN_OPIVI_GVEC_TRANS(vsra_vi, 1, vsra_vx, sari) + +/* Vector Narrowing Integer Right Shift Instructions */ +static bool opivv_narrow_check(DisasContext *s, arg_rmrr *a) +{ +return (vext_check_isa_ill(s, RVV) && +vext_check_overlap_mask(s, a->rd, a->vm, false) && +vext_check_reg(s, a->rd, false) && +vext_check_reg(s, a->rs2, true) && +vext_check_reg(s, a->rs1, false) && +vext_check_overlap_group(a->rd, 1 << s->lmul, a->rs2, +2 << s->lmul) && +(s->lmul < 0x3) && (s->sew < 0x3)); +} + +/* OPIVV with NARROW */ +#define GEN_OPIVV_NARROW_TRANS(NAME) \ +static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ +{ \ +if (opivv_narrow_check(s, a)) {\ +uint32_t data = 0; \ +static gen_helper_gvec_4_ptr * const fns[3] = {\ +gen_helper_##NAME##_b, \ +gen_helper_##NAME##_h, \ +gen_helper_##NAME##_w, \ +}; \ +data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ +data = FIELD_DP32(data, VDATA, VM, a->vm); \ +data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ +tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ +vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2), \ +cpu_env, 0, s->vlen / 8, data, fns[s->sew]); \ +return true; \ +} \ +return false; \ +} +GEN_OPIVV_NARROW_TRANS(vnsra_vv) +GEN_OPIVV_NARROW_TRANS(vnsrl_vv) + +static bool opivx_narrow_check(DisasContext *s, arg_rmrr *a) +{ +return (vext_check_isa_ill(s, RVV) && +vext_check_overlap_mask(s, a->rd, a->vm, false) && +vext_check_reg(s, a->rd, false) &&
[PATCH v4 17/60] target/riscv: vector single-width integer multiply instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 33 ++ target/riscv/insn32.decode | 8 ++ target/riscv/insn_trans/trans_rvv.inc.c | 10 ++ target/riscv/vector_helper.c| 147 4 files changed, 198 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index c7d4ff185a..f42a12eef3 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -525,3 +525,36 @@ DEF_HELPER_6(vmax_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmax_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmax_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmax_vx_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vmul_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmul_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmulh_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmulh_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmulh_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmulh_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmulhu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmulhu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmulhu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmulhu_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmulhsu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmulhsu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmulhsu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmulhsu_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmul_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmul_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmul_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmul_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmulh_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmulh_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmulh_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmulh_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmulhu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmulhu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmulhu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmulhu_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmulhsu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmulhsu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmulhsu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmulhsu_vx_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index a7619f4e3d..a8ac4e9e9d 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -362,6 +362,14 @@ vmaxu_vv000110 . . . 000 . 1010111 @r_vm vmaxu_vx000110 . . . 100 . 1010111 @r_vm vmax_vv 000111 . . . 000 . 1010111 @r_vm vmax_vx 000111 . . . 100 . 1010111 @r_vm +vmul_vv 100101 . . . 010 . 1010111 @r_vm +vmul_vx 100101 . . . 110 . 1010111 @r_vm +vmulh_vv100111 . . . 010 . 1010111 @r_vm +vmulh_vx100111 . . . 110 . 1010111 @r_vm +vmulhu_vv 100100 . . . 010 . 1010111 @r_vm +vmulhu_vx 100100 . . . 110 . 1010111 @r_vm +vmulhsu_vv 100110 . . . 010 . 1010111 @r_vm +vmulhsu_vx 100110 . . . 110 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 4437a77878..a1ecc9f52d 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1434,3 +1434,13 @@ GEN_OPIVX_TRANS(vminu_vx, opivx_check) GEN_OPIVX_TRANS(vmin_vx, opivx_check) GEN_OPIVX_TRANS(vmaxu_vx, opivx_check) GEN_OPIVX_TRANS(vmax_vx, opivx_check) + +/* Vector Single-Width Integer Multiply Instructions */ +GEN_OPIVV_GVEC_TRANS(vmul_vv, mul) +GEN_OPIVV_TRANS(vmulh_vv, opivv_check) +GEN_OPIVV_TRANS(vmulhu_vv, opivv_check) +GEN_OPIVV_TRANS(vmulhsu_vv, opivv_check) +GEN_OPIVX_GVEC_TRANS(vmul_vx, muls) +GEN_OPIVX_TRANS(vmulh_vx, opivx_check) +GEN_OPIVX_TRANS(vmulhu_vx, opivx_check) +GEN_OPIVX_TRANS(vmulhsu_vx, opivx_check) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 03e001262f..93daafd5bd 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -853,6 +853,10 @@ GEN_VEXT_AMO(vamomaxuw_v_w, uint32_t, uint32_t, idx_w, clearl) #define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t #define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t #define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t,
[PATCH v4 19/60] target/riscv: vector widening integer multiply instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 19 + target/riscv/insn32.decode | 6 +++ target/riscv/insn_trans/trans_rvv.inc.c | 8 target/riscv/vector_helper.c| 51 + 4 files changed, 84 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 357f149198..1704b8c512 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -591,3 +591,22 @@ DEF_HELPER_6(vrem_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vrem_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vrem_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vrem_vx_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vwmul_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmulu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmulu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmulu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmulsu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmulsu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmulsu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwmul_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmul_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmul_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmulu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmulu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmulu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmulsu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmulsu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwmulsu_vx_w, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 2afe24dd34..ceddfe4b6c 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -378,6 +378,12 @@ vremu_vv100010 . . . 010 . 1010111 @r_vm vremu_vx100010 . . . 110 . 1010111 @r_vm vrem_vv 100011 . . . 010 . 1010111 @r_vm vrem_vx 100011 . . . 110 . 1010111 @r_vm +vwmulu_vv 111000 . . . 010 . 1010111 @r_vm +vwmulu_vx 111000 . . . 110 . 1010111 @r_vm +vwmulsu_vv 111010 . . . 010 . 1010111 @r_vm +vwmulsu_vx 111010 . . . 110 . 1010111 @r_vm +vwmul_vv111011 . . . 010 . 1010111 @r_vm +vwmul_vx111011 . . . 110 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 9f0645a92b..990433f866 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1454,3 +1454,11 @@ GEN_OPIVX_TRANS(vdivu_vx, opivx_check) GEN_OPIVX_TRANS(vdiv_vx, opivx_check) GEN_OPIVX_TRANS(vremu_vx, opivx_check) GEN_OPIVX_TRANS(vrem_vx, opivx_check) + +/* Vector Widening Integer Multiply Instructions */ +GEN_OPIVV_WIDEN_TRANS(vwmul_vv, opivv_widen_check) +GEN_OPIVV_WIDEN_TRANS(vwmulu_vv, opivv_widen_check) +GEN_OPIVV_WIDEN_TRANS(vwmulsu_vv, opivv_widen_check) +GEN_OPIVX_WIDEN_TRANS(vwmul_vx) +GEN_OPIVX_WIDEN_TRANS(vwmulu_vx) +GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 6330f5882f..beb84f9674 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -857,6 +857,18 @@ GEN_VEXT_AMO(vamomaxuw_v_w, uint32_t, uint32_t, idx_w, clearl) #define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t #define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t #define OP_SUS_D int64_t, uint64_t, int64_t, uint64_t, int64_t +#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t +#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t +#define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t +#define WOP_SSS_B int16_t, int8_t, int8_t, int16_t, int16_t +#define WOP_SSS_H int32_t, int16_t, int16_t, int32_t, int32_t +#define WOP_SSS_W int64_t, int32_t, int32_t, int64_t, int64_t +#define WOP_SUS_B int16_t, uint8_t, int8_t, uint16_t, int16_t +#define WOP_SUS_H int32_t, uint16_t, int16_t, uint32_t, int32_t +#define WOP_SUS_W int64_t, uint32_t, int32_t, uint64_t, int64_t +#define WOP_SSU_B int16_t, int8_t, uint8_t, int16_t, uint16_t +#define WOP_SSU_H int32_t, int16_t, uint16_t, int32_t, uint32_t +#define WOP_SSU_W int64_t, int32_t, uint32_t, int64_t, uint64_t /* operation of two vector elements */ #define OPIVV2(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP)\ @@ -1771,3 +1783,42 @@ GEN_VEXT_VX(vrem_vx_b, 1, 1, clearb) GEN_VEXT_VX(vrem_vx_h, 2, 2, clearh) GEN_VEXT_VX(vrem_vx_w, 4, 4, clearl) GEN_VEXT_VX(vrem_vx_d, 8, 8,
[PATCH v4 13/60] target/riscv: vector single-width bit shift instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 25 target/riscv/insn32.decode | 9 +++ target/riscv/insn_trans/trans_rvv.inc.c | 44 + target/riscv/vector_helper.c| 82 + 4 files changed, 160 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 4373e9e8c2..47284c7476 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -397,3 +397,28 @@ DEF_HELPER_6(vxor_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vxor_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vxor_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vxor_vx_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vsll_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsll_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsll_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsll_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsrl_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsrl_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsrl_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsrl_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsra_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsra_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsra_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsra_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsll_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsll_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsll_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsll_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsrl_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsrl_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsrl_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsrl_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsra_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsra_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsra_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsra_vx_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 29a505cede..dbbfa34b97 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -319,6 +319,15 @@ vor_vi 001010 . . . 011 . 1010111 @r_vm vxor_vv 001011 . . . 000 . 1010111 @r_vm vxor_vx 001011 . . . 100 . 1010111 @r_vm vxor_vi 001011 . . . 011 . 1010111 @r_vm +vsll_vv 100101 . . . 000 . 1010111 @r_vm +vsll_vx 100101 . . . 100 . 1010111 @r_vm +vsll_vi 100101 . . . 011 . 1010111 @r_vm +vsrl_vv 101000 . . . 000 . 1010111 @r_vm +vsrl_vx 101000 . . . 100 . 1010111 @r_vm +vsrl_vi 101000 . . . 011 . 1010111 @r_vm +vsra_vv 101001 . . . 000 . 1010111 @r_vm +vsra_vx 101001 . . . 100 . 1010111 @r_vm +vsra_vi 101001 . . . 011 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 3a4696dbcd..a60518e1df 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1223,3 +1223,47 @@ GEN_OPIVX_GVEC_TRANS(vxor_vx, xors) GEN_OPIVI_GVEC_TRANS(vand_vi, 0, vand_vx, andi) GEN_OPIVI_GVEC_TRANS(vor_vi, 0, vor_vx, ori) GEN_OPIVI_GVEC_TRANS(vxor_vi, 0, vxor_vx, xori) + +/* Vector Single-Width Bit Shift Instructions */ +GEN_OPIVV_GVEC_TRANS(vsll_vv, shlv) +GEN_OPIVV_GVEC_TRANS(vsrl_vv, shrv) +GEN_OPIVV_GVEC_TRANS(vsra_vv, sarv) + +#define GEN_OPIVX_GVEC_SHIFT_TRANS(NAME, GVSUF) \ +static bool trans_##NAME(DisasContext *s, arg_rmrr *a)\ +{ \ +if (!opivx_check(s, a)) { \ +return false; \ +} \ + \ +if (a->vm && s->vl_eq_vlmax) {\ +TCGv_i32 src1 = tcg_temp_new_i32(); \ +TCGv tmp = tcg_temp_new();\ +gen_get_gpr(tmp, a->rs1); \ +tcg_gen_trunc_tl_i32(src1, tmp); \ +tcg_gen_gvec_##GVSUF(8 << s->sew, vreg_ofs(s, a->rd), \ +vreg_ofs(s, a->rs2), src1, MAXSZ(s),
[PATCH v4 15/60] target/riscv: vector integer comparison instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 57 +++ target/riscv/insn32.decode | 20 target/riscv/insn_trans/trans_rvv.inc.c | 66 target/riscv/vector_helper.c| 130 4 files changed, 273 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 0f36a8ce43..4e6c47c2d2 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -435,3 +435,60 @@ DEF_HELPER_6(vnsrl_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vnsra_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vnsra_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vnsra_vx_w, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vmseq_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmseq_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmseq_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmseq_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsne_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsne_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsne_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsne_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsltu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsltu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsltu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsltu_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmslt_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmslt_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmslt_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmslt_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsleu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsleu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsleu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsleu_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsle_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsle_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsle_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmsle_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vmseq_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmseq_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmseq_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmseq_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsne_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsne_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsne_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsne_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsltu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsltu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsltu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsltu_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmslt_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmslt_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmslt_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmslt_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsleu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsleu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsleu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsleu_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsle_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsle_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsle_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsle_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsgtu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsgtu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsgtu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsgtu_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsgt_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsgt_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsgt_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vmsgt_vx_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index e21b3d6b5e..525b2fa442 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -334,6 +334,26 @@ vnsrl_vi101100 . . . 011 . 1010111 @r_vm vnsra_vv101101 . . . 000 . 1010111 @r_vm vnsra_vx101101 . . . 100 . 1010111 @r_vm vnsra_vi101101 . . . 011 . 1010111 @r_vm +vmseq_vv011000 . . . 000 . 1010111 @r_vm +vmseq_vx011000 . . . 100 . 1010111 @r_vm +vmseq_vi011000 . . . 011 . 1010111 @r_vm +vmsne_vv011001 . . . 000 . 1010111 @r_vm +vmsne_vx011001 . . . 100 . 1010111 @r_vm +vmsne_vi011001 . . . 011 . 1010111
[PATCH v4 32/60] target/riscv: vector widening floating-point multiply
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 5 + target/riscv/insn32.decode | 2 ++ target/riscv/insn_trans/trans_rvv.inc.c | 4 target/riscv/vector_helper.c| 22 ++ 4 files changed, 33 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index a2d7ed19a8..3ec2dcadd4 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -834,3 +834,8 @@ DEF_HELPER_6(vfdiv_vf_d, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfrdiv_vf_h, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfrdiv_vf_w, void, ptr, ptr, i64, ptr, env, i32) DEF_HELPER_6(vfrdiv_vf_d, void, ptr, ptr, i64, ptr, env, i32) + +DEF_HELPER_6(vfwmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vfwmul_vf_h, void, ptr, ptr, i64, ptr, env, i32) +DEF_HELPER_6(vfwmul_vf_w, void, ptr, ptr, i64, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 050b2fd467..e0ee8f5a7c 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -456,6 +456,8 @@ vfmul_vf100100 . . . 101 . 1010111 @r_vm vfdiv_vv10 . . . 001 . 1010111 @r_vm vfdiv_vf10 . . . 101 . 1010111 @r_vm vfrdiv_vf 11 . . . 101 . 1010111 @r_vm +vfwmul_vv 111000 . . . 001 . 1010111 @r_vm +vfwmul_vf 111000 . . . 101 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 8dcbff6c64..b4d3797685 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1802,3 +1802,7 @@ GEN_OPFVV_TRANS(vfdiv_vv, opfvv_check) GEN_OPFVF_TRANS(vfmul_vf, opfvf_check) GEN_OPFVF_TRANS(vfdiv_vf, opfvf_check) GEN_OPFVF_TRANS(vfrdiv_vf, opfvf_check) + +/* Vector Widening Floating-Point Multiply */ +GEN_OPFVV_WIDEN_TRANS(vfwmul_vv, opfvv_widen_check) +GEN_OPFVF_WIDEN_TRANS(vfwmul_vf) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index bd7ee4de18..8bb6ac158f 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -3154,3 +3154,25 @@ RVVCALL(OPFVF2, vfrdiv_vf_d, OP_UUU_D, H8, H8, float64_rdiv) GEN_VEXT_VF(vfrdiv_vf_h, 2, 2, clearh) GEN_VEXT_VF(vfrdiv_vf_w, 4, 4, clearl) GEN_VEXT_VF(vfrdiv_vf_d, 8, 8, clearq) + +/* Vector Widening Floating-Point Multiply */ +static uint32_t vfwmul16(uint16_t a, uint16_t b, float_status *s) +{ +return float32_mul(float16_to_float32(a, true, s), +float16_to_float32(b, true, s), s); +} + +static uint64_t vfwmul32(uint32_t a, uint32_t b, float_status *s) +{ +return float64_mul(float32_to_float64(a, s), +float32_to_float64(b, s), s); + +} +RVVCALL(OPFVV2, vfwmul_vv_h, WOP_UUU_H, H4, H2, H2, vfwmul16) +RVVCALL(OPFVV2, vfwmul_vv_w, WOP_UUU_W, H8, H4, H4, vfwmul32) +GEN_VEXT_VV_ENV(vfwmul_vv_h, 2, 4, clearl) +GEN_VEXT_VV_ENV(vfwmul_vv_w, 4, 8, clearq) +RVVCALL(OPFVF2, vfwmul_vf_h, WOP_UUU_H, H4, H2, vfwmul16) +RVVCALL(OPFVF2, vfwmul_vf_w, WOP_UUU_W, H8, H4, vfwmul32) +GEN_VEXT_VF(vfwmul_vf_h, 2, 4, clearl) +GEN_VEXT_VF(vfwmul_vf_w, 4, 8, clearq) -- 2.23.0
[PATCH v4 12/60] target/riscv: vector bitwise logical instructions
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 25 target/riscv/insn32.decode | 9 + target/riscv/insn_trans/trans_rvv.inc.c | 11 ++ target/riscv/vector_helper.c| 51 + 4 files changed, 96 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 72c733bf49..4373e9e8c2 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -372,3 +372,28 @@ DEF_HELPER_6(vmsbc_vxm_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmsbc_vxm_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmsbc_vxm_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vmsbc_vxm_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vand_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vand_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vand_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vand_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vor_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vor_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vor_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vor_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vxor_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vxor_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vxor_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vxor_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vand_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vand_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vand_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vand_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vor_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vor_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vor_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vor_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vxor_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vxor_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vxor_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vxor_vx_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index e8ddf95d3d..29a505cede 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -310,6 +310,15 @@ vsbc_vvm010010 1 . . 000 . 1010111 @r vsbc_vxm010010 1 . . 100 . 1010111 @r vmsbc_vvm 010011 1 . . 000 . 1010111 @r vmsbc_vxm 010011 1 . . 100 . 1010111 @r +vand_vv 001001 . . . 000 . 1010111 @r_vm +vand_vx 001001 . . . 100 . 1010111 @r_vm +vand_vi 001001 . . . 011 . 1010111 @r_vm +vor_vv 001010 . . . 000 . 1010111 @r_vm +vor_vx 001010 . . . 100 . 1010111 @r_vm +vor_vi 001010 . . . 011 . 1010111 @r_vm +vxor_vv 001011 . . . 000 . 1010111 @r_vm +vxor_vx 001011 . . . 100 . 1010111 @r_vm +vxor_vi 001011 . . . 011 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index a1f2e84eb8..3a4696dbcd 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1212,3 +1212,14 @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \ } GEN_OPIVI_R_TRANS(vadc_vim, 0, vadc_vxm, opivx_vadc_check) GEN_OPIVI_R_TRANS(vmadc_vim, 0, vmadc_vxm, opivx_vmadc_check) + +/* Vector Bitwise Logical Instructions */ +GEN_OPIVV_GVEC_TRANS(vand_vv, and) +GEN_OPIVV_GVEC_TRANS(vor_vv, or) +GEN_OPIVV_GVEC_TRANS(vxor_vv, xor) +GEN_OPIVX_GVEC_TRANS(vand_vx, ands) +GEN_OPIVX_GVEC_TRANS(vor_vx, ors) +GEN_OPIVX_GVEC_TRANS(vxor_vx, xors) +GEN_OPIVI_GVEC_TRANS(vand_vi, 0, vand_vx, andi) +GEN_OPIVI_GVEC_TRANS(vor_vi, 0, vor_vx, ori) +GEN_OPIVI_GVEC_TRANS(vxor_vi, 0, vxor_vx, xori) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index dd85b94fe7..532b373f99 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -1202,3 +1202,54 @@ GEN_VEXT_VMADC_VXM(vmsbc_vxm_b, uint8_t, H1, DO_MSBC) GEN_VEXT_VMADC_VXM(vmsbc_vxm_h, uint16_t, H2, DO_MSBC) GEN_VEXT_VMADC_VXM(vmsbc_vxm_w, uint32_t, H4, DO_MSBC) GEN_VEXT_VMADC_VXM(vmsbc_vxm_d, uint64_t, H8, DO_MSBC) + +/* Vector Bitwise Logical Instructions */ +RVVCALL(OPIVV2, vand_vv_b, OP_SSS_B, H1, H1, H1, DO_AND) +RVVCALL(OPIVV2, vand_vv_h, OP_SSS_H, H2, H2, H2, DO_AND) +RVVCALL(OPIVV2, vand_vv_w, OP_SSS_W, H4, H4, H4, DO_AND) +RVVCALL(OPIVV2, vand_vv_d, OP_SSS_D, H8, H8, H8, DO_AND) +RVVCALL(OPIVV2, vor_vv_b, OP_SSS_B, H1, H1, H1, DO_OR) +RVVCALL(OPIVV2, vor_vv_h, OP_SSS_H, H2, H2, H2, DO_OR) +RVVCALL(OPIVV2, vor_vv_w, OP_SSS_W, H4, H4, H4,
[PATCH v4 10/60] target/riscv: vector widening integer add and subtract
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 49 target/riscv/insn32.decode | 16 +++ target/riscv/insn_trans/trans_rvv.inc.c | 154 target/riscv/vector_helper.c| 112 + 4 files changed, 331 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index e73701d4bb..1256defb6c 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -290,3 +290,52 @@ DEF_HELPER_6(vrsub_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vrsub_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vrsub_vx_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vrsub_vx_d, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vwaddu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwaddu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwaddu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsubu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsubu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsubu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsub_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwaddu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwaddu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwaddu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsubu_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsubu_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsubu_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwadd_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwadd_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwadd_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsub_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsub_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsub_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwaddu_wv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwaddu_wv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwaddu_wv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsubu_wv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsubu_wv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsubu_wv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwadd_wv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwadd_wv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwadd_wv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsub_wv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsub_wv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwsub_wv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vwaddu_wx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwaddu_wx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwaddu_wx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsubu_wx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsubu_wx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsubu_wx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwadd_wx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwadd_wx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwadd_wx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsub_wx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsub_wx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vwsub_wx_w, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index d1034a0e61..4bdbfd16fa 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -284,6 +284,22 @@ vsub_vv 10 . . . 000 . 1010111 @r_vm vsub_vx 10 . . . 100 . 1010111 @r_vm vrsub_vx11 . . . 100 . 1010111 @r_vm vrsub_vi11 . . . 011 . 1010111 @r_vm +vwaddu_vv 11 . . . 010 . 1010111 @r_vm +vwaddu_vx 11 . . . 110 . 1010111 @r_vm +vwadd_vv110001 . . . 010 . 1010111 @r_vm +vwadd_vx110001 . . . 110 . 1010111 @r_vm +vwsubu_vv 110010 . . . 010 . 1010111 @r_vm +vwsubu_vx 110010 . . . 110 . 1010111 @r_vm +vwsub_vv110011 . . . 010 . 1010111 @r_vm +vwsub_vx110011 . . . 110 . 1010111 @r_vm +vwaddu_wv 110100 . . . 010 . 1010111 @r_vm +vwaddu_wx 110100 . . . 110 . 1010111 @r_vm +vwadd_wv110101 . . . 010 . 1010111 @r_vm +vwadd_wx110101 . . . 110 . 1010111 @r_vm +vwsubu_wv 110110 . . . 010 . 1010111 @r_vm +vwsubu_wx 110110 . . . 110 .
[PATCH v4 08/60] target/riscv: add vector amo operations
Vector AMOs operate as if aq and rl bits were zero on each element with regard to ordering relative to other instructions in the same hart. Vector AMOs provide no ordering guarantee between element operations in the same vector AMO instruction Signed-off-by: LIU Zhiwei --- target/riscv/cpu.h | 1 + target/riscv/helper.h | 29 + target/riscv/insn32-64.decode | 11 ++ target/riscv/insn32.decode | 13 +++ target/riscv/insn_trans/trans_rvv.inc.c | 130 + target/riscv/vector_helper.c| 143 6 files changed, 327 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index a6761f3838..6fcaa5bc89 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -374,6 +374,7 @@ FIELD(VDATA, MLEN, 0, 8) FIELD(VDATA, VM, 8, 1) FIELD(VDATA, LMUL, 9, 2) FIELD(VDATA, NF, 11, 4) +FIELD(VDATA, WD, 11, 1) FIELD(TB_FLAGS, VL_EQ_VLMAX, 2, 1) FIELD(TB_FLAGS, LMUL, 3, 2) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 72ba4d9bdb..70a4b05f75 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -240,3 +240,32 @@ DEF_HELPER_5(vlhuff_v_w, void, ptr, ptr, tl, env, i32) DEF_HELPER_5(vlhuff_v_d, void, ptr, ptr, tl, env, i32) DEF_HELPER_5(vlwuff_v_w, void, ptr, ptr, tl, env, i32) DEF_HELPER_5(vlwuff_v_d, void, ptr, ptr, tl, env, i32) +#ifdef TARGET_RISCV64 +DEF_HELPER_6(vamoswapw_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamoswapd_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamoaddw_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamoaddd_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamoxorw_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamoxord_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamoandw_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamoandd_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamoorw_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamoord_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamominw_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamomind_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamomaxw_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamomaxd_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamominuw_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamominud_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamomaxuw_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamomaxud_v_d, void, ptr, ptr, tl, ptr, env, i32) +#endif +DEF_HELPER_6(vamoswapw_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamoaddw_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamoxorw_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamoandw_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamoorw_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamominw_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamomaxw_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamominuw_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vamomaxuw_v_w, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode index 380bf791bc..86153d93fa 100644 --- a/target/riscv/insn32-64.decode +++ b/target/riscv/insn32-64.decode @@ -57,6 +57,17 @@ amomax_d 10100 . . . . 011 . 010 @atom_st amominu_d 11000 . . . . 011 . 010 @atom_st amomaxu_d 11100 . . . . 011 . 010 @atom_st +#*** Vector AMO operations (in addition to Zvamo) *** +vamoswapd_v 1 . . . . 111 . 010 @r_wdvm +vamoaddd_v 0 . . . . 111 . 010 @r_wdvm +vamoxord_v 00100 . . . . 111 . 010 @r_wdvm +vamoandd_v 01100 . . . . 111 . 010 @r_wdvm +vamoord_v 01000 . . . . 111 . 010 @r_wdvm +vamomind_v 1 . . . . 111 . 010 @r_wdvm +vamomaxd_v 10100 . . . . 111 . 010 @r_wdvm +vamominud_v 11000 . . . . 111 . 010 @r_wdvm +vamomaxud_v 11100 . . . . 111 . 010 @r_wdvm + # *** RV64F Standard Extension (in addition to RV32F) *** fcvt_l_s 110 00010 . ... . 1010011 @r2_rm fcvt_lu_s 110 00011 . ... . 1010011 @r2_rm diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index b76c09c8c0..1330703720 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -44,6 +44,7 @@ imm rd shamt rs1 rd aq rl rs2 rs1 rd + vm wd rd rs1 rs2 vm rd rs1 nf vm rd rs1 rs2 nf @@ -67,6 +68,7 @@ @r2 ... . . ... . ... %rs1 %rd @r2_nfvm ... ... vm:1 . . ... . ... %nf %rs1 %rd @r_nfvm ... ... vm:1 . . ... . ... %nf %rs2 %rs1 %rd +@r_wdvm . wd:1 vm:1 . . ... . ... %rs2 %rs1 %rd @r2_zimm . zimm:11 . ... .
[PATCH v4 02/60] target/riscv: implementation-defined constant parameters
vlen is the vector register length in bits. elen is the max element size in bits. vext_spec is the vector specification version, default value is v0.7.1. Signed-off-by: LIU Zhiwei Reviewed-by: Alistair Francis Reviewed-by: Richard Henderson --- target/riscv/cpu.c | 7 +++ target/riscv/cpu.h | 5 + 2 files changed, 12 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index c0b7023100..6e4135583d 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -106,6 +106,11 @@ static void set_priv_version(CPURISCVState *env, int priv_ver) env->priv_ver = priv_ver; } +static void set_vext_version(CPURISCVState *env, int vext_ver) +{ +env->vext_ver = vext_ver; +} + static void set_feature(CPURISCVState *env, int feature) { env->features |= (1ULL << feature); @@ -364,6 +369,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) CPURISCVState *env = >env; RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev); int priv_version = PRIV_VERSION_1_11_0; +int vext_version = VEXT_VERSION_0_07_1; target_ulong target_misa = 0; Error *local_err = NULL; @@ -389,6 +395,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) } set_priv_version(env, priv_version); +set_vext_version(env, vext_version); set_resetvec(env, DEFAULT_RSTVEC); if (cpu->cfg.mmu) { diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 0c1f7bdd8b..603715f849 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -84,6 +84,8 @@ enum { #define PRIV_VERSION_1_10_0 0x00011000 #define PRIV_VERSION_1_11_0 0x00011100 +#define VEXT_VERSION_0_07_1 0x0701 + #define TRANSLATE_PMP_FAIL 2 #define TRANSLATE_FAIL 1 #define TRANSLATE_SUCCESS 0 @@ -119,6 +121,7 @@ struct CPURISCVState { target_ulong guest_phys_fault_addr; target_ulong priv_ver; +target_ulong vext_ver; target_ulong misa; target_ulong misa_mask; @@ -281,6 +284,8 @@ typedef struct RISCVCPU { char *priv_spec; char *user_spec; +uint16_t vlen; +uint16_t elen; bool mmu; bool pmp; } cfg; -- 2.23.0
[PATCH v4 06/60] target/riscv: add vector index load and store instructions
Vector indexed operations add the contents of each element of the vector offset operand specified by vs2 to the base effective address to give the effective address of each element. Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 35 +++ target/riscv/insn32.decode | 13 +++ target/riscv/insn_trans/trans_rvv.inc.c | 124 target/riscv/vector_helper.c| 117 ++ 4 files changed, 289 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 87dfa90609..f9b3da60ca 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -183,3 +183,38 @@ DEF_HELPER_6(vsse_v_b, void, ptr, ptr, tl, tl, env, i32) DEF_HELPER_6(vsse_v_h, void, ptr, ptr, tl, tl, env, i32) DEF_HELPER_6(vsse_v_w, void, ptr, ptr, tl, tl, env, i32) DEF_HELPER_6(vsse_v_d, void, ptr, ptr, tl, tl, env, i32) +DEF_HELPER_6(vlxb_v_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxb_v_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxb_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxb_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxh_v_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxh_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxh_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxw_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxw_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxe_v_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxe_v_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxe_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxe_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxbu_v_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxbu_v_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxbu_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxbu_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxhu_v_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxhu_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxhu_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxwu_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vlxwu_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsxb_v_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsxb_v_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsxb_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsxb_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsxh_v_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsxh_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsxh_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsxw_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsxw_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsxe_v_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsxe_v_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsxe_v_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsxe_v_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index ef521152c5..bc36df33b5 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -241,6 +241,19 @@ vssh_v ... 010 . . . 101 . 0100111 @r_nfvm vssw_v ... 010 . . . 110 . 0100111 @r_nfvm vsse_v ... 010 . . . 111 . 0100111 @r_nfvm +vlxb_v ... 111 . . . 000 . 111 @r_nfvm +vlxh_v ... 111 . . . 101 . 111 @r_nfvm +vlxw_v ... 111 . . . 110 . 111 @r_nfvm +vlxe_v ... 011 . . . 111 . 111 @r_nfvm +vlxbu_v... 011 . . . 000 . 111 @r_nfvm +vlxhu_v... 011 . . . 101 . 111 @r_nfvm +vlxwu_v... 011 . . . 110 . 111 @r_nfvm +# Vector ordered-indexed and unordered-indexed store insns. +vsxb_v ... -11 . . . 000 . 0100111 @r_nfvm +vsxh_v ... -11 . . . 101 . 0100111 @r_nfvm +vsxw_v ... -11 . . . 110 . 0100111 @r_nfvm +vsxe_v ... -11 . . . 111 . 0100111 @r_nfvm + # *** new major opcode OP-V *** vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index d85f2aec68..5d1eeef323 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -407,3 +407,127 @@ GEN_VEXT_TRANS(vssb_v, 0, rnfvm, st_stride_op, st_stride_check) GEN_VEXT_TRANS(vssh_v, 1, rnfvm, st_stride_op, st_stride_check) GEN_VEXT_TRANS(vssw_v, 2, rnfvm, st_stride_op, st_stride_check) GEN_VEXT_TRANS(vsse_v, 3, rnfvm, st_stride_op, st_stride_check) + +/* + *** index load and store + */ +typedef void gen_helper_ldst_index(TCGv_ptr, TCGv_ptr, TCGv, +TCGv_ptr, TCGv_env, TCGv_i32); + +static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, +uint32_t data, gen_helper_ldst_index *fn,
[PATCH v4 01/60] target/riscv: add vector extension field in CPURISCVState
The 32 vector registers will be viewed as a continuous memory block. It avoids the convension between element index and (regno, offset). Thus elements can be directly accessed by offset from the first vector base address. Signed-off-by: LIU Zhiwei Acked-by: Alistair Francis Reviewed-by: Richard Henderson --- target/riscv/cpu.h | 12 1 file changed, 12 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 3dcdf92227..0c1f7bdd8b 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -64,6 +64,7 @@ #define RVA RV('A') #define RVF RV('F') #define RVD RV('D') +#define RVV RV('V') #define RVC RV('C') #define RVS RV('S') #define RVU RV('U') @@ -94,9 +95,20 @@ typedef struct CPURISCVState CPURISCVState; #include "pmp.h" +#define RV_VLEN_MAX 512 + struct CPURISCVState { target_ulong gpr[32]; uint64_t fpr[32]; /* assume both F and D extensions */ + +/* vector coprocessor state. */ +uint64_t vreg[32 * RV_VLEN_MAX / 64] QEMU_ALIGNED(16); +target_ulong vxrm; +target_ulong vxsat; +target_ulong vl; +target_ulong vstart; +target_ulong vtype; + target_ulong pc; target_ulong load_res; target_ulong load_val; -- 2.23.0
[PATCH v4 05/60] target/riscv: add vector stride load and store instructions
Vector strided operations access the first memory element at the base address, and then access subsequent elements at address increments given by the byte offset contained in the x register specified by rs2. Vector unit-stride operations access elements stored contiguously in memory starting from the base effective address. It can been seen as a special case of strided operations. Signed-off-by: LIU Zhiwei --- target/riscv/cpu.h | 6 + target/riscv/helper.h | 105 ++ target/riscv/insn32.decode | 32 ++ target/riscv/insn_trans/trans_rvv.inc.c | 340 target/riscv/translate.c| 7 + target/riscv/vector_helper.c| 406 6 files changed, 896 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 11fc573168..a6761f3838 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -369,6 +369,12 @@ typedef CPURISCVState CPUArchState; typedef RISCVCPU ArchCPU; #include "exec/cpu-all.h" +/* share data between vector helpers and decode code */ +FIELD(VDATA, MLEN, 0, 8) +FIELD(VDATA, VM, 8, 1) +FIELD(VDATA, LMUL, 9, 2) +FIELD(VDATA, NF, 11, 4) + FIELD(TB_FLAGS, VL_EQ_VLMAX, 2, 1) FIELD(TB_FLAGS, LMUL, 3, 2) FIELD(TB_FLAGS, SEW, 5, 3) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 3c28c7e407..87dfa90609 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -78,3 +78,108 @@ DEF_HELPER_1(tlb_flush, void, env) #endif /* Vector functions */ DEF_HELPER_3(vsetvl, tl, env, tl, tl) +DEF_HELPER_5(vlb_v_b, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlb_v_b_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlb_v_h, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlb_v_h_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlb_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlb_v_w_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlb_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlb_v_d_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlh_v_h, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlh_v_h_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlh_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlh_v_w_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlh_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlh_v_d_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlw_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlw_v_w_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlw_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlw_v_d_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vle_v_b, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vle_v_b_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vle_v_h, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vle_v_h_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vle_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vle_v_w_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vle_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vle_v_d_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbu_v_b, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbu_v_b_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbu_v_h, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbu_v_h_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbu_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbu_v_w_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbu_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbu_v_d_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlhu_v_h, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlhu_v_h_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlhu_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlhu_v_w_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlhu_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlhu_v_d_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlwu_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlwu_v_w_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlwu_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlwu_v_d_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsb_v_b, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsb_v_b_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsb_v_h, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsb_v_h_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsb_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsb_v_w_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsb_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsb_v_d_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsh_v_h, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsh_v_h_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsh_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsh_v_w_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsh_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsh_v_d_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsw_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsw_v_w_mask, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vsw_v_d, void, ptr, ptr, tl, env, i32)
[PATCH v4 09/60] target/riscv: vector single-width integer add and subtract
Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 21 +++ target/riscv/insn32.decode | 10 ++ target/riscv/insn_trans/trans_rvv.inc.c | 220 target/riscv/vector_helper.c| 122 + 4 files changed, 373 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 70a4b05f75..e73701d4bb 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -269,3 +269,24 @@ DEF_HELPER_6(vamominw_v_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vamomaxw_v_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vamominuw_v_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vamomaxuw_v_w, void, ptr, ptr, tl, ptr, env, i32) + +DEF_HELPER_6(vadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsub_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vadd_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vadd_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vadd_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vadd_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsub_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsub_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsub_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vsub_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vrsub_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vrsub_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vrsub_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vrsub_vx_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 1330703720..d1034a0e61 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -44,6 +44,7 @@ imm rd shamt rs1 rd aq rl rs2 rs1 rd + vm rd rs1 rs2 vm wd rd rs1 rs2 vm rd rs1 nf vm rd rs1 rs2 nf @@ -68,6 +69,7 @@ @r2 ... . . ... . ... %rs1 %rd @r2_nfvm ... ... vm:1 . . ... . ... %nf %rs1 %rd @r_nfvm ... ... vm:1 . . ... . ... %nf %rs2 %rs1 %rd +@r_vm.. vm:1 . . ... . ... %rs2 %rs1 %rd @r_wdvm . wd:1 vm:1 . . ... . ... %rs2 %rs1 %rd @r2_zimm . zimm:11 . ... . ... %rs1 %rd @@ -275,5 +277,13 @@ vamominuw_v 11000 . . . . 110 . 010 @r_wdvm vamomaxuw_v 11100 . . . . 110 . 010 @r_wdvm # *** new major opcode OP-V *** +vadd_vv 00 . . . 000 . 1010111 @r_vm +vadd_vx 00 . . . 100 . 1010111 @r_vm +vadd_vi 00 . . . 011 . 1010111 @r_vm +vsub_vv 10 . . . 000 . 1010111 @r_vm +vsub_vx 10 . . . 100 . 1010111 @r_vm +vrsub_vx11 . . . 100 . 1010111 @r_vm +vrsub_vi11 . . . 011 . 1010111 @r_vm + vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 3c677160c5..00c7ec976f 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -730,3 +730,223 @@ GEN_VEXT_TRANS(vamomaxd_v, 15, rwdvm, amo_op, amo_check) GEN_VEXT_TRANS(vamominud_v, 16, rwdvm, amo_op, amo_check) GEN_VEXT_TRANS(vamomaxud_v, 17, rwdvm, amo_op, amo_check) #endif + +/* + *** Vector Integer Arithmetic Instructions + */ +#define MAXSZ(s) (s->vlen >> (3 - s->lmul)) + +static bool opivv_check(DisasContext *s, arg_rmrr *a) +{ +return (vext_check_isa_ill(s, RVV) && +vext_check_overlap_mask(s, a->rd, a->vm, false) && +vext_check_reg(s, a->rd, false) && +vext_check_reg(s, a->rs2, false) && +vext_check_reg(s, a->rs1, false)); +} + +/* OPIVV with GVEC IR */ +#define GEN_OPIVV_GVEC_TRANS(NAME, GVSUF) \ +static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ +{ \ +if (!opivv_check(s, a)) { \ +return false; \ +} \ + \ +if (a->vm && s->vl_eq_vlmax) { \ +tcg_gen_gvec_##GVSUF(8 << s->sew, vreg_ofs(s, a->rd), \ +vreg_ofs(s, a->rs2), vreg_ofs(s, a->rs1),
[PATCH v4 04/60] target/riscv: add vector configure instruction
vsetvl and vsetvli are two configure instructions for vl, vtype. TB flags should update after configure instructions. The (ill, lmul, sew ) of vtype and the bit of (VSTART == 0 && VL == VLMAX) will be placed within tb_flags. Signed-off-by: LIU Zhiwei --- target/riscv/Makefile.objs | 2 +- target/riscv/cpu.h | 63 ++ target/riscv/helper.h | 2 + target/riscv/insn32.decode | 5 ++ target/riscv/insn_trans/trans_rvv.inc.c | 69 + target/riscv/translate.c| 17 +- target/riscv/vector_helper.c| 53 +++ 7 files changed, 199 insertions(+), 12 deletions(-) create mode 100644 target/riscv/insn_trans/trans_rvv.inc.c create mode 100644 target/riscv/vector_helper.c diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs index ff651f69f6..ff38df6219 100644 --- a/target/riscv/Makefile.objs +++ b/target/riscv/Makefile.objs @@ -1,4 +1,4 @@ -obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o gdbstub.o +obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o vector_helper.o gdbstub.o obj-$(CONFIG_SOFTMMU) += pmp.o ifeq ($(CONFIG_SOFTMMU),y) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 603715f849..11fc573168 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -21,6 +21,7 @@ #define RISCV_CPU_H #include "hw/core/cpu.h" +#include "hw/registerfields.h" #include "exec/cpu-defs.h" #include "fpu/softfloat-types.h" @@ -99,6 +100,12 @@ typedef struct CPURISCVState CPURISCVState; #define RV_VLEN_MAX 512 +FIELD(VTYPE, VLMUL, 0, 2) +FIELD(VTYPE, VSEW, 2, 3) +FIELD(VTYPE, VEDIV, 5, 2) +FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9) +FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 2, 1) + struct CPURISCVState { target_ulong gpr[32]; uint64_t fpr[32]; /* assume both F and D extensions */ @@ -358,19 +365,62 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong); #define TB_FLAGS_MMU_MASK 3 #define TB_FLAGS_MSTATUS_FS MSTATUS_FS +typedef CPURISCVState CPUArchState; +typedef RISCVCPU ArchCPU; +#include "exec/cpu-all.h" + +FIELD(TB_FLAGS, VL_EQ_VLMAX, 2, 1) +FIELD(TB_FLAGS, LMUL, 3, 2) +FIELD(TB_FLAGS, SEW, 5, 3) +FIELD(TB_FLAGS, VILL, 8, 1) + +/* + * A simplification for VLMAX + * = (1 << LMUL) * VLEN / (8 * (1 << SEW)) + * = (VLEN << LMUL) / (8 << SEW) + * = (VLEN << LMUL) >> (SEW + 3) + * = VLEN >> (SEW + 3 - LMUL) + */ +static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) +{ +uint8_t sew, lmul; + +sew = FIELD_EX64(vtype, VTYPE, VSEW); +lmul = FIELD_EX64(vtype, VTYPE, VLMUL); +return cpu->cfg.vlen >> (sew + 3 - lmul); +} + static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, -target_ulong *cs_base, uint32_t *flags) +target_ulong *cs_base, uint32_t *pflags) { +uint32_t flags = 0; + *pc = env->pc; *cs_base = 0; + +if (env->misa & RVV) { +uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype); +bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl); +flags = FIELD_DP32(flags, TB_FLAGS, VILL, +FIELD_EX64(env->vtype, VTYPE, VILL)); +flags = FIELD_DP32(flags, TB_FLAGS, SEW, +FIELD_EX64(env->vtype, VTYPE, VSEW)); +flags = FIELD_DP32(flags, TB_FLAGS, LMUL, +FIELD_EX64(env->vtype, VTYPE, VLMUL)); +flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax); +} else { +flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1); +} + #ifdef CONFIG_USER_ONLY -*flags = TB_FLAGS_MSTATUS_FS; +flags |= TB_FLAGS_MSTATUS_FS; #else -*flags = cpu_mmu_index(env, 0); +flags = cpu_mmu_index(env, 0); if (riscv_cpu_fp_enabled(env)) { -*flags |= env->mstatus & MSTATUS_FS; +flags |= env->mstatus & MSTATUS_FS; } #endif +*pflags = flags; } int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, @@ -411,9 +461,4 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops); void riscv_cpu_register_gdb_regs_for_features(CPUState *cs); -typedef CPURISCVState CPUArchState; -typedef RISCVCPU ArchCPU; - -#include "exec/cpu-all.h" - #endif /* RISCV_CPU_H */ diff --git a/target/riscv/helper.h b/target/riscv/helper.h index debb22a480..3c28c7e407 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -76,3 +76,5 @@ DEF_HELPER_2(mret, tl, env, tl) DEF_HELPER_1(wfi, void, env) DEF_HELPER_1(tlb_flush, void, env) #endif +/* Vector functions */ +DEF_HELPER_3(vsetvl, tl, env, tl, tl) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index b883672e63..53340bdbc4 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -62,6 +62,7 @@ @r_rm... . . ... . ... %rs2 %rs1 %rm
[PATCH v4 03/60] target/riscv: support vector extension csr
The v0.7.1 specification does not define vector status within mstatus. A future revision will define the privileged portion of the vector status. Signed-off-by: LIU Zhiwei --- target/riscv/cpu_bits.h | 15 + target/riscv/csr.c | 75 - 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 7f64ee1174..8117e8b5a7 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -29,6 +29,14 @@ #define FSR_NXA (FPEXC_NX << FSR_AEXC_SHIFT) #define FSR_AEXC(FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA) +/* Vector Fixed-Point round model */ +#define FSR_VXRM_SHIFT 9 +#define FSR_VXRM(0x3 << FSR_VXRM_SHIFT) + +/* Vector Fixed-Point saturation flag */ +#define FSR_VXSAT_SHIFT 8 +#define FSR_VXSAT (0x1 << FSR_VXSAT_SHIFT) + /* Control and Status Registers */ /* User Trap Setup */ @@ -48,6 +56,13 @@ #define CSR_FRM 0x002 #define CSR_FCSR0x003 +/* User Vector CSRs */ +#define CSR_VSTART 0x008 +#define CSR_VXSAT 0x009 +#define CSR_VXRM0x00a +#define CSR_VL 0xc20 +#define CSR_VTYPE 0xc21 + /* User Timers and Counters */ #define CSR_CYCLE 0xc00 #define CSR_TIME0xc01 diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 11d184cd16..d71c49dfff 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -46,6 +46,10 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops) static int fs(CPURISCVState *env, int csrno) { #if !defined(CONFIG_USER_ONLY) +/* loose check condition for fcsr in vector extension */ +if ((csrno == CSR_FCSR) && (env->misa & RVV)) { +return 0; +} if (!env->debugger && !riscv_cpu_fp_enabled(env)) { return -1; } @@ -53,6 +57,14 @@ static int fs(CPURISCVState *env, int csrno) return 0; } +static int vs(CPURISCVState *env, int csrno) +{ +if (env->misa & RVV) { +return 0; +} +return -1; +} + static int ctr(CPURISCVState *env, int csrno) { #if !defined(CONFIG_USER_ONLY) @@ -174,6 +186,10 @@ static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val) #endif *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT) | (env->frm << FSR_RD_SHIFT); +if (vs(env, csrno) >= 0) { +*val |= (env->vxrm << FSR_VXRM_SHIFT) +| (env->vxsat << FSR_VXSAT_SHIFT); +} return 0; } @@ -186,10 +202,62 @@ static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val) env->mstatus |= MSTATUS_FS; #endif env->frm = (val & FSR_RD) >> FSR_RD_SHIFT; +if (vs(env, csrno) >= 0) { +env->vxrm = (val & FSR_VXRM) >> FSR_VXRM_SHIFT; +env->vxsat = (val & FSR_VXSAT) >> FSR_VXSAT_SHIFT; +} riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT); return 0; } +static int read_vtype(CPURISCVState *env, int csrno, target_ulong *val) +{ +*val = env->vtype; +return 0; +} + +static int read_vl(CPURISCVState *env, int csrno, target_ulong *val) +{ +*val = env->vl; +return 0; +} + +static int read_vxrm(CPURISCVState *env, int csrno, target_ulong *val) +{ +*val = env->vxrm; +return 0; +} + +static int write_vxrm(CPURISCVState *env, int csrno, target_ulong val) +{ +env->vxrm = val; +return 0; +} + +static int read_vxsat(CPURISCVState *env, int csrno, target_ulong *val) +{ +*val = env->vxsat; +return 0; +} + +static int write_vxsat(CPURISCVState *env, int csrno, target_ulong val) +{ +env->vxsat = val; +return 0; +} + +static int read_vstart(CPURISCVState *env, int csrno, target_ulong *val) +{ +*val = env->vstart; +return 0; +} + +static int write_vstart(CPURISCVState *env, int csrno, target_ulong val) +{ +env->vstart = val; +return 0; +} + /* User Timers and Counters */ static int read_instret(CPURISCVState *env, int csrno, target_ulong *val) { @@ -1269,7 +1337,12 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_FFLAGS] = { fs, read_fflags, write_fflags }, [CSR_FRM] = { fs, read_frm, write_frm }, [CSR_FCSR] ={ fs, read_fcsr,write_fcsr}, - +/* Vector CSRs */ +[CSR_VSTART] = { vs, read_vstart, write_vstart }, +[CSR_VXSAT] = { vs, read_vxsat, write_vxsat }, +[CSR_VXRM] ={ vs, read_vxrm,write_vxrm}, +[CSR_VL] = { vs, read_vl }, +[CSR_VTYPE] = { vs, read_vtype }, /* User Timers and Counters */ [CSR_CYCLE] = { ctr, read_instret}, [CSR_INSTRET] = { ctr, read_instret}, -- 2.23.0
[PATCH v4 00/60] target/riscv: support vector extension v0.7.1
This patchset implements the vector extension for RISC-V on QEMU. You can also find the patchset and all *test cases* in my repo(https://github.com/romanheros/qemu.git branch:vector-upstream-v3). All the test cases are in the directory qemu/tests/riscv/vector/. They are riscv64 linux user mode programs. You can test the patchset by the script qemu/tests/riscv/vector/runcase.sh. Features: * support specification riscv-v-spec-0.7.1.(https://github.com/riscv/riscv-v-spec/releases/tag/0.7.1/) * support basic vector extension. * support Zvlsseg. * support Zvamo. * not support Zvediv as it is changing. * SLEN always equals VLEN. * element width support 8bit, 16bit, 32bit, 64bit. Changelog: v4 * no change v3 * move check code from execution-time to translation-time * use a continous memory block for vector register description. * vector registers as direct fields in RISCVCPUState. * support VLEN configure from qemu command line. * support ELEN configure from qemu command line. * support vector specification version configure from qemu command line. * probe pages before real load or store access. * use probe_page_check for no-fault operations in linux user mode. * generation atomic exit exception when in parallel environment. * fixup a lot of concrete bugs. V2 * use float16_compare{_quiet} * only use GETPC() in outer most helper * add ctx.ext_v Property LIU Zhiwei (60): target/riscv: add vector extension field in CPURISCVState target/riscv: implementation-defined constant parameters target/riscv: support vector extension csr target/riscv: add vector configure instruction target/riscv: add vector stride load and store instructions target/riscv: add vector index load and store instructions target/riscv: add fault-only-first unit stride load target/riscv: add vector amo operations target/riscv: vector single-width integer add and subtract target/riscv: vector widening integer add and subtract target/riscv: vector integer add-with-carry / subtract-with-borrow instructions target/riscv: vector bitwise logical instructions target/riscv: vector single-width bit shift instructions target/riscv: vector narrowing integer right shift instructions target/riscv: vector integer comparison instructions target/riscv: vector integer min/max instructions target/riscv: vector single-width integer multiply instructions target/riscv: vector integer divide instructions target/riscv: vector widening integer multiply instructions target/riscv: vector single-width integer multiply-add instructions target/riscv: vector widening integer multiply-add instructions target/riscv: vector integer merge and move instructions target/riscv: vector single-width saturating add and subtract target/riscv: vector single-width averaging add and subtract target/riscv: vector single-width fractional multiply with rounding and saturation target/riscv: vector widening saturating scaled multiply-add target/riscv: vector single-width scaling shift instructions target/riscv: vector narrowing fixed-point clip instructions target/riscv: vector single-width floating-point add/subtract instructions target/riscv: vector widening floating-point add/subtract instructions target/riscv: vector single-width floating-point multiply/divide instructions target/riscv: vector widening floating-point multiply target/riscv: vector single-width floating-point fused multiply-add instructions target/riscv: vector widening floating-point fused multiply-add instructions target/riscv: vector floating-point square-root instruction target/riscv: vector floating-point min/max instructions target/riscv: vector floating-point sign-injection instructions target/riscv: vector floating-point compare instructions target/riscv: vector floating-point classify instructions target/riscv: vector floating-point merge instructions target/riscv: vector floating-point/integer type-convert instructions target/riscv: widening floating-point/integer type-convert instructions target/riscv: narrowing floating-point/integer type-convert instructions target/riscv: vector single-width integer reduction instructions target/riscv: vector wideing integer reduction instructions target/riscv: vector single-width floating-point reduction instructions target/riscv: vector widening floating-point reduction instructions target/riscv: vector mask-register logical instructions target/riscv: vector mask population count vmpopc target/riscv: vmfirst find-first-set mask bit target/riscv: set-X-first mask bit target/riscv: vector iota instruction target/riscv: vector element index instruction target/riscv: integer extract instruction target/riscv: integer scalar move instruction target/riscv: floating-point scalar move instructions target/riscv: vector slide instructions target/riscv: vector register gather instruction
[PATCH v4 07/60] target/riscv: add fault-only-first unit stride load
The unit-stride fault-only-fault load instructions are used to vectorize loops with data-dependent exit conditions(while loops). These instructions execute as a regular load except that they will only take a trap on element 0. Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 22 + target/riscv/insn32.decode | 7 ++ target/riscv/insn_trans/trans_rvv.inc.c | 69 +++ target/riscv/vector_helper.c| 111 4 files changed, 209 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index f9b3da60ca..72ba4d9bdb 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -218,3 +218,25 @@ DEF_HELPER_6(vsxe_v_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vsxe_v_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vsxe_v_w, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vsxe_v_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_5(vlbff_v_b, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbff_v_h, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbff_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbff_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlhff_v_h, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlhff_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlhff_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlwff_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlwff_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vleff_v_b, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vleff_v_h, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vleff_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vleff_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbuff_v_b, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbuff_v_h, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbuff_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlbuff_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlhuff_v_h, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlhuff_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlhuff_v_d, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlwuff_v_w, void, ptr, ptr, tl, env, i32) +DEF_HELPER_5(vlwuff_v_d, void, ptr, ptr, tl, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index bc36df33b5..b76c09c8c0 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -224,6 +224,13 @@ vle_v ... 000 . 0 . 111 . 111 @r2_nfvm vlbu_v ... 000 . 0 . 000 . 111 @r2_nfvm vlhu_v ... 000 . 0 . 101 . 111 @r2_nfvm vlwu_v ... 000 . 0 . 110 . 111 @r2_nfvm +vlbff_v... 100 . 1 . 000 . 111 @r2_nfvm +vlhff_v... 100 . 1 . 101 . 111 @r2_nfvm +vlwff_v... 100 . 1 . 110 . 111 @r2_nfvm +vleff_v... 000 . 1 . 111 . 111 @r2_nfvm +vlbuff_v ... 000 . 1 . 000 . 111 @r2_nfvm +vlhuff_v ... 000 . 1 . 101 . 111 @r2_nfvm +vlwuff_v ... 000 . 1 . 110 . 111 @r2_nfvm vsb_v ... 000 . 0 . 000 . 0100111 @r2_nfvm vsh_v ... 000 . 0 . 101 . 0100111 @r2_nfvm vsw_v ... 000 . 0 . 110 . 0100111 @r2_nfvm diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 5d1eeef323..9d9fc886d6 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -531,3 +531,72 @@ GEN_VEXT_TRANS(vsxb_v, 0, rnfvm, st_index_op, st_index_check) GEN_VEXT_TRANS(vsxh_v, 1, rnfvm, st_index_op, st_index_check) GEN_VEXT_TRANS(vsxw_v, 2, rnfvm, st_index_op, st_index_check) GEN_VEXT_TRANS(vsxe_v, 3, rnfvm, st_index_op, st_index_check) + +/* + *** unit stride fault-only-first load + */ +static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data, +gen_helper_ldst_us *fn, DisasContext *s) +{ +TCGv_ptr dest, mask; +TCGv base; +TCGv_i32 desc; + +dest = tcg_temp_new_ptr(); +mask = tcg_temp_new_ptr(); +base = tcg_temp_new(); +desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data)); + +gen_get_gpr(base, rs1); +tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd)); +tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0)); + +fn(dest, mask, base, cpu_env, desc); + +tcg_temp_free_ptr(dest); +tcg_temp_free_ptr(mask); +tcg_temp_free(base); +tcg_temp_free_i32(desc); +return true; +} + +static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq) +{ +uint32_t data = 0; +gen_helper_ldst_us *fn; +static gen_helper_ldst_us * const fns[7][4] = { +{ gen_helper_vlbff_v_b, gen_helper_vlbff_v_h, + gen_helper_vlbff_v_w, gen_helper_vlbff_v_d }, +{ NULL, gen_helper_vlhff_v_h, + gen_helper_vlhff_v_w, gen_helper_vlhff_v_d }, +{ NULL, NULL, + gen_helper_vlwff_v_w, gen_helper_vlwff_v_d }, +{ gen_helper_vleff_v_b, gen_helper_vleff_v_h, +
Re: Program counter stuck at 0xFFFFFFFC when emulating e5500 processor on T4240-RDB board
On Thu, Feb 20, 2020 at 09:44:13AM +0100, Philippe Mathieu-Daudé wrote: > Hello, > > On 2/20/20 6:40 AM, Wayne Li wrote: > > Dear QEMU list members, > > No subject: it is unlikely your question get noticed... > > Also you didn't Cc'ed the people who might help you (doing that for you): > > ./scripts/get_maintainer.pl -f target/ppc/cpu-models.c > David Gibson (maintainer:PowerPC TCG CPUs) > qemu-...@nongnu.org (open list:PowerPC TCG CPUs) > qemu-devel@nongnu.org (open list:All patches CC here) Right. Unfortunately the embedded cpu support is barely maintained, so there's only a little bit of help I can give. > > This will kind of be a repost but I'd like to post my question again > > because I've gained some more knowledge that makes me feel that my > > question would be easier to answer. So we developed a custom-made QEMU > > VM that emulates a custom machine that has an e5500 processor. I'm > > running this VM on a T4240-RDB board which has an e6500 processor and > > I'm trying to get the VM running with KVM enabled. The problem I'm > > having is the program counter refuses to increment at all. It just > > stays at the address 0xFFFC. On a run without KVM enabled, the VM > > will also start executing at this same address but the program counter > > beings to increment immediately. I know this is a custom QEMU VM and > > maybe some of the startup stuff we do could be causing problems, but > > what could possibly stop the program counter from incrementing > > altogether? > > > > Also, I do have another side question. When running with KVM enabled, I > > see the kernel-level ioctl call KVM_RUN running and then returning over > > and over again (by the way before the VM kinda grinds to a halt I only > > see QEMU make the KVM_RUN call twice, but the kernel-level ioctl > > function is being called over and over again for some reason). And each > > time the KVM_RUN call returns, the return-from-interrupt takes the VM to > > the address 0xFFFC. What is the KVM_RUN ioctl call used for? Why > > is it being called over and over again? Maybe if I understood this > > better I'd be able to figure out what's stopping my program counter from > > incrementing. I don't really know if KVM even attempts to support e5500 cpus. We'd need to at least know what your host kernel is and what KVM variant it is using. What's the instruction at 0xfffc which seems not to be handled here properly? It sounds like you might be getting some sort of rolling trap, because KVM isn't handling that instruction correctly. The KVM_RUN is what causes KVM to actual enter the guest and execute instructions. It returns when something triggers a guest exit - a trap or various other events can do this. -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
Re: I am trying to fixes a issue with QEMU with VxWorks.
On Tue, Mar 10, 2020 at 08:48:49PM +0800, 罗勇刚(Yonggang Luo) wrote: > I have already debugging it. I have infinite interrupt after calling to > motTsecGracefulStop, What interrupt is it, and what instruction is triggering it? > I am simulating wrSbc834x using etsec with PPC. Unfortunately the freescale and other embedded ppc chips are only barely maintained at present - there just aren't that many people with both the interest and skills to do so. So, I'll do what I can, but you'll probably have to do most of the debugging here yourself. > ``` > Chain 0: 088bad00 [/00e0ccf0/0x2000] sysTimestamp64Set > Trace 0: 08a90940 [/00e06358/0x2000] motTsecGracefulStop > 32-bits write 0x1039 to register 0x0 > 32-bits write 0x1002 to register 0x0 > 32-bits write 0x62110180 to register 0x0 > 32-bits write 0x0935 to register 0x0 > 32-bits write 0x0937 to register 0x0 > Chain 0: 086f9c40 [/00e2b51c/0x2000] intUnlock > Stopped execution of TB chain before 086f9c40 [00e2b51c] intUnlock > Trace 0: 086f9c40 [/00e2b51c/0x2000] intUnlock > Raise exception at 00e2b52c => 0004 (00) > Trace 0: 08771f80 [/0500/0] > Chain 0: 087720c0 [/00e87280/0] excConnectCode > Chain 0: 08747cc0 [/00e7bf24/0] intEnt > Chain 0: 08748980 [/00e7c09c/0] intEnt > Trace 0: 08748b00 [/00e7c0b4/0] intEnt > Trace 0: 08748c00 [/00e7c0bc/0] intEnt > Chain 0: 08748dc0 [/00e050bc/0] timeMonitorCtxSwitchToIsr > Chain 0: 08749040 [/00e7c0cc/0] intEnt > Chain 0: 08772200 [/00e87294/0] excConnectCode > Chain 0: 08772380 [/00e00a20/0] quiccIntrDeMux > Trace 0: 08772840 [/00e00a6c/0] quiccIntrDeMux > Trace 0: 08772bc0 [/00e00f48/0] quiccIvecToInum > Chain 0: 08772ec0 [/00e00abc/0] quiccIntrDeMux > Trace 0: 08772bc0 [/00e00f48/0] quiccIvecToInum > Chain 0: 08773180 [/00e00afc/0] quiccIntrDeMux > Chain 0: 08773400 [/00e00b38/0] quiccIntrDeMux > Chain 0: 086b0ac0 [/00e2b51c/0] intUnlock > Raise exception at 00e2b52c => 000a (00) > Trace 0: 08747a40 [/0900/0] > Chain 0: 08747b80 [/00e87480/0] excConnectCode > Chain 0: 08747cc0 [/00e7bf24/0] intEnt > Chain 0: 08748980 [/00e7c09c/0] intEnt > Trace 0: 08748b00 [/00e7c0b4/0] intEnt > Trace 0: 08748c00 [/00e7c0bc/0] intEnt > Chain 0: 08748dc0 [/00e050bc/0] timeMonitorCtxSwitchToIsr > Chain 0: 08749040 [/00e7c0cc/0] intEnt > Chain 0: 08749200 [/00e87494/0] excConnectCode > Chain 0: 08749380 [/00e0c654/0] sysClkInt > Chain 0: 086a0a00 [/00e7ac78/0] vxTimeBaseGet > Chain 0: 0874a180 [/00e0cc44/0] sysTimestamp64Get > Chain 0: 0874a5c0 [/00e0c780/0] sysClkInt > Chain 0: 086b0ac0 [/00e2b51c/0] intUnlock > Trace 0: 086b0c00 [/00e2b52c/0] intUnlock > Trace 0: 086b0d00 [/00e2b530/0] intUnlock > Chain 0: 0874bdc0 [/00e0c848/0] sysClkInt > Chain 0: 0874c180 [/00e0d8d8/0] usrClock > Chain 0: 0874c3c0 [/00e6f110/0] tickAnnounce > Chain 0: 0874c9c0 [/00e7d0f8/0] windTickAnnounce > Chain 0: 0874d580 [/00e54b80/0] qPriListAdvance > Chain 0: 0874d700 [/00e7d238/0] windTickAnnounce > Chain 0: 0874da40 [/00e54b8c/0] qPriListGetExpired > Chain 0: 0874de40 [/00e7d4d4/0] windTickAnnounce > Chain 0: 0874e640 [/00e6f1d8/0] tickAnnounce > Chain 0: 0874e740 [/00e7bb20/0] windExit > Trace 0: 0874eac0 [/00e7bb44/0] windExit > Trace 0: 0874ebc0 [/00e7bb48/0] windExit > Chain 0: 0874f340 [/00e7bb54/0] windExit > Trace 0: 087500c0 [/00e7bb70/0] windExit > Trace 0: 087501c0 [/00e7bb78/0] windExit > Stopped execution of TB chain before 087501c0 [00e7bb78] windExit > Raise exception at 00e7bb78 => 000a (00) > Trace 0: 08747a40 [/0900/0] > Chain 0: 08747b80 [/00e87480/0] excConnectCode > Chain 0: 08747cc0 [/00e7bf24/0] intEnt > Chain 0: 08748980 [/00e7c09c/0] intEnt > Trace 0: 08748b00 [/00e7c0b4/0] intEnt > Trace 0: 08748c00 [/00e7c0bc/0] intEnt > Chain 0: 08748dc0 [/00e050bc/0] timeMonitorCtxSwitchToIsr > Chain 0: 08749040 [/00e7c0cc/0] intEnt > Chain 0: 08749200 [/00e87494/0] excConnectCode > Chain 0: 08749380 [/00e0c654/0] sysClkInt > Chain 0: 086a0a00 [/00e7ac78/0] vxTimeBaseGet >
Re: [PATCH] tests/acceptance/ppc_prep_40p: Use cdn.netbsd.org hostname
On Mon, Mar 09, 2020 at 10:32:34PM -0400, Cleber Rosa wrote: > > > - Original Message - > > From: "David Gibson" > > To: "Alex Bennée" > > Cc: qemu-devel@nongnu.org, "Wainer dos Santos Moschetta" > > , "Kamil Rytarowski" > > , "Hervé Poussineau" , "Cleber > > Rosa" , > > qemu-...@nongnu.org, "Philippe Mathieu-Daudé" > > Sent: Monday, March 9, 2020 9:41:16 PM > > Subject: Re: [PATCH] tests/acceptance/ppc_prep_40p: Use cdn.netbsd.org > > hostname > > > > On Fri, Feb 28, 2020 at 04:10:19PM +, Alex Bennée wrote: > > > > > > Philippe Mathieu-Daudé writes: > > > > > > > Use NetBSD content delivery network to get faster downloads. > > > > > > Even with this patch I get failures on my big dev box: > > > > > > (48/67) > > > > > > tests/acceptance/ppc_prep_40p.py:IbmPrep40pMachine.test_openbios_and_netbsd: > > > INTERRUPTED: Failed to fetch NetBSD-7.1.2-prep.iso.\nRunner error > > > occurred: Timeout reached\nOriginal status: ERROR\n{'name': > > > > > > '48-tests/acceptance/ppc_prep_40p.py:IbmPrep40pMachine.test_openbios_and_netbsd', > > > 'logdir': '/home/alex/lsrc/qemu.git/builds/all/tests/results/jo... (60.31 > > > s) > > > > > > I think ultimately a whole ISO download is just too much for an > > > acceptance test. > > > > I tend to agree. Here in a network-remote part of the world, these > > always seem to cause timeouts and other problems, in a bunch of the > > testcases. > > > > Those are testing useful things though, so I'd really like to see the > > downloads split out into some sort of preparation step that can be > > done just once, rather than part of the test proper. > > We have added functionality in the latest Avocado that will let us > easily set a "cancel this test if the ISO has not being previously > downloaded", or "cancel if it fails to be downloaded during the > test". That certainly sounds like an improvement. I still don't love the idea that the test results will vary based on something outside of the tested code, even if a cancel is definitely better than a fail. > +Willian can explain how it works, and if found to be suitable, and work > on a patch. Ok. That would be good to know - will there be some command to run in advance to attempt to download all the necessary images? Would that run without a timeout - or at least a much longer timeout than the testcase itself has. -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
Re: [PATCH v3] hw/char/pl011: Enable TxFIFO and async transmission
Patchew URL: https://patchew.org/QEMU/20200311040923.29115-1-gs...@redhat.com/ Hi, This series failed the asan build test. Please find the testing commands and their output below. If you have Docker installed, you can probably reproduce it locally. === TEST SCRIPT BEGIN === #!/bin/bash export ARCH=x86_64 make docker-image-fedora V=1 NETWORK=1 time make docker-test-debug@fedora TARGET_LIST=x86_64-softmmu J=14 NETWORK=1 === TEST SCRIPT END === PASS 1 fdc-test /x86_64/fdc/cmos PASS 2 fdc-test /x86_64/fdc/no_media_on_start PASS 3 fdc-test /x86_64/fdc/read_without_media ==6124==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 4 fdc-test /x86_64/fdc/media_change PASS 5 fdc-test /x86_64/fdc/sense_interrupt PASS 6 fdc-test /x86_64/fdc/relative_seek --- PASS 32 test-opts-visitor /visitor/opts/range/beyond PASS 33 test-opts-visitor /visitor/opts/dict/unvisited MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-coroutine -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-coroutine" ==6172==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! ==6172==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x718ab000; bottom 0x7efcbd91; size: 0x010333f9b000 (1113268531200) False positive error reports may follow For details see https://github.com/google/sanitizers/issues/189 PASS 1 test-coroutine /basic/no-dangling-access --- PASS 12 test-aio /aio/event/flush PASS 13 test-aio /aio/event/wait/no-flush-cb PASS 14 test-aio /aio/timer/schedule ==6187==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 15 test-aio /aio/coroutine/queue-chaining PASS 16 test-aio /aio-gsource/flush PASS 17 test-aio /aio-gsource/bh/schedule --- PASS 13 fdc-test /x86_64/fdc/fuzz-registers MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64 QTEST_QEMU_IMG=qemu-img tests/qtest/ide-test -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="ide-test" PASS 28 test-aio /aio-gsource/timer/schedule ==6195==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-aio-multithread -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-aio-multithread" PASS 1 ide-test /x86_64/ide/identify ==6202==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-aio-multithread /aio/multi/lifecycle ==6204==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 2 ide-test /x86_64/ide/flush PASS 2 test-aio-multithread /aio/multi/schedule ==6221==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 3 ide-test /x86_64/ide/bmdma/simple_rw PASS 3 test-aio-multithread /aio/multi/mutex/contended ==6232==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 4 ide-test /x86_64/ide/bmdma/trim ==6243==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 4 test-aio-multithread /aio/multi/mutex/handoff PASS 5 test-aio-multithread /aio/multi/mutex/mcs PASS 6 test-aio-multithread /aio/multi/mutex/pthread MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-throttle -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-throttle" ==6260==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-throttle /throttle/leak_bucket PASS 2 test-throttle /throttle/compute_wait PASS 3 test-throttle /throttle/init --- PASS 14 test-throttle /throttle/config/max PASS 15 test-throttle /throttle/config/iops_size MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-thread-pool -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-thread-pool" ==6264==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-thread-pool /thread-pool/submit PASS 2 test-thread-pool /thread-pool/submit-aio PASS 3 test-thread-pool /thread-pool/submit-co PASS 4 test-thread-pool /thread-pool/submit-many ==6331==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 5 test-thread-pool /thread-pool/cancel PASS 6 test-thread-pool /thread-pool/cancel-async MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-hbitmap -m=quick -k
[Bug 1656927] Re: Network (TCP) access regression
[Expired for QEMU because there has been no activity for 60 days.] ** Changed in: qemu Status: Incomplete => Expired -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1656927 Title: Network (TCP) access regression Status in QEMU: Expired Bug description: Starting a VM with /usr/bin/qemu-system-x86_64 -machine pc-i440fx-1.7,accel=kvm -usb -usbdevice tablet -usbdevice keyboard -enable-kvm -cpu core2duo -smp 2 -drive file=winp ro.qcow,index=0,media=disk,format=qcow2 -m 4096 -vga vmware -vnc :3 -k en-us -device rtl8139,netdev=nic1 -netdev user,id=nic1,smb=/data/vps/files/,hostfw d=tcp::10053-:10053,hostfwd=tcp::3387-:3389 -rtc base=utc,clock=host -daemonize in 2.5.1, all works fine in any version after 2.5.1.1, the network terminate TCP connections after a certain period . To reproduce, starts an app that use always connected TCP sockets (I am using Metatrader 4), let it run a an hour, the app does not realize the TCP is out of order but the TCP connection is closed by QEMU in 2.5.1.x, Metatrader works perfectly Thank you for your help To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1656927/+subscriptions
[Bug 1657841] Re: QEMU Intel HAX Windows
[Expired for QEMU because there has been no activity for 60 days.] ** Changed in: qemu Status: Incomplete => Expired -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1657841 Title: QEMU Intel HAX Windows Status in QEMU: Expired Bug description: Hi, Using the latest exe's from http://qemu.weilnetz.de/w32/ C:\Users\therock247uk\Desktop\jan\qemu-w64-setup-20170113>qemu-system-i386 --enable-hax -m 512 -cdrom C:\Users\therock247uk\Desktop\jan\en_windows_xp_professional_with_service_pack_3_x86_cd_x14-80428.iso HAX is working and emulator runs in fast virt mode. Failed to allocate 2000 memory The emulator seems to hang/get stuck during booting from the CD taking out --enable-hax allows it to boot. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1657841/+subscriptions
[PATCH v3] hw/char/pl011: Enable TxFIFO and async transmission
The depth of TxFIFO can be 1 or 16 depending on LCR[4]. The TxFIFO is disabled when its depth is 1. It's nice to have TxFIFO enabled if possible because more characters can be piled and transmitted at once, which would have less overhead. Besides, we can be blocked because of qemu_chr_fe_write_all(), which isn't nice. This enables TxFIFO if possible. On ther other hand, the asynchronous transmission is enabled if needed, as we did in hw/char/cadence_uart.c Signed-off-by: Gavin Shan --- v3: Use PL011() to do data type conversion Return G_SOURCE_REMOVE when the backend is disconnected in pl011_xmit() Drop parenthesis in the condition validating @size in pl011_write_fifo() --- hw/char/pl011.c | 105 +--- include/hw/char/pl011.h | 3 ++ 2 files changed, 102 insertions(+), 6 deletions(-) diff --git a/hw/char/pl011.c b/hw/char/pl011.c index 13e784f9d9..dccb8c42b0 100644 --- a/hw/char/pl011.c +++ b/hw/char/pl011.c @@ -169,6 +169,73 @@ static void pl011_set_read_trigger(PL011State *s) s->read_trigger = 1; } +static gboolean pl011_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) +{ +PL011State *s = PL011(opaque); +int ret; + +/* Drain FIFO if there is no backend */ +if (!qemu_chr_fe_backend_connected(>chr)) { +s->write_count = 0; +s->flags &= ~PL011_FLAG_TXFF; +s->flags |= PL011_FLAG_TXFE; +return G_SOURCE_REMOVE; +} + +/* Nothing to do */ +if (!s->write_count) { +return FALSE; +} + +ret = qemu_chr_fe_write(>chr, s->write_fifo, s->write_count); +if (ret > 0) { +s->write_count -= ret; +memmove(s->write_fifo, s->write_fifo + ret, s->write_count); +s->flags &= ~PL011_FLAG_TXFF; +if (!s->write_count) { +s->flags |= PL011_FLAG_TXFE; +} +} + +if (s->write_count) { +s->watch_tag = qemu_chr_fe_add_watch(>chr, G_IO_OUT | G_IO_HUP, + pl011_xmit, s); +if (!s->watch_tag) { +s->write_count = 0; +s->flags &= ~PL011_FLAG_TXFF; +s->flags |= PL011_FLAG_TXFE; +return FALSE; +} +} + +s->int_level |= PL011_INT_TX; +pl011_update(s); +return FALSE; +} + +static void pl011_write_fifo(void *opaque, const unsigned char *buf, int size) +{ +PL011State *s = PL011(opaque); +int depth = (s->lcr & 0x10) ? 16 : 1; + +if (size >= depth - s->write_count) { +size = depth - s->write_count; +} + +if (size > 0) { +memcpy(s->write_fifo + s->write_count, buf, size); +s->write_count += size; +if (s->write_count >= depth) { +s->flags |= PL011_FLAG_TXFF; +} +s->flags &= ~PL011_FLAG_TXFE; +} + +if (!s->watch_tag) { +pl011_xmit(NULL, G_IO_OUT, s); +} +} + static void pl011_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { @@ -179,13 +246,8 @@ static void pl011_write(void *opaque, hwaddr offset, switch (offset >> 2) { case 0: /* UARTDR */ -/* ??? Check if transmitter is enabled. */ ch = value; -/* XXX this blocks entire thread. Rewrite to use - * qemu_chr_fe_write and background I/O callbacks */ -qemu_chr_fe_write_all(>chr, , 1); -s->int_level |= PL011_INT_TX; -pl011_update(s); +pl011_write_fifo(opaque, , 1); break; case 1: /* UARTRSR/UARTECR */ s->rsr = 0; @@ -207,7 +269,16 @@ static void pl011_write(void *opaque, hwaddr offset, if ((s->lcr ^ value) & 0x10) { s->read_count = 0; s->read_pos = 0; + +if (s->watch_tag) { +g_source_remove(s->watch_tag); +s->watch_tag = 0; +} +s->write_count = 0; +s->flags &= ~PL011_FLAG_TXFF; +s->flags |= PL011_FLAG_TXFE; } + s->lcr = value; pl011_set_read_trigger(s); break; @@ -292,6 +363,24 @@ static const MemoryRegionOps pl011_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +static bool pl011_write_fifo_needed(void *opaque) +{ +PL011State *s = PL011(opaque); +return s->write_count > 0; +} + +static const VMStateDescription vmstate_pl011_write_fifo = { +.name = "pl011/write_fifo", +.version_id = 1, +.minimum_version_id = 1, +.needed = pl011_write_fifo_needed, +.fields = (VMStateField[]) { +VMSTATE_INT32(write_count, PL011State), +VMSTATE_UINT8_ARRAY(write_fifo, PL011State, 16), +VMSTATE_END_OF_LIST() +} +}; + static const VMStateDescription vmstate_pl011 = { .name = "pl011", .version_id = 2, @@ -314,6 +403,10 @@ static const VMStateDescription vmstate_pl011 = { VMSTATE_INT32(read_count, PL011State), VMSTATE_INT32(read_trigger, PL011State), VMSTATE_END_OF_LIST() +}, +
Re: Questions about pollute the mail list archives
On 3/10/20 7:19 PM, LIU Zhiwei wrote: > Is it serious? It isn't ideal. I would eventually try to review via your branch, and find a copy of the patch to reply, or send a reply to the cover letter if no copy of the patch arrived. > Is there any way to clear it in the mail list archives? No. > Can I send it again to the mail list? Yes. To avoid confusion I would label it v4, even if there are no changes since v3. I would recommend using the --batch-size and --relogin-delay options to git-send-email. I don't know exactly what parameters you need, but choosing small batches and long-ish delays should mean that the whole patch set trickles out over the course of an hour or two. Patience is something that computers are good at. :-) r~
Re: [PATCH qemu v8 1/3] ppc/spapr: Move GPRs setup to one place
On Tue, Mar 10, 2020 at 04:07:31PM +1100, Alexey Kardashevskiy wrote: > At the moment "pseries" starts in SLOF which only expects the FDT blob > pointer in r3. As we are going to introduce a OpenFirmware support in > QEMU, we will be booting OF clients directly and these expect a stack > pointer in r1, Linux looks at r3/r4 for the initramdisk location > (although vmlinux can find this from the device tree but zImage from > distro kernels cannot). > > This extends spapr_cpu_set_entry_state() to take more registers. This > should cause no behavioral change. > > Signed-off-by: Alexey Kardashevskiy LGTM independent of the other changes, so applied to ppc-for-5.0. > --- > Changes: > v7: > * removed r5 as it points to prom entry which is now provided by > a new firmware in later patches > --- > include/hw/ppc/spapr_cpu_core.h | 4 +++- > hw/ppc/spapr.c | 2 +- > hw/ppc/spapr_cpu_core.c | 6 +- > hw/ppc/spapr_rtas.c | 2 +- > 4 files changed, 10 insertions(+), 4 deletions(-) > > diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h > index 1c4cc6559c52..7aed8f555b4f 100644 > --- a/include/hw/ppc/spapr_cpu_core.h > +++ b/include/hw/ppc/spapr_cpu_core.h > @@ -40,7 +40,9 @@ typedef struct SpaprCpuCoreClass { > } SpaprCpuCoreClass; > > const char *spapr_get_cpu_core_type(const char *cpu_type); > -void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, > target_ulong r3); > +void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, > + target_ulong r1, target_ulong r3, > + target_ulong r4); > > typedef struct SpaprCpuState { > uint64_t vpa_addr; > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index 2eb0d8f70de6..64bc8b83e91e 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -1698,7 +1698,7 @@ static void spapr_machine_reset(MachineState *machine) > spapr->fdt_blob = fdt; > > /* Set up the entry state */ > -spapr_cpu_set_entry_state(first_ppc_cpu, SPAPR_ENTRY_POINT, fdt_addr); > +spapr_cpu_set_entry_state(first_ppc_cpu, SPAPR_ENTRY_POINT, 0, fdt_addr, > 0); > first_ppc_cpu->env.gpr[5] = 0; > > spapr->cas_reboot = false; > diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c > index 36ed3a2b665b..ac1c10942771 100644 > --- a/hw/ppc/spapr_cpu_core.c > +++ b/hw/ppc/spapr_cpu_core.c > @@ -76,13 +76,17 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu) > spapr_irq_cpu_intc_reset(spapr, cpu); > } > > -void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, > target_ulong r3) > +void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, > + target_ulong r1, target_ulong r3, > + target_ulong r4) > { > PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); > CPUPPCState *env = >env; > > env->nip = nip; > +env->gpr[1] = r1; > env->gpr[3] = r3; > +env->gpr[4] = r4; > kvmppc_set_reg_ppc_online(cpu, 1); > CPU(cpu)->halted = 0; > /* Enable Power-saving mode Exit Cause exceptions */ > diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c > index 656fdd221665..fe83b50c6629 100644 > --- a/hw/ppc/spapr_rtas.c > +++ b/hw/ppc/spapr_rtas.c > @@ -190,7 +190,7 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, > SpaprMachineState *spapr, > */ > newcpu->env.tb_env->tb_offset = callcpu->env.tb_env->tb_offset; > > -spapr_cpu_set_entry_state(newcpu, start, r3); > +spapr_cpu_set_entry_state(newcpu, start, 0, r3, 0); > > qemu_cpu_kick(CPU(newcpu)); > -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
Re: [PATCH v7 07/17] target/ppc: Use class fields to simplify LPCR masking
On Tue, Mar 10, 2020 at 11:06:08AM +0100, Cédric Le Goater wrote: > On 3/3/20 4:43 AM, David Gibson wrote: > > When we store the Logical Partitioning Control Register (LPCR) we have a > > big switch statement to work out which are valid bits for the cpu model > > we're emulating. > > > > As well as being ugly, this isn't really conceptually correct, since it is > > based on the mmu_model variable, whereas the LPCR isn't (only) about the > > MMU, so mmu_model is basically just acting as a proxy for the cpu model. > > > > Handle this in a simpler way, by adding a suitable lpcr_mask to the QOM > > class. > > > > Signed-off-by: David Gibson > > Reviewed-by: Cédric Le Goater > > Reviewed-by: Greg Kurz > > --- > > target/ppc/cpu-qom.h| 1 + > > target/ppc/mmu-hash64.c | 36 ++--- > > target/ppc/translate_init.inc.c | 27 + > > 3 files changed, 26 insertions(+), 38 deletions(-) > > > > diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h > > index e499575dc8..15d6b54a7d 100644 > > --- a/target/ppc/cpu-qom.h > > +++ b/target/ppc/cpu-qom.h > > @@ -177,6 +177,7 @@ typedef struct PowerPCCPUClass { > > uint64_t insns_flags; > > uint64_t insns_flags2; > > uint64_t msr_mask; > > +uint64_t lpcr_mask; /* Available bits in the LPCR */ > > uint64_t lpcr_pm; /* Power-saving mode Exit Cause Enable > > bits */ > > powerpc_mmu_t mmu_model; > > powerpc_excp_t excp_model; > > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c > > index caf47ad6fc..0ef330a614 100644 > > --- a/target/ppc/mmu-hash64.c > > +++ b/target/ppc/mmu-hash64.c > > @@ -1095,42 +1095,10 @@ static void ppc_hash64_update_vrma(PowerPCCPU *cpu) > > > > void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val) > > { > > +PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); > > CPUPPCState *env = >env; > > -uint64_t lpcr = 0; > > > > -/* Filter out bits */ > > -switch (env->mmu_model) { > > -case POWERPC_MMU_2_03: /* P5p */ > > -lpcr = val & (LPCR_RMLS | LPCR_ILE | > > - LPCR_LPES0 | LPCR_LPES1 | > > - LPCR_RMI | LPCR_HDICE); > > -break; > > -case POWERPC_MMU_2_06: /* P7 */ > > -lpcr = val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD | > > - LPCR_VRMASD | LPCR_RMLS | LPCR_ILE | > > - LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 | > > - LPCR_MER | LPCR_TC | > > - LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE); > > -break; > > -case POWERPC_MMU_2_07: /* P8 */ > > -lpcr = val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV | > > - LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE | > > - LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 | > > - LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 | > > - LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE); > > -break; > > -case POWERPC_MMU_3_00: /* P9 */ > > -lpcr = val & (LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD | > > - (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL > > | > > - LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | > > LPCR_LD | > > - (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | > > LPCR_EEE | > > - LPCR_DEE | LPCR_OEE)) | LPCR_MER | LPCR_GTSE | > > LPCR_TC | > > - LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE); > > -break; > > -default: > > -g_assert_not_reached(); > > -} > > -env->spr[SPR_LPCR] = lpcr; > > +env->spr[SPR_LPCR] = val & pcc->lpcr_mask; > > ppc_hash64_update_rmls(cpu); > > ppc_hash64_update_vrma(cpu); > > } > > diff --git a/target/ppc/translate_init.inc.c > > b/target/ppc/translate_init.inc.c > > index f7acd3d61d..68aa4dfad8 100644 > > --- a/target/ppc/translate_init.inc.c > > +++ b/target/ppc/translate_init.inc.c > > @@ -8476,6 +8476,8 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data) > > (1ull << MSR_DR) | > > (1ull << MSR_PMM) | > > (1ull << MSR_RI); > > +pcc->lpcr_mask = LPCR_RMLS | LPCR_ILE | LPCR_LPES0 | LPCR_LPES1 | > > +LPCR_RMI | LPCR_HDICE; > > pcc->mmu_model = POWERPC_MMU_2_03; > > #if defined(CONFIG_SOFTMMU) > > pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; > > @@ -8614,6 +8616,12 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) > > (1ull << MSR_PMM) | > > (1ull << MSR_RI) | > > (1ull << MSR_LE); > > +pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD | > > +LPCR_VRMASD | LPCR_RMLS | LPCR_ILE | > > +LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 | > > +LPCR_MER | LPCR_TC | > > +
[PATCH v3] block/iscsi:use the flags in iscsi_open() prevent Clang warning
Clang static code analyzer show warning: block/iscsi.c:1920:9: warning: Value stored to 'flags' is never read flags &= ~BDRV_O_RDWR; ^ In iscsi_allocmap_init() only checks BDRV_O_NOCACHE, which is the same in both of flags and bs->open_flags. We can use the flags instead bs->open_flags to prevent Clang warning. Reported-by: Euler Robot Signed-off-by: Chen Qun Reviewed-by: Kevin Wolf --- Cc: Ronnie Sahlberg Cc: Paolo Bonzini Cc: Peter Lieven Cc: Kevin Wolf Cc: Max Reitz Cc: Laurent Vivier v1->v2: Keep the 'flags' then use it(Base on Kevin's comments). v2->v3: Modify subject and commit messages(Base on Kevin's and Laurent's comments). --- block/iscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/iscsi.c b/block/iscsi.c index 682abd8e09..50bae51700 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -2002,7 +2002,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, iscsilun->cluster_size = iscsilun->bl.opt_unmap_gran * iscsilun->block_size; if (iscsilun->lbprz) { -ret = iscsi_allocmap_init(iscsilun, bs->open_flags); +ret = iscsi_allocmap_init(iscsilun, flags); } } -- 2.23.0
[Bug 1866870] Re: KVM Guest pauses after upgrade to Ubuntu 20.04
** Also affects: ubuntu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1866870 Title: KVM Guest pauses after upgrade to Ubuntu 20.04 Status in QEMU: New Status in Ubuntu: New Bug description: As outlined here: https://bugs.launchpad.net/qemu/+bug/1813165/comments/15 After upgrade, all KVM guests are in a default pause state. Even after forcing them off via virsh, and restarting them the guests are paused. These Guests are not nested. A lot of diganostic information are outlined in the previous bug report link provided. The solution mentioned in previous report had been allegedly integrated into the downstream updates. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1866870/+subscriptions
Re: [PATCH] vfio/pci: Use defined memcpy() behavior
On 2020/3/11 1:15, Alex Williamson wrote: > vfio_rom_read() relies on memcpy() doing the logically correct thing, > ie. safely copying zero bytes from a NULL pointer when rom_size is > zero, rather than the spec definition, which is undefined when the > source or target pointers are NULL. Resolve this by wrapping the > call in the condition expressed previously by the ternary. > > Additionally, we still use @val to fill data based on the provided > @size regardless of mempcy(), so we should initialize @val rather > than @data. > > Reported-by: Longpeng > Reported-by: Laszlo Ersek > Signed-off-by: Alex Williamson > --- > hw/vfio/pci.c |9 + > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c > index 5e75a95129ac..b0799cdc28ad 100644 > --- a/hw/vfio/pci.c > +++ b/hw/vfio/pci.c > @@ -859,16 +859,17 @@ static uint64_t vfio_rom_read(void *opaque, hwaddr > addr, unsigned size) > uint16_t word; > uint32_t dword; > uint64_t qword; > -} val; > -uint64_t data = 0; > +} val = { 0 }; > +uint64_t data; > 'val.qword' won't be used, maybe we could drop it silently. Reviewed-by: Longpeng > /* Load the ROM lazily when the guest tries to read it */ > if (unlikely(!vdev->rom && !vdev->rom_read_failed)) { > vfio_pci_load_rom(vdev); > } > > -memcpy(, vdev->rom + addr, > - (addr < vdev->rom_size) ? MIN(size, vdev->rom_size - addr) : 0); > +if (addr < vdev->rom_size) { > +memcpy(, vdev->rom + addr, MIN(size, vdev->rom_size - addr)); > +} > > switch (size) { > case 1: > > . > --- Regards, Longpeng(Mike)
[PATCH v6 12/13] hw/i386: Move arch_id decode inside x86_cpus_init
Apicid calculation depends on knowing the total number of numa nodes for EPYC cpu models. Right now, we are calculating the arch_id while parsing the numa(parse_numa). At this time, it is not known how many total numa nodes are configured in the system. Move the arch_id inside x86_cpus_init. At this time smp parse is already completed and numa node information is available. Signed-off-by: Babu Moger Acked-by: Michael S. Tsirkin --- hw/i386/x86.c | 17 +++-- 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/hw/i386/x86.c b/hw/i386/x86.c index ad85347142..be93c1fd1b 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -140,6 +140,9 @@ void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version) MachineState *ms = MACHINE(x86ms); MachineClass *mc = MACHINE_GET_CLASS(x86ms); +/* Check for apicid encoding */ +x86_check_apic_id_encoding(ms); + x86_cpu_set_default_version(default_cpu_version); /* @@ -153,6 +156,12 @@ void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version) x86ms->apic_id_limit = x86_cpu_apic_id_from_index(x86ms, ms->smp.max_cpus - 1) + 1; possible_cpus = mc->possible_cpu_arch_ids(ms); + +for (i = 0; i < ms->smp.cpus; i++) { +ms->possible_cpus->cpus[i].arch_id = +x86_cpu_apic_id_from_index(x86ms, i); +} + for (i = 0; i < ms->smp.cpus; i++) { x86_cpu_new(x86ms, possible_cpus->cpus[i].arch_id, _fatal); } @@ -177,8 +186,7 @@ int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx) init_topo_info(_info, x86ms); assert(idx < ms->possible_cpus->len); - x86ms->topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id, - _info, _ids); + x86ms->topo_ids_from_idx(_info, idx, _ids); return topo_ids.pkg_id % ms->numa_state->num_nodes; } @@ -212,10 +220,7 @@ const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms) ms->possible_cpus->cpus[i].type = ms->cpu_type; ms->possible_cpus->cpus[i].vcpus_count = 1; -ms->possible_cpus->cpus[i].arch_id = -x86_cpu_apic_id_from_index(x86ms, i); -x86ms->topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id, -_info, _ids); +x86ms->topo_ids_from_idx(_info, i, _ids); ms->possible_cpus->cpus[i].props.has_socket_id = true; ms->possible_cpus->cpus[i].props.socket_id = topo_ids.pkg_id; if (x86ms->smp_dies > 1) {
[PATCH v6 05/13] hw/i386: Update structures to save the number of nodes per package
Update structures X86CPUTopoIDs and CPUX86State to hold the number of nodes per package. This is required to build EPYC mode topology. Signed-off-by: Babu Moger Reviewed-by: Igor Mammedov Acked-by: Michael S. Tsirkin --- hw/i386/pc.c |1 + hw/i386/x86.c |1 + include/hw/i386/topology.h |1 + target/i386/cpu.c |1 + target/i386/cpu.h |1 + tests/test-x86-cpuid.c | 40 6 files changed, 25 insertions(+), 20 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 05e7f1090f..ee89fcd1c3 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1525,6 +1525,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, init_topo_info(_info, x86ms); env->nr_dies = x86ms->smp_dies; +env->nr_nodes = topo_info.nodes_per_pkg; /* * If APIC ID is not set, diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 79badcc4ec..929b80c9c7 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -62,6 +62,7 @@ inline void init_topo_info(X86CPUTopoInfo *topo_info, { MachineState *ms = MACHINE(x86ms); +topo_info->nodes_per_pkg = ms->numa_state->num_nodes / ms->smp.sockets; topo_info->dies_per_pkg = x86ms->smp_dies; topo_info->cores_per_die = ms->smp.cores; topo_info->threads_per_core = ms->smp.threads; diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h index ba52d49079..04f01e2a09 100644 --- a/include/hw/i386/topology.h +++ b/include/hw/i386/topology.h @@ -53,6 +53,7 @@ typedef struct X86CPUTopoIDs { } X86CPUTopoIDs; typedef struct X86CPUTopoInfo { +unsigned nodes_per_pkg; unsigned dies_per_pkg; unsigned cores_per_die; unsigned threads_per_core; diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 6df3127fd7..2e5be37b21 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -6957,6 +6957,7 @@ static void x86_cpu_initfn(Object *obj) FeatureWord w; env->nr_dies = 1; +env->nr_nodes = 1; cpu_set_cpustate_pointers(cpu); object_property_add(obj, "family", "int", diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 68b186d258..7e9e963d78 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1609,6 +1609,7 @@ typedef struct CPUX86State { TPRAccess tpr_access_type; unsigned nr_dies; +unsigned nr_nodes; } CPUX86State; struct kvm_msrs; diff --git a/tests/test-x86-cpuid.c b/tests/test-x86-cpuid.c index bfabc0403a..049030a50e 100644 --- a/tests/test-x86-cpuid.c +++ b/tests/test-x86-cpuid.c @@ -31,12 +31,12 @@ static void test_topo_bits(void) X86CPUTopoInfo topo_info = {0}; /* simple tests for 1 thread per core, 1 core per die, 1 die per package */ -topo_info = (X86CPUTopoInfo) {1, 1, 1}; +topo_info = (X86CPUTopoInfo) {0, 1, 1, 1}; g_assert_cmpuint(apicid_smt_width(_info), ==, 0); g_assert_cmpuint(apicid_core_width(_info), ==, 0); g_assert_cmpuint(apicid_die_width(_info), ==, 0); -topo_info = (X86CPUTopoInfo) {1, 1, 1}; +topo_info = (X86CPUTopoInfo) {0, 1, 1, 1}; g_assert_cmpuint(x86_apicid_from_cpu_idx(_info, 0), ==, 0); g_assert_cmpuint(x86_apicid_from_cpu_idx(_info, 1), ==, 1); g_assert_cmpuint(x86_apicid_from_cpu_idx(_info, 2), ==, 2); @@ -45,39 +45,39 @@ static void test_topo_bits(void) /* Test field width calculation for multiple values */ -topo_info = (X86CPUTopoInfo) {1, 1, 2}; +topo_info = (X86CPUTopoInfo) {0, 1, 1, 2}; g_assert_cmpuint(apicid_smt_width(_info), ==, 1); -topo_info = (X86CPUTopoInfo) {1, 1, 3}; +topo_info = (X86CPUTopoInfo) {0, 1, 1, 3}; g_assert_cmpuint(apicid_smt_width(_info), ==, 2); -topo_info = (X86CPUTopoInfo) {1, 1, 4}; +topo_info = (X86CPUTopoInfo) {0, 1, 1, 4}; g_assert_cmpuint(apicid_smt_width(_info), ==, 2); -topo_info = (X86CPUTopoInfo) {1, 1, 14}; +topo_info = (X86CPUTopoInfo) {0, 1, 1, 14}; g_assert_cmpuint(apicid_smt_width(_info), ==, 4); -topo_info = (X86CPUTopoInfo) {1, 1, 15}; +topo_info = (X86CPUTopoInfo) {0, 1, 1, 15}; g_assert_cmpuint(apicid_smt_width(_info), ==, 4); -topo_info = (X86CPUTopoInfo) {1, 1, 16}; +topo_info = (X86CPUTopoInfo) {0, 1, 1, 16}; g_assert_cmpuint(apicid_smt_width(_info), ==, 4); -topo_info = (X86CPUTopoInfo) {1, 1, 17}; +topo_info = (X86CPUTopoInfo) {0, 1, 1, 17}; g_assert_cmpuint(apicid_smt_width(_info), ==, 5); -topo_info = (X86CPUTopoInfo) {1, 30, 2}; +topo_info = (X86CPUTopoInfo) {0, 1, 30, 2}; g_assert_cmpuint(apicid_core_width(_info), ==, 5); -topo_info = (X86CPUTopoInfo) {1, 31, 2}; +topo_info = (X86CPUTopoInfo) {0, 1, 31, 2}; g_assert_cmpuint(apicid_core_width(_info), ==, 5); -topo_info = (X86CPUTopoInfo) {1, 32, 2}; +topo_info = (X86CPUTopoInfo) {0, 1, 32, 2}; g_assert_cmpuint(apicid_core_width(_info), ==, 5); -topo_info = (X86CPUTopoInfo) {1, 33, 2}; +topo_info = (X86CPUTopoInfo) {0, 1, 33, 2};
[PATCH v6 10/13] i386: Check for apic id encoding
Check X86CPUDefinition if use_epyc_apic_id_encoding is enabled. If enabled update X86MachineState with EPYC mode apic_id encoding handlers. Also update the calling convention to use apic_id handlers from X86MachineState. Signed-off-by: Babu Moger Acked-by: Michael S. Tsirkin --- hw/i386/pc.c |6 +++--- hw/i386/x86.c | 32 +++- target/i386/cpu.c | 11 +++ target/i386/cpu.h |1 + 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 98ee763f68..2d7d611184 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1580,14 +1580,14 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, topo_ids.die_id = cpu->die_id; topo_ids.core_id = cpu->core_id; topo_ids.smt_id = cpu->thread_id; -cpu->apic_id = x86_apicid_from_topo_ids(_info, _ids); +cpu->apic_id = x86ms->apicid_from_topo_ids(_info, _ids); } cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, ); if (!cpu_slot) { MachineState *ms = MACHINE(pcms); -x86_topo_ids_from_apicid(cpu->apic_id, _info, _ids); +x86ms->topo_ids_from_apicid(cpu->apic_id, _info, _ids); error_setg(errp, "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with" " APIC ID %" PRIu32 ", valid index range 0:%d", @@ -1608,7 +1608,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, /* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn() * once -smp refactoring is complete and there will be CPU private * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */ -x86_topo_ids_from_apicid(cpu->apic_id, _info, _ids); +x86ms->topo_ids_from_apicid(cpu->apic_id, _info, _ids); if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) { error_setg(errp, "property socket-id: %u doesn't match set apic-id:" " 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 7dc237c014..ad85347142 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -68,6 +68,25 @@ inline void init_topo_info(X86CPUTopoInfo *topo_info, topo_info->threads_per_core = ms->smp.threads; } +/* + * Check for APIC ID encoding + * + * AMD uses different apic id encoding for their EPYC based cpus. + * Check if we need to use different handlers than the default. + */ +static void x86_check_apic_id_encoding(MachineState *machine) +{ +X86MachineState *x86ms = X86_MACHINE(machine); + +if (cpu_x86_use_epyc_apic_id_encoding(machine->cpu_type)) { +x86ms->apicid_from_cpu_idx = x86_apicid_from_cpu_idx_epyc; +x86ms->topo_ids_from_apicid = x86_topo_ids_from_apicid_epyc; +x86ms->topo_ids_from_idx = x86_topo_ids_from_idx_epyc; +x86ms->apicid_from_topo_ids = x86_apicid_from_topo_ids_epyc; +x86ms->apicid_pkg_offset = apicid_pkg_offset_epyc; +} +} + /* * Calculates initial APIC ID for a specific CPU index * @@ -86,7 +105,7 @@ uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms, init_topo_info(_info, x86ms); -correct_id = x86_apicid_from_cpu_idx(_info, cpu_index); +correct_id = x86ms->apicid_from_cpu_idx(_info, cpu_index); if (x86mc->compat_apic_id_mode) { if (cpu_index != correct_id && !warned && !qtest_enabled()) { error_report("APIC IDs set in compatibility mode, " @@ -158,8 +177,8 @@ int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx) init_topo_info(_info, x86ms); assert(idx < ms->possible_cpus->len); - x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id, -_info, _ids); + x86ms->topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id, + _info, _ids); return topo_ids.pkg_id % ms->numa_state->num_nodes; } @@ -179,6 +198,9 @@ const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms) return ms->possible_cpus; } +/* Check for apicid encoding */ +x86_check_apic_id_encoding(ms); + ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) + sizeof(CPUArchId) * max_cpus); ms->possible_cpus->len = max_cpus; @@ -192,8 +214,8 @@ const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms) ms->possible_cpus->cpus[i].vcpus_count = 1; ms->possible_cpus->cpus[i].arch_id = x86_cpu_apic_id_from_index(x86ms, i); -x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id, - _info, _ids); +x86ms->topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id, +_info, _ids); ms->possible_cpus->cpus[i].props.has_socket_id = true; ms->possible_cpus->cpus[i].props.socket_id = topo_ids.pkg_id; if (x86ms->smp_dies > 1) { diff --git a/target/i386/cpu.c b/target/i386/cpu.c index
[PATCH v6 11/13] target/i386: Enable new apic id encoding for EPYC based cpus models
The APIC ID is decoded based on the sequence sockets->dies->cores->threads. This works fine for most standard AMD and other vendors' configurations, but this decoding sequence does not follow that of AMD's APIC ID enumeration strictly. In some cases this can cause CPU topology inconsistency. When booting a guest VM, the kernel tries to validate the topology, and finds it inconsistent with the enumeration of EPYC cpu models. The more details are in the bug https://bugzilla.redhat.com/show_bug.cgi?id=1728166. To fix the problem we need to build the topology as per the Processor Programming Reference (PPR) for AMD Family 17h Model 01h, Revision B1 Processors. The documentation is available from the bugzilla Link below. Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537 It is also available at https://www.amd.com/system/files/TechDocs/55570-B1_PUB.zip Here is the text from the PPR. Operating systems are expected to use Core::X86::Cpuid::SizeId[ApicIdSize], the number of least significant bits in the Initial APIC ID that indicate core ID within a processor, in constructing per-core CPUID masks. Core::X86::Cpuid::SizeId[ApicIdSize] determines the maximum number of cores (MNC) that the processor could theoretically support, not the actual number of cores that are actually implemented or enabled on the processor, as indicated by Core::X86::Cpuid::SizeId[NC]. Each Core::X86::Apic::ApicId[ApicId] register is preset as follows: • ApicId[6] = Socket ID. • ApicId[5:4] = Node ID. • ApicId[3] = Logical CCX L3 complex ID • ApicId[2:0]= (SMT) ? {LogicalCoreID[1:0],ThreadId} : {1'b0,LogicalCoreID[1:0]} The new apic id encoding is enabled for EPYC and EPYC-Rome models. Signed-off-by: Babu Moger Acked-by: Michael S. Tsirkin --- target/i386/cpu.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 19de79d01c..5d5734af76 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -3921,6 +3921,7 @@ static X86CPUDefinition builtin_x86_defs[] = { .xlevel = 0x801E, .model_id = "AMD EPYC Processor", .cache_info = _cache_info, +.use_epyc_apic_id_encoding = 1, .versions = (X86CPUVersionDefinition[]) { { .version = 1 }, { @@ -4048,6 +4049,7 @@ static X86CPUDefinition builtin_x86_defs[] = { .xlevel = 0x801E, .model_id = "AMD EPYC-Rome Processor", .cache_info = _rome_cache_info, +.use_epyc_apic_id_encoding = 1, }, };
[PATCH v6 04/13] hw/i386: Remove unnecessary initialization in x86_cpu_new
The function pc_cpu_pre_plug takes care of initialization of CPUX86State. So, remove the initialization here. Suggested-by: Igor Mammedov Signed-off-by: Babu Moger Reviewed-by: Igor Mammedov Acked-by: Michael S. Tsirkin --- hw/i386/x86.c |4 1 file changed, 4 deletions(-) diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 03b8962c98..79badcc4ec 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -103,13 +103,9 @@ void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp) { Object *cpu = NULL; Error *local_err = NULL; -CPUX86State *env = NULL; cpu = object_new(MACHINE(x86ms)->cpu_type); -env = _CPU(cpu)->env; -env->nr_dies = x86ms->smp_dies; - object_property_set_uint(cpu, apic_id, "apic-id", _err); object_property_set_bool(cpu, true, "realized", _err);
[PATCH v6 13/13] i386: Fix pkg_id offset for EPYC cpu models
If the system is numa configured the pkg_offset needs to be adjusted for EPYC cpu models. Fix it calling the model specific handler. Signed-off-by: Babu Moger Reviewed-by: Igor Mammedov Acked-by: Michael S. Tsirkin --- hw/i386/pc.c |1 + target/i386/cpu.c |4 ++-- target/i386/cpu.h |1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 2d7d611184..ab6da19bab 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1526,6 +1526,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, env->nr_dies = x86ms->smp_dies; env->nr_nodes = topo_info.nodes_per_pkg; +env->pkg_offset = x86ms->apicid_pkg_offset(_info); /* * If APIC ID is not set, diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 5d5734af76..f205c56f9a 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -5606,7 +5606,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx |= CPUID_TOPOLOGY_LEVEL_SMT; break; case 1: -*eax = apicid_pkg_offset(_info); +*eax = env->pkg_offset; *ebx = cs->nr_cores * cs->nr_threads; *ecx |= CPUID_TOPOLOGY_LEVEL_CORE; break; @@ -5640,7 +5640,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx |= CPUID_TOPOLOGY_LEVEL_CORE; break; case 2: -*eax = apicid_pkg_offset(_info); +*eax = env->pkg_offset; *ebx = env->nr_dies * cs->nr_cores * cs->nr_threads; *ecx |= CPUID_TOPOLOGY_LEVEL_DIE; break; diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 6e522fcd34..92872d2b7a 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1610,6 +1610,7 @@ typedef struct CPUX86State { unsigned nr_dies; unsigned nr_nodes; +unsigned pkg_offset; } CPUX86State; struct kvm_msrs;
[PATCH v6 06/13] hw/i386: Rename apicid_from_topo_ids to x86_apicid_from_topo_ids
For consistancy rename apicid_from_topo_ids to x86_apicid_from_topo_ids. No functional change. Signed-off-by: Babu Moger Reviewed-by: Igor Mammedov Acked-by: Michael S. Tsirkin --- hw/i386/pc.c |2 +- include/hw/i386/topology.h |6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index ee89fcd1c3..98ee763f68 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1580,7 +1580,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, topo_ids.die_id = cpu->die_id; topo_ids.core_id = cpu->core_id; topo_ids.smt_id = cpu->thread_id; -cpu->apic_id = apicid_from_topo_ids(_info, _ids); +cpu->apic_id = x86_apicid_from_topo_ids(_info, _ids); } cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, ); diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h index 04f01e2a09..b9593b9905 100644 --- a/include/hw/i386/topology.h +++ b/include/hw/i386/topology.h @@ -112,8 +112,8 @@ static inline unsigned apicid_pkg_offset(X86CPUTopoInfo *topo_info) * * The caller must make sure core_id < nr_cores and smt_id < nr_threads. */ -static inline apic_id_t apicid_from_topo_ids(X86CPUTopoInfo *topo_info, - const X86CPUTopoIDs *topo_ids) +static inline apic_id_t x86_apicid_from_topo_ids(X86CPUTopoInfo *topo_info, + const X86CPUTopoIDs *topo_ids) { return (topo_ids->pkg_id << apicid_pkg_offset(topo_info)) | (topo_ids->die_id << apicid_die_offset(topo_info)) | @@ -165,7 +165,7 @@ static inline apic_id_t x86_apicid_from_cpu_idx(X86CPUTopoInfo *topo_info, { X86CPUTopoIDs topo_ids; x86_topo_ids_from_idx(topo_info, cpu_index, _ids); -return apicid_from_topo_ids(topo_info, _ids); +return x86_apicid_from_topo_ids(topo_info, _ids); } #endif /* HW_I386_TOPOLOGY_H */
[PATCH v6 09/13] hw/i386: Introduce apicid functions inside X86MachineState
Introduce model specific apicid functions inside X86MachineState. These functions will be loaded from X86CPUDefinition. Signed-off-by: Babu Moger Reviewed-by: Igor Mammedov Acked-by: Michael S. Tsirkin --- hw/i386/x86.c |6 ++ include/hw/i386/x86.h | 11 +++ 2 files changed, 17 insertions(+) diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 929b80c9c7..7dc237c014 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -911,6 +911,12 @@ static void x86_machine_initfn(Object *obj) x86ms->smm = ON_OFF_AUTO_AUTO; x86ms->max_ram_below_4g = 0; /* use default */ x86ms->smp_dies = 1; + +x86ms->apicid_from_cpu_idx = x86_apicid_from_cpu_idx; +x86ms->topo_ids_from_apicid = x86_topo_ids_from_apicid; +x86ms->topo_ids_from_idx = x86_topo_ids_from_idx; +x86ms->apicid_from_topo_ids = x86_apicid_from_topo_ids; +x86ms->apicid_pkg_offset = apicid_pkg_offset; } static void x86_machine_class_init(ObjectClass *oc, void *data) diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h index 22babcb3bb..57c1d13483 100644 --- a/include/hw/i386/x86.h +++ b/include/hw/i386/x86.h @@ -65,6 +65,17 @@ typedef struct { OnOffAuto smm; +/* Apic id specific handlers */ +uint32_t (*apicid_from_cpu_idx)(X86CPUTopoInfo *topo_info, +unsigned cpu_index); +void (*topo_ids_from_apicid)(apic_id_t apicid, X86CPUTopoInfo *topo_info, + X86CPUTopoIDs *topo_ids); +void (*topo_ids_from_idx)(X86CPUTopoInfo *topo_info, unsigned idx, + X86CPUTopoIDs *topo_ids); +apic_id_t (*apicid_from_topo_ids)(X86CPUTopoInfo *topo_info, + const X86CPUTopoIDs *topo_ids); +uint32_t (*apicid_pkg_offset)(X86CPUTopoInfo *topo_info); + /* * Address space used by IOAPIC device. All IOAPIC interrupts * will be translated to MSI messages in the address space.
[PATCH v6 08/13] target/i386: Cleanup and use the EPYC mode topology functions
Use the new functions from topology.h and delete the unused code. Given the sockets, nodes, cores and threads, the new functions generate apic id for EPYC mode. Removes all the hardcoded values. Signed-off-by: Babu Moger Acked-by: Michael S. Tsirkin --- target/i386/cpu.c | 162 +++-- 1 file changed, 35 insertions(+), 127 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 2e5be37b21..a3051524a2 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -338,68 +338,15 @@ static void encode_cache_cpuid8006(CPUCacheInfo *l2, } } -/* - * Definitions used for building CPUID Leaf 0x801D and 0x801E - * Please refer to the AMD64 Architecture Programmer’s Manual Volume 3. - * Define the constants to build the cpu topology. Right now, TOPOEXT - * feature is enabled only on EPYC. So, these constants are based on - * EPYC supported configurations. We may need to handle the cases if - * these values change in future. - */ -/* Maximum core complexes in a node */ -#define MAX_CCX 2 -/* Maximum cores in a core complex */ -#define MAX_CORES_IN_CCX 4 -/* Maximum cores in a node */ -#define MAX_CORES_IN_NODE 8 -/* Maximum nodes in a socket */ -#define MAX_NODES_PER_SOCKET 4 - -/* - * Figure out the number of nodes required to build this config. - * Max cores in a node is 8 - */ -static int nodes_in_socket(int nr_cores) -{ -int nodes; - -nodes = DIV_ROUND_UP(nr_cores, MAX_CORES_IN_NODE); - - /* Hardware does not support config with 3 nodes, return 4 in that case */ -return (nodes == 3) ? 4 : nodes; -} - -/* - * Decide the number of cores in a core complex with the given nr_cores using - * following set constants MAX_CCX, MAX_CORES_IN_CCX, MAX_CORES_IN_NODE and - * MAX_NODES_PER_SOCKET. Maintain symmetry as much as possible - * L3 cache is shared across all cores in a core complex. So, this will also - * tell us how many cores are sharing the L3 cache. - */ -static int cores_in_core_complex(int nr_cores) -{ -int nodes; - -/* Check if we can fit all the cores in one core complex */ -if (nr_cores <= MAX_CORES_IN_CCX) { -return nr_cores; -} -/* Get the number of nodes required to build this config */ -nodes = nodes_in_socket(nr_cores); - -/* - * Divide the cores accros all the core complexes - * Return rounded up value - */ -return DIV_ROUND_UP(nr_cores, nodes * MAX_CCX); -} - /* Encode cache info for CPUID[801D] */ -static void encode_cache_cpuid801d(CPUCacheInfo *cache, CPUState *cs, -uint32_t *eax, uint32_t *ebx, -uint32_t *ecx, uint32_t *edx) +static void encode_cache_cpuid801d(CPUCacheInfo *cache, + X86CPUTopoInfo *topo_info, + uint32_t *eax, uint32_t *ebx, + uint32_t *ecx, uint32_t *edx) { uint32_t l3_cores; +unsigned nodes = MAX(topo_info->nodes_per_pkg, 1); + assert(cache->size == cache->line_size * cache->associativity * cache->partitions * cache->sets); @@ -408,10 +355,13 @@ static void encode_cache_cpuid801d(CPUCacheInfo *cache, CPUState *cs, /* L3 is shared among multiple cores */ if (cache->level == 3) { -l3_cores = cores_in_core_complex(cs->nr_cores); -*eax |= ((l3_cores * cs->nr_threads) - 1) << 14; +l3_cores = DIV_ROUND_UP((topo_info->dies_per_pkg * + topo_info->cores_per_die * + topo_info->threads_per_core), + nodes); +*eax |= (l3_cores - 1) << 14; } else { -*eax |= ((cs->nr_threads - 1) << 14); +*eax |= ((topo_info->threads_per_core - 1) << 14); } assert(cache->line_size > 0); @@ -431,55 +381,17 @@ static void encode_cache_cpuid801d(CPUCacheInfo *cache, CPUState *cs, (cache->complex_indexing ? CACHE_COMPLEX_IDX : 0); } -/* Data structure to hold the configuration info for a given core index */ -struct core_topology { -/* core complex id of the current core index */ -int ccx_id; -/* - * Adjusted core index for this core in the topology - * This can be 0,1,2,3 with max 4 cores in a core complex - */ -int core_id; -/* Node id for this core index */ -int node_id; -/* Number of nodes in this config */ -int num_nodes; -}; - -/* - * Build the configuration closely match the EPYC hardware. Using the EPYC - * hardware configuration values (MAX_CCX, MAX_CORES_IN_CCX, MAX_CORES_IN_NODE) - * right now. This could change in future. - * nr_cores : Total number of cores in the config - * core_id : Core index of the current CPU - * topo : Data structure to hold all the config info for this core index - */ -static void build_core_topology(int nr_cores, int core_id, -
[PATCH v6 03/13] machine: Add SMP Sockets in CpuTopology
Store the smp sockets in CpuTopology. The socket information required to build the apic id in EPYC mode. Right now socket information is not passed to down when decoding the apic id. Add the socket information here. Signed-off-by: Babu Moger Reviewed-by: Eduardo Habkost Reviewed-by: Igor Mammedov Acked-by: Michael S. Tsirkin --- hw/core/machine.c |1 + hw/i386/pc.c|1 + include/hw/boards.h |2 ++ softmmu/vl.c|1 + 4 files changed, 5 insertions(+) diff --git a/hw/core/machine.c b/hw/core/machine.c index 4778bc6b08..b958cd1b99 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -757,6 +757,7 @@ static void smp_parse(MachineState *ms, QemuOpts *opts) ms->smp.cpus = cpus; ms->smp.cores = cores; ms->smp.threads = threads; +ms->smp.sockets = sockets; } if (ms->smp.cpus > 1) { diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 662abb549d..05e7f1090f 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -781,6 +781,7 @@ void pc_smp_parse(MachineState *ms, QemuOpts *opts) ms->smp.cpus = cpus; ms->smp.cores = cores; ms->smp.threads = threads; +ms->smp.sockets = sockets; x86ms->smp_dies = dies; } diff --git a/include/hw/boards.h b/include/hw/boards.h index 9bc42dfb22..d01056286a 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -236,12 +236,14 @@ typedef struct DeviceMemoryState { * @cpus: the number of present logical processors on the machine * @cores: the number of cores in one package * @threads: the number of threads in one core + * @sockets: the number of sockets on the machine * @max_cpus: the maximum number of logical processors on the machine */ typedef struct CpuTopology { unsigned int cpus; unsigned int cores; unsigned int threads; +unsigned int sockets; unsigned int max_cpus; } CpuTopology; diff --git a/softmmu/vl.c b/softmmu/vl.c index ff2685dff8..dadb798ac7 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -3935,6 +3935,7 @@ void qemu_init(int argc, char **argv, char **envp) current_machine->smp.max_cpus = machine_class->default_cpus; current_machine->smp.cores = 1; current_machine->smp.threads = 1; +current_machine->smp.sockets = 1; machine_class->smp_parse(current_machine, qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
[PATCH v6 02/13] hw/i386: Consolidate topology functions
Now that we have all the parameters in X86CPUTopoInfo, we can just pass the structure to calculate the offsets and width. Signed-off-by: Babu Moger Reviewed-by: Igor Mammedov Acked-by: Michael S. Tsirkin --- include/hw/i386/topology.h | 68 +-- target/i386/cpu.c | 23 +++ tests/test-x86-cpuid.c | 69 +++- 3 files changed, 75 insertions(+), 85 deletions(-) diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h index 7ea507f376..ba52d49079 100644 --- a/include/hw/i386/topology.h +++ b/include/hw/i386/topology.h @@ -69,56 +69,42 @@ static unsigned apicid_bitwidth_for_count(unsigned count) /* Bit width of the SMT_ID (thread ID) field on the APIC ID */ -static inline unsigned apicid_smt_width(unsigned nr_dies, -unsigned nr_cores, -unsigned nr_threads) +static inline unsigned apicid_smt_width(X86CPUTopoInfo *topo_info) { -return apicid_bitwidth_for_count(nr_threads); +return apicid_bitwidth_for_count(topo_info->threads_per_core); } /* Bit width of the Core_ID field */ -static inline unsigned apicid_core_width(unsigned nr_dies, - unsigned nr_cores, - unsigned nr_threads) +static inline unsigned apicid_core_width(X86CPUTopoInfo *topo_info) { -return apicid_bitwidth_for_count(nr_cores); +return apicid_bitwidth_for_count(topo_info->cores_per_die); } /* Bit width of the Die_ID field */ -static inline unsigned apicid_die_width(unsigned nr_dies, -unsigned nr_cores, -unsigned nr_threads) +static inline unsigned apicid_die_width(X86CPUTopoInfo *topo_info) { -return apicid_bitwidth_for_count(nr_dies); +return apicid_bitwidth_for_count(topo_info->dies_per_pkg); } /* Bit offset of the Core_ID field */ -static inline unsigned apicid_core_offset(unsigned nr_dies, - unsigned nr_cores, - unsigned nr_threads) +static inline unsigned apicid_core_offset(X86CPUTopoInfo *topo_info) { -return apicid_smt_width(nr_dies, nr_cores, nr_threads); +return apicid_smt_width(topo_info); } /* Bit offset of the Die_ID field */ -static inline unsigned apicid_die_offset(unsigned nr_dies, - unsigned nr_cores, - unsigned nr_threads) +static inline unsigned apicid_die_offset(X86CPUTopoInfo *topo_info) { -return apicid_core_offset(nr_dies, nr_cores, nr_threads) + - apicid_core_width(nr_dies, nr_cores, nr_threads); +return apicid_core_offset(topo_info) + apicid_core_width(topo_info); } /* Bit offset of the Pkg_ID (socket ID) field */ -static inline unsigned apicid_pkg_offset(unsigned nr_dies, - unsigned nr_cores, - unsigned nr_threads) +static inline unsigned apicid_pkg_offset(X86CPUTopoInfo *topo_info) { -return apicid_die_offset(nr_dies, nr_cores, nr_threads) + - apicid_die_width(nr_dies, nr_cores, nr_threads); +return apicid_die_offset(topo_info) + apicid_die_width(topo_info); } /* Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID @@ -128,16 +114,9 @@ static inline unsigned apicid_pkg_offset(unsigned nr_dies, static inline apic_id_t apicid_from_topo_ids(X86CPUTopoInfo *topo_info, const X86CPUTopoIDs *topo_ids) { -unsigned nr_dies = topo_info->dies_per_pkg; -unsigned nr_cores = topo_info->cores_per_die; -unsigned nr_threads = topo_info->threads_per_core; - -return (topo_ids->pkg_id << - apicid_pkg_offset(nr_dies, nr_cores, nr_threads)) | - (topo_ids->die_id << - apicid_die_offset(nr_dies, nr_cores, nr_threads)) | - (topo_ids->core_id << - apicid_core_offset(nr_dies, nr_cores, nr_threads)) | +return (topo_ids->pkg_id << apicid_pkg_offset(topo_info)) | + (topo_ids->die_id << apicid_die_offset(topo_info)) | + (topo_ids->core_id << apicid_core_offset(topo_info)) | topo_ids->smt_id; } @@ -165,20 +144,15 @@ static inline void x86_topo_ids_from_apicid(apic_id_t apicid, X86CPUTopoInfo *topo_info, X86CPUTopoIDs *topo_ids) { -unsigned nr_dies = topo_info->dies_per_pkg; -unsigned nr_cores = topo_info->cores_per_die; -unsigned nr_threads = topo_info->threads_per_core; - topo_ids->smt_id = apicid & -~(0xUL << apicid_smt_width(nr_dies, nr_cores, nr_threads)); +~(0xUL << apicid_smt_width(topo_info)); topo_ids->core_id = -
[PATCH v6 07/13] hw/386: Add EPYC mode topology decoding functions
These functions add support for building EPYC mode topology given the smp details like numa nodes, cores, threads and sockets. The new apic id decoding is mostly similar to current apic id decoding except that it adds a new field node_id when numa configured. Removes all the hardcoded values. Subsequent patches will use these functions to build the topology. Following functions are added. apicid_llc_width_epyc apicid_llc_offset_epyc apicid_pkg_offset_epyc apicid_from_topo_ids_epyc x86_topo_ids_from_idx_epyc x86_topo_ids_from_apicid_epyc x86_apicid_from_cpu_idx_epyc The topology details are available in Processor Programming Reference (PPR) for AMD Family 17h Model 01h, Revision B1 Processors. The revision guides are available from the bugzilla Link below. Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537 Signed-off-by: Babu Moger Acked-by: Igor Mammedov Acked-by: Michael S. Tsirkin --- include/hw/i386/topology.h | 100 1 file changed, 100 insertions(+) diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h index b9593b9905..07239f95f4 100644 --- a/include/hw/i386/topology.h +++ b/include/hw/i386/topology.h @@ -47,6 +47,7 @@ typedef uint32_t apic_id_t; typedef struct X86CPUTopoIDs { unsigned pkg_id; +unsigned node_id; unsigned die_id; unsigned core_id; unsigned smt_id; @@ -88,6 +89,11 @@ static inline unsigned apicid_die_width(X86CPUTopoInfo *topo_info) return apicid_bitwidth_for_count(topo_info->dies_per_pkg); } +/* Bit width of the node_id field per socket */ +static inline unsigned apicid_node_width_epyc(X86CPUTopoInfo *topo_info) +{ +return apicid_bitwidth_for_count(MAX(topo_info->nodes_per_pkg, 1)); +} /* Bit offset of the Core_ID field */ static inline unsigned apicid_core_offset(X86CPUTopoInfo *topo_info) @@ -108,6 +114,100 @@ static inline unsigned apicid_pkg_offset(X86CPUTopoInfo *topo_info) return apicid_die_offset(topo_info) + apicid_die_width(topo_info); } +#define NODE_ID_OFFSET 3 /* Minimum node_id offset if numa configured */ + +/* + * Bit offset of the node_id field + * + * Make sure nodes_per_pkg > 0 if numa configured else zero. + */ +static inline unsigned apicid_node_offset_epyc(X86CPUTopoInfo *topo_info) +{ +unsigned offset = apicid_die_offset(topo_info) + + apicid_die_width(topo_info); + +if (topo_info->nodes_per_pkg) { +return MAX(NODE_ID_OFFSET, offset); +} else { +return offset; +} +} + +/* Bit offset of the Pkg_ID (socket ID) field */ +static inline unsigned apicid_pkg_offset_epyc(X86CPUTopoInfo *topo_info) +{ +return apicid_node_offset_epyc(topo_info) + + apicid_node_width_epyc(topo_info); +} + +/* + * Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID + * + * The caller must make sure core_id < nr_cores and smt_id < nr_threads. + */ +static inline apic_id_t +x86_apicid_from_topo_ids_epyc(X86CPUTopoInfo *topo_info, + const X86CPUTopoIDs *topo_ids) +{ +return (topo_ids->pkg_id << apicid_pkg_offset_epyc(topo_info)) | + (topo_ids->node_id << apicid_node_offset_epyc(topo_info)) | + (topo_ids->die_id << apicid_die_offset(topo_info)) | + (topo_ids->core_id << apicid_core_offset(topo_info)) | + topo_ids->smt_id; +} + +static inline void x86_topo_ids_from_idx_epyc(X86CPUTopoInfo *topo_info, + unsigned cpu_index, + X86CPUTopoIDs *topo_ids) +{ +unsigned nr_nodes = MAX(topo_info->nodes_per_pkg, 1); +unsigned nr_dies = topo_info->dies_per_pkg; +unsigned nr_cores = topo_info->cores_per_die; +unsigned nr_threads = topo_info->threads_per_core; +unsigned cores_per_node = DIV_ROUND_UP((nr_dies * nr_cores * nr_threads), +nr_nodes); + +topo_ids->pkg_id = cpu_index / (nr_dies * nr_cores * nr_threads); +topo_ids->node_id = (cpu_index / cores_per_node) % nr_nodes; +topo_ids->die_id = cpu_index / (nr_cores * nr_threads) % nr_dies; +topo_ids->core_id = cpu_index / nr_threads % nr_cores; +topo_ids->smt_id = cpu_index % nr_threads; +} + +/* + * Calculate thread/core/package IDs for a specific topology, + * based on APIC ID + */ +static inline void x86_topo_ids_from_apicid_epyc(apic_id_t apicid, +X86CPUTopoInfo *topo_info, +X86CPUTopoIDs *topo_ids) +{ +topo_ids->smt_id = apicid & +~(0xUL << apicid_smt_width(topo_info)); +topo_ids->core_id = +(apicid >> apicid_core_offset(topo_info)) & +~(0xUL << apicid_core_width(topo_info)); +topo_ids->die_id = +(apicid >> apicid_die_offset(topo_info)) & +~(0xUL << apicid_die_width(topo_info)); +topo_ids->node_id = +(apicid >>
[PATCH v6 01/13] hw/i386: Introduce X86CPUTopoInfo to contain topology info
This is an effort to re-arrange few data structure for better readability. 1. Add X86CPUTopoInfo which will have all the topology informations required to build the cpu topology. There is no functional changes. 2. Introduce init_topo_info to initialize X86CPUTopoInfo members from X86MachineState. 3. Update x86 unit tests for new calling convention with parameter X86CPUTopoInfo There is no functional changes. Signed-off-by: Babu Moger --- hw/i386/pc.c | 12 ++-- hw/i386/x86.c | 32 include/hw/i386/topology.h | 38 -- include/hw/i386/x86.h |3 +++ tests/test-x86-cpuid.c | 43 --- 5 files changed, 81 insertions(+), 47 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index f52e84b2ba..662abb549d 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1513,6 +1513,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, X86MachineState *x86ms = X86_MACHINE(pcms); unsigned int smp_cores = ms->smp.cores; unsigned int smp_threads = ms->smp.threads; +X86CPUTopoInfo topo_info; if(!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { error_setg(errp, "Invalid CPU type, expected cpu type: '%s'", @@ -1520,6 +1521,8 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, return; } +init_topo_info(_info, x86ms); + env->nr_dies = x86ms->smp_dies; /* @@ -1575,16 +1578,14 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, topo_ids.die_id = cpu->die_id; topo_ids.core_id = cpu->core_id; topo_ids.smt_id = cpu->thread_id; -cpu->apic_id = apicid_from_topo_ids(x86ms->smp_dies, smp_cores, -smp_threads, _ids); +cpu->apic_id = apicid_from_topo_ids(_info, _ids); } cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, ); if (!cpu_slot) { MachineState *ms = MACHINE(pcms); -x86_topo_ids_from_apicid(cpu->apic_id, x86ms->smp_dies, - smp_cores, smp_threads, _ids); +x86_topo_ids_from_apicid(cpu->apic_id, _info, _ids); error_setg(errp, "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with" " APIC ID %" PRIu32 ", valid index range 0:%d", @@ -1605,8 +1606,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, /* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn() * once -smp refactoring is complete and there will be CPU private * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */ -x86_topo_ids_from_apicid(cpu->apic_id, x86ms->smp_dies, - smp_cores, smp_threads, _ids); +x86_topo_ids_from_apicid(cpu->apic_id, _info, _ids); if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) { error_setg(errp, "property socket-id: %u doesn't match set apic-id:" " 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 322fb6abbc..03b8962c98 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -57,6 +57,16 @@ /* Physical Address of PVH entry point read from kernel ELF NOTE */ static size_t pvh_start_addr; +inline void init_topo_info(X86CPUTopoInfo *topo_info, + const X86MachineState *x86ms) +{ +MachineState *ms = MACHINE(x86ms); + +topo_info->dies_per_pkg = x86ms->smp_dies; +topo_info->cores_per_die = ms->smp.cores; +topo_info->threads_per_core = ms->smp.threads; +} + /* * Calculates initial APIC ID for a specific CPU index * @@ -68,13 +78,14 @@ static size_t pvh_start_addr; uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms, unsigned int cpu_index) { -MachineState *ms = MACHINE(x86ms); X86MachineClass *x86mc = X86_MACHINE_GET_CLASS(x86ms); +X86CPUTopoInfo topo_info; uint32_t correct_id; static bool warned; -correct_id = x86_apicid_from_cpu_idx(x86ms->smp_dies, ms->smp.cores, - ms->smp.threads, cpu_index); +init_topo_info(_info, x86ms); + +correct_id = x86_apicid_from_cpu_idx(_info, cpu_index); if (x86mc->compat_apic_id_mode) { if (cpu_index != correct_id && !warned && !qtest_enabled()) { error_report("APIC IDs set in compatibility mode, " @@ -145,19 +156,22 @@ int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx) { X86CPUTopoIDs topo_ids; X86MachineState *x86ms = X86_MACHINE(ms); + X86CPUTopoInfo topo_info; + + init_topo_info(_info, x86ms); assert(idx < ms->possible_cpus->len); x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id, -x86ms->smp_dies, ms->smp.cores, -ms->smp.threads, _ids); +
[PATCH v6 00/13] APIC ID fixes for AMD EPYC CPU model
This series fixes APIC ID encoding problem reported on AMD EPYC cpu models. https://bugzilla.redhat.com/show_bug.cgi?id=1728166 Currently, the APIC ID is decoded based on the sequence sockets->dies->cores->threads. This works for most standard AMD and other vendors' configurations, but this decoding sequence does not follow that of AMD's APIC ID enumeration strictly. In some cases this can cause CPU topology inconsistency. When booting a guest VM, the kernel tries to validate the topology, and finds it inconsistent with the enumeration of EPYC cpu models. To fix the problem we need to build the topology as per the Processor Programming Reference (PPR) for AMD Family 17h Model 01h, Revision B1 Processors. The documentation is available from the bugzilla Link below. Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537 Here is the text from the PPR. Operating systems are expected to use Core::X86::Cpuid::SizeId[ApicIdSize], the number of least significant bits in the Initial APIC ID that indicate core ID within a processor, in constructing per-core CPUID masks. Core::X86::Cpuid::SizeId[ApicIdSize] determines the maximum number of cores (MNC) that the processor could theoretically support, not the actual number of cores that are actually implemented or enabled on the processor, as indicated by Core::X86::Cpuid::SizeId[NC]. Each Core::X86::Apic::ApicId[ApicId] register is preset as follows: • ApicId[6] = Socket ID. • ApicId[5:4] = Node ID. • ApicId[3] = Logical CCX L3 complex ID • ApicId[2:0]= (SMT) ? {LogicalCoreID[1:0],ThreadId} : {1'b0,LogicalCoreID[1:0]} v6: Generated the patches on top of git://github.com/ehabkost/qemu.git (x86-next). Changes from v5. 1. Eduardo has already queued couple of patches, submitting the rest here. 2. Major change is how the EPYC mode apic id encoding handlers are loaded. Added a boolean variable use_epyc_apic_id_encoding in X86CPUDefinition. The variable is will be used to tell if we need to use EPYC mode encoding. 3. Eduardo reported bysectability problem with x86 unit test code. Quashed the patches in 1 and 2 to resolve it. Problem was change in calling conventions of topology related functions. 4. Also set the use_epyc_apic_id_encoding for EPYC-Rome. This model is added recently to the cpu table. v5: https://lore.kernel.org/qemu-devel/158326531474.40452.11433722850425537745.st...@naples-babu.amd.com/ Generated the patches on top of git://github.com/ehabkost/qemu.git (x86-next). Changes from v4. 1. Re-arranged the patches 2 and 4 as suggested by Igor. 2. Kept the apicid handler functions inside X86MachineState as discussed. These handlers are loaded from X86CPUDefinitions. 3. Removed unnecessary X86CPUstate initialization from x86_cpu_new. Suggested by Igor. 4. And other minor changes related to patch format. v4: https://lore.kernel.org/qemu-devel/158161767653.48948.10578064482878399556.st...@naples-babu.amd.com/ Changes from v3. 1. Moved the arch_id calculation inside the function x86_cpus_init. With this change, we dont need to change common numa code.(suggested by Igor) 2. Introduced the model specific handlers inside X86CPUDefinitions. These handlers are loaded into X86MachineState during the init. 3. Removed llc_id from x86CPU. 4. Removed init_apicid_fn hanlder from MachineClass. Kept all the code changes inside the x86. 5. Added new handler function apicid_pkg_offset for pkg_offset calculation. 6. And some Other minor changes. v3: https://lore.kernel.org/qemu-devel/157541968844.46157.17994918142533791313.st...@naples-babu.amd.com/ 1. Consolidated the topology information in structure X86CPUTopoInfo. 2. Changed the ccx_id to llc_id as commented by upstream. 3. Generalized the apic id decoding. It is mostly similar to current apic id except that it adds new field llc_id when numa configured. Removes all the hardcoded values. 4. Removed the earlier parse_numa split. And moved the numa node initialization inside the numa_complete_configuration. This is bit cleaner as commented by Eduardo. 5. Added new function init_apicid_fn inside machine_class structure. This will be used to update the apic id handler specific to cpu model. 6. Updated the cpuid unit tests. 7. TODO : Need to figure out how to dynamically update the handlers using cpu models. I might some guidance on that. v2: https://lore.kernel.org/qemu-devel/156779689013.21957.1631551572950676212.stgit@localhost.localdomain/ 1. Introduced the new property epyc to enable new epyc mode. 2. Separated the epyc mode and non epyc mode function. 3. Introduced function pointers in PCMachineState to handle the differences. 4. Mildly tested different combinations to make things are working as expected. 5. TODO : Setting the epyc feature bit needs to be worked out. This feature is supported only on AMD EPYC models. I may need some guidance on that. v1:
Questions about pollute the mail list archives
Hi, forks When I sent vector extension patchset v3(2020/03/09), my mail system works some wrong, and only part of the patchset were sent. When I try to send again, it either can't work. Even more, I found the mail list archives were polluted, many repetitions and scattered in many threads. And no thread is complete. Is it serious? Is there any way to clear it in the mail list archives? Can I send it again to the mail list? Zhiwei
RE: [PATCH v3 02/12] block/iscsi:Remove redundant statement in iscsi_open()
>-Original Message- >From: Laurent Vivier [mailto:laur...@vivier.eu] >Sent: Tuesday, March 10, 2020 11:02 PM >To: Kevin Wolf ; Chenqun (kuhn) > >Cc: peter.mayd...@linaro.org; Zhanghailiang >; qemu-triv...@nongnu.org; Peter Lieven >; qemu-devel@nongnu.org; Max Reitz ; >Ronnie Sahlberg ; Euler Robot >; Paolo Bonzini >Subject: Re: [PATCH v3 02/12] block/iscsi:Remove redundant statement in >iscsi_open() > >Le 10/03/2020 à 15:26, Kevin Wolf a écrit : >> Am 02.03.2020 um 14:07 hat Chen Qun geschrieben: >>> Clang static code analyzer show warning: >>> block/iscsi.c:1920:9: warning: Value stored to 'flags' is never read >>> flags &= ~BDRV_O_RDWR; >>> ^ >>> >>> Reported-by: Euler Robot >>> Signed-off-by: Chen Qun >>> --- >>> Cc: Ronnie Sahlberg >>> Cc: Paolo Bonzini >>> Cc: Peter Lieven >>> Cc: Kevin Wolf >>> Cc: Max Reitz >>> >>> v1->v2: >>> Keep the 'flags' then use it(Base on Kevin's comments). >> >> I think this patch wants a different subject line now. > Yes, it needs a more appropriate subject. >It needs also a better explanation in the commit message and should not go >through trivial as the change is not obvious. > OK , I will update the commit message base on existing comments. Thanks. >Thanks, >Laurent > >> >>> diff --git a/block/iscsi.c b/block/iscsi.c index >>> 682abd8e09..50bae51700 100644 >>> --- a/block/iscsi.c >>> +++ b/block/iscsi.c >>> @@ -2002,7 +2002,7 @@ static int iscsi_open(BlockDriverState *bs, QDict >*options, int flags, >>> iscsilun->cluster_size = iscsilun->bl.opt_unmap_gran * >>> iscsilun->block_size; >>> if (iscsilun->lbprz) { >>> -ret = iscsi_allocmap_init(iscsilun, bs->open_flags); >>> +ret = iscsi_allocmap_init(iscsilun, flags); >>> } >>> } >> >> The code looks good. >> >> Reviewed-by: Kevin Wolf >> >>
Re: [PATCH RESEND 1/3] vfio/pci: fix a null pointer reference in vfio_rom_read
On Wed, 11 Mar 2020 00:14:31 +0100 Laszlo Ersek wrote: > On 03/10/20 17:11, Alex Williamson wrote: > > > commit 2088fc1e1f426b98e9ca4d7bcdbe53d886a18c37 > > Author: Alex Williamson > > Date: Tue Mar 10 10:04:36 2020 -0600 > > > > vfio/pci: Use defined memcpy() behavior > > > > vfio_rom_read() relies on memcpy() doing the logically correct thing, > > ie. safely copying zero bytes from a NULL pointer when rom_size is > > zero, rather than the spec definition, which is undefined when the > > source or target pointers are NULL. Resolve this by wrapping the > > call in the condition expressed previously by the ternary. > > > > Additionally, we still use @val to fill data based on the provided > > @size regardless of mempcy(), so we should initialize @val rather > > than @data. > > > > Reported-by: Longpeng > > Reported-by: Laszlo Ersek > > Signed-off-by: Alex Williamson > > > > diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c > > index 5e75a95129ac..b0799cdc28ad 100644 > > --- a/hw/vfio/pci.c > > +++ b/hw/vfio/pci.c > > @@ -859,16 +859,17 @@ static uint64_t vfio_rom_read(void *opaque, hwaddr > > addr, unsigned size) > > uint16_t word; > > uint32_t dword; > > uint64_t qword; > > -} val; > > -uint64_t data = 0; > > +} val = { 0 }; > > +uint64_t data; > > > > /* Load the ROM lazily when the guest tries to read it */ > > if (unlikely(!vdev->rom && !vdev->rom_read_failed)) { > > vfio_pci_load_rom(vdev); > > } > > > > -memcpy(, vdev->rom + addr, > > - (addr < vdev->rom_size) ? MIN(size, vdev->rom_size - addr) : 0); > > +if (addr < vdev->rom_size) { > > +memcpy(, vdev->rom + addr, MIN(size, vdev->rom_size - addr)); > > +} > > > > switch (size) { > > case 1: > > Regarding the pre-patch code: > > My understanding is that the memcpy() could be reached with a > guest-originated "addr" even if "vdev->rom" was NULL. If that's the > case, then the pre-patch code invokes undefined behavior regardless of > memcpy(), because it performs pointer arithmetic on a null pointer (not > to mention that the type of that pointer is (void *)) > > Regarding the proposed change: > > (addr < vdev->rom_size) requires that "vdev->rom_size" be positive. In > that case, I assume that > > - "vdev->rom" is not NULL, and > - MIN(size, vdev->rom_size - addr) bytes are "in range" for the object > allocated at "vdev->rom". > > So from a memcpy() and range perspective, the patch looks OK. But > there's still a wart I dislike: we should never perform pointer > arithmetic on a (void*). I suggest casting (vdev->rom) to (uint8_t*) or > (unsigned char*) first. > > Here's an excerpt from the ISO C99 standard: > > -v- > 6.5.6 Additive operators > > Constraints > > 2 For addition, either both operands shall have arithmetic type, or one > operand shall be a pointer to an object type and the other shall have > integer type. [...] > -^- > > A "pointer-to-void" is not a "pointer to an object type", because "void" > is not an object type -- it is an incomplete type that cannot be completed: > > -v- > 6.2.5 Types > > 1 [...] Types are partitioned into object types (types that fully > describe objects), function types (types that describe functions), and > incomplete types (types that describe objects but lack information > needed to determine their sizes). > > [...] > > 19 The void type comprises an empty set of values; it is an incomplete >type that cannot be completed. > -^- > > For a different illustration, (vdev->rom + addr) is equivalent to > &(vdev->rom[addr]) -- and we clearly can't have an "array of void". > > This anti-pattern (of doing pointer arithmetic on (void*)) likely comes > from a guarantee that the standard does make, in the same "6.2.5 Types" > section: > > -v- > 27 A pointer to void shall have the same representation and alignment >requirements as a pointer to a character type. 39) [...] > > Footnote 39: The same representation and alignment requirements are > meant to imply interchangeability as arguments to > functions, return values from functions, and members of > unions. > -^- > > It does not extend to the "+" operator. GNU C specifically allows arithmetic on pointers and defines the size of a void as 1. I'll comply, but this makes me want to stab myself in the face :-\ Thanks, Alex
Re: [PATCH v4 10/11] 9pfs: T_readdir latency optimization
On Dienstag, 10. März 2020 19:33:36 CET Greg Kurz wrote: > > This patch is also too big for my preference, but I don't see a viable way > > to split it further into separate patches. I already separated all the > > patches I could. If you have suggestions, very much appreciated! > > Well, the patch could be split in two or three parts at least: > > (1) introduce the new function that reads multiple entries in codir.c > > (2) use it from 9p.c > > (3) remove unused stuff if anything remains > > This doesn't seem to change much but the smaller diffstats > for each individual patch make them less scary :) and with > (1) applied only it is easier to compare what the old code > in 9p.c and the new one in codir.c do. > > > The reason for this is that in order to fix these issues with current > > T_readdir implementation, it requires to separate what's currently one > > task > > (i.e. one function) into two separate tasks (i.e. two functions). There is > > no sensible way to do that. > > Yeah, I won't ask for finer grain. Me confused. Does that mean your split suggestion was just theoretical, or do you need it? > > But don't be too scared about this patch; if you look just at the diff > > directly then yes, the diff is not very human readable. However if you > > apply the patch and look at the resulting code, you'll notice that there > > are actually only 2 functions (v9fs_do_readdir() in 9p.c and > > do_readdir_lowlat() in codir.c) which require careful reviewing and that > > their resulting code is actually very, very straight forward, and not > > long either. > > These are personal opinions. Careful reviewing can take a lot of time :) Well, depends on what precisely you mean with opinion. :) That this patch actually reduces code complexity is a fact (less branches, less locks, less dispatches, less side effects, less error/cleanup handlers). These are objectively measurable quantities. But yes, nevertheless reviewing it costs time. > > Current code on master is much more tricky and error prone due to the huge > > amount of potential branches, individual error/cleanup handlers, high > > amount of thread dispatching and much more. In the patched version all > > these code complexities and error sources are removed. > > Come on :) The 9pfs code has been a can of worms from the beginning. > It produced more than the average amount of security-related bugs, > and most sadly, due to the overall lack of interest, it bitrotted > and missed a lot of cool improvements like an appropriate support of > unlinked files, QOM-ification of fsdev, conversion of proxy fsdev to > vhost-user, hot plug/unplug support, live migration support and > "much more"... The performance aspect of things is a full time job No, the performance issues are actually very managable in case of 9pfs. I already addressed readdir with this patch (by far the worst performance issue), and then there would just be one more severe performance issue: walkdir. My intention is not to squeeze out the last fractional percent of performance for 9pfs, but you certainly agree that a simple "ls" blocking for more than 1 second is something that should be fixed, and fortunately the amount of changes involved are far less than I originally feared they would. > I never had the opportunity to even consider. So yes, your changes > are likely beneficial but the code base is still extremely fragile > and sensible to huge changes... not breaking things that happen > to work, even in a sub-optimal way, is essentially what I care for > these days. And I think I'm also very careful not breaking anything. I carefully consider what to touch and what not. I wrote test cases and I am actively testing my changes with real installations and snapshots as well. I think the cause of disagreements we have are solely our use cases of 9pfs: your personal use case does not seem to require any performance considerations or multi-user aspects, whereas my use case requires at least some minimum performance grade for utilizing 9pfs for server applications. > > > Oh, so we'd still have the current implementation being used, even > > > with this patch applied... This would be okay for a RFC patch but > > > in the end I'd really like to merge something that also converts > > > v9fs_do_readdir_with_stat(). > > > > Yes, I know, but I would not recommend mixing these things at this point, > > because it would be an entire effort on its own. > > > > v9fs_do_readdir_with_stat() is used for 9P2000.u, while v9fs_do_readdir() > > is used for 9P2000.L. They're behaving very differently, so it would not > > only require me to update v9fs_do_readdir_with_stat() and v9fs_read(), I > > would also need to write their own test cases (plural, since there are > > none at all yet) and benchmarks, and of course somebody what need to > > review all that additional amount of code, and who would actually test > > it? I am actively testing my 9P2000.L changes, but I am not actually
Re: Upstream QEMU guest support policy ? Re: [PATCH v3 0/2] spapr: Use vIOMMU translation for virtio by default
On Tue, Mar 10, 2020 at 11:43:43AM +, Daniel P. Berrangé wrote: > On Thu, Mar 05, 2020 at 03:30:07PM +1100, David Gibson wrote: > > Upcoming Secure VM support for pSeries machines introduces some > > complications for virtio, since the transfer buffers need to be > > explicitly shared so that the hypervisor can access them. > > > > While it's not strictly speaking dependent on it, the fact that virtio > > devices bypass normal platform IOMMU translation complicates the issue > > on the guest side. Since there are some significan downsides to > > bypassing the vIOMMU anyway, let's just disable that. > > > > There's already a flag to do this in virtio, just turn it on by > > default for forthcoming pseries machine types. > > Breaking existing guest OS to support a new secure VM feature that > may not even be used/wanted doesn't seems like a sensible tradeoff > for default out of the box behaviour. > > IOW, if Secure VM needs this, can we tie the change in virtio and > IOMMU defaults to the machine type flag that enables the use of > Secure VM. There is no such flag. In the POWER secure VM model, the secure mode option isn't something that's constructed in when the hypervisor builds the VM. Instead the VM is started normally and transitions itself to secure mode by talking directly with the ultravisor (it then uses TPM shenannigans to safely get the keys to its real storage backend(s)). > That way the changed virtio defaults only take effect if a user/mgmt > app has explicitly opted in to the new Secure VM feature, and existing > users won't be broken by a new feature they don't even use. Sure, but qemu has no natural way to know if secure VM is in use, until too late. I am wondering if we have to introduce an "svm=on" flag anyway. It's pretty ugly, since all it would be doing is changing defaults here and there for compatibilty with a possible future SVM transition, but maybe it's the best we can do :/. > > Any opinions on whether dropping support for the older guest kernels > > is acceptable at this point? > > > I think this question has different answers depending on whether you > are considering downstream vendor policy, current upstream policy, > and a possible new downstream policy on guest support. IOW a bit of a > can of worms... > > > In the case of RHEL downstream there is a very narrow matrix for > what guest OS are considered supported. > > In the case of current upstream, there has essentially never been > any documented guest matrix. The unwritten implicit rule upstream > has followed is to not change defaults in a way that would break > ability to run existing guest OS. Hrm, ok, that's not how I've been treating it for for pseries, though previous breakages have been for much older / rarer cases. We broke support for guests that don't call "ibm,client-architecture-support" long, long ago (but such guests are really, really ancient). We broke support (without workarounds) for guests with 4kiB standard page size more recently, but those are at least a decade old for common downstream distros (you can build such kernels today, but approximately nobody does). > As an example, on x86 upstream defaults to i440fx and thus still > uses virtio devices in transitional mode by default, while downstream > RHEL used its narrow support matrix as a justification for why it was > ok to switch to q35 by default & loose guest support in many cases. > Even that was problematic though, because RHEL still needed to support > RHEL-6 guest which are broken by default with q35 since they only > support legacy mode virtio. Thus we needed work in management apps > to enable RHEL-6 to continue working with q35 chipset, by placing > the devices onto a PCI bridge, instead of a PCIe root port, or by > explicitly using i440fx instead. Yeah, and here's where x86's visibility with mgmt because a big thing. Most of these changes are easily enough worked around with machine type options - and there's no inherent reason those are harder to work with than whole machine types, or other config details. But getting mgmt apps to support machine option based workarounds for us is a real challenge. > Thus if we follow our *current* upstream guest support policy, I don't > think it is acceptable to break existing guests with the new machine > type upstream. It is reasonable to do it downstream if the downstream > is willing to sacrifice these guests, or invest to make any mgmt apps > add workaround/revert QEMU changes. > > > With that all said, I do *NOT* think current upstream practice is good > or sustainable long term (though I admit I've argued on the other side > in the past). > > This policy is why we're still using a machine designed in 1995 on x86 > by default, in order that we avoid breaking the popular guest OS of the > day, like Windows 95. > > This is similar to the problem we had with host build platforms, where > we afraid to make any change which would break an existing build platform,
Re: [PATCH v3 1/2] spapr: Disable legacy virtio devices for pseries-5.0 and later
On Tue, Mar 10, 2020 at 11:56:11AM +, Daniel P. Berrangé wrote: > On Thu, Mar 05, 2020 at 03:30:08PM +1100, David Gibson wrote: > > PAPR specifies a kind of odd, paravirtualized PCI bus, which looks to > > the guess mostly like classic PCI, even if some of the individual > > devices on the bus are PCI Express. One consequence of that is that > > virtio-pci devices still default to being in transitional mode, though > > legacy mode is now disabled by default on current q35 x86 machine > > types. > > Two things to note here > > x86 defaults to the i440fx machine type, and so defaults > to transitional mode. AFAIK, only RHEL-8 downstream changed > x86 to defualt to q35 > > With q35 whether you get transitional mode or not is actually > dependent on where you place the device. If it is placed into > a PCIe root port, then it is modern-only. If it is placed into > a PCI bridge, then it is transitional still. Yes, I'm aware. > > Legacy mode virtio devices aren't really necessary any more, and are > > Legacy mode is required for RHEL-6 which has not reached EOL yet. Yeah.. I'm concerned about this, but I'm not sure what to do about it. > > causing some problems for future changes. Therefore, for the > > pseries-5.0 machine type (and onwards), switch to modern-only > > virtio-pci devices by default. > > The challenge I see with pseries, as compared to x86 is around > how apps deal with mgmt / guest setup. With x86 there are > distinct machine types i440fx / q35, so mgmt apps could decide > what todo based on the chipset & device support. eg they can > determine whether the guest supports PCIe at all, and they > can determine whether the guest supports virtio-1.0. Thus > they can decide between three options > > - Use i440fx > - Use q35 with placement in PCI bridge > - Use q35 with placement in PCIe root port > > These rules applies no matter what version of q35/i440fx > is in use. Yeah.. x86 also has the advantage of enough visibility that it can reasonbly easily get mgmt layers to do stuff about it. This is much harder for POWER :/. > With PPC, we're changing behaviour of the existing pseries > machine type in a minor version. Management apps need to > avoid creating logic that depends on a specific minor version > because these version numbers are all changed by downstream > distro vendors. IOW, as a comparison to x86, this change is > akin to altering behaviour of the i440fx machine type so > that it disables legacy mode despite still being PCI, and > not PCIe. > > Is there any liklihood we'll ever introduce a true PCIe > based machine type for PPC, so we get something much > closer to x86/aarch64 machine types in terms of PCIe > architecture ? It doesn't really make sense to do so. For x86 - or more strictly for pc - the change from PCI to PCIe is a pretty fundamental system change with affects in lots of places, which makes a whole new versioned series of machine types a reasonable option. For pseries - that's not really the case. PCI under PAPR is paravirtualized, and it always has been. The interface we're matching is not real hardware, but the PAPR spec and to a lesser extent the existing PowerVM implementation of it. [Aside: you've made a subtle but common x86-centric assumption above that there's only one important platform design per ISA. There is a real PCIe based PPC machine type in "pnv" (and maybe some of the embedded ones as well), but that's not the environment we care about for guests in production, since we can't use KVM with it] What PAPR has is an odd hybrid - individual devices can be PCIe (we have calls to access extended config space) - but the overall bus structure is more-or-less like vanilla PCI. I think it would be possible to kind of expose a more PCIe like structure, but a) it would be weirdly artificial, b) it doesn't match the PAPR interfaces very well, c) it would make our behaviour different from PowerVM. It would certainly be possible to better handle PCIe devices on a root bus. That's been on my todo someday list for ages, but I've kept putting it off because the tangible benefits are pretty minimal. Note that several things that I believe are now in the PCIe spec, but really derive more from PC legacy considerations, don't apply at all for PAPR. e.g. there's no meaningful distinction between integrated and slotted devices, multiple independent host bridges is routine and doesn't require any (virtual) hardware visible domain numbers. > > This does mean we no longer support guest kernels prior to 4.0, unless > > they have modern virtio support backported (which some distro kernels > > like that in RHEL7 do). > > > > Signed-off-by: David Gibson > > --- > > hw/ppc/spapr.c | 17 + > > 1 file changed, 17 insertions(+) > > > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > > index 2eb0d8f70d..3cfc98ac61 100644 > > --- a/hw/ppc/spapr.c > > +++ b/hw/ppc/spapr.c > > @@ -65,6 +65,7 @@ > > > > #include "hw/pci/pci.h" > >
RE: [PATCH] hw/scsi/megasas:Clean up some redundant code fix Clang warnings
>-Original Message- >From: Peter Maydell [mailto:peter.mayd...@linaro.org] >Sent: Tuesday, March 10, 2020 9:47 PM >To: Chenqun (kuhn) >Cc: QEMU Developers ; QEMU Trivial triv...@nongnu.org>; Fam Zheng ; Hannes Reinecke >; Zhanghailiang ; >Qemu-block ; Euler Robot >; Paolo Bonzini >Subject: Re: [PATCH] hw/scsi/megasas:Clean up some redundant code fix >Clang warnings > >On Tue, 10 Mar 2020 at 13:10, Chen Qun >wrote: >> >> Here are some redundant statements, we can clean them up. >> Clang static code analyzer show warning: >> hw/scsi/megasas.c:1175:32: warning: Value stored to 'max_ld_disks' during >its initialization is never read >> uint32_t num_ld_disks = 0, max_ld_disks = s->fw_luns; >>^~~~ ~~ >> hw/scsi/megasas.c:1183:9: warning: Value stored to 'max_ld_disks' is never >read >> max_ld_disks = 0; >> ^ ~ >> >> Reported-by: Euler Robot >> Signed-off-by: Chen Qun >> --- >> Cc: Paolo Bonzini >> Cc: Fam Zheng >> Cc: Hannes Reinecke >> Cc: qemu-bl...@nongnu.org >> --- >> hw/scsi/megasas.c | 3 +-- >> 1 file changed, 1 insertion(+), 2 deletions(-) >> >> diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index >> af18c88b65..3f982e1d3b 100644 >> --- a/hw/scsi/megasas.c >> +++ b/hw/scsi/megasas.c >> @@ -1172,7 +1172,7 @@ static int >megasas_dcmd_ld_list_query(MegasasState *s, MegasasCmd *cmd) >> uint16_t flags; >> struct mfi_ld_targetid_list info; >> size_t dcmd_size = sizeof(info), resid; >> -uint32_t num_ld_disks = 0, max_ld_disks = s->fw_luns; >> +uint32_t num_ld_disks = 0, max_ld_disks; >> BusChild *kid; >> >> /* mbox0 contains flags */ >> @@ -1180,7 +1180,6 @@ static int >megasas_dcmd_ld_list_query(MegasasState *s, MegasasCmd *cmd) >> trace_megasas_dcmd_ld_list_query(cmd->index, flags); >> if (flags != MR_LD_QUERY_TYPE_ALL && >> flags != MR_LD_QUERY_TYPE_EXPOSED_TO_HOST) { >> -max_ld_disks = 0; >> } > >This doesn't look right -- your change removes the only statement in the body >of this "if". I think you need to examine what the function is trying to do >with >the test it is doing on these flags in order to identify what the right change >is... > Ah, sorry for trouble, it is not a mistake that should happen. I should double check it next time. >Probably this means going back to the h/w spec to identify the correct >behaviour overall. > Yes, I should go back the hw spec in order to understand the behaviour overall. Thanks. Chen Qun
Re: [PATCH] util: fix to get configuration macros in util/mmap-alloc.c
On 3/10/2020 5:12 PM, Michael S. Tsirkin wrote: On Tue, Mar 10, 2020 at 04:58:38PM +0800, Liu, Jingqi wrote: On 3/9/2020 9:35 PM, Peter Maydell wrote: On Mon, 9 Mar 2020 at 13:23, Liu, Jingqi wrote: On 3/6/2020 12:40 AM, Peter Maydell wrote: On Thu, 5 Mar 2020 at 16:11, Ján Tomko wrote: On a Thursday in 2020, Jingqi Liu wrote: The CONFIG_LINUX symbol is always not defined in this file. This fixes that "config-host.h" header file is not included for getting macros. Signed-off-by: Jingqi Liu --- util/mmap-alloc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c index 27dcccd8ec..24c0e380f3 100644 --- a/util/mmap-alloc.c +++ b/util/mmap-alloc.c @@ -10,6 +10,8 @@ * later. See the COPYING file in the top-level directory. */ +#include "config-host.h" + According to CODING_STYLE.rst, qemu/osdep.h is the header file that should be included first, before all the other includes. So the minimal fix would be moving qemu/osdep.h up here. Yes, osdep must always be first. #ifdef CONFIG_LINUX #include #else /* !CONFIG_LINUX */ Do we really need this? osdep.h will pull in sys/mman.h for you, which should define the MAP_* constants. Also, you have no fallbmack for "I'm on Linux but the system headers don't define MAP_SHARED_VALIDATE or MAP_SYNC". Wouldn't it be better to just have #ifndef MAP_SYNC #define MAP_SYNC 0 #endif etc ? osdep.h pulls in sys/mman.h, which defines the MAP_* constants except for MAP_SYNC and MAP_SHARED_VALIDATE on Linux. Why not? Is this just "not yet in the version of glibc we're using", or is it a bug/missed feature in glibc that needs to be addressed there ? I'm using the version 2.27 of glibc. I downloaded the version 2.28 of glibc source for compilation and installation. I found MAP_SYNC and MAP_SHARED_VALIDATE are defined in this version. Seems it's older glibc version issue. How about just adding the following code in util/mmap-alloc.c ? #ifndef MAP_SYNC #define MAP_SYNC 0x8 #endif #ifndef MAP_SHARED_VALIDATE #define MAP_SHARED_VALIDATE 0x03 #endif You don't want to do that for non-Linux systems, so there you need to fall back to defining them to be 0. Are there any systems (distros) where the standard system sys/mman.h does not define these new MAP_* constants but we still really really need to use them? If not, then we could just have the fallback-to-0 fallback everywhere. Good point. So as you mentioned, it would be better to just have the following code: #ifndef MAP_SYNC #define MAP_SYNC 0 #endif #ifndef MAP_SHARED_VALIDATE #define MAP_SHARED_VALIDATE 0 #endif Won't this defeat the purpose of MAP_SHARED_VALIDATE? We really have linux-headers/linux/mman.h for exactly this purpose. Yes, linux-headers/linux/mman.h has defined MAP_SYNC and MAP_SHARED_VALIDATE. 1) If '#include ' first then '#include qemu/osdep.h', it should be fine. 2) Peter mentioned osdep.h should go first. It will cause redefinitions of other MAP_* macros after '#include '. This is where the conflict lies. Any comments ? Thanks, Jingqi Thanks, Jingqi thanks -- PMM
Re: [PATCH] vfio/pci: Use defined memcpy() behavior
On 03/10/20 18:15, Alex Williamson wrote: > vfio_rom_read() relies on memcpy() doing the logically correct thing, > ie. safely copying zero bytes from a NULL pointer when rom_size is > zero, rather than the spec definition, which is undefined when the > source or target pointers are NULL. Resolve this by wrapping the > call in the condition expressed previously by the ternary. > > Additionally, we still use @val to fill data based on the provided > @size regardless of mempcy(), so we should initialize @val rather > than @data. > > Reported-by: Longpeng > Reported-by: Laszlo Ersek > Signed-off-by: Alex Williamson > --- > hw/vfio/pci.c |9 + > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c > index 5e75a95129ac..b0799cdc28ad 100644 > --- a/hw/vfio/pci.c > +++ b/hw/vfio/pci.c > @@ -859,16 +859,17 @@ static uint64_t vfio_rom_read(void *opaque, hwaddr > addr, unsigned size) > uint16_t word; > uint32_t dword; > uint64_t qword; > -} val; > -uint64_t data = 0; > +} val = { 0 }; > +uint64_t data; > > /* Load the ROM lazily when the guest tries to read it */ > if (unlikely(!vdev->rom && !vdev->rom_read_failed)) { > vfio_pci_load_rom(vdev); > } > > -memcpy(, vdev->rom + addr, > - (addr < vdev->rom_size) ? MIN(size, vdev->rom_size - addr) : 0); > +if (addr < vdev->rom_size) { > +memcpy(, vdev->rom + addr, MIN(size, vdev->rom_size - addr)); > +} > > switch (size) { > case 1: > sorry I'm processing my INBOX in basically... random order. :/ So as I stated in the earlier thread, I suggest casting "vdev->rom" to a character type, before the addition operator "+" binds. With that: Reviewed-by: Laszlo Ersek Thanks Laszlo
Re: [PATCH] target/ppc: Fix rlwinm on ppc64
On Mon, Mar 09, 2020 at 11:45:57PM +0300, Vitaly Chikunov wrote: > rlwinm cannot just AND with Mask if shift value is zero on ppc64 when > Mask Begin is greater than Mask End and high bits are set to 1. > > Note that PowerISA 3.0B says that for `rlwinm' ROTL32 is used, and > ROTL32 is defined (in 3.3.14) so that rotated value should have two > copies of lower word of the source value. > > This seems to be another incarnation of the fix from 820724d170 > ("target-ppc: Fix rlwimi, rlwinm, rlwnm again"), except I leave > optimization when Mask value is less than 32 bits. > > Fixes: 7b4d326f47 ("target-ppc: Use the new deposit and extract ops") > Cc: qemu-sta...@nongnu.org > Signed-off-by: Vitaly Chikunov Applied to ppc-for-5.0. > --- > target/ppc/translate.c | 20 +++- > 1 file changed, 11 insertions(+), 9 deletions(-) > > diff --git a/target/ppc/translate.c b/target/ppc/translate.c > index 36fa27367c..127c82a24e 100644 > --- a/target/ppc/translate.c > +++ b/target/ppc/translate.c > @@ -1938,15 +1938,17 @@ static void gen_rlwinm(DisasContext *ctx) > me += 32; > #endif > mask = MASK(mb, me); > -if (sh == 0) { > -tcg_gen_andi_tl(t_ra, t_rs, mask); > -} else if (mask <= 0xu) { > -TCGv_i32 t0 = tcg_temp_new_i32(); > -tcg_gen_trunc_tl_i32(t0, t_rs); > -tcg_gen_rotli_i32(t0, t0, sh); > -tcg_gen_andi_i32(t0, t0, mask); > -tcg_gen_extu_i32_tl(t_ra, t0); > -tcg_temp_free_i32(t0); > +if (mask <= 0xu) { > +if (sh == 0) { > +tcg_gen_andi_tl(t_ra, t_rs, mask); > +} else { > +TCGv_i32 t0 = tcg_temp_new_i32(); > +tcg_gen_trunc_tl_i32(t0, t_rs); > +tcg_gen_rotli_i32(t0, t0, sh); > +tcg_gen_andi_i32(t0, t0, mask); > +tcg_gen_extu_i32_tl(t_ra, t0); > +tcg_temp_free_i32(t0); > +} > } else { > #if defined(TARGET_PPC64) > tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32); -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
Re: [PATCH RESEND 1/3] vfio/pci: fix a null pointer reference in vfio_rom_read
On 03/10/20 17:11, Alex Williamson wrote: > commit 2088fc1e1f426b98e9ca4d7bcdbe53d886a18c37 > Author: Alex Williamson > Date: Tue Mar 10 10:04:36 2020 -0600 > > vfio/pci: Use defined memcpy() behavior > > vfio_rom_read() relies on memcpy() doing the logically correct thing, > ie. safely copying zero bytes from a NULL pointer when rom_size is > zero, rather than the spec definition, which is undefined when the > source or target pointers are NULL. Resolve this by wrapping the > call in the condition expressed previously by the ternary. > > Additionally, we still use @val to fill data based on the provided > @size regardless of mempcy(), so we should initialize @val rather > than @data. > > Reported-by: Longpeng > Reported-by: Laszlo Ersek > Signed-off-by: Alex Williamson > > diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c > index 5e75a95129ac..b0799cdc28ad 100644 > --- a/hw/vfio/pci.c > +++ b/hw/vfio/pci.c > @@ -859,16 +859,17 @@ static uint64_t vfio_rom_read(void *opaque, hwaddr > addr, unsigned size) > uint16_t word; > uint32_t dword; > uint64_t qword; > -} val; > -uint64_t data = 0; > +} val = { 0 }; > +uint64_t data; > > /* Load the ROM lazily when the guest tries to read it */ > if (unlikely(!vdev->rom && !vdev->rom_read_failed)) { > vfio_pci_load_rom(vdev); > } > > -memcpy(, vdev->rom + addr, > - (addr < vdev->rom_size) ? MIN(size, vdev->rom_size - addr) : 0); > +if (addr < vdev->rom_size) { > +memcpy(, vdev->rom + addr, MIN(size, vdev->rom_size - addr)); > +} > > switch (size) { > case 1: Regarding the pre-patch code: My understanding is that the memcpy() could be reached with a guest-originated "addr" even if "vdev->rom" was NULL. If that's the case, then the pre-patch code invokes undefined behavior regardless of memcpy(), because it performs pointer arithmetic on a null pointer (not to mention that the type of that pointer is (void *)) Regarding the proposed change: (addr < vdev->rom_size) requires that "vdev->rom_size" be positive. In that case, I assume that - "vdev->rom" is not NULL, and - MIN(size, vdev->rom_size - addr) bytes are "in range" for the object allocated at "vdev->rom". So from a memcpy() and range perspective, the patch looks OK. But there's still a wart I dislike: we should never perform pointer arithmetic on a (void*). I suggest casting (vdev->rom) to (uint8_t*) or (unsigned char*) first. Here's an excerpt from the ISO C99 standard: -v- 6.5.6 Additive operators Constraints 2 For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to an object type and the other shall have integer type. [...] -^- A "pointer-to-void" is not a "pointer to an object type", because "void" is not an object type -- it is an incomplete type that cannot be completed: -v- 6.2.5 Types 1 [...] Types are partitioned into object types (types that fully describe objects), function types (types that describe functions), and incomplete types (types that describe objects but lack information needed to determine their sizes). [...] 19 The void type comprises an empty set of values; it is an incomplete type that cannot be completed. -^- For a different illustration, (vdev->rom + addr) is equivalent to &(vdev->rom[addr]) -- and we clearly can't have an "array of void". This anti-pattern (of doing pointer arithmetic on (void*)) likely comes from a guarantee that the standard does make, in the same "6.2.5 Types" section: -v- 27 A pointer to void shall have the same representation and alignment requirements as a pointer to a character type. 39) [...] Footnote 39: The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions. -^- It does not extend to the "+" operator. Thanks Laszlo
Re: [PATCH v4 1/4] ide/via: Get rid of via_init_ide()
On Tue, 10 Mar 2020, BALATON Zoltan wrote: Follow example of CMD646 and remove via_init_ide function and do it directly in board code instead. There's a typo in the title and commit message, it should read via_ide_init in both. If a v5 is needed I'll fix that otherwise maybe it could be fixed up when committing? Regards, BALATON Zoltan Signed-off-by: BALATON Zoltan --- hw/ide/via.c| 8 hw/mips/mips_fulong2e.c | 5 - include/hw/ide.h| 1 - 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/hw/ide/via.c b/hw/ide/via.c index 096de8dba0..df0b352b58 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -213,14 +213,6 @@ static void via_ide_exitfn(PCIDevice *dev) } } -void via_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) -{ -PCIDevice *dev; - -dev = pci_create_simple(bus, devfn, "via-ide"); -pci_ide_create_devs(dev, hd_table); -} - static void via_ide_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c index 4727b1d3a4..639ba2a091 100644 --- a/hw/mips/mips_fulong2e.c +++ b/hw/mips/mips_fulong2e.c @@ -37,6 +37,7 @@ #include "qemu/log.h" #include "hw/loader.h" #include "hw/ide.h" +#include "hw/ide/pci.h" #include "elf.h" #include "hw/isa/vt82c686.h" #include "hw/rtc/mc146818rtc.h" @@ -239,6 +240,7 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, qemu_irq *i8259; ISABus *isa_bus; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; +PCIDevice *dev; isa_bus = vt82c686b_isa_init(pci_bus, PCI_DEVFN(slot, 0)); if (!isa_bus) { @@ -256,8 +258,9 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, /* Super I/O */ isa_create_simple(isa_bus, TYPE_VT82C686B_SUPERIO); +dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), "via-ide"); ide_drive_get(hd, ARRAY_SIZE(hd)); -via_ide_init(pci_bus, hd, PCI_DEVFN(slot, 1)); +pci_ide_create_devs(dev, hd); pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci"); pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), "vt82c686b-usb-uhci"); diff --git a/include/hw/ide.h b/include/hw/ide.h index 0c7080ed92..dea0ecf5be 100644 --- a/include/hw/ide.h +++ b/include/hw/ide.h @@ -16,7 +16,6 @@ PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); int pci_piix3_xen_ide_unplug(DeviceState *dev, bool aux); -void via_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); /* ide-mmio.c */ void mmio_ide_init_drives(DeviceState *dev, DriveInfo *hd0, DriveInfo *hd1);
Re: [PATCH v7 00/18] Add Allwinner H3 SoC and Orange Pi PC Machine
Patchew URL: https://patchew.org/QEMU/20200310213203.18730-1-nieklinnenb...@gmail.com/ Hi, This series failed the asan build test. Please find the testing commands and their output below. If you have Docker installed, you can probably reproduce it locally. === TEST SCRIPT BEGIN === #!/bin/bash export ARCH=x86_64 make docker-image-fedora V=1 NETWORK=1 time make docker-test-debug@fedora TARGET_LIST=x86_64-softmmu J=14 NETWORK=1 === TEST SCRIPT END === PASS 1 fdc-test /x86_64/fdc/cmos PASS 2 fdc-test /x86_64/fdc/no_media_on_start PASS 3 fdc-test /x86_64/fdc/read_without_media ==6195==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 4 fdc-test /x86_64/fdc/media_change PASS 5 fdc-test /x86_64/fdc/sense_interrupt PASS 6 fdc-test /x86_64/fdc/relative_seek --- PASS 32 test-opts-visitor /visitor/opts/range/beyond PASS 33 test-opts-visitor /visitor/opts/dict/unvisited MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-coroutine -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-coroutine" ==6250==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! ==6250==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x7ffe5de1c000; bottom 0x7f003ecd9000; size: 0x00fe1f143000 (1091443109888) False positive error reports may follow For details see https://github.com/google/sanitizers/issues/189 PASS 11 fdc-test /x86_64/fdc/read_no_dma_18 --- PASS 12 fdc-test /x86_64/fdc/read_no_dma_19 PASS 13 fdc-test /x86_64/fdc/fuzz-registers MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64 QTEST_QEMU_IMG=qemu-img tests/qtest/ide-test -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="ide-test" ==6273==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 ide-test /x86_64/ide/identify ==6265==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 14 test-aio /aio/timer/schedule ==6279==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 15 test-aio /aio/coroutine/queue-chaining PASS 16 test-aio /aio-gsource/flush PASS 17 test-aio /aio-gsource/bh/schedule --- PASS 26 test-aio /aio-gsource/event/flush PASS 27 test-aio /aio-gsource/event/wait/no-flush-cb PASS 2 ide-test /x86_64/ide/flush ==6285==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 3 ide-test /x86_64/ide/bmdma/simple_rw ==6291==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 4 ide-test /x86_64/ide/bmdma/trim PASS 28 test-aio /aio-gsource/timer/schedule MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-aio-multithread -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-aio-multithread" ==6300==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-aio-multithread /aio/multi/lifecycle ==6297==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 2 test-aio-multithread /aio/multi/schedule PASS 3 test-aio-multithread /aio/multi/mutex/contended PASS 4 test-aio-multithread /aio/multi/mutex/handoff ==6332==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 5 test-aio-multithread /aio/multi/mutex/mcs PASS 6 test-aio-multithread /aio/multi/mutex/pthread MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-throttle -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-throttle" ==6344==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-throttle /throttle/leak_bucket PASS 2 test-throttle /throttle/compute_wait PASS 3 test-throttle /throttle/init --- PASS 14 test-throttle /throttle/config/max PASS 15 test-throttle /throttle/config/iops_size MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-thread-pool -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-thread-pool" ==6348==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-thread-pool /thread-pool/submit PASS 2 test-thread-pool /thread-pool/submit-aio PASS 3 test-thread-pool /thread-pool/submit-co PASS 4 test-thread-pool /thread-pool/submit-many PASS 5 test-thread-pool /thread-pool/cancel ==6415==WARNING: ASan doesn't fully support makecontext/swapcontext functions and
RE: [PATCH v5 16/16] tests: Update the Unit tests
[AMD Official Use Only - Internal Distribution Only] > -Original Message- > From: Eduardo Habkost > Sent: Tuesday, March 10, 2020 6:06 PM > To: Moger, Babu > Cc: marcel.apfelb...@gmail.com; pbonz...@redhat.com; r...@twiddle.net; > m...@redhat.com; imamm...@redhat.com; qemu-devel@nongnu.org > Subject: Re: [PATCH v5 16/16] tests: Update the Unit tests > > On Tue, Mar 03, 2020 at 01:58:38PM -0600, Babu Moger wrote: > > Since the topology routines have changed, update > > the unit tests to use the new APIs. > > > > Signed-off-by: Babu Moger > > This has to be part of the patches that changed the function > interfaces, otherwise we break bisectability. Yes. That is right. Will quash with other patch. > > -- > Eduardo
Re: [PATCH v5 16/16] tests: Update the Unit tests
On Tue, Mar 03, 2020 at 01:58:38PM -0600, Babu Moger wrote: > Since the topology routines have changed, update > the unit tests to use the new APIs. > > Signed-off-by: Babu Moger This has to be part of the patches that changed the function interfaces, otherwise we break bisectability. -- Eduardo
Re: [PATCH v5 02/16] hw/i386: Introduce X86CPUTopoInfo to contain topology info
On Tue, Mar 03, 2020 at 01:57:05PM -0600, Babu Moger wrote: > This is an effort to re-arrange few data structure for better readability. > > 1. Add X86CPUTopoInfo which will have all the topology informations >required to build the cpu topology. There is no functional changes. > 2. Introduce init_topo_info to initialize X86CPUTopoInfo members from >X86MachineState. > > There is no functional changes. > > Signed-off-by: Babu Moger I was queueing this one, but I had to dequeue. You forgot to tests/test-x86-cpuid.c to use the new X86CPUTopoInfo argument. -- Eduardo
Re: [PATCH v2 0/3] Wire up USB controllers in i.MX6 emulations
On 3/10/20 3:10 PM, no-re...@patchew.org wrote: > Patchew URL: > https://patchew.org/QEMU/20200310210434.31544-1-li...@roeck-us.net/ > > > > Hi, > > This series failed the asan build test. Please find the testing commands and > their output below. If you have Docker installed, you can probably reproduce > it > locally. > I have no clue what this log tries to tell me. On the plus side (well, kind of), it looks like other patch series experience the same problem, so my working assumption is that this is either a test infrastructure problem, or that it is caused by some other patch which already made it into qemu. Guenter
Re: [PATCH v4 0/4] Implement "non 100% native mode" in via-ide
Patchew URL: https://patchew.org/QEMU/cover.1583867210.git.bala...@eik.bme.hu/ Hi, This series failed the asan build test. Please find the testing commands and their output below. If you have Docker installed, you can probably reproduce it locally. === TEST SCRIPT BEGIN === #!/bin/bash export ARCH=x86_64 make docker-image-fedora V=1 NETWORK=1 time make docker-test-debug@fedora TARGET_LIST=x86_64-softmmu J=14 NETWORK=1 === TEST SCRIPT END === PASS 1 fdc-test /x86_64/fdc/cmos PASS 2 fdc-test /x86_64/fdc/no_media_on_start PASS 3 fdc-test /x86_64/fdc/read_without_media ==6176==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 4 fdc-test /x86_64/fdc/media_change PASS 5 fdc-test /x86_64/fdc/sense_interrupt PASS 6 fdc-test /x86_64/fdc/relative_seek --- PASS 32 test-opts-visitor /visitor/opts/range/beyond PASS 33 test-opts-visitor /visitor/opts/dict/unvisited MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-coroutine -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-coroutine" ==6227==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! ==6227==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x7fff30fcf000; bottom 0x7f372272; size: 0x00c80e8af000 (859237445632) False positive error reports may follow For details see https://github.com/google/sanitizers/issues/189 PASS 1 test-coroutine /basic/no-dangling-access --- PASS 12 test-aio /aio/event/flush PASS 13 test-aio /aio/event/wait/no-flush-cb PASS 14 test-aio /aio/timer/schedule ==6242==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 15 test-aio /aio/coroutine/queue-chaining PASS 16 test-aio /aio-gsource/flush PASS 17 test-aio /aio-gsource/bh/schedule --- PASS 28 test-aio /aio-gsource/timer/schedule MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-aio-multithread -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-aio-multithread" PASS 12 fdc-test /x86_64/fdc/read_no_dma_19 ==6247==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-aio-multithread /aio/multi/lifecycle PASS 13 fdc-test /x86_64/fdc/fuzz-registers MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64 QTEST_QEMU_IMG=qemu-img tests/qtest/ide-test -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="ide-test" ==6264==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 2 test-aio-multithread /aio/multi/schedule PASS 1 ide-test /x86_64/ide/identify ==6275==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 2 ide-test /x86_64/ide/flush PASS 3 test-aio-multithread /aio/multi/mutex/contended ==6281==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 3 ide-test /x86_64/ide/bmdma/simple_rw ==6292==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 4 ide-test /x86_64/ide/bmdma/trim ==6298==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 4 test-aio-multithread /aio/multi/mutex/handoff PASS 5 test-aio-multithread /aio/multi/mutex/mcs PASS 6 test-aio-multithread /aio/multi/mutex/pthread MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-throttle -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-throttle" ==6315==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-throttle /throttle/leak_bucket PASS 2 test-throttle /throttle/compute_wait PASS 3 test-throttle /throttle/init --- PASS 14 test-throttle /throttle/config/max PASS 15 test-throttle /throttle/config/iops_size MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-thread-pool -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-thread-pool" ==6319==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-thread-pool /thread-pool/submit PASS 2 test-thread-pool /thread-pool/submit-aio PASS 3 test-thread-pool /thread-pool/submit-co PASS 4 test-thread-pool /thread-pool/submit-many PASS 5 test-thread-pool /thread-pool/cancel ==6386==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 6 test-thread-pool /thread-pool/cancel-async MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255
Re: [PATCH v2 00/16]: hw/i386/vmport: Bug fixes and improvements
On 11/03/2020 0:00, Michael S. Tsirkin wrote: On Tue, Mar 10, 2020 at 11:57:49PM +0200, Liran Alon wrote: On 10/03/2020 23:44, Michael S. Tsirkin wrote: On Tue, Mar 10, 2020 at 02:29:42PM -0700, Liran Alon wrote: On 10/03/2020 22:56, Michael S. Tsirkin wrote: On Tue, Mar 10, 2020 at 08:09:09PM +0200, Liran Alon wrote: On 10/03/2020 19:44, Michael S. Tsirkin wrote: On Tue, Mar 10, 2020 at 06:53:16PM +0200, Liran Alon wrote: Hi, This series aims to fix several bugs in VMPort and improve it by supporting more VMPort commands and make command results more configurable to user via QEMU command-line. This functionality was proven to be useful to run various VMware VMs when attempting to run them as-is on top of QEMU/KVM. For more details, see commit messages. Well two versions in one day and some review comments weren't addressed. There is a single review comment that wasn't addressed which is replacing an enum with a comment. And I explicitly mentioned that it's because I want additional opinion on this. I don't see why such a small thing should block review for 15 patches... All the rest of the comments (Which were great) have been addressed. Unless I have mistakenly missed something, which please point it out if I did. OK I just took a quick peek, two things quickly jumped out at me. Thanks for having a look. version property really should be a boolean and have some documentation saying what functionality enables. I thought that having a version number approach is more generic and easy to maintain going forward. If I understand correctly, this is also the approach taken by qxl & qxl-vga. The more elaborate alternative could have been introducing compat_flags (As PVSCSI does) but it seems like it will pollute the property space with a lot of useless VMPort properties. (E.g. x-read-eax-bug, x-no-report-unsupported-cmd, x-no-report-vmx-type and etc.). What is the advantage of having a boolean such as "x-vmport-v2" instead of having a single "version" property? It's not clear what should happen going forward. Let's say version is incremented again. This then becomes challenging for downstreams to backport. As all conditions are in the form of "if (s->version > X)" then incrementing version from 1 to 2 doesn't break any condition of "if (s->version > 1)". What is the challenge of backporting I'm missing? the challenge is figuring out which parts does version apply to. It might be easy if there's just code, harder if there's also data, etc. You mean things such as the following? s->some_field = (s->version > X) ? A : B; True that it could be a bit more difficult to spot. Will it suffice if I would just add documentation above "version" property on what is was the functionality in "version==1"? (Though, it's just easy to scan the vmport.c code for if's involving ">version"... "version" is more of an internal field for machine-type compatibility and not really meant to be used by user) Which approach do you prefer? I just dislike versions, they are hard to maintain. Individual ones is cleanest imho. Self-documenting. I agree. That's the PVSCSI approach of compat_flags. Have many properties but each define bit in a compat_flags that specifies behavior. The disadvantage it have is that it over-complicates code and introduce many properties that will never be used as it's just for internal binding to machine-type. But if not, I'd do something like "x-vmport-fixes" and set bits there for each bugfix. Hmm this could a nice and simple approach. Will it be OK then in this case to define "x-vmport-fixes" value in hw_compat_4_2[] to a hard-coded value (e.g. "20") without directly encoding each individual bit via vmport.h constants? Well how are you going to check a specific flag then? In the code itself I will have constants of course. I meant just in hw_compat_4_2[] machine-type compat entry because the bitmask value there should be specified as a string value. I will note though that it seems this "x-vmport-fixes" bitmap seems to be the first of it's kind. But I'm OK with this approach. So just to be clear before implementing your suggesting approach, this doesn't bother you right?
Re: [PATCH v2 0/3] Wire up USB controllers in i.MX6 emulations
Patchew URL: https://patchew.org/QEMU/20200310210434.31544-1-li...@roeck-us.net/ Hi, This series failed the asan build test. Please find the testing commands and their output below. If you have Docker installed, you can probably reproduce it locally. === TEST SCRIPT BEGIN === #!/bin/bash export ARCH=x86_64 make docker-image-fedora V=1 NETWORK=1 time make docker-test-debug@fedora TARGET_LIST=x86_64-softmmu J=14 NETWORK=1 === TEST SCRIPT END === PASS 1 fdc-test /x86_64/fdc/cmos PASS 2 fdc-test /x86_64/fdc/no_media_on_start PASS 3 fdc-test /x86_64/fdc/read_without_media ==6147==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 4 fdc-test /x86_64/fdc/media_change PASS 5 fdc-test /x86_64/fdc/sense_interrupt PASS 6 fdc-test /x86_64/fdc/relative_seek --- PASS 32 test-opts-visitor /visitor/opts/range/beyond PASS 33 test-opts-visitor /visitor/opts/dict/unvisited MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-coroutine -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-coroutine" ==6190==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-coroutine /basic/no-dangling-access PASS 2 test-coroutine /basic/lifecycle PASS 3 test-coroutine /basic/yield ==6190==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x7ffe4a11b000; bottom 0x7f55e802; size: 0x00a8620fb000 (723199700992) False positive error reports may follow For details see https://github.com/google/sanitizers/issues/189 PASS 4 test-coroutine /basic/nesting --- PASS 12 fdc-test /x86_64/fdc/read_no_dma_19 PASS 13 fdc-test /x86_64/fdc/fuzz-registers MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64 QTEST_QEMU_IMG=qemu-img tests/qtest/ide-test -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="ide-test" ==6205==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 14 test-aio /aio/timer/schedule PASS 15 test-aio /aio/coroutine/queue-chaining PASS 16 test-aio /aio-gsource/flush --- PASS 25 test-aio /aio-gsource/event/wait PASS 26 test-aio /aio-gsource/event/flush PASS 27 test-aio /aio-gsource/event/wait/no-flush-cb ==6213==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 ide-test /x86_64/ide/identify ==6219==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 2 ide-test /x86_64/ide/flush PASS 28 test-aio /aio-gsource/timer/schedule MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-aio-multithread -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-aio-multithread" ==6225==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! ==6231==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 1 test-aio-multithread /aio/multi/lifecycle PASS 3 ide-test /x86_64/ide/bmdma/simple_rw ==6245==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 4 ide-test /x86_64/ide/bmdma/trim PASS 2 test-aio-multithread /aio/multi/schedule ==6251==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 3 test-aio-multithread /aio/multi/mutex/contended PASS 4 test-aio-multithread /aio/multi/mutex/handoff PASS 5 test-aio-multithread /aio/multi/mutex/mcs ==6277==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 6 test-aio-multithread /aio/multi/mutex/pthread MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-throttle -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-throttle" PASS 1 test-throttle /throttle/leak_bucket --- PASS 6 test-throttle /throttle/detach_attach PASS 7 test-throttle /throttle/config_functions PASS 8 test-throttle /throttle/accounting ==6284==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 9 test-throttle /throttle/groups PASS 10 test-throttle /throttle/config/enabled PASS 11 test-throttle /throttle/config/conflicting --- MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))} tests/test-thread-pool -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl --test-name="test-thread-pool" PASS 1 test-thread-pool /thread-pool/submit PASS 2 test-thread-pool /thread-pool/submit-aio ==6288==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases! PASS 3
Re: [PATCH 05/14] hw/i386/vmport: Report VMX type in CMD_GETVERSION
On Tue, Mar 10, 2020 at 11:59:29PM +0200, Liran Alon wrote: > > On 10/03/2020 23:49, Michael S. Tsirkin wrote: > > On Tue, Mar 10, 2020 at 11:34:00PM +0200, Liran Alon wrote: > > > On 10/03/2020 23:16, Michael S. Tsirkin wrote: > > > > On Tue, Mar 10, 2020 at 04:46:19PM +0200, Liran Alon wrote: > > > > > There is no license issue here. It's only definitions. > > > > So it seems that in your opinion > > > > - definition names in the interface do not need a license > > > > and > > > > - it is fair to reuse them without a license for the purpose > > > > of making your compatible interface easier to use for > > > > people familiar with the original > > > > > > > > Did I get that right? > > > I'm for sure not an expert on open source code licenses. You probably know > > > this area much more than I do. > > > But yes, this is what I would have thought. That it's not an issue to copy > > > the enum definition. > > I'm not a lawyer. I think attribution is important even for small > > things, and it was missing in v1. v2 has it but link would be better. I > > also think respecting author's wishes is important, and a license gives > > a hint as to that. > > > Oh maybe I misunderstood you. > So you're saying I should just add a link to open-vm-tools git-repo for > attribution? I even posted a code snippet, feel free to reuse. > Which author's wishes you refer to? > > -Liran I really just said one should check before copying code. In this case if we don't really need to make vmport depend on GPL only code we shouldn't since original author wanted it to be copyleft. -- MST
Re: [PATCH v2 00/16]: hw/i386/vmport: Bug fixes and improvements
On Tue, Mar 10, 2020 at 11:57:49PM +0200, Liran Alon wrote: > > On 10/03/2020 23:44, Michael S. Tsirkin wrote: > > On Tue, Mar 10, 2020 at 02:29:42PM -0700, Liran Alon wrote: > > > On 10/03/2020 22:56, Michael S. Tsirkin wrote: > > > > On Tue, Mar 10, 2020 at 08:09:09PM +0200, Liran Alon wrote: > > > > > On 10/03/2020 19:44, Michael S. Tsirkin wrote: > > > > > > On Tue, Mar 10, 2020 at 06:53:16PM +0200, Liran Alon wrote: > > > > > > > Hi, > > > > > > > > > > > > > > This series aims to fix several bugs in VMPort and improve it by > > > > > > > supporting > > > > > > > more VMPort commands and make command results more configurable to > > > > > > > user via QEMU command-line. > > > > > > > > > > > > > > This functionality was proven to be useful to run various VMware > > > > > > > VMs > > > > > > > when attempting to run them as-is on top of QEMU/KVM. > > > > > > > > > > > > > > For more details, see commit messages. > > > > > > Well two versions in one day and some review comments weren't > > > > > > addressed. > > > > > There is a single review comment that wasn't addressed which is > > > > > replacing an > > > > > enum with a comment. And I explicitly mentioned that it's because I > > > > > want > > > > > additional opinion on this. > > > > > I don't see why such a small thing should block review for 15 > > > > > patches... > > > > > All the rest of the comments (Which were great) have been addressed. > > > > > Unless > > > > > I have mistakenly missed something, which please point it out if I > > > > > did. > > > > OK I just took a quick peek, two things quickly jumped out at me. > > > Thanks for having a look. > > > > version property really should be a boolean and have some documentation > > > > saying what functionality enables. > > > I thought that having a version number approach is more generic and easy > > > to > > > maintain going forward. > > > If I understand correctly, this is also the approach taken by qxl & > > > qxl-vga. > > > > > > The more elaborate alternative could have been introducing compat_flags > > > (As > > > PVSCSI does) but it seems like it will pollute the property space with a > > > lot > > > of useless VMPort properties. > > > (E.g. x-read-eax-bug, x-no-report-unsupported-cmd, x-no-report-vmx-type > > > and > > > etc.). > > > > > > What is the advantage of having a boolean such as "x-vmport-v2" instead of > > > having a single "version" property? > > It's not clear what should happen going forward. Let's say version is > > incremented again. This then becomes challenging for downstreams to > > backport. > As all conditions are in the form of "if (s->version > X)" then incrementing > version from 1 to 2 doesn't break any condition of "if (s->version > 1)". > What is the challenge of backporting I'm missing? the challenge is figuring out which parts does version apply to. It might be easy if there's just code, harder if there's also data, etc. > > > > > Will it suffice if I would just add documentation above "version" property > > > on what is was the functionality in "version==1"? > > > (Though, it's just easy to scan the vmport.c code for if's involving > > > ">version"... "version" is more of an internal field for machine-type > > > compatibility and not really meant to be used by user) > > > > > > Which approach do you prefer? > > I just dislike versions, they are hard to maintain. > > > > Individual ones is cleanest imho. Self-documenting. > I agree. That's the PVSCSI approach of compat_flags. Have many properties > but each define bit in a compat_flags that specifies behavior. > The disadvantage it have is that it over-complicates code and introduce many > properties that will never be used as it's just for internal binding to > machine-type. > > But if not, I'd do something like "x-vmport-fixes" and > > set bits there for each bugfix. > Hmm this could a nice and simple approach. > Will it be OK then in this case to define "x-vmport-fixes" value in > hw_compat_4_2[] to a hard-coded value (e.g. "20") without directly encoding > each individual bit via vmport.h constants? Well how are you going to check a specific flag then? > I will note though that it seems this "x-vmport-fixes" bitmap seems to be > the first of it's kind. But I'm OK with this approach. > > > > > > > > userspace properties should use the non-abbreviated > > > > vm-executable since vmx is easy to confuse with vm extensions. > > > I really wish you would reconsider this. VMX is a really common term in > > > VMware terminology. > > > It is found in binary names, ".vmx" file, ".vmx" file properties, VMware > > > Tools prints, open-vm-tools source code and etc. > > Well that at least is easy to google. > > > > .vmx > > > > .vmx > > > > This is the primary configuration file, which stores settings > > chosen in the New Virtual Machine Wizard or virtual machine settings > > editor. If you created the virtual machine under an earlier version of > > VMware
Re: [PATCH 05/14] hw/i386/vmport: Report VMX type in CMD_GETVERSION
On 10/03/2020 23:49, Michael S. Tsirkin wrote: On Tue, Mar 10, 2020 at 11:34:00PM +0200, Liran Alon wrote: On 10/03/2020 23:16, Michael S. Tsirkin wrote: On Tue, Mar 10, 2020 at 04:46:19PM +0200, Liran Alon wrote: There is no license issue here. It's only definitions. So it seems that in your opinion - definition names in the interface do not need a license and - it is fair to reuse them without a license for the purpose of making your compatible interface easier to use for people familiar with the original Did I get that right? I'm for sure not an expert on open source code licenses. You probably know this area much more than I do. But yes, this is what I would have thought. That it's not an issue to copy the enum definition. I'm not a lawyer. I think attribution is important even for small things, and it was missing in v1. v2 has it but link would be better. I also think respecting author's wishes is important, and a license gives a hint as to that. Oh maybe I misunderstood you. So you're saying I should just add a link to open-vm-tools git-repo for attribution? Which author's wishes you refer to? -Liran
Re: [PATCH v2 00/16]: hw/i386/vmport: Bug fixes and improvements
On 10/03/2020 23:44, Michael S. Tsirkin wrote: On Tue, Mar 10, 2020 at 02:29:42PM -0700, Liran Alon wrote: On 10/03/2020 22:56, Michael S. Tsirkin wrote: On Tue, Mar 10, 2020 at 08:09:09PM +0200, Liran Alon wrote: On 10/03/2020 19:44, Michael S. Tsirkin wrote: On Tue, Mar 10, 2020 at 06:53:16PM +0200, Liran Alon wrote: Hi, This series aims to fix several bugs in VMPort and improve it by supporting more VMPort commands and make command results more configurable to user via QEMU command-line. This functionality was proven to be useful to run various VMware VMs when attempting to run them as-is on top of QEMU/KVM. For more details, see commit messages. Well two versions in one day and some review comments weren't addressed. There is a single review comment that wasn't addressed which is replacing an enum with a comment. And I explicitly mentioned that it's because I want additional opinion on this. I don't see why such a small thing should block review for 15 patches... All the rest of the comments (Which were great) have been addressed. Unless I have mistakenly missed something, which please point it out if I did. OK I just took a quick peek, two things quickly jumped out at me. Thanks for having a look. version property really should be a boolean and have some documentation saying what functionality enables. I thought that having a version number approach is more generic and easy to maintain going forward. If I understand correctly, this is also the approach taken by qxl & qxl-vga. The more elaborate alternative could have been introducing compat_flags (As PVSCSI does) but it seems like it will pollute the property space with a lot of useless VMPort properties. (E.g. x-read-eax-bug, x-no-report-unsupported-cmd, x-no-report-vmx-type and etc.). What is the advantage of having a boolean such as "x-vmport-v2" instead of having a single "version" property? It's not clear what should happen going forward. Let's say version is incremented again. This then becomes challenging for downstreams to backport. As all conditions are in the form of "if (s->version > X)" then incrementing version from 1 to 2 doesn't break any condition of "if (s->version > 1)". What is the challenge of backporting I'm missing? Will it suffice if I would just add documentation above "version" property on what is was the functionality in "version==1"? (Though, it's just easy to scan the vmport.c code for if's involving ">version"... "version" is more of an internal field for machine-type compatibility and not really meant to be used by user) Which approach do you prefer? I just dislike versions, they are hard to maintain. Individual ones is cleanest imho. Self-documenting. I agree. That's the PVSCSI approach of compat_flags. Have many properties but each define bit in a compat_flags that specifies behavior. The disadvantage it have is that it over-complicates code and introduce many properties that will never be used as it's just for internal binding to machine-type. But if not, I'd do something like "x-vmport-fixes" and set bits there for each bugfix. Hmm this could a nice and simple approach. Will it be OK then in this case to define "x-vmport-fixes" value in hw_compat_4_2[] to a hard-coded value (e.g. "20") without directly encoding each individual bit via vmport.h constants? I will note though that it seems this "x-vmport-fixes" bitmap seems to be the first of it's kind. But I'm OK with this approach. userspace properties should use the non-abbreviated vm-executable since vmx is easy to confuse with vm extensions. I really wish you would reconsider this. VMX is a really common term in VMware terminology. It is found in binary names, ".vmx" file, ".vmx" file properties, VMware Tools prints, open-vm-tools source code and etc. Well that at least is easy to google. .vmx .vmx This is the primary configuration file, which stores settings chosen in the New Virtual Machine Wizard or virtual machine settings editor. If you created the virtual machine under an earlier version of VMware Workstation on a Linux host, this file may have a .cfg extension so .vmx as used here has nothing to do with VM Executable version or type. Looks like it's just a source of confusion on the vmware side too :) Well, the ".vmx" file is the configuration file for the VM given to VMX. But I agree VMware terminology is weird. :) In contrast, even though I have dealt for many years with VMware technologies, I have never known that VMX==vm-executable. Well you said that's what it stands for. I have no idea. From what you say now maybe vmx basically is being used as a prefix for all things vmware. No. It's just use to specify things related to VMX. i.e. The host VMM. In that case vmport-version and vmport-type or even vmware-version and vmware-type will do just as well. vmware-version is also confusing. As one could confuse it with the product version number. VMware
Re: [PATCH] tests: Disable dbus-vmstate-test
Hi On Tue, Mar 10, 2020 at 4:27 PM Paolo Bonzini wrote: > > On 10/03/20 16:21, Peter Maydell wrote: > > > > dbus-daemon[9321]: Could not get password database information for UID of > > current process: User "???" unknown or no memory to allocate password entry > > > > ** > > > > ERROR:/tmp/qemu-test/src/tests/qtest/dbus-vmstate-test.c:114:get_connection: > > assertion failed (err == NULL): The connection is closed > > (g-io-error-quark, 18) > > cleaning up pid 9321 > > ERROR - Bail out! > > ERROR:/tmp/qemu-test/src/tests/qtest/dbus-vmstate-test.c:114:get_connection: > > assertion failed (err == NULL): The connection is closed > > (g-io-error-quark, 18) > > make: *** [/tmp/qemu-test/src/tests/Makefile.include:632: > > check-qtest-x86_64] Error 1 > > make: *** Waiting for unfinished jobs > > > > It's not clear why this is happening (perhaps a recently revealed > > race condition or a change in the patchew build environment?). > > > > For the moment, disable this test so that patchew test runs are > > useful and don't email the list with spurious failure mails. I tried to reproduce on a fresh ubuntu 19.10, with make docker-test-debug@fedora there, and the dbus-vmstate test pass, as well as the rest for the build. Any help on how to reproduce appreciated. -- Marc-André Lureau
[PATCH 1/2] hw/arm: fsl-imx25: Wire up eSDHC controllers
Wire up eSDHC controllers in fsl-imx25. For imx25-pdk, connect drives provided on the command line to available eSDHC controllers. This patch enables booting the imx25-pdk emulation from SD card. Signed-off-by: Guenter Roeck --- hw/arm/fsl-imx25.c | 32 hw/arm/imx25_pdk.c | 16 include/hw/arm/fsl-imx25.h | 9 + 3 files changed, 57 insertions(+) diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c index da3471b395..f977c42426 100644 --- a/hw/arm/fsl-imx25.c +++ b/hw/arm/fsl-imx25.c @@ -31,6 +31,8 @@ #include "hw/qdev-properties.h" #include "chardev/char.h" +#define IMX25_ESDHC_CAPABILITIES 0x07e2 + static void fsl_imx25_init(Object *obj) { FslIMX25State *s = FSL_IMX25(obj); @@ -74,6 +76,11 @@ static void fsl_imx25_init(Object *obj) sysbus_init_child_obj(obj, "gpio[*]", >gpio[i], sizeof(s->gpio[i]), TYPE_IMX_GPIO); } + +for (i = 0; i < FSL_IMX25_NUM_ESDHCS; i++) { +sysbus_init_child_obj(obj, "sdhc[*]", >esdhc[i], sizeof(s->esdhc[i]), + TYPE_IMX_USDHC); +} } static void fsl_imx25_realize(DeviceState *dev, Error **errp) @@ -246,6 +253,31 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp) gpio_table[i].irq)); } +/* Initialize all SDHC */ +for (i = 0; i < FSL_IMX25_NUM_ESDHCS; i++) { +static const struct { +hwaddr addr; +unsigned int irq; +} esdhc_table[FSL_IMX25_NUM_ESDHCS] = { +{ FSL_IMX25_ESDHC1_ADDR, FSL_IMX25_ESDHC1_IRQ }, +{ FSL_IMX25_ESDHC2_ADDR, FSL_IMX25_ESDHC2_IRQ }, +}; + +object_property_set_uint(OBJECT(>esdhc[i]), 2, "sd-spec-version", + ); +object_property_set_uint(OBJECT(>esdhc[i]), IMX25_ESDHC_CAPABILITIES, + "capareg", ); +object_property_set_bool(OBJECT(>esdhc[i]), true, "realized", ); +if (err) { +error_propagate(errp, err); +return; +} +sysbus_mmio_map(SYS_BUS_DEVICE(>esdhc[i]), 0, esdhc_table[i].addr); +sysbus_connect_irq(SYS_BUS_DEVICE(>esdhc[i]), 0, + qdev_get_gpio_in(DEVICE(>avic), +esdhc_table[i].irq)); +} + /* initialize 2 x 16 KB ROM */ memory_region_init_rom(>rom[0], NULL, "imx25.rom0", FSL_IMX25_ROM0_SIZE, ); diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c index 26713d9a7e..b3ca82bafa 100644 --- a/hw/arm/imx25_pdk.c +++ b/hw/arm/imx25_pdk.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "cpu.h" +#include "hw/qdev-properties.h" #include "hw/arm/fsl-imx25.h" #include "hw/boards.h" #include "qemu/error-report.h" @@ -120,6 +121,21 @@ static void imx25_pdk_init(MachineState *machine) imx25_pdk_binfo.board_id = 1771, imx25_pdk_binfo.nb_cpus = 1; +for (i = 0; i < FSL_IMX25_NUM_ESDHCS; i++) { +BusState *bus; +DeviceState *carddev; +DriveInfo *di; +BlockBackend *blk; + +di = drive_get_next(IF_SD); +blk = di ? blk_by_legacy_dinfo(di) : NULL; +bus = qdev_get_child_bus(DEVICE(>soc.esdhc[i]), "sd-bus"); +carddev = qdev_create(bus, TYPE_SD_CARD); +qdev_prop_set_drive(carddev, "drive", blk, _fatal); +object_property_set_bool(OBJECT(carddev), true, + "realized", _fatal); +} + /* * We test explicitly for qtest here as it is not done (yet?) in * arm_load_kernel(). Without this the "make check" command would diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h index 1c86bb55fb..4e2d4868cd 100644 --- a/include/hw/arm/fsl-imx25.h +++ b/include/hw/arm/fsl-imx25.h @@ -27,6 +27,7 @@ #include "hw/misc/imx_rngc.h" #include "hw/i2c/imx_i2c.h" #include "hw/gpio/imx_gpio.h" +#include "hw/sd/sdhci.h" #include "exec/memory.h" #include "target/arm/cpu.h" @@ -38,6 +39,7 @@ #define FSL_IMX25_NUM_EPITS 2 #define FSL_IMX25_NUM_I2CS 3 #define FSL_IMX25_NUM_GPIOS 4 +#define FSL_IMX25_NUM_ESDHCS 2 typedef struct FslIMX25State { /*< private >*/ @@ -54,6 +56,7 @@ typedef struct FslIMX25State { IMXRNGCState rngc; IMXI2CStatei2c[FSL_IMX25_NUM_I2CS]; IMXGPIOState gpio[FSL_IMX25_NUM_GPIOS]; +SDHCIState esdhc[FSL_IMX25_NUM_ESDHCS]; MemoryRegion rom[2]; MemoryRegion iram; MemoryRegion iram_alias; @@ -215,6 +218,10 @@ typedef struct FslIMX25State { #define FSL_IMX25_GPIO3_SIZE0x4000 #define FSL_IMX25_RNGC_ADDR 0x53FB #define FSL_IMX25_RNGC_SIZE 0x4000 +#define FSL_IMX25_ESDHC1_ADDR 0x53FB4000 +#define FSL_IMX25_ESDHC1_SIZE 0x4000 +#define FSL_IMX25_ESDHC2_ADDR 0x53FB8000 +#define FSL_IMX25_ESDHC2_SIZE 0x4000 #define FSL_IMX25_GPIO1_ADDR
[PATCH 2/2] hw/arm/fsl-imx25: Wire up USB controllers
i.MX25 supports two USB controllers. Let's wire them up. With this patch, imx25-pdk can boot from both USB ports. Signed-off-by: Guenter Roeck --- hw/arm/fsl-imx25.c | 24 include/hw/arm/fsl-imx25.h | 9 + 2 files changed, 33 insertions(+) diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c index f977c42426..a3f829f436 100644 --- a/hw/arm/fsl-imx25.c +++ b/hw/arm/fsl-imx25.c @@ -81,6 +81,12 @@ static void fsl_imx25_init(Object *obj) sysbus_init_child_obj(obj, "sdhc[*]", >esdhc[i], sizeof(s->esdhc[i]), TYPE_IMX_USDHC); } + +for (i = 0; i < FSL_IMX25_NUM_USBS; i++) { +sysbus_init_child_obj(obj, "usb[*]", >usb[i], sizeof(s->usb[i]), + TYPE_CHIPIDEA); +} + } static void fsl_imx25_realize(DeviceState *dev, Error **errp) @@ -278,6 +284,24 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp) esdhc_table[i].irq)); } +/* USB */ +for (i = 0; i < FSL_IMX25_NUM_USBS; i++) { +static const struct { +hwaddr addr; +unsigned int irq; +} usb_table[FSL_IMX25_NUM_USBS] = { +{ FSL_IMX25_USB1_ADDR, FSL_IMX25_USB1_IRQ }, +{ FSL_IMX25_USB2_ADDR, FSL_IMX25_USB2_IRQ }, +}; + +object_property_set_bool(OBJECT(>usb[i]), true, "realized", + _abort); +sysbus_mmio_map(SYS_BUS_DEVICE(>usb[i]), 0, usb_table[i].addr); +sysbus_connect_irq(SYS_BUS_DEVICE(>usb[i]), 0, + qdev_get_gpio_in(DEVICE(>avic), +usb_table[i].irq)); +} + /* initialize 2 x 16 KB ROM */ memory_region_init_rom(>rom[0], NULL, "imx25.rom0", FSL_IMX25_ROM0_SIZE, ); diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h index 4e2d4868cd..5e196bbf05 100644 --- a/include/hw/arm/fsl-imx25.h +++ b/include/hw/arm/fsl-imx25.h @@ -28,6 +28,7 @@ #include "hw/i2c/imx_i2c.h" #include "hw/gpio/imx_gpio.h" #include "hw/sd/sdhci.h" +#include "hw/usb/chipidea.h" #include "exec/memory.h" #include "target/arm/cpu.h" @@ -40,6 +41,7 @@ #define FSL_IMX25_NUM_I2CS 3 #define FSL_IMX25_NUM_GPIOS 4 #define FSL_IMX25_NUM_ESDHCS 2 +#define FSL_IMX25_NUM_USBS 2 typedef struct FslIMX25State { /*< private >*/ @@ -57,6 +59,7 @@ typedef struct FslIMX25State { IMXI2CStatei2c[FSL_IMX25_NUM_I2CS]; IMXGPIOState gpio[FSL_IMX25_NUM_GPIOS]; SDHCIState esdhc[FSL_IMX25_NUM_ESDHCS]; +ChipideaState usb[FSL_IMX25_NUM_USBS]; MemoryRegion rom[2]; MemoryRegion iram; MemoryRegion iram_alias; @@ -226,6 +229,10 @@ typedef struct FslIMX25State { #define FSL_IMX25_GPIO1_SIZE0x4000 #define FSL_IMX25_GPIO2_ADDR0x53FD #define FSL_IMX25_GPIO2_SIZE0x4000 +#define FSL_IMX25_USB1_ADDR 0x53FF4000 +#define FSL_IMX25_USB1_SIZE 0x0200 +#define FSL_IMX25_USB2_ADDR 0x53FF4400 +#define FSL_IMX25_USB2_SIZE 0x0200 #define FSL_IMX25_AVIC_ADDR 0x6800 #define FSL_IMX25_AVIC_SIZE 0x4000 #define FSL_IMX25_IRAM_ADDR 0x7800 @@ -259,5 +266,7 @@ typedef struct FslIMX25State { #define FSL_IMX25_GPIO4_IRQ 23 #define FSL_IMX25_ESDHC1_IRQ9 #define FSL_IMX25_ESDHC2_IRQ8 +#define FSL_IMX25_USB1_IRQ 37 +#define FSL_IMX25_USB2_IRQ 35 #endif /* FSL_IMX25_H */ -- 2.17.1
[PATCH 0/2] hw/arm: fsl-imx25: Connect eSDHC and USB controllers
The following two patches wire up eSDHC and USB controllers for fsl-imx25. With these patches in place, the imx25-pdk emulation can boot from SD cards and from USB. Guenter Roeck (2): hw/arm: fsl-imx25: Wire up eSDHC controllers hw/arm/fsl-imx25: Wire up USB controllers hw/arm/fsl-imx25.c | 56 ++ hw/arm/imx25_pdk.c | 16 + include/hw/arm/fsl-imx25.h | 18 +++ 3 files changed, 90 insertions(+)
Re: [PATCH 05/14] hw/i386/vmport: Report VMX type in CMD_GETVERSION
On Tue, Mar 10, 2020 at 11:34:00PM +0200, Liran Alon wrote: > > On 10/03/2020 23:16, Michael S. Tsirkin wrote: > > On Tue, Mar 10, 2020 at 04:46:19PM +0200, Liran Alon wrote: > > > There is no license issue here. It's only definitions. > > So it seems that in your opinion > > - definition names in the interface do not need a license > > and > > - it is fair to reuse them without a license for the purpose > >of making your compatible interface easier to use for > >people familiar with the original > > > > Did I get that right? > I'm for sure not an expert on open source code licenses. You probably know > this area much more than I do. > But yes, this is what I would have thought. That it's not an issue to copy > the enum definition. I'm not a lawyer. I think attribution is important even for small things, and it was missing in v1. v2 has it but link would be better. I also think respecting author's wishes is important, and a license gives a hint as to that. -- MST
Re: Any interest in dwc-otg (aka dwc2) device emulation? For Raspi 3 and below.
On 3/10/20 3:00 PM, Paul Zimmerman wrote: > Hi Peter, > > I used to work for Synopsys, who is the vendor for the usb-otg IP, and > am the author of the dwc2 driver in the Linux kernel (actually just a > port of the vendor driver to Linux). So I am pretty familiar with the > hardware. But I had to give up all the documentation when I left > Synopsys. So, beyond what I could find on the web (register > description and programming model), I don't have any further > documentation. > > Thanks, > Paul > That's awesome! We don't always have specs for everything, but as many (public and legal) references as you can spell out in your git commit messages, the better, for the sake of maintainers who might need to audit changes in the future (and don't have your expertise.) Correlating things against the kernel driver will probably be plenty good enough, I'd hope -- if the driver winds up having a bug against real hardware we'd hope to see it in the wild, so it should be safe to reference against. (This is a bit of the snake eating its own tail but sometimes we just don't have better.) I wasn't aware you were the author of the kernel driver too. Now I'm convinced it'd be a shame if you didn't at least post a v1! --js
Re: [PATCH 05/14] hw/i386/vmport: Report VMX type in CMD_GETVERSION
On 10/03/2020 23:16, Michael S. Tsirkin wrote: On Tue, Mar 10, 2020 at 04:46:19PM +0200, Liran Alon wrote: There is no license issue here. It's only definitions. So it seems that in your opinion - definition names in the interface do not need a license and - it is fair to reuse them without a license for the purpose of making your compatible interface easier to use for people familiar with the original Did I get that right? I'm for sure not an expert on open source code licenses. You probably know this area much more than I do. But yes, this is what I would have thought. That it's not an issue to copy the enum definition. If I'm wrong and it is an issue, is declaring a new enum with new names not a license issue and can be done instead? Or am I only allowed to use hard-coded numbers, point to original code from where I deduced the number, and specify number meaning in comment? -Liran
Re: [PATCH v2 00/16]: hw/i386/vmport: Bug fixes and improvements
On Tue, Mar 10, 2020 at 02:29:42PM -0700, Liran Alon wrote: > > On 10/03/2020 22:56, Michael S. Tsirkin wrote: > > On Tue, Mar 10, 2020 at 08:09:09PM +0200, Liran Alon wrote: > > > On 10/03/2020 19:44, Michael S. Tsirkin wrote: > > > > On Tue, Mar 10, 2020 at 06:53:16PM +0200, Liran Alon wrote: > > > > > Hi, > > > > > > > > > > This series aims to fix several bugs in VMPort and improve it by > > > > > supporting > > > > > more VMPort commands and make command results more configurable to > > > > > user via QEMU command-line. > > > > > > > > > > This functionality was proven to be useful to run various VMware VMs > > > > > when attempting to run them as-is on top of QEMU/KVM. > > > > > > > > > > For more details, see commit messages. > > > > Well two versions in one day and some review comments weren't addressed. > > > There is a single review comment that wasn't addressed which is replacing > > > an > > > enum with a comment. And I explicitly mentioned that it's because I want > > > additional opinion on this. > > > I don't see why such a small thing should block review for 15 patches... > > > All the rest of the comments (Which were great) have been addressed. > > > Unless > > > I have mistakenly missed something, which please point it out if I did. > > OK I just took a quick peek, two things quickly jumped out at me. > Thanks for having a look. > > > > version property really should be a boolean and have some documentation > > saying what functionality enables. > I thought that having a version number approach is more generic and easy to > maintain going forward. > If I understand correctly, this is also the approach taken by qxl & qxl-vga. > > The more elaborate alternative could have been introducing compat_flags (As > PVSCSI does) but it seems like it will pollute the property space with a lot > of useless VMPort properties. > (E.g. x-read-eax-bug, x-no-report-unsupported-cmd, x-no-report-vmx-type and > etc.). > > What is the advantage of having a boolean such as "x-vmport-v2" instead of > having a single "version" property? It's not clear what should happen going forward. Let's say version is incremented again. This then becomes challenging for downstreams to backport. > Will it suffice if I would just add documentation above "version" property > on what is was the functionality in "version==1"? > (Though, it's just easy to scan the vmport.c code for if's involving > ">version"... "version" is more of an internal field for machine-type > compatibility and not really meant to be used by user) > > Which approach do you prefer? I just dislike versions, they are hard to maintain. Individual ones is cleanest imho. Self-documenting. But if not, I'd do something like "x-vmport-fixes" and set bits there for each bugfix. > > userspace properties should use the non-abbreviated > > vm-executable since vmx is easy to confuse with vm extensions. > I really wish you would reconsider this. VMX is a really common term in > VMware terminology. > It is found in binary names, ".vmx" file, ".vmx" file properties, VMware > Tools prints, open-vm-tools source code and etc. Well that at least is easy to google. .vmx .vmx This is the primary configuration file, which stores settings chosen in the New Virtual Machine Wizard or virtual machine settings editor. If you created the virtual machine under an earlier version of VMware Workstation on a Linux host, this file may have a .cfg extension so .vmx as used here has nothing to do with VM Executable version or type. Looks like it's just a source of confusion on the vmware side too :) > > In contrast, even though I have dealt for many years with VMware > technologies, I have never known that VMX==vm-executable. Well you said that's what it stands for. I have no idea. From what you say now maybe vmx basically is being used as a prefix for all things vmware. In that case vmport-version and vmport-type or even vmware-version and vmware-type will do just as well. > I still think it will introduce much confusion. On the other hard, I don't > see much confusing with this use of VMX with Intel VT-x > because it is only used inside vmport.c and in vmport properties names. And > the properties names match the names of the guest > code that interface with vmport in open-vm-tools source code. > > If you still have a strong opinion on this, I will change it as you say in > v3... But please consider above arguments. I'm just saying don't use vmx. It's too late to try to give it a different meaning. Figure out what it's supposed to stand for and write it out in full. > > > > That's just a quick look. > > > > > > > > Some people do this, try to wear the maintainers out by sheer volume. > > > > It works sometimes but it's not a nice tactic. I personally think it's > > > > worth taking the time to think harder about ways to address all > > > > comments, not try to dismiss them. > > > That's not what I tried to
[PATCH v7 17/18] tests/boot_linux_console: Test booting NetBSD via U-Boot on OrangePi PC
From: Philippe Mathieu-Daudé This test boots U-Boot then NetBSD (stored on a SD card) on a OrangePi PC board. As it requires ~1.3GB of storage, it is disabled by default. U-Boot is built by the Debian project [1], and the SD card image is provided by the NetBSD organization [2]. Once the compressed SD card image is downloaded (304MB) and extracted, this test is fast: $ AVOCADO_ALLOW_LARGE_STORAGE=yes \ avocado --show=app,console run -t machine:orangepi-pc \ tests/acceptance/boot_linux_console.py console: U-Boot SPL 2020.01+dfsg-1 (Jan 08 2020 - 08:19:44 +) console: DRAM: 1024 MiB console: U-Boot 2020.01+dfsg-1 (Jan 08 2020 - 08:19:44 +) Allwinner Technology console: CPU: Allwinner H3 (SUN8I ) console: scanning bus usb@1c1b000 for devices... 1 USB Device(s) found console: scanning bus usb@1c1d000 for devices... 1 USB Device(s) found console: scanning usb for storage devices... 0 Storage Device(s) found console: Hit any key to stop autoboot: 0 console: => setenv bootargs root=ld0a console: => setenv kernel netbsd-GENERIC.ub console: => setenv fdtfile dtb/sun8i-h3-orangepi-pc.dtb console: => boot console: ## Booting kernel from Legacy Image at 4200 ... console: Image Name: NetBSD/earmv7hf 9.0_RC1 console: Image Type: ARM Linux Kernel Image (no loading done) (uncompressed) console: XIP Kernel Image (no loading done) console: Loading Device Tree to 49ff6000, end 49fffe01 ... OK console: Starting kernel ... console: [ 1.000] NetBSD/evbarm (fdt) booting ... console: [ 1.000] NetBSD 9.0 (GENERIC) #0: Fri Feb 14 00:06:28 UTC 2020 console: [ 1.000] mkre...@mkrepro.netbsd.org:/usr/src/sys/arch/evbarm/compile/GENERIC console: [ 1.000] total memory = 1024 MB console: [ 1.000] avail memory = 1003 MB console: [ 1.000] armfdt0 (root) console: [ 1.000] simplebus0 at armfdt0: Xunlong Orange Pi PC console: [ 1.000] cpu0 at cpus0: Cortex-A7 r0p5 (Cortex V7A core) console: [ 1.000] cpu0: DC enabled IC enabled WB enabled LABT branch prediction enabled console: [ 1.000] cpu0: 32KB/64B 2-way L1 VIPT Instruction cache console: [ 1.000] cpu0: 32KB/64B 2-way write-back-locking-C L1 PIPT Data cache console: [ 1.000] cpu0: 2304KB/64B 16-way write-through L2 PIPT Unified cache console: [ 1.000] vfp0 at cpu0: NEON MPE (VFP 3.0+), rounding, NaN propagation, denormals ... console: [ 2.3812082] sdmmc0: SD card status: 4-bit, C0 console: [ 2.3812082] ld0 at sdmmc0: <0xaa:0x5859:QEMU!:0x01:0xdeadbeef:0x062> console: [ 2.4012856] ld0: 1226 MB, 622 cyl, 64 head, 63 sec, 512 bytes/sect x 2511872 sectors console: [ 2.5321222] ld0: 4-bit width, High-Speed/SDR25, 50.000 MHz console: [ 3.1068718] WARNING: 4 errors while detecting hardware; check system log. console: [ 3.1179868] boot device: ld0 console: [ 3.1470623] root on ld0a dumps on ld0b console: [ 3.2464436] root file system type: ffs console: [ 3.2897123] kern.module.path=/stand/evbarm/9.0/modules console: Mon Feb 17 20:33:35 UTC 2020 console: Starting root file system check: PASS (35.96 s) RESULTS: PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0 JOB TIME : 36.09 s Note, this test only took ~65 seconds to run on Travis-CI, see: [3]. This test is based on a description from Niek Linnenbank from [4]. [1] https://wiki.debian.org/InstallingDebianOn/Allwinner#Creating_a_bootable_SD_Card_with_u-boot [2] https://wiki.netbsd.org/ports/evbarm/allwinner/ [3] https://travis-ci.org/philmd/qemu/jobs/638823612#L3778 [4] https://www.mail-archive.com/qemu-devel@nongnu.org/msg669347.html Signed-off-by: Philippe Mathieu-Daudé [NL: changed test to use NetBSD 9.0 final release and -global allwinner-rtc.base-year] Tested-by: Niek Linnenbank Signed-off-by: Niek Linnenbank --- tests/acceptance/boot_linux_console.py | 70 ++ 1 file changed, 70 insertions(+) diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py index e035c88b07..f825cd9ef5 100644 --- a/tests/acceptance/boot_linux_console.py +++ b/tests/acceptance/boot_linux_console.py @@ -16,6 +16,7 @@ import shutil from avocado import skipUnless from avocado_qemu import Test from avocado_qemu import exec_command_and_wait_for_pattern +from avocado_qemu import interrupt_interactive_console_until_pattern from avocado_qemu import wait_for_console_pattern from avocado.utils import process from avocado.utils import archive @@ -667,6 +668,75 @@ class BootLinuxConsole(Test): 'to ') self.wait_for_console_pattern('Starting Load Kernel Modules...') +@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited') +def test_arm_orangepi_uboot_netbsd9(self): +""" +:avocado: tags=arch:arm +:avocado: tags=machine:orangepi-pc +""" +
[PATCH v7 18/18] docs: add Orange Pi PC document
The Xunlong Orange Pi PC machine is a functional ARM machine based on the Allwinner H3 System-on-Chip. It supports mainline Linux, U-Boot, NetBSD and is covered by acceptance tests. This commit adds a documentation text file with a description of the machine and instructions for the user. Signed-off-by: Niek Linnenbank --- docs/system/orangepi.rst | 253 + docs/system/target-arm.rst | 2 + MAINTAINERS| 1 + 3 files changed, 256 insertions(+) create mode 100644 docs/system/orangepi.rst diff --git a/docs/system/orangepi.rst b/docs/system/orangepi.rst new file mode 100644 index 00..a76d52fb33 --- /dev/null +++ b/docs/system/orangepi.rst @@ -0,0 +1,253 @@ +Orange Pi PC Machine Type +^ + +The Xunlong Orange Pi PC is an Allwinner H3 System on Chip +based embedded computer with mainline support in both U-Boot +and Linux. The board comes with a Quad Core Cortex-A7 @ 1.3GHz, +1GiB RAM, 100Mbit ethernet, USB, SD/MMC, USB, HDMI and +various other I/O. + +Supported devices +" + +The Orange Pi PC machine supports the following devices: + + * SMP (Quad Core Cortex-A7) + * Generic Interrupt Controller configuration + * SRAM mappings + * SDRAM controller + * Real Time Clock + * Timer device (re-used from Allwinner A10) + * UART + * SD/MMC storage controller + * EMAC ethernet + * USB 2.0 interfaces + * Clock Control Unit + * System Control module + * Security Identifier device + +Limitations +""" + +Currently, Orange Pi PC does *not* support the following features: + +- Graphical output via HDMI, GPU and/or the Display Engine +- Audio output +- Hardware Watchdog + +Also see the 'unimplemented' array in the Allwinner H3 SoC module +for a complete list of unimplemented I/O devices: ``./hw/arm/allwinner-h3.c`` + +Boot options + + +The Orange Pi PC machine can start using the standard -kernel functionality +for loading a Linux kernel or ELF executable. Additionally, the Orange Pi PC +machine can also emulate the BootROM which is present on an actual Allwinner H3 +based SoC, which loads the bootloader from a SD card, specified via the -sd argument +to qemu-system-arm. + +Machine-specific options + + +The following machine-specific options are supported: + +- allwinner-rtc.base-year= + + The Allwinner RTC device is automatically created by the Orange Pi PC machine + and uses a default base year value which can be overridden using the 'base-year' property. + The base year is the actual represented year when the RTC year value is zero. + This option can be used in case the target operating system driver uses a different + base year value. The minimum value for the base year is 1900. + +- allwinner-sid.identifier=abcd1122-a000-b000-c000-12345678 + + The Security Identifier value can be read by the guest. + For example, U-Boot uses it to determine a unique MAC address. + +The above machine-specific options can be specified in qemu-system-arm +via the '-global' argument, for example: + +.. code-block:: bash + + $ qemu-system-arm -M orangepi-pc -sd mycard.img \ + -global allwinner-rtc.base-year=2000 + +Running mainline Linux +"" + +Mainline Linux kernels from 4.19 up to latest master are known to work. +To build a Linux mainline kernel that can be booted by the Orange Pi PC machine, +simply configure the kernel using the sunxi_defconfig configuration: + +.. code-block:: bash + + $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make mrproper + $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make sunxi_defconfig + +To be able to use USB storage, you need to manually enable the corresponding +configuration item. Start the kconfig configuration tool: + +.. code-block:: bash + + $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make menuconfig + +Navigate to the following item, enable it and save your configuration: + + Device Drivers > USB support > USB Mass Storage support + +Build the Linux kernel with: + +.. code-block:: bash + + $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make + +To boot the newly build linux kernel in QEMU with the Orange Pi PC machine, use: + +.. code-block:: bash + + $ qemu-system-arm -M orangepi-pc -nic user -nographic \ + -kernel /path/to/linux/arch/arm/boot/zImage \ + -append 'console=ttyS0,115200' \ + -dtb /path/to/linux/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dtb + +Orange Pi PC images +""" + +Note that the mainline kernel does not have a root filesystem. You may provide it +with an official Orange Pi PC image from the official website: + + http://www.orangepi.org/downloadresources/ + +Another possibility is to run an Armbian image for Orange Pi PC which +can be downloaded from: + + https://www.armbian.com/orange-pi-pc/ + +Alternatively, you can also choose to build you own image with buildroot +using the orangepi_pc_defconfig. Also see https://buildroot.org for more information. +