Re: [PATCH 11/11] hw/m68k/next-cube: Add missing header comment to next-cube.h

2021-01-15 Thread Thomas Huth
Am Fri, 15 Jan 2021 20:12:06 +
schrieb Peter Maydell :

> The next-cube.h file is missing the usual copyright-and-license
> header; add it (same as the next-cube.c one).
> 
> Signed-off-by: Peter Maydell 
> ---
>  include/hw/m68k/next-cube.h | 10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/include/hw/m68k/next-cube.h b/include/hw/m68k/next-cube.h
> index d38c52d540d..43577282d15 100644
> --- a/include/hw/m68k/next-cube.h
> +++ b/include/hw/m68k/next-cube.h
> @@ -1,3 +1,13 @@
> +/*
> + * NeXT Cube
> + *
> + * Copyright (c) 2011 Bryce Lanham
> + *
> + * This code is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published
> + * by the Free Software Foundation; either version 2 of the License,
> + * or (at your option) any later version.
> + */
>  
>  #ifndef NEXT_CUBE_H
>  #define NEXT_CUBE_H

The file is based on Bryce's original version, indeed:

 https://github.com/blanham/qemu-NeXT/blob/next-cube/hw/next-cube.h

So I think that header comment is appropriate.

Reviewed-by: Thomas Huth 



Re: [PATCH 03/11] hw/m68k/next-cube: Move mmio_ops into NeXTPC device

2021-01-15 Thread Thomas Huth
Am Fri, 15 Jan 2021 20:11:58 +
schrieb Peter Maydell :

> Move the registers handled by the mmio_ops struct into the NeXTPC
> device.  This allows us to also move the scr1 and scr2 data fields.
> 
> Signed-off-by: Peter Maydell 
> ---
>  hw/m68k/next-cube.c | 80
> + 1 file changed, 44
> insertions(+), 36 deletions(-)

Reviewed-by: Thomas Huth 



Re: [PATCH 01/11] hw/m68k/next-cube: Make next_irq() function static

2021-01-15 Thread Thomas Huth
Am Fri, 15 Jan 2021 20:11:56 +
schrieb Peter Maydell :

> The next_irq() function is global, but isn't actually used anywhere
> outside next-cube.c. Make it static.
> 
> Signed-off-by: Peter Maydell 
> ---
>  include/hw/m68k/next-cube.h | 2 --
>  hw/m68k/next-cube.c | 2 +-
>  2 files changed, 1 insertion(+), 3 deletions(-)

Reviewed-by: Thomas Huth 



[PATCH v2 2/2] target/riscv: Remove built-in GDB XML files for CSRs

2021-01-15 Thread Bin Meng
From: Bin Meng 

Now that we have switched to generate the RISC-V CSR XML dynamically,
remove the built-in hardcoded XML files.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

(no changes since v1)

 .../targets/riscv32-linux-user.mak|   2 +-
 default-configs/targets/riscv32-softmmu.mak   |   2 +-
 .../targets/riscv64-linux-user.mak|   2 +-
 default-configs/targets/riscv64-softmmu.mak   |   2 +-
 gdb-xml/riscv-32bit-csr.xml   | 250 --
 gdb-xml/riscv-64bit-csr.xml   | 250 --
 6 files changed, 4 insertions(+), 504 deletions(-)
 delete mode 100644 gdb-xml/riscv-32bit-csr.xml
 delete mode 100644 gdb-xml/riscv-64bit-csr.xml

diff --git a/default-configs/targets/riscv32-linux-user.mak 
b/default-configs/targets/riscv32-linux-user.mak
index dfb259e8aa..07e6ca13f3 100644
--- a/default-configs/targets/riscv32-linux-user.mak
+++ b/default-configs/targets/riscv32-linux-user.mak
@@ -1,4 +1,4 @@
 TARGET_ARCH=riscv32
 TARGET_BASE_ARCH=riscv
 TARGET_ABI_DIR=riscv
-TARGET_XML_FILES= gdb-xml/riscv-32bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-32bit-csr.xml 
gdb-xml/riscv-32bit-virtual.xml
+TARGET_XML_FILES= gdb-xml/riscv-32bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-32bit-virtual.xml
diff --git a/default-configs/targets/riscv32-softmmu.mak 
b/default-configs/targets/riscv32-softmmu.mak
index 9446d96d13..d8b71cddcd 100644
--- a/default-configs/targets/riscv32-softmmu.mak
+++ b/default-configs/targets/riscv32-softmmu.mak
@@ -1,5 +1,5 @@
 TARGET_ARCH=riscv32
 TARGET_BASE_ARCH=riscv
 TARGET_SUPPORTS_MTTCG=y
-TARGET_XML_FILES= gdb-xml/riscv-32bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-32bit-csr.xml 
gdb-xml/riscv-32bit-virtual.xml
+TARGET_XML_FILES= gdb-xml/riscv-32bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-32bit-virtual.xml
 TARGET_NEED_FDT=y
diff --git a/default-configs/targets/riscv64-linux-user.mak 
b/default-configs/targets/riscv64-linux-user.mak
index b13895f3b0..191c2c483f 100644
--- a/default-configs/targets/riscv64-linux-user.mak
+++ b/default-configs/targets/riscv64-linux-user.mak
@@ -1,4 +1,4 @@
 TARGET_ARCH=riscv64
 TARGET_BASE_ARCH=riscv
 TARGET_ABI_DIR=riscv
-TARGET_XML_FILES= gdb-xml/riscv-64bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-64bit-csr.xml 
gdb-xml/riscv-64bit-virtual.xml
+TARGET_XML_FILES= gdb-xml/riscv-64bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-64bit-virtual.xml
diff --git a/default-configs/targets/riscv64-softmmu.mak 
b/default-configs/targets/riscv64-softmmu.mak
index d809bd666a..7c0e7eeb42 100644
--- a/default-configs/targets/riscv64-softmmu.mak
+++ b/default-configs/targets/riscv64-softmmu.mak
@@ -1,5 +1,5 @@
 TARGET_ARCH=riscv64
 TARGET_BASE_ARCH=riscv
 TARGET_SUPPORTS_MTTCG=y
-TARGET_XML_FILES= gdb-xml/riscv-64bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-64bit-csr.xml 
gdb-xml/riscv-64bit-virtual.xml
+TARGET_XML_FILES= gdb-xml/riscv-64bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-64bit-virtual.xml
 TARGET_NEED_FDT=y
diff --git a/gdb-xml/riscv-32bit-csr.xml b/gdb-xml/riscv-32bit-csr.xml
deleted file mode 100644
index da1bf19e2f..00
--- a/gdb-xml/riscv-32bit-csr.xml
+++ /dev/null
@@ -1,250 +0,0 @@
-
-
-
-
-
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-
diff --git a/gdb-xml/riscv-64bit-csr.xml b/gdb-xml/riscv-64bit-csr.xml
deleted file mode 100644
index 6aa4bed9f5..00
--- a/gdb-xml/riscv-64bit-csr.xml
+++ /dev/null
@@ -1,250 +0,0 @@
-
-
-
-
-
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  

[PATCH v2 1/2] target/riscv: Generate the GDB XML file for CSR registers dynamically

2021-01-15 Thread Bin Meng
From: Bin Meng 

At present QEMU RISC-V uses a hardcoded XML to report the feature
"org.gnu.gdb.riscv.csr" [1]. There are two major issues with the
approach being used currently:

- The XML does not specify the "regnum" field of a CSR entry, hence
  consecutive numbers are used by the remote GDB client to access
  CSRs. In QEMU we have to maintain a map table to convert the GDB
  number to the hardware number which is error prone.
- The XML contains some CSRs that QEMU does not implement at all,
  which causes an "E14" response sent to remote GDB client.

Change to generate the CSR register list dynamically, based on the
availability presented in the CSR function table. This new approach
will reflect a correct list of CSRs that QEMU actually implements.

[1] 
https://sourceware.org/gdb/current/onlinedocs/gdb/RISC_002dV-Features.html#RISC_002dV-Features

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v2:
- rebase on top of riscv-to-apply.next branch
- drop the first 2 patches that are already applied on riscv-to-apply.next

 target/riscv/cpu.h |   2 +
 target/riscv/cpu.c |  12 ++
 target/riscv/gdbstub.c | 308 ++---
 3 files changed, 58 insertions(+), 264 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 2718617ef4..02758ae0eb 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -272,6 +272,8 @@ struct RISCVCPU {
 CPUNegativeOffsetState neg;
 CPURISCVState env;
 
+char *dyn_csr_xml;
+
 /* Configuration Settings */
 struct {
 bool ext_i;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6aafe4e62c..27788021eb 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -569,6 +569,17 @@ static gchar *riscv_gdb_arch_name(CPUState *cs)
 }
 }
 
+static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+
+if (strcmp(xmlname, "riscv-csr.xml") == 0) {
+return cpu->dyn_csr_xml;
+}
+
+return NULL;
+}
+
 static void riscv_cpu_class_init(ObjectClass *c, void *data)
 {
 RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
@@ -605,6 +616,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
 cc->vmsd = _riscv_cpu;
 #endif
 cc->gdb_arch_name = riscv_gdb_arch_name;
+cc->gdb_get_dynamic_xml = riscv_gdb_get_dynamic_xml;
 #ifdef CONFIG_TCG
 cc->tcg_initialize = riscv_translate_init;
 cc->tlb_fill = riscv_cpu_tlb_fill;
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index eba12a86f2..5f96b7ea2a 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -20,256 +20,6 @@
 #include "exec/gdbstub.h"
 #include "cpu.h"
 
-/*
- * The GDB CSR xml files list them in documentation order, not numerical order,
- * and are missing entries for unnamed CSRs.  So we need to map the gdb numbers
- * to the hardware numbers.
- */
-
-static int csr_register_map[] = {
-CSR_USTATUS,
-CSR_UIE,
-CSR_UTVEC,
-CSR_USCRATCH,
-CSR_UEPC,
-CSR_UCAUSE,
-CSR_UTVAL,
-CSR_UIP,
-CSR_FFLAGS,
-CSR_FRM,
-CSR_FCSR,
-CSR_CYCLE,
-CSR_TIME,
-CSR_INSTRET,
-CSR_HPMCOUNTER3,
-CSR_HPMCOUNTER4,
-CSR_HPMCOUNTER5,
-CSR_HPMCOUNTER6,
-CSR_HPMCOUNTER7,
-CSR_HPMCOUNTER8,
-CSR_HPMCOUNTER9,
-CSR_HPMCOUNTER10,
-CSR_HPMCOUNTER11,
-CSR_HPMCOUNTER12,
-CSR_HPMCOUNTER13,
-CSR_HPMCOUNTER14,
-CSR_HPMCOUNTER15,
-CSR_HPMCOUNTER16,
-CSR_HPMCOUNTER17,
-CSR_HPMCOUNTER18,
-CSR_HPMCOUNTER19,
-CSR_HPMCOUNTER20,
-CSR_HPMCOUNTER21,
-CSR_HPMCOUNTER22,
-CSR_HPMCOUNTER23,
-CSR_HPMCOUNTER24,
-CSR_HPMCOUNTER25,
-CSR_HPMCOUNTER26,
-CSR_HPMCOUNTER27,
-CSR_HPMCOUNTER28,
-CSR_HPMCOUNTER29,
-CSR_HPMCOUNTER30,
-CSR_HPMCOUNTER31,
-CSR_CYCLEH,
-CSR_TIMEH,
-CSR_INSTRETH,
-CSR_HPMCOUNTER3H,
-CSR_HPMCOUNTER4H,
-CSR_HPMCOUNTER5H,
-CSR_HPMCOUNTER6H,
-CSR_HPMCOUNTER7H,
-CSR_HPMCOUNTER8H,
-CSR_HPMCOUNTER9H,
-CSR_HPMCOUNTER10H,
-CSR_HPMCOUNTER11H,
-CSR_HPMCOUNTER12H,
-CSR_HPMCOUNTER13H,
-CSR_HPMCOUNTER14H,
-CSR_HPMCOUNTER15H,
-CSR_HPMCOUNTER16H,
-CSR_HPMCOUNTER17H,
-CSR_HPMCOUNTER18H,
-CSR_HPMCOUNTER19H,
-CSR_HPMCOUNTER20H,
-CSR_HPMCOUNTER21H,
-CSR_HPMCOUNTER22H,
-CSR_HPMCOUNTER23H,
-CSR_HPMCOUNTER24H,
-CSR_HPMCOUNTER25H,
-CSR_HPMCOUNTER26H,
-CSR_HPMCOUNTER27H,
-CSR_HPMCOUNTER28H,
-CSR_HPMCOUNTER29H,
-CSR_HPMCOUNTER30H,
-CSR_HPMCOUNTER31H,
-CSR_SSTATUS,
-CSR_SEDELEG,
-CSR_SIDELEG,
-CSR_SIE,
-CSR_STVEC,
-CSR_SCOUNTEREN,
-CSR_SSCRATCH,
-CSR_SEPC,
-CSR_SCAUSE,
-CSR_STVAL,
-CSR_SIP,
-CSR_SATP,
-CSR_MVENDORID,
-CSR_MARCHID,
-CSR_MIMPID,
-CSR_MHARTID,
-CSR_MSTATUS,
-CSR_MISA,
-CSR_MEDELEG,
-CSR_MIDELEG,
-CSR_MIE,
-CSR_MTVEC,
-CSR_MCOUNTEREN,
-CSR_MSCRATCH,
-CSR_MEPC,
-  

[PATCH v2 0/2] target/riscv: Generate the GDB XML file for CSR registers dynamically

2021-01-15 Thread Bin Meng
From: Bin Meng 


At present QEMU RISC-V uses a hardcoded XML to report the feature
"org.gnu.gdb.riscv.csr" [1]. There are two major issues with the
approach being used currently:

- The XML does not specify the "regnum" field of a CSR entry, hence
  consecutive numbers are used by the remote GDB client to access
  CSRs. In QEMU we have to maintain a map table to convert the GDB
  number to the hardware number which is error prone.
- The XML contains some CSRs that QEMU does not implement at all,
  which causes an "E14" response sent to remote GDB client.

Change to generate the CSR register list dynamically, based on the
availability presented in the CSR function table. This new approach
will reflect a correct list of CSRs that QEMU actually implements.

[1] 
https://sourceware.org/gdb/current/onlinedocs/gdb/RISC_002dV-Features.html#RISC_002dV-Features

Changes in v2:
- rebase on top of riscv-to-apply.next branch
- drop the first 2 patches that are already applied on riscv-to-apply.next

Bin Meng (2):
  target/riscv: Generate the GDB XML file for CSR registers dynamically
  target/riscv: Remove built-in GDB XML files for CSRs

 .../targets/riscv32-linux-user.mak|   2 +-
 default-configs/targets/riscv32-softmmu.mak   |   2 +-
 .../targets/riscv64-linux-user.mak|   2 +-
 default-configs/targets/riscv64-softmmu.mak   |   2 +-
 target/riscv/cpu.h|   2 +
 target/riscv/cpu.c|  12 +
 target/riscv/gdbstub.c| 308 +++---
 gdb-xml/riscv-32bit-csr.xml   | 250 --
 gdb-xml/riscv-64bit-csr.xml   | 250 --
 9 files changed, 62 insertions(+), 768 deletions(-)
 delete mode 100644 gdb-xml/riscv-32bit-csr.xml
 delete mode 100644 gdb-xml/riscv-64bit-csr.xml

-- 
2.25.1




[Bug 1699867] Re: x86_64 qemu crashes at far call into long-mode

2021-01-15 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1699867

Title:
  x86_64 qemu crashes at far call into long-mode

Status in QEMU:
  Expired

Bug description:
  I am experimenting with this OS https://github.com/phil-opp/blog_os
  and spotted a weird behavior with qemu.

  I am looking at code that does transition from 32bit mode to 64bit
  mode. Right now it does 'jmp $SELECTOR,64bitfunction'.
  https://github.com/phil-
  
opp/blog_os/blob/557c6a58ea11e31685b9d014d307002d64df5c22/src/arch/x86_64/boot.asm#L32

  This code works fine with qemu/kvm/vmware.

  To transition from 32 to 64 bit code it is possible to use 'call'
  operation. So I am trying to replace that code with 'call
  $SELECTOR,64bitfunction'. It works fine with kvm and wmware. But it
  fails with Qemu emulation. See the interrup debug log attached. qemu
  crashes at 10302c (far call mnemonic).

  
103016:   e8 18 00 00 00  callq  103033 
10301b:   e8 5c 00 00 00  callq  10307c 
103020:   e8 ec 00 00 00  callq  103111 
103025:   0f 01 15 28 00 10 00lgdt   0x100028(%rip)# 203054 

10302c:   9a  (bad)  
10302d:   40 31 10rex xor %edx,(%rax)
103030:   00 08   add%cl,(%rax)

  
  As the code works at hardware I expect it to work with qemu. Thus current 
qemu behavior looks like a bug.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1699867/+subscriptions



[Bug 1740887] Re: qemu-system-arm & qemu-system-aarch64 for windows crash at start

2021-01-15 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1740887

Title:
  qemu-system-arm & qemu-system-aarch64 for windows crash at start

Status in QEMU:
  Expired

Bug description:
  In Windows 7 64 bit (both 32 & 64 bit QEMU emulator version 2.11.0
  (v2.11.0-11693-g21057c841e-dirty)).

  With arguments:

  qemu-system-arm.exe -M raspi2

  It crashes and reports:

  
ERROR:/home/stefan/src/qemu/repo.or.cz/qemu/ar7/qom/object.c:176:type_get_parent:
  assertion failed: (type->parent_type != NULL)

  Same goes for qemu-system-aarch64.exe or with -M raspi argument.

  Have a nice day,
  f.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1740887/+subscriptions



[Bug 1492649] Re: QEMU soundhw HDA huge microphone lag

2021-01-15 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1492649

Title:
  QEMU soundhw HDA huge microphone lag

Status in QEMU:
  Expired

Bug description:
  I use a Windows 7 x86_64 guest with VGA passthrough and -soundhw hda.
  The audio plays fine, but the microphone input is delayed by more than
  20 seconds.

  -soundhw ac97 does not have this delay but it has choppy sound
  playback and input.

  System:
  Arch linux
  Kernel: 4.1.6-1-ARCH
  Audio hardware: 00:1b.0 Audio device: Intel Corporation 82801JI (ICH10 
Family) HD Audio Controller
  Audio system: Pulseaudio 6.0

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1492649/+subscriptions



[Bug 1743214] Re: OS/2 Warp 3 support broken in 2.11

2021-01-15 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1743214

Title:
  OS/2 Warp 3 support broken in 2.11

Status in QEMU:
  Expired

Bug description:
  Hello, I used to run OS/2 Warp 3 on QEMU with the following command line: 
qemu-system-i386 -vga cirrus -soundhw sb16 -hda os2warp3v2.img -boot c. It runs 
OK on QEMU 2.10, but immediately gives TRAP 0006 (invalid opcode?) on QEMU 2.11 
(see screenshot).
  If it is important I have Fixpack 40 and GRADD installed in OS/2.
  Here is the image:
  https://drive.google.com/open?id=15umPecy7JlPLKUP6520MB_87CfrCDWO5

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1743214/+subscriptions



[Bug 1737194] Re: Windows NT 4.0 fails to boot from qcow2 installation

2021-01-15 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1737194

Title:
  Windows NT 4.0 fails to boot from qcow2 installation

Status in QEMU:
  Expired

Bug description:
  Windows NT 4.0 will not boot from an installation more than once if
  installed in a qcow2 image file. A quick fix to this problem is to use
  the qcow format instead.

  Steps to reproduce this issue:

  Create the image file:
  qemu-img create -f qcow2 winnt4.qcow2 1G

  Boot from a Windows NT 4.0 Workstation CD:
  qemu-system-i386 -hda winnt4.qcow2 -cdrom /dev/cdrom -boot d -m 128 -cpu 
pentium -vga cirrus

  During the installation process you have the choise between FAT and
  NTFS. You can pick anyone.

  After finishing the installation the guest will reboot to install
  additional items. Once this is done the guest will be bootable. Eject
  any CD media from QEMU and reboot. You will then see Windows NT 4.0
  booting up to the desktop. Go to "Start->Shut down" to shut down. Then
  when Windows is ready quit QEMU.

  Now try to boot using this command:
  qemu-system-i386 -hda winnt4.qcow2 -boot c -m 128 -cpu pentium -vga cirrus 
   
  The BIOS screen will display an error message:

  For NTFS: 
  Booting from Hard Disk...
  A disk read error occurred.
  Insert a system diskette and restart
  the system.

  For FAT:
  No bootable device.

  Additional information:
  qemu-system-i386 version: 2.10.1
  qemu-img version: 2.10.92 (v2.11.0-rc4-dirty)

  If you don't have a Windows NT 4.0 Workstation installation CD, you may 
download one from here:
  https://winworldpc.com/product/windows-nt-40/40

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1737194/+subscriptions



[Bug 1743337] Re: OS/2 Warp 4 HPFS corruption

2021-01-15 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1743337

Title:
  OS/2 Warp 4 HPFS corruption

Status in QEMU:
  Expired

Bug description:
  How to reproduce:
  Install OS/2 Warp 4 onto HPFS-formatted partition. After reboot there will be 
messages about "missing" files and OS2.INI not found. Chkdsk C: complains about 
FS corruption. Nothing changes even after fixing errors and next reboot. If you 
install OS/2 onto FAT partition instead, everything will be OK. I also tried 
booting images with OS/2 pre-installed through VBOX with same results. Is that 
HPFS driver or QEMU fault?
  There is an image for bug reproducing: https://yadi.sk/d/skMswNoy7txIg

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1743337/+subscriptions



[Bug 1696746] Re: netdev user, restrict=on prevents forwarded ports from being accessed from other systems

2021-01-15 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1696746

Title:
  netdev user,restrict=on prevents forwarded ports from being accessed
  from other systems

Status in QEMU:
  Expired

Bug description:
  I've got a guest only network and I'm wanting to access SSH on one of the 
guests externally.
  I'm using -netdev user,id=usernet0,hostfwd=tcp::-:22,restrict=yes -device 
virtio-net-pci,netdev=usernet0
  to forward  to 22 in the guest.

  The docs state:
  restrict=on|off

  If this option is enabled, the guest will be isolated, i.e. it
  will not be able to contact the host and no guest IP packets will be
  routed over the host to the outside. This option does not affect any
  explicitly set forwarding rules.

  
  However, with restrict=on, the forwarded port is only accessible from the 
host. Other systems receive no data.

  This was tested with qemu 2.8. Changelog for 2.9 doesn't mention any
  (relevant) user networking changes, so that should also fail.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1696746/+subscriptions



[Bug 1744009] Re: qemu for windows fails to use multicast socket as netdev

2021-01-15 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1744009

Title:
  qemu for windows fails to use multicast socket as netdev

Status in QEMU:
  Expired

Bug description:
  My host OS is Windows 7 x64 SP1. I installed qemu for windows from
  https://qemu.weilnetz.de/w64/.The version is 2.10.1,
  qemu-w64-setup-20171006.exe. I run qemu with the following command:

  qemu-system-x86_64.exe -net nic -net socket,mcast=234.5.5.5:6000
  disk1.qcow2

  It stopped with error:
  bind: Unknown error
  qemu-system-x86_64.exe: -net socket,mcast=234.5.5.5:6000: Device 'socket' 
could not be initialized

  Using the -netdev option has the same problem:
  qemu-system-x86_64.exe -netdev socket,id=hostnet0,mcast=234.5.5.5:6000 
-device e1000,netdev=hostnet0 disk1.qcow2

  I tried many versions from https://qemu.weilnetz.de/w64/, but none of
  them could work.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1744009/+subscriptions



Re: [PATCH 3/4] target/riscv: Generate the GDB XML file for CSR registers dynamically

2021-01-15 Thread Bin Meng
On Sat, Jan 16, 2021 at 6:08 AM Alistair Francis  wrote:
>
> On Fri, Jan 15, 2021 at 1:59 PM Alistair Francis  wrote:
> >
> > On Mon, Jan 11, 2021 at 8:55 PM Bin Meng  wrote:
> > >
> > > From: Bin Meng 
> > >
> > > At present QEMU RISC-V uses a hardcoded XML to report the feature
> > > "org.gnu.gdb.riscv.csr" [1]. There are two major issues with the
> > > approach being used currently:
> > >
> > > - The XML does not specify the "regnum" field of a CSR entry, hence
> > >   consecutive numbers are used by the remote GDB client to access
> > >   CSRs. In QEMU we have to maintain a map table to convert the GDB
> > >   number to the hardware number which is error prone.
> > > - The XML contains some CSRs that QEMU does not implement at all,
> > >   which causes an "E14" response sent to remote GDB client.
> > >
> > > Change to generate the CSR register list dynamically, based on the
> > > availability presented in the CSR function table. This new approach
> > > will reflect a correct list of CSRs that QEMU actually implements.
> > >
> > > [1] 
> > > https://sourceware.org/gdb/current/onlinedocs/gdb/RISC_002dV-Features.html#RISC_002dV-Features
>
> Do you mind rebasing this patch on the current riscv-to-apply.next
> branch: https://github.com/alistair23/qemu/tree/riscv-to-apply.next
>

Yes, for sure.

Regards,
Bin



Re: [PATCH v3 00/21] target-arm: Implement ARMv8.5-MemTag, user mode

2021-01-15 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20210115224645.1196742-1-richard.hender...@linaro.org/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20210115224645.1196742-1-richard.hender...@linaro.org
Subject: [PATCH v3 00/21] target-arm: Implement ARMv8.5-MemTag, user mode

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  patchew/20201104092900.21214-1-green@sifive.com -> 
patchew/20201104092900.21214-1-green@sifive.com
 - [tag update]  
patchew/20210110185109.29841-1-space.monkey.deliv...@gmail.com -> 
patchew/20210110185109.29841-1-space.monkey.deliv...@gmail.com
 * [new tag] 
patchew/20210115224645.1196742-1-richard.hender...@linaro.org -> 
patchew/20210115224645.1196742-1-richard.hender...@linaro.org
Switched to a new branch 'test'
b51c62b tests/tcg/aarch64: Add mte smoke tests
2bb6651 target/arm: Enable MTE for user-only
581006b target/arm: Add allocation tag storage for user mode
3995c13 linux-user/aarch64: Signal SEGV_MTEAERR for async tag check error
3b2735a linux-user/aarch64: Signal SEGV_MTESERR for sync tag check fault
87773dc linux-user/aarch64: Pass syndrome to EXC_*_ABORT
c77b9e7 target/arm: Split out syndrome.h from internals.h
03409db linux-user/aarch64: Implement PROT_MTE
a349186 linux-user/aarch64: Implement PR_MTE_TCF and PR_MTE_TAG
1bf3014 linux-user/aarch64: Implement PR_TAGGED_ADDR_ENABLE
dda6aba exec: Add support for TARGET_TAGGED_ADDRESSES
37ecbdb linux-user: Fix guest_addr_valid vs reserved_va
b45e037 linux-user: Do not use guest_addr_valid for h2g_valid
cabbb07 bsd-user: Tidy VERIFY_READ/VERIFY_WRITE
9528890 linux-user: Tidy VERIFY_READ/VERIFY_WRITE
074f1b6 linux-user: Check for overflow in access_ok
a57aaa3 exec: Improve types for guest_addr_valid
acb28c7 exec: Use uintptr_t in cpu_ldst.h
6b630ff exec: Use uintptr_t for guest_base
6b7daa3 linux-user: Introduce PAGE_ANON
b7dc05d tcg: Introduce target-specific page data for user-only

=== OUTPUT BEGIN ===
1/21 Checking commit b7dc05ddcc5b (tcg: Introduce target-specific page data for 
user-only)
2/21 Checking commit 6b7daa34298c (linux-user: Introduce PAGE_ANON)
3/21 Checking commit 6b630ffe4c66 (exec: Use uintptr_t for guest_base)
4/21 Checking commit acb28c7cb60b (exec: Use uintptr_t in cpu_ldst.h)
5/21 Checking commit a57aaa3359f2 (exec: Improve types for guest_addr_valid)
6/21 Checking commit 074f1b6a03d3 (linux-user: Check for overflow in access_ok)
7/21 Checking commit 952889066ba0 (linux-user: Tidy VERIFY_READ/VERIFY_WRITE)
8/21 Checking commit cabbb07508f6 (bsd-user: Tidy VERIFY_READ/VERIFY_WRITE)
9/21 Checking commit b45e037c08d2 (linux-user: Do not use guest_addr_valid for 
h2g_valid)
10/21 Checking commit 37ecbdbf6a08 (linux-user: Fix guest_addr_valid vs 
reserved_va)
11/21 Checking commit dda6aba68cc2 (exec: Add support for 
TARGET_TAGGED_ADDRESSES)
12/21 Checking commit 1bf30143d18d (linux-user/aarch64: Implement 
PR_TAGGED_ADDR_ENABLE)
13/21 Checking commit a349186d27f0 (linux-user/aarch64: Implement PR_MTE_TCF 
and PR_MTE_TAG)
14/21 Checking commit 03409db2e4ec (linux-user/aarch64: Implement PROT_MTE)
15/21 Checking commit c77b9e72eb32 (target/arm: Split out syndrome.h from 
internals.h)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#277: 
new file mode 100644

total: 0 errors, 1 warnings, 530 lines checked

Patch 15/21 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
16/21 Checking commit 87773dca7e38 (linux-user/aarch64: Pass syndrome to 
EXC_*_ABORT)
17/21 Checking commit 3b2735ac2c32 (linux-user/aarch64: Signal SEGV_MTESERR for 
sync tag check fault)
18/21 Checking commit 3995c13283cb (linux-user/aarch64: Signal SEGV_MTEAERR for 
async tag check error)
19/21 Checking commit 581006bf041a (target/arm: Add allocation tag storage for 
user mode)
20/21 Checking commit 2bb6651fbcf7 (target/arm: Enable MTE for user-only)
21/21 Checking commit b51c62bbd980 (tests/tcg/aarch64: Add mte smoke tests)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#28: 
new file mode 100644

ERROR: trailing statements should be on next line
#157: FILE: tests/tcg/aarch64/mte-3.c:46:
+while (1);

ERROR: braces {} are necessary for all arms of this statement
#157: FILE: tests/tcg/aarch64/mte-3.c:46:
+while (1);
[...]

ERROR: use qemu_real_host_page_size instead of getpagesize()
#192: FILE: tests/tcg/aarch64/mte-4.c:28:
+size_t size = getpagesize() * 4;

total: 3 errors, 1 warnings, 231 lines checked

Patch 21/21 has style problems, please review.  If any of these errors

[Bug 1906193] Re: riscv32 user mode emulation: fork return values broken

2021-01-15 Thread Alistair Francis
Can you add a Tested-by: tag to the patch?

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1906193

Title:
  riscv32 user mode emulation: fork return values broken

Status in QEMU:
  Confirmed

Bug description:
  When running in a chroot with riscv32 (on x86_64; qemu git master as
  of today):

  The following short program forks; the child immediately returns with
  exit(42). The parent checks for the return value - and obtains 40!

  gcc-10.2

  ===
  #include 
  #include 
  #include 
  #include 

  main(c, v)
   int c;
   char **v;
  {
pid_t pid, p;
int s, i, n;

s = 0;
pid = fork();
if (pid == 0)
  exit(42);

/* wait for the process */
p = wait();
if (p != pid)
  exit (255);

if (WIFEXITED(s))
{
   int r=WEXITSTATUS(s);
   if (r!=42) {
printf("child wants to return %i (0x%X), parent received %i (0x%X), 
difference %i\n",42,42,r,r,r-42);
   }
}
  }
  ===

  (riscv-ilp32 chroot) farino /tmp # ./wait-test-short 
  child wants to return 42 (0x2A), parent received 40 (0x28), difference -2

  ===
  (riscv-ilp32 chroot) farino /tmp # gcc --version
  gcc (Gentoo 10.2.0-r1 p2) 10.2.0
  Copyright (C) 2020 Free Software Foundation, Inc.
  Dies ist freie Software; die Kopierbedingungen stehen in den Quellen. Es
  gibt KEINE Garantie; auch nicht für MARKTGÄNGIGKEIT oder FÜR SPEZIELLE ZWECKE.

  (riscv-ilp32 chroot) farino /tmp # ld --version
  GNU ld (Gentoo 2.34 p6) 2.34.0
  Copyright (C) 2020 Free Software Foundation, Inc.
  This program is free software; you may redistribute it under the terms of
  the GNU General Public License version 3 or (at your option) a later version.
  This program has absolutely no warranty.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1906193/+subscriptions



Re: [PATCH] hw/misc/sifive_u_otp: handling the fails of blk_pread and blk_pwrite

2021-01-15 Thread Alistair Francis
On Fri, Jan 15, 2021 at 2:17 PM Peter Maydell  wrote:
>
> On Fri, 15 Jan 2021 at 21:43, Alistair Francis  wrote:
> >
> > On Fri, Jan 15, 2021 at 6:09 AM Bin Meng  wrote:
> > >
> > > On Fri, Jan 15, 2021 at 9:55 PM Peter Maydell  
> > > wrote
> > > > printf is definitely the wrong thing... you need to either report
> > > > the error back to the guest if the interface the guest is using
> > > > has a facility for reporting read/write failures, or log or report
> > > > it to the user using one of our APIs for that.
> > >
> > > It seems the hardware does not have a mechanism to report to the
> > > software when hardware cannot fulfill the task requested by software.
> > >
> > > I checked all existence of block_pwrite() callers. It looks like this
> > > is not handled consistently. Some indeed call printf(), some call
> > > error_setg_errno(), some call fprintf(stderr), some call qemu_log()
> > > ...
> >
> > Logging a guest error seems like the best bet, I'm not really sure
> > what else we would do.
>
> Looking at the other options, I think error_report() of some kind is
> probably the best bet here.

Ok

@Green Wan do you mind sending a new version?

Alistair

>
> thanks
> -- PMM



Re: [PATCH] cpu_exec_step_atomic: update the cpu running flag

2021-01-15 Thread Richard Henderson
On 9/21/20 9:42 PM, Douglas Crosher wrote:
> 
> The cpu_exec_step_atomic() function is called with the cpu->running
> clear and proceeds to run target code without setting this flag. If
> this target code generates an exception then handle_cpu_signal() will
> unnecessarily abort.
> 
> For example if atomic code generates a memory protection fault.
> 
> This patch at least sets and clears this running flag.
> 
> The related code paths look rather convoluted and it is not immediately clear
> that this patch comprehensively addresses the issue, but it might at least
> direct people to a problem, and it might be an incremental improvement, and it
> gets some code running here. The patch adds some assertions to help detect
> other cases.
> 
> Signed-off-by: Douglas Crosher 

Sorry this got overlooked, but better late than never.
Yes, this looks right, thanks.

Queued to tcg-next.


r~



Re: [PATCH v1 1/1] riscv: Pass RISCVHartArrayState by pointer

2021-01-15 Thread Palmer Dabbelt

On Fri, 15 Jan 2021 15:00:27 PST (-0800), Alistair Francis wrote:

We were accidently passing RISCVHartArrayState by value instead of
pointer. The type is 824 bytes long so let's correct that and pass it by
pointer instead.

Fixes: Coverity CID 1438099
Fixes: Coverity CID 1438100
Fixes: Coverity CID 1438101
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/boot.h |  6 +++---
 hw/riscv/boot.c |  8 
 hw/riscv/sifive_u.c | 10 +-
 hw/riscv/spike.c|  8 
 hw/riscv/virt.c |  8 
 5 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 20ff5fe5e5..11a21dd584 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -24,9 +24,9 @@
 #include "hw/loader.h"
 #include "hw/riscv/riscv_hart.h"

-bool riscv_is_32bit(RISCVHartArrayState harts);
+bool riscv_is_32bit(RISCVHartArrayState *harts);

-target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState harts,
+target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts,
   target_ulong firmware_end_addr);
 target_ulong riscv_find_and_load_firmware(MachineState *machine,
   const char *default_machine_firmware,
@@ -42,7 +42,7 @@ target_ulong riscv_load_kernel(const char *kernel_filename,
 hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
  uint64_t kernel_entry, hwaddr *start);
 uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt);
-void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState 
harts,
+void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState 
*harts,
hwaddr saddr,
hwaddr rom_base, hwaddr rom_size,
uint64_t kernel_entry,
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 83586aef41..acf77675b2 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -33,14 +33,14 @@

 #include 

-bool riscv_is_32bit(RISCVHartArrayState harts)
+bool riscv_is_32bit(RISCVHartArrayState *harts)
 {
-RISCVCPU hart = harts.harts[0];
+RISCVCPU hart = harts->harts[0];

 return riscv_cpu_is_32bit();
 }

-target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState harts,
+target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts,
   target_ulong firmware_end_addr) {
 if (riscv_is_32bit(harts)) {
 return QEMU_ALIGN_UP(firmware_end_addr, 4 * MiB);
@@ -247,7 +247,7 @@ void riscv_rom_copy_firmware_info(MachineState *machine, 
hwaddr rom_base,
_space_memory);
 }

-void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState 
harts,
+void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState 
*harts,
hwaddr start_addr,
hwaddr rom_base, hwaddr rom_size,
uint64_t kernel_entry,
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index f5c400dd44..d23f349b4e 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -466,7 +466,7 @@ static void sifive_u_machine_init(MachineState *machine)

 /* create device tree */
 create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
-   riscv_is_32bit(s->soc.u_cpus));
+   riscv_is_32bit(>soc.u_cpus));

 if (s->start_in_flash) {
 /*
@@ -495,7 +495,7 @@ static void sifive_u_machine_init(MachineState *machine)
 break;
 }

-if (riscv_is_32bit(s->soc.u_cpus)) {
+if (riscv_is_32bit(>soc.u_cpus)) {
 firmware_end_addr = riscv_find_and_load_firmware(machine,
 "opensbi-riscv32-generic-fw_dynamic.bin",
 start_addr, NULL);
@@ -506,7 +506,7 @@ static void sifive_u_machine_init(MachineState *machine)
 }

 if (machine->kernel_filename) {
-kernel_start_addr = riscv_calc_kernel_start_addr(s->soc.u_cpus,
+kernel_start_addr = riscv_calc_kernel_start_addr(>soc.u_cpus,
  firmware_end_addr);

 kernel_entry = riscv_load_kernel(machine->kernel_filename,
@@ -533,7 +533,7 @@ static void sifive_u_machine_init(MachineState *machine)
 /* Compute the fdt load address in dram */
 fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DEV_DRAM].base,
