Re: [PATCH] target/riscv: fix right shifts shamt value for rv128c
Le 09/07/2022 à 10:52, Weiwei Li a écrit : 在 2022/7/8 下午11:00, Frédéric Pétrot 写道: For rv128c right shifts, the 6-bit shamt is sign extended to 7 bits. Signed-off-by: Frédéric Pétrot --- target/riscv/insn16.decode | 7 --- disas/riscv.c | 27 +-- target/riscv/translate.c | 12 +++- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode index 02c8f61b48..ea3c5a0411 100644 --- a/target/riscv/insn16.decode +++ b/target/riscv/insn16.decode @@ -31,7 +31,8 @@ %imm_cb12:s1 5:2 2:1 10:2 3:2 !function=ex_shift_1 %imm_cj12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1 -%shimm_6bit 12:1 2:5 !function=ex_rvc_shifti +%shlimm_6bit 12:1 2:5 !function=ex_rvc_shiftli +%shrimm_6bit 12:1 2:5 !function=ex_rvc_shiftri %uimm_6bit_lq 2:4 12:1 6:1 !function=ex_shift_4 %uimm_6bit_ld 2:3 12:1 5:2 !function=ex_shift_3 %uimm_6bit_lw 2:2 12:1 4:3 !function=ex_shift_2 It's better to maintain the alignment here. Ooups! I'll do that. @@ -82,9 +83,9 @@ @c_addi16sp ... . . . .. imm=%imm_addi16sp rs1=2 rd=2 @c_shift... . .. ... . .. \ - rd=%rs1_3 rs1=%rs1_3 shamt=%shimm_6bit + rd=%rs1_3 rs1=%rs1_3 shamt=%shrimm_6bit @c_shift2 ... . .. ... . .. \ - rd=%rd rs1=%rd shamt=%shimm_6bit + rd=%rd rs1=%rd shamt=%shlimm_6bit @c_andi ... . .. ... . .. imm=%imm_ci rs1=%rs1_3 rd=%rs1_3 diff --git a/disas/riscv.c b/disas/riscv.c index 7af6afc8fa..489c2ae5e8 100644 --- a/disas/riscv.c +++ b/disas/riscv.c @@ -2402,10 +2402,25 @@ static int32_t operand_sbimm12(rv_inst inst) ((inst << 56) >> 63) << 11; } -static uint32_t operand_cimmsh6(rv_inst inst) +static uint32_t operand_cimmshl6(rv_inst inst, rv_isa isa) { -return ((inst << 51) >> 63) << 5 | +int imm = ((inst << 51) >> 63) << 5 | (inst << 57) >> 59; +if (isa == rv128) { +imm = imm ? imm : 64; +} +return imm; +} + +static uint32_t operand_cimmshr6(rv_inst inst, rv_isa isa) +{ +int imm = ((inst << 51) >> 63) << 5 | +(inst << 57) >> 59; +if (isa == rv128) { +imm = imm | (imm & 32) << 1; +imm = imm ? imm : 64; +} +return imm; } static int32_t operand_cimmi(rv_inst inst) @@ -2529,7 +2544,7 @@ static uint32_t operand_rnum(rv_inst inst) /* decode operands */ -static void decode_inst_operands(rv_decode *dec) +static void decode_inst_operands(rv_decode *dec, rv_isa isa) { rv_inst inst = dec->inst; dec->codec = opcode_data[dec->op].codec; @@ -2652,7 +2667,7 @@ static void decode_inst_operands(rv_decode *dec) case rv_codec_cb_sh6: dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8; dec->rs2 = rv_ireg_zero; -dec->imm = operand_cimmsh6(inst); +dec->imm = operand_cimmshr6(inst, isa); break; case rv_codec_ci: dec->rd = dec->rs1 = operand_crs1rd(inst); @@ -2667,7 +2682,7 @@ static void decode_inst_operands(rv_decode *dec) case rv_codec_ci_sh6: dec->rd = dec->rs1 = operand_crs1rd(inst); dec->rs2 = rv_ireg_zero; -dec->imm = operand_cimmsh6(inst); +dec->imm = operand_cimmshl6(inst, isa); break; case rv_codec_ci_16sp: dec->rd = rv_ireg_sp; @@ -3193,7 +3208,7 @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst) dec.pc = pc; dec.inst = inst; decode_inst_opcode(, isa); -decode_inst_operands(); +decode_inst_operands(, isa); decode_inst_decompress(, isa); decode_inst_lift_pseudo(); format_inst(buf, buflen, 16, ); diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 63b04e8a94..af3a2cd68c 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -705,12 +705,22 @@ static int ex_rvc_register(DisasContext *ctx, int reg) return 8 + reg; } -static int ex_rvc_shifti(DisasContext *ctx, int imm) +static int ex_rvc_shiftli(DisasContext *ctx, int imm) { /* For RV128 a shamt of 0 means a shift by 64. */ return imm ? imm : 64; } +static int ex_rvc_shiftri(DisasContext *ctx, int imm) +{ +/* + * For RV128 a shamt of 0 means a shift by 64, furthermore, for right + * shifts, the shamt is sign-extended. + */ +imm = imm | (imm & 32) << 1; +return imm ? imm : 64; +} + This calculation didn't add limitation for only working in RV128, and may trigger fault in RV32/RV64, such as following check in gen_shift_imm_fn: if (a->shamt >= max_len) { return false; } Indeed! Thanks for pointing that mistake out. Also 0 becoming 64 is a rv128 only thing, and a shamt of zero should be a hint in rv64/rv32, so I believe the immediat should not be changed.
Re: [PATCH v6 03/10] i386/pc: pass pci_hole64_size to pc_memory_init()
Am 1. Juli 2022 16:10:07 UTC schrieb Joao Martins : >Use the pre-initialized pci-host qdev and fetch the >pci-hole64-size into pc_memory_init() newly added argument. >piix needs a bit of care given all the !pci_enabled() >and that the pci_hole64_size is private to i440fx. It exposes this value as the property PCI_HOST_PROP_PCI_HOLE64_SIZE. Reusing it allows for not touching i440fx in this patch at all. For code symmetry reasons the analogue property could be used for Q35 as well. Best regards, Bernhard > >This is in preparation to determine that host-phys-bits are >enough and for pci-hole64-size to be considered to relocate >ram-above-4g to be at 1T (on AMD platforms). > >Signed-off-by: Joao Martins >Reviewed-by: Igor Mammedov >--- > hw/i386/pc.c | 3 ++- > hw/i386/pc_piix.c| 5 - > hw/i386/pc_q35.c | 8 +++- > hw/pci-host/i440fx.c | 7 +++ > include/hw/i386/pc.h | 3 ++- > include/hw/pci-host/i440fx.h | 1 + > 6 files changed, 23 insertions(+), 4 deletions(-) > >diff --git a/hw/i386/pc.c b/hw/i386/pc.c >index a9d1bf95649a..1bb89a9c17ec 100644 >--- a/hw/i386/pc.c >+++ b/hw/i386/pc.c >@@ -817,7 +817,8 @@ void xen_load_linux(PCMachineState *pcms) > void pc_memory_init(PCMachineState *pcms, > MemoryRegion *system_memory, > MemoryRegion *rom_memory, >-MemoryRegion **ram_memory) >+MemoryRegion **ram_memory, >+uint64_t pci_hole64_size) > { > int linux_boot, i; > MemoryRegion *option_rom_mr; >diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c >index 6186a1473755..f3c726e42400 100644 >--- a/hw/i386/pc_piix.c >+++ b/hw/i386/pc_piix.c >@@ -91,6 +91,7 @@ static void pc_init1(MachineState *machine, > MemoryRegion *pci_memory; > MemoryRegion *rom_memory; > ram_addr_t lowmem; >+uint64_t hole64_size; > DeviceState *i440fx_host; > > /* >@@ -166,10 +167,12 @@ static void pc_init1(MachineState *machine, > memory_region_init(pci_memory, NULL, "pci", UINT64_MAX); > rom_memory = pci_memory; > i440fx_host = qdev_new(host_type); >+hole64_size = i440fx_pci_hole64_size(i440fx_host); > } else { > pci_memory = NULL; > rom_memory = system_memory; > i440fx_host = NULL; >+hole64_size = 0; > } > > pc_guest_info_init(pcms); >@@ -186,7 +189,7 @@ static void pc_init1(MachineState *machine, > /* allocate ram and load rom/bios */ > if (!xen_enabled()) { > pc_memory_init(pcms, system_memory, >- rom_memory, _memory); >+ rom_memory, _memory, hole64_size); > } else { > pc_system_flash_cleanup_unused(pcms); > if (machine->kernel_filename != NULL) { >diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c >index 46ea89e564de..5a4a737fe203 100644 >--- a/hw/i386/pc_q35.c >+++ b/hw/i386/pc_q35.c >@@ -138,6 +138,7 @@ static void pc_q35_init(MachineState *machine) > MachineClass *mc = MACHINE_GET_CLASS(machine); > bool acpi_pcihp; > bool keep_pci_slot_hpc; >+uint64_t pci_hole64_size = 0; > > /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory > * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping >@@ -206,8 +207,13 @@ static void pc_q35_init(MachineState *machine) > /* create pci host bus */ > q35_host = Q35_HOST_DEVICE(qdev_new(TYPE_Q35_HOST_DEVICE)); > >+if (pcmc->pci_enabled) { >+pci_hole64_size = q35_host->mch.pci_hole64_size; >+} >+ > /* allocate ram and load rom/bios */ >-pc_memory_init(pcms, get_system_memory(), rom_memory, _memory); >+pc_memory_init(pcms, get_system_memory(), rom_memory, _memory, >+ pci_hole64_size); > > object_property_add_child(qdev_get_machine(), "q35", OBJECT(q35_host)); > object_property_set_link(OBJECT(q35_host), MCH_HOST_PROP_RAM_MEM, >diff --git a/hw/pci-host/i440fx.c b/hw/pci-host/i440fx.c >index d5426ef4a53c..15680da7d709 100644 >--- a/hw/pci-host/i440fx.c >+++ b/hw/pci-host/i440fx.c >@@ -237,6 +237,13 @@ static void i440fx_realize(PCIDevice *dev, Error **errp) > } > } > >+uint64_t i440fx_pci_hole64_size(DeviceState *i440fx_dev) >+{ >+I440FXState *i440fx = I440FX_PCI_HOST_BRIDGE(i440fx_dev); >+ >+return i440fx->pci_hole64_size; >+} >+ > PCIBus *i440fx_init(const char *pci_type, > DeviceState *dev, > MemoryRegion *address_space_mem, >diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h >index b7735dccfc81..568c226d3034 100644 >--- a/include/hw/i386/pc.h >+++ b/include/hw/i386/pc.h >@@ -159,7 +159,8 @@ void xen_load_linux(PCMachineState *pcms); > void pc_memory_init(PCMachineState *pcms, > MemoryRegion *system_memory, > MemoryRegion *rom_memory, >-MemoryRegion **ram_memory); >+MemoryRegion **ram_memory, >+
Re: [PATCH v8 00/12] qtests: Check accelerator available at runtime via QMP 'query-accels'
Second attempt of trying to resurrect this thread :-) May anybody please let us know what else is missing in this series of patches? I'm trying to add a 'query-nvmm' qmp command but got redirected to this thread. On 4/7/22 21:27, Antonio Huete Jimenez wrote: Are all these changes OK or is there anything else missing? I was thinking in adding a QMP 'query-nvmm' command but I got pointed to this thread as a better alternative to having a per-accelerator query command.
Re: [PATCH 2/2] target/riscv: Auto set elen from vector extension by default
在 2022/7/9 下午4:11, Weiwei Li 写道: 在 2022/7/8 下午3:39, Kito Cheng 写道: Default ELEN is setting to 64 for now, which is incorrect setting for Zve32*, and spec has mention minimum VLEN and supported EEW in chapter "Zve*: Vector Extensions for Embedded Processors" is 32 for Zve32. ELEN actaully could be derived from which extensions are enabled, so this patch set elen to 0 as auto detect, and keep the capability to let user could configure that. Signed-off-by: Kito Cheng --- target/riscv/cpu.c | 16 +--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 487d0faa63..c1b96da7da 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -751,13 +751,22 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) "Vector extension ELEN must be power of 2"); return; } - if (cpu->cfg.elen > 64 || cpu->cfg.vlen < 8) { + if (cpu->cfg.elen == 0) { + if (cpu->cfg.ext_zve32f) { + cpu->cfg.elen = 32; + } + if (cpu->cfg.ext_zve64f || cpu->cfg.ext_v) { + cpu->cfg.elen = 64; + } This code is in the "if(cpu->cfg.ext_v){...}", so "cpu->cfg.ext_zve64f || cpu->cfg.ext_v" will always be true. It can use "else ... " directly. Sorry, misunderstood the logic. It seems that we should set cpu->cfg.elen=64 directly here. Regards, Weiwei Li + } + if (cpu->cfg.elen != 0 && (cpu->cfg.elen > 64 || + cpu->cfg.elen < 8)) { error_setg(errp, "Vector extension implementation only supports ELEN " "in the range [8, 64]"); return; } - if (cpu->cfg.vlen < cpu->cfg.elen) { + if (cpu->cfg.elen != 0 && cpu->cfg.vlen < cpu->cfg.elen) { when cfg.elen is set to zero, it will be changed to the auto detect value(32/64) before this two check. So this two modifications seem unnecessary. Regards, Weiwei Li error_setg(errp, "Vector extension VLEN must be greater than or equal " "to ELEN"); @@ -901,7 +910,8 @@ static Property riscv_cpu_extensions[] = { DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec), DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec), DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), - DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), + /* elen = 0 means set from v or zve* extension */ + DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 0), DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false), DEFINE_PROP_BOOL("svnapot", RISCVCPU, cfg.ext_svnapot, false),
Re: [PATCH 1/2] target/riscv: Lower bound of VLEN is 32, and check VLEN >= ELEN
在 2022/7/8 下午3:39, Kito Cheng 写道: According RVV spec 1.0, the minmal requirement of VLEN is great than or equal to ELEN, and minmal possible ELEN is 32, and also spec has mention `Minimum VLEN` for zve32* is 32, so the lower bound of VLEN is 32 I think. [1] https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#2-implementation-defined-constant-parameters [2] https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#182-zve-vector-extensions-for-embedded-processors Signed-off-by: Kito Cheng --- target/riscv/cpu.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1bb3973806..487d0faa63 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -740,10 +740,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) "Vector extension VLEN must be power of 2"); return; } -if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) { +if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 32) { error_setg(errp, "Vector extension implementation only supports VLEN " -"in the range [128, %d]", RV_VLEN_MAX); +"in the range [32, %d]", RV_VLEN_MAX); return; } The check for "VLEN in the range [128, RV_VLEN_MAX]" seems right here, since this check is for V vector extension in current implementation and "The V vector extension requires Zvl128b"(in section 18.3). Regards, Weiwei Li if (!is_power_of_2(cpu->cfg.elen)) { @@ -757,6 +757,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) "in the range [8, 64]"); return; } +if (cpu->cfg.vlen < cpu->cfg.elen) { +error_setg(errp, +"Vector extension VLEN must be greater than or equal " +"to ELEN"); +return; +} if (cpu->cfg.vext_spec) { if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) { vext_version = VEXT_VERSION_1_00_0;
Re: [PATCH 2/2] target/riscv: Implement dump content of vector register
在 2022/7/8 下午4:57, Kito Cheng 写道: Implement -d cpu,vu to dump content of vector register. Signed-off-by: Kito Cheng --- target/riscv/cpu.c | 31 +++ 1 file changed, 31 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index c1b96da7da..97b289d277 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -72,6 +72,15 @@ const char * const riscv_fpr_regnames[] = { "f30/ft10", "f31/ft11" }; +const char * const riscv_vr_regnames[] = { + "v0", "v1", "v2", "v3", "v4", "v5", + "v6", "v7", "v8", "v9", "v10", "v11", + "v12", "v13", "v14", "v15", "v16", "v17", + "v18", "v19", "v20", "v21", "v22", "v23", + "v24", "v25", "v26", "v27", "v28", "v29", + "v30", "v31" +}; + static const char * const riscv_excp_names[] = { "misaligned_fetch", "fault_fetch", @@ -375,6 +384,28 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) } } } +if (flags & CPU_DUMP_VU) { +int vlen = cpu->cfg.vlen; +int n_chunk = vlen / 64; +if (vlen == 32) { +for (i = 0; i < 32; i++) { +qemu_fprintf(f, "0x%08" PRIx64 "\n", env->vreg[i]); +} Seems forget to dump the riscv_vr_regnames here. Just another question: whether is it necessary to dump the vector related csrs too? Regards, Weiwei Li +} else { +for (i = 0; i < 32; i++) { +qemu_fprintf(f, " %-8s ", + riscv_vr_regnames[i]); + +int vec_reg_offset = i * vlen / 64; +qemu_fprintf(f, "0x"); +for (int j = n_chunk - 1; j >= 0; --j) { +qemu_fprintf(f, "%016" PRIx64, + env->vreg[vec_reg_offset + j]); +} +qemu_fprintf(f, "\n"); +} +} +} } static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
Re: [PATCH] target/riscv: fix right shifts shamt value for rv128c
在 2022/7/8 下午11:00, Frédéric Pétrot 写道: For rv128c right shifts, the 6-bit shamt is sign extended to 7 bits. Signed-off-by: Frédéric Pétrot --- target/riscv/insn16.decode | 7 --- disas/riscv.c | 27 +-- target/riscv/translate.c | 12 +++- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode index 02c8f61b48..ea3c5a0411 100644 --- a/target/riscv/insn16.decode +++ b/target/riscv/insn16.decode @@ -31,7 +31,8 @@ %imm_cb12:s1 5:2 2:1 10:2 3:2 !function=ex_shift_1 %imm_cj12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1 -%shimm_6bit 12:1 2:5 !function=ex_rvc_shifti +%shlimm_6bit 12:1 2:5 !function=ex_rvc_shiftli +%shrimm_6bit 12:1 2:5 !function=ex_rvc_shiftri %uimm_6bit_lq 2:4 12:1 6:1 !function=ex_shift_4 %uimm_6bit_ld 2:3 12:1 5:2 !function=ex_shift_3 %uimm_6bit_lw 2:2 12:1 4:3 !function=ex_shift_2 It's better to maintain the alignment here. @@ -82,9 +83,9 @@ @c_addi16sp ... . . . .. imm=%imm_addi16sp rs1=2 rd=2 @c_shift... . .. ... . .. \ - rd=%rs1_3 rs1=%rs1_3 shamt=%shimm_6bit + rd=%rs1_3 rs1=%rs1_3 shamt=%shrimm_6bit @c_shift2 ... . .. ... . .. \ - rd=%rd rs1=%rd shamt=%shimm_6bit + rd=%rd rs1=%rd shamt=%shlimm_6bit @c_andi ... . .. ... . .. imm=%imm_ci rs1=%rs1_3 rd=%rs1_3 diff --git a/disas/riscv.c b/disas/riscv.c index 7af6afc8fa..489c2ae5e8 100644 --- a/disas/riscv.c +++ b/disas/riscv.c @@ -2402,10 +2402,25 @@ static int32_t operand_sbimm12(rv_inst inst) ((inst << 56) >> 63) << 11; } -static uint32_t operand_cimmsh6(rv_inst inst) +static uint32_t operand_cimmshl6(rv_inst inst, rv_isa isa) { -return ((inst << 51) >> 63) << 5 | +int imm = ((inst << 51) >> 63) << 5 | (inst << 57) >> 59; +if (isa == rv128) { +imm = imm ? imm : 64; +} +return imm; +} + +static uint32_t operand_cimmshr6(rv_inst inst, rv_isa isa) +{ +int imm = ((inst << 51) >> 63) << 5 | +(inst << 57) >> 59; +if (isa == rv128) { +imm = imm | (imm & 32) << 1; +imm = imm ? imm : 64; +} +return imm; } static int32_t operand_cimmi(rv_inst inst) @@ -2529,7 +2544,7 @@ static uint32_t operand_rnum(rv_inst inst) /* decode operands */ -static void decode_inst_operands(rv_decode *dec) +static void decode_inst_operands(rv_decode *dec, rv_isa isa) { rv_inst inst = dec->inst; dec->codec = opcode_data[dec->op].codec; @@ -2652,7 +2667,7 @@ static void decode_inst_operands(rv_decode *dec) case rv_codec_cb_sh6: dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8; dec->rs2 = rv_ireg_zero; -dec->imm = operand_cimmsh6(inst); +dec->imm = operand_cimmshr6(inst, isa); break; case rv_codec_ci: dec->rd = dec->rs1 = operand_crs1rd(inst); @@ -2667,7 +2682,7 @@ static void decode_inst_operands(rv_decode *dec) case rv_codec_ci_sh6: dec->rd = dec->rs1 = operand_crs1rd(inst); dec->rs2 = rv_ireg_zero; -dec->imm = operand_cimmsh6(inst); +dec->imm = operand_cimmshl6(inst, isa); break; case rv_codec_ci_16sp: dec->rd = rv_ireg_sp; @@ -3193,7 +3208,7 @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst) dec.pc = pc; dec.inst = inst; decode_inst_opcode(, isa); -decode_inst_operands(); +decode_inst_operands(, isa); decode_inst_decompress(, isa); decode_inst_lift_pseudo(); format_inst(buf, buflen, 16, ); diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 63b04e8a94..af3a2cd68c 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -705,12 +705,22 @@ static int ex_rvc_register(DisasContext *ctx, int reg) return 8 + reg; } -static int ex_rvc_shifti(DisasContext *ctx, int imm) +static int ex_rvc_shiftli(DisasContext *ctx, int imm) { /* For RV128 a shamt of 0 means a shift by 64. */ return imm ? imm : 64; } +static int ex_rvc_shiftri(DisasContext *ctx, int imm) +{ +/* + * For RV128 a shamt of 0 means a shift by 64, furthermore, for right + * shifts, the shamt is sign-extended. + */ +imm = imm | (imm & 32) << 1; +return imm ? imm : 64; +} + This calculation didn't add limitation for only working in RV128, and may trigger fault in RV32/RV64, such as following check in gen_shift_imm_fn: if (a->shamt >= max_len) { return false; } Regards, Weiwei Li /* Include the auto-generated decoder for 32 bit insn */ #include "decode-insn32.c.inc"
Re: [PATCH 1/2] target/riscv: Lower bound of VLEN is 32, and check VLEN >= ELEN
在 2022/7/8 下午3:39, Kito Cheng 写道: According RVV spec 1.0, the minmal requirement of VLEN is great than or equal to ELEN, and minmal possible ELEN is 32, and also spec has mention `Minimum VLEN` for zve32* is 32, so the lower bound of VLEN is 32 I think. Sorry. I have a question about how to decide the minmal possible ELEN to be 32? In current implementation, elen should be in the range [8, 64](and there seems to be a typo in the check for this). If the minmal possible ELEN is 32, maybe we need change the check to "elen >= 32" too. Regards, Weiwei Li [1] https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#2-implementation-defined-constant-parameters [2] https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#182-zve-vector-extensions-for-embedded-processors Signed-off-by: Kito Cheng --- target/riscv/cpu.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1bb3973806..487d0faa63 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -740,10 +740,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) "Vector extension VLEN must be power of 2"); return; } -if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) { +if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 32) { error_setg(errp, "Vector extension implementation only supports VLEN " -"in the range [128, %d]", RV_VLEN_MAX); +"in the range [32, %d]", RV_VLEN_MAX); return; } if (!is_power_of_2(cpu->cfg.elen)) { @@ -757,6 +757,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) "in the range [8, 64]"); return; } +if (cpu->cfg.vlen < cpu->cfg.elen) { +error_setg(errp, +"Vector extension VLEN must be greater than or equal " +"to ELEN"); +return; +} if (cpu->cfg.vext_spec) { if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) { vext_version = VEXT_VERSION_1_00_0;
Re: [PATCH 2/2] target/riscv: Auto set elen from vector extension by default
在 2022/7/8 下午3:39, Kito Cheng 写道: Default ELEN is setting to 64 for now, which is incorrect setting for Zve32*, and spec has mention minimum VLEN and supported EEW in chapter "Zve*: Vector Extensions for Embedded Processors" is 32 for Zve32. ELEN actaully could be derived from which extensions are enabled, so this patch set elen to 0 as auto detect, and keep the capability to let user could configure that. Signed-off-by: Kito Cheng --- target/riscv/cpu.c | 16 +--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 487d0faa63..c1b96da7da 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -751,13 +751,22 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) "Vector extension ELEN must be power of 2"); return; } -if (cpu->cfg.elen > 64 || cpu->cfg.vlen < 8) { +if (cpu->cfg.elen == 0) { + if (cpu->cfg.ext_zve32f) { +cpu->cfg.elen = 32; + } + if (cpu->cfg.ext_zve64f || cpu->cfg.ext_v) { +cpu->cfg.elen = 64; + } This code is in the "if(cpu->cfg.ext_v){...}", so "cpu->cfg.ext_zve64f || cpu->cfg.ext_v" will always be true. It can use "else ... " directly. +} +if (cpu->cfg.elen != 0 && (cpu->cfg.elen > 64 || + cpu->cfg.elen < 8)) { error_setg(errp, "Vector extension implementation only supports ELEN " "in the range [8, 64]"); return; } -if (cpu->cfg.vlen < cpu->cfg.elen) { +if (cpu->cfg.elen != 0 && cpu->cfg.vlen < cpu->cfg.elen) { when cfg.elen is set to zero, it will be changed to the auto detect value(32/64) before this two check. So this two modifications seem unnecessary. Regards, Weiwei Li error_setg(errp, "Vector extension VLEN must be greater than or equal " "to ELEN"); @@ -901,7 +910,8 @@ static Property riscv_cpu_extensions[] = { DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec), DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec), DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), -DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), +/* elen = 0 means set from v or zve* extension */ +DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 0), DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false), DEFINE_PROP_BOOL("svnapot", RISCVCPU, cfg.ext_svnapot, false),