Re: [PATCH v7] audio/pwaudio.c: Add Pipewire audio backend for QEMU
Hi Dorinda, I've started to write down my suggestions and comments. After more than one page of text, I think that without sample code, the text is not very understandable. Therefore I will write three mails. In this mail I describe the problem with the QEMU Pipewire audio backend. My next mail is a patch for the v7 QEMU pipewire backend with my suggestions how I would change the code. I can then reply to my own mail with comments, explaining my changes. I tested the pipewire audio backend with the QEMU hda device. Audio playback doesn't work well on my computer. I hear dropouts every few seconds. +#define BUFFER_SAMPLES512 BUFFER_SAMPLES can't be a fixed size. To hear the problem please start QEMU with qemu-system-x86_64 -device ich9-intel-hda -device hda-duplex,audiodev=audio0 -audiodev pipewire,id=audio0,out.frequency=96000,in.frequency=96000 ... . The pipewire backend tells QEMU to use a buffer size of 512 audio frames. The buffer can hold data for 512 frames / 96000 frames/s = 5.3ms. With a timer-period of 10ms there is no way to transport enough frames to the pipewire buffer. Just using a larger BUFFER_SAMPLES value also doesn't work. When I start QEMU with qemu-system-x86_64 -device ich9-intel-hda -device hda-duplex,audiodev=audio0 -audiodev pipewire,id=audio0,timer-period=2000 ... the maximum audio frame throughput increases as when using a larger BUFFER_SAMPLES value. But the higher maximum throughput makes the dropout issue more audible. This has to do with how often pipewire calls playback_on_process() and capture_on_process(). On my system pipewire calls playback_on_process() and capture_on_process() every 21ms and sometimes the callback is delayed by 42ms. At a guest audio frame rate of 44100 frames/s the QEMU hda device drops its buffer if data wasn't read for longer than 23ms on average. With a timer period of 2ms, the PWVoice buffer fills quicker and the time to the next pipewire update is longer. This increases the chance that the hda device drops its buffer. With a timer period of 10ms, the PWVoice buffer fills slower. This is similar to a jitter buffer, but a good jitter buffer implementation would work better. My next mail with the sample code will give pipewire a hint to call the callbacks faster than timer-period and then remove BUFFER_SAMPLES. With best regards, Volker
Re: [PULL 3/3] edk2: update firmware binaries
On Thu, Mar 09, 2023 at 02:09:30PM -0800, Simon Glass wrote: > Hi Gerd, > > Where did these binaries come from? What commit and how were they built? See patch 1/3 for the source (edk2 submodule) update and patch 2/3 for the build scripts. take care, Gerd
Re: [RFC PATCH 1/2] gtk: Make sure widget is realized before updating
On Wed, Mar 8, 2023 at 8:26 PM Damian Hobson-Garcia wrote: > Check that a widget has a window before trying > to update its contents. > --- > ui/gtk.c | 4 > 1 file changed, 4 insertions(+) > Reviewed-by: Marc-André Lureau > > diff --git a/ui/gtk.c b/ui/gtk.c > index fd82e9b1ca..e4e0980323 100644 > --- a/ui/gtk.c > +++ b/ui/gtk.c > @@ -340,6 +340,10 @@ static void gd_update_full_redraw(VirtualConsole *vc) > { > GtkWidget *area = vc->gfx.drawing_area; > int ww, wh; > + > +if (!gtk_widget_get_realized(area)) { > +return; > +} > ww = gdk_window_get_width(gtk_widget_get_window(area)); > wh = gdk_window_get_height(gtk_widget_get_window(area)); > #if defined(CONFIG_OPENGL) > -- > 2.25.1 > >
Re: [PATCH] Fix slli_uw decoding
On Mon, Feb 27, 2023 at 7:06 PM Ivan Klokov wrote: > > The decoding of the slli_uw currently contains decoding > error: shamt part of opcode has six bits, not five. > > Fixes 3de1fb71("target/riscv: update disas.c for xnor/orn/andn and slli.uw") > > Signed-off-by: Ivan Klokov Thanks! Applied to riscv-to-apply.next Alistair > --- > disas/riscv.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/disas/riscv.c b/disas/riscv.c > index ddda687c13..03cfefb0d3 100644 > --- a/disas/riscv.c > +++ b/disas/riscv.c > @@ -1647,7 +1647,7 @@ const rv_opcode_data opcode_data[] = { > { "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > { "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > { "cpopw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "slli.uw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, > +{ "slli.uw", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, > { "add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, > { "rolw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, > { "rorw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, > @@ -2617,10 +2617,10 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa > isa) > switch (((inst >> 12) & 0b111)) { > case 0: op = rv_op_addiw; break; > case 1: > -switch (((inst >> 25) & 0b111)) { > +switch (((inst >> 26) & 0b11)) { > case 0: op = rv_op_slliw; break; > -case 4: op = rv_op_slli_uw; break; > -case 48: > +case 2: op = rv_op_slli_uw; break; > +case 24: > switch ((inst >> 20) & 0b1) { > case 0b0: op = rv_op_clzw; break; > case 0b1: op = rv_op_ctzw; break; > -- > 2.34.1 > >
Re: [PATCH v2 14/18] ui/sdl: add optional logging when _SDL_DEBUG is set
Hi (adding Sam Lantinga, SDL maintainer, in CC. I noticed he worked on QEMU SDL backend yesterday! ;) On Thu, Mar 9, 2023 at 8:40 PM Philippe Mathieu-Daudé wrote: > On 7/3/23 12:56, marcandre.lur...@redhat.com wrote: > > From: Marc-André Lureau > > > > Apparently, there is no environment variable you can set for libsdl to > > enable logging. > > Why not use getenv() in QEMU then? > QEMU has few environment variables. We generally prefer qmp/cmd arguments. And that change does not fit with QEMU tracing etc. > > (similar to _VNC_DEBUG) > > > > Signed-off-by: Marc-André Lureau > > --- > > include/ui/sdl2.h | 2 ++ > > ui/sdl2.c | 4 > > 2 files changed, 6 insertions(+) > > > > diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h > > index 8fb7e08262..6fea36db82 100644 > > --- a/include/ui/sdl2.h > > +++ b/include/ui/sdl2.h > > @@ -6,6 +6,8 @@ > > > > #include > > > > +/* #define _SDL_DEBUG 1 */ > > + > > /* with Alpine / muslc SDL headers pull in directfb headers > >* which in turn trigger warning about redundant decls for > >* direct_waitqueue_deinit. > > diff --git a/ui/sdl2.c b/ui/sdl2.c > > index f259e4c4d1..592eca3e1c 100644 > > --- a/ui/sdl2.c > > +++ b/ui/sdl2.c > > @@ -841,6 +841,10 @@ static void sdl2_display_init(DisplayState *ds, > DisplayOptions *o) > > } > > #endif > > > > +#ifdef _SDL_DEBUG > > +SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE); > > +#endif > Sam, do you suggest a better way to enable SDL debugging when starting QEMU? Is there a way to enable it with existing SDL environment variables? thanks > + > > if (SDL_Init(SDL_INIT_VIDEO)) { > > fprintf(stderr, "Could not initialize SDL(%s) - exiting\n", > > SDL_GetError()); > >
Re: [PATCH 1/2] hw/intc/arm_gicv3: Make ITT entry size configurable
On Fri, Dec 23, 2022 at 12:50 AM Alexander Graf wrote: > > An ITT entry is opaque to the OS. The only thing it does get told by HW is > its size. In theory, that size can be any byte aligned number, in practice > HW will always use power of 2s to simplify offset calculation. We currently > expose the size as 12, which is not a power of 2. > > To prepare for a future where we expose power of 2 sized entry sizes, let's > make the size itself configurable. We only need to watch out that we don't > have an entry be smaller than the fields we want to access inside. Bigger > is always fine. > > Signed-off-by: Alexander Graf > --- Tested-by: Joelle van Dyne
Re: [PATCH] hvf: arm: Add support for GICv3
On Mon, Dec 19, 2022 at 2:08 PM Alexander Graf wrote: > > We currently only support GICv2 emulation. To also support GICv3, we will > need to pass a few system registers into their respective handler functions. > > This patch adds support for HVF to call into the TCG callbacks for GICv3 > system register handlers. This is safe because the GICv3 TCG code is generic > as long as we limit ourselves to EL0 and EL1 - which are the only modes > supported by HVF. > > To make sure nobody trips over that, we also annotate callbacks that don't > work in HVF mode, such as EL state change hooks. > > With GICv3 support in place, we can run with more than 8 vCPUs. > > Signed-off-by: Alexander Graf > --- Tested-by: Joelle van Dyne
Re: [PATCH] Fix slli_uw decoding
On Mon, Feb 27, 2023 at 7:06 PM Ivan Klokov wrote: > > The decoding of the slli_uw currently contains decoding > error: shamt part of opcode has six bits, not five. > > Fixes 3de1fb71("target/riscv: update disas.c for xnor/orn/andn and slli.uw") > > Signed-off-by: Ivan Klokov Acked-by: Alistair Francis Alistair > --- > disas/riscv.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/disas/riscv.c b/disas/riscv.c > index ddda687c13..03cfefb0d3 100644 > --- a/disas/riscv.c > +++ b/disas/riscv.c > @@ -1647,7 +1647,7 @@ const rv_opcode_data opcode_data[] = { > { "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > { "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > { "cpopw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "slli.uw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, > +{ "slli.uw", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, > { "add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, > { "rolw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, > { "rorw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, > @@ -2617,10 +2617,10 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa > isa) > switch (((inst >> 12) & 0b111)) { > case 0: op = rv_op_addiw; break; > case 1: > -switch (((inst >> 25) & 0b111)) { > +switch (((inst >> 26) & 0b11)) { > case 0: op = rv_op_slliw; break; > -case 4: op = rv_op_slli_uw; break; > -case 48: > +case 2: op = rv_op_slli_uw; break; > +case 24: > switch ((inst >> 20) & 0b1) { > case 0b0: op = rv_op_clzw; break; > case 0b1: op = rv_op_ctzw; break; > -- > 2.34.1 > >
Re: [PATCH] Fix incorrect register name in RISC-V disassembler for fmv,fabs,fneg instructions
On Tue, Feb 28, 2023 at 12:53 AM Mikhail Tyutin wrote: > > Fix incorrect register name in RISC-V disassembler for fmv,fabs,fneg > instructions > > Signed-off-by: Mikhail Tyutin It looks like this needs to be rebased. Do you mind rebasing it and sending a v2? Alistair > --- > disas/riscv.c | 19 ++- > 1 file changed, 10 insertions(+), 9 deletions(-) > > diff --git a/disas/riscv.c b/disas/riscv.c > index ddda687c13..58ad3df24d 100644 > --- a/disas/riscv.c > +++ b/disas/riscv.c > @@ -1014,6 +1014,7 @@ static const char rv_vreg_name_sym[32][4] = { > #define rv_fmt_rd_offset "O\t0,o" > #define rv_fmt_rd_rs1_rs2 "O\t0,1,2" > #define rv_fmt_frd_rs1"O\t3,1" > +#define rv_fmt_frd_frs1 "O\t3,4" > #define rv_fmt_rd_frs1"O\t0,4" > #define rv_fmt_rd_frs1_frs2 "O\t0,4,5" > #define rv_fmt_frd_frs1_frs2 "O\t3,4,5" > @@ -1580,15 +1581,15 @@ const rv_opcode_data opcode_data[] = { > { "snez", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 }, > { "sltz", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > { "sgtz", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 }, > -{ "fmv.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fabs.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fneg.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fmv.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fabs.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fneg.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fmv.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fabs.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fneg.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > +{ "fmv.s", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fabs.s", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fneg.s", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fmv.d", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fabs.d", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fneg.d", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fmv.q", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fabs.q", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fneg.q", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > { "beqz", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 }, > { "bnez", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 }, > { "blez", rv_codec_sb, rv_fmt_rs2_offset, NULL, 0, 0, 0 }, > -- > 2.34.1 > >
Re: [PATCH 2/2] target/riscv: Make the "virt" register writable by GDB
On Sun, Mar 5, 2023 at 7:43 PM Jim Shu wrote: > > This patch also enables debugger to set current privilege mode to > VU/VS-mode. > > Extend previous commit 81d2929c41d32af138f3562f5a7b309f6eac7ca7 to > support H-extension. I'm not sure we want this. What is the use case for this? Changing the virt mode on the fly like this is likely to break lots of software. Should we really allow users to do this? Alistair > > Signed-off-by: Jim Shu > Reviewed-by: Frank Chang > --- > target/riscv/gdbstub.c | 18 -- > 1 file changed, 16 insertions(+), 2 deletions(-) > > diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c > index 1755fd9d51..a7f234beaf 100644 > --- a/target/riscv/gdbstub.c > +++ b/target/riscv/gdbstub.c > @@ -203,15 +203,29 @@ static int riscv_gdb_get_virtual(CPURISCVState *cs, > GByteArray *buf, int n) > > static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n) > { > +#ifdef CONFIG_USER_ONLY > +if (n >= 0 && n <= 1) { > +return sizeof(target_ulong); > +} > +#else > +bool virt; > + > if (n == 0) { > -#ifndef CONFIG_USER_ONLY > cs->priv = ldtul_p(mem_buf) & 0x3; > if (cs->priv == PRV_H) { > cs->priv = PRV_S; > } > -#endif > +return sizeof(target_ulong); > +} else if (n == 1) { > +virt = ldtul_p(mem_buf) & 0x1; > +if ((cs->priv == PRV_M) && (virt == true)) { > +/* M-mode only supports V=0. */ > +virt = false; > +} > +riscv_cpu_set_virt_enabled(cs, virt); > return sizeof(target_ulong); > } > +#endif > return 0; > } > > -- > 2.17.1 > >
Re: [PATCH v15 15/60] i386/xen: add pc_machine_kvm_type to initialize XEN_EMULATE mode
On 3/1/2023 9:51 PM, David Woodhouse wrote: From: David Woodhouse The xen_overlay device (and later similar devices for event channels and grant tables) need to be instantiated. Do this from a kvm_type method on the PC machine derivatives, since KVM is only way to support Xen emulation for now. Just curious, isn't there any more reasonable place to add machine specific initialization? abusing the mc->kvm_type() looks bad to me. If everything goes well, KVM x86 will support multiple vm_type[1]. At that time, QEMU will need to implement mc->kvm_type() to get/parse vm type. I have posted the patch to enable it for TDX[2]. [1] https://github.com/sean-jc/linux/commit/fbc35ac0be99b5e02248e7c8f1f3cacb9da512ce [2] https://lore.kernel.org/qemu-devel/20220802074750.2581308-4-xiaoyao...@intel.com/ Signed-off-by: David Woodhouse Reviewed-by: Paul Durrant --- hw/i386/pc.c | 11 +++ include/hw/i386/pc.h | 3 +++ 2 files changed, 14 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 992951c107..a316a01b15 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -90,6 +90,7 @@ #include "hw/virtio/virtio-iommu.h" #include "hw/virtio/virtio-pmem-pci.h" #include "hw/virtio/virtio-mem-pci.h" +#include "hw/i386/kvm/xen_overlay.h" #include "hw/mem/memory-device.h" #include "sysemu/replay.h" #include "target/i386/cpu.h" @@ -1846,6 +1847,16 @@ static void pc_machine_initfn(Object *obj) cxl_machine_init(obj, >cxl_devices_state); } +int pc_machine_kvm_type(MachineState *machine, const char *kvm_type) +{ +#ifdef CONFIG_XEN_EMU +if (xen_mode == XEN_EMULATE) { +xen_overlay_create(); +} +#endif +return 0; +} + static void pc_machine_reset(MachineState *machine, ShutdownCause reason) { CPUState *cs; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 66e3d059ef..467311007e 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -291,12 +291,15 @@ extern const size_t pc_compat_1_5_len; extern GlobalProperty pc_compat_1_4[]; extern const size_t pc_compat_1_4_len; +int pc_machine_kvm_type(MachineState *machine, const char *vm_type); + #define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \ static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \ { \ MachineClass *mc = MACHINE_CLASS(oc); \ optsfn(mc); \ mc->init = initfn; \ +mc->kvm_type = pc_machine_kvm_type; \ } \ static const TypeInfo pc_machine_type_##suffix = { \ .name = namestr TYPE_MACHINE_SUFFIX, \
RE: [PATCH] intel-iommu: Set status bit after operation completed
Hi Peter >-Original Message- >From: Peter Xu >Sent: Thursday, March 9, 2023 10:56 PM >To: Duan, Zhenzhong >Cc: qemu-devel@nongnu.org; m...@redhat.com; jasow...@redhat.com; >pbonz...@redhat.com; richard.hender...@linaro.org; edua...@habkost.net; >marcel.apfelb...@gmail.com >Subject: Re: [PATCH] intel-iommu: Set status bit after operation completed > >Hi, Zhenzhong, > >On Thu, Mar 09, 2023 at 05:23:19PM +0800, Zhenzhong Duan wrote: >> According to SDM 11.4.4.2 Global Status Register: >> "This field is cleared by hardware when software sets the SRTP field >> in the Global Command register. This field is set by hardware when >> hardware completes the ‘Set Root Table Pointer’ operation using the >> value provided in the Root Table Address register" >> >> Follow above spec to clear then set RTPS after finish all works, this >> way helps avoiding potential race with guest kernel. Though linux >> kernel is single threaded in writing GCMD_REG and checking GSTS_REG. >> >> Same reasion for GSTS_REG.TES > >Is this a real bug? Or, when it'll make a difference to the guest? Not a real bug, just for robustness. Sorry, I should have made it clear in comments. I think it may break with special designed guest OS, E.x: Imagine a guest write GCMD_REG and start a new thread to do further work. New thread find status bit in GTS_REG set and go ahead, but the address space switch may not finish yet if guest memory is big, which may trigger a potential race. Original code lives for a long history so it looks all the practiced os aren't designed as above. Thanks Zhenzhong
[PATCH v7 6/6] memory: Introduce address_space_to_flatview_rcu()
In last patch, we wrap vm_load with begin/commit, here we introduce address_space_to_flatview_rcu() to avoid unnecessary enforce commit during vm_load. Signed-off-by: Chuang Xu --- include/exec/memory-internal.h | 2 +- include/exec/memory.h | 20 softmmu/memory.c | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 100c1237ac..1432240449 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -30,7 +30,7 @@ static inline AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv) static inline AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as) { -return flatview_to_dispatch(address_space_to_flatview(as)); +return flatview_to_dispatch(address_space_to_flatview_rcu(as)); } FlatView *address_space_get_flatview(AddressSpace *as); diff --git a/include/exec/memory.h b/include/exec/memory.h index d6fd89db64..235e3017bc 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1100,6 +1100,9 @@ bool memory_region_transaction_in_progress(void); void memory_region_transaction_do_commit(void); +/* + * We recommend using this by default. + */ static inline FlatView *address_space_to_flatview(AddressSpace *as) { if (qemu_mutex_iothread_locked()) { @@ -1123,6 +1126,23 @@ static inline FlatView *address_space_to_flatview(AddressSpace *as) return qatomic_rcu_read(>current_map); } +/* + * We recommend using address_space_to_flatview() rather than this one. + * Note that if we use this during a memory region transaction, we may + * see obsolete flatviews. We must bear with an obsolete map until commit. + * And outside a memory region transaction, this is basically the same as + * address_space_to_flatview(). + */ +static inline FlatView *address_space_to_flatview_rcu(AddressSpace *as) +{ +/* + * Before using any flatview, sanity check BQL or RCU is held. + */ +assert(qemu_mutex_iothread_locked() || rcu_read_is_locked()); + +return qatomic_rcu_read(>current_map); +} + /** * typedef flatview_cb: callback for flatview_for_each_range() * diff --git a/softmmu/memory.c b/softmmu/memory.c index 6a8e8b4e71..33d14e967d 100644 --- a/softmmu/memory.c +++ b/softmmu/memory.c @@ -815,7 +815,7 @@ FlatView *address_space_get_flatview(AddressSpace *as) RCU_READ_LOCK_GUARD(); do { -view = address_space_to_flatview(as); +view = address_space_to_flatview_rcu(as); /* If somebody has replaced as->current_map concurrently, * flatview_ref returns false. */ -- 2.20.1
[PATCH v7 4/6] memory: Add sanity check in address_space_to_flatview
Before using any flatview, sanity check whether BQL or rcu is held. And if we're during a memory region transaction, try to immediately update mappings, or the map can be invalid. Signed-off-by: Chuang Xu --- include/exec/memory.h | 23 +++ softmmu/memory.c | 5 + 2 files changed, 28 insertions(+) diff --git a/include/exec/memory.h b/include/exec/memory.h index 6fa0b071f0..d6fd89db64 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -27,6 +27,7 @@ #include "qemu/notify.h" #include "qom/object.h" #include "qemu/rcu.h" +#include "qemu/main-loop.h" #define RAM_ADDR_INVALID (~(ram_addr_t)0) @@ -1095,8 +1096,30 @@ struct FlatView { MemoryRegion *root; }; +bool memory_region_transaction_in_progress(void); + +void memory_region_transaction_do_commit(void); + static inline FlatView *address_space_to_flatview(AddressSpace *as) { +if (qemu_mutex_iothread_locked()) { +/* We exclusively own the flatview now.. */ +if (memory_region_transaction_in_progress()) { +/* + * Fetch the flatview within a transaction in-progress, it + * means current_map may not be the latest, we need to update + * immediately to make sure the caller won't see obsolete + * mapping. + */ +memory_region_transaction_do_commit(); +} + +/* No further protection needed to access current_map */ +return as->current_map; +} + +/* Otherwise we must have had the RCU lock or something went wrong */ +assert(rcu_read_is_locked()); return qatomic_rcu_read(>current_map); } diff --git a/softmmu/memory.c b/softmmu/memory.c index 33ecc62ee9..6a8e8b4e71 100644 --- a/softmmu/memory.c +++ b/softmmu/memory.c @@ -1130,6 +1130,11 @@ void memory_region_transaction_commit(void) } } +bool memory_region_transaction_in_progress(void) +{ +return memory_region_transaction_depth != 0; +} + static void memory_region_destructor_none(MemoryRegion *mr) { } -- 2.20.1
[PATCH v7 2/6] rcu: Introduce rcu_read_is_locked()
Add rcu_read_is_locked() to detect holding of rcu lock. Signed-off-by: Chuang Xu --- include/qemu/rcu.h | 7 +++ 1 file changed, 7 insertions(+) diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h index 313fc414bc..7bf45602e1 100644 --- a/include/qemu/rcu.h +++ b/include/qemu/rcu.h @@ -115,6 +115,13 @@ static inline void rcu_read_unlock(void) } } +static inline bool rcu_read_is_locked(void) +{ +struct rcu_reader_data *p_rcu_reader = get_ptr_rcu_reader(); + +return p_rcu_reader->depth > 0; +} + extern void synchronize_rcu(void); /* -- 2.20.1
[PATCH v7 3/6] memory: Introduce memory_region_transaction_do_commit()
Split memory_region_transaction_do_commit() from memory_region_transaction_commit(). We'll call do_commit() in address_space_to_flatview() in the later patch. Signed-off-by: Chuang Xu --- softmmu/memory.c | 47 +++ 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/softmmu/memory.c b/softmmu/memory.c index a992a365d9..33ecc62ee9 100644 --- a/softmmu/memory.c +++ b/softmmu/memory.c @@ -1093,34 +1093,41 @@ void memory_region_transaction_begin(void) ++memory_region_transaction_depth; } -void memory_region_transaction_commit(void) +void memory_region_transaction_do_commit(void) { AddressSpace *as; -assert(memory_region_transaction_depth); assert(qemu_mutex_iothread_locked()); ---memory_region_transaction_depth; -if (!memory_region_transaction_depth) { -if (memory_region_update_pending) { -flatviews_reset(); +if (memory_region_update_pending) { +flatviews_reset(); -MEMORY_LISTENER_CALL_GLOBAL(begin, Forward); +MEMORY_LISTENER_CALL_GLOBAL(begin, Forward); -QTAILQ_FOREACH(as, _spaces, address_spaces_link) { -address_space_set_flatview(as); -address_space_update_ioeventfds(as); -} -memory_region_update_pending = false; -ioeventfd_update_pending = false; -MEMORY_LISTENER_CALL_GLOBAL(commit, Forward); -} else if (ioeventfd_update_pending) { -QTAILQ_FOREACH(as, _spaces, address_spaces_link) { -address_space_update_ioeventfds(as); -} -ioeventfd_update_pending = false; +QTAILQ_FOREACH(as, _spaces, address_spaces_link) { +address_space_set_flatview(as); +address_space_update_ioeventfds(as); +} +memory_region_update_pending = false; +ioeventfd_update_pending = false; +MEMORY_LISTENER_CALL_GLOBAL(commit, Forward); +} else if (ioeventfd_update_pending) { +QTAILQ_FOREACH(as, _spaces, address_spaces_link) { +address_space_update_ioeventfds(as); } - } +ioeventfd_update_pending = false; +} +} + +void memory_region_transaction_commit(void) +{ +assert(memory_region_transaction_depth); +assert(qemu_mutex_iothread_locked()); + +--memory_region_transaction_depth; +if (!memory_region_transaction_depth) { +memory_region_transaction_do_commit(); +} } static void memory_region_destructor_none(MemoryRegion *mr) -- 2.20.1
[PATCH v7 1/6] memory: Reference as->current_map directly in memory commit
From: Peter Xu Calling RCU variance of address_space_get|to_flatview() during memory commit (flatview updates, triggering memory listeners, or updating ioeventfds, etc.) is not 100% accurate, because commit() requires BQL rather than RCU read lock, so the context exclusively owns current_map and can be directly referenced. Neither does it need a refcount to current_map because it cannot be freed from under the caller. Add address_space_get_flatview_raw() for the case where the context holds BQL rather than RCU read lock and use it across the core memory updates, Drop the extra refcounts on FlatView*. Signed-off-by: Peter Xu --- softmmu/memory.c | 28 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/softmmu/memory.c b/softmmu/memory.c index 4699ba55ec..a992a365d9 100644 --- a/softmmu/memory.c +++ b/softmmu/memory.c @@ -61,6 +61,13 @@ struct AddrRange { Int128 size; }; +/* Called with BQL held */ +static inline FlatView *address_space_to_flatview_raw(AddressSpace *as) +{ +assert(qemu_mutex_iothread_locked()); +return as->current_map; +} + static AddrRange addrrange_make(Int128 start, Int128 size) { return (AddrRange) { start, size }; @@ -155,7 +162,7 @@ enum ListenerDirection { Forward, Reverse }; #define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback, _args...) \ do {\ MemoryRegionSection mrs = section_from_flat_range(fr, \ -address_space_to_flatview(as)); \ +address_space_to_flatview_raw(as)); \ MEMORY_LISTENER_CALL(as, callback, dir, , ##_args); \ } while(0) @@ -753,6 +760,7 @@ static FlatView *generate_memory_topology(MemoryRegion *mr) } static void address_space_add_del_ioeventfds(AddressSpace *as, + FlatView *view, MemoryRegionIoeventfd *fds_new, unsigned fds_new_nb, MemoryRegionIoeventfd *fds_old, @@ -774,7 +782,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as, _new[inew]))) { fd = _old[iold]; section = (MemoryRegionSection) { -.fv = address_space_to_flatview(as), +.fv = view, .offset_within_address_space = int128_get64(fd->addr.start), .size = fd->addr.size, }; @@ -787,7 +795,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as, _old[iold]))) { fd = _new[inew]; section = (MemoryRegionSection) { -.fv = address_space_to_flatview(as), +.fv = view, .offset_within_address_space = int128_get64(fd->addr.start), .size = fd->addr.size, }; @@ -833,7 +841,7 @@ static void address_space_update_ioeventfds(AddressSpace *as) ioeventfd_max = QEMU_ALIGN_UP(as->ioeventfd_nb, 4); ioeventfds = g_new(MemoryRegionIoeventfd, ioeventfd_max); -view = address_space_get_flatview(as); +view = address_space_to_flatview_raw(as); FOR_EACH_FLAT_RANGE(fr, view) { for (i = 0; i < fr->mr->ioeventfd_nb; ++i) { tmp = addrrange_shift(fr->mr->ioeventfds[i].addr, @@ -852,13 +860,12 @@ static void address_space_update_ioeventfds(AddressSpace *as) } } -address_space_add_del_ioeventfds(as, ioeventfds, ioeventfd_nb, +address_space_add_del_ioeventfds(as, view, ioeventfds, ioeventfd_nb, as->ioeventfds, as->ioeventfd_nb); g_free(as->ioeventfds); as->ioeventfds = ioeventfds; as->ioeventfd_nb = ioeventfd_nb; -flatview_unref(view); } /* @@ -1026,7 +1033,7 @@ static void flatviews_reset(void) static void address_space_set_flatview(AddressSpace *as) { -FlatView *old_view = address_space_to_flatview(as); +FlatView *old_view = address_space_to_flatview_raw(as); MemoryRegion *physmr = memory_region_get_flatview_root(as->root); FlatView *new_view = g_hash_table_lookup(flat_views, physmr); @@ -2979,8 +2986,7 @@ static void listener_add_address_space(MemoryListener *listener, listener->log_global_start(listener); } } - -view = address_space_get_flatview(as); +view = address_space_to_flatview_raw(as); FOR_EACH_FLAT_RANGE(fr, view) { MemoryRegionSection section = section_from_flat_range(fr, view); @@ -2994,7 +3000,6 @@ static void listener_add_address_space(MemoryListener *listener, if (listener->commit) { listener->commit(listener); } -flatview_unref(view); } static void listener_del_address_space(MemoryListener *listener, @@
[PATCH v7 5/6] migration: Reduce time of loading non-iterable vmstate
The duration of loading non-iterable vmstate accounts for a significant portion of downtime (starting with the timestamp of source qemu stop and ending with the timestamp of target qemu start). Most of the time is spent committing memory region changes repeatedly. This patch packs all the changes to memory region during the period of loading non-iterable vmstate in a single memory transaction. With the increase of devices, this patch will greatly improve the performance. Note that the following test results are based on the application of the next patch. Without the next patch, the improvement will be reduced. Here are the test1 results: test info: - Host - Intel(R) Xeon(R) Platinum 8362 CPU - Mellanox Technologies MT28841 - VM - 32 CPUs 128GB RAM VM - 8 16-queue vhost-net device - 16 4-queue vhost-user-blk device. time of loading non-iterable vmstate downtime before about 112 ms 285 ms after about 20 ms 194 ms In test2, we keep the number of the device the same as test1, reduce the number of queues per device: Here are the test2 results: test info: - Host - Intel(R) Xeon(R) Platinum 8362 CPU - Mellanox Technologies MT28841 - VM - 32 CPUs 128GB RAM VM - 8 1-queue vhost-net device - 16 1-queue vhost-user-blk device. time of loading non-iterable vmstate downtime before about 65 ms about 151 ms after about 19 ms about 100 ms In test3, we keep the number of queues per device the same as test1, reduce the number of devices: Here are the test3 results: test info: - Host - Intel(R) Xeon(R) Platinum 8362 CPU - Mellanox Technologies MT28841 - VM - 32 CPUs 128GB RAM VM - 1 16-queue vhost-net device - 1 4-queue vhost-user-blk device. time of loading non-iterable vmstate downtime before about 24 ms about 51 ms after about 9 ms about 36 ms As we can see from the test results above, both the number of queues and the number of devices have a great impact on the time of loading non-iterable vmstate. The growth of the number of devices and queues will lead to more mr commits, and the time consumption caused by the flatview reconstruction will also increase. Signed-off-by: Chuang Xu --- migration/savevm.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/migration/savevm.c b/migration/savevm.c index aa54a67fda..9a7d3e40d6 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2762,6 +2762,7 @@ out: goto retry; } } + return ret; } @@ -2787,7 +2788,25 @@ int qemu_loadvm_state(QEMUFile *f) cpu_synchronize_all_pre_loadvm(); +/* + * Call memory_region_transaction_begin() before loading vmstate. + * This call is paired with memory_region_transaction_commit() at + * the end of qemu_loadvm_state_main(), in order to pack all the + * changes to memory region during the period of loading + * non-iterable vmstate in a single memory transaction. + * This operation will reduce time of loading non-iterable vmstate + */ +memory_region_transaction_begin(); + ret = qemu_loadvm_state_main(f, mis); + +/* + * Call memory_region_transaction_commit() after loading vmstate. + * At this point, qemu actually completes all the previous memory + * region transactions. + */ +memory_region_transaction_commit(); + qemu_event_set(>main_thread_load_event); trace_qemu_loadvm_state_post_main(ret); -- 2.20.1
[PATCH v7 0/6] migration: reduce time of loading non-iterable vmstate
In this version: - introduce address_space_to_flatview_rcu() - squash peter's fix into patch 1 - rebase to latest upstream - update test results The duration of loading non-iterable vmstate accounts for a significant portion of downtime (starting with the timestamp of source qemu stop and ending with the timestamp of target qemu start). Most of the time is spent committing memory region changes repeatedly. This patch packs all the changes to memory region during the period of loading non-iterable vmstate in a single memory transaction. With the increase of devices, this patch will greatly improve the performance. Here are the test1 results: test info: - Host - Intel(R) Xeon(R) Platinum 8362 CPU - Mellanox Technologies MT28841 - VM - 32 CPUs 128GB RAM VM - 8 16-queue vhost-net device - 16 4-queue vhost-user-blk device. time of loading non-iterable vmstate downtime before 112 ms 285 ms after20 ms194 ms In test2, we keep the number of the device the same as test1, reduce the number of queues per device: Here are the test2 results: test info: - Host - Intel(R) Xeon(R) Platinum 8362 CPU - Mellanox Technologies MT28841 - VM - 32 CPUs 128GB RAM VM - 8 1-queue vhost-net device - 16 1-queue vhost-user-blk device. time of loading non-iterable vmstate downtime before 65 ms151 ms after19 ms100 ms In test3, we keep the number of queues per device the same as test1, reduce the number of devices: Here are the test3 results: test info: - Host - Intel(R) Xeon(R) Platinum 8362 CPU - Mellanox Technologies MT28841 - VM - 32 CPUs 128GB RAM VM - 1 16-queue vhost-net device - 1 4-queue vhost-user-blk device. time of loading non-iterable vmstate downtime before 24 ms51 ms after9 ms 36 ms As we can see from the test results above, both the number of queues and the number of devices have a great impact on the time of loading non-iterable vmstate. The growth of the number of devices and queues will lead to more mr commits, and the time consumption caused by the flatview reconstruction will also increase. Please review, Chuang [v6] - add peter's patch. - split mr_do_commit() from mr_commit(). - adjust the sanity check in address_space_to_flatview(). - rebase to latest upstream. - replace 8260 with 8362 as testing host. - update the latest test results. [v5] - rename rcu_read_locked() to rcu_read_is_locked(). - adjust the sanity check in address_space_to_flatview(). - improve some comments. [v4] - attach more information in the cover letter. - remove changes on virtio_load. - add rcu_read_locked() to detect holding of rcu lock. [v3] - move virtio_load_check_delay() from virtio_memory_listener_commit() to virtio_vmstate_change(). - add delay_check flag to VirtIODevice to make sure virtio_load_check_delay() will be called when delay_check is true. [v2] - rebase to latest upstream. - add sanity check to address_space_to_flatview(). - postpone the init of the vring cache until migration's loading completes. [v1] The duration of loading non-iterable vmstate accounts for a significant portion of downtime (starting with the timestamp of source qemu stop and ending with the timestamp of target qemu start). Most of the time is spent committing memory region changes repeatedly. This patch packs all the changes to memory region during the period of loading non-iterable vmstate in a single memory transaction. With the increase of devices, this patch will greatly improve the performance. Here are the test results: test vm info: - 32 CPUs 128GB RAM - 8 16-queue vhost-net device - 16 4-queue vhost-user-blk device. time of loading non-iterable vmstate before about 210 ms after about 40 ms
Re: [PATCH] target/riscv/csr.c: fix H extension TVM trap
On 2023/3/8 20:34, chenyi2...@zju.edu.cn wrote: From: Yi Chen Trap accesses to hgatp if MSTATUS_TVM is enabled. Don't trap accesses to vsatp even if MSTATUS_TVM is enabled. By the way, do you know why mstatus_tvm and hstatus_tvm are needed? The specification said, The TVM mechanism improves virtualization efficiency by permitting guest operating systems to execute in S-mode, rather than classically virtualizing them in U-mode. This approach obviates the need to trap accesses to most S-mode CSRs. I don't know how the tvm field obviates the need to trap accesses to most S-mode CSRs. Thanks, Zhiwei Signed-off-by: Yi Chen --- target/riscv/csr.c | 18 ++ 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/target/riscv/csr.c b/target/riscv/csr.c index ab56663..09bc780 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -2655,7 +2655,7 @@ static RISCVException read_satp(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } -if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) { +if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) && get_field(env->mstatus, MSTATUS_TVM)) { return RISCV_EXCP_ILLEGAL_INST; } else { *val = env->satp; @@ -2683,7 +2683,7 @@ static RISCVException write_satp(CPURISCVState *env, int csrno, } if (vm && mask) { -if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) { +if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) && get_field(env->mstatus, MSTATUS_TVM)) { return RISCV_EXCP_ILLEGAL_INST; } else { /* @@ -3047,14 +3047,24 @@ static RISCVException read_hgeip(CPURISCVState *env, int csrno, static RISCVException read_hgatp(CPURISCVState *env, int csrno, target_ulong *val) { -*val = env->hgatp; +if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) { +return RISCV_EXCP_ILLEGAL_INST; +} else { +*val = env->hgatp; +} + return RISCV_EXCP_NONE; } static RISCVException write_hgatp(CPURISCVState *env, int csrno, target_ulong val) { -env->hgatp = val; +if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) { +return RISCV_EXCP_ILLEGAL_INST; +} else { +env->hgatp = val; +} + return RISCV_EXCP_NONE; }
Re: [PATCH for-8.1 03/17] target/riscv/cpu.c: remove set_priv_version()
On Fri, Mar 10, 2023 at 2:23 AM Daniel Henrique Barboza wrote: > > > > On 3/9/23 04:28, LIU Zhiwei wrote: > > > > On 2023/3/9 4:19, Daniel Henrique Barboza wrote: > >> The setter is doing nothing special. Just set env->priv_ver directly. > > IMHO, No better than the older implementation. > > In the current context having a setter means that the function is doing > something else other than simply setting the attr. Because we're setting a > lot of other 'env' attrs directly: env->pc, env->priv, env->menvcfg and > so on. So a setter is a special function (e.g. set_misa()). > > But then set_priv_version() and set_vext_version() are just setting > env->priv_ver/env->vext_version and nothing else. This means that every > time we read > > "set_priv_version(env, val)" > > We're either required to remember that this is just a simple setter or we > spend > a few seconds looking it up to see that it's a simple setter. We could, > instead, > just read > > "env->priv_ver = val" > > and moved on. > > > I really think we should get rid of all these kind of setters in the code. > It's not > like these are user facing APIs that needs encapsulation. I tend to agree. I don't think they add anything. I guess you could debate they are kind of self commenting as the function name describes what is happening, but I think in a lot of cases it's pretty clear as is. Alistair > > > Thanks, > > > Daniel > > > > > > > Zhiwei > > > >> > >> Signed-off-by: Daniel Henrique Barboza > >> --- > >> target/riscv/cpu.c | 30 +- > >> 1 file changed, 13 insertions(+), 17 deletions(-) > >> > >> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > >> index 0baed79ec2..964817b9d2 100644 > >> --- a/target/riscv/cpu.c > >> +++ b/target/riscv/cpu.c > >> @@ -240,11 +240,6 @@ static void set_misa(CPURISCVState *env, RISCVMXL > >> mxl, uint32_t ext) > >> env->misa_ext_mask = env->misa_ext = ext; > >> } > >> -static void set_priv_version(CPURISCVState *env, int priv_ver) > >> -{ > >> -env->priv_ver = priv_ver; > >> -} > >> - > >> #ifndef CONFIG_USER_ONLY > >> static uint8_t satp_mode_from_str(const char *satp_mode_str) > >> { > >> @@ -343,7 +338,7 @@ static void riscv_any_cpu_init(Object *obj) > >> VM_1_10_SV32 : VM_1_10_SV57); > >> #endif > >> -set_priv_version(env, PRIV_VERSION_1_12_0); > >> +env->priv_ver = PRIV_VERSION_1_12_0; > >> register_cpu_props(obj); > >> } > >> @@ -355,7 +350,7 @@ static void rv64_base_cpu_init(Object *obj) > >> set_misa(env, MXL_RV64, 0); > >> register_cpu_props(obj); > >> /* Set latest version of privileged specification */ > >> -set_priv_version(env, PRIV_VERSION_1_12_0); > >> +env->priv_ver = PRIV_VERSION_1_12_0; > >> #ifndef CONFIG_USER_ONLY > >> set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57); > >> #endif > >> @@ -366,7 +361,7 @@ static void rv64_sifive_u_cpu_init(Object *obj) > >> CPURISCVState *env = _CPU(obj)->env; > >> set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | > >> RVU); > >> register_cpu_props(obj); > >> -set_priv_version(env, PRIV_VERSION_1_10_0); > >> +env->priv_ver = PRIV_VERSION_1_10_0; > >> #ifndef CONFIG_USER_ONLY > >> set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39); > >> #endif > >> @@ -379,7 +374,7 @@ static void rv64_sifive_e_cpu_init(Object *obj) > >> set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU); > >> register_cpu_props(obj); > >> -set_priv_version(env, PRIV_VERSION_1_10_0); > >> +env->priv_ver = PRIV_VERSION_1_10_0; > >> cpu->cfg.mmu = false; > >> #ifndef CONFIG_USER_ONLY > >> set_satp_mode_max_supported(cpu, VM_1_10_MBARE); > >> @@ -392,7 +387,7 @@ static void rv64_thead_c906_cpu_init(Object *obj) > >> RISCVCPU *cpu = RISCV_CPU(obj); > >> set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | > >> RVU); > >> -set_priv_version(env, PRIV_VERSION_1_11_0); > >> +env->priv_ver = PRIV_VERSION_1_11_0; > >> cpu->cfg.ext_g = true; > >> cpu->cfg.ext_c = true; > >> @@ -431,7 +426,7 @@ static void rv128_base_cpu_init(Object *obj) > >> set_misa(env, MXL_RV128, 0); > >> register_cpu_props(obj); > >> /* Set latest version of privileged specification */ > >> -set_priv_version(env, PRIV_VERSION_1_12_0); > >> +env->priv_ver = PRIV_VERSION_1_12_0; > >> #ifndef CONFIG_USER_ONLY > >> set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57); > >> #endif > >> @@ -444,7 +439,7 @@ static void rv32_base_cpu_init(Object *obj) > >> set_misa(env, MXL_RV32, 0); > >> register_cpu_props(obj); > >> /* Set latest version of privileged specification */ > >> -set_priv_version(env, PRIV_VERSION_1_12_0); > >> +env->priv_ver = PRIV_VERSION_1_12_0; > >> #ifndef CONFIG_USER_ONLY > >> set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32); > >> #endif > >>
Re: [PATCH 1/2] target/riscv: Expose "virt" register for GDB for reads
On Sun, Mar 5, 2023 at 7:43 PM Jim Shu wrote: > > This patch enables a debugger to read current virtualization mode via > virtual "virt" register. After it, we could get full current privilege > mode via both "priv" and "virt" register. > > Extend previous commit ab9056ff9bdb3f95db6e7a666d10522d289f14ec to > support H-extension. > > Signed-off-by: Jim Shu > Reviewed-by: Frank Chang Reviewed-by: Alistair Francis Alistair > --- > gdb-xml/riscv-32bit-virtual.xml | 1 + > gdb-xml/riscv-64bit-virtual.xml | 1 + > target/riscv/gdbstub.c | 12 > 3 files changed, 10 insertions(+), 4 deletions(-) > > diff --git a/gdb-xml/riscv-32bit-virtual.xml b/gdb-xml/riscv-32bit-virtual.xml > index 905f1c555d..d44b6ca2dc 100644 > --- a/gdb-xml/riscv-32bit-virtual.xml > +++ b/gdb-xml/riscv-32bit-virtual.xml > @@ -8,4 +8,5 @@ > > > > + > > diff --git a/gdb-xml/riscv-64bit-virtual.xml b/gdb-xml/riscv-64bit-virtual.xml > index 62d86c237b..7c9b63d5b6 100644 > --- a/gdb-xml/riscv-64bit-virtual.xml > +++ b/gdb-xml/riscv-64bit-virtual.xml > @@ -8,4 +8,5 @@ > > > > + > > diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c > index 6048541606..1755fd9d51 100644 > --- a/target/riscv/gdbstub.c > +++ b/target/riscv/gdbstub.c > @@ -187,13 +187,17 @@ static int riscv_gdb_set_csr(CPURISCVState *env, > uint8_t *mem_buf, int n) > > static int riscv_gdb_get_virtual(CPURISCVState *cs, GByteArray *buf, int n) > { > -if (n == 0) { > #ifdef CONFIG_USER_ONLY > +if (n >= 0 && n <= 1) { > return gdb_get_regl(buf, 0); > +} > #else > +if (n == 0) { > return gdb_get_regl(buf, cs->priv); > -#endif > +} else if (n == 1) { > +return gdb_get_regl(buf, riscv_cpu_virt_enabled(cs)); > } > +#endif > return 0; > } > > @@ -328,13 +332,13 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState > *cs) > case MXL_RV32: > gdb_register_coprocessor(cs, riscv_gdb_get_virtual, > riscv_gdb_set_virtual, > - 1, "riscv-32bit-virtual.xml", 0); > + 2, "riscv-32bit-virtual.xml", 0); > break; > case MXL_RV64: > case MXL_RV128: > gdb_register_coprocessor(cs, riscv_gdb_get_virtual, > riscv_gdb_set_virtual, > - 1, "riscv-64bit-virtual.xml", 0); > + 2, "riscv-64bit-virtual.xml", 0); > break; > default: > g_assert_not_reached(); > -- > 2.17.1 > >
Re: [PATCH] Fix incorrect register name in RISC-V disassembler for fmv,fabs,fneg instructions
On Tue, Feb 28, 2023 at 12:53 AM Mikhail Tyutin wrote: > > Fix incorrect register name in RISC-V disassembler for fmv,fabs,fneg > instructions > > Signed-off-by: Mikhail Tyutin Reviewed-by: Alistair Francis Alistair > --- > disas/riscv.c | 19 ++- > 1 file changed, 10 insertions(+), 9 deletions(-) > > diff --git a/disas/riscv.c b/disas/riscv.c > index ddda687c13..58ad3df24d 100644 > --- a/disas/riscv.c > +++ b/disas/riscv.c > @@ -1014,6 +1014,7 @@ static const char rv_vreg_name_sym[32][4] = { > #define rv_fmt_rd_offset "O\t0,o" > #define rv_fmt_rd_rs1_rs2 "O\t0,1,2" > #define rv_fmt_frd_rs1"O\t3,1" > +#define rv_fmt_frd_frs1 "O\t3,4" > #define rv_fmt_rd_frs1"O\t0,4" > #define rv_fmt_rd_frs1_frs2 "O\t0,4,5" > #define rv_fmt_frd_frs1_frs2 "O\t3,4,5" > @@ -1580,15 +1581,15 @@ const rv_opcode_data opcode_data[] = { > { "snez", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 }, > { "sltz", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > { "sgtz", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 }, > -{ "fmv.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fabs.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fneg.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fmv.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fabs.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fneg.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fmv.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fabs.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > -{ "fneg.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, > +{ "fmv.s", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fabs.s", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fneg.s", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fmv.d", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fabs.d", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fneg.d", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fmv.q", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fabs.q", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > +{ "fneg.q", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, > { "beqz", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 }, > { "bnez", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 }, > { "blez", rv_codec_sb, rv_fmt_rs2_offset, NULL, 0, 0, 0 }, > -- > 2.34.1 > >
Re: [Question] Support RISC-V Board on QEMU
On Wed, Mar 8, 2023 at 12:10 AM 김진홍 wrote: > > Dear Developer of QEMU. > > > > I have a question to run QEMU by RISC-V board. > > > > Currently, sifive has "HiFive Unleashed" and "HiFive Unmatched" boards. > > > > HiFive Unleashed board is set when executed with "-M sifive_u" option in QEMU > (v7.2.0). > > > > And the official guide of QEMU is also the guide of "HiFive Unleashed". > (https://www.qemu.org/docs/master/system/riscv/sifive_u.html) > > > > QEMU currently supports the HiFive Unmatched board? and if so, is there a > guide? QEMU doesn't support the HiFive Unmatched. Most QEMU users end up using the virt board, as it has the most extensions (more than any physical board). Alistair > > > > Thank you. > > > >
[PATCH v5 2/3] qga: Add `merged` variant to GuestExecCaptureOutputMode
Currently, any captured output (via `capture-output`) is segregated into separate GuestExecStatus fields (`out-data` and `err-data`). This means that downstream consumers have no way to reassemble the captured data back into the original stream. This is relevant for chatty and semi-interactive (ie. read only) CLI tools. Such tools may deliberately interleave stdout and stderr for visual effect. If segregated, the output becomes harder to visually understand. This commit adds a new enum variant to the GuestExecCaptureOutputMode qapi to merge the output streams such that consumers can have a pristine view of the original command output. Signed-off-by: Daniel Xu --- qga/commands.c | 31 +-- qga/qapi-schema.json | 4 +++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/qga/commands.c b/qga/commands.c index 01f68b45ab..c347d434ed 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -270,12 +270,26 @@ static void guest_exec_child_watch(GPid pid, gint status, gpointer data) g_spawn_close_pid(pid); } -/** Reset ignored signals back to default. */ static void guest_exec_task_setup(gpointer data) { #if !defined(G_OS_WIN32) +bool has_merge = *(bool *)data; struct sigaction sigact; +if (has_merge) { +/* + * FIXME: When `GLIB_VERSION_MIN_REQUIRED` is bumped to 2.58+, use + * g_spawn_async_with_fds() to be portable on windows. The current + * logic does not work on windows b/c `GSpawnChildSetupFunc` is run + * inside the parent, not the child. + */ +if (dup2(STDOUT_FILENO, STDERR_FILENO) != 0) { +slog("dup2() failed to merge stderr into stdout: %s", + strerror(errno)); +} +} + +/* Reset ignored signals back to default. */ memset(, 0, sizeof(struct sigaction)); sigact.sa_handler = SIG_DFL; @@ -409,6 +423,7 @@ GuestExec *qmp_guest_exec(const char *path, GIOChannel *in_ch, *out_ch, *err_ch; GSpawnFlags flags; bool has_output = false; +bool has_merge = false; GuestExecCaptureOutputMode output_mode; g_autofree uint8_t *input = NULL; size_t ninput = 0; @@ -445,13 +460,25 @@ GuestExec *qmp_guest_exec(const char *path, case GUEST_EXEC_CAPTURE_OUTPUT_MODE_SEPARATED: has_output = true; break; +case GUEST_EXEC_CAPTURE_OUTPUT_MODE_MERGED: +has_output = true; +has_merge = true; +break; case GUEST_EXEC_CAPTURE_OUTPUT_MODE__MAX: /* Silence warning; impossible branch */ break; } +#if defined(G_OS_WIN32) +/* FIXME: see comment in guest_exec_task_setup() */ +if (has_merge) { +error_setg(errp, "merged unsupported on windows"); +return NULL; +} +#endif + ret = g_spawn_async_with_pipes(NULL, argv, envp, flags, -guest_exec_task_setup, NULL, , input_data ? _fd : NULL, +guest_exec_task_setup, _merge, , input_data ? _fd : NULL, has_output ? _fd : NULL, has_output ? _fd : NULL, ); if (!ret) { error_setg(errp, QERR_QGA_COMMAND_FAILED, gerr->message); diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index d1e00a4234..b4782525ae 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -1210,11 +1210,13 @@ # @stderr: only capture stderr # @separated: capture both stdout and stderr, but separated into # GuestExecStatus out-data and err-data, respectively +# @merged: capture both stdout and stderr, but merge together +# into out-data. not effective on windows guests. # # Since: 8.0 ## { 'enum': 'GuestExecCaptureOutputMode', - 'data': [ 'none', 'stdout', 'stderr', 'separated' ] } + 'data': [ 'none', 'stdout', 'stderr', 'separated', 'merged' ] } ## # @GuestExecCaptureOutput: -- 2.39.1
[PATCH v5 0/3] qga: Support merging output streams in guest-exec
Currently, the captured output (via `capture-output`) is segregated into separate GuestExecStatus fields (`out-data` and `err-data`). This means that downstream consumers have no way to reassemble the captured data back into the original stream. This is relevant for chatty and semi-interactive (ie. read only) CLI tools. Such tools may deliberately interleave stdout and stderr for visual effect. If segregated, the output becomes harder to visually understand. This patchset adds support for merging stderr and stdout output streams via a backwards compatibile refactor and a new enum variant, `all-merge`. --- Changes from v4: * Rename `all` -> `separated` * Rename `all-merge` -> `merged` Changes from v3: * Split out ASAN fixes into separate patch series * Refactor `capture-output` flag into an enum * Avoid using /bin/bash on windows Changes from v2: * Error out if `merge-output` on windows guests * Add FIXMEs for when glib is updated * Fix memory leaks in qemu-keymap Changes from v1: * Drop invalid test fix * Do not support `merge-output` on windows guests * Fix a UAF in tests Daniel Xu (3): qga: Refactor guest-exec capture-output to take enum qga: Add `merged` variant to GuestExecCaptureOutputMode qga: test: Add tests for `merged` flag qga/commands.c| 68 -- qga/qapi-schema.json | 35 +- tests/unit/test-qga.c | 158 +- 3 files changed, 238 insertions(+), 23 deletions(-) -- 2.39.1
[PATCH v5 1/3] qga: Refactor guest-exec capture-output to take enum
Previously capture-output was an optional boolean flag that either captured all output or captured none. While this is OK in most cases, it lacks flexibility for more advanced capture cases, such as wanting to only capture stdout. This commits refactors guest-exec qapi to take an enum for capture mode instead while preserving backwards compatibility. Suggested-by: Daniel P. Berrangé Signed-off-by: Daniel Xu --- qga/commands.c | 37 ++--- qga/qapi-schema.json | 33 - 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/qga/commands.c b/qga/commands.c index 172826f8f8..01f68b45ab 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -379,11 +379,23 @@ close: return false; } +static GuestExecCaptureOutputMode ga_parse_capture_output( +GuestExecCaptureOutput *capture_output) +{ +if (!capture_output) +return GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE; +else if (capture_output->type == QTYPE_QBOOL) +return capture_output->u.flag ? GUEST_EXEC_CAPTURE_OUTPUT_MODE_SEPARATED + : GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE; +else +return capture_output->u.mode; +} + GuestExec *qmp_guest_exec(const char *path, bool has_arg, strList *arg, bool has_env, strList *env, const char *input_data, - bool has_capture_output, bool capture_output, + GuestExecCaptureOutput *capture_output, Error **errp) { GPid pid; @@ -396,7 +408,8 @@ GuestExec *qmp_guest_exec(const char *path, gint in_fd, out_fd, err_fd; GIOChannel *in_ch, *out_ch, *err_ch; GSpawnFlags flags; -bool has_output = (has_capture_output && capture_output); +bool has_output = false; +GuestExecCaptureOutputMode output_mode; g_autofree uint8_t *input = NULL; size_t ninput = 0; @@ -415,8 +428,26 @@ GuestExec *qmp_guest_exec(const char *path, flags = G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH_FROM_ENVP; -if (!has_output) { + +output_mode = ga_parse_capture_output(capture_output); +switch (output_mode) { +case GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE: flags |= G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL; +break; +case GUEST_EXEC_CAPTURE_OUTPUT_MODE_STDOUT: +has_output = true; +flags |= G_SPAWN_STDERR_TO_DEV_NULL; +break; +case GUEST_EXEC_CAPTURE_OUTPUT_MODE_STDERR: +has_output = true; +flags |= G_SPAWN_STDOUT_TO_DEV_NULL; +break; +case GUEST_EXEC_CAPTURE_OUTPUT_MODE_SEPARATED: +has_output = true; +break; +case GUEST_EXEC_CAPTURE_OUTPUT_MODE__MAX: +/* Silence warning; impossible branch */ +break; } ret = g_spawn_async_with_pipes(NULL, argv, envp, flags, diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index 796434ed34..d1e00a4234 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -1200,6 +1200,37 @@ { 'struct': 'GuestExec', 'data': { 'pid': 'int'} } +## +# @GuestExecCaptureOutputMode: +# +# An enumeration of guest-exec capture modes. +# +# @none: do not capture any output +# @stdout: only capture stdout +# @stderr: only capture stderr +# @separated: capture both stdout and stderr, but separated into +# GuestExecStatus out-data and err-data, respectively +# +# Since: 8.0 +## + { 'enum': 'GuestExecCaptureOutputMode', + 'data': [ 'none', 'stdout', 'stderr', 'separated' ] } + +## +# @GuestExecCaptureOutput: +# +# Controls what guest-exec output gets captures. +# +# @flag: captures both stdout and stderr if true. Equivalent +#to GuestExecCaptureOutputMode::all. (since 2.5) +# @mode: capture mode; preferred interface +# +# Since: 8.0 +## + { 'alternate': 'GuestExecCaptureOutput', + 'data': { 'flag': 'bool', + 'mode': 'GuestExecCaptureOutputMode'} } + ## # @guest-exec: # @@ -1218,7 +1249,7 @@ ## { 'command': 'guest-exec', 'data':{ 'path': 'str', '*arg': ['str'], '*env': ['str'], - '*input-data': 'str', '*capture-output': 'bool' }, + '*input-data': 'str', '*capture-output': 'GuestExecCaptureOutput' }, 'returns': 'GuestExec' } -- 2.39.1
[PATCH v5 3/3] qga: test: Add tests for `merged` flag
This commit adds a test to ensure `merged` functions as expected. We also add a negative test to ensure we haven't regressed previous functionality. Signed-off-by: Daniel Xu --- tests/unit/test-qga.c | 158 +- 1 file changed, 141 insertions(+), 17 deletions(-) diff --git a/tests/unit/test-qga.c b/tests/unit/test-qga.c index b4e0a14573..360b4cab23 100644 --- a/tests/unit/test-qga.c +++ b/tests/unit/test-qga.c @@ -755,6 +755,31 @@ static void test_qga_fsfreeze_status(gconstpointer fix) g_assert_cmpstr(status, ==, "thawed"); } +static QDict *wait_for_guest_exec_completion(int fd, int64_t pid) +{ +QDict *ret = NULL; +int64_t now; +bool exited; +QDict *val; + +now = g_get_monotonic_time(); +do { +ret = qmp_fd(fd, + "{'execute': 'guest-exec-status'," + " 'arguments': { 'pid': %" PRId64 " } }", pid); +g_assert_nonnull(ret); +val = qdict_get_qdict(ret, "return"); +exited = qdict_get_bool(val, "exited"); +if (!exited) { +qobject_unref(ret); +} +} while (!exited && + g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND); +g_assert(exited); + +return ret; +} + static void test_qga_guest_exec(gconstpointer fix) { const TestFixture *fixture = fix; @@ -762,9 +787,8 @@ static void test_qga_guest_exec(gconstpointer fix) QDict *val; const gchar *out; g_autofree guchar *decoded = NULL; -int64_t pid, now, exitcode; +int64_t pid, exitcode; gsize len; -bool exited; /* exec 'echo foo bar' */ ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {" @@ -777,23 +801,10 @@ static void test_qga_guest_exec(gconstpointer fix) g_assert_cmpint(pid, >, 0); qobject_unref(ret); -/* wait for completion */ -now = g_get_monotonic_time(); -do { -ret = qmp_fd(fixture->fd, - "{'execute': 'guest-exec-status'," - " 'arguments': { 'pid': %" PRId64 " } }", pid); -g_assert_nonnull(ret); -val = qdict_get_qdict(ret, "return"); -exited = qdict_get_bool(val, "exited"); -if (!exited) { -qobject_unref(ret); -} -} while (!exited && - g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND); -g_assert(exited); +ret = wait_for_guest_exec_completion(fixture->fd, pid); /* check stdout */ +val = qdict_get_qdict(ret, "return"); exitcode = qdict_get_int(val, "exitcode"); g_assert_cmpint(exitcode, ==, 0); out = qdict_get_str(val, "out-data"); @@ -802,6 +813,115 @@ static void test_qga_guest_exec(gconstpointer fix) g_assert_cmpstr((char *)decoded, ==, "\" test_str \""); } +#if defined(G_OS_WIN32) +static void test_qga_guest_exec_separated(gconstpointer fix) +{ +} +static void test_qga_guest_exec_merged(gconstpointer fix) +{ +const TestFixture *fixture = fix; +g_autoptr(QDict) ret = NULL; +QDict *val; +const gchar *class, *desc; +g_autofree guchar *decoded = NULL; + +/* exec 'echo foo bar' */ +ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {" + " 'path': 'echo'," + " 'arg': [ 'execution never reaches here' ]," + " 'capture-output': 'merged' } }"); + +g_assert_nonnull(ret); +val = qdict_get_qdict(ret, "error"); +g_assert_nonnull(val); +class = qdict_get_str(val, "class"); +desc = qdict_get_str(val, "desc"); +g_assert_cmpstr(class, ==, "GenericError"); +g_assert_cmpint(strlen(desc), >, 0); +} +#else +static void test_qga_guest_exec_separated(gconstpointer fix) +{ +const TestFixture *fixture = fix; +g_autoptr(QDict) ret = NULL; +QDict *val; +const gchar *out, *err; +g_autofree guchar *out_decoded = NULL; +g_autofree guchar *err_decoded = NULL; +int64_t pid, exitcode; +gsize len; + +/* exec 'echo foo bar' */ +ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {" + " 'path': '/bin/bash'," + " 'arg': [ '-c', 'for i in $(seq 4); do if (( $i %% 2 )); then echo stdout; else echo stderr 1>&2; fi; done;' ]," + " 'capture-output': 'separated' } }"); +g_assert_nonnull(ret); +qmp_assert_no_error(ret); +val = qdict_get_qdict(ret, "return"); +pid = qdict_get_int(val, "pid"); +g_assert_cmpint(pid, >, 0); +qobject_unref(ret); + +ret = wait_for_guest_exec_completion(fixture->fd, pid); + +val = qdict_get_qdict(ret, "return"); +exitcode = qdict_get_int(val, "exitcode"); +g_assert_cmpint(exitcode, ==, 0); + +/* check stdout */ +out = qdict_get_str(val, "out-data"); +out_decoded = g_base64_decode(out, ); +g_assert_cmpint(len, ==, 14); +g_assert_cmpstr((char *)out_decoded, ==, "stdout\nstdout\n"); + +/* check stderr */ +err = qdict_get_try_str(val, "err-data"); +
Re: [PULL 3/3] edk2: update firmware binaries
Hi Gerd, Where did these binaries come from? What commit and how were they built? Regards, Simon
Re: [PATCH v6 2/4] qapi: add DEVICE_ON and query-hotplug infrastructure
On 07.03.23 20:31, Michael S. Tsirkin wrote: On Tue, Mar 07, 2023 at 07:05:35PM +0300, Vladimir Sementsov-Ogievskiy wrote: We have DEVICE_DELETED event, that signals that device_del command is actually completed. But we don't have a counter-part for device_add. Still it's sensible for SHPC and PCIe-native hotplug, as there are time when the device in some intermediate state. Let's add an event that say that the device is finally powered on, power indicator is on and everything is OK for next manipulation on that device. Motivations: 1. To be sure that device is "accepted" by guest. Guest may ignore hotplugged device for some reason (for example during OS booting). Management wants to catch this and handle the problem, instead of silent assume that everything is OK. So, if we don't get the event by some timeout, we can report an error, try to unplug/plug the disk again or do some other things to handle the problem. 2. The device can't be removed (by blockdev-del) while power indicator of hotplug controller is blinking (QEMU reports "guest is busy (power indicator blinking)"). So, management should avoid removing the device until it gets the DEVICE_ON event. (Probably, better solution for this point is to automatically postpone deletion until power indicator stops blinking) 3. Also, management tool may make a GUI visualization of power indicator with help of this event. As a counter-part add query-hotplug command, that shows "device-on" state as well as some addtional information. I wanted to say s/as/and/ :) Signed-off-by: Vladimir Sementsov-Ogievskiy From commit log it sounds you are just adding one new event. In fact there's more new stuff in qdev.json Pls document in commit log too. But yes "some additional information" is not enough. Maybe, something like: """ New query-hotplug command in additon to "device-on" state also provides SHPC/PCIe-native specific hotplug controller properties (like leds) that may help to determine real state of hotplug controller. That may help to get additional information for further debugging when DEVICE_ON / DEVICE_DELETED not come in time as expected. """ -- Best regards, Vladimir
Re: [PULL 0/1] qemu-openbios queue 20230307
On Tue, 7 Mar 2023 at 23:55, Mark Cave-Ayland wrote: > > The following changes since commit 9832009d9dd2386664c15cc70f6e6bfe062be8bd: > > Merge tag 'pull-riscv-to-apply-20230306' of > https://gitlab.com/palmer-dabbelt/qemu into staging (2023-03-07 12:53:00 > +) > > are available in the Git repository at: > > https://github.com/mcayland/qemu.git tags/qemu-openbios-20230307 > > for you to fetch changes up to fff1aaf4451231ac680aa278e9fafc4f8b69ff57: > > roms/openbios: update OpenBIOS images to af97fd7a built from submodule > (2023-03-07 22:30:06 +) > > > qemu-openbios queue > > > Mark Cave-Ayland (1): > roms/openbios: update OpenBIOS images to af97fd7a built from submodule > Applied, thanks. Please update the changelog at https://wiki.qemu.org/ChangeLog/8.0 for any user-visible changes. -- PMM
Re: [PULL 00/30] gdbstub refactor for smaller build
On Tue, 7 Mar 2023 at 21:21, Alex Bennée wrote: > > The following changes since commit 9832009d9dd2386664c15cc70f6e6bfe062be8bd: > > Merge tag 'pull-riscv-to-apply-20230306' of > https://gitlab.com/palmer-dabbelt/qemu into staging (2023-03-07 12:53:00 > +) > > are available in the Git repository at: > > https://gitlab.com/stsquad/qemu.git tags/pull-gdbstub-070323-3 > > for you to fetch changes up to 412ae12647d1086c713e13841fd25d10d5418c7f: > > gdbstub: move update guest debug to accel ops (2023-03-07 20:44:09 +) > > > gdbstub refactor: > > - split user and softmmu code > - use cleaner headers for tb_flush, target_ulong > - probe for gdb multiarch support at configure > - make syscall handling target independent > - add update guest debug of accel ops Applied, thanks. Please update the changelog at https://wiki.qemu.org/ChangeLog/8.0 for any user-visible changes. -- PMM
Re: [PATCH for-8.1 00/17] centralize CPU extensions logic
Just realized that the subject doesn't mention 'riscv' anywhere. Yes, this is target/riscv specific. I'll make sure to mention that in the future versions. Thanks, Daniel On 3/8/23 17:19, Daniel Henrique Barboza wrote: Hi, During the review of a series that did some work in the RISCV_FEATURES* enum, Liu Zhiwei commented on how we could centralize the all the extension validation code and integrate it with write_misa() [1]. This does at least part of what was suggested. The idea is that, ATM, we have too many places setting cpu->cfg and the validation logic is scattered around (e.g. there are some contraints in write_misa() that should be applicable elsewhere). This series is an attempt to centralize things a bit. The main accomplishments of this series are: - the parent device riscv-cpu no longer sets any cpu->cfg attribute. This was forcing init() functions to disable extensions that it wouldn't use just because the parent device was enabling it; - all validations are centered in validate_set_extensions(), with pontual exceptions in write_misa() that has exclusive contraints; - set_misa() now writes cpu->cfg. No need to have one function to set env->misa_ext and then another to set cpu->cfg; - register_cpu_props() now only exposes user-facing props; - all validations from validate_set_extensions() are done at the start of the function. Validate first, set extensions after; - RVE is now forbidden in all validations, not just in write_misa(); - RVG is now forbidden in write_misa(); - write_misa now uses set_misa() and validate_set_extensions(). [1] https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg05092.html Daniel Henrique Barboza (17): target/riscv/cpu.c: add riscv_cpu_validate_v() target/riscv/cpu.c: remove set_vext_version() target/riscv/cpu.c: remove set_priv_version() target/riscv: add PRIV_VERSION_LATEST macro target/riscv/cpu.c: add riscv_cpu_validate_priv_spec() target/riscv: move realize() validations to riscv_cpu_validate_set_extensions() target/riscv/cpu.c: remove cfg setup from riscv_cpu_init() target/riscv/cpu.c: avoid set_misa() in validate_set_extensions() target/riscv/cpu.c: set cpu config in set_misa() target/riscv/cpu.c: redesign register_cpu_props() target/riscv/cpu.c: move riscv_cpu_validate_v() up target/riscv: put env->misa_ext <-> cpu->cfg code into helpers target/riscv/cpu.c: split riscv_cpu_validate_priv_spec() target/riscv/cpu.c: do not allow RVE to be set target/riscv: add RVG target/riscv: do not allow RVG in write_misa() target/riscv: rework write_misa() target/riscv/cpu.c | 516 + target/riscv/cpu.h | 9 +- target/riscv/csr.c | 52 ++--- 3 files changed, 323 insertions(+), 254 deletions(-)
Re: [PATCH v8 03/11] target/arm: Move aa32_max_features out of cpu_tcg.c
On 3/9/23 12:14, Fabiano Rosas wrote: In preparation to moving the cpu_tcg.c code into a 32-bit, tcg-only file, move the aa32_max_features function which is shared between 32/64/tcg/non-tcg into cpu.c. Signed-off-by: Fabiano Rosas --- target/arm/cpu.c | 69 target/arm/cpu_tcg.c | 69 2 files changed, 69 insertions(+), 69 deletions(-) I'm not keen on this, as it's completely tcg. Perhaps it would be better to let -cpu max devolve to aarch64_a57_initfn when tcg is not available (i.e. qtest_enabled())? Move all of the tcg stuff out of aarch64_max_initfn into tcg/cpu64.c. Thoughts? r~
Re: [PATCH 4/4] target/riscv: Simplify arguments for riscv_csrrw_check
On 3/9/23 04:13, Weiwei Li wrote: Remove RISCVCPU argument, and get cfg infomation from CPURISCVState directly. Signed-off-by: Weiwei Li Signed-off-by: Junqiang Wang --- Reviewed-by: Daniel Henrique Barboza target/riscv/csr.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 53143f4d9a..80fc15e4d6 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -3755,15 +3755,14 @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno, static inline RISCVException riscv_csrrw_check(CPURISCVState *env, int csrno, - bool write_mask, - RISCVCPU *cpu) + bool write_mask) { /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */ bool read_only = get_field(csrno, 0xC00) == 3; int csr_min_priv = csr_ops[csrno].min_priv_ver; /* ensure the CSR extension is enabled */ -if (!cpu->cfg.ext_icsr) { +if (!riscv_cpu_cfg(env)->ext_icsr) { return RISCV_EXCP_ILLEGAL_INST; } @@ -3859,9 +3858,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask) { -RISCVCPU *cpu = env_archcpu(env); - -RISCVException ret = riscv_csrrw_check(env, csrno, write_mask, cpu); +RISCVException ret = riscv_csrrw_check(env, csrno, write_mask); if (ret != RISCV_EXCP_NONE) { return ret; } @@ -3914,9 +3911,8 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno, Int128 new_value, Int128 write_mask) { RISCVException ret; -RISCVCPU *cpu = env_archcpu(env); -ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask), cpu); +ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask)); if (ret != RISCV_EXCP_NONE) { return ret; }
Re: [PATCH 3/4] target/riscv: Simplify type conversion for CPURISCVState
On 3/9/23 04:13, Weiwei Li wrote: Use CPURISCVState as argument directly in riscv_cpu_update_mip and riscv_timer_write_timecmp, since type converts from CPURISCVState to RISCVCPU in many caller of them and then back to CPURISCVState in them. Signed-off-by: Weiwei Li Signed-off-by: Junqiang Wang --- Reviewed-by: Daniel Henrique Barboza target/riscv/cpu.c | 6 +++--- target/riscv/cpu.h | 3 ++- target/riscv/cpu_helper.c | 8 target/riscv/csr.c | 35 +++ target/riscv/pmu.c | 6 +++--- target/riscv/time_helper.c | 15 +++ target/riscv/time_helper.h | 2 +- 7 files changed, 31 insertions(+), 44 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1e97473af2..16e465a0ab 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1302,7 +1302,7 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level) if (kvm_enabled()) { kvm_riscv_set_irq(cpu, irq, level); } else { -riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level)); +riscv_cpu_update_mip(env, 1 << irq, BOOL_TO_MASK(level)); } break; case IRQ_S_EXT: @@ -1310,7 +1310,7 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level) kvm_riscv_set_irq(cpu, irq, level); } else { env->external_seip = level; -riscv_cpu_update_mip(cpu, 1 << irq, +riscv_cpu_update_mip(env, 1 << irq, BOOL_TO_MASK(level | env->software_seip)); } break; @@ -1336,7 +1336,7 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level) } /* Update mip.SGEIP bit */ -riscv_cpu_update_mip(cpu, MIP_SGEIP, +riscv_cpu_update_mip(env, MIP_SGEIP, BOOL_TO_MASK(!!(env->hgeie & env->hgeip))); } else { g_assert_not_reached(); diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 638e47c75a..5adefe4ab5 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -602,7 +602,8 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request); void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env); int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts); -uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value); +uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask, + uint64_t value); #define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */ void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *), void *arg); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index e677255f87..824f0cbd92 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -590,7 +590,7 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable) * * To solve this, we check and inject interrupt after setting V=1. */ -riscv_cpu_update_mip(env_archcpu(env), 0, 0); +riscv_cpu_update_mip(env, 0, 0); } } @@ -610,10 +610,10 @@ int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts) } } -uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value) +uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask, + uint64_t value) { -CPURISCVState *env = >env; -CPUState *cs = CPU(cpu); +CPUState *cs = env_cpu(env); uint64_t gein, vsgein = 0, vstip = 0, old = env->mip; if (riscv_cpu_virt_enabled(env)) { diff --git a/target/riscv/csr.c b/target/riscv/csr.c index b453d8e8ca..53143f4d9a 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -990,15 +990,13 @@ static RISCVException read_vstimecmph(CPURISCVState *env, int csrno, static RISCVException write_vstimecmp(CPURISCVState *env, int csrno, target_ulong val) { -RISCVCPU *cpu = env_archcpu(env); - if (riscv_cpu_mxl(env) == MXL_RV32) { env->vstimecmp = deposit64(env->vstimecmp, 0, 32, (uint64_t)val); } else { env->vstimecmp = val; } -riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp, +riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp, env->htimedelta, MIP_VSTIP); return RISCV_EXCP_NONE; @@ -1007,10 +1005,8 @@ static RISCVException write_vstimecmp(CPURISCVState *env, int csrno, static RISCVException write_vstimecmph(CPURISCVState *env, int csrno, target_ulong val) { -RISCVCPU *cpu = env_archcpu(env); - env->vstimecmp = deposit64(env->vstimecmp, 32, 32,
Re: [PATCH 2/4] target/riscv: Simplify getting RISCVCPU pointer from env
On 3/9/23 04:13, Weiwei Li wrote: Use env_archcpu() to get RISCVCPU pointer from env directly. Signed-off-by: Weiwei Li Signed-off-by: Junqiang Wang --- Reviewed-by: Daniel Henrique Barboza target/riscv/pmu.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c index b8e56d2b7b..a200741083 100644 --- a/target/riscv/pmu.c +++ b/target/riscv/pmu.c @@ -223,7 +223,7 @@ bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env, return true; } -cpu = RISCV_CPU(env_cpu(env)); +cpu = env_archcpu(env); if (!cpu->pmu_event_ctr_map) { return false; } @@ -249,7 +249,7 @@ bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env, uint32_t target_ctr) return true; } -cpu = RISCV_CPU(env_cpu(env)); +cpu = env_archcpu(env); if (!cpu->pmu_event_ctr_map) { return false; } @@ -289,7 +289,7 @@ int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value, uint32_t ctr_idx) { uint32_t event_idx; -RISCVCPU *cpu = RISCV_CPU(env_cpu(env)); +RISCVCPU *cpu = env_archcpu(env); if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->pmu_event_ctr_map) { return -1; @@ -390,7 +390,7 @@ int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value, uint32_t ctr_idx) { uint64_t overflow_delta, overflow_at; int64_t overflow_ns, overflow_left = 0; -RISCVCPU *cpu = RISCV_CPU(env_cpu(env)); +RISCVCPU *cpu = env_archcpu(env); PMUCTRState *counter = >pmu_ctrs[ctr_idx]; if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->cfg.ext_sscofpmf) {
Re: [PATCH 1/4] target/riscv: Avoid env_archcpu() when reading RISCVCPUConfig
On 3/9/23 04:13, Weiwei Li wrote: Use riscv_cpu_cfg(env) instead of env_archcpu().cfg. Signed-off-by: Weiwei Li Signed-off-by: Junqiang Wang --- Reviewed-by: Daniel Henrique Barboza target/riscv/cpu_helper.c | 9 - target/riscv/csr.c| 40 --- target/riscv/gdbstub.c| 4 ++-- 3 files changed, 18 insertions(+), 35 deletions(-) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index f88c503cf4..e677255f87 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -314,7 +314,6 @@ static int riscv_cpu_pending_to_irq(CPURISCVState *env, int extirq, unsigned int extirq_def_prio, uint64_t pending, uint8_t *iprio) { -RISCVCPU *cpu = env_archcpu(env); int irq, best_irq = RISCV_EXCP_NONE; unsigned int prio, best_prio = UINT_MAX; @@ -323,7 +322,8 @@ static int riscv_cpu_pending_to_irq(CPURISCVState *env, } irq = ctz64(pending); -if (!((extirq == IRQ_M_EXT) ? cpu->cfg.ext_smaia : cpu->cfg.ext_ssaia)) { +if (!((extirq == IRQ_M_EXT) ? riscv_cpu_cfg(env)->ext_smaia : + riscv_cpu_cfg(env)->ext_ssaia)) { return irq; } @@ -765,7 +765,6 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical, int mode = mmu_idx & TB_FLAGS_PRIV_MMU_MASK; bool use_background = false; hwaddr ppn; -RISCVCPU *cpu = env_archcpu(env); int napot_bits = 0; target_ulong napot_mask; @@ -946,7 +945,7 @@ restart: if (riscv_cpu_sxl(env) == MXL_RV32) { ppn = pte >> PTE_PPN_SHIFT; -} else if (pbmte || cpu->cfg.ext_svnapot) { +} else if (pbmte || riscv_cpu_cfg(env)->ext_svnapot) { ppn = (pte & (target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT; } else { ppn = pte >> PTE_PPN_SHIFT; @@ -1043,7 +1042,7 @@ restart: benefit. */ target_ulong vpn = addr >> PGSHIFT; -if (cpu->cfg.ext_svnapot && (pte & PTE_N)) { +if (riscv_cpu_cfg(env)->ext_svnapot && (pte & PTE_N)) { napot_bits = ctzl(ppn) + 1; if ((i != (levels - 1)) || (napot_bits != 4)) { return TRANSLATE_FAIL; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index ab566639e5..b453d8e8ca 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -88,9 +88,7 @@ static RISCVException fs(CPURISCVState *env, int csrno) static RISCVException vs(CPURISCVState *env, int csrno) { -RISCVCPU *cpu = env_archcpu(env); - -if (cpu->cfg.ext_zve32f) { +if (riscv_cpu_cfg(env)->ext_zve32f) { #if !defined(CONFIG_USER_ONLY) if (!env->debugger && !riscv_cpu_vector_enabled(env)) { return RISCV_EXCP_ILLEGAL_INST; @@ -193,9 +191,7 @@ static RISCVException mctr32(CPURISCVState *env, int csrno) static RISCVException sscofpmf(CPURISCVState *env, int csrno) { -RISCVCPU *cpu = env_archcpu(env); - -if (!cpu->cfg.ext_sscofpmf) { +if (!riscv_cpu_cfg(env)->ext_sscofpmf) { return RISCV_EXCP_ILLEGAL_INST; } @@ -310,9 +306,7 @@ static RISCVException umode32(CPURISCVState *env, int csrno) static RISCVException mstateen(CPURISCVState *env, int csrno) { -RISCVCPU *cpu = env_archcpu(env); - -if (!cpu->cfg.ext_smstateen) { +if (!riscv_cpu_cfg(env)->ext_smstateen) { return RISCV_EXCP_ILLEGAL_INST; } @@ -321,9 +315,7 @@ static RISCVException mstateen(CPURISCVState *env, int csrno) static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base) { -RISCVCPU *cpu = env_archcpu(env); - -if (!cpu->cfg.ext_smstateen) { +if (!riscv_cpu_cfg(env)->ext_smstateen) { return RISCV_EXCP_ILLEGAL_INST; } @@ -390,10 +382,9 @@ static RISCVException sstateen(CPURISCVState *env, int csrno) static RISCVException sstc(CPURISCVState *env, int csrno) { -RISCVCPU *cpu = env_archcpu(env); bool hmode_check = false; -if (!cpu->cfg.ext_sstc || !env->rdtime_fn) { +if (!riscv_cpu_cfg(env)->ext_sstc || !env->rdtime_fn) { return RISCV_EXCP_ILLEGAL_INST; } @@ -1170,27 +1161,21 @@ static RISCVException write_ignore(CPURISCVState *env, int csrno, static RISCVException read_mvendorid(CPURISCVState *env, int csrno, target_ulong *val) { -RISCVCPU *cpu = env_archcpu(env); - -*val = cpu->cfg.mvendorid; +*val = riscv_cpu_cfg(env)->mvendorid; return RISCV_EXCP_NONE; } static RISCVException read_marchid(CPURISCVState *env, int csrno, target_ulong *val) { -RISCVCPU *cpu = env_archcpu(env); - -*val = cpu->cfg.marchid; +*val = riscv_cpu_cfg(env)->marchid; return RISCV_EXCP_NONE; } static RISCVException
Re: [PATCH v8 11/11] target/arm: gdbstub: Guard pauth code with CONFIG_TCG
On 3/9/23 12:14, Fabiano Rosas wrote: We currently don't have the reading of pauth regs implemented for KVM so wrap the pauth registration with CONFIG_TCG. This avoids the build error when using --disable-tcg: libqemu-aarch64-softmmu.fa.p/target_arm_gdbstub64.c.o: in function `aarch64_gdb_get_pauth_reg': ../target/arm/gdbstub64.c:233: undefined reference to `pauth_ptr_mask' Signed-off-by: Fabiano Rosas --- Does this make sense? I seem to remember we had a rule that for KVM register values should come from the ONE_REG interface. --- target/arm/gdbstub.c | 2 ++ target/arm/gdbstub64.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c index 2ecc362ac2..fc937580dd 100644 --- a/target/arm/gdbstub.c +++ b/target/arm/gdbstub.c @@ -521,11 +521,13 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) aarch64_gdb_set_fpu_reg, 34, "aarch64-fpu.xml", 0); } +#ifdef CONFIG_TCG if (isar_feature_aa64_pauth(>isar)) { gdb_register_coprocessor(cs, aarch64_gdb_get_pauth_reg, aarch64_gdb_set_pauth_reg, 4, "aarch64-pauth.xml", 0); I think this should be tcg_enabled(), which should avoid the need for ifdef. r~ } +#endif /* CONFIG_TCG */ #endif } else { if (arm_feature(env, ARM_FEATURE_NEON)) { diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c index 3bee892fb7..67c7cbb63c 100644 --- a/target/arm/gdbstub64.c +++ b/target/arm/gdbstub64.c @@ -210,6 +210,7 @@ int aarch64_gdb_set_sve_reg(CPUARMState *env, uint8_t *buf, int reg) return 0; } +#ifdef CONFIG_TCG int aarch64_gdb_get_pauth_reg(CPUARMState *env, GByteArray *buf, int reg) { switch (reg) { @@ -243,6 +244,7 @@ int aarch64_gdb_set_pauth_reg(CPUARMState *env, uint8_t *buf, int reg) /* All pseudo registers are read-only. */ return 0; } +#endif static void output_vector_union_type(GString *s, int reg_width, const char *name)
Re: [PATCH v8 10/11] target/arm: gdbstub: Guard M-profile code with CONFIG_TCG
On 3/9/23 12:14, Fabiano Rosas wrote: This code is only relevant when TCG is present in the build. If we try to build with --disable-tcg we currently get: libqemu-aarch64-softmmu.fa.p/target_arm_gdbstub.c.o: in function `m_sysreg_ptr': ../target/arm/gdbstub.c:356: undefined reference to `arm_v7m_get_sp_ptr' Signed-off-by: Fabiano Rosas --- target/arm/gdbstub.c | 4 1 file changed, 4 insertions(+) Reviewed-by: Richard Henderson r~
[PULL v2 89/91] target/tricore: Use min/max for saturate
Use tcg_constant_i32 for the bounds. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/tricore/translate.c | 14 +++--- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index a3a5263a5d..2646cb3eb5 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -2443,21 +2443,13 @@ gen_msubsui_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high, static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low) { -TCGv sat_neg = tcg_const_i32(low); -TCGv temp = tcg_const_i32(up); - -/* sat_neg = (arg < low ) ? low : arg; */ -tcg_gen_movcond_tl(TCG_COND_LT, sat_neg, arg, sat_neg, sat_neg, arg); - -/* ret = (sat_neg > up ) ? up : sat_neg; */ -tcg_gen_movcond_tl(TCG_COND_GT, ret, sat_neg, temp, temp, sat_neg); +tcg_gen_smax_tl(ret, arg, tcg_constant_i32(low)); +tcg_gen_smin_tl(ret, ret, tcg_constant_i32(up)); } static void gen_saturate_u(TCGv ret, TCGv arg, int32_t up) { -TCGv temp = tcg_const_i32(up); -/* sat_neg = (arg > up ) ? up : arg; */ -tcg_gen_movcond_tl(TCG_COND_GTU, ret, arg, temp, temp, arg); +tcg_gen_umin_tl(ret, arg, tcg_constant_i32(up)); } static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count) -- 2.34.1
[PATCH v8 03/11] target/arm: Move aa32_max_features out of cpu_tcg.c
In preparation to moving the cpu_tcg.c code into a 32-bit, tcg-only file, move the aa32_max_features function which is shared between 32/64/tcg/non-tcg into cpu.c. Signed-off-by: Fabiano Rosas --- target/arm/cpu.c | 69 target/arm/cpu_tcg.c | 69 2 files changed, 69 insertions(+), 69 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 5182ed0c91..eccbb8f123 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2158,6 +2158,75 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) acc->parent_realize(dev, errp); } +/* Share AArch32 -cpu max features with AArch64. */ +void aa32_max_features(ARMCPU *cpu) +{ +uint32_t t; + +/* Add additional features supported by QEMU */ +t = cpu->isar.id_isar5; +t = FIELD_DP32(t, ID_ISAR5, AES, 2); /* FEAT_PMULL */ +t = FIELD_DP32(t, ID_ISAR5, SHA1, 1); /* FEAT_SHA1 */ +t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); /* FEAT_SHA256 */ +t = FIELD_DP32(t, ID_ISAR5, CRC32, 1); +t = FIELD_DP32(t, ID_ISAR5, RDM, 1); /* FEAT_RDM */ +t = FIELD_DP32(t, ID_ISAR5, VCMA, 1); /* FEAT_FCMA */ +cpu->isar.id_isar5 = t; + +t = cpu->isar.id_isar6; +t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);/* FEAT_JSCVT */ +t = FIELD_DP32(t, ID_ISAR6, DP, 1); /* Feat_DotProd */ +t = FIELD_DP32(t, ID_ISAR6, FHM, 1); /* FEAT_FHM */ +t = FIELD_DP32(t, ID_ISAR6, SB, 1); /* FEAT_SB */ +t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1); /* FEAT_SPECRES */ +t = FIELD_DP32(t, ID_ISAR6, BF16, 1); /* FEAT_AA32BF16 */ +t = FIELD_DP32(t, ID_ISAR6, I8MM, 1); /* FEAT_AA32I8MM */ +cpu->isar.id_isar6 = t; + +t = cpu->isar.mvfr1; +t = FIELD_DP32(t, MVFR1, FPHP, 3);/* FEAT_FP16 */ +t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* FEAT_FP16 */ +cpu->isar.mvfr1 = t; + +t = cpu->isar.mvfr2; +t = FIELD_DP32(t, MVFR2, SIMDMISC, 3);/* SIMD MaxNum */ +t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */ +cpu->isar.mvfr2 = t; + +t = cpu->isar.id_mmfr3; +t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* FEAT_PAN2 */ +cpu->isar.id_mmfr3 = t; + +t = cpu->isar.id_mmfr4; +t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* FEAT_AA32HPD */ +t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */ +t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* FEAT_TTCNP */ +t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* FEAT_XNX */ +t = FIELD_DP32(t, ID_MMFR4, EVT, 2); /* FEAT_EVT */ +cpu->isar.id_mmfr4 = t; + +t = cpu->isar.id_mmfr5; +t = FIELD_DP32(t, ID_MMFR5, ETS, 1); /* FEAT_ETS */ +cpu->isar.id_mmfr5 = t; + +t = cpu->isar.id_pfr0; +t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CVS2 */ +t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */ +t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */ +cpu->isar.id_pfr0 = t; + +t = cpu->isar.id_pfr2; +t = FIELD_DP32(t, ID_PFR2, CSV3, 1); /* FEAT_CSV3 */ +t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */ +cpu->isar.id_pfr2 = t; + +t = cpu->isar.id_dfr0; +t = FIELD_DP32(t, ID_DFR0, COPDBG, 9);/* FEAT_Debugv8p4 */ +t = FIELD_DP32(t, ID_DFR0, COPSDBG, 9); /* FEAT_Debugv8p4 */ +t = FIELD_DP32(t, ID_DFR0, PERFMON, 6); /* FEAT_PMUv3p5 */ +cpu->isar.id_dfr0 = t; +} + static ObjectClass *arm_cpu_class_by_name(const char *cpu_model) { ObjectClass *oc; diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c index 6ce728134f..5a2690f56e 100644 --- a/target/arm/cpu_tcg.c +++ b/target/arm/cpu_tcg.c @@ -24,75 +24,6 @@ #endif -/* Share AArch32 -cpu max features with AArch64. */ -void aa32_max_features(ARMCPU *cpu) -{ -uint32_t t; - -/* Add additional features supported by QEMU */ -t = cpu->isar.id_isar5; -t = FIELD_DP32(t, ID_ISAR5, AES, 2); /* FEAT_PMULL */ -t = FIELD_DP32(t, ID_ISAR5, SHA1, 1); /* FEAT_SHA1 */ -t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); /* FEAT_SHA256 */ -t = FIELD_DP32(t, ID_ISAR5, CRC32, 1); -t = FIELD_DP32(t, ID_ISAR5, RDM, 1); /* FEAT_RDM */ -t = FIELD_DP32(t, ID_ISAR5, VCMA, 1); /* FEAT_FCMA */ -cpu->isar.id_isar5 = t; - -t = cpu->isar.id_isar6; -t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);/* FEAT_JSCVT */ -t = FIELD_DP32(t, ID_ISAR6, DP, 1); /* Feat_DotProd */ -t = FIELD_DP32(t, ID_ISAR6, FHM, 1); /* FEAT_FHM */ -t = FIELD_DP32(t, ID_ISAR6, SB, 1); /* FEAT_SB */ -t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1); /* FEAT_SPECRES */ -t = FIELD_DP32(t, ID_ISAR6, BF16, 1); /* FEAT_AA32BF16 */ -t = FIELD_DP32(t, ID_ISAR6, I8MM, 1); /* FEAT_AA32I8MM */ -cpu->isar.id_isar6 = t; - -t =
[PATCH v2 1/2] target/m68k: Reject immediate as destination in gen_ea_mode
In theory this should never happen, as all such instructions are illegal. This is checked in e.g. gen_lea_mode and gen_ea_mode_fp but not here. In case something higher up isn't checking modes properly, return NULL_QREG. This will result in an illegal instruction exception being raised. Signed-off-by: Richard Henderson --- target/m68k/translate.c | 4 1 file changed, 4 insertions(+) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 422f4652f1..e16c608ef8 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -894,6 +894,10 @@ static TCGv gen_ea_mode(CPUM68KState *env, DisasContext *s, int mode, int reg0, case 3: /* pc index+displacement. */ goto do_indirect; case 4: /* Immediate. */ +/* Should never be used for an output or RMW input. */ +if (what == EA_STORE || addrp) { +return NULL_QREG; +} /* Sign extend values for consistency. */ switch (opsize) { case OS_BYTE: -- 2.34.1
[PULL v2 87/91] target/ppc: Fix gen_tlbsx_booke206
Fix incorrect read from rD. Avoid adding 0 when rA == 0. Reviewed-by: Daniel Henrique Barboza Signed-off-by: Richard Henderson --- target/ppc/translate.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index df324fc7ff..7ec940b7d8 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -5875,12 +5875,10 @@ static void gen_tlbsx_booke206(DisasContext *ctx) CHK_SV(ctx); if (rA(ctx->opcode)) { t0 = tcg_temp_new(); -tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]); +tcg_gen_add_tl(t0, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); } else { -t0 = tcg_const_tl(0); +t0 = cpu_gpr[rB(ctx->opcode)]; } - -tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]); gen_helper_booke206_tlbsx(cpu_env, t0); #endif /* defined(CONFIG_USER_ONLY) */ } -- 2.34.1
[PULL v2 51/91] target/mips: Avoid tcg_const_* throughout
All remaining uses are strictly read-only. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/mips/tcg/mxu_translate.c | 4 +- target/mips/tcg/translate.c | 56 +++ target/mips/tcg/tx79_translate.c | 4 +- target/mips/tcg/micromips_translate.c.inc | 4 +- target/mips/tcg/nanomips_translate.c.inc | 16 --- 5 files changed, 43 insertions(+), 41 deletions(-) diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c index 8703b0cef4..bdd20709c0 100644 --- a/target/mips/tcg/mxu_translate.c +++ b/target/mips/tcg/mxu_translate.c @@ -1072,7 +1072,7 @@ static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx) uint32_t XRx = XRb ? XRb : XRc; /* ...and do half-word-wise max/min with one operand 0 */ TCGv_i32 t0 = tcg_temp_new(); -TCGv_i32 t1 = tcg_const_i32(0); +TCGv_i32 t1 = tcg_constant_i32(0); /* the left half-word first */ tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x); @@ -1163,7 +1163,7 @@ static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx) uint32_t XRx = XRb ? XRb : XRc; /* ...and do byte-wise max/min with one operand 0 */ TCGv_i32 t0 = tcg_temp_new(); -TCGv_i32 t1 = tcg_const_i32(0); +TCGv_i32 t1 = tcg_constant_i32(0); int32_t i; /* the leftmost byte (byte 3) first */ diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index bbc2212660..1fb4ef7127 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -2099,14 +2099,14 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, gen_store_gpr(t1, rt); break; case OPC_LDPC: -t1 = tcg_const_tl(pc_relative_pc(ctx)); +t1 = tcg_constant_tl(pc_relative_pc(ctx)); gen_op_addr_add(ctx, t0, t0, t1); tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); gen_store_gpr(t0, rt); break; #endif case OPC_LWPC: -t1 = tcg_const_tl(pc_relative_pc(ctx)); +t1 = tcg_constant_tl(pc_relative_pc(ctx)); gen_op_addr_add(ctx, t0, t0, t1); tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL); gen_store_gpr(t0, rt); @@ -2733,7 +2733,7 @@ static void gen_cond_move(DisasContext *ctx, uint32_t opc, t0 = tcg_temp_new(); gen_load_gpr(t0, rt); -t1 = tcg_const_tl(0); +t1 = tcg_constant_tl(0); t2 = tcg_temp_new(); gen_load_gpr(t2, rs); switch (opc) { @@ -3084,8 +3084,8 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) break; case R6_OPC_DIVU: { -TCGv t2 = tcg_const_tl(0); -TCGv t3 = tcg_const_tl(1); +TCGv t2 = tcg_constant_tl(0); +TCGv t3 = tcg_constant_tl(1); tcg_gen_ext32u_tl(t0, t0); tcg_gen_ext32u_tl(t1, t1); tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); @@ -3095,8 +3095,8 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) break; case R6_OPC_MODU: { -TCGv t2 = tcg_const_tl(0); -TCGv t3 = tcg_const_tl(1); +TCGv t2 = tcg_constant_tl(0); +TCGv t3 = tcg_constant_tl(1); tcg_gen_ext32u_tl(t0, t0); tcg_gen_ext32u_tl(t1, t1); tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); @@ -3175,16 +3175,16 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) break; case R6_OPC_DDIVU: { -TCGv t2 = tcg_const_tl(0); -TCGv t3 = tcg_const_tl(1); +TCGv t2 = tcg_constant_tl(0); +TCGv t3 = tcg_constant_tl(1); tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); } break; case R6_OPC_DMODU: { -TCGv t2 = tcg_const_tl(0); -TCGv t3 = tcg_const_tl(1); +TCGv t2 = tcg_constant_tl(0); +TCGv t3 = tcg_constant_tl(1); tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); } @@ -3248,8 +3248,8 @@ static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) break; case MMI_OPC_DIVU1: { -TCGv t2 = tcg_const_tl(0); -TCGv t3 = tcg_const_tl(1); +TCGv t2 = tcg_constant_tl(0); +TCGv t3 = tcg_constant_tl(1); tcg_gen_ext32u_tl(t0, t0); tcg_gen_ext32u_tl(t1, t1); tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); @@ -3304,8 +3304,8 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, break; case OPC_DIVU: { -TCGv t2 = tcg_const_tl(0); -TCGv t3 = tcg_const_tl(1); +TCGv t2 = tcg_constant_tl(0); +TCGv t3 = tcg_constant_tl(1);
[PATCH v8 02/11] target/arm: Move 64-bit TCG CPUs into tcg/
Move the 64-bit CPUs that are TCG-only: - cortex-a35 - cortex-a55 - cortex-a72 - cortex-a76 - a64fx - neoverse-n1 Keep the CPUs that can be used with KVM: - cortex-a57 - cortex-a53 - max - host For the special case "max" CPU, there's a nuance that while KVM/HVF use the "host" model instead, we still cannot move all of the TCG code into the tcg directory because the qtests might reach the !kvm && !hvf branch. Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson --- hw/arm/virt.c | 6 +- target/arm/cpu64.c | 398 + target/arm/internals.h | 1 + target/arm/tcg/cpu64.c | 438 + target/arm/tcg/meson.build | 1 + 5 files changed, 445 insertions(+), 399 deletions(-) create mode 100644 target/arm/tcg/cpu64.c diff --git a/hw/arm/virt.c b/hw/arm/virt.c index ac626b3bef..999c1ada79 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -206,14 +206,16 @@ static const int a15irqmap[] = { static const char *valid_cpus[] = { ARM_CPU_TYPE_NAME("cortex-a7"), ARM_CPU_TYPE_NAME("cortex-a15"), +#ifdef CONFIG_TCG ARM_CPU_TYPE_NAME("cortex-a35"), -ARM_CPU_TYPE_NAME("cortex-a53"), ARM_CPU_TYPE_NAME("cortex-a55"), -ARM_CPU_TYPE_NAME("cortex-a57"), ARM_CPU_TYPE_NAME("cortex-a72"), ARM_CPU_TYPE_NAME("cortex-a76"), ARM_CPU_TYPE_NAME("a64fx"), ARM_CPU_TYPE_NAME("neoverse-n1"), +#endif +ARM_CPU_TYPE_NAME("cortex-a53"), +ARM_CPU_TYPE_NAME("cortex-a57"), ARM_CPU_TYPE_NAME("host"), ARM_CPU_TYPE_NAME("max"), }; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 9f193927d8..0b55598f9d 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -31,86 +31,6 @@ #include "internals.h" #include "cpregs.h" -static void aarch64_a35_initfn(Object *obj) -{ -ARMCPU *cpu = ARM_CPU(obj); - -cpu->dtb_compatible = "arm,cortex-a35"; -set_feature(>env, ARM_FEATURE_V8); -set_feature(>env, ARM_FEATURE_NEON); -set_feature(>env, ARM_FEATURE_GENERIC_TIMER); -set_feature(>env, ARM_FEATURE_AARCH64); -set_feature(>env, ARM_FEATURE_CBAR_RO); -set_feature(>env, ARM_FEATURE_EL2); -set_feature(>env, ARM_FEATURE_EL3); -set_feature(>env, ARM_FEATURE_PMU); - -/* From B2.2 AArch64 identification registers. */ -cpu->midr = 0x411fd040; -cpu->revidr = 0; -cpu->ctr = 0x84448004; -cpu->isar.id_pfr0 = 0x0131; -cpu->isar.id_pfr1 = 0x00011011; -cpu->isar.id_dfr0 = 0x03010066; -cpu->id_afr0 = 0; -cpu->isar.id_mmfr0 = 0x10201105; -cpu->isar.id_mmfr1 = 0x4000; -cpu->isar.id_mmfr2 = 0x0126; -cpu->isar.id_mmfr3 = 0x02102211; -cpu->isar.id_isar0 = 0x02101110; -cpu->isar.id_isar1 = 0x13112111; -cpu->isar.id_isar2 = 0x21232042; -cpu->isar.id_isar3 = 0x01112131; -cpu->isar.id_isar4 = 0x00011142; -cpu->isar.id_isar5 = 0x00011121; -cpu->isar.id_aa64pfr0 = 0x; -cpu->isar.id_aa64pfr1 = 0; -cpu->isar.id_aa64dfr0 = 0x10305106; -cpu->isar.id_aa64dfr1 = 0; -cpu->isar.id_aa64isar0 = 0x00011120; -cpu->isar.id_aa64isar1 = 0; -cpu->isar.id_aa64mmfr0 = 0x00101122; -cpu->isar.id_aa64mmfr1 = 0; -cpu->clidr = 0x0a200023; -cpu->dcz_blocksize = 4; - -/* From B2.4 AArch64 Virtual Memory control registers */ -cpu->reset_sctlr = 0x00c50838; - -/* From B2.10 AArch64 performance monitor registers */ -cpu->isar.reset_pmcr_el0 = 0x410a3000; - -/* From B2.29 Cache ID registers */ -cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */ -cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */ -cpu->ccsidr[2] = 0x703fe03a; /* 512KB L2 cache */ - -/* From B3.5 VGIC Type register */ -cpu->gic_num_lrs = 4; -cpu->gic_vpribits = 5; -cpu->gic_vprebits = 5; -cpu->gic_pribits = 5; - -/* From C6.4 Debug ID Register */ -cpu->isar.dbgdidr = 0x3516d000; -/* From C6.5 Debug Device ID Register */ -cpu->isar.dbgdevid = 0x00110f13; -/* From C6.6 Debug Device ID Register 1 */ -cpu->isar.dbgdevid1 = 0x2; - -/* From Cortex-A35 SIMD and Floating-point Support r1p0 */ -/* From 3.2 AArch32 register summary */ -cpu->reset_fpsid = 0x41034043; - -/* From 2.2 AArch64 register summary */ -cpu->isar.mvfr0 = 0x10110222; -cpu->isar.mvfr1 = 0x1211; -cpu->isar.mvfr2 = 0x0043; - -/* These values are the same with A53/A57/A72. */ -define_cortex_a72_a57_a53_cp_reginfo(cpu); -} - void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { /* @@ -541,7 +461,7 @@ static void cpu_arm_get_default_vec_len(Object *obj, Visitor *v, } #endif -static void aarch64_add_sve_properties(Object *obj) +void aarch64_add_sve_properties(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); uint32_t vq; @@ -787,316 +707,6 @@ static void aarch64_a53_initfn(Object *obj) define_cortex_a72_a57_a53_cp_reginfo(cpu); } -static void aarch64_a55_initfn(Object *obj) -{ -ARMCPU *cpu =
[PULL v2 84/91] target/ppc: Avoid tcg_const_* in fp-impl.c.inc
All uses are strictly read-only. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Daniel Henrique Barboza Signed-off-by: Richard Henderson --- target/ppc/translate/fp-impl.c.inc | 26 -- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc index d5d88e7d49..57d8437851 100644 --- a/target/ppc/translate/fp-impl.c.inc +++ b/target/ppc/translate/fp-impl.c.inc @@ -348,7 +348,7 @@ static void gen_fcmpo(DisasContext *ctx) t0 = tcg_temp_new_i64(); t1 = tcg_temp_new_i64(); gen_reset_fpstatus(); -crf = tcg_const_i32(crfD(ctx->opcode)); +crf = tcg_constant_i32(crfD(ctx->opcode)); get_fpr(t0, rA(ctx->opcode)); get_fpr(t1, rB(ctx->opcode)); gen_helper_fcmpo(cpu_env, t0, t1, crf); @@ -368,7 +368,7 @@ static void gen_fcmpu(DisasContext *ctx) t0 = tcg_temp_new_i64(); t1 = tcg_temp_new_i64(); gen_reset_fpstatus(); -crf = tcg_const_i32(crfD(ctx->opcode)); +crf = tcg_constant_i32(crfD(ctx->opcode)); get_fpr(t0, rA(ctx->opcode)); get_fpr(t1, rB(ctx->opcode)); gen_helper_fcmpu(cpu_env, t0, t1, crf); @@ -541,7 +541,7 @@ static void gen_mcrfs(DisasContext *ctx) tcg_gen_andi_i64(tnew_fpscr, tnew_fpscr, ~((0xF << shift) & FP_EX_CLEAR_BITS)); /* FEX and VX need to be updated, so don't set fpscr directly */ -tmask = tcg_const_i32(1 << nibble); +tmask = tcg_constant_i32(1 << nibble); gen_helper_store_fpscr(cpu_env, tnew_fpscr, tmask); } @@ -681,9 +681,7 @@ static void gen_mtfsb0(DisasContext *ctx) crb = 31 - crbD(ctx->opcode); gen_reset_fpstatus(); if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) { -TCGv_i32 t0; -t0 = tcg_const_i32(crb); -gen_helper_fpscr_clrbit(cpu_env, t0); +gen_helper_fpscr_clrbit(cpu_env, tcg_constant_i32(crb)); } if (unlikely(Rc(ctx->opcode) != 0)) { tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr); @@ -703,9 +701,7 @@ static void gen_mtfsb1(DisasContext *ctx) crb = 31 - crbD(ctx->opcode); /* XXX: we pretend we can only do IEEE floating-point computations */ if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) { -TCGv_i32 t0; -t0 = tcg_const_i32(crb); -gen_helper_fpscr_setbit(cpu_env, t0); +gen_helper_fpscr_setbit(cpu_env, tcg_constant_i32(crb)); } if (unlikely(Rc(ctx->opcode) != 0)) { tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr); @@ -733,10 +729,12 @@ static void gen_mtfsf(DisasContext *ctx) gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); return; } -if (l) { -t0 = tcg_const_i32((ctx->insns_flags2 & PPC2_ISA205) ? 0x : 0xff); +if (!l) { +t0 = tcg_constant_i32(flm << (w * 8)); +} else if (ctx->insns_flags2 & PPC2_ISA205) { +t0 = tcg_constant_i32(0x); } else { -t0 = tcg_const_i32(flm << (w * 8)); +t0 = tcg_constant_i32(0xff); } t1 = tcg_temp_new_i64(); get_fpr(t1, rB(ctx->opcode)); @@ -767,8 +765,8 @@ static void gen_mtfsfi(DisasContext *ctx) return; } sh = (8 * w) + 7 - bf; -t0 = tcg_const_i64(((uint64_t)FPIMM(ctx->opcode)) << (4 * sh)); -t1 = tcg_const_i32(1 << sh); +t0 = tcg_constant_i64(((uint64_t)FPIMM(ctx->opcode)) << (4 * sh)); +t1 = tcg_constant_i32(1 << sh); gen_helper_store_fpscr(cpu_env, t0, t1); if (unlikely(Rc(ctx->opcode) != 0)) { tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr); -- 2.34.1
[PATCH v2 2/2] linux-user/m68k: Handle EXCP_ADDRESS in cpu_loop
This exception can be raised by illegal instructions. Signed-off-by: Richard Henderson --- linux-user/m68k/cpu_loop.c | 5 - tests/tcg/m68k/excp-address.c | 32 tests/tcg/m68k/Makefile.target | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/tcg/m68k/excp-address.c diff --git a/linux-user/m68k/cpu_loop.c b/linux-user/m68k/cpu_loop.c index caead1cb74..84b5d290c0 100644 --- a/linux-user/m68k/cpu_loop.c +++ b/linux-user/m68k/cpu_loop.c @@ -35,7 +35,10 @@ void cpu_loop(CPUM68KState *env) cpu_exec_end(cs); process_queued_cpu_work(cs); -switch(trapnr) { +switch (trapnr) { +case EXCP_ADDRESS: +force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, env->pc); +break; case EXCP_ILLEGAL: case EXCP_LINEA: case EXCP_LINEF: diff --git a/tests/tcg/m68k/excp-address.c b/tests/tcg/m68k/excp-address.c new file mode 100644 index 00..1dbdddef58 --- /dev/null +++ b/tests/tcg/m68k/excp-address.c @@ -0,0 +1,32 @@ +/* + * Test m68k address exception + */ + +#define _GNU_SOURCE 1 +#include +#include + +static void sig_handler(int sig, siginfo_t *si, void *puc) +{ +exit(0); +} + +int main(int argc, char **argv) +{ +struct sigaction act = { +.sa_sigaction = sig_handler, +.sa_flags = SA_SIGINFO +}; + +sigaction(SIGBUS, , NULL); + +/* + * addl %d0,#0 -- with immediate as destination is illegal. + * Buggy qemu interpreted the insn as 5 words: 2 for immediate source + * and another 2 for immediate destination. Provide all that padding + * so that abort gets called. + */ +asm volatile(".word 0xd1bc,0,0,0,0"); + +abort(); +} diff --git a/tests/tcg/m68k/Makefile.target b/tests/tcg/m68k/Makefile.target index 1163c7ef03..d3b0bc48a3 100644 --- a/tests/tcg/m68k/Makefile.target +++ b/tests/tcg/m68k/Makefile.target @@ -4,6 +4,7 @@ # VPATH += $(SRC_PATH)/tests/tcg/m68k +TESTS += excp-address TESTS += trap # On m68k Linux supports 4k and 8k pages (but 8k is currently broken) -- 2.34.1
[PULL v2 82/91] target/ppc: Avoid tcg_const_* in xxeval
Initialize a new temp instead of tcg_const_*. Fix a pasto in a comment. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Daniel Henrique Barboza Signed-off-by: Richard Henderson --- target/ppc/translate/vsx-impl.c.inc | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc index 6e63403727..9916784e64 100644 --- a/target/ppc/translate/vsx-impl.c.inc +++ b/target/ppc/translate/vsx-impl.c.inc @@ -2449,7 +2449,8 @@ static void gen_xxeval_i64(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b, TCGv_i64 c, TCGv_i64 conj, disj; conj = tcg_temp_new_i64(); -disj = tcg_const_i64(0); +disj = tcg_temp_new_i64(); +tcg_gen_movi_i64(disj, 0); /* Iterate over set bits from the least to the most significant bit */ while (imm) { @@ -2492,8 +2493,9 @@ static void gen_xxeval_vec(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b, int bit; TCGv_vec disj, conj; -disj = tcg_const_zeros_vec_matching(t); conj = tcg_temp_new_vec_matching(t); +disj = tcg_temp_new_vec_matching(t); +tcg_gen_dupi_vec(vece, disj, 0); /* Iterate over set bits from the least to the most significant bit */ while (imm) { @@ -2546,7 +2548,7 @@ static bool trans_XXEVAL(DisasContext *ctx, arg_8RR_XX4_imm *a) /* Equivalent functions that can be implemented with a single gen_gvec */ switch (a->imm) { -case 0b: /* true */ +case 0b: /* false */ set_cpu_vsr(a->xt, tcg_constant_i64(0), true); set_cpu_vsr(a->xt, tcg_constant_i64(0), false); break; -- 2.34.1
[PULL v2 79/91] target/m68k: Use tcg_constant_i32 in gen_ea_mode
Return a constant for an immediate input. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/m68k/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 44c3ac0bc3..422f4652f1 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -916,7 +916,7 @@ static TCGv gen_ea_mode(CPUM68KState *env, DisasContext *s, int mode, int reg0, default: g_assert_not_reached(); } -return tcg_const_i32(offset); +return tcg_constant_i32(offset); default: return NULL_QREG; } -- 2.34.1
[PULL v2 86/91] target/ppc: Rewrite trans_ADDG6S
Compute all carry bits in parallel instead of a loop. Reviewed-by: Daniel Henrique Barboza Signed-off-by: Richard Henderson --- target/ppc/translate/fixedpoint-impl.c.inc | 44 +++--- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/target/ppc/translate/fixedpoint-impl.c.inc b/target/ppc/translate/fixedpoint-impl.c.inc index 20ea484c3d..02d86b77a8 100644 --- a/target/ppc/translate/fixedpoint-impl.c.inc +++ b/target/ppc/translate/fixedpoint-impl.c.inc @@ -484,33 +484,35 @@ static bool trans_PEXTD(DisasContext *ctx, arg_X *a) static bool trans_ADDG6S(DisasContext *ctx, arg_X *a) { -const uint64_t carry_bits = 0xULL; -TCGv t0, t1, carry, zero = tcg_constant_tl(0); +const target_ulong carry_bits = (target_ulong)-1 / 0xf; +TCGv in1, in2, carryl, carryh, tmp; +TCGv zero = tcg_constant_tl(0); REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206); -t0 = tcg_temp_new(); -t1 = tcg_const_tl(0); -carry = tcg_const_tl(0); +in1 = cpu_gpr[a->ra]; +in2 = cpu_gpr[a->rb]; +tmp = tcg_temp_new(); +carryl = tcg_temp_new(); +carryh = tcg_temp_new(); -for (int i = 0; i < 16; i++) { -tcg_gen_shri_tl(t0, cpu_gpr[a->ra], i * 4); -tcg_gen_andi_tl(t0, t0, 0xf); -tcg_gen_add_tl(t1, t1, t0); +/* Addition with carry. */ +tcg_gen_add2_tl(carryl, carryh, in1, zero, in2, zero); +/* Addition without carry. */ +tcg_gen_xor_tl(tmp, in1, in2); +/* Difference between the two is carry in to each bit. */ +tcg_gen_xor_tl(carryl, carryl, tmp); -tcg_gen_shri_tl(t0, cpu_gpr[a->rb], i * 4); -tcg_gen_andi_tl(t0, t0, 0xf); -tcg_gen_add_tl(t1, t1, t0); +/* + * The carry-out that we're looking for is the carry-in to + * the next nibble. Shift the double-word down one nibble, + * which puts all of the bits back into one word. + */ +tcg_gen_extract2_tl(carryl, carryl, carryh, 4); -tcg_gen_andi_tl(t1, t1, 0x10); -tcg_gen_setcond_tl(TCG_COND_NE, t1, t1, zero); - -tcg_gen_shli_tl(t0, t1, i * 4); -tcg_gen_or_tl(carry, carry, t0); -} - -tcg_gen_xori_tl(carry, carry, (target_long)carry_bits); -tcg_gen_muli_tl(cpu_gpr[a->rt], carry, 6); +/* Invert, isolate the carry bits, and produce 6's. */ +tcg_gen_andc_tl(carryl, tcg_constant_tl(carry_bits), carryl); +tcg_gen_muli_tl(cpu_gpr[a->rt], carryl, 6); return true; } -- 2.34.1
[PULL v2 59/91] target/sh4: Avoid tcg_const_i32 for TAS.B
Since we're assigning to cpu_sr_t in the end, use that as the intermediate temp as well. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/sh4/translate.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/target/sh4/translate.c b/target/sh4/translate.c index ad6de41712..70a45c26e8 100644 --- a/target/sh4/translate.c +++ b/target/sh4/translate.c @@ -1610,12 +1610,9 @@ static void _decode_opc(DisasContext * ctx) tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16); return; case 0x401b: /* tas.b @Rn */ -{ -TCGv val = tcg_const_i32(0x80); -tcg_gen_atomic_fetch_or_i32(val, REG(B11_8), val, -ctx->memidx, MO_UB); -tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0); -} +tcg_gen_atomic_fetch_or_i32(cpu_sr_t, REG(B11_8), +tcg_constant_i32(0x80), ctx->memidx, MO_UB); +tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, cpu_sr_t, 0); return; case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */ CHECK_FPU_ENABLED -- 2.34.1
[PULL v2 88/91] target/ppc: Avoid tcg_const_* in translate.c
All remaining uses are strictly read-only. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Daniel Henrique Barboza Signed-off-by: Richard Henderson --- target/ppc/translate.c | 142 + 1 file changed, 72 insertions(+), 70 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 7ec940b7d8..9d05357d03 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -263,8 +263,8 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error) * faulting instruction */ gen_update_nip(ctx, ctx->cia); -t0 = tcg_const_i32(excp); -t1 = tcg_const_i32(error); +t0 = tcg_constant_i32(excp); +t1 = tcg_constant_i32(error); gen_helper_raise_exception_err(cpu_env, t0, t1); ctx->base.is_jmp = DISAS_NORETURN; } @@ -278,7 +278,7 @@ static void gen_exception(DisasContext *ctx, uint32_t excp) * faulting instruction */ gen_update_nip(ctx, ctx->cia); -t0 = tcg_const_i32(excp); +t0 = tcg_constant_i32(excp); gen_helper_raise_exception(cpu_env, t0); ctx->base.is_jmp = DISAS_NORETURN; } @@ -289,7 +289,7 @@ static void gen_exception_nip(DisasContext *ctx, uint32_t excp, TCGv_i32 t0; gen_update_nip(ctx, nip); -t0 = tcg_const_i32(excp); +t0 = tcg_constant_i32(excp); gen_helper_raise_exception(cpu_env, t0); ctx->base.is_jmp = DISAS_NORETURN; } @@ -386,7 +386,7 @@ void spr_noaccess(DisasContext *ctx, int gprn, int sprn) static void spr_load_dump_spr(int sprn) { #ifdef PPC_DUMP_SPR_ACCESSES -TCGv_i32 t0 = tcg_const_i32(sprn); +TCGv_i32 t0 = tcg_constant_i32(sprn); gen_helper_load_dump_spr(cpu_env, t0); #endif } @@ -400,7 +400,7 @@ void spr_read_generic(DisasContext *ctx, int gprn, int sprn) static void spr_store_dump_spr(int sprn) { #ifdef PPC_DUMP_SPR_ACCESSES -TCGv_i32 t0 = tcg_const_i32(sprn); +TCGv_i32 t0 = tcg_constant_i32(sprn); gen_helper_store_dump_spr(cpu_env, t0); #endif } @@ -672,25 +672,25 @@ void spr_read_ibat_h(DisasContext *ctx, int gprn, int sprn) void spr_write_ibatu(DisasContext *ctx, int sprn, int gprn) { -TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2); +TCGv_i32 t0 = tcg_constant_i32((sprn - SPR_IBAT0U) / 2); gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]); } void spr_write_ibatu_h(DisasContext *ctx, int sprn, int gprn) { -TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4U) / 2) + 4); +TCGv_i32 t0 = tcg_constant_i32(((sprn - SPR_IBAT4U) / 2) + 4); gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]); } void spr_write_ibatl(DisasContext *ctx, int sprn, int gprn) { -TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0L) / 2); +TCGv_i32 t0 = tcg_constant_i32((sprn - SPR_IBAT0L) / 2); gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]); } void spr_write_ibatl_h(DisasContext *ctx, int sprn, int gprn) { -TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4L) / 2) + 4); +TCGv_i32 t0 = tcg_constant_i32(((sprn - SPR_IBAT4L) / 2) + 4); gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]); } @@ -712,25 +712,25 @@ void spr_read_dbat_h(DisasContext *ctx, int gprn, int sprn) void spr_write_dbatu(DisasContext *ctx, int sprn, int gprn) { -TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0U) / 2); +TCGv_i32 t0 = tcg_constant_i32((sprn - SPR_DBAT0U) / 2); gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]); } void spr_write_dbatu_h(DisasContext *ctx, int sprn, int gprn) { -TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4U) / 2) + 4); +TCGv_i32 t0 = tcg_constant_i32(((sprn - SPR_DBAT4U) / 2) + 4); gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]); } void spr_write_dbatl(DisasContext *ctx, int sprn, int gprn) { -TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0L) / 2); +TCGv_i32 t0 = tcg_constant_i32((sprn - SPR_DBAT0L) / 2); gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]); } void spr_write_dbatl_h(DisasContext *ctx, int sprn, int gprn) { -TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4L) / 2) + 4); +TCGv_i32 t0 = tcg_constant_i32(((sprn - SPR_DBAT4L) / 2) + 4); gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]); } @@ -1040,13 +1040,15 @@ void spr_write_booke206_mmucsr0(DisasContext *ctx, int sprn, int gprn) void spr_write_booke_pid(DisasContext *ctx, int sprn, int gprn) { -TCGv_i32 t0 = tcg_const_i32(sprn); +TCGv_i32 t0 = tcg_constant_i32(sprn); gen_helper_booke_setpid(cpu_env, t0, cpu_gpr[gprn]); } + void spr_write_eplc(DisasContext *ctx, int sprn, int gprn) { gen_helper_booke_set_eplc(cpu_env, cpu_gpr[gprn]); } + void spr_write_epsc(DisasContext *ctx, int sprn, int gprn) { gen_helper_booke_set_epsc(cpu_env, cpu_gpr[gprn]); @@ -1080,9 +1082,9 @@ void spr_read_mas73(DisasContext *ctx, int gprn, int sprn) static void gen_fscr_facility_check(DisasContext *ctx, int facility_sprn, int bit, int sprn, int
[PATCH v8 04/11] target/arm: move cpu_tcg to tcg/cpu32.c
From: Claudio Fontana move the module containing cpu models definitions for 32bit TCG-only CPUs to tcg/ and rename it for clarity. Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Acked-by: Thomas Huth Signed-off-by: Fabiano Rosas --- hw/arm/virt.c | 2 +- target/arm/meson.build| 1 - target/arm/{cpu_tcg.c => tcg/cpu32.c} | 13 +++-- target/arm/tcg/meson.build| 1 + tests/qtest/arm-cpu-features.c| 12 +--- 5 files changed, 14 insertions(+), 15 deletions(-) rename target/arm/{cpu_tcg.c => tcg/cpu32.c} (99%) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 999c1ada79..b661b8d91b 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -204,9 +204,9 @@ static const int a15irqmap[] = { }; static const char *valid_cpus[] = { +#ifdef CONFIG_TCG ARM_CPU_TYPE_NAME("cortex-a7"), ARM_CPU_TYPE_NAME("cortex-a15"), -#ifdef CONFIG_TCG ARM_CPU_TYPE_NAME("cortex-a35"), ARM_CPU_TYPE_NAME("cortex-a55"), ARM_CPU_TYPE_NAME("cortex-a72"), diff --git a/target/arm/meson.build b/target/arm/meson.build index 3469926295..359a649eaf 100644 --- a/target/arm/meson.build +++ b/target/arm/meson.build @@ -5,7 +5,6 @@ arm_ss.add(files( 'gdbstub.c', 'helper.c', 'vfp_helper.c', - 'cpu_tcg.c', )) arm_ss.add(zlib) diff --git a/target/arm/cpu_tcg.c b/target/arm/tcg/cpu32.c similarity index 99% rename from target/arm/cpu_tcg.c rename to target/arm/tcg/cpu32.c index 5a2690f56e..4cbd7d68fb 100644 --- a/target/arm/cpu_tcg.c +++ b/target/arm/tcg/cpu32.c @@ -1,5 +1,5 @@ /* - * QEMU ARM TCG CPUs. + * QEMU ARM TCG-only CPUs. * * Copyright (c) 2012 SUSE LINUX Products GmbH * @@ -10,9 +10,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#ifdef CONFIG_TCG #include "hw/core/tcg-cpu-ops.h" -#endif /* CONFIG_TCG */ #include "internals.h" #include "target/arm/idau.h" #if !defined(CONFIG_USER_ONLY) @@ -27,7 +25,7 @@ /* CPU models. These are not needed for the AArch64 linux-user build. */ #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) -#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG) +#if !defined(CONFIG_USER_ONLY) static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { CPUClass *cc = CPU_GET_CLASS(cs); @@ -51,7 +49,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) } return ret; } -#endif /* !CONFIG_USER_ONLY && CONFIG_TCG */ +#endif /* !CONFIG_USER_ONLY */ static void arm926_initfn(Object *obj) { @@ -947,7 +945,6 @@ static void pxa270c5_initfn(Object *obj) cpu->reset_sctlr = 0x0078; } -#ifdef CONFIG_TCG static const struct TCGCPUOps arm_v7m_tcg_ops = { .initialize = arm_translate_init, .synchronize_from_tb = arm_cpu_synchronize_from_tb, @@ -968,7 +965,6 @@ static const struct TCGCPUOps arm_v7m_tcg_ops = { .debug_check_breakpoint = arm_debug_check_breakpoint, #endif /* !CONFIG_USER_ONLY */ }; -#endif /* CONFIG_TCG */ static void arm_v7m_class_init(ObjectClass *oc, void *data) { @@ -976,10 +972,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data) CPUClass *cc = CPU_CLASS(oc); acc->info = data; -#ifdef CONFIG_TCG cc->tcg_ops = _v7m_tcg_ops; -#endif /* CONFIG_TCG */ - cc->gdb_core_xml_file = "arm-m-profile.xml"; } diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build index 128f782816..4d99f6dacb 100644 --- a/target/arm/tcg/meson.build +++ b/target/arm/tcg/meson.build @@ -18,6 +18,7 @@ gen = [ arm_ss.add(gen) arm_ss.add(files( + 'cpu32.c', 'translate.c', 'translate-m-nocp.c', 'translate-mve.c', diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c index 1cb08138ad..1555b0bab8 100644 --- a/tests/qtest/arm-cpu-features.c +++ b/tests/qtest/arm-cpu-features.c @@ -506,9 +506,15 @@ static void test_query_cpu_model_expansion_kvm(const void *data) QDict *resp; char *error; -assert_error(qts, "cortex-a15", -"We cannot guarantee the CPU type 'cortex-a15' works " -"with KVM on this host", NULL); +if (qtest_has_accel("tcg")) { +assert_error(qts, "cortex-a15", + "We cannot guarantee the CPU type 'cortex-a15' works " + "with KVM on this host", NULL); +} else { +assert_error(qts, "cortex-a15", + "The CPU type 'cortex-a15' is not a " + "recognized ARM CPU type", NULL); +} assert_has_feature_enabled(qts, "host", "aarch64"); -- 2.35.3
[PATCH v8 06/11] arm/Kconfig: Do not build TCG-only boards on a KVM-only build
Move all the CONFIG_FOO=y from default.mak into "default y if TCG" statements in Kconfig. That way they won't be selected when CONFIG_TCG=n. I'm leaving CONFIG_ARM_VIRT in default.mak because it allows us to keep the two default.mak files not empty and keep aarch64-default.mak including arm-default.mak. That way we don't surprise anyone that's used to altering these files. With this change we can start building with --disable-tcg. Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson --- configs/devices/aarch64-softmmu/default.mak | 4 -- configs/devices/arm-softmmu/default.mak | 37 -- hw/arm/Kconfig | 42 - 3 files changed, 41 insertions(+), 42 deletions(-) diff --git a/configs/devices/aarch64-softmmu/default.mak b/configs/devices/aarch64-softmmu/default.mak index cf43ac8da1..70e05a197d 100644 --- a/configs/devices/aarch64-softmmu/default.mak +++ b/configs/devices/aarch64-softmmu/default.mak @@ -2,7 +2,3 @@ # We support all the 32 bit boards so need all their config include ../arm-softmmu/default.mak - -CONFIG_XLNX_ZYNQMP_ARM=y -CONFIG_XLNX_VERSAL=y -CONFIG_SBSA_REF=y diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak index cb3e5aea65..647fbce88d 100644 --- a/configs/devices/arm-softmmu/default.mak +++ b/configs/devices/arm-softmmu/default.mak @@ -4,40 +4,3 @@ # CONFIG_TEST_DEVICES=n CONFIG_ARM_VIRT=y -CONFIG_CUBIEBOARD=y -CONFIG_EXYNOS4=y -CONFIG_HIGHBANK=y -CONFIG_INTEGRATOR=y -CONFIG_FSL_IMX31=y -CONFIG_MUSICPAL=y -CONFIG_MUSCA=y -CONFIG_CHEETAH=y -CONFIG_SX1=y -CONFIG_NSERIES=y -CONFIG_STELLARIS=y -CONFIG_STM32VLDISCOVERY=y -CONFIG_REALVIEW=y -CONFIG_VERSATILE=y -CONFIG_VEXPRESS=y -CONFIG_ZYNQ=y -CONFIG_MAINSTONE=y -CONFIG_GUMSTIX=y -CONFIG_SPITZ=y -CONFIG_TOSA=y -CONFIG_Z2=y -CONFIG_NPCM7XX=y -CONFIG_COLLIE=y -CONFIG_ASPEED_SOC=y -CONFIG_NETDUINO2=y -CONFIG_NETDUINOPLUS2=y -CONFIG_OLIMEX_STM32_H405=y -CONFIG_MPS2=y -CONFIG_RASPI=y -CONFIG_DIGIC=y -CONFIG_SABRELITE=y -CONFIG_EMCRAFT_SF2=y -CONFIG_MICROBIT=y -CONFIG_FSL_IMX25=y -CONFIG_FSL_IMX7=y -CONFIG_FSL_IMX6UL=y -CONFIG_ALLWINNER_H3=y diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index c0b213f42d..dd189eae2b 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -34,20 +34,24 @@ config ARM_VIRT config CHEETAH bool +default y if TCG && ARM select OMAP select TSC210X config CUBIEBOARD bool +default y if TCG && ARM select ALLWINNER_A10 config DIGIC bool +default y if TCG && ARM select PTIMER select PFLASH_CFI02 config EXYNOS4 bool +default y if TCG && ARM imply I2C_DEVICES select A9MPCORE select I2C @@ -60,6 +64,7 @@ config EXYNOS4 config HIGHBANK bool +default y if TCG && ARM select A9MPCORE select A15MPCORE select AHCI @@ -74,6 +79,7 @@ config HIGHBANK config INTEGRATOR bool +default y if TCG && ARM select ARM_TIMER select INTEGRATOR_DEBUG select PL011 # UART @@ -86,12 +92,14 @@ config INTEGRATOR config MAINSTONE bool +default y if TCG && ARM select PXA2XX select PFLASH_CFI01 select SMC91C111 config MUSCA bool +default y if TCG && ARM select ARMSSE select PL011 select PL031 @@ -103,6 +111,7 @@ config MARVELL_88W8618 config MUSICPAL bool +default y if TCG && ARM select OR_IRQ select BITBANG_I2C select MARVELL_88W8618 @@ -113,18 +122,22 @@ config MUSICPAL config NETDUINO2 bool +default y if TCG && ARM select STM32F205_SOC config NETDUINOPLUS2 bool +default y if TCG && ARM select STM32F405_SOC config OLIMEX_STM32_H405 bool +default y if TCG && ARM select STM32F405_SOC config NSERIES bool +default y if TCG && ARM select OMAP select TMP105 # tempature sensor select BLIZZARD # LCD/TV controller @@ -157,12 +170,14 @@ config PXA2XX config GUMSTIX bool +default y if TCG && ARM select PFLASH_CFI01 select SMC91C111 select PXA2XX config TOSA bool +default y if TCG && ARM select ZAURUS # scoop select MICRODRIVE select PXA2XX @@ -170,6 +185,7 @@ config TOSA config SPITZ bool +default y if TCG && ARM select ADS7846 # touch-screen controller select MAX111X # A/D converter select WM8750 # audio codec @@ -182,6 +198,7 @@ config SPITZ config Z2 bool +default y if TCG && ARM select PFLASH_CFI01 select WM8750 select PL011 # UART @@ -189,6 +206,7 @@ config Z2 config REALVIEW bool +default y if TCG && ARM imply PCI_DEVICES imply PCI_TESTDEV imply I2C_DEVICES @@ -217,6 +235,7 @@ config REALVIEW config SBSA_REF bool +default y if TCG && AARCH64 imply PCI_DEVICES select AHCI select ARM_SMMUV3 @@ -232,11 +251,13 @@ config SBSA_REF config SABRELITE bool +default y if TCG &&
[PATCH v8 05/11] arm/Kconfig: Always select SEMIHOSTING when TCG is present
We are about to enable the build without TCG, so CONFIG_SEMIHOSTING and CONFIG_ARM_COMPATIBLE_SEMIHOSTING cannot be unconditionally set in default.mak anymore. So reflect the change in a Kconfig. Instead of using semihosting/Kconfig, use a target-specific file, so that the change doesn't affect other architectures which might implement semihosting in a way compatible with KVM. The selection from ARM_v7M needs to be removed to avoid a cycle during parsing. Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson --- configs/devices/arm-softmmu/default.mak | 2 -- hw/arm/Kconfig | 1 - target/arm/Kconfig | 7 +++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak index 1b49a7830c..cb3e5aea65 100644 --- a/configs/devices/arm-softmmu/default.mak +++ b/configs/devices/arm-softmmu/default.mak @@ -40,6 +40,4 @@ CONFIG_MICROBIT=y CONFIG_FSL_IMX25=y CONFIG_FSL_IMX7=y CONFIG_FSL_IMX6UL=y -CONFIG_SEMIHOSTING=y -CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y CONFIG_ALLWINNER_H3=y diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index b5aed4aff5..c0b213f42d 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -316,7 +316,6 @@ config ARM_V7M # currently v7M must be included in a TCG build due to translate.c default y if TCG && (ARM || AARCH64) select PTIMER -select ARM_COMPATIBLE_SEMIHOSTING config ALLWINNER_A10 bool diff --git a/target/arm/Kconfig b/target/arm/Kconfig index 3f3394a22b..39f05b6420 100644 --- a/target/arm/Kconfig +++ b/target/arm/Kconfig @@ -4,3 +4,10 @@ config ARM config AARCH64 bool select ARM + +# This config exists just so we can make SEMIHOSTING default when TCG +# is selected without also changing it for other architectures. +config ARM_SEMIHOSTING +bool +default y if TCG && ARM +select ARM_COMPATIBLE_SEMIHOSTING -- 2.35.3
[PULL v2 70/91] target/arm: Improve arm_rmode_to_sf
Use proper enumeration types for input and output. Use a const array to perform the mapping, with an assert that the input is valid. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/arm/internals.h | 12 +--- target/arm/tcg/translate-mve.c | 2 +- target/arm/vfp_helper.c| 33 - 3 files changed, 18 insertions(+), 29 deletions(-) diff --git a/target/arm/internals.h b/target/arm/internals.h index b1ef05963f..673519a24a 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -193,16 +193,22 @@ void arm_restore_state_to_opc(CPUState *cs, void arm_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb); #endif /* CONFIG_TCG */ -enum arm_fprounding { +typedef enum ARMFPRounding { FPROUNDING_TIEEVEN, FPROUNDING_POSINF, FPROUNDING_NEGINF, FPROUNDING_ZERO, FPROUNDING_TIEAWAY, FPROUNDING_ODD -}; +} ARMFPRounding; -int arm_rmode_to_sf(int rmode); +extern const FloatRoundMode arm_rmode_to_sf_map[6]; + +static inline FloatRoundMode arm_rmode_to_sf(ARMFPRounding rmode) +{ +assert((unsigned)rmode < ARRAY_SIZE(arm_rmode_to_sf_map)); +return arm_rmode_to_sf_map[rmode]; +} static inline void aarch64_save_sp(CPUARMState *env, int el) { diff --git a/target/arm/tcg/translate-mve.c b/target/arm/tcg/translate-mve.c index 798b4fddfe..9744bf3de0 100644 --- a/target/arm/tcg/translate-mve.c +++ b/target/arm/tcg/translate-mve.c @@ -588,7 +588,7 @@ DO_VCVT(VCVT_FS, vcvt_hs, vcvt_fs) DO_VCVT(VCVT_FU, vcvt_hu, vcvt_fu) static bool do_vcvt_rmode(DisasContext *s, arg_1op *a, - enum arm_fprounding rmode, bool u) + ARMFPRounding rmode, bool u) { /* * Handle VCVT fp to int with specified rounding mode. diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c index 90cc324f71..36906db8e0 100644 --- a/target/arm/vfp_helper.c +++ b/target/arm/vfp_helper.c @@ -1104,31 +1104,14 @@ float64 HELPER(rintd)(float64 x, void *fp_status) } /* Convert ARM rounding mode to softfloat */ -int arm_rmode_to_sf(int rmode) -{ -switch (rmode) { -case FPROUNDING_TIEAWAY: -rmode = float_round_ties_away; -break; -case FPROUNDING_ODD: -rmode = float_round_to_odd; -break; -case FPROUNDING_TIEEVEN: -default: -rmode = float_round_nearest_even; -break; -case FPROUNDING_POSINF: -rmode = float_round_up; -break; -case FPROUNDING_NEGINF: -rmode = float_round_down; -break; -case FPROUNDING_ZERO: -rmode = float_round_to_zero; -break; -} -return rmode; -} +const FloatRoundMode arm_rmode_to_sf_map[] = { +[FPROUNDING_TIEEVEN] = float_round_nearest_even, +[FPROUNDING_POSINF] = float_round_up, +[FPROUNDING_NEGINF] = float_round_down, +[FPROUNDING_ZERO] = float_round_to_zero, +[FPROUNDING_TIEAWAY] = float_round_ties_away, +[FPROUNDING_ODD] = float_round_to_odd, +}; /* * Implement float64 to int32_t conversion without saturation; -- 2.34.1
[PULL v2 60/91] target/sh4: Avoid tcg_const_i32
All remaining uses are strictly read-only. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/sh4/translate.c | 26 +- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/target/sh4/translate.c b/target/sh4/translate.c index 70a45c26e8..97da8bce48 100644 --- a/target/sh4/translate.c +++ b/target/sh4/translate.c @@ -526,13 +526,13 @@ static void _decode_opc(DisasContext * ctx) return; case 0x9000: /* mov.w @(disp,PC),Rn */ { -TCGv addr = tcg_const_i32(ctx->base.pc_next + 4 + B7_0 * 2); +TCGv addr = tcg_constant_i32(ctx->base.pc_next + 4 + B7_0 * 2); tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESW); } return; case 0xd000: /* mov.l @(disp,PC),Rn */ { -TCGv addr = tcg_const_i32((ctx->base.pc_next + 4 + B7_0 * 4) & ~3); +TCGv addr = tcg_constant_i32((ctx->base.pc_next + 4 + B7_0 * 4) & ~3); tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL); } return; @@ -694,7 +694,7 @@ static void _decode_opc(DisasContext * ctx) case 0x300e: /* addc Rm,Rn */ { TCGv t0, t1; -t0 = tcg_const_tl(0); +t0 = tcg_constant_tl(0); t1 = tcg_temp_new(); tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0); tcg_gen_add2_i32(REG(B11_8), cpu_sr_t, @@ -754,7 +754,7 @@ static void _decode_opc(DisasContext * ctx) TCGv t0 = tcg_temp_new(); TCGv t1 = tcg_temp_new(); TCGv t2 = tcg_temp_new(); -TCGv zero = tcg_const_i32(0); +TCGv zero = tcg_constant_i32(0); /* shift left arg1, saving the bit being pushed out and inserting T on the right */ @@ -849,7 +849,7 @@ static void _decode_opc(DisasContext * ctx) return; case 0x600a: /* negc Rm,Rn */ { -TCGv t0 = tcg_const_i32(0); +TCGv t0 = tcg_constant_i32(0); tcg_gen_add2_i32(REG(B11_8), cpu_sr_t, REG(B7_4), t0, cpu_sr_t, t0); tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t, @@ -913,7 +913,7 @@ static void _decode_opc(DisasContext * ctx) case 0x300a: /* subc Rm,Rn */ { TCGv t0, t1; -t0 = tcg_const_tl(0); +t0 = tcg_constant_tl(0); t1 = tcg_temp_new(); tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0); tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t, @@ -1242,7 +1242,7 @@ static void _decode_opc(DisasContext * ctx) TCGv imm; CHECK_NOT_DELAY_SLOT gen_save_cpu_state(ctx, true); - imm = tcg_const_i32(B7_0); + imm = tcg_constant_i32(B7_0); gen_helper_trapa(cpu_env, imm); ctx->base.is_jmp = DISAS_NORETURN; } @@ -1709,8 +1709,8 @@ static void _decode_opc(DisasContext * ctx) CHECK_FPU_ENABLED CHECK_FPSCR_PR_1 { -TCGv m = tcg_const_i32((ctx->opcode >> 8) & 3); -TCGv n = tcg_const_i32((ctx->opcode >> 10) & 3); +TCGv m = tcg_constant_i32((ctx->opcode >> 8) & 3); +TCGv n = tcg_constant_i32((ctx->opcode >> 10) & 3); gen_helper_fipr(cpu_env, m, n); return; } @@ -1722,7 +1722,7 @@ static void _decode_opc(DisasContext * ctx) if ((ctx->opcode & 0x0300) != 0x0100) { goto do_illegal; } -TCGv n = tcg_const_i32((ctx->opcode >> 10) & 3); +TCGv n = tcg_constant_i32((ctx->opcode >> 10) & 3); gen_helper_ftrv(cpu_env, n); return; } @@ -1926,7 +1926,7 @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env) } op_dst = B11_8; op_opc = INDEX_op_xor_i32; -op_arg = tcg_const_i32(-1); +op_arg = tcg_constant_i32(-1); break; case 0x7000 ... 0x700f: /* add #imm,Rn */ @@ -1934,7 +1934,7 @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env) goto fail; } op_opc = INDEX_op_add_i32; -op_arg = tcg_const_i32(B7_0s); +op_arg = tcg_constant_i32(B7_0s); break; case 0x3000: /* cmp/eq Rm,Rn */ @@ -1980,7 +1980,7 @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env) goto fail; } op_opc = INDEX_op_setcond_i32; -op_arg = tcg_const_i32(0); +op_arg = tcg_constant_i32(0); NEXT_INSN; if ((ctx->opcode & 0xff00) != 0x8900 /* bt label */ -- 2.34.1
[PATCH v8 01/11] target/arm: Move cortex sysregs into a separate file
The file cpu_tcg.c is about to be moved into the tcg/ directory, so move the register definitions into a new file. Also move the function declaration to the more appropriate cpregs.h. Reviewed-by: Richard Henderson Signed-off-by: Fabiano Rosas --- target/arm/cortex-regs.c | 69 target/arm/cpregs.h | 6 target/arm/cpu64.c | 1 + target/arm/cpu_tcg.c | 59 -- target/arm/internals.h | 6 target/arm/meson.build | 1 + 6 files changed, 77 insertions(+), 65 deletions(-) create mode 100644 target/arm/cortex-regs.c diff --git a/target/arm/cortex-regs.c b/target/arm/cortex-regs.c new file mode 100644 index 00..17708480e7 --- /dev/null +++ b/target/arm/cortex-regs.c @@ -0,0 +1,69 @@ +/* + * ARM Cortex-A registers + * + * This code is licensed under the GNU GPL v2 or later. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "cpregs.h" + + +static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ +ARMCPU *cpu = env_archcpu(env); + +/* Number of cores is in [25:24]; otherwise we RAZ */ +return (cpu->core_count - 1) << 24; +} + +static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = { +{ .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2, + .access = PL1_RW, .readfn = l2ctlr_read, + .writefn = arm_cp_write_ignore }, +{ .name = "L2CTLR", + .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2, + .access = PL1_RW, .readfn = l2ctlr_read, + .writefn = arm_cp_write_ignore }, +{ .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, +{ .name = "L2ECTLR", + .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, +{ .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, +{ .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, +{ .name = "CPUACTLR", + .cp = 15, .opc1 = 0, .crm = 15, + .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, +{ .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, +{ .name = "CPUECTLR", + .cp = 15, .opc1 = 1, .crm = 15, + .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, +{ .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 2, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, +{ .name = "CPUMERRSR", + .cp = 15, .opc1 = 2, .crm = 15, + .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, +{ .name = "L2MERRSR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 3, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, +{ .name = "L2MERRSR", + .cp = 15, .opc1 = 3, .crm = 15, + .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, +}; + +void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) +{ +define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo); +} diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h index 1ee64e99de..b04d344a9f 100644 --- a/target/arm/cpregs.h +++ b/target/arm/cpregs.h @@ -1071,4 +1071,10 @@ static inline bool arm_cpreg_in_idspace(const ARMCPRegInfo *ri) ri->crn, ri->crm); } +#ifdef CONFIG_USER_ONLY +static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { } +#else +void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu); +#endif + #endif /* TARGET_ARM_CPREGS_H */ diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 4066950da1..9f193927d8 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -29,6 +29,7 @@ #include "qapi/visitor.h" #include "hw/qdev-properties.h" #include "internals.h" +#include "cpregs.h" static void aarch64_a35_initfn(Object *obj) { diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c index df0c45e523..6ce728134f 100644 --- a/target/arm/cpu_tcg.c +++ b/target/arm/cpu_tcg.c @@ -93,65 +93,6 @@ void aa32_max_features(ARMCPU *cpu) cpu->isar.id_dfr0 = t; } -#ifndef CONFIG_USER_ONLY -static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ -ARMCPU *cpu = env_archcpu(env); - -/* Number of cores is in [25:24]; otherwise we RAZ */ -return (cpu->core_count - 1) << 24; -} - -static const ARMCPRegInfo
[PULL v2 83/91] target/ppc: Avoid tcg_const_* in vsx-impl.c.inc
All remaining uses are strictly read-only. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Daniel Henrique Barboza Signed-off-by: Richard Henderson --- target/ppc/translate/vsx-impl.c.inc | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc index 9916784e64..0f5b0056f1 100644 --- a/target/ppc/translate/vsx-impl.c.inc +++ b/target/ppc/translate/vsx-impl.c.inc @@ -154,7 +154,7 @@ static void gen_lxvdsx(DisasContext *ctx) static void gen_bswap16x8(TCGv_i64 outh, TCGv_i64 outl, TCGv_i64 inh, TCGv_i64 inl) { -TCGv_i64 mask = tcg_const_i64(0x00FF00FF00FF00FF); +TCGv_i64 mask = tcg_constant_i64(0x00FF00FF00FF00FF); TCGv_i64 t0 = tcg_temp_new_i64(); TCGv_i64 t1 = tcg_temp_new_i64(); @@ -825,7 +825,7 @@ static bool trans_XSCVQPDP(DisasContext *ctx, arg_X_tb_rc *a) REQUIRE_INSNS_FLAGS2(ctx, ISA300); REQUIRE_VSX(ctx); -ro = tcg_const_i32(a->rc); +ro = tcg_constant_i32(a->rc); xt = gen_avr_ptr(a->rt); xb = gen_avr_ptr(a->rb); @@ -860,7 +860,7 @@ static void gen_##name(DisasContext *ctx) \ gen_exception(ctx, POWERPC_EXCP_VSXU);\ return; \ } \ -opc = tcg_const_i32(ctx->opcode); \ +opc = tcg_constant_i32(ctx->opcode); \ gen_helper_##name(cpu_env, opc); \ } @@ -900,7 +900,7 @@ static void gen_##name(DisasContext *ctx) \ gen_exception(ctx, POWERPC_EXCP_VSXU);\ return; \ } \ -opc = tcg_const_i32(ctx->opcode); \ +opc = tcg_constant_i32(ctx->opcode); \ xa = gen_vsr_ptr(xA(ctx->opcode));\ xb = gen_vsr_ptr(xB(ctx->opcode));\ gen_helper_##name(cpu_env, opc, xa, xb); \ @@ -915,7 +915,7 @@ static void gen_##name(DisasContext *ctx) \ gen_exception(ctx, POWERPC_EXCP_VSXU);\ return; \ } \ -opc = tcg_const_i32(ctx->opcode); \ +opc = tcg_constant_i32(ctx->opcode); \ xb = gen_vsr_ptr(xB(ctx->opcode));\ gen_helper_##name(cpu_env, opc, xb); \ } @@ -929,7 +929,7 @@ static void gen_##name(DisasContext *ctx) \ gen_exception(ctx, POWERPC_EXCP_VSXU);\ return; \ } \ -opc = tcg_const_i32(ctx->opcode); \ +opc = tcg_constant_i32(ctx->opcode); \ xt = gen_vsr_ptr(rD(ctx->opcode) + 32); \ xa = gen_vsr_ptr(rA(ctx->opcode) + 32); \ xb = gen_vsr_ptr(rB(ctx->opcode) + 32); \ @@ -945,7 +945,7 @@ static void gen_##name(DisasContext *ctx) \ gen_exception(ctx, POWERPC_EXCP_VSXU);\ return; \ } \ -opc = tcg_const_i32(ctx->opcode); \ +opc = tcg_constant_i32(ctx->opcode); \ xt = gen_vsr_ptr(rD(ctx->opcode) + 32); \ xb = gen_vsr_ptr(rB(ctx->opcode) + 32); \ gen_helper_##name(cpu_env, opc, xt, xb); \ @@ -960,7 +960,7 @@ static void gen_##name(DisasContext *ctx) \ gen_exception(ctx, POWERPC_EXCP_VSXU);\ return; \ } \ -
[PATCH v8 09/11] tests/avocado: Pass parameters to migration test
The migration tests are currently broken for an aarch64 host because the tests pass no 'machine' and 'cpu' options on the QEMU command line. Add a separate class to each architecture so that we can specify 'machine' and 'cpu' options instead of relying on defaults. Add a skip decorator to keep the current behavior of only running migration tests when the qemu target matches the host architecture. Signed-off-by: Fabiano Rosas --- tests/avocado/migration.py | 83 +++--- 1 file changed, 78 insertions(+), 5 deletions(-) diff --git a/tests/avocado/migration.py b/tests/avocado/migration.py index 4b25680c50..8b2ec0e3c4 100644 --- a/tests/avocado/migration.py +++ b/tests/avocado/migration.py @@ -11,6 +11,8 @@ import tempfile +import os + from avocado_qemu import QemuSystemTest from avocado import skipUnless @@ -19,7 +21,7 @@ from avocado.utils.path import find_command -class Migration(QemuSystemTest): +class MigrationTest(QemuSystemTest): """ :avocado: tags=migration """ @@ -62,20 +64,91 @@ def _get_free_port(self): self.cancel('Failed to find a free port') return port - -def test_migration_with_tcp_localhost(self): +def migration_with_tcp_localhost(self): dest_uri = 'tcp:localhost:%u' % self._get_free_port() self.do_migrate(dest_uri) -def test_migration_with_unix(self): +def migration_with_unix(self): with tempfile.TemporaryDirectory(prefix='socket_') as socket_path: dest_uri = 'unix:%s/qemu-test.sock' % socket_path self.do_migrate(dest_uri) @skipUnless(find_command('nc', default=False), "'nc' command not found") -def test_migration_with_exec(self): +def migration_with_exec(self): """The test works for both netcat-traditional and netcat-openbsd packages.""" free_port = self._get_free_port() dest_uri = 'exec:nc -l localhost %u' % free_port src_uri = 'exec:nc localhost %u' % free_port self.do_migrate(dest_uri, src_uri) + + +@skipUnless('aarch64' in os.uname()[4], "host != target") +class Aarch64(MigrationTest): +""" +:avocado: tags=arch:aarch64 +:avocado: tags=machine:virt +:avocado: tags=cpu:max +""" + +def test_migration_with_tcp_localhost(self): +self.migration_with_tcp_localhost() + +def test_migration_with_unix(self): +self.migration_with_unix() + +def test_migration_with_exec(self): +self.migration_with_exec() + + +@skipUnless('x86_64' in os.uname()[4], "host != target") +class X86_64(MigrationTest): +""" +:avocado: tags=arch:x86_64 +:avocado: tags=machine:pc +:avocado: tags=cpu:qemu64 +""" + +def test_migration_with_tcp_localhost(self): +self.migration_with_tcp_localhost() + +def test_migration_with_unix(self): +self.migration_with_unix() + +def test_migration_with_exec(self): +self.migration_with_exec() + + +@skipUnless('ppc64le' in os.uname()[4], "host != target") +class PPC64(MigrationTest): +""" +:avocado: tags=arch:ppc64 +:avocado: tags=machine:pseries +:avocado: tags=cpu:power9_v2.0 +""" + +def test_migration_with_tcp_localhost(self): +self.migration_with_tcp_localhost() + +def test_migration_with_unix(self): +self.migration_with_unix() + +def test_migration_with_exec(self): +self.migration_with_exec() + + +@skipUnless('s390x' in os.uname()[4], "host != target") +class S390X(MigrationTest): +""" +:avocado: tags=arch:s390x +:avocado: tags=machine:s390-ccw-virtio +:avocado: tags=cpu:qemu +""" + +def test_migration_with_tcp_localhost(self): +self.migration_with_tcp_localhost() + +def test_migration_with_unix(self): +self.migration_with_unix() + +def test_migration_with_exec(self): +self.migration_with_exec() -- 2.35.3
[PULL v2 78/91] target/arm: Avoid tcg_const_ptr in handle_rev
Here it is not trivial to notice first initialization, so explicitly zero the temps. Use an array for the output, rather than separate tcg_rd/tcg_rd_hi variables. Fixes a bug by adding a missing clear_vec_high. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/arm/tcg/translate-a64.c | 26 +++--- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 082a8b82dd..dff391bfe2 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -12003,22 +12003,26 @@ static void handle_rev(DisasContext *s, int opcode, bool u, int esize = 8 << size; int elements = dsize / esize; TCGv_i64 tcg_rn = tcg_temp_new_i64(); -TCGv_i64 tcg_rd = tcg_const_i64(0); -TCGv_i64 tcg_rd_hi = tcg_const_i64(0); +TCGv_i64 tcg_rd[2]; + +for (i = 0; i < 2; i++) { +tcg_rd[i] = tcg_temp_new_i64(); +tcg_gen_movi_i64(tcg_rd[i], 0); +} for (i = 0; i < elements; i++) { int e_rev = (i & 0xf) ^ revmask; -int off = e_rev * esize; +int w = (e_rev * esize) / 64; +int o = (e_rev * esize) % 64; + read_vec_element(s, tcg_rn, rn, i, size); -if (off >= 64) { -tcg_gen_deposit_i64(tcg_rd_hi, tcg_rd_hi, -tcg_rn, off - 64, esize); -} else { -tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_rn, off, esize); -} +tcg_gen_deposit_i64(tcg_rd[w], tcg_rd[w], tcg_rn, o, esize); } -write_vec_element(s, tcg_rd, rd, 0, MO_64); -write_vec_element(s, tcg_rd_hi, rd, 1, MO_64); + +for (i = 0; i < 2; i++) { +write_vec_element(s, tcg_rd[i], rd, i, MO_64); +} +clear_vec_high(s, true, rd); } } -- 2.34.1
[PATCH v8 00/11] target/arm: Allow CONFIG_TCG=n builds
Changes since v7: - patch 8: moved calls to qtest_has_accel after g_test_init to avoid the TAP error; - moved the avocado patch towards the end of the series so we can merge the rest without it if needed; - two new patches to fix regressions due to gdbstub changes. CI run: https://gitlab.com/farosas/qemu/-/pipelines/801656194 v7 resend: https://lore.kernel.org/r/20230228192628.26140-1-faro...@suse.de v7: https://lore.kernel.org/r/20230223130841.25916-1-faro...@suse.de v6: https://lore.kernel.org/r/20230217201150.22032-1-faro...@suse.de v5 resend: https://lore.kernel.org/r/20230213202927.28992-1-faro...@suse.de v5: https://lore.kernel.org/r/20230120184825.31626-1-faro...@suse.de v4: https://lore.kernel.org/r/20230119135424.5417-1-faro...@suse.de v3: https://lore.kernel.org/r/20230113140419.4013-1-faro...@suse.de v2: https://lore.kernel.org/r/20230109224232.11661-1-faro...@suse.de v1: https://lore.kernel.org/r/20230104215835.24692-1-faro...@suse.de Claudio Fontana (1): target/arm: move cpu_tcg to tcg/cpu32.c Fabiano Rosas (9): target/arm: Move cortex sysregs into a separate file target/arm: Move 64-bit TCG CPUs into tcg/ target/arm: Move aa32_max_features out of cpu_tcg.c arm/Kconfig: Always select SEMIHOSTING when TCG is present arm/Kconfig: Do not build TCG-only boards on a KVM-only build tests/qtest: Fix tests when no KVM or TCG are present tests/avocado: Pass parameters to migration test target/arm: gdbstub: Guard M-profile code with CONFIG_TCG target/arm: gdbstub: Guard pauth code with CONFIG_TCG Philippe Mathieu-Daudé (1): gitlab-ci: Check building KVM-only aarch64 target .gitlab-ci.d/crossbuilds.yml | 11 + .../custom-runners/ubuntu-22.04-aarch64.yml | 4 - configs/devices/aarch64-softmmu/default.mak | 4 - configs/devices/arm-softmmu/default.mak | 39 -- hw/arm/Kconfig| 43 +- hw/arm/virt.c | 6 +- target/arm/Kconfig| 7 + target/arm/cortex-regs.c | 69 +++ target/arm/cpregs.h | 6 + target/arm/cpu.c | 69 +++ target/arm/cpu64.c| 399 +--- target/arm/gdbstub.c | 6 + target/arm/gdbstub64.c| 2 + target/arm/internals.h| 7 +- target/arm/meson.build| 2 +- target/arm/{cpu_tcg.c => tcg/cpu32.c} | 141 +- target/arm/tcg/cpu64.c| 438 ++ target/arm/tcg/meson.build| 2 + tests/avocado/migration.py| 83 +++- tests/qtest/arm-cpu-features.c| 12 +- tests/qtest/bios-tables-test.c| 10 +- tests/qtest/boot-serial-test.c| 10 + tests/qtest/migration-test.c | 9 +- tests/qtest/pxe-test.c| 7 +- tests/qtest/vmgenid-test.c| 8 +- 25 files changed, 787 insertions(+), 607 deletions(-) create mode 100644 target/arm/cortex-regs.c rename target/arm/{cpu_tcg.c => tcg/cpu32.c} (87%) create mode 100644 target/arm/tcg/cpu64.c -- 2.35.3
[PATCH v2 0/2] target/m68k: Reject immediate as destination
The translate.c fix is extracted from a larger patch set. I then add a test case and fix cpu_loop to raise the proper signal. r~ Richard Henderson (2): target/m68k: Reject immediate as destination in gen_ea_mode linux-user/m68k: Handle EXCP_ADDRESS in cpu_loop linux-user/m68k/cpu_loop.c | 5 - target/m68k/translate.c| 4 tests/tcg/m68k/excp-address.c | 32 tests/tcg/m68k/Makefile.target | 1 + 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 tests/tcg/m68k/excp-address.c -- 2.34.1
[PULL v2 91/91] tcg: Drop tcg_const_*
These functions are no longer used. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- include/tcg/tcg-op.h | 4 include/tcg/tcg.h| 6 -- tcg/tcg.c| 16 3 files changed, 26 deletions(-) diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h index 70856147c5..dff17c7072 100644 --- a/include/tcg/tcg-op.h +++ b/include/tcg/tcg-op.h @@ -1089,9 +1089,7 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t); #define tcg_gen_extract_tl tcg_gen_extract_i64 #define tcg_gen_sextract_tl tcg_gen_sextract_i64 #define tcg_gen_extract2_tl tcg_gen_extract2_i64 -#define tcg_const_tl tcg_const_i64 #define tcg_constant_tl tcg_constant_i64 -#define tcg_const_local_tl tcg_const_local_i64 #define tcg_gen_movcond_tl tcg_gen_movcond_i64 #define tcg_gen_add2_tl tcg_gen_add2_i64 #define tcg_gen_sub2_tl tcg_gen_sub2_i64 @@ -1205,9 +1203,7 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t); #define tcg_gen_extract_tl tcg_gen_extract_i32 #define tcg_gen_sextract_tl tcg_gen_sextract_i32 #define tcg_gen_extract2_tl tcg_gen_extract2_i32 -#define tcg_const_tl tcg_const_i32 #define tcg_constant_tl tcg_constant_i32 -#define tcg_const_local_tl tcg_const_local_i32 #define tcg_gen_movcond_tl tcg_gen_movcond_i32 #define tcg_gen_add2_tl tcg_gen_add2_i32 #define tcg_gen_sub2_tl tcg_gen_sub2_i32 diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index d620012c48..5cfaa53938 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -996,10 +996,6 @@ void tcg_remove_ops_after(TCGOp *op); void tcg_optimize(TCGContext *s); -/* Allocate a new temporary and initialize it with a constant. */ -TCGv_i32 tcg_const_i32(int32_t val); -TCGv_i64 tcg_const_i64(int64_t val); - /* * Locate or create a read-only temporary that is a constant. * This kind of temporary need not be freed, but for convenience @@ -1021,10 +1017,8 @@ TCGv_vec tcg_constant_vec(TCGType type, unsigned vece, int64_t val); TCGv_vec tcg_constant_vec_matching(TCGv_vec match, unsigned vece, int64_t val); #if UINTPTR_MAX == UINT32_MAX -# define tcg_const_ptr(x)((TCGv_ptr)tcg_const_i32((intptr_t)(x))) # define tcg_constant_ptr(x) ((TCGv_ptr)tcg_constant_i32((intptr_t)(x))) #else -# define tcg_const_ptr(x)((TCGv_ptr)tcg_const_i64((intptr_t)(x))) # define tcg_constant_ptr(x) ((TCGv_ptr)tcg_constant_i64((intptr_t)(x))) #endif diff --git a/tcg/tcg.c b/tcg/tcg.c index d2993826c8..bb52bc060b 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1445,22 +1445,6 @@ TCGv_vec tcg_constant_vec_matching(TCGv_vec match, unsigned vece, int64_t val) return tcg_constant_vec(t->base_type, vece, val); } -TCGv_i32 tcg_const_i32(int32_t val) -{ -TCGv_i32 t0; -t0 = tcg_temp_new_i32(); -tcg_gen_movi_i32(t0, val); -return t0; -} - -TCGv_i64 tcg_const_i64(int64_t val) -{ -TCGv_i64 t0; -t0 = tcg_temp_new_i64(); -tcg_gen_movi_i64(t0, val); -return t0; -} - /* Return true if OP may appear in the opcode stream. Test the runtime variable that controls each opcode. */ bool tcg_op_supported(TCGOpcode op) -- 2.34.1
[PULL v2 45/91] target/m68k: Avoid tcg_const_i32 when modified
In several instances, a temp is initialized with a for use as a constant, and then subsequently used as an unrelated temp. Split them. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/m68k/translate.c | 29 - 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 3055d2d246..0002d80bf9 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -1631,8 +1631,8 @@ static void bcd_add(TCGv dest, TCGv src) *= result with some possible exceeding 0x6 */ -t0 = tcg_const_i32(0x066); -tcg_gen_add_i32(t0, t0, src); +t0 = tcg_temp_new(); +tcg_gen_addi_i32(t0, src, 0x066); t1 = tcg_temp_new(); tcg_gen_add_i32(t1, t0, dest); @@ -1818,7 +1818,8 @@ DISAS_INSN(nbcd) SRC_EA(env, src, OS_BYTE, 0, ); -dest = tcg_const_i32(0); +dest = tcg_temp_new(); +tcg_gen_movi_i32(dest, 0); bcd_sub(dest, src); DEST_EA(env, insn, OS_BYTE, dest, ); @@ -1896,8 +1897,8 @@ DISAS_INSN(bitop_reg) else tcg_gen_andi_i32(src2, DREG(insn, 9), 31); -tmp = tcg_const_i32(1); -tcg_gen_shl_i32(tmp, tmp, src2); +tmp = tcg_temp_new(); +tcg_gen_shl_i32(tmp, tcg_constant_i32(1), src2); tcg_gen_and_i32(QREG_CC_Z, src1, tmp); @@ -3076,7 +3077,7 @@ DISAS_INSN(suba) static inline void gen_subx(DisasContext *s, TCGv src, TCGv dest, int opsize) { -TCGv tmp; +TCGv tmp, zero; gen_flush_flags(s); /* compute old Z */ @@ -3085,14 +3086,15 @@ static inline void gen_subx(DisasContext *s, TCGv src, TCGv dest, int opsize) * (X, N) = dest - (src + X); */ -tmp = tcg_const_i32(0); -tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, src, tmp, QREG_CC_X, tmp); -tcg_gen_sub2_i32(QREG_CC_N, QREG_CC_X, dest, tmp, QREG_CC_N, QREG_CC_X); +zero = tcg_constant_i32(0); +tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, src, zero, QREG_CC_X, zero); +tcg_gen_sub2_i32(QREG_CC_N, QREG_CC_X, dest, zero, QREG_CC_N, QREG_CC_X); gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1); tcg_gen_andi_i32(QREG_CC_X, QREG_CC_X, 1); /* Compute signed-overflow for subtract. */ +tmp = tcg_temp_new(); tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, dest); tcg_gen_xor_i32(tmp, dest, src); tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, tmp); @@ -3279,7 +3281,7 @@ DISAS_INSN(adda) static inline void gen_addx(DisasContext *s, TCGv src, TCGv dest, int opsize) { -TCGv tmp; +TCGv tmp, zero; gen_flush_flags(s); /* compute old Z */ @@ -3288,13 +3290,14 @@ static inline void gen_addx(DisasContext *s, TCGv src, TCGv dest, int opsize) * (X, N) = src + dest + X; */ -tmp = tcg_const_i32(0); -tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, QREG_CC_X, tmp, dest, tmp); -tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, QREG_CC_N, QREG_CC_X, src, tmp); +zero = tcg_constant_i32(0); +tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, QREG_CC_X, zero, dest, zero); +tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, QREG_CC_N, QREG_CC_X, src, zero); gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1); /* Compute signed-overflow for addition. */ +tmp = tcg_temp_new(); tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, src); tcg_gen_xor_i32(tmp, dest, src); tcg_gen_andc_i32(QREG_CC_V, QREG_CC_V, tmp); -- 2.34.1
[PULL v2 55/91] target/rx: Use cpu_psw_z as temp in flags computation
Since PSW_Z = PSW_S, we can move that assignment to the end and use PSW_Z as a temporary while computing PSW_O. Use tcg_constant_i32 instead of tcg_const_i32. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/rx/translate.c | 28 +--- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/target/rx/translate.c b/target/rx/translate.c index 998e6e0b7e..c47aa26893 100644 --- a/target/rx/translate.c +++ b/target/rx/translate.c @@ -967,14 +967,13 @@ static bool trans_NEG_rr(DisasContext *ctx, arg_NEG_rr *a) /* ret = arg1 + arg2 + psw_c */ static void rx_adc(TCGv ret, TCGv arg1, TCGv arg2) { -TCGv z; -z = tcg_const_i32(0); +TCGv z = tcg_constant_i32(0); tcg_gen_add2_i32(cpu_psw_s, cpu_psw_c, arg1, z, cpu_psw_c, z); tcg_gen_add2_i32(cpu_psw_s, cpu_psw_c, cpu_psw_s, cpu_psw_c, arg2, z); -tcg_gen_mov_i32(cpu_psw_z, cpu_psw_s); tcg_gen_xor_i32(cpu_psw_o, cpu_psw_s, arg1); -tcg_gen_xor_i32(z, arg1, arg2); -tcg_gen_andc_i32(cpu_psw_o, cpu_psw_o, z); +tcg_gen_xor_i32(cpu_psw_z, arg1, arg2); +tcg_gen_andc_i32(cpu_psw_o, cpu_psw_o, cpu_psw_z); +tcg_gen_mov_i32(cpu_psw_z, cpu_psw_s); tcg_gen_mov_i32(ret, cpu_psw_s); } @@ -1006,13 +1005,12 @@ static bool trans_ADC_mr(DisasContext *ctx, arg_ADC_mr *a) /* ret = arg1 + arg2 */ static void rx_add(TCGv ret, TCGv arg1, TCGv arg2) { -TCGv z; -z = tcg_const_i32(0); +TCGv z = tcg_constant_i32(0); tcg_gen_add2_i32(cpu_psw_s, cpu_psw_c, arg1, z, arg2, z); -tcg_gen_mov_i32(cpu_psw_z, cpu_psw_s); tcg_gen_xor_i32(cpu_psw_o, cpu_psw_s, arg1); -tcg_gen_xor_i32(z, arg1, arg2); -tcg_gen_andc_i32(cpu_psw_o, cpu_psw_o, z); +tcg_gen_xor_i32(cpu_psw_z, arg1, arg2); +tcg_gen_andc_i32(cpu_psw_o, cpu_psw_o, cpu_psw_z); +tcg_gen_mov_i32(cpu_psw_z, cpu_psw_s); tcg_gen_mov_i32(ret, cpu_psw_s); } @@ -1042,23 +1040,23 @@ static bool trans_ADD_rrr(DisasContext *ctx, arg_ADD_rrr *a) /* ret = arg1 - arg2 */ static void rx_sub(TCGv ret, TCGv arg1, TCGv arg2) { -TCGv temp; tcg_gen_sub_i32(cpu_psw_s, arg1, arg2); -tcg_gen_mov_i32(cpu_psw_z, cpu_psw_s); tcg_gen_setcond_i32(TCG_COND_GEU, cpu_psw_c, arg1, arg2); tcg_gen_xor_i32(cpu_psw_o, cpu_psw_s, arg1); -temp = tcg_temp_new_i32(); -tcg_gen_xor_i32(temp, arg1, arg2); -tcg_gen_and_i32(cpu_psw_o, cpu_psw_o, temp); +tcg_gen_xor_i32(cpu_psw_z, arg1, arg2); +tcg_gen_and_i32(cpu_psw_o, cpu_psw_o, cpu_psw_z); +tcg_gen_mov_i32(cpu_psw_z, cpu_psw_s); /* CMP not required return */ if (ret) { tcg_gen_mov_i32(ret, cpu_psw_s); } } + static void rx_cmp(TCGv dummy, TCGv arg1, TCGv arg2) { rx_sub(NULL, arg1, arg2); } + /* ret = arg1 - arg2 - !psw_c */ /* -> ret = arg1 + ~arg2 + psw_c */ static void rx_sbb(TCGv ret, TCGv arg1, TCGv arg2) -- 2.34.1
[PATCH v8 07/11] gitlab-ci: Check building KVM-only aarch64 target
From: Philippe Mathieu-Daudé Add a manual new job to cross-build the aarch64 target with only the KVM accelerator enabled (in particular, no TCG). Re-enable running the similar job on the project Aarch64 custom runner. Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Fabiano Rosas Reviewed-by: Thomas Huth --- .gitlab-ci.d/crossbuilds.yml | 11 +++ .gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml | 4 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml index d3a31a2112..e73efdf719 100644 --- a/.gitlab-ci.d/crossbuilds.yml +++ b/.gitlab-ci.d/crossbuilds.yml @@ -220,3 +220,14 @@ cross-arm64-xen-only: IMAGE: debian-arm64-cross ACCEL: xen EXTRA_CONFIGURE_OPTS: --disable-tcg --disable-kvm + +# Similar job is run by qemu-project's custom runner by default +cross-arm64-kvm-only: + extends: .cross_accel_build_job + needs: +job: arm64-debian-cross-container + variables: +QEMU_JOB_OPTIONAL: 1 +IMAGE: debian-arm64-cross +ACCEL: kvm +EXTRA_CONFIGURE_OPTS: --disable-tcg --disable-xen --without-default-devices diff --git a/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml b/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml index 13e14a0f87..c61be46b82 100644 --- a/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml +++ b/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml @@ -115,11 +115,7 @@ ubuntu-22.04-aarch64-notcg: - aarch64 rules: - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - when: manual - allow_failure: true - if: "$AARCH64_RUNNER_AVAILABLE" - when: manual - allow_failure: true script: - mkdir build - cd build -- 2.35.3
[PULL v2 50/91] target/mips: Avoid tcg_const_tl in gen_r6_ld
Allocate a separate temp for modification. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/mips/tcg/translate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index 7018c427be..bbc2212660 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -2964,8 +2964,8 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) static inline void gen_r6_ld(target_long addr, int reg, int memidx, MemOp memop) { -TCGv t0 = tcg_const_tl(addr); -tcg_gen_qemu_ld_tl(t0, t0, memidx, memop); +TCGv t0 = tcg_temp_new(); +tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop); gen_store_gpr(t0, reg); } -- 2.34.1
[PULL v2 69/91] target/arm: Handle FPROUNDING_ODD in arm_rmode_to_sf
While this enumerator has been present since the first commit, it isn't ever used. The first actual use of round-to-odd came with SVE, which currently uses float_round_to_odd instead of the arm-specific enumerator. Amusingly, the comment about unhandled TIEAWAY has been out of date since the initial commit of translate-a64.c. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/arm/vfp_helper.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c index 24e3d820a5..90cc324f71 100644 --- a/target/arm/vfp_helper.c +++ b/target/arm/vfp_helper.c @@ -,10 +,8 @@ int arm_rmode_to_sf(int rmode) rmode = float_round_ties_away; break; case FPROUNDING_ODD: -/* FIXME: add support for TIEAWAY and ODD */ -qemu_log_mask(LOG_UNIMP, "arm: unimplemented rounding mode: %d\n", - rmode); -/* fall through for now */ +rmode = float_round_to_odd; +break; case FPROUNDING_TIEEVEN: default: rmode = float_round_nearest_even; -- 2.34.1
[PATCH v8 10/11] target/arm: gdbstub: Guard M-profile code with CONFIG_TCG
This code is only relevant when TCG is present in the build. If we try to build with --disable-tcg we currently get: libqemu-aarch64-softmmu.fa.p/target_arm_gdbstub.c.o: in function `m_sysreg_ptr': ../target/arm/gdbstub.c:356: undefined reference to `arm_v7m_get_sp_ptr' Signed-off-by: Fabiano Rosas --- target/arm/gdbstub.c | 4 1 file changed, 4 insertions(+) diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c index 3f799f5d05..2ecc362ac2 100644 --- a/target/arm/gdbstub.c +++ b/target/arm/gdbstub.c @@ -322,6 +322,7 @@ static int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg) return cpu->dyn_sysreg_xml.num; } +#ifdef CONFIG_TCG typedef enum { M_SYSREG_MSP, M_SYSREG_PSP, @@ -479,6 +480,7 @@ static int arm_gen_dynamic_m_secextreg_xml(CPUState *cs, int orig_base_reg) return cpu->dyn_m_secextreg_xml.num; } #endif +#endif /* CONFIG_TCG */ const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname) { @@ -553,6 +555,7 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs), "system-registers.xml", 0); +#ifdef CONFIG_TCG if (arm_feature(env, ARM_FEATURE_M)) { gdb_register_coprocessor(cs, arm_gdb_get_m_systemreg, arm_gdb_set_m_systemreg, @@ -567,4 +570,5 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) } #endif } +#endif } -- 2.35.3
[PULL v2 76/91] target/arm: Avoid tcg_const_ptr in disas_simd_zip_trn
It is easy enough to use mov instead of or-with-zero and relying on the optimizer to fold away the or. Use an array for the output, rather than separate tcg_res{l,h} variables. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/arm/tcg/translate-a64.c | 41 +- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 989c958de6..2ad7c48901 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -7442,10 +7442,10 @@ static void disas_simd_zip_trn(DisasContext *s, uint32_t insn) bool part = extract32(insn, 14, 1); bool is_q = extract32(insn, 30, 1); int esize = 8 << size; -int i, ofs; +int i; int datasize = is_q ? 128 : 64; int elements = datasize / esize; -TCGv_i64 tcg_res, tcg_resl, tcg_resh; +TCGv_i64 tcg_res[2], tcg_ele; if (opcode == 0 || (size == 3 && !is_q)) { unallocated_encoding(s); @@ -7456,37 +7456,39 @@ static void disas_simd_zip_trn(DisasContext *s, uint32_t insn) return; } -tcg_resl = tcg_const_i64(0); -tcg_resh = is_q ? tcg_const_i64(0) : NULL; -tcg_res = tcg_temp_new_i64(); +tcg_res[0] = tcg_temp_new_i64(); +tcg_res[1] = is_q ? tcg_temp_new_i64() : NULL; +tcg_ele = tcg_temp_new_i64(); for (i = 0; i < elements; i++) { +int o, w; + switch (opcode) { case 1: /* UZP1/2 */ { int midpoint = elements / 2; if (i < midpoint) { -read_vec_element(s, tcg_res, rn, 2 * i + part, size); +read_vec_element(s, tcg_ele, rn, 2 * i + part, size); } else { -read_vec_element(s, tcg_res, rm, +read_vec_element(s, tcg_ele, rm, 2 * (i - midpoint) + part, size); } break; } case 2: /* TRN1/2 */ if (i & 1) { -read_vec_element(s, tcg_res, rm, (i & ~1) + part, size); +read_vec_element(s, tcg_ele, rm, (i & ~1) + part, size); } else { -read_vec_element(s, tcg_res, rn, (i & ~1) + part, size); +read_vec_element(s, tcg_ele, rn, (i & ~1) + part, size); } break; case 3: /* ZIP1/2 */ { int base = part * elements / 2; if (i & 1) { -read_vec_element(s, tcg_res, rm, base + (i >> 1), size); +read_vec_element(s, tcg_ele, rm, base + (i >> 1), size); } else { -read_vec_element(s, tcg_res, rn, base + (i >> 1), size); +read_vec_element(s, tcg_ele, rn, base + (i >> 1), size); } break; } @@ -7494,19 +7496,18 @@ static void disas_simd_zip_trn(DisasContext *s, uint32_t insn) g_assert_not_reached(); } -ofs = i * esize; -if (ofs < 64) { -tcg_gen_shli_i64(tcg_res, tcg_res, ofs); -tcg_gen_or_i64(tcg_resl, tcg_resl, tcg_res); +w = (i * esize) / 64; +o = (i * esize) % 64; +if (o == 0) { +tcg_gen_mov_i64(tcg_res[w], tcg_ele); } else { -tcg_gen_shli_i64(tcg_res, tcg_res, ofs - 64); -tcg_gen_or_i64(tcg_resh, tcg_resh, tcg_res); +tcg_gen_shli_i64(tcg_ele, tcg_ele, o); +tcg_gen_or_i64(tcg_res[w], tcg_res[w], tcg_ele); } } -write_vec_element(s, tcg_resl, rd, 0, MO_64); -if (is_q) { -write_vec_element(s, tcg_resh, rd, 1, MO_64); +for (i = 0; i <= is_q; ++i) { +write_vec_element(s, tcg_res[i], rd, i, MO_64); } clear_vec_high(s, is_q, rd); } -- 2.34.1
[PULL v2 62/91] target/tricore: Split t_n as constant from temp as variable
As required, allocate temp separately. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/tricore/translate.c | 268 +++-- 1 file changed, 140 insertions(+), 128 deletions(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 127f9a989a..194bef27a6 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -595,21 +595,22 @@ static inline void gen_madd_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3, uint32_t n, uint32_t mode) { -TCGv temp = tcg_const_i32(n); +TCGv t_n = tcg_constant_i32(n); +TCGv temp = tcg_temp_new(); TCGv temp2 = tcg_temp_new(); TCGv_i64 temp64 = tcg_temp_new_i64(); switch (mode) { case MODE_LL: -GEN_HELPER_LL(mul_h, temp64, r2, r3, temp); +GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n); break; case MODE_LU: -GEN_HELPER_LU(mul_h, temp64, r2, r3, temp); +GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n); break; case MODE_UL: -GEN_HELPER_UL(mul_h, temp64, r2, r3, temp); +GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n); break; case MODE_UU: -GEN_HELPER_UU(mul_h, temp64, r2, r3, temp); +GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n); break; } tcg_gen_extr_i64_i32(temp, temp2, temp64); @@ -621,21 +622,22 @@ static inline void gen_maddsu_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3, uint32_t n, uint32_t mode) { -TCGv temp = tcg_const_i32(n); +TCGv t_n = tcg_constant_i32(n); +TCGv temp = tcg_temp_new(); TCGv temp2 = tcg_temp_new(); TCGv_i64 temp64 = tcg_temp_new_i64(); switch (mode) { case MODE_LL: -GEN_HELPER_LL(mul_h, temp64, r2, r3, temp); +GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n); break; case MODE_LU: -GEN_HELPER_LU(mul_h, temp64, r2, r3, temp); +GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n); break; case MODE_UL: -GEN_HELPER_UL(mul_h, temp64, r2, r3, temp); +GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n); break; case MODE_UU: -GEN_HELPER_UU(mul_h, temp64, r2, r3, temp); +GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n); break; } tcg_gen_extr_i64_i32(temp, temp2, temp64); @@ -647,22 +649,22 @@ static inline void gen_maddsum_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3, uint32_t n, uint32_t mode) { -TCGv temp = tcg_const_i32(n); +TCGv t_n = tcg_constant_i32(n); TCGv_i64 temp64 = tcg_temp_new_i64(); TCGv_i64 temp64_2 = tcg_temp_new_i64(); TCGv_i64 temp64_3 = tcg_temp_new_i64(); switch (mode) { case MODE_LL: -GEN_HELPER_LL(mul_h, temp64, r2, r3, temp); +GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n); break; case MODE_LU: -GEN_HELPER_LU(mul_h, temp64, r2, r3, temp); +GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n); break; case MODE_UL: -GEN_HELPER_UL(mul_h, temp64, r2, r3, temp); +GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n); break; case MODE_UU: -GEN_HELPER_UU(mul_h, temp64, r2, r3, temp); +GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n); break; } tcg_gen_concat_i32_i64(temp64_3, r1_low, r1_high); @@ -682,23 +684,24 @@ static inline void gen_madds_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3, uint32_t n, uint32_t mode) { -TCGv temp = tcg_const_i32(n); +TCGv t_n = tcg_constant_i32(n); +TCGv temp = tcg_temp_new(); TCGv temp2 = tcg_temp_new(); TCGv temp3 = tcg_temp_new(); TCGv_i64 temp64 = tcg_temp_new_i64(); switch (mode) { case MODE_LL: -GEN_HELPER_LL(mul_h, temp64, r2, r3, temp); +GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n); break; case MODE_LU: -GEN_HELPER_LU(mul_h, temp64, r2, r3, temp); +GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n); break; case MODE_UL: -GEN_HELPER_UL(mul_h, temp64, r2, r3, temp); +GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n); break; case MODE_UU: -GEN_HELPER_UU(mul_h, temp64, r2, r3, temp); +GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n); break; } tcg_gen_extr_i64_i32(temp, temp2, temp64); @@ -718,23 +721,24 @@ static inline void gen_maddsus_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3, uint32_t n, uint32_t mode) { -TCGv temp = tcg_const_i32(n); +TCGv t_n = tcg_constant_i32(n); +TCGv temp = tcg_temp_new(); TCGv temp2 = tcg_temp_new(); TCGv temp3 = tcg_temp_new(); TCGv_i64 temp64 = tcg_temp_new_i64(); switch (mode) { case MODE_LL: -GEN_HELPER_LL(mul_h, temp64, r2, r3, temp); +GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n); break;
[PULL v2 72/91] target/arm: Create gen_set_rmode, gen_restore_rmode
Split out common subroutines for handing rounding mode changes during translation. Use tcg_constant_i32 and tcg_temp_new_i32 instead of tcg_const_i32. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/arm/tcg/translate.h | 17 target/arm/tcg/translate-a64.c | 47 ++ target/arm/tcg/translate-sve.c | 6 ++--- target/arm/tcg/translate-vfp.c | 26 --- 4 files changed, 48 insertions(+), 48 deletions(-) diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h index 20f3ca7aca..f02d4685b4 100644 --- a/target/arm/tcg/translate.h +++ b/target/arm/tcg/translate.h @@ -616,6 +616,23 @@ static inline TCGv_ptr gen_lookup_cp_reg(uint32_t key) return ret; } +/* + * Set and reset rounding mode around another operation. + */ +static inline TCGv_i32 gen_set_rmode(ARMFPRounding rmode, TCGv_ptr fpst) +{ +TCGv_i32 new = tcg_constant_i32(arm_rmode_to_sf(rmode)); +TCGv_i32 old = tcg_temp_new_i32(); + +gen_helper_set_rmode(old, new, fpst); +return old; +} + +static inline void gen_restore_rmode(TCGv_i32 old, TCGv_ptr fpst) +{ +gen_helper_set_rmode(old, old, fpst); +} + /* * Helpers for implementing sets of trans_* functions. * Defer the implementation of NAME to FUNC, with optional extra arguments. diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 210899ff79..989c958de6 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -6146,13 +6146,12 @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) case 0xb: /* FRINTZ */ case 0xc: /* FRINTA */ { -TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7)); +TCGv_i32 tcg_rmode; + fpst = fpstatus_ptr(FPST_FPCR_F16); - -gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst); +tcg_rmode = gen_set_rmode(opcode & 7, fpst); gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst); - -gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst); +gen_restore_rmode(tcg_rmode, fpst); break; } case 0xe: /* FRINTX */ @@ -6231,10 +6230,9 @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) fpst = fpstatus_ptr(FPST_FPCR); if (rmode >= 0) { -TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode)); -gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst); +TCGv_i32 tcg_rmode = gen_set_rmode(rmode, fpst); gen_fpst(tcg_res, tcg_op, fpst); -gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst); +gen_restore_rmode(tcg_rmode, fpst); } else { gen_fpst(tcg_res, tcg_op, fpst); } @@ -6304,10 +6302,9 @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) fpst = fpstatus_ptr(FPST_FPCR); if (rmode >= 0) { -TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode)); -gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst); +TCGv_i32 tcg_rmode = gen_set_rmode(rmode, fpst); gen_fpst(tcg_res, tcg_op, fpst); -gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst); +gen_restore_rmode(tcg_rmode, fpst); } else { gen_fpst(tcg_res, tcg_op, fpst); } @@ -6944,9 +6941,7 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode, rmode = FPROUNDING_TIEAWAY; } -tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode)); - -gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus); +tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus); switch (type) { case 1: /* float64 */ @@ -7023,7 +7018,7 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode, g_assert_not_reached(); } -gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus); +gen_restore_rmode(tcg_rmode, tcg_fpstatus); } } @@ -8771,9 +8766,8 @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar, assert(!(is_scalar && is_q)); -tcg_rmode = tcg_const_i32(arm_rmode_to_sf(FPROUNDING_ZERO)); tcg_fpstatus = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); -gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus); +tcg_rmode = gen_set_rmode(FPROUNDING_ZERO, tcg_fpstatus); fracbits = (16 << size) - immhb; tcg_shift = tcg_constant_i32(fracbits); @@ -8831,7 +8825,7 @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar, } } -gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus); +gen_restore_rmode(tcg_rmode, tcg_fpstatus); } /* AdvSIMD scalar shift by immediate @@ -10219,12 +10213,11 @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) } if (is_fcvt) { -tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode)); tcg_fpstatus = fpstatus_ptr(FPST_FPCR); -
[PULL v2 66/91] target/tricore: Avoid tcg_const_i32
All remaining uses are strictly read-only. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/tricore/translate.c | 127 +++-- 1 file changed, 64 insertions(+), 63 deletions(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 4e3e648049..a3a5263a5d 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -124,7 +124,7 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f, int flags) /* Makros for generating helpers */ #define gen_helper_1arg(name, arg) do { \ -TCGv_i32 helper_tmp = tcg_const_i32(arg); \ +TCGv_i32 helper_tmp = tcg_constant_i32(arg); \ gen_helper_##name(cpu_env, helper_tmp); \ } while (0) @@ -513,7 +513,7 @@ static inline void gen_madd32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3) static inline void gen_maddi32_d(TCGv ret, TCGv r1, TCGv r2, int32_t con) { -TCGv temp = tcg_const_i32(con); +TCGv temp = tcg_constant_i32(con); gen_madd32_d(ret, r1, r2, temp); } @@ -579,7 +579,7 @@ static inline void gen_maddi64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high, int32_t con) { -TCGv temp = tcg_const_i32(con); +TCGv temp = tcg_constant_i32(con); gen_madd64_d(ret_low, ret_high, r1, r2_low, r2_high, temp); } @@ -587,7 +587,7 @@ static inline void gen_maddui64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high, int32_t con) { -TCGv temp = tcg_const_i32(con); +TCGv temp = tcg_constant_i32(con); gen_maddu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp); } @@ -1224,7 +1224,7 @@ static inline void gen_msub32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3) static inline void gen_msubi32_d(TCGv ret, TCGv r1, TCGv r2, int32_t con) { -TCGv temp = tcg_const_i32(con); +TCGv temp = tcg_constant_i32(con); gen_msub32_d(ret, r1, r2, temp); } @@ -1260,7 +1260,7 @@ static inline void gen_msubi64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high, int32_t con) { -TCGv temp = tcg_const_i32(con); +TCGv temp = tcg_constant_i32(con); gen_msub64_d(ret_low, ret_high, r1, r2_low, r2_high, temp); } @@ -1296,13 +1296,13 @@ static inline void gen_msubui64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high, int32_t con) { -TCGv temp = tcg_const_i32(con); +TCGv temp = tcg_constant_i32(con); gen_msubu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp); } static inline void gen_addi_d(TCGv ret, TCGv r1, target_ulong r2) { -TCGv temp = tcg_const_i32(r2); +TCGv temp = tcg_constant_i32(r2); gen_add_d(ret, r1, temp); } @@ -1332,7 +1332,7 @@ static inline void gen_add_CC(TCGv ret, TCGv r1, TCGv r2) static inline void gen_addi_CC(TCGv ret, TCGv r1, int32_t con) { -TCGv temp = tcg_const_i32(con); +TCGv temp = tcg_constant_i32(con); gen_add_CC(ret, r1, temp); } @@ -1364,7 +1364,7 @@ static inline void gen_addc_CC(TCGv ret, TCGv r1, TCGv r2) static inline void gen_addci_CC(TCGv ret, TCGv r1, int32_t con) { -TCGv temp = tcg_const_i32(con); +TCGv temp = tcg_constant_i32(con); gen_addc_CC(ret, r1, temp); } @@ -1375,7 +1375,7 @@ static inline void gen_cond_add(TCGCond cond, TCGv r1, TCGv r2, TCGv r3, TCGv temp2 = tcg_temp_new(); TCGv result = tcg_temp_new(); TCGv mask = tcg_temp_new(); -TCGv t0 = tcg_const_i32(0); +TCGv t0 = tcg_constant_i32(0); /* create mask for sticky bits */ tcg_gen_setcond_tl(cond, mask, r4, t0); @@ -1404,7 +1404,7 @@ static inline void gen_cond_add(TCGCond cond, TCGv r1, TCGv r2, TCGv r3, static inline void gen_condi_add(TCGCond cond, TCGv r1, int32_t r2, TCGv r3, TCGv r4) { -TCGv temp = tcg_const_i32(r2); +TCGv temp = tcg_constant_i32(r2); gen_cond_add(cond, r1, temp, r3, r4); } @@ -1492,7 +1492,7 @@ static inline void gen_cond_sub(TCGCond cond, TCGv r1, TCGv r2, TCGv r3, TCGv temp2 = tcg_temp_new(); TCGv result = tcg_temp_new(); TCGv mask = tcg_temp_new(); -TCGv t0 = tcg_const_i32(0); +TCGv t0 = tcg_constant_i32(0); /* create mask for sticky bits */ tcg_gen_setcond_tl(cond, mask, r4, t0); @@ -1705,14 +1705,14 @@ gen_msubr32s_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode) static inline void gen_msubr_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n) { -TCGv temp = tcg_const_i32(n); +TCGv temp = tcg_constant_i32(n); gen_helper_msubr_q(ret, cpu_env, r1, r2, r3, temp); } static inline void gen_msubrs_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n) { -TCGv temp = tcg_const_i32(n); +TCGv temp = tcg_constant_i32(n); gen_helper_msubr_q_ssov(ret, cpu_env, r1, r2, r3, temp); } @@ -2149,13 +2149,13 @@ static inline void gen_absdif(TCGv ret, TCGv r1,
[PULL v2 41/91] target/cris: Avoid use of tcg_const_i32 throughout
All remaining uses are strictly read-only. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/cris/translate.c | 46 +++-- target/cris/translate_v10.c.inc | 26 +-- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/target/cris/translate.c b/target/cris/translate.c index 5172c9b9b2..b2beb9964d 100644 --- a/target/cris/translate.c +++ b/target/cris/translate.c @@ -175,10 +175,7 @@ static const int preg_sizes[] = { #define t_gen_mov_env_TN(member, tn) \ tcg_gen_st_tl(tn, cpu_env, offsetof(CPUCRISState, member)) #define t_gen_movi_env_TN(member, c) \ -do { \ -TCGv tc = tcg_const_tl(c); \ -t_gen_mov_env_TN(member, tc); \ -} while (0) +t_gen_mov_env_TN(member, tcg_constant_tl(c)) static inline void t_gen_mov_TN_preg(TCGv tn, int r) { @@ -268,8 +265,7 @@ static void cris_lock_irq(DisasContext *dc) static inline void t_gen_raise_exception(uint32_t index) { -TCGv_i32 tmp = tcg_const_i32(index); -gen_helper_raise_exception(cpu_env, tmp); +gen_helper_raise_exception(cpu_env, tcg_constant_i32(index)); } static void t_gen_lsl(TCGv d, TCGv a, TCGv b) @@ -277,7 +273,7 @@ static void t_gen_lsl(TCGv d, TCGv a, TCGv b) TCGv t0, t_31; t0 = tcg_temp_new(); -t_31 = tcg_const_tl(31); +t_31 = tcg_constant_tl(31); tcg_gen_shl_tl(d, a, b); tcg_gen_sub_tl(t0, t_31, b); @@ -1250,7 +1246,7 @@ static int dec_addq(CPUCRISState *env, DisasContext *dc) cris_cc_mask(dc, CC_MASK_NZVC); -c = tcg_const_tl(dc->op1); +c = tcg_constant_tl(dc->op1); cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], c, 4); return 2; @@ -1274,7 +1270,7 @@ static int dec_subq(CPUCRISState *env, DisasContext *dc) LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2); cris_cc_mask(dc, CC_MASK_NZVC); -c = tcg_const_tl(dc->op1); +c = tcg_constant_tl(dc->op1); cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], c, 4); return 2; @@ -1289,7 +1285,7 @@ static int dec_cmpq(CPUCRISState *env, DisasContext *dc) LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2); cris_cc_mask(dc, CC_MASK_NZVC); -c = tcg_const_tl(imm); +c = tcg_constant_tl(imm); cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], c, 4); return 2; @@ -1304,7 +1300,7 @@ static int dec_andq(CPUCRISState *env, DisasContext *dc) LOG_DIS("andq %d, $r%d\n", imm, dc->op2); cris_cc_mask(dc, CC_MASK_NZ); -c = tcg_const_tl(imm); +c = tcg_constant_tl(imm); cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], cpu_R[dc->op2], c, 4); return 2; @@ -1318,7 +1314,7 @@ static int dec_orq(CPUCRISState *env, DisasContext *dc) LOG_DIS("orq %d, $r%d\n", imm, dc->op2); cris_cc_mask(dc, CC_MASK_NZ); -c = tcg_const_tl(imm); +c = tcg_constant_tl(imm); cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], cpu_R[dc->op2], c, 4); return 2; @@ -1330,7 +1326,7 @@ static int dec_btstq(CPUCRISState *env, DisasContext *dc) LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2); cris_cc_mask(dc, CC_MASK_NZ); -c = tcg_const_tl(dc->op1); +c = tcg_constant_tl(dc->op1); cris_evaluate_flags(dc); gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2], c, cpu_PR[PR_CCS]); @@ -1945,8 +1941,8 @@ static int dec_move_rs(CPUCRISState *env, DisasContext *dc) { TCGv c2, c1; LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2); -c1 = tcg_const_tl(dc->op1); -c2 = tcg_const_tl(dc->op2); +c1 = tcg_constant_tl(dc->op1); +c2 = tcg_constant_tl(dc->op2); cris_cc_mask(dc, 0); gen_helper_movl_sreg_reg(cpu_env, c2, c1); return 2; @@ -1955,8 +1951,8 @@ static int dec_move_sr(CPUCRISState *env, DisasContext *dc) { TCGv c2, c1; LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1); -c1 = tcg_const_tl(dc->op1); -c2 = tcg_const_tl(dc->op2); +c1 = tcg_constant_tl(dc->op1); +c2 = tcg_constant_tl(dc->op2); cris_cc_mask(dc, 0); gen_helper_movl_reg_sreg(cpu_env, c1, c2); return 2; @@ -2237,7 +2233,7 @@ static int dec_test_m(CPUCRISState *env, DisasContext *dc) cris_cc_mask(dc, CC_MASK_NZ); tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3); -c = tcg_const_tl(0); +c = tcg_constant_tl(0); cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[1], c, memsize_zz(dc)); do_postinc(dc, memsize); @@ -2582,7 +2578,7 @@ static int dec_jas_r(CPUCRISState *env, DisasContext *dc) if (dc->op2 > 15) { abort(); } -c = tcg_const_tl(dc->pc + 4); +c = tcg_constant_tl(dc->pc + 4); t_gen_mov_preg_TN(dc, dc->op2, c); cris_prepare_jmp(dc, JMP_INDIRECT); @@ -2598,7 +2594,7 @@ static int dec_jas_im(CPUCRISState *env, DisasContext *dc) LOG_DIS("jas 0x%x\n", imm); cris_cc_mask(dc, 0); -c = tcg_const_tl(dc->pc + 8); +c = tcg_constant_tl(dc->pc +
[PATCH v8 08/11] tests/qtest: Fix tests when no KVM or TCG are present
It is possible to have a build with both TCG and KVM disabled due to Xen requiring the i386 and x86_64 binaries to be present in an aarch64 host. If we build with --disable-tcg on the aarch64 host, we will end-up with a QEMU binary (x86) that does not support TCG nor KVM. Fix tests that crash or hang in the above scenario. Do not include any test cases if TCG and KVM are missing. Make sure that calls to qtest_has_accel are placed after g_test_init in similar fashion to commit ae4b01b349 ("tests: Ensure TAP version is printed before other messages") to avoid TAP parsing errors. Signed-off-by: Fabiano Rosas Reviewed-by: Juan Quintela --- This currently affects Arm, but will also affect x86 after the xenpvh series gets merged. This patch fixes both scenarios. --- tests/qtest/bios-tables-test.c | 10 -- tests/qtest/boot-serial-test.c | 10 ++ tests/qtest/migration-test.c | 9 - tests/qtest/pxe-test.c | 7 ++- tests/qtest/vmgenid-test.c | 8 ++-- 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c index d29a4e47af..5cbad2f29f 100644 --- a/tests/qtest/bios-tables-test.c +++ b/tests/qtest/bios-tables-test.c @@ -2109,8 +2109,7 @@ static void test_acpi_virt_oem_fields(void) int main(int argc, char *argv[]) { const char *arch = qtest_get_arch(); -const bool has_kvm = qtest_has_accel("kvm"); -const bool has_tcg = qtest_has_accel("tcg"); +bool has_kvm, has_tcg; char *v_env = getenv("V"); int ret; @@ -2120,6 +2119,13 @@ int main(int argc, char *argv[]) g_test_init(, , NULL); +has_kvm = qtest_has_accel("kvm"); +has_tcg = qtest_has_accel("tcg"); + +if (!has_tcg && !has_kvm) { +return 0; +} + if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { ret = boot_sector_init(disk); if (ret) { diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c index 3aef3a97a9..406b4421cc 100644 --- a/tests/qtest/boot-serial-test.c +++ b/tests/qtest/boot-serial-test.c @@ -17,6 +17,9 @@ #include "libqtest.h" #include "libqos/libqos-spapr.h" +static bool has_tcg; +static bool has_kvm; + static const uint8_t bios_avr[] = { 0x88, 0xe0, /* ldi r24, 0x08 */ 0x80, 0x93, 0xc1, 0x00, /* sts 0x00C1, r24 ; Enable tx */ @@ -287,6 +290,13 @@ int main(int argc, char *argv[]) g_test_init(, , NULL); +has_tcg = qtest_has_accel("tcg"); +has_kvm = qtest_has_accel("kvm"); + +if (!has_tcg && !has_kvm) { +return 0; +} + for (i = 0; tests[i].arch != NULL; i++) { if (g_str_equal(arch, tests[i].arch) && qtest_has_machine(tests[i].machine)) { diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index d4ab3934ed..7eedee7b2d 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -2459,7 +2459,7 @@ static bool kvm_dirty_ring_supported(void) int main(int argc, char **argv) { -const bool has_kvm = qtest_has_accel("kvm"); +bool has_kvm, has_tcg; const bool has_uffd = ufd_version_check(); const char *arch = qtest_get_arch(); g_autoptr(GError) err = NULL; @@ -2467,6 +2467,13 @@ int main(int argc, char **argv) g_test_init(, , NULL); +has_kvm = qtest_has_accel("kvm"); +has_tcg = qtest_has_accel("tcg"); + +if (!has_tcg && !has_kvm) { +return 0; +} + /* * On ppc64, the test only works with kvm-hv, but not with kvm-pr and TCG * is touchy due to race conditions on dirty bits (especially on PPC for diff --git a/tests/qtest/pxe-test.c b/tests/qtest/pxe-test.c index 62b6eef464..935b661dac 100644 --- a/tests/qtest/pxe-test.c +++ b/tests/qtest/pxe-test.c @@ -131,11 +131,16 @@ int main(int argc, char *argv[]) int ret; const char *arch = qtest_get_arch(); +g_test_init(, , NULL); + +if (!qtest_has_accel("tcg") && !qtest_has_accel("kvm")) { +return 0; +} + ret = boot_sector_init(disk); if(ret) return ret; -g_test_init(, , NULL); if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { test_batch(x86_tests, false); diff --git a/tests/qtest/vmgenid-test.c b/tests/qtest/vmgenid-test.c index efba76e716..9eb6371ae8 100644 --- a/tests/qtest/vmgenid-test.c +++ b/tests/qtest/vmgenid-test.c @@ -165,13 +165,17 @@ int main(int argc, char **argv) { int ret; +g_test_init(, , NULL); + +if (!qtest_has_accel("tcg") && !qtest_has_accel("kvm")) { +return 0; +} + ret = boot_sector_init(disk); if (ret) { return ret; } -g_test_init(, , NULL); - qtest_add_func("/vmgenid/vmgenid/set-guid", vmgenid_set_guid_test); qtest_add_func("/vmgenid/vmgenid/set-guid-auto", -- 2.35.3
[PULL v2 85/91] target/ppc: Avoid tcg_const_* in power8-pmu-regs.c.inc
All uses are strictly read-only. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Daniel Henrique Barboza Signed-off-by: Richard Henderson --- target/ppc/power8-pmu-regs.c.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc index 42f2cd04a1..d900e13cad 100644 --- a/target/ppc/power8-pmu-regs.c.inc +++ b/target/ppc/power8-pmu-regs.c.inc @@ -177,7 +177,7 @@ void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int gprn) void spr_read_PMC(DisasContext *ctx, int gprn, int sprn) { -TCGv_i32 t_sprn = tcg_const_i32(sprn); +TCGv_i32 t_sprn = tcg_constant_i32(sprn); gen_icount_io_start(ctx); gen_helper_read_pmc(cpu_gpr[gprn], cpu_env, t_sprn); @@ -210,7 +210,7 @@ void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int sprn) void spr_write_PMC(DisasContext *ctx, int sprn, int gprn) { -TCGv_i32 t_sprn = tcg_const_i32(sprn); +TCGv_i32 t_sprn = tcg_constant_i32(sprn); gen_icount_io_start(ctx); gen_helper_store_pmc(cpu_env, t_sprn, cpu_gpr[gprn]); -- 2.34.1
[PULL v2 58/91] target/s390x: Avoid tcg_const_i64
All uses are strictly read-only. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/s390x/tcg/translate.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index 7969051ce9..32d61fc40d 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -4857,13 +4857,13 @@ static DisasJumpType op_xi(DisasContext *s, DisasOps *o) static DisasJumpType op_zero(DisasContext *s, DisasOps *o) { -o->out = tcg_const_i64(0); +o->out = tcg_constant_i64(0); return DISAS_NEXT; } static DisasJumpType op_zero2(DisasContext *s, DisasOps *o) { -o->out = tcg_const_i64(0); +o->out = tcg_constant_i64(0); o->out2 = o->out; return DISAS_NEXT; } @@ -5762,7 +5762,7 @@ static void in2_sh(DisasContext *s, DisasOps *o) int d2 = get_field(s, d2); if (b2 == 0) { -o->in2 = tcg_const_i64(d2 & 0x3f); +o->in2 = tcg_constant_i64(d2 & 0x3f); } else { o->in2 = get_address(s, 0, b2, d2); tcg_gen_andi_i64(o->in2, o->in2, 0x3f); @@ -5868,46 +5868,46 @@ static void in2_mri2_64(DisasContext *s, DisasOps *o) static void in2_i2(DisasContext *s, DisasOps *o) { -o->in2 = tcg_const_i64(get_field(s, i2)); +o->in2 = tcg_constant_i64(get_field(s, i2)); } #define SPEC_in2_i2 0 static void in2_i2_8u(DisasContext *s, DisasOps *o) { -o->in2 = tcg_const_i64((uint8_t)get_field(s, i2)); +o->in2 = tcg_constant_i64((uint8_t)get_field(s, i2)); } #define SPEC_in2_i2_8u 0 static void in2_i2_16u(DisasContext *s, DisasOps *o) { -o->in2 = tcg_const_i64((uint16_t)get_field(s, i2)); +o->in2 = tcg_constant_i64((uint16_t)get_field(s, i2)); } #define SPEC_in2_i2_16u 0 static void in2_i2_32u(DisasContext *s, DisasOps *o) { -o->in2 = tcg_const_i64((uint32_t)get_field(s, i2)); +o->in2 = tcg_constant_i64((uint32_t)get_field(s, i2)); } #define SPEC_in2_i2_32u 0 static void in2_i2_16u_shl(DisasContext *s, DisasOps *o) { uint64_t i2 = (uint16_t)get_field(s, i2); -o->in2 = tcg_const_i64(i2 << s->insn->data); +o->in2 = tcg_constant_i64(i2 << s->insn->data); } #define SPEC_in2_i2_16u_shl 0 static void in2_i2_32u_shl(DisasContext *s, DisasOps *o) { uint64_t i2 = (uint32_t)get_field(s, i2); -o->in2 = tcg_const_i64(i2 << s->insn->data); +o->in2 = tcg_constant_i64(i2 << s->insn->data); } #define SPEC_in2_i2_32u_shl 0 #ifndef CONFIG_USER_ONLY static void in2_insn(DisasContext *s, DisasOps *o) { -o->in2 = tcg_const_i64(s->fields.raw_insn); +o->in2 = tcg_constant_i64(s->fields.raw_insn); } #define SPEC_in2_insn 0 #endif -- 2.34.1
[PULL v2 44/91] target/i386: Avoid use of tcg_const_* throughout
All uses are strictly read-only. Most of the obviously so, as direct arguments to gen_helper_*. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/i386/tcg/translate.c | 83 +++-- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index fa422ebd0b..9dfad2f7bc 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -884,7 +884,7 @@ static void gen_compute_eflags(DisasContext *s) live = cc_op_live[s->cc_op] & ~USES_CC_SRCT; dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2); if (dead) { -zero = tcg_const_tl(0); +zero = tcg_constant_tl(0); if (dead & USES_CC_DST) { dst = zero; } @@ -1412,7 +1412,7 @@ static void gen_helper_fp_arith_ST0_FT0(int op) /* NOTE the exception in "r" op ordering */ static void gen_helper_fp_arith_STN_ST0(int op, int opreg) { -TCGv_i32 tmp = tcg_const_i32(opreg); +TCGv_i32 tmp = tcg_constant_i32(opreg); switch (op) { case 0: gen_helper_fadd_STN_ST0(cpu_env, tmp); @@ -1439,7 +1439,7 @@ static void gen_exception(DisasContext *s, int trapno) { gen_update_cc_op(s); gen_update_eip_cur(s); -gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno)); +gen_helper_raise_exception(cpu_env, tcg_constant_i32(trapno)); s->base.is_jmp = DISAS_NORETURN; } @@ -1633,7 +1633,7 @@ static void gen_shift_flags(DisasContext *s, MemOp ot, TCGv result, /* Store the results into the CC variables. If we know that the variable must be dead, store unconditionally. Otherwise we'll need to not disrupt the current contents. */ -z_tl = tcg_const_tl(0); +z_tl = tcg_constant_tl(0); if (cc_op_live[s->cc_op] & USES_CC_DST) { tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl, result, cpu_cc_dst); @@ -1657,7 +1657,7 @@ static void gen_shift_flags(DisasContext *s, MemOp ot, TCGv result, } /* Conditionally store the CC_OP value. */ -z32 = tcg_const_i32(0); +z32 = tcg_constant_i32(0); s32 = tcg_temp_new_i32(); tcg_gen_trunc_tl_i32(s32, count); tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, s->tmp2_i32, oldop); @@ -1813,7 +1813,7 @@ static void gen_rot_rm_T1(DisasContext *s, MemOp ot, int op1, int is_right) is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live. Otherwise reuse CC_OP_ADCOX which have the C and O flags split out exactly as we computed above. */ -t0 = tcg_const_i32(0); +t0 = tcg_constant_i32(0); t1 = tcg_temp_new_i32(); tcg_gen_trunc_tl_i32(t1, s->T1); tcg_gen_movi_i32(s->tmp2_i32, CC_OP_ADCOX); @@ -2497,7 +2497,7 @@ static void gen_cmovcc1(CPUX86State *env, DisasContext *s, MemOp ot, int b, cc.reg = t0; } if (!cc.use_reg2) { -cc.reg2 = tcg_const_tl(cc.imm); +cc.reg2 = tcg_constant_tl(cc.imm); } tcg_gen_movcond_tl(cc.cond, s->T0, cc.reg, cc.reg2, @@ -2525,7 +2525,7 @@ static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg) { if (PE(s) && !VM86(s)) { tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); -gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), s->tmp2_i32); +gen_helper_load_seg(cpu_env, tcg_constant_i32(seg_reg), s->tmp2_i32); /* abort translation because the addseg value may change or because ss32 may change. For R_SS, translation must always stop as a special handling must be done to disable hardware @@ -4344,7 +4344,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) gen_op_mov_v_reg(s, ot, s->T1, reg); if (shift) { -TCGv imm = tcg_const_tl(x86_ldub_code(env, s)); +TCGv imm = tcg_constant_tl(x86_ldub_code(env, s)); gen_shiftd_rm_T1(s, ot, opreg, op, imm); } else { gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]); @@ -4503,7 +4503,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) break; case 0x0c: /* fldenv mem */ gen_helper_fldenv(cpu_env, s->A0, - tcg_const_i32(dflag - 1)); + tcg_constant_i32(dflag - 1)); update_fip = update_fdp = false; break; case 0x0d: /* fldcw mem */ @@ -4514,7 +4514,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) break; case 0x0e: /* fnstenv mem */ gen_helper_fstenv(cpu_env, s->A0, - tcg_const_i32(dflag - 1)); + tcg_constant_i32(dflag - 1)); update_fip = update_fdp = false; break; case 0x0f: /* fnstcw mem */ @@ -4532,12
[PULL v2 90/91] tcg: Drop tcg_const_*_vec
Replace with tcg_constant_vec*. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- include/tcg/tcg.h | 4 tcg/tcg-op-vec.c | 34 ++ tcg/i386/tcg-target.c.inc | 9 - 3 files changed, 6 insertions(+), 41 deletions(-) diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index 00c4fbe613..d620012c48 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -999,10 +999,6 @@ void tcg_optimize(TCGContext *s); /* Allocate a new temporary and initialize it with a constant. */ TCGv_i32 tcg_const_i32(int32_t val); TCGv_i64 tcg_const_i64(int64_t val); -TCGv_vec tcg_const_zeros_vec(TCGType); -TCGv_vec tcg_const_ones_vec(TCGType); -TCGv_vec tcg_const_zeros_vec_matching(TCGv_vec); -TCGv_vec tcg_const_ones_vec_matching(TCGv_vec); /* * Locate or create a read-only temporary that is a constant. diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 0f023f42c6..aeeb2435cb 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -229,32 +229,6 @@ void tcg_gen_mov_vec(TCGv_vec r, TCGv_vec a) } } -TCGv_vec tcg_const_zeros_vec(TCGType type) -{ -TCGv_vec ret = tcg_temp_new_vec(type); -tcg_gen_dupi_vec(MO_64, ret, 0); -return ret; -} - -TCGv_vec tcg_const_ones_vec(TCGType type) -{ -TCGv_vec ret = tcg_temp_new_vec(type); -tcg_gen_dupi_vec(MO_64, ret, -1); -return ret; -} - -TCGv_vec tcg_const_zeros_vec_matching(TCGv_vec m) -{ -TCGTemp *t = tcgv_vec_temp(m); -return tcg_const_zeros_vec(t->base_type); -} - -TCGv_vec tcg_const_ones_vec_matching(TCGv_vec m) -{ -TCGTemp *t = tcgv_vec_temp(m); -return tcg_const_ones_vec(t->base_type); -} - void tcg_gen_dupi_vec(unsigned vece, TCGv_vec r, uint64_t a) { TCGTemp *rt = tcgv_vec_temp(r); @@ -431,9 +405,7 @@ void tcg_gen_not_vec(unsigned vece, TCGv_vec r, TCGv_vec a) const TCGOpcode *hold_list = tcg_swap_vecop_list(NULL); if (!TCG_TARGET_HAS_not_vec || !do_op2(vece, r, a, INDEX_op_not_vec)) { -TCGv_vec t = tcg_const_ones_vec_matching(r); -tcg_gen_xor_vec(0, r, a, t); -tcg_temp_free_vec(t); +tcg_gen_xor_vec(0, r, a, tcg_constant_vec_matching(r, 0, -1)); } tcg_swap_vecop_list(hold_list); } @@ -446,9 +418,7 @@ void tcg_gen_neg_vec(unsigned vece, TCGv_vec r, TCGv_vec a) hold_list = tcg_swap_vecop_list(NULL); if (!TCG_TARGET_HAS_neg_vec || !do_op2(vece, r, a, INDEX_op_neg_vec)) { -TCGv_vec t = tcg_const_zeros_vec_matching(r); -tcg_gen_sub_vec(vece, r, t, a); -tcg_temp_free_vec(t); +tcg_gen_sub_vec(vece, r, tcg_constant_vec_matching(r, vece, 0), a); } tcg_swap_vecop_list(hold_list); } diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index 4060a35cf6..eb9234 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -3651,6 +3651,7 @@ static void expand_vec_sari(TCGType type, unsigned vece, break; case MO_64: +t1 = tcg_temp_new_vec(type); if (imm <= 32) { /* * We can emulate a small sign extend by performing an arithmetic @@ -3659,24 +3660,22 @@ static void expand_vec_sari(TCGType type, unsigned vece, * 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, 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), tcgv_vec_arg(t1), 0xaa); -tcg_temp_free_vec(t1); } else { /* Otherwise we will need to use a compare vs 0 to produce * the sign-extend, shift and merge. */ -t1 = tcg_const_zeros_vec(type); -tcg_gen_cmp_vec(TCG_COND_GT, MO_64, t1, t1, v1); +tcg_gen_cmp_vec(TCG_COND_GT, MO_64, t1, +tcg_constant_vec(type, MO_64, 0), v1); tcg_gen_shri_vec(MO_64, v0, v1, imm); tcg_gen_shli_vec(MO_64, t1, t1, 64 - imm); tcg_gen_or_vec(MO_64, v0, v0, t1); -tcg_temp_free_vec(t1); } +tcg_temp_free_vec(t1); break; default: -- 2.34.1
[PULL v2 67/91] tcg: Replace tcg_const_i64 in tcg-op.c
These three instances got missed in previous conversion. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/tcg-op.c | 12 +++- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index 1a039a292c..ddab20a6a6 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -1563,9 +1563,7 @@ void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) } else if (is_power_of_2(arg2)) { tcg_gen_shli_i64(ret, arg1, ctz64(arg2)); } else { -TCGv_i64 t0 = tcg_const_i64(arg2); -tcg_gen_mul_i64(ret, arg1, t0); -tcg_temp_free_i64(t0); +tcg_gen_mul_i64(ret, arg1, tcg_constant_i64(arg2)); } } @@ -1962,9 +1960,7 @@ void tcg_gen_clzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2) tcg_gen_movi_i32(TCGV_HIGH(ret), 0); tcg_temp_free_i32(t); } else { -TCGv_i64 t0 = tcg_const_i64(arg2); -tcg_gen_clz_i64(ret, arg1, t0); -tcg_temp_free_i64(t0); +tcg_gen_clz_i64(ret, arg1, tcg_constant_i64(arg2)); } } @@ -2016,9 +2012,7 @@ void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2) tcg_gen_ctpop_i64(ret, t); tcg_temp_free_i64(t); } else { -TCGv_i64 t0 = tcg_const_i64(arg2); -tcg_gen_ctz_i64(ret, arg1, t0); -tcg_temp_free_i64(t0); +tcg_gen_ctz_i64(ret, arg1, tcg_constant_i64(arg2)); } } -- 2.34.1
[PULL v2 54/91] target/rx: Use tcg_gen_abs_i32
Remove the local definition of rx_abs. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/rx/translate.c | 12 +--- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/target/rx/translate.c b/target/rx/translate.c index 6624414739..998e6e0b7e 100644 --- a/target/rx/translate.c +++ b/target/rx/translate.c @@ -1126,21 +1126,11 @@ static bool trans_SBB_mr(DisasContext *ctx, arg_SBB_mr *a) return true; } -static void rx_abs(TCGv ret, TCGv arg1) -{ -TCGv neg; -TCGv zero; -neg = tcg_temp_new(); -zero = tcg_const_i32(0); -tcg_gen_neg_i32(neg, arg1); -tcg_gen_movcond_i32(TCG_COND_LT, ret, arg1, zero, neg, arg1); -} - /* abs rd */ /* abs rs, rd */ static bool trans_ABS_rr(DisasContext *ctx, arg_ABS_rr *a) { -rx_gen_op_rr(rx_abs, a->rd, a->rs); +rx_gen_op_rr(tcg_gen_abs_i32, a->rd, a->rs); return true; } -- 2.34.1
[PULL v2 80/91] target/ppc: Avoid tcg_const_i64 in do_vcntmb
Compute both partial results separately and accumulate at the end, instead of accumulating in the middle. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Daniel Henrique Barboza Signed-off-by: Richard Henderson --- target/ppc/translate/vmx-impl.c.inc | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index 7af6d7217d..ca27c11d87 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -2236,24 +2236,25 @@ static bool trans_MTVSRBMI(DisasContext *ctx, arg_DX_b *a) static bool do_vcntmb(DisasContext *ctx, arg_VX_mp *a, int vece) { -TCGv_i64 rt, vrb, mask; -rt = tcg_const_i64(0); -vrb = tcg_temp_new_i64(); +TCGv_i64 r[2], mask; + +r[0] = tcg_temp_new_i64(); +r[1] = tcg_temp_new_i64(); mask = tcg_constant_i64(dup_const(vece, 1ULL << ((8 << vece) - 1))); for (int i = 0; i < 2; i++) { -get_avr64(vrb, a->vrb, i); +get_avr64(r[i], a->vrb, i); if (a->mp) { -tcg_gen_and_i64(vrb, mask, vrb); +tcg_gen_and_i64(r[i], mask, r[i]); } else { -tcg_gen_andc_i64(vrb, mask, vrb); +tcg_gen_andc_i64(r[i], mask, r[i]); } -tcg_gen_ctpop_i64(vrb, vrb); -tcg_gen_add_i64(rt, rt, vrb); +tcg_gen_ctpop_i64(r[i], r[i]); } -tcg_gen_shli_i64(rt, rt, TARGET_LONG_BITS - 8 + vece); -tcg_gen_trunc_i64_tl(cpu_gpr[a->rt], rt); +tcg_gen_add_i64(r[0], r[0], r[1]); +tcg_gen_shli_i64(r[0], r[0], TARGET_LONG_BITS - 8 + vece); +tcg_gen_trunc_i64_tl(cpu_gpr[a->rt], r[0]); return true; } -- 2.34.1
[PULL v2 09/91] target/mips: Drop tcg_temp_free from translate.c
Translators are no longer required to free tcg temporaries. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/mips/tcg/translate.c | 537 +--- 1 file changed, 14 insertions(+), 523 deletions(-) diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index 24993bc97d..0fa9634d39 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -1274,11 +1274,8 @@ static inline void gen_load_srsgpr(int from, int to) tcg_gen_add_ptr(addr, cpu_env, addr); tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); -tcg_temp_free_ptr(addr); -tcg_temp_free_i32(t2); } gen_store_gpr(t0, to); -tcg_temp_free(t0); } static inline void gen_store_srsgpr(int from, int to) @@ -1297,9 +1294,6 @@ static inline void gen_store_srsgpr(int from, int to) tcg_gen_add_ptr(addr, cpu_env, addr); tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); -tcg_temp_free_ptr(addr); -tcg_temp_free_i32(t2); -tcg_temp_free(t0); } } @@ -1396,7 +1390,6 @@ void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) t64 = tcg_temp_new_i64(); tcg_gen_extu_i32_i64(t64, t); tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); -tcg_temp_free_i64(t64); } static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) @@ -1414,7 +1407,6 @@ static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) TCGv_i64 t64 = tcg_temp_new_i64(); tcg_gen_extu_i32_i64(t64, t); tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); -tcg_temp_free_i64(t64); } else { gen_store_fpr32(ctx, t, reg | 1); } @@ -1439,7 +1431,6 @@ void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) t0 = tcg_temp_new_i64(); tcg_gen_shri_i64(t0, t, 32); tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); -tcg_temp_free_i64(t0); } } @@ -1852,8 +1843,6 @@ static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ default: \ abort(); \ } \ -tcg_temp_free_i##bits(fp0); \ -tcg_temp_free_i##bits(fp1); \ } FOP_CONDS(, 0, d, FMT_D, 64) @@ -1946,8 +1935,6 @@ static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ abort();\ } \ STORE; \ -tcg_temp_free_i ## bits(fp0); \ -tcg_temp_free_i ## bits(fp1); \ } FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) @@ -1967,7 +1954,6 @@ static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));\ tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));\ -tcg_temp_free(t0); \ } #else #define OP_LD_ATOMIC(insn, fname) \ @@ -2065,9 +2051,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, tcg_gen_shl_tl(t2, t2, t1); gen_load_gpr(t1, rt); tcg_gen_andc_tl(t1, t1, t2); -tcg_temp_free(t2); tcg_gen_or_tl(t0, t0, t1); -tcg_temp_free(t1); gen_store_gpr(t0, rt); break; case OPC_LDR: @@ -2090,15 +2074,12 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, tcg_gen_shl_tl(t2, t2, t1); gen_load_gpr(t1, rt); tcg_gen_and_tl(t1, t1, t2); -tcg_temp_free(t2); tcg_gen_or_tl(t0, t0, t1); -tcg_temp_free(t1); gen_store_gpr(t0, rt); break; case OPC_LDPC: t1 = tcg_const_tl(pc_relative_pc(ctx)); gen_op_addr_add(ctx, t0, t0, t1); -tcg_temp_free(t1); tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); gen_store_gpr(t0, rt); break; @@ -2106,7 +2087,6 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, case OPC_LWPC: t1 = tcg_const_tl(pc_relative_pc(ctx)); gen_op_addr_add(ctx, t0, t0, t1); -tcg_temp_free(t1); tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL); gen_store_gpr(t0, rt); break; @@ -2170,9 +2150,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, tcg_gen_shl_tl(t2, t2, t1); gen_load_gpr(t1, rt);
[PULL v2 31/91] target/riscv: Remove `NB_MMU_MODES` define
From: Anton Johansson Signed-off-by: Anton Johansson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alex Bennée Reviewed-by: Richard Henderson Message-Id: <20230306175230.7110-17-a...@rev.ng> Signed-off-by: Richard Henderson --- target/riscv/cpu-param.h | 1 - 1 file changed, 1 deletion(-) diff --git a/target/riscv/cpu-param.h b/target/riscv/cpu-param.h index ebaf26d26d..b2a9396dec 100644 --- a/target/riscv/cpu-param.h +++ b/target/riscv/cpu-param.h @@ -27,6 +27,5 @@ * - S mode HLV/HLVX/HSV 0b101 * - M mode HLV/HLVX/HSV 0b111 */ -#define NB_MMU_MODES 8 #endif -- 2.34.1
[PULL v2 49/91] target/mips: Split out gen_lxr
Common subroutine for LDR and LWR. Use tcg_constant_tl of ~1 instead of tcg_const_tl of 0x..fe. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/mips/tcg/translate.c | 116 +--- 1 file changed, 40 insertions(+), 76 deletions(-) diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index 05c8d4ce44..7018c427be 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -2021,11 +2021,39 @@ static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr, tcg_gen_or_tl(reg, t0, t1); } +/* LWR or LDR, depending on MemOp. */ +static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr, + int mem_idx, MemOp mop) +{ +int size = memop_size(mop); +int sizem1 = size - 1; +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); + +/* + * Do a byte access to possibly trigger a page + * fault with the unaligned address. + */ +tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); +tcg_gen_andi_tl(t1, addr, sizem1); +if (cpu_is_bigendian(ctx)) { +tcg_gen_xori_tl(t1, t1, sizem1); +} +tcg_gen_shli_tl(t1, t1, 3); +tcg_gen_andi_tl(t0, addr, ~sizem1); +tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); +tcg_gen_shr_tl(t0, t0, t1); +tcg_gen_xori_tl(t1, t1, size * 8 - 1); +tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1); +tcg_gen_and_tl(t1, reg, t1); +tcg_gen_or_tl(reg, t0, t1); +} + /* Load */ static void gen_ld(DisasContext *ctx, uint32_t opc, int rt, int base, int offset) { -TCGv t0, t1, t2; +TCGv t0, t1; int mem_idx = ctx->mem_idx; if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | @@ -2066,26 +2094,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, break; case OPC_LDR: t1 = tcg_temp_new(); -/* - * Do a byte access to possibly trigger a page - * fault with the unaligned address. - */ -tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); -tcg_gen_andi_tl(t1, t0, 7); -if (cpu_is_bigendian(ctx)) { -tcg_gen_xori_tl(t1, t1, 7); -} -tcg_gen_shli_tl(t1, t1, 3); -tcg_gen_andi_tl(t0, t0, ~7); -tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); -tcg_gen_shr_tl(t0, t0, t1); -tcg_gen_xori_tl(t1, t1, 63); -t2 = tcg_const_tl(0xfffeull); -tcg_gen_shl_tl(t2, t2, t1); gen_load_gpr(t1, rt); -tcg_gen_and_tl(t1, t1, t2); -tcg_gen_or_tl(t0, t0, t1); -gen_store_gpr(t0, rt); +gen_lxr(ctx, t1, t0, mem_idx, MO_TEUQ); +gen_store_gpr(t1, rt); break; case OPC_LDPC: t1 = tcg_const_tl(pc_relative_pc(ctx)); @@ -2153,27 +2164,10 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, /* fall through */ case OPC_LWR: t1 = tcg_temp_new(); -/* - * Do a byte access to possibly trigger a page - * fault with the unaligned address. - */ -tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); -tcg_gen_andi_tl(t1, t0, 3); -if (cpu_is_bigendian(ctx)) { -tcg_gen_xori_tl(t1, t1, 3); -} -tcg_gen_shli_tl(t1, t1, 3); -tcg_gen_andi_tl(t0, t0, ~3); -tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); -tcg_gen_shr_tl(t0, t0, t1); -tcg_gen_xori_tl(t1, t1, 31); -t2 = tcg_const_tl(0xfffeull); -tcg_gen_shl_tl(t2, t2, t1); gen_load_gpr(t1, rt); -tcg_gen_and_tl(t1, t1, t2); -tcg_gen_or_tl(t0, t0, t1); -tcg_gen_ext32s_tl(t0, t0); -gen_store_gpr(t0, rt); +gen_lxr(ctx, t1, t0, mem_idx, MO_TEUL); +tcg_gen_ext32s_tl(t1, t1); +gen_store_gpr(t1, rt); break; case OPC_LLE: mem_idx = MIPS_HFLAG_UM; @@ -4150,7 +4144,7 @@ static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) static void gen_loongson_lswc2(DisasContext *ctx, int rt, int rs, int rd) { -TCGv t0, t1, t2; +TCGv t0, t1; TCGv_i32 fp0; #if defined(TARGET_MIPS64) int lsq_rt1 = ctx->opcode & 0x1f; @@ -4225,29 +4219,12 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, case OPC_GSLWRC1: check_cp1_enabled(ctx); gen_base_offset_addr(ctx, t0, rs, shf_offset); -t1 = tcg_temp_new(); -tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); -tcg_gen_andi_tl(t1, t0, 3); -if (cpu_is_bigendian(ctx)) { -tcg_gen_xori_tl(t1, t1, 3); -} -tcg_gen_shli_tl(t1, t1, 3); -tcg_gen_andi_tl(t0, t0, ~3); -tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); -tcg_gen_shr_tl(t0, t0, t1); -tcg_gen_xori_tl(t1, t1, 31); -t2 = tcg_const_tl(0xfffeull); -tcg_gen_shl_tl(t2, t2, t1);
[PATCH v8 11/11] target/arm: gdbstub: Guard pauth code with CONFIG_TCG
We currently don't have the reading of pauth regs implemented for KVM so wrap the pauth registration with CONFIG_TCG. This avoids the build error when using --disable-tcg: libqemu-aarch64-softmmu.fa.p/target_arm_gdbstub64.c.o: in function `aarch64_gdb_get_pauth_reg': ../target/arm/gdbstub64.c:233: undefined reference to `pauth_ptr_mask' Signed-off-by: Fabiano Rosas --- Does this make sense? I seem to remember we had a rule that for KVM register values should come from the ONE_REG interface. --- target/arm/gdbstub.c | 2 ++ target/arm/gdbstub64.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c index 2ecc362ac2..fc937580dd 100644 --- a/target/arm/gdbstub.c +++ b/target/arm/gdbstub.c @@ -521,11 +521,13 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) aarch64_gdb_set_fpu_reg, 34, "aarch64-fpu.xml", 0); } +#ifdef CONFIG_TCG if (isar_feature_aa64_pauth(>isar)) { gdb_register_coprocessor(cs, aarch64_gdb_get_pauth_reg, aarch64_gdb_set_pauth_reg, 4, "aarch64-pauth.xml", 0); } +#endif /* CONFIG_TCG */ #endif } else { if (arm_feature(env, ARM_FEATURE_NEON)) { diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c index 3bee892fb7..67c7cbb63c 100644 --- a/target/arm/gdbstub64.c +++ b/target/arm/gdbstub64.c @@ -210,6 +210,7 @@ int aarch64_gdb_set_sve_reg(CPUARMState *env, uint8_t *buf, int reg) return 0; } +#ifdef CONFIG_TCG int aarch64_gdb_get_pauth_reg(CPUARMState *env, GByteArray *buf, int reg) { switch (reg) { @@ -243,6 +244,7 @@ int aarch64_gdb_set_pauth_reg(CPUARMState *env, uint8_t *buf, int reg) /* All pseudo registers are read-only. */ return 0; } +#endif static void output_vector_union_type(GString *s, int reg_width, const char *name) -- 2.35.3
[PULL v2 53/91] target/ppc: Avoid tcg_const_i64 in do_vector_shift_quad
Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/ppc/translate/vmx-impl.c.inc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index ee656d6a44..7af6d7217d 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -906,7 +906,6 @@ static bool do_vector_shift_quad(DisasContext *ctx, arg_VX *a, bool right, hi = tcg_temp_new_i64(); lo = tcg_temp_new_i64(); t0 = tcg_temp_new_i64(); -t1 = tcg_const_i64(0); get_avr64(lo, a->vra, false); get_avr64(hi, a->vra, true); @@ -917,7 +916,10 @@ static bool do_vector_shift_quad(DisasContext *ctx, arg_VX *a, bool right, if (right) { tcg_gen_movcond_i64(TCG_COND_NE, lo, t0, zero, hi, lo); if (alg) { +t1 = tcg_temp_new_i64(); tcg_gen_sari_i64(t1, lo, 63); +} else { +t1 = zero; } tcg_gen_movcond_i64(TCG_COND_NE, hi, t0, zero, t1, hi); } else { -- 2.34.1
[PULL v2 81/91] target/ppc: Avoid tcg_const_* in vmx-impl.c.inc
All remaining uses are strictly read-only. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Daniel Henrique Barboza Signed-off-by: Richard Henderson --- target/ppc/translate/vmx-impl.c.inc | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index ca27c11d87..112233b541 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -1624,7 +1624,7 @@ static void glue(gen_, name)(DisasContext *ctx) \ gen_exception(ctx, POWERPC_EXCP_VPU); \ return; \ } \ -uimm = tcg_const_i32(UIMM5(ctx->opcode)); \ +uimm = tcg_constant_i32(UIMM5(ctx->opcode));\ rb = gen_avr_ptr(rB(ctx->opcode)); \ rd = gen_avr_ptr(rD(ctx->opcode)); \ gen_helper_##name(cpu_env, rd, rb, uimm); \ @@ -1965,7 +1965,7 @@ static void gen_vsldoi(DisasContext *ctx) ra = gen_avr_ptr(rA(ctx->opcode)); rb = gen_avr_ptr(rB(ctx->opcode)); rd = gen_avr_ptr(rD(ctx->opcode)); -sh = tcg_const_i32(VSH(ctx->opcode)); +sh = tcg_constant_i32(VSH(ctx->opcode)); gen_helper_vsldoi(rd, ra, rb, sh); } @@ -2575,7 +2575,7 @@ static void gen_##op(DisasContext *ctx) \ rb = gen_avr_ptr(rB(ctx->opcode)); \ rd = gen_avr_ptr(rD(ctx->opcode)); \ \ -ps = tcg_const_i32((ctx->opcode & 0x200) != 0); \ +ps = tcg_constant_i32((ctx->opcode & 0x200) != 0); \ \ gen_helper_##op(cpu_crf[6], rd, ra, rb, ps);\ } @@ -2594,7 +2594,7 @@ static void gen_##op(DisasContext *ctx) \ rb = gen_avr_ptr(rB(ctx->opcode)); \ rd = gen_avr_ptr(rD(ctx->opcode)); \ \ -ps = tcg_const_i32((ctx->opcode & 0x200) != 0); \ +ps = tcg_constant_i32((ctx->opcode & 0x200) != 0); \ \ gen_helper_##op(cpu_crf[6], rd, rb, ps);\ } @@ -2726,7 +2726,7 @@ static void gen_##op(DisasContext *ctx) \ } \ ra = gen_avr_ptr(rA(ctx->opcode));\ rd = gen_avr_ptr(rD(ctx->opcode));\ -st_six = tcg_const_i32(rB(ctx->opcode)); \ +st_six = tcg_constant_i32(rB(ctx->opcode)); \ gen_helper_##op(rd, ra, st_six); \ } -- 2.34.1
[PULL v2 05/91] target/mips: Drop tcg_temp_free from octeon_translate.c
Translators are no longer required to free tcg temporaries. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/mips/tcg/octeon_translate.c | 23 --- 1 file changed, 23 deletions(-) diff --git a/target/mips/tcg/octeon_translate.c b/target/mips/tcg/octeon_translate.c index 6a207d2e7e..103c304d10 100644 --- a/target/mips/tcg/octeon_translate.c +++ b/target/mips/tcg/octeon_translate.c @@ -40,8 +40,6 @@ static bool trans_BBIT(DisasContext *ctx, arg_BBIT *a) ctx->hflags |= MIPS_HFLAG_BC; ctx->btarget = ctx->base.pc_next + 4 + a->offset * 4; ctx->hflags |= MIPS_HFLAG_BDS32; - -tcg_temp_free(t0); return true; } @@ -61,10 +59,6 @@ static bool trans_BADDU(DisasContext *ctx, arg_BADDU *a) tcg_gen_add_tl(t0, t0, t1); tcg_gen_andi_i64(cpu_gpr[a->rd], t0, 0xff); - -tcg_temp_free(t0); -tcg_temp_free(t1); - return true; } @@ -83,10 +77,6 @@ static bool trans_DMUL(DisasContext *ctx, arg_DMUL *a) gen_load_gpr(t1, a->rt); tcg_gen_mul_i64(cpu_gpr[a->rd], t0, t1); - -tcg_temp_free(t0); -tcg_temp_free(t1); - return true; } @@ -103,8 +93,6 @@ static bool trans_EXTS(DisasContext *ctx, arg_EXTS *a) gen_load_gpr(t0, a->rs); tcg_gen_sextract_tl(t0, t0, a->p, a->lenm1 + 1); gen_store_gpr(t0, a->rt); -tcg_temp_free(t0); - return true; } @@ -121,8 +109,6 @@ static bool trans_CINS(DisasContext *ctx, arg_CINS *a) gen_load_gpr(t0, a->rs); tcg_gen_deposit_z_tl(t0, t0, a->p, a->lenm1 + 1); gen_store_gpr(t0, a->rt); -tcg_temp_free(t0); - return true; } @@ -142,8 +128,6 @@ static bool trans_POP(DisasContext *ctx, arg_POP *a) } tcg_gen_ctpop_tl(t0, t0); gen_store_gpr(t0, a->rd); -tcg_temp_free(t0); - return true; } @@ -167,10 +151,6 @@ static bool trans_SEQNE(DisasContext *ctx, arg_SEQNE *a) } else { tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr[a->rd], t1, t0); } - -tcg_temp_free(t0); -tcg_temp_free(t1); - return true; } @@ -194,8 +174,5 @@ static bool trans_SEQNEI(DisasContext *ctx, arg_SEQNEI *a) } else { tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr[a->rt], t0, imm); } - -tcg_temp_free(t0); - return true; } -- 2.34.1
[PULL v2 12/91] target/s390x: Drop tcg_temp_free from translate.c
Translators are no longer required to free tcg temporaries. Acked-by: David Hildenbrand Reviewed-by: Ilya Leoshkevich Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/s390x/tcg/translate.c | 105 --- 1 file changed, 105 deletions(-) diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index 669671075e..954a1edd10 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -306,8 +306,6 @@ static TCGv_i128 load_freg_128(int reg) TCGv_i128 r = tcg_temp_new_i128(); tcg_gen_concat_i64_i128(r, l, h); -tcg_temp_free_i64(h); -tcg_temp_free_i64(l); return r; } @@ -1263,10 +1261,8 @@ static DisasJumpType help_branch(DisasContext *s, DisasCompare *c, TCGv_i64 z = tcg_constant_i64(0); tcg_gen_setcond_i32(c->cond, t0, c->u.s32.a, c->u.s32.b); tcg_gen_extu_i32_i64(t1, t0); -tcg_temp_free_i32(t0); tcg_gen_movcond_i64(TCG_COND_NE, psw_addr, t1, z, cdest, next); per_branch_cond(s, TCG_COND_NE, t1, z); -tcg_temp_free_i64(t1); } ret = DISAS_PC_UPDATED; @@ -1525,7 +1521,6 @@ static void save_link_info(DisasContext *s, DisasOps *o) tcg_gen_extu_i32_i64(t, cc_op); tcg_gen_shli_i64(t, t, 28); tcg_gen_or_i64(o->out, o->out, t); -tcg_temp_free_i64(t); } static DisasJumpType op_bal(DisasContext *s, DisasOps *o) @@ -1589,7 +1584,6 @@ static DisasJumpType op_bct32(DisasContext *s, DisasOps *o) c.u.s32.a = tcg_temp_new_i32(); c.u.s32.b = tcg_constant_i32(0); tcg_gen_extrl_i64_i32(c.u.s32.a, t); -tcg_temp_free_i64(t); return help_branch(s, , is_imm, imm, o->in2); } @@ -1611,7 +1605,6 @@ static DisasJumpType op_bcth(DisasContext *s, DisasOps *o) c.u.s32.a = tcg_temp_new_i32(); c.u.s32.b = tcg_constant_i32(0); tcg_gen_extrl_i64_i32(c.u.s32.a, t); -tcg_temp_free_i64(t); return help_branch(s, , 1, imm, o->in2); } @@ -1652,7 +1645,6 @@ static DisasJumpType op_bx32(DisasContext *s, DisasOps *o) tcg_gen_extrl_i64_i32(c.u.s32.a, t); tcg_gen_extrl_i64_i32(c.u.s32.b, regs[r3 | 1]); store_reg32_i64(r1, t); -tcg_temp_free_i64(t); return help_branch(s, , is_imm, imm, o->in2); } @@ -1971,11 +1963,9 @@ static DisasJumpType op_cksm(DisasContext *s, DisasOps *o) gen_helper_cksm(pair, cpu_env, o->in1, o->in2, regs[r2 + 1]); set_cc_static(s); tcg_gen_extr_i128_i64(o->out, len, pair); -tcg_temp_free_i128(pair); tcg_gen_add_i64(regs[r2], regs[r2], len); tcg_gen_sub_i64(regs[r2 + 1], regs[r2 + 1], len); -tcg_temp_free_i64(len); return DISAS_NEXT; } @@ -2077,7 +2067,6 @@ static DisasJumpType op_clm(DisasContext *s, DisasOps *o) tcg_gen_extrl_i64_i32(t1, o->in1); gen_helper_clm(cc_op, cpu_env, t1, m3, o->in2); set_cc_static(s); -tcg_temp_free_i32(t1); return DISAS_NEXT; } @@ -2087,7 +2076,6 @@ static DisasJumpType op_clst(DisasContext *s, DisasOps *o) gen_helper_clst(pair, cpu_env, regs[0], o->in1, o->in2); tcg_gen_extr_i128_i64(o->in2, o->in1, pair); -tcg_temp_free_i128(pair); set_cc_static(s); return DISAS_NEXT; @@ -2099,7 +2087,6 @@ static DisasJumpType op_cps(DisasContext *s, DisasOps *o) tcg_gen_andi_i64(t, o->in1, 0x8000ull); tcg_gen_andi_i64(o->out, o->in2, 0x7fffull); tcg_gen_or_i64(o->out, o->out, t); -tcg_temp_free_i64(t); return DISAS_NEXT; } @@ -2115,14 +2102,12 @@ static DisasJumpType op_cs(DisasContext *s, DisasOps *o) addr = get_address(s, 0, b2, d2); tcg_gen_atomic_cmpxchg_i64(o->out, addr, o->in2, o->in1, get_mem_index(s), s->insn->data | MO_ALIGN); -tcg_temp_free_i64(addr); /* Are the memory and expected values (un)equal? Note that this setcond produces the output CC value, thus the NE sense of the test. */ cc = tcg_temp_new_i64(); tcg_gen_setcond_i64(TCG_COND_NE, cc, o->in2, o->out); tcg_gen_extrl_i64_i32(cc_op, cc); -tcg_temp_free_i64(cc); set_cc_static(s); return DISAS_NEXT; @@ -2182,7 +2167,6 @@ static DisasJumpType op_csp(DisasContext *s, DisasOps *o) tcg_gen_andi_i64(addr, o->in2, -1ULL << (mop & MO_SIZE)); tcg_gen_atomic_cmpxchg_i64(old, addr, o->in1, o->out2, get_mem_index(s), mop | MO_ALIGN); -tcg_temp_free_i64(addr); /* Are the memory and expected values (un)equal? */ cc = tcg_temp_new_i64(); @@ -2196,14 +2180,12 @@ static DisasJumpType op_csp(DisasContext *s, DisasOps *o) } else { tcg_gen_mov_i64(o->out, old); } -tcg_temp_free_i64(old); /* If the comparison was equal, and the LSB of R2 was set, then we need to flush the TLB (for all cpus). */ tcg_gen_xori_i64(cc, cc, 1); tcg_gen_and_i64(cc, cc, o->in2);
[PULL v2 73/91] target/arm: Improve trans_BFCI
Reorg temporary usage so that we can use tcg_constant_i32. tcg_gen_deposit_i32 already has a width == 32 special case, so remove the check here. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/arm/tcg/translate.c | 13 + 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c index b70b628000..4451aea09c 100644 --- a/target/arm/tcg/translate.c +++ b/target/arm/tcg/translate.c @@ -7261,8 +7261,8 @@ static bool trans_UBFX(DisasContext *s, arg_UBFX *a) static bool trans_BFCI(DisasContext *s, arg_BFCI *a) { -TCGv_i32 tmp; int msb = a->msb, lsb = a->lsb; +TCGv_i32 t_in, t_rd; int width; if (!ENABLE_ARCH_6T2) { @@ -7277,16 +7277,13 @@ static bool trans_BFCI(DisasContext *s, arg_BFCI *a) width = msb + 1 - lsb; if (a->rn == 15) { /* BFC */ -tmp = tcg_const_i32(0); +t_in = tcg_constant_i32(0); } else { /* BFI */ -tmp = load_reg(s, a->rn); +t_in = load_reg(s, a->rn); } -if (width != 32) { -TCGv_i32 tmp2 = load_reg(s, a->rd); -tcg_gen_deposit_i32(tmp, tmp2, tmp, lsb, width); -} -store_reg(s, a->rd, tmp); +t_rd = load_reg(s, a->rd); +tcg_gen_deposit_i32(t_rd, t_rd, t_in, lsb, width); return true; } -- 2.34.1
[PULL v2 63/91] target/tricore: Rename t_off10 and use tcg_constant_i32
While temp3 could simply be initialized with tcg_constant_i32, the renaming makes the purpose clearer. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/tricore/translate.c | 56 ++ 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 194bef27a6..19cf4b6cc7 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -4380,7 +4380,7 @@ static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx) uint32_t op2; uint32_t off10; int32_t r1, r2; -TCGv temp, temp2, temp3; +TCGv temp, temp2, t_off10; r1 = MASK_OP_BO_S1D(ctx->opcode); r2 = MASK_OP_BO_S2(ctx->opcode); @@ -4389,7 +4389,7 @@ static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx) temp = tcg_temp_new(); temp2 = tcg_temp_new(); -temp3 = tcg_const_i32(off10); +t_off10 = tcg_constant_i32(off10); CHECK_REG_PAIR(r2); tcg_gen_ext16u_tl(temp, cpu_gpr_a[r2+1]); tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp); @@ -4403,7 +4403,7 @@ static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx) case OPC2_32_BO_CACHEA_WI_CIRC: case OPC2_32_BO_CACHEA_W_CIRC: case OPC2_32_BO_CACHEA_I_CIRC: -gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); +gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10); break; case OPC2_32_BO_ST_A_BR: tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL); @@ -4411,7 +4411,7 @@ static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx) break; case OPC2_32_BO_ST_A_CIRC: tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL); -gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); +gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10); break; case OPC2_32_BO_ST_B_BR: tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB); @@ -4419,7 +4419,7 @@ static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx) break; case OPC2_32_BO_ST_B_CIRC: tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB); -gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); +gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10); break; case OPC2_32_BO_ST_D_BR: CHECK_REG_PAIR(r1); @@ -4434,7 +4434,7 @@ static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx) tcg_gen_rem_tl(temp, temp, temp2); tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp); tcg_gen_qemu_st_tl(cpu_gpr_d[r1+1], temp2, ctx->mem_idx, MO_LEUL); -gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); +gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10); break; case OPC2_32_BO_ST_DA_BR: CHECK_REG_PAIR(r1); @@ -4449,7 +4449,7 @@ static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx) tcg_gen_rem_tl(temp, temp, temp2); tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp); tcg_gen_qemu_st_tl(cpu_gpr_a[r1+1], temp2, ctx->mem_idx, MO_LEUL); -gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); +gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10); break; case OPC2_32_BO_ST_H_BR: tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW); @@ -4457,7 +4457,7 @@ static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx) break; case OPC2_32_BO_ST_H_CIRC: tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW); -gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); +gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10); break; case OPC2_32_BO_ST_Q_BR: tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16); @@ -4467,7 +4467,7 @@ static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx) case OPC2_32_BO_ST_Q_CIRC: tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16); tcg_gen_qemu_st_tl(temp, temp2, ctx->mem_idx, MO_LEUW); -gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); +gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10); break; case OPC2_32_BO_ST_W_BR: tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL); @@ -4475,7 +4475,7 @@ static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx) break; case OPC2_32_BO_ST_W_CIRC: tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL); -gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); +gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10); break; default: generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); @@ -4619,8 +4619,7 @@ static void
[PULL v2 48/91] target/mips: Split out gen_lxl
Common subroutine for LDL and LWL. Use tcg_constant_tl instead of tcg_const_tl and t2. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/mips/tcg/translate.c | 106 1 file changed, 36 insertions(+), 70 deletions(-) diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index 0fa9634d39..05c8d4ce44 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -1995,6 +1995,32 @@ static target_ulong pc_relative_pc(DisasContext *ctx) return pc; } +/* LWL or LDL, depending on MemOp. */ +static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr, + int mem_idx, MemOp mop) +{ +int sizem1 = memop_size(mop) - 1; +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); + +/* + * Do a byte access to possibly trigger a page + * fault with the unaligned address. + */ +tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); +tcg_gen_andi_tl(t1, addr, sizem1); +if (!cpu_is_bigendian(ctx)) { +tcg_gen_xori_tl(t1, t1, sizem1); +} +tcg_gen_shli_tl(t1, t1, 3); +tcg_gen_andi_tl(t0, addr, ~sizem1); +tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); +tcg_gen_shl_tl(t0, t0, t1); +tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1); +tcg_gen_andc_tl(t1, reg, t1); +tcg_gen_or_tl(reg, t0, t1); +} + /* Load */ static void gen_ld(DisasContext *ctx, uint32_t opc, int rt, int base, int offset) @@ -2034,25 +2060,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, break; case OPC_LDL: t1 = tcg_temp_new(); -/* - * Do a byte access to possibly trigger a page - * fault with the unaligned address. - */ -tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); -tcg_gen_andi_tl(t1, t0, 7); -if (!cpu_is_bigendian(ctx)) { -tcg_gen_xori_tl(t1, t1, 7); -} -tcg_gen_shli_tl(t1, t1, 3); -tcg_gen_andi_tl(t0, t0, ~7); -tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); -tcg_gen_shl_tl(t0, t0, t1); -t2 = tcg_const_tl(-1); -tcg_gen_shl_tl(t2, t2, t1); gen_load_gpr(t1, rt); -tcg_gen_andc_tl(t1, t1, t2); -tcg_gen_or_tl(t0, t0, t1); -gen_store_gpr(t0, rt); +gen_lxl(ctx, t1, t0, mem_idx, MO_TEUQ); +gen_store_gpr(t1, rt); break; case OPC_LDR: t1 = tcg_temp_new(); @@ -2133,26 +2143,10 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, /* fall through */ case OPC_LWL: t1 = tcg_temp_new(); -/* - * Do a byte access to possibly trigger a page - * fault with the unaligned address. - */ -tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); -tcg_gen_andi_tl(t1, t0, 3); -if (!cpu_is_bigendian(ctx)) { -tcg_gen_xori_tl(t1, t1, 3); -} -tcg_gen_shli_tl(t1, t1, 3); -tcg_gen_andi_tl(t0, t0, ~3); -tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); -tcg_gen_shl_tl(t0, t0, t1); -t2 = tcg_const_tl(-1); -tcg_gen_shl_tl(t2, t2, t1); gen_load_gpr(t1, rt); -tcg_gen_andc_tl(t1, t1, t2); -tcg_gen_or_tl(t0, t0, t1); -tcg_gen_ext32s_tl(t0, t0); -gen_store_gpr(t0, rt); +gen_lxl(ctx, t1, t0, mem_idx, MO_TEUL); +tcg_gen_ext32s_tl(t1, t1); +gen_store_gpr(t1, rt); break; case OPC_LWRE: mem_idx = MIPS_HFLAG_UM; @@ -4220,28 +4214,12 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, case OPC_GSLWLC1: check_cp1_enabled(ctx); gen_base_offset_addr(ctx, t0, rs, shf_offset); -t1 = tcg_temp_new(); -tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); -tcg_gen_andi_tl(t1, t0, 3); -if (!cpu_is_bigendian(ctx)) { -tcg_gen_xori_tl(t1, t1, 3); -} -tcg_gen_shli_tl(t1, t1, 3); -tcg_gen_andi_tl(t0, t0, ~3); -tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); -tcg_gen_shl_tl(t0, t0, t1); -t2 = tcg_const_tl(-1); -tcg_gen_shl_tl(t2, t2, t1); fp0 = tcg_temp_new_i32(); gen_load_fpr32(ctx, fp0, rt); +t1 = tcg_temp_new(); tcg_gen_ext_i32_tl(t1, fp0); -tcg_gen_andc_tl(t1, t1, t2); -tcg_gen_or_tl(t0, t0, t1); -#if defined(TARGET_MIPS64) -tcg_gen_extrl_i64_i32(fp0, t0); -#else -tcg_gen_ext32s_tl(fp0, t0); -#endif +gen_lxl(ctx, t1, t0, ctx->mem_idx, MO_TEUL); +tcg_gen_trunc_tl_i32(fp0, t1); gen_store_fpr32(ctx, fp0, rt); break; case OPC_GSLWRC1: @@ -4277,21 +4255,9 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, check_cp1_enabled(ctx); gen_base_offset_addr(ctx, t0, rs, shf_offset); t1 =
[PULL v2 52/91] target/ppc: Split out gen_vx_vmul10
Move the body out of this large macro. Use tcg_constant_i64. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/ppc/translate/vmx-impl.c.inc | 95 +++-- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index 05ba9c9492..ee656d6a44 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -171,53 +171,56 @@ static void gen_mtvscr(DisasContext *ctx) gen_helper_mtvscr(cpu_env, val); } +static void gen_vx_vmul10(DisasContext *ctx, bool add_cin, bool ret_carry) +{ +TCGv_i64 t0; +TCGv_i64 t1; +TCGv_i64 t2; +TCGv_i64 avr; +TCGv_i64 ten, z; + +if (unlikely(!ctx->altivec_enabled)) { +gen_exception(ctx, POWERPC_EXCP_VPU); +return; +} + +t0 = tcg_temp_new_i64(); +t1 = tcg_temp_new_i64(); +t2 = tcg_temp_new_i64(); +avr = tcg_temp_new_i64(); +ten = tcg_constant_i64(10); +z = tcg_constant_i64(0); + +if (add_cin) { +get_avr64(avr, rA(ctx->opcode), false); +tcg_gen_mulu2_i64(t0, t1, avr, ten); +get_avr64(avr, rB(ctx->opcode), false); +tcg_gen_andi_i64(t2, avr, 0xF); +tcg_gen_add2_i64(avr, t2, t0, t1, t2, z); +set_avr64(rD(ctx->opcode), avr, false); +} else { +get_avr64(avr, rA(ctx->opcode), false); +tcg_gen_mulu2_i64(avr, t2, avr, ten); +set_avr64(rD(ctx->opcode), avr, false); +} + +if (ret_carry) { +get_avr64(avr, rA(ctx->opcode), true); +tcg_gen_mulu2_i64(t0, t1, avr, ten); +tcg_gen_add2_i64(t0, avr, t0, t1, t2, z); +set_avr64(rD(ctx->opcode), avr, false); +set_avr64(rD(ctx->opcode), z, true); +} else { +get_avr64(avr, rA(ctx->opcode), true); +tcg_gen_mul_i64(t0, avr, ten); +tcg_gen_add_i64(avr, t0, t2); +set_avr64(rD(ctx->opcode), avr, true); +} +} + #define GEN_VX_VMUL10(name, add_cin, ret_carry) \ -static void glue(gen_, name)(DisasContext *ctx) \ -{ \ -TCGv_i64 t0;\ -TCGv_i64 t1;\ -TCGv_i64 t2;\ -TCGv_i64 avr; \ -TCGv_i64 ten, z;\ -\ -if (unlikely(!ctx->altivec_enabled)) { \ -gen_exception(ctx, POWERPC_EXCP_VPU); \ -return; \ -} \ -\ -t0 = tcg_temp_new_i64();\ -t1 = tcg_temp_new_i64();\ -t2 = tcg_temp_new_i64();\ -avr = tcg_temp_new_i64(); \ -ten = tcg_const_i64(10);\ -z = tcg_const_i64(0); \ -\ -if (add_cin) { \ -get_avr64(avr, rA(ctx->opcode), false); \ -tcg_gen_mulu2_i64(t0, t1, avr, ten);\ -get_avr64(avr, rB(ctx->opcode), false); \ -tcg_gen_andi_i64(t2, avr, 0xF); \ -tcg_gen_add2_i64(avr, t2, t0, t1, t2, z); \ -set_avr64(rD(ctx->opcode), avr, false); \ -} else {\ -get_avr64(avr, rA(ctx->opcode), false); \ -tcg_gen_mulu2_i64(avr, t2, avr, ten); \ -set_avr64(rD(ctx->opcode), avr, false); \ -} \ -\ -if (ret_carry) {\ -get_avr64(avr, rA(ctx->opcode), true); \ -tcg_gen_mulu2_i64(t0, t1, avr, ten);\ -tcg_gen_add2_i64(t0, avr, t0, t1, t2, z); \ -set_avr64(rD(ctx->opcode), avr, false); \ -set_avr64(rD(ctx->opcode), z, true);\ -}
[PULL v2 27/91] target/mips: Remove `NB_MMU_MODES` define
From: Anton Johansson Signed-off-by: Anton Johansson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alex Bennée Reviewed-by: Richard Henderson Message-Id: <20230306175230.7110-13-a...@rev.ng> Signed-off-by: Richard Henderson --- target/mips/cpu-param.h | 1 - 1 file changed, 1 deletion(-) diff --git a/target/mips/cpu-param.h b/target/mips/cpu-param.h index f4c76994ea..594c91a156 100644 --- a/target/mips/cpu-param.h +++ b/target/mips/cpu-param.h @@ -29,6 +29,5 @@ #define TARGET_PAGE_BITS_VARY #define TARGET_PAGE_BITS_MIN 12 #endif -#define NB_MMU_MODES 4 #endif -- 2.34.1
[PULL v2 77/91] target/arm: Avoid tcg_const_ptr in handle_vec_simd_sqshrn
It is easy enough to use mov instead of or-with-zero and relying on the optimizer to fold away the or. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/arm/tcg/translate-a64.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 2ad7c48901..082a8b82dd 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -8459,7 +8459,7 @@ static void handle_vec_simd_sqshrn(DisasContext *s, bool is_scalar, bool is_q, tcg_rn = tcg_temp_new_i64(); tcg_rd = tcg_temp_new_i64(); tcg_rd_narrowed = tcg_temp_new_i32(); -tcg_final = tcg_const_i64(0); +tcg_final = tcg_temp_new_i64(); if (round) { tcg_round = tcg_constant_i64(1ULL << (shift - 1)); @@ -8473,7 +8473,11 @@ static void handle_vec_simd_sqshrn(DisasContext *s, bool is_scalar, bool is_q, false, is_u_shift, size+1, shift); narrowfn(tcg_rd_narrowed, cpu_env, tcg_rd); tcg_gen_extu_i32_i64(tcg_rd, tcg_rd_narrowed); -tcg_gen_deposit_i64(tcg_final, tcg_final, tcg_rd, esize * i, esize); +if (i == 0) { +tcg_gen_mov_i64(tcg_final, tcg_rd); +} else { +tcg_gen_deposit_i64(tcg_final, tcg_final, tcg_rd, esize * i, esize); +} } if (!is_q) { -- 2.34.1
[PULL v2 68/91] target/arm: Use rmode >= 0 for need_rmode
Initialize rmode to -1 instead of keeping two variables. This is already used elsewhere in translate-a64.c. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/arm/tcg/translate-a64.c | 34 ++ 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 2c2ea45b47..bef66086a2 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -12133,7 +12133,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) int rn = extract32(insn, 5, 5); int rd = extract32(insn, 0, 5); bool need_fpstatus = false; -bool need_rmode = false; int rmode = -1; TCGv_i32 tcg_rmode; TCGv_ptr tcg_fpstatus; @@ -12283,7 +12282,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) case 0x7a: /* FCVTPU */ case 0x7b: /* FCVTZU */ need_fpstatus = true; -need_rmode = true; rmode = extract32(opcode, 5, 1) | (extract32(opcode, 0, 1) << 1); if (size == 3 && !is_q) { unallocated_encoding(s); @@ -12293,7 +12291,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) case 0x5c: /* FCVTAU */ case 0x1c: /* FCVTAS */ need_fpstatus = true; -need_rmode = true; rmode = FPROUNDING_TIEAWAY; if (size == 3 && !is_q) { unallocated_encoding(s); @@ -12352,7 +12349,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) case 0x19: /* FRINTM */ case 0x38: /* FRINTP */ case 0x39: /* FRINTZ */ -need_rmode = true; rmode = extract32(opcode, 5, 1) | (extract32(opcode, 0, 1) << 1); /* fall through */ case 0x59: /* FRINTX */ @@ -12364,7 +12360,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) } break; case 0x58: /* FRINTA */ -need_rmode = true; rmode = FPROUNDING_TIEAWAY; need_fpstatus = true; if (size == 3 && !is_q) { @@ -12380,7 +12375,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) break; case 0x1e: /* FRINT32Z */ case 0x1f: /* FRINT64Z */ -need_rmode = true; rmode = FPROUNDING_ZERO; /* fall through */ case 0x5e: /* FRINT32X */ @@ -12406,12 +12400,12 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) return; } -if (need_fpstatus || need_rmode) { +if (need_fpstatus || rmode >= 0) { tcg_fpstatus = fpstatus_ptr(FPST_FPCR); } else { tcg_fpstatus = NULL; } -if (need_rmode) { +if (rmode >= 0) { tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode)); gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus); } else { @@ -12595,7 +12589,7 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) } clear_vec_high(s, is_q, rd); -if (need_rmode) { +if (tcg_rmode) { gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus); } } @@ -12625,9 +12619,8 @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) int pass; TCGv_i32 tcg_rmode = NULL; TCGv_ptr tcg_fpstatus = NULL; -bool need_rmode = false; bool need_fpst = true; -int rmode; +int rmode = -1; if (!dc_isar_feature(aa64_fp16, s)) { unallocated_encoding(s); @@ -12676,27 +12669,22 @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) case 0x3f: /* FRECPX */ break; case 0x18: /* FRINTN */ -need_rmode = true; only_in_vector = true; rmode = FPROUNDING_TIEEVEN; break; case 0x19: /* FRINTM */ -need_rmode = true; only_in_vector = true; rmode = FPROUNDING_NEGINF; break; case 0x38: /* FRINTP */ -need_rmode = true; only_in_vector = true; rmode = FPROUNDING_POSINF; break; case 0x39: /* FRINTZ */ -need_rmode = true; only_in_vector = true; rmode = FPROUNDING_ZERO; break; case 0x58: /* FRINTA */ -need_rmode = true; only_in_vector = true; rmode = FPROUNDING_TIEAWAY; break; @@ -12706,43 +12694,33 @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) /* current rounding mode */ break; case 0x1a: /* FCVTNS */ -need_rmode = true; rmode = FPROUNDING_TIEEVEN; break; case 0x1b: /* FCVTMS */ -need_rmode = true; rmode = FPROUNDING_NEGINF; break; case 0x1c: /* FCVTAS */ -need_rmode = true; rmode = FPROUNDING_TIEAWAY; break; case 0x3a: /* FCVTPS */ -
[PULL v2 61/91] tcg/sparc: Avoid tcg_const_tl in gen_edge
Push tcg_constant_tl into the shift argument directly. Since t1 no longer exists as a temp, replace with lo1, whose last use was just above. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/sparc/translate.c | 14 ++ 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 5ee293326c..137bdc5159 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -2838,7 +2838,7 @@ static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_env cpu_env) static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2, int width, bool cc, bool left) { -TCGv lo1, lo2, t1, t2; +TCGv lo1, lo2; uint64_t amask, tabl, tabr; int shift, imask, omask; @@ -2905,10 +2905,8 @@ static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2, tcg_gen_shli_tl(lo1, lo1, shift); tcg_gen_shli_tl(lo2, lo2, shift); -t1 = tcg_const_tl(tabl); -t2 = tcg_const_tl(tabr); -tcg_gen_shr_tl(lo1, t1, lo1); -tcg_gen_shr_tl(lo2, t2, lo2); +tcg_gen_shr_tl(lo1, tcg_constant_tl(tabl), lo1); +tcg_gen_shr_tl(lo2, tcg_constant_tl(tabr), lo2); tcg_gen_andi_tl(dst, lo1, omask); tcg_gen_andi_tl(lo2, lo2, omask); @@ -2927,9 +2925,9 @@ static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2, lo2 |= -(s1 == s2) dst &= lo2 */ -tcg_gen_setcond_tl(TCG_COND_EQ, t1, s1, s2); -tcg_gen_neg_tl(t1, t1); -tcg_gen_or_tl(lo2, lo2, t1); +tcg_gen_setcond_tl(TCG_COND_EQ, lo1, s1, s2); +tcg_gen_neg_tl(lo1, lo1); +tcg_gen_or_tl(lo2, lo2, lo1); tcg_gen_and_tl(dst, dst, lo2); } -- 2.34.1