machine->ram_size, s->fdt);
-if (!riscv_is_32bit(s->soc.u_cpus)) {
+if (!riscv_is_32bit(>soc.u_cpus)) {
 start_addr_hi32 = (uint64_t)start_addr >> 32;
 }

@@ -552,7 +552,7 @@ static void sifive_u_machine_init(MachineState *machine)
 0x,
/* fw_dyn: */
 };
-if (riscv_is_32bit(s->soc.u_cpus)) {
+if (riscv_is_32bit(>soc.u_cpus)) {
 

Re: [PULL 11/24] tcg/optimize: Use tcg_constant_internal with constant folding

2021-01-15 Thread Alistair Francis
On Wed, Jan 13, 2021 at 6:32 PM Richard Henderson
 wrote:
>
> Signed-off-by: Richard Henderson 

This patch results in a QEMU seg fault when starting userspace on RISC-V 32-bit.

This is the full backtrace:

```
#0  0x55a67c4d in ts_are_copies (ts2=0x7fffa8008008,
ts1=0x7fffa8001e40) at ../tcg/optimize.c:163
#1  tcg_opt_gen_mov (s=s@entry=0x7fffa8000b60,
op=op@entry=0x7fffa81ac778, dst=140736011968064, src=140736011993096)
at ../tcg/optimize.c:191
#2  0x55a67dcb in tcg_opt_gen_movi (s=s@entry=0x7fffa8000b60,
temps_used=temps_used@entry=0x71cb92c0,
op=op@entry=0x7fffa81ac778, dst=, val=)
at ../tcg/optimize.c:249
#3  0x55a6914d in tcg_optimize (s=s@entry=0x7fffa8000b60) at
../tcg/optimize.c:1242
#4  0x55abb248 in tcg_gen_code (s=0x7fffa8000b60,
tb=tb@entry=0x7fffae84edc0 ) at
../tcg/tcg.c:4406
#5  0x55a7f4d5 in tb_gen_code (cpu=cpu@entry=0x77fac930,
pc=160234, cs_base=0, flags=16640, cflags=-16252928) at
../accel/tcg/translate-all.c:1952
#6  0x55ae4fe4 in tb_find (cf_mask=, tb_exit=0,
last_tb=0x0, cpu=0x77fac930) at ../accel/tcg/cpu-exec.c:454
#7  cpu_exec (cpu=cpu@entry=0x77fac930) at ../accel/tcg/cpu-exec.c:810
#8  0x55aa6513 in tcg_cpus_exec (cpu=cpu@entry=0x77fac930)
at ../accel/tcg/tcg-cpus.c:57
#9  0x55a8c7a3 in mttcg_cpu_thread_fn
(arg=arg@entry=0x77fac930) at ../accel/tcg/tcg-cpus-mttcg.c:69
#10 0x55c94209 in qemu_thread_start (args=0x71cb96d0) at
../util/qemu-thread-posix.c:521
#11 0x7673a3e9 in start_thread () at /usr/lib/libpthread.so.0
#12 0x76395293 in clone () at /usr/lib/libc.so.6
```

I run QEMU with these arguments:

./build/riscv32-softmmu/qemu-system-riscv32 \
-machine virt -serial mon:stdio -serial null -nographic \
-append "root=/dev/vda rw highres=off  console=ttyS0 ip=dhcp earlycon=sbi" \
-device virtio-net-device,netdev=net0,mac=52:54:00:12:34:02
-netdev user,id=net0 \
-object rng-random,filename=/dev/urandom,id=rng0 -device
virtio-rng-device,rng=rng0 \
-smp 4 -d guest_errors -m 256M \
-kernel ./Image \
-drive 
id=disk0,file=./core-image-minimal-qemuriscv32.ext4,if=none,format=raw
\
-device virtio-blk-device,drive=disk0 \
-bios default

I am uploading the images to:
https://nextcloud.alistair23.me/index.php/s/MQFyGGNLPZjLZPH

Although apparently it will take a few hours to upload the 2GB rootFS.

Alistair


> ---
>  tcg/optimize.c | 108 ++---
>  1 file changed, 49 insertions(+), 59 deletions(-)
>
> diff --git a/tcg/optimize.c b/tcg/optimize.c
> index 49bf1386c7..bda727d5ed 100644
> --- a/tcg/optimize.c
> +++ b/tcg/optimize.c
> @@ -178,37 +178,6 @@ static bool args_are_copies(TCGArg arg1, TCGArg arg2)
>  return ts_are_copies(arg_temp(arg1), arg_temp(arg2));
>  }
>
> -static void tcg_opt_gen_movi(TCGContext *s, TCGOp *op, TCGArg dst, uint64_t 
> val)
> -{
> -const TCGOpDef *def;
> -TCGOpcode new_op;
> -uint64_t mask;
> -TempOptInfo *di = arg_info(dst);
> -
> -def = _op_defs[op->opc];
> -if (def->flags & TCG_OPF_VECTOR) {
> -new_op = INDEX_op_dupi_vec;
> -} else if (def->flags & TCG_OPF_64BIT) {
> -new_op = INDEX_op_movi_i64;
> -} else {
> -new_op = INDEX_op_movi_i32;
> -}
> -op->opc = new_op;
> -/* TCGOP_VECL and TCGOP_VECE remain unchanged.  */
> -op->args[0] = dst;
> -op->args[1] = val;
> -
> -reset_temp(dst);
> -di->is_const = true;
> -di->val = val;
> -mask = val;
> -if (TCG_TARGET_REG_BITS > 32 && new_op == INDEX_op_movi_i32) {
> -/* High bits of the destination are now garbage.  */
> -mask |= ~0xull;
> -}
> -di->mask = mask;
> -}
> -
>  static void tcg_opt_gen_mov(TCGContext *s, TCGOp *op, TCGArg dst, TCGArg src)
>  {
>  TCGTemp *dst_ts = arg_temp(dst);
> @@ -259,6 +228,27 @@ static void tcg_opt_gen_mov(TCGContext *s, TCGOp *op, 
> TCGArg dst, TCGArg src)
>  }
>  }
>
> +static void tcg_opt_gen_movi(TCGContext *s, TCGTempSet *temps_used,
> + TCGOp *op, TCGArg dst, uint64_t val)
> +{
> +const TCGOpDef *def = _op_defs[op->opc];
> +TCGType type;
> +TCGTemp *tv;
> +
> +if (def->flags & TCG_OPF_VECTOR) {
> +type = TCGOP_VECL(op) + TCG_TYPE_V64;
> +} else if (def->flags & TCG_OPF_64BIT) {
> +type = TCG_TYPE_I64;
> +} else {
> +type = TCG_TYPE_I32;
> +}
> +
> +/* Convert movi to mov with constant temp. */
> +tv = tcg_constant_internal(type, val);
> +init_ts_info(temps_used, tv);
> +tcg_opt_gen_mov(s, op, dst, temp_arg(tv));
> +}
> +
>  static uint64_t do_constant_folding_2(TCGOpcode op, uint64_t x, uint64_t y)
>  {
>  uint64_t l64, h64;
> @@ -622,7 +612,7 @@ void tcg_optimize(TCGContext *s)
>  nb_temps = s->nb_temps;
>  nb_globals = s->nb_globals;
>
> -bitmap_zero(temps_used.l, nb_temps);
> +memset(_used, 0, sizeof(temps_used));
>  for (i = 

[PATCH v1 1/1] riscv: Pass RISCVHartArrayState by pointer

2021-01-15 Thread Alistair Francis
We were accidently passing RISCVHartArrayState by value instead of
pointer. The type is 824 bytes long so let's correct that and pass it by
pointer instead.

Fixes: Coverity CID 1438099
Fixes: Coverity CID 1438100
Fixes: Coverity CID 1438101
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/boot.h |  6 +++---
 hw/riscv/boot.c |  8 
 hw/riscv/sifive_u.c | 10 +-
 hw/riscv/spike.c|  8 
 hw/riscv/virt.c |  8 
 5 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 20ff5fe5e5..11a21dd584 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -24,9 +24,9 @@
 #include "hw/loader.h"
 #include "hw/riscv/riscv_hart.h"
 
-bool riscv_is_32bit(RISCVHartArrayState harts);
+bool riscv_is_32bit(RISCVHartArrayState *harts);
 
-target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState harts,
+target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts,
   target_ulong firmware_end_addr);
 target_ulong riscv_find_and_load_firmware(MachineState *machine,
   const char *default_machine_firmware,
@@ -42,7 +42,7 @@ target_ulong riscv_load_kernel(const char *kernel_filename,
 hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
  uint64_t kernel_entry, hwaddr *start);
 uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt);
-void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState 
harts,
+void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState 
*harts,
hwaddr saddr,
hwaddr rom_base, hwaddr rom_size,
uint64_t kernel_entry,
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 83586aef41..acf77675b2 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -33,14 +33,14 @@
 
 #include 
 
-bool riscv_is_32bit(RISCVHartArrayState harts)
+bool riscv_is_32bit(RISCVHartArrayState *harts)
 {
-RISCVCPU hart = harts.harts[0];
+RISCVCPU hart = harts->harts[0];
 
 return riscv_cpu_is_32bit();
 }
 
-target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState harts,
+target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts,
   target_ulong firmware_end_addr) {
 if (riscv_is_32bit(harts)) {
 return QEMU_ALIGN_UP(firmware_end_addr, 4 * MiB);
@@ -247,7 +247,7 @@ void riscv_rom_copy_firmware_info(MachineState *machine, 
hwaddr rom_base,
_space_memory);
 }
 
-void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState 
harts,
+void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState 
*harts,
hwaddr start_addr,
hwaddr rom_base, hwaddr rom_size,
uint64_t kernel_entry,
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index f5c400dd44..d23f349b4e 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -466,7 +466,7 @@ static void sifive_u_machine_init(MachineState *machine)
 
 /* create device tree */
 create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
-   riscv_is_32bit(s->soc.u_cpus));
+   riscv_is_32bit(>soc.u_cpus));
 
 if (s->start_in_flash) {
 /*
@@ -495,7 +495,7 @@ static void sifive_u_machine_init(MachineState *machine)
 break;
 }
 
-if (riscv_is_32bit(s->soc.u_cpus)) {
+if (riscv_is_32bit(>soc.u_cpus)) {
 firmware_end_addr = riscv_find_and_load_firmware(machine,
 "opensbi-riscv32-generic-fw_dynamic.bin",
 start_addr, NULL);
@@ -506,7 +506,7 @@ static void sifive_u_machine_init(MachineState *machine)
 }
 
 if (machine->kernel_filename) {
-kernel_start_addr = riscv_calc_kernel_start_addr(s->soc.u_cpus,
+kernel_start_addr = riscv_calc_kernel_start_addr(>soc.u_cpus,
  firmware_end_addr);
 
 kernel_entry = riscv_load_kernel(machine->kernel_filename,
@@ -533,7 +533,7 @@ static void sifive_u_machine_init(MachineState *machine)
 /* Compute the fdt load address in dram */
 fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DEV_DRAM].base,
machine->ram_size, s->fdt);
-if (!riscv_is_32bit(s->soc.u_cpus)) {
+if (!riscv_is_32bit(>soc.u_cpus)) {
 start_addr_hi32 = (uint64_t)start_addr >> 32;
 }
 
@@ -552,7 +552,7 @@ static void sifive_u_machine_init(MachineState *machine)
 0x,
/* fw_dyn: */
 };
-if (riscv_is_32bit(s->soc.u_cpus)) {
+if (riscv_is_32bit(>soc.u_cpus)) {
 reset_vec[4] = 0x0202a583; /* lw a1, 32(t0) */
 

Re: [PATCH v1 1/1] linux-user/signal: Decode waitid si_code

2021-01-15 Thread Alistair Francis
On Sat, Dec 19, 2020 at 10:11 AM Alistair Francis
 wrote:
>
> When mapping the host waitid status to the target status we previously
> just used decoding information in the status value. This doesn't follow
> what the waitid documentation describes, which instead suggests using
> the si_code value for the decoding. This results in the incorrect values
> seen when calling waitid. This is especially apparent on RV32 where all
> wait calls use waitid (see the bug case).
>
> This patch uses the si_code value to map the waitid status.
>
> Buglink: https://bugs.launchpad.net/qemu/+bug/1906193
> Signed-off-by: Alistair Francis 

Ping!

Alistair

> ---
>  linux-user/signal.c | 26 --
>  1 file changed, 24 insertions(+), 2 deletions(-)
>
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index 73de934c65..b6c9326521 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -305,6 +305,7 @@ static inline void 
> host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
>  int sig = host_to_target_signal(info->si_signo);
>  int si_code = info->si_code;
>  int si_type;
> +int status = info->si_status;
>  tinfo->si_signo = sig;
>  tinfo->si_errno = 0;
>  tinfo->si_code = info->si_code;
> @@ -349,8 +350,29 @@ static inline void 
> host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
>  case TARGET_SIGCHLD:
>  tinfo->_sifields._sigchld._pid = info->si_pid;
>  tinfo->_sifields._sigchld._uid = info->si_uid;
> -tinfo->_sifields._sigchld._status
> -= host_to_target_waitstatus(info->si_status);
> +
> +/*
> + * Map host to target signal numbers for the waitid family of
> + * syscalls. This is similar to the functionality in
> + * host_to_target_waitstatus() except we use the si_code to
> + * determine the operation.
> + */
> +switch (info->si_code) {
> +case CLD_KILLED:
> +case CLD_DUMPED:
> +tinfo->_sifields._sigchld._status =
> +host_to_target_signal(WTERMSIG(status)) |
> +  (status & ~0x7f);
> +break;
> +case CLD_STOPPED:
> +tinfo->_sifields._sigchld._status =
> +(host_to_target_signal(WSTOPSIG(status)) << 8) |
> +(status & 0xff);
> +break;
> +default:
> +tinfo->_sifields._sigchld._status = status;
> +}
> +
>  tinfo->_sifields._sigchld._utime = info->si_utime;
>  tinfo->_sifields._sigchld._stime = info->si_stime;
>  si_type = QEMU_SI_CHLD;
> --
> 2.29.2
>



[PATCH v3 20/21] target/arm: Enable MTE for user-only

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index abc0affd00..5e613a747a 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -208,6 +208,22 @@ static void arm_cpu_reset(DeviceState *dev)
  * Do not modify this without other changes.
  */
 env->cp15.tcr_el[1].raw_tcr = (3ULL << 37);
+
+/* Enable MTE */
+if (cpu_isar_feature(aa64_mte, cpu)) {
+/* Enable tag access, but leave TCF0 as No Effect (0). */
+env->cp15.sctlr_el[1] |= SCTLR_ATA0;
+/*
+ * Exclude all tags, so that tag 0 is always used.
+ * This corresponds to Linux current->thread.gcr_incl = 0.
+ *
+ * Set RRND, so that helper_irg() will generate a seed later.
+ * Here in cpu_reset(), the crypto subsystem has not yet been
+ * initialized.
+ */
+env->cp15.gcr_el1 = 0x1;
+}
+
 # ifdef TARGET_TAGGED_ADDRESSES
 env->untagged_addr_mask = -1;
 # endif
-- 
2.25.1




[PATCH v3 18/21] linux-user/aarch64: Signal SEGV_MTEAERR for async tag check error

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_signal.h |  1 +
 linux-user/aarch64/cpu_loop.c  | 34 +-
 target/arm/mte_helper.c| 10 +
 3 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/linux-user/aarch64/target_signal.h 
b/linux-user/aarch64/target_signal.h
index 777fb667fe..18013e1b23 100644
--- a/linux-user/aarch64/target_signal.h
+++ b/linux-user/aarch64/target_signal.h
@@ -21,6 +21,7 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
+#define TARGET_SEGV_MTEAERR  8  /* Asynchronous ARM MTE error */
 #define TARGET_SEGV_MTESERR  9  /* Synchronous ARM MTE exception */
 
 #define TARGET_ARCH_HAS_SETUP_FRAME
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index 6867f0db2b..6160a401bd 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -72,6 +72,21 @@
 put_user_u16(__x, (gaddr)); \
 })
 
+static bool check_mte_async_fault(CPUARMState *env, target_siginfo_t *info)
+{
+if (likely(env->cp15.tfsr_el[0] == 0)) {
+return false;
+}
+
+env->cp15.tfsr_el[0] = 0;
+info->si_signo = TARGET_SIGSEGV;
+info->si_errno = 0;
+info->_sifields._sigfault._addr = 0;
+info->si_code = TARGET_SEGV_MTEAERR;
+queue_signal(env, info->si_signo, QEMU_SI_FAULT, info);
+return true;
+}
+
 /* AArch64 main loop */
 void cpu_loop(CPUARMState *env)
 {
@@ -88,15 +103,13 @@ void cpu_loop(CPUARMState *env)
 
 switch (trapnr) {
 case EXCP_SWI:
-ret = do_syscall(env,
- env->xregs[8],
- env->xregs[0],
- env->xregs[1],
- env->xregs[2],
- env->xregs[3],
- env->xregs[4],
- env->xregs[5],
- 0, 0);
+if (check_mte_async_fault(env, )) {
+ret = -TARGET_ERESTARTSYS;
+} else {
+ret = do_syscall(env, env->xregs[8], env->xregs[0],
+ env->xregs[1], env->xregs[2], env->xregs[3],
+ env->xregs[4], env->xregs[5], 0, 0);
+}
 if (ret == -TARGET_ERESTARTSYS) {
 env->pc -= 4;
 } else if (ret != -TARGET_QEMU_ESIGRETURN) {
@@ -104,7 +117,8 @@ void cpu_loop(CPUARMState *env)
 }
 break;
 case EXCP_INTERRUPT:
-/* just indicate that signals should be handled asap */
+/* Just indicate that signals should be handled asap. */
+check_mte_async_fault(env, );
 break;
 case EXCP_UDEF:
 info.si_signo = TARGET_SIGILL;
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index 153bd1e9df..d55f8d1e1e 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -565,6 +565,16 @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
 select = 0;
 }
 env->cp15.tfsr_el[el] |= 1 << select;
+#ifdef CONFIG_USER_ONLY
+/*
+ * Stand in for a timer irq, setting _TIF_MTE_ASYNC_FAULT,
+ * which then sends a SIGSEGV when the thread is next scheduled.
+ * This cpu will return to the main loop at the end of the TB,
+ * which is rather sooner than "normal".  But the alternative
+ * is waiting until the next syscall.
+ */
+qemu_cpu_kick(env_cpu(env));
+#endif
 break;
 
 default:
-- 
2.25.1




[PATCH v3 15/21] target/arm: Split out syndrome.h from internals.h

2021-01-15 Thread Richard Henderson
Move everything related to syndromes to a new file,
which can be shared with linux-user.

Signed-off-by: Richard Henderson 
---
 target/arm/internals.h | 245 +---
 target/arm/syndrome.h  | 273 +
 2 files changed, 274 insertions(+), 244 deletions(-)
 create mode 100644 target/arm/syndrome.h

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 5460678756..1e60c0e0e8 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -26,6 +26,7 @@
 #define TARGET_ARM_INTERNALS_H
 
 #include "hw/registerfields.h"
+#include "syndrome.h"
 
 /* register banks for CPU modes */
 #define BANK_USRSYS 0
@@ -256,250 +257,6 @@ static inline bool extended_addresses_enabled(CPUARMState 
*env)
(arm_feature(env, ARM_FEATURE_LPAE) && (tcr->raw_tcr & TTBCR_EAE));
 }
 
-/* Valid Syndrome Register EC field values */
-enum arm_exception_class {
-EC_UNCATEGORIZED  = 0x00,
-EC_WFX_TRAP   = 0x01,
-EC_CP15RTTRAP = 0x03,
-EC_CP15RRTTRAP= 0x04,
-EC_CP14RTTRAP = 0x05,
-EC_CP14DTTRAP = 0x06,
-EC_ADVSIMDFPACCESSTRAP= 0x07,
-EC_FPIDTRAP   = 0x08,
-EC_PACTRAP= 0x09,
-EC_CP14RRTTRAP= 0x0c,
-EC_BTITRAP= 0x0d,
-EC_ILLEGALSTATE   = 0x0e,
-EC_AA32_SVC   = 0x11,
-EC_AA32_HVC   = 0x12,
-EC_AA32_SMC   = 0x13,
-EC_AA64_SVC   = 0x15,
-EC_AA64_HVC   = 0x16,
-EC_AA64_SMC   = 0x17,
-EC_SYSTEMREGISTERTRAP = 0x18,
-EC_SVEACCESSTRAP  = 0x19,
-EC_INSNABORT  = 0x20,
-EC_INSNABORT_SAME_EL  = 0x21,
-EC_PCALIGNMENT= 0x22,
-EC_DATAABORT  = 0x24,
-EC_DATAABORT_SAME_EL  = 0x25,
-EC_SPALIGNMENT= 0x26,
-EC_AA32_FPTRAP= 0x28,
-EC_AA64_FPTRAP= 0x2c,
-EC_SERROR = 0x2f,
-EC_BREAKPOINT = 0x30,
-EC_BREAKPOINT_SAME_EL = 0x31,
-EC_SOFTWARESTEP   = 0x32,
-EC_SOFTWARESTEP_SAME_EL   = 0x33,
-EC_WATCHPOINT = 0x34,
-EC_WATCHPOINT_SAME_EL = 0x35,
-EC_AA32_BKPT  = 0x38,
-EC_VECTORCATCH= 0x3a,
-EC_AA64_BKPT  = 0x3c,
-};
-
-#define ARM_EL_EC_SHIFT 26
-#define ARM_EL_IL_SHIFT 25
-#define ARM_EL_ISV_SHIFT 24
-#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
-#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
-
-static inline uint32_t syn_get_ec(uint32_t syn)
-{
-return syn >> ARM_EL_EC_SHIFT;
-}
-
-/* Utility functions for constructing various kinds of syndrome value.
- * Note that in general we follow the AArch64 syndrome values; in a
- * few cases the value in HSR for exceptions taken to AArch32 Hyp
- * mode differs slightly, and we fix this up when populating HSR in
- * arm_cpu_do_interrupt_aarch32_hyp().
- * The exception is FP/SIMD access traps -- these report extra information
- * when taking an exception to AArch32. For those we include the extra coproc
- * and TA fields, and mask them out when taking the exception to AArch64.
- */
-static inline uint32_t syn_uncategorized(void)
-{
-return (EC_UNCATEGORIZED << ARM_EL_EC_SHIFT) | ARM_EL_IL;
-}
-
-static inline uint32_t syn_aa64_svc(uint32_t imm16)
-{
-return (EC_AA64_SVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0x);
-}
-
-static inline uint32_t syn_aa64_hvc(uint32_t imm16)
-{
-return (EC_AA64_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0x);
-}
-
-static inline uint32_t syn_aa64_smc(uint32_t imm16)
-{
-return (EC_AA64_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0x);
-}
-
-static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_16bit)
-{
-return (EC_AA32_SVC << ARM_EL_EC_SHIFT) | (imm16 & 0x)
-| (is_16bit ? 0 : ARM_EL_IL);
-}
-
-static inline uint32_t syn_aa32_hvc(uint32_t imm16)
-{
-return (EC_AA32_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0x);
-}
-
-static inline uint32_t syn_aa32_smc(void)
-{
-return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL;
-}
-
-static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
-{
-return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0x);
-}
-
-static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_16bit)
-{
-return (EC_AA32_BKPT << ARM_EL_EC_SHIFT) | (imm16 & 0x)
-| (is_16bit ? 0 : ARM_EL_IL);
-}
-
-static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2,
-   int crn, int crm, int rt,
-   int isread)
-{
-return (EC_SYSTEMREGISTERTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL
-| (op0 << 20) | (op2 << 17) | (op1 << 14) | (crn << 10) | (rt << 5)
-| (crm << 1) | isread;
-}
-
-static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2,
-  

[PATCH v3 21/21] tests/tcg/aarch64: Add mte smoke tests

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tests/tcg/aarch64/mte.h   | 53 +++
 tests/tcg/aarch64/mte-1.c | 25 +++
 tests/tcg/aarch64/mte-2.c | 42 
 tests/tcg/aarch64/mte-3.c | 47 +++
 tests/tcg/aarch64/mte-4.c | 42 
 tests/tcg/aarch64/Makefile.target |  6 
 tests/tcg/configure.sh|  4 +++
 7 files changed, 219 insertions(+)
 create mode 100644 tests/tcg/aarch64/mte.h
 create mode 100644 tests/tcg/aarch64/mte-1.c
 create mode 100644 tests/tcg/aarch64/mte-2.c
 create mode 100644 tests/tcg/aarch64/mte-3.c
 create mode 100644 tests/tcg/aarch64/mte-4.c

diff --git a/tests/tcg/aarch64/mte.h b/tests/tcg/aarch64/mte.h
new file mode 100644
index 00..038d33ab6c
--- /dev/null
+++ b/tests/tcg/aarch64/mte.h
@@ -0,0 +1,53 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef PR_SET_TAGGED_ADDR_CTRL
+# define PR_SET_TAGGED_ADDR_CTRL  55
+#endif
+#ifndef PR_TAGGED_ADDR_ENABLE
+# define PR_TAGGED_ADDR_ENABLE(1UL << 0)
+#endif
+#ifndef PR_MTE_TCF_SHIFT
+# define PR_MTE_TCF_SHIFT 1
+# define PR_MTE_TCF_NONE  (0UL << PR_MTE_TCF_SHIFT)
+# define PR_MTE_TCF_SYNC  (1UL << PR_MTE_TCF_SHIFT)
+# define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT)
+# define PR_MTE_TAG_SHIFT 3
+#endif
+
+#ifndef PROT_MTE
+# define PROT_MTE 0x20
+#endif
+
+#ifndef SEGV_MTEAERR
+# define SEGV_MTEAERR8
+# define SEGV_MTESERR9
+#endif
+
+static void enable_mte(int tcf)
+{
+int r = prctl(PR_SET_TAGGED_ADDR_CTRL,
+  PR_TAGGED_ADDR_ENABLE | tcf | (0xfffe << PR_MTE_TAG_SHIFT),
+  0, 0, 0);
+if (r < 0) {
+perror("PR_SET_TAGGED_ADDR_CTRL");
+exit(2);
+}
+}
+
+static void *alloc_mte_mem(size_t size)
+{
+void *p = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_MTE,
+   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+if (p == MAP_FAILED) {
+perror("mmap PROT_MTE");
+exit(2);
+}
+return p;
+}
diff --git a/tests/tcg/aarch64/mte-1.c b/tests/tcg/aarch64/mte-1.c
new file mode 100644
index 00..02bc978482
--- /dev/null
+++ b/tests/tcg/aarch64/mte-1.c
@@ -0,0 +1,25 @@
+/*
+ * Memory tagging, basic pass cases.
+ */
+
+#include "mte.h"
+
+int main(int ac, char **av)
+{
+int *p0, *p1, *p2;
+long c;
+
+enable_mte(PR_MTE_TCF_NONE);
+p0 = alloc_mte_mem(sizeof(*p0));
+
+asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(1));
+assert(p1 != p0);
+asm("subp %0,%1,%2" : "=r"(c) : "r"(p0), "r"(p1));
+assert(c == 0);
+
+asm("stg %0, [%0]" : : "r"(p1));
+asm("ldg %0, [%1]" : "=r"(p2) : "r"(p0), "0"(p0));
+assert(p1 == p2);
+
+return 0;
+}
diff --git a/tests/tcg/aarch64/mte-2.c b/tests/tcg/aarch64/mte-2.c
new file mode 100644
index 00..a05f5183cb
--- /dev/null
+++ b/tests/tcg/aarch64/mte-2.c
@@ -0,0 +1,42 @@
+/*
+ * Memory tagging, basic fail cases.
+ */
+
+#include "mte.h"
+
+void pass(int sig, siginfo_t *info, void *uc)
+{
+assert(info->si_code == SEGV_MTESERR);
+exit(0);
+}
+
+int main(int ac, char **av)
+{
+struct sigaction sa;
+int *p0, *p1, *p2;
+long excl = 1;
+
+enable_mte(PR_MTE_TCF_SYNC);
+p0 = alloc_mte_mem(sizeof(*p0));
+
+/* Create two differently tagged pointers.  */
+asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(excl));
+asm("gmi %0,%1,%0" : "+r"(excl) : "r" (p1));
+assert(excl != 1);
+asm("irg %0,%1,%2" : "=r"(p2) : "r"(p0), "r"(excl));
+assert(p1 != p2);
+
+/* Store the tag from the first pointer.  */
+asm("stg %0, [%0]" : : "r"(p1));
+
+*p1 = 0;
+
+memset(, 0, sizeof(sa));
+sa.sa_sigaction = pass;
+sa.sa_flags = SA_SIGINFO;
+sigaction(SIGSEGV, , NULL);
+
+*p2 = 0;
+
+abort();
+}
diff --git a/tests/tcg/aarch64/mte-3.c b/tests/tcg/aarch64/mte-3.c
new file mode 100644
index 00..0d08b477cc
--- /dev/null
+++ b/tests/tcg/aarch64/mte-3.c
@@ -0,0 +1,47 @@
+/*
+ * Memory tagging, basic fail cases.
+ */
+
+#include "mte.h"
+
+void pass(int sig, siginfo_t *info, void *uc)
+{
+assert(info->si_code == SEGV_MTEAERR);
+exit(0);
+}
+
+int main(int ac, char **av)
+{
+struct sigaction sa;
+int *p0, *p1, *p2;
+long excl = 1;
+
+enable_mte(PR_MTE_TCF_ASYNC);
+p0 = alloc_mte_mem(sizeof(*p0));
+
+/* Create two differently tagged pointers.  */
+asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(excl));
+asm("gmi %0,%1,%0" : "+r"(excl) : "r" (p1));
+assert(excl != 1);
+asm("irg %0,%1,%2" : "=r"(p2) : "r"(p0), "r"(excl));
+assert(p1 != p2);
+
+/* Store the tag from the first pointer.  */
+asm("stg %0, [%0]" : : "r"(p1));
+
+*p1 = 0;
+
+memset(, 0, sizeof(sa));
+sa.sa_sigaction = pass;
+sa.sa_flags = SA_SIGINFO;
+sigaction(SIGSEGV, , NULL);
+
+/*
+ * Signal for async error will happen eventually.
+ 

[PATCH v3 19/21] target/arm: Add allocation tag storage for user mode

2021-01-15 Thread Richard Henderson
Use the now-saved PAGE_ANON and PAGE_MTE bits,
and the per-page saved data.

Signed-off-by: Richard Henderson 
---
 target/arm/mte_helper.c | 29 +++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index d55f8d1e1e..1c569336ea 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -78,8 +78,33 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int 
ptr_mmu_idx,
int tag_size, uintptr_t ra)
 {
 #ifdef CONFIG_USER_ONLY
-/* Tag storage not implemented.  */
-return NULL;
+uint64_t clean_ptr = useronly_clean_ptr(ptr);
+int flags = page_get_flags(clean_ptr);
+uint8_t *tags;
+uintptr_t index;
+
+if (!(flags & (ptr_access == MMU_DATA_STORE ? PAGE_WRITE : PAGE_READ))) {
+/* SIGSEGV */
+arm_cpu_tlb_fill(env_cpu(env), ptr, ptr_size, ptr_access,
+ ptr_mmu_idx, false, ra);
+g_assert_not_reached();
+}
+
+/* Require both MAP_ANON and PROT_MTE for the page. */
+if (!(flags & PAGE_ANON) || !(flags & PAGE_MTE)) {
+return NULL;
+}
+
+tags = page_get_target_data(clean_ptr);
+if (tags == NULL) {
+size_t alloc_size = TARGET_PAGE_SIZE >> (LOG2_TAG_GRANULE + 1);
+tags = page_alloc_target_data(clean_ptr, alloc_size);
+assert(tags != NULL);
+}
+
+index = extract32(ptr, LOG2_TAG_GRANULE + 1,
+  TARGET_PAGE_BITS - LOG2_TAG_GRANULE - 1);
+return tags + index;
 #else
 uintptr_t index;
 CPUIOTLBEntry *iotlbentry;
-- 
2.25.1




[PATCH v3 13/21] linux-user/aarch64: Implement PR_MTE_TCF and PR_MTE_TAG

2021-01-15 Thread Richard Henderson
These prctl fields are required for the function of MTE.

Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_syscall.h |  9 ++
 linux-user/syscall.c| 44 +
 2 files changed, 53 insertions(+)

