Re: 回复: Fw: 来自Leo Hou的邮件

2023-11-01 Thread leohou

On 2023/11/2 12:46, leohou wrote:

On 2023/11/2 11:33, leohou1...@gmail.com wrote:

On 31/10/23 16:13:32 Philippe Mathieu-Daudé wrote:

Hi Leo,

On 31/10/23 04:10, Leo Hou wrote:

hi , all
     Does qemu plan to support CPU heterogeneity?

Short answer is yes. When will this be available is yet to
be determined, as a lot of work is required.




I'm going to talk about the challenges and possible roadmap
later today, feel free to join the call scheduled at 2pm CET
on https://meet.jit.si/kvmcallmeeting.
(See
https://lore.kernel.org/qemu-devel/calendar-1ad16449-09cc-40fb-ab4a-24eafcc62...@google.com/) 



Hi Philippe


Thank you for your reply. I didn't check my email in time
  because of the mailbox problem. Now I will reply to you
  by changing my email address.

With regard to your discussion, is it convenient to announce
the results of the discussion now?


Is there a need for the architecture of the main cpu and several 
coprocessors?



Examples include SCP and MCP in the ARM N2 platform, or an ARM host 
machine containing a risc-v coprocessor.




Re: [PATCH v4 33/33] hw/riscv/shakti_c: Check CPU type in machine_run_board_init()

2023-11-01 Thread Richard Henderson

On 11/1/23 17:25, Gavin Shan wrote:

Set mc->valid_cpu_types so that the user specified CPU type can
be validated in machine_run_board_init(). We needn't to do it
by ourselves.

Signed-off-by: Gavin Shan 
Reviewed-by: Philippe Mathieu-Daudé 
---
  hw/riscv/shakti_c.c | 11 +--
  1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c
index 12ea74b032..fc83ed4db4 100644
--- a/hw/riscv/shakti_c.c
+++ b/hw/riscv/shakti_c.c
@@ -28,6 +28,10 @@
  #include "exec/address-spaces.h"
  #include "hw/riscv/boot.h"
  
+static const char * const valid_cpu_types[] = {

+RISCV_CPU_TYPE_NAME("shakti-c"),
+NULL
+};


Why are you using a different form here...


@@ -85,6 +83,7 @@ static void shakti_c_machine_class_init(ObjectClass *klass, 
void *data)
  mc->desc = "RISC-V Board compatible with Shakti SDK";
  mc->init = shakti_c_machine_state_init;
  mc->default_cpu_type = TYPE_RISCV_CPU_SHAKTI_C;


... than here?


r~


+mc->valid_cpu_types = valid_cpu_types;
  mc->default_ram_id = "riscv.shakti.c.ram";
  }
  





Re: [PATCH v4 32/33] hw/arm: Check CPU type in machine_run_board_init()

2023-11-01 Thread Richard Henderson

On 11/1/23 17:24, Gavin Shan wrote:

Set mc->valid_cpu_types so that the user specified CPU type can
be validated in machine_run_board_init(). We needn't to do it by
ourselves.

Signed-off-by: Gavin Shan 
---
  hw/arm/bananapi_m2u.c   | 12 ++--
  hw/arm/cubieboard.c | 12 ++--
  hw/arm/mps2-tz.c| 20 ++--
  hw/arm/mps2.c   | 25 +++--
  hw/arm/msf2-som.c   | 12 ++--
  hw/arm/musca.c  | 13 ++---
  hw/arm/npcm7xx_boards.c | 13 ++---
  hw/arm/orangepi.c   | 12 ++--
  8 files changed, 69 insertions(+), 50 deletions(-)


Reviewed-by: Richard Henderson 


r~



Re: [PATCH v4 31/33] hw/arm/sbsa-ref: Check CPU type in machine_run_board_init()

2023-11-01 Thread Richard Henderson

On 11/1/23 17:24, Gavin Shan wrote:

Set mc->valid_cpu_types so that the user specified CPU type can
be validated in machine_run_board_init(). We needn't to do it
by ourselves.

Signed-off-by: Gavin Shan 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Leif Lindholm 
---
  hw/arm/sbsa-ref.c | 21 +++--
  1 file changed, 3 insertions(+), 18 deletions(-)


Reviewed-by: Richard Henderson 


r~



Re: [PATCH v4 30/33] hw/arm/virt: Hide host CPU model for tcg

2023-11-01 Thread Richard Henderson

On 11/1/23 17:24, Gavin Shan wrote:

The 'host' CPU model isn't available until KVM or HVF is enabled.
For example, the following error messages are seen when the guest
is started with option '-cpu cortex-a8' on tcg.

   ERROR:../hw/core/machine.c:1423:is_cpu_type_supported: \
   assertion failed: (model != NULL)
   Bail out! ERROR:../hw/core/machine.c:1423:is_cpu_type_supported: \
   assertion failed: (model != NULL)
   Aborted (core dumped)

Hide 'host' CPU model until KVM or HVF is enabled. With this applied,
the valid CPU models can be shown.

   qemu-system-aarch64: Invalid CPU type: cortex-a8
   The valid types are: cortex-a7, cortex-a15, cortex-a35, \
   cortex-a55, cortex-a72, cortex-a76, cortex-a710, a64fx, \
   neoverse-n1, neoverse-v1, neoverse-n2, cortex-a53,  \
   cortex-a57, max

Signed-off-by: Gavin Shan 


This patch has to be sorted before the previous patch, for exactly this assert.
With that,

Reviewed-by: Richard Henderson 


r~



Re: [PATCH v4 29/33] hw/arm/virt: Check CPU type in machine_run_board_init()

2023-11-01 Thread Richard Henderson

On 11/1/23 17:24, Gavin Shan wrote:

Set mc->valid_cpu_types so that the user specified CPU type can be
validated in machine_run_board_init(). We needn't to do the check
by ourselves.

Signed-off-by: Gavin Shan 
Reviewed-by: Philippe Mathieu-Daudé 
---
  hw/arm/virt.c | 21 +++--
  1 file changed, 3 insertions(+), 18 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v4 28/33] machine: Print CPU model name instead of CPU type name

2023-11-01 Thread Richard Henderson

On 11/1/23 17:24, Gavin Shan wrote:

The names of supported CPU models instead of CPU types should be
printed when the user specified CPU type isn't supported, to be
consistent with the output from '-cpu ?'.

Correct the error messages to print CPU model names instead of CPU
type names.

Signed-off-by: Gavin Shan 
---
  hw/core/machine.c | 19 +++
  1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 2d78692df1..1dd0f8831b 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1391,6 +1391,7 @@ static void is_cpu_type_supported(MachineState *machine, 
Error **errp)
  MachineClass *mc = MACHINE_GET_CLASS(machine);
  ObjectClass *oc = object_class_by_name(machine->cpu_type);
  CPUClass *cc;
+char *model;


No need for this outside...



  int i;
  
  /*

@@ -1407,11 +1408,21 @@ static void is_cpu_type_supported(MachineState 
*machine, Error **errp)
  
  /* The user specified CPU type isn't valid */

  if (!mc->valid_cpu_types[i]) {


... this block.


-error_setg(errp, "Invalid CPU type: %s", machine->cpu_type);
-error_append_hint(errp, "The valid types are: %s",
-  mc->valid_cpu_types[0]);
+model = cpu_model_from_type(machine->cpu_type);
+g_assert(model != NULL);
+error_setg(errp, "Invalid CPU type: %s", model);
+g_free(model);
+
+model = cpu_model_from_type(mc->valid_cpu_types[0]);
+g_assert(model != NULL);
+error_append_hint(errp, "The valid types are: %s", model);
+g_free(model);
+
  for (i = 1; mc->valid_cpu_types[i]; i++) {
-error_append_hint(errp, ", %s", mc->valid_cpu_types[i]);
+model = cpu_model_from_type(mc->valid_cpu_types[i]);
+g_assert(model != NULL);
+error_append_hint(errp, ", %s", model);
+g_free(model);
  }


I really don't like all of the replicated asserts for non-null.

You already know there's no path through cpu_model_from_type that doesn't return 
something...  And anyway, in extremis, "(nil)" will print just fine.



r~



Re: [PATCH v4 27/33] machine: Introduce helper is_cpu_type_supported()

2023-11-01 Thread Richard Henderson

On 11/1/23 17:24, Gavin Shan wrote:

The logic, to check if the specified CPU type is supported in
machine_run_board_init(), is independent enough. Factor it out into
helper is_cpu_type_supported(). machine_run_board_init() looks a bit
clean with this. Since we're here, @machine_class is renamed to @mc
to avoid multiple line spanning of code. The comments are tweaked a
bit either.

No functional change intended.

Signed-off-by: Gavin Shan 
---
  hw/core/machine.c | 82 +--
  1 file changed, 44 insertions(+), 38 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 1c17a0d5bf..2d78692df1 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1386,13 +1386,51 @@ out:
  return r;
  }
  
+static void is_cpu_type_supported(MachineState *machine, Error **errp)

+{
+MachineClass *mc = MACHINE_GET_CLASS(machine);
+ObjectClass *oc = object_class_by_name(machine->cpu_type);


machine->cpu_type is used...


+CPUClass *cc;
+int i;
+
+/*
+ * Check if the user specified CPU type is supported when the valid
+ * CPU types have been determined. Note that the user specified CPU
+ * type is provided through '-cpu' option.
+ */
+if (mc->valid_cpu_types && machine->cpu_type) {


... before checking that it is set.


+for (i = 0; mc->valid_cpu_types[i]; i++) {
+if (object_class_dynamic_cast(oc, mc->valid_cpu_types[i])) {
+break;
+}
+}
+
+/* The user specified CPU type isn't valid */
+if (!mc->valid_cpu_types[i]) {
+error_setg(errp, "Invalid CPU type: %s", machine->cpu_type);
+error_append_hint(errp, "The valid types are: %s",
+  mc->valid_cpu_types[0]);
+for (i = 1; mc->valid_cpu_types[i]; i++) {
+error_append_hint(errp, ", %s", mc->valid_cpu_types[i]);
+}
+
+error_append_hint(errp, "\n");
+return;
+}
+}
+
+/* Check if CPU type is deprecated and warn if so */
+cc = CPU_CLASS(oc);


... and here you've not even checked that oc resolved correctly.


+if (cc && cc->deprecation_note) {


I guess you're assuming that CPU_CLASS is a plain cast, so this second check 
filters NULL.


r~



Re: [PATCH v4 26/33] machine: Use error handling when CPU type is checked

2023-11-01 Thread Richard Henderson

On 11/1/23 17:24, Gavin Shan wrote:

QEMU will be terminated if the specified CPU type isn't supported
in machine_run_board_init(). The list of supported CPU type names
is tracked by mc->valid_cpu_types.

The error handling can be used to propagate error messages, to be
consistent how the errors are handled for other situations in the
same function.

No functional change intended.

Suggested-by: Igor Mammedov 
Signed-off-by: Gavin Shan 
---
  hw/core/machine.c | 14 --
  1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 50edaab737..1c17a0d5bf 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1393,6 +1393,7 @@ void machine_run_board_init(MachineState *machine, const 
char *mem_path, Error *
  MachineClass *machine_class = MACHINE_GET_CLASS(machine);
  ObjectClass *oc = object_class_by_name(machine->cpu_type);
  CPUClass *cc;
+Error *local_err = NULL;



This...

  
  /* This checkpoint is required by replay to separate prior clock

 reading from the other reads, because timer polling functions query
@@ -1465,15 +1466,16 @@ void machine_run_board_init(MachineState *machine, 
const char *mem_path, Error *
  
  if (!machine_class->valid_cpu_types[i]) {

  /* The user specified CPU is not valid */
-error_report("Invalid CPU type: %s", machine->cpu_type);
-error_printf("The valid types are: %s",
- machine_class->valid_cpu_types[0]);
+error_setg(_err, "Invalid CPU type: %s", machine->cpu_type);


... could go in this block.

Though I don't see why you can't write to errp directly?


r~



Re: 回复: Fw: 来自Leo Hou的邮件

2023-11-01 Thread leohou

On 2023/11/2 11:33, leohou1...@gmail.com wrote:

On 31/10/23 16:13:32 Philippe Mathieu-Daudé wrote:

Hi Leo,

On 31/10/23 04:10, Leo Hou wrote:

hi , all
     Does qemu plan to support CPU heterogeneity?

Short answer is yes. When will this be available is yet to
be determined, as a lot of work is required.




I'm going to talk about the challenges and possible roadmap
later today, feel free to join the call scheduled at 2pm CET
on https://meet.jit.si/kvmcallmeeting.
(See
https://lore.kernel.org/qemu-devel/calendar-1ad16449-09cc-40fb-ab4a-24eafcc62...@google.com/)


Hi Philippe


Thank you for your reply. I didn't check my email in time
  because of the mailbox problem. Now I will reply to you
  by changing my email address.

With regard to your discussion, is it convenient to announce
the results of the discussion now?


Is there a need for the architecture of the main cpu and several 
coprocessors?






Re: [RFC PATCH 00/18] Map memory at destination .load_setup in vDPA-net migration

2023-11-01 Thread Jason Wang
On Thu, Oct 19, 2023 at 10:35 PM Eugenio Pérez  wrote:
>
> Current memory operations like pinning may take a lot of time at the
> destination.  Currently they are done after the source of the migration is
> stopped, and before the workload is resumed at the destination.  This is a
> period where neigher traffic can flow, nor the VM workload can continue
> (downtime).
>
> We can do better as we know the memory layout of the guest RAM at the
> destination from the moment the migration starts.  Moving that operation 
> allows
> QEMU to communicate the kernel the maps while the workload is still running in
> the source, so Linux can start mapping them.  Ideally, all IOMMU is 
> configured,
> but if the vDPA parent driver uses on-chip IOMMU and .set_map we're still
> saving all the pinning time.
>
> Note that further devices setup at the end of the migration may alter the 
> guest
> memory layout. But same as the previous point, many operations are still done
> incrementally, like memory pinning, so we're saving time anyway.
>
> The first bunch of patches just reorganizes the code, so memory related
> operation parameters are shared between all vhost_vdpa devices.  This is
> because the destination does not know what vhost_vdpa struct will have the
> registered listener member, so it is easier to place them in a shared struct
> rather to keep them in vhost_vdpa struct.  Future version may squash or omit
> these patches.
>
> Only tested with vdpa_sim. I'm sending this before full benchmark, as some 
> work
> like [1] can be based on it, and Si-Wei agreed on benchmark this series with
> his experience.

I'd expect we can see some improvement even without other
optimizations? For example, do we see improvement on mlx5?

(Or we can probably add some delay to the simulator to see)

Thanks

>
> Future directions on top of this series may include:
> * Iterative migration of virtio-net devices, as it may reduce downtime per 
> [1].
>   vhost-vdpa net can apply the configuration through CVQ in the destination
>   while the source is still migrating.
> * Move more things ahead of migration time, like DRIVER_OK.
> * Check that the devices of the destination are valid, and cancel the 
> migration
>   in case it is not.
>
> [1] 
> https://lore.kernel.org/qemu-devel/6c8ebb97-d546-3f1c-4cdd-54e23a566...@nvidia.com/T/
>
> Eugenio Pérez (18):
>   vdpa: add VhostVDPAShared
>   vdpa: move iova tree to the shared struct
>   vdpa: move iova_range to vhost_vdpa_shared
>   vdpa: move shadow_data to vhost_vdpa_shared
>   vdpa: use vdpa shared for tracing
>   vdpa: move file descriptor to vhost_vdpa_shared
>   vdpa: move iotlb_batch_begin_sent to vhost_vdpa_shared
>   vdpa: move backend_cap to vhost_vdpa_shared
>   vdpa: remove msg type of vhost_vdpa
>   vdpa: move iommu_list to vhost_vdpa_shared
>   vdpa: use VhostVDPAShared in vdpa_dma_map and unmap
>   vdpa: use dev_shared in vdpa_iommu
>   vdpa: move memory listener to vhost_vdpa_shared
>   vdpa: do not set virtio status bits if unneeded
>   vdpa: add vhost_vdpa_load_setup
>   vdpa: add vhost_vdpa_net_load_setup NetClient callback
>   vdpa: use shadow_data instead of first device v->shadow_vqs_enabled
>   virtio_net: register incremental migration handlers
>
>  include/hw/virtio/vhost-vdpa.h |  43 +---
>  include/net/net.h  |   4 +
>  hw/net/virtio-net.c|  23 +
>  hw/virtio/vdpa-dev.c   |   7 +-
>  hw/virtio/vhost-vdpa.c | 183 ++---
>  net/vhost-vdpa.c   | 127 ---
>  hw/virtio/trace-events |  14 +--
>  7 files changed, 239 insertions(+), 162 deletions(-)
>
> --
> 2.39.3
>
>




Re: [PATCH v4 25/33] machine: Constify MachineClass::valid_cpu_types[i]

2023-11-01 Thread Richard Henderson

On 11/1/23 17:24, Gavin Shan wrote:

Constify MachineClass::valid_cpu_types[i], as suggested by Richard
Henderson.

Suggested-by: Richard Henderson 
Signed-off-by: Gavin Shan 
Reviewed-by: Philippe Mathieu-Daudé 
---
  hw/m68k/q800.c  | 2 +-
  include/hw/boards.h | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)


Reviewed-by: Richard Henderson 


r~



回复: Fw: 来自Leo Hou的邮件

2023-11-01 Thread leohou1...@gmail.com
On 31/10/23 16:13:32 Philippe Mathieu-Daudé wrote:
>Hi Leo,
>
>On 31/10/23 04:10, Leo Hou wrote:
>> hi , all
>>    Does qemu plan to support CPU heterogeneity?

>

>Short answer is yes. When will this be available is yet to
>be determined, as a lot of work is required.



>I'm going to talk about the challenges and possible roadmap
>later today, feel free to join the call scheduled at 2pm CET
>on https://meet.jit.si/kvmcallmeeting.
>(See 
>https://lore.kernel.org/qemu-devel/calendar-1ad16449-09cc-40fb-ab4a-24eafcc62...@google.com/)


Hi Philippe


Thank you for your reply. I didn't check my email in time
 because of the mailbox problem. Now I will reply to you
 by changing my email address.

With regard to your discussion, is it convenient to announce 
the results of the discussion now?


Re: [PATCH] file-posix: fix over-writing of returning zone_append offset

2023-11-01 Thread Stefan Hajnoczi
On Mon, Oct 30, 2023 at 04:38:53PM +0900, Naohiro Aota wrote:
> raw_co_zone_append() sets "s->offset" where "BDRVRawState *s". This pointer
> is used later at raw_co_prw() to save the block address where the data is
> written.
> 
> When multiple IOs are on-going at the same time, a later IO's
> raw_co_zone_append() call over-writes a former IO's offset address before
> raw_co_prw() completes. As a result, the former zone append IO returns the
> initial value (= the start address of the writing zone), instead of the
> proper address.
> 
> Fix the issue by passing the offset pointer to raw_co_prw() instead of
> passing it through s->offset. Also, remove "offset" from BDRVRawState as
> there is no usage anymore.
> 
> Fixes: 4751d09adcc3 ("block: introduce zone append write for zoned devices")
> Signed-off-by: Naohiro Aota 
> ---
>  block/file-posix.c | 16 +++-
>  1 file changed, 7 insertions(+), 9 deletions(-)

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


Re: [PATCH v6 06/12] target/riscv/tcg: add user flag for profile support

2023-11-01 Thread Alistair Francis
On Tue, Oct 31, 2023 at 3:19 AM Daniel Henrique Barboza
 wrote:
>
>
>
> On 10/30/23 10:28, Daniel Henrique Barboza wrote:
> >
> >
> > On 10/28/23 05:54, Daniel Henrique Barboza wrote:
> >> The TCG emulation implements all the extensions described in the
> >> RVA22U64 profile, both mandatory and optional. The mandatory extensions
> >> will be enabled via the profile flag. We'll leave the optional
> >> extensions to be enabled by hand.
> >>
> >> Given that this is the first profile we're implementing in TCG we'll
> >> need some ground work first:
> >>
> >> - all profiles declared in riscv_profiles[] will be exposed to users.
> >> TCG is the main accelerator we're considering when adding profile
> >> support in QEMU, so for now it's safe to assume that all profiles in
> >> riscv_profiles[] will be relevant to TCG;
> >>
> >> - we'll not support user profile settings for vendor CPUs. The flags
> >> will still be exposed but users won't be able to change them. The idea
> >> is that vendor CPUs in the future can enable profiles internally in
> >> their cpu_init() functions, showing to the external world that the CPU
> >> supports a certain profile. But users won't be able to enable/disable
> >> it;
> >>
> >> - Setting a profile to 'true' means 'enable all mandatory extensions of
> >> this profile, setting it to 'false' means 'do not enable all mandatory
> >> extensions for this profile'. This is the same semantics used by RVG.
> >> Regular left-to-right option order will determine the resulting CPU
> >> configuration, i.e. the following QEMU command line:
> >>
> >> -cpu rv64,zicbom=false,zifencei=false,rva22u64=true
> >>
> >> Enables all rva22u64 mandatory extensions, including 'zicbom' and
> >> 'zifencei', while this other command line:
> >>
> >> -cpu rv64,rva22u64=true,zicbom=false,zifencei=false
> >>
> >> Enables all mandatory rva22u64 extensions, and then disable both zicbom
> >> and zifencei.
> >>
> >> For now we'll handle multi-letter extensions only. MISA extensions need
> >> additional steps that we'll take care later.
> >>
> >> Signed-off-by: Daniel Henrique Barboza 
> >> Reviewed-by: Andrew Jones 
> >> ---
> >>   target/riscv/tcg/tcg-cpu.c | 63 ++
> >>   1 file changed, 63 insertions(+)
> >>
> >> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> >> index 65d59bc984..5fdec8f04e 100644
> >> --- a/target/riscv/tcg/tcg-cpu.c
> >> +++ b/target/riscv/tcg/tcg-cpu.c
> >> @@ -783,6 +783,67 @@ static void riscv_cpu_add_misa_properties(Object 
> >> *cpu_obj)
> >>   }
> >>   }
> >> +static void cpu_set_profile(Object *obj, Visitor *v, const char *name,
> >> +void *opaque, Error **errp)
> >> +{
> >> +RISCVCPUProfile *profile = opaque;
> >> +RISCVCPU *cpu = RISCV_CPU(obj);
> >> +bool value;
> >> +int i, ext_offset;
> >> +
> >> +if (object_dynamic_cast(obj, TYPE_RISCV_DYNAMIC_CPU) == NULL) {
> >> +error_setg(errp, "Profile %s only available for generic CPUs",
> >> +   profile->name);
> >> +return;
> >> +}
> >> +
> >> +if (cpu->env.misa_mxl != MXL_RV64) {
> >> +error_setg(errp, "Profile %s only available for 64 bit CPUs",
> >> +   profile->name);
> >> +return;
> >> +}
> >> +
> >> +if (!visit_type_bool(v, name, , errp)) {
> >> +return;
> >> +}
> >> +
> >> +profile->user_set = true;
> >> +profile->enabled = value;
> >> +
> >> +if (!profile->enabled) {
> >> +return;
> >> +}
> >
> > My idea here was to prevent the following from disabling default rv64
> > extensions:
> >
> > -cpu rv64,rva22u64=false

I think that's the right approach

> >
> > And yeah, this is a niche (I'll refrain from using the word I really 
> > wanted) use
> > of the profile extension, but we should keep in mind that setting a default 
> > 'false'
> > option to 'false' shouldn't make changes in the CPU.
> >
> > But now if I do this:
> >
> > -cpu rv64,rva22u64=true (...) -cpu rv64,rva22u64=false
> >
> > This will enable the profile in rv64 regardless of setting it to 'false' 
> > later
> > on. Which is also a weird mechanic. One way of solving this would be to 
> > postpone

Urgh, that is odd.

> > profile enable/disable to realize()/finalize(), but then we're back to the 
> > problem
> > we had in v2 where, for multiple profiles, we can't tell the order in which 
> > the
> > user enabled/disabled them in the command line during realize().

Are the properties not just set in order automatically? So we end up
with the property being set by the last one?

> >
> > Let me think a bit about it.
>
> To be honest, all the debate around this feature is due to rv64 having default
> extensions and users doing non-orthodox stuff with the flag that will crop
> rv64 defaults, resulting in something that we don't know what this is.

Ok, just to summarise.

The idea is that having a CPU with nothing enabled makes it easy to
then enable features 

Re: [PATCH v8 02/19] target/riscv/tcg: do not use "!generic" CPU checks

2023-11-01 Thread Alistair Francis
On Thu, Nov 2, 2023 at 8:13 AM Daniel Henrique Barboza
 wrote:
>
> Our current logic in get/setters of MISA and multi-letter extensions
> works because we have only 2 CPU types, generic and vendor, and by using
> "!generic" we're implying that we're talking about vendor CPUs. When adding
> a third CPU type this logic will break so let's handle it beforehand.
>
> In set_misa_ext_cfg() and set_multi_ext_cfg(), check for "vendor" cpu instead
> of "not generic". The "generic CPU" checks remaining are from
> riscv_cpu_add_misa_properties() and cpu_add_multi_ext_prop() before
> applying default values for the extensions.
>
> This leaves us with:
>
> - vendor CPUs will not allow extension enablement, all other CPUs will;
>
> - generic CPUs will inherit default values for extensions, all others
>   won't.
>
> And now we can add a new, third CPU type, that will allow extensions to
> be enabled and will not inherit defaults, without changing the existing
> logic.
>
> Signed-off-by: Daniel Henrique Barboza 
> Reviewed-by: Andrew Jones 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/tcg/tcg-cpu.c | 13 +
>  1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 093bda2e75..f54069d06f 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -612,6 +612,11 @@ static bool riscv_cpu_is_generic(Object *cpu_obj)
>  return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
>  }
>
> +static bool riscv_cpu_is_vendor(Object *cpu_obj)
> +{
> +return object_dynamic_cast(cpu_obj, TYPE_RISCV_VENDOR_CPU) != NULL;
> +}
> +
>  /*
>   * We'll get here via the following path:
>   *
> @@ -674,7 +679,7 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, 
> const char *name,
>  target_ulong misa_bit = misa_ext_cfg->misa_bit;
>  RISCVCPU *cpu = RISCV_CPU(obj);
>  CPURISCVState *env = >env;
> -bool generic_cpu = riscv_cpu_is_generic(obj);
> +bool vendor_cpu = riscv_cpu_is_vendor(obj);
>  bool prev_val, value;
>
>  if (!visit_type_bool(v, name, , errp)) {
> @@ -688,7 +693,7 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, 
> const char *name,
>  }
>
>  if (value) {
> -if (!generic_cpu) {
> +if (vendor_cpu) {
>  g_autofree char *cpuname = riscv_cpu_get_name(cpu);
>  error_setg(errp, "'%s' CPU does not allow enabling extensions",
> cpuname);
> @@ -793,7 +798,7 @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor 
> *v, const char *name,
>  {
>  const RISCVCPUMultiExtConfig *multi_ext_cfg = opaque;
>  RISCVCPU *cpu = RISCV_CPU(obj);
> -bool generic_cpu = riscv_cpu_is_generic(obj);
> +bool vendor_cpu = riscv_cpu_is_vendor(obj);
>  bool prev_val, value;
>
>  if (!visit_type_bool(v, name, , errp)) {
> @@ -817,7 +822,7 @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor 
> *v, const char *name,
>  return;
>  }
>
> -if (value && !generic_cpu) {
> +if (value && vendor_cpu) {
>  g_autofree char *cpuname = riscv_cpu_get_name(cpu);
>  error_setg(errp, "'%s' CPU does not allow enabling extensions",
> cpuname);
> --
> 2.41.0
>
>



Re: [PATCH v8 01/19] target/riscv: create TYPE_RISCV_VENDOR_CPU

2023-11-01 Thread Alistair Francis
On Thu, Nov 2, 2023 at 7:53 AM Daniel Henrique Barboza
 wrote:
>
> We want to add a new CPU type for bare CPUs that will inherit specific
> traits of the 2 existing types:
>
> - it will allow for extensions to be enabled/disabled, like generic
>   CPUs;
>
> - it will NOT inherit defaults, like vendor CPUs.
>
> We can make this conditions met by adding an explicit type for the
> existing vendor CPUs and change the existing logic to not imply that
> "not generic" means vendor CPUs.
>
> Let's add the "vendor" CPU type first.
>
> Signed-off-by: Daniel Henrique Barboza 
> Reviewed-by: Andrew Jones 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu-qom.h |  1 +
>  target/riscv/cpu.c | 30 +-
>  2 files changed, 22 insertions(+), 9 deletions(-)
>
> diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
> index f3fbe37a2c..7831e86d37 100644
> --- a/target/riscv/cpu-qom.h
> +++ b/target/riscv/cpu-qom.h
> @@ -24,6 +24,7 @@
>
>  #define TYPE_RISCV_CPU "riscv-cpu"
>  #define TYPE_RISCV_DYNAMIC_CPU "riscv-dynamic-cpu"
> +#define TYPE_RISCV_VENDOR_CPU "riscv-vendor-cpu"
>
>  #define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU
>  #define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX)
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index f40da4c661..822970345c 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1725,6 +1725,13 @@ void riscv_cpu_list(void)
>  .instance_init = initfn   \
>  }
>
> +#define DEFINE_VENDOR_CPU(type_name, initfn) \
> +{\
> +.name = type_name,   \
> +.parent = TYPE_RISCV_VENDOR_CPU, \
> +.instance_init = initfn  \
> +}
> +
>  static const TypeInfo riscv_cpu_type_infos[] = {
>  {
>  .name = TYPE_RISCV_CPU,
> @@ -1742,21 +1749,26 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>  .parent = TYPE_RISCV_CPU,
>  .abstract = true,
>  },
> +{
> +.name = TYPE_RISCV_VENDOR_CPU,
> +.parent = TYPE_RISCV_CPU,
> +.abstract = true,
> +},
>  DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY,  riscv_any_cpu_init),
>  DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX,  riscv_max_cpu_init),
>  #if defined(TARGET_RISCV32)
>  DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE32,   rv32_base_cpu_init),
> -DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
> -DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31,   rv32_sifive_e_cpu_init),
> -DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34,   rv32_imafcu_nommu_cpu_init),
> -DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,   rv32_sifive_u_cpu_init),
> +DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_IBEX,rv32_ibex_cpu_init),
> +DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E31,  rv32_sifive_e_cpu_init),
> +DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E34,  
> rv32_imafcu_nommu_cpu_init),
> +DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U34,  rv32_sifive_u_cpu_init),
>  #elif defined(TARGET_RISCV64)
>  DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE64,   rv64_base_cpu_init),
> -DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51,   rv64_sifive_e_cpu_init),
> -DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,   rv64_sifive_u_cpu_init),
> -DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
> -DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906,   rv64_thead_c906_cpu_init),
> -DEFINE_CPU(TYPE_RISCV_CPU_VEYRON_V1,rv64_veyron_v1_cpu_init),
> +DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E51,  rv64_sifive_e_cpu_init),
> +DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U54,  rv64_sifive_u_cpu_init),
> +DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SHAKTI_C,rv64_sifive_u_cpu_init),
> +DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906,  rv64_thead_c906_cpu_init),
> +DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1,   rv64_veyron_v1_cpu_init),
>  DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128,  rv128_base_cpu_init),
>  #endif
>  };
> --
> 2.41.0
>
>



[PATCH v3 67/88] target/hppa: Implement HSHLADD, HSHRADD

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/helper.h |  2 ++
 target/hppa/insns.decode | 12 ++--
 target/hppa/op_helper.c  | 32 
 target/hppa/translate.c  | 32 
 4 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index 51c24b31b0..c5f1db574b 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -17,6 +17,8 @@ DEF_HELPER_FLAGS_1(ldc_check, TCG_CALL_NO_RWG, void, tl)
 DEF_HELPER_FLAGS_2(hadd_ss, TCG_CALL_NO_RWG, i64, i64, i64)
 DEF_HELPER_FLAGS_2(hadd_us, TCG_CALL_NO_RWG, i64, i64, i64)
 DEF_HELPER_FLAGS_2(havg, TCG_CALL_NO_RWG, i64, i64, i64)
+DEF_HELPER_FLAGS_3(hshladd, TCG_CALL_NO_RWG, i64, i64, i64, i32)
+DEF_HELPER_FLAGS_3(hshradd, TCG_CALL_NO_RWG, i64, i64, i64, i32)
 DEF_HELPER_FLAGS_2(hsub_ss, TCG_CALL_NO_RWG, i64, i64, i64)
 DEF_HELPER_FLAGS_2(hsub_us, TCG_CALL_NO_RWG, i64, i64, i64)
 
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index bb5cd267b0..87db726d9e 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -68,6 +68,7 @@
 t r1 r2
 _cf t r1 r2 cf
 _cf_d   t r1 r2 cf d
+_sh t r1 r2 sh
 _cf_d_sht r1 r2 cf d sh
 t r i
 _cf t r i cf
@@ -86,6 +87,7 @@
 @rrr.. r2:5 r1:5  ... t:5   
 @rrr_cf .. r2:5 r1:5 cf:4 ... t:5   _cf
 @rrr_cf_d   .. r2:5 r1:5 cf:4 .. d:1 t:5_cf_d
+@rrr_sh .. r2:5 r1:5  sh:2 . t:5_sh
 @rrr_cf_d_sh.. r2:5 r1:5 cf:4  sh:2 d:1 t:5 _cf_d_sh
 @rrr_cf_d_sh0   .. r2:5 r1:5 cf:4 .. d:1 t:5_cf_d_sh sh=0
 @rri_cf .. r:5  t:5  cf:4 . ... _cf i=%lowsign_11
@@ -187,14 +189,20 @@ dcor_i  10 . 0  10 . .  
@rr_cf_d
 add 10 . .  0110.. . .  @rrr_cf_d_sh
 add_l   10 . .  1010.. . .  @rrr_cf_d_sh
 add_tsv 10 . .  1110.. . .  @rrr_cf_d_sh
-add_c   10 . .  011100 . .  @rrr_cf_d_sh0
+{
+  add_c 10 . .  011100 . .  @rrr_cf_d_sh0
+  hshladd   10 . .  0111.. 0 .  @rrr_sh
+}
 add_c_tsv   10 . .  00 . .  @rrr_cf_d_sh0
 
 sub 10 . .  01 . .  @rrr_cf_d
 sub_tsv 10 . .  11 . .  @rrr_cf_d
 sub_tc  10 . .  010011 . .  @rrr_cf_d
 sub_tsv_tc  10 . .  110011 . .  @rrr_cf_d
-sub_b   10 . .  010100 . .  @rrr_cf_d
+{
+  sub_b 10 . .  010100 . .  @rrr_cf_d
+  hshradd   10 . .  0101.. 0 .  @rrr_sh
+}
 sub_b_tsv   10 . .  110100 . .  @rrr_cf_d
 
 ldil001000 t:5 .i=%assemble_21
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index cba610ac75..9d8e728460 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -455,3 +455,35 @@ uint64_t HELPER(hsub_us)(uint64_t r1, uint64_t r2)
 }
 return ret;
 }
+
+uint64_t HELPER(hshladd)(uint64_t r1, uint64_t r2, uint32_t sh)
+{
+uint64_t ret = 0;
+
+for (int i = 0; i < 64; i += 16) {
+int f1 = sextract64(r1, i, 16);
+int f2 = sextract64(r2, i, 16);
+int fr = (f1 << sh) + f2;
+
+fr = MIN(fr, INT16_MAX);
+fr = MAX(fr, INT16_MIN);
+ret = deposit64(ret, i, 16, fr);
+}
+return ret;
+}
+
+uint64_t HELPER(hshradd)(uint64_t r1, uint64_t r2, uint32_t sh)
+{
+uint64_t ret = 0;
+
+for (int i = 0; i < 64; i += 16) {
+int f1 = sextract64(r1, i, 16);
+int f2 = sextract64(r2, i, 16);
+int fr = (f1 >> sh) + f2;
+
+fr = MIN(fr, INT16_MAX);
+fr = MAX(fr, INT16_MIN);
+ret = deposit64(ret, i, 16, fr);
+}
+return ret;
+}
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index d342df2dfa..dc68d5a263 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2809,6 +2809,28 @@ static bool do_multimedia_sh(DisasContext *ctx, arg_rri 
*a,
 return nullify_end(ctx);
 }
 
+static bool do_multimedia_shadd(DisasContext *ctx, arg_rrr_sh *a,
+void (*fn)(TCGv_i64, TCGv_i64,
+   TCGv_i64, TCGv_i32))
+{
+TCGv_i64 r1, r2, dest;
+
+if (!ctx->is_pa20) {
+return false;
+}
+
+nullify_over(ctx);
+
+r1 = load_gpr(ctx, a->r1);
+r2 = load_gpr(ctx, a->r2);
+dest = dest_gpr(ctx, a->t);
+
+fn(dest, r1, r2, tcg_constant_i32(a->sh));
+save_gpr(ctx, a->t, dest);
+
+return nullify_end(ctx);
+}
+
 static bool trans_hadd(DisasContext *ctx, arg_rrr *a)
 {
 return do_multimedia(ctx, a, tcg_gen_vec_add16_i64);
@@ -2844,6 +2866,16 @@ static bool trans_hshr_u(DisasContext 

回复: 来自Leo Hou的邮件

2023-11-01 Thread leohou...@163.com
hi , all


  Does qemu plan to support CPU heterogeneity?










[PATCH v3 73/88] include/hw/elf: Remove truncating signed casts

2023-11-01 Thread Richard Henderson
There's nothing about elf that specifically requires signed vs unsigned.
This is very much a target-specific preference.

In the meantime, casting low and high from uint64_t back to Elf_SWord
to uint64_t discards high bits that might have been set by translate_fn.

Signed-off-by: Richard Henderson 
---
 include/hw/elf_ops.h | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
index dffb0e73d2..0a5c258fe6 100644
--- a/include/hw/elf_ops.h
+++ b/include/hw/elf_ops.h
@@ -385,10 +385,11 @@ static ssize_t glue(load_elf, SZ)(const char *name, int 
fd,
 }
 
 if (pflags) {
-*pflags = (elf_word)ehdr.e_flags;
+*pflags = ehdr.e_flags;
+}
+if (pentry) {
+*pentry = ehdr.e_entry;
 }
-if (pentry)
-*pentry = (uint64_t)(elf_sword)ehdr.e_entry;
 
 glue(load_symbols, SZ)(, fd, must_swab, clear_lsb, sym_cb);
 
@@ -610,10 +611,12 @@ static ssize_t glue(load_elf, SZ)(const char *name, int 
fd,
 }
 }
 
-if (lowaddr)
-*lowaddr = (uint64_t)(elf_sword)low;
-if (highaddr)
-*highaddr = (uint64_t)(elf_sword)high;
+if (lowaddr) {
+*lowaddr = low;
+}
+if (highaddr) {
+*highaddr = high;
+}
 ret = total_size;
  fail:
 if (mapped_file) {
-- 
2.34.1




[PATCH v3 86/88] hw/hppa: Turn on 64-bit CPU for C3700 machine

2023-11-01 Thread Richard Henderson
From: Helge Deller 

Signed-off-by: Helge Deller 
---
 hw/hppa/machine.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 43c7afb89d..da9ca85806 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -696,7 +696,7 @@ static void HP_C3700_machine_init_class_init(ObjectClass 
*oc, void *data)
 NMIClass *nc = NMI_CLASS(oc);
 
 mc->desc = "HP C3700 workstation";
-mc->default_cpu_type = TYPE_HPPA_CPU;
+mc->default_cpu_type = TYPE_HPPA64_CPU;
 mc->init = machine_HP_C3700_init;
 mc->reset = hppa_machine_reset;
 mc->block_default_type = IF_SCSI;
-- 
2.34.1




[PATCH v3 58/88] target/hppa: Remove most of the TARGET_REGISTER_BITS redirections

2023-11-01 Thread Richard Henderson
Remove all but those intended to change type to or from i64.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 910 ++--
 1 file changed, 406 insertions(+), 504 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 2c3e114b86..520a375e3a 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -36,110 +36,15 @@
 /* Since we have a distinction between register size and address size,
we need to redefine all of these.  */
 
-#undef TCGv
-#undef tcg_temp_new
-#undef tcg_global_mem_new
-
-#define TCGv_tl  TCGv_i64
-#define tcg_temp_new_tl  tcg_temp_new_i64
 #define tcg_gen_extu_reg_tl  tcg_gen_mov_i64
-
-#define TCGv_reg TCGv_i64
-
-#define tcg_temp_new tcg_temp_new_i64
-#define tcg_global_mem_new   tcg_global_mem_new_i64
-
-#define tcg_gen_movi_reg tcg_gen_movi_i64
-#define tcg_gen_mov_reg  tcg_gen_mov_i64
-#define tcg_gen_ld8u_reg tcg_gen_ld8u_i64
-#define tcg_gen_ld8s_reg tcg_gen_ld8s_i64
-#define tcg_gen_ld16u_regtcg_gen_ld16u_i64
-#define tcg_gen_ld16s_regtcg_gen_ld16s_i64
-#define tcg_gen_ld32u_regtcg_gen_ld32u_i64
-#define tcg_gen_ld32s_regtcg_gen_ld32s_i64
-#define tcg_gen_ld_reg   tcg_gen_ld_i64
-#define tcg_gen_st8_reg  tcg_gen_st8_i64
-#define tcg_gen_st16_reg tcg_gen_st16_i64
-#define tcg_gen_st32_reg tcg_gen_st32_i64
-#define tcg_gen_st_reg   tcg_gen_st_i64
-#define tcg_gen_add_reg  tcg_gen_add_i64
-#define tcg_gen_addi_reg tcg_gen_addi_i64
-#define tcg_gen_sub_reg  tcg_gen_sub_i64
-#define tcg_gen_neg_reg  tcg_gen_neg_i64
-#define tcg_gen_subfi_regtcg_gen_subfi_i64
-#define tcg_gen_subi_reg tcg_gen_subi_i64
-#define tcg_gen_and_reg  tcg_gen_and_i64
-#define tcg_gen_andi_reg tcg_gen_andi_i64
-#define tcg_gen_or_reg   tcg_gen_or_i64
-#define tcg_gen_ori_reg  tcg_gen_ori_i64
-#define tcg_gen_xor_reg  tcg_gen_xor_i64
-#define tcg_gen_xori_reg tcg_gen_xori_i64
-#define tcg_gen_not_reg  tcg_gen_not_i64
-#define tcg_gen_shl_reg  tcg_gen_shl_i64
-#define tcg_gen_shli_reg tcg_gen_shli_i64
-#define tcg_gen_shr_reg  tcg_gen_shr_i64
-#define tcg_gen_shri_reg tcg_gen_shri_i64
-#define tcg_gen_sar_reg  tcg_gen_sar_i64
-#define tcg_gen_sari_reg tcg_gen_sari_i64
-#define tcg_gen_brcond_reg   tcg_gen_brcond_i64
-#define tcg_gen_brcondi_reg  tcg_gen_brcondi_i64
-#define tcg_gen_setcond_reg  tcg_gen_setcond_i64
-#define tcg_gen_setcondi_reg tcg_gen_setcondi_i64
-#define tcg_gen_mul_reg  tcg_gen_mul_i64
-#define tcg_gen_muli_reg tcg_gen_muli_i64
-#define tcg_gen_div_reg  tcg_gen_div_i64
-#define tcg_gen_rem_reg  tcg_gen_rem_i64
-#define tcg_gen_divu_reg tcg_gen_divu_i64
-#define tcg_gen_remu_reg tcg_gen_remu_i64
-#define tcg_gen_discard_reg  tcg_gen_discard_i64
-#define tcg_gen_trunc_reg_i32 tcg_gen_extrl_i64_i32
 #define tcg_gen_trunc_i64_reg tcg_gen_mov_i64
-#define tcg_gen_extu_i32_reg tcg_gen_extu_i32_i64
-#define tcg_gen_ext_i32_reg  tcg_gen_ext_i32_i64
 #define tcg_gen_extu_reg_i64 tcg_gen_mov_i64
 #define tcg_gen_ext_reg_i64  tcg_gen_mov_i64
-#define tcg_gen_ext8u_regtcg_gen_ext8u_i64
-#define tcg_gen_ext8s_regtcg_gen_ext8s_i64
-#define tcg_gen_ext16u_reg   tcg_gen_ext16u_i64
-#define tcg_gen_ext16s_reg   tcg_gen_ext16s_i64
-#define tcg_gen_ext32u_reg   tcg_gen_ext32u_i64
-#define tcg_gen_ext32s_reg   tcg_gen_ext32s_i64
-#define tcg_gen_bswap16_reg  tcg_gen_bswap16_i64
-#define tcg_gen_bswap32_reg  tcg_gen_bswap32_i64
-#define tcg_gen_bswap64_reg  tcg_gen_bswap64_i64
-#define tcg_gen_concat_reg_i64 tcg_gen_concat32_i64
-#define tcg_gen_andc_reg tcg_gen_andc_i64
-#define tcg_gen_eqv_reg  tcg_gen_eqv_i64
-#define tcg_gen_nand_reg tcg_gen_nand_i64
-#define tcg_gen_nor_reg  tcg_gen_nor_i64
-#define tcg_gen_orc_reg  tcg_gen_orc_i64
-#define tcg_gen_clz_reg  tcg_gen_clz_i64
-#define tcg_gen_ctz_reg  tcg_gen_ctz_i64
-#define tcg_gen_clzi_reg tcg_gen_clzi_i64
-#define tcg_gen_ctzi_reg tcg_gen_ctzi_i64
-#define tcg_gen_clrsb_regtcg_gen_clrsb_i64
-#define tcg_gen_ctpop_regtcg_gen_ctpop_i64
-#define tcg_gen_rotl_reg tcg_gen_rotl_i64
-#define tcg_gen_rotli_regtcg_gen_rotli_i64
-#define tcg_gen_rotr_reg tcg_gen_rotr_i64
-#define tcg_gen_rotri_regtcg_gen_rotri_i64
-#define tcg_gen_deposit_reg  tcg_gen_deposit_i64
-#define tcg_gen_deposit_z_reg tcg_gen_deposit_z_i64
-#define tcg_gen_extract_reg  tcg_gen_extract_i64
-#define tcg_gen_sextract_reg tcg_gen_sextract_i64
-#define tcg_gen_extract2_reg tcg_gen_extract2_i64
-#define tcg_constant_reg tcg_constant_i64
-#define tcg_gen_movcond_reg  tcg_gen_movcond_i64
-#define tcg_gen_add2_reg tcg_gen_add2_i64
-#define tcg_gen_sub2_reg tcg_gen_sub2_i64
-#define tcg_gen_qemu_ld_reg  tcg_gen_qemu_ld_i64
-#define tcg_gen_qemu_st_reg  tcg_gen_qemu_st_i64
-#define tcg_gen_atomic_xchg_reg tcg_gen_atomic_xchg_i64
-#define 

[PATCH v3 88/88] hw/hppa: Map PDC ROM and I/O memory area into lower memory

2023-11-01 Thread Richard Henderson
From: Helge Deller 

When running a 64-bit CPU in 32-bit mode (e.g. when using a
32-bit kernel) the PDC ROM and I/O area has to be accessible
in the 0xf000 memory region.

Signed-off-by: Helge Deller 
---
 hw/hppa/machine.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index a3222d3a96..e488914bba 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -603,6 +603,7 @@ static void machine_HP_C3700_init(MachineState *machine)
 AstroState *astro;
 DeviceState *astro_dev;
 MemoryRegion *addr_space = get_system_memory();
+MemoryRegion *io_low_alias = g_new(MemoryRegion, 2);
 TranslateFn *translate;
 
 /* Create CPUs and RAM.  */
@@ -614,6 +615,20 @@ static void machine_HP_C3700_init(MachineState *machine)
 exit(1);
 }
 
+/* map PDC ROM into lower memory region, needed if PSW.W=0 */
+memory_region_init_alias(_low_alias[0], NULL, "firmware-alias",
+ addr_space, translate(NULL, FIRMWARE_START),
+ FIRMWARE_END - FIRMWARE_START);
+memory_region_add_subregion(addr_space, (uint32_t) FIRMWARE_START,
+ _low_alias[0]);
+
+/* map all of I/O area into lower memory region, needed if PSW.W=0 */
+memory_region_init_alias(_low_alias[1], NULL, "iomem-alias",
+ addr_space, translate(NULL, 0xf100UL),
+ 0xf00UL);
+memory_region_add_subregion(addr_space, (uint32_t) 0xf100UL,
+ _low_alias[1]);
+
 /* Init Astro and the Elroys (PCI host bus chips).  */
 astro = astro_init();
 astro_dev = DEVICE(astro);
-- 
2.34.1




Re: [PATCH 1/1] MAINTAINERS: update mail address for Weiwei Li

2023-11-01 Thread Alistair Francis
On Mon, Oct 30, 2023 at 6:17 PM Weiwei Li  wrote:
>
> My Iscas mail account will be disabled soon, change to my personal
> gmail account.
>
> Signed-off-by: Weiwei Li 

Thanks!

I hope you can continue working on QEMU :)

Applied to riscv-to-apply.next

Alistair

> ---
>  MAINTAINERS | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index cd8d6b140f..aa5c5d4bff 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -323,7 +323,7 @@ RISC-V TCG CPUs
>  M: Palmer Dabbelt 
>  M: Alistair Francis 
>  M: Bin Meng 
> -R: Weiwei Li 
> +R: Weiwei Li 
>  R: Daniel Henrique Barboza 
>  R: Liu Zhiwei 
>  L: qemu-ri...@nongnu.org
> --
> 2.25.1
>
>



[PATCH v3 45/88] target/hppa: Decode d for bb instructions

2023-11-01 Thread Richard Henderson
Manipulate the shift count so that the bit to be tested
is always placed at the MSB.

Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode | 4 ++--
 target/hppa/translate.c  | 6 ++
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index ad454adcbb..b185523021 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -290,8 +290,8 @@ fmpysub_d   100110 . . . . 1 .  
@mpyadd
 # Conditional Branches
 
 
-bb_sar  11 0 r:5 c:1 10 ... n:1 .  disp=%assemble_12
-bb_imm  110001 p:5   r:5 c:1 10 ... n:1 .  disp=%assemble_12
+bb_sar  11 0 r:5 c:1 1 d:1 ... n:1 . disp=%assemble_12
+bb_imm  110001 p:5   r:5 c:1 1 d:1 ... n:1 . disp=%assemble_12
 
 movb110010 . . ... ... . .  @rrb_cf f=0
 movbi   110011 . . ... ... . .  @rib_cf f=0
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index f2b2933c88..e326f63866 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3172,13 +3172,12 @@ static bool trans_bb_sar(DisasContext *ctx, arg_bb_sar 
*a)
 {
 TCGv_reg tmp, tcg_r;
 DisasCond cond;
-bool d = false;
 
 nullify_over(ctx);
 
 tmp = tcg_temp_new();
 tcg_r = load_gpr(ctx, a->r);
-if (cond_need_ext(ctx, d)) {
+if (cond_need_ext(ctx, a->d)) {
 /* Force shift into [32,63] */
 tcg_gen_ori_reg(tmp, cpu_sar, 32);
 tcg_gen_shl_reg(tmp, tcg_r, tmp);
@@ -3194,14 +3193,13 @@ static bool trans_bb_imm(DisasContext *ctx, arg_bb_imm 
*a)
 {
 TCGv_reg tmp, tcg_r;
 DisasCond cond;
-bool d = false;
 int p;
 
 nullify_over(ctx);
 
 tmp = tcg_temp_new();
 tcg_r = load_gpr(ctx, a->r);
-p = a->p | (cond_need_ext(ctx, d) ? 32 : 0);
+p = a->p | (cond_need_ext(ctx, a->d) ? 32 : 0);
 tcg_gen_shli_reg(tmp, tcg_r, p);
 
 cond = cond_make_0(a->c ? TCG_COND_GE : TCG_COND_LT, tmp);
-- 
2.34.1




[PATCH v3 71/88] target/hppa: Precompute zero into DisasContext

2023-11-01 Thread Richard Henderson
Reduce the number of times we look for the constant 0.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 34 ++
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 36653486fb..5d780bcf56 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -53,6 +53,8 @@ typedef struct DisasContext {
 DisasCond null_cond;
 TCGLabel *null_lab;
 
+TCGv_i64 zero;
+
 uint32_t insn;
 uint32_t tb_flags;
 int mmu_idx;
@@ -1017,14 +1019,13 @@ static void do_add(DisasContext *ctx, unsigned rt, 
TCGv_i64 in1,
 }
 
 if (!is_l || cond_need_cb(c)) {
-TCGv_i64 zero = tcg_constant_i64(0);
 cb_msb = tcg_temp_new_i64();
 cb = tcg_temp_new_i64();
 
-tcg_gen_add2_i64(dest, cb_msb, in1, zero, in2, zero);
+tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero, in2, ctx->zero);
 if (is_c) {
 tcg_gen_add2_i64(dest, cb_msb, dest, cb_msb,
- get_psw_carry(ctx, d), zero);
+ get_psw_carry(ctx, d), ctx->zero);
 }
 tcg_gen_xor_i64(cb, in1, in2);
 tcg_gen_xor_i64(cb, cb, dest);
@@ -1102,7 +1103,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, 
TCGv_i64 in1,
TCGv_i64 in2, bool is_tsv, bool is_b,
bool is_tc, unsigned cf, bool d)
 {
-TCGv_i64 dest, sv, cb, cb_msb, zero, tmp;
+TCGv_i64 dest, sv, cb, cb_msb, tmp;
 unsigned c = cf >> 1;
 DisasCond cond;
 
@@ -1110,12 +,12 @@ static void do_sub(DisasContext *ctx, unsigned rt, 
TCGv_i64 in1,
 cb = tcg_temp_new_i64();
 cb_msb = tcg_temp_new_i64();
 
-zero = tcg_constant_i64(0);
 if (is_b) {
 /* DEST,C = IN1 + ~IN2 + C.  */
 tcg_gen_not_i64(cb, in2);
-tcg_gen_add2_i64(dest, cb_msb, in1, zero, get_psw_carry(ctx, d), zero);
-tcg_gen_add2_i64(dest, cb_msb, dest, cb_msb, cb, zero);
+tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero,
+ get_psw_carry(ctx, d), ctx->zero);
+tcg_gen_add2_i64(dest, cb_msb, dest, cb_msb, cb, ctx->zero);
 tcg_gen_xor_i64(cb, cb, in1);
 tcg_gen_xor_i64(cb, cb, dest);
 } else {
@@ -1124,7 +1125,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, 
TCGv_i64 in1,
  * operations by seeding the high word with 1 and subtracting.
  */
 TCGv_i64 one = tcg_constant_i64(1);
-tcg_gen_sub2_i64(dest, cb_msb, in1, one, in2, zero);
+tcg_gen_sub2_i64(dest, cb_msb, in1, one, in2, ctx->zero);
 tcg_gen_eqv_i64(cb, in1, in2);
 tcg_gen_xor_i64(cb, cb, dest);
 }
@@ -2458,7 +2459,7 @@ static bool trans_lci(DisasContext *ctx, arg_lci *a)
physical address.  Two addresses with the same CI have a coherent
view of the cache.  Our implementation is to return 0 for all,
since the entire address space is coherent.  */
-save_gpr(ctx, a->t, tcg_constant_i64(0));
+save_gpr(ctx, a->t, ctx->zero);
 
 cond_free(>null_cond);
 return true;
@@ -2667,7 +2668,7 @@ static bool trans_dcor_i(DisasContext *ctx, arg_rr_cf_d 
*a)
 
 static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
 {
-TCGv_i64 dest, add1, add2, addc, zero, in1, in2;
+TCGv_i64 dest, add1, add2, addc, in1, in2;
 TCGv_i64 cout;
 
 nullify_over(ctx);
@@ -2679,7 +2680,6 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
 add2 = tcg_temp_new_i64();
 addc = tcg_temp_new_i64();
 dest = tcg_temp_new_i64();
-zero = tcg_constant_i64(0);
 
 /* Form R1 << 1 | PSW[CB]{8}.  */
 tcg_gen_add_i64(add1, in1, in1);
@@ -2695,8 +2695,9 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
 tcg_gen_xor_i64(add2, in2, addc);
 tcg_gen_andi_i64(addc, addc, 1);
 
-tcg_gen_add2_i64(dest, cpu_psw_cb_msb, add1, zero, add2, zero);
-tcg_gen_add2_i64(dest, cpu_psw_cb_msb, dest, cpu_psw_cb_msb, addc, zero);
+tcg_gen_add2_i64(dest, cpu_psw_cb_msb, add1, ctx->zero, add2, ctx->zero);
+tcg_gen_add2_i64(dest, cpu_psw_cb_msb, dest, cpu_psw_cb_msb,
+ addc, ctx->zero);
 
 /* Write back the result register.  */
 save_gpr(ctx, a->t, dest);
@@ -2996,7 +2997,7 @@ static bool trans_st(DisasContext *ctx, arg_ldst *a)
 static bool trans_ldc(DisasContext *ctx, arg_ldst *a)
 {
 MemOp mop = MO_TE | MO_ALIGN | a->size;
-TCGv_i64 zero, dest, ofs;
+TCGv_i64 dest, ofs;
 TCGv_i64 addr;
 
 if (!ctx->is_pa20 && a->size > MO_32) {
@@ -3026,8 +3027,7 @@ static bool trans_ldc(DisasContext *ctx, arg_ldst *a)
  */
 gen_helper_ldc_check(addr);
 
-zero = tcg_constant_i64(0);
-tcg_gen_atomic_xchg_i64(dest, addr, zero, ctx->mmu_idx, mop);
+tcg_gen_atomic_xchg_i64(dest, addr, ctx->zero, ctx->mmu_idx, mop);
 
 if (a->m) {
 save_gpr(ctx, a->b, ofs);
@@ -4380,6 +4380,8 @@ static void 

[PATCH v3 61/88] target/hppa: Use tcg_temp_new_i64 not tcg_temp_new

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 162 
 1 file changed, 82 insertions(+), 80 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index ce8d812e04..59d172f355 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -32,6 +32,8 @@
 #include "exec/helper-info.c.inc"
 #undef  HELPER_H
 
+/* Choose to use explicit sizes within this file. */
+#undef tcg_temp_new
 
 typedef struct DisasCond {
 TCGCond c;
@@ -269,15 +271,15 @@ static DisasCond cond_make_0_tmp(TCGCond c, TCGv_i64 a0)
 
 static DisasCond cond_make_0(TCGCond c, TCGv_i64 a0)
 {
-TCGv_i64 tmp = tcg_temp_new();
+TCGv_i64 tmp = tcg_temp_new_i64();
 tcg_gen_mov_i64(tmp, a0);
 return cond_make_0_tmp(c, tmp);
 }
 
 static DisasCond cond_make(TCGCond c, TCGv_i64 a0, TCGv_i64 a1)
 {
-TCGv_i64 t0 = tcg_temp_new();
-TCGv_i64 t1 = tcg_temp_new();
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i64 t1 = tcg_temp_new_i64();
 
 tcg_gen_mov_i64(t0, a0);
 tcg_gen_mov_i64(t1, a1);
@@ -302,7 +304,7 @@ static void cond_free(DisasCond *cond)
 static TCGv_i64 load_gpr(DisasContext *ctx, unsigned reg)
 {
 if (reg == 0) {
-TCGv_i64 t = tcg_temp_new();
+TCGv_i64 t = tcg_temp_new_i64();
 tcg_gen_movi_i64(t, 0);
 return t;
 } else {
@@ -313,7 +315,7 @@ static TCGv_i64 load_gpr(DisasContext *ctx, unsigned reg)
 static TCGv_i64 dest_gpr(DisasContext *ctx, unsigned reg)
 {
 if (reg == 0 || ctx->null_cond.c != TCG_COND_NEVER) {
-return tcg_temp_new();
+return tcg_temp_new_i64();
 } else {
 return cpu_gr[reg];
 }
@@ -437,7 +439,7 @@ static void nullify_over(DisasContext *ctx)
 
 /* If we're using PSW[N], copy it to a temp because... */
 if (ctx->null_cond.a0 == cpu_psw_n) {
-ctx->null_cond.a0 = tcg_temp_new();
+ctx->null_cond.a0 = tcg_temp_new_i64();
 tcg_gen_mov_i64(ctx->null_cond.a0, cpu_psw_n);
 }
 /* ... we clear it before branching over the implementation,
@@ -657,14 +659,14 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, 
bool d,
 break;
 case 1: /* = / <>(Z / !Z) */
 if (cond_need_ext(ctx, d)) {
-tmp = tcg_temp_new();
+tmp = tcg_temp_new_i64();
 tcg_gen_ext32u_i64(tmp, res);
 res = tmp;
 }
 cond = cond_make_0(TCG_COND_EQ, res);
 break;
 case 2: /* < / >=(N ^ V / !(N ^ V) */
-tmp = tcg_temp_new();
+tmp = tcg_temp_new_i64();
 tcg_gen_xor_i64(tmp, res, sv);
 if (cond_need_ext(ctx, d)) {
 tcg_gen_ext32s_i64(tmp, tmp);
@@ -681,7 +683,7 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, 
bool d,
  *   !(~(res ^ sv) >> 31) | !res
  *   !(~(res ^ sv) >> 31 & res)
  */
-tmp = tcg_temp_new();
+tmp = tcg_temp_new_i64();
 tcg_gen_eqv_i64(tmp, res, sv);
 if (cond_need_ext(ctx, d)) {
 tcg_gen_sextract_i64(tmp, tmp, 31, 1);
@@ -698,7 +700,7 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, 
bool d,
 cond = cond_make_0(TCG_COND_EQ, cb_msb);
 break;
 case 5: /* ZNV / VNZ (!C | Z / C & !Z) */
-tmp = tcg_temp_new();
+tmp = tcg_temp_new_i64();
 tcg_gen_neg_i64(tmp, cb_msb);
 tcg_gen_and_i64(tmp, tmp, res);
 if (cond_need_ext(ctx, d)) {
@@ -708,14 +710,14 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, 
bool d,
 break;
 case 6: /* SV / NSV  (V / !V) */
 if (cond_need_ext(ctx, d)) {
-tmp = tcg_temp_new();
+tmp = tcg_temp_new_i64();
 tcg_gen_ext32s_i64(tmp, sv);
 sv = tmp;
 }
 cond = cond_make_0(TCG_COND_LT, sv);
 break;
 case 7: /* OD / EV */
-tmp = tcg_temp_new();
+tmp = tcg_temp_new_i64();
 tcg_gen_andi_i64(tmp, res, 1);
 cond = cond_make_0_tmp(TCG_COND_NE, tmp);
 break;
@@ -769,8 +771,8 @@ static DisasCond do_sub_cond(DisasContext *ctx, unsigned 
cf, bool d,
 tc = tcg_invert_cond(tc);
 }
 if (cond_need_ext(ctx, d)) {
-TCGv_i64 t1 = tcg_temp_new();
-TCGv_i64 t2 = tcg_temp_new();
+TCGv_i64 t1 = tcg_temp_new_i64();
+TCGv_i64 t2 = tcg_temp_new_i64();
 
 if (ext_uns) {
 tcg_gen_ext32u_i64(t1, in1);
@@ -846,7 +848,7 @@ static DisasCond do_log_cond(DisasContext *ctx, unsigned 
cf, bool d,
 }
 
 if (cond_need_ext(ctx, d)) {
-TCGv_i64 tmp = tcg_temp_new();
+TCGv_i64 tmp = tcg_temp_new_i64();
 
 if (ext_uns) {
 tcg_gen_ext32u_i64(tmp, res);
@@ -891,8 +893,8 @@ static DisasCond do_unit_cond(unsigned cf, bool d, TCGv_i64 
res,
  * do our normal thing and compute carry-in of bit B+1 since that
  * leaves us with carry bits spread 

[PATCH v3 70/88] target/hppa: Fix interruption based on default PSW

2023-11-01 Thread Richard Henderson
From: Helge Deller 

The default PSW is set by the operating system with the PDC_PSW
firmware call.  Use that setting to decide if wide mode is to be
enabled for interruptions and EIRR usage.

Signed-off-by: Helge Deller 
Reviewed-by: Richard Henderson 
Signed-off-by: Richard Henderson 
---
 target/hppa/cpu.h|  2 ++
 target/hppa/int_helper.c | 18 ++
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index ea676ba062..ea8e7e99a4 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -137,6 +137,8 @@
 #define PSW_SM_W 0x200  /* PA2.0 only : Enable Wide Mode */
 
 #define CR_RC0
+#define CR_PSW_DEFAULT   6  /* see SeaBIOS PDC_PSW firmware call */
+#define  PDC_PSW_WIDE_BIT 2
 #define CR_PID1  8
 #define CR_PID2  9
 #define CR_PID3  12
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index f355c4c76b..a11d607b31 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -52,9 +52,17 @@ static void io_eir_write(void *opaque, hwaddr addr,
  uint64_t data, unsigned size)
 {
 HPPACPU *cpu = opaque;
-int le_bit = ~data & 31;
+CPUHPPAState *env = >env;
+int widthm1 = 31;
+int le_bit;
 
-cpu->env.cr[CR_EIRR] |= (target_ulong)1 << le_bit;
+/* The default PSW.W controls the width of EIRR. */
+if (hppa_is_pa20(env) && env->cr[CR_PSW_DEFAULT] & PDC_PSW_WIDE_BIT) {
+widthm1 = 63;
+}
+le_bit = ~data & widthm1;
+
+env->cr[CR_EIRR] |= 1ull << le_bit;
 eval_interrupt(cpu);
 }
 
@@ -104,8 +112,10 @@ void hppa_cpu_do_interrupt(CPUState *cs)
 /* step 1 */
 env->cr[CR_IPSW] = old_psw = cpu_hppa_get_psw(env);
 
-/* step 2 -- note PSW_W == 0 for !HPPA64.  */
-cpu_hppa_put_psw(env, PSW_W | (i == EXCP_HPMC ? PSW_M : 0));
+/* step 2 -- Note PSW_W is masked out again for pa1.x */
+cpu_hppa_put_psw(env,
+ (env->cr[CR_PSW_DEFAULT] & PDC_PSW_WIDE_BIT ? PSW_W : 0) |
+ (i == EXCP_HPMC ? PSW_M : 0));
 
 /* step 3 */
 env->cr[CR_IIASQ] = iasq_f >> 32;
-- 
2.34.1




[PATCH v3 35/88] target/hppa: Pass d to do_sed_cond

2023-11-01 Thread Richard Henderson
Hoist the resolution of d up one level above do_sed_cond.
The MOVB comparison and the existing shift/extract/deposit
are all 32-bit.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index ac7f1f048c..eb4605a9c7 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1050,10 +1050,10 @@ static DisasCond do_log_cond(DisasContext *ctx, 
unsigned cf, bool d,
 
 /* Similar, but for shift/extract/deposit conditions.  */
 
-static DisasCond do_sed_cond(DisasContext *ctx, unsigned orig, TCGv_reg res)
+static DisasCond do_sed_cond(DisasContext *ctx, unsigned orig, bool d,
+ TCGv_reg res)
 {
 unsigned c, f;
-bool d = false;
 
 /* Convert the compressed condition codes to standard.
0-2 are the same as logicals (nv,<,<=), while 3 is OD.
@@ -3224,7 +3224,8 @@ static bool trans_movb(DisasContext *ctx, arg_movb *a)
 tcg_gen_mov_reg(dest, cpu_gr[a->r1]);
 }
 
-cond = do_sed_cond(ctx, a->c, dest);
+/* All MOVB conditions are 32-bit. */
+cond = do_sed_cond(ctx, a->c, false, dest);
 return do_cbranch(ctx, a->disp, a->n, );
 }
 
@@ -3238,7 +3239,8 @@ static bool trans_movbi(DisasContext *ctx, arg_movbi *a)
 dest = dest_gpr(ctx, a->r);
 tcg_gen_movi_reg(dest, a->i);
 
-cond = do_sed_cond(ctx, a->c, dest);
+/* All MOVBI conditions are 32-bit. */
+cond = do_sed_cond(ctx, a->c, false, dest);
 return do_cbranch(ctx, a->disp, a->n, );
 }
 
@@ -3276,7 +3278,7 @@ static bool trans_shrpw_sar(DisasContext *ctx, 
arg_shrpw_sar *a)
 /* Install the new nullification.  */
 cond_free(>null_cond);
 if (a->c) {
-ctx->null_cond = do_sed_cond(ctx, a->c, dest);
+ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
 }
 return nullify_end(ctx);
 }
@@ -3312,7 +3314,7 @@ static bool trans_shrpw_imm(DisasContext *ctx, 
arg_shrpw_imm *a)
 /* Install the new nullification.  */
 cond_free(>null_cond);
 if (a->c) {
-ctx->null_cond = do_sed_cond(ctx, a->c, dest);
+ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
 }
 return nullify_end(ctx);
 }
@@ -3346,7 +3348,7 @@ static bool trans_extrw_sar(DisasContext *ctx, 
arg_extrw_sar *a)
 /* Install the new nullification.  */
 cond_free(>null_cond);
 if (a->c) {
-ctx->null_cond = do_sed_cond(ctx, a->c, dest);
+ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
 }
 return nullify_end(ctx);
 }
@@ -3373,7 +3375,7 @@ static bool trans_extrw_imm(DisasContext *ctx, 
arg_extrw_imm *a)
 /* Install the new nullification.  */
 cond_free(>null_cond);
 if (a->c) {
-ctx->null_cond = do_sed_cond(ctx, a->c, dest);
+ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
 }
 return nullify_end(ctx);
 }
@@ -3410,7 +3412,7 @@ static bool trans_depwi_imm(DisasContext *ctx, 
arg_depwi_imm *a)
 /* Install the new nullification.  */
 cond_free(>null_cond);
 if (a->c) {
-ctx->null_cond = do_sed_cond(ctx, a->c, dest);
+ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
 }
 return nullify_end(ctx);
 }
@@ -3440,7 +3442,7 @@ static bool trans_depw_imm(DisasContext *ctx, 
arg_depw_imm *a)
 /* Install the new nullification.  */
 cond_free(>null_cond);
 if (a->c) {
-ctx->null_cond = do_sed_cond(ctx, a->c, dest);
+ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
 }
 return nullify_end(ctx);
 }
@@ -3477,7 +3479,7 @@ static bool do_depw_sar(DisasContext *ctx, unsigned rt, 
unsigned c,
 /* Install the new nullification.  */
 cond_free(>null_cond);
 if (c) {
-ctx->null_cond = do_sed_cond(ctx, c, dest);
+ctx->null_cond = do_sed_cond(ctx, c, false, dest);
 }
 return nullify_end(ctx);
 }
-- 
2.34.1




[PATCH v3 06/88] target/hppa: Populate an interval tree with valid tlb entries

2023-11-01 Thread Richard Henderson
Complete the data structure conversion started earlier.  This reduces
the perf overhead of hppa_get_physical_address from ~5% to ~0.25%.

Signed-off-by: Richard Henderson 
---
 target/hppa/cpu.h|  24 +-
 target/hppa/cpu.c|   2 +
 target/hppa/machine.c|  51 -
 target/hppa/mem_helper.c | 161 +++
 4 files changed, 167 insertions(+), 71 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 1480d0237a..08de894393 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -176,7 +176,10 @@ typedef int64_t  target_sreg;
 #endif
 
 typedef struct HPPATLBEntry {
-IntervalTreeNode itree;
+union {
+IntervalTreeNode itree;
+struct HPPATLBEntry *unused_next;
+};
 
 target_ureg pa;
 
@@ -234,10 +237,22 @@ typedef struct CPUArchState {
 #define HPPA_TLB_ENTRIES256
 #define HPPA_BTLB_ENTRIES   (HPPA_BTLB_FIXED + HPPA_BTLB_VARIABLE)
 
-/* ??? Implement a unified itlb/dtlb for the moment.  */
-/* ??? We should use a more intelligent data structure.  */
-HPPATLBEntry tlb[HPPA_TLB_ENTRIES];
+/* Index for round-robin tlb eviction. */
 uint32_t tlb_last;
+
+/*
+ * For pa1.x, the partial initialized, still invalid tlb entry
+ * which has had ITLBA performed, but not yet ITLBP.
+ */
+HPPATLBEntry *tlb_partial;
+
+/* Linked list of all invalid (unused) tlb entries. */
+HPPATLBEntry *tlb_unused;
+
+/* Root of the search tree for all valid tlb entries. */
+IntervalTreeRoot tlb_root;
+
+HPPATLBEntry tlb[HPPA_TLB_ENTRIES];
 } CPUHPPAState;
 
 /**
@@ -356,6 +371,7 @@ int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray 
*buf, int reg);
 int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
 #ifndef CONFIG_USER_ONLY
+void hppa_ptlbe(CPUHPPAState *env);
 hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr);
 bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 1644297bf8..5e1240c631 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -137,8 +137,10 @@ static void hppa_cpu_realizefn(DeviceState *dev, Error 
**errp)
 #ifndef CONFIG_USER_ONLY
 {
 HPPACPU *cpu = HPPA_CPU(cs);
+
 cpu->alarm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
 hppa_cpu_alarm_timer, cpu);
+hppa_ptlbe(>env);
 }
 #endif
 }
diff --git a/target/hppa/machine.c b/target/hppa/machine.c
index 4535195ca2..ab3e8c81fa 100644
--- a/target/hppa/machine.c
+++ b/target/hppa/machine.c
@@ -72,8 +72,6 @@ static int get_tlb(QEMUFile *f, void *opaque, size_t size,
 HPPATLBEntry *ent = opaque;
 uint32_t val;
 
-memset(ent, 0, sizeof(*ent));
-
 ent->itree.start = qemu_get_be64(f);
 ent->pa = qemu_get_betr(f);
 val = qemu_get_be32(f);
@@ -122,6 +120,53 @@ static const VMStateInfo vmstate_tlb = {
 .put = put_tlb,
 };
 
+static int tlb_pre_load(void *opaque)
+{
+CPUHPPAState *env = opaque;
+
+/*
+ * Zap the entire tlb, on-the-side data structures and all.
+ * Each tlb entry will have data re-filled by put_tlb.
+ */
+memset(env->tlb, 0, sizeof(env->tlb));
+memset(>tlb_root, 0, sizeof(env->tlb_root));
+env->tlb_unused = NULL;
+env->tlb_partial = NULL;
+
+return 0;
+}
+
+static int tlb_post_load(void *opaque, int version_id)
+{
+CPUHPPAState *env = opaque;
+HPPATLBEntry **unused = >tlb_unused;
+HPPATLBEntry *partial = NULL;
+
+/*
+ * Re-create the interval tree from the valid entries.
+ * Truely invalid entries should have start == end == 0.
+ * Otherwise it should be the in-flight tlb_partial entry.
+ */
+for (uint32_t i = 0; i < ARRAY_SIZE(env->tlb); ++i) {
+HPPATLBEntry *e = >tlb[i];
+
+if (e->entry_valid) {
+interval_tree_insert(>itree, >tlb_root);
+} else if (i < HPPA_BTLB_ENTRIES) {
+/* btlb not in unused list */
+} else if (partial == NULL && e->itree.start < e->itree.last) {
+partial = e;
+} else {
+*unused = e;
+unused = >unused_next;
+}
+}
+env->tlb_partial = partial;
+*unused = NULL;
+
+return 0;
+}
+
 static VMStateField vmstate_env_fields[] = {
 VMSTATE_UINTTR_ARRAY(gr, CPUHPPAState, 32),
 VMSTATE_UINT64_ARRAY(fr, CPUHPPAState, 32),
@@ -164,6 +209,8 @@ static const VMStateDescription vmstate_env = {
 .version_id = 1,
 .minimum_version_id = 1,
 .fields = vmstate_env_fields,
+.pre_load = tlb_pre_load,
+.post_load = tlb_post_load,
 };
 
 static VMStateField vmstate_cpu_fields[] = {
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 828cceb29c..b1773ece61 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -27,16 +27,13 @@
 

[PATCH v3 68/88] target/hppa: Implement MIXH, MIXW

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode |  5 
 target/hppa/translate.c  | 55 
 2 files changed, 60 insertions(+)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 87db726d9e..22ec07f892 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -233,6 +233,11 @@ hsub10 . . 0001 11 0 .  
@rrr
 hsub_ss 10 . . 0001 01 0 .  @rrr
 hsub_us 10 . . 0001 00 0 .  @rrr
 
+mixh_l  10 . . 1 00 0010 .  @rrr
+mixh_r  10 . . 1 10 0010 .  @rrr
+mixw_l  10 . . 1 00  .  @rrr
+mixw_r  10 . . 1 10  .  @rrr
+
 
 # Index Mem
 
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index dc68d5a263..47ca71e2a3 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2891,6 +2891,61 @@ static bool trans_hsub_us(DisasContext *ctx, arg_rrr *a)
 return do_multimedia(ctx, a, gen_helper_hsub_us);
 }
 
+static void gen_mixh_l(TCGv_i64 dst, TCGv_i64 r1, TCGv_i64 r2)
+{
+uint64_t mask = 0xull;
+TCGv_i64 tmp = tcg_temp_new_i64();
+
+tcg_gen_andi_i64(tmp, r2, mask);
+tcg_gen_andi_i64(dst, r1, mask);
+tcg_gen_shri_i64(tmp, tmp, 16);
+tcg_gen_or_i64(dst, dst, tmp);
+}
+
+static bool trans_mixh_l(DisasContext *ctx, arg_rrr *a)
+{
+return do_multimedia(ctx, a, gen_mixh_l);
+}
+
+static void gen_mixh_r(TCGv_i64 dst, TCGv_i64 r1, TCGv_i64 r2)
+{
+uint64_t mask = 0xull;
+TCGv_i64 tmp = tcg_temp_new_i64();
+
+tcg_gen_andi_i64(tmp, r1, mask);
+tcg_gen_andi_i64(dst, r2, mask);
+tcg_gen_shli_i64(tmp, tmp, 16);
+tcg_gen_or_i64(dst, dst, tmp);
+}
+
+static bool trans_mixh_r(DisasContext *ctx, arg_rrr *a)
+{
+return do_multimedia(ctx, a, gen_mixh_r);
+}
+
+static void gen_mixw_l(TCGv_i64 dst, TCGv_i64 r1, TCGv_i64 r2)
+{
+TCGv_i64 tmp = tcg_temp_new_i64();
+
+tcg_gen_shri_i64(tmp, r2, 32);
+tcg_gen_deposit_i64(dst, r1, tmp, 0, 32);
+}
+
+static bool trans_mixw_l(DisasContext *ctx, arg_rrr *a)
+{
+return do_multimedia(ctx, a, gen_mixw_l);
+}
+
+static void gen_mixw_r(TCGv_i64 dst, TCGv_i64 r1, TCGv_i64 r2)
+{
+tcg_gen_deposit_i64(dst, r2, r1, 32, 32);
+}
+
+static bool trans_mixw_r(DisasContext *ctx, arg_rrr *a)
+{
+return do_multimedia(ctx, a, gen_mixw_r);
+}
+
 static bool trans_ld(DisasContext *ctx, arg_ldst *a)
 {
 if (!ctx->is_pa20 && a->size > MO_32) {
-- 
2.34.1




Re: [PATCH v5 00/13] RISC-V: ACPI: Enable AIA, PLIC and update RHCT

2023-11-01 Thread Alistair Francis
On Mon, Oct 30, 2023 at 11:23 PM Sunil V L  wrote:
>
> This series primarily enables external interrupt controllers (AIA and PLIC)
> in ACPI tables for RISC-V virt platform. It also updates RHCT with CMO and
> MMU related information.
>
> Below ECRs for these changes are approved by ASWG and will be
> available in next ACPI spec release.
>
> 1) MADT (AIA) - 
> https://drive.google.com/file/d/1oMGPyOD58JaPgMl1pKasT-VKsIKia7zR/view?usp=sharing
> 2) RHCT - 
> https://drive.google.com/file/d/1sKbOa8m1UZw1JkquZYe3F1zQBN1xXsaf/view?usp=sharing
>
> First two patches in this series are to migrate a couple of functions from
> ARM architecture to common code so that RISC-V doesn't need to duplicate
> the same.
>
> The patch set is based on Alistair's riscv-to-apply.next branch.
>
> These changes are also available in  riscv_acpi_b2_v5 branch at:
> https://github.com/vlsunil/qemu/
>
> Changes since v4:
> 1) Updated copyright for new files as per SPDX format suggested by 
> Drew.
> 2) Updated RINTC patch to avoid code duplication as suggested by Drew.
> 3) Moved mmu offset below cmo in MMU patch as suggested by Drew.
> 4) Updated tags.
>
> Changes since v3:
> 1) Addressed comments from Daniel and Drew.
> 2) Added a new patch in microvm to use common function for virtio in 
> DSDT.
> 3) Rebased to latest riscv-to-apply.next branch and added tags.
>
> Changes since v2:
> 1) Rebased to latest riscv-to-apply.next branch which needed
>changing ext_icboz to ext_zicboz in CMO patch.
> 2) Fixed node type in MMU node.
> 3) Added latest tags.
>
> Changes since v1:
> 1) As per Igor's suggestion, migrated fw_cfg and virtio creation
>functions to device specific file instead of generic aml-build.c.
>Since ACPI is optional, new files are created and enabled for
>build only when CONFIG_ACPI is enabled.
> 2) As per Igor's suggestion, properties are added to the GPEX PCI
>host to indicate MMIO ranges. The platform fw can initialize
>these to appropriate values and the DSDT generator can fetch
>the information from the host bus itself. This makes the code
>generic instead of machine specific.
> 3) Added PLIC patch from Haibo.
> 4) Rebased to latest riscv-to-apply.next and added RB tags as
>appropriate.
>
> Sunil V L (13):
>   hw/arm/virt-acpi-build.c: Migrate fw_cfg creation to common location
>   hw/arm/virt-acpi-build.c: Migrate virtio creation to common location
>   hw/i386/acpi-microvm.c: Use common function to add virtio in DSDT
>   hw/riscv: virt: Make few IMSIC macros and functions public
>   hw/riscv/virt-acpi-build.c: Add AIA support in RINTC
>   hw/riscv/virt-acpi-build.c: Add IMSIC in the MADT
>   hw/riscv/virt-acpi-build.c: Add APLIC in the MADT
>   hw/riscv/virt-acpi-build.c: Add CMO information in RHCT
>   hw/riscv/virt-acpi-build.c: Add MMU node in RHCT
>   hw/pci-host/gpex: Define properties for MMIO ranges
>   hw/riscv/virt: Update GPEX MMIO related properties
>   hw/riscv/virt-acpi-build.c: Add IO controllers and devices
>   hw/riscv/virt-acpi-build.c: Add PLIC in MADT

Thanks!

Applied to riscv-to-apply.next

Alistair

>
>  hw/arm/virt-acpi-build.c|  51 +
>  hw/i386/acpi-microvm.c  |  15 +-
>  hw/nvram/fw_cfg-acpi.c  |  23 +++
>  hw/nvram/meson.build|   1 +
>  hw/pci-host/gpex-acpi.c |  13 ++
>  hw/pci-host/gpex.c  |  12 ++
>  hw/riscv/Kconfig|   1 +
>  hw/riscv/virt-acpi-build.c  | 323 +---
>  hw/riscv/virt.c |  72 ---
>  hw/virtio/meson.build   |   1 +
>  hw/virtio/virtio-acpi.c |  32 
>  include/hw/nvram/fw_cfg_acpi.h  |  15 ++
>  include/hw/pci-host/gpex.h  |  28 ++-
>  include/hw/riscv/virt.h |  26 +++
>  include/hw/virtio/virtio-acpi.h |  16 ++
>  15 files changed, 498 insertions(+), 131 deletions(-)
>  create mode 100644 hw/nvram/fw_cfg-acpi.c
>  create mode 100644 hw/virtio/virtio-acpi.c
>  create mode 100644 include/hw/nvram/fw_cfg_acpi.h
>  create mode 100644 include/hw/virtio/virtio-acpi.h
>
> --
> 2.39.2
>
>



[PATCH v3 80/88] target/hppa: Add unwind_breg to CPUHPPAState

2023-11-01 Thread Richard Henderson
Fill in the insn_start value during form_gva, and copy
it out to the env field in hppa_restore_state_to_opc.
The value is not yet consumed.

Signed-off-by: Richard Henderson 
---
 target/hppa/cpu.h   |  8 +++-
 target/hppa/cpu.c   |  1 +
 target/hppa/translate.c | 13 -
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index ea8e7e99a4..144794d089 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -45,7 +45,7 @@
 #define MMU_IDX_TO_P(MIDX)  (((MIDX) - MMU_KERNEL_IDX) & 1)
 #define PRIV_P_TO_MMU_IDX(PRIV, P)  ((PRIV) * 2 + !!(P) + MMU_KERNEL_IDX)
 
-#define TARGET_INSN_START_EXTRA_WORDS 1
+#define TARGET_INSN_START_EXTRA_WORDS 2
 
 /* No need to flush MMU_PHYS_IDX  */
 #define HPPA_MMU_FLUSH_MASK \
@@ -208,6 +208,12 @@ typedef struct CPUArchState {
 target_ulong cr_back[2]; /* back of cr17/cr18 */
 target_ulong shadow[7];  /* shadow registers */
 
+/*
+ * During unwind of a memory insn, the base register of the address.
+ * This is used to construct CR_IOR for pa2.0.
+ */
+uint32_t unwind_breg;
+
 /*
  * ??? The number of entries isn't specified by the architecture.
  * BTLBs are not supported in 64-bit machines.
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index e1597ba8a5..04de1689d7 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -80,6 +80,7 @@ static void hppa_restore_state_to_opc(CPUState *cs,
 if (data[1] != (target_ulong)-1) {
 cpu->env.iaoq_b = data[1];
 }
+cpu->env.unwind_breg = data[2];
 /*
  * Since we were executing the instruction at IAOQ_F, and took some
  * sort of action that provoked the cpu_restore_state, we can infer
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index f7621590e4..27846f5ad8 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -44,6 +44,7 @@ typedef struct DisasCond {
 typedef struct DisasContext {
 DisasContextBase base;
 CPUState *cs;
+TCGOp *insn_start;
 
 uint64_t iaoq_f;
 uint64_t iaoq_b;
@@ -234,6 +235,13 @@ void hppa_translate_init(void)
 "iasq_b");
 }
 
+static void set_insn_breg(DisasContext *ctx, int breg)
+{
+assert(ctx->insn_start != NULL);
+tcg_set_insn_start_param(ctx->insn_start, 2, breg);
+ctx->insn_start = NULL;
+}
+
 static DisasCond cond_make_f(void)
 {
 return (DisasCond){
@@ -1324,6 +1332,8 @@ static void form_gva(DisasContext *ctx, TCGv_i64 *pgva, 
TCGv_i64 *pofs,
 TCGv_i64 ofs;
 TCGv_i64 addr;
 
+set_insn_breg(ctx, rb);
+
 /* Note that RX is mutually exclusive with DISP.  */
 if (rx) {
 ofs = tcg_temp_new_i64();
@@ -4455,7 +4465,8 @@ static void hppa_tr_insn_start(DisasContextBase *dcbase, 
CPUState *cs)
 {
 DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
-tcg_gen_insn_start(ctx->iaoq_f, ctx->iaoq_b);
+tcg_gen_insn_start(ctx->iaoq_f, ctx->iaoq_b, 0);
+ctx->insn_start = tcg_last_op();
 }
 
 static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
-- 
2.34.1




[PATCH v3 85/88] hw/pci-host/astro: Trigger CPU irq on CPU HPA in high memory

2023-11-01 Thread Richard Henderson
From: Helge Deller 

The CPU HPA is in the high F-region on PA2.0 CPUs, so use F_EXTEND()
to trigger interrupt request at the right CPU HPA address.
Note that the cpu_hpa value comes out of the IRT, which doesn't store the
higher addresss bits.

Signed-off-by: Helge Deller 
---
 hw/pci-host/astro.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/pci-host/astro.c b/hw/pci-host/astro.c
index df61386bd9..b19f0917c5 100644
--- a/hw/pci-host/astro.c
+++ b/hw/pci-host/astro.c
@@ -384,7 +384,7 @@ static void elroy_set_irq(void *opaque, int irq, int level)
 uint32_t ena = bit & ~old_ilr;
 s->ilr = old_ilr | bit;
 if (ena != 0) {
-stl_be_phys(_space_memory, cpu_hpa, val & 63);
+stl_be_phys(_space_memory, F_EXTEND(cpu_hpa), val & 63);
 }
 } else {
 s->ilr = old_ilr & ~bit;
-- 
2.34.1




[PATCH v3 53/88] target/hppa: Implement CLRBTS, POPBTS, PUSHBTS, PUSHNOM

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode | 2 ++
 target/hppa/translate.c  | 6 ++
 2 files changed, 8 insertions(+)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 6f0c3f6ea5..ba7731b517 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -381,6 +381,8 @@ bl  111010 . . 101 ... n:1 .
 l=2 \
 disp=%assemble_22
 b_gate  111010 . . 001 ... .   .@bl
 blr 111010 l:5   x:5   010 000 n:1 0
+nopbts  111010 0 0 010 0-1   0 1# clrbts/popbts
+nopbts  111010 0 - 010 000   0 1# pushbts/pushnom
 bv  111010 b:5   x:5   110 000 n:1 0
 bve 111010 b:5   0 110 100 n:1 -l=0
 bve 111010 b:5   0 111 100 n:1 -l=2
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 897b44d7e3..91249d89ca 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3782,6 +3782,12 @@ static bool trans_bve(DisasContext *ctx, arg_bve *a)
 #endif
 }
 
+static bool trans_nopbts(DisasContext *ctx, arg_nopbts *a)
+{
+/* All branch target stack instructions implement as nop. */
+return ctx->is_pa20;
+}
+
 /*
  * Float class 0
  */
-- 
2.34.1




[PATCH v3 43/88] target/hppa: Decode d for add instructions

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode | 16 
 target/hppa/translate.c  | 21 +++--
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index d4a03b0299..0f29869949 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -62,7 +62,7 @@
 _cf_dt r cf d
 _cf t r1 r2 cf
 _cf_d   t r1 r2 cf d
-_cf_sh  t r1 r2 cf sh
+_cf_d_sht r1 r2 cf d sh
 _cf t r i cf
 _cf_d   t r i cf d
 
@@ -76,8 +76,8 @@
 @rr_cf_d.. r:5 . cf:4 .. d:1 t:5_cf_d
 @rrr_cf .. r2:5 r1:5 cf:4 ... t:5   _cf
 @rrr_cf_d   .. r2:5 r1:5 cf:4 .. d:1 t:5_cf_d
-@rrr_cf_sh  .. r2:5 r1:5 cf:4  sh:2 . t:5   _cf_sh
-@rrr_cf_sh0 .. r2:5 r1:5 cf:4 ... t:5   _cf_sh sh=0
+@rrr_cf_d_sh.. r2:5 r1:5 cf:4  sh:2 d:1 t:5 _cf_d_sh
+@rrr_cf_d_sh0   .. r2:5 r1:5 cf:4 .. d:1 t:5_cf_d_sh sh=0
 @rri_cf .. r:5  t:5  cf:4 . ... _cf i=%lowsign_11
 @rri_cf_d   .. r:5  t:5  cf:4 d:1 ...   _cf_d i=%lowsign_11
 
@@ -166,11 +166,11 @@ uaddcm_tc   10 . .  100111 . .  
@rrr_cf_d
 dcor10 . 0  101110 . .  @rr_cf_d
 dcor_i  10 . 0  10 . .  @rr_cf_d
 
-add 10 . .  0110.. - .  @rrr_cf_sh
-add_l   10 . .  1010.. 0 .  @rrr_cf_sh
-add_tsv 10 . .  1110.. 0 .  @rrr_cf_sh
-add_c   10 . .  011100 0 .  @rrr_cf_sh0
-add_c_tsv   10 . .  00 0 .  @rrr_cf_sh0
+add 10 . .  0110.. . .  @rrr_cf_d_sh
+add_l   10 . .  1010.. . .  @rrr_cf_d_sh
+add_tsv 10 . .  1110.. . .  @rrr_cf_d_sh
+add_c   10 . .  011100 . .  @rrr_cf_d_sh0
+add_c_tsv   10 . .  00 . .  @rrr_cf_d_sh0
 
 sub 10 . .  01 - .  @rrr_cf
 sub_tsv 10 . .  11 0 .  @rrr_cf
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 8301d007ff..2f5cc597ad 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1186,12 +1186,11 @@ static TCGv_reg do_sub_sv(DisasContext *ctx, TCGv_reg 
res,
 
 static void do_add(DisasContext *ctx, unsigned rt, TCGv_reg in1,
TCGv_reg in2, unsigned shift, bool is_l,
-   bool is_tsv, bool is_tc, bool is_c, unsigned cf)
+   bool is_tsv, bool is_tc, bool is_c, unsigned cf, bool d)
 {
 TCGv_reg dest, cb, cb_msb, cb_cond, sv, tmp;
 unsigned c = cf >> 1;
 DisasCond cond;
-bool d = false;
 
 dest = tcg_temp_new();
 cb = NULL;
@@ -1256,7 +1255,7 @@ static void do_add(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 ctx->null_cond = cond;
 }
 
-static bool do_add_reg(DisasContext *ctx, arg_rrr_cf_sh *a,
+static bool do_add_reg(DisasContext *ctx, arg_rrr_cf_d_sh *a,
bool is_l, bool is_tsv, bool is_tc, bool is_c)
 {
 TCGv_reg tcg_r1, tcg_r2;
@@ -1266,7 +1265,8 @@ static bool do_add_reg(DisasContext *ctx, arg_rrr_cf_sh 
*a,
 }
 tcg_r1 = load_gpr(ctx, a->r1);
 tcg_r2 = load_gpr(ctx, a->r2);
-do_add(ctx, a->t, tcg_r1, tcg_r2, a->sh, is_l, is_tsv, is_tc, is_c, a->cf);
+do_add(ctx, a->t, tcg_r1, tcg_r2, a->sh, is_l,
+   is_tsv, is_tc, is_c, a->cf, a->d);
 return nullify_end(ctx);
 }
 
@@ -1280,7 +1280,8 @@ static bool do_add_imm(DisasContext *ctx, arg_rri_cf *a,
 }
 tcg_im = tcg_constant_reg(a->i);
 tcg_r2 = load_gpr(ctx, a->r);
-do_add(ctx, a->t, tcg_im, tcg_r2, 0, 0, is_tsv, is_tc, 0, a->cf);
+/* All ADDI conditions are 32-bit. */
+do_add(ctx, a->t, tcg_im, tcg_r2, 0, 0, is_tsv, is_tc, 0, a->cf, false);
 return nullify_end(ctx);
 }
 
@@ -2635,27 +2636,27 @@ static bool trans_lci(DisasContext *ctx, arg_lci *a)
 return true;
 }
 
-static bool trans_add(DisasContext *ctx, arg_rrr_cf_sh *a)
+static bool trans_add(DisasContext *ctx, arg_rrr_cf_d_sh *a)
 {
 return do_add_reg(ctx, a, false, false, false, false);
 }
 
-static bool trans_add_l(DisasContext *ctx, arg_rrr_cf_sh *a)
+static bool trans_add_l(DisasContext *ctx, arg_rrr_cf_d_sh *a)
 {
 return do_add_reg(ctx, a, true, false, false, false);
 }
 
-static bool trans_add_tsv(DisasContext *ctx, arg_rrr_cf_sh *a)
+static bool trans_add_tsv(DisasContext *ctx, arg_rrr_cf_d_sh *a)
 {
 return do_add_reg(ctx, a, false, true, false, false);
 }
 
-static bool trans_add_c(DisasContext *ctx, arg_rrr_cf_sh *a)
+static bool trans_add_c(DisasContext *ctx, arg_rrr_cf_d_sh *a)
 {
 return do_add_reg(ctx, a, false, false, false, true);
 }
 
-static bool trans_add_c_tsv(DisasContext *ctx, arg_rrr_cf_sh *a)
+static bool 

[PATCH v3 64/88] target/hppa: Implement HSUB

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/helper.h |  2 ++
 target/hppa/insns.decode |  4 
 target/hppa/op_helper.c  | 32 
 target/hppa/translate.c  | 15 +++
 4 files changed, 53 insertions(+)

diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index b3c961b50d..02798aa105 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -16,6 +16,8 @@ DEF_HELPER_FLAGS_1(ldc_check, TCG_CALL_NO_RWG, void, tl)
 
 DEF_HELPER_FLAGS_2(hadd_ss, TCG_CALL_NO_RWG, i64, i64, i64)
 DEF_HELPER_FLAGS_2(hadd_us, TCG_CALL_NO_RWG, i64, i64, i64)
+DEF_HELPER_FLAGS_2(hsub_ss, TCG_CALL_NO_RWG, i64, i64, i64)
+DEF_HELPER_FLAGS_2(hsub_us, TCG_CALL_NO_RWG, i64, i64, i64)
 
 DEF_HELPER_FLAGS_4(probe, TCG_CALL_NO_WG, tl, env, tl, i32, i32)
 
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 4bcfc94b1c..29b49c6cf4 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -214,6 +214,10 @@ hadd10 . . 0011 11 0 .  
@rrr
 hadd_ss 10 . . 0011 01 0 .  @rrr
 hadd_us 10 . . 0011 00 0 .  @rrr
 
+hsub10 . . 0001 11 0 .  @rrr
+hsub_ss 10 . . 0001 01 0 .  @rrr
+hsub_us 10 . . 0001 00 0 .  @rrr
+
 
 # Index Mem
 
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index a230a3a0c3..ece523bea0 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -409,3 +409,35 @@ uint64_t HELPER(hadd_us)(uint64_t r1, uint64_t r2)
 }
 return ret;
 }
+
+uint64_t HELPER(hsub_ss)(uint64_t r1, uint64_t r2)
+{
+uint64_t ret = 0;
+
+for (int i = 0; i < 64; i += 16) {
+int f1 = sextract64(r1, i, 16);
+int f2 = sextract64(r2, i, 16);
+int fr = f1 - f2;
+
+fr = MIN(fr, INT16_MAX);
+fr = MAX(fr, INT16_MIN);
+ret = deposit64(ret, i, 16, fr);
+}
+return ret;
+}
+
+uint64_t HELPER(hsub_us)(uint64_t r1, uint64_t r2)
+{
+uint64_t ret = 0;
+
+for (int i = 0; i < 64; i += 16) {
+int f1 = extract64(r1, i, 16);
+int f2 = sextract64(r2, i, 16);
+int fr = f1 - f2;
+
+fr = MIN(fr, UINT16_MAX);
+fr = MAX(fr, 0);
+ret = deposit64(ret, i, 16, fr);
+}
+return ret;
+}
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index f564aea8fb..2f1333b91c 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2804,6 +2804,21 @@ static bool trans_hadd_us(DisasContext *ctx, arg_rrr *a)
 return do_multimedia(ctx, a, gen_helper_hadd_us);
 }
 
+static bool trans_hsub(DisasContext *ctx, arg_rrr *a)
+{
+return do_multimedia(ctx, a, tcg_gen_vec_sub16_i64);
+}
+
+static bool trans_hsub_ss(DisasContext *ctx, arg_rrr *a)
+{
+return do_multimedia(ctx, a, gen_helper_hsub_ss);
+}
+
+static bool trans_hsub_us(DisasContext *ctx, arg_rrr *a)
+{
+return do_multimedia(ctx, a, gen_helper_hsub_us);
+}
+
 static bool trans_ld(DisasContext *ctx, arg_ldst *a)
 {
 if (!ctx->is_pa20 && a->size > MO_32) {
-- 
2.34.1




Re: [PATCH v2 00/14] Update RISC-V vector crypto to ratified v1.0.0

2023-11-01 Thread Alistair Francis
On Fri, Oct 27, 2023 at 1:19 AM Max Chou  wrote:
>
> This patchset updates the RISC-V vector cryptography support to the
> ratified version v1.0.0 (commit 1769c26, released on 2023/10).
>
> v2:
>
> - Fixed the instruction order at disassembler part.
> - Fixed the vror.vi disassembler format.
> - Verified by code examples provided by vector crypto spec repository
>   (riscv-crypto).
> - Rebased to riscv-to-apply.next branch (1f910f3)
>
> v1:
>
> - Support Zvkb, Zvkt, and other shorthand extensions(Zvkn, Zvknc, Zvkng,
>   Zvks, Zvksc, Zvksg).
> - Support the disassembler for vector crypto extensions.
> - Moved vector crypto extensions from experimental extensions to ratified
>   extensions.
> - Replaced TAB indentations with spaces in disas/riscv.c.
>
>
> Max Chou (14):
>   target/riscv: Add cfg property for Zvkt extension
>   target/riscv: Expose Zvkt extension property
>   target/riscv: Add cfg property for Zvkb extension
>   target/riscv: Replace Zvbb checking by Zvkb
>   target/riscv: Expose Zvkb extension property
>   target/riscv: Add cfg properties for Zvkn[c|g] extensions
>   target/riscv: Expose Zvkn[c|g] extnesion properties
>   target/riscv: Add cfg properties for Zvks[c|g] extensions
>   target/riscv: Expose Zvks[c|g] extnesion properties
>   target/riscv: Move vector crypto extensions to riscv_cpu_extensions
>   disas/riscv: Add rv_fmt_vd_vs2_uimm format
>   disas/riscv: Add rv_codec_vror_vi for vror.vi
>   disas/riscv: Add support for vector crypto extensions
>   disas/riscv: Replace TABs with space

Thanks!

Applied to riscv-to-apply.next

Alistair

>
>  disas/riscv.c| 157 ++-
>  disas/riscv.h|   2 +
>  target/riscv/cpu.c   |  36 --
>  target/riscv/cpu_cfg.h   |   8 ++
>  target/riscv/insn_trans/trans_rvvk.c.inc |  37 --
>  target/riscv/tcg/tcg-cpu.c   |  48 ++-
>  6 files changed, 258 insertions(+), 30 deletions(-)
>
> --
> 2.34.1
>
>



[PATCH v3 56/88] hw/hppa: Use uint32_t instead of target_ureg

2023-11-01 Thread Richard Henderson
The size of target_ureg is going to change.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 hw/hppa/machine.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 85682e6bab..1f09b4b490 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -391,9 +391,9 @@ static void machine_HP_common_init_tail(MachineState 
*machine, PCIBus *pci_bus)
 true, EM_PARISC, 0, 0);
 
 /* Unfortunately, load_elf sign-extends reading elf32.  */
-firmware_entry = (target_ureg)firmware_entry;
-firmware_low = (target_ureg)firmware_low;
-firmware_high = (target_ureg)firmware_high;
+firmware_entry = (uint32_t)firmware_entry;
+firmware_low = (uint32_t)firmware_low;
+firmware_high = (uint32_t)firmware_high;
 
 if (size < 0) {
 error_report("could not load firmware '%s'", firmware_filename);
@@ -420,9 +420,9 @@ static void machine_HP_common_init_tail(MachineState 
*machine, PCIBus *pci_bus)
 true, EM_PARISC, 0, 0);
 
 /* Unfortunately, load_elf sign-extends reading elf32.  */
-kernel_entry = (target_ureg) cpu_hppa_to_phys(NULL, kernel_entry);
-kernel_low = (target_ureg)kernel_low;
-kernel_high = (target_ureg)kernel_high;
+kernel_entry = (uint32_t) cpu_hppa_to_phys(NULL, kernel_entry);
+kernel_low = (uint32_t)kernel_low;
+kernel_high = (uint32_t)kernel_high;
 
 if (size < 0) {
 error_report("could not load kernel '%s'", kernel_filename);
-- 
2.34.1




[PATCH v3 76/88] target/hppa: Implement pa2.0 data prefetch instructions

2023-11-01 Thread Richard Henderson
These are aliased onto the normal integer loads to %g0.
Since we don't emulate caches, prefetch is a nop.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 3d8240ea7d..0883b146a9 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2976,7 +2976,15 @@ static bool trans_permh(DisasContext *ctx, arg_permh *a)
 
 static bool trans_ld(DisasContext *ctx, arg_ldst *a)
 {
-if (!ctx->is_pa20 && a->size > MO_32) {
+if (ctx->is_pa20) {
+   /*
+* With pa20, LDB, LDH, LDW, LDD to %g0 are prefetches.
+* Any base modification still occurs.
+*/
+if (a->t == 0) {
+return trans_nop_addrx(ctx, a);
+}
+} else if (a->size > MO_32) {
 return gen_illegal(ctx);
 }
 return do_load(ctx, a->t, a->b, a->x, a->scale ? a->size : 0,
-- 
2.34.1




[PATCH v3 59/88] target/hppa: Remove remaining TARGET_REGISTER_BITS redirections

2023-11-01 Thread Richard Henderson
The conversions to/from i64 can be eliminated entirely,
folding computation into adjacent operations.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 46 -
 1 file changed, 13 insertions(+), 33 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 520a375e3a..ce8d812e04 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -33,15 +33,6 @@
 #undef  HELPER_H
 
 
-/* Since we have a distinction between register size and address size,
-   we need to redefine all of these.  */
-
-#define tcg_gen_extu_reg_tl  tcg_gen_mov_i64
-#define tcg_gen_trunc_i64_reg tcg_gen_mov_i64
-#define tcg_gen_extu_reg_i64 tcg_gen_mov_i64
-#define tcg_gen_ext_reg_i64  tcg_gen_mov_i64
-
-
 typedef struct DisasCond {
 TCGCond c;
 TCGv_i64 a0, a1;
@@ -1345,8 +1336,7 @@ static void form_gva(DisasContext *ctx, TCGv_i64 *pgva, 
TCGv_i64 *pofs,
 
 *pofs = ofs;
 *pgva = addr = tcg_temp_new_i64();
-tcg_gen_extu_reg_tl(addr, modify <= 0 ? ofs : base);
-tcg_gen_andi_tl(addr, addr, gva_offset_mask(ctx));
+tcg_gen_andi_tl(addr, modify <= 0 ? ofs : base, gva_offset_mask(ctx));
 #ifndef CONFIG_USER_ONLY
 if (!is_phys) {
 tcg_gen_or_tl(addr, addr, space_select(ctx, sp, base));
@@ -1966,13 +1956,11 @@ static bool trans_mfsp(DisasContext *ctx, arg_mfsp *a)
 unsigned rt = a->t;
 unsigned rs = a->sp;
 TCGv_i64 t0 = tcg_temp_new_i64();
-TCGv_i64 t1 = tcg_temp_new();
 
 load_spr(ctx, t0, rs);
 tcg_gen_shri_i64(t0, t0, 32);
-tcg_gen_trunc_i64_reg(t1, t0);
 
-save_gpr(ctx, rt, t1);
+save_gpr(ctx, rt, t0);
 
 cond_free(>null_cond);
 return true;
@@ -2029,22 +2017,21 @@ static bool trans_mtsp(DisasContext *ctx, arg_mtsp *a)
 {
 unsigned rr = a->r;
 unsigned rs = a->sp;
-TCGv_i64 t64;
+TCGv_i64 tmp;
 
 if (rs >= 5) {
 CHECK_MOST_PRIVILEGED(EXCP_PRIV_REG);
 }
 nullify_over(ctx);
 
-t64 = tcg_temp_new_i64();
-tcg_gen_extu_reg_i64(t64, load_gpr(ctx, rr));
-tcg_gen_shli_i64(t64, t64, 32);
+tmp = tcg_temp_new_i64();
+tcg_gen_shli_i64(tmp, load_gpr(ctx, rr), 32);
 
 if (rs >= 4) {
-tcg_gen_st_i64(t64, tcg_env, offsetof(CPUHPPAState, sr[rs]));
+tcg_gen_st_i64(tmp, tcg_env, offsetof(CPUHPPAState, sr[rs]));
 ctx->tb_flags &= ~TB_FLAG_SR_SAME;
 } else {
-tcg_gen_mov_i64(cpu_sr[rs], t64);
+tcg_gen_mov_i64(cpu_sr[rs], tmp);
 }
 
 return nullify_end(ctx);
@@ -2135,11 +2122,8 @@ static bool trans_ldsid(DisasContext *ctx, arg_ldsid *a)
 /* We don't implement space registers in user mode. */
 tcg_gen_movi_i64(dest, 0);
 #else
-TCGv_i64 t0 = tcg_temp_new_i64();
-
-tcg_gen_mov_i64(t0, space_select(ctx, a->sp, load_gpr(ctx, a->b)));
-tcg_gen_shri_i64(t0, t0, 32);
-tcg_gen_trunc_i64_reg(dest, t0);
+tcg_gen_mov_i64(dest, space_select(ctx, a->sp, load_gpr(ctx, a->b)));
+tcg_gen_shri_i64(dest, dest, 32);
 #endif
 save_gpr(ctx, a->t, dest);
 
@@ -3185,10 +3169,8 @@ static bool trans_shrp_sar(DisasContext *ctx, 
arg_shrp_sar *a)
 TCGv_i64 s = tcg_temp_new_i64();
 
 tcg_gen_concat32_i64(t, src2, src1);
-tcg_gen_extu_reg_i64(s, cpu_sar);
-tcg_gen_andi_i64(s, s, 31);
-tcg_gen_shr_i64(t, t, s);
-tcg_gen_trunc_i64_reg(dest, t);
+tcg_gen_andi_i64(s, cpu_sar, 31);
+tcg_gen_shr_i64(dest, t, s);
 }
 }
 save_gpr(ctx, a->t, dest);
@@ -3230,10 +3212,8 @@ static bool trans_shrp_imm(DisasContext *ctx, 
arg_shrp_imm *a)
 tcg_gen_rotri_i32(t32, t32, sa);
 tcg_gen_extu_i32_i64(dest, t32);
 } else {
-TCGv_i64 t64 = tcg_temp_new_i64();
-tcg_gen_concat32_i64(t64, t2, cpu_gr[a->r1]);
-tcg_gen_shri_i64(t64, t64, sa);
-tcg_gen_trunc_i64_reg(dest, t64);
+tcg_gen_concat32_i64(dest, t2, cpu_gr[a->r1]);
+tcg_gen_extract_i64(dest, dest, sa, 32);
 }
 }
 save_gpr(ctx, a->t, dest);
-- 
2.34.1




[PATCH v3 47/88] target/hppa: Decode CMPIB double-word

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode | 10 --
 target/hppa/translate.c  | 11 ++-
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index fc327e2bb3..48f09c9b06 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -51,6 +51,7 @@
 %pos_to_m   0:1  !function=pos_to_m
 %neg_to_m   0:1  !function=neg_to_m
 %a_to_m 2:1  !function=neg_to_m
+%cmpbid_c   13:2 !function=cmpbid_c
 
 
 # Argument set definitions
@@ -69,6 +70,7 @@
 _c_fdisp n c f r1 r2
 _c_d_f  disp n c d f r1 r2
 _c_fdisp n c f r i
+_c_d_f  disp n c d f r i
 
 
 # Format definitions
@@ -88,6 +90,8 @@
 _c_d_f disp=%assemble_12
 @rib_cf .. r:5 . c:3 ... n:1 .  \
 _c_f disp=%assemble_12 i=%im5_16
+@rib_cdf.. r:5 . c:3 ... n:1 .  \
+_c_d_f disp=%assemble_12 i=%im5_16
 
 
 # System
@@ -303,8 +307,10 @@ cmpb10 . . ... ... . .  
@rrb_cdf d=0 f=0
 cmpb100010 . . ... ... . .  @rrb_cdf d=0 f=1
 cmpb100111 . . ... ... . .  @rrb_cdf d=1 f=0
 cmpb10 . . ... ... . .  @rrb_cdf d=1 f=1
-cmpbi   11 . . ... ... . .  @rib_cf f=0
-cmpbi   100011 . . ... ... . .  @rib_cf f=1
+cmpbi   11 . . ... ... . .  @rib_cdf d=0 f=0
+cmpbi   100011 . . ... ... . .  @rib_cdf d=0 f=1
+cmpbi   111011 r:5 . f:1 .. ... n:1 . \
+_c_d_f d=1 disp=%assemble_12 c=%cmpbid_c i=%im5_16
 
 addb101000 . . ... ... . .  @rrb_cf f=0
 addb101010 . . ... ... . .  @rrb_cf f=1
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 6cd06fbc0d..7f767fea64 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -329,6 +329,12 @@ static int expand_shl11(DisasContext *ctx, int val)
 return val << 11;
 }
 
+/* Translate CMPI doubleword conditions to standard. */
+static int cmpbid_c(DisasContext *ctx, int val)
+{
+return val ? val : 4; /* 0 == "*<<" */
+}
+
 
 /* Include the auto-generated decoder.  */
 #include "decode-insns.c.inc"
@@ -3122,9 +3128,12 @@ static bool trans_cmpb(DisasContext *ctx, arg_cmpb *a)
 
 static bool trans_cmpbi(DisasContext *ctx, arg_cmpbi *a)
 {
+if (!ctx->is_pa20 && a->d) {
+return false;
+}
 nullify_over(ctx);
 return do_cmpb(ctx, a->r, tcg_constant_reg(a->i),
-   a->c, a->f, false, a->n, a->disp);
+   a->c, a->f, a->d, a->n, a->disp);
 }
 
 static bool do_addb(DisasContext *ctx, unsigned r, TCGv_reg in1,
-- 
2.34.1




[PATCH v3 83/88] target/hppa: Improve interrupt logging

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/int_helper.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index 54875442e7..467ee7daf5 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -258,14 +258,10 @@ void hppa_cpu_do_interrupt(CPUState *cs)
 snprintf(unknown, sizeof(unknown), "unknown %d", i);
 name = unknown;
 }
-qemu_log("INT %6d: %s @ " TARGET_FMT_lx "," TARGET_FMT_lx
- " -> " TARGET_FMT_lx " " TARGET_FMT_lx "\n",
- ++count, name,
- hppa_form_gva(env, env->iasq_f, env->iaoq_f),
- hppa_form_gva(env, env->iasq_b, env->iaoq_b),
- env->iaoq_f,
- hppa_form_gva(env, (uint64_t)env->cr[CR_ISR] << 32,
-   env->cr[CR_IOR]));
+qemu_log("INT %6d: %s @ " TARGET_FMT_lx ":" TARGET_FMT_lx
+ " for " TARGET_FMT_lx ":" TARGET_FMT_lx "\n",
+ ++count, name, env->cr[CR_IIASQ], env->cr[CR_IIAOQ],
+ env->cr[CR_ISR], env->cr[CR_IOR]);
 }
 cs->exception_index = -1;
 }
-- 
2.34.1




[PATCH v3 57/88] target/hppa: Remove TARGET_REGISTER_BITS

2023-11-01 Thread Richard Henderson
Rely only on TARGET_LONG_BITS, fixed at 64, and hppa_is_pa20.

Signed-off-by: Richard Henderson 
---
 target/hppa/cpu-param.h  |   1 -
 target/hppa/cpu.h|  50 ---
 target/hppa/helper.h |  51 +--
 target/hppa/cpu.c|   2 +-
 target/hppa/helper.c |  32 +++
 target/hppa/int_helper.c |  17 ++--
 target/hppa/machine.c|  45 +++---
 target/hppa/mem_helper.c |  16 ++--
 target/hppa/op_helper.c  |  30 +++
 target/hppa/sys_helper.c |   4 +-
 target/hppa/translate.c  | 186 ---
 11 files changed, 135 insertions(+), 299 deletions(-)

diff --git a/target/hppa/cpu-param.h b/target/hppa/cpu-param.h
index 2fb8e7924b..6746869a3b 100644
--- a/target/hppa/cpu-param.h
+++ b/target/hppa/cpu-param.h
@@ -9,7 +9,6 @@
 #define HPPA_CPU_PARAM_H
 
 #define TARGET_LONG_BITS  64
-#define TARGET_REGISTER_BITS  64
 
 #if defined(CONFIG_USER_ONLY) && defined(TARGET_ABI32)
 # define TARGET_PHYS_ADDR_SPACE_BITS  32
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 77ddb20ac2..ea676ba062 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -154,25 +154,13 @@
 #define CR_IPSW  22
 #define CR_EIRR  23
 
-#if TARGET_REGISTER_BITS == 32
-typedef uint32_t target_ureg;
-typedef int32_t  target_sreg;
-#define TREG_FMT_lx   "%08"PRIx32
-#define TREG_FMT_ld   "%"PRId32
-#else
-typedef uint64_t target_ureg;
-typedef int64_t  target_sreg;
-#define TREG_FMT_lx   "%016"PRIx64
-#define TREG_FMT_ld   "%"PRId64
-#endif
-
 typedef struct HPPATLBEntry {
 union {
 IntervalTreeNode itree;
 struct HPPATLBEntry *unused_next;
 };
 
-target_ureg pa;
+target_ulong pa;
 
 unsigned entry_valid : 1;
 
@@ -187,16 +175,16 @@ typedef struct HPPATLBEntry {
 } HPPATLBEntry;
 
 typedef struct CPUArchState {
-target_ureg iaoq_f;  /* front */
-target_ureg iaoq_b;  /* back, aka next instruction */
+target_ulong iaoq_f; /* front */
+target_ulong iaoq_b; /* back, aka next instruction */
 
-target_ureg gr[32];
+target_ulong gr[32];
 uint64_t fr[32];
 uint64_t sr[8];  /* stored shifted into place for gva */
 
-target_ureg psw; /* All psw bits except the following:  */
-target_ureg psw_n;   /* boolean */
-target_sreg psw_v;   /* in most significant bit */
+target_ulong psw;/* All psw bits except the following:  */
+target_ulong psw_n;  /* boolean */
+target_long psw_v;   /* in most significant bit */
 
 /* Splitting the carry-borrow field into the MSB and "the rest", allows
  * for "the rest" to be deleted when it is unused, but the MSB is in use.
@@ -205,8 +193,8 @@ typedef struct CPUArchState {
  * host has the appropriate add-with-carry insn to compute the msb).
  * Therefore the carry bits are stored as: cb_msb : cb & 0x1110.
  */
-target_ureg psw_cb;  /* in least significant bit of next nibble */
-target_ureg psw_cb_msb;  /* boolean */
+target_ulong psw_cb; /* in least significant bit of next nibble */
+target_ulong psw_cb_msb; /* boolean */
 
 uint64_t iasq_f;
 uint64_t iasq_b;
@@ -214,9 +202,9 @@ typedef struct CPUArchState {
 uint32_t fr0_shadow; /* flags, c, ca/cq, rm, d, enables */
 float_status fp_status;
 
-target_ureg cr[32];  /* control registers */
-target_ureg cr_back[2];  /* back of cr17/cr18 */
-target_ureg shadow[7];   /* shadow registers */
+target_ulong cr[32]; /* control registers */
+target_ulong cr_back[2]; /* back of cr17/cr18 */
+target_ulong shadow[7];  /* shadow registers */
 
 /*
  * ??? The number of entries isn't specified by the architecture.
@@ -287,8 +275,8 @@ void hppa_translate_init(void);
 
 #define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
 
-static inline target_ulong hppa_form_gva_psw(target_ureg psw, uint64_t spc,
- target_ureg off)
+static inline target_ulong hppa_form_gva_psw(target_ulong psw, uint64_t spc,
+ target_ulong off)
 {
 #ifdef CONFIG_USER_ONLY
 return off;
@@ -299,7 +287,7 @@ static inline target_ulong hppa_form_gva_psw(target_ureg 
psw, uint64_t spc,
 }
 
 static inline target_ulong hppa_form_gva(CPUHPPAState *env, uint64_t spc,
- target_ureg off)
+ target_ulong off)
 {
 return hppa_form_gva_psw(env->psw, spc, off);
 }
@@ -343,8 +331,8 @@ static inline void cpu_get_tb_cpu_state(CPUHPPAState *env, 
vaddr *pc,
which is the primary case we care about -- using goto_tb within a page.
Failure is indicated by a zero difference.  */
 if (env->iasq_f == env->iasq_b) {
-target_sreg diff = env->iaoq_b - env->iaoq_f;
-if (TARGET_REGISTER_BITS == 32 || diff == (int32_t)diff) {
+target_long diff = env->iaoq_b - env->iaoq_f;
+if (diff == 

[PATCH v3 03/88] target/hppa: Use IntervalTreeNode in HPPATLBEntry

2023-11-01 Thread Richard Henderson
Replace the va_b and va_b fields with the interval tree node.
The actual interval tree is not yet used.

Signed-off-by: Richard Henderson 
---
 target/hppa/cpu.h|  5 +++--
 target/hppa/machine.c|  6 +++---
 target/hppa/mem_helper.c | 31 +--
 3 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 22edfc955d..84bb6edc60 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -23,6 +23,7 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 #include "qemu/cpu-float.h"
+#include "qemu/interval-tree.h"
 
 /* PA-RISC 1.x processors have a strong memory model.  */
 /* ??? While we do not yet implement PA-RISC 2.0, those processors have
@@ -175,8 +176,8 @@ typedef int64_t  target_sreg;
 #endif
 
 typedef struct HPPATLBEntry {
-uint64_t va_b;
-uint64_t va_e;
+IntervalTreeNode itree;
+
 target_ureg pa;
 unsigned u : 1;
 unsigned t : 1;
diff --git a/target/hppa/machine.c b/target/hppa/machine.c
index 1d3f9b639d..4535195ca2 100644
--- a/target/hppa/machine.c
+++ b/target/hppa/machine.c
@@ -74,7 +74,7 @@ static int get_tlb(QEMUFile *f, void *opaque, size_t size,
 
 memset(ent, 0, sizeof(*ent));
 
-ent->va_b = qemu_get_be64(f);
+ent->itree.start = qemu_get_be64(f);
 ent->pa = qemu_get_betr(f);
 val = qemu_get_be32(f);
 
@@ -88,7 +88,7 @@ static int get_tlb(QEMUFile *f, void *opaque, size_t size,
 ent->d = extract32(val, 28, 1);
 ent->t = extract32(val, 29, 1);
 
-ent->va_e = ent->va_b + TARGET_PAGE_SIZE - 1;
+ent->itree.last = ent->itree.start + TARGET_PAGE_SIZE - 1;
 return 0;
 }
 
@@ -110,7 +110,7 @@ static int put_tlb(QEMUFile *f, void *opaque, size_t size,
 val = deposit32(val, 29, 1, ent->t);
 }
 
-qemu_put_be64(f, ent->va_b);
+qemu_put_be64(f, ent->itree.start);
 qemu_put_betr(f, ent->pa);
 qemu_put_be32(f, val);
 return 0;
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index a22de81a48..687ae44ed0 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -31,9 +31,10 @@ static HPPATLBEntry *hppa_find_tlb(CPUHPPAState *env, vaddr 
addr)
 
 for (i = 0; i < ARRAY_SIZE(env->tlb); ++i) {
 HPPATLBEntry *ent = >tlb[i];
-if (ent->va_b <= addr && addr <= ent->va_e) {
+if (ent->itree.start <= addr && addr <= ent->itree.last) {
 trace_hppa_tlb_find_entry(env, ent + i, ent->entry_valid,
-  ent->va_b, ent->va_e, ent->pa);
+  ent->itree.start, ent->itree.last,
+  ent->pa);
 return ent;
 }
 }
@@ -50,11 +51,12 @@ static void hppa_flush_tlb_ent(CPUHPPAState *env, 
HPPATLBEntry *ent,
 return;
 }
 
-trace_hppa_tlb_flush_ent(env, ent, ent->va_b, ent->va_e, ent->pa);
+trace_hppa_tlb_flush_ent(env, ent, ent->itree.start,
+ ent->itree.last, ent->pa);
 
-tlb_flush_range_by_mmuidx(cs, ent->va_b,
-ent->va_e - ent->va_b + 1,
-HPPA_MMU_FLUSH_MASK, TARGET_LONG_BITS);
+tlb_flush_range_by_mmuidx(cs, ent->itree.start,
+  ent->itree.last - ent->itree.start + 1,
+  HPPA_MMU_FLUSH_MASK, TARGET_LONG_BITS);
 
 /* never clear BTLBs, unless forced to do so. */
 if (ent < >tlb[HPPA_BTLB_ENTRIES] && !force_flush_btlb) {
@@ -62,7 +64,7 @@ static void hppa_flush_tlb_ent(CPUHPPAState *env, 
HPPATLBEntry *ent,
 }
 
 memset(ent, 0, sizeof(*ent));
-ent->va_b = -1;
+ent->itree.start = -1;
 }
 
 static HPPATLBEntry *hppa_alloc_tlb_ent(CPUHPPAState *env)
@@ -118,7 +120,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr 
addr, int mmu_idx,
 }
 
 /* We now know the physical address.  */
-phys = ent->pa + (addr - ent->va_b);
+phys = ent->pa + (addr - ent->itree.start);
 
 /* Map TLB access_rights field to QEMU protection.  */
 priv = MMU_IDX_TO_PRIV(mmu_idx);
@@ -281,7 +283,7 @@ void HELPER(itlba)(CPUHPPAState *env, target_ulong addr, 
target_ureg reg)
 /* Zap any old entries covering ADDR; notice empty entries on the way.  */
 for (i = HPPA_BTLB_ENTRIES; i < ARRAY_SIZE(env->tlb); ++i) {
 HPPATLBEntry *ent = >tlb[i];
-if (ent->va_b <= addr && addr <= ent->va_e) {
+if (ent->itree.start <= addr && addr <= ent->itree.last) {
 if (ent->entry_valid) {
 hppa_flush_tlb_ent(env, ent, false);
 }
@@ -297,10 +299,11 @@ void HELPER(itlba)(CPUHPPAState *env, target_ulong addr, 
target_ureg reg)
 }
 
 /* Note that empty->entry_valid == 0 already.  */
-empty->va_b = addr & TARGET_PAGE_MASK;
-empty->va_e = empty->va_b + TARGET_PAGE_SIZE - 1;
+empty->itree.start = addr & TARGET_PAGE_MASK;
+empty->itree.last = empty->itree.start + TARGET_PAGE_SIZE - 1;
 empty->pa = 

[PATCH v3 48/88] target/hppa: Decode ADDB double-word

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 7f767fea64..1b4fa401ba 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3143,6 +3143,17 @@ static bool do_addb(DisasContext *ctx, unsigned r, 
TCGv_reg in1,
 DisasCond cond;
 bool d = false;
 
+/*
+ * For hppa64, the ADDB conditions change with PSW.W,
+ * dropping ZNV, SV, OD in favor of double-word EQ, LT, LE.
+ */
+if (ctx->tb_flags & PSW_W) {
+d = c >= 5;
+if (d) {
+c &= 3;
+}
+}
+
 in2 = load_gpr(ctx, r);
 dest = tcg_temp_new();
 sv = NULL;
-- 
2.34.1




[PATCH v3 05/88] target/hppa: Split out hppa_flush_tlb_range

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/mem_helper.c | 39 ---
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 60cae646cc..828cceb29c 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -67,6 +67,25 @@ static void hppa_flush_tlb_ent(CPUHPPAState *env, 
HPPATLBEntry *ent,
 ent->itree.start = -1;
 }
 
+static HPPATLBEntry *hppa_flush_tlb_range(CPUHPPAState *env,
+  vaddr va_b, vaddr va_e)
+{
+HPPATLBEntry *empty = NULL;
+
+/* Zap any old entries covering ADDR; notice empty entries on the way.  */
+for (int i = HPPA_BTLB_ENTRIES; i < ARRAY_SIZE(env->tlb); ++i) {
+HPPATLBEntry *ent = >tlb[i];
+
+if (!ent->entry_valid) {
+empty = ent;
+} else if (va_e >= ent->itree.start && va_b <= ent->itree.last) {
+hppa_flush_tlb_ent(env, ent, false);
+empty = ent;
+}
+}
+return empty;
+}
+
 static HPPATLBEntry *hppa_alloc_tlb_ent(CPUHPPAState *env)
 {
 HPPATLBEntry *ent;
@@ -284,21 +303,11 @@ bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
 /* Insert (Insn/Data) TLB Address.  Note this is PA 1.1 only.  */
 void HELPER(itlba)(CPUHPPAState *env, target_ulong addr, target_ureg reg)
 {
-HPPATLBEntry *empty = NULL;
-int i;
+HPPATLBEntry *empty;
 
 /* Zap any old entries covering ADDR; notice empty entries on the way.  */
-for (i = HPPA_BTLB_ENTRIES; i < ARRAY_SIZE(env->tlb); ++i) {
-HPPATLBEntry *ent = >tlb[i];
-if (ent->itree.start <= addr && addr <= ent->itree.last) {
-if (ent->entry_valid) {
-hppa_flush_tlb_ent(env, ent, false);
-}
-if (!empty) {
-empty = ent;
-}
-}
-}
+addr &= TARGET_PAGE_MASK;
+empty = hppa_flush_tlb_range(env, addr, addr + TARGET_PAGE_SIZE - 1);
 
 /* If we didn't see an empty entry, evict one.  */
 if (empty == NULL) {
@@ -306,8 +315,8 @@ void HELPER(itlba)(CPUHPPAState *env, target_ulong addr, 
target_ureg reg)
 }
 
 /* Note that empty->entry_valid == 0 already.  */
-empty->itree.start = addr & TARGET_PAGE_MASK;
-empty->itree.last = empty->itree.start + TARGET_PAGE_SIZE - 1;
+empty->itree.start = addr;
+empty->itree.last = addr + TARGET_PAGE_SIZE - 1;
 empty->pa = extract32(reg, 5, 20) << TARGET_PAGE_BITS;
 trace_hppa_tlb_itlba(env, empty, empty->itree.start,
  empty->itree.last, empty->pa);
-- 
2.34.1




[PATCH v3 34/88] target/hppa: Pass d to do_log_cond

2023-11-01 Thread Richard Henderson
Hoist the resolution of d up one level above do_log_cond.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 48 -
 1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 72971097bb..ac7f1f048c 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -983,9 +983,11 @@ static DisasCond do_sub_cond(DisasContext *ctx, unsigned 
cf, bool d,
  * how cases c={2,3} are treated.
  */
 
-static DisasCond do_log_cond(DisasContext *ctx, unsigned cf, TCGv_reg res)
+static DisasCond do_log_cond(DisasContext *ctx, unsigned cf, bool d,
+ TCGv_reg res)
 {
-bool d = false;
+TCGCond tc;
+bool ext_uns;
 
 switch (cf) {
 case 0:  /* never */
@@ -1001,17 +1003,29 @@ static DisasCond do_log_cond(DisasContext *ctx, 
unsigned cf, TCGv_reg res)
 return cond_make_t();
 
 case 2:  /* == */
-return cond_make_0(TCG_COND_EQ, res);
+tc = TCG_COND_EQ;
+ext_uns = true;
+break;
 case 3:  /* <> */
-return cond_make_0(TCG_COND_NE, res);
+tc = TCG_COND_NE;
+ext_uns = true;
+break;
 case 4:  /* < */
-return cond_make_0(TCG_COND_LT, res);
+tc = TCG_COND_LT;
+ext_uns = false;
+break;
 case 5:  /* >= */
-return cond_make_0(TCG_COND_GE, res);
+tc = TCG_COND_GE;
+ext_uns = false;
+break;
 case 6:  /* <= */
-return cond_make_0(TCG_COND_LE, res);
+tc = TCG_COND_LE;
+ext_uns = false;
+break;
 case 7:  /* > */
-return cond_make_0(TCG_COND_GT, res);
+tc = TCG_COND_GT;
+ext_uns = false;
+break;
 
 case 14: /* OD */
 case 15: /* EV */
@@ -1020,6 +1034,18 @@ static DisasCond do_log_cond(DisasContext *ctx, unsigned 
cf, TCGv_reg res)
 default:
 g_assert_not_reached();
 }
+
+if (cond_need_ext(ctx, d)) {
+TCGv_reg tmp = tcg_temp_new();
+
+if (ext_uns) {
+tcg_gen_ext32u_reg(tmp, res);
+} else {
+tcg_gen_ext32s_reg(tmp, res);
+}
+return cond_make_0_tmp(tc, tmp);
+}
+return cond_make_0(tc, res);
 }
 
 /* Similar, but for shift/extract/deposit conditions.  */
@@ -1027,6 +1053,7 @@ static DisasCond do_log_cond(DisasContext *ctx, unsigned 
cf, TCGv_reg res)
 static DisasCond do_sed_cond(DisasContext *ctx, unsigned orig, TCGv_reg res)
 {
 unsigned c, f;
+bool d = false;
 
 /* Convert the compressed condition codes to standard.
0-2 are the same as logicals (nv,<,<=), while 3 is OD.
@@ -1037,7 +1064,7 @@ static DisasCond do_sed_cond(DisasContext *ctx, unsigned 
orig, TCGv_reg res)
 }
 f = (orig & 4) / 4;
 
-return do_log_cond(ctx, c * 2 + f, res);
+return do_log_cond(ctx, c * 2 + f, d, res);
 }
 
 /* Similar, but for unit conditions.  */
@@ -1381,6 +1408,7 @@ static void do_log(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
void (*fn)(TCGv_reg, TCGv_reg, TCGv_reg))
 {
 TCGv_reg dest = dest_gpr(ctx, rt);
+bool d = false;
 
 /* Perform the operation, and writeback.  */
 fn(dest, in1, in2);
@@ -1389,7 +1417,7 @@ static void do_log(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 /* Install the new nullification.  */
 cond_free(>null_cond);
 if (cf) {
-ctx->null_cond = do_log_cond(ctx, cf, dest);
+ctx->null_cond = do_log_cond(ctx, cf, d, dest);
 }
 }
 
-- 
2.34.1




[PATCH v3 72/88] target/hppa: Return zero for r0 from load_gpr

2023-11-01 Thread Richard Henderson
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 5d780bcf56..3d8240ea7d 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -307,9 +307,7 @@ static void cond_free(DisasCond *cond)
 static TCGv_i64 load_gpr(DisasContext *ctx, unsigned reg)
 {
 if (reg == 0) {
-TCGv_i64 t = tcg_temp_new_i64();
-tcg_gen_movi_i64(t, 0);
-return t;
+return ctx->zero;
 } else {
 return cpu_gr[reg];
 }
-- 
2.34.1




[PATCH v3 87/88] hw/hppa: Allow C3700 with 64-bit and B160L with 32-bit CPU only

2023-11-01 Thread Richard Henderson
From: Helge Deller 

Prevent that users try to boot a 64-bit only C3700 machine with a 32-bit
CPU, and to boot a 32-bit only B160L machine with a 64-bit CPU.

Signed-off-by: Helge Deller 
---
 hw/hppa/machine.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index da9ca85806..a3222d3a96 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -528,6 +528,12 @@ static void machine_HP_B160L_init(MachineState *machine)
 /* Create CPUs and RAM.  */
 translate = machine_HP_common_init_cpus(machine);
 
+if (hppa_is_pa20([0]->env)) {
+error_report("The HP B160L workstation requires a 32-bit "
+ "CPU. Use '-machine C3700' instead.");
+exit(1);
+}
+
 /* Init Lasi chip */
 lasi_dev = DEVICE(lasi_init());
 memory_region_add_subregion(addr_space, translate(NULL, LASI_HPA),
@@ -602,6 +608,12 @@ static void machine_HP_C3700_init(MachineState *machine)
 /* Create CPUs and RAM.  */
 translate = machine_HP_common_init_cpus(machine);
 
+if (!hppa_is_pa20([0]->env)) {
+error_report("The HP C3000 workstation requires a 64-bit CPU. "
+ "Use '-machine B160L' instead.");
+exit(1);
+}
+
 /* Init Astro and the Elroys (PCI host bus chips).  */
 astro = astro_init();
 astro_dev = DEVICE(astro);
@@ -659,6 +671,11 @@ static void hppa_nmi(NMIState *n, int cpu_index, Error 
**errp)
 }
 }
 
+static const char *HP_B160L_machine_valid_cpu_types[] = {
+TYPE_HPPA_CPU,
+NULL
+};
+
 static void HP_B160L_machine_init_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
@@ -666,6 +683,7 @@ static void HP_B160L_machine_init_class_init(ObjectClass 
*oc, void *data)
 
 mc->desc = "HP B160L workstation";
 mc->default_cpu_type = TYPE_HPPA_CPU;
+mc->valid_cpu_types = HP_B160L_machine_valid_cpu_types;
 mc->init = machine_HP_B160L_init;
 mc->reset = hppa_machine_reset;
 mc->block_default_type = IF_SCSI;
@@ -690,6 +708,11 @@ static const TypeInfo HP_B160L_machine_init_typeinfo = {
 },
 };
 
+static const char *HP_C3700_machine_valid_cpu_types[] = {
+TYPE_HPPA64_CPU,
+NULL
+};
+
 static void HP_C3700_machine_init_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
@@ -697,6 +720,7 @@ static void HP_C3700_machine_init_class_init(ObjectClass 
*oc, void *data)
 
 mc->desc = "HP C3700 workstation";
 mc->default_cpu_type = TYPE_HPPA64_CPU;
+mc->valid_cpu_types = HP_C3700_machine_valid_cpu_types;
 mc->init = machine_HP_C3700_init;
 mc->reset = hppa_machine_reset;
 mc->block_default_type = IF_SCSI;
-- 
2.34.1




[PATCH v3 49/88] target/hppa: Implement LDD, LDCD, LDDA, STD, STDA

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode | 15 +++
 target/hppa/translate.c  |  4 
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 48f09c9b06..33eec3f4c3 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -215,9 +215,14 @@ ld  11 . . .. . 0 -- 00 size:2 
..   @ldstx
 st  11 . . .. . 1 -- 10 size:2 ..   @stim5
 ldc 11 . . .. . 1 -- 0111  ..   @ldim5 size=2
 ldc 11 . . .. . 0 -- 0111  ..   @ldstx size=2
+ldc 11 . . .. . 1 -- 0101  ..   @ldim5 size=3
+ldc 11 . . .. . 0 -- 0101  ..   @ldstx size=3
 lda 11 . . .. . 1 -- 0110  ..   @ldim5 size=2
 lda 11 . . .. . 0 -- 0110  ..   @ldstx size=2
+lda 11 . . .. . 1 -- 0100  ..   @ldim5 size=3
+lda 11 . . .. . 0 -- 0100  ..   @ldstx size=3
 sta 11 . . .. . 1 -- 1110  ..   @stim5 size=2
+sta 11 . . .. . 1 --   ..   @stim5 size=3
 stby11 b:5 r:5 sp:2 a:1 1 -- 1100 m:1   .   disp=%im5_0
 
 @fldstwx.. b:5 x:5   sp:2 scale:1 ... m:1 . \
@@ -244,6 +249,8 @@ fstd001011 . . .. . 1 -- 100 0 . .  
@fldstdi
 # Offset Mem
 
 
+@ldstim11   .. b:5 t:5 sp:2 ..  \
+ disp=%assemble_11a m=%ma2_to_m x=0 scale=0 size=3
 @ldstim14   .. b:5 t:5 sp:2 ..  \
  disp=%lowsign_14 x=0 scale=0 m=0
 @ldstim14m  .. b:5 t:5 sp:2 ..  \
@@ -275,11 +282,11 @@ fstw00 b:5 . sp:2 ..\
 fstw01 b:5 . sp:2 ...0..\
  disp=%assemble_12a t=%rm64 m=0 x=0 scale=0 size=2
 
-fldd010100 b:5 t:5   sp:2 .. .. 1 . \
- disp=%assemble_11a m=%ma2_to_m x=0 scale=0 size=3
+ld  010100 . . .. 0.@ldstim11
+fldd010100 . . .. 1.@ldstim11
 
-fstd011100 b:5 t:5   sp:2 .. .. 1 . \
- disp=%assemble_11a m=%ma2_to_m x=0 scale=0 size=3
+st  011100 . . .. 0.@ldstim11
+fstd011100 . . .. 1.@ldstim11
 
 
 # Floating-point Multiply Add
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 1b4fa401ba..4562f865f4 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2972,6 +2972,10 @@ static bool trans_ldc(DisasContext *ctx, arg_ldst *a)
 TCGv_reg zero, dest, ofs;
 TCGv_tl addr;
 
+if (unlikely(TARGET_REGISTER_BITS == 32 && a->size > MO_32)) {
+return gen_illegal(ctx);
+}
+
 nullify_over(ctx);
 
 if (a->m) {
-- 
2.34.1




[PATCH v3 41/88] target/hppa: Decode d for unit instructions

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode | 14 +++---
 target/hppa/translate.c  | 25 -
 2 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 26ca9f1063..03b1a11cac 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -59,7 +59,7 @@
 # All insns that need to form a virtual address should use this set.
t b x disp sp m scale size
 
-_cf  t r cf
+_cf_dt r cf d
 _cf t r1 r2 cf
 _cf_d   t r1 r2 cf d
 _cf_sh  t r1 r2 cf sh
@@ -72,7 +72,7 @@
 # Format definitions
 
 
-@rr_cf  .. r:5 . cf:4 ... t:5   _cf
+@rr_cf_d.. r:5 . cf:4 .. d:1 t:5_cf_d
 @rrr_cf .. r2:5 r1:5 cf:4 ... t:5   _cf
 @rrr_cf_d   .. r2:5 r1:5 cf:4 .. d:1 t:5_cf_d
 @rrr_cf_sh  .. r2:5 r1:5 cf:4  sh:2 . t:5   _cf_sh
@@ -156,13 +156,13 @@ andcm   10 . .  00 . .  
@rrr_cf_d
 and 10 . .  001000 . .  @rrr_cf_d
 or  10 . .  001001 . .  @rrr_cf_d
 xor 10 . .  001010 . .  @rrr_cf_d
-uxor10 . .  001110 0 .  @rrr_cf
+uxor10 . .  001110 . .  @rrr_cf_d
 ds  10 . .  010001 0 .  @rrr_cf
 cmpclr  10 . .  100010 0 .  @rrr_cf
-uaddcm  10 . .  100110 0 .  @rrr_cf
-uaddcm_tc   10 . .  100111 0 .  @rrr_cf
-dcor10 . 0  101110 0 .  @rr_cf
-dcor_i  10 . 0  10 0 .  @rr_cf
+uaddcm  10 . .  100110 . .  @rrr_cf_d
+uaddcm_tc   10 . .  100111 . .  @rrr_cf_d
+dcor10 . 0  101110 . .  @rr_cf_d
+dcor_i  10 . 0  10 . .  @rr_cf_d
 
 add 10 . .  0110.. - .  @rrr_cf_sh
 add_l   10 . .  1010.. 0 .  @rrr_cf_sh
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 227d59b263..a0785bb32c 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1436,12 +1436,11 @@ static bool do_log_reg(DisasContext *ctx, arg_rrr_cf_d 
*a,
 }
 
 static void do_unit(DisasContext *ctx, unsigned rt, TCGv_reg in1,
-TCGv_reg in2, unsigned cf, bool is_tc,
+TCGv_reg in2, unsigned cf, bool d, bool is_tc,
 void (*fn)(TCGv_reg, TCGv_reg, TCGv_reg))
 {
 TCGv_reg dest;
 DisasCond cond;
-bool d = false;
 
 if (cf == 0) {
 dest = dest_gpr(ctx, rt);
@@ -2772,7 +2771,7 @@ static bool trans_cmpclr(DisasContext *ctx, arg_rrr_cf *a)
 return nullify_end(ctx);
 }
 
-static bool trans_uxor(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_uxor(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 TCGv_reg tcg_r1, tcg_r2;
 
@@ -2781,11 +2780,11 @@ static bool trans_uxor(DisasContext *ctx, arg_rrr_cf *a)
 }
 tcg_r1 = load_gpr(ctx, a->r1);
 tcg_r2 = load_gpr(ctx, a->r2);
-do_unit(ctx, a->t, tcg_r1, tcg_r2, a->cf, false, tcg_gen_xor_reg);
+do_unit(ctx, a->t, tcg_r1, tcg_r2, a->cf, a->d, false, tcg_gen_xor_reg);
 return nullify_end(ctx);
 }
 
-static bool do_uaddcm(DisasContext *ctx, arg_rrr_cf *a, bool is_tc)
+static bool do_uaddcm(DisasContext *ctx, arg_rrr_cf_d *a, bool is_tc)
 {
 TCGv_reg tcg_r1, tcg_r2, tmp;
 
@@ -2796,21 +2795,21 @@ static bool do_uaddcm(DisasContext *ctx, arg_rrr_cf *a, 
bool is_tc)
 tcg_r2 = load_gpr(ctx, a->r2);
 tmp = tcg_temp_new();
 tcg_gen_not_reg(tmp, tcg_r2);
-do_unit(ctx, a->t, tcg_r1, tmp, a->cf, is_tc, tcg_gen_add_reg);
+do_unit(ctx, a->t, tcg_r1, tmp, a->cf, a->d, is_tc, tcg_gen_add_reg);
 return nullify_end(ctx);
 }
 
-static bool trans_uaddcm(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_uaddcm(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 return do_uaddcm(ctx, a, false);
 }
 
-static bool trans_uaddcm_tc(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_uaddcm_tc(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 return do_uaddcm(ctx, a, true);
 }
 
-static bool do_dcor(DisasContext *ctx, arg_rr_cf *a, bool is_i)
+static bool do_dcor(DisasContext *ctx, arg_rr_cf_d *a, bool is_i)
 {
 TCGv_reg tmp;
 
@@ -2821,19 +2820,19 @@ static bool do_dcor(DisasContext *ctx, arg_rr_cf *a, 
bool is_i)
 if (!is_i) {
 tcg_gen_not_reg(tmp, tmp);
 }
-tcg_gen_andi_reg(tmp, tmp, 0x);
+tcg_gen_andi_reg(tmp, tmp, (target_ureg)0xull);
 tcg_gen_muli_reg(tmp, tmp, 6);
-do_unit(ctx, a->t, load_gpr(ctx, a->r), tmp, a->cf, false,
+do_unit(ctx, a->t, load_gpr(ctx, a->r), tmp, a->cf, a->d, false,
 is_i ? tcg_gen_add_reg : tcg_gen_sub_reg);
 return nullify_end(ctx);
 }
 

[PATCH v3 82/88] target/hppa: Update IIAOQ, IIASQ for pa2.0

2023-11-01 Thread Richard Henderson
These registers have a different format for pa2.0.

Signed-off-by: Richard Henderson 
---
 target/hppa/int_helper.c | 46 
 target/hppa/sys_helper.c | 10 +
 2 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index a11d607b31..54875442e7 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -102,11 +102,7 @@ void hppa_cpu_do_interrupt(CPUState *cs)
 HPPACPU *cpu = HPPA_CPU(cs);
 CPUHPPAState *env = >env;
 int i = cs->exception_index;
-target_ulong iaoq_f = env->iaoq_f;
-target_ulong iaoq_b = env->iaoq_b;
-uint64_t iasq_f = env->iasq_f;
-uint64_t iasq_b = env->iasq_b;
-target_ulong old_psw;
+uint64_t old_psw;
 
 /* As documented in pa2.0 -- interruption handling.  */
 /* step 1 */
@@ -118,10 +114,25 @@ void hppa_cpu_do_interrupt(CPUState *cs)
  (i == EXCP_HPMC ? PSW_M : 0));
 
 /* step 3 */
-env->cr[CR_IIASQ] = iasq_f >> 32;
-env->cr_back[0] = iasq_b >> 32;
-env->cr[CR_IIAOQ] = iaoq_f;
-env->cr_back[1] = iaoq_b;
+/*
+ * For pa1.x, IIASQ is simply a copy of IASQ.
+ * For pa2.0, IIASQ is the top bits of the virtual address,
+ *or zero if translation is disabled.
+ */
+if (!hppa_is_pa20(env)) {
+env->cr[CR_IIASQ] = env->iasq_f >> 32;
+env->cr_back[0] = env->iasq_b >> 32;
+} else if (old_psw & PSW_C) {
+env->cr[CR_IIASQ] =
+hppa_form_gva_psw(old_psw, env->iasq_f, env->iaoq_f) >> 32;
+env->cr_back[0] =
+hppa_form_gva_psw(old_psw, env->iasq_f, env->iaoq_f) >> 32;
+} else {
+env->cr[CR_IIASQ] = 0;
+env->cr_back[0] = 0;
+}
+env->cr[CR_IIAOQ] = env->iaoq_f;
+env->cr_back[1] = env->iaoq_b;
 
 if (old_psw & PSW_Q) {
 /* step 5 */
@@ -154,14 +165,13 @@ void hppa_cpu_do_interrupt(CPUState *cs)
 /* ??? An alternate fool-proof method would be to store the
instruction data into the unwind info.  That's probably
a bit too much in the way of extra storage required.  */
-vaddr vaddr;
-hwaddr paddr;
+vaddr vaddr = env->iaoq_f & -4;
+hwaddr paddr = vaddr;
 
-paddr = vaddr = iaoq_f & -4;
 if (old_psw & PSW_C) {
 int prot, t;
 
-vaddr = hppa_form_gva_psw(old_psw, iasq_f, vaddr);
+vaddr = hppa_form_gva_psw(old_psw, env->iasq_f, vaddr);
 t = hppa_get_physical_address(env, vaddr, MMU_KERNEL_IDX,
   0, , , NULL);
 if (t >= 0) {
@@ -191,14 +201,14 @@ void hppa_cpu_do_interrupt(CPUState *cs)
 
 /* step 7 */
 if (i == EXCP_TOC) {
-env->iaoq_f = FIRMWARE_START;
+env->iaoq_f = hppa_form_gva(env, 0, FIRMWARE_START);
 /* help SeaBIOS and provide iaoq_b and iasq_back in shadow regs */
 env->gr[24] = env->cr_back[0];
 env->gr[25] = env->cr_back[1];
 } else {
-env->iaoq_f = env->cr[CR_IVA] + 32 * i;
+env->iaoq_f = hppa_form_gva(env, 0, env->cr[CR_IVA] + 32 * i);
 }
-env->iaoq_b = env->iaoq_f + 4;
+env->iaoq_b = hppa_form_gva(env, 0, env->iaoq_f + 4);
 env->iasq_f = 0;
 env->iasq_b = 0;
 
@@ -251,8 +261,8 @@ void hppa_cpu_do_interrupt(CPUState *cs)
 qemu_log("INT %6d: %s @ " TARGET_FMT_lx "," TARGET_FMT_lx
  " -> " TARGET_FMT_lx " " TARGET_FMT_lx "\n",
  ++count, name,
- hppa_form_gva(env, iasq_f, iaoq_f),
- hppa_form_gva(env, iasq_b, iaoq_b),
+ hppa_form_gva(env, env->iasq_f, env->iaoq_f),
+ hppa_form_gva(env, env->iasq_b, env->iaoq_b),
  env->iaoq_f,
  hppa_form_gva(env, (uint64_t)env->cr[CR_ISR] << 32,
env->cr[CR_IOR]));
diff --git a/target/hppa/sys_helper.c b/target/hppa/sys_helper.c
index 8850576ac3..a59245eed3 100644
--- a/target/hppa/sys_helper.c
+++ b/target/hppa/sys_helper.c
@@ -80,6 +80,16 @@ void HELPER(rfi)(CPUHPPAState *env)
 env->iasq_b = (uint64_t)env->cr_back[0] << 32;
 env->iaoq_f = env->cr[CR_IIAOQ];
 env->iaoq_b = env->cr_back[1];
+
+/*
+ * For pa2.0, IIASQ is the top bits of the virtual address.
+ * To recreate the space identifier, remove the offset bits.
+ */
+if (hppa_is_pa20(env)) {
+env->iasq_f &= ~env->iaoq_f;
+env->iasq_b &= ~env->iaoq_b;
+}
+
 cpu_hppa_put_psw(env, env->cr[CR_IPSW]);
 }
 
-- 
2.34.1




[PATCH v3 81/88] target/hppa: Create raise_exception_with_ior

2023-11-01 Thread Richard Henderson
Handle pa2.0 logic for filling in ISR+IOR.

Signed-off-by: Richard Henderson 
---
 target/hppa/mem_helper.c | 64 
 1 file changed, 51 insertions(+), 13 deletions(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 602e6c809f..858ce6ec7f 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -289,6 +289,53 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 return excp == EXCP_DTLB_MISS ? -1 : phys;
 }
 
+G_NORETURN static void
+raise_exception_with_ior(CPUHPPAState *env, int excp, uintptr_t retaddr,
+ vaddr addr, bool mmu_disabled)
+{
+CPUState *cs = env_cpu(env);
+
+cs->exception_index = excp;
+
+if (env->psw & PSW_Q) {
+/*
+ * For pa1.x, the offset and space never overlap, and so we
+ * simply extract the high and low part of the virtual address.
+ *
+ * For pa2.0, the formation of these are described in section
+ * "Interruption Parameter Registers", page 2-15.
+ */
+env->cr[CR_IOR] = (uint32_t)addr;
+env->cr[CR_ISR] = addr >> 32;
+
+if (hppa_is_pa20(env)) {
+if (mmu_disabled) {
+/*
+ * If data translation was disabled, the ISR contains
+ * the upper portion of the abs address, zero-extended.
+ */
+env->cr[CR_ISR] &= 0x3fff;
+} else {
+/*
+ * If data translation was enabled, the upper two bits
+ * of the IOR (the b field) are equal to the two space
+ * bits from the base register used to form the gva.
+ */
+uint64_t b;
+
+cpu_restore_state(cs, retaddr);
+
+b = env->gr[env->unwind_breg];
+b >>= (env->psw & PSW_W ? 62 : 30);
+env->cr[CR_IOR] |= b << 62;
+
+cpu_loop_exit(cs);
+}
+}
+}
+cpu_loop_exit_restore(cs, retaddr);
+}
+
 bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
MMUAccessType type, int mmu_idx,
bool probe, uintptr_t retaddr)
@@ -318,14 +365,10 @@ bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
 return false;
 }
 trace_hppa_tlb_fill_excp(env, addr, size, type, mmu_idx);
+
 /* Failure.  Raise the indicated exception.  */
-cs->exception_index = excp;
-if (cpu->env.psw & PSW_Q) {
-/* ??? Needs tweaking for hppa64.  */
-cpu->env.cr[CR_IOR] = addr;
-cpu->env.cr[CR_ISR] = addr >> 32;
-}
-cpu_loop_exit_restore(cs, retaddr);
+raise_exception_with_ior(env, excp, retaddr,
+ addr, mmu_idx == MMU_PHYS_IDX);
 }
 
 trace_hppa_tlb_fill_success(env, addr & TARGET_PAGE_MASK,
@@ -553,16 +596,11 @@ target_ulong HELPER(lpa)(CPUHPPAState *env, target_ulong 
addr)
 excp = hppa_get_physical_address(env, addr, MMU_KERNEL_IDX, 0,
  , , NULL);
 if (excp >= 0) {
-if (env->psw & PSW_Q) {
-/* ??? Needs tweaking for hppa64.  */
-env->cr[CR_IOR] = addr;
-env->cr[CR_ISR] = addr >> 32;
-}
 if (excp == EXCP_DTLB_MISS) {
 excp = EXCP_NA_DTLB_MISS;
 }
 trace_hppa_tlb_lpa_failed(env, addr);
-hppa_dynamic_excp(env, excp, GETPC());
+raise_exception_with_ior(env, excp, GETPC(), addr, false);
 }
 trace_hppa_tlb_lpa_success(env, addr, phys);
 return phys;
-- 
2.34.1




[PATCH v3 75/88] linux-user/hppa: Drop EXCP_DUMP from handled exceptions

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/hppa/cpu_loop.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
index 8ab1335106..d5232f37fe 100644
--- a/linux-user/hppa/cpu_loop.c
+++ b/linux-user/hppa/cpu_loop.c
@@ -147,12 +147,10 @@ void cpu_loop(CPUHPPAState *env)
 force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, env->iaoq_f);
 break;
 case EXCP_ILL:
-EXCP_DUMP(env, "qemu: EXCP_ILL exception %#x\n", trapnr);
 force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->iaoq_f);
 break;
 case EXCP_PRIV_OPR:
 /* check for glibc ABORT_INSTRUCTION "iitlbp %r0,(%sr0, %r0)" */
-EXCP_DUMP(env, "qemu: EXCP_PRIV_OPR exception %#x\n", trapnr);
 if (env->cr[CR_IIR] == 0x0400) {
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, 
env->iaoq_f);
 } else {
@@ -160,7 +158,6 @@ void cpu_loop(CPUHPPAState *env)
 }
 break;
 case EXCP_PRIV_REG:
-EXCP_DUMP(env, "qemu: EXCP_PRIV_REG exception %#x\n", trapnr);
 force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVREG, env->iaoq_f);
 break;
 case EXCP_OVERFLOW:
@@ -173,7 +170,6 @@ void cpu_loop(CPUHPPAState *env)
 force_sig_fault(TARGET_SIGFPE, 0, env->iaoq_f);
 break;
 case EXCP_BREAK:
-EXCP_DUMP(env, "qemu: EXCP_BREAK exception %#x\n", trapnr);
 force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->iaoq_f & 
~3);
 break;
 case EXCP_DEBUG:
-- 
2.34.1




[PATCH v3 42/88] target/hppa: Decode d for cmpclr instructions

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode |  6 --
 target/hppa/translate.c  | 11 +--
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 03b1a11cac..d4a03b0299 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -64,6 +64,7 @@
 _cf_d   t r1 r2 cf d
 _cf_sh  t r1 r2 cf sh
 _cf t r i cf
+_cf_d   t r i cf d
 
 _c_fdisp n c f r1 r2
 _c_fdisp n c f r i
@@ -78,6 +79,7 @@
 @rrr_cf_sh  .. r2:5 r1:5 cf:4  sh:2 . t:5   _cf_sh
 @rrr_cf_sh0 .. r2:5 r1:5 cf:4 ... t:5   _cf_sh sh=0
 @rri_cf .. r:5  t:5  cf:4 . ... _cf i=%lowsign_11
+@rri_cf_d   .. r:5  t:5  cf:4 d:1 ...   _cf_d i=%lowsign_11
 
 @rrb_cf .. r2:5 r1:5 c:3 ... n:1 .  \
 _c_f disp=%assemble_12
@@ -158,7 +160,7 @@ or  10 . .  001001 . .  
@rrr_cf_d
 xor 10 . .  001010 . .  @rrr_cf_d
 uxor10 . .  001110 . .  @rrr_cf_d
 ds  10 . .  010001 0 .  @rrr_cf
-cmpclr  10 . .  100010 0 .  @rrr_cf
+cmpclr  10 . .  100010 . .  @rrr_cf_d
 uaddcm  10 . .  100110 . .  @rrr_cf_d
 uaddcm_tc   10 . .  100111 . .  @rrr_cf_d
 dcor10 . 0  101110 . .  @rr_cf_d
@@ -189,7 +191,7 @@ addi_tc_tsv 101100 . .  1 ...   
@rri_cf
 subi100101 . .  0 ...   @rri_cf
 subi_tsv100101 . .  1 ...   @rri_cf
 
-cmpiclr 100100 . .  0 ...   @rri_cf
+cmpiclr 100100 . .  . ...   @rri_cf_d
 
 
 # Index Mem
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index a0785bb32c..8301d007ff 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1377,11 +1377,10 @@ static bool do_sub_imm(DisasContext *ctx, arg_rri_cf 
*a, bool is_tsv)
 }
 
 static void do_cmpclr(DisasContext *ctx, unsigned rt, TCGv_reg in1,
-  TCGv_reg in2, unsigned cf)
+  TCGv_reg in2, unsigned cf, bool d)
 {
 TCGv_reg dest, sv;
 DisasCond cond;
-bool d = false;
 
 dest = tcg_temp_new();
 tcg_gen_sub_reg(dest, in1, in2);
@@ -2758,7 +2757,7 @@ static bool trans_xor(DisasContext *ctx, arg_rrr_cf_d *a)
 return do_log_reg(ctx, a, tcg_gen_xor_reg);
 }
 
-static bool trans_cmpclr(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_cmpclr(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 TCGv_reg tcg_r1, tcg_r2;
 
@@ -2767,7 +2766,7 @@ static bool trans_cmpclr(DisasContext *ctx, arg_rrr_cf *a)
 }
 tcg_r1 = load_gpr(ctx, a->r1);
 tcg_r2 = load_gpr(ctx, a->r2);
-do_cmpclr(ctx, a->t, tcg_r1, tcg_r2, a->cf);
+do_cmpclr(ctx, a->t, tcg_r1, tcg_r2, a->cf, a->d);
 return nullify_end(ctx);
 }
 
@@ -2925,7 +2924,7 @@ static bool trans_subi_tsv(DisasContext *ctx, arg_rri_cf 
*a)
 return do_sub_imm(ctx, a, true);
 }
 
-static bool trans_cmpiclr(DisasContext *ctx, arg_rri_cf *a)
+static bool trans_cmpiclr(DisasContext *ctx, arg_rri_cf_d *a)
 {
 TCGv_reg tcg_im, tcg_r2;
 
@@ -2935,7 +2934,7 @@ static bool trans_cmpiclr(DisasContext *ctx, arg_rri_cf 
*a)
 
 tcg_im = tcg_constant_reg(a->i);
 tcg_r2 = load_gpr(ctx, a->r);
-do_cmpclr(ctx, a->t, tcg_im, tcg_r2, a->cf);
+do_cmpclr(ctx, a->t, tcg_im, tcg_r2, a->cf, a->d);
 
 return nullify_end(ctx);
 }
-- 
2.34.1




[PATCH v3 54/88] target/hppa: Implement STDBY

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/helper.h |   5 ++
 target/hppa/insns.decode |   1 +
 target/hppa/op_helper.c  | 178 +--
 target/hppa/translate.c  |  31 +++
 4 files changed, 210 insertions(+), 5 deletions(-)

diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index 647f043c85..9920d38ded 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -16,6 +16,11 @@ DEF_HELPER_FLAGS_3(stby_b_parallel, TCG_CALL_NO_WG, void, 
env, tl, tr)
 DEF_HELPER_FLAGS_3(stby_e, TCG_CALL_NO_WG, void, env, tl, tr)
 DEF_HELPER_FLAGS_3(stby_e_parallel, TCG_CALL_NO_WG, void, env, tl, tr)
 
+DEF_HELPER_FLAGS_3(stdby_b, TCG_CALL_NO_WG, void, env, tl, tr)
+DEF_HELPER_FLAGS_3(stdby_b_parallel, TCG_CALL_NO_WG, void, env, tl, tr)
+DEF_HELPER_FLAGS_3(stdby_e, TCG_CALL_NO_WG, void, env, tl, tr)
+DEF_HELPER_FLAGS_3(stdby_e_parallel, TCG_CALL_NO_WG, void, env, tl, tr)
+
 DEF_HELPER_FLAGS_1(ldc_check, TCG_CALL_NO_RWG, void, tl)
 
 DEF_HELPER_FLAGS_4(probe, TCG_CALL_NO_WG, tr, env, tl, i32, i32)
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index ba7731b517..9d8c6a1a16 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -228,6 +228,7 @@ lda 11 . . .. . 0 -- 0100  
..   @ldstx size=3
 sta 11 . . .. . 1 -- 1110  ..   @stim5 size=2
 sta 11 . . .. . 1 --   ..   @stim5 size=3
 stby11 b:5 r:5 sp:2 a:1 1 -- 1100 m:1   .   disp=%im5_0
+stdby   11 b:5 r:5 sp:2 a:1 1 -- 1101 m:1   .   disp=%im5_0
 
 @fldstwx.. b:5 x:5   sp:2 scale:1 ... m:1 . \
  t=%rt64 disp=0 size=2
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index 837e2b3117..94c9ca5858 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -56,11 +56,11 @@ void HELPER(tcond)(CPUHPPAState *env, target_ureg cond)
 }
 }
 
-static void atomic_store_3(CPUHPPAState *env, target_ulong addr,
-   uint32_t val, uintptr_t ra)
+static void atomic_store_mask32(CPUHPPAState *env, target_ulong addr,
+uint32_t val, uint32_t mask, uintptr_t ra)
 {
 int mmu_idx = cpu_mmu_index(env, 0);
-uint32_t old, new, cmp, mask, *haddr;
+uint32_t old, new, cmp, *haddr;
 void *vaddr;
 
 vaddr = probe_access(env, addr, 3, MMU_DATA_STORE, mmu_idx, ra);
@@ -81,6 +81,35 @@ static void atomic_store_3(CPUHPPAState *env, target_ulong 
addr,
 }
 }
 
+static void atomic_store_mask64(CPUHPPAState *env, target_ulong addr,
+uint64_t val, uint64_t mask,
+int size, uintptr_t ra)
+{
+#ifdef CONFIG_ATOMIC64
+int mmu_idx = cpu_mmu_index(env, 0);
+uint64_t old, new, cmp, *haddr;
+void *vaddr;
+
+vaddr = probe_access(env, addr, size, MMU_DATA_STORE, mmu_idx, ra);
+if (vaddr == NULL) {
+cpu_loop_exit_atomic(env_cpu(env), ra);
+}
+haddr = (uint64_t *)((uintptr_t)vaddr & -8);
+
+old = *haddr;
+while (1) {
+new = be32_to_cpu((cpu_to_be32(old) & ~mask) | (val & mask));
+cmp = qatomic_cmpxchg__nocheck(haddr, old, new);
+if (cmp == old) {
+return;
+}
+old = cmp;
+}
+#else
+cpu_loop_exit_atomic(env_cpu(env), ra);
+#endif
+}
+
 static void do_stby_b(CPUHPPAState *env, target_ulong addr, target_ureg val,
   bool parallel, uintptr_t ra)
 {
@@ -94,7 +123,7 @@ static void do_stby_b(CPUHPPAState *env, target_ulong addr, 
target_ureg val,
 case 1:
 /* The 3 byte store must appear atomic.  */
 if (parallel) {
-atomic_store_3(env, addr, val, ra);
+atomic_store_mask32(env, addr, val, 0x00ffu, ra);
 } else {
 cpu_stb_data_ra(env, addr, val >> 16, ra);
 cpu_stw_data_ra(env, addr + 1, val, ra);
@@ -106,6 +135,62 @@ static void do_stby_b(CPUHPPAState *env, target_ulong 
addr, target_ureg val,
 }
 }
 
+static void do_stdby_b(CPUHPPAState *env, target_ulong addr, uint64_t val,
+   bool parallel, uintptr_t ra)
+{
+switch (addr & 7) {
+case 7:
+cpu_stb_data_ra(env, addr, val, ra);
+break;
+case 6:
+cpu_stw_data_ra(env, addr, val, ra);
+break;
+case 5:
+/* The 3 byte store must appear atomic.  */
+if (parallel) {
+atomic_store_mask32(env, addr, val, 0x00ffu, ra);
+} else {
+cpu_stb_data_ra(env, addr, val >> 16, ra);
+cpu_stw_data_ra(env, addr + 1, val, ra);
+}
+break;
+case 4:
+cpu_stl_data_ra(env, addr, val, ra);
+break;
+case 3:
+/* The 5 byte store must appear atomic.  */
+if (parallel) {
+atomic_store_mask64(env, addr, val, 0x00ffull, 5, ra);
+} else {
+cpu_stb_data_ra(env, addr, 

[PATCH v3 44/88] target/hppa: Decode d for sub instructions

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode | 12 ++--
 target/hppa/translate.c  | 22 +++---
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 0f29869949..ad454adcbb 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -172,12 +172,12 @@ add_tsv 10 . .  1110.. . .  
@rrr_cf_d_sh
 add_c   10 . .  011100 . .  @rrr_cf_d_sh0
 add_c_tsv   10 . .  00 . .  @rrr_cf_d_sh0
 
-sub 10 . .  01 - .  @rrr_cf
-sub_tsv 10 . .  11 0 .  @rrr_cf
-sub_tc  10 . .  010011 0 .  @rrr_cf
-sub_tsv_tc  10 . .  110011 0 .  @rrr_cf
-sub_b   10 . .  010100 0 .  @rrr_cf
-sub_b_tsv   10 . .  110100 0 .  @rrr_cf
+sub 10 . .  01 . .  @rrr_cf_d
+sub_tsv 10 . .  11 . .  @rrr_cf_d
+sub_tc  10 . .  010011 . .  @rrr_cf_d
+sub_tsv_tc  10 . .  110011 . .  @rrr_cf_d
+sub_b   10 . .  010100 . .  @rrr_cf_d
+sub_b_tsv   10 . .  110100 . .  @rrr_cf_d
 
 ldil001000 t:5 .i=%assemble_21
 addil   001010 r:5 .i=%assemble_21
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 2f5cc597ad..f2b2933c88 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1287,12 +1287,11 @@ static bool do_add_imm(DisasContext *ctx, arg_rri_cf *a,
 
 static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
TCGv_reg in2, bool is_tsv, bool is_b,
-   bool is_tc, unsigned cf)
+   bool is_tc, unsigned cf, bool d)
 {
 TCGv_reg dest, sv, cb, cb_msb, zero, tmp;
 unsigned c = cf >> 1;
 DisasCond cond;
-bool d = false;
 
 dest = tcg_temp_new();
 cb = tcg_temp_new();
@@ -1350,7 +1349,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 ctx->null_cond = cond;
 }
 
-static bool do_sub_reg(DisasContext *ctx, arg_rrr_cf *a,
+static bool do_sub_reg(DisasContext *ctx, arg_rrr_cf_d *a,
bool is_tsv, bool is_b, bool is_tc)
 {
 TCGv_reg tcg_r1, tcg_r2;
@@ -1360,7 +1359,7 @@ static bool do_sub_reg(DisasContext *ctx, arg_rrr_cf *a,
 }
 tcg_r1 = load_gpr(ctx, a->r1);
 tcg_r2 = load_gpr(ctx, a->r2);
-do_sub(ctx, a->t, tcg_r1, tcg_r2, is_tsv, is_b, is_tc, a->cf);
+do_sub(ctx, a->t, tcg_r1, tcg_r2, is_tsv, is_b, is_tc, a->cf, a->d);
 return nullify_end(ctx);
 }
 
@@ -1373,7 +1372,8 @@ static bool do_sub_imm(DisasContext *ctx, arg_rri_cf *a, 
bool is_tsv)
 }
 tcg_im = tcg_constant_reg(a->i);
 tcg_r2 = load_gpr(ctx, a->r);
-do_sub(ctx, a->t, tcg_im, tcg_r2, is_tsv, 0, 0, a->cf);
+/* All SUBI conditions are 32-bit. */
+do_sub(ctx, a->t, tcg_im, tcg_r2, is_tsv, 0, 0, a->cf, false);
 return nullify_end(ctx);
 }
 
@@ -2661,32 +2661,32 @@ static bool trans_add_c_tsv(DisasContext *ctx, 
arg_rrr_cf_d_sh *a)
 return do_add_reg(ctx, a, false, true, false, true);
 }
 
-static bool trans_sub(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_sub(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 return do_sub_reg(ctx, a, false, false, false);
 }
 
-static bool trans_sub_tsv(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_sub_tsv(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 return do_sub_reg(ctx, a, true, false, false);
 }
 
-static bool trans_sub_tc(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_sub_tc(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 return do_sub_reg(ctx, a, false, false, true);
 }
 
-static bool trans_sub_tsv_tc(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_sub_tsv_tc(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 return do_sub_reg(ctx, a, true, false, true);
 }
 
-static bool trans_sub_b(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_sub_b(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 return do_sub_reg(ctx, a, false, true, false);
 }
 
-static bool trans_sub_b_tsv(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_sub_b_tsv(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 return do_sub_reg(ctx, a, true, true, false);
 }
-- 
2.34.1




[PATCH v3 37/88] linux-user/hppa: Fixes for TARGET_ABI32

2023-11-01 Thread Richard Henderson
Avoid target_ulong and use abi_* types.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/hppa/signal.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/linux-user/hppa/signal.c b/linux-user/hppa/signal.c
index 17920e9ceb..d08a97dae6 100644
--- a/linux-user/hppa/signal.c
+++ b/linux-user/hppa/signal.c
@@ -86,7 +86,7 @@ static void setup_sigcontext(struct target_sigcontext *sc, 
CPUArchState *env)
 
 static void restore_sigcontext(CPUArchState *env, struct target_sigcontext *sc)
 {
-target_ulong psw;
+abi_ulong psw;
 int i;
 
 __get_user(psw, >sc_gr[0]);
@@ -150,10 +150,10 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
 haddr = ka->_sa_handler;
 if (haddr & 2) {
 /* Function descriptor.  */
-target_ulong *fdesc, dest;
+abi_ptr *fdesc, dest;
 
 haddr &= -4;
-fdesc = lock_user(VERIFY_READ, haddr, 2 * sizeof(target_ulong), 1);
+fdesc = lock_user(VERIFY_READ, haddr, 2 * sizeof(abi_ptr), 1);
 if (!fdesc) {
 goto give_sigsegv;
 }
-- 
2.34.1




[PATCH v3 46/88] target/hppa: Decode d for cmpb instructions

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode |  9 +++--
 target/hppa/translate.c  | 12 
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index b185523021..fc327e2bb3 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -67,6 +67,7 @@
 _cf_d   t r i cf d
 
 _c_fdisp n c f r1 r2
+_c_d_f  disp n c d f r1 r2
 _c_fdisp n c f r i
 
 
@@ -83,6 +84,8 @@
 
 @rrb_cf .. r2:5 r1:5 c:3 ... n:1 .  \
 _c_f disp=%assemble_12
+@rrb_cdf.. r2:5 r1:5 c:3 ... n:1 .  \
+_c_d_f disp=%assemble_12
 @rib_cf .. r:5 . c:3 ... n:1 .  \
 _c_f disp=%assemble_12 i=%im5_16
 
@@ -296,8 +299,10 @@ bb_imm  110001 p:5   r:5 c:1 1 d:1 ... n:1 
. disp=%assemble_12
 movb110010 . . ... ... . .  @rrb_cf f=0
 movbi   110011 . . ... ... . .  @rib_cf f=0
 
-cmpb10 . . ... ... . .  @rrb_cf f=0
-cmpb100010 . . ... ... . .  @rrb_cf f=1
+cmpb10 . . ... ... . .  @rrb_cdf d=0 f=0
+cmpb100010 . . ... ... . .  @rrb_cdf d=0 f=1
+cmpb100111 . . ... ... . .  @rrb_cdf d=1 f=0
+cmpb10 . . ... ... . .  @rrb_cdf d=1 f=1
 cmpbi   11 . . ... ... . .  @rib_cf f=0
 cmpbi   100011 . . ... ... . .  @rib_cf f=1
 
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index e326f63866..6cd06fbc0d 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3091,11 +3091,10 @@ static bool trans_ldo(DisasContext *ctx, arg_ldo *a)
 }
 
 static bool do_cmpb(DisasContext *ctx, unsigned r, TCGv_reg in1,
-unsigned c, unsigned f, unsigned n, int disp)
+unsigned c, unsigned f, bool d, unsigned n, int disp)
 {
 TCGv_reg dest, in2, sv;
 DisasCond cond;
-bool d = false;
 
 in2 = load_gpr(ctx, r);
 dest = tcg_temp_new();
@@ -3113,14 +3112,19 @@ static bool do_cmpb(DisasContext *ctx, unsigned r, 
TCGv_reg in1,
 
 static bool trans_cmpb(DisasContext *ctx, arg_cmpb *a)
 {
+if (!ctx->is_pa20 && a->d) {
+return false;
+}
 nullify_over(ctx);
-return do_cmpb(ctx, a->r2, load_gpr(ctx, a->r1), a->c, a->f, a->n, 
a->disp);
+return do_cmpb(ctx, a->r2, load_gpr(ctx, a->r1),
+   a->c, a->f, a->d, a->n, a->disp);
 }
 
 static bool trans_cmpbi(DisasContext *ctx, arg_cmpbi *a)
 {
 nullify_over(ctx);
-return do_cmpb(ctx, a->r, tcg_constant_reg(a->i), a->c, a->f, a->n, 
a->disp);
+return do_cmpb(ctx, a->r, tcg_constant_reg(a->i),
+   a->c, a->f, false, a->n, a->disp);
 }
 
 static bool do_addb(DisasContext *ctx, unsigned r, TCGv_reg in1,
-- 
2.34.1




[PATCH v3 55/88] target/hppa: Implement IDTLBT, IITLBT

2023-11-01 Thread Richard Henderson
Rename the existing insert tlb helpers to emphasize that they
are for pa1.1 cpus.  Implement a combined i/d tlb for pa2.0.
Still missing is the new 'P' tlb bit.

Signed-off-by: Richard Henderson 
---
 target/hppa/helper.h |  6 ++--
 target/hppa/insns.decode |  4 +++
 target/hppa/mem_helper.c | 61 
 target/hppa/translate.c  | 42 +++
 4 files changed, 100 insertions(+), 13 deletions(-)

diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index 9920d38ded..0b346e24f3 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -94,8 +94,10 @@ DEF_HELPER_FLAGS_2(write_interval_timer, TCG_CALL_NO_RWG, 
void, env, tr)
 DEF_HELPER_FLAGS_2(write_eirr, TCG_CALL_NO_RWG, void, env, tr)
 DEF_HELPER_FLAGS_2(write_eiem, TCG_CALL_NO_RWG, void, env, tr)
 DEF_HELPER_FLAGS_2(swap_system_mask, TCG_CALL_NO_RWG, tr, env, tr)
-DEF_HELPER_FLAGS_3(itlba, TCG_CALL_NO_RWG, void, env, tl, tr)
-DEF_HELPER_FLAGS_3(itlbp, TCG_CALL_NO_RWG, void, env, tl, tr)
+DEF_HELPER_FLAGS_3(itlba_pa11, TCG_CALL_NO_RWG, void, env, tl, tr)
+DEF_HELPER_FLAGS_3(itlbp_pa11, TCG_CALL_NO_RWG, void, env, tl, tr)
+DEF_HELPER_FLAGS_3(idtlbt_pa20, TCG_CALL_NO_RWG, void, env, tr, tr)
+DEF_HELPER_FLAGS_3(iitlbt_pa20, TCG_CALL_NO_RWG, void, env, tr, tr)
 DEF_HELPER_FLAGS_2(ptlb, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_FLAGS_1(ptlbe, TCG_CALL_NO_RWG, void, env)
 DEF_HELPER_FLAGS_2(lpa, TCG_CALL_NO_WG, tr, env, tl)
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 9d8c6a1a16..820049b0c5 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -145,6 +145,7 @@ nop_addrx   01 . . -- 01001110 . 0  
@addrx # pdc
 
 probe   01 b:5 ri:5 sp:2 imm:1 100011 write:1 0 t:5
 
+# pa1.x tlb insert instructions
 ixtlbx  01 b:5 r:5 sp:2 010 addr:1 0 0  data=1
 ixtlbx  01 b:5 r:5 ... 00 addr:1 0 0\
 sp=%assemble_sr3x data=0
@@ -152,6 +153,9 @@ ixtlbx  01 b:5 r:5 ... 00 addr:1 0 0
\
 # pcxl and pcxl2 Fast TLB Insert instructions
 ixtlbxf 01 0 r:5 00 0 data:1 01000 addr:1 0 0
 
+# pa2.0 tlb insert idtlbt and iitlbt instructions
+ixtlbt  01 r2:5 r1:5 000 data:1 10 0 0# idtlbt
+
 pxtlbx  01 b:5 x:5 sp:2 0100100 local:1 m:1 -   data=1
 pxtlbx  01 b:5 x:5 ... 000100 local:1 m:1 - \
 sp=%assemble_sr3x data=0
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 420b43a0f6..d5d2d62f4a 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -344,7 +344,7 @@ bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
 }
 
 /* Insert (Insn/Data) TLB Address.  Note this is PA 1.1 only.  */
-void HELPER(itlba)(CPUHPPAState *env, target_ulong addr, target_ureg reg)
+void HELPER(itlba_pa11)(CPUHPPAState *env, target_ulong addr, target_ureg reg)
 {
 HPPATLBEntry *ent;
 
@@ -365,7 +365,8 @@ void HELPER(itlba)(CPUHPPAState *env, target_ulong addr, 
target_ureg reg)
 trace_hppa_tlb_itlba(env, ent, ent->itree.start, ent->itree.last, ent->pa);
 }
 
-static void set_access_bits(CPUHPPAState *env, HPPATLBEntry *ent, target_ureg 
reg)
+static void set_access_bits_pa11(CPUHPPAState *env, HPPATLBEntry *ent,
+ target_ureg reg)
 {
 ent->access_id = extract32(reg, 1, 18);
 ent->u = extract32(reg, 19, 1);
@@ -383,20 +384,70 @@ static void set_access_bits(CPUHPPAState *env, 
HPPATLBEntry *ent, target_ureg re
 }
 
 /* Insert (Insn/Data) TLB Protection.  Note this is PA 1.1 only.  */
-void HELPER(itlbp)(CPUHPPAState *env, target_ulong addr, target_ureg reg)
+void HELPER(itlbp_pa11)(CPUHPPAState *env, target_ulong addr, target_ureg reg)
 {
 HPPATLBEntry *ent = env->tlb_partial;
 
 if (ent) {
 env->tlb_partial = NULL;
 if (ent->itree.start <= addr && addr <= ent->itree.last) {
-set_access_bits(env, ent, reg);
+set_access_bits_pa11(env, ent, reg);
 return;
 }
 }
 qemu_log_mask(LOG_GUEST_ERROR, "ITLBP not following ITLBA\n");
 }
 
+static void itlbt_pa20(CPUHPPAState *env, target_ureg r1,
+   target_ureg r2, vaddr va_b)
+{
+HPPATLBEntry *ent;
+vaddr va_e;
+uint64_t va_size;
+int mask_shift;
+
+mask_shift = 2 * (r1 & 0xf);
+va_size = TARGET_PAGE_SIZE << mask_shift;
+va_b &= -va_size;
+va_e = va_b + va_size - 1;
+
+hppa_flush_tlb_range(env, va_b, va_e);
+ent = hppa_alloc_tlb_ent(env);
+
+ent->itree.start = va_b;
+ent->itree.last = va_e;
+ent->pa = (r1 << 7) & (TARGET_PAGE_MASK << mask_shift);
+ent->t = extract64(r2, 61, 1);
+ent->d = extract64(r2, 60, 1);
+ent->b = extract64(r2, 59, 1);
+ent->ar_type = extract64(r2, 56, 3);
+ent->ar_pl1 = extract64(r2, 54, 2);
+ent->ar_pl2 = extract64(r2, 52, 2);
+ent->u = extract64(r2, 51, 1);
+

[PATCH v3 50/88] target/hppa: Implement DEPD, DEPDI

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode | 19 --
 target/hppa/translate.c  | 80 +++-
 2 files changed, 69 insertions(+), 30 deletions(-)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 33eec3f4c3..12684b590e 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -46,6 +46,10 @@
 
 %im5_0  0:s1 1:4
 %im5_16 16:s1 17:4
+%len5   0:5  !function=assemble_6
+%len6_8 8:1 0:5  !function=assemble_6
+%len6_1212:1 0:5 !function=assemble_6
+%cpos6_11   11:1 5:5
 %ma_to_m5:1 13:1 !function=ma_to_m
 %ma2_to_m   2:2  !function=ma_to_m
 %pos_to_m   0:1  !function=pos_to_m
@@ -334,10 +338,17 @@ shrpw_imm   110100 r2:5 r1:5 c:3 01 0cpos:5 t:5
 extrw_sar   110100 r:5  t:5  c:3 10 se:1 0  clen:5
 extrw_imm   110100 r:5  t:5  c:3 11 se:1 pos:5  clen:5
 
-depw_sar110101 t:5 r:5   c:3 00 nz:1 0  clen:5
-depw_imm110101 t:5 r:5   c:3 01 nz:1 cpos:5 clen:5
-depwi_sar   110101 t:5 . c:3 10 nz:1 0  clen:5  i=%im5_16
-depwi_imm   110101 t:5 . c:3 11 nz:1 cpos:5 clen:5  i=%im5_16
+dep_sar 110101 t:5 r:5   c:3 00 nz:1 00 000 . d=0 len=%len5
+dep_sar 110101 t:5 r:5   c:3 00 nz:1 1. 000 . d=1 len=%len6_8
+dep_imm 110101 t:5 r:5   c:3 01 nz:1 cpos:5 . d=0 len=%len5
+dep_imm 00 t:5 r:5   c:3 .. nz:1 . .  \
+d=1 len=%len6_12 cpos=%cpos6_11
+depi_sar110101 t:5 . c:3 10 nz:1 d:1 . 000 .  \
+i=%im5_16 len=%len6_8
+depi_imm110101 t:5 . c:3 11 nz:1 cpos:5 . \
+d=0 i=%im5_16 len=%len5
+depi_imm01 t:5 . c:3 .. nz:1 . .  \
+d=1 i=%im5_16 len=%len6_12 cpos=%cpos6_11
 
 
 # Branch External
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 4562f865f4..ea2150cc55 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -329,6 +329,17 @@ static int expand_shl11(DisasContext *ctx, int val)
 return val << 11;
 }
 
+static int assemble_6(DisasContext *ctx, int val)
+{
+/*
+ * Officially, 32 * x + 32 - y.
+ * Here, x is already in bit 5, and y is [4:0].
+ * Since -y = ~y + 1, in 5 bits 32 - y => y ^ 31 + 1,
+ * with the overflow from bit 4 summing with x.
+ */
+return (val ^ 31) + 1;
+}
+
 /* Translate CMPI doubleword conditions to standard. */
 static int cmpbid_c(DisasContext *ctx, int val)
 {
@@ -3404,17 +3415,23 @@ static bool trans_extrw_imm(DisasContext *ctx, 
arg_extrw_imm *a)
 return nullify_end(ctx);
 }
 
-static bool trans_depwi_imm(DisasContext *ctx, arg_depwi_imm *a)
+static bool trans_depi_imm(DisasContext *ctx, arg_depi_imm *a)
 {
-unsigned len = 32 - a->clen;
+unsigned len, width;
 target_sreg mask0, mask1;
 TCGv_reg dest;
 
+if (!ctx->is_pa20 && a->d) {
+return false;
+}
 if (a->c) {
 nullify_over(ctx);
 }
-if (a->cpos + len > 32) {
-len = 32 - a->cpos;
+
+len = a->len;
+width = a->d ? 64 : 32;
+if (a->cpos + len > width) {
+len = width - a->cpos;
 }
 
 dest = dest_gpr(ctx, a->t);
@@ -3423,11 +3440,8 @@ static bool trans_depwi_imm(DisasContext *ctx, 
arg_depwi_imm *a)
 
 if (a->nz) {
 TCGv_reg src = load_gpr(ctx, a->t);
-if (mask1 != -1) {
-tcg_gen_andi_reg(dest, src, mask1);
-src = dest;
-}
-tcg_gen_ori_reg(dest, src, mask0);
+tcg_gen_andi_reg(dest, src, mask1);
+tcg_gen_ori_reg(dest, dest, mask0);
 } else {
 tcg_gen_movi_reg(dest, mask0);
 }
@@ -3436,22 +3450,28 @@ static bool trans_depwi_imm(DisasContext *ctx, 
arg_depwi_imm *a)
 /* Install the new nullification.  */
 cond_free(>null_cond);
 if (a->c) {
-ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
+ctx->null_cond = do_sed_cond(ctx, a->c, a->d, dest);
 }
 return nullify_end(ctx);
 }
 
-static bool trans_depw_imm(DisasContext *ctx, arg_depw_imm *a)
+static bool trans_dep_imm(DisasContext *ctx, arg_dep_imm *a)
 {
 unsigned rs = a->nz ? a->t : 0;
-unsigned len = 32 - a->clen;
+unsigned len, width;
 TCGv_reg dest, val;
 
+if (!ctx->is_pa20 && a->d) {
+return false;
+}
 if (a->c) {
 nullify_over(ctx);
 }
-if (a->cpos + len > 32) {
-len = 32 - a->cpos;
+
+len = a->len;
+width = a->d ? 64 : 32;
+if (a->cpos + len > width) {
+len = width - a->cpos;
 }
 
 dest = dest_gpr(ctx, a->t);
@@ -3466,26 +3486,26 @@ static bool trans_depw_imm(DisasContext *ctx, 
arg_depw_imm *a)
 /* Install the new nullification.  */
 cond_free(>null_cond);
 if (a->c) {
-ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
+ctx->null_cond = do_sed_cond(ctx, a->c, a->d, dest);
   

[PATCH v3 74/88] hw/hppa: Translate phys addresses for the cpu

2023-11-01 Thread Richard Henderson
Hack the machine to use pa2.0 physical layout when required,
using the PSW.W=0 absolute to physical mapping.

Signed-off-by: Richard Henderson 
---
 hw/hppa/machine.c | 117 --
 1 file changed, 71 insertions(+), 46 deletions(-)

diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 1f09b4b490..43c7afb89d 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -87,7 +87,7 @@ static const MemoryRegionOps hppa_pci_ignore_ops = {
 },
 };
 
-static ISABus *hppa_isa_bus(void)
+static ISABus *hppa_isa_bus(hwaddr addr)
 {
 ISABus *isa_bus;
 qemu_irq *isa_irqs;
@@ -96,8 +96,7 @@ static ISABus *hppa_isa_bus(void)
 isa_region = g_new(MemoryRegion, 1);
 memory_region_init_io(isa_region, NULL, _pci_ignore_ops,
   NULL, "isa-io", 0x800);
-memory_region_add_subregion(get_system_memory(), IDE_HPA,
-isa_region);
+memory_region_add_subregion(get_system_memory(), addr, isa_region);
 
 isa_bus = isa_bus_new(NULL, get_system_memory(), isa_region,
   _abort);
@@ -163,13 +162,24 @@ static const MemoryRegionOps hppa_io_helper_ops = {
 },
 };
 
+typedef uint64_t TranslateFn(void *opaque, uint64_t addr);
 
-static uint64_t cpu_hppa_to_phys(void *opaque, uint64_t addr)
+static uint64_t linux_kernel_virt_to_phys(void *opaque, uint64_t addr)
 {
 addr &= (0x1000 - 1);
 return addr;
 }
 
+static uint64_t translate_pa10(void *dummy, uint64_t addr)
+{
+return (uint32_t)addr;
+}
+
+static uint64_t translate_pa20(void *dummy, uint64_t addr)
+{
+return hppa_abs_to_phys_pa2_w0(addr);
+}
+
 static HPPACPU *cpu[HPPA_MAX_CPUS];
 static uint64_t firmware_entry;
 
@@ -179,7 +189,8 @@ static void fw_cfg_boot_set(void *opaque, const char 
*boot_device,
 fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
 }
 
-static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus)
+static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus,
+ hwaddr addr)
 {
 FWCfgState *fw_cfg;
 uint64_t val;
@@ -188,7 +199,7 @@ static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus 
*pci_bus)
 int btlb_entries = HPPA_BTLB_ENTRIES([0]->env);
 int len;
 
-fw_cfg = fw_cfg_init_mem(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4);
+fw_cfg = fw_cfg_init_mem(addr, addr + 4);
 fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, ms->smp.cpus);
 fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, HPPA_MAX_CPUS);
 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, ms->ram_size);
@@ -258,32 +269,45 @@ static DinoState *dino_init(MemoryRegion *addr_space)
 /*
  * Step 1: Create CPUs and Memory
  */
-static void machine_HP_common_init_cpus(MachineState *machine)
+static TranslateFn *machine_HP_common_init_cpus(MachineState *machine)
 {
 MemoryRegion *addr_space = get_system_memory();
-MemoryRegion *cpu_region;
-long i;
 unsigned int smp_cpus = machine->smp.cpus;
-char *name;
+TranslateFn *translate;
+MemoryRegion *cpu_region;
 
 /* Create CPUs.  */
-for (i = 0; i < smp_cpus; i++) {
-name = g_strdup_printf("cpu%ld-io-eir", i);
+for (unsigned int i = 0; i < smp_cpus; i++) {
 cpu[i] = HPPA_CPU(cpu_create(machine->cpu_type));
+}
+
+/*
+ * For now, treat address layout as if PSW_W is clear.
+ * TODO: create a proper hppa64 board model and load elf64 firmware.
+ */
+if (hppa_is_pa20([0]->env)) {
+translate = translate_pa20;
+} else {
+translate = translate_pa10;
+}
+
+for (unsigned int i = 0; i < smp_cpus; i++) {
+g_autofree char *name = g_strdup_printf("cpu%u-io-eir", i);
 
 cpu_region = g_new(MemoryRegion, 1);
 memory_region_init_io(cpu_region, OBJECT(cpu[i]), _io_eir_ops,
   cpu[i], name, 4);
-memory_region_add_subregion(addr_space, CPU_HPA + i * 0x1000,
+memory_region_add_subregion(addr_space,
+translate(NULL, CPU_HPA + i * 0x1000),
 cpu_region);
-g_free(name);
 }
 
 /* RTC and DebugOutputPort on CPU #0 */
 cpu_region = g_new(MemoryRegion, 1);
 memory_region_init_io(cpu_region, OBJECT(cpu[0]), _io_helper_ops,
   cpu[0], "cpu0-io-rtc", 2 * sizeof(uint64_t));
-memory_region_add_subregion(addr_space, CPU_HPA + 16, cpu_region);
+memory_region_add_subregion(addr_space, translate(NULL, CPU_HPA + 16),
+cpu_region);
 
 /* Main memory region. */
 if (machine->ram_size > 3 * GiB) {
@@ -291,12 +315,15 @@ static void machine_HP_common_init_cpus(MachineState 
*machine)
 exit(EXIT_FAILURE);
 }
 memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1);
+
+return translate;
 }
 
 /*
  * Last creation step: Add SCSI discs, NICs, graphics & load firmware
  */
-static void 

[PATCH v3 63/88] target/hppa: Implement HADD

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/helper.h |  3 +++
 target/hppa/insns.decode |  8 +++-
 target/hppa/op_helper.c  | 32 
 target/hppa/translate.c  | 37 +
 4 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index 57ea5447b6..b3c961b50d 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -14,6 +14,9 @@ DEF_HELPER_FLAGS_3(stdby_e_parallel, TCG_CALL_NO_WG, void, 
env, tl, tl)
 
 DEF_HELPER_FLAGS_1(ldc_check, TCG_CALL_NO_RWG, void, tl)
 
+DEF_HELPER_FLAGS_2(hadd_ss, TCG_CALL_NO_RWG, i64, i64, i64)
+DEF_HELPER_FLAGS_2(hadd_us, TCG_CALL_NO_RWG, i64, i64, i64)
+
 DEF_HELPER_FLAGS_4(probe, TCG_CALL_NO_WG, tl, env, tl, i32, i32)
 
 DEF_HELPER_FLAGS_1(loaded_fr0, TCG_CALL_NO_RWG, void, env)
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 820049b0c5..4bcfc94b1c 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -65,6 +65,7 @@
t b x disp sp m scale size
 
 _cf_dt r cf d
+t r1 r2
 _cf t r1 r2 cf
 _cf_d   t r1 r2 cf d
 _cf_d_sht r1 r2 cf d sh
@@ -81,6 +82,7 @@
 
 
 @rr_cf_d.. r:5 . cf:4 .. d:1 t:5_cf_d
+@rrr.. r2:5 r1:5  ... t:5   
 @rrr_cf .. r2:5 r1:5 cf:4 ... t:5   _cf
 @rrr_cf_d   .. r2:5 r1:5 cf:4 .. d:1 t:5_cf_d
 @rrr_cf_d_sh.. r2:5 r1:5 cf:4  sh:2 d:1 t:5 _cf_d_sh
@@ -208,6 +210,10 @@ subi_tsv100101 . .  1 ...   
@rri_cf
 
 cmpiclr 100100 . .  . ...   @rri_cf_d
 
+hadd10 . . 0011 11 0 .  @rrr
+hadd_ss 10 . . 0011 01 0 .  @rrr
+hadd_us 10 . . 0011 00 0 .  @rrr
+
 
 # Index Mem
 
@@ -429,7 +435,7 @@ fmpyfadd_d  101110 rm1:5 rm2:5 ... 0 1 ..0 0 0 neg:1 
t:5ra3=%rc32
 
 @f0e_f_3.. . . ... .0 110 ..0 .\
  r1=%ra64 r2=%rb64 t=%rt64
-@f0e_d_3.. r1:5  r2:5  ... 01 110 000 t:5
+@f0e_d_3.. r1:5  r2:5  ... 01 110 000 t:5  
 
 # Floating point class 0
 
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index 0bccca1e11..a230a3a0c3 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -377,3 +377,35 @@ target_ulong HELPER(read_interval_timer)(void)
 return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >> 2;
 #endif
 }
+
+uint64_t HELPER(hadd_ss)(uint64_t r1, uint64_t r2)
+{
+uint64_t ret = 0;
+
+for (int i = 0; i < 64; i += 16) {
+int f1 = sextract64(r1, i, 16);
+int f2 = sextract64(r2, i, 16);
+int fr = f1 + f2;
+
+fr = MIN(fr, INT16_MAX);
+fr = MAX(fr, INT16_MIN);
+ret = deposit64(ret, i, 16, fr);
+}
+return ret;
+}
+
+uint64_t HELPER(hadd_us)(uint64_t r1, uint64_t r2)
+{
+uint64_t ret = 0;
+
+for (int i = 0; i < 64; i += 16) {
+int f1 = extract64(r1, i, 16);
+int f2 = sextract64(r2, i, 16);
+int fr = f1 + f2;
+
+fr = MIN(fr, UINT16_MAX);
+fr = MAX(fr, 0);
+ret = deposit64(ret, i, 16, fr);
+}
+return ret;
+}
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index f570b17ecd..f564aea8fb 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -23,6 +23,7 @@
 #include "qemu/host-utils.h"
 #include "exec/exec-all.h"
 #include "tcg/tcg-op.h"
+#include "tcg/tcg-op-gvec.h"
 #include "exec/helper-proto.h"
 #include "exec/helper-gen.h"
 #include "exec/translator.h"
@@ -2767,6 +2768,42 @@ static bool trans_cmpiclr(DisasContext *ctx, 
arg_rri_cf_d *a)
 return nullify_end(ctx);
 }
 
+static bool do_multimedia(DisasContext *ctx, arg_rrr *a,
+  void (*fn)(TCGv_i64, TCGv_i64, TCGv_i64))
+{
+TCGv_i64 r1, r2, dest;
+
+if (!ctx->is_pa20) {
+return false;
+}
+
+nullify_over(ctx);
+
+r1 = load_gpr(ctx, a->r1);
+r2 = load_gpr(ctx, a->r2);
+dest = dest_gpr(ctx, a->t);
+
+fn(dest, r1, r2);
+save_gpr(ctx, a->t, dest);
+
+return nullify_end(ctx);
+}
+
+static bool trans_hadd(DisasContext *ctx, arg_rrr *a)
+{
+return do_multimedia(ctx, a, tcg_gen_vec_add16_i64);
+}
+
+static bool trans_hadd_ss(DisasContext *ctx, arg_rrr *a)
+{
+return do_multimedia(ctx, a, gen_helper_hadd_ss);
+}
+
+static bool trans_hadd_us(DisasContext *ctx, arg_rrr *a)
+{
+return do_multimedia(ctx, a, gen_helper_hadd_us);
+}
+
 static bool trans_ld(DisasContext *ctx, arg_ldst *a)
 {
 if (!ctx->is_pa20 && a->size > MO_32) {
-- 
2.34.1




[PATCH v3 69/88] target/hppa: Implement PERMH

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode |  2 ++
 target/hppa/translate.c  | 29 +
 2 files changed, 31 insertions(+)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 22ec07f892..19e537df24 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -238,6 +238,8 @@ mixh_r  10 . . 1 10 0010 .  @rrr
 mixw_l  10 . . 1 00  .  @rrr
 mixw_r  10 . . 1 10  .  @rrr
 
+permh   10 r1:5  r2:5  0 c0:2 0 c1:2 c2:2 c3:2 0 t:5
+
 
 # Index Mem
 
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 47ca71e2a3..36653486fb 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2946,6 +2946,35 @@ static bool trans_mixw_r(DisasContext *ctx, arg_rrr *a)
 return do_multimedia(ctx, a, gen_mixw_r);
 }
 
+static bool trans_permh(DisasContext *ctx, arg_permh *a)
+{
+TCGv_i64 r, t0, t1, t2, t3;
+
+if (!ctx->is_pa20) {
+return false;
+}
+
+nullify_over(ctx);
+
+r = load_gpr(ctx, a->r1);
+t0 = tcg_temp_new_i64();
+t1 = tcg_temp_new_i64();
+t2 = tcg_temp_new_i64();
+t3 = tcg_temp_new_i64();
+
+tcg_gen_extract_i64(t0, r, (3 - a->c0) * 16, 16);
+tcg_gen_extract_i64(t1, r, (3 - a->c1) * 16, 16);
+tcg_gen_extract_i64(t2, r, (3 - a->c2) * 16, 16);
+tcg_gen_extract_i64(t3, r, (3 - a->c3) * 16, 16);
+
+tcg_gen_deposit_i64(t0, t1, t0, 16, 48);
+tcg_gen_deposit_i64(t2, t3, t2, 16, 48);
+tcg_gen_deposit_i64(t0, t2, t0, 32, 32);
+
+save_gpr(ctx, a->t, t0);
+return nullify_end(ctx);
+}
+
 static bool trans_ld(DisasContext *ctx, arg_ldst *a)
 {
 if (!ctx->is_pa20 && a->size > MO_32) {
-- 
2.34.1




[PATCH v3 79/88] target/hppa: Clear upper bits in mtctl for pa1.x

2023-11-01 Thread Richard Henderson
From: Helge Deller 

Signed-off-by: Helge Deller 
Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index d9595c5c7c..f7621590e4 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2060,7 +2060,13 @@ static bool trans_mtctl(DisasContext *ctx, arg_mtctl *a)
 
 #ifndef CONFIG_USER_ONLY
 nullify_over(ctx);
-reg = load_gpr(ctx, a->r);
+
+if (ctx->is_pa20) {
+reg = load_gpr(ctx, a->r);
+} else {
+reg = tcg_temp_new_i64();
+tcg_gen_ext32u_i64(reg, load_gpr(ctx, a->r));
+}
 
 switch (ctl) {
 case CR_IT:
-- 
2.34.1




[PATCH v3 60/88] target/hppa: Adjust vmstate_env for pa2.0 tlb

2023-11-01 Thread Richard Henderson
Split out the tlb to a subsection so that it can be separately
versioned -- the format is only partially following the architecture
and is partially guided by the qemu implementation.

Signed-off-by: Richard Henderson 
---
 target/hppa/machine.c | 93 ++-
 1 file changed, 57 insertions(+), 36 deletions(-)

diff --git a/target/hppa/machine.c b/target/hppa/machine.c
index f6df4deac5..823e6af7ee 100644
--- a/target/hppa/machine.c
+++ b/target/hppa/machine.c
@@ -44,28 +44,30 @@ static const VMStateInfo vmstate_psw = {
 .put = put_psw,
 };
 
-/* FIXME: Use the PA2.0 format, which is a superset of the PA1.1 format.  */
 static int get_tlb(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field)
 {
 HPPATLBEntry *ent = opaque;
-uint32_t val;
+uint64_t val;
 
 ent->itree.start = qemu_get_be64(f);
+ent->itree.last = qemu_get_be64(f);
 ent->pa = qemu_get_be64(f);
-val = qemu_get_be32(f);
+val = qemu_get_be64(f);
 
-ent->entry_valid = extract32(val, 0, 1);
-ent->access_id = extract32(val, 1, 18);
-ent->u = extract32(val, 19, 1);
-ent->ar_pl2 = extract32(val, 20, 2);
-ent->ar_pl1 = extract32(val, 22, 2);
-ent->ar_type = extract32(val, 24, 3);
-ent->b = extract32(val, 27, 1);
-ent->d = extract32(val, 28, 1);
-ent->t = extract32(val, 29, 1);
-
-ent->itree.last = ent->itree.start + TARGET_PAGE_SIZE - 1;
+if (val) {
+ent->t = extract64(val, 61, 1);
+ent->d = extract64(val, 60, 1);
+ent->b = extract64(val, 59, 1);
+ent->ar_type = extract64(val, 56, 3);
+ent->ar_pl1 = extract64(val, 54, 2);
+ent->ar_pl2 = extract64(val, 52, 2);
+ent->u = extract64(val, 51, 1);
+/* o = bit 50 */
+/* p = bit 49 */
+ent->access_id = extract64(val, 1, 31);
+ent->entry_valid = 1;
+}
 return 0;
 }
 
@@ -73,27 +75,30 @@ static int put_tlb(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field, JSONWriter *vmdesc)
 {
 HPPATLBEntry *ent = opaque;
-uint32_t val = 0;
+uint64_t val = 0;
 
 if (ent->entry_valid) {
 val = 1;
-val = deposit32(val, 1, 18, ent->access_id);
-val = deposit32(val, 19, 1, ent->u);
-val = deposit32(val, 20, 2, ent->ar_pl2);
-val = deposit32(val, 22, 2, ent->ar_pl1);
-val = deposit32(val, 24, 3, ent->ar_type);
-val = deposit32(val, 27, 1, ent->b);
-val = deposit32(val, 28, 1, ent->d);
-val = deposit32(val, 29, 1, ent->t);
+val = deposit64(val, 61, 1, ent->t);
+val = deposit64(val, 60, 1, ent->d);
+val = deposit64(val, 59, 1, ent->b);
+val = deposit64(val, 56, 3, ent->ar_type);
+val = deposit64(val, 54, 2, ent->ar_pl1);
+val = deposit64(val, 52, 2, ent->ar_pl2);
+val = deposit64(val, 51, 1, ent->u);
+/* o = bit 50 */
+/* p = bit 49 */
+val = deposit64(val, 1, 31, ent->access_id);
 }
 
 qemu_put_be64(f, ent->itree.start);
+qemu_put_be64(f, ent->itree.last);
 qemu_put_be64(f, ent->pa);
-qemu_put_be32(f, val);
+qemu_put_be64(f, val);
 return 0;
 }
 
-static const VMStateInfo vmstate_tlb = {
+static const VMStateInfo vmstate_tlb_entry = {
 .name = "tlb entry",
 .get = get_tlb,
 .put = put_tlb,
@@ -147,7 +152,24 @@ static int tlb_post_load(void *opaque, int version_id)
 return 0;
 }
 
-static VMStateField vmstate_env_fields[] = {
+static const VMStateField vmstate_tlb_fields[] = {
+VMSTATE_ARRAY(tlb, CPUHPPAState,
+  ARRAY_SIZE(((CPUHPPAState *)0)->tlb),
+  0, vmstate_tlb_entry, HPPATLBEntry),
+VMSTATE_UINT32(tlb_last, CPUHPPAState),
+VMSTATE_END_OF_LIST()
+};
+
+static const VMStateDescription vmstate_tlb = {
+.name = "cpu/tlb",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = vmstate_tlb_fields,
+.pre_load = tlb_pre_load,
+.post_load = tlb_post_load,
+};
+
+static const VMStateField vmstate_env_fields[] = {
 VMSTATE_UINT64_ARRAY(gr, CPUHPPAState, 32),
 VMSTATE_UINT64_ARRAY(fr, CPUHPPAState, 32),
 VMSTATE_UINT64_ARRAY(sr, CPUHPPAState, 8),
@@ -176,24 +198,23 @@ static VMStateField vmstate_env_fields[] = {
 VMSTATE_UINT64(iasq_b, CPUHPPAState),
 
 VMSTATE_UINT32(fr0_shadow, CPUHPPAState),
-
-VMSTATE_ARRAY(tlb, CPUHPPAState, ARRAY_SIZE(((CPUHPPAState *)0)->tlb),
-  0, vmstate_tlb, HPPATLBEntry),
-VMSTATE_UINT32(tlb_last, CPUHPPAState),
-
 VMSTATE_END_OF_LIST()
 };
 
+static const VMStateDescription *vmstate_env_subsections[] = {
+_tlb,
+NULL
+};
+
 static const VMStateDescription vmstate_env = {
 .name = "env",
-.version_id = 2,
-.minimum_version_id = 2,
+.version_id = 3,
+.minimum_version_id = 3,
 .fields = vmstate_env_fields,
-.pre_load = tlb_pre_load,
-.post_load = tlb_post_load,
+

[PATCH v3 39/88] target/hppa: Remove TARGET_HPPA64

2023-11-01 Thread Richard Henderson
Allow both user-only and system mode to run pa2.0 cpus.
Avoid creating a separate qemu-system-hppa64 binary;
force the qemu-hppa binary to use TARGET_ABI32.

Signed-off-by: Richard Henderson 
---
 configs/targets/hppa-linux-user.mak |  1 +
 target/hppa/cpu-param.h | 23 +++
 target/hppa/cpu.h   |  9 -
 target/hppa/cpu.c   |  2 --
 target/hppa/translate.c |  2 --
 5 files changed, 8 insertions(+), 29 deletions(-)

diff --git a/configs/targets/hppa-linux-user.mak 
b/configs/targets/hppa-linux-user.mak
index 361ea39d71..8e0a80492f 100644
--- a/configs/targets/hppa-linux-user.mak
+++ b/configs/targets/hppa-linux-user.mak
@@ -1,4 +1,5 @@
 TARGET_ARCH=hppa
+TARGET_ABI32=y
 TARGET_SYSTBL_ABI=common,32
 TARGET_SYSTBL=syscall.tbl
 TARGET_BIG_ENDIAN=y
diff --git a/target/hppa/cpu-param.h b/target/hppa/cpu-param.h
index c2791ae5f2..2fb8e7924b 100644
--- a/target/hppa/cpu-param.h
+++ b/target/hppa/cpu-param.h
@@ -8,26 +8,17 @@
 #ifndef HPPA_CPU_PARAM_H
 #define HPPA_CPU_PARAM_H
 
-#ifdef TARGET_HPPA64
-# define TARGET_LONG_BITS 64
-# define TARGET_REGISTER_BITS 64
-# define TARGET_VIRT_ADDR_SPACE_BITS  64
-# define TARGET_PHYS_ADDR_SPACE_BITS  64
-#elif defined(CONFIG_USER_ONLY)
-# define TARGET_LONG_BITS 32
-# define TARGET_REGISTER_BITS 32
+#define TARGET_LONG_BITS  64
+#define TARGET_REGISTER_BITS  64
+
+#if defined(CONFIG_USER_ONLY) && defined(TARGET_ABI32)
+# define TARGET_PHYS_ADDR_SPACE_BITS  32
 # define TARGET_VIRT_ADDR_SPACE_BITS  32
-# define TARGET_PHYS_ADDR_SPACE_BITS  32
 #else
-/*
- * In order to form the GVA from space:offset,
- * we need a 64-bit virtual address space.
- */
-# define TARGET_LONG_BITS 64
-# define TARGET_REGISTER_BITS 32
+# define TARGET_PHYS_ADDR_SPACE_BITS  64
 # define TARGET_VIRT_ADDR_SPACE_BITS  64
-# define TARGET_PHYS_ADDR_SPACE_BITS  32
 #endif
+
 #define TARGET_PAGE_BITS 12
 
 #endif
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index cb838defb0..77ddb20ac2 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -120,11 +120,7 @@
 #define PSW_T0x0100
 #define PSW_S0x0200
 #define PSW_E0x0400
-#ifdef TARGET_HPPA64
 #define PSW_W0x0800 /* PA2.0 only */
-#else
-#define PSW_W0
-#endif
 #define PSW_Z0x4000 /* PA1.x only */
 #define PSW_Y0x8000 /* PA1.x only */
 
@@ -137,13 +133,8 @@
 #define PSW_SM_P PSW_P
 #define PSW_SM_Q PSW_Q  /* Enable Interrupt State Collection */
 #define PSW_SM_R PSW_R  /* Enable Recover Counter Trap */
-#ifdef TARGET_HPPA64
 #define PSW_SM_E 0x100
 #define PSW_SM_W 0x200  /* PA2.0 only : Enable Wide Mode */
-#else
-#define PSW_SM_E 0
-#define PSW_SM_W 0
-#endif
 
 #define CR_RC0
 #define CR_PID1  8
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 70ce0c3b99..9582619be2 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -252,12 +252,10 @@ static const TypeInfo hppa_cpu_type_infos[] = {
 .class_size = sizeof(HPPACPUClass),
 .class_init = hppa_cpu_class_init,
 },
-#ifdef TARGET_HPPA64
 {
 .name = TYPE_HPPA64_CPU,
 .parent = TYPE_HPPA_CPU,
 },
-#endif
 };
 
 DEFINE_TYPES(hppa_cpu_type_infos)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 41f4e06841..187d47f4c3 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2177,7 +2177,6 @@ static bool trans_mfctl(DisasContext *ctx, arg_mfctl *a)
 
 switch (ctl) {
 case CR_SAR:
-#ifdef TARGET_HPPA64
 if (a->e == 0) {
 /* MFSAR without ,W masks low 5 bits.  */
 tmp = dest_gpr(ctx, rt);
@@ -2185,7 +2184,6 @@ static bool trans_mfctl(DisasContext *ctx, arg_mfctl *a)
 save_gpr(ctx, rt, tmp);
 goto done;
 }
-#endif
 save_gpr(ctx, rt, cpu_sar);
 goto done;
 case CR_IT: /* Interval Timer */
-- 
2.34.1




[PATCH v3 77/88] target/hppa: Add pa2.0 cpu local tlb flushes

2023-11-01 Thread Richard Henderson
From: Helge Deller 

The previous decoding misnamed the bit it called "local".
Other than the name, the implementation was correct for pa1.x.
Rename this field to "tlbe".

PA2.0 adds (a real) local bit to PxTLB, and also adds a range
of pages to flush in GR[b].

Signed-off-by: Helge Deller 
Signed-off-by: Richard Henderson 
---
 target/hppa/helper.h |  1 +
 target/hppa/insns.decode | 20 ++---
 target/hppa/mem_helper.c | 26 ++
 target/hppa/translate.c  | 48 +++-
 target/hppa/trace-events |  1 +
 5 files changed, 84 insertions(+), 12 deletions(-)

diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index c5f1db574b..c38539c76e 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -98,6 +98,7 @@ DEF_HELPER_FLAGS_3(itlbp_pa11, TCG_CALL_NO_RWG, void, env, 
tl, tl)
 DEF_HELPER_FLAGS_3(idtlbt_pa20, TCG_CALL_NO_RWG, void, env, tl, tl)
 DEF_HELPER_FLAGS_3(iitlbt_pa20, TCG_CALL_NO_RWG, void, env, tl, tl)
 DEF_HELPER_FLAGS_2(ptlb, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_FLAGS_2(ptlb_l, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_FLAGS_1(ptlbe, TCG_CALL_NO_RWG, void, env)
 DEF_HELPER_FLAGS_2(lpa, TCG_CALL_NO_WG, tl, env, tl)
 DEF_HELPER_FLAGS_1(change_prot_id, TCG_CALL_NO_RWG, void, env)
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 19e537df24..f5a3f02fd1 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -161,9 +161,23 @@ ixtlbxf 01 0 r:5 00 0 data:1 01000 addr:1 
0 0
 # pa2.0 tlb insert idtlbt and iitlbt instructions
 ixtlbt  01 r2:5 r1:5 000 data:1 10 0 0# idtlbt
 
-pxtlbx  01 b:5 x:5 sp:2 0100100 local:1 m:1 -   data=1
-pxtlbx  01 b:5 x:5 ... 000100 local:1 m:1 - \
-sp=%assemble_sr3x data=0
+# pdtlb, pitlb
+pxtlb   01 b:5 x:5 sp:2 01001000 m:1 - \
+ disp=0 scale=0 size=0 t=0
+pxtlb   01 b:5 x:5 ...   0001000 m:1 - \
+ disp=0 scale=0 size=0 t=0 sp=%assemble_sr3x
+
+# ... pa20 local
+pxtlb_l 01 b:5 x:5 sp:2 01011000 m:1 - \
+ disp=0 scale=0 size=0 t=0
+pxtlb_l 01 b:5 x:5 ...   0011000 m:1 - \
+ disp=0 scale=0 size=0 t=0 sp=%assemble_sr3x
+
+# pdtlbe, pitlbe
+pxtlbe  01 b:5 x:5 sp:2 01001001 m:1 - \
+ disp=0 scale=0 size=0 t=0
+pxtlbe  01 b:5 x:5 ...   0001001 m:1 - \
+ disp=0 scale=0 size=0 t=0 sp=%assemble_sr3x
 
 lpa 01 b:5 x:5 sp:2 01001101 m:1 t:5\
  disp=0 scale=0 size=0
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 9be68b860b..7132ea221c 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -448,16 +448,34 @@ void HELPER(iitlbt_pa20)(CPUHPPAState *env, target_ulong 
r1, target_ulong r2)
 itlbt_pa20(env, r1, r2, va_b);
 }
 
-/* Purge (Insn/Data) TLB.  This is explicitly page-based, and is
-   synchronous across all processors.  */
+/* Purge (Insn/Data) TLB. */
 static void ptlb_work(CPUState *cpu, run_on_cpu_data data)
 {
 CPUHPPAState *env = cpu_env(cpu);
-target_ulong addr = (target_ulong) data.target_ptr;
+vaddr start = data.target_ptr;
+vaddr end;
 
-hppa_flush_tlb_range(env, addr, addr);
+/*
+ * PA2.0 allows a range of pages encoded into GR[b], which we have
+ * copied into the bottom bits of the otherwise page-aligned address.
+ * PA1.x will always provide zero here, for a single page flush.
+ */
+end = start & 0xf;
+start &= TARGET_PAGE_MASK;
+end = TARGET_PAGE_SIZE << (2 * end);
+end = start + end - 1;
+
+hppa_flush_tlb_range(env, start, end);
 }
 
+/* This is local to the current cpu. */
+void HELPER(ptlb_l)(CPUHPPAState *env, target_ulong addr)
+{
+trace_hppa_tlb_ptlb_local(env);
+ptlb_work(env_cpu(env), RUN_ON_CPU_TARGET_PTR(addr));
+}
+
+/* This is synchronous across all processors.  */
 void HELPER(ptlb)(CPUHPPAState *env, target_ulong addr)
 {
 CPUState *src = env_cpu(env);
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 0883b146a9..d9595c5c7c 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2320,7 +2320,7 @@ static bool trans_ixtlbx(DisasContext *ctx, arg_ixtlbx *a)
 #endif
 }
 
-static bool trans_pxtlbx(DisasContext *ctx, arg_pxtlbx *a)
+static bool do_pxtlb(DisasContext *ctx, arg_ldst *a, bool local)
 {
 CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
 #ifndef CONFIG_USER_ONLY
@@ -2330,15 +2330,53 @@ static bool trans_pxtlbx(DisasContext *ctx, arg_pxtlbx 
*a)
 nullify_over(ctx);
 
 form_gva(ctx, , , a->b, a->x, 0, 0, a->sp, a->m, false);
-if (a->m) {
-save_gpr(ctx, a->b, ofs);
+
+/*
+ * Page align now, rather than later, so that we can add in the
+ * page_size field from pa2.0 from the low 4 bits of GR[b].
+ */
+tcg_gen_andi_i64(addr, addr, 

[PATCH v3 40/88] target/hppa: Decode d for logical instructions

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode | 10 ++
 target/hppa/translate.c  | 15 +++
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index aebe03ccfd..26ca9f1063 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -61,6 +61,7 @@
 
 _cf  t r cf
 _cf t r1 r2 cf
+_cf_d   t r1 r2 cf d
 _cf_sh  t r1 r2 cf sh
 _cf t r i cf
 
@@ -73,6 +74,7 @@
 
 @rr_cf  .. r:5 . cf:4 ... t:5   _cf
 @rrr_cf .. r2:5 r1:5 cf:4 ... t:5   _cf
+@rrr_cf_d   .. r2:5 r1:5 cf:4 .. d:1 t:5_cf_d
 @rrr_cf_sh  .. r2:5 r1:5 cf:4  sh:2 . t:5   _cf_sh
 @rrr_cf_sh0 .. r2:5 r1:5 cf:4 ... t:5   _cf_sh sh=0
 @rri_cf .. r:5  t:5  cf:4 . ... _cf i=%lowsign_11
@@ -150,10 +152,10 @@ lci 01 - - -- 01001100 0 t:5
 # Arith/Log
 
 
-andcm   10 . .  00 - .  @rrr_cf
-and 10 . .  001000 - .  @rrr_cf
-or  10 . .  001001 - .  @rrr_cf
-xor 10 . .  001010 0 .  @rrr_cf
+andcm   10 . .  00 . .  @rrr_cf_d
+and 10 . .  001000 . .  @rrr_cf_d
+or  10 . .  001001 . .  @rrr_cf_d
+xor 10 . .  001010 . .  @rrr_cf_d
 uxor10 . .  001110 0 .  @rrr_cf
 ds  10 . .  010001 0 .  @rrr_cf
 cmpclr  10 . .  100010 0 .  @rrr_cf
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 187d47f4c3..227d59b263 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1405,11 +1405,10 @@ static void do_cmpclr(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 }
 
 static void do_log(DisasContext *ctx, unsigned rt, TCGv_reg in1,
-   TCGv_reg in2, unsigned cf,
+   TCGv_reg in2, unsigned cf, bool d,
void (*fn)(TCGv_reg, TCGv_reg, TCGv_reg))
 {
 TCGv_reg dest = dest_gpr(ctx, rt);
-bool d = false;
 
 /* Perform the operation, and writeback.  */
 fn(dest, in1, in2);
@@ -1422,7 +1421,7 @@ static void do_log(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 }
 }
 
-static bool do_log_reg(DisasContext *ctx, arg_rrr_cf *a,
+static bool do_log_reg(DisasContext *ctx, arg_rrr_cf_d *a,
void (*fn)(TCGv_reg, TCGv_reg, TCGv_reg))
 {
 TCGv_reg tcg_r1, tcg_r2;
@@ -1432,7 +1431,7 @@ static bool do_log_reg(DisasContext *ctx, arg_rrr_cf *a,
 }
 tcg_r1 = load_gpr(ctx, a->r1);
 tcg_r2 = load_gpr(ctx, a->r2);
-do_log(ctx, a->t, tcg_r1, tcg_r2, a->cf, fn);
+do_log(ctx, a->t, tcg_r1, tcg_r2, a->cf, a->d, fn);
 return nullify_end(ctx);
 }
 
@@ -2693,17 +2692,17 @@ static bool trans_sub_b_tsv(DisasContext *ctx, 
arg_rrr_cf *a)
 return do_sub_reg(ctx, a, true, true, false);
 }
 
-static bool trans_andcm(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_andcm(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 return do_log_reg(ctx, a, tcg_gen_andc_reg);
 }
 
-static bool trans_and(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_and(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 return do_log_reg(ctx, a, tcg_gen_and_reg);
 }
 
-static bool trans_or(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_or(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 if (a->cf == 0) {
 unsigned r2 = a->r2;
@@ -2755,7 +2754,7 @@ static bool trans_or(DisasContext *ctx, arg_rrr_cf *a)
 return do_log_reg(ctx, a, tcg_gen_or_reg);
 }
 
-static bool trans_xor(DisasContext *ctx, arg_rrr_cf *a)
+static bool trans_xor(DisasContext *ctx, arg_rrr_cf_d *a)
 {
 return do_log_reg(ctx, a, tcg_gen_xor_reg);
 }
-- 
2.34.1




[PATCH v3 51/88] target/hppa: Implement EXTRD

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode |  7 +--
 target/hppa/translate.c  | 42 +---
 2 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 12684b590e..7b51f39b9e 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -335,8 +335,11 @@ addbi   101011 . . ... ... . .  
@rib_cf f=1
 shrpw_sar   110100 r2:5 r1:5 c:3 00 00  t:5
 shrpw_imm   110100 r2:5 r1:5 c:3 01 0cpos:5 t:5
 
-extrw_sar   110100 r:5  t:5  c:3 10 se:1 0  clen:5
-extrw_imm   110100 r:5  t:5  c:3 11 se:1 pos:5  clen:5
+extr_sar110100 r:5  t:5  c:3 10 se:1 00 000 . d=0 len=%len5
+extr_sar110100 r:5  t:5  c:3 10 se:1 1. 000 . d=1 len=%len6_8
+extr_imm110100 r:5  t:5  c:3 11 se:1 pos:5  . d=0 len=%len5
+extr_imm110110 r:5  t:5  c:3 .. se:1 . .  \
+d=1 len=%len6_12 pos=%cpos6_11
 
 dep_sar 110101 t:5 r:5   c:3 00 nz:1 00 000 . d=0 len=%len5
 dep_sar 110101 t:5 r:5   c:3 00 nz:1 1. 000 . d=1 len=%len6_8
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index ea2150cc55..533e29879e 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3354,11 +3354,14 @@ static bool trans_shrpw_imm(DisasContext *ctx, 
arg_shrpw_imm *a)
 return nullify_end(ctx);
 }
 
-static bool trans_extrw_sar(DisasContext *ctx, arg_extrw_sar *a)
+static bool trans_extr_sar(DisasContext *ctx, arg_extr_sar *a)
 {
-unsigned len = 32 - a->clen;
+unsigned widthm1 = a->d ? 63 : 31;
 TCGv_reg dest, src, tmp;
 
+if (!ctx->is_pa20 && a->d) {
+return false;
+}
 if (a->c) {
 nullify_over(ctx);
 }
@@ -3368,36 +3371,53 @@ static bool trans_extrw_sar(DisasContext *ctx, 
arg_extrw_sar *a)
 tmp = tcg_temp_new();
 
 /* Recall that SAR is using big-endian bit numbering.  */
-tcg_gen_andi_reg(tmp, cpu_sar, 31);
-tcg_gen_xori_reg(tmp, tmp, 31);
+tcg_gen_andi_reg(tmp, cpu_sar, widthm1);
+tcg_gen_xori_reg(tmp, tmp, widthm1);
 
 if (a->se) {
+if (!a->d) {
+tcg_gen_ext32s_reg(dest, src);
+src = dest;
+}
 tcg_gen_sar_reg(dest, src, tmp);
-tcg_gen_sextract_reg(dest, dest, 0, len);
+tcg_gen_sextract_reg(dest, dest, 0, a->len);
 } else {
+if (!a->d) {
+tcg_gen_ext32u_reg(dest, src);
+src = dest;
+}
 tcg_gen_shr_reg(dest, src, tmp);
-tcg_gen_extract_reg(dest, dest, 0, len);
+tcg_gen_extract_reg(dest, dest, 0, a->len);
 }
 save_gpr(ctx, a->t, dest);
 
 /* Install the new nullification.  */
 cond_free(>null_cond);
 if (a->c) {
-ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
+ctx->null_cond = do_sed_cond(ctx, a->c, a->d, dest);
 }
 return nullify_end(ctx);
 }
 
-static bool trans_extrw_imm(DisasContext *ctx, arg_extrw_imm *a)
+static bool trans_extr_imm(DisasContext *ctx, arg_extr_imm *a)
 {
-unsigned len = 32 - a->clen;
-unsigned cpos = 31 - a->pos;
+unsigned len, cpos, width;
 TCGv_reg dest, src;
 
+if (!ctx->is_pa20 && a->d) {
+return false;
+}
 if (a->c) {
 nullify_over(ctx);
 }
 
+len = a->len;
+width = a->d ? 64 : 32;
+cpos = width - 1 - a->pos;
+if (cpos + len > width) {
+len = width - cpos;
+}
+
 dest = dest_gpr(ctx, a->t);
 src = load_gpr(ctx, a->r);
 if (a->se) {
@@ -3410,7 +3430,7 @@ static bool trans_extrw_imm(DisasContext *ctx, 
arg_extrw_imm *a)
 /* Install the new nullification.  */
 cond_free(>null_cond);
 if (a->c) {
-ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
+ctx->null_cond = do_sed_cond(ctx, a->c, a->d, dest);
 }
 return nullify_end(ctx);
 }
-- 
2.34.1




[PATCH v3 16/88] target/hppa: Fix do_add, do_sub for hppa64

2023-11-01 Thread Richard Henderson
Select the proper carry bit for input to the arithmetic
and for output for the condition.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 50 ++---
 1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 8ba95ae320..b0cd12a2d0 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1094,13 +1094,15 @@ static void do_add(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
TCGv_reg in2, unsigned shift, bool is_l,
bool is_tsv, bool is_tc, bool is_c, unsigned cf)
 {
-TCGv_reg dest, cb, cb_msb, sv, tmp;
+TCGv_reg dest, cb, cb_msb, cb_cond, sv, tmp;
 unsigned c = cf >> 1;
 DisasCond cond;
+bool d = false;
 
 dest = tcg_temp_new();
 cb = NULL;
 cb_msb = NULL;
+cb_cond = NULL;
 
 if (shift) {
 tmp = tcg_temp_new();
@@ -,19 +1113,22 @@ static void do_add(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 if (!is_l || cond_need_cb(c)) {
 TCGv_reg zero = tcg_constant_reg(0);
 cb_msb = tcg_temp_new();
+cb = tcg_temp_new();
+
 tcg_gen_add2_reg(dest, cb_msb, in1, zero, in2, zero);
 if (is_c) {
-tcg_gen_add2_reg(dest, cb_msb, dest, cb_msb, cpu_psw_cb_msb, zero);
+tcg_gen_add2_reg(dest, cb_msb, dest, cb_msb,
+ get_psw_carry(ctx, d), zero);
 }
-if (!is_l) {
-cb = tcg_temp_new();
-tcg_gen_xor_reg(cb, in1, in2);
-tcg_gen_xor_reg(cb, cb, dest);
+tcg_gen_xor_reg(cb, in1, in2);
+tcg_gen_xor_reg(cb, cb, dest);
+if (cond_need_cb(c)) {
+cb_cond = get_carry(ctx, d, cb, cb_msb);
 }
 } else {
 tcg_gen_add_reg(dest, in1, in2);
 if (is_c) {
-tcg_gen_add_reg(dest, dest, cpu_psw_cb_msb);
+tcg_gen_add_reg(dest, dest, get_psw_carry(ctx, d));
 }
 }
 
@@ -1138,7 +1143,7 @@ static void do_add(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 }
 
 /* Emit any conditional trap before any writeback.  */
-cond = do_cond(cf, dest, cb_msb, sv);
+cond = do_cond(cf, dest, cb_cond, sv);
 if (is_tc) {
 tmp = tcg_temp_new();
 tcg_gen_setcond_reg(cond.c, tmp, cond.a0, cond.a1);
@@ -1192,6 +1197,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 TCGv_reg dest, sv, cb, cb_msb, zero, tmp;
 unsigned c = cf >> 1;
 DisasCond cond;
+bool d = false;
 
 dest = tcg_temp_new();
 cb = tcg_temp_new();
@@ -1201,15 +1207,17 @@ static void do_sub(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 if (is_b) {
 /* DEST,C = IN1 + ~IN2 + C.  */
 tcg_gen_not_reg(cb, in2);
-tcg_gen_add2_reg(dest, cb_msb, in1, zero, cpu_psw_cb_msb, zero);
+tcg_gen_add2_reg(dest, cb_msb, in1, zero, get_psw_carry(ctx, d), zero);
 tcg_gen_add2_reg(dest, cb_msb, dest, cb_msb, cb, zero);
 tcg_gen_xor_reg(cb, cb, in1);
 tcg_gen_xor_reg(cb, cb, dest);
 } else {
-/* DEST,C = IN1 + ~IN2 + 1.  We can produce the same result in fewer
-   operations by seeding the high word with 1 and subtracting.  */
-tcg_gen_movi_reg(cb_msb, 1);
-tcg_gen_sub2_reg(dest, cb_msb, in1, cb_msb, in2, zero);
+/*
+ * DEST,C = IN1 + ~IN2 + 1.  We can produce the same result in fewer
+ * operations by seeding the high word with 1 and subtracting.
+ */
+TCGv_reg one = tcg_constant_reg(1);
+tcg_gen_sub2_reg(dest, cb_msb, in1, one, in2, zero);
 tcg_gen_eqv_reg(cb, in1, in2);
 tcg_gen_xor_reg(cb, cb, dest);
 }
@@ -1227,7 +1235,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 if (!is_b) {
 cond = do_sub_cond(cf, dest, in1, in2, sv);
 } else {
-cond = do_cond(cf, dest, cb_msb, sv);
+cond = do_cond(cf, dest, get_carry(ctx, d, cb, cb_msb), sv);
 }
 
 /* Emit any conditional trap before any writeback.  */
@@ -3019,18 +3027,24 @@ static bool trans_cmpbi(DisasContext *ctx, arg_cmpbi *a)
 static bool do_addb(DisasContext *ctx, unsigned r, TCGv_reg in1,
 unsigned c, unsigned f, unsigned n, int disp)
 {
-TCGv_reg dest, in2, sv, cb_msb;
+TCGv_reg dest, in2, sv, cb_cond;
 DisasCond cond;
+bool d = false;
 
 in2 = load_gpr(ctx, r);
 dest = tcg_temp_new();
 sv = NULL;
-cb_msb = NULL;
+cb_cond = NULL;
 
 if (cond_need_cb(c)) {
-cb_msb = tcg_temp_new();
+TCGv_reg cb = tcg_temp_new();
+TCGv_reg cb_msb = tcg_temp_new();
+
 tcg_gen_movi_reg(cb_msb, 0);
 tcg_gen_add2_reg(dest, cb_msb, in1, cb_msb, in2, cb_msb);
+tcg_gen_xor_reg(cb, in1, in2);
+tcg_gen_xor_reg(cb, cb, dest);
+cb_cond = get_carry(ctx, d, cb, cb_msb);
 } else {
 tcg_gen_add_reg(dest, in1, in2);
 }

[PATCH v3 84/88] hw/pci-host/astro: Map Astro chip into 64-bit I/O memory region

2023-11-01 Thread Richard Henderson
From: Helge Deller 

Map Astro into high F-region and add alias for 32-bit OS in low region.

Signed-off-by: Helge Deller 
---
 hw/pci-host/astro.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/pci-host/astro.c b/hw/pci-host/astro.c
index 4b2d7caf2d..df61386bd9 100644
--- a/hw/pci-host/astro.c
+++ b/hw/pci-host/astro.c
@@ -19,6 +19,8 @@
 
 #define TYPE_ASTRO_IOMMU_MEMORY_REGION "astro-iommu-memory-region"
 
+#define F_EXTEND(addr) ((addr) | MAKE_64BIT_MASK(32, 32))
+
 #include "qemu/osdep.h"
 #include "qemu/module.h"
 #include "qemu/units.h"
@@ -821,15 +823,16 @@ static void astro_realize(DeviceState *obj, Error **errp)
 
 /* map elroys mmio */
 map_size = LMMIO_DIST_BASE_SIZE / ROPES_PER_IOC;
-map_addr = (uint32_t) (LMMIO_DIST_BASE_ADDR + rope * map_size);
+map_addr = F_EXTEND(LMMIO_DIST_BASE_ADDR + rope * map_size);
 memory_region_init_alias(>pci_mmio_alias, OBJECT(elroy),
  "pci-mmio-alias",
- >pci_mmio, map_addr, map_size);
+ >pci_mmio, (uint32_t) map_addr, 
map_size);
 memory_region_add_subregion(get_system_memory(), map_addr,
  >pci_mmio_alias);
 
+/* map elroys io */
 map_size = IOS_DIST_BASE_SIZE / ROPES_PER_IOC;
-map_addr = (uint32_t) (IOS_DIST_BASE_ADDR + rope * map_size);
+map_addr = F_EXTEND(IOS_DIST_BASE_ADDR + rope * map_size);
 memory_region_add_subregion(get_system_memory(), map_addr,
  >pci_io);
 
-- 
2.34.1




[PATCH v3 32/88] target/hppa: Pass d to do_cond

2023-11-01 Thread Richard Henderson
Hoist the resolution of d up one level above do_cond.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 82 +++--
 1 file changed, 54 insertions(+), 28 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 1694b988ae..7b0e48c42b 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -827,7 +827,7 @@ static bool cond_need_cb(int c)
 /* Need extensions from TCGv_i32 to TCGv_reg. */
 static bool cond_need_ext(DisasContext *ctx, bool d)
 {
-return TARGET_REGISTER_BITS == 64 && !d;
+return TARGET_REGISTER_BITS == 64 && !(ctx->is_pa20 && d);
 }
 
 /*
@@ -835,8 +835,8 @@ static bool cond_need_ext(DisasContext *ctx, bool d)
  * the Parisc 1.1 Architecture Reference Manual for details.
  */
 
-static DisasCond do_cond(unsigned cf, TCGv_reg res,
- TCGv_reg cb_msb, TCGv_reg sv)
+static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d,
+ TCGv_reg res, TCGv_reg cb_msb, TCGv_reg sv)
 {
 DisasCond cond;
 TCGv_reg tmp;
@@ -846,11 +846,19 @@ static DisasCond do_cond(unsigned cf, TCGv_reg res,
 cond = cond_make_f();
 break;
 case 1: /* = / <>(Z / !Z) */
+if (cond_need_ext(ctx, d)) {
+tmp = tcg_temp_new();
+tcg_gen_ext32u_reg(tmp, res);
+res = tmp;
+}
 cond = cond_make_0(TCG_COND_EQ, res);
 break;
 case 2: /* < / >=(N ^ V / !(N ^ V) */
 tmp = tcg_temp_new();
 tcg_gen_xor_reg(tmp, res, sv);
+if (cond_need_ext(ctx, d)) {
+tcg_gen_ext32s_reg(tmp, tmp);
+}
 cond = cond_make_0_tmp(TCG_COND_LT, tmp);
 break;
 case 3: /* <= / >(N ^ V) | Z / !((N ^ V) | Z) */
@@ -865,20 +873,35 @@ static DisasCond do_cond(unsigned cf, TCGv_reg res,
  */
 tmp = tcg_temp_new();
 tcg_gen_eqv_reg(tmp, res, sv);
-tcg_gen_sari_reg(tmp, tmp, TARGET_REGISTER_BITS - 1);
-tcg_gen_and_reg(tmp, tmp, res);
+if (cond_need_ext(ctx, d)) {
+tcg_gen_sextract_reg(tmp, tmp, 31, 1);
+tcg_gen_and_reg(tmp, tmp, res);
+tcg_gen_ext32u_reg(tmp, tmp);
+} else {
+tcg_gen_sari_reg(tmp, tmp, TARGET_REGISTER_BITS - 1);
+tcg_gen_and_reg(tmp, tmp, res);
+}
 cond = cond_make_0_tmp(TCG_COND_EQ, tmp);
 break;
 case 4: /* NUV / UV  (!C / C) */
+/* Only bit 0 of cb_msb is ever set. */
 cond = cond_make_0(TCG_COND_EQ, cb_msb);
 break;
 case 5: /* ZNV / VNZ (!C | Z / C & !Z) */
 tmp = tcg_temp_new();
 tcg_gen_neg_reg(tmp, cb_msb);
 tcg_gen_and_reg(tmp, tmp, res);
+if (cond_need_ext(ctx, d)) {
+tcg_gen_ext32u_reg(tmp, tmp);
+}
 cond = cond_make_0_tmp(TCG_COND_EQ, tmp);
 break;
 case 6: /* SV / NSV  (V / !V) */
+if (cond_need_ext(ctx, d)) {
+tmp = tcg_temp_new();
+tcg_gen_ext32s_reg(tmp, sv);
+sv = tmp;
+}
 cond = cond_make_0(TCG_COND_LT, sv);
 break;
 case 7: /* OD / EV */
@@ -900,10 +923,11 @@ static DisasCond do_cond(unsigned cf, TCGv_reg res,
can use the inputs directly.  This can allow other computation to be
deleted as unused.  */
 
-static DisasCond do_sub_cond(unsigned cf, TCGv_reg res,
+static DisasCond do_sub_cond(DisasContext *ctx, unsigned cf, TCGv_reg res,
  TCGv_reg in1, TCGv_reg in2, TCGv_reg sv)
 {
 DisasCond cond;
+bool d = false;
 
 switch (cf >> 1) {
 case 1: /* = / <> */
@@ -922,7 +946,7 @@ static DisasCond do_sub_cond(unsigned cf, TCGv_reg res,
 cond = cond_make(TCG_COND_LEU, in1, in2);
 break;
 default:
-return do_cond(cf, res, NULL, sv);
+return do_cond(ctx, cf, d, res, NULL, sv);
 }
 if (cf & 1) {
 cond.c = tcg_invert_cond(cond.c);
@@ -940,8 +964,10 @@ static DisasCond do_sub_cond(unsigned cf, TCGv_reg res,
  * how cases c={2,3} are treated.
  */
 
-static DisasCond do_log_cond(unsigned cf, TCGv_reg res)
+static DisasCond do_log_cond(DisasContext *ctx, unsigned cf, TCGv_reg res)
 {
+bool d = false;
+
 switch (cf) {
 case 0:  /* never */
 case 9:  /* undef, C */
@@ -970,7 +996,7 @@ static DisasCond do_log_cond(unsigned cf, TCGv_reg res)
 
 case 14: /* OD */
 case 15: /* EV */
-return do_cond(cf, res, NULL, NULL);
+return do_cond(ctx, cf, d, res, NULL, NULL);
 
 default:
 g_assert_not_reached();
@@ -979,7 +1005,7 @@ static DisasCond do_log_cond(unsigned cf, TCGv_reg res)
 
 /* Similar, but for shift/extract/deposit conditions.  */
 
-static DisasCond do_sed_cond(unsigned orig, TCGv_reg res)
+static DisasCond do_sed_cond(DisasContext *ctx, unsigned orig, TCGv_reg res)
 {
 unsigned c, f;
 
@@ -992,7 +1018,7 @@ static DisasCond do_sed_cond(unsigned 

[PATCH v3 00/88] target/hppa: Implement hppa64 cpu

2023-11-01 Thread Richard Henderson
This is the pa2.0 cpu that should populate Helge's C3700 workstation.

I have adjusted both user and system binaries to always support the
64-bit cpu but default to the 32-bit cpu.

Changes for v3:
  * Rebased.
  * Improve TLB lookups and flushing:
- Separate PSW.P mmu_idx, so that we don't need to flush when
  PSW.P changes.  This was the majority of all TLB flushing.
- Use an interval tree for TLB lookup, rather than a linear
  search across an array.
  * Incorporate some of Helge's machine patches.


r~


Helge Deller (9):
  target/hppa: sar register allows only 5 bits on 32-bit CPU
  target/hppa: Fix interruption based on default PSW
  target/hppa: Add pa2.0 cpu local tlb flushes
  target/hppa: Clear upper bits in mtctl for pa1.x
  hw/pci-host/astro: Map Astro chip into 64-bit I/O memory region
  hw/pci-host/astro: Trigger CPU irq on CPU HPA in high memory
  hw/hppa: Turn on 64-bit CPU for C3700 machine
  hw/hppa: Allow C3700 with 64-bit and B160L with 32-bit CPU only
  hw/hppa: Map PDC ROM and I/O memory area into lower memory

Richard Henderson (79):
  target/hppa: Include PSW_P in tb flags and mmu index
  target/hppa: Rename hppa_tlb_entry to HPPATLBEntry
  target/hppa: Use IntervalTreeNode in HPPATLBEntry
  target/hppa: Always report one page to tlb_set_page
  target/hppa: Split out hppa_flush_tlb_range
  target/hppa: Populate an interval tree with valid tlb entries
  tcg: Improve expansion of deposit of constant
  tcg: Improve expansion of deposit into a constant
  target/hppa: Remove get_temp
  target/hppa: Remove get_temp_tl
  target/hppa: Remove load_const
  target/hppa: Fix hppa64 case in machine.c
  target/hppa: Fix load in do_load_32
  target/hppa: Truncate rotate count in trans_shrpw_sar
  target/hppa: Fix trans_ds for hppa64
  target/hppa: Fix do_add, do_sub for hppa64
  target/hppa: Fix bb_sar for hppa64
  target/hppa: Fix extrw and depw with sar for hppa64
  target/hppa: Introduce TYPE_HPPA64_CPU
  target/hppa: Make HPPA_BTLB_ENTRIES variable
  target/hppa: Implement cpu_list
  target/hppa: Implement hppa_cpu_class_by_name
  target/hppa: Update cpu_hppa_get/put_psw for hppa64
  target/hppa: Handle absolute addresses for pa2.0
  target/hppa: Adjust hppa_cpu_dump_state for hppa64
  target/hppa: Fix hppa64 addressing
  target/hppa: Pass DisasContext to copy_iaoq_entry
  target/hppa: Always use copy_iaoq_entry to set cpu_iaoq_[fb]
  target/hppa: Use copy_iaoq_entry for link in do_ibranch
  target/hppa: Mask inputs in copy_iaoq_entry
  target/hppa: Pass d to do_cond
  target/hppa: Pass d to do_sub_cond
  target/hppa: Pass d to do_log_cond
  target/hppa: Pass d to do_sed_cond
  target/hppa: Pass d to do_unit_cond
  linux-user/hppa: Fixes for TARGET_ABI32
  target/hppa: Drop attempted gdbstub support for hppa64
  target/hppa: Remove TARGET_HPPA64
  target/hppa: Decode d for logical instructions
  target/hppa: Decode d for unit instructions
  target/hppa: Decode d for cmpclr instructions
  target/hppa: Decode d for add instructions
  target/hppa: Decode d for sub instructions
  target/hppa: Decode d for bb instructions
  target/hppa: Decode d for cmpb instructions
  target/hppa: Decode CMPIB double-word
  target/hppa: Decode ADDB double-word
  target/hppa: Implement LDD, LDCD, LDDA, STD, STDA
  target/hppa: Implement DEPD, DEPDI
  target/hppa: Implement EXTRD
  target/hppa: Implement SHRPD
  target/hppa: Implement CLRBTS, POPBTS, PUSHBTS, PUSHNOM
  target/hppa: Implement STDBY
  target/hppa: Implement IDTLBT, IITLBT
  hw/hppa: Use uint32_t instead of target_ureg
  target/hppa: Remove TARGET_REGISTER_BITS
  target/hppa: Remove most of the TARGET_REGISTER_BITS redirections
  target/hppa: Remove remaining TARGET_REGISTER_BITS redirections
  target/hppa: Adjust vmstate_env for pa2.0 tlb
  target/hppa: Use tcg_temp_new_i64 not tcg_temp_new
  target/hppa: Replace tcg_gen_*_tl with tcg_gen_*_i64
  target/hppa: Implement HADD
  target/hppa: Implement HSUB
  target/hppa: Implement HAVG
  target/hppa: Implement HSHL, HSHR
  target/hppa: Implement HSHLADD, HSHRADD
  target/hppa: Implement MIXH, MIXW
  target/hppa: Implement PERMH
  target/hppa: Precompute zero into DisasContext
  target/hppa: Return zero for r0 from load_gpr
  include/hw/elf: Remove truncating signed casts
  hw/hppa: Translate phys addresses for the cpu
  linux-user/hppa: Drop EXCP_DUMP from handled exceptions
  target/hppa: Implement pa2.0 data prefetch instructions
  target/hppa: Avoid async_safe_run_on_cpu on uniprocessor system
  target/hppa: Add unwind_breg to CPUHPPAState
  target/hppa: Create raise_exception_with_ior
  target/hppa: Update IIAOQ, IIASQ for pa2.0
  target/hppa: Improve interrupt logging

 configs/targets/hppa-linux-user.mak |1 +
 include/hw/elf_ops.h|   17 +-
 linux-user/hppa/target_elf.h|2 +-
 target/hppa/cpu-param.h |   22 +-
 target/hppa/cpu-qom.h   |1 +
 target/hppa/cpu.h   |  180 ++-
 target/hppa/helper.h| 

[PATCH v3 01/88] target/hppa: Include PSW_P in tb flags and mmu index

2023-11-01 Thread Richard Henderson
Use a separate mmu index for PSW_P enabled vs disabled.
This means we can elide the tlb flush in cpu_hppa_put_psw
when PSW_P changes.  This turns out to be the majority
of all tlb flushes.

Signed-off-by: Richard Henderson 
---
 target/hppa/cpu.h| 36 
 target/hppa/helper.c |  8 
 target/hppa/mem_helper.c |  6 ++
 target/hppa/translate.c  |  5 +++--
 4 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 798d0c26d7..48d735929e 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -30,21 +30,33 @@
basis.  It's probably easier to fall back to a strong memory model.  */
 #define TCG_GUEST_DEFAULT_MOTCG_MO_ALL
 
-#define MMU_KERNEL_IDX   11
-#define MMU_PL1_IDX  12
-#define MMU_PL2_IDX  13
-#define MMU_USER_IDX 14
-#define MMU_PHYS_IDX 15
+#define MMU_KERNEL_IDX7
+#define MMU_KERNEL_P_IDX  8
+#define MMU_PL1_IDX   9
+#define MMU_PL1_P_IDX 10
+#define MMU_PL2_IDX   11
+#define MMU_PL2_P_IDX 12
+#define MMU_USER_IDX  13
+#define MMU_USER_P_IDX14
+#define MMU_PHYS_IDX  15
 
-#define PRIV_TO_MMU_IDX(priv)(MMU_KERNEL_IDX + (priv))
-#define MMU_IDX_TO_PRIV(mmu_idx) ((mmu_idx) - MMU_KERNEL_IDX)
+#define MMU_IDX_TO_PRIV(MIDX)   (((MIDX) - MMU_KERNEL_IDX) / 2)
+#define MMU_IDX_TO_P(MIDX)  (((MIDX) - MMU_KERNEL_IDX) & 1)
+#define PRIV_P_TO_MMU_IDX(PRIV, P)  ((PRIV) * 2 + !!(P) + MMU_KERNEL_IDX)
 
 #define TARGET_INSN_START_EXTRA_WORDS 1
 
 /* No need to flush MMU_PHYS_IDX  */
 #define HPPA_MMU_FLUSH_MASK \
-(1 << MMU_KERNEL_IDX | 1 << MMU_PL1_IDX |   \
- 1 << MMU_PL2_IDX| 1 << MMU_USER_IDX)
+(1 << MMU_KERNEL_IDX | 1 << MMU_KERNEL_P_IDX |  \
+ 1 << MMU_PL1_IDX| 1 << MMU_PL1_P_IDX|  \
+ 1 << MMU_PL2_IDX| 1 << MMU_PL2_P_IDX|  \
+ 1 << MMU_USER_IDX   | 1 << MMU_USER_P_IDX)
+
+/* Indicies to flush for access_id changes. */
+#define HPPA_MMU_FLUSH_P_MASK \
+(1 << MMU_KERNEL_P_IDX | 1 << MMU_PL1_P_IDX  |  \
+ 1 << MMU_PL2_P_IDX| 1 << MMU_USER_P_IDX)
 
 /* Hardware exceptions, interrupts, faults, and traps.  */
 #define EXCP_HPMC1  /* high priority machine check */
@@ -249,7 +261,7 @@ static inline int cpu_mmu_index(CPUHPPAState *env, bool 
ifetch)
 return MMU_USER_IDX;
 #else
 if (env->psw & (ifetch ? PSW_C : PSW_D)) {
-return PRIV_TO_MMU_IDX(env->iaoq_f & 3);
+return PRIV_P_TO_MMU_IDX(env->iaoq_f & 3, env->psw & PSW_P);
 }
 return MMU_PHYS_IDX;  /* mmu disabled */
 #endif
@@ -299,8 +311,8 @@ static inline void cpu_get_tb_cpu_state(CPUHPPAState *env, 
vaddr *pc,
 *cs_base = env->iaoq_b & -4;
 flags |= TB_FLAG_UNALIGN * !env_cpu(env)->prctl_unalign_sigbus;
 #else
-/* ??? E, T, H, L, B, P bits need to be here, when implemented.  */
-flags |= env->psw & (PSW_W | PSW_C | PSW_D);
+/* ??? E, T, H, L, B bits need to be here, when implemented.  */
+flags |= env->psw & (PSW_W | PSW_C | PSW_D | PSW_P);
 flags |= (env->iaoq_f & 3) << TB_FLAG_PRIV_SHIFT;
 
 *pc = (env->psw & PSW_C
diff --git a/target/hppa/helper.c b/target/hppa/helper.c
index a8d3f456ee..cba8160b3d 100644
--- a/target/hppa/helper.c
+++ b/target/hppa/helper.c
@@ -51,7 +51,6 @@ target_ureg cpu_hppa_get_psw(CPUHPPAState *env)
 
 void cpu_hppa_put_psw(CPUHPPAState *env, target_ureg psw)
 {
-target_ureg old_psw = env->psw;
 target_ureg cb = 0;
 
 env->psw = psw & ~(PSW_N | PSW_V | PSW_CB);
@@ -67,13 +66,6 @@ void cpu_hppa_put_psw(CPUHPPAState *env, target_ureg psw)
 cb |= ((psw >>  9) & 1) <<  8;
 cb |= ((psw >>  8) & 1) <<  4;
 env->psw_cb = cb;
-
-/* If PSW_P changes, it affects how we translate addresses.  */
-if ((psw ^ old_psw) & PSW_P) {
-#ifndef CONFIG_USER_ONLY
-tlb_flush_by_mmuidx(env_cpu(env), HPPA_MMU_FLUSH_MASK);
-#endif
-}
 }
 
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int flags)
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 350485f619..729032288d 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -144,7 +144,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr 
addr, int mmu_idx,
 }
 
 /* access_id == 0 means public page and no check is performed */
-if ((env->psw & PSW_P) && ent->access_id) {
+if (ent->access_id && MMU_IDX_TO_P(mmu_idx)) {
 /* If bits [31:1] match, and bit 0 is set, suppress write.  */
 int match = ent->access_id * 2 + 1;
 
@@ -373,9 +373,7 @@ void HELPER(ptlbe)(CPUHPPAState *env)
 
 void cpu_hppa_change_prot_id(CPUHPPAState *env)
 {
-if (env->psw & PSW_P) {
-tlb_flush_by_mmuidx(env_cpu(env), HPPA_MMU_FLUSH_MASK);
-}
+tlb_flush_by_mmuidx(env_cpu(env), HPPA_MMU_FLUSH_P_MASK);
 }
 
 void HELPER(change_prot_id)(CPUHPPAState *env)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 

[PATCH v3 13/88] target/hppa: Fix load in do_load_32

2023-11-01 Thread Richard Henderson
The destination is TCGv_i32, so use tcg_gen_qemu_ld_i32
not tcg_gen_qemu_ld_reg.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index c8384fccd9..20e44ed528 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1430,7 +1430,7 @@ static void do_load_32(DisasContext *ctx, TCGv_i32 dest, 
unsigned rb,
 
 form_gva(ctx, , , rb, rx, scale, disp, sp, modify,
  ctx->mmu_idx == MMU_PHYS_IDX);
-tcg_gen_qemu_ld_reg(dest, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
+tcg_gen_qemu_ld_i32(dest, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
 if (modify) {
 save_gpr(ctx, rb, ofs);
 }
-- 
2.34.1




[PATCH v3 02/88] target/hppa: Rename hppa_tlb_entry to HPPATLBEntry

2023-11-01 Thread Richard Henderson
Rename to CamelCase per coding style.

Signed-off-by: Richard Henderson 
---
 target/hppa/cpu.h|  8 
 target/hppa/machine.c|  6 +++---
 target/hppa/mem_helper.c | 30 +++---
 3 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 48d735929e..22edfc955d 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -174,7 +174,7 @@ typedef int64_t  target_sreg;
 #define TREG_FMT_ld   "%"PRId64
 #endif
 
-typedef struct {
+typedef struct HPPATLBEntry {
 uint64_t va_b;
 uint64_t va_e;
 target_ureg pa;
@@ -188,7 +188,7 @@ typedef struct {
 unsigned ar_pl2 : 2;
 unsigned entry_valid : 1;
 unsigned access_id : 16;
-} hppa_tlb_entry;
+} HPPATLBEntry;
 
 typedef struct CPUArchState {
 target_ureg iaoq_f;  /* front */
@@ -234,7 +234,7 @@ typedef struct CPUArchState {
 
 /* ??? Implement a unified itlb/dtlb for the moment.  */
 /* ??? We should use a more intelligent data structure.  */
-hppa_tlb_entry tlb[HPPA_TLB_ENTRIES];
+HPPATLBEntry tlb[HPPA_TLB_ENTRIES];
 uint32_t tlb_last;
 } CPUHPPAState;
 
@@ -362,7 +362,7 @@ void hppa_cpu_do_interrupt(CPUState *cpu);
 bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
 int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
   int type, hwaddr *pphys, int *pprot,
-  hppa_tlb_entry **tlb_entry);
+  HPPATLBEntry **tlb_entry);
 extern const MemoryRegionOps hppa_io_eir_ops;
 extern const VMStateDescription vmstate_hppa_cpu;
 void hppa_cpu_alarm_timer(void *);
diff --git a/target/hppa/machine.c b/target/hppa/machine.c
index 905991d7f9..1d3f9b639d 100644
--- a/target/hppa/machine.c
+++ b/target/hppa/machine.c
@@ -69,7 +69,7 @@ static const VMStateInfo vmstate_psw = {
 static int get_tlb(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field)
 {
-hppa_tlb_entry *ent = opaque;
+HPPATLBEntry *ent = opaque;
 uint32_t val;
 
 memset(ent, 0, sizeof(*ent));
@@ -95,7 +95,7 @@ static int get_tlb(QEMUFile *f, void *opaque, size_t size,
 static int put_tlb(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field, JSONWriter *vmdesc)
 {
-hppa_tlb_entry *ent = opaque;
+HPPATLBEntry *ent = opaque;
 uint32_t val = 0;
 
 if (ent->entry_valid) {
@@ -153,7 +153,7 @@ static VMStateField vmstate_env_fields[] = {
 VMSTATE_UINT32(fr0_shadow, CPUHPPAState),
 
 VMSTATE_ARRAY(tlb, CPUHPPAState, ARRAY_SIZE(((CPUHPPAState *)0)->tlb),
-  0, vmstate_tlb, hppa_tlb_entry),
+  0, vmstate_tlb, HPPATLBEntry),
 VMSTATE_UINT32(tlb_last, CPUHPPAState),
 
 VMSTATE_END_OF_LIST()
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 729032288d..a22de81a48 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -25,12 +25,12 @@
 #include "hw/core/cpu.h"
 #include "trace.h"
 
-static hppa_tlb_entry *hppa_find_tlb(CPUHPPAState *env, vaddr addr)
+static HPPATLBEntry *hppa_find_tlb(CPUHPPAState *env, vaddr addr)
 {
 int i;
 
 for (i = 0; i < ARRAY_SIZE(env->tlb); ++i) {
-hppa_tlb_entry *ent = >tlb[i];
+HPPATLBEntry *ent = >tlb[i];
 if (ent->va_b <= addr && addr <= ent->va_e) {
 trace_hppa_tlb_find_entry(env, ent + i, ent->entry_valid,
   ent->va_b, ent->va_e, ent->pa);
@@ -41,7 +41,7 @@ static hppa_tlb_entry *hppa_find_tlb(CPUHPPAState *env, vaddr 
addr)
 return NULL;
 }
 
-static void hppa_flush_tlb_ent(CPUHPPAState *env, hppa_tlb_entry *ent,
+static void hppa_flush_tlb_ent(CPUHPPAState *env, HPPATLBEntry *ent,
bool force_flush_btlb)
 {
 CPUState *cs = env_cpu(env);
@@ -65,9 +65,9 @@ static void hppa_flush_tlb_ent(CPUHPPAState *env, 
hppa_tlb_entry *ent,
 ent->va_b = -1;
 }
 
-static hppa_tlb_entry *hppa_alloc_tlb_ent(CPUHPPAState *env)
+static HPPATLBEntry *hppa_alloc_tlb_ent(CPUHPPAState *env)
 {
-hppa_tlb_entry *ent;
+HPPATLBEntry *ent;
 uint32_t i;
 
 if (env->tlb_last < HPPA_BTLB_ENTRIES || env->tlb_last >= 
ARRAY_SIZE(env->tlb)) {
@@ -86,11 +86,11 @@ static hppa_tlb_entry *hppa_alloc_tlb_ent(CPUHPPAState *env)
 
 int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
   int type, hwaddr *pphys, int *pprot,
-  hppa_tlb_entry **tlb_entry)
+  HPPATLBEntry **tlb_entry)
 {
 hwaddr phys;
 int prot, r_prot, w_prot, x_prot, priv;
-hppa_tlb_entry *ent;
+HPPATLBEntry *ent;
 int ret = -1;
 
 if (tlb_entry) {
@@ -231,7 +231,7 @@ bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
 {
 HPPACPU *cpu = HPPA_CPU(cs);
 CPUHPPAState *env = >env;
-hppa_tlb_entry *ent;
+HPPATLBEntry *ent;
 int prot, excp, a_prot;
 hwaddr 

[PATCH v3 78/88] target/hppa: Avoid async_safe_run_on_cpu on uniprocessor system

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/mem_helper.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 7132ea221c..602e6c809f 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -480,6 +480,7 @@ void HELPER(ptlb)(CPUHPPAState *env, target_ulong addr)
 {
 CPUState *src = env_cpu(env);
 CPUState *cpu;
+bool wait = false;
 
 trace_hppa_tlb_ptlb(env);
 run_on_cpu_data data = RUN_ON_CPU_TARGET_PTR(addr);
@@ -487,9 +488,14 @@ void HELPER(ptlb)(CPUHPPAState *env, target_ulong addr)
 CPU_FOREACH(cpu) {
 if (cpu != src) {
 async_run_on_cpu(cpu, ptlb_work, data);
+wait = true;
 }
 }
-async_safe_run_on_cpu(src, ptlb_work, data);
+if (wait) {
+async_safe_run_on_cpu(src, ptlb_work, data);
+} else {
+ptlb_work(src, data);
+}
 }
 
 void hppa_ptlbe(CPUHPPAState *env)
-- 
2.34.1




[PATCH v3 52/88] target/hppa: Implement SHRPD

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode |  6 ++-
 target/hppa/translate.c  | 97 
 2 files changed, 72 insertions(+), 31 deletions(-)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 7b51f39b9e..6f0c3f6ea5 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -332,8 +332,10 @@ addbi   101011 . . ... ... . .  
@rib_cf f=1
 # Shift, Extract, Deposit
 
 
-shrpw_sar   110100 r2:5 r1:5 c:3 00 00  t:5
-shrpw_imm   110100 r2:5 r1:5 c:3 01 0cpos:5 t:5
+shrp_sar110100 r2:5 r1:5 c:3 00 0 d:1   t:5
+shrp_imm110100 r2:5 r1:5 c:3 01 0 cpos:5t:5   d=0
+shrp_imm110100 r2:5 r1:5 c:3 0. 1 .  t:5  \
+d=1 cpos=%cpos6_11
 
 extr_sar110100 r:5  t:5  c:3 10 se:1 00 000 . d=0 len=%len5
 extr_sar110100 r:5  t:5  c:3 10 se:1 1. 000 . d=1 len=%len6_8
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 533e29879e..897b44d7e3 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3279,34 +3279,64 @@ static bool trans_movbi(DisasContext *ctx, arg_movbi *a)
 return do_cbranch(ctx, a->disp, a->n, );
 }
 
-static bool trans_shrpw_sar(DisasContext *ctx, arg_shrpw_sar *a)
+static bool trans_shrp_sar(DisasContext *ctx, arg_shrp_sar *a)
 {
-TCGv_reg dest;
+TCGv_reg dest, src2;
 
+if (!ctx->is_pa20 && a->d) {
+return false;
+}
 if (a->c) {
 nullify_over(ctx);
 }
 
 dest = dest_gpr(ctx, a->t);
+src2 = load_gpr(ctx, a->r2);
 if (a->r1 == 0) {
-tcg_gen_ext32u_reg(dest, load_gpr(ctx, a->r2));
-tcg_gen_shr_reg(dest, dest, cpu_sar);
+if (a->d) {
+tcg_gen_shr_reg(dest, src2, cpu_sar);
+} else {
+TCGv_reg tmp = tcg_temp_new();
+
+tcg_gen_ext32u_reg(dest, src2);
+tcg_gen_andi_reg(tmp, cpu_sar, 31);
+tcg_gen_shr_reg(dest, dest, tmp);
+}
 } else if (a->r1 == a->r2) {
-TCGv_i32 t32 = tcg_temp_new_i32();
-TCGv_i32 s32 = tcg_temp_new_i32();
+if (a->d) {
+tcg_gen_rotr_reg(dest, src2, cpu_sar);
+} else {
+TCGv_i32 t32 = tcg_temp_new_i32();
+TCGv_i32 s32 = tcg_temp_new_i32();
 
-tcg_gen_trunc_reg_i32(t32, load_gpr(ctx, a->r2));
-tcg_gen_trunc_reg_i32(s32, cpu_sar);
-tcg_gen_rotr_i32(t32, t32, s32);
-tcg_gen_extu_i32_reg(dest, t32);
+tcg_gen_trunc_reg_i32(t32, src2);
+tcg_gen_trunc_reg_i32(s32, cpu_sar);
+tcg_gen_andi_i32(s32, s32, 31);
+tcg_gen_rotr_i32(t32, t32, s32);
+tcg_gen_extu_i32_reg(dest, t32);
+}
 } else {
-TCGv_i64 t = tcg_temp_new_i64();
-TCGv_i64 s = tcg_temp_new_i64();
+TCGv_reg src1 = load_gpr(ctx, a->r1);
 
-tcg_gen_concat_reg_i64(t, load_gpr(ctx, a->r2), load_gpr(ctx, a->r1));
-tcg_gen_extu_reg_i64(s, cpu_sar);
-tcg_gen_shr_i64(t, t, s);
-tcg_gen_trunc_i64_reg(dest, t);
+if (a->d) {
+TCGv_reg t = tcg_temp_new();
+TCGv_reg n = tcg_temp_new();
+
+tcg_gen_xori_reg(n, cpu_sar, 63);
+tcg_gen_shl_reg(t, src2, n);
+tcg_gen_shli_reg(t, t, 1);
+tcg_gen_shr_reg(dest, src1, cpu_sar);
+tcg_gen_or_reg(dest, dest, t);
+} else {
+TCGv_i64 t = tcg_temp_new_i64();
+TCGv_i64 s = tcg_temp_new_i64();
+
+tcg_gen_concat_reg_i64(t, src2, src1);
+tcg_gen_extu_reg_i64(s, cpu_sar);
+tcg_gen_andi_i64(s, s, 31);
+tcg_gen_shr_i64(t, t, s);
+tcg_gen_trunc_i64_reg(dest, t);
+}
 }
 save_gpr(ctx, a->t, dest);
 
@@ -3318,31 +3348,40 @@ static bool trans_shrpw_sar(DisasContext *ctx, 
arg_shrpw_sar *a)
 return nullify_end(ctx);
 }
 
-static bool trans_shrpw_imm(DisasContext *ctx, arg_shrpw_imm *a)
+static bool trans_shrp_imm(DisasContext *ctx, arg_shrp_imm *a)
 {
-unsigned sa = 31 - a->cpos;
+unsigned width, sa;
 TCGv_reg dest, t2;
 
+if (!ctx->is_pa20 && a->d) {
+return false;
+}
 if (a->c) {
 nullify_over(ctx);
 }
 
+width = a->d ? 64 : 32;
+sa = width - 1 - a->cpos;
+
 dest = dest_gpr(ctx, a->t);
 t2 = load_gpr(ctx, a->r2);
 if (a->r1 == 0) {
-tcg_gen_extract_reg(dest, t2, sa, 32 - sa);
-} else if (TARGET_REGISTER_BITS == 32) {
+tcg_gen_extract_reg(dest, t2, sa, width - sa);
+} else if (width == TARGET_REGISTER_BITS) {
 tcg_gen_extract2_reg(dest, t2, cpu_gr[a->r1], sa);
-} else if (a->r1 == a->r2) {
-TCGv_i32 t32 = tcg_temp_new_i32();
-tcg_gen_trunc_reg_i32(t32, t2);
-tcg_gen_rotri_i32(t32, t32, sa);
-tcg_gen_extu_i32_reg(dest, t32);
 } else {
-TCGv_i64 t64 = 

[PATCH v3 33/88] target/hppa: Pass d to do_sub_cond

2023-11-01 Thread Richard Henderson
Hoist the resolution of d up one level above do_sub_cond.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 77 ++---
 1 file changed, 49 insertions(+), 28 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 7b0e48c42b..72971097bb 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -446,12 +446,15 @@ static DisasCond cond_make_n(void)
 };
 }
 
-static DisasCond cond_make_0_tmp(TCGCond c, TCGv_reg a0)
+static DisasCond cond_make_tmp(TCGCond c, TCGv_reg a0, TCGv_reg a1)
 {
 assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
-return (DisasCond){
-.c = c, .a0 = a0, .a1 = tcg_constant_reg(0)
-};
+return (DisasCond){ .c = c, .a0 = a0, .a1 = a1 };
+}
+
+static DisasCond cond_make_0_tmp(TCGCond c, TCGv_reg a0)
+{
+return cond_make_tmp(c, a0, tcg_constant_reg(0));
 }
 
 static DisasCond cond_make_0(TCGCond c, TCGv_reg a0)
@@ -463,15 +466,12 @@ static DisasCond cond_make_0(TCGCond c, TCGv_reg a0)
 
 static DisasCond cond_make(TCGCond c, TCGv_reg a0, TCGv_reg a1)
 {
-DisasCond r = { .c = c };
+TCGv_reg t0 = tcg_temp_new();
+TCGv_reg t1 = tcg_temp_new();
 
-assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
-r.a0 = tcg_temp_new();
-tcg_gen_mov_reg(r.a0, a0);
-r.a1 = tcg_temp_new();
-tcg_gen_mov_reg(r.a1, a1);
-
-return r;
+tcg_gen_mov_reg(t0, a0);
+tcg_gen_mov_reg(t1, a1);
+return cond_make_tmp(c, t0, t1);
 }
 
 static void cond_free(DisasCond *cond)
@@ -923,36 +923,55 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, 
bool d,
can use the inputs directly.  This can allow other computation to be
deleted as unused.  */
 
-static DisasCond do_sub_cond(DisasContext *ctx, unsigned cf, TCGv_reg res,
- TCGv_reg in1, TCGv_reg in2, TCGv_reg sv)
+static DisasCond do_sub_cond(DisasContext *ctx, unsigned cf, bool d,
+ TCGv_reg res, TCGv_reg in1,
+ TCGv_reg in2, TCGv_reg sv)
 {
-DisasCond cond;
-bool d = false;
+TCGCond tc;
+bool ext_uns;
 
 switch (cf >> 1) {
 case 1: /* = / <> */
-cond = cond_make(TCG_COND_EQ, in1, in2);
+tc = TCG_COND_EQ;
+ext_uns = true;
 break;
 case 2: /* < / >= */
-cond = cond_make(TCG_COND_LT, in1, in2);
+tc = TCG_COND_LT;
+ext_uns = false;
 break;
 case 3: /* <= / > */
-cond = cond_make(TCG_COND_LE, in1, in2);
+tc = TCG_COND_LE;
+ext_uns = false;
 break;
 case 4: /* << / >>= */
-cond = cond_make(TCG_COND_LTU, in1, in2);
+tc = TCG_COND_LTU;
+ext_uns = true;
 break;
 case 5: /* <<= / >> */
-cond = cond_make(TCG_COND_LEU, in1, in2);
+tc = TCG_COND_LEU;
+ext_uns = true;
 break;
 default:
 return do_cond(ctx, cf, d, res, NULL, sv);
 }
-if (cf & 1) {
-cond.c = tcg_invert_cond(cond.c);
-}
 
-return cond;
+if (cf & 1) {
+tc = tcg_invert_cond(tc);
+}
+if (cond_need_ext(ctx, d)) {
+TCGv_reg t1 = tcg_temp_new();
+TCGv_reg t2 = tcg_temp_new();
+
+if (ext_uns) {
+tcg_gen_ext32u_reg(t1, in1);
+tcg_gen_ext32u_reg(t2, in2);
+} else {
+tcg_gen_ext32s_reg(t1, in1);
+tcg_gen_ext32s_reg(t2, in2);
+}
+return cond_make_tmp(tc, t1, t2);
+}
+return cond_make(tc, in1, in2);
 }
 
 /*
@@ -1280,7 +1299,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 
 /* Compute the condition.  We cannot use the special case for borrow.  */
 if (!is_b) {
-cond = do_sub_cond(ctx, cf, dest, in1, in2, sv);
+cond = do_sub_cond(ctx, cf, d, dest, in1, in2, sv);
 } else {
 cond = do_cond(ctx, cf, d, dest, get_carry(ctx, d, cb, cb_msb), sv);
 }
@@ -1334,6 +1353,7 @@ static void do_cmpclr(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 {
 TCGv_reg dest, sv;
 DisasCond cond;
+bool d = false;
 
 dest = tcg_temp_new();
 tcg_gen_sub_reg(dest, in1, in2);
@@ -1345,7 +1365,7 @@ static void do_cmpclr(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 }
 
 /* Form the condition for the compare.  */
-cond = do_sub_cond(ctx, cf, dest, in1, in2, sv);
+cond = do_sub_cond(ctx, cf, d, dest, in1, in2, sv);
 
 /* Clear.  */
 tcg_gen_movi_reg(dest, 0);
@@ -3049,6 +3069,7 @@ static bool do_cmpb(DisasContext *ctx, unsigned r, 
TCGv_reg in1,
 {
 TCGv_reg dest, in2, sv;
 DisasCond cond;
+bool d = false;
 
 in2 = load_gpr(ctx, r);
 dest = tcg_temp_new();
@@ -3060,7 +3081,7 @@ static bool do_cmpb(DisasContext *ctx, unsigned r, 
TCGv_reg in1,
 sv = do_sub_sv(ctx, dest, in1, in2);
 }
 
-cond = do_sub_cond(ctx, c * 2 + f, dest, in1, in2, sv);
+cond = do_sub_cond(ctx, c * 2 + f, d, dest, in1, in2, sv);
 

[PATCH v3 62/88] target/hppa: Replace tcg_gen_*_tl with tcg_gen_*_i64

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 59d172f355..f570b17ecd 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1338,10 +1338,10 @@ static void form_gva(DisasContext *ctx, TCGv_i64 *pgva, 
TCGv_i64 *pofs,
 
 *pofs = ofs;
 *pgva = addr = tcg_temp_new_i64();
-tcg_gen_andi_tl(addr, modify <= 0 ? ofs : base, gva_offset_mask(ctx));
+tcg_gen_andi_i64(addr, modify <= 0 ? ofs : base, gva_offset_mask(ctx));
 #ifndef CONFIG_USER_ONLY
 if (!is_phys) {
-tcg_gen_or_tl(addr, addr, space_select(ctx, sp, base));
+tcg_gen_or_i64(addr, addr, space_select(ctx, sp, base));
 }
 #endif
 }
@@ -2382,7 +2382,7 @@ static bool trans_ixtlbxf(DisasContext *ctx, arg_ixtlbxf 
*a)
   a->data ? offsetof(CPUHPPAState, cr[CR_IOR])
   : offsetof(CPUHPPAState, cr[CR_IIAOQ]));
 tcg_gen_shli_i64(stl, stl, 32);
-tcg_gen_or_tl(addr, atl, stl);
+tcg_gen_or_i64(addr, atl, stl);
 
 reg = load_gpr(ctx, a->r);
 if (a->addr) {
@@ -2939,7 +2939,7 @@ static bool trans_ldo(DisasContext *ctx, arg_ldo *a)
 TCGv_i64 tcg_rt = dest_gpr(ctx, a->t);
 
 /* Special case rb == 0, for the LDI pseudo-op.
-   The COPY pseudo-op is handled for free within tcg_gen_addi_tl.  */
+   The COPY pseudo-op is handled for free within tcg_gen_addi_i64.  */
 if (a->b == 0) {
 tcg_gen_movi_i64(tcg_rt, a->i);
 } else {
-- 
2.34.1




[PATCH v3 19/88] target/hppa: Introduce TYPE_HPPA64_CPU

2023-11-01 Thread Richard Henderson
Prepare for the qemu binary supporting both pa10 and pa20
at the same time.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/hppa/cpu-qom.h   |  1 +
 target/hppa/cpu.h   |  5 +
 target/hppa/cpu.c   | 33 ++---
 target/hppa/translate.c |  2 ++
 4 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/target/hppa/cpu-qom.h b/target/hppa/cpu-qom.h
index b96e0318c7..4a85ebf5e0 100644
--- a/target/hppa/cpu-qom.h
+++ b/target/hppa/cpu-qom.h
@@ -24,6 +24,7 @@
 #include "qom/object.h"
 
 #define TYPE_HPPA_CPU "hppa-cpu"
+#define TYPE_HPPA64_CPU "hppa64-cpu"
 
 OBJECT_DECLARE_CPU_TYPE(HPPACPU, HPPACPUClass, HPPA_CPU)
 
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 08de894393..0ac307e0e9 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -272,6 +272,11 @@ struct ArchCPU {
 
 #include "exec/cpu-all.h"
 
+static inline bool hppa_is_pa20(CPUHPPAState *env)
+{
+return object_dynamic_cast(OBJECT(env_cpu(env)), TYPE_HPPA64_CPU) != NULL;
+}
+
 static inline int cpu_mmu_index(CPUHPPAState *env, bool ifetch)
 {
 #ifdef CONFIG_USER_ONLY
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 5e1240c631..07fae42bb8 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -209,20 +209,23 @@ static void hppa_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->tcg_ops = _tcg_ops;
 }
 
-static const TypeInfo hppa_cpu_type_info = {
-.name = TYPE_HPPA_CPU,
-.parent = TYPE_CPU,
-.instance_size = sizeof(HPPACPU),
-.instance_align = __alignof(HPPACPU),
-.instance_init = hppa_cpu_initfn,
-.abstract = false,
-.class_size = sizeof(HPPACPUClass),
-.class_init = hppa_cpu_class_init,
+static const TypeInfo hppa_cpu_type_infos[] = {
+{
+.name = TYPE_HPPA_CPU,
+.parent = TYPE_CPU,
+.instance_size = sizeof(HPPACPU),
+.instance_align = __alignof(HPPACPU),
+.instance_init = hppa_cpu_initfn,
+.abstract = false,
+.class_size = sizeof(HPPACPUClass),
+.class_init = hppa_cpu_class_init,
+},
+#ifdef TARGET_HPPA64
+{
+.name = TYPE_HPPA64_CPU,
+.parent = TYPE_HPPA_CPU,
+},
+#endif
 };
 
-static void hppa_cpu_register_types(void)
-{
-type_register_static(_cpu_type_info);
-}
-
-type_init(hppa_cpu_register_types)
+DEFINE_TYPES(hppa_cpu_type_infos)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index ed88f724ce..44c9911720 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -262,6 +262,7 @@ typedef struct DisasContext {
 int mmu_idx;
 int privilege;
 bool psw_n_nonzero;
+bool is_pa20;
 
 #ifdef CONFIG_USER_ONLY
 MemOp unalign;
@@ -4091,6 +4092,7 @@ static void hppa_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 
 ctx->cs = cs;
 ctx->tb_flags = ctx->base.tb->flags;
+ctx->is_pa20 = hppa_is_pa20(cpu_env(cs));
 
 #ifdef CONFIG_USER_ONLY
 ctx->privilege = MMU_IDX_TO_PRIV(MMU_USER_IDX);
-- 
2.34.1




[PATCH v3 18/88] target/hppa: Fix extrw and depw with sar for hppa64

2023-11-01 Thread Richard Henderson
These are 32-bit operations regardless of processor.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index ffa367b91f..ed88f724ce 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3230,7 +3230,9 @@ static bool trans_extrw_sar(DisasContext *ctx, 
arg_extrw_sar *a)
 tmp = tcg_temp_new();
 
 /* Recall that SAR is using big-endian bit numbering.  */
-tcg_gen_xori_reg(tmp, cpu_sar, TARGET_REGISTER_BITS - 1);
+tcg_gen_andi_reg(tmp, cpu_sar, 31);
+tcg_gen_xori_reg(tmp, tmp, 31);
+
 if (a->se) {
 tcg_gen_sar_reg(dest, src, tmp);
 tcg_gen_sextract_reg(dest, dest, 0, len);
@@ -3355,7 +3357,8 @@ static bool do_depw_sar(DisasContext *ctx, unsigned rt, 
unsigned c,
 tmp = tcg_temp_new();
 
 /* Convert big-endian bit numbering in SAR to left-shift.  */
-tcg_gen_xori_reg(shift, cpu_sar, TARGET_REGISTER_BITS - 1);
+tcg_gen_andi_reg(shift, cpu_sar, 31);
+tcg_gen_xori_reg(shift, shift, 31);
 
 mask = tcg_temp_new();
 tcg_gen_movi_reg(mask, msb + (msb - 1));
-- 
2.34.1




[PATCH v3 30/88] target/hppa: Mask inputs in copy_iaoq_entry

2023-11-01 Thread Richard Henderson
Ensure that the destination is always a valid GVA offset.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index c2db2782f4..cf05d8b6e4 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -720,10 +720,22 @@ static target_ureg gva_offset_mask(DisasContext *ctx)
 static void copy_iaoq_entry(DisasContext *ctx, TCGv_reg dest,
 target_ureg ival, TCGv_reg vval)
 {
-if (unlikely(ival == -1)) {
+target_ureg mask = gva_offset_mask(ctx);
+
+if (ival != -1) {
+tcg_gen_movi_reg(dest, ival & mask);
+return;
+}
+tcg_debug_assert(vval != NULL);
+
+/*
+ * We know that the IAOQ is already properly masked.
+ * This optimization is primarily for "iaoq_f = iaoq_b".
+ */
+if (vval == cpu_iaoq_f || vval == cpu_iaoq_b) {
 tcg_gen_mov_reg(dest, vval);
 } else {
-tcg_gen_movi_reg(dest, ival);
+tcg_gen_andi_reg(dest, vval, mask);
 }
 }
 
-- 
2.34.1




[PATCH v3 66/88] target/hppa: Implement HSHL, HSHR

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/insns.decode |  5 +
 target/hppa/translate.c  | 35 +++
 2 files changed, 40 insertions(+)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 6959555bf3..bb5cd267b0 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -69,6 +69,7 @@
 _cf t r1 r2 cf
 _cf_d   t r1 r2 cf d
 _cf_d_sht r1 r2 cf d sh
+t r i
 _cf t r i cf
 _cf_d   t r i cf d
 
@@ -216,6 +217,10 @@ hadd_us 10 . . 0011 00 0 .  
@rrr
 
 havg10 . . 0010 11 0 .  @rrr
 
+hshl10 0 r:5   100010 i:4  0 t:5
+hshr_s  10 r:5   0 110011 i:4  0 t:5
+hshr_u  10 r:5   0 110010 i:4  0 t:5
+
 hsub10 . . 0001 11 0 .  @rrr
 hsub_ss 10 . . 0001 01 0 .  @rrr
 hsub_us 10 . . 0001 00 0 .  @rrr
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 2fdd4448ae..d342df2dfa 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2789,6 +2789,26 @@ static bool do_multimedia(DisasContext *ctx, arg_rrr *a,
 return nullify_end(ctx);
 }
 
+static bool do_multimedia_sh(DisasContext *ctx, arg_rri *a,
+ void (*fn)(TCGv_i64, TCGv_i64, int64_t))
+{
+TCGv_i64 r, dest;
+
+if (!ctx->is_pa20) {
+return false;
+}
+
+nullify_over(ctx);
+
+r = load_gpr(ctx, a->r);
+dest = dest_gpr(ctx, a->t);
+
+fn(dest, r, a->i);
+save_gpr(ctx, a->t, dest);
+
+return nullify_end(ctx);
+}
+
 static bool trans_hadd(DisasContext *ctx, arg_rrr *a)
 {
 return do_multimedia(ctx, a, tcg_gen_vec_add16_i64);
@@ -2809,6 +2829,21 @@ static bool trans_havg(DisasContext *ctx, arg_rrr *a)
 return do_multimedia(ctx, a, gen_helper_havg);
 }
 
+static bool trans_hshl(DisasContext *ctx, arg_rri *a)
+{
+return do_multimedia_sh(ctx, a, tcg_gen_vec_shl16i_i64);
+}
+
+static bool trans_hshr_s(DisasContext *ctx, arg_rri *a)
+{
+return do_multimedia_sh(ctx, a, tcg_gen_vec_sar16i_i64);
+}
+
+static bool trans_hshr_u(DisasContext *ctx, arg_rri *a)
+{
+return do_multimedia_sh(ctx, a, tcg_gen_vec_shr16i_i64);
+}
+
 static bool trans_hsub(DisasContext *ctx, arg_rrr *a)
 {
 return do_multimedia(ctx, a, tcg_gen_vec_sub16_i64);
-- 
2.34.1




[PATCH v3 20/88] target/hppa: Make HPPA_BTLB_ENTRIES variable

2023-11-01 Thread Richard Henderson
Depend on hppa_is_pa20.

Signed-off-by: Richard Henderson 
---
 target/hppa/cpu.h| 19 +++
 hw/hppa/machine.c|  9 +++--
 target/hppa/machine.c|  3 ++-
 target/hppa/mem_helper.c | 40 ++--
 4 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 0ac307e0e9..48ddcffb8a 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -227,15 +227,13 @@ typedef struct CPUArchState {
 target_ureg cr_back[2];  /* back of cr17/cr18 */
 target_ureg shadow[7];   /* shadow registers */
 
-/* ??? The number of entries isn't specified by the architecture.  */
-#ifdef TARGET_HPPA64
-#define HPPA_BTLB_FIXED 0   /* BTLBs are not supported in 64-bit 
machines */
-#else
-#define HPPA_BTLB_FIXED 16
-#endif
-#define HPPA_BTLB_VARIABLE  0
+/*
+ * ??? The number of entries isn't specified by the architecture.
+ * BTLBs are not supported in 64-bit machines.
+ */
+#define PA10_BTLB_FIXED 16
+#define PA10_BTLB_VARIABLE  0
 #define HPPA_TLB_ENTRIES256
-#define HPPA_BTLB_ENTRIES   (HPPA_BTLB_FIXED + HPPA_BTLB_VARIABLE)
 
 /* Index for round-robin tlb eviction. */
 uint32_t tlb_last;
@@ -277,6 +275,11 @@ static inline bool hppa_is_pa20(CPUHPPAState *env)
 return object_dynamic_cast(OBJECT(env_cpu(env)), TYPE_HPPA64_CPU) != NULL;
 }
 
+static inline int HPPA_BTLB_ENTRIES(CPUHPPAState *env)
+{
+return hppa_is_pa20(env) ? 0 : PA10_BTLB_FIXED + PA10_BTLB_VARIABLE;
+}
+
 static inline int cpu_mmu_index(CPUHPPAState *env, bool ifetch)
 {
 #ifdef CONFIG_USER_ONLY
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 67d4d1b5e0..85682e6bab 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -185,6 +185,7 @@ static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus 
*pci_bus)
 uint64_t val;
 const char qemu_version[] = QEMU_VERSION;
 MachineClass *mc = MACHINE_GET_CLASS(ms);
+int btlb_entries = HPPA_BTLB_ENTRIES([0]->env);
 int len;
 
 fw_cfg = fw_cfg_init_mem(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4);
@@ -196,11 +197,11 @@ static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus 
*pci_bus)
 fw_cfg_add_file(fw_cfg, "/etc/firmware-min-version",
 g_memdup(, sizeof(val)), sizeof(val));
 
-val = cpu_to_le64(HPPA_TLB_ENTRIES - HPPA_BTLB_ENTRIES);
+val = cpu_to_le64(HPPA_TLB_ENTRIES - btlb_entries);
 fw_cfg_add_file(fw_cfg, "/etc/cpu/tlb_entries",
 g_memdup(, sizeof(val)), sizeof(val));
 
-val = cpu_to_le64(HPPA_BTLB_ENTRIES);
+val = cpu_to_le64(btlb_entries);
 fw_cfg_add_file(fw_cfg, "/etc/cpu/btlb_entries",
 g_memdup(, sizeof(val)), sizeof(val));
 
@@ -608,10 +609,6 @@ static void hppa_machine_reset(MachineState *ms, 
ShutdownCause reason)
 
 cs->exception_index = -1;
 cs->halted = 0;
-
-/* clear any existing TLB and BTLB entries */
-memset(cpu[i]->env.tlb, 0, sizeof(cpu[i]->env.tlb));
-cpu[i]->env.tlb_last = HPPA_BTLB_ENTRIES;
 }
 
 /* already initialized by machine_hppa_init()? */
diff --git a/target/hppa/machine.c b/target/hppa/machine.c
index 61ae942ff1..473305ffea 100644
--- a/target/hppa/machine.c
+++ b/target/hppa/machine.c
@@ -139,6 +139,7 @@ static int tlb_pre_load(void *opaque)
 static int tlb_post_load(void *opaque, int version_id)
 {
 CPUHPPAState *env = opaque;
+uint32_t btlb_entries = HPPA_BTLB_ENTRIES(env);
 HPPATLBEntry **unused = >tlb_unused;
 HPPATLBEntry *partial = NULL;
 
@@ -152,7 +153,7 @@ static int tlb_post_load(void *opaque, int version_id)
 
 if (e->entry_valid) {
 interval_tree_insert(>itree, >tlb_root);
-} else if (i < HPPA_BTLB_ENTRIES) {
+} else if (i < btlb_entries) {
 /* btlb not in unused list */
 } else if (partial == NULL && e->itree.start < e->itree.last) {
 partial = e;
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index b1773ece61..327fb20c17 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -57,7 +57,7 @@ static void hppa_flush_tlb_ent(CPUHPPAState *env, 
HPPATLBEntry *ent,
   HPPA_MMU_FLUSH_MASK, TARGET_LONG_BITS);
 
 /* Never clear BTLBs, unless forced to do so. */
-is_btlb = ent < >tlb[HPPA_BTLB_ENTRIES];
+is_btlb = ent < >tlb[HPPA_BTLB_ENTRIES(env)];
 if (is_btlb && !force_flush_btlb) {
 return;
 }
@@ -93,10 +93,11 @@ static HPPATLBEntry *hppa_alloc_tlb_ent(CPUHPPAState *env)
 HPPATLBEntry *ent = env->tlb_unused;
 
 if (ent == NULL) {
+uint32_t btlb_entries = HPPA_BTLB_ENTRIES(env);
 uint32_t i = env->tlb_last;
 
-if (i < HPPA_BTLB_ENTRIES || i >= ARRAY_SIZE(env->tlb)) {
-i = HPPA_BTLB_ENTRIES;
+if (i < btlb_entries || i >= ARRAY_SIZE(env->tlb)) {
+i = btlb_entries;
 }
 

[PATCH v3 26/88] target/hppa: Fix hppa64 addressing

2023-11-01 Thread Richard Henderson
In form_gva and cpu_get_tb_cpu_state, we must truncate when PSW_W == 0.
In space_select, the bits that choose the space depend on PSW_W.

Signed-off-by: Richard Henderson 
---
 target/hppa/cpu.h   |  7 +++
 target/hppa/translate.c | 22 +-
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 2999df9ff9..cb838defb0 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -302,7 +302,7 @@ static inline target_ulong hppa_form_gva_psw(target_ureg 
psw, uint64_t spc,
 #ifdef CONFIG_USER_ONLY
 return off;
 #else
-off &= (psw & PSW_W ? 0x3fffull : 0xull);
+off &= psw & PSW_W ? MAKE_64BIT_MASK(0, 62) : MAKE_64BIT_MASK(0, 32);
 return spc | off;
 #endif
 }
@@ -343,9 +343,8 @@ static inline void cpu_get_tb_cpu_state(CPUHPPAState *env, 
vaddr *pc,
 flags |= env->psw & (PSW_W | PSW_C | PSW_D | PSW_P);
 flags |= (env->iaoq_f & 3) << TB_FLAG_PRIV_SHIFT;
 
-*pc = (env->psw & PSW_C
-   ? hppa_form_gva_psw(env->psw, env->iasq_f, env->iaoq_f & -4)
-   : env->iaoq_f & -4);
+*pc = hppa_form_gva_psw(env->psw, (env->psw & PSW_C ? env->iasq_f : 0),
+env->iaoq_f & -4);
 *cs_base = env->iasq_f;
 
 /* Insert a difference between IAOQ_B and IAOQ_F within the otherwise zero
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 44c9911720..4e0bc48b09 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -710,6 +710,13 @@ static bool nullify_end(DisasContext *ctx)
 return true;
 }
 
+static target_ureg gva_offset_mask(DisasContext *ctx)
+{
+return (ctx->tb_flags & PSW_W
+? MAKE_64BIT_MASK(0, 62)
+: MAKE_64BIT_MASK(0, 32));
+}
+
 static void copy_iaoq_entry(TCGv_reg dest, target_ureg ival, TCGv_reg vval)
 {
 if (unlikely(ival == -1)) {
@@ -1398,7 +1405,8 @@ static TCGv_i64 space_select(DisasContext *ctx, int sp, 
TCGv_reg base)
 tmp = tcg_temp_new();
 spc = tcg_temp_new_tl();
 
-tcg_gen_shri_reg(tmp, base, TARGET_REGISTER_BITS - 5);
+/* Extract top 2 bits of the address, shift left 3 for uint64_t index. */
+tcg_gen_shri_reg(tmp, base, (ctx->tb_flags & PSW_W ? 64 : 32) - 5);
 tcg_gen_andi_reg(tmp, tmp, 030);
 tcg_gen_trunc_reg_ptr(ptr, tmp);
 
@@ -1415,6 +1423,7 @@ static void form_gva(DisasContext *ctx, TCGv_tl *pgva, 
TCGv_reg *pofs,
 {
 TCGv_reg base = load_gpr(ctx, rb);
 TCGv_reg ofs;
+TCGv_tl addr;
 
 /* Note that RX is mutually exclusive with DISP.  */
 if (rx) {
@@ -1429,18 +1438,13 @@ static void form_gva(DisasContext *ctx, TCGv_tl *pgva, 
TCGv_reg *pofs,
 }
 
 *pofs = ofs;
-#ifdef CONFIG_USER_ONLY
-*pgva = (modify <= 0 ? ofs : base);
-#else
-TCGv_tl addr = tcg_temp_new_tl();
+*pgva = addr = tcg_temp_new_tl();
 tcg_gen_extu_reg_tl(addr, modify <= 0 ? ofs : base);
-if (ctx->tb_flags & PSW_W) {
-tcg_gen_andi_tl(addr, addr, 0x3fffull);
-}
+tcg_gen_andi_tl(addr, addr, gva_offset_mask(ctx));
+#ifndef CONFIG_USER_ONLY
 if (!is_phys) {
 tcg_gen_or_tl(addr, addr, space_select(ctx, sp, base));
 }
-*pgva = addr;
 #endif
 }
 
-- 
2.34.1




[PATCH v3 15/88] target/hppa: Fix trans_ds for hppa64

2023-11-01 Thread Richard Henderson
This instruction always uses the input carry from bit 32,
but produces all 16 output carry bits.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 48 +++--
 1 file changed, 37 insertions(+), 11 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index d6ccce020a..8ba95ae320 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -803,6 +803,12 @@ static bool cond_need_cb(int c)
 return c == 4 || c == 5;
 }
 
+/* Need extensions from TCGv_i32 to TCGv_reg. */
+static bool cond_need_ext(DisasContext *ctx, bool d)
+{
+return TARGET_REGISTER_BITS == 64 && !d;
+}
+
 /*
  * Compute conditional for arithmetic.  See Page 5-3, Table 5-1, of
  * the Parisc 1.1 Architecture Reference Manual for details.
@@ -1040,6 +1046,22 @@ static DisasCond do_unit_cond(unsigned cf, TCGv_reg res,
 return cond;
 }
 
+static TCGv_reg get_carry(DisasContext *ctx, bool d,
+  TCGv_reg cb, TCGv_reg cb_msb)
+{
+if (cond_need_ext(ctx, d)) {
+TCGv_reg t = tcg_temp_new();
+tcg_gen_extract_reg(t, cb, 32, 1);
+return t;
+}
+return cb_msb;
+}
+
+static TCGv_reg get_psw_carry(DisasContext *ctx, bool d)
+{
+return get_carry(ctx, d, cpu_psw_cb, cpu_psw_cb_msb);
+}
+
 /* Compute signed overflow for addition.  */
 static TCGv_reg do_add_sv(DisasContext *ctx, TCGv_reg res,
   TCGv_reg in1, TCGv_reg in2)
@@ -2712,6 +2734,7 @@ static bool trans_dcor_i(DisasContext *ctx, arg_rr_cf *a)
 static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
 {
 TCGv_reg dest, add1, add2, addc, zero, in1, in2;
+TCGv_reg cout;
 
 nullify_over(ctx);
 
@@ -2726,18 +2749,20 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
 
 /* Form R1 << 1 | PSW[CB]{8}.  */
 tcg_gen_add_reg(add1, in1, in1);
-tcg_gen_add_reg(add1, add1, cpu_psw_cb_msb);
+tcg_gen_add_reg(add1, add1, get_psw_carry(ctx, false));
 
-/* Add or subtract R2, depending on PSW[V].  Proper computation of
-   carry{8} requires that we subtract via + ~R2 + 1, as described in
-   the manual.  By extracting and masking V, we can produce the
-   proper inputs to the addition without movcond.  */
-tcg_gen_sari_reg(addc, cpu_psw_v, TARGET_REGISTER_BITS - 1);
+/*
+ * Add or subtract R2, depending on PSW[V].  Proper computation of
+ * carry requires that we subtract via + ~R2 + 1, as described in
+ * the manual.  By extracting and masking V, we can produce the
+ * proper inputs to the addition without movcond.
+ */
+tcg_gen_sextract_reg(addc, cpu_psw_v, 31, 1);
 tcg_gen_xor_reg(add2, in2, addc);
 tcg_gen_andi_reg(addc, addc, 1);
-/* ??? This is only correct for 32-bit.  */
-tcg_gen_add2_i32(dest, cpu_psw_cb_msb, add1, zero, add2, zero);
-tcg_gen_add2_i32(dest, cpu_psw_cb_msb, dest, cpu_psw_cb_msb, addc, zero);
+
+tcg_gen_add2_reg(dest, cpu_psw_cb_msb, add1, zero, add2, zero);
+tcg_gen_add2_reg(dest, cpu_psw_cb_msb, dest, cpu_psw_cb_msb, addc, zero);
 
 /* Write back the result register.  */
 save_gpr(ctx, a->t, dest);
@@ -2747,7 +2772,8 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
 tcg_gen_xor_reg(cpu_psw_cb, cpu_psw_cb, dest);
 
 /* Write back PSW[V] for the division step.  */
-tcg_gen_neg_reg(cpu_psw_v, cpu_psw_cb_msb);
+cout = get_psw_carry(ctx, false);
+tcg_gen_neg_reg(cpu_psw_v, cout);
 tcg_gen_xor_reg(cpu_psw_v, cpu_psw_v, in2);
 
 /* Install the new nullification.  */
@@ -2757,7 +2783,7 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
 /* ??? The lshift is supposed to contribute to overflow.  */
 sv = do_add_sv(ctx, dest, add1, add2);
 }
-ctx->null_cond = do_cond(a->cf, dest, cpu_psw_cb_msb, sv);
+ctx->null_cond = do_cond(a->cf, dest, cout, sv);
 }
 
 return nullify_end(ctx);
-- 
2.34.1




[PATCH v3 65/88] target/hppa: Implement HAVG

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/helper.h |  1 +
 target/hppa/insns.decode |  2 ++
 target/hppa/op_helper.c  | 14 ++
 target/hppa/translate.c  |  5 +
 4 files changed, 22 insertions(+)

diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index 02798aa105..51c24b31b0 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -16,6 +16,7 @@ DEF_HELPER_FLAGS_1(ldc_check, TCG_CALL_NO_RWG, void, tl)
 
 DEF_HELPER_FLAGS_2(hadd_ss, TCG_CALL_NO_RWG, i64, i64, i64)
 DEF_HELPER_FLAGS_2(hadd_us, TCG_CALL_NO_RWG, i64, i64, i64)
+DEF_HELPER_FLAGS_2(havg, TCG_CALL_NO_RWG, i64, i64, i64)
 DEF_HELPER_FLAGS_2(hsub_ss, TCG_CALL_NO_RWG, i64, i64, i64)
 DEF_HELPER_FLAGS_2(hsub_us, TCG_CALL_NO_RWG, i64, i64, i64)
 
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 29b49c6cf4..6959555bf3 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -214,6 +214,8 @@ hadd10 . . 0011 11 0 .  @rrr
 hadd_ss 10 . . 0011 01 0 .  @rrr
 hadd_us 10 . . 0011 00 0 .  @rrr
 
+havg10 . . 0010 11 0 .  @rrr
+
 hsub10 . . 0001 11 0 .  @rrr
 hsub_ss 10 . . 0001 01 0 .  @rrr
 hsub_us 10 . . 0001 00 0 .  @rrr
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index ece523bea0..cba610ac75 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -410,6 +410,20 @@ uint64_t HELPER(hadd_us)(uint64_t r1, uint64_t r2)
 return ret;
 }
 
+uint64_t HELPER(havg)(uint64_t r1, uint64_t r2)
+{
+uint64_t ret = 0;
+
+for (int i = 0; i < 64; i += 16) {
+int f1 = extract64(r1, i, 16);
+int f2 = extract64(r2, i, 16);
+int fr = f1 + f2;
+
+ret = deposit64(ret, i, 16, (fr >> 1) | (fr & 1));
+}
+return ret;
+}
+
 uint64_t HELPER(hsub_ss)(uint64_t r1, uint64_t r2)
 {
 uint64_t ret = 0;
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 2f1333b91c..2fdd4448ae 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2804,6 +2804,11 @@ static bool trans_hadd_us(DisasContext *ctx, arg_rrr *a)
 return do_multimedia(ctx, a, gen_helper_hadd_us);
 }
 
+static bool trans_havg(DisasContext *ctx, arg_rrr *a)
+{
+return do_multimedia(ctx, a, gen_helper_havg);
+}
+
 static bool trans_hsub(DisasContext *ctx, arg_rrr *a)
 {
 return do_multimedia(ctx, a, tcg_gen_vec_sub16_i64);
-- 
2.34.1




[PATCH v3 29/88] target/hppa: Use copy_iaoq_entry for link in do_ibranch

2023-11-01 Thread Richard Henderson
We need to make sure the link is masked properly along the
use_nullify_skip path.  The other three settings of a link
register already use this.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 348fdb75e5..c2db2782f4 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1898,7 +1898,7 @@ static bool do_ibranch(DisasContext *ctx, TCGv_reg dest,
 
 nullify_over(ctx);
 if (link != 0) {
-tcg_gen_movi_reg(cpu_gr[link], ctx->iaoq_n);
+copy_iaoq_entry(ctx, cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
 }
 tcg_gen_lookup_and_goto_ptr();
 return nullify_end(ctx);
-- 
2.34.1




[PATCH v3 38/88] target/hppa: Drop attempted gdbstub support for hppa64

2023-11-01 Thread Richard Henderson
There is no support for hppa64 in gdb.  Any attempt to provide the
data for the larger hppa64 registers results in an error from gdb.
Mask CR_SAR writes to the width of the register: 5 or 6 bits.

Signed-off-by: Richard Henderson 
---
 target/hppa/gdbstub.c | 32 +---
 1 file changed, 13 insertions(+), 19 deletions(-)

diff --git a/target/hppa/gdbstub.c b/target/hppa/gdbstub.c
index 48a514384f..4a965b38d7 100644
--- a/target/hppa/gdbstub.c
+++ b/target/hppa/gdbstub.c
@@ -21,11 +21,16 @@
 #include "cpu.h"
 #include "gdbstub/helpers.h"
 
+/*
+ * GDB 15 only supports PA1.0 via the remote protocol, and ignores
+ * any provided xml.  Which means that any attempt to provide more
+ * data results in "Remote 'g' packet reply is too long".
+ */
+
 int hppa_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
 {
-HPPACPU *cpu = HPPA_CPU(cs);
-CPUHPPAState *env = >env;
-target_ureg val;
+CPUHPPAState *env = cpu_env(cs);
+uint32_t val;
 
 switch (n) {
 case 0:
@@ -139,24 +144,13 @@ int hppa_cpu_gdb_read_register(CPUState *cs, GByteArray 
*mem_buf, int n)
 break;
 }
 
-if (TARGET_REGISTER_BITS == 64) {
-return gdb_get_reg64(mem_buf, val);
-} else {
-return gdb_get_reg32(mem_buf, val);
-}
+return gdb_get_reg32(mem_buf, val);
 }
 
 int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 {
-HPPACPU *cpu = HPPA_CPU(cs);
-CPUHPPAState *env = >env;
-target_ureg val;
-
-if (TARGET_REGISTER_BITS == 64) {
-val = ldq_p(mem_buf);
-} else {
-val = ldl_p(mem_buf);
-}
+CPUHPPAState *env = cpu_env(cs);
+uint32_t val = ldl_p(mem_buf);
 
 switch (n) {
 case 0:
@@ -166,7 +160,7 @@ int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 env->gr[n] = val;
 break;
 case 32:
-env->cr[CR_SAR] = val;
+env->cr[CR_SAR] = val & (hppa_is_pa20(env) ? 63 : 31);
 break;
 case 33:
 env->iaoq_f = val;
@@ -278,5 +272,5 @@ int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 }
 break;
 }
-return sizeof(target_ureg);
+return 4;
 }
-- 
2.34.1




[PATCH v3 21/88] target/hppa: Implement cpu_list

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/cpu.h |  5 +
 target/hppa/cpu.c | 24 
 2 files changed, 29 insertions(+)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 48ddcffb8a..301c82114a 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -396,4 +396,9 @@ int hppa_artype_for_page(CPUHPPAState *env, target_ulong 
vaddr);
 #endif
 G_NORETURN void hppa_dynamic_excp(CPUHPPAState *env, int excp, uintptr_t ra);
 
+#define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
+
+#define cpu_list hppa_cpu_list
+void hppa_cpu_list(void);
+
 #endif /* HPPA_CPU_H */
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 07fae42bb8..27c74f0d27 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -161,6 +161,30 @@ static ObjectClass *hppa_cpu_class_by_name(const char 
*cpu_model)
 return object_class_by_name(TYPE_HPPA_CPU);
 }
 
+static void hppa_cpu_list_entry(gpointer data, gpointer user_data)
+{
+ObjectClass *oc = data;
+CPUClass *cc = CPU_CLASS(oc);
+const char *tname = object_class_get_name(oc);
+g_autofree char *name = g_strndup(tname, strchr(tname, '-') - tname);
+
+if (cc->deprecation_note) {
+qemu_printf("  %s (deprecated)\n", name);
+} else {
+qemu_printf("  %s\n", name);
+}
+}
+
+void hppa_cpu_list(void)
+{
+GSList *list;
+
+list = object_class_get_list_sorted(TYPE_HPPA_CPU, false);
+qemu_printf("Available CPUs:\n");
+g_slist_foreach(list, hppa_cpu_list_entry, NULL);
+g_slist_free(list);
+}
+
 #ifndef CONFIG_USER_ONLY
 #include "hw/core/sysemu-cpu-ops.h"
 
-- 
2.34.1




[PATCH v3 09/88] target/hppa: Remove get_temp

2023-11-01 Thread Richard Henderson
Replace with tcg_temp_new without recording into ctx.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 76 +
 1 file changed, 31 insertions(+), 45 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index f6a656325c..99b9fc0561 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -254,8 +254,7 @@ typedef struct DisasContext {
 target_ureg iaoq_n;
 TCGv_reg iaoq_n_var;
 
-int ntempr, ntempl;
-TCGv_reg tempr[8];
+int ntempl;
 TCGv_tl  templ[4];
 
 DisasCond null_cond;
@@ -492,13 +491,6 @@ static void cond_free(DisasCond *cond)
 }
 }
 
-static TCGv_reg get_temp(DisasContext *ctx)
-{
-unsigned i = ctx->ntempr++;
-g_assert(i < ARRAY_SIZE(ctx->tempr));
-return ctx->tempr[i] = tcg_temp_new();
-}
-
 #ifndef CONFIG_USER_ONLY
 static TCGv_tl get_temp_tl(DisasContext *ctx)
 {
@@ -510,7 +502,7 @@ static TCGv_tl get_temp_tl(DisasContext *ctx)
 
 static TCGv_reg load_const(DisasContext *ctx, target_sreg v)
 {
-TCGv_reg t = get_temp(ctx);
+TCGv_reg t = tcg_temp_new();
 tcg_gen_movi_reg(t, v);
 return t;
 }
@@ -518,7 +510,7 @@ static TCGv_reg load_const(DisasContext *ctx, target_sreg v)
 static TCGv_reg load_gpr(DisasContext *ctx, unsigned reg)
 {
 if (reg == 0) {
-TCGv_reg t = get_temp(ctx);
+TCGv_reg t = tcg_temp_new();
 tcg_gen_movi_reg(t, 0);
 return t;
 } else {
@@ -529,7 +521,7 @@ static TCGv_reg load_gpr(DisasContext *ctx, unsigned reg)
 static TCGv_reg dest_gpr(DisasContext *ctx, unsigned reg)
 {
 if (reg == 0 || ctx->null_cond.c != TCG_COND_NEVER) {
-return get_temp(ctx);
+return tcg_temp_new();
 } else {
 return cpu_gr[reg];
 }
@@ -1071,7 +1063,7 @@ static DisasCond do_unit_cond(unsigned cf, TCGv_reg res,
 static TCGv_reg do_add_sv(DisasContext *ctx, TCGv_reg res,
   TCGv_reg in1, TCGv_reg in2)
 {
-TCGv_reg sv = get_temp(ctx);
+TCGv_reg sv = tcg_temp_new();
 TCGv_reg tmp = tcg_temp_new();
 
 tcg_gen_xor_reg(sv, res, in1);
@@ -1085,7 +1077,7 @@ static TCGv_reg do_add_sv(DisasContext *ctx, TCGv_reg res,
 static TCGv_reg do_sub_sv(DisasContext *ctx, TCGv_reg res,
   TCGv_reg in1, TCGv_reg in2)
 {
-TCGv_reg sv = get_temp(ctx);
+TCGv_reg sv = tcg_temp_new();
 TCGv_reg tmp = tcg_temp_new();
 
 tcg_gen_xor_reg(sv, res, in1);
@@ -1108,20 +1100,20 @@ static void do_add(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 cb_msb = NULL;
 
 if (shift) {
-tmp = get_temp(ctx);
+tmp = tcg_temp_new();
 tcg_gen_shli_reg(tmp, in1, shift);
 in1 = tmp;
 }
 
 if (!is_l || cond_need_cb(c)) {
 TCGv_reg zero = tcg_constant_reg(0);
-cb_msb = get_temp(ctx);
+cb_msb = tcg_temp_new();
 tcg_gen_add2_reg(dest, cb_msb, in1, zero, in2, zero);
 if (is_c) {
 tcg_gen_add2_reg(dest, cb_msb, dest, cb_msb, cpu_psw_cb_msb, zero);
 }
 if (!is_l) {
-cb = get_temp(ctx);
+cb = tcg_temp_new();
 tcg_gen_xor_reg(cb, in1, in2);
 tcg_gen_xor_reg(cb, cb, dest);
 }
@@ -1414,11 +1406,11 @@ static void form_gva(DisasContext *ctx, TCGv_tl *pgva, 
TCGv_reg *pofs,
 
 /* Note that RX is mutually exclusive with DISP.  */
 if (rx) {
-ofs = get_temp(ctx);
+ofs = tcg_temp_new();
 tcg_gen_shli_reg(ofs, cpu_gr[rx], scale);
 tcg_gen_add_reg(ofs, ofs, base);
 } else if (disp || modify) {
-ofs = get_temp(ctx);
+ofs = tcg_temp_new();
 tcg_gen_addi_reg(ofs, base, disp);
 } else {
 ofs = base;
@@ -1538,7 +1530,7 @@ static bool do_load(DisasContext *ctx, unsigned rt, 
unsigned rb,
 dest = dest_gpr(ctx, rt);
 } else {
 /* Make sure if RT == RB, we see the result of the load.  */
-dest = get_temp(ctx);
+dest = tcg_temp_new();
 }
 do_load_reg(ctx, dest, rb, rx, scale, disp, sp, modify, mop);
 save_gpr(ctx, rt, dest);
@@ -1854,7 +1846,7 @@ static bool do_ibranch(DisasContext *ctx, TCGv_reg dest,
 if (link != 0) {
 copy_iaoq_entry(cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
 }
-next = get_temp(ctx);
+next = tcg_temp_new();
 tcg_gen_mov_reg(next, dest);
 if (is_n) {
 if (use_nullify_skip(ctx)) {
@@ -1896,7 +1888,7 @@ static bool do_ibranch(DisasContext *ctx, TCGv_reg dest,
 a1 = ctx->null_cond.a1;
 
 tmp = tcg_temp_new();
-next = get_temp(ctx);
+next = tcg_temp_new();
 
 copy_iaoq_entry(tmp, ctx->iaoq_n, ctx->iaoq_n_var);
 tcg_gen_movcond_reg(c, next, a0, a1, tmp, dest);
@@ -1938,11 +1930,11 @@ static TCGv_reg do_ibranch_priv(DisasContext *ctx, 
TCGv_reg offset)
 return offset;
 case 3:
 /* Privilege 3 is 

[PATCH v3 08/88] tcg: Improve expansion of deposit into a constant

2023-11-01 Thread Richard Henderson
Generalize tcg_gen_deposit_z_* from 0 to any constant.
Use this to automatically simplify tcg_gen_deposit_*.

Signed-off-by: Richard Henderson 
---
 tcg/tcg-op.c | 295 ++-
 1 file changed, 174 insertions(+), 121 deletions(-)

diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index e305260099..e6bf942106 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -603,6 +603,70 @@ void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, 
int32_t arg2)
 }
 }
 
+static void tcg_gen_deposit_i_i32(TCGv_i32 ret, uint32_t i, TCGv_i32 arg,
+  unsigned int ofs, unsigned int len)
+{
+i = deposit32(i, ofs, len, 0);
+
+if (ofs + len == 32) {
+tcg_gen_shli_i32(ret, arg, ofs);
+goto finish;
+}
+if (ofs == 0) {
+tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
+goto finish;
+}
+if (TCG_TARGET_HAS_deposit_i32
+&& TCG_TARGET_deposit_i32_valid(ofs, len)) {
+tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret,
+  tcg_constant_i32(i), arg, ofs, len);
+return;
+}
+
+/*
+ * To help two-operand hosts we prefer to zero-extend first,
+ * which allows ARG to stay live.
+ */
+switch (len) {
+case 16:
+if (TCG_TARGET_HAS_ext16u_i32) {
+tcg_gen_ext16u_i32(ret, arg);
+tcg_gen_shli_i32(ret, ret, ofs);
+goto finish;
+}
+break;
+case 8:
+if (TCG_TARGET_HAS_ext8u_i32) {
+tcg_gen_ext8u_i32(ret, arg);
+tcg_gen_shli_i32(ret, ret, ofs);
+goto finish;
+}
+break;
+}
+/* Otherwise prefer zero-extension over AND for code size.  */
+switch (ofs + len) {
+case 16:
+if (TCG_TARGET_HAS_ext16u_i32) {
+tcg_gen_shli_i32(ret, arg, ofs);
+tcg_gen_ext16u_i32(ret, ret);
+goto finish;
+}
+break;
+case 8:
+if (TCG_TARGET_HAS_ext8u_i32) {
+tcg_gen_shli_i32(ret, arg, ofs);
+tcg_gen_ext8u_i32(ret, ret);
+goto finish;
+}
+break;
+}
+tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
+tcg_gen_shli_i32(ret, ret, ofs);
+
+ finish:
+tcg_gen_ori_i32(ret, ret, i);
+}
+
 void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
  unsigned int ofs, unsigned int len)
 {
@@ -619,6 +683,14 @@ void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, 
TCGv_i32 arg2,
 tcg_gen_mov_i32(ret, arg2);
 return;
 }
+
+/* Deposit of a value into a constant. */
+ts = tcgv_i32_temp(arg1);
+if (ts->kind == TEMP_CONST) {
+tcg_gen_deposit_i_i32(ret, ts->val, arg2, ofs, len);
+return;
+}
+
 if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) {
 tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
 return;
@@ -673,53 +745,7 @@ void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg,
 tcg_debug_assert(len <= 32);
 tcg_debug_assert(ofs + len <= 32);
 
-if (ofs + len == 32) {
-tcg_gen_shli_i32(ret, arg, ofs);
-} else if (ofs == 0) {
-tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
-} else if (TCG_TARGET_HAS_deposit_i32
-   && TCG_TARGET_deposit_i32_valid(ofs, len)) {
-TCGv_i32 zero = tcg_constant_i32(0);
-tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, zero, arg, ofs, len);
-} else {
-/* To help two-operand hosts we prefer to zero-extend first,
-   which allows ARG to stay live.  */
-switch (len) {
-case 16:
-if (TCG_TARGET_HAS_ext16u_i32) {
-tcg_gen_ext16u_i32(ret, arg);
-tcg_gen_shli_i32(ret, ret, ofs);
-return;
-}
-break;
-case 8:
-if (TCG_TARGET_HAS_ext8u_i32) {
-tcg_gen_ext8u_i32(ret, arg);
-tcg_gen_shli_i32(ret, ret, ofs);
-return;
-}
-break;
-}
-/* Otherwise prefer zero-extension over AND for code size.  */
-switch (ofs + len) {
-case 16:
-if (TCG_TARGET_HAS_ext16u_i32) {
-tcg_gen_shli_i32(ret, arg, ofs);
-tcg_gen_ext16u_i32(ret, ret);
-return;
-}
-break;
-case 8:
-if (TCG_TARGET_HAS_ext8u_i32) {
-tcg_gen_shli_i32(ret, arg, ofs);
-tcg_gen_ext8u_i32(ret, ret);
-return;
-}
-break;
-}
-tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
-tcg_gen_shli_i32(ret, ret, ofs);
-}
+tcg_gen_deposit_i_i32(ret, 0, arg, ofs, len);
 }
 
 void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg,
@@ -2238,6 +2264,98 @@ void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, 
int64_t arg2)
 }
 }
 
+static void 

[PATCH v3 17/88] target/hppa: Fix bb_sar for hppa64

2023-11-01 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index b0cd12a2d0..ffa367b91f 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3073,14 +3073,21 @@ static bool trans_bb_sar(DisasContext *ctx, arg_bb_sar 
*a)
 {
 TCGv_reg tmp, tcg_r;
 DisasCond cond;
+bool d = false;
 
 nullify_over(ctx);
 
 tmp = tcg_temp_new();
 tcg_r = load_gpr(ctx, a->r);
-tcg_gen_shl_reg(tmp, tcg_r, cpu_sar);
+if (cond_need_ext(ctx, d)) {
+/* Force shift into [32,63] */
+tcg_gen_ori_reg(tmp, cpu_sar, 32);
+tcg_gen_shl_reg(tmp, tcg_r, tmp);
+} else {
+tcg_gen_shl_reg(tmp, tcg_r, cpu_sar);
+}
 
-cond = cond_make_0(a->c ? TCG_COND_GE : TCG_COND_LT, tmp);
+cond = cond_make_0_tmp(a->c ? TCG_COND_GE : TCG_COND_LT, tmp);
 return do_cbranch(ctx, a->disp, a->n, );
 }
 
@@ -3088,12 +3095,15 @@ static bool trans_bb_imm(DisasContext *ctx, arg_bb_imm 
*a)
 {
 TCGv_reg tmp, tcg_r;
 DisasCond cond;
+bool d = false;
+int p;
 
 nullify_over(ctx);
 
 tmp = tcg_temp_new();
 tcg_r = load_gpr(ctx, a->r);
-tcg_gen_shli_reg(tmp, tcg_r, a->p);
+p = a->p | (cond_need_ext(ctx, d) ? 32 : 0);
+tcg_gen_shli_reg(tmp, tcg_r, p);
 
 cond = cond_make_0(a->c ? TCG_COND_GE : TCG_COND_LT, tmp);
 return do_cbranch(ctx, a->disp, a->n, );
-- 
2.34.1




[PATCH v3 36/88] target/hppa: Pass d to do_unit_cond

2023-11-01 Thread Richard Henderson
Hoist the resolution of d up one level above do_unit_cond.
All computations are logical, and are simplified by using a mask of the
correct width, after which the result may be compared with zero.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index eb4605a9c7..41f4e06841 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1069,11 +1069,12 @@ static DisasCond do_sed_cond(DisasContext *ctx, 
unsigned orig, bool d,
 
 /* Similar, but for unit conditions.  */
 
-static DisasCond do_unit_cond(unsigned cf, TCGv_reg res,
+static DisasCond do_unit_cond(unsigned cf, bool d, TCGv_reg res,
   TCGv_reg in1, TCGv_reg in2)
 {
 DisasCond cond;
 TCGv_reg tmp, cb = NULL;
+target_ureg d_repl = d ? 0x00010001ull : 1;
 
 if (cf & 8) {
 /* Since we want to test lots of carry-out bits all at once, do not
@@ -1100,32 +1101,32 @@ static DisasCond do_unit_cond(unsigned cf, TCGv_reg res,
  * https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
  */
 tmp = tcg_temp_new();
-tcg_gen_subi_reg(tmp, res, 0x01010101u);
+tcg_gen_subi_reg(tmp, res, d_repl * 0x01010101u);
 tcg_gen_andc_reg(tmp, tmp, res);
-tcg_gen_andi_reg(tmp, tmp, 0x80808080u);
+tcg_gen_andi_reg(tmp, tmp, d_repl * 0x80808080u);
 cond = cond_make_0(TCG_COND_NE, tmp);
 break;
 
 case 3: /* SHZ / NHZ */
 tmp = tcg_temp_new();
-tcg_gen_subi_reg(tmp, res, 0x00010001u);
+tcg_gen_subi_reg(tmp, res, d_repl * 0x00010001u);
 tcg_gen_andc_reg(tmp, tmp, res);
-tcg_gen_andi_reg(tmp, tmp, 0x80008000u);
+tcg_gen_andi_reg(tmp, tmp, d_repl * 0x80008000u);
 cond = cond_make_0(TCG_COND_NE, tmp);
 break;
 
 case 4: /* SDC / NDC */
-tcg_gen_andi_reg(cb, cb, 0xu);
+tcg_gen_andi_reg(cb, cb, d_repl * 0xu);
 cond = cond_make_0(TCG_COND_NE, cb);
 break;
 
 case 6: /* SBC / NBC */
-tcg_gen_andi_reg(cb, cb, 0x80808080u);
+tcg_gen_andi_reg(cb, cb, d_repl * 0x80808080u);
 cond = cond_make_0(TCG_COND_NE, cb);
 break;
 
 case 7: /* SHC / NHC */
-tcg_gen_andi_reg(cb, cb, 0x80008000u);
+tcg_gen_andi_reg(cb, cb, d_repl * 0x80008000u);
 cond = cond_make_0(TCG_COND_NE, cb);
 break;
 
@@ -1441,6 +1442,7 @@ static void do_unit(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 {
 TCGv_reg dest;
 DisasCond cond;
+bool d = false;
 
 if (cf == 0) {
 dest = dest_gpr(ctx, rt);
@@ -1451,7 +1453,7 @@ static void do_unit(DisasContext *ctx, unsigned rt, 
TCGv_reg in1,
 dest = tcg_temp_new();
 fn(dest, in1, in2);
 
-cond = do_unit_cond(cf, dest, in1, in2);
+cond = do_unit_cond(cf, d, dest, in1, in2);
 
 if (is_tc) {
 TCGv_reg tmp = tcg_temp_new();
-- 
2.34.1




[PATCH v3 23/88] target/hppa: Update cpu_hppa_get/put_psw for hppa64

2023-11-01 Thread Richard Henderson
With 64-bit registers, there are 16 carry bits in the PSW.
Clear reserved bits based on cpu revision.

Signed-off-by: Richard Henderson 
---
 target/hppa/helper.c | 63 
 1 file changed, 52 insertions(+), 11 deletions(-)

diff --git a/target/hppa/helper.c b/target/hppa/helper.c
index cba8160b3d..fa17fe6931 100644
--- a/target/hppa/helper.c
+++ b/target/hppa/helper.c
@@ -28,19 +28,35 @@
 target_ureg cpu_hppa_get_psw(CPUHPPAState *env)
 {
 target_ureg psw;
+target_ureg mask1 = (target_ureg)-1 / 0xf;
+target_ureg maskf = (target_ureg)-1 / 0x * 0xf;
 
 /* Fold carry bits down to 8 consecutive bits.  */
-/* ??? Needs tweaking for hppa64.  */
-/* ...b...c...d...e...f...g...h */
-psw = (env->psw_cb >> 4) & 0x0111;
-/* ...b..bc..cd..de..ef..fg..gh */
+/* ^^^b^^^c^^^d^^^e^^^f^^^g^^^h^^^i^^^j^^^k^^^l^^^m^^^n^^^o^^^p */
+/* ^^^b^^^c^^^d^^^e^^^f^^^g^^^h */
+psw = (env->psw_cb >> 4) & mask1;
+/* ...b...c...d...e...f...g...h...i...j...k...l...m...n...o...p */
+/* ...b...c...d...e...f...g...h */
 psw |= psw >> 3;
-/* .bcdefgh */
-psw |= (psw >> 6) & 0x000f000f;
-/* .bcdefgh */
-psw |= (psw >> 12) & 0xf;
-psw |= env->psw_cb_msb << 7;
-psw = (psw & 0xff) << 8;
+/* ...b..bc..cd..de..ef..fg..gh..hi..ij..jk..kl..lm..mn..no..op */
+/* ...b..bc..cd..de..ef..fg..gh */
+psw |= psw >> 6;
+psw &= maskf;
+/* .bcdefghijklmnop */
+/* .bcdefgh */
+psw |= psw >> 12;
+/* .bcd.bcdefghefghijklijklmnop */
+/* .bcd.bcdefgh */
+psw |= env->psw_cb_msb << (TARGET_REGISTER_BITS == 64 ? 39 : 7);
+/* .bcdabcdefghefghijklijklmnop */
+/* .bcdabcdefgh */
+
+/* For hppa64, the two 8-bit fields are discontiguous. */
+if (hppa_is_pa20(env)) {
+psw = (psw & 0xffull) | ((psw & 0xff) << 8);
+} else {
+psw = (psw & 0xff) << 8;
+}
 
 psw |= env->psw_n * PSW_N;
 psw |= (env->psw_v < 0) * PSW_V;
@@ -51,13 +67,38 @@ target_ureg cpu_hppa_get_psw(CPUHPPAState *env)
 
 void cpu_hppa_put_psw(CPUHPPAState *env, target_ureg psw)
 {
+uint64_t reserved;
 target_ureg cb = 0;
 
+/* Do not allow reserved bits to be set. */
+if (hppa_is_pa20(env)) {
+reserved = MAKE_64BIT_MASK(40, 24) | MAKE_64BIT_MASK(28, 4);
+reserved |= PSW_G;  /* PA1.x only */
+reserved |= PSW_E;  /* not implemented */
+} else {
+reserved = MAKE_64BIT_MASK(32, 32) | MAKE_64BIT_MASK(28, 2);
+reserved |= PSW_O | PSW_W;  /* PA2.0 only */
+reserved |= PSW_E | PSW_Y | PSW_Z;  /* not implemented */
+}
+psw &= ~reserved;
+
 env->psw = psw & ~(PSW_N | PSW_V | PSW_CB);
 env->psw_n = (psw / PSW_N) & 1;
 env->psw_v = -((psw / PSW_V) & 1);
-env->psw_cb_msb = (psw >> 15) & 1;
 
+#if TARGET_REGISTER_BITS == 32
+env->psw_cb_msb = (psw >> 15) & 1;
+#else
+env->psw_cb_msb = (psw >> 39) & 1;
+cb |= ((psw >> 38) & 1) << 60;
+cb |= ((psw >> 37) & 1) << 56;
+cb |= ((psw >> 36) & 1) << 52;
+cb |= ((psw >> 35) & 1) << 48;
+cb |= ((psw >> 34) & 1) << 44;
+cb |= ((psw >> 33) & 1) << 40;
+cb |= ((psw >> 32) & 1) << 36;
+cb |= ((psw >> 15) & 1) << 32;
+#endif
 cb |= ((psw >> 14) & 1) << 28;
 cb |= ((psw >> 13) & 1) << 24;
 cb |= ((psw >> 12) & 1) << 20;
-- 
2.34.1




[PATCH v3 28/88] target/hppa: Always use copy_iaoq_entry to set cpu_iaoq_[fb]

2023-11-01 Thread Richard Henderson
This will be how we ensure that the IAOQ is always
valid per PSW.W, therefore all stores to these two
variables must be done with this function.

Use third argument -1 if the destination is always dynamic,
and fourth argument NULL if the destination is always static.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 35 ++-
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index e342cc1d08..348fdb75e5 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -792,8 +792,8 @@ static void gen_goto_tb(DisasContext *ctx, int which,
 {
 if (f != -1 && b != -1 && use_goto_tb(ctx, f)) {
 tcg_gen_goto_tb(which);
-tcg_gen_movi_reg(cpu_iaoq_f, f);
-tcg_gen_movi_reg(cpu_iaoq_b, b);
+copy_iaoq_entry(ctx, cpu_iaoq_f, f, NULL);
+copy_iaoq_entry(ctx, cpu_iaoq_b, b, NULL);
 tcg_gen_exit_tb(ctx->base.tb, which);
 } else {
 copy_iaoq_entry(ctx, cpu_iaoq_f, f, cpu_iaoq_b);
@@ -1867,8 +1867,9 @@ static bool do_ibranch(DisasContext *ctx, TCGv_reg dest,
 tcg_gen_mov_reg(next, dest);
 if (is_n) {
 if (use_nullify_skip(ctx)) {
-tcg_gen_mov_reg(cpu_iaoq_f, next);
-tcg_gen_addi_reg(cpu_iaoq_b, next, 4);
+copy_iaoq_entry(ctx, cpu_iaoq_f, -1, next);
+tcg_gen_addi_reg(next, next, 4);
+copy_iaoq_entry(ctx, cpu_iaoq_b, -1, next);
 nullify_set(ctx, 0);
 ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
 return true;
@@ -1890,8 +1891,10 @@ static bool do_ibranch(DisasContext *ctx, TCGv_reg dest,
 /* We do have to handle the non-local temporary, DEST, before
branching.  Since IOAQ_F is not really live at this point, we
can simply store DEST optimistically.  Similarly with IAOQ_B.  */
-tcg_gen_mov_reg(cpu_iaoq_f, dest);
-tcg_gen_addi_reg(cpu_iaoq_b, dest, 4);
+copy_iaoq_entry(ctx, cpu_iaoq_f, -1, dest);
+next = tcg_temp_new();
+tcg_gen_addi_reg(next, dest, 4);
+copy_iaoq_entry(ctx, cpu_iaoq_b, -1, next);
 
 nullify_over(ctx);
 if (link != 0) {
@@ -1970,6 +1973,8 @@ static TCGv_reg do_ibranch_priv(DisasContext *ctx, 
TCGv_reg offset)
aforementioned BE.  */
 static void do_page_zero(DisasContext *ctx)
 {
+TCGv_reg tmp;
+
 /* If by some means we get here with PSW[N]=1, that implies that
the B,GATE instruction would be skipped, and we'd fault on the
next insn within the privileged page.  */
@@ -2006,8 +2011,11 @@ static void do_page_zero(DisasContext *ctx)
 
 case 0xe0: /* SET_THREAD_POINTER */
 tcg_gen_st_reg(cpu_gr[26], tcg_env, offsetof(CPUHPPAState, cr[27]));
-tcg_gen_ori_reg(cpu_iaoq_f, cpu_gr[31], 3);
-tcg_gen_addi_reg(cpu_iaoq_b, cpu_iaoq_f, 4);
+tmp = tcg_temp_new();
+tcg_gen_ori_reg(tmp, cpu_gr[31], 3);
+copy_iaoq_entry(ctx, cpu_iaoq_f, -1, tmp);
+tcg_gen_addi_reg(tmp, tmp, 4);
+copy_iaoq_entry(ctx, cpu_iaoq_b, -1, tmp);
 ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
 break;
 
@@ -3438,8 +3446,9 @@ static bool trans_be(DisasContext *ctx, arg_be *a)
 tcg_gen_mov_i64(cpu_sr[0], cpu_iasq_f);
 }
 if (a->n && use_nullify_skip(ctx)) {
-tcg_gen_mov_reg(cpu_iaoq_f, tmp);
-tcg_gen_addi_reg(cpu_iaoq_b, cpu_iaoq_f, 4);
+copy_iaoq_entry(ctx, cpu_iaoq_f, -1, tmp);
+tcg_gen_addi_reg(tmp, tmp, 4);
+copy_iaoq_entry(ctx, cpu_iaoq_b, -1, tmp);
 tcg_gen_mov_i64(cpu_iasq_f, new_spc);
 tcg_gen_mov_i64(cpu_iasq_b, cpu_iasq_f);
 } else {
@@ -3447,7 +3456,7 @@ static bool trans_be(DisasContext *ctx, arg_be *a)
 if (ctx->iaoq_b == -1) {
 tcg_gen_mov_i64(cpu_iasq_f, cpu_iasq_b);
 }
-tcg_gen_mov_reg(cpu_iaoq_b, tmp);
+copy_iaoq_entry(ctx, cpu_iaoq_b, -1, tmp);
 tcg_gen_mov_i64(cpu_iasq_b, new_spc);
 nullify_set(ctx, a->n);
 }
@@ -4218,7 +4227,7 @@ static void hppa_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs)
 case DISAS_IAQ_N_STALE:
 case DISAS_IAQ_N_STALE_EXIT:
 if (ctx->iaoq_f == -1) {
-tcg_gen_mov_reg(cpu_iaoq_f, cpu_iaoq_b);
+copy_iaoq_entry(ctx, cpu_iaoq_f, -1, cpu_iaoq_b);
 copy_iaoq_entry(ctx, cpu_iaoq_b, ctx->iaoq_n, ctx->iaoq_n_var);
 #ifndef CONFIG_USER_ONLY
 tcg_gen_mov_i64(cpu_iasq_f, cpu_iasq_b);
@@ -4228,7 +4237,7 @@ static void hppa_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs)
 ? DISAS_EXIT
 : DISAS_IAQ_N_UPDATED);
 } else if (ctx->iaoq_b == -1) {
-tcg_gen_mov_reg(cpu_iaoq_b, ctx->iaoq_n_var);
+copy_iaoq_entry(ctx, cpu_iaoq_b, -1, ctx->iaoq_n_var);
 }
 break;
 
-- 
2.34.1




[PATCH v3 31/88] target/hppa: sar register allows only 5 bits on 32-bit CPU

2023-11-01 Thread Richard Henderson
From: Helge Deller 

The sar shift amount register is limited to 5 bits when running
a 32-bit CPU. Strip off the remaining bits.

The interesting part is, that this register allows to detect at runtime
if a physical CPU is capable to execute PA2.0 (64-bit) instructions.

Signed-off-by: Helge Deller 
---
 target/hppa/translate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index cf05d8b6e4..1694b988ae 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2176,7 +2176,7 @@ static bool trans_mtctl(DisasContext *ctx, arg_mtctl *a)
 if (ctl == CR_SAR) {
 reg = load_gpr(ctx, a->r);
 tmp = tcg_temp_new();
-tcg_gen_andi_reg(tmp, reg, TARGET_REGISTER_BITS - 1);
+tcg_gen_andi_reg(tmp, reg, ctx->is_pa20 ? 63 : 31);
 save_or_nullify(ctx, cpu_sar, tmp);
 
 cond_free(>null_cond);
@@ -2237,7 +2237,7 @@ static bool trans_mtsarcm(DisasContext *ctx, arg_mtsarcm 
*a)
 TCGv_reg tmp = tcg_temp_new();
 
 tcg_gen_not_reg(tmp, load_gpr(ctx, a->r));
-tcg_gen_andi_reg(tmp, tmp, TARGET_REGISTER_BITS - 1);
+tcg_gen_andi_reg(tmp, tmp, ctx->is_pa20 ? 63 : 31);
 save_or_nullify(ctx, cpu_sar, tmp);
 
 cond_free(>null_cond);
-- 
2.34.1




  1   2   3   >