diff --git a/linux-user/aarch64/target_syscall.h 
b/linux-user/aarch64/target_syscall.h
index 820601dfcc..76f6c3391d 100644
--- a/linux-user/aarch64/target_syscall.h
+++ b/linux-user/aarch64/target_syscall.h
@@ -33,5 +33,14 @@ struct target_pt_regs {
 #define TARGET_PR_SET_TAGGED_ADDR_CTRL 55
 #define TARGET_PR_GET_TAGGED_ADDR_CTRL 56
 # define TARGET_PR_TAGGED_ADDR_ENABLE  (1UL << 0)
+/* MTE tag check fault modes */
+# define TARGET_PR_MTE_TCF_SHIFT   1
+# define TARGET_PR_MTE_TCF_NONE(0UL << TARGET_PR_MTE_TCF_SHIFT)
+# define TARGET_PR_MTE_TCF_SYNC(1UL << TARGET_PR_MTE_TCF_SHIFT)
+# define TARGET_PR_MTE_TCF_ASYNC   (2UL << TARGET_PR_MTE_TCF_SHIFT)
+# define TARGET_PR_MTE_TCF_MASK(3UL << TARGET_PR_MTE_TCF_SHIFT)
+/* MTE tag inclusion mask */
+# define TARGET_PR_MTE_TAG_SHIFT   3
+# define TARGET_PR_MTE_TAG_MASK(0xUL << TARGET_PR_MTE_TAG_SHIFT)
 
 #endif /* AARCH64_TARGET_SYSCALL_H */
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ebb4e2898c..0316497636 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -10952,10 +10952,46 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 {
 abi_ulong valid_mask = TARGET_PR_TAGGED_ADDR_ENABLE;
 CPUARMState *env = cpu_env;
+ARMCPU *cpu = env_archcpu(env);
+
+if (cpu_isar_feature(aa64_mte, cpu)) {
+valid_mask |= TARGET_PR_MTE_TCF_MASK;
+valid_mask |= TARGET_PR_MTE_TAG_MASK;
+}
 
 if ((arg2 & ~valid_mask) || arg3 || arg4 || arg5) {
 return -TARGET_EINVAL;
 }
+
+if (cpu_isar_feature(aa64_mte, cpu)) {
+switch (arg2 & TARGET_PR_MTE_TCF_MASK) {
+case TARGET_PR_MTE_TCF_NONE:
+case TARGET_PR_MTE_TCF_SYNC:
+case TARGET_PR_MTE_TCF_ASYNC:
+break;
+default:
+return -EINVAL;
+}
+
+/*
+ * Write PR_MTE_TCF to SCTLR_EL1[TCF0].
+ * Note that the syscall values are consistent with hw.
+ */
+env->cp15.sctlr_el[1] =
+deposit64(env->cp15.sctlr_el[1], 38, 2,
+  arg2 >> TARGET_PR_MTE_TCF_SHIFT);
+
+/*
+ * Write PR_MTE_TAG to GCR_EL1[Exclude].
+ * Note that the syscall uses an include mask,
+ * and hardware uses an exclude mask -- invert.
+ */
+env->cp15.gcr_el1 =
+deposit64(env->cp15.gcr_el1, 0, 16,
+  ~arg2 >> TARGET_PR_MTE_TAG_SHIFT);
+arm_rebuild_hflags(env);
+}
+
 env->untagged_addr_mask = (arg2 & TARGET_PR_TAGGED_ADDR_ENABLE
? MAKE_64BIT_MASK(0, 56) : -1);
 return 0;
@@ -10964,6 +11000,7 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 {
 abi_long ret = 0;
 CPUARMState *env = cpu_env;
+ARMCPU *cpu = env_archcpu(env);
 
 if (arg2 || arg3 || arg4 || arg5) {
 return -TARGET_EINVAL;
@@ -10971,6 +11008,13 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 if (env->untagged_addr_mask != -1) {
 ret |= TARGET_PR_TAGGED_ADDR_ENABLE;
 }
+if (cpu_isar_feature(aa64_mte, cpu)) {
+/* See above. */
+ret |= (extract64(env->cp15.sctlr_el[1], 38, 2)
+<< TARGET_PR_MTE_TCF_SHIFT);
+ret = deposit64(ret, TARGET_PR_MTE_TAG_SHIFT, 16,
+~env->cp15.gcr_el1);
+}
 return ret;
 }
 #endif /* AARCH64 */
-- 
2.25.1




[PATCH v3 11/21] exec: Add support for TARGET_TAGGED_ADDRESSES

2021-01-15 Thread Richard Henderson
The AArch64 Linux ABI has always enabled TBI, but has historically
required that pointer tags be removed before a syscall.  This has
changed in the lead-up to ARMv8.5-MTE, in a way that affects the
ABI generically and not specifically to MTE.

This patch allows the target to indicate that (1) there are tags
and (2) whether or not they should be taken into account at the
syscall level.

Adjust g2h, guest_addr_valid, and guest_range_valid to ignore
pointer tags, similar to how TIF_TAGGED_ADDR alters __range_ok
in the arm64 kernel source.

The prctl syscall is not not yet updated, so this change by itself
has no visible effect.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu_ldst.h | 20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index e62f4fba00..1df9b93e59 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -69,17 +69,31 @@ typedef uint64_t abi_ptr;
 #define TARGET_ABI_FMT_ptr "%"PRIx64
 #endif
 
+static inline abi_ptr untagged_addr(abi_ptr x)
+{
+#ifdef TARGET_TAGGED_ADDRESSES
+if (current_cpu) {
+return cpu_untagged_addr(current_cpu, x);
+}
+#endif
+return x;
+}
+
 /* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
-#define g2h(x) ((void *)((uintptr_t)(abi_ptr)(x) + guest_base))
+static inline void *g2h(abi_ulong x)
+{
+return (void *)((uintptr_t)untagged_addr(x) + guest_base);
+}
 
 static inline bool guest_addr_valid(abi_ulong x)
 {
-return x <= GUEST_ADDR_MAX;
+return untagged_addr(x) <= GUEST_ADDR_MAX;
 }
 
 static inline bool guest_range_valid(abi_ulong start, abi_ulong len)
 {
-return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
+return len - 1 <= GUEST_ADDR_MAX &&
+   untagged_addr(start) <= GUEST_ADDR_MAX - len + 1;
 }
 
 #define h2g_valid(x) \
-- 
2.25.1




[PATCH v3 12/21] linux-user/aarch64: Implement PR_TAGGED_ADDR_ENABLE

2021-01-15 Thread Richard Henderson
This is the prctl bit that controls whether syscalls accept tagged
addresses.  See Documentation/arm64/tagged-address-abi.rst in the
linux kernel.

Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_syscall.h |  4 
 target/arm/cpu-param.h  |  3 +++
 target/arm/cpu.h| 23 +++
 linux-user/syscall.c| 25 +
 target/arm/cpu.c|  3 +++
 5 files changed, 58 insertions(+)

diff --git a/linux-user/aarch64/target_syscall.h 
b/linux-user/aarch64/target_syscall.h
index 3194e6b009..820601dfcc 100644
--- a/linux-user/aarch64/target_syscall.h
+++ b/linux-user/aarch64/target_syscall.h
@@ -30,4 +30,8 @@ struct target_pt_regs {
 # define TARGET_PR_PAC_APDBKEY   (1 << 3)
 # define TARGET_PR_PAC_APGAKEY   (1 << 4)
 
+#define TARGET_PR_SET_TAGGED_ADDR_CTRL 55
+#define TARGET_PR_GET_TAGGED_ADDR_CTRL 56
+# define TARGET_PR_TAGGED_ADDR_ENABLE  (1UL << 0)
+
 #endif /* AARCH64_TARGET_SYSCALL_H */
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
index 6321385b46..f922aa0650 100644
--- a/target/arm/cpu-param.h
+++ b/target/arm/cpu-param.h
@@ -20,6 +20,9 @@
 
 #ifdef CONFIG_USER_ONLY
 #define TARGET_PAGE_BITS 12
+# ifdef TARGET_AARCH64
+#  define TARGET_TAGGED_ADDRESSES
+# endif
 #else
 /*
  * ARMv7 and later CPUs have 4K pages minimum, but ARMv5 and v6
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index f3bca73d98..6ddfd9ebe6 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -712,6 +712,10 @@ typedef struct CPUARMState {
 const struct arm_boot_info *boot_info;
 /* Store GICv3CPUState to access from this struct */
 void *gicv3state;
+
+#ifdef TARGET_TAGGED_ADDRESSES
+target_ulong untagged_addr_mask;
+#endif
 } CPUARMState;
 
 static inline void set_feature(CPUARMState *env, int feature)
@@ -3556,6 +3560,25 @@ static inline MemTxAttrs 
*typecheck_memtxattrs(MemTxAttrs *x)
  */
 #define PAGE_BTI  PAGE_TARGET_1
 
+#ifdef TARGET_TAGGED_ADDRESSES
+/**
+ * cpu_untagged_addr:
+ * @cs: CPU context
+ * @x: tagged address
+ *
+ * Remove any address tag from @x.  This is explicitly related to the
+ * linux syscall TIF_TAGGED_ADDR setting, not TBI in general.
+ *
+ * There should be a better place to put this, but we need this in
+ * include/exec/cpu_ldst.h, and not some place linux-user specific.
+ */
+static inline target_ulong cpu_untagged_addr(CPUState *cs, target_ulong x)
+{
+ARMCPU *cpu = ARM_CPU(cs);
+return x & cpu->env.untagged_addr_mask;
+}
+#endif
+
 /*
  * Naming convention for isar_feature functions:
  * Functions which test 32-bit ID registers should have _aa32_ in
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bec2ab7769..ebb4e2898c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -10948,6 +10948,31 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 }
 }
 return -TARGET_EINVAL;
+case TARGET_PR_SET_TAGGED_ADDR_CTRL:
+{
+abi_ulong valid_mask = TARGET_PR_TAGGED_ADDR_ENABLE;
+CPUARMState *env = cpu_env;
+
+if ((arg2 & ~valid_mask) || arg3 || arg4 || arg5) {
+return -TARGET_EINVAL;
+}
+env->untagged_addr_mask = (arg2 & TARGET_PR_TAGGED_ADDR_ENABLE
+   ? MAKE_64BIT_MASK(0, 56) : -1);
+return 0;
+}
+case TARGET_PR_GET_TAGGED_ADDR_CTRL:
+{
+abi_long ret = 0;
+CPUARMState *env = cpu_env;
+
+if (arg2 || arg3 || arg4 || arg5) {
+return -TARGET_EINVAL;
+}
+if (env->untagged_addr_mask != -1) {
+ret |= TARGET_PR_TAGGED_ADDR_ENABLE;
+}
+return ret;
+}
 #endif /* AARCH64 */
 case PR_GET_SECCOMP:
 case PR_SET_SECCOMP:
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 8387e94b94..abc0affd00 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -208,6 +208,9 @@ static void arm_cpu_reset(DeviceState *dev)
  * Do not modify this without other changes.
  */
 env->cp15.tcr_el[1].raw_tcr = (3ULL << 37);
+# ifdef TARGET_TAGGED_ADDRESSES
+env->untagged_addr_mask = -1;
+# endif
 #else
 /* Reset into the highest available EL */
 if (arm_feature(env, ARM_FEATURE_EL3)) {
-- 
2.25.1




[PATCH v3 07/21] linux-user: Tidy VERIFY_READ/VERIFY_WRITE

2021-01-15 Thread Richard Henderson
These constants are only ever used with access_ok, and friends.
Rather than translating them to PAGE_* bits, let them equal
the PAGE_* bits to begin.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 linux-user/qemu.h | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index a0f670832e..329a6de669 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -486,8 +486,8 @@ extern unsigned long guest_stack_size;
 
 /* user access */
 
-#define VERIFY_READ 0
-#define VERIFY_WRITE 1 /* implies read access */
+#define VERIFY_READ  PAGE_READ
+#define VERIFY_WRITE (PAGE_READ | PAGE_WRITE)
 
 static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
 {
@@ -499,9 +499,7 @@ static inline bool access_ok(int type, abi_ulong addr, 
abi_ulong size)
  !guest_addr_valid(addr + size - 1))) {
 return false;
 }
-return page_check_range((target_ulong)addr, size,
-(type == VERIFY_READ) ? PAGE_READ :
-(PAGE_READ | PAGE_WRITE)) == 0;
+return page_check_range((target_ulong)addr, size, type) == 0;
 }
 
 /* NOTE __get_user and __put_user use host pointers and don't check access.
-- 
2.25.1




[PATCH v3 16/21] linux-user/aarch64: Pass syndrome to EXC_*_ABORT

2021-01-15 Thread Richard Henderson
A proper syndrome is required to fill in the proper si_code.
Use page_get_flags to determine permission vs translation for user-only.

Signed-off-by: Richard Henderson 
---
v3: Use syndrome.h, arm_deliver_fault.
---
 linux-user/aarch64/cpu_loop.c | 24 +---
 target/arm/tlb_helper.c   | 15 +--
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index bbe9fefca8..7811440c68 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -22,6 +22,7 @@
 #include "qemu.h"
 #include "cpu_loop-common.h"
 #include "qemu/guest-random.h"
+#include "target/arm/syndrome.h"
 
 #define get_user_code_u32(x, gaddr, env)\
 ({ abi_long __r = get_user_u32((x), (gaddr));   \
@@ -75,7 +76,7 @@
 void cpu_loop(CPUARMState *env)
 {
 CPUState *cs = env_cpu(env);
-int trapnr;
+int trapnr, ec, fsc;
 abi_long ret;
 target_siginfo_t info;
 
@@ -116,9 +117,26 @@ void cpu_loop(CPUARMState *env)
 case EXCP_DATA_ABORT:
 info.si_signo = TARGET_SIGSEGV;
 info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
 info._sifields._sigfault._addr = env->exception.vaddress;
+
+/* We should only arrive here with EC in {DATAABORT, INSNABORT}. */
+ec = syn_get_ec(env->exception.syndrome);
+assert(ec == EC_DATAABORT || ec == EC_INSNABORT);
+
+/* Both EC have the same format for FSC, or close enough. */
+fsc = extract32(env->exception.syndrome, 0, 6);
+switch (fsc) {
+case 0x04 ... 0x07: /* Translation fault, level {0-3} */
+info.si_code = TARGET_SEGV_MAPERR;
+break;
+case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
+case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
+info.si_code = TARGET_SEGV_ACCERR;
+break;
+default:
+g_assert_not_reached();
+}
+
 queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
 break;
 case EXCP_DEBUG:
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
index b35dc8a011..31015749fd 100644
--- a/target/arm/tlb_helper.c
+++ b/target/arm/tlb_helper.c
@@ -151,21 +151,24 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
   bool probe, uintptr_t retaddr)
 {
 ARMCPU *cpu = ARM_CPU(cs);
+ARMMMUFaultInfo fi = {};
 
 #ifdef CONFIG_USER_ONLY
-cpu->env.exception.vaddress = address;
-if (access_type == MMU_INST_FETCH) {
-cs->exception_index = EXCP_PREFETCH_ABORT;
+int flags = page_get_flags(useronly_clean_ptr(address));
+if (flags & PAGE_VALID) {
+fi.type = ARMFault_Permission;
 } else {
-cs->exception_index = EXCP_DATA_ABORT;
+fi.type = ARMFault_Translation;
 }
-cpu_loop_exit_restore(cs, retaddr);
+
+/* now we have a real cpu fault */
+cpu_restore_state(cs, retaddr, true);
+arm_deliver_fault(cpu, address, access_type, mmu_idx, );
 #else
 hwaddr phys_addr;
 target_ulong page_size;
 int prot, ret;
 MemTxAttrs attrs = {};
-ARMMMUFaultInfo fi = {};
 ARMCacheAttrs cacheattrs = {};
 
 /*
-- 
2.25.1




[PATCH v3 09/21] linux-user: Do not use guest_addr_valid for h2g_valid

2021-01-15 Thread Richard Henderson
This is the only use of guest_addr_valid that does not begin
with a guest address, but a host address being transformed to
a guest address.

We will shortly adjust guest_addr_valid to handle guest memory
tags, and the host address should not be subjected to that.

Move h2g_valid adjacent to the other h2g macros.

Signed-off-by: Richard Henderson 
---
v3: Ditch type changes; retain true for HLB <= GAM (pmm).
---
 include/exec/cpu_ldst.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index 5e8878ee9b..4e6ef3d542 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -77,13 +77,16 @@ typedef uint64_t abi_ptr;
 #else
 #define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
 #endif
-#define h2g_valid(x) guest_addr_valid((uintptr_t)(x) - guest_base)
 
 static inline bool guest_range_valid(abi_ulong start, abi_ulong len)
 {
 return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
 }
 
+#define h2g_valid(x) \
+(HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS || \
+ (uintptr_t)(x) - guest_base <= GUEST_ADDR_MAX)
+
 #define h2g_nocheck(x) ({ \
 uintptr_t __ret = (uintptr_t)(x) - guest_base; \
 (abi_ptr)__ret; \
-- 
2.25.1




[PATCH v3 17/21] linux-user/aarch64: Signal SEGV_MTESERR for sync tag check fault

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_signal.h | 2 ++
 linux-user/aarch64/cpu_loop.c  | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/linux-user/aarch64/target_signal.h 
b/linux-user/aarch64/target_signal.h
index ddd73169f0..777fb667fe 100644
--- a/linux-user/aarch64/target_signal.h
+++ b/linux-user/aarch64/target_signal.h
@@ -21,5 +21,7 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
+#define TARGET_SEGV_MTESERR  9  /* Synchronous ARM MTE exception */
+
 #define TARGET_ARCH_HAS_SETUP_FRAME
 #endif /* AARCH64_TARGET_SIGNAL_H */
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index 7811440c68..6867f0db2b 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -133,6 +133,9 @@ void cpu_loop(CPUARMState *env)
 case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
 info.si_code = TARGET_SEGV_ACCERR;
 break;
+case 0x11: /* Synchronous Tag Check Fault */
+info.si_code = TARGET_SEGV_MTESERR;
+break;
 default:
 g_assert_not_reached();
 }
-- 
2.25.1




[PATCH v3 04/21] exec: Use uintptr_t in cpu_ldst.h

2021-01-15 Thread Richard Henderson
This is more descriptive than 'unsigned long'.
No functional change, since these match on all linux+bsd hosts.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu_ldst.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index ef54cb7e1f..3f9063aade 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -70,14 +70,14 @@ typedef uint64_t abi_ptr;
 #endif
 
 /* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
-#define g2h(x) ((void *)((unsigned long)(abi_ptr)(x) + guest_base))
+#define g2h(x) ((void *)((uintptr_t)(abi_ptr)(x) + guest_base))
 
 #if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
 #define guest_addr_valid(x) (1)
 #else
 #define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
 #endif
-#define h2g_valid(x) guest_addr_valid((unsigned long)(x) - guest_base)
+#define h2g_valid(x) guest_addr_valid((uintptr_t)(x) - guest_base)
 
 static inline int guest_range_valid(unsigned long start, unsigned long len)
 {
@@ -85,7 +85,7 @@ static inline int guest_range_valid(unsigned long start, 
unsigned long len)
 }
 
 #define h2g_nocheck(x) ({ \
-unsigned long __ret = (unsigned long)(x) - guest_base; \
+uintptr_t __ret = (uintptr_t)(x) - guest_base; \
 (abi_ptr)__ret; \
 })
 
-- 
2.25.1




[PATCH v3 08/21] bsd-user: Tidy VERIFY_READ/VERIFY_WRITE

2021-01-15 Thread Richard Henderson
These constants are only ever used with access_ok, and friends.
Rather than translating them to PAGE_* bits, let them equal
the PAGE_* bits to begin.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 bsd-user/qemu.h | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index f8bb1e5459..4076adabd0 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -218,13 +218,12 @@ extern unsigned long x86_stack_size;
 
 /* user access */
 
-#define VERIFY_READ 0
-#define VERIFY_WRITE 1 /* implies read access */
+#define VERIFY_READ  PAGE_READ
+#define VERIFY_WRITE (PAGE_READ | PAGE_WRITE)
 
-static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
+static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
 {
-return page_check_range((target_ulong)addr, size,
-(type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | 
PAGE_WRITE)) == 0;
+return page_check_range((target_ulong)addr, size, type) == 0;
 }
 
 /* NOTE __get_user and __put_user use host pointers and don't check access. */
-- 
2.25.1




[PATCH v3 03/21] exec: Use uintptr_t for guest_base

2021-01-15 Thread Richard Henderson
This is more descriptive than 'unsigned long'.
No functional change, since these match on all linux+bsd hosts.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu-all.h | 2 +-
 bsd-user/main.c| 2 +-
 linux-user/main.c  | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index c23c77589b..c52180e8e6 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -158,7 +158,7 @@ static inline void tswap64s(uint64_t *s)
 /* On some host systems the guest address space is reserved on the host.
  * This allows the guest address space to be offset to a convenient location.
  */
-extern unsigned long guest_base;
+extern uintptr_t guest_base;
 extern bool have_guest_base;
 extern unsigned long reserved_va;
 
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 65163e1396..5c8e6a4acd 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -41,7 +41,7 @@
 
 int singlestep;
 unsigned long mmap_min_addr;
-unsigned long guest_base;
+uintptr_t guest_base;
 bool have_guest_base;
 unsigned long reserved_va;
 
diff --git a/linux-user/main.c b/linux-user/main.c
index bb4e55e8fc..2600245300 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -58,7 +58,7 @@ static const char *cpu_model;
 static const char *cpu_type;
 static const char *seed_optarg;
 unsigned long mmap_min_addr;
-unsigned long guest_base;
+uintptr_t guest_base;
 bool have_guest_base;
 
 /*
-- 
2.25.1




[PATCH v3 05/21] exec: Improve types for guest_addr_valid

2021-01-15 Thread Richard Henderson
Return bool not int; pass abi_ulong not 'unsigned long'.
All callers use abi_ulong already, so the change in type
has no effect.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu_ldst.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index 3f9063aade..5e8878ee9b 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -79,7 +79,7 @@ typedef uint64_t abi_ptr;
 #endif
 #define h2g_valid(x) guest_addr_valid((uintptr_t)(x) - guest_base)
 
-static inline int guest_range_valid(unsigned long start, unsigned long len)
+static inline bool guest_range_valid(abi_ulong start, abi_ulong len)
 {
 return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
 }
-- 
2.25.1




[PATCH v3 14/21] linux-user/aarch64: Implement PROT_MTE

2021-01-15 Thread Richard Henderson
Remember the PROT_MTE bit as PAGE_MTE/PAGE_TARGET_2.
Otherwise this does not yet have effect.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
v3: Do not overlap PAGE_TARGET_2 with PAGE_RESERVED.
---
 include/exec/cpu-all.h|  1 +
 linux-user/syscall_defs.h |  1 +
 target/arm/cpu.h  |  1 +
 linux-user/mmap.c | 22 ++
 4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index c52180e8e6..b2a72f70ec 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -284,6 +284,7 @@ extern intptr_t qemu_host_page_mask;
 #endif
 /* Target-specific bits that will be used via page_get_flags().  */
 #define PAGE_TARGET_1  0x0080
+#define PAGE_TARGET_2  0x0200
 
 #if defined(CONFIG_USER_ONLY)
 void page_dump(FILE *f);
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index a00bfc2647..0d6bb1ff8b 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -1311,6 +1311,7 @@ struct target_winsize {
 
 #ifdef TARGET_AARCH64
 #define TARGET_PROT_BTI 0x10
+#define TARGET_PROT_MTE 0x20
 #endif
 
 /* Common */
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 6ddfd9ebe6..e14c9a6277 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3559,6 +3559,7 @@ static inline MemTxAttrs *typecheck_memtxattrs(MemTxAttrs 
*x)
  * AArch64 usage of the PAGE_TARGET_* bits for linux-user.
  */
 #define PAGE_BTI  PAGE_TARGET_1
+#define PAGE_MTE  PAGE_TARGET_2
 
 #ifdef TARGET_TAGGED_ADDRESSES
 /**
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 7fb4c628e1..34bd114f97 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -84,18 +84,24 @@ static int validate_prot_to_pageflags(int *host_prot, int 
prot)
| (prot & PROT_EXEC ? PROT_READ : 0);
 
 #ifdef TARGET_AARCH64
-/*
- * The PROT_BTI bit is only accepted if the cpu supports the feature.
- * Since this is the unusual case, don't bother checking unless
- * the bit has been requested.  If set and valid, record the bit
- * within QEMU's page_flags.
- */
-if (prot & TARGET_PROT_BTI) {
+{
 ARMCPU *cpu = ARM_CPU(thread_cpu);
-if (cpu_isar_feature(aa64_bti, cpu)) {
+
+/*
+ * The PROT_BTI bit is only accepted if the cpu supports the feature.
+ * Since this is the unusual case, don't bother checking unless
+ * the bit has been requested.  If set and valid, record the bit
+ * within QEMU's page_flags.
+ */
+if ((prot & TARGET_PROT_BTI) && cpu_isar_feature(aa64_bti, cpu)) {
 valid |= TARGET_PROT_BTI;
 page_flags |= PAGE_BTI;
 }
+/* Similarly for the PROT_MTE bit. */
+if ((prot & TARGET_PROT_MTE) && cpu_isar_feature(aa64_mte, cpu)) {
+valid |= TARGET_PROT_MTE;
+page_flags |= PAGE_MTE;
+}
 }
 #endif
 
-- 
2.25.1




[PATCH v3 06/21] linux-user: Check for overflow in access_ok

2021-01-15 Thread Richard Henderson
Verify that addr + size - 1 does not wrap around.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 linux-user/qemu.h | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 534753ca12..a0f670832e 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -489,12 +489,19 @@ extern unsigned long guest_stack_size;
 #define VERIFY_READ 0
 #define VERIFY_WRITE 1 /* implies read access */
 
-static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
+static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
 {
-return guest_addr_valid(addr) &&
-   (size == 0 || guest_addr_valid(addr + size - 1)) &&
-   page_check_range((target_ulong)addr, size,
-(type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | 
PAGE_WRITE)) == 0;
+if (!guest_addr_valid(addr)) {
+return false;
+}
+if (size != 0 &&
+(addr + size - 1 < addr ||
+ !guest_addr_valid(addr + size - 1))) {
+return false;
+}
+return page_check_range((target_ulong)addr, size,
+(type == VERIFY_READ) ? PAGE_READ :
+(PAGE_READ | PAGE_WRITE)) == 0;
 }
 
 /* NOTE __get_user and __put_user use host pointers and don't check access.
-- 
2.25.1




[PATCH v3 02/21] linux-user: Introduce PAGE_ANON

2021-01-15 Thread Richard Henderson
Record whether the backing page is anonymous, or if it has file
backing.  This will allow us to get close to the Linux AArch64
ABI for MTE, which allows tag memory only on ram-backed VMAs.

The real ABI allows tag memory on files, when those files are
on ram-backed filesystems, such as tmpfs.  We will not be able
to implement that in QEMU linux-user.

Thankfully, anonymous memory for malloc arenas is the primary
consumer of this feature, so this restricted version should
still be of use.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 include/exec/cpu-all.h | 2 ++
 linux-user/mmap.c  | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 99a09ee137..c23c77589b 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -275,6 +275,8 @@ extern intptr_t qemu_host_page_mask;
 #define PAGE_WRITE_INV 0x0020
 /* For use with page_set_flags: page is being replaced; target_data cleared. */
 #define PAGE_RESET 0x0040
+/* For linux-user, indicates that the page is MAP_ANON. */
+#define PAGE_ANON  0x0080
 
 #if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
 /* FIXME: Code that sets/uses this is broken and needs to go away.  */
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index c693505b60..7fb4c628e1 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -599,6 +599,9 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
target_prot,
 }
 }
  the_end1:
+if (flags & MAP_ANONYMOUS) {
+page_flags |= PAGE_ANON;
+}
 page_flags |= PAGE_RESET;
 page_set_flags(start, start + len, page_flags);
  the_end:
-- 
2.25.1




[PATCH v3 10/21] linux-user: Fix guest_addr_valid vs reserved_va

2021-01-15 Thread Richard Henderson
We must always use GUEST_ADDR_MAX, because even 32-bit hosts can
use -R  to restrict the memory address of the guest.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu_ldst.h | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index 4e6ef3d542..e62f4fba00 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -72,11 +72,10 @@ typedef uint64_t abi_ptr;
 /* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
 #define g2h(x) ((void *)((uintptr_t)(abi_ptr)(x) + guest_base))
 
-#if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
-#define guest_addr_valid(x) (1)
-#else
-#define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
-#endif
+static inline bool guest_addr_valid(abi_ulong x)
+{
+return x <= GUEST_ADDR_MAX;
+}
 
 static inline bool guest_range_valid(abi_ulong start, abi_ulong len)
 {
-- 
2.25.1




[PATCH v3 00/21] target-arm: Implement ARMv8.5-MemTag, user mode

2021-01-15 Thread Richard Henderson
The kernel abi was finally merged into 5.10.

Changes for v3:
  * Split out type changes to separate patches.
  * Add doc comments; tweak alloc so that the !PAGE_VALID case is clear.
  * Do not overlap PAGE_TARGET_2 with PAGE_RESERVED.
  * Use syndrome.h, arm_deliver_fault.


r~


v1: 
https://patchew.org/QEMU/20191015163254.12041-1-richard.hender...@linaro.org/
v2: 
https://patchew.org/QEMU/20200605041733.415188-1-richard.hender...@linaro.org/

Richard Henderson (21):
  tcg: Introduce target-specific page data for user-only
  linux-user: Introduce PAGE_ANON
  exec: Use uintptr_t for guest_base
  exec: Use uintptr_t in cpu_ldst.h
  exec: Improve types for guest_addr_valid
  linux-user: Check for overflow in access_ok
  linux-user: Tidy VERIFY_READ/VERIFY_WRITE
  bsd-user: Tidy VERIFY_READ/VERIFY_WRITE
  linux-user: Do not use guest_addr_valid for h2g_valid
  linux-user: Fix guest_addr_valid vs reserved_va
  exec: Add support for TARGET_TAGGED_ADDRESSES
  linux-user/aarch64: Implement PR_TAGGED_ADDR_ENABLE
  linux-user/aarch64: Implement PR_MTE_TCF and PR_MTE_TAG
  linux-user/aarch64: Implement PROT_MTE
  target/arm: Split out syndrome.h from internals.h
  linux-user/aarch64: Pass syndrome to EXC_*_ABORT
  linux-user/aarch64: Signal SEGV_MTESERR for sync tag check fault
  linux-user/aarch64: Signal SEGV_MTEAERR for async tag check error
  target/arm: Add allocation tag storage for user mode
  target/arm: Enable MTE for user-only
  tests/tcg/aarch64: Add mte smoke tests

 bsd-user/qemu.h |   9 +-
 include/exec/cpu-all.h  |  47 -
 include/exec/cpu_ldst.h |  42 +++--
 linux-user/aarch64/target_signal.h  |   3 +
 linux-user/aarch64/target_syscall.h |  13 ++
 linux-user/qemu.h   |  19 +-
 linux-user/syscall_defs.h   |   1 +
 target/arm/cpu-param.h  |   3 +
 target/arm/cpu.h|  24 +++
 target/arm/internals.h  | 245 +
 target/arm/syndrome.h   | 273 
 tests/tcg/aarch64/mte.h |  53 ++
 accel/tcg/translate-all.c   |  28 +++
 bsd-user/main.c |   2 +-
 linux-user/aarch64/cpu_loop.c   |  61 +--
 linux-user/main.c   |   2 +-
 linux-user/mmap.c   |  29 ++-
 linux-user/syscall.c|  73 +++-
 target/arm/cpu.c|  19 ++
 target/arm/mte_helper.c |  39 +++-
 target/arm/tlb_helper.c |  15 +-
 tests/tcg/aarch64/mte-1.c   |  25 +++
 tests/tcg/aarch64/mte-2.c   |  42 +
 tests/tcg/aarch64/mte-3.c   |  47 +
 tests/tcg/aarch64/mte-4.c   |  42 +
 tests/tcg/aarch64/Makefile.target   |   6 +
 tests/tcg/configure.sh  |   4 +
 27 files changed, 856 insertions(+), 310 deletions(-)
 create mode 100644 target/arm/syndrome.h
 create mode 100644 tests/tcg/aarch64/mte.h
 create mode 100644 tests/tcg/aarch64/mte-1.c
 create mode 100644 tests/tcg/aarch64/mte-2.c
 create mode 100644 tests/tcg/aarch64/mte-3.c
 create mode 100644 tests/tcg/aarch64/mte-4.c

-- 
2.25.1




[PATCH v3 01/21] tcg: Introduce target-specific page data for user-only

2021-01-15 Thread Richard Henderson
This data can be allocated by page_alloc_target_data() and
released by page_set_flags(start, end, prot | PAGE_RESET).

This data will be used to hold tag memory for AArch64 MTE.

Signed-off-by: Richard Henderson 
---
v3: Add doc comments; tweak alloc so that the !PAGE_VALID case is clear.
---
 include/exec/cpu-all.h| 42 +--
 accel/tcg/translate-all.c | 28 ++
 linux-user/mmap.c |  4 +++-
 linux-user/syscall.c  |  4 ++--
 4 files changed, 69 insertions(+), 9 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 4b5408c341..99a09ee137 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -264,15 +264,21 @@ extern intptr_t qemu_host_page_mask;
 #define PAGE_EXEC  0x0004
 #define PAGE_BITS  (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
 #define PAGE_VALID 0x0008
-/* original state of the write flag (used when tracking self-modifying
-   code */
+/*
+ * Original state of the write flag (used when tracking self-modifying code)
+ */
 #define PAGE_WRITE_ORG 0x0010
-/* Invalidate the TLB entry immediately, helpful for s390x
- * Low-Address-Protection. Used with PAGE_WRITE in tlb_set_page_with_attrs() */
-#define PAGE_WRITE_INV 0x0040
+/*
+ * Invalidate the TLB entry immediately, helpful for s390x
+ * Low-Address-Protection. Used with PAGE_WRITE in tlb_set_page_with_attrs()
+ */
+#define PAGE_WRITE_INV 0x0020
+/* For use with page_set_flags: page is being replaced; target_data cleared. */
+#define PAGE_RESET 0x0040
+
 #if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
 /* FIXME: Code that sets/uses this is broken and needs to go away.  */
-#define PAGE_RESERVED  0x0020
+#define PAGE_RESERVED  0x0100
 #endif
 /* Target-specific bits that will be used via page_get_flags().  */
 #define PAGE_TARGET_1  0x0080
@@ -287,6 +293,30 @@ int walk_memory_regions(void *, walk_memory_regions_fn);
 int page_get_flags(target_ulong address);
 void page_set_flags(target_ulong start, target_ulong end, int flags);
 int page_check_range(target_ulong start, target_ulong len, int flags);
+
+/**
+ * page_alloc_target_data(address, size)
+ * @address: guest virtual address
+ * @size: size of data to allocate
+ *
+ * Allocate @size bytes of out-of-band data to associate with the
+ * guest page at @address.  If the page is not mapped, NULL will
+ * be returned.  If there is existing data associated with @address,
+ * no new memory will be allocated.
+ *
+ * The memory will be freed when the guest page is deallocated,
+ * e.g. with the munmap system call.
+ */
+void *page_alloc_target_data(target_ulong address, size_t size);
+
+/**
+ * page_get_target_data(address)
+ * @address: guest virtual address
+ *
+ * Return any out-of-bound memory assocated with the guest page
+ * at @address, as per page_alloc_target_data.
+ */
+void *page_get_target_data(target_ulong address);
 #endif
 
 CPUArchState *cpu_copy(CPUArchState *env);
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index e9de6ff9dd..7bcb6663f1 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -113,6 +113,7 @@ typedef struct PageDesc {
 unsigned int code_write_count;
 #else
 unsigned long flags;
+void *target_data;
 #endif
 #ifndef CONFIG_USER_ONLY
 QemuSpin lock;
@@ -2740,6 +2741,7 @@ int page_get_flags(target_ulong address)
 void page_set_flags(target_ulong start, target_ulong end, int flags)
 {
 target_ulong addr, len;
+bool reset_target_data;
 
 /* This function should never be called with addresses outside the
guest address space.  If this assert fires, it probably indicates
@@ -2754,6 +2756,8 @@ void page_set_flags(target_ulong start, target_ulong end, 
int flags)
 if (flags & PAGE_WRITE) {
 flags |= PAGE_WRITE_ORG;
 }
+reset_target_data = !(flags & PAGE_VALID) || (flags & PAGE_RESET);
+flags &= ~PAGE_RESET;
 
 for (addr = start, len = end - start;
  len != 0;
@@ -2767,10 +2771,34 @@ void page_set_flags(target_ulong start, target_ulong 
end, int flags)
 p->first_tb) {
 tb_invalidate_phys_page(addr, 0);
 }
+if (reset_target_data && p->target_data) {
+g_free(p->target_data);
+p->target_data = NULL;
+}
 p->flags = flags;
 }
 }
 
+void *page_get_target_data(target_ulong address)
+{
+PageDesc *p = page_find(address >> TARGET_PAGE_BITS);
+return p ? p->target_data : NULL;
+}
+
+void *page_alloc_target_data(target_ulong address, size_t size)
+{
+PageDesc *p = page_find(address >> TARGET_PAGE_BITS);
+void *ret = NULL;
+
+if (p->flags & PAGE_VALID) {
+ret = p->target_data;
+if (!ret) {
+p->target_data = ret = g_malloc0(size);
+}
+}
+return ret;
+}
+
 int page_check_range(target_ulong start, target_ulong len, int flags)
 {
 PageDesc *p;
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 

Re: [PATCH 3/4] tests/qtest: Only run fuzz-megasas-test if megasas device is available

2021-01-15 Thread Alexander Bulekov
On 210115 1609, Philippe Mathieu-Daudé wrote:
> This test fails when QEMU is built without the megasas device,
> restrict it to its availability.

Should we just make a separate directory for fuzzer tests and have a
separate source file for each reproducer (or for each device)? That way,
we avoid confusion about what to do with new reproducers: they always go
into e.g. tests/qtest/reproducers/device_name.c 



Re: [PATCH v2 09/22] tcg/riscv: Split out target constraints to tcg-target-con-str.h

2021-01-15 Thread Richard Henderson
On 1/15/21 12:13 PM, Alistair Francis wrote:
> On Fri, Jan 15, 2021 at 1:09 PM Richard Henderson
>  wrote:
>>
>> Signed-off-by: Richard Henderson 
>> ---
>>  tcg/riscv/tcg-target-con-str.h | 21 ++
>>  tcg/riscv/tcg-target.h |  1 +
>>  tcg/riscv/tcg-target.c.inc | 50 --
>>  3 files changed, 33 insertions(+), 39 deletions(-)
>>  create mode 100644 tcg/riscv/tcg-target-con-str.h
>>
>> diff --git a/tcg/riscv/tcg-target-con-str.h b/tcg/riscv/tcg-target-con-str.h
>> new file mode 100644
>> index 00..587fcd3593
>> --- /dev/null
>> +++ b/tcg/riscv/tcg-target-con-str.h
>> @@ -0,0 +1,21 @@
>> +/* SPDX-License-Identifier: MIT */
>> +/*
>> + * Define RISC-V target-specific operand constraints.
>> + * Copyright (c) 2021 Linaro
>> + */
>> +
>> +/*
>> + * Define constraint letters for register sets:
>> + * REGS(letter, register_mask)
>> + */
>> +REGS('r', ALL_GENERAL_REGS)
>> +REGS('L', ALL_QLDST_REGS)
>> +
>> +/*
>> + * Define constraint letters for constants:
>> + * CONST(letter, TCG_CT_CONST_* bit set)
>> + */
>> +CONST('I', TCG_CT_CONST_S12)
>> +CONST('N', TCG_CT_CONST_N12)
>> +CONST('M', TCG_CT_CONST_M12)
>> +CONST('Z', TCG_CT_CONST_ZERO)
>> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
>> index 727c8df418..daf3ef7b5c 100644
>> --- a/tcg/riscv/tcg-target.h
>> +++ b/tcg/riscv/tcg-target.h
>> @@ -171,5 +171,6 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
>> uintptr_t, uintptr_t);
>>  #define TCG_TARGET_NEED_POOL_LABELS
>>
>>  #define TCG_TARGET_HAS_MEMORY_BSWAP 0
>> +#define TCG_TARGET_CON_STR_H
>>
>>  #endif
>> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
>> index 71c0badc02..185b569f4b 100644
>> --- a/tcg/riscv/tcg-target.c.inc
>> +++ b/tcg/riscv/tcg-target.c.inc
>> @@ -122,6 +122,17 @@ static const int tcg_target_call_oarg_regs[] = {
>>  #define TCG_CT_CONST_N12   0x400
>>  #define TCG_CT_CONST_M12   0x800
>>
>> +#define ALL_GENERAL_REGS  0xu
>> +#ifdef CONFIG_SOFTMMU
>> +#define ALL_QLDST_REGS \
>> +(ALL_GENERAL_REGS & ~((1 << TCG_REG_A0) | (1 << TCG_REG_A1) | \
>> +  (1 << TCG_REG_A2) | (1 << TCG_REG_A3) | \
>> +  (1 << TCG_REG_A5)))
> 
> Why is this not TCG_REG_A4?

Typo, thanks.


r~



Re: [PATCH] hw/riscv: microchip_pfsoc: specify XIP image

2021-01-15 Thread Alistair Francis
On Tue, Jan 12, 2021 at 4:11 AM Vitaly Wool  wrote:
>
> Hi Bin,
>
> On Tue, Jan 5, 2021 at 7:27 AM Bin Meng  wrote:
> >
> > +Alistair Francis
> >
> > On Sat, Dec 19, 2020 at 8:24 AM Vitaly Wool  
> > wrote:
> > >
> > > Add command line parameter to microchip_pfsoc machine to be able
> > > to specify XIP kernel image file. To pass over XIP image file, it
> > > will be enough to run
> > >
> > > $ qemu-system-riscv64 -M microchip-icicle-kit,xipImage= ...
> > >
> > > Signed-off-by: Vitaly Wool 
> > > ---
> > >  hw/riscv/microchip_pfsoc.c | 42 +++---
> > >  include/hw/riscv/microchip_pfsoc.h |  1 +
> > >  2 files changed, 39 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
> > > index e952b49e8c..04d81d52fe 100644
> > > --- a/hw/riscv/microchip_pfsoc.c
> > > +++ b/hw/riscv/microchip_pfsoc.c
> > > @@ -181,6 +181,7 @@ static void microchip_pfsoc_soc_instance_init(Object 
> > > *obj)
> > >  static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
> > >  {
> > >  MachineState *ms = MACHINE(qdev_get_machine());
> > > +MicrochipIcicleKitState *mks = MICROCHIP_ICICLE_KIT_MACHINE(ms);
> > >  MicrochipPFSoCState *s = MICROCHIP_PFSOC(dev);
> > >  const struct MemmapEntry *memmap = microchip_pfsoc_memmap;
> > >  MemoryRegion *system_memory = get_system_memory();
> > > @@ -415,10 +416,19 @@ static void microchip_pfsoc_soc_realize(DeviceState 
> > > *dev, Error **errp)
> > >  memmap[MICROCHIP_PFSOC_IOSCB].base);
> > >
> > >  /* QSPI Flash */
> > > -memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
> >
> > I believe we only need to change this to memory_region_init_ram(),
> > then use the device loader the load the XIP image into this space. The
> > remove the need to introduce the XIP image property as you did.
>
> I think it should be possible to use the device loader with rom as
> well, and in this case we can skip this patch altogether. However, my
> idea was that specifying explicitly it's not just a random data being
> loaded but a kernel image in the XIP format would make things clearer.
> OTOH, I would then introduce a property that isn't strictly speaking
> necessary. I'll let Alistair decide what is the best way to go :)

In general I would say let's avoid machine properties. The more
aligned we can be to general QEMU arguments the better. That way
someone swapping from some other platform shouldn't have too much
trouble getting started.

Ideally we want to use either the device loader or the `-drive`
argument for loading these images. The RISC-V virt machine has -drive
support, maybe that is what you want here instead?

Alistair

>
> ~Vitaly
>
> >
> > > -   "microchip.pfsoc.qspi_xip",
> > > -   memmap[MICROCHIP_PFSOC_QSPI_XIP].size,
> > > -   _fatal);
> > > +if (mks->xip_image) {
> > > +memory_region_init_ram_from_file(qspi_xip_mem, OBJECT(dev),
> > > + "microchip.pfsoc.qspi_xip",
> > > + 
> > > memmap[MICROCHIP_PFSOC_QSPI_XIP].size,
> > > + 0x1 /* align */, 0 /* 
> > > ram_flags */,
> > > + mks->xip_image, _fatal);
> > > +qspi_xip_mem->readonly = true;
> > > +} else {
> > > +memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
> > > +   "microchip.pfsoc.qspi_xip",
> > > +   memmap[MICROCHIP_PFSOC_QSPI_XIP].size,
> > > +   _fatal);
> > > +}
> > >  memory_region_add_subregion(system_memory,
> > >  memmap[MICROCHIP_PFSOC_QSPI_XIP].base,
> > >  qspi_xip_mem);
> > > @@ -517,6 +527,24 @@ static void 
> > > microchip_icicle_kit_machine_init(MachineState *machine)
> > >  }
> > >  }
> > >
> >
> > Regards,
> > Bin
>



Re: [PATCH 2/4] tests/qtest: Make fuzz-test generic to all targets

2021-01-15 Thread Thomas Huth

On 15/01/2021 16.09, Philippe Mathieu-Daudé wrote:

Tests in fuzz-test's main() already check for the supported
architecture before adding tests, therefore this test is not
specific to the X86 target. Move it to the generic set.


As long as it does not run any test on non-x86, it does not make sense to 
move it to the generic set, does it? We'd only waste compile cycles that way?


 Thomas




Re: [PATCH v7 3/6] [RISCV_PM] Print new PM CSRs in QEMU logs

2021-01-15 Thread Alistair Francis
On Sun, Jan 10, 2021 at 10:57 AM Alexey Baturo  wrote:
>
> Signed-off-by: Alexey Baturo 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c | 25 +
>  1 file changed, 25 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index d50f09b757..19398977d3 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -287,6 +287,31 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, 
> int flags)
>  qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "htval ", env->htval);
>  qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval2 ", env->mtval2);
>  }
> +if (riscv_has_ext(env, RVJ)) {
> +qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mmte", env->mmte);
> +switch (env->priv) {
> +case PRV_U:
> +qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "upmbase ",
> + env->upmbase);
> +qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "upmmask ",
> + env->upmmask);
> +break;
> +case PRV_S:
> +qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "spmbase ",
> + env->spmbase);
> +qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "spmmask ",
> + env->spmmask);
> +break;
> +case PRV_M:
> +qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mpmbase ",
> + env->mpmbase);
> +qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mpmmask ",
> + env->mpmmask);
> +break;
> +default:
> +g_assert_not_reached();
> +}
> +}
>  #endif
>
>  for (i = 0; i < 32; i++) {
> --
> 2.20.1
>
>



Re: [PATCH] hw/misc/sifive_u_otp: handling the fails of blk_pread and blk_pwrite

2021-01-15 Thread Peter Maydell
On Fri, 15 Jan 2021 at 21:43, Alistair Francis  wrote:
>
> On Fri, Jan 15, 2021 at 6:09 AM Bin Meng  wrote:
> >
> > On Fri, Jan 15, 2021 at 9:55 PM Peter Maydell  
> > wrote
> > > printf is definitely the wrong thing... you need to either report
> > > the error back to the guest if the interface the guest is using
> > > has a facility for reporting read/write failures, or log or report
> > > it to the user using one of our APIs for that.
> >
> > It seems the hardware does not have a mechanism to report to the
> > software when hardware cannot fulfill the task requested by software.
> >
> > I checked all existence of block_pwrite() callers. It looks like this
> > is not handled consistently. Some indeed call printf(), some call
> > error_setg_errno(), some call fprintf(stderr), some call qemu_log()
> > ...
>
> Logging a guest error seems like the best bet, I'm not really sure
> what else we would do.

Looking at the other options, I think error_report() of some kind is
probably the best bet here.

thanks
-- PMM



Re: [PATCH v2 09/22] tcg/riscv: Split out target constraints to tcg-target-con-str.h

2021-01-15 Thread Alistair Francis
On Fri, Jan 15, 2021 at 1:09 PM Richard Henderson
 wrote:
>
> Signed-off-by: Richard Henderson 
> ---
>  tcg/riscv/tcg-target-con-str.h | 21 ++
>  tcg/riscv/tcg-target.h |  1 +
>  tcg/riscv/tcg-target.c.inc | 50 --
>  3 files changed, 33 insertions(+), 39 deletions(-)
>  create mode 100644 tcg/riscv/tcg-target-con-str.h
>
> diff --git a/tcg/riscv/tcg-target-con-str.h b/tcg/riscv/tcg-target-con-str.h
> new file mode 100644
> index 00..587fcd3593
> --- /dev/null
> +++ b/tcg/riscv/tcg-target-con-str.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Define RISC-V target-specific operand constraints.
> + * Copyright (c) 2021 Linaro
> + */
> +
> +/*
> + * Define constraint letters for register sets:
> + * REGS(letter, register_mask)
> + */
> +REGS('r', ALL_GENERAL_REGS)
> +REGS('L', ALL_QLDST_REGS)
> +
> +/*
> + * Define constraint letters for constants:
> + * CONST(letter, TCG_CT_CONST_* bit set)
> + */
> +CONST('I', TCG_CT_CONST_S12)
> +CONST('N', TCG_CT_CONST_N12)
> +CONST('M', TCG_CT_CONST_M12)
> +CONST('Z', TCG_CT_CONST_ZERO)
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index 727c8df418..daf3ef7b5c 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -171,5 +171,6 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
> uintptr_t, uintptr_t);
>  #define TCG_TARGET_NEED_POOL_LABELS
>
>  #define TCG_TARGET_HAS_MEMORY_BSWAP 0
> +#define TCG_TARGET_CON_STR_H
>
>  #endif
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 71c0badc02..185b569f4b 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -122,6 +122,17 @@ static const int tcg_target_call_oarg_regs[] = {
>  #define TCG_CT_CONST_N12   0x400
>  #define TCG_CT_CONST_M12   0x800
>
> +#define ALL_GENERAL_REGS  0xu
> +#ifdef CONFIG_SOFTMMU
> +#define ALL_QLDST_REGS \
> +(ALL_GENERAL_REGS & ~((1 << TCG_REG_A0) | (1 << TCG_REG_A1) | \
> +  (1 << TCG_REG_A2) | (1 << TCG_REG_A3) | \
> +  (1 << TCG_REG_A5)))

Why is this not TCG_REG_A4?

Alistair

> +#else
> +#define ALL_QLDST_REGS   ALL_GENERAL_REGS
> +#endif
> +
> +
>  static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len)
>  {
>  if (TCG_TARGET_REG_BITS == 32) {
> @@ -131,45 +142,6 @@ static inline tcg_target_long sextreg(tcg_target_long 
> val, int pos, int len)
>  }
>  }
>
> -/* parse target specific constraints */
> -static const char *target_parse_constraint(TCGArgConstraint *ct,
> -   const char *ct_str, TCGType type)
> -{
> -switch (*ct_str++) {
> -case 'r':
> -ct->regs = 0x;
> -break;
> -case 'L':
> -/* qemu_ld/qemu_st constraint */
> -ct->regs = 0x;
> -/* qemu_ld/qemu_st uses TCG_REG_TMP0 */
> -#if defined(CONFIG_SOFTMMU)
> -tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[0]);
> -tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[1]);
> -tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[2]);
> -tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[3]);
> -tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[4]);
> -#endif
> -break;
> -case 'I':
> -ct->ct |= TCG_CT_CONST_S12;
> -break;
> -case 'N':
> -ct->ct |= TCG_CT_CONST_N12;
> -break;
> -case 'M':
> -ct->ct |= TCG_CT_CONST_M12;
> -break;
> -case 'Z':
> -/* we can use a zero immediate as a zero register argument. */
> -ct->ct |= TCG_CT_CONST_ZERO;
> -break;
> -default:
> -return NULL;
> -}
> -return ct_str;
> -}
> -
>  /* test if a constant matches the constraint */
>  static int tcg_target_const_match(tcg_target_long val, TCGType type,
>const TCGArgConstraint *arg_ct)
> --
> 2.25.1
>
>



Re: [PATCH v7 1/6] [RISCV_PM] Add J-extension into RISC-V

2021-01-15 Thread Alistair Francis
On Sun, Jan 10, 2021 at 10:51 AM Alexey Baturo  wrote:
>
> Signed-off-by: Alexey Baturo 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 6339e84819..d152842e37 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -72,6 +72,7 @@
>  #define RVS RV('S')
>  #define RVU RV('U')
>  #define RVH RV('H')
> +#define RVJ RV('J')
>
>  /* S extension denotes that Supervisor mode exists, however it is possible
> to have a core that support S mode but does not have an MMU and there
> @@ -285,6 +286,7 @@ struct RISCVCPU {
>  bool ext_s;
>  bool ext_u;
>  bool ext_h;
> +bool ext_j;
>  bool ext_v;
>  bool ext_counters;
>  bool ext_ifencei;
> --
> 2.20.1
>
>



Re: [PATCH v7 6/6] [RISCV_PM] Allow experimental J-ext to be turned on

2021-01-15 Thread Alistair Francis
On Sun, Jan 10, 2021 at 11:00 AM Alexey Baturo  wrote:
>
> Signed-off-by: Alexey Baturo 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 19398977d3..234401c3c6 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -499,6 +499,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> **errp)
>  }
>  if (cpu->cfg.ext_j) {
>  env->mmte |= PM_EXT_INITIAL;
> +target_misa |= RVJ;
>  }
>  if (cpu->cfg.ext_v) {
>  target_misa |= RVV;
> @@ -571,6 +572,7 @@ static Property riscv_cpu_properties[] = {
>  DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
>  /* This is experimental so mark with 'x-' */
>  DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
> +DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
>  DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false),
>  DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
>  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
> --
> 2.20.1
>
>



Re: [PATCH 3/4] target/riscv: Generate the GDB XML file for CSR registers dynamically

2021-01-15 Thread Alistair Francis
On Fri, Jan 15, 2021 at 1:59 PM Alistair Francis  wrote:
>
> On Mon, Jan 11, 2021 at 8:55 PM Bin Meng  wrote:
> >
> > From: Bin Meng 
> >
> > At present QEMU RISC-V uses a hardcoded XML to report the feature
> > "org.gnu.gdb.riscv.csr" [1]. There are two major issues with the
> > approach being used currently:
> >
> > - The XML does not specify the "regnum" field of a CSR entry, hence
> >   consecutive numbers are used by the remote GDB client to access
> >   CSRs. In QEMU we have to maintain a map table to convert the GDB
> >   number to the hardware number which is error prone.
> > - The XML contains some CSRs that QEMU does not implement at all,
> >   which causes an "E14" response sent to remote GDB client.
> >
> > Change to generate the CSR register list dynamically, based on the
> > availability presented in the CSR function table. This new approach
> > will reflect a correct list of CSRs that QEMU actually implements.
> >
> > [1] 
> > https://sourceware.org/gdb/current/onlinedocs/gdb/RISC_002dV-Features.html#RISC_002dV-Features

Do you mind rebasing this patch on the current riscv-to-apply.next
branch: https://github.com/alistair23/qemu/tree/riscv-to-apply.next

Alistair

> >
> > Signed-off-by: Bin Meng 
>
> Reviewed-by: Alistair Francis 
>
> Alistair
>
> > ---
> >
> >  target/riscv/cpu.h |   2 +
> >  target/riscv/cpu.c |  12 ++
> >  target/riscv/gdbstub.c | 308 
> > +++--
> >  3 files changed, 58 insertions(+), 264 deletions(-)
> >
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 6684316..f810169 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -272,6 +272,8 @@ struct RISCVCPU {
> >  CPUNegativeOffsetState neg;
> >  CPURISCVState env;
> >
> > +char *dyn_csr_xml;
> > +
> >  /* Configuration Settings */
> >  struct {
> >  bool ext_i;
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index dfe5d4e..c0dd646 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -569,6 +569,17 @@ static gchar *riscv_gdb_arch_name(CPUState *cs)
> >  }
> >  }
> >
> > +static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char 
> > *xmlname)
> > +{
> > +RISCVCPU *cpu = RISCV_CPU(cs);
> > +
> > +if (strcmp(xmlname, "riscv-csr.xml") == 0) {
> > +return cpu->dyn_csr_xml;
> > +}
> > +
> > +return NULL;
> > +}
> > +
> >  static void riscv_cpu_class_init(ObjectClass *c, void *data)
> >  {
> >  RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
> > @@ -607,6 +618,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
> > *data)
> >  cc->write_elf32_note = riscv_cpu_write_elf32_note;
> >  #endif
> >  cc->gdb_arch_name = riscv_gdb_arch_name;
> > +cc->gdb_get_dynamic_xml = riscv_gdb_get_dynamic_xml;
> >  #ifdef CONFIG_TCG
> >  cc->tcg_initialize = riscv_translate_init;
> >  cc->tlb_fill = riscv_cpu_tlb_fill;
> > diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> > index eba12a8..5f96b7e 100644
> > --- a/target/riscv/gdbstub.c
> > +++ b/target/riscv/gdbstub.c
> > @@ -20,256 +20,6 @@
> >  #include "exec/gdbstub.h"
> >  #include "cpu.h"
> >
> > -/*
> > - * The GDB CSR xml files list them in documentation order, not numerical 
> > order,
> > - * and are missing entries for unnamed CSRs.  So we need to map the gdb 
> > numbers
> > - * to the hardware numbers.
> > - */
> > -
> > -static int csr_register_map[] = {
> > -CSR_USTATUS,
> > -CSR_UIE,
> > -CSR_UTVEC,
> > -CSR_USCRATCH,
> > -CSR_UEPC,
> > -CSR_UCAUSE,
> > -CSR_UTVAL,
> > -CSR_UIP,
> > -CSR_FFLAGS,
> > -CSR_FRM,
> > -CSR_FCSR,
> > -CSR_CYCLE,
> > -CSR_TIME,
> > -CSR_INSTRET,
> > -CSR_HPMCOUNTER3,
> > -CSR_HPMCOUNTER4,
> > -CSR_HPMCOUNTER5,
> > -CSR_HPMCOUNTER6,
> > -CSR_HPMCOUNTER7,
> > -CSR_HPMCOUNTER8,
> > -CSR_HPMCOUNTER9,
> > -CSR_HPMCOUNTER10,
> > -CSR_HPMCOUNTER11,
> > -CSR_HPMCOUNTER12,
> > -CSR_HPMCOUNTER13,
> > -CSR_HPMCOUNTER14,
> > -CSR_HPMCOUNTER15,
> > -CSR_HPMCOUNTER16,
> > -CSR_HPMCOUNTER17,
> > -CSR_HPMCOUNTER18,
> > -CSR_HPMCOUNTER19,
> > -CSR_HPMCOUNTER20,
> > -CSR_HPMCOUNTER21,
> > -CSR_HPMCOUNTER22,
> > -CSR_HPMCOUNTER23,
> > -CSR_HPMCOUNTER24,
> > -CSR_HPMCOUNTER25,
> > -CSR_HPMCOUNTER26,
> > -CSR_HPMCOUNTER27,
> > -CSR_HPMCOUNTER28,
> > -CSR_HPMCOUNTER29,
> > -CSR_HPMCOUNTER30,
> > -CSR_HPMCOUNTER31,
> > -CSR_CYCLEH,
> > -CSR_TIMEH,
> > -CSR_INSTRETH,
> > -CSR_HPMCOUNTER3H,
> > -CSR_HPMCOUNTER4H,
> > -CSR_HPMCOUNTER5H,
> > -CSR_HPMCOUNTER6H,
> > -CSR_HPMCOUNTER7H,
> > -CSR_HPMCOUNTER8H,
> > -CSR_HPMCOUNTER9H,
> > -CSR_HPMCOUNTER10H,
> > -CSR_HPMCOUNTER11H,
> > -CSR_HPMCOUNTER12H,
> > -CSR_HPMCOUNTER13H,
> > -CSR_HPMCOUNTER14H,
> > -CSR_HPMCOUNTER15H,
> > -CSR_HPMCOUNTER16H,
> > -CSR_HPMCOUNTER17H,
> > -  

Re: [PATCH 04/15] arc: TCG and decoder glue code and helpers

2021-01-15 Thread Cupertino Miranda
Ok, enter and leave will officially get to be TCG code.
To be honest initially we thought that helper code would be preferable 
to TCG one. Apparently we were wrong. :-)

Thanks for your quick feedback.

On 1/15/21 9:53 PM, Richard Henderson wrote:
> On 1/15/21 11:48 AM, Cupertino Miranda wrote:
>>> In the case of enter or leave, this is one load/store plus one addition,
>>> followed by a branch.  All of which is encoded as fields in the instruction.
>>> Extremely simple.
>>
>> So your recommendation is leave the conditional exception triggering of
>> enter and leave in a helper and move the loads/stores to tcg ?
> 
> What?  No.
> 
> 
> r~
> 


Re: [PATCH 4/4] target/riscv: Remove built-in GDB XML files for CSRs

2021-01-15 Thread Alistair Francis
On Mon, Jan 11, 2021 at 8:55 PM Bin Meng  wrote:
>
> From: Bin Meng 
>
> Now that we have switched to generate the RISC-V CSR XML dynamically,
> remove the built-in hardcoded XML files.
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

>
> ---
>
>  default-configs/targets/riscv32-linux-user.mak |   2 +-
>  default-configs/targets/riscv32-softmmu.mak|   2 +-
>  default-configs/targets/riscv64-linux-user.mak |   2 +-
>  default-configs/targets/riscv64-softmmu.mak|   2 +-
>  gdb-xml/riscv-32bit-csr.xml| 250 
> -
>  gdb-xml/riscv-64bit-csr.xml| 250 
> -
>  6 files changed, 4 insertions(+), 504 deletions(-)
>  delete mode 100644 gdb-xml/riscv-32bit-csr.xml
>  delete mode 100644 gdb-xml/riscv-64bit-csr.xml
>
> diff --git a/default-configs/targets/riscv32-linux-user.mak 
> b/default-configs/targets/riscv32-linux-user.mak
> index dfb259e..07e6ca1 100644
> --- a/default-configs/targets/riscv32-linux-user.mak
> +++ b/default-configs/targets/riscv32-linux-user.mak
> @@ -1,4 +1,4 @@
>  TARGET_ARCH=riscv32
>  TARGET_BASE_ARCH=riscv
>  TARGET_ABI_DIR=riscv
> -TARGET_XML_FILES= gdb-xml/riscv-32bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
> gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-32bit-csr.xml 
> gdb-xml/riscv-32bit-virtual.xml
> +TARGET_XML_FILES= gdb-xml/riscv-32bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
> gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-32bit-virtual.xml
> diff --git a/default-configs/targets/riscv32-softmmu.mak 
> b/default-configs/targets/riscv32-softmmu.mak
> index 9446d96..d8b71cd 100644
> --- a/default-configs/targets/riscv32-softmmu.mak
> +++ b/default-configs/targets/riscv32-softmmu.mak
> @@ -1,5 +1,5 @@
>  TARGET_ARCH=riscv32
>  TARGET_BASE_ARCH=riscv
>  TARGET_SUPPORTS_MTTCG=y
> -TARGET_XML_FILES= gdb-xml/riscv-32bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
> gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-32bit-csr.xml 
> gdb-xml/riscv-32bit-virtual.xml
> +TARGET_XML_FILES= gdb-xml/riscv-32bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
> gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-32bit-virtual.xml
>  TARGET_NEED_FDT=y
> diff --git a/default-configs/targets/riscv64-linux-user.mak 
> b/default-configs/targets/riscv64-linux-user.mak
> index b13895f..191c2c4 100644
> --- a/default-configs/targets/riscv64-linux-user.mak
> +++ b/default-configs/targets/riscv64-linux-user.mak
> @@ -1,4 +1,4 @@
>  TARGET_ARCH=riscv64
>  TARGET_BASE_ARCH=riscv
>  TARGET_ABI_DIR=riscv
> -TARGET_XML_FILES= gdb-xml/riscv-64bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
> gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-64bit-csr.xml 
> gdb-xml/riscv-64bit-virtual.xml
> +TARGET_XML_FILES= gdb-xml/riscv-64bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
> gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-64bit-virtual.xml
> diff --git a/default-configs/targets/riscv64-softmmu.mak 
> b/default-configs/targets/riscv64-softmmu.mak
> index d809bd6..7c0e7ee 100644
> --- a/default-configs/targets/riscv64-softmmu.mak
> +++ b/default-configs/targets/riscv64-softmmu.mak
> @@ -1,5 +1,5 @@
>  TARGET_ARCH=riscv64
>  TARGET_BASE_ARCH=riscv
>  TARGET_SUPPORTS_MTTCG=y
> -TARGET_XML_FILES= gdb-xml/riscv-64bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
> gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-64bit-csr.xml 
> gdb-xml/riscv-64bit-virtual.xml
> +TARGET_XML_FILES= gdb-xml/riscv-64bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml 
> gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-64bit-virtual.xml
>  TARGET_NEED_FDT=y
> diff --git a/gdb-xml/riscv-32bit-csr.xml b/gdb-xml/riscv-32bit-csr.xml
> deleted file mode 100644
> index da1bf19..000
> --- a/gdb-xml/riscv-32bit-csr.xml
> +++ /dev/null
> @@ -1,250 +0,0 @@
> -
> -
> -
> -
> -
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  
> -  

Re: [PATCH 3/4] target/riscv: Generate the GDB XML file for CSR registers dynamically

2021-01-15 Thread Alistair Francis
On Mon, Jan 11, 2021 at 8:55 PM Bin Meng  wrote:
>
> From: Bin Meng 
>
> At present QEMU RISC-V uses a hardcoded XML to report the feature
> "org.gnu.gdb.riscv.csr" [1]. There are two major issues with the
> approach being used currently:
>
> - The XML does not specify the "regnum" field of a CSR entry, hence
>   consecutive numbers are used by the remote GDB client to access
>   CSRs. In QEMU we have to maintain a map table to convert the GDB
>   number to the hardware number which is error prone.
> - The XML contains some CSRs that QEMU does not implement at all,
>   which causes an "E14" response sent to remote GDB client.
>
> Change to generate the CSR register list dynamically, based on the
> availability presented in the CSR function table. This new approach
> will reflect a correct list of CSRs that QEMU actually implements.
>
> [1] 
> https://sourceware.org/gdb/current/onlinedocs/gdb/RISC_002dV-Features.html#RISC_002dV-Features
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  target/riscv/cpu.h |   2 +
>  target/riscv/cpu.c |  12 ++
>  target/riscv/gdbstub.c | 308 
> +++--
>  3 files changed, 58 insertions(+), 264 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 6684316..f810169 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -272,6 +272,8 @@ struct RISCVCPU {
>  CPUNegativeOffsetState neg;
>  CPURISCVState env;
>
> +char *dyn_csr_xml;
> +
>  /* Configuration Settings */
>  struct {
>  bool ext_i;
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index dfe5d4e..c0dd646 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -569,6 +569,17 @@ static gchar *riscv_gdb_arch_name(CPUState *cs)
>  }
>  }
>
> +static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char 
> *xmlname)
> +{
> +RISCVCPU *cpu = RISCV_CPU(cs);
> +
> +if (strcmp(xmlname, "riscv-csr.xml") == 0) {
> +return cpu->dyn_csr_xml;
> +}
> +
> +return NULL;
> +}
> +
>  static void riscv_cpu_class_init(ObjectClass *c, void *data)
>  {
>  RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
> @@ -607,6 +618,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
> *data)
>  cc->write_elf32_note = riscv_cpu_write_elf32_note;
>  #endif
>  cc->gdb_arch_name = riscv_gdb_arch_name;
> +cc->gdb_get_dynamic_xml = riscv_gdb_get_dynamic_xml;
>  #ifdef CONFIG_TCG
>  cc->tcg_initialize = riscv_translate_init;
>  cc->tlb_fill = riscv_cpu_tlb_fill;
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index eba12a8..5f96b7e 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -20,256 +20,6 @@
>  #include "exec/gdbstub.h"
>  #include "cpu.h"
>
> -/*
> - * The GDB CSR xml files list them in documentation order, not numerical 
> order,
> - * and are missing entries for unnamed CSRs.  So we need to map the gdb 
> numbers
> - * to the hardware numbers.
> - */
> -
> -static int csr_register_map[] = {
> -CSR_USTATUS,
> -CSR_UIE,
> -CSR_UTVEC,
> -CSR_USCRATCH,
> -CSR_UEPC,
> -CSR_UCAUSE,
> -CSR_UTVAL,
> -CSR_UIP,
> -CSR_FFLAGS,
> -CSR_FRM,
> -CSR_FCSR,
> -CSR_CYCLE,
> -CSR_TIME,
> -CSR_INSTRET,
> -CSR_HPMCOUNTER3,
> -CSR_HPMCOUNTER4,
> -CSR_HPMCOUNTER5,
> -CSR_HPMCOUNTER6,
> -CSR_HPMCOUNTER7,
> -CSR_HPMCOUNTER8,
> -CSR_HPMCOUNTER9,
> -CSR_HPMCOUNTER10,
> -CSR_HPMCOUNTER11,
> -CSR_HPMCOUNTER12,
> -CSR_HPMCOUNTER13,
> -CSR_HPMCOUNTER14,
> -CSR_HPMCOUNTER15,
> -CSR_HPMCOUNTER16,
> -CSR_HPMCOUNTER17,
> -CSR_HPMCOUNTER18,
> -CSR_HPMCOUNTER19,
> -CSR_HPMCOUNTER20,
> -CSR_HPMCOUNTER21,
> -CSR_HPMCOUNTER22,
> -CSR_HPMCOUNTER23,
> -CSR_HPMCOUNTER24,
> -CSR_HPMCOUNTER25,
> -CSR_HPMCOUNTER26,
> -CSR_HPMCOUNTER27,
> -CSR_HPMCOUNTER28,
> -CSR_HPMCOUNTER29,
> -CSR_HPMCOUNTER30,
> -CSR_HPMCOUNTER31,
> -CSR_CYCLEH,
> -CSR_TIMEH,
> -CSR_INSTRETH,
> -CSR_HPMCOUNTER3H,
> -CSR_HPMCOUNTER4H,
> -CSR_HPMCOUNTER5H,
> -CSR_HPMCOUNTER6H,
> -CSR_HPMCOUNTER7H,
> -CSR_HPMCOUNTER8H,
> -CSR_HPMCOUNTER9H,
> -CSR_HPMCOUNTER10H,
> -CSR_HPMCOUNTER11H,
> -CSR_HPMCOUNTER12H,
> -CSR_HPMCOUNTER13H,
> -CSR_HPMCOUNTER14H,
> -CSR_HPMCOUNTER15H,
> -CSR_HPMCOUNTER16H,
> -CSR_HPMCOUNTER17H,
> -CSR_HPMCOUNTER18H,
> -CSR_HPMCOUNTER19H,
> -CSR_HPMCOUNTER20H,
> -CSR_HPMCOUNTER21H,
> -CSR_HPMCOUNTER22H,
> -CSR_HPMCOUNTER23H,
> -CSR_HPMCOUNTER24H,
> -CSR_HPMCOUNTER25H,
> -CSR_HPMCOUNTER26H,
> -CSR_HPMCOUNTER27H,
> -CSR_HPMCOUNTER28H,
> -CSR_HPMCOUNTER29H,
> -CSR_HPMCOUNTER30H,
> -CSR_HPMCOUNTER31H,
> -CSR_SSTATUS,
> -CSR_SEDELEG,
> -CSR_SIDELEG,
> -CSR_SIE,
> -CSR_STVEC,
> -CSR_SCOUNTEREN,
> -CSR_SSCRATCH,
> -CSR_SEPC,
> -

Re: [PATCH] hw/misc/sifive_u_otp: handling the fails of blk_pread and blk_pwrite

2021-01-15 Thread Alistair Francis
On Fri, Jan 15, 2021 at 3:50 AM Peter Maydell  wrote:
>
> Ping! This patch was trying to fix a Coverity issue (CID 1435959,
> 1435960, 1435961) -- is anybody planning to review it?
>
> (I'm not entirely sure 'guest error' is the right warning category,
> but I don't know the specifics of this device.)

Thanks for the ping, this feel through the cracks somehow.

Applied to riscv-to-apply.next

Alistair

>
> thanks
> -- PMM
>
> On Wed, 4 Nov 2020 at 09:29, Green Wan  wrote:
> >
> > Fix code coverage issues by checking return value and handling fail case
> > of blk_pread() and blk_pwrite(). Return default value 0xff if read fails.
> >
> > Signed-off-by: Green Wan 
> > ---
> >  hw/misc/sifive_u_otp.c | 31 +++
> >  1 file changed, 23 insertions(+), 8 deletions(-)
> >
> > diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
> > index 60066375ab..4314727d0d 100644
> > --- a/hw/misc/sifive_u_otp.c
> > +++ b/hw/misc/sifive_u_otp.c
> > @@ -62,8 +62,13 @@ static uint64_t sifive_u_otp_read(void *opaque, hwaddr 
> > addr, unsigned int size)
> >  if (s->blk) {
> >  int32_t buf;
> >
> > -blk_pread(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD, ,
> > -  SIFIVE_U_OTP_FUSE_WORD);
> > +if (blk_pread(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD, ,
> > +  SIFIVE_U_OTP_FUSE_WORD) < 0) {
> > +qemu_log_mask(LOG_GUEST_ERROR,
> > +  "read error index<%d>\n", s->pa);
> > +return 0xff;
> > +}
> > +
> >  return buf;
> >  }
> >
> > @@ -160,8 +165,12 @@ static void sifive_u_otp_write(void *opaque, hwaddr 
> > addr,
> >
> >  /* write to backend */
> >  if (s->blk) {
> > -blk_pwrite(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD,
> > -   >fuse[s->pa], SIFIVE_U_OTP_FUSE_WORD, 0);
> > +if (blk_pwrite(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD,
> > +   >fuse[s->pa], SIFIVE_U_OTP_FUSE_WORD,
> > +   0) < 0) {
> > +qemu_log_mask(LOG_GUEST_ERROR,
> > +  "write error index<%d>\n", s->pa);
> > +}
> >  }
> >
> >  /* update written bit */
> > @@ -248,12 +257,18 @@ static void sifive_u_otp_reset(DeviceState *dev)
> >  int index = SIFIVE_U_OTP_SERIAL_ADDR;
> >
> >  serial_data = s->serial;
> > -blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD,
> > -   _data, SIFIVE_U_OTP_FUSE_WORD, 0);
> > +if (blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD,
> > +   _data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
> > +qemu_log_mask(LOG_GUEST_ERROR,
> > +  "write error index<%d>\n", index);
> > +}
> >
> >  serial_data = ~(s->serial);
> > -blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
> > -   _data, SIFIVE_U_OTP_FUSE_WORD, 0);
> > +if (blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
> > +   _data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
> > +qemu_log_mask(LOG_GUEST_ERROR,
> > +  "write error index<%d>\n", index + 1);
> > +}
> >  }
> >
> >  /* Initialize write-once map */
> > --
> > 2.17.1



Re: [PATCH 04/15] arc: TCG and decoder glue code and helpers

2021-01-15 Thread Richard Henderson
On 1/15/21 11:48 AM, Cupertino Miranda wrote:
>> In the case of enter or leave, this is one load/store plus one addition,
>> followed by a branch.  All of which is encoded as fields in the instruction.
>> Extremely simple.
> 
> So your recommendation is leave the conditional exception triggering of 
> enter and leave in a helper and move the loads/stores to tcg ?

What?  No.


r~



Re: [PATCH 2/4] target/riscv: Add CSR name in the CSR function table

2021-01-15 Thread Alistair Francis
On Fri, Jan 15, 2021 at 5:35 AM Alexander Richardson
 wrote:
>
> On Tue, 12 Jan 2021 at 05:02, Bin Meng  wrote:
> >
> > From: Bin Meng 
> >
> > In preparation to generate the CSR register list for GDB stub
> > dynamically, let's add the CSR name in the CSR function table.
> >
> > Signed-off-by: Bin Meng 
> > ---
> >
> >  target/riscv/cpu.h |   1 +
> >  target/riscv/csr.c | 332 
> > +++--
> >  2 files changed, 249 insertions(+), 84 deletions(-)
> >
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 6f9e1cc..6684316 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -476,6 +476,7 @@ typedef int (*riscv_csr_op_fn)(CPURISCVState *env, int 
> > csrno,
> >  target_ulong *ret_value, target_ulong new_value, target_ulong 
> > write_mask);
> >
> >  typedef struct {
> > +const char *name;
> >  riscv_csr_predicate_fn predicate;
> >  riscv_csr_read_fn read;
> >  riscv_csr_write_fn write;
>
> In our CHERI fork, we also added the name to this table for better
> instruction logging output:
> 
> We used some macros to avoid repeating the same string multiple times:
> in that patch we use e.g. [CSR_FCSR] = CSR_OP_RW(fs, fcsr)," instead
> of
> "[CSR_FCSR] = { "fcsr", fs, read_fcsr,write_fcsr   },"
> Would it make sense to upstream these helper macros? This would
> significantly reduce merge conflicts on our side in the future.

If you send the patches then I'll merge it :)

In general it would be great if you upstream as much as possible. That
will save you work in the long run and help improve the code base.

Alistair

>
> Thanks,
> Alex
>
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 507e8ee..fd2e636 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -1372,112 +1372,276 @@ int riscv_csrrw_debug(CPURISCVState *env, int 
> > csrno, target_ulong *ret_value,
> >  /* Control and Status Register function table */
> >  riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> >  /* User Floating-Point CSRs */
> > -[CSR_FFLAGS] =  { fs,   read_fflags,  write_fflags 
> >  },
> > -[CSR_FRM] = { fs,   read_frm, write_frm
> >  },
> > -[CSR_FCSR] ={ fs,   read_fcsr,write_fcsr   
> >  },
> > +[CSR_FFLAGS]   = { "fflags",   fs, read_fflags,  write_fflags },
> > +[CSR_FRM]  = { "frm",  fs, read_frm, write_frm},
> > +[CSR_FCSR] = { "fcsr", fs, read_fcsr,write_fcsr   },
> >  /* Vector CSRs */
> > -[CSR_VSTART] =  { vs,   read_vstart,  write_vstart 
> >  },
> > -[CSR_VXSAT] =   { vs,   read_vxsat,   write_vxsat  
> >  },
> > -[CSR_VXRM] ={ vs,   read_vxrm,write_vxrm   
> >  },
> > -[CSR_VL] =  { vs,   read_vl
> >  },
> > -[CSR_VTYPE] =   { vs,   read_vtype 
> >  },
> > +[CSR_VSTART]   = { "vstart",   vs, read_vstart,  write_vstart },
> > +[CSR_VXSAT]= { "vxsat",vs, read_vxsat,   write_vxsat  },
> > +[CSR_VXRM] = { "vxrm", vs, read_vxrm,write_vxrm   },
> > +[CSR_VL]   = { "vl",   vs, read_vl},
> > +[CSR_VTYPE]= { "vtype",vs, read_vtype },
> >  /* User Timers and Counters */
> > -[CSR_CYCLE] =   { ctr,  read_instret   
> >  },
> > -[CSR_INSTRET] = { ctr,  read_instret   
> >  },
> > -[CSR_CYCLEH] =  { ctr32,  read_instreth
> >  },
> > -[CSR_INSTRETH] ={ ctr32,  read_instreth
> >  },
> > -
> > -/* In privileged mode, the monitor will have to emulate TIME CSRs only 
> > if
> > - * rdtime callback is not provided by machine/platform emulation */
> > -[CSR_TIME] ={ ctr,  read_time  
> >  },
> > -[CSR_TIMEH] =   { ctr32,  read_timeh   
> >  },
> > +[CSR_CYCLE]= { "cycle",ctr,read_instret  },
> > +[CSR_INSTRET]  = { "instret",  ctr,read_instret  },
> > +[CSR_CYCLEH]   = { "cycleh",   ctr32,  read_instreth },
> > +[CSR_INSTRETH] = { "instreth", ctr32,  read_instreth },
> > +
> > +/*
> > + * In privileged mode, the monitor will have to emulate TIME CSRs only 
> > if
> > + * rdtime callback is not provided by machine/platform emulation.
> > + */
> > +[CSR_TIME]  = { "time",  ctr,   read_time  },
> > +[CSR_TIMEH] = { "timeh", ctr32, read_timeh },
> >
> >  #if !defined(CONFIG_USER_ONLY)
> >  /* Machine Timers and Counters */
> > 

Re: [PATCH 2/4] target/riscv: Add CSR name in the CSR function table

2021-01-15 Thread Alistair Francis
On Mon, Jan 11, 2021 at 9:05 PM Bin Meng  wrote:
>
> From: Bin Meng 
>
> In preparation to generate the CSR register list for GDB stub
> dynamically, let's add the CSR name in the CSR function table.
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  target/riscv/cpu.h |   1 +
>  target/riscv/csr.c | 332 
> +++--
>  2 files changed, 249 insertions(+), 84 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 6f9e1cc..6684316 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -476,6 +476,7 @@ typedef int (*riscv_csr_op_fn)(CPURISCVState *env, int 
> csrno,
>  target_ulong *ret_value, target_ulong new_value, target_ulong 
> write_mask);
>
>  typedef struct {
> +const char *name;
>  riscv_csr_predicate_fn predicate;
>  riscv_csr_read_fn read;
>  riscv_csr_write_fn write;
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 507e8ee..fd2e636 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1372,112 +1372,276 @@ int riscv_csrrw_debug(CPURISCVState *env, int 
> csrno, target_ulong *ret_value,
>  /* Control and Status Register function table */
>  riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>  /* User Floating-Point CSRs */
> -[CSR_FFLAGS] =  { fs,   read_fflags,  write_fflags  
> },
> -[CSR_FRM] = { fs,   read_frm, write_frm 
> },
> -[CSR_FCSR] ={ fs,   read_fcsr,write_fcsr
> },
> +[CSR_FFLAGS]   = { "fflags",   fs, read_fflags,  write_fflags },
> +[CSR_FRM]  = { "frm",  fs, read_frm, write_frm},
> +[CSR_FCSR] = { "fcsr", fs, read_fcsr,write_fcsr   },
>  /* Vector CSRs */
> -[CSR_VSTART] =  { vs,   read_vstart,  write_vstart  
> },
> -[CSR_VXSAT] =   { vs,   read_vxsat,   write_vxsat   
> },
> -[CSR_VXRM] ={ vs,   read_vxrm,write_vxrm
> },
> -[CSR_VL] =  { vs,   read_vl 
> },
> -[CSR_VTYPE] =   { vs,   read_vtype  
> },
> +[CSR_VSTART]   = { "vstart",   vs, read_vstart,  write_vstart },
> +[CSR_VXSAT]= { "vxsat",vs, read_vxsat,   write_vxsat  },
> +[CSR_VXRM] = { "vxrm", vs, read_vxrm,write_vxrm   },
> +[CSR_VL]   = { "vl",   vs, read_vl},
> +[CSR_VTYPE]= { "vtype",vs, read_vtype },
>  /* User Timers and Counters */
> -[CSR_CYCLE] =   { ctr,  read_instret
> },
> -[CSR_INSTRET] = { ctr,  read_instret
> },
> -[CSR_CYCLEH] =  { ctr32,  read_instreth 
> },
> -[CSR_INSTRETH] ={ ctr32,  read_instreth 
> },
> -
> -/* In privileged mode, the monitor will have to emulate TIME CSRs only if
> - * rdtime callback is not provided by machine/platform emulation */
> -[CSR_TIME] ={ ctr,  read_time   
> },
> -[CSR_TIMEH] =   { ctr32,  read_timeh
> },
> +[CSR_CYCLE]= { "cycle",ctr,read_instret  },
> +[CSR_INSTRET]  = { "instret",  ctr,read_instret  },
> +[CSR_CYCLEH]   = { "cycleh",   ctr32,  read_instreth },
> +[CSR_INSTRETH] = { "instreth", ctr32,  read_instreth },
> +
> +/*
> + * In privileged mode, the monitor will have to emulate TIME CSRs only if
> + * rdtime callback is not provided by machine/platform emulation.
> + */
> +[CSR_TIME]  = { "time",  ctr,   read_time  },
> +[CSR_TIMEH] = { "timeh", ctr32, read_timeh },
>
>  #if !defined(CONFIG_USER_ONLY)
>  /* Machine Timers and Counters */
> -[CSR_MCYCLE] =  { any,  read_instret
> },
> -[CSR_MINSTRET] ={ any,  read_instret
> },
> -[CSR_MCYCLEH] = { any32,  read_instreth 
> },
> -[CSR_MINSTRETH] =   { any32,  read_instreth 
> },
> +[CSR_MCYCLE]= { "mcycle",any,   read_instret  },
> +[CSR_MINSTRET]  = { "minstret",  any,   read_instret  },
> +[CSR_MCYCLEH]   = { "mcycleh",   any32, read_instreth },
> +[CSR_MINSTRETH] = { "minstreth", any32, read_instreth },
>
>  /* Machine Information Registers */
> -[CSR_MVENDORID] =   { any,  read_zero   
> },
> -[CSR_MARCHID] = { any,  read_zero   
> },
> -[CSR_MIMPID] =  { any,  read_zero   
> },
> -[CSR_MHARTID] = { any,  read_mhartid
> },
> +[CSR_MVENDORID] = { "mvendorid", any,   read_zero},
> +

Re: [PATCH 1/4] target/riscv: Make csr_ops[CSR_TABLE_SIZE] external

2021-01-15 Thread Alistair Francis
On Mon, Jan 11, 2021 at 8:53 PM Bin Meng  wrote:
>
> From: Bin Meng 
>
> In preparation to generate the CSR register list for GDB stub
> dynamically, change csr_ops[] to non-static so that it can be
> referenced externally.
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  target/riscv/cpu.h |  8 
>  target/riscv/csr.c | 10 +-
>  2 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 2649949..6f9e1cc 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -482,6 +482,14 @@ typedef struct {
>  riscv_csr_op_fn op;
>  } riscv_csr_operations;
>
> +/* CSR function table constants */
> +enum {
> +CSR_TABLE_SIZE = 0x1000
> +};
> +
> +/* CSR function table */
> +extern riscv_csr_operations csr_ops[];
> +
>  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
>  void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 10ab82e..507e8ee 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -23,14 +23,6 @@
>  #include "qemu/main-loop.h"
>  #include "exec/exec-all.h"
>
> -/* CSR function table */
> -static riscv_csr_operations csr_ops[];
> -
> -/* CSR function table constants */
> -enum {
> -CSR_TABLE_SIZE = 0x1000
> -};
> -
>  /* CSR function table public API */
>  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
>  {
> @@ -1378,7 +1370,7 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, 
> target_ulong *ret_value,
>  }
>
>  /* Control and Status Register function table */
> -static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> +riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>  /* User Floating-Point CSRs */
>  [CSR_FFLAGS] =  { fs,   read_fflags,  write_fflags  
> },
>  [CSR_FRM] = { fs,   read_frm, write_frm 
> },
> --
> 2.7.4
>
>



Re: [PATCH 04/15] arc: TCG and decoder glue code and helpers

2021-01-15 Thread Richard Henderson
On 1/15/21 11:28 AM, Shahab Vahedi wrote:
>>> +cpu_stl_data(env, tmp_sp, CPU_FP(env));
>>> +}
>>
>> And what if these stores raise an exception?  I doubt you're going to get an
>> exception at the correct pc.
> 
> I've added a few bad-weather test cases [1] and they work as expected. Indeed,
> none of those tests trigger an exception during the "cpu_stl_data()". Could 
> you
> elaborate why you think the PC might be incorrect? Then I can add the 
> corresponding
> tests and fix the behavior.

Because you're using cpu_stl_data_ra, with GETPC, if the store faults (e.g.
SIGSEGV) then the exception unwind will not be done.  This will happen to work
ok if and only if "enter" is the first insn of the TB.

>> In the case of enter or leave, this is one load/store plus one addition,
>> followed by a branch.  All of which is encoded as fields in the instruction.
>> Extremely simple.
> 
> You're suggesting that "enter/leave" should use TCG opcodes instead of
> helpers? If yes, do you really think it is possible to implement each with ~10
> opcodes?

More or less.  Two per registers stored, plus two moves.  It looks like the
limit of registers is either 3 or 14, depending on the cpu configuration.

Certainly this is no different from other "push multiple" type of instructions
of other architectures, which do exactly this.


r~



Re: [PATCH 04/15] arc: TCG and decoder glue code and helpers

2021-01-15 Thread Cupertino Miranda


On 1/15/21 8:31 PM, Richard Henderson wrote:
> On 1/15/21 7:11 AM, Cupertino Miranda wrote:
>>> Similarly.  I think that both of these could be implemented entirely in
>>> translate, which is what
>>>
 +bool restore_fp= u7 & 0x10; /* u[4] indicates if fp must be saved 
  */
 +bool restore_blink = u7 & 0x20; /* u[5] indicates saving of blink 
  */
 +bool jump_to_blink = u7 & 0x40; /* u[6] should we jump to blink?  
  */
>>>
>>> these bits strongly imply.
>>>
>>
>> For lack of knowing better, it is unclear to me where to draw the line
>> when choosing between a translate time (tcg) or helper implementation.
>> Your suggestions for carry/overflow computation are sharp and we should
>> have never used an helper, however I wonder what would be the benefit of
>> implementing enter and leave through TCG.
>>
>> We have dealt with those exception issues by just changing SP in the end
>> of the instruction implementation, when no exceptions can happen.
> 
> 5-10 tcg opcodes is the rule of thumb.  A conditional exception (requiring a
> branch) is a good reason to put the whole thing out of line.
> 
> In the case of enter or leave, this is one load/store plus one addition,
> followed by a branch.  All of which is encoded as fields in the instruction.
> Extremely simple.

So your recommendation is leave the conditional exception triggering of 
enter and leave in a helper and move the loads/stores to tcg ?

> 
>> As far as I understand when an exception happens in the middle of the
>> helper or even on a TCG implementation, it jumps out of that TB
>> execution to deal with the exception. On rtie instead of it returning to
>> the same tcg_ld or tcg_st where it actually triggered the exception it
>> will re-decode the same instruction which triggered the exception, and
>> re-attempts to execute it.
>> Is that the case in current TCG implementation, or did it improved and
>> it is now able to return to previous execution flow (i.e translation
>> block) ?
> 
> I think I don't understand your question.
> 
> An exception leaves the TB, via longjmp.  Before the longjmp, there is 
> normally
> an "unwind" or "restore" operation, to sync the cpu state with the middle of
> the TB.  This happens in restore_state_to_opc().
> 
> When processing of the exception is complete, execution will continue with the
> appropriate cpu state.  Which will probably be a new TB that (logically)
> partially overlaps the previous TB.
> 
> I.e. everything will work as you'd expect.
> 
> So... what's the question?
> 
You answered the question. That is exactly how I understand it works.

> 
> r~
> 


Re: [PATCH] hw/misc/sifive_u_otp: handling the fails of blk_pread and blk_pwrite

2021-01-15 Thread Alistair Francis
On Fri, Jan 15, 2021 at 6:09 AM Bin Meng  wrote:
>
> On Fri, Jan 15, 2021 at 9:55 PM Peter Maydell  
> wrote:
> >
> > On Fri, 15 Jan 2021 at 13:33, Bin Meng  wrote:
> > >
> > > On Fri, Jan 15, 2021 at 7:50 PM Peter Maydell  
> > > wrote:
> > > >
> > > > Ping! This patch was trying to fix a Coverity issue (CID 1435959,
> > > > 1435960, 1435961) -- is anybody planning to review it?
> > > >
> > > > (I'm not entirely sure 'guest error' is the right warning category,
> > > > but I don't know the specifics of this device.)
> > > >
> > >
> > > I think we should just use 'printf' instead of log a "guest error"
> > > because the guest does nothing wrong.
> >
> > printf is definitely the wrong thing... you need to either report
> > the error back to the guest if the interface the guest is using
> > has a facility for reporting read/write failures, or log or report
> > it to the user using one of our APIs for that.
>
> It seems the hardware does not have a mechanism to report to the
> software when hardware cannot fulfill the task requested by software.
>
> I checked all existence of block_pwrite() callers. It looks like this
> is not handled consistently. Some indeed call printf(), some call
> error_setg_errno(), some call fprintf(stderr), some call qemu_log()
> ...

Logging a guest error seems like the best bet, I'm not really sure
what else we would do.

Alistair

>
> Regards,
> Bin



Re: [PATCH v1 7/7] spapr.c: consider CPU core online state before allowing unplug

2021-01-15 Thread Daniel Henrique Barboza




On 1/15/21 2:22 PM, Greg Kurz wrote:

On Thu, 14 Jan 2021 15:06:28 -0300
Daniel Henrique Barboza  wrote:


The only restriction we have when unplugging CPUs is to forbid unplug of
the boot cpu core. spapr_core_unplug_possible() does not contemplate the


I can't remember why this restriction was introduced in the first place...
This should be investigated and documented if the limitation still stands.



I looked it up and found out that restriction was added by this commit:

commit 62be8b044adf47327ebefdefb25f28a40316ebd0
Author: Bharata B Rao 
Date:   Wed Jul 27 10:44:42 2016 +0530

spapr: Prevent boot CPU core removal

Boot CPU is assumed to be always present in QEMU code. So

until that assumptions are gone, deny removal request.
In another words, QEMU won't support boot CPU core hot-unplug.


I don't think it necessarily has to do with pSeries code though. I was unable to
offline the CPU0 of my x86 notebook:


# lscpu | grep -i 'on-line'
On-line CPU(s) list: 0-7
# echo 0 > /sys/devices/system/cpu/cpu0/online
bash: /sys/devices/system/cpu/cpu0/online: Permission denied
#
# echo 0 > /sys/devices/system/cpu/cpu1/online
#
# lscpu | grep -i 'on-line'
On-line CPU(s) list: 0,2-7
# echo 0 > /sys/devices/system/cpu/cpu0/online
bash: /sys/devices/system/cpu/cpu0/online: Permission denied
#

The pseries kernel does not have this restriction (offlining CPU0).

Maybe we're limiting CPU0 unplug in pseries because it would break common QEMU
code that has this restriction due to x86/ACPI mechanics because, apparently,
x86 can't hotunplug CPU0.


If a good x86 soul reads this and confirm/deny my assumption I appreciate :)



Thanks,


DHB





possibility of some cores being offlined by the guest, meaning that we're
rolling the dice regarding on whether we're unplugging the last online
CPU core the guest has.



Trying to unplug the last CPU is obviously something that deserves
special care. LoPAPR is quite explicit on the outcome : this should
terminate the partition.

13.7.4.1.1. Isolation of CPUs

The isolation of a CPU, in all cases, is preceded by the stop-self
RTAS function for all processor threads, and the OS insures that all
the CPU’s threads are in the RTAS stopped state prior to isolating the
CPU. Isolation of a processor that is not stopped produces unpredictable
results. The stopping of the last processor thread of a LPAR partition
effectively kills the partition, and at that point, ownership of all
partition resources reverts to the platform firmware.

R1-13.7.4.1.1-1. For the LRDR option: Prior to issuing the RTAS
set-indicator specifying isolate isolation-state of a CPU DR
connector type, all the CPU threads must be in the RTAS stopped
state.

R1-13.7.4.1.1-2. For the LRDR option: Stopping of the last processor
thread of a LPAR partition with the stop-self RTAS function, must kill
the partition, with ownership of all partition resources reverting to
the platform firmware.

This is clearly not how things work today : linux doesn't call
"stop-self" on the last vCPU and even if it did, QEMU doesn't
terminate the VM.

If there's a valid reason to not implement this PAPR behavior, I'd like
it to be documented.


If we hit the jackpot, we're going to detach the core DRC and pulse the
hotplug IRQ, but the guest OS will refuse to release the CPU. Our
spapr_core_unplug() DRC release callback will never be called and the CPU
core object will keep existing in QEMU. No error message will be sent
to the user, but the CPU core wasn't unplugged from the guest.

If the guest OS onlines the CPU core again we won't be able to hotunplug it
either. 'dmesg' inside the guest will report a failed attempt to offline an
unknown CPU:

[  923.003994] pseries-hotplug-cpu: Failed to offline CPU , rc: -16

This is the result of stopping the DRC state transition in the middle in the
first failed attempt.



Yes, at this point only a machine reset can fix things up.

Given this is linux's choice not to call "stop-self" as it should do, I'm not
super fan of hardcoding this logic in QEMU, unless there are really good
reasons to do so.


We can avoid this, and potentially other bad things from happening, if we
avoid to attempt the unplug altogether in this scenario. Let's check for
the online/offline state of the CPU cores in the guest before allowing
the hotunplug, and forbid removing a CPU core if it's the last one online
in the guest.

Reported-by: Xujun Ma 
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1911414
Signed-off-by: Daniel Henrique Barboza 
---
  hw/ppc/spapr.c | 39 ++-
  1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a2f01c21aa..d269dcd102 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3709,9 +3709,16 @@ static void spapr_core_unplug(HotplugHandler 
*hotplug_dev, DeviceState *dev)
  static int spapr_core_unplug_possible(HotplugHandler *hotplug_dev, CPUCore 
*cc,
   

Re: [PATCH v1 7/7] spapr.c: consider CPU core online state before allowing unplug

2021-01-15 Thread Daniel Henrique Barboza




On 1/15/21 2:22 PM, Greg Kurz wrote:

On Thu, 14 Jan 2021 15:06:28 -0300
Daniel Henrique Barboza  wrote:


The only restriction we have when unplugging CPUs is to forbid unplug of
the boot cpu core. spapr_core_unplug_possible() does not contemplate the


I can't remember why this restriction was introduced in the first place...
This should be investigated and documented if the limitation still stands.



I looked it up and found out that restriction was added by this commit:

commit 62be8b044adf47327ebefdefb25f28a40316ebd0
Author: Bharata B Rao 
Date:   Wed Jul 27 10:44:42 2016 +0530

spapr: Prevent boot CPU core removal

Boot CPU is assumed to be always present in QEMU code. So

until that assumptions are gone, deny removal request.
In another words, QEMU won't support boot CPU core hot-unplug.


I don't think it necessarily has to do with pSeries code though. I was unable to
offline the CPU0 of my x86 notebook:


# lscpu | grep -i 'on-line'
On-line CPU(s) list: 0-7
# echo 0 > /sys/devices/system/cpu/cpu0/online
bash: /sys/devices/system/cpu/cpu0/online: Permission denied
#
# echo 0 > /sys/devices/system/cpu/cpu1/online
#
# lscpu | grep -i 'on-line'
On-line CPU(s) list: 0,2-7
# echo 0 > /sys/devices/system/cpu/cpu0/online
bash: /sys/devices/system/cpu/cpu0/online: Permission denied
#

The pseries kernel does not have this restriction (offlining CPU0).

Maybe we're limiting CPU0 unplug in pseries because it would break common QEMU
code that has this restriction due to x86/ACPI mechanics because, apparently,
x86 can't hotunplug CPU0.


If a good x86 soul reads this and confirm/deny my assumption I appreciate :)



Thanks,


DHB





possibility of some cores being offlined by the guest, meaning that we're
rolling the dice regarding on whether we're unplugging the last online
CPU core the guest has.



Trying to unplug the last CPU is obviously something that deserves
special care. LoPAPR is quite explicit on the outcome : this should
terminate the partition.

13.7.4.1.1. Isolation of CPUs

The isolation of a CPU, in all cases, is preceded by the stop-self
RTAS function for all processor threads, and the OS insures that all
the CPU’s threads are in the RTAS stopped state prior to isolating the
CPU. Isolation of a processor that is not stopped produces unpredictable
results. The stopping of the last processor thread of a LPAR partition
effectively kills the partition, and at that point, ownership of all
partition resources reverts to the platform firmware.

R1-13.7.4.1.1-1. For the LRDR option: Prior to issuing the RTAS
set-indicator specifying isolate isolation-state of a CPU DR
connector type, all the CPU threads must be in the RTAS stopped
state.

R1-13.7.4.1.1-2. For the LRDR option: Stopping of the last processor
thread of a LPAR partition with the stop-self RTAS function, must kill
the partition, with ownership of all partition resources reverting to
the platform firmware.

This is clearly not how things work today : linux doesn't call
"stop-self" on the last vCPU and even if it did, QEMU doesn't
terminate the VM.

If there's a valid reason to not implement this PAPR behavior, I'd like
it to be documented.


If we hit the jackpot, we're going to detach the core DRC and pulse the
hotplug IRQ, but the guest OS will refuse to release the CPU. Our
spapr_core_unplug() DRC release callback will never be called and the CPU
core object will keep existing in QEMU. No error message will be sent
to the user, but the CPU core wasn't unplugged from the guest.

If the guest OS onlines the CPU core again we won't be able to hotunplug it
either. 'dmesg' inside the guest will report a failed attempt to offline an
unknown CPU:

[  923.003994] pseries-hotplug-cpu: Failed to offline CPU , rc: -16

This is the result of stopping the DRC state transition in the middle in the
first failed attempt.



Yes, at this point only a machine reset can fix things up.

Given this is linux's choice not to call "stop-self" as it should do, I'm not
super fan of hardcoding this logic in QEMU, unless there are really good
reasons to do so.


We can avoid this, and potentially other bad things from happening, if we
avoid to attempt the unplug altogether in this scenario. Let's check for
the online/offline state of the CPU cores in the guest before allowing
the hotunplug, and forbid removing a CPU core if it's the last one online
in the guest.

Reported-by: Xujun Ma 
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1911414
Signed-off-by: Daniel Henrique Barboza 
---
  hw/ppc/spapr.c | 39 ++-
  1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a2f01c21aa..d269dcd102 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3709,9 +3709,16 @@ static void spapr_core_unplug(HotplugHandler 
*hotplug_dev, DeviceState *dev)
  static int spapr_core_unplug_possible(HotplugHandler *hotplug_dev, CPUCore 
*cc,
   

Re: [PATCH] hw/misc/sifive_u_otp: handling the fails of blk_pread and blk_pwrite

2021-01-15 Thread Alistair Francis
On Wed, Nov 4, 2020 at 1:29 AM Green Wan  wrote:
>
> Fix code coverage issues by checking return value and handling fail case
> of blk_pread() and blk_pwrite(). Return default value 0xff if read fails.
>
> Signed-off-by: Green Wan 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/misc/sifive_u_otp.c | 31 +++
>  1 file changed, 23 insertions(+), 8 deletions(-)
>
> diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
> index 60066375ab..4314727d0d 100644
> --- a/hw/misc/sifive_u_otp.c
> +++ b/hw/misc/sifive_u_otp.c
> @@ -62,8 +62,13 @@ static uint64_t sifive_u_otp_read(void *opaque, hwaddr 
> addr, unsigned int size)
>  if (s->blk) {
>  int32_t buf;
>
> -blk_pread(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD, ,
> -  SIFIVE_U_OTP_FUSE_WORD);
> +if (blk_pread(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD, ,
> +  SIFIVE_U_OTP_FUSE_WORD) < 0) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "read error index<%d>\n", s->pa);
> +return 0xff;
> +}
> +
>  return buf;
>  }
>
> @@ -160,8 +165,12 @@ static void sifive_u_otp_write(void *opaque, hwaddr addr,
>
>  /* write to backend */
>  if (s->blk) {
> -blk_pwrite(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD,
> -   >fuse[s->pa], SIFIVE_U_OTP_FUSE_WORD, 0);
> +if (blk_pwrite(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD,
> +   >fuse[s->pa], SIFIVE_U_OTP_FUSE_WORD,
> +   0) < 0) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "write error index<%d>\n", s->pa);
> +}
>  }
>
>  /* update written bit */
> @@ -248,12 +257,18 @@ static void sifive_u_otp_reset(DeviceState *dev)
>  int index = SIFIVE_U_OTP_SERIAL_ADDR;
>
>  serial_data = s->serial;
> -blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD,
> -   _data, SIFIVE_U_OTP_FUSE_WORD, 0);
> +if (blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD,
> +   _data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "write error index<%d>\n", index);
> +}
>
>  serial_data = ~(s->serial);
> -blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
> -   _data, SIFIVE_U_OTP_FUSE_WORD, 0);
> +if (blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
> +   _data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "write error index<%d>\n", index + 1);
> +}
>  }
>
>  /* Initialize write-once map */
> --
> 2.17.1
>



Re: [PATCH 04/15] arc: TCG and decoder glue code and helpers

2021-01-15 Thread Shahab Vahedi
Hi Richard,

On 12/1/20 10:35 PM, Richard Henderson wrote:
> On 11/11/20 10:17 AM, cupertinomira...@gmail.com wrote:
>> From: Cupertino Miranda 
>> +void helper_enter(CPUARCState *env, uint32_t u6)
>> +{
>> +/* nothing to do? then bye-bye! */
>> +if (!u6) {
>> +return;
>> +}
>> +
>> +uint8_t regs   = u6 & 0x0f; /* u[3:0] determines registers to save 
>> */
>> +boolsave_fp= u6 & 0x10; /* u[4] indicates if fp must be saved  
>> */
>> +boolsave_blink = u6 & 0x20; /* u[5] indicates saving of blink  
>> */
>> +uint8_t stack_size = 4 * (regs + save_fp + save_blink);
>> +
>> +/* number of regs to be saved must be sane */
>> +check_enter_leave_nr_regs(env, regs, GETPC());
> 
> Both of these checks could be translate time.
> 
>> +/* this cannot be executed in a delay/execution slot */
>> +check_delay_or_execution_slot(env, GETPC());
> 
> As could this.
> 
>> +/* stack must be a multiple of 4 (32 bit aligned) */
>> +check_addr_is_word_aligned(env, CPU_SP(env) - stack_size, GETPC());
>> +
>> +uint32_t tmp_sp = CPU_SP(env);
>> +
>> +if (save_fp) {
>> +tmp_sp -= 4;
>> +cpu_stl_data(env, tmp_sp, CPU_FP(env));
>> +}
> 
> And what if these stores raise an exception?  I doubt you're going to get an
> exception at the correct pc.

I've added a few bad-weather test cases [1] and they work as expected. Indeed,
none of those tests trigger an exception during the "cpu_stl_data()". Could you
elaborate why you think the PC might be incorrect? Then I can add the 
corresponding
tests and fix the behavior.

[1]
https://github.com/foss-for-synopsys-dwc-arc-processors/qemu/blob/master/tests/tcg/arc/check_enter_leave.S#L227

> 5-10 tcg opcodes is the rule of thumb.  A conditional exception (requiring a
> branch) is a good reason to put the whole thing out of line.
> 
> In the case of enter or leave, this is one load/store plus one addition,
> followed by a branch.  All of which is encoded as fields in the instruction.
> Extremely simple.

You're suggesting that "enter/leave" should use TCG opcodes instead of helpers? 
If yes,
do you really think it is possible to implement each with ~10 opcodes?

-- 
Shahab


Re: [PATCH 05/15] arc: TCG instruction generator and hand-definitions

2021-01-15 Thread Cupertino Miranda
Thanks for your quick reply.

On 1/15/21 8:17 PM, Richard Henderson wrote:
> On 1/15/21 7:11 AM, Cupertino Miranda wrote:
>>> On 11/11/20 10:17 AM, cupertinomira...@gmail.com wrote:
 +/*
 + * The macro to add boiler plate code for conditional execution.
 + * It will add tcg_gen codes only if there is a condition to
 + * be checked (ctx->insn.cc != 0). This macro assumes that there
 + * is a "ctx" variable of type "DisasCtxt *" in context. Remember
 + * to pair it with CC_EPILOGUE macro.
 + */
 +#define CC_PROLOGUE   \
 +  TCGv cc = tcg_temp_local_new(); \
 +  TCGLabel *done = gen_new_label();   \
 +  do {\
 +if (ctx->insn.cc) {   \
 +arc_gen_verifyCCFlag(ctx, cc);\
 +tcg_gen_brcondi_tl(TCG_COND_NE, cc, 1, done); \
 +} \
 +  } while (0)
 +
 +/*
 + * The finishing counter part of CC_PROLUGE. This is supposed
 + * to be put at the end of the function using it.
 + */
 +#define CC_EPILOGUE  \
 +if (ctx->insn.cc) {  \
 +gen_set_label(done); \
 +}\
 +tcg_temp_free(cc)
>>>
>>> Why would this need to be boiler-plate?  Why would this not simply exist in
>>> exactly one location?
>>>
>>> You don't need a tcg_temp_local_new, because the cc value is not used past 
>>> the
>>> branch.  You should free the temp immediately after the branch.
>>>
>>
>> I wonder if what you thought was to move those macros to functions and
>> call it when CC_PROLOGUE and CC_EPILOGUE are used.
>> I think the macros were choosen due to the sharing of the 'cc' and
>> 'done' variables in both CC_PROLOGUE AND CC_EPILOGUE.
> 
> I meant that the checking of ctx->insn.cc could be done at a higher level, so
> that this code existed in exactly one place, not scattered between all of the
> different instructions.
> 
> But if that isn't possible for some reason, you can certainly put "done" into
> the DisasContext so that you can have to functions cc_prologue(ctx) and
> cc_epilogue(ctx).
> 
> 
 +void gen_goto_tb(DisasContext *ctx, int n, TCGv dest)
 +{
 +tcg_gen_mov_tl(cpu_pc, dest);
 +tcg_gen_andi_tl(cpu_pcl, dest, 0xfffc);
 +if (ctx->base.singlestep_enabled) {
 +gen_helper_debug(cpu_env);
 +}
 +tcg_gen_exit_tb(NULL, 0);
>>>
>>> Missing else.  This is dead code for single-step.
>> Goes a little above my knowledge of QEMU internals to be honest.
>> Do you have a recommendation what we should be doing here ?
> 
> Both of these actions end the TB, so:
> 
>if (ctx->base.singlestep_enabled) {
>  gen_helper_debug(cpu_env);
>} else {
>  tcg_gen_exit_tb(NULL, 0);
>}
> 
Clear !!! :-)

>>> You could put all of these into a const static table.
>> What do you mean, can we make the effect of tcg_global_mem_new_i32 as
>> constant ?
> 
> No, I mean all of the data that is passed to tcg_global_mem_new.  See for
> instance target/sparc/translate.c, sparc_tcg_init().
Clear.
> 
> 
 +static void init_constants(void)
 +{
 +#define SEMANTIC_FUNCTION(...)
 +#define MAPPING(...)
 +#define CONSTANT(NAME, MNEMONIC, OP_NUM, VALUE) \
 +  add_constant_operand(MAP_##MNEMONIC##_##NAME, OP_NUM, VALUE);
 +#include "target/arc/semfunc_mapping.def"
 +#include "target/arc/extra_mapping.def"
 +#undef MAPPING
 +#undef CONSTANT
 +#undef SEMANTIC_FUNCTION
 +}
>>>
>>> Ew.  Yet another thing that can be done at build time.
>> As far as I remember it, there was no way I could generate this table
>> using the C pre-processor. Do you suggest to make this table using an
>> external tool ?
> 
> I assumed that you could just as easily generate a table using the c
> preprocessor as this function.  I guess I'd like to know more about why you
> can't...

To be fair, it would be possible but not so economical.
This would actually be a 2 dimensional table of size ((NAME * MNEMONIC) 
x (3)). 3 is the assumed maximum operand size.

In order to minimize wasted space the second dimension was implemented 
as a linked list.
Considering also this the entries in the table would also need to be of 
type struct, as we needed to mark somehow the entries that did not 
define a CONSTANT.

Please notice there are only 16 entries of this CONSTANT macro, making 
this initialization negligible.

> 
 +int32_t limm = operand.value;
 +if (operand.type & ARC_OPERAND_LIMM) {
 +limm = ctx->insn.limm;
 +tcg_gen_movi_tl(cpu_limm, limm);
 +ret = cpu_r[62];
 +} else {
 +ret = tcg_const_local_i32(limm);
 +}
 +}
 +}
 +
 +  return ret;
>>>
>>> Why 

Re: [PATCH v2 00/22] tcg: backend constraints cleanup

2021-01-15 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20210115210456.1053477-1-richard.hender...@linaro.org/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20210115210456.1053477-1-richard.hender...@linaro.org
Subject: [PATCH v2 00/22] tcg: backend constraints cleanup

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] 
patchew/20210115210456.1053477-1-richard.hender...@linaro.org -> 
patchew/20210115210456.1053477-1-richard.hender...@linaro.org
Switched to a new branch 'test'
d68e872 tcg: Remove TCG_TARGET_CON_SET_H
e95d871 tcg/tci: Split out constraint sets to tcg-target-con-set.h
1b77fd4 tcg/sparc: Split out constraint sets to tcg-target-con-set.h
8fbb090 tcg/s390: Split out constraint sets to tcg-target-con-set.h
30a9f30 tcg/riscv: Split out constraint sets to tcg-target-con-set.h
0cd363f tcg/ppc: Split out constraint sets to tcg-target-con-set.h
99ea40d tcg/mips: Split out constraint sets to tcg-target-con-set.h
3bf16ec tcg/arm: Split out constraint sets to tcg-target-con-set.h
b9a5ab6 tcg/aarch64: Split out constraint sets to tcg-target-con-set.h
40105f9 tcg/i386: Split out constraint sets to tcg-target-con-set.h
1a6d1cf tcg: Remove TCG_TARGET_CON_STR_H
bf438b2 tcg/sparc: Split out target constraints to tcg-target-con-str.h
2b16079 tcg/s390: Split out target constraints to tcg-target-con-str.h
a8d918c tcg/riscv: Split out target constraints to tcg-target-con-str.h
3a49051 tcg/mips: Split out target constraints to tcg-target-con-str.h
7d43318 tcg/tci: Split out target constraints to tcg-target-con-str.h
639d63b tcg/ppc: Split out target constraints to tcg-target-con-str.h
7be4d7c tcg/aarch64: Split out target constraints to tcg-target-con-str.h
9728a63 tcg/arm: Split out target constraints to tcg-target-con-str.h
899b298 tcg/i386: Split out target constraints to tcg-target-con-str.h
185b424 tcg/i386: Move constraint type check to tcg_target_const_match
50f1d89 tcg/tci: Drop L and S constraints

=== OUTPUT BEGIN ===
1/22 Checking commit 50f1d89ed020 (tcg/tci: Drop L and S constraints)
2/22 Checking commit 185b424e1b0d (tcg/i386: Move constraint type check to 
tcg_target_const_match)
3/22 Checking commit 899b298a9cad (tcg/i386: Split out target constraints to 
tcg-target-con-str.h)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#16: 
new file mode 100644

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#224: FILE: tcg/tcg.c:2465:
+#define CONST(CASE, MASK) \
+case CASE: def->args_ct[i].ct |= MASK; ct_str++; break;

ERROR: trailing statements should be on next line
#225: FILE: tcg/tcg.c:2466:
+case CASE: def->args_ct[i].ct |= MASK; ct_str++; break;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#226: FILE: tcg/tcg.c:2467:
+#define REGS(CASE, MASK) \
+case CASE: def->args_ct[i].regs |= MASK; ct_str++; break;

ERROR: trailing statements should be on next line
#227: FILE: tcg/tcg.c:2468:
+case CASE: def->args_ct[i].regs |= MASK; ct_str++; break;

total: 4 errors, 1 warnings, 213 lines checked

Patch 3/22 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

4/22 Checking commit 9728a63c04b5 (tcg/arm: Split out target constraints to 
tcg-target-con-str.h)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#11: 
new file mode 100644

total: 0 errors, 1 warnings, 106 lines checked

Patch 4/22 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
5/22 Checking commit 7be4d7c469dd (tcg/aarch64: Split out target constraints to 
tcg-target-con-str.h)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#11: 
new file mode 100644

total: 0 errors, 1 warnings, 89 lines checked

Patch 5/22 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
6/22 Checking commit 639d63b228ab (tcg/ppc: Split out target constraints to 
tcg-target-con-str.h)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#11: 
new file mode 100644

total: 0 errors, 1 warnings, 121 lines checked

Patch 6/22 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
7/22 Checking commit 7d43318efe71 (tcg/tci: Split out target constraints to 
tcg-target-con-str.h)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#11: 
new file 

[PATCH v2 18/22] tcg/riscv: Split out constraint sets to tcg-target-con-set.h

2021-01-15 Thread Richard Henderson
Reviewed-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target-con-set.h | 30 
 tcg/riscv/tcg-target.h |  1 +
 tcg/riscv/tcg-target.c.inc | 83 ++
 3 files changed, 54 insertions(+), 60 deletions(-)
 create mode 100644 tcg/riscv/tcg-target-con-set.h

diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
new file mode 100644
index 00..cf0ac4d751
--- /dev/null
+++ b/tcg/riscv/tcg-target-con-set.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define RISC-V target-specific constraint sets.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * C_On_Im(...) defines a constraint set with  outputs and  inputs.
+ * Each operand should be a sequence of constraint letters as defined by
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
+ */
+C_O0_I1(r)
+C_O0_I2(LZ, L)
+C_O0_I2(rZ, r)
+C_O0_I2(rZ, rZ)
+C_O0_I3(LZ, L, L)
+C_O0_I3(LZ, LZ, L)
+C_O0_I4(LZ, LZ, L, L)
+C_O0_I4(rZ, rZ, rZ, rZ)
+C_O1_I1(r, L)
+C_O1_I1(r, r)
+C_O1_I2(r, L, L)
+C_O1_I2(r, r, ri)
+C_O1_I2(r, r, rI)
+C_O1_I2(r, rZ, rN)
+C_O1_I2(r, rZ, rZ)
+C_O1_I4(r, rZ, rZ, rZ, rZ)
+C_O2_I1(r, r, L)
+C_O2_I2(r, r, L, L)
+C_O2_I4(r, r, rZ, rZ, rM, rM)
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 727c8df418..a998b951e4 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -171,5 +171,6 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_POOL_LABELS
 
 #define TCG_TARGET_HAS_MEMORY_BSWAP 0
+#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 185b569f4b..67605b7cf8 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -1541,50 +1541,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 }
 }
 
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 {
-static const TCGTargetOpDef r
-= { .args_ct_str = { "r" } };
-static const TCGTargetOpDef r_r
-= { .args_ct_str = { "r", "r" } };
-static const TCGTargetOpDef rZ_r
-= { .args_ct_str = { "rZ", "r" } };
-static const TCGTargetOpDef rZ_rZ
-= { .args_ct_str = { "rZ", "rZ" } };
-static const TCGTargetOpDef rZ_rZ_rZ_rZ
-= { .args_ct_str = { "rZ", "rZ", "rZ", "rZ" } };
-static const TCGTargetOpDef r_r_ri
-= { .args_ct_str = { "r", "r", "ri" } };
-static const TCGTargetOpDef r_r_rI
-= { .args_ct_str = { "r", "r", "rI" } };
-static const TCGTargetOpDef r_rZ_rN
-= { .args_ct_str = { "r", "rZ", "rN" } };
-static const TCGTargetOpDef r_rZ_rZ
-= { .args_ct_str = { "r", "rZ", "rZ" } };
-static const TCGTargetOpDef r_rZ_rZ_rZ_rZ
-= { .args_ct_str = { "r", "rZ", "rZ", "rZ", "rZ" } };
-static const TCGTargetOpDef r_L
-= { .args_ct_str = { "r", "L" } };
-static const TCGTargetOpDef r_r_L
-= { .args_ct_str = { "r", "r", "L" } };
-static const TCGTargetOpDef r_L_L
-= { .args_ct_str = { "r", "L", "L" } };
-static const TCGTargetOpDef r_r_L_L
-= { .args_ct_str = { "r", "r", "L", "L" } };
-static const TCGTargetOpDef LZ_L
-= { .args_ct_str = { "LZ", "L" } };
-static const TCGTargetOpDef LZ_L_L
-= { .args_ct_str = { "LZ", "L", "L" } };
-static const TCGTargetOpDef LZ_LZ_L
-= { .args_ct_str = { "LZ", "LZ", "L" } };
-static const TCGTargetOpDef LZ_LZ_L_L
-= { .args_ct_str = { "LZ", "LZ", "L", "L" } };
-static const TCGTargetOpDef r_r_rZ_rZ_rM_rM
-= { .args_ct_str = { "r", "r", "rZ", "rZ", "rM", "rM" } };
-
 switch (op) {
 case INDEX_op_goto_ptr:
-return 
+return C_O0_I1(r);
 
 case INDEX_op_ld8u_i32:
 case INDEX_op_ld8s_i32:
@@ -1616,7 +1577,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_extrl_i64_i32:
 case INDEX_op_extrh_i64_i32:
 case INDEX_op_ext_i32_i64:
-return _r;
+return C_O1_I1(r, r);
 
 case INDEX_op_st8_i32:
 case INDEX_op_st16_i32:
@@ -1625,7 +1586,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_st16_i64:
 case INDEX_op_st32_i64:
 case INDEX_op_st_i64:
-return _r;
+return C_O0_I2(rZ, r);
 
 case INDEX_op_add_i32:
 case INDEX_op_and_i32:
@@ -1635,11 +1596,11 @@ static const TCGTargetOpDef 
*tcg_target_op_def(TCGOpcode op)
 case INDEX_op_and_i64:
 case INDEX_op_or_i64:
 case INDEX_op_xor_i64:
-return _r_rI;
+return C_O1_I2(r, r, rI);
 
 case INDEX_op_sub_i32:
 case INDEX_op_sub_i64:
-return _rZ_rN;
+return C_O1_I2(r, rZ, rN);
 
 case INDEX_op_mul_i32:
 case INDEX_op_mulsh_i32:
@@ -1657,7 +1618,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_rem_i64:
 case 

[PATCH v2 22/22] tcg: Remove TCG_TARGET_CON_SET_H

2021-01-15 Thread Richard Henderson
All backends have now been converted to tcg-target-con-set.h,
so we can remove the fallback code.

Reviewed-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.h |  1 -
 tcg/arm/tcg-target.h |  1 -
 tcg/i386/tcg-target.h|  1 -
 tcg/mips/tcg-target.h|  1 -
 tcg/ppc/tcg-target.h |  1 -
 tcg/riscv/tcg-target.h   |  1 -
 tcg/s390/tcg-target.h|  1 -
 tcg/sparc/tcg-target.h   |  1 -
 tcg/tci/tcg-target.h |  2 --
 tcg/tcg.c| 12 
 10 files changed, 22 deletions(-)

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 200e9b5e0e..5ec30dba25 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -155,6 +155,5 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
-#define TCG_TARGET_CON_SET_H
 
 #endif /* AARCH64_TCG_TARGET_H */
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 4d201b1216..8d1fee6327 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -142,6 +142,5 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
-#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 48a6f2a336..b693d3692d 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -235,6 +235,5 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
-#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index e520a9d6e3..c2c32fb38f 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -207,6 +207,5 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #ifdef CONFIG_SOFTMMU
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
-#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index 551f8d0fc9..d1339afc66 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -185,6 +185,5 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
-#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index a998b951e4..727c8df418 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -171,6 +171,5 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_POOL_LABELS
 
 #define TCG_TARGET_HAS_MEMORY_BSWAP 0
-#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index 7aafd25a46..641464eea4 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -159,6 +159,5 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
-#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index f50e8d50ee..f66f5d07dc 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -168,6 +168,5 @@ extern bool use_vis3_instructions;
 void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
 
 #define TCG_TARGET_NEED_POOL_LABELS
-#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 1efd8c4fb0..bb784e018e 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -207,6 +207,4 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 /* no need to flush icache explicitly */
 }
 
-#define TCG_TARGET_CON_SET_H
-
 #endif /* TCG_TARGET_H */
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 36fdeef10f..4d4f4e9b71 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -69,9 +69,6 @@
 /* Forward declarations for functions declared in tcg-target.c.inc and
used here. */
 static void tcg_target_init(TCGContext *s);
-#ifndef TCG_TARGET_CON_SET_H
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode);
-#endif
 static void tcg_target_qemu_prologue(TCGContext *s);
 static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
 intptr_t value, intptr_t addend);
@@ -349,7 +346,6 @@ static void set_jmp_reset_offset(TCGContext *s, int which)
 s->tb_jmp_reset_offset[which] = tcg_current_code_size(s);
 }
 
-#ifdef TCG_TARGET_CON_SET_H
 #define C_PFX1(P, A)P##A
 #define C_PFX2(P, A, B) P##A##_##B
 #define C_PFX3(P, A, B, C)  P##A##_##B##_##C
@@ -463,8 +459,6 @@ static const TCGTargetOpDef constraint_sets[] = {
 #define C_O2_I4(O1, O2, I1, I2, I3, I4) \
 C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4)
 
-#endif /* TCG_TARGET_CON_SET_H */
-
 #include "tcg-target.c.inc"
 
 /* compare a pointer @ptr and 

[PATCH v2 17/22] tcg/ppc: Split out constraint sets to tcg-target-con-set.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/ppc/tcg-target-con-set.h |  42 +++
 tcg/ppc/tcg-target.h |   1 +
 tcg/ppc/tcg-target.c.inc | 136 +++
 3 files changed, 99 insertions(+), 80 deletions(-)
 create mode 100644 tcg/ppc/tcg-target-con-set.h

diff --git a/tcg/ppc/tcg-target-con-set.h b/tcg/ppc/tcg-target-con-set.h
new file mode 100644
index 00..a1a345883d
--- /dev/null
+++ b/tcg/ppc/tcg-target-con-set.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define PowerPC target-specific constraint sets.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * C_On_Im(...) defines a constraint set with  outputs and  inputs.
+ * Each operand should be a sequence of constraint letters as defined by
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
+ */
+C_O0_I1(r)
+C_O0_I2(r, r)
+C_O0_I2(r, ri)
+C_O0_I2(S, S)
+C_O0_I2(v, r)
+C_O0_I3(S, S, S)
+C_O0_I4(r, r, ri, ri)
+C_O0_I4(S, S, S, S)
+C_O1_I1(r, L)
+C_O1_I1(r, r)
+C_O1_I1(v, r)
+C_O1_I1(v, v)
+C_O1_I1(v, vr)
+C_O1_I2(r, 0, rZ)
+C_O1_I2(r, L, L)
+C_O1_I2(r, rI, ri)
+C_O1_I2(r, rI, rT)
+C_O1_I2(r, r, r)
+C_O1_I2(r, r, ri)
+C_O1_I2(r, r, rI)
+C_O1_I2(r, r, rT)
+C_O1_I2(r, r, rU)
+C_O1_I2(r, r, rZW)
+C_O1_I2(v, v, v)
+C_O1_I3(v, v, v, v)
+C_O1_I4(r, r, ri, rZ, rZ)
+C_O1_I4(r, r, r, ri, ri)
+C_O2_I1(L, L, L)
+C_O2_I2(L, L, L, L)
+C_O2_I4(r, r, rI, rZM, r, r)
+C_O2_I4(r, r, r, r, rI, rZM)
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index d1339afc66..551f8d0fc9 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -185,5 +185,6 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
+#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index e5aa8d2d10..4377d15d62 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -3456,62 +3456,17 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece,
 va_end(va);
 }
 
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 {
-static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
-static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
-static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
-static const TCGTargetOpDef S_S = { .args_ct_str = { "S", "S" } };
-static const TCGTargetOpDef r_ri = { .args_ct_str = { "r", "ri" } };
-static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } };
-static const TCGTargetOpDef r_L_L = { .args_ct_str = { "r", "L", "L" } };
-static const TCGTargetOpDef L_L_L = { .args_ct_str = { "L", "L", "L" } };
-static const TCGTargetOpDef S_S_S = { .args_ct_str = { "S", "S", "S" } };
-static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
-static const TCGTargetOpDef r_r_rI = { .args_ct_str = { "r", "r", "rI" } };
-static const TCGTargetOpDef r_r_rT = { .args_ct_str = { "r", "r", "rT" } };
-static const TCGTargetOpDef r_r_rU = { .args_ct_str = { "r", "r", "rU" } };
-static const TCGTargetOpDef r_rI_ri
-= { .args_ct_str = { "r", "rI", "ri" } };
-static const TCGTargetOpDef r_rI_rT
-= { .args_ct_str = { "r", "rI", "rT" } };
-static const TCGTargetOpDef r_r_rZW
-= { .args_ct_str = { "r", "r", "rZW" } };
-static const TCGTargetOpDef L_L_L_L
-= { .args_ct_str = { "L", "L", "L", "L" } };
-static const TCGTargetOpDef S_S_S_S
-= { .args_ct_str = { "S", "S", "S", "S" } };
-static const TCGTargetOpDef movc
-= { .args_ct_str = { "r", "r", "ri", "rZ", "rZ" } };
-static const TCGTargetOpDef dep
-= { .args_ct_str = { "r", "0", "rZ" } };
-static const TCGTargetOpDef br2
-= { .args_ct_str = { "r", "r", "ri", "ri" } };
-static const TCGTargetOpDef setc2
-= { .args_ct_str = { "r", "r", "r", "ri", "ri" } };
-static const TCGTargetOpDef add2
-= { .args_ct_str = { "r", "r", "r", "r", "rI", "rZM" } };
-static const TCGTargetOpDef sub2
-= { .args_ct_str = { "r", "r", "rI", "rZM", "r", "r" } };
-static const TCGTargetOpDef v_r = { .args_ct_str = { "v", "r" } };
-static const TCGTargetOpDef v_vr = { .args_ct_str = { "v", "vr" } };
-static const TCGTargetOpDef v_v = { .args_ct_str = { "v", "v" } };
-static const TCGTargetOpDef v_v_v = { .args_ct_str = { "v", "v", "v" } };
-static const TCGTargetOpDef v_v_v_v
-= { .args_ct_str = { "v", "v", "v", "v" } };
-
 switch (op) {
 case INDEX_op_goto_ptr:
-return 
+return C_O0_I1(r);
 
 case INDEX_op_ld8u_i32:
 case INDEX_op_ld8s_i32:
 case INDEX_op_ld16u_i32:
 case INDEX_op_ld16s_i32:
 case INDEX_op_ld_i32:
-case INDEX_op_st8_i32:
-case INDEX_op_st16_i32:
-case INDEX_op_st_i32:
 case INDEX_op_ctpop_i32:

[PATCH v2 21/22] tcg/tci: Split out constraint sets to tcg-target-con-set.h

2021-01-15 Thread Richard Henderson
This requires finishing the conversion to tcg_target_op_def.
Remove quite a lot of ifdefs, since we can reference opcodes
even if they are not implemented.

Signed-off-by: Richard Henderson 
---
 tcg/tci/tcg-target-con-set.h |  25 +++
 tcg/tci/tcg-target.h |   2 +
 tcg/tci/tcg-target.c.inc | 343 +--
 3 files changed, 152 insertions(+), 218 deletions(-)
 create mode 100644 tcg/tci/tcg-target-con-set.h

diff --git a/tcg/tci/tcg-target-con-set.h b/tcg/tci/tcg-target-con-set.h
new file mode 100644
index 00..38e82f7535
--- /dev/null
+++ b/tcg/tci/tcg-target-con-set.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * TCI target-specific constraint sets.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * C_On_Im(...) defines a constraint set with  outputs and  inputs.
+ * Each operand should be a sequence of constraint letters as defined by
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
+ */
+C_O0_I2(r, r)
+C_O0_I2(r, ri)
+C_O0_I3(r, r, r)
+C_O0_I4(r, r, ri, ri)
+C_O0_I4(r, r, r, r)
+C_O1_I1(r, r)
+C_O1_I2(r, 0, r)
+C_O1_I2(r, ri, ri)
+C_O1_I2(r, r, r)
+C_O1_I2(r, r, ri)
+C_O1_I4(r, r, r, ri, ri)
+C_O2_I1(r, r, r)
+C_O2_I2(r, r, r, r)
+C_O2_I4(r, r, r, r, r, r)
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index bb784e018e..1efd8c4fb0 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -207,4 +207,6 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 /* no need to flush icache explicitly */
 }
 
+#define TCG_TARGET_CON_SET_H
+
 #endif /* TCG_TARGET_H */
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index c913d85c37..62bedaca28 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -37,236 +37,143 @@
 /* Bitfield n...m (in 32 bit value). */
 #define BITS(n, m) (((0xU << (31 - n)) >> (31 - n + m)) << m)
 
-/* Macros used in tcg_target_op_defs. */
-#define R   "r"
-#define RI  "ri"
-#if TCG_TARGET_REG_BITS == 32
-# define R64"r", "r"
-#else
-# define R64"r"
-#endif
-#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
-# define L  "r", "r"
-# define S  "r", "r"
-#else
-# define L  "r"
-# define S  "r"
-#endif
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
+{
+switch (op) {
+case INDEX_op_ld8u_i32:
+case INDEX_op_ld8s_i32:
+case INDEX_op_ld16u_i32:
+case INDEX_op_ld16s_i32:
+case INDEX_op_ld_i32:
+case INDEX_op_ld8u_i64:
+case INDEX_op_ld8s_i64:
+case INDEX_op_ld16u_i64:
+case INDEX_op_ld16s_i64:
+case INDEX_op_ld32u_i64:
+case INDEX_op_ld32s_i64:
+case INDEX_op_ld_i64:
+case INDEX_op_not_i32:
+case INDEX_op_not_i64:
+case INDEX_op_neg_i32:
+case INDEX_op_neg_i64:
+case INDEX_op_ext8s_i32:
+case INDEX_op_ext8s_i64:
+case INDEX_op_ext16s_i32:
+case INDEX_op_ext16s_i64:
+case INDEX_op_ext8u_i32:
+case INDEX_op_ext8u_i64:
+case INDEX_op_ext16u_i32:
+case INDEX_op_ext16u_i64:
+case INDEX_op_ext32s_i64:
+case INDEX_op_ext32u_i64:
+case INDEX_op_ext_i32_i64:
+case INDEX_op_extu_i32_i64:
+case INDEX_op_bswap16_i32:
+case INDEX_op_bswap16_i64:
+case INDEX_op_bswap32_i32:
+case INDEX_op_bswap32_i64:
+case INDEX_op_bswap64_i64:
+return C_O1_I1(r, r);
 
-/* TODO: documentation. */
-static const TCGTargetOpDef tcg_target_op_defs[] = {
-{ INDEX_op_exit_tb, { NULL } },
-{ INDEX_op_goto_tb, { NULL } },
-{ INDEX_op_br, { NULL } },
+case INDEX_op_st8_i32:
+case INDEX_op_st16_i32:
+case INDEX_op_st_i32:
+case INDEX_op_st8_i64:
+case INDEX_op_st16_i64:
+case INDEX_op_st32_i64:
+case INDEX_op_st_i64:
+return C_O0_I2(r, r);
 
-{ INDEX_op_ld8u_i32, { R, R } },
-{ INDEX_op_ld8s_i32, { R, R } },
-{ INDEX_op_ld16u_i32, { R, R } },
-{ INDEX_op_ld16s_i32, { R, R } },
-{ INDEX_op_ld_i32, { R, R } },
-{ INDEX_op_st8_i32, { R, R } },
-{ INDEX_op_st16_i32, { R, R } },
-{ INDEX_op_st_i32, { R, R } },
+case INDEX_op_div_i32:
+case INDEX_op_div_i64:
+case INDEX_op_divu_i32:
+case INDEX_op_divu_i64:
+case INDEX_op_rem_i32:
+case INDEX_op_rem_i64:
+case INDEX_op_remu_i32:
+case INDEX_op_remu_i64:
+return C_O1_I2(r, r, r);
 
-{ INDEX_op_add_i32, { R, RI, RI } },
-{ INDEX_op_sub_i32, { R, RI, RI } },
-{ INDEX_op_mul_i32, { R, RI, RI } },
-#if TCG_TARGET_HAS_div_i32
-{ INDEX_op_div_i32, { R, R, R } },
-{ INDEX_op_divu_i32, { R, R, R } },
-{ INDEX_op_rem_i32, { R, R, R } },
-{ INDEX_op_remu_i32, { R, R, R } },
-#elif TCG_TARGET_HAS_div2_i32
-{ INDEX_op_div2_i32, { R, R, "0", "1", R } },
-{ INDEX_op_divu2_i32, { R, R, "0", "1", R } },
-#endif
-/* TODO: Does R, RI, RI result in faster code than R, R, RI?
-   If both operands are constants, we can optimize. */
-{ INDEX_op_and_i32, { R, RI, RI } },
-#if TCG_TARGET_HAS_andc_i32
-{ 

[PATCH v2 13/22] tcg/i386: Split out constraint sets to tcg-target-con-set.h

2021-01-15 Thread Richard Henderson
This exports the constraint sets from tcg_target_op_def to
a place we will be able to manipulate more in future.

Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target-con-set.h |  54 ++
 tcg/i386/tcg-target.h |   1 +
 tcg/tcg.c | 122 +
 tcg/i386/tcg-target.c.inc | 194 --
 4 files changed, 244 insertions(+), 127 deletions(-)
 create mode 100644 tcg/i386/tcg-target-con-set.h

diff --git a/tcg/i386/tcg-target-con-set.h b/tcg/i386/tcg-target-con-set.h
new file mode 100644
index 00..66123ab193
--- /dev/null
+++ b/tcg/i386/tcg-target-con-set.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define i386 target-specific constraint sets.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * C_On_Im(...) defines a constraint set with  outputs and  inputs.
+ * Each operand should be a sequence of constraint letters as defined by
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
+ *
+ * C_N1_Im(...) defines a constraint set with 1 output and  inputs,
+ * except that the output must use a new register.
+ */
+C_O0_I1(r)
+C_O0_I2(L, L)
+C_O0_I2(qi, r)
+C_O0_I2(re, r)
+C_O0_I2(ri, r)
+C_O0_I2(r, re)
+C_O0_I2(s, L)
+C_O0_I2(x, r)
+C_O0_I3(L, L, L)
+C_O0_I3(s, L, L)
+C_O0_I4(L, L, L, L)
+C_O0_I4(r, r, ri, ri)
+C_O1_I1(r, 0)
+C_O1_I1(r, L)
+C_O1_I1(r, q)
+C_O1_I1(r, r)
+C_O1_I1(x, r)
+C_O1_I1(x, x)
+C_O1_I2(Q, 0, Q)
+C_O1_I2(q, r, re)
+C_O1_I2(r, 0, ci)
+C_O1_I2(r, 0, r)
+C_O1_I2(r, 0, re)
+C_O1_I2(r, 0, reZ)
+C_O1_I2(r, 0, ri)
+C_O1_I2(r, 0, rI)
+C_O1_I2(r, L, L)
+C_O1_I2(r, r, re)
+C_O1_I2(r, r, ri)
+C_O1_I2(x, x, x)
+C_N1_I2(r, r, r)
+C_N1_I2(r, r, rW)
+C_O1_I3(x, x, x, x)
+C_O1_I4(r, r, re, r, 0)
+C_O1_I4(r, r, r, ri, ri)
+C_O2_I1(r, r, L)
+C_O2_I2(a, d, a, r)
+C_O2_I2(r, r, L, L)
+C_O2_I3(a, d, 0, 1, r)
+C_O2_I4(r, r, 0, 1, re, re)
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index b693d3692d..48a6f2a336 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -235,5 +235,6 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
+#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 7b4d0b3f69..36fdeef10f 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -69,7 +69,9 @@
 /* Forward declarations for functions declared in tcg-target.c.inc and
used here. */
 static void tcg_target_init(TCGContext *s);
+#ifndef TCG_TARGET_CON_SET_H
 static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode);
+#endif
 static void tcg_target_qemu_prologue(TCGContext *s);
 static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
 intptr_t value, intptr_t addend);
@@ -347,6 +349,122 @@ static void set_jmp_reset_offset(TCGContext *s, int which)
 s->tb_jmp_reset_offset[which] = tcg_current_code_size(s);
 }
 
+#ifdef TCG_TARGET_CON_SET_H
+#define C_PFX1(P, A)P##A
+#define C_PFX2(P, A, B) P##A##_##B
+#define C_PFX3(P, A, B, C)  P##A##_##B##_##C
+#define C_PFX4(P, A, B, C, D)   P##A##_##B##_##C##_##D
+#define C_PFX5(P, A, B, C, D, E)P##A##_##B##_##C##_##D##_##E
+#define C_PFX6(P, A, B, C, D, E, F) P##A##_##B##_##C##_##D##_##E##_##F
+
+/* Define an enumeration for the various combinations. */
+
+#define C_O0_I1(I1) C_PFX1(c_o0_i1_, I1),
+#define C_O0_I2(I1, I2) C_PFX2(c_o0_i2_, I1, I2),
+#define C_O0_I3(I1, I2, I3) C_PFX3(c_o0_i3_, I1, I2, I3),
+#define C_O0_I4(I1, I2, I3, I4) C_PFX4(c_o0_i4_, I1, I2, I3, I4),
+
+#define C_O1_I1(O1, I1) C_PFX2(c_o1_i1_, O1, I1),
+#define C_O1_I2(O1, I1, I2) C_PFX3(c_o1_i2_, O1, I1, I2),
+#define C_O1_I3(O1, I1, I2, I3) C_PFX4(c_o1_i3_, O1, I1, I2, I3),
+#define C_O1_I4(O1, I1, I2, I3, I4) C_PFX5(c_o1_i4_, O1, I1, I2, I3, I4),
+
+#define C_N1_I2(O1, I1, I2) C_PFX3(c_n1_i2_, O1, I1, I2),
+
+#define C_O2_I1(O1, O2, I1) C_PFX3(c_o2_i1_, O1, O2, I1),
+#define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2),
+#define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3),
+#define C_O2_I4(O1, O2, I1, I2, I3, I4) \
+C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4),
+
+typedef enum {
+#include "tcg-target-con-set.h"
+} TCGConstraintSetIndex;
+
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode);
+
+#undef C_O0_I1
+#undef C_O0_I2
+#undef C_O0_I3
+#undef C_O0_I4
+#undef C_O1_I1
+#undef C_O1_I2
+#undef C_O1_I3
+#undef C_O1_I4
+#undef C_N1_I2
+#undef C_O2_I1
+#undef C_O2_I2
+#undef C_O2_I3
+#undef C_O2_I4
+
+/* Put all of the constraint sets into an array, indexed by the enum. */
+
+#define C_O0_I1(I1) { .args_ct_str = { #I1 } },
+#define C_O0_I2(I1, I2) { .args_ct_str = { #I1, #I2 } },
+#define C_O0_I3(I1, I2, I3) { .args_ct_str = { #I1, #I2, #I3 } },

[PATCH v2 16/22] tcg/mips: Split out constraint sets to tcg-target-con-set.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/mips/tcg-target-con-set.h | 36 +
 tcg/mips/tcg-target.h |  1 +
 tcg/mips/tcg-target.c.inc | 96 +++
 3 files changed, 66 insertions(+), 67 deletions(-)
 create mode 100644 tcg/mips/tcg-target-con-set.h

diff --git a/tcg/mips/tcg-target-con-set.h b/tcg/mips/tcg-target-con-set.h
new file mode 100644
index 00..fe3e868a2f
--- /dev/null
+++ b/tcg/mips/tcg-target-con-set.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define MIPS target-specific constraint sets.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * C_On_Im(...) defines a constraint set with  outputs and  inputs.
+ * Each operand should be a sequence of constraint letters as defined by
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
+ */
+C_O0_I1(r)
+C_O0_I2(rZ, r)
+C_O0_I2(rZ, rZ)
+C_O0_I2(SZ, S)
+C_O0_I3(SZ, S, S)
+C_O0_I3(SZ, SZ, S)
+C_O0_I4(rZ, rZ, rZ, rZ)
+C_O0_I4(SZ, SZ, S, S)
+C_O1_I1(r, L)
+C_O1_I1(r, r)
+C_O1_I2(r, 0, rZ)
+C_O1_I2(r, L, L)
+C_O1_I2(r, r, ri)
+C_O1_I2(r, r, rI)
+C_O1_I2(r, r, rIK)
+C_O1_I2(r, r, rJ)
+C_O1_I2(r, r, rWZ)
+C_O1_I2(r, rZ, rN)
+C_O1_I2(r, rZ, rZ)
+C_O1_I4(r, rZ, rZ, rZ, 0)
+C_O1_I4(r, rZ, rZ, rZ, rZ)
+C_O2_I1(r, r, L)
+C_O2_I2(r, r, L, L)
+C_O2_I2(r, r, r, r)
+C_O2_I4(r, r, rZ, rZ, rN, rN)
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index c2c32fb38f..e520a9d6e3 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -207,5 +207,6 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #ifdef CONFIG_SOFTMMU
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
+#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
index 61e8740012..c93ddbe6b1 100644
--- a/tcg/mips/tcg-target.c.inc
+++ b/tcg/mips/tcg-target.c.inc
@@ -2107,52 +2107,11 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc,
 }
 }
 
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 {
-static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
-static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
-static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
-static const TCGTargetOpDef rZ_r = { .args_ct_str = { "rZ", "r" } };
-static const TCGTargetOpDef SZ_S = { .args_ct_str = { "SZ", "S" } };
-static const TCGTargetOpDef rZ_rZ = { .args_ct_str = { "rZ", "rZ" } };
-static const TCGTargetOpDef r_r_L = { .args_ct_str = { "r", "r", "L" } };
-static const TCGTargetOpDef r_L_L = { .args_ct_str = { "r", "L", "L" } };
-static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
-static const TCGTargetOpDef r_r_rI = { .args_ct_str = { "r", "r", "rI" } };
-static const TCGTargetOpDef r_r_rJ = { .args_ct_str = { "r", "r", "rJ" } };
-static const TCGTargetOpDef SZ_S_S = { .args_ct_str = { "SZ", "S", "S" } };
-static const TCGTargetOpDef SZ_SZ_S
-= { .args_ct_str = { "SZ", "SZ", "S" } };
-static const TCGTargetOpDef SZ_SZ_S_S
-= { .args_ct_str = { "SZ", "SZ", "S", "S" } };
-static const TCGTargetOpDef r_rZ_rN
-= { .args_ct_str = { "r", "rZ", "rN" } };
-static const TCGTargetOpDef r_rZ_rZ
-= { .args_ct_str = { "r", "rZ", "rZ" } };
-static const TCGTargetOpDef r_r_rIK
-= { .args_ct_str = { "r", "r", "rIK" } };
-static const TCGTargetOpDef r_r_rWZ
-= { .args_ct_str = { "r", "r", "rWZ" } };
-static const TCGTargetOpDef r_r_r_r
-= { .args_ct_str = { "r", "r", "r", "r" } };
-static const TCGTargetOpDef r_r_L_L
-= { .args_ct_str = { "r", "r", "L", "L" } };
-static const TCGTargetOpDef dep
-= { .args_ct_str = { "r", "0", "rZ" } };
-static const TCGTargetOpDef movc
-= { .args_ct_str = { "r", "rZ", "rZ", "rZ", "0" } };
-static const TCGTargetOpDef movc_r6
-= { .args_ct_str = { "r", "rZ", "rZ", "rZ", "rZ" } };
-static const TCGTargetOpDef add2
-= { .args_ct_str = { "r", "r", "rZ", "rZ", "rN", "rN" } };
-static const TCGTargetOpDef br2
-= { .args_ct_str = { "rZ", "rZ", "rZ", "rZ" } };
-static const TCGTargetOpDef setc2
-= { .args_ct_str = { "r", "rZ", "rZ", "rZ", "rZ" } };
-
 switch (op) {
 case INDEX_op_goto_ptr:
-return 
+return C_O0_I1(r);
 
 case INDEX_op_ld8u_i32:
 case INDEX_op_ld8s_i32:
@@ -2185,7 +2144,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_extrl_i64_i32:
 case INDEX_op_extrh_i64_i32:
 case INDEX_op_extract_i64:
-return _r;
+return C_O1_I1(r, r);
 
 case INDEX_op_st8_i32:
 case INDEX_op_st16_i32:
@@ -2194,14 +2153,14 @@ static const TCGTargetOpDef 
*tcg_target_op_def(TCGOpcode op)
 case INDEX_op_st16_i64:
 case INDEX_op_st32_i64:
 case INDEX_op_st_i64:
-return _r;
+return 

[PATCH v2 20/22] tcg/sparc: Split out constraint sets to tcg-target-con-set.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/sparc/tcg-target-con-set.h | 32 +++
 tcg/sparc/tcg-target.h |  1 +
 tcg/sparc/tcg-target.c.inc | 75 +++---
 3 files changed, 56 insertions(+), 52 deletions(-)
 create mode 100644 tcg/sparc/tcg-target-con-set.h

diff --git a/tcg/sparc/tcg-target-con-set.h b/tcg/sparc/tcg-target-con-set.h
new file mode 100644
index 00..3b751dc3fb
--- /dev/null
+++ b/tcg/sparc/tcg-target-con-set.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define Sparc target-specific constraint sets.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * C_On_Im(...) defines a constraint set with  outputs and  inputs.
+ * Each operand should be a sequence of constraint letters as defined by
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
+ */
+C_O0_I1(r)
+C_O0_I2(rZ, r)
+C_O0_I2(RZ, r)
+C_O0_I2(rZ, rJ)
+C_O0_I2(RZ, RJ)
+C_O0_I2(sZ, A)
+C_O0_I2(SZ, A)
+C_O1_I1(r, A)
+C_O1_I1(R, A)
+C_O1_I1(r, r)
+C_O1_I1(r, R)
+C_O1_I1(R, r)
+C_O1_I1(R, R)
+C_O1_I2(R, R, R)
+C_O1_I2(r, rZ, rJ)
+C_O1_I2(R, RZ, RJ)
+C_O1_I4(r, rZ, rJ, rI, 0)
+C_O1_I4(R, RZ, RJ, RI, 0)
+C_O2_I2(r, r, rZ, rJ)
+C_O2_I4(R, R, RZ, RZ, RJ, RI)
+C_O2_I4(r, r, rZ, rZ, rJ, rJ)
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index f66f5d07dc..f50e8d50ee 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -168,5 +168,6 @@ extern bool use_vis3_instructions;
 void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
 
 #define TCG_TARGET_NEED_POOL_LABELS
+#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
index ea2b3274d4..03f3aa6a23 100644
--- a/tcg/sparc/tcg-target.c.inc
+++ b/tcg/sparc/tcg-target.c.inc
@@ -1559,40 +1559,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 }
 }
 
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 {
-static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
-static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
-static const TCGTargetOpDef R_r = { .args_ct_str = { "R", "r" } };
-static const TCGTargetOpDef r_R = { .args_ct_str = { "r", "R" } };
-static const TCGTargetOpDef R_R = { .args_ct_str = { "R", "R" } };
-static const TCGTargetOpDef r_A = { .args_ct_str = { "r", "A" } };
-static const TCGTargetOpDef R_A = { .args_ct_str = { "R", "A" } };
-static const TCGTargetOpDef rZ_r = { .args_ct_str = { "rZ", "r" } };
-static const TCGTargetOpDef RZ_r = { .args_ct_str = { "RZ", "r" } };
-static const TCGTargetOpDef sZ_A = { .args_ct_str = { "sZ", "A" } };
-static const TCGTargetOpDef SZ_A = { .args_ct_str = { "SZ", "A" } };
-static const TCGTargetOpDef rZ_rJ = { .args_ct_str = { "rZ", "rJ" } };
-static const TCGTargetOpDef RZ_RJ = { .args_ct_str = { "RZ", "RJ" } };
-static const TCGTargetOpDef R_R_R = { .args_ct_str = { "R", "R", "R" } };
-static const TCGTargetOpDef r_rZ_rJ
-= { .args_ct_str = { "r", "rZ", "rJ" } };
-static const TCGTargetOpDef R_RZ_RJ
-= { .args_ct_str = { "R", "RZ", "RJ" } };
-static const TCGTargetOpDef r_r_rZ_rJ
-= { .args_ct_str = { "r", "r", "rZ", "rJ" } };
-static const TCGTargetOpDef movc_32
-= { .args_ct_str = { "r", "rZ", "rJ", "rI", "0" } };
-static const TCGTargetOpDef movc_64
-= { .args_ct_str = { "R", "RZ", "RJ", "RI", "0" } };
-static const TCGTargetOpDef add2_32
-= { .args_ct_str = { "r", "r", "rZ", "rZ", "rJ", "rJ" } };
-static const TCGTargetOpDef add2_64
-= { .args_ct_str = { "R", "R", "RZ", "RZ", "RJ", "RI" } };
-
 switch (op) {
 case INDEX_op_goto_ptr:
-return 
+return C_O0_I1(r);
 
 case INDEX_op_ld8u_i32:
 case INDEX_op_ld8s_i32:
@@ -1601,12 +1572,12 @@ static const TCGTargetOpDef 
*tcg_target_op_def(TCGOpcode op)
 case INDEX_op_ld_i32:
 case INDEX_op_neg_i32:
 case INDEX_op_not_i32:
-return _r;
+return C_O1_I1(r, r);
 
 case INDEX_op_st8_i32:
 case INDEX_op_st16_i32:
 case INDEX_op_st_i32:
-return _r;
+return C_O0_I2(rZ, r);
 
 case INDEX_op_add_i32:
 case INDEX_op_mul_i32:
@@ -1622,18 +1593,18 @@ static const TCGTargetOpDef 
*tcg_target_op_def(TCGOpcode op)
 case INDEX_op_shr_i32:
 case INDEX_op_sar_i32:
 case INDEX_op_setcond_i32:
-return _rZ_rJ;
+return C_O1_I2(r, rZ, rJ);
 
 case INDEX_op_brcond_i32:
-return _rJ;
+return C_O0_I2(rZ, rJ);
 case INDEX_op_movcond_i32:
-return _32;
+return C_O1_I4(r, rZ, rJ, rI, 0);
 case INDEX_op_add2_i32:
 case INDEX_op_sub2_i32:
-return _32;
+return C_O2_I4(r, r, rZ, rZ, rJ, rJ);
 case INDEX_op_mulu2_i32:
 case INDEX_op_muls2_i32:
-return _r_rZ_rJ;
+return C_O2_I2(r, r, rZ, rJ);
 
 case 

[PATCH v2 14/22] tcg/aarch64: Split out constraint sets to tcg-target-con-set.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target-con-set.h | 36 +
 tcg/aarch64/tcg-target.h |  1 +
 tcg/aarch64/tcg-target.c.inc | 86 +++-
 3 files changed, 65 insertions(+), 58 deletions(-)
 create mode 100644 tcg/aarch64/tcg-target-con-set.h

diff --git a/tcg/aarch64/tcg-target-con-set.h b/tcg/aarch64/tcg-target-con-set.h
new file mode 100644
index 00..d6c6866878
--- /dev/null
+++ b/tcg/aarch64/tcg-target-con-set.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Define AArch64 target-specific constraint sets.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * C_On_Im(...) defines a constraint set with  outputs and  inputs.
+ * Each operand should be a sequence of constraint letters as defined by
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
+ */
+C_O0_I1(r)
+C_O0_I2(lZ, l)
+C_O0_I2(r, rA)
+C_O0_I2(rZ, r)
+C_O0_I2(w, r)
+C_O1_I1(r, l)
+C_O1_I1(r, r)
+C_O1_I1(w, r)
+C_O1_I1(w, w)
+C_O1_I1(w, wr)
+C_O1_I2(r, 0, rZ)
+C_O1_I2(r, r, r)
+C_O1_I2(r, r, rA)
+C_O1_I2(r, r, rAL)
+C_O1_I2(r, r, ri)
+C_O1_I2(r, r, rL)
+C_O1_I2(r, rZ, rZ)
+C_O1_I2(w, 0, w)
+C_O1_I2(w, w, w)
+C_O1_I2(w, w, wN)
+C_O1_I2(w, w, wO)
+C_O1_I2(w, w, wZ)
+C_O1_I3(w, w, w, w)
+C_O1_I4(r, r, rA, rZ, rZ)
+C_O2_I4(r, r, rZ, rZ, rA, rMZ)
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 5ec30dba25..200e9b5e0e 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -155,5 +155,6 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
+#define TCG_TARGET_CON_SET_H
 
 #endif /* AARCH64_TCG_TARGET_H */
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index 42037c98fa..3c1ee39fd4 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -2547,42 +2547,11 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece,
 va_end(va);
 }
 
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 {
-static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
-static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
-static const TCGTargetOpDef w_w = { .args_ct_str = { "w", "w" } };
-static const TCGTargetOpDef w_r = { .args_ct_str = { "w", "r" } };
-static const TCGTargetOpDef w_wr = { .args_ct_str = { "w", "wr" } };
-static const TCGTargetOpDef r_l = { .args_ct_str = { "r", "l" } };
-static const TCGTargetOpDef r_rA = { .args_ct_str = { "r", "rA" } };
-static const TCGTargetOpDef rZ_r = { .args_ct_str = { "rZ", "r" } };
-static const TCGTargetOpDef lZ_l = { .args_ct_str = { "lZ", "l" } };
-static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } };
-static const TCGTargetOpDef w_w_w = { .args_ct_str = { "w", "w", "w" } };
-static const TCGTargetOpDef w_0_w = { .args_ct_str = { "w", "0", "w" } };
-static const TCGTargetOpDef w_w_wO = { .args_ct_str = { "w", "w", "wO" } };
-static const TCGTargetOpDef w_w_wN = { .args_ct_str = { "w", "w", "wN" } };
-static const TCGTargetOpDef w_w_wZ = { .args_ct_str = { "w", "w", "wZ" } };
-static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
-static const TCGTargetOpDef r_r_rA = { .args_ct_str = { "r", "r", "rA" } };
-static const TCGTargetOpDef r_r_rL = { .args_ct_str = { "r", "r", "rL" } };
-static const TCGTargetOpDef r_r_rAL
-= { .args_ct_str = { "r", "r", "rAL" } };
-static const TCGTargetOpDef dep
-= { .args_ct_str = { "r", "0", "rZ" } };
-static const TCGTargetOpDef ext2
-= { .args_ct_str = { "r", "rZ", "rZ" } };
-static const TCGTargetOpDef movc
-= { .args_ct_str = { "r", "r", "rA", "rZ", "rZ" } };
-static const TCGTargetOpDef add2
-= { .args_ct_str = { "r", "r", "rZ", "rZ", "rA", "rMZ" } };
-static const TCGTargetOpDef w_w_w_w
-= { .args_ct_str = { "w", "w", "w", "w" } };
-
 switch (op) {
 case INDEX_op_goto_ptr:
-return 
+return C_O0_I1(r);
 
 case INDEX_op_ld8u_i32:
 case INDEX_op_ld8s_i32:
@@ -2621,7 +2590,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_extract_i64:
 case INDEX_op_sextract_i32:
 case INDEX_op_sextract_i64:
-return _r;
+return C_O1_I1(r, r);
 
 case INDEX_op_st8_i32:
 case INDEX_op_st16_i32:
@@ -2630,7 +2599,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_st16_i64:
 case INDEX_op_st32_i64:
 case INDEX_op_st_i64:
-return _r;
+return C_O0_I2(rZ, r);
 
 case INDEX_op_add_i32:
 case INDEX_op_add_i64:
@@ -2638,7 +2607,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_sub_i64:
 case INDEX_op_setcond_i32:
 case 

[PATCH v2 12/22] tcg: Remove TCG_TARGET_CON_STR_H

2021-01-15 Thread Richard Henderson
All backends have now been converted to tcg-target-con-str.h,
so we can remove the fallback code.

Reviewed-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.h |  1 -
 tcg/arm/tcg-target.h |  1 -
 tcg/i386/tcg-target.h|  1 -
 tcg/mips/tcg-target.h|  1 -
 tcg/ppc/tcg-target.h |  1 -
 tcg/riscv/tcg-target.h   |  1 -
 tcg/s390/tcg-target.h|  1 -
 tcg/sparc/tcg-target.h   |  1 -
 tcg/tci/tcg-target.h |  2 --
 tcg/tcg.c| 16 
 10 files changed, 26 deletions(-)

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 4fc20b58ec..5ec30dba25 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -155,6 +155,5 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
-#define TCG_TARGET_CON_STR_H
 
 #endif /* AARCH64_TCG_TARGET_H */
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 16336cd545..8d1fee6327 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -142,6 +142,5 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
-#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 77693e13ea..b693d3692d 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -235,6 +235,5 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
-#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index d850200855..c2c32fb38f 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -207,6 +207,5 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #ifdef CONFIG_SOFTMMU
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
-#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index 40ed4b82dd..d1339afc66 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -185,6 +185,5 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
-#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index daf3ef7b5c..727c8df418 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -171,6 +171,5 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_POOL_LABELS
 
 #define TCG_TARGET_HAS_MEMORY_BSWAP 0
-#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index c43d6aba84..641464eea4 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -159,6 +159,5 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
-#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index 5185b00524..f66f5d07dc 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -168,6 +168,5 @@ extern bool use_vis3_instructions;
 void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
 
 #define TCG_TARGET_NEED_POOL_LABELS
-#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index ab832aecc3..bb784e018e 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -207,6 +207,4 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 /* no need to flush icache explicitly */
 }
 
-#define TCG_TARGET_CON_STR_H
-
 #endif /* TCG_TARGET_H */
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 2a85532589..7b4d0b3f69 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -103,10 +103,6 @@ static void tcg_register_jit_int(const void *buf, size_t 
size,
 __attribute__((unused));
 
 /* Forward declarations for functions declared and used in tcg-target.c.inc. */
-#ifndef TCG_TARGET_CON_STR_H
-static const char *target_parse_constraint(TCGArgConstraint *ct,
-   const char *ct_str, TCGType type);
-#endif
 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
intptr_t arg2);
 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
@@ -2458,7 +2454,6 @@ static void process_op_defs(TCGContext *s)
 ct_str++;
 break;
 
-#ifdef TCG_TARGET_CON_STR_H
 /* Include all of the target-specific constraints. */
 
 #undef CONST
@@ -2474,17 +2469,6 @@ static void process_op_defs(TCGContext *s)
 default:
 /* Typo in TCGTargetOpDef constraint. */
 

[PATCH v2 19/22] tcg/s390: Split out constraint sets to tcg-target-con-set.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/s390/tcg-target-con-set.h |  29 
 tcg/s390/tcg-target.h |   1 +
 tcg/s390/tcg-target.c.inc | 121 ++
 3 files changed, 81 insertions(+), 70 deletions(-)
 create mode 100644 tcg/s390/tcg-target-con-set.h

diff --git a/tcg/s390/tcg-target-con-set.h b/tcg/s390/tcg-target-con-set.h
new file mode 100644
index 00..31985e4903
--- /dev/null
+++ b/tcg/s390/tcg-target-con-set.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define S390 target-specific constraint sets.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * C_On_Im(...) defines a constraint set with  outputs and  inputs.
+ * Each operand should be a sequence of constraint letters as defined by
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
+ */
+C_O0_I1(r)
+C_O0_I2(L, L)
+C_O0_I2(r, r)
+C_O0_I2(r, ri)
+C_O1_I1(r, L)
+C_O1_I1(r, r)
+C_O1_I2(r, 0, ri)
+C_O1_I2(r, 0, rI)
+C_O1_I2(r, 0, rJ)
+C_O1_I2(r, r, ri)
+C_O1_I2(r, rZ, r)
+C_O1_I4(r, r, ri, r, 0)
+C_O1_I4(r, r, ri, rI, 0)
+C_O2_I2(b, a, 0, r)
+C_O2_I3(b, a, 0, 1, r)
+C_O2_I4(r, r, 0, 1, rA, r)
+C_O2_I4(r, r, 0, 1, ri, r)
+C_O2_I4(r, r, 0, 1, r, r)
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index 641464eea4..7aafd25a46 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -159,5 +159,6 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
+#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
index 616bcfafc8..b227f9e2b8 100644
--- a/tcg/s390/tcg-target.c.inc
+++ b/tcg/s390/tcg-target.c.inc
@@ -2261,27 +2261,11 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc,
 }
 }
 
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 {
-static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
-static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
-static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
-static const TCGTargetOpDef L_L = { .args_ct_str = { "L", "L" } };
-static const TCGTargetOpDef r_ri = { .args_ct_str = { "r", "ri" } };
-static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
-static const TCGTargetOpDef r_0_ri = { .args_ct_str = { "r", "0", "ri" } };
-static const TCGTargetOpDef r_0_rI = { .args_ct_str = { "r", "0", "rI" } };
-static const TCGTargetOpDef r_0_rJ = { .args_ct_str = { "r", "0", "rJ" } };
-static const TCGTargetOpDef a2_r
-= { .args_ct_str = { "r", "r", "0", "1", "r", "r" } };
-static const TCGTargetOpDef a2_ri
-= { .args_ct_str = { "r", "r", "0", "1", "ri", "r" } };
-static const TCGTargetOpDef a2_rA
-= { .args_ct_str = { "r", "r", "0", "1", "rA", "r" } };
-
 switch (op) {
 case INDEX_op_goto_ptr:
-return 
+return C_O0_I1(r);
 
 case INDEX_op_ld8u_i32:
 case INDEX_op_ld8u_i64:
@@ -2295,6 +2279,8 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_ld32u_i64:
 case INDEX_op_ld32s_i64:
 case INDEX_op_ld_i64:
+return C_O1_I1(r, r);
+
 case INDEX_op_st8_i32:
 case INDEX_op_st8_i64:
 case INDEX_op_st16_i32:
@@ -2302,11 +2288,22 @@ static const TCGTargetOpDef 
*tcg_target_op_def(TCGOpcode op)
 case INDEX_op_st_i32:
 case INDEX_op_st32_i64:
 case INDEX_op_st_i64:
-return _r;
+return C_O0_I2(r, r);
 
 case INDEX_op_add_i32:
 case INDEX_op_add_i64:
-return _r_ri;
+case INDEX_op_shl_i64:
+case INDEX_op_shr_i64:
+case INDEX_op_sar_i64:
+case INDEX_op_rotl_i32:
+case INDEX_op_rotl_i64:
+case INDEX_op_rotr_i32:
+case INDEX_op_rotr_i64:
+case INDEX_op_clz_i64:
+case INDEX_op_setcond_i32:
+case INDEX_op_setcond_i64:
+return C_O1_I2(r, r, ri);
+
 case INDEX_op_sub_i32:
 case INDEX_op_sub_i64:
 case INDEX_op_and_i32:
@@ -2315,35 +2312,33 @@ static const TCGTargetOpDef 
*tcg_target_op_def(TCGOpcode op)
 case INDEX_op_or_i64:
 case INDEX_op_xor_i32:
 case INDEX_op_xor_i64:
-return (s390_facilities & FACILITY_DISTINCT_OPS ? _r_ri : _0_ri);
+return (s390_facilities & FACILITY_DISTINCT_OPS
+? C_O1_I2(r, r, ri)
+: C_O1_I2(r, 0, ri));
 
 case INDEX_op_mul_i32:
 /* If we have the general-instruction-extensions, then we have
MULTIPLY SINGLE IMMEDIATE with a signed 32-bit, otherwise we
have only MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit.  */
-return (s390_facilities & FACILITY_GEN_INST_EXT ? _0_ri : _0_rI);
+return (s390_facilities & FACILITY_GEN_INST_EXT
+? C_O1_I2(r, 0, ri)
+: C_O1_I2(r, 0, rI));
+
 case INDEX_op_mul_i64:
-return 

[PATCH v2 15/22] tcg/arm: Split out constraint sets to tcg-target-con-set.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/arm/tcg-target-con-set.h | 35 ++
 tcg/arm/tcg-target.h |  1 +
 tcg/arm/tcg-target.c.inc | 94 
 3 files changed, 68 insertions(+), 62 deletions(-)
 create mode 100644 tcg/arm/tcg-target-con-set.h

diff --git a/tcg/arm/tcg-target-con-set.h b/tcg/arm/tcg-target-con-set.h
new file mode 100644
index 00..ab63e089c2
--- /dev/null
+++ b/tcg/arm/tcg-target-con-set.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define Arm target-specific constraint sets.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * C_On_Im(...) defines a constraint set with  outputs and  inputs.
+ * Each operand should be a sequence of constraint letters as defined by
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
+ */
+C_O0_I1(r)
+C_O0_I2(r, r)
+C_O0_I2(r, rIN)
+C_O0_I2(s, s)
+C_O0_I3(s, s, s)
+C_O0_I4(r, r, rI, rI)
+C_O0_I4(s, s, s, s)
+C_O1_I1(r, l)
+C_O1_I1(r, r)
+C_O1_I2(r, 0, rZ)
+C_O1_I2(r, l, l)
+C_O1_I2(r, r, r)
+C_O1_I2(r, r, rI)
+C_O1_I2(r, r, rIK)
+C_O1_I2(r, r, rIN)
+C_O1_I2(r, r, ri)
+C_O1_I2(r, rZ, rZ)
+C_O1_I4(r, r, r, rI, rI)
+C_O1_I4(r, r, rIN, rIK, 0)
+C_O2_I1(r, r, l)
+C_O2_I2(r, r, l, l)
+C_O2_I2(r, r, r, r)
+C_O2_I4(r, r, r, r, rIN, rIK)
+C_O2_I4(r, r, rI, rI, rIN, rIK)
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 8d1fee6327..4d201b1216 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -142,5 +142,6 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
+#define TCG_TARGET_CON_SET_H
 
 #endif
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index e1a247b27f..6bc75516fd 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -2031,57 +2031,17 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc,
 }
 }
 
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 {
-static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
-static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
-static const TCGTargetOpDef s_s = { .args_ct_str = { "s", "s" } };
-static const TCGTargetOpDef r_l = { .args_ct_str = { "r", "l" } };
-static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } };
-static const TCGTargetOpDef r_r_l = { .args_ct_str = { "r", "r", "l" } };
-static const TCGTargetOpDef r_l_l = { .args_ct_str = { "r", "l", "l" } };
-static const TCGTargetOpDef s_s_s = { .args_ct_str = { "s", "s", "s" } };
-static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
-static const TCGTargetOpDef r_r_rI = { .args_ct_str = { "r", "r", "rI" } };
-static const TCGTargetOpDef r_r_rIN
-= { .args_ct_str = { "r", "r", "rIN" } };
-static const TCGTargetOpDef r_r_rIK
-= { .args_ct_str = { "r", "r", "rIK" } };
-static const TCGTargetOpDef r_r_r_r
-= { .args_ct_str = { "r", "r", "r", "r" } };
-static const TCGTargetOpDef r_r_l_l
-= { .args_ct_str = { "r", "r", "l", "l" } };
-static const TCGTargetOpDef s_s_s_s
-= { .args_ct_str = { "s", "s", "s", "s" } };
-static const TCGTargetOpDef br
-= { .args_ct_str = { "r", "rIN" } };
-static const TCGTargetOpDef ext2
-= { .args_ct_str = { "r", "rZ", "rZ" } };
-static const TCGTargetOpDef dep
-= { .args_ct_str = { "r", "0", "rZ" } };
-static const TCGTargetOpDef movc
-= { .args_ct_str = { "r", "r", "rIN", "rIK", "0" } };
-static const TCGTargetOpDef add2
-= { .args_ct_str = { "r", "r", "r", "r", "rIN", "rIK" } };
-static const TCGTargetOpDef sub2
-= { .args_ct_str = { "r", "r", "rI", "rI", "rIN", "rIK" } };
-static const TCGTargetOpDef br2
-= { .args_ct_str = { "r", "r", "rI", "rI" } };
-static const TCGTargetOpDef setc2
-= { .args_ct_str = { "r", "r", "r", "rI", "rI" } };
-
 switch (op) {
 case INDEX_op_goto_ptr:
-return 
+return C_O0_I1(r);
 
 case INDEX_op_ld8u_i32:
 case INDEX_op_ld8s_i32:
 case INDEX_op_ld16u_i32:
 case INDEX_op_ld16s_i32:
 case INDEX_op_ld_i32:
-case INDEX_op_st8_i32:
-case INDEX_op_st16_i32:
-case INDEX_op_st_i32:
 case INDEX_op_neg_i32:
 case INDEX_op_not_i32:
 case INDEX_op_bswap16_i32:
@@ -2091,62 +2051,72 @@ static const TCGTargetOpDef 
*tcg_target_op_def(TCGOpcode op)
 case INDEX_op_ext16u_i32:
 case INDEX_op_extract_i32:
 case INDEX_op_sextract_i32:
-return _r;
+return C_O1_I1(r, r);
+
+case INDEX_op_st8_i32:
+case INDEX_op_st16_i32:
+case INDEX_op_st_i32:
+return C_O0_I2(r, r);
 
 case INDEX_op_add_i32:
 case INDEX_op_sub_i32:
 case INDEX_op_setcond_i32:
-return _r_rIN;
+return C_O1_I2(r, r, rIN);
+
 case 

[PATCH v2 02/22] tcg/i386: Move constraint type check to tcg_target_const_match

2021-01-15 Thread Richard Henderson
Rather than check the type when filling in the constraint,
check it when matching the constant.  This removes the only
use of the type argument to target_parse_constraint.

Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target.c.inc | 28 +---
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index 050f3cb0b1..74637f654a 100644
--- a/tcg/i386/tcg-target.c.inc
+++ b/tcg/i386/tcg-target.c.inc
@@ -263,13 +263,13 @@ static const char 
*target_parse_constraint(TCGArgConstraint *ct,
 break;
 
 case 'e':
-ct->ct |= (type == TCG_TYPE_I32 ? TCG_CT_CONST : TCG_CT_CONST_S32);
+ct->ct |= TCG_CT_CONST_S32;
 break;
 case 'Z':
-ct->ct |= (type == TCG_TYPE_I32 ? TCG_CT_CONST : TCG_CT_CONST_U32);
+ct->ct |= TCG_CT_CONST_U32;
 break;
 case 'I':
-ct->ct |= (type == TCG_TYPE_I32 ? TCG_CT_CONST : TCG_CT_CONST_I32);
+ct->ct |= TCG_CT_CONST_I32;
 break;
 
 default:
@@ -286,14 +286,20 @@ static inline int tcg_target_const_match(tcg_target_long 
val, TCGType type,
 if (ct & TCG_CT_CONST) {
 return 1;
 }
-if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
-return 1;
-}
-if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
-return 1;
-}
-if ((ct & TCG_CT_CONST_I32) && ~val == (int32_t)~val) {
-return 1;
+if (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32) {
+if (ct & (TCG_CT_CONST_S32 | TCG_CT_CONST_U32 | TCG_CT_CONST_I32)) {
+return 1;
+}
+} else {
+if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_I32) && ~val == (int32_t)~val) {
+return 1;
+}
 }
 if ((ct & TCG_CT_CONST_WSZ) && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
 return 1;
-- 
2.25.1




[PATCH v2 11/22] tcg/sparc: Split out target constraints to tcg-target-con-str.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/sparc/tcg-target-con-str.h | 22 +
 tcg/sparc/tcg-target.h |  5 +---
 tcg/sparc/tcg-target.c.inc | 45 +-
 3 files changed, 29 insertions(+), 43 deletions(-)
 create mode 100644 tcg/sparc/tcg-target-con-str.h

diff --git a/tcg/sparc/tcg-target-con-str.h b/tcg/sparc/tcg-target-con-str.h
new file mode 100644
index 00..6dc5b95f33
--- /dev/null
+++ b/tcg/sparc/tcg-target-con-str.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define Sparc target-specific operand constraints.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * Define constraint letters for register sets:
+ * REGS(letter, register_mask)
+ */
+REGS('r', 0x)
+REGS('R', ALL_64)
+REGS('s', 0x & ~RESERVE_QLDST)
+REGS('S', ALL_64 & ~RESERVE_QLDST)
+
+/*
+ * Define constraint letters for constants:
+ * CONST(letter, TCG_CT_CONST_* bit set)
+ */
+CONST('I', TCG_CT_CONST_S11)
+CONST('J', TCG_CT_CONST_S13)
+CONST('Z', TCG_CT_CONST_ZERO)
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index 95ab9af955..5185b00524 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -66,10 +66,6 @@ typedef enum {
 TCG_REG_I7,
 } TCGReg;
 
-#define TCG_CT_CONST_S11  0x100
-#define TCG_CT_CONST_S13  0x200
-#define TCG_CT_CONST_ZERO 0x400
-
 /* used for function call generation */
 #define TCG_REG_CALL_STACK TCG_REG_O6
 
@@ -172,5 +168,6 @@ extern bool use_vis3_instructions;
 void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
 
 #define TCG_TARGET_NEED_POOL_LABELS
+#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
index 28b5b6559a..ea2b3274d4 100644
--- a/tcg/sparc/tcg-target.c.inc
+++ b/tcg/sparc/tcg-target.c.inc
@@ -67,6 +67,10 @@ static const char * const 
tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
 # define SPARC64 0
 #endif
 
+#define TCG_CT_CONST_S11  0x100
+#define TCG_CT_CONST_S13  0x200
+#define TCG_CT_CONST_ZERO 0x400
+
 /* Note that sparcv8plus can only hold 64 bit quantities in %g and %o
registers.  These are saved manually by the kernel in full 64-bit
slots.  The %i and %l registers are saved by the register window
@@ -79,6 +83,8 @@ static const char * const 
tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
 # define ALL_64  0xu
 #endif
 
+#define RESERVE_QLDST  (7u << TCG_REG_O0)  /* O0, O1, O2 */
+
 /* Define some temporary registers.  T2 is used for constant generation.  */
 #define TCG_REG_T1  TCG_REG_G1
 #define TCG_REG_T2  TCG_REG_O7
@@ -320,45 +326,6 @@ static bool patch_reloc(tcg_insn_unit *src_rw, int type,
 return true;
 }
 
-/* parse target specific constraints */
-static const char *target_parse_constraint(TCGArgConstraint *ct,
-   const char *ct_str, TCGType type)
-{
-switch (*ct_str++) {
-case 'r':
-ct->regs = 0x;
-break;
-case 'R':
-ct->regs = ALL_64;
-break;
-case 'A': /* qemu_ld/st address constraint */
-ct->regs = TARGET_LONG_BITS == 64 ? ALL_64 : 0x;
-reserve_helpers:
-tcg_regset_reset_reg(ct->regs, TCG_REG_O0);
-tcg_regset_reset_reg(ct->regs, TCG_REG_O1);
-tcg_regset_reset_reg(ct->regs, TCG_REG_O2);
-break;
-case 's': /* qemu_st data 32-bit constraint */
-ct->regs = 0x;
-goto reserve_helpers;
-case 'S': /* qemu_st data 64-bit constraint */
-ct->regs = ALL_64;
-goto reserve_helpers;
-case 'I':
-ct->ct |= TCG_CT_CONST_S11;
-break;
-case 'J':
-ct->ct |= TCG_CT_CONST_S13;
-break;
-case 'Z':
-ct->ct |= TCG_CT_CONST_ZERO;
-break;
-default:
-return NULL;
-}
-return ct_str;
-}
-
 /* test if a constant matches the constraint */
 static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
  const TCGArgConstraint *arg_ct)
-- 
2.25.1




[PATCH v2 10/22] tcg/s390: Split out target constraints to tcg-target-con-str.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/s390/tcg-target-con-str.h | 23 
 tcg/s390/tcg-target.h |  1 +
 tcg/s390/tcg-target.c.inc | 40 ---
 3 files changed, 24 insertions(+), 40 deletions(-)
 create mode 100644 tcg/s390/tcg-target-con-str.h

diff --git a/tcg/s390/tcg-target-con-str.h b/tcg/s390/tcg-target-con-str.h
new file mode 100644
index 00..f905b357c3
--- /dev/null
+++ b/tcg/s390/tcg-target-con-str.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define S390 target-specific operand constraints.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * Define constraint letters for register sets:
+ * REGS(letter, register_mask)
+ */
+REGS('r', 0x)
+REGS('L', 0x & ~((1 << TCG_REG_R2) | (1 << TCG_REG_R3) | (1 << 
TCG_REG_R4)))
+REGS('a', 1u << TCG_REG_R2)
+REGS('b', 1u << TCG_REG_R3)
+
+/*
+ * Define constraint letters for constants:
+ * CONST(letter, TCG_CT_CONST_* bit set)
+ */
+CONST('A', TCG_CT_CONST_S33)
+CONST('I', TCG_CT_CONST_S16)
+CONST('J', TCG_CT_CONST_S32)
+CONST('Z', TCG_CT_CONST_ZERO)
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index 641464eea4..c43d6aba84 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -159,5 +159,6 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
+#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
index 8517e55232..616bcfafc8 100644
--- a/tcg/s390/tcg-target.c.inc
+++ b/tcg/s390/tcg-target.c.inc
@@ -403,46 +403,6 @@ static bool patch_reloc(tcg_insn_unit *src_rw, int type,
 return false;
 }
 
-/* parse target specific constraints */
-static const char *target_parse_constraint(TCGArgConstraint *ct,
-   const char *ct_str, TCGType type)
-{
-switch (*ct_str++) {
-case 'r':  /* all registers */
-ct->regs = 0x;
-break;
-case 'L':  /* qemu_ld/st constraint */
-ct->regs = 0x;
-tcg_regset_reset_reg(ct->regs, TCG_REG_R2);
-tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
-tcg_regset_reset_reg(ct->regs, TCG_REG_R4);
-break;
-case 'a':  /* force R2 for division */
-ct->regs = 0;
-tcg_regset_set_reg(ct->regs, TCG_REG_R2);
-break;
-case 'b':  /* force R3 for division */
-ct->regs = 0;
-tcg_regset_set_reg(ct->regs, TCG_REG_R3);
-break;
-case 'A':
-ct->ct |= TCG_CT_CONST_S33;
-break;
-case 'I':
-ct->ct |= TCG_CT_CONST_S16;
-break;
-case 'J':
-ct->ct |= TCG_CT_CONST_S32;
-break;
-case 'Z':
-ct->ct |= TCG_CT_CONST_ZERO;
-break;
-default:
-return NULL;
-}
-return ct_str;
-}
-
 /* Test if a constant matches the constraint. */
 static int tcg_target_const_match(tcg_target_long val, TCGType type,
   const TCGArgConstraint *arg_ct)
-- 
2.25.1




[PATCH v2 08/22] tcg/mips: Split out target constraints to tcg-target-con-str.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/mips/tcg-target-con-str.h | 24 
 tcg/mips/tcg-target.h |  1 +
 tcg/mips/tcg-target.c.inc | 72 ---
 3 files changed, 41 insertions(+), 56 deletions(-)
 create mode 100644 tcg/mips/tcg-target-con-str.h

diff --git a/tcg/mips/tcg-target-con-str.h b/tcg/mips/tcg-target-con-str.h
new file mode 100644
index 00..e4b2965c72
--- /dev/null
+++ b/tcg/mips/tcg-target-con-str.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define MIPS target-specific operand constraints.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * Define constraint letters for register sets:
+ * REGS(letter, register_mask)
+ */
+REGS('r', ALL_GENERAL_REGS)
+REGS('L', ALL_QLOAD_REGS)
+REGS('S', ALL_QSTORE_REGS)
+
+/*
+ * Define constraint letters for constants:
+ * CONST(letter, TCG_CT_CONST_* bit set)
+ */
+CONST('I', TCG_CT_CONST_U16)
+CONST('J', TCG_CT_CONST_S16)
+CONST('K', TCG_CT_CONST_P2M1)
+CONST('N', TCG_CT_CONST_N16)
+CONST('W', TCG_CT_CONST_WSZ)
+CONST('Z', TCG_CT_CONST_ZERO)
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index c2c32fb38f..d850200855 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -207,5 +207,6 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #ifdef CONFIG_SOFTMMU
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
+#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
index 7293169ab2..61e8740012 100644
--- a/tcg/mips/tcg-target.c.inc
+++ b/tcg/mips/tcg-target.c.inc
@@ -171,67 +171,27 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
 #define TCG_CT_CONST_N16  0x1000   /* "Negatable" 16-bit: -32767 - 32767 */
 #define TCG_CT_CONST_WSZ  0x2000   /* word size */
 
+#define ALL_GENERAL_REGS  0xu
+#define NOA0_REGS (ALL_GENERAL_REGS & ~(1 << TCG_REG_A0))
+
+#ifdef CONFIG_SOFTMMU
+#define ALL_QLOAD_REGS \
+(NOA0_REGS & ~((TCG_TARGET_REG_BITS < TARGET_LONG_BITS) << TCG_REG_A2))
+#define ALL_QSTORE_REGS \
+(NOA0_REGS & ~(TCG_TARGET_REG_BITS < TARGET_LONG_BITS   \
+   ? (1 << TCG_REG_A2) | (1 << TCG_REG_A3)  \
+   : (1 << TCG_REG_A1)))
+#else
+#define ALL_QLOAD_REGS   NOA0_REGS
+#define ALL_QSTORE_REGS  NOA0_REGS
+#endif
+
+
 static inline bool is_p2m1(tcg_target_long val)
 {
 return val && ((val + 1) & val) == 0;
 }
 
-/* parse target specific constraints */
-static const char *target_parse_constraint(TCGArgConstraint *ct,
-   const char *ct_str, TCGType type)
-{
-switch(*ct_str++) {
-case 'r':
-ct->regs = 0x;
-break;
-case 'L': /* qemu_ld input arg constraint */
-ct->regs = 0x;
-tcg_regset_reset_reg(ct->regs, TCG_REG_A0);
-#if defined(CONFIG_SOFTMMU)
-if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
-tcg_regset_reset_reg(ct->regs, TCG_REG_A2);
-}
-#endif
-break;
-case 'S': /* qemu_st constraint */
-ct->regs = 0x;
-tcg_regset_reset_reg(ct->regs, TCG_REG_A0);
-#if defined(CONFIG_SOFTMMU)
-if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
-tcg_regset_reset_reg(ct->regs, TCG_REG_A2);
-tcg_regset_reset_reg(ct->regs, TCG_REG_A3);
-} else {
-tcg_regset_reset_reg(ct->regs, TCG_REG_A1);
-}
-#endif
-break;
-case 'I':
-ct->ct |= TCG_CT_CONST_U16;
-break;
-case 'J':
-ct->ct |= TCG_CT_CONST_S16;
-break;
-case 'K':
-ct->ct |= TCG_CT_CONST_P2M1;
-break;
-case 'N':
-ct->ct |= TCG_CT_CONST_N16;
-break;
-case 'W':
-ct->ct |= TCG_CT_CONST_WSZ;
-break;
-case 'Z':
-/* We are cheating a bit here, using the fact that the register
-   ZERO is also the register number 0. Hence there is no need
-   to check for const_args in each instruction. */
-ct->ct |= TCG_CT_CONST_ZERO;
-break;
-default:
-return NULL;
-}
-return ct_str;
-}
-
 /* test if a constant matches the constraint */
 static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
  const TCGArgConstraint *arg_ct)
-- 
2.25.1




[PATCH v2 04/22] tcg/arm: Split out target constraints to tcg-target-con-str.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/arm/tcg-target-con-str.h | 22 
 tcg/arm/tcg-target.h |  1 +
 tcg/arm/tcg-target.c.inc | 69 +++-
 3 files changed, 36 insertions(+), 56 deletions(-)
 create mode 100644 tcg/arm/tcg-target-con-str.h

diff --git a/tcg/arm/tcg-target-con-str.h b/tcg/arm/tcg-target-con-str.h
new file mode 100644
index 00..2451ec6c7f
--- /dev/null
+++ b/tcg/arm/tcg-target-con-str.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define Arm target-specific operand constraint.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * Define constraint letters for register sets:
+ * REGS(letter, register_mask)
+ */
+REGS('r', ALL_GENERAL_REGS)
+REGS('l', ALL_QLOAD_REGS)
+REGS('s', ALL_QSTORE_REGS)
+
+/*
+ * Define constraint letters for constants:
+ * CONST(letter, TCG_CT_CONST_* bit set)
+ */
+CONST('I', TCG_CT_CONST_ARM)
+CONST('K', TCG_CT_CONST_INV)
+CONST('N', TCG_CT_CONST_NEG)
+CONST('Z', TCG_CT_CONST_ZERO)
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 8d1fee6327..16336cd545 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -142,5 +142,6 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
+#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index c2b26b3c45..e1a247b27f 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -237,65 +237,22 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
 #define TCG_CT_CONST_NEG  0x400
 #define TCG_CT_CONST_ZERO 0x800
 
-/* parse target specific constraints */
-static const char *target_parse_constraint(TCGArgConstraint *ct,
-   const char *ct_str, TCGType type)
-{
-switch (*ct_str++) {
-case 'I':
-ct->ct |= TCG_CT_CONST_ARM;
-break;
-case 'K':
-ct->ct |= TCG_CT_CONST_INV;
-break;
-case 'N': /* The gcc constraint letter is L, already used here.  */
-ct->ct |= TCG_CT_CONST_NEG;
-break;
-case 'Z':
-ct->ct |= TCG_CT_CONST_ZERO;
-break;
+#define ALL_GENERAL_REGS  0xu
 
-case 'r':
-ct->regs = 0x;
-break;
-
-/* qemu_ld address */
-case 'l':
-ct->regs = 0x;
 #ifdef CONFIG_SOFTMMU
-/* r0-r2,lr will be overwritten when reading the tlb entry,
-   so don't use these. */
-tcg_regset_reset_reg(ct->regs, TCG_REG_R0);
-tcg_regset_reset_reg(ct->regs, TCG_REG_R1);
-tcg_regset_reset_reg(ct->regs, TCG_REG_R2);
-tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
-tcg_regset_reset_reg(ct->regs, TCG_REG_R14);
+#define ALL_QLOAD_REGS \
+(ALL_GENERAL_REGS & ~((1 << TCG_REG_R0) | (1 << TCG_REG_R1) | \
+  (1 << TCG_REG_R2) | (1 << TCG_REG_R3) | \
+  (1 << TCG_REG_R14)))
+#define ALL_QSTORE_REGS \
+(ALL_GENERAL_REGS & ~((1 << TCG_REG_R0) | (1 << TCG_REG_R1) | \
+  (1 << TCG_REG_R2) | (1 << TCG_REG_R14) | \
+  ((TARGET_LONG_BITS == 64) << TCG_REG_R3)))
+#else
+#define ALL_QLOAD_REGS   ALL_GENERAL_REGS
+#define ALL_QSTORE_REGS \
+(ALL_GENERAL_REGS & ~((1 << TCG_REG_R0) | (1 << TCG_REG_R1)))
 #endif
-break;
-
-/* qemu_st address & data */
-case 's':
-ct->regs = 0x;
-/* r0-r2 will be overwritten when reading the tlb entry (softmmu only)
-   and r0-r1 doing the byte swapping, so don't use these. */
-tcg_regset_reset_reg(ct->regs, TCG_REG_R0);
-tcg_regset_reset_reg(ct->regs, TCG_REG_R1);
-#if defined(CONFIG_SOFTMMU)
-/* Avoid clashes with registers being used for helper args */
-tcg_regset_reset_reg(ct->regs, TCG_REG_R2);
-#if TARGET_LONG_BITS == 64
-/* Avoid clashes with registers being used for helper args */
-tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
-#endif
-tcg_regset_reset_reg(ct->regs, TCG_REG_R14);
-#endif
-break;
-
-default:
-return NULL;
-}
-return ct_str;
-}
 
 static inline uint32_t rotl(uint32_t val, int n)
 {
-- 
2.25.1




[PATCH v2 09/22] tcg/riscv: Split out target constraints to tcg-target-con-str.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target-con-str.h | 21 ++
 tcg/riscv/tcg-target.h |  1 +
 tcg/riscv/tcg-target.c.inc | 50 --
 3 files changed, 33 insertions(+), 39 deletions(-)
 create mode 100644 tcg/riscv/tcg-target-con-str.h

diff --git a/tcg/riscv/tcg-target-con-str.h b/tcg/riscv/tcg-target-con-str.h
new file mode 100644
index 00..587fcd3593
--- /dev/null
+++ b/tcg/riscv/tcg-target-con-str.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define RISC-V target-specific operand constraints.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * Define constraint letters for register sets:
+ * REGS(letter, register_mask)
+ */
+REGS('r', ALL_GENERAL_REGS)
+REGS('L', ALL_QLDST_REGS)
+
+/*
+ * Define constraint letters for constants:
+ * CONST(letter, TCG_CT_CONST_* bit set)
+ */
+CONST('I', TCG_CT_CONST_S12)
+CONST('N', TCG_CT_CONST_N12)
+CONST('M', TCG_CT_CONST_M12)
+CONST('Z', TCG_CT_CONST_ZERO)
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 727c8df418..daf3ef7b5c 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -171,5 +171,6 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_POOL_LABELS
 
 #define TCG_TARGET_HAS_MEMORY_BSWAP 0
+#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 71c0badc02..185b569f4b 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -122,6 +122,17 @@ static const int tcg_target_call_oarg_regs[] = {
 #define TCG_CT_CONST_N12   0x400
 #define TCG_CT_CONST_M12   0x800
 
+#define ALL_GENERAL_REGS  0xu
+#ifdef CONFIG_SOFTMMU
+#define ALL_QLDST_REGS \
+(ALL_GENERAL_REGS & ~((1 << TCG_REG_A0) | (1 << TCG_REG_A1) | \
+  (1 << TCG_REG_A2) | (1 << TCG_REG_A3) | \
+  (1 << TCG_REG_A5)))
+#else
+#define ALL_QLDST_REGS   ALL_GENERAL_REGS
+#endif
+
+
 static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len)
 {
 if (TCG_TARGET_REG_BITS == 32) {
@@ -131,45 +142,6 @@ static inline tcg_target_long sextreg(tcg_target_long val, 
int pos, int len)
 }
 }
 
-/* parse target specific constraints */
-static const char *target_parse_constraint(TCGArgConstraint *ct,
-   const char *ct_str, TCGType type)
-{
-switch (*ct_str++) {
-case 'r':
-ct->regs = 0x;
-break;
-case 'L':
-/* qemu_ld/qemu_st constraint */
-ct->regs = 0x;
-/* qemu_ld/qemu_st uses TCG_REG_TMP0 */
-#if defined(CONFIG_SOFTMMU)
-tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[0]);
-tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[1]);
-tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[2]);
-tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[3]);
-tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[4]);
-#endif
-break;
-case 'I':
-ct->ct |= TCG_CT_CONST_S12;
-break;
-case 'N':
-ct->ct |= TCG_CT_CONST_N12;
-break;
-case 'M':
-ct->ct |= TCG_CT_CONST_M12;
-break;
-case 'Z':
-/* we can use a zero immediate as a zero register argument. */
-ct->ct |= TCG_CT_CONST_ZERO;
-break;
-default:
-return NULL;
-}
-return ct_str;
-}
-
 /* test if a constant matches the constraint */
 static int tcg_target_const_match(tcg_target_long val, TCGType type,
   const TCGArgConstraint *arg_ct)
-- 
2.25.1




[PATCH v2 06/22] tcg/ppc: Split out target constraints to tcg-target-con-str.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/ppc/tcg-target-con-str.h | 30 +++
 tcg/ppc/tcg-target.h |  1 +
 tcg/ppc/tcg-target.c.inc | 73 
 3 files changed, 46 insertions(+), 58 deletions(-)
 create mode 100644 tcg/ppc/tcg-target-con-str.h

diff --git a/tcg/ppc/tcg-target-con-str.h b/tcg/ppc/tcg-target-con-str.h
new file mode 100644
index 00..298ca20d5b
--- /dev/null
+++ b/tcg/ppc/tcg-target-con-str.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define PowerPC target-specific operand constraints.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * Define constraint letters for register sets:
+ * REGS(letter, register_mask)
+ */
+REGS('r', ALL_GENERAL_REGS)
+REGS('v', ALL_VECTOR_REGS)
+REGS('A', 1u << TCG_REG_R3)
+REGS('B', 1u << TCG_REG_R4)
+REGS('C', 1u << TCG_REG_R5)
+REGS('D', 1u << TCG_REG_R6)
+REGS('L', ALL_QLOAD_REGS)
+REGS('S', ALL_QSTORE_REGS)
+
+/*
+ * Define constraint letters for constants:
+ * CONST(letter, TCG_CT_CONST_* bit set)
+ */
+CONST('I', TCG_CT_CONST_S16)
+CONST('J', TCG_CT_CONST_U16)
+CONST('M', TCG_CT_CONST_MONE)
+CONST('T', TCG_CT_CONST_S32)
+CONST('U', TCG_CT_CONST_U32)
+CONST('W', TCG_CT_CONST_WSZ)
+CONST('Z', TCG_CT_CONST_ZERO)
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index d1339afc66..40ed4b82dd 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -185,5 +185,6 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
+#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index cf64892295..e5aa8d2d10 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -62,6 +62,21 @@
 #define TCG_CT_CONST_MONE 0x2000
 #define TCG_CT_CONST_WSZ  0x4000
 
+#define ALL_GENERAL_REGS  0xu
+#define ALL_VECTOR_REGS   0xull
+
+#ifdef CONFIG_SOFTMMU
+#define ALL_QLOAD_REGS \
+(ALL_GENERAL_REGS & \
+ ~((1 << TCG_REG_R3) | (1 << TCG_REG_R4) | (1 << TCG_REG_R5)))
+#define ALL_QSTORE_REGS \
+(ALL_GENERAL_REGS & ~((1 << TCG_REG_R3) | (1 << TCG_REG_R4) | \
+  (1 << TCG_REG_R5) | (1 << TCG_REG_R6)))
+#else
+#define ALL_QLOAD_REGS  (ALL_GENERAL_REGS & ~(1 << TCG_REG_R3))
+#define ALL_QSTORE_REGS ALL_QLOAD_REGS
+#endif
+
 TCGPowerISA have_isa;
 static bool have_isel;
 bool have_altivec;
@@ -222,64 +237,6 @@ static bool reloc_pc14(tcg_insn_unit *src_rw, const 
tcg_insn_unit *target)
 return false;
 }
 
-/* parse target specific constraints */
-static const char *target_parse_constraint(TCGArgConstraint *ct,
-   const char *ct_str, TCGType type)
-{
-switch (*ct_str++) {
-case 'A': case 'B': case 'C': case 'D':
-tcg_regset_set_reg(ct->regs, 3 + ct_str[0] - 'A');
-break;
-case 'r':
-ct->regs = 0x;
-break;
-case 'v':
-ct->regs = 0xull;
-break;
-case 'L':   /* qemu_ld constraint */
-ct->regs = 0x;
-tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
-#ifdef CONFIG_SOFTMMU
-tcg_regset_reset_reg(ct->regs, TCG_REG_R4);
-tcg_regset_reset_reg(ct->regs, TCG_REG_R5);
-#endif
-break;
-case 'S':   /* qemu_st constraint */
-ct->regs = 0x;
-tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
-#ifdef CONFIG_SOFTMMU
-tcg_regset_reset_reg(ct->regs, TCG_REG_R4);
-tcg_regset_reset_reg(ct->regs, TCG_REG_R5);
-tcg_regset_reset_reg(ct->regs, TCG_REG_R6);
-#endif
-break;
-case 'I':
-ct->ct |= TCG_CT_CONST_S16;
-break;
-case 'J':
-ct->ct |= TCG_CT_CONST_U16;
-break;
-case 'M':
-ct->ct |= TCG_CT_CONST_MONE;
-break;
-case 'T':
-ct->ct |= TCG_CT_CONST_S32;
-break;
-case 'U':
-ct->ct |= TCG_CT_CONST_U32;
-break;
-case 'W':
-ct->ct |= TCG_CT_CONST_WSZ;
-break;
-case 'Z':
-ct->ct |= TCG_CT_CONST_ZERO;
-break;
-default:
-return NULL;
-}
-return ct_str;
-}
-
 /* test if a constant matches the constraint */
 static int tcg_target_const_match(tcg_target_long val, TCGType type,
   const TCGArgConstraint *arg_ct)
-- 
2.25.1




[PATCH v2 01/22] tcg/tci: Drop L and S constraints

2021-01-15 Thread Richard Henderson
These are identical to the 'r' constraint.

Signed-off-by: Richard Henderson 
---
 tcg/tci/tcg-target.c.inc | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index 15981265db..9c45f5f88f 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -46,11 +46,11 @@
 # define R64"r"
 #endif
 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
-# define L  "L", "L"
-# define S  "S", "S"
+# define L  "r", "r"
+# define S  "r", "r"
 #else
-# define L  "L"
-# define S  "S"
+# define L  "r"
+# define S  "r"
 #endif
 
 /* TODO: documentation. */
@@ -390,8 +390,6 @@ static const char *target_parse_constraint(TCGArgConstraint 
*ct,
 {
 switch (*ct_str++) {
 case 'r':
-case 'L':   /* qemu_ld constraint */
-case 'S':   /* qemu_st constraint */
 ct->regs = BIT(TCG_TARGET_NB_REGS) - 1;
 break;
 default:
-- 
2.25.1




[PATCH v2 05/22] tcg/aarch64: Split out target constraints to tcg-target-con-str.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target-con-str.h | 24 +++
 tcg/aarch64/tcg-target.h |  1 +
 tcg/aarch64/tcg-target.c.inc | 51 +---
 3 files changed, 33 insertions(+), 43 deletions(-)
 create mode 100644 tcg/aarch64/tcg-target-con-str.h

diff --git a/tcg/aarch64/tcg-target-con-str.h b/tcg/aarch64/tcg-target-con-str.h
new file mode 100644
index 00..00adb64594
--- /dev/null
+++ b/tcg/aarch64/tcg-target-con-str.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Define AArch64 target-specific operand constraints.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * Define constraint letters for register sets:
+ * REGS(letter, register_mask)
+ */
+REGS('r', ALL_GENERAL_REGS)
+REGS('l', ALL_QLDST_REGS)
+REGS('w', ALL_VECTOR_REGS)
+
+/*
+ * Define constraint letters for constants:
+ * CONST(letter, TCG_CT_CONST_* bit set)
+ */
+CONST('A', TCG_CT_CONST_AIMM)
+CONST('L', TCG_CT_CONST_LIMM)
+CONST('M', TCG_CT_CONST_MONE)
+CONST('O', TCG_CT_CONST_ORRI)
+CONST('N', TCG_CT_CONST_ANDI)
+CONST('Z', TCG_CT_CONST_ZERO)
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 5ec30dba25..4fc20b58ec 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -155,5 +155,6 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
+#define TCG_TARGET_CON_STR_H
 
 #endif /* AARCH64_TCG_TARGET_H */
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index 23954ec7cf..42037c98fa 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -126,51 +126,16 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
 #define TCG_CT_CONST_ORRI 0x1000
 #define TCG_CT_CONST_ANDI 0x2000
 
-/* parse target specific constraints */
-static const char *target_parse_constraint(TCGArgConstraint *ct,
-   const char *ct_str, TCGType type)
-{
-switch (*ct_str++) {
-case 'r': /* general registers */
-ct->regs |= 0xu;
-break;
-case 'w': /* advsimd registers */
-ct->regs |= 0xull;
-break;
-case 'l': /* qemu_ld / qemu_st address, data_reg */
-ct->regs = 0xu;
+#define ALL_GENERAL_REGS  0xu
+#define ALL_VECTOR_REGS   0xull
+
 #ifdef CONFIG_SOFTMMU
-/* x0 and x1 will be overwritten when reading the tlb entry,
-   and x2, and x3 for helper args, better to avoid using them. */
-tcg_regset_reset_reg(ct->regs, TCG_REG_X0);
-tcg_regset_reset_reg(ct->regs, TCG_REG_X1);
-tcg_regset_reset_reg(ct->regs, TCG_REG_X2);
-tcg_regset_reset_reg(ct->regs, TCG_REG_X3);
+#define ALL_QLDST_REGS \
+(ALL_GENERAL_REGS & ~((1 << TCG_REG_X0) | (1 << TCG_REG_X1) | \
+  (1 << TCG_REG_X2) | (1 << TCG_REG_X3)))
+#else
+#define ALL_QLDST_REGS   ALL_GENERAL_REGS
 #endif
-break;
-case 'A': /* Valid for arithmetic immediate (positive or negative).  */
-ct->ct |= TCG_CT_CONST_AIMM;
-break;
-case 'L': /* Valid for logical immediate.  */
-ct->ct |= TCG_CT_CONST_LIMM;
-break;
-case 'M': /* minus one */
-ct->ct |= TCG_CT_CONST_MONE;
-break;
-case 'O': /* vector orr/bic immediate */
-ct->ct |= TCG_CT_CONST_ORRI;
-break;
-case 'N': /* vector orr/bic immediate, inverted */
-ct->ct |= TCG_CT_CONST_ANDI;
-break;
-case 'Z': /* zero */
-ct->ct |= TCG_CT_CONST_ZERO;
-break;
-default:
-return NULL;
-}
-return ct_str;
-}
 
 /* Match a constant valid for addition (12-bit, optionally shifted).  */
 static inline bool is_aimm(uint64_t val)
-- 
2.25.1




[PATCH v2 03/22] tcg/i386: Split out target constraints to tcg-target-con-str.h

2021-01-15 Thread Richard Henderson
This eliminates the target-specific function target_parse_constraint
and folds it into the single caller, process_op_defs.  Since this is
done directly into the switch statement, duplicates are compilation
errors rather than silently ignored at runtime.

Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target-con-str.h |  33 +++
 tcg/i386/tcg-target.h |   1 +
 tcg/tcg.c |  33 +--
 tcg/i386/tcg-target.c.inc | 101 ++
 4 files changed, 78 insertions(+), 90 deletions(-)
 create mode 100644 tcg/i386/tcg-target-con-str.h

diff --git a/tcg/i386/tcg-target-con-str.h b/tcg/i386/tcg-target-con-str.h
new file mode 100644
index 00..24e6bcb80d
--- /dev/null
+++ b/tcg/i386/tcg-target-con-str.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define i386 target-specific operand constraints.
+ * Copyright (c) 2021 Linaro
+ *
+ */
+
+/*
+ * Define constraint letters for register sets:
+ * REGS(letter, register_mask)
+ */
+REGS('a', 1u << TCG_REG_EAX)
+REGS('b', 1u << TCG_REG_EBX)
+REGS('c', 1u << TCG_REG_ECX)
+REGS('d', 1u << TCG_REG_EDX)
+REGS('S', 1u << TCG_REG_ESI)
+REGS('D', 1u << TCG_REG_EDI)
+
+REGS('r', ALL_GENERAL_REGS)
+REGS('x', ALL_VECTOR_REGS)
+REGS('q', ALL_BYTEL_REGS) /* regs that can be used as a byte operand */
+REGS('Q', ALL_BYTEH_REGS) /* regs with a second byte (e.g. %ah) */
+REGS('L', ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS)  /* qemu_ld/st */
+REGS('s', ALL_BYTEL_REGS & ~SOFTMMU_RESERVE_REGS)/* qemu_st8_i32 data */
+
+/*
+ * Define constraint letters for constants:
+ * CONST(letter, TCG_CT_CONST_* bit set)
+ */
+CONST('e', TCG_CT_CONST_S32)
+CONST('I', TCG_CT_CONST_I32)
+CONST('W', TCG_CT_CONST_WSZ)
+CONST('Z', TCG_CT_CONST_U32)
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index b693d3692d..77693e13ea 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -235,5 +235,6 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 #define TCG_TARGET_NEED_LDST_LABELS
 #endif
 #define TCG_TARGET_NEED_POOL_LABELS
+#define TCG_TARGET_CON_STR_H
 
 #endif
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 8f8badb61c..2a85532589 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -103,8 +103,10 @@ static void tcg_register_jit_int(const void *buf, size_t 
size,
 __attribute__((unused));
 
 /* Forward declarations for functions declared and used in tcg-target.c.inc. */
+#ifndef TCG_TARGET_CON_STR_H
 static const char *target_parse_constraint(TCGArgConstraint *ct,
const char *ct_str, TCGType type);
+#endif
 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
intptr_t arg2);
 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
@@ -2409,7 +2411,6 @@ static void process_op_defs(TCGContext *s)
 for (op = 0; op < NB_OPS; op++) {
 TCGOpDef *def = _op_defs[op];
 const TCGTargetOpDef *tdefs;
-TCGType type;
 int i, nb_args;
 
 if (def->flags & TCG_OPF_NOT_PRESENT) {
@@ -2425,7 +2426,6 @@ static void process_op_defs(TCGContext *s)
 /* Missing TCGTargetOpDef entry. */
 tcg_debug_assert(tdefs != NULL);
 
-type = (def->flags & TCG_OPF_64BIT ? TCG_TYPE_I64 : TCG_TYPE_I32);
 for (i = 0; i < nb_args; i++) {
 const char *ct_str = tdefs->args_ct_str[i];
 /* Incomplete TCGTargetOpDef entry. */
@@ -2457,11 +2457,34 @@ static void process_op_defs(TCGContext *s)
 def->args_ct[i].ct |= TCG_CT_CONST;
 ct_str++;
 break;
+
+#ifdef TCG_TARGET_CON_STR_H
+/* Include all of the target-specific constraints. */
+
+#undef CONST
+#define CONST(CASE, MASK) \
+case CASE: def->args_ct[i].ct |= MASK; ct_str++; break;
+#define REGS(CASE, MASK) \
+case CASE: def->args_ct[i].regs |= MASK; ct_str++; break;
+
+#include "tcg-target-con-str.h"
+
+#undef REGS
+#undef CONST
 default:
-ct_str = target_parse_constraint(>args_ct[i],
- ct_str, type);
 /* Typo in TCGTargetOpDef constraint. */
-tcg_debug_assert(ct_str != NULL);
+g_assert_not_reached();
+#else
+default:
+{
+TCGType type = (def->flags & TCG_OPF_64BIT
+? TCG_TYPE_I64 : TCG_TYPE_I32);
+ct_str = target_parse_constraint(>args_ct[i],
+ ct_str, type);
+/* Typo in TCGTargetOpDef constraint. */
+tcg_debug_assert(ct_str != NULL);
+}
+#endif
 }
 }
 }
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index 74637f654a..c4b0b6bfca 

[PATCH v2 00/22] tcg: backend constraints cleanup

2021-01-15 Thread Richard Henderson
This pulls out constraints to a couple of headers, which
reduces the boilerplate just a little.

I have a longer term goal, which this aids, in which I
move some of the startup-time debug-only validation into
build/compile-time validation.  But not yet.

Changes for v2:
  * Rename "conset" -> "con-str" and "constr" -> "con-str" (pmm).
  * Fix a bunch of comment spelling mistakes.
  * Add some macro usage comments.


r~


Richard Henderson (22):
  tcg/tci: Drop L and S constraints
  tcg/i386: Move constraint type check to tcg_target_const_match
  tcg/i386: Split out target constraints to tcg-target-con-str.h
  tcg/arm: Split out target constraints to tcg-target-con-str.h
  tcg/aarch64: Split out target constraints to tcg-target-con-str.h
  tcg/ppc: Split out target constraints to tcg-target-con-str.h
  tcg/tci: Split out target constraints to tcg-target-con-str.h
  tcg/mips: Split out target constraints to tcg-target-con-str.h
  tcg/riscv: Split out target constraints to tcg-target-con-str.h
  tcg/s390: Split out target constraints to tcg-target-con-str.h
  tcg/sparc: Split out target constraints to tcg-target-con-str.h
  tcg: Remove TCG_TARGET_CON_STR_H
  tcg/i386: Split out constraint sets to tcg-target-con-set.h
  tcg/aarch64: Split out constraint sets to tcg-target-con-set.h
  tcg/arm: Split out constraint sets to tcg-target-con-set.h
  tcg/mips: Split out constraint sets to tcg-target-con-set.h
  tcg/ppc: Split out constraint sets to tcg-target-con-set.h
  tcg/riscv: Split out constraint sets to tcg-target-con-set.h
  tcg/s390: Split out constraint sets to tcg-target-con-set.h
  tcg/sparc: Split out constraint sets to tcg-target-con-set.h
  tcg/tci: Split out constraint sets to tcg-target-con-set.h
  tcg: Remove TCG_TARGET_CON_SET_H

 tcg/aarch64/tcg-target-con-set.h |  36 
 tcg/aarch64/tcg-target-con-str.h |  24 +++
 tcg/arm/tcg-target-con-set.h |  35 +++
 tcg/arm/tcg-target-con-str.h |  22 ++
 tcg/i386/tcg-target-con-set.h|  54 +
 tcg/i386/tcg-target-con-str.h|  33 +++
 tcg/mips/tcg-target-con-set.h|  36 
 tcg/mips/tcg-target-con-str.h|  24 +++
 tcg/ppc/tcg-target-con-set.h |  42 
 tcg/ppc/tcg-target-con-str.h |  30 +++
 tcg/riscv/tcg-target-con-set.h   |  30 +++
 tcg/riscv/tcg-target-con-str.h   |  21 ++
 tcg/s390/tcg-target-con-set.h|  29 +++
 tcg/s390/tcg-target-con-str.h|  23 ++
 tcg/sparc/tcg-target-con-set.h   |  32 +++
 tcg/sparc/tcg-target-con-str.h   |  22 ++
 tcg/sparc/tcg-target.h   |   4 -
 tcg/tci/tcg-target-con-set.h |  25 +++
 tcg/tci/tcg-target-con-str.h |  11 +
 tcg/tcg.c| 139 +++-
 tcg/aarch64/tcg-target.c.inc | 137 
 tcg/arm/tcg-target.c.inc | 163 --
 tcg/i386/tcg-target.c.inc| 317 +--
 tcg/mips/tcg-target.c.inc| 168 ---
 tcg/ppc/tcg-target.c.inc | 209 ++
 tcg/riscv/tcg-target.c.inc   | 133 +++-
 tcg/s390/tcg-target.c.inc| 161 +-
 tcg/sparc/tcg-target.c.inc   | 120 +++
 tcg/tci/tcg-target.c.inc | 359 +++
 29 files changed, 1190 insertions(+), 1249 deletions(-)
 create mode 100644 tcg/aarch64/tcg-target-con-set.h
 create mode 100644 tcg/aarch64/tcg-target-con-str.h
 create mode 100644 tcg/arm/tcg-target-con-set.h
 create mode 100644 tcg/arm/tcg-target-con-str.h
 create mode 100644 tcg/i386/tcg-target-con-set.h
 create mode 100644 tcg/i386/tcg-target-con-str.h
 create mode 100644 tcg/mips/tcg-target-con-set.h
 create mode 100644 tcg/mips/tcg-target-con-str.h
 create mode 100644 tcg/ppc/tcg-target-con-set.h
 create mode 100644 tcg/ppc/tcg-target-con-str.h
 create mode 100644 tcg/riscv/tcg-target-con-set.h
 create mode 100644 tcg/riscv/tcg-target-con-str.h
 create mode 100644 tcg/s390/tcg-target-con-set.h
 create mode 100644 tcg/s390/tcg-target-con-str.h
 create mode 100644 tcg/sparc/tcg-target-con-set.h
 create mode 100644 tcg/sparc/tcg-target-con-str.h
 create mode 100644 tcg/tci/tcg-target-con-set.h
 create mode 100644 tcg/tci/tcg-target-con-str.h

-- 
2.25.1




[PATCH v2 07/22] tcg/tci: Split out target constraints to tcg-target-con-str.h

2021-01-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/tci/tcg-target-con-str.h | 11 +++
 tcg/tci/tcg-target.h |  2 ++
 tcg/tci/tcg-target.c.inc | 14 --
 3 files changed, 13 insertions(+), 14 deletions(-)
 create mode 100644 tcg/tci/tcg-target-con-str.h

diff --git a/tcg/tci/tcg-target-con-str.h b/tcg/tci/tcg-target-con-str.h
new file mode 100644
index 00..87c0f19e9c
--- /dev/null
+++ b/tcg/tci/tcg-target-con-str.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define TCI target-specific operand constraints.
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * Define constraint letters for register sets:
+ * REGS(letter, register_mask)
+ */
+REGS('r', MAKE_64BIT_MASK(0, TCG_TARGET_NB_REGS))
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index bb784e018e..ab832aecc3 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -207,4 +207,6 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 /* no need to flush icache explicitly */
 }
 
+#define TCG_TARGET_CON_STR_H
+
 #endif /* TCG_TARGET_H */
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index 9c45f5f88f..c913d85c37 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -384,20 +384,6 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
 return true;
 }
 
-/* Parse target specific constraints. */
-static const char *target_parse_constraint(TCGArgConstraint *ct,
-   const char *ct_str, TCGType type)
-{
-switch (*ct_str++) {
-case 'r':
-ct->regs = BIT(TCG_TARGET_NB_REGS) - 1;
-break;
-default:
-return NULL;
-}
-return ct_str;
-}
-
 #if defined(CONFIG_DEBUG_TCG_INTERPRETER)
 /* Show current bytecode. Used by tcg interpreter. */
 void tci_disas(uint8_t opc)
-- 
2.25.1




[PATCH v2] docs/devel: Explain how acceptance tests can be skipped

2021-01-15 Thread Wainer dos Santos Moschetta
Documented under the "Acceptance tests using the Avocado Framework"
section in testing.rst how environment variables are used to skip tests.

Signed-off-by: Wainer dos Santos Moschetta 
---
v2:
 - Made the changes Thomas pointed out.

 docs/devel/testing.rst | 62 ++
 1 file changed, 62 insertions(+)

diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
index 0aa7a13bba..9f8b77c8ec 100644
--- a/docs/devel/testing.rst
+++ b/docs/devel/testing.rst
@@ -871,6 +871,68 @@ qemu_bin
 
 The exact QEMU binary to be used on QEMUMachine.
 
+Skipping tests
+--
+The Avocado framework provides Python decorators which allow for easily skip
+tests running under certain conditions. For example, on the lack of a binary
+on the test system or when the running environment is a CI system. For further
+information about those decorators, please refer to::
+
+  
https://avocado-framework.readthedocs.io/en/latest/guides/writer/chapters/writing.html#skipping-tests
+
+While the conditions for skipping tests are often specifics of each one, there
+are recurring scenarios identified by the QEMU developers and the use of
+environment variables became a kind of standard way to enable/disable tests.
+
+Here is a list of the most used variables:
+
+AVOCADO_ALLOW_LARGE_STORAGE
+~~~
+Tests which are going to fetch or produce assets considered *large* are not
+going to run unless that `AVOCADO_ALLOW_LARGE_STORAGE=1` is exported on
+the environment.
+
+The definition of *large* is a bit arbitrary here, but it usually means an
+asset which occupies at least 1GB of size on disk when uncompressed.
+
+AVOCADO_ALLOW_UNTRUSTED_CODE
+
+There are tests which will boot a kernel image or firmware that can be
+considered not safe to run on the developer's workstation, thus they are
+skipped by default. The definition of *not safe* is also arbitrary but
+usually it means a blob which either its source or build process aren't
+public available.
+
+You should export `AVOCADO_ALLOW_UNTRUSTED_CODE=1` on the environment in
+order to allow tests which make use of those kind of assets.
+
+AVOCADO_TIMEOUT_EXPECTED
+
+The Avocado framework has a timeout mechanism which interrupts tests to avoid 
the
+test suite of getting stuck. The timeout value can be set via test parameter or
+property defined in the test class, for further details::
+
+  
https://avocado-framework.readthedocs.io/en/latest/guides/writer/chapters/writing.html#setting-a-test-timeout
+
+Even though the timeout can be set by the test developer, there are some tests
+that may not have a well-defined limit of time to finish under certain
+conditions. For example, tests that take longer to execute when QEMU is
+compiled with debug flags. Therefore, the `AVOCADO_TIMEOUT_EXPECTED` variable
+has been used to determine whether those tests should run or not.
+
+GITLAB_CI
+~
+A number of tests are flagged to not run on the GitLab CI. Usually because
+they proved to the flaky or there are constraints on the CI environment which
+would make them fail. If you encounter a similar situation then use that
+variable as shown on the code snippet below to skip the test:
+
+.. code::
+
+  @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
+  def test(self):
+  do_something()
+
 Uninstalling Avocado
 
 
-- 
2.28.0




[PATCH] tests: Fix memory leak in tpm-util.c

2021-01-15 Thread Stefan Berger
This patch fixes the following memory leak detected by asan:

Indirect leak of 560320 byte(s) in 136 object(s) allocated from:
#0 0x556b3b3f9b57 in calloc 
(/home/stefanb/tmp/qemu-tip/build/tests/qtest/tpm-crb-swtpm-test+0x23fb57)
#1 0x152b0e96b9b0 in g_malloc0 (/lib64/libglib-2.0.so.0+0x589b0)
#2 0x556b3b588f61 in parse_object 
/home/stefanb/tmp/qemu-tip/build/../qobject/json-parser.c:318:12
#3 0x556b3b588f61 in parse_value 
/home/stefanb/tmp/qemu-tip/build/../qobject/json-parser.c:546:16
#4 0x556b3b5886e8 in json_parser_parse 
/home/stefanb/tmp/qemu-tip/build/../qobject/json-parser.c:580:14
#5 0x556b3b52ff4a in json_message_process_token 
/home/stefanb/tmp/qemu-tip/build/../qobject/json-streamer.c:92:12
#6 0x556b3b59896f in json_lexer_feed_char 
/home/stefanb/tmp/qemu-tip/build/../qobject/json-lexer.c:313:13
#7 0x556b3b598443 in json_lexer_feed 
/home/stefanb/tmp/qemu-tip/build/../qobject/json-lexer.c:350:9
#8 0x556b3b436c70 in qmp_fd_receive 
/home/stefanb/tmp/qemu-tip/build/../tests/qtest/libqtest.c:614:9
#9 0x556b3b435871 in qtest_qmp_receive_dict 
/home/stefanb/tmp/qemu-tip/build/../tests/qtest/libqtest.c:636:12
#10 0x556b3b435871 in qtest_qmp_receive 
/home/stefanb/tmp/qemu-tip/build/../tests/qtest/libqtest.c:624:27
#11 0x556b3b435c59 in qtest_vqmp 
/home/stefanb/tmp/qemu-tip/build/../tests/qtest/libqtest.c:715:12
#12 0x556b3b435c59 in qtest_qmp 
/home/stefanb/tmp/qemu-tip/build/../tests/qtest/libqtest.c:756:16
#13 0x556b3b4328c7 in tpm_util_wait_for_migration_complete 
/home/stefanb/tmp/qemu-tip/build/../tests/qtest/tpm-util.c:245:15
#14 0x556b3b4333be in tpm_test_swtpm_migration_test 
/home/stefanb/tmp/qemu-tip/build/../tests/qtest/tpm-tests.c:117:5
#15 0x152b0e98e29d  (/lib64/libglib-2.0.so.0+0x7b29d)

Signed-off-by: Stefan Berger 
Cc: Philippe Mathieu-Daudé 
---
 tests/qtest/tpm-util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qtest/tpm-util.c b/tests/qtest/tpm-util.c
index 5a33a6ef0f..b70cc32d60 100644
--- a/tests/qtest/tpm-util.c
+++ b/tests/qtest/tpm-util.c
@@ -250,7 +250,7 @@ void tpm_util_wait_for_migration_complete(QTestState *who)
 status = qdict_get_str(rsp_return, "status");
 completed = strcmp(status, "completed") == 0;
 g_assert_cmpstr(status, !=,  "failed");
-qobject_unref(rsp_return);
+qobject_unref(rsp);
 if (completed) {
 return;
 }
-- 
2.26.2




Re: [PATCH v2 12/25] tests/docker: add script for automating container refresh

2021-01-15 Thread Wainer dos Santos Moschetta

Hi,

On 1/14/21 10:02 AM, Daniel P. Berrangé wrote:

Signed-off-by: Daniel P. Berrangé 
---
  tests/docker/dockerfiles/refresh | 53 
  1 file changed, 53 insertions(+)
  create mode 100755 tests/docker/dockerfiles/refresh

diff --git a/tests/docker/dockerfiles/refresh b/tests/docker/dockerfiles/refresh


My suggestion is to rename the file to gen_dockerfiles.py and move to 
the parent directory.


To the best of my knowledge this community isn't picky about the style 
of Python code but if you run pylint you gonna see some warns worth a 
fix (mostly about bad indentation).



new file mode 100755
index 00..b1d99963e9
--- /dev/null
+++ b/tests/docker/dockerfiles/refresh
@@ -0,0 +1,53 @@
+#!/usr/bin/python3
+#
+# Re-generate container recipes
+#
+# This script uses the "lcitool" available from
+#
+#   https://gitlab.com/libvirt/libvirt-ci


Shouldn't we document somewhere else the use of this tool in QEMU? For 
those who don't know its purpose, how it can be installed/extended, 
etc... maybe having a README under tests/docker or just appending some 
words on "Docker based tests" section from docs/devel/testing.rst?


- Wainer


+#
+# Copyright (c) 2020 Red Hat Inc.
+#
+# This work is licensed under the terms of the GNU GPL, version 2
+# or (at your option) any later version. See the COPYING file in
+# the top-level directory.
+
+import sys
+import os
+import subprocess
+
+if len(sys.argv) != 2:
+   print("syntax: %s PATH-TO-LCITOOL" % sys.argv[0], file=sys.stderr)
+   sys.exit(1)
+
+lcitool_path=sys.argv[1]
+
+def atomic_write(filename, content):
+   try:
+  with open(filename + ".tmp", "w") as fp:
+ print(content, file=fp, end="")
+ os.replace(filename + ".tmp", filename)
+   except Exception as ex:
+  os.unlink(filename + ".tmp")
+  raise
+
+def generate_image(filename, host, cross=None, trailer=None):
+   print("Generate %s" % filename)
+   args = [lcitool_path, "dockerfile"]
+   if cross is not None:
+  args.extend(["--cross", cross])
+   args.extend([host, "qemu"])
+   lcitool=subprocess.run(args, capture_output=True)
+
+   if lcitool.returncode != 0:
+  raise Exception("Failed to generate %s: %s" % (filename, lcitool.stderr))
+
+   content = lcitool.stdout.decode("utf8")
+   if trailer is not None:
+  content += trailer
+   atomic_write(filename, content)
+
+try:
+   pass
+except Exception as ex:
+   print(str(ex), file=sys.stderr)





Re: [PATCH 04/15] arc: TCG and decoder glue code and helpers

2021-01-15 Thread Richard Henderson
On 1/15/21 7:11 AM, Cupertino Miranda wrote:
>> Similarly.  I think that both of these could be implemented entirely in
>> translate, which is what
>>
>>> +bool restore_fp= u7 & 0x10; /* u[4] indicates if fp must be saved  
>>> */
>>> +bool restore_blink = u7 & 0x20; /* u[5] indicates saving of blink  
>>> */
>>> +bool jump_to_blink = u7 & 0x40; /* u[6] should we jump to blink?   
>>> */
>>
>> these bits strongly imply.
>>
> 
> For lack of knowing better, it is unclear to me where to draw the line 
> when choosing between a translate time (tcg) or helper implementation.
> Your suggestions for carry/overflow computation are sharp and we should 
> have never used an helper, however I wonder what would be the benefit of 
> implementing enter and leave through TCG.
> 
> We have dealt with those exception issues by just changing SP in the end 
> of the instruction implementation, when no exceptions can happen.

5-10 tcg opcodes is the rule of thumb.  A conditional exception (requiring a
branch) is a good reason to put the whole thing out of line.

In the case of enter or leave, this is one load/store plus one addition,
followed by a branch.  All of which is encoded as fields in the instruction.
Extremely simple.

> As far as I understand when an exception happens in the middle of the 
> helper or even on a TCG implementation, it jumps out of that TB 
> execution to deal with the exception. On rtie instead of it returning to 
> the same tcg_ld or tcg_st where it actually triggered the exception it 
> will re-decode the same instruction which triggered the exception, and 
> re-attempts to execute it.
> Is that the case in current TCG implementation, or did it improved and 
> it is now able to return to previous execution flow (i.e translation 
> block) ?

I think I don't understand your question.

An exception leaves the TB, via longjmp.  Before the longjmp, there is normally
an "unwind" or "restore" operation, to sync the cpu state with the middle of
the TB.  This happens in restore_state_to_opc().

When processing of the exception is complete, execution will continue with the
appropriate cpu state.  Which will probably be a new TB that (logically)
partially overlaps the previous TB.

I.e. everything will work as you'd expect.

So... what's the question?


r~




Re: [PATCH 05/15] arc: TCG instruction generator and hand-definitions

2021-01-15 Thread Richard Henderson
On 1/15/21 7:11 AM, Cupertino Miranda wrote:
>> On 11/11/20 10:17 AM, cupertinomira...@gmail.com wrote:
>>> +/*
>>> + * The macro to add boiler plate code for conditional execution.
>>> + * It will add tcg_gen codes only if there is a condition to
>>> + * be checked (ctx->insn.cc != 0). This macro assumes that there
>>> + * is a "ctx" variable of type "DisasCtxt *" in context. Remember
>>> + * to pair it with CC_EPILOGUE macro.
>>> + */
>>> +#define CC_PROLOGUE   \
>>> +  TCGv cc = tcg_temp_local_new(); \
>>> +  TCGLabel *done = gen_new_label();   \
>>> +  do {\
>>> +if (ctx->insn.cc) {   \
>>> +arc_gen_verifyCCFlag(ctx, cc);\
>>> +tcg_gen_brcondi_tl(TCG_COND_NE, cc, 1, done); \
>>> +} \
>>> +  } while (0)
>>> +
>>> +/*
>>> + * The finishing counter part of CC_PROLUGE. This is supposed
>>> + * to be put at the end of the function using it.
>>> + */
>>> +#define CC_EPILOGUE  \
>>> +if (ctx->insn.cc) {  \
>>> +gen_set_label(done); \
>>> +}\
>>> +tcg_temp_free(cc)
>>
>> Why would this need to be boiler-plate?  Why would this not simply exist in
>> exactly one location?
>>
>> You don't need a tcg_temp_local_new, because the cc value is not used past 
>> the
>> branch.  You should free the temp immediately after the branch.
>>
> 
> I wonder if what you thought was to move those macros to functions and 
> call it when CC_PROLOGUE and CC_EPILOGUE are used.
> I think the macros were choosen due to the sharing of the 'cc' and 
> 'done' variables in both CC_PROLOGUE AND CC_EPILOGUE.

I meant that the checking of ctx->insn.cc could be done at a higher level, so
that this code existed in exactly one place, not scattered between all of the
different instructions.

But if that isn't possible for some reason, you can certainly put "done" into
the DisasContext so that you can have to functions cc_prologue(ctx) and
cc_epilogue(ctx).


>>> +void gen_goto_tb(DisasContext *ctx, int n, TCGv dest)
>>> +{
>>> +tcg_gen_mov_tl(cpu_pc, dest);
>>> +tcg_gen_andi_tl(cpu_pcl, dest, 0xfffc);
>>> +if (ctx->base.singlestep_enabled) {
>>> +gen_helper_debug(cpu_env);
>>> +}
>>> +tcg_gen_exit_tb(NULL, 0);
>>
>> Missing else.  This is dead code for single-step.
> Goes a little above my knowledge of QEMU internals to be honest.
> Do you have a recommendation what we should be doing here ?

Both of these actions end the TB, so:

  if (ctx->base.singlestep_enabled) {
gen_helper_debug(cpu_env);
  } else {
tcg_gen_exit_tb(NULL, 0);
  }

>> You could put all of these into a const static table.
> What do you mean, can we make the effect of tcg_global_mem_new_i32 as 
> constant ?

No, I mean all of the data that is passed to tcg_global_mem_new.  See for
instance target/sparc/translate.c, sparc_tcg_init().


>>> +static void init_constants(void)
>>> +{
>>> +#define SEMANTIC_FUNCTION(...)
>>> +#define MAPPING(...)
>>> +#define CONSTANT(NAME, MNEMONIC, OP_NUM, VALUE) \
>>> +  add_constant_operand(MAP_##MNEMONIC##_##NAME, OP_NUM, VALUE);
>>> +#include "target/arc/semfunc_mapping.def"
>>> +#include "target/arc/extra_mapping.def"
>>> +#undef MAPPING
>>> +#undef CONSTANT
>>> +#undef SEMANTIC_FUNCTION
>>> +}
>>
>> Ew.  Yet another thing that can be done at build time.
> As far as I remember it, there was no way I could generate this table 
> using the C pre-processor. Do you suggest to make this table using an 
> external tool ?

I assumed that you could just as easily generate a table using the c
preprocessor as this function.  I guess I'd like to know more about why you
can't...

>>> +int32_t limm = operand.value;
>>> +if (operand.type & ARC_OPERAND_LIMM) {
>>> +limm = ctx->insn.limm;
>>> +tcg_gen_movi_tl(cpu_limm, limm);
>>> +ret = cpu_r[62];
>>> +} else {
>>> +ret = tcg_const_local_i32(limm);
>>> +}
>>> +}
>>> +}
>>> +
>>> +  return ret;
>>
>> Why are you using locals for everything?  Is it because you have no proper
>> control over your use of branching?
> 
> Initially we though locals the good way to define temporaries. :-(
> What should be the best ? We will need to change a lot of code for this.

TCG is a poor optimizer.  If you can at all avoid branches, while implementing
a single instruction, do so.  Because this means that you can use
tcg_temp_new_i32 (et al) which are "normal" temps, and are not spilled to the
stack at the end of the BB.

This does not necessarily apply to conditional execution (cc_prologue, et al)
because you can think of those as "outside" of the instruction, merely wrapping
them.  The actual live temps will be "inside" and not live past the done label.

>>> +/* Return from 

  1   2   3   4   5